]> git.gag.com Git - debian/sudo/commitdiff
Imported Upstream version 1.8.4p4 upstream/1.8.4p4
authorBdale Garbee <bdale@gag.com>
Mon, 19 Mar 2012 10:35:21 +0000 (11:35 +0100)
committerBdale Garbee <bdale@gag.com>
Mon, 19 Mar 2012 10:35:21 +0000 (11:35 +0100)
187 files changed:
ChangeLog
INSTALL
MANIFEST
Makefile.in
NEWS
README
aclocal.m4
common/Makefile.in
common/aix.c
common/alloc.c
common/atobool.c
common/fileops.c
common/fmt_string.c
common/lbuf.c
common/list.c
common/setgroups.c
common/sudo_conf.c [new file with mode: 0644]
common/sudo_debug.c [new file with mode: 0644]
common/term.c
compat/Makefile.in
compat/fnmatch.c
compat/fnmatch.h
compat/getaddrinfo.c [new file with mode: 0644]
compat/getaddrinfo.h [new file with mode: 0644]
compat/nanosleep.c
compat/pw_dup.c [new file with mode: 0644]
compat/stdbool.h [new file with mode: 0644]
config.guess
config.h.in
config.sub
configure
configure.in
doc/CONTRIBUTORS
doc/LICENSE
doc/Makefile.in
doc/TROUBLESHOOTING
doc/UPGRADE
doc/contributors.pod
doc/sample.sudo.conf
doc/sudo.cat
doc/sudo.man.in
doc/sudo.pod
doc/sudo_plugin.cat
doc/sudo_plugin.man.in
doc/sudo_plugin.pod
doc/sudoers.cat
doc/sudoers.ldap.cat
doc/sudoers.ldap.man.in
doc/sudoers.ldap.pod
doc/sudoers.man.in
doc/sudoers.pod
doc/sudoreplay.cat
doc/sudoreplay.man.in
doc/visudo.cat
doc/visudo.man.in
doc/visudo.pod
include/Makefile.in
include/error.h
include/fileops.h
include/missing.h
include/sudo_conf.h [new file with mode: 0644]
include/sudo_debug.h [new file with mode: 0644]
include/sudo_plugin.h
ltmain.sh
m4/libtool.m4
m4/ltoptions.m4
m4/ltversion.m4
mkdep.pl
mkpkg
plugins/sample/Makefile.in
plugins/sample/sample_plugin.c
plugins/sample_group/Makefile.in
plugins/sample_group/sample_group.c
plugins/sudoers/Makefile.in
plugins/sudoers/alias.c
plugins/sudoers/audit.c
plugins/sudoers/auth/afs.c
plugins/sudoers/auth/aix_auth.c
plugins/sudoers/auth/bsdauth.c
plugins/sudoers/auth/dce.c
plugins/sudoers/auth/fwtk.c
plugins/sudoers/auth/kerb4.c [deleted file]
plugins/sudoers/auth/kerb5.c
plugins/sudoers/auth/pam.c
plugins/sudoers/auth/passwd.c
plugins/sudoers/auth/rfc1938.c
plugins/sudoers/auth/secureware.c
plugins/sudoers/auth/securid.c [deleted file]
plugins/sudoers/auth/securid5.c
plugins/sudoers/auth/sia.c
plugins/sudoers/auth/sudo_auth.c
plugins/sudoers/auth/sudo_auth.h
plugins/sudoers/boottime.c
plugins/sudoers/bsm_audit.c
plugins/sudoers/check.c
plugins/sudoers/def_data.c
plugins/sudoers/def_data.h
plugins/sudoers/def_data.in
plugins/sudoers/defaults.c
plugins/sudoers/defaults.h
plugins/sudoers/env.c
plugins/sudoers/find_path.c
plugins/sudoers/getdate.c
plugins/sudoers/getspwuid.c
plugins/sudoers/goodpath.c
plugins/sudoers/gram.c
plugins/sudoers/gram.y
plugins/sudoers/group_plugin.c
plugins/sudoers/interfaces.c
plugins/sudoers/interfaces.h
plugins/sudoers/iolog.c
plugins/sudoers/iolog_path.c
plugins/sudoers/ldap.c
plugins/sudoers/linux_audit.c
plugins/sudoers/logging.c
plugins/sudoers/logwrap.c
plugins/sudoers/match.c
plugins/sudoers/match_addr.c
plugins/sudoers/parse.c
plugins/sudoers/parse.h
plugins/sudoers/plugin_error.c
plugins/sudoers/po/da.mo
plugins/sudoers/po/da.po
plugins/sudoers/po/eo.mo
plugins/sudoers/po/eo.po
plugins/sudoers/po/fi.mo
plugins/sudoers/po/fi.po
plugins/sudoers/po/ja.mo
plugins/sudoers/po/ja.po
plugins/sudoers/po/pl.mo
plugins/sudoers/po/pl.po
plugins/sudoers/po/sudoers.pot
plugins/sudoers/po/uk.mo
plugins/sudoers/po/uk.po
plugins/sudoers/po/zh_CN.mo
plugins/sudoers/po/zh_CN.po
plugins/sudoers/pwutil.c
plugins/sudoers/redblack.c
plugins/sudoers/regress/iolog_path/check_iolog_path.c
plugins/sudoers/regress/logging/check_wrap.c
plugins/sudoers/regress/parser/check_addr.c
plugins/sudoers/regress/parser/check_fill.c
plugins/sudoers/regress/sudoers/test4.out.ok
plugins/sudoers/regress/sudoers/test5.out.ok
plugins/sudoers/regress/sudoers/test7.out.ok
plugins/sudoers/regress/sudoers/test8.out.ok
plugins/sudoers/set_perms.c
plugins/sudoers/sudo_nss.c
plugins/sudoers/sudoers.c
plugins/sudoers/sudoers.h
plugins/sudoers/sudoers_version.h
plugins/sudoers/sudoreplay.c
plugins/sudoers/testsudoers.c
plugins/sudoers/toke.c
plugins/sudoers/toke.h
plugins/sudoers/toke.l
plugins/sudoers/toke_util.c
plugins/sudoers/visudo.c
pp
src/Makefile.in
src/conversation.c
src/error.c
src/exec.c
src/exec_common.c [new file with mode: 0644]
src/exec_pty.c
src/get_pty.c
src/load_plugins.c
src/net_ifs.c
src/parse_args.c
src/po/es.mo [new file with mode: 0644]
src/po/es.po [new file with mode: 0644]
src/po/sr.mo [new file with mode: 0644]
src/po/sr.po [new file with mode: 0644]
src/po/sudo.pot
src/selinux.c
src/sesh.c
src/sudo.c
src/sudo.h
src/sudo_edit.c
src/sudo_exec.h
src/sudo_noexec.c
src/sudo_plugin_int.h
src/tgetpass.c
src/ttyname.c [new file with mode: 0644]
src/ttysize.c
src/utmp.c
sudo.pp

index 343eed79b57b1058ddbb0f26dd58b247d20bf8bd..87c7c504ef73d0808c0eb42369f1f3f7ed08d0cf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
-2012-01-24  Todd C. Miller  <Todd.Miller@courtesan.com>
+2012-03-12  Todd C. Miller  <Todd.Miller@courtesan.com>
 
-       * src/sudo.c:
-       Fixed a format string vulnerability when the sudo binary (or a 
-       symbolic link to the sudo binary) contains printf format escapes
-       and the -D (debugging) flag is used.
+       * .hgtags:
+       Added tag SUDO_1_8_4p4 for changeset 11a942f61d47
+       [4a20e5e9af5d] [tip] <1.8>
 
-2012-01-13  Todd C. Miller  <Todd.Miller@courtesan.com>
+       * NEWS, configure, configure.in:
+       Update for sudo 1.8.4p4
+       [11a942f61d47] [SUDO_1_8_4p4] <1.8>
+
+       * plugins/sudoers/parse.c:
+       Fix bogus int -> bool conversion; tags can have a value of -1.
+       [85ec4ae84fcf] <1.8>
 
        * sudo.pp:
-       Include parent directories in case they don't already exist. This
+       Fix application of debian-specific sudoers mods when building
+       packages as non-root.
+       [e3e7f75d718c] <1.8>
+
+       * .hgtags:
+       Added tag SUDO_1_8_4p3 for changeset 3093c8558862
+       [b82d3b208a4d] <1.8>
+
+       * NEWS, configure, configure.in:
+       Update for sudo 1.8.4p3
+       [3093c8558862] [SUDO_1_8_4p3] <1.8>
+
+       * plugins/sudoers/env.c:
+       matches_env_check() returns int, not boolean
+       [110f954181e1] <1.8>
+
+       * src/ttyname.c:
+       Simply move the free of ki_proc outside the realloc() loop.
+       [18209f1ff9f7] <1.8>
+
+       * src/ttyname.c:
+       Bring back the erealloc() for the ENOMEM loop and just zero the
+       pointer after we free it.
+       [83a1c1ec6b03] <1.8>
+
+       * doc/visudo.cat, doc/visudo.man.in:
+       regen
+       [04ea41a8657c] <1.8>
+
+       * src/ttyname.c:
+       Don't try to erealloc() a potentially freed pointer; Mateusz Guzik
+       [cca8a33ed286] <1.8>
+
+2012-03-09  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * src/exec_pty.c, src/ttyname.c:
+       Fix format string warning on Solaris with gcc 3.4.3.
+       [45322f41e677] <1.8>
+
+       * src/Makefile.in:
+       Honor LDFLAGS when linking sesh; from Vita Cizek
+       [349b3c929637] <1.8>
+
+       * src/sesh.c:
+       Include alloc.h for estrdup() prototype; from Vita Cizek
+       [f5ed422a6553] <1.8>
+
+2012-03-08  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * INSTALL:
+       Fix editor goof.
+       [574f0b17a91f] <1.8>
+
+2012-03-01  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * configure, configure.in:
+       Add check for variadic macro support in cpp.
+       [1ce59ac2e4f9] <1.8>
+
+2012-02-28  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * doc/visudo.pod, plugins/sudoers/visudo.c:
+       Check the owner and mode in -c (check) mode unless the -f option is
+       specified. Previously, the owner and mode were checked on the main
+       sudoers file when the -s (strict) option was given, but this was not
+       documented.
+       [dff2805fc49e] <1.8>
+
+       * config.h.in, configure, configure.in, src/ttyname.c:
+       Prefer KERN_PROC2 over KERN_PROC. Fixes compilation on some
+       versions of OpenBSD versions that have KERN_PROC2 but not KERN_PROC.
+       [dceb6078cda5] <1.8>
+
+2012-02-27  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * .hgtags:
+       Added tag SUDO_1_8_4p2 for changeset db564e1c02cf
+       [52638c160a4b] <1.8>
+
+       * NEWS, configure, configure.in:
+       bump version to 1.8.4p2
+       [db564e1c02cf] [SUDO_1_8_4p2] <1.8>
+
+       * src/exec_pty.c:
+       Fix typo in safe_close() made while converting to debug framework
+       that prevented it from actually closing anything.
+       [833a8ce346d2] <1.8>
+
+       * common/Makefile.in, compat/Makefile.in, doc/Makefile.in,
+       include/Makefile.in:
+       We need sysconfdir in compat/Makfile to get the proper sudo.conf
+       path. Add standard prefix and foodir expansion in all Makefiles to
+       avoid this problem in the future.
+       [ce1caa89c24d] <1.8>
+
+2012-02-24  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * plugins/sudoers/ldap.c:
+       When adding gids to the LDAP filter, only add the primary gid once.
+       This is consistent with the space computation/allocation. From Eric
+       Lakin
+       [229db740f035] <1.8>
+
+       * doc/TROUBLESHOOTING:
+       Add entry for AIX enhanced RBAC config.
+       [24f1e176e398] <1.8>
+
+       * mkpkg:
+       Target Mac OS X 10.5 when building packages.
+       [7b296251013d] <1.8>
+
+2012-02-21  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * .hgtags:
+       Added tag SUDO_1_8_4p1 for changeset aeb6b9701150
+       [26bc7af7c304] <1.8>
+
+       * NEWS:
+       List 1.8.4p1
+       [aeb6b9701150] [SUDO_1_8_4p1] <1.8>
+
+       * configure, configure.in:
+       bump version to 1.8.4p1
+       [2c7edc0bf0b7] <1.8>
+
+       * Fix the description of noexec.
+       [b5baebe2f820] <1.8>
+
+       * The "op" parameter to set_default() must be int, not bool since it
+       is set to '+' or '-' for list add and subtract.
+       [b6bf0980fb08] <1.8>
+
+       * Make sure sudoers is writable before calling ed script.
+       [97e0078b19ae] <1.8>
+
+2012-02-17  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * .hgtags:
+       Added tag SUDO_1_8_4 for changeset 7b0b7dfc84c7
+       [18d646360da5] <1.8>
+
+       * Update contributors. Now includes translators and authors of compat
+       code.
+       [7b0b7dfc84c7] [SUDO_1_8_4] <1.8>
+
+2012-02-16  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * src/po/sudo.pot:
+       regen
+       [fda54a3b1cd1] <1.8>
+
+       * Build flat packages, not package bundles, on Mac OS X.
+       [2f6f0704a09e] <1.8>
+
+2012-02-10  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * Sync with translationproject.org
+       [77a0b5480ae5] <1.8>
+
+       * configure, configure.in:
+       Don't permanently add -D_FORTIFY_SOURCE=2 to CPPFLAGS
+       [6588fc4a55a1] <1.8>
+
+       * sudo.pp:
+       Move macos section to be with the other OS-specific sections.
+       [c3cc794fd586] <1.8>
+
+       * Add Mac OS X support, printing the latest chunk of the NEWS file and
+       the license text in the installer.
+       [905d8fab423f] <1.8>
+
+       * Add explicit file modes that match those used by "make install"
+       [7e1eb99baf92] <1.8>
+
+       * Sync with upstream for Mac OS X fixes.
+       [90cec33d1108] <1.8>
+
+       * Got back to using "install-sh -M" for files installed as non-
+       readable by owner. This fixes "make install" as non-root for
+       package building.
+       [9e1e87961712] <1.8>
+
+2012-02-09  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * Sync with translationproject.org
+       [0c835326e22c] <1.8>
+
+       * Makefile.in:
+       Use -m not -M for install-sh for everything except setuid. Install
+       locale .mo files mode 0444, not 0644. If timedir parent doesn't
+       exist, use default dir mode, not 0700.
+       [451576bb0772] <1.8>
+
+2012-02-07  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * Re-sync with upstream; no longer need a local patch.
+       [342d3dceba65] <1.8>
+
+       * Add support for building Mac OS X packages.
+       [e047b6fbba17] <1.8>
+
+       * Sync with upstream
+       [20cc2ff83ee3] <1.8>
+
+       * No longer need to define _PATH_SUDO_CONF here.
+       [7da6e017c6d0] <1.8>
+
+       * Fix noexec for Mac OS X.
+       [71b8ee9eea74] <1.8>
+
+2012-02-06  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * Move _PATH_SUDO_CONF override to common to match sudo_conf.c
+       [639fe46fc8c0] <1.8>
+
+       * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+       fix version in .pot files
+       [37dbb6f99fc9] <1.8>
+
+       * More complete fix for LDR_PRELOAD on AIX. The addition of
+       set_perm(PERM_ROOT) before calling the nss open functions (needed to
+       avoid a GNU TLS bug) also broke LDR_PRELOAD. Setting the effective
+       and then real uid to 0 for PERM_ROOT works around the issue.
+       [5d52d2565dca] <1.8>
+
+       * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+       regen
+       [98e788019e50] <1.8>
+
+       * Set real uid to root before calling sudo_edit() or run_command() so
+       that the monitor process is owned by root and not by the user.
+       Otherwise, on AIX at least, the monitor process shows up in ps as
+       belonging to the user (and can be killed by the user).
+       [de4d852fef96] <1.8>
+
+       * For PERM_ROOT when using setreuid(), only set the euid to 0 prior to
+       the call to setuid(0) if the current euid is non-zero. This
+       effectively restores the state of things prior to rev 7bfeb629fccb.
+       Fixes a problem on AIX where LDR_PRELOAD was not being honored for
+       the command being executed.
+       [be1222842fc1] <1.8>
+
+       * configure, configure.in:
+       Make a copy of the struct passwd in exec_setup() to make sure
+       nothing in the policy init modifies it.
+       [5cbbbfffd1dc] <1.8>
+
+2012-02-05  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * doc/sudo.cat, doc/sudo.man.in, doc/sudoers.cat, doc/sudoers.man.in:
+       regen
+       [b67fc8934d2e] <1.8>
+
+       * update copyright
+       [df51e0f417de] <1.8>
+
+       * g/c now-unused debug subsystems
+       [888961d378f3] <1.8>
+
+       * Enumerate the debug subsystems used by sudo and sudoers.
+       [5418d7dd8ef4] <1.8>
+
+2012-02-03  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * NEWS, doc/sudo.cat, doc/sudo.man.in:
+       Normally, sudo disables core dumps while it is running. This
+       behavior can now be modified at run time with a line in sudo.conf
+       like "Set disable_coredumps false"
+       [ad21e940c5c2] <1.8>
+
+       * NEWS:
+       Mention Spanish translation
+       [bef71da9a4c2] <1.8>
+
+       * Make sure we don't try to fall back to using the conversation
+       function for debugging in the main sudo process if we are unable to
+       open the debug file.
+       [1f0e6451c85c] <1.8>
+
+       * Add sudo Spanish translation from translationproject.org
+       [2f71e4ecc6f9] <1.8>
+
+       * Better debug subsystem usage
+       [b313903c1fe4] <1.8>
+
+       * Remove duplicate function prototypes
+       [60860ae4d303] <1.8>
+
+2012-02-01  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * configure, configure.in:
+       Error out if user specified --with-pam but we can't find the headers
+       or library. Also throw an error if the headers are present but the
+       library is not and vice versa.
+       [445de14974ff] <1.8>
+
+2012-01-31  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * Fix the sudoers permission check when the expected sudoers mode is
+       owner-writable.
+       [ee1104bb2142] <1.8>
+
+2012-01-30  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * configure, configure.in:
+       Verify that we can link executables built with -D_FORTIFY_SOURCE
+       before using it.
+       [4dee7e2b5795] <1.8>
+
+       * Fix potential off-by-one when making a copy of the environment for
+       LD_PRELOAD insertion. Fixes bug #534
+       [3ddcf9a4de63] <1.8>
+
+       * configure, configure.in:
+       Add rudimentary check for _FORTIFY_SOURCE support by checking for
+       __sprintf_chk, one of the functions used by gcc to support it.
+       [029db376a497] <1.8>
+
+       * configure, configure.in:
+       Use AC_HEADER_STDBOOL instead of checking for stdbool.h ourselves.
+       [201d1f3b4aa2] <1.8>
+
+2012-01-29  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+       regen
+       [3c0ebf67b333] <1.8>
+
+2012-01-25  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * The change in 4fe0f357d34b that caused to exit when the monitor dies
+       created a race condition between the monitor exiting and the status
+       being read. All we really want to do is make sure that select()
+       notifies us that there is a status change when the monitor dies
+       unexpectedly so shutdown the socketpair connected to the monitor for
+       writing when it dies. That way we can still read the status that is
+       pending on the socket and select() on Linux will tell us that the fd
+       is ready.
+       [16c1a3da35c6] <1.8>
+
+       * Refactor disable_execute() and my_execve() into exec_common.c for
+       use by sesh.c. This fixes NOEXEC when SELinux is used. Instead of
+       disabling exec in exec_setup(), disable it immediately before
+       executing the command. Adapted from a diff by Arno Schuring.
+       [d266fdb5d00e] <1.8>
+
+2012-01-20  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * configure, configure.in:
+       Add custom version of AC_CHECK_LIB that uses the extra libs in the
+       cache value name. With this we no longer need to rely on a modified
+       version of autoconf.
+       [f5293f1a5968] <1.8>
+
+2012-01-19  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * configure, configure.in:
+       Better handling of network functions that need -lsocket -lnsl
+       [91dcddb6ec61] <1.8>
+
+       * When setting up the execution environment, set groups before
+       gid/egid like sudo 1.7 did.
+       [97a921461313] <1.8>
+
+       * configure, configure.in:
+       Remove "WARNING: unable to find foo() trying -lsocket -lnsl"
+       [c1c174183607] <1.8>
+
+       * For "sudo -g" prepend the specified group ID to the beginning of the
+       groups list. This matches BSD convention where the effective gid is
+       the first entry in the group list. This is required on newer
+       FreeBSD where the effective gid is not tracked separately and thus
+       setgroups() changes the egid if this convention is not followed.
+       Fixes bug #532
+       [5050708c2579] <1.8>
+
+2012-01-17  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * configure, configure.in:
+       Fix sh warning; use "test" instead of "["
+       [417fbc1dc5e8] <1.8>
+
+       * When not logging I/O, use a signal handler that only forwards
+       SIGINT, SIGQUIT and SIGHUP when they are user-generated signals.
+       Fixes a race in the non-I/O logging path where the command may
+       receive two keyboard-generated signals; one from the kernel and one
+       from the sudo process.
+       [24137cae39af] <1.8>
+
+       * Back out change that put the command in its own pgrp when not
+       logging I/O. It causes problems with pipelines.
+       [9c906f88e28c] <1.8>
+
+       * configure, configure.in:
+       Only run compat regress tests on compat objects we actually build.
+       Fixes "make check" in the compat dir for systems that don't
+       implement character classes in fnmatch() or glob(). Bug #531
+       [c052875fa32e] <1.8>
+
+2012-01-14  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * Update po files from translationproject.org
+       [8e54824c7b71] <1.8>
+
+2012-01-13  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * Include parent directories in case they don't already exist. This
        fixes a directory permissions problem with the AIX package when the
        /usr/local directories don't already exist.
+       [83df6fcba859] <1.8>
 
-2011-10-25  Todd C. Miller  <Todd.Miller@courtesan.com>
+       * sync with git version
+       [0964a02ba83e] <1.8>
 
-       * plugins/sudoers/Makefile.in:
-       check_addr needs to link with the network libraries on Solaris
-       [322bd70e316e]
+       * regen dependencies
+       [342e3719dc9e] <1.8>
 
-       * plugins/sudoers/match.c:
-       When matching a RunasAlias for a runas group, pass the alias in as
+       * Move tty name lookup code to its own file.
+       [9679de390de0] <1.8>
+
+2012-01-12  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * NEWS:
+       Update with latest sudo 1.8.4 changes.
+       [ef4e0a762766] <1.8>
+
+       * configure, configure.in:
+       Remove obsolete template for HAVE_TIMESPEC
+       [54a81b130d7e] <1.8>
+
+       * Add a check for devname() returning a fully-qualified pathname. None
+       of the devname() implementations do this today but you never know
+       when this might change.
+       [634654d38143] <1.8>
+
+2012-01-11  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * For "visudo -c" also list include files that were checked when
+       everything is OK.
+       [aa3be04c5d12] <1.8>
+
+       * The device name returned by devname() does not include the /dev/
+       prefix so we need to add it ourselves. Also add debug warning if
+       KERN_PROC sysctl fails or devname() can't resolve the tty device to
+       a name.
+       [5e90760f6c24] <1.8>
+
+       * The result of writev() is never checked so just cast to NULL.
+       [4a6820c77d7c] <1.8>
+
+       * Update Esperanto, Finnish, Polish and Ukrainian translations from
+       translationproject.org.
+       [3796fba03ff1] <1.8>
+
+2012-01-10  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * configure, configure.in:
+       Add support for determining tty via sysctl on other BSD variants.
+       [6e4b1ce7f45a] <1.8>
+
+       * configure, configure.in:
+       Only check for struct kinfo_proc.ki_tdev on systems that support
+       sysctl.
+       [33c700b439ff] <1.8>
+
+       * For FreeBSD, try the KERN_PROC_PID sysctl() first, falling back on
+       ttyname() of std{in,out,err}.
+       [30789189030b] <1.8>
+
+2012-01-09  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * configure, configure.in:
+       On newer FreeBSD we can get the parent's tty name via sysctl().
+       [d9449833859b] <1.8>
+
+       * Include locale.h
+       [98114209d1b5] <1.8>
+
+       * Silence a gcc warning.
+       [113934aaafa8] <1.8>
+
+       * Need to include gettext.h and sudo_debug.h; from John Hein
+       [3ec4bf7fcacf] <1.8>
+
+       * Initialize the debug framework from the I/O plugin too.
+       [ff525b1d9c4b] <1.8>
+
+       * Enable debugging via sudo.conf.
+       [2970ab524d25] <1.8>
+
+       * Use SUDO_DEBUG_ALIAS for alias checking functions.
+       [854fd74fe685] <1.8>
+
+       * configure, configure.in:
+       More complete test for getaddrinfo() that doesn't rely on the
+       network libraries already being added to LIBS.
+       [543af760a5d3] <1.8>
+
+2012-01-06  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * Add debug support.
+       [3b6aff4ee2bd] <1.8>
+
+       * configure, configure.in:
+       Need -lsocket -lnsl for getaddrinfo(3) on Solaris at least.
+       [f5b3fba6c83a] <1.8>
+
+       * Include errno.h and missing.h
+       [8a05166bb4d0] <1.8>
+
+       * doc/sudo.cat, doc/sudo.man.in, doc/sudo_plugin.cat,
+       doc/sudo_plugin.man.in, doc/sudoers.cat, doc/sudoers.ldap.cat,
+       doc/sudoers.ldap.man.in, doc/sudoers.man.in, doc/sudoreplay.cat,
+       doc/sudoreplay.man.in, doc/visudo.cat, doc/visudo.man.in:
+       regen
+       [f45ed34d9a97] <1.8>
+
+       * ignore doc/varsub
+       [51d0dfb2e274] <1.8>
+
+       * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+       regen pot files
+       [9ba13496954e] <1.8>
+
+       * configure.in:
+       Update copyright year.
+       [5219ae27b734] <1.8>
+
+       * NEWS:
+       Update for sudo 1.8.4
+       [75a6711efa76] <1.8>
+
+       * plugins/sudoers/po/sudoers.pot, src/po/sudo.pot:
+       regen pot files
+       [c8183dc16517] <1.8>
+
+       * Enable debugging via sudo.conf.
+       [63bee1548d5b] <1.8>
+
+       * Allow "visudo -c" to work when we only have read-only access to the
+       sudoers include files.
+       [c8a5e1f16e60] <1.8>
+
+       * Mention the CONTRIBUTORS file, not HISTORY in AUTHOR section. Add
+       HISTORY section in sudo that points to HISTORY file.
+       [8d845530d44f] <1.8>
+
+       * Document Debug setting in sudo.conf and debug_flags in plugin.
+       [da43e61209c0] <1.8>
+
+       * Do not include GLOB_MARK in the flags we pass to glob(3). Fixes a
+       bug where a pattern like "/usr/*" include /usr/bin/ in the results,
+       which would be incorrectly be interpreted as if the sudoers file had
+       specified a directory. From Vitezslav Cizek.
+       [5c71c962d1ad] <1.8>
+
+       * INSTALL, configure, configure.in:
+       Add --enable-kerb5-instance configure option to allow people using
+       Kerberos V authentication to use a custom instance. Adapted from a
+       diff by Michael E Burr.
+       [f432314f0a33] <1.8>
+
+       * Remove -D debug_level option.
+       [2754a61efbbe] <1.8>
+
+       * Update copyright year.
+       [3bd531625eeb] <1.8>
+
+2012-01-04  Todd C. Miller  <Todd.Miller@courtesan.com>
+
+       * parse_error is now bool, not int
+       [0cbd5c12b3eb] <1.8>
+
+       * Print a more sensible error if yyparse() returns non-zero but
+       yyerror() was not called.
+       [325a9871ff32] <1.8>
+
+       * Replace y.tab.c with the correct filename in #line directives.
+       [3073f5823a41] <1.8>
+
+       * configure, configure.in:
+       Bump version to 1.8.4
+       [4fe77346a1d1] <1.8>
+
+       * When trying to determine the tty, fall back on /proc/ppid/fd/{0,1,2}
+       if the main process's fds 0-2 are not hooked up to a tty. Adapted
+       from a diff by Zdenek Behan.
+       [40863388db30] <1.8>
+
+       * When not logging I/O, put command in its own pgrp and make that the
+       controlling pgrp if the command is in the foreground. Fixes a race
+       in the non-I/O logging path where the command may receive two
+       keyboard-generated signals; one from the kernel and one from the
+       sudo process.
+       [9f6ed53a62d6] <1.8>
+
+       * Quiet a bogus gcc warning.
+       [423322e16e27] <1.8>
+
+       * Fix warnings related to sudo.conf accessors.
+       [67b769099eec] <1.8>
+
+       * Separate sudo.conf parsing from plugin loading and move the parse
+       functions into the common lib so that visudo, etc. can use them.
+       [916162ff2443] <1.8>
+
+       * Remove support for noexec_file in sudoers and the plugin API
+       [e8a6743911be] <1.8>
+
+       * Don't dump interfaces if there are none.
+       [5a0326c36a1b] <1.8>
+
+       * Add missing %s printf escape to the group_plugin, iolog_dir and
+       iolog_file descriptions.
+       [05e3018e336c] <1.8>
+
+       * Fix typo in visiblepw description; from Joel Pickett
+       [f3a99aaf938f] <1.8>
+
+       * configure, configure.in, plugins/sudoers/login_class.c:
+       When running a login shell with a login_class specified, use
+       LOGIN_SETENV instead of rolling our own login.conf setenv support
+       since FreeBSD's login.conf has more than just setenv capabilities.
+       This requires us to swap the plugin-provided envp for the global
+       environ before calling setusercontext() and then stash the resulting
+       environ pointer back into the command details, which is kind of a
+       hack.
+       [99c71b6f629a] <1.8>
+
+       * If srcdir is "." just use the basename of the yacc/lex file when
+       generating the C version. This matches the generated files
+       currently in the repo.
+       [abcc3703d2e4] <1.8>
+
+       * Clean up the DEVEL noise
+       [b22a09c484cf] <1.8>
+
+       * Handle different Unix domain socket (actually socketpair) semantics
+       in BSD vs. Linux. In BSD if one end of the socketpair goes away
+       select() returns the fd as readable and the read will fail with
+       ECONNRESET. This doesn't appear to happen on Linux so if we notice
+       that the monitor process has died when I/O logging is enabled,
+       behave like the command has exited. This means we log the wait
+       status of the monitor, not the command, but there is nothing else we
+       can do at that point. This should only be an issue if SIGKILL is
+       sent to the monitor process.
+       [4fe0f357d34b] <1.8>
+
+       * Catch common signals in the monitor process so they get passed to
+       the command. Fixes a problem when the entire login session is
+       killed when ssh is disconnected or the terminal window is closed.
+       Previously, the monitor would exit and plugin's close method would
+       not be called.
+       [e41b2d9fc2c2] <1.8>
+
+       * INSTALL, configure, configure.in:
+       Mention how to configure pam_hpsec on HP-UX to play nicely with
+       sudo.
+       [ee4c73cce11d] <1.8>
+
+       * Escape values in the search expression as per RFC 4515.
+       [a249b85caccc] <1.8>
+
+       * No need for install target to depend explicitly on install-dirs, the
+       install-foo targets all depend on it.
+       [5f40ec883621] <1.8>
+
+       * ignore src/sesh
+       [0227b029ee08] <1.8>
+
+       * configure, configure.in:
+       Add support for setenv entries in login.conf. We can't use
+       LOGIN_SETENV since the plugin sets up the envp the command is
+       executed with. Also regen the Makefile.in files while here. Fixes
+       bug #527
+       [67d30f44bf45] <1.8>
+
+       * configure, configure.in:
+       Add getaddrinfo() for those without it, written by Russ Allbery
+       [57dd9b565bb6] <1.8>
+
+       * Restore PACKAGE_TARNAME, it is used in docdir
+       [cf27a773d65e] <1.8>
+
+       * SunPro C Compiler also has a _Bool builtin. Also add stdbool.h to
+       the MANIFEST
+       [4fa4f6cef15e] <1.8>
+
+       * Remove duplicate return statements.
+       [f0f9000461c1] <1.8>
+
+       * emove inaccurate comment
+       [e3bf2cef6256] <1.8>
+
+       * Fetch the login class for the user we authenticate specifically when
+       using BSD authentication. That user may have a different login
+       class than what we will use to run the command. When setting the
+       login class for the command, use the target user's struct passwd,
+       not the invoking user's. Fixes bug 526
+       [e3094ce63bd7] <1.8>
+
+       * configure, configure.in:
+       Replace @DEV@ prefix with DEVEL variable so we can do "make DEVEL=1"
+       [453f562645a2] <1.8>
+
+       * Fix "make check" fallout from the sudo_conv changes in sudo_debug.
+       [1e2f0d298b06] <1.8>
+
+       * configure, configure.in:
+       Use stdbool.h instead of rolling our own TRUE/FALSE macros.
+       [2a5841db0c50] <1.8>
+
+       * configure, configure.in:
+       Add stdbool.h for systems without it.
+       [8ac0317f2ba0] <1.8>
+
+       * configure, configure.in:
+       No longer need SUDO_CHECK_TYPE and SUDO_TYPE_* now that the default
+       includes have unistd.h in them. Add check for socklen_t for
+       upcoming getaddrinfo compat.
+       [7c0ed30c075d] <1.8>
+
+       * configure, configure.in:
+       Use HAVE_STRUCT_TIMESPEC and HAVE_STRUCT_IN6_ADDR instead of
+       HAVE_TIMESPEC and HAVE_IN6_ADDR respectively.
+       [57a6a5bf69a2] <1.8>
+
+       * No longer need to include time.h here as missing.h does not use
+       time_t.
+       [029653d78ba2] <1.8>
+
+       * Fix mode on sudoers as needed when the -f option is not specified.
+       [c4aba4a1b23b] <1.8>
+
+       * Add Serbian translation for sudo from translationproject.org
+       [47a04d718e36] <1.8>
+
+       * No longer pass debug_file to plugin, plugins must now use
+       CONV_DEBUG_MSG
+       [c7ceddf724bf] <1.8>
+
+       * Build PIE executables for newer Debian and Ubuntu
+       [2e9162e59c2c] <1.8>
+
+       * Include time.h for ctime() prototype.
+       [5f27df493b93] <1.8>
+
+       * Do not close error pipe or debug fd via closefrom() as we need them
+       to report an exec error should one occur.
+       [9638f4e7fd14] <1.8>
+
+       * Document that a sudoUser may now be a group ID.
+       [42d725aa8b6d] <1.8>
+
+       * Add support for permitting access by group ID in addition to group
+       name.
+       [3506e5c7e41c] <1.8>
+
+       * Older Netscape LDAP SDKs don't prototype ldapssl_set_strength()
+       [4c973a863d0d] <1.8>
+
+       * Replace UCB fnmatch.c with a non-recursive version written by
+       William A. Rowe Jr.
+       [76666139f49d] <1.8>
+
+       * Fix typo, return_debug vs. debug_return
+       [810d9b2d2f9a] <1.8>
+
+       * Update Japanese sudoers translation from translationproject.org
+       [b051e2bc692e] <1.8>
+
+       * Make the env_reset descriptions consistent.
+       [3cf883ec8b33] <1.8>
+
+       * configure, configure.in:
+       Do multiple expansion when expanding paths to the noexec file, sesh
+       and the plugin directory. Adapted from a diff by Mike Frysinger
+       [68cdecdd8457] <1.8>
+
+       * regen
+       [ca37d8cb647b] <1.8>
+
+       * Add ignore file; from Mike Frysinger
+       [0bd0f92a2d40] <1.8>
+
+       * no longer save old Makefile.in to .old
+       [7dcf2a857c6b] <1.8>
+
+       * regen
+       [a029a2ad7256] <1.8>
+
+       * configure:
+       Update to libtool 2.4.2
+       [6590ddb6a23f] <1.8>
+
+       * Bump grammar version for #include and #includedir relative path
+       support.
+       [138a446a638e] <1.8>
+
+       * Add support for relative paths in #include and #includedir
+       [8bf56e39e1ad] <1.8>
+
+       * Fix install-plugin when shared objects are unsupported or disabled.
+       [952cf7867482] <1.8>
+
+       * Don't write to sbp if it is NULL
+       [0cc959722ab8] <1.8>
+
+       * Makefile.in:
+       If LINGUAS is set, only install matching .mo files
+       [5d83050eec1f] <1.8>
+
+       * Fix non-dynamic (no dlopen) sudo build.
+       [fd688ac640a0] <1.8>
+
+       * configure, configure.in:
+       Don't error out if the user specified --disable-shared
+       [4f811a8ee9e8] <1.8>
+
+       * Use SUDO_CONV_DEBUG_MSG in the plugin instead of writing directly to
+       the debug file.
+       [bc6124038170] <1.8>
+
+       * Make sudo_goodpath() return value bolean
+       [25bf43cdf7f0] <1.8>
+
+       * INSTALL, configure, configure.in, plugins/sudoers/auth/securid.c:
+       Remove obsolete securid auth method.
+       [a8a092f8bd83] <1.8>
+
+       * Prefix authentication functions with a "sudo_" prefix to avoid
+       namespace problems.
+       [049ea2995793] <1.8>
+
+       * INSTALL, configure, configure.in, plugins/sudoers/auth/kerb4.c:
+       Remove the old Kerberos IV support
+       [c59b0b39af66] <1.8>
+
+       * Don't print garbage at the end of the custom lecture.
+       [4f1fd9a1241a] <1.8>
+
+       * Add lexer tracing as debug@parser
+       [ebf43f87296a] <1.8>
+
+       * Add devdir before srcdir in include path and fix up dependecies
+       accordingly and add better devdir support to mkdep.pl. We also need
+       to #include <gram.h> not "gram.h" and <def_data.h> and not
+       "def_data.h" when generating the parser in a build dir.
+       [daeafaec094b] <1.8>
+
+       * Mark libexec files as optional. If we build without shared object
+       support, libexec is not used.
+       [194434733454] <1.8>
+
+       * Change Debug sudo.conf setting to take a program name as the first
+       argument. In the future, this will allow visudo and sudoreplay to
+       use their own Debug entries.
+       [92abedbd38c6] <1.8>
+
+       * fix sudo_debug_printf priority
+       [0815bedee086] <1.8>
+
+       * add missing debug_return_int
+       [37840a0d8fe4] <1.8>
+
+       * Fold SUDO_DEBUG_PROGERR and SUDO_DEBUG_SYSERR into SUDO_DEBUG_ERROR
+       [82f7deaff7ba] <1.8>
+
+       * Add missing word in HOME security note.
+       [87bd6a891eac] <1.8>
+
+       * Prevent "testsudoers -d username" from trying to malloc(0).
+       [d7acceacf6e8] <1.8>
+
+       * Tests for empty sudoers (should parse OK) and syntax errors within a
+       line (should report correct line number) both with and without the
+       trailing newline.
+       [cf44b45af86d] <1.8>
+
+       * Print line number when there is a parser error.
+       [34380cefcfdf] <1.8>
+
+       * Keep track of the last token returned. On error, if the last token
+       was COMMENT, decrement sudolineno since the error most likely
+       occurred on the preceding line. Previously we always uses
+       sudolineno-1 which will give the wrong line number for errors within
+       a line.
+       [02ce7cc40f4d] <1.8>
+
+       * NEWS:
+       update with sudo 1.8.3p1 info
+       [5f4cd440bf00] <1.8>
+
+       * Fix crash when "sudo -g group -i" is run. Fixes bug 521
+       [83ee9a90b107] <1.8>
+
+       * Make alias_remove_recursive() return TRUE/FALSE as its callers
+       expect and remove two unused arguments. Fixes bug 519.
+       [ec2cfa235c65] <1.8>
+
+       * Add regress test for bugzilla 519
+       [237b3698c8ae] <1.8>
+
+       * Disable warning/error wrapping in regress tests.
+       [630ac985bcfc] <1.8>
+
+       * Makefile.in:
+       Do compile-po as part of sync-po so that the .mo files get rebuild
+       automatically when we sync with translationproject.org
+       [f09f15a5c40e] <1.8>
+
+       * check_addr needs to link with the network libraries on Solaris
+       [04465307990f] <1.8>
+
+       * When matching a RunasAlias for a runas group, pass the alias in as
        the group_list, not the user_list. From Daniel Kopecek.
-       [766545edf141]
+       [9c8f4b57b7cb] <1.8>
 
-       * plugins/sudoers/check.c, plugins/sudoers/sudoers.c:
-       We need to init the auth system regardless of whether we need a
+       * We need to init the auth system regardless of whether we need a
        password since we will be closing the PAM session in the monitor
        process. Fixes a crash in the monitor on Solaris; bugzilla #518
-       [e82809f86fb3]
+       [7e312caf74eb] <1.8>
+
+       * Get rid of done: label. If the child exits we still need to close
+       the pty, update utmp and restore the SELinux tty context.
+       [cda935f856e8] <1.8>
+
+       * Add debug_decl/debug_return (almost) everywhere. Remove old
+       sudo_debug() and convert users to sudo_debug_printf().
+       [a97d9dc61e3f] <1.8>
+
+       * Wrap error/errorx and warning/warningx functions with debug
+       statements. Disable wrapping for standalone sudoers programs as well
+       as memory allocation functions (to avoid infinite recursion).
+       [e942083dab8e] <1.8>
+
+       * README, configure, configure.in:
+       Add checks for __func__ and __FUNCTION__ and mention that we now
+       require a cpp that supports variadic macros.
+       [961dfb044b4e] <1.8>
+
+       * New debug framework for sudo and plugins using /etc/sudo.conf that
+       also supports function call tracing.
+       [94d9aa72df19] <1.8>
 
 2011-10-21  Todd C. Miller  <Todd.Miller@courtesan.com>
 
diff --git a/INSTALL b/INSTALL
index a2c9cb46c4004cad237e5a5e438267123cc3a28b..faa294ae0fb4e9d2e3127af203c2477180091cd3 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -166,19 +166,13 @@ Special features/options:
 
   --with-SecurID[=DIR]
        Enable SecurID support.  If specified, DIR is directory containing
-       sdiclient.a, sdi_athd.h, sdconf.h, and sdacmvls.h.
+       libaceclnt.a, acexport.h, and sdacmvls.h.
 
   --with-fwtk[=DIR]
        Enable TIS Firewall Toolkit (FWTK) 'authsrv' support. If specified,
        DIR is the base directory containing the compiled FWTK package
        (or at least the library and header files).
 
-  --with-kerb4[=DIR]
-       Enable Kerberos IV support.  If specified, DIR is the base
-       directory containing the Kerberos IV include and lib dirs.
-       This uses Kerberos passphrases for authentication but does
-       not use the Kerberos cookie scheme.
-
   --with-kerb5[=DIR]
        Enable Kerberos V support.  If specified, DIR is the base
        directory containing the Kerberos V include and lib dirs.
@@ -186,6 +180,13 @@ Special features/options:
        does not use the Kerberos cookie scheme.  Will not work for
        Kerberos V older than version 1.1.
 
+  --enable-kerb5-instance=string
+        By default, the user name is used as the principal name
+        when authenticating via Kerberos V.  If this option is
+        enabled, the specified instance string will be appended to
+        the user name (separated by a slash) when creating the
+        principal name.
+
   --with-ldap[=DIR]
        Enable LDAP support.  If specified, DIR is the base directory
        containing the LDAP include and lib directories.  Please see
@@ -285,7 +286,7 @@ Special features/options:
         older PAM implementations or on operating systems where
         opening a PAM session changes the utmp or wtmp files.  If
         PAM session support is disabled, resource limits may not
-        be updatedin for command being run.
+        be updated for the command being run.
 
   --disable-root-mailer
        By default sudo will run the mailer as root when tattling
@@ -744,6 +745,12 @@ HP-UX:
 
     sudo       session required        libpam_hpsec.so.1 bypass_umask
 
+    If every command run via sudo displays information about the last
+    successful login and the last authentication failure you should
+    make use an /etc/pam.conf line like:
+
+    sudo       session required        libpam_hpsec.so.1 bypass_umask bypass_last_login
+
 Digital UNIX:
     By default, sudo will use SIA (Security Integration Architecture)
     to validate a user.  If you want to use an alternative authentication
index f7c1f90ba6034515b3962c9e4d38b6a06afc8fcc..03106b2728cd24e6cb0589adf9f63c31d85c4b8e 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -16,6 +16,8 @@ common/fmt_string.c
 common/lbuf.c
 common/list.c
 common/setgroups.c
+common/sudo_conf.c
+common/sudo_debug.c
 common/term.c
 common/zero_bytes.c
 compat/Makefile.in
@@ -25,6 +27,8 @@ compat/dlfcn.h
 compat/dlopen.c
 compat/fnmatch.c
 compat/fnmatch.h
+compat/getaddrinfo.c
+compat/getaddrinfo.h
 compat/getcwd.c
 compat/getgrouplist.c
 compat/getline.c
@@ -37,6 +41,7 @@ compat/mksiglist.c
 compat/mksiglist.h
 compat/mktemp.c
 compat/nanosleep.c
+compat/pw_dup.c
 compat/regress/fnmatch/fnm_test.c
 compat/regress/fnmatch/fnm_test.in
 compat/regress/glob/files
@@ -45,6 +50,7 @@ compat/regress/glob/globtest.in
 compat/setenv.c
 compat/siglist.in
 compat/snprintf.c
+compat/stdbool.h
 compat/strlcat.c
 compat/strlcpy.c
 compat/strsignal.c
@@ -101,6 +107,8 @@ include/gettext.h
 include/lbuf.h
 include/list.h
 include/missing.h
+include/sudo_conf.h
+include/sudo_debug.h
 include/sudo_plugin.h
 indent.pro
 install-sh
@@ -132,13 +140,11 @@ plugins/sudoers/auth/aix_auth.c
 plugins/sudoers/auth/bsdauth.c
 plugins/sudoers/auth/dce.c
 plugins/sudoers/auth/fwtk.c
-plugins/sudoers/auth/kerb4.c
 plugins/sudoers/auth/kerb5.c
 plugins/sudoers/auth/pam.c
 plugins/sudoers/auth/passwd.c
 plugins/sudoers/auth/rfc1938.c
 plugins/sudoers/auth/secureware.c
-plugins/sudoers/auth/securid.c
 plugins/sudoers/auth/securid5.c
 plugins/sudoers/auth/sia.c
 plugins/sudoers/auth/sudo_auth.c
@@ -262,6 +268,7 @@ src/Makefile.in
 src/conversation.c
 src/error.c
 src/exec.c
+src/exec_common.c
 src/exec_pty.c
 src/get_pty.c
 src/load_plugins.c
@@ -272,6 +279,8 @@ src/po/da.mo
 src/po/da.po
 src/po/eo.mo
 src/po/eo.po
+src/po/es.mo
+src/po/es.po
 src/po/eu.mo
 src/po/eu.po
 src/po/fi.mo
@@ -284,6 +293,8 @@ src/po/pl.mo
 src/po/pl.po
 src/po/ru.mo
 src/po/ru.po
+src/po/sr.mo
+src/po/sr.po
 src/po/sudo.pot
 src/po/uk.mo
 src/po/uk.po
@@ -300,6 +311,7 @@ src/sudo_noexec.c
 src/sudo_plugin_int.h
 src/sudo_usage.h.in
 src/tgetpass.c
+src/ttyname.c
 src/ttysize.c
 src/utmp.c
 sudo.pp
index d367fd25d903b6305ee03eaac68e9460a7e73aa0..fcfbbc9ce0b0a3b7a514e628d01d48025e5cb456 100644 (file)
@@ -114,11 +114,7 @@ uninstall: uninstall-nls
 uninstall-nls:
        for pot in $(POTFILES); do \
            domain=`basename $$pot .pot`; \
-           podir=`dirname $$pot`; \
-           for po in $$podir/*.po; do \
-               lang=`basename $$po .po`; \
-               rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$$domain.mo; \
-           done; \
+           rm -f $(DESTDIR)$(localedir)/*/LC_MESSAGES/$$domain.mo; \
        done
 
 autoconf:
@@ -166,7 +162,9 @@ libtool: $(LIBTOOL_DEPS)
 Makefile: $(srcdir)/Makefile.in
        ./config.status --file Makefile
 
-sync-po:
+sync-po: rsync-po compile-po
+
+rsync-po:
        rsync -Lrtvz  translationproject.org::tp/latest/sudo/ src/po/
        rsync -Lrtvz  translationproject.org::tp/latest/sudoers/ plugins/sudoers/po/
 
@@ -231,12 +229,13 @@ install-nls:
            for pot in $(POTFILES); do \
                podir=`dirname $$pot`; \
                domain=`basename $$pot .pot`; \
+               SUDO_LINGUAS=$${LINGUAS-"`echo $$podir/*.mo|sed 's:'$$podir'/\([^ ]*\).mo:\1:g'`"}; \
                echo $(ECHO_N) "Installing $$domain message catalogs:$(ECHO_C)"; \
-               for mo in $$podir/*.mo; do \
-                   lang=`basename $$mo .mo`; \
+               for lang in $$SUDO_LINGUAS; do \
+                   test -s $$podir/$$lang.mo || continue; \
                    echo $(ECHO_N) " $$lang$(ECHO_C)"; \
                    $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES; \
-                   $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0644 $$mo $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$$domain.mo; \
+                   $(INSTALL) -O $(install_uid) -G $(install_gid) -m 0444 $$podir/$$lang.mo $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$$domain.mo; \
                done; \
                echo ""; \
            done; \
diff --git a/NEWS b/NEWS
index 49d454b26a7e3c7317b8f778ed2a63ee5ef14670..16842e788dd40dba874601ee9f5343a8ee9e7518 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,115 @@
+What's new in Sudo 1.8.4p4?
+
+ * Fixed a bug introduced in Sudo 1.8.4 which prevented "sudo -v"
+   from working.
+
+What's new in Sudo 1.8.4p3?
+
+ * Fixed a crash on FreeBSD when no tty is present.
+
+ * Fixed a bug introduced in Sudo 1.8.4 that allowed users to
+   specify environment variables to set on the command line without
+   having sudo "ALL" permissions or the "SETENV" tag.
+
+ * When visudo is run with the -c (check) option, the sudoers
+   file(s) owner and mode are now also checked unless the -f option
+   was specified.
+
+What's new in Sudo 1.8.4p2?
+
+ * Fixed a bug introduced in Sudo 1.8.4 where insufficient space
+   was allocated for group IDs in the LDAP filter.
+
+ * Fixed a bug introduced in Sudo 1.8.4 where the path to sudo.conf
+   was "/sudo.conf" instead of "/etc/sudo.conf".
+
+ * Fixed a bug introduced in Sudo 1.8.4 which could cause a hang
+   when I/O logging is enabled and input is from a pipe or file.
+
+What's new in Sudo 1.8.4p1?
+
+ * Fixed a bug introduced in sudo 1.8.4 that broke adding to or
+   deleting from the env_keep, env_check and env_delete lists in
+   sudoers on some platforms.
+
+What's new in Sudo 1.8.4?
+
+ * The -D flag in sudo has been replaced with a more general debugging
+   framework that is configured in sudo.conf.
+
+ * Fixed a false positive in visudo strict mode when aliases are
+   in use.
+
+ * Fixed a crash with "sudo -i" when a runas group was specified
+   without a runas user.
+
+ * The line on which a syntax error is reported in the sudoers file
+   is now more accurate.  Previously it was often off by a line.
+
+ * Fixed a bug where stack garbage could be printed at the end of
+   the lecture when the "lecture_file" option was enabled.
+
+ * "make install" now honors the LINGUAS environment variable.
+
+ * The #include and #includedir directives in sudoers now support
+   relative paths.  If the path is not fully qualified it is expected
+   to be located in the same directory of the sudoers file that is
+   including it.
+
+ * Serbian and Spanish translations for sudo from translationproject.org.
+
+ * LDAP-based sudoers may now access by group ID in addition to
+   group name.
+
+ * visudo will now fix the mode on the sudoers file even if no changes
+   are made unless the -f option is specified.
+
+ * The "use_loginclass" sudoers option works properly again.
+
+ * On systems that use login.conf, "sudo -i" now sets environment
+   variables based on login.conf.
+
+ * For LDAP-based sudoers, values in the search expression are now
+   escaped as per RFC 4515.
+
+ * The plugin close function is now properly called when a login
+   session is killed (as opposed to the actual command being killed).
+   This can happen when an ssh session is disconnected or the
+   terminal window is closed.
+
+ * The deprecated "noexec_file" sudoers option is no longer supported.
+
+ * Fixed a race condition when I/O logging is not enabled that could
+   result in tty-generated signals (e.g. control-C) being received
+   by the command twice.
+
+ * If none of the standard input, output or error are connected to
+   a tty device, sudo will now check its parent's standard input,
+   output or error for the tty name on systems with /proc and BSD
+   systems that support the KERN_PROC_PID sysctl.  This allows
+   tty-based tickets to work properly even when, e.g. standard
+   input, output and error are redirected to /dev/null.
+
+ * Added the --enable-kerb5-instance configure option to allow
+   people using Kerberos V authentication to specify a custom
+   instance so the principal name can be, e.g. "username/sudo"
+   similar to how ksu uses "username/root".
+
+ * Fixed a bug where a pattern like "/usr/*" included /usr/bin/ in
+   the results, which would be incorrectly be interpreted as if the
+   sudoers file had specified a directory.
+
+ * "visudo -c" will now list any include files that were checked
+   in addition to the main sudoers file when everything parses OK.
+
+ * Users that only have read-only access to the sudoers file may
+   now run "visudo -c".  Previously, write permissions were required
+   even though no writing is down in check-only mode.
+
+ * It is now possible to prevent the disabling of core dumps from
+   within sudo itself by adding a line to the sudo.conf file like
+   "Set disable_coredump false".
+
 What's new in Sudo 1.8.3p2?
 
  * Fixed a format string vulnerability when the sudo binary (or a
@@ -80,7 +192,7 @@ What's new in Sudo 1.8.2?
  * Visudo now checks the contents of an alias and warns about cycles
    when the alias is expanded.
 
- * If the user specifes a group via sudo's -g option that matches
+ * If the user specifies a group via sudo's -g option that matches
    the target user's group in the password database, it is now
    allowed even if no groups are present in the Runas_Spec.
 
diff --git a/README b/README
index 919c74a6565d97e06382a0e45a97ac4d34e99c08..d5a0b22ee6705005d4631cb69bcc3c3808fc130b 100644 (file)
--- a/README
+++ b/README
@@ -11,11 +11,10 @@ version.  The latest sudo may always be gotten via anonymous ftp from
 ftp.sudo.ws in the directory /pub/sudo/ or from the sudo web site,
 http://www.sudo.ws/
 
-The distribution is sudo-M.m.tar.gz where `M' is the major
-version number and `m' is the minor version number.
-BETA versions of sudo may also be available.  If you join
-the `sudo-workers' mailing list you will get the BETA announcements
-(see the `Mailing lists' section below).
+The distribution is sudo-M.m.tar.gz where `M' is the major version
+number and `m' is the minor version number.  BETA versions of sudo may
+also be available.  If you join the `sudo-workers' mailing list you
+will get the BETA announcements (see the `Mailing lists' section below).
 
 What's new
 ==========
@@ -28,22 +27,22 @@ If you are upgrading from an earlier version of Sudo, please see
 the UPGRADE file in the doc directory.
 
 For a history of sudo please see the HISTORY file in the doc directory.
+You can find a list of contributors to sudo in the doc/CONTRIBUTORS file.
 
 System requirements
 ===================
-To build sudo from the source distribution you need a nominally
-POSIX-compliant operating system (any modern version of BSD, Linux
-or UNIX should work), a working ANSI/ISO C compiler (C89 or higher),
-and the ar, make and ranlib utilities
+To build sudo from the source distribution you need a POSIX-compliant
+operating system (any modern version of BSD, Linux or Unix should
+work), an ANSI/ISO C compiler that supports variadic marcos (a C99
+feature) and the ar, make and ranlib utilities.
 
 If you wish to modify the parser then you will need flex version
 2.5.2 or later and either bison or byacc (sudo comes with a pre-flex'd
 tokenizer and pre-yacc'd grammar parser).  You'll also have to
 uncomment a few lines from the Makefile or run configure with the
---with-devel option.  You can get flex via anonymous ftp from
-ftp://ftp.ee.lbl.gov/pub/flex* as well as any GNU mirror.  You can
-get GNU bison from ftp://ftp.gnu.org/pub/gnu/bison/ or any GNU
-mirror.
+--with-devel option.  You can get flex from http://flex.sourceforge.net/.
+You can get GNU bison from ftp://ftp.gnu.org/pub/gnu/bison/ or any
+GNU mirror.
 
 Building the release
 ====================
index e83926cf9a4419545355efeb967b583175f24c76..c14b04f07f546dd8bd66e3690723e88a6e3925d4 100644 (file)
@@ -156,52 +156,6 @@ AC_DEFUN([SUDO_IO_LOGDIR], [
     AC_MSG_RESULT($iolog_dir)
 ])dnl
 
-dnl
-dnl SUDO_CHECK_TYPE(TYPE, DEFAULT)
-dnl XXX - should require the check for unistd.h...
-dnl
-AC_DEFUN([SUDO_CHECK_TYPE],
-[AC_REQUIRE([AC_HEADER_STDC])dnl
-AC_MSG_CHECKING(for $1)
-AC_CACHE_VAL(sudo_cv_type_$1,
-[AC_EGREP_CPP($1, [#include <sys/types.h>
-#include <stdio.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif], sudo_cv_type_$1=yes, sudo_cv_type_$1=no)])dnl
-AC_MSG_RESULT($sudo_cv_type_$1)
-if test $sudo_cv_type_$1 = no; then
-  AC_DEFINE($1, $2, [Define if your system lacks the $1 type.])
-fi
-])
-
-dnl
-dnl Check for size_t declation
-dnl
-AC_DEFUN([SUDO_TYPE_SIZE_T],
-[SUDO_CHECK_TYPE(size_t, int)])
-
-dnl
-dnl Check for ssize_t declation
-dnl
-AC_DEFUN([SUDO_TYPE_SSIZE_T],
-[SUDO_CHECK_TYPE(ssize_t, int)])
-
-dnl
-dnl Check for dev_t declation
-dnl
-AC_DEFUN([SUDO_TYPE_DEV_T],
-[SUDO_CHECK_TYPE(dev_t, int)])
-
-dnl
-dnl Check for ino_t declation
-dnl
-AC_DEFUN([SUDO_TYPE_INO_T],
-[SUDO_CHECK_TYPE(ino_t, unsigned int)])
-
 dnl
 dnl check for working fnmatch(3)
 dnl
@@ -231,6 +185,28 @@ AC_DEFUN([SUDO_FUNC_ISBLANK],
   fi
 ])
 
+AC_DEFUN([SUDO_CHECK_LIB], [
+    _sudo_check_lib_extras=`echo "$5"|sed -e 's/[      ]*//g' -e 's/-l/_/g'`
+    AC_MSG_CHECKING([for $2 in -l$1${5+ }$5])
+    AC_CACHE_VAL([sudo_cv_lib_$1''_$2$_sudo_check_lib_extras], [
+       SUDO_CHECK_LIB_OLIBS="$LIBS"
+       LIBS="$LIBS -l$1${5+ }$5"
+       AC_LINK_IFELSE(
+           [AC_LANG_CALL([], [$2])],
+           [eval sudo_cv_lib_$1''_$2$_sudo_check_lib_extras=yes],
+           [eval sudo_cv_lib_$1''_$2$_sudo_check_lib_extras=no]
+       )
+       LIBS="$SUDO_CHECK_LIB_OLIBS"
+    ])
+    if eval test \$sudo_cv_lib_$1''_$2$_sudo_check_lib_extras = "yes"; then
+       AC_MSG_RESULT([yes])
+       $3
+    else
+       AC_MSG_RESULT([no])
+       $4
+    fi
+])
+
 dnl
 dnl check unsetenv() return value
 dnl
@@ -257,7 +233,7 @@ dnl check for sa_len field in struct sockaddr
 dnl
 AC_DEFUN([SUDO_SOCK_SA_LEN], [
     AC_CHECK_MEMBER([struct sockaddr.sa_len], 
-       [AC_DEFINE(HAVE_SA_LEN, 1, [Define if your struct sockadr has an sa_len field.])],    
+       [AC_DEFINE(HAVE_STRUCT_SOCKADDR_SA_LEN, 1, [Define if your struct sockadr has an sa_len field.])],    
        [],
        [ #include <sys/types.h>
          #include <sys/socket.h>] 
index a1319eff6304842f8b3884511636c7ce8a5e9f88..7dd7c9d110ef6abc0c081b9b290bd02a92637e8c 100644 (file)
@@ -25,6 +25,16 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 incdir = $(top_srcdir)/include
 
+# Where to install things...
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
+datarootdir = @datarootdir@
+localstatedir = @localstatedir@
+
 # Compiler & tools to use
 CC = @CC@
 LIBTOOL = @LIBTOOL@
@@ -36,14 +46,15 @@ CPPFLAGS = -I$(incdir) -I$(top_builddir) -I$(top_srcdir) @CPPFLAGS@
 CFLAGS = @CFLAGS@
 
 # OS dependent defines
-DEFS = @OSDEFS@
+DEFS = @OSDEFS@ -D_PATH_SUDO_CONF=\"$(sysconfdir)/sudo.conf\"
 
 #### End of system configuration section. ####
 
 SHELL = @SHELL@
 
-LTOBJS = alloc.lo atobool.lo fileops.lo fmt_string.lo \
-        lbuf.lo list.lo setgroups.lo term.lo zero_bytes.lo @COMMON_OBJS@
+LTOBJS = alloc.lo atobool.lo fileops.lo fmt_string.lo lbuf.lo \
+        list.lo setgroups.lo sudo_conf.lo sudo_debug.lo term.lo \
+        zero_bytes.lo @COMMON_OBJS@
 
 all: libcommon.la
 
@@ -93,29 +104,45 @@ cleandir: realclean
 
 # Autogenerated dependencies, do not modify
 aix.lo: $(srcdir)/aix.c $(top_builddir)/config.h $(incdir)/missing.h \
-        $(incdir)/alloc.h $(incdir)/error.h $(incdir)/gettext.h
+        $(incdir)/alloc.h $(incdir)/error.h $(incdir)/sudo_debug.h \
+        $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/aix.c
 alloc.lo: $(srcdir)/alloc.c $(top_builddir)/config.h $(incdir)/missing.h \
           $(incdir)/alloc.h $(incdir)/error.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/alloc.c
-atobool.lo: $(srcdir)/atobool.c $(top_builddir)/config.h $(incdir)/missing.h
+atobool.lo: $(srcdir)/atobool.c $(top_builddir)/config.h $(incdir)/missing.h \
+            $(incdir)/sudo_debug.h
        $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/atobool.c
 fileops.lo: $(srcdir)/fileops.c $(top_builddir)/config.h \
-            $(top_srcdir)/compat/timespec.h $(incdir)/missing.h \
-            $(incdir)/fileops.h
+            $(top_srcdir)/compat/stdbool.h $(top_srcdir)/compat/timespec.h \
+            $(incdir)/missing.h $(incdir)/fileops.h $(incdir)/sudo_debug.h
        $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/fileops.c
 fmt_string.lo: $(srcdir)/fmt_string.c $(top_builddir)/config.h \
-               $(incdir)/missing.h
+               $(incdir)/missing.h $(incdir)/sudo_debug.h
        $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/fmt_string.c
 lbuf.lo: $(srcdir)/lbuf.c $(top_builddir)/config.h $(incdir)/missing.h \
-         $(incdir)/alloc.h $(incdir)/error.h $(incdir)/lbuf.h
+         $(incdir)/alloc.h $(incdir)/error.h $(incdir)/lbuf.h \
+         $(incdir)/sudo_debug.h
        $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/lbuf.c
 list.lo: $(srcdir)/list.c $(top_builddir)/config.h $(incdir)/missing.h \
          $(incdir)/list.h $(incdir)/error.h
        $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/list.c
-setgroups.lo: $(srcdir)/setgroups.c $(top_builddir)/config.h $(incdir)/missing.h
+setgroups.lo: $(srcdir)/setgroups.c $(top_builddir)/config.h \
+              $(incdir)/missing.h $(incdir)/sudo_debug.h
        $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/setgroups.c
-term.lo: $(srcdir)/term.c $(top_builddir)/config.h $(incdir)/missing.h
+sudo_conf.lo: $(srcdir)/sudo_conf.c $(top_builddir)/config.h \
+              $(top_srcdir)/compat/stdbool.h $(incdir)/missing.h \
+              $(incdir)/alloc.h $(incdir)/error.h $(incdir)/fileops.h \
+              $(top_builddir)/pathnames.h $(incdir)/sudo_plugin.h \
+              $(incdir)/sudo_conf.h $(incdir)/list.h $(incdir)/sudo_debug.h
+       $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/sudo_conf.c
+sudo_debug.lo: $(srcdir)/sudo_debug.c $(top_builddir)/config.h \
+               $(top_srcdir)/compat/stdbool.h $(incdir)/missing.h \
+               $(incdir)/alloc.h $(incdir)/error.h $(incdir)/gettext.h \
+               $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h
+       $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/sudo_debug.c
+term.lo: $(srcdir)/term.c $(top_builddir)/config.h $(incdir)/missing.h \
+         $(incdir)/sudo_debug.h
        $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/term.c
 zero_bytes.lo: $(srcdir)/zero_bytes.c $(top_builddir)/config.h \
                $(incdir)/missing.h
index 875eb8cbb91d456a5d89b2fb187edd1556cb4b29..bd20b2672466251502a9dfdcb7ca9820b28c5cf2 100644 (file)
@@ -34,6 +34,7 @@
 #include "missing.h"
 #include "alloc.h"
 #include "error.h"
+#include "sudo_debug.h"
 
 #define DEFAULT_TEXT_DOMAIN    "sudo"
 #include "gettext.h"
@@ -72,11 +73,12 @@ static int
 aix_getlimit(char *user, char *lim, rlim64_t *valp)
 {
     int val;
+    debug_decl(aix_getlimit, SUDO_DEBUG_UTIL)
 
     if (getuserattr(user, lim, &val, SEC_INT) != 0)
-       return -1;
+       debug_return_int(-1);
     *valp = val;
-    return 0;
+    debug_return_int(0);
 }
 
 static void
@@ -85,6 +87,7 @@ aix_setlimits(char *user)
     struct rlimit64 rlim;
     rlim64_t val;
     int n;
+    debug_decl(aix_setlimits, SUDO_DEBUG_UTIL)
 
     if (setuserdb(S_READ) != 0)
        error(1, "unable to open userdb");
@@ -126,6 +129,7 @@ aix_setlimits(char *user)
        (void)setrlimit64(aix_limits[n].resource, &rlim);
     }
     enduserdb();
+    debug_return;
 }
 
 #ifdef HAVE_SETAUTHDB
@@ -138,6 +142,7 @@ void
 aix_setauthdb(char *user)
 {
     char *registry;
+    debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL)
 
     if (user != NULL) {
        if (setuserdb(S_READ) != 0)
@@ -149,6 +154,7 @@ aix_setauthdb(char *user)
        }
        enduserdb();
     }
+    debug_return;
 }
 
 /*
@@ -157,8 +163,12 @@ aix_setauthdb(char *user)
 void
 aix_restoreauthdb(void)
 {
+    debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL)
+
     if (setauthdb(NULL, NULL) != 0)
        error(1, _("unable to restore registry"));
+
+    debug_return;
 }
 #endif
 
@@ -167,6 +177,7 @@ aix_prep_user(char *user, const char *tty)
 {
     char *info;
     int len;
+    debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL)
 
     /* set usrinfo, like login(1) does */
     len = easprintf(&info, "NAME=%s%cLOGIN=%s%cLOGNAME=%s%cTTY=%s%c",
@@ -181,5 +192,7 @@ aix_prep_user(char *user, const char *tty)
 
     /* set resource limits */
     aix_setlimits(user);
+
+    debug_return;
 }
 #endif /* HAVE_GETUSERATTR */
index d3a251657c2186796b9d32bf1f3aac99fd612318..7d5fe7e9e5c7596238861eb9a2baa8ce5d1fe626 100644 (file)
@@ -79,10 +79,10 @@ emalloc(size_t size)
     void *ptr;
 
     if (size == 0)
-       errorx(1, _("internal error, tried to emalloc(0)"));
+       errorx2(1, _("internal error, tried to emalloc(0)"));
 
     if ((ptr = malloc(size)) == NULL)
-       errorx(1, _("unable to allocate memory"));
+       errorx2(1, _("unable to allocate memory"));
     return ptr;
 }
 
@@ -96,13 +96,13 @@ emalloc2(size_t nmemb, size_t size)
     void *ptr;
 
     if (nmemb == 0 || size == 0)
-       errorx(1, _("internal error, tried to emalloc2(0)"));
+       errorx2(1, _("internal error, tried to emalloc2(0)"));
     if (nmemb > SIZE_MAX / size)
-       errorx(1, _("internal error, emalloc2() overflow"));
+       errorx2(1, _("internal error, emalloc2() overflow"));
 
     size *= nmemb;
     if ((ptr = malloc(size)) == NULL)
-       errorx(1, _("unable to allocate memory"));
+       errorx2(1, _("unable to allocate memory"));
     return ptr;
 }
 
@@ -116,11 +116,11 @@ erealloc(void *ptr, size_t size)
 {
 
     if (size == 0)
-       errorx(1, _("internal error, tried to erealloc(0)"));
+       errorx2(1, _("internal error, tried to erealloc(0)"));
 
     ptr = ptr ? realloc(ptr, size) : malloc(size);
     if (ptr == NULL)
-       errorx(1, _("unable to allocate memory"));
+       errorx2(1, _("unable to allocate memory"));
     return ptr;
 }
 
@@ -135,14 +135,14 @@ erealloc3(void *ptr, size_t nmemb, size_t size)
 {
 
     if (nmemb == 0 || size == 0)
-       errorx(1, _("internal error, tried to erealloc3(0)"));
+       errorx2(1, _("internal error, tried to erealloc3(0)"));
     if (nmemb > SIZE_MAX / size)
-       errorx(1, _("internal error, erealloc3() overflow"));
+       errorx2(1, _("internal error, erealloc3() overflow"));
 
     size *= nmemb;
     ptr = ptr ? realloc(ptr, size) : malloc(size);
     if (ptr == NULL)
-       errorx(1, _("unable to allocate memory"));
+       errorx2(1, _("unable to allocate memory"));
     return ptr;
 }
 
@@ -200,7 +200,7 @@ easprintf(char **ret, const char *fmt, ...)
     va_end(ap);
 
     if (len == -1)
-       errorx(1, _("unable to allocate memory"));
+       errorx2(1, _("unable to allocate memory"));
     return len;
 }
 
@@ -214,7 +214,7 @@ evasprintf(char **ret, const char *format, va_list args)
     int len;
 
     if ((len = vasprintf(ret, format, args)) == -1)
-       errorx(1, _("unable to allocate memory"));
+       errorx2(1, _("unable to allocate memory"));
     return len;
 }
 
index f22aae8a0f2d44e3c7986473467ab83a43c4a1a5..6d6b5028938bbabb209eb1d2d6072c37e59ab31a 100644 (file)
 #endif /* HAVE_STRINGS_H */
 
 #include "missing.h"
+#include "sudo_debug.h"
 
 int
 atobool(const char *str)
 {
+    debug_decl(atobool, SUDO_DEBUG_UTIL)
+
     switch (*str) {
        case '0':
        case '1':
@@ -77,5 +80,5 @@ atobool(const char *str)
                return 0;
            break;
     }
-    return -1;
+    debug_return_int(-1);
 }
index 38cc0c1c6ca72bdde36d89bc10d6a6d05af1e79f..f99710c0330d96a25ad14bd264bc0e68c59c2655 100644 (file)
 # include <sys/file.h>
 #endif /* HAVE_FLOCK */
 #include <stdio.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
 #ifdef HAVE_STRING_H
 # include <string.h>
 #endif /* HAVE_STRING_H */
 #if TIME_WITH_SYS_TIME
 # include <time.h>
 #endif
-#ifndef HAVE_TIMESPEC
+#ifndef HAVE_STRUCT_TIMESPEC
 # include "compat/timespec.h"
 #endif
 
 #include "missing.h"
 #include "fileops.h"
+#include "sudo_debug.h"
 
 #ifndef LINE_MAX
 # define LINE_MAX 2048
@@ -61,6 +67,8 @@ int
 touch(int fd, char *path, struct timeval *tvp)
 {
     struct timeval times[2];
+    int rval = -1;
+    debug_decl(touch, SUDO_DEBUG_UTIL)
 
     if (tvp != NULL) {
        times[0].tv_sec = times[1].tv_sec = tvp->tv_sec;
@@ -69,23 +77,23 @@ touch(int fd, char *path, struct timeval *tvp)
 
 #if defined(HAVE_FUTIME) || defined(HAVE_FUTIMES)
     if (fd != -1)
-       return futimes(fd, tvp ? times : NULL);
+       rval = futimes(fd, tvp ? times : NULL);
     else
 #endif
     if (path != NULL)
-       return utimes(path, tvp ? times : NULL);
-    else
-       return -1;
+       rval = utimes(path, tvp ? times : NULL);
+    debug_return_int(rval);
 }
 
 /*
  * Lock/unlock a file.
  */
 #ifdef HAVE_LOCKF
-int
+bool
 lock_file(int fd, int lockit)
 {
     int op = 0;
+    debug_decl(lock_file, SUDO_DEBUG_UTIL)
 
     switch (lockit) {
        case SUDO_LOCK:
@@ -98,13 +106,14 @@ lock_file(int fd, int lockit)
            op = F_ULOCK;
            break;
     }
-    return lockf(fd, op, 0) == 0;
+    debug_return_bool(lockf(fd, op, 0) == 0);
 }
 #elif HAVE_FLOCK
-int
+bool
 lock_file(int fd, int lockit)
 {
     int op = 0;
+    debug_decl(lock_file, SUDO_DEBUG_UTIL)
 
     switch (lockit) {
        case SUDO_LOCK:
@@ -117,15 +126,16 @@ lock_file(int fd, int lockit)
            op = LOCK_UN;
            break;
     }
-    return flock(fd, op) == 0;
+    debug_return_bool(flock(fd, op) == 0);
 }
 #else
-int
+bool
 lock_file(int fd, int lockit)
 {
 #ifdef F_SETLK
     int func;
     struct flock lock;
+    debug_decl(lock_file, SUDO_DEBUG_UTIL)
 
     lock.l_start = 0;
     lock.l_len = 0;
@@ -134,9 +144,9 @@ lock_file(int fd, int lockit)
     lock.l_whence = SEEK_SET;
     func = (lockit == SUDO_LOCK) ? F_SETLKW : F_SETLK;
 
-    return fcntl(fd, func, &lock) == 0;
+    debug_return_bool(fcntl(fd, func, &lock) == 0);
 #else
-    return TRUE;
+    return true;
 #endif
 }
 #endif
@@ -151,6 +161,7 @@ sudo_parseln(FILE *fp)
     size_t len;
     char *cp = NULL;
     static char buf[LINE_MAX];
+    debug_decl(sudo_parseln, SUDO_DEBUG_UTIL)
 
     if (fgets(buf, sizeof(buf), fp) != NULL) {
        /* Remove comments */
@@ -164,5 +175,5 @@ sudo_parseln(FILE *fp)
        for (cp = buf; isblank((unsigned char)*cp); cp++)
            continue;
     }
-    return cp;
+    debug_return_str(cp);
 }
index a9c723218ac9b3bc3d60f59cc7b43922a473726d..23bc5f72bdf8fe794d7ddc54cfdcf54876b3e5e3 100644 (file)
@@ -39,6 +39,7 @@
 #endif /* HAVE_STRINGS_H */
 
 #include "missing.h"
+#include "sudo_debug.h"
 
 /*
  * Allocate storage for a name=value string and return it.
@@ -49,6 +50,7 @@ fmt_string(const char *var, const char *val)
     size_t var_len = strlen(var);
     size_t val_len = strlen(val);
     char *cp, *str;
+    debug_decl(fmt_string, SUDO_DEBUG_UTIL)
 
     cp = str = malloc(var_len + 1 + val_len + 1);
        if (str != NULL) {
@@ -60,5 +62,5 @@ fmt_string(const char *var, const char *val)
        *cp = '\0';
     }
 
-    return str;
+    debug_return_str(str);
 }
index dc2b7bfafdc13891de04e5163975020604f36c92..4618b94b5b3bd047fb418219ef97255c9c91ef13 100644 (file)
 #include "alloc.h"
 #include "error.h"
 #include "lbuf.h"
+#include "sudo_debug.h"
 
 void
 lbuf_init(struct lbuf *lbuf, int (*output)(const char *),
     int indent, const char *continuation, int cols)
 {
+    debug_decl(lbuf_init, SUDO_DEBUG_UTIL)
+
     lbuf->output = output;
     lbuf->continuation = continuation;
     lbuf->indent = indent;
@@ -59,13 +62,19 @@ lbuf_init(struct lbuf *lbuf, int (*output)(const char *),
     lbuf->len = 0;
     lbuf->size = 0;
     lbuf->buf = NULL;
+
+    debug_return;
 }
 
 void
 lbuf_destroy(struct lbuf *lbuf)
 {
+    debug_decl(lbuf_destroy, SUDO_DEBUG_UTIL)
+
     efree(lbuf->buf);
     lbuf->buf = NULL;
+
+    debug_return;
 }
 
 /*
@@ -78,6 +87,7 @@ lbuf_append_quoted(struct lbuf *lbuf, const char *set, const char *fmt, ...)
     va_list ap;
     int len;
     char *cp, *s = NULL;
+    debug_decl(lbuf_append_quoted, SUDO_DEBUG_UTIL)
 
     va_start(ap, fmt);
     while (*fmt != '\0') {
@@ -118,6 +128,8 @@ lbuf_append_quoted(struct lbuf *lbuf, const char *set, const char *fmt, ...)
     }
     lbuf->buf[lbuf->len] = '\0';
     va_end(ap);
+
+    debug_return;
 }
 
 /*
@@ -129,6 +141,7 @@ lbuf_append(struct lbuf *lbuf, const char *fmt, ...)
     va_list ap;
     int len;
     char *s = NULL;
+    debug_decl(lbuf_append, SUDO_DEBUG_UTIL)
 
     va_start(ap, fmt);
     while (*fmt != '\0') {
@@ -155,6 +168,8 @@ lbuf_append(struct lbuf *lbuf, const char *fmt, ...)
     }
     lbuf->buf[lbuf->len] = '\0';
     va_end(ap);
+
+    debug_return;
 }
 
 static void
@@ -162,6 +177,7 @@ lbuf_println(struct lbuf *lbuf, char *line, int len)
 {
     char *cp, save;
     int i, have, contlen;
+    debug_decl(lbuf_println, SUDO_DEBUG_UTIL)
 
     contlen = lbuf->continuation ? strlen(lbuf->continuation) : 0;
 
@@ -210,6 +226,8 @@ lbuf_println(struct lbuf *lbuf, char *line, int len)
        }
        lbuf->output("\n");
     }
+
+    debug_return;
 }
 
 /*
@@ -221,6 +239,7 @@ lbuf_print(struct lbuf *lbuf)
 {
     char *cp, *ep;
     int len;
+    debug_decl(lbuf_print, SUDO_DEBUG_UTIL)
 
     if (lbuf->buf == NULL || lbuf->len == 0)
        goto done;
@@ -250,4 +269,6 @@ lbuf_print(struct lbuf *lbuf)
 
 done:
     lbuf->len = 0;             /* reset the buffer for re-use. */
+
+    debug_return;
 }
index 693317773888c4db2ff4f15b4edc5dc9c9679d30..a656a6e8e3b43a51dce288e7654a04a94810ea70 100644 (file)
@@ -81,7 +81,7 @@ list2tq(void *vh, void *vl)
     if (l != NULL) {
 #ifdef DEBUG
        if (l->prev == NULL) {
-           warningx("list2tq called with non-semicircular list");
+           warningx2("list2tq called with non-semicircular list");
            abort();
        }
 #endif
index 2c42816f1734d673ec8449d4cf1e7edbfa417c35..41df2256c1fb677eac23a0ca856528e1a440ff14 100644 (file)
 #include <limits.h>
 
 #include "missing.h"
+#include "sudo_debug.h"
 
 int
 sudo_setgroups(int ngids, const GETGROUPS_T *gids)
 {
     int maxgids, rval;
+    debug_decl(sudo_setgroups, SUDO_DEBUG_UTIL)
 
     rval = setgroups(ngids, gids);
     if (rval == -1 && errno == EINVAL) {
@@ -53,5 +55,5 @@ sudo_setgroups(int ngids, const GETGROUPS_T *gids)
        if (ngids > maxgids)
            rval = setgroups(maxgids, gids);
     }
-    return rval;
+    debug_return_int(rval);
 }
diff --git a/common/sudo_conf.c b/common/sudo_conf.c
new file mode 100644 (file)
index 0000000..3ddd861
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2009-2011 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 <sys/stat.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <ctype.h>
+
+#define SUDO_ERROR_WRAP        0
+
+#include "missing.h"
+#include "alloc.h"
+#include "error.h"
+#include "fileops.h"
+#include "pathnames.h"
+#include "sudo_plugin.h"
+#include "sudo_conf.h"
+#include "sudo_debug.h"
+
+#ifndef _PATH_SUDO_ASKPASS
+# define _PATH_SUDO_ASKPASS    NULL
+#endif
+
+extern bool atobool(const char *str); /* atobool.c */
+
+struct sudo_conf_table {
+    const char *name;
+    unsigned int namelen;
+    bool (*setter)(const char *entry);
+};
+
+struct sudo_conf_paths {
+    const char *pname;
+    unsigned int pnamelen;
+    const char *pval;
+};
+
+static bool set_debug(const char *entry);
+static bool set_path(const char *entry);
+static bool set_plugin(const char *entry);
+static bool set_variable(const char *entry);
+
+static struct sudo_conf_table sudo_conf_table[] = {
+    { "Debug", sizeof("Debug") - 1, set_debug },
+    { "Path", sizeof("Path") - 1, set_path },
+    { "Plugin", sizeof("Plugin") - 1, set_plugin },
+    { "Set", sizeof("Set") - 1, set_variable },
+    { NULL }
+};
+
+static struct sudo_conf_data {
+    bool disable_coredump;
+    const char *debug_flags;
+    struct sudo_conf_paths paths[3];
+    struct plugin_info_list plugins;
+} sudo_conf_data = {
+    true,
+    NULL,
+    {
+#define SUDO_CONF_ASKPASS_IDX  0
+       { "askpass", sizeof("askpass"), _PATH_SUDO_ASKPASS },
+#ifdef _PATH_SUDO_NOEXEC
+#define SUDO_CONF_NOEXEC_IDX   1
+       { "noexec", sizeof("noexec"), _PATH_SUDO_NOEXEC },
+#endif
+       { NULL }
+    }
+};
+
+/*
+ * "Set variable_name value"
+ */
+static bool
+set_variable(const char *entry)
+{
+#undef DC_LEN
+#define DC_LEN (sizeof("disable_coredump") - 1)
+    /* Currently the only variable supported is "disable_coredump". */
+    if (strncmp(entry, "disable_coredump", DC_LEN) == 0 &&
+       isblank((unsigned char)entry[DC_LEN])) {
+       entry += DC_LEN + 1;
+       while (isblank((unsigned char)*entry))
+           entry++;
+       sudo_conf_data.disable_coredump = atobool(entry);
+    }
+#undef DC_LEN
+    return true;
+}
+
+/*
+ * "Debug progname debug_file debug_flags"
+ */
+static bool
+set_debug(const char *entry)
+{
+    size_t filelen, proglen;
+    const char *progname;
+    char *debug_file, *debug_flags;
+
+    /* Is this debug setting for me? */
+    progname = getprogname();
+    if (strcmp(progname, "sudoedit") == 0)
+       progname = "sudo";
+    proglen = strlen(progname);
+    if (strncmp(entry, progname, proglen) != 0 ||
+       !isblank((unsigned char)entry[proglen]))
+       return false;
+    entry += proglen + 1;
+    while (isblank((unsigned char)*entry))
+       entry++;
+
+    debug_flags = strpbrk(entry, " \t");
+    if (debug_flags == NULL)
+       return false;
+    filelen = (size_t)(debug_flags - entry);
+    while (isblank((unsigned char)*debug_flags))
+       debug_flags++;
+
+    /* Set debug file and parse the flags (init debug as soon as possible). */
+    debug_file = estrndup(entry, filelen);
+    debug_flags = estrdup(debug_flags);
+    sudo_debug_init(debug_file, debug_flags);
+    efree(debug_file);
+
+    sudo_conf_data.debug_flags = debug_flags;
+
+    return true;
+}
+
+static bool
+set_path(const char *entry)
+{
+    const char *name, *path;
+    struct sudo_conf_paths *cur;
+
+    /* Parse Path line */
+    name = entry;
+    path = strpbrk(entry, " \t");
+    if (path == NULL)
+       return false;
+    while (isblank((unsigned char)*path))
+       path++;
+
+    /* Match supported paths, ignore the rest. */
+    for (cur = sudo_conf_data.paths; cur->pname != NULL; cur++) {
+       if (strncasecmp(name, cur->pname, cur->pnamelen) == 0 &&
+           isblank((unsigned char)name[cur->pnamelen])) {
+           cur->pval = estrdup(path);
+           break;
+       }
+    }
+
+    return true;
+}
+
+static bool
+set_plugin(const char *entry)
+{
+    struct plugin_info *info;
+    const char *name, *path;
+    size_t namelen;
+
+    /* Parse Plugin line */
+    name = entry;
+    path = strpbrk(entry, " \t");
+    if (path == NULL)
+       return false;
+    namelen = (size_t)(path - name);
+    while (isblank((unsigned char)*path))
+       path++;
+
+    info = emalloc(sizeof(*info));
+    info->symbol_name = estrndup(name, namelen);
+    info->path = estrdup(path);
+    info->prev = info;
+    info->next = NULL;
+    tq_append(&sudo_conf_data.plugins, info);
+
+    return true;
+}
+
+const char *
+sudo_conf_askpass_path(void)
+{
+    return sudo_conf_data.paths[SUDO_CONF_ASKPASS_IDX].pval;
+}
+
+#ifdef _PATH_SUDO_NOEXEC
+const char *
+sudo_conf_noexec_path(void)
+{
+    return sudo_conf_data.paths[SUDO_CONF_NOEXEC_IDX].pval;
+}
+#endif
+
+const char *
+sudo_conf_debug_flags(void)
+{
+    return sudo_conf_data.debug_flags;
+}
+
+struct plugin_info_list *
+sudo_conf_plugins(void)
+{
+    return &sudo_conf_data.plugins;
+}
+
+bool
+sudo_conf_disable_coredump(void)
+{
+    return sudo_conf_data.disable_coredump;
+}
+
+/*
+ * Reads in /etc/sudo.conf
+ * Returns a list of plugins.
+ */
+void
+sudo_conf_read(void)
+{
+    struct sudo_conf_table *cur;
+    struct plugin_info *info;
+    FILE *fp;
+    char *cp;
+
+    if ((fp = fopen(_PATH_SUDO_CONF, "r")) == NULL)
+       goto done;
+
+    while ((cp = sudo_parseln(fp)) != NULL) {
+       /* Skip blank or comment lines */
+       if (*cp == '\0')
+           continue;
+
+       for (cur = sudo_conf_table; cur->name != NULL; cur++) {
+           if (strncasecmp(cp, cur->name, cur->namelen) == 0 &&
+               isblank((unsigned char)cp[cur->namelen])) {
+               cp += cur->namelen;
+               while (isblank((unsigned char)*cp))
+                   cp++;
+               if (cur->setter(cp))
+                   break;
+           }
+       }
+    }
+    fclose(fp);
+
+done:
+    if (tq_empty(&sudo_conf_data.plugins)) {
+       /* Default policy plugin */
+       info = emalloc(sizeof(*info));
+       info->symbol_name = "sudoers_policy";
+       info->path = SUDOERS_PLUGIN;
+       info->prev = info;
+       info->next = NULL;
+       tq_append(&sudo_conf_data.plugins, info);
+
+       /* Default I/O plugin */
+       info = emalloc(sizeof(*info));
+       info->symbol_name = "sudoers_io";
+       info->path = SUDOERS_PLUGIN;
+       info->prev = info;
+       info->next = NULL;
+       tq_append(&sudo_conf_data.plugins, info);
+    }
+}
diff --git a/common/sudo_debug.c b/common/sudo_debug.c
new file mode 100644 (file)
index 0000000..de98d0d
--- /dev/null
@@ -0,0 +1,432 @@
+/*
+ * Copyright (c) 2011 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 <sys/stat.h>
+#include <sys/uio.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_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <time.h>
+
+#include "missing.h"
+#include "alloc.h"
+#include "error.h"
+#include "gettext.h"
+#include "sudo_plugin.h"
+#include "sudo_debug.h"
+
+/*
+ * The debug priorities and subsystems are currently hard-coded.
+ * In the future we might consider allowing plugins to register their
+ * own subsystems and provide direct access to the debugging API.
+ */
+
+/* Note: this must match the order in sudo_debug.h */
+const char *const sudo_debug_priorities[] = {
+    "crit",
+    "err",
+    "warn",
+    "notice",
+    "diag",
+    "info",
+    "trace",
+    "debug",
+    NULL
+};
+
+/* Note: this must match the order in sudo_debug.h */
+const char *const sudo_debug_subsystems[] = {
+    "main",
+    "args",
+    "exec",
+    "pty",
+    "utmp",
+    "conv",
+    "pcomm",
+    "util",
+    "netif",
+    "audit",
+    "edit",
+    "selinux",
+    "ldap",
+    "match",
+    "parser",
+    "alias",
+    "defaults",
+    "auth",
+    "env",
+    "logging",
+    "nss",
+    "rbtree",
+    "perms",
+    "plugin",
+    NULL
+};
+
+#define NUM_SUBSYSTEMS (sizeof(sudo_debug_subsystems) / sizeof(sudo_debug_subsystems[0]) - 1)
+
+/* Values for sudo_debug_mode */
+#define SUDO_DEBUG_MODE_DISABLED       0
+#define SUDO_DEBUG_MODE_FILE           1
+#define SUDO_DEBUG_MODE_CONV           2
+
+static int sudo_debug_settings[NUM_SUBSYSTEMS];
+static int sudo_debug_fd = -1;
+static int sudo_debug_mode;
+
+extern sudo_conv_t sudo_conv;
+
+/*
+ * Parse settings string from sudo.conf and open debugfile.
+ * Returns 1 on success, 0 if cannot open debugfile.
+ * Unsupported subsystems and priorities are silently ignored.
+ */
+int sudo_debug_init(const char *debugfile, const char *settings)
+{
+    char *buf, *cp, *subsys, *pri;
+    int i, j;
+
+    /* Init per-subsystems settings to -1 since 0 is a valid priority. */
+    for (i = 0; i < NUM_SUBSYSTEMS; i++)
+       sudo_debug_settings[i] = -1;
+
+    /* Open debug file if specified. */
+    if (debugfile != NULL) {
+       if (sudo_debug_fd != -1)
+           close(sudo_debug_fd);
+       sudo_debug_fd = open(debugfile, O_WRONLY|O_APPEND|O_CREAT,
+           S_IRUSR|S_IWUSR);
+       if (sudo_debug_fd == -1)
+           return 0;
+       (void)fcntl(sudo_debug_fd, F_SETFD, FD_CLOEXEC);
+       sudo_debug_mode = SUDO_DEBUG_MODE_FILE;
+    } else {
+       /* Called from the plugin, no debug file. */
+       sudo_debug_mode = SUDO_DEBUG_MODE_CONV;
+    }
+
+    /* Parse settings string. */
+    buf = estrdup(settings);
+    for ((cp = strtok(buf, ",")); cp != NULL; (cp = strtok(NULL, ","))) {
+       /* Should be in the form subsys@pri. */
+       subsys = cp;
+       if ((pri = strchr(cp, '@')) == NULL)
+           continue;
+       *pri++ = '\0';
+
+       /* Look up priority and subsystem, fill in sudo_debug_settings[]. */
+       for (i = 0; sudo_debug_priorities[i] != NULL; i++) {
+           if (strcasecmp(pri, sudo_debug_priorities[i]) == 0) {
+               for (j = 0; sudo_debug_subsystems[j] != NULL; j++) {
+                   if (strcasecmp(subsys, "all") == 0) {
+                       sudo_debug_settings[j] = i;
+                       continue;
+                   }
+                   if (strcasecmp(subsys, sudo_debug_subsystems[j]) == 0) {
+                       sudo_debug_settings[j] = i;
+                       break;
+                   }
+               }
+               break;
+           }
+       }
+    }
+    efree(buf);
+
+    return 1;
+}
+
+void
+sudo_debug_enter(const char *func, const char *file, int line,
+    int subsys)
+{
+    sudo_debug_printf2(subsys | SUDO_DEBUG_TRACE, "-> %s @ %s:%d", func,
+       file, line);
+}
+
+void sudo_debug_exit(const char *func, const char *file, int line,
+    int subsys)
+{
+    sudo_debug_printf2(subsys | SUDO_DEBUG_TRACE, "<- %s @ %s:%d", func,
+       file, line);
+}
+
+void sudo_debug_exit_int(const char *func, const char *file, int line,
+    int subsys, int rval)
+{
+    sudo_debug_printf2(subsys | SUDO_DEBUG_TRACE, "<- %s @ %s:%d := %d", func,
+       file, line, rval);
+}
+
+void sudo_debug_exit_long(const char *func, const char *file, int line,
+    int subsys, long rval)
+{
+    sudo_debug_printf2(subsys | SUDO_DEBUG_TRACE, "<- %s @ %s:%d := %ld", func,
+       file, line, rval);
+}
+
+void sudo_debug_exit_size_t(const char *func, const char *file, int line,
+    int subsys, size_t rval)
+{
+    /* XXX - should use %zu but our snprintf.c doesn't support it */
+    sudo_debug_printf2(subsys | SUDO_DEBUG_TRACE, "<- %s @ %s:%d := %lu", func,
+       file, line, (unsigned long)rval);
+}
+
+/* We use int, not bool, here for functions that return -1 on error. */
+void sudo_debug_exit_bool(const char *func, const char *file, int line,
+    int subsys, int rval)
+{
+    if (rval == true || rval == false) {
+       sudo_debug_printf2(subsys | SUDO_DEBUG_TRACE, "<- %s @ %s:%d := %s",
+           func, file, line, rval ? "true" : "false");
+    } else {
+       sudo_debug_printf2(subsys | SUDO_DEBUG_TRACE, "<- %s @ %s:%d := %d",
+           func, file, line, rval);
+    }
+}
+
+void sudo_debug_exit_str(const char *func, const char *file, int line,
+    int subsys, const char *rval)
+{
+    sudo_debug_printf2(subsys | SUDO_DEBUG_TRACE, "<- %s @ %s:%d := %s", func,
+       file, line, rval ? rval : "(null)");
+}
+
+void sudo_debug_exit_str_masked(const char *func, const char *file, int line,
+    int subsys, const char *rval)
+{
+    static const char stars[] = "********************************************************************************";
+    int len = rval ? strlen(rval) : sizeof("(null)") - 1;
+
+    sudo_debug_printf2(subsys | SUDO_DEBUG_TRACE, "<- %s @ %s:%d := %.*s", func,
+       file, line, len, rval ? stars : "(null)");
+}
+
+void sudo_debug_exit_ptr(const char *func, const char *file, int line,
+    int subsys, const void *rval)
+{
+    sudo_debug_printf2(subsys | SUDO_DEBUG_TRACE, "<- %s @ %s:%d := %p", func,
+       file, line, rval);
+}
+
+void
+sudo_debug_write(const char *str, int len)
+{
+    char *timestr;
+    time_t now;
+    struct iovec iov[5];
+    int iovcnt = 4;
+
+    if (len <= 0)
+       return;
+
+    switch (sudo_debug_mode) {
+    case SUDO_DEBUG_MODE_CONV:
+       /* Call conversation function */
+       if (sudo_conv != NULL) {
+           struct sudo_conv_message msg;
+           struct sudo_conv_reply repl;
+
+           memset(&msg, 0, sizeof(msg));
+           memset(&repl, 0, sizeof(repl));
+           msg.msg_type = SUDO_CONV_DEBUG_MSG;
+           msg.msg = str;
+           sudo_conv(1, &msg, &repl);
+       }
+       break;
+    case SUDO_DEBUG_MODE_FILE:
+       /* Prepend program name with trailing space. */
+       iov[1].iov_base = (char *)getprogname();
+       iov[1].iov_len = strlen(iov[1].iov_base);
+       iov[2].iov_base = " ";
+       iov[2].iov_len = 1;
+
+       /* Add string along with newline if it doesn't have one. */
+       iov[3].iov_base = (char *)str;
+       iov[3].iov_len = len;
+       if (str[len - 1] != '\n') {
+           /* force newline */
+           iov[4].iov_base = "\n";
+           iov[4].iov_len = 1;
+           iovcnt++;
+       }
+
+       /* Do timestamp last due to ctime's static buffer. */
+       now = time(NULL);
+       timestr = ctime(&now) + 4;
+       timestr[15] = ' ';      /* replace year with a space */
+       timestr[16] = '\0';
+       iov[0].iov_base = timestr;
+       iov[0].iov_len = 16;
+
+       /* Write message in a single syscall */
+       (void) writev(sudo_debug_fd, iov, iovcnt);
+       break;
+    }
+}
+
+void
+sudo_debug_printf2(int level, const char *fmt, ...)
+{
+    int buflen, pri, subsys;
+    va_list ap;
+    char *buf;
+
+    if (!sudo_debug_mode)
+       return;
+
+    /* Extract pri and subsystem from level. */
+    pri = SUDO_DEBUG_PRI(level);
+    subsys = SUDO_DEBUG_SUBSYS(level);
+
+    /* Make sure we want debug info at this level. */
+    if (subsys >= NUM_SUBSYSTEMS || sudo_debug_settings[subsys] < pri)
+       return;
+
+    va_start(ap, fmt);
+    buflen = vasprintf(&buf, fmt, ap);
+    va_end(ap);
+    if (buflen != -1) {
+       sudo_debug_write(buf, buflen);
+       free(buf);
+    }
+}
+
+void
+sudo_debug_execve2(int level, const char *path, char *const argv[], char *const envp[])
+{
+    char * const *av;
+    char *buf, *cp;
+    int buflen, pri, subsys, log_envp = 0;
+    size_t plen;
+
+    if (!sudo_debug_mode)
+       return;
+
+    /* Extract pri and subsystem from level. */
+    pri = SUDO_DEBUG_PRI(level);
+    subsys = SUDO_DEBUG_SUBSYS(level);
+
+    /* Make sure we want debug info at this level. */
+    if (subsys >= NUM_SUBSYSTEMS || sudo_debug_settings[subsys] < pri)
+       return;
+
+    /* Log envp for debug level "debug". */
+    if (sudo_debug_settings[subsys] >= SUDO_DEBUG_DEBUG - 1 && envp[0] != NULL)
+       log_envp = 1;
+
+#define EXEC_PREFIX "exec "
+
+    /* Alloc and build up buffer. */
+    plen = strlen(path);
+    buflen = sizeof(EXEC_PREFIX) -1 + plen;
+    if (argv[0] != NULL) {
+       buflen += sizeof(" []") - 1;
+       for (av = argv; *av; av++)
+           buflen += strlen(*av) + 1;
+       buflen--;
+    }
+    if (log_envp) {
+       buflen += sizeof(" []") - 1;
+       for (av = envp; *av; av++)
+           buflen += strlen(*av) + 1;
+       buflen--;
+    }
+    buf = malloc(buflen + 1);
+    if (buf == NULL)
+       return;
+
+    /* Copy prefix and command. */
+    memcpy(buf, EXEC_PREFIX, sizeof(EXEC_PREFIX) - 1);
+    cp = buf + sizeof(EXEC_PREFIX) - 1;
+    memcpy(cp, path, plen);
+    cp += plen;
+
+    /* Copy argv. */
+    if (argv[0] != NULL) {
+       *cp++ = ' ';
+       *cp++ = '[';
+       for (av = argv; *av; av++) {
+           size_t avlen = strlen(*av);
+           memcpy(cp, *av, avlen);
+           cp += avlen;
+           *cp++ = ' ';
+       }
+       cp[-1] = ']';
+    }
+
+    if (log_envp) {
+       *cp++ = ' ';
+       *cp++ = '[';
+       for (av = envp; *av; av++) {
+           size_t avlen = strlen(*av);
+           memcpy(cp, *av, avlen);
+           cp += avlen;
+           *cp++ = ' ';
+       }
+       cp[-1] = ']';
+    }
+
+    *cp = '\0';
+
+    sudo_debug_write(buf, buflen);
+    free(buf);
+}
+
+/*
+ * Dup sudo_debug_fd to the specified value so we don't
+ * close it when calling closefrom().
+ */
+int
+sudo_debug_fd_set(int fd)
+{
+    if (sudo_debug_fd != -1 && fd != sudo_debug_fd) {
+       if (dup2(sudo_debug_fd, fd) == -1)
+           return -1;
+       (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
+       close(sudo_debug_fd);
+       sudo_debug_fd = fd;
+    }
+    return sudo_debug_fd;
+}
index b8f03db0b6a0c2e0ba5345bd69af83f904c247f7..e9c4a499df1949be87bb2067fe411ab4acc53c50 100644 (file)
@@ -39,6 +39,7 @@
 #include <termios.h>
 
 #include "missing.h"
+#include "sudo_debug.h"
 
 #ifndef TCSASOFT
 # define TCSASOFT      0
@@ -69,21 +70,25 @@ int term_kill;
 int
 term_restore(int fd, int flush)
 {
+    debug_decl(term_restore, SUDO_DEBUG_UTIL)
+
     if (changed) {
        int flags = TCSASOFT;
        flags |= flush ? TCSAFLUSH : TCSADRAIN;
        if (tcsetattr(fd, flags, &oterm) != 0)
-           return 0;
+           debug_return_int(0);
        changed = 0;
     }
-    return 1;
+    debug_return_int(1);
 }
 
 int
 term_noecho(int fd)
 {
+    debug_decl(term_noecho, SUDO_DEBUG_UTIL)
+
     if (!changed && tcgetattr(fd, &oterm) != 0)
-       return 0;
+       debug_return_int(0);
     (void) memcpy(&term, &oterm, sizeof(term));
     CLR(term.c_lflag, ECHO|ECHONL);
 #ifdef VSTATUS
@@ -91,15 +96,16 @@ term_noecho(int fd)
 #endif
     if (tcsetattr(fd, TCSADRAIN|TCSASOFT, &term) == 0) {
        changed = 1;
-       return 1;
+       debug_return_int(1);
     }
-    return 0;
+    debug_return_int(0);
 }
 
 int
 term_raw(int fd, int isig)
 {
     struct termios term;
+    debug_decl(term_raw, SUDO_DEBUG_UTIL)
 
     if (!changed && tcgetattr(fd, &oterm) != 0)
        return 0;
@@ -114,14 +120,16 @@ term_raw(int fd, int isig)
        SET(term.c_lflag, ISIG);
     if (tcsetattr(fd, TCSADRAIN|TCSASOFT, &term) == 0) {
        changed = 1;
-       return 1;
+       debug_return_int(1);
     }
-    return 0;
+    debug_return_int(0);
 }
 
 int
 term_cbreak(int fd)
 {
+    debug_decl(term_cbreak, SUDO_DEBUG_UTIL)
+
     if (!changed && tcgetattr(fd, &oterm) != 0)
        return 0;
     (void) memcpy(&term, &oterm, sizeof(term));
@@ -137,19 +145,20 @@ term_cbreak(int fd)
        term_erase = term.c_cc[VERASE];
        term_kill = term.c_cc[VKILL];
        changed = 1;
-       return 1;
+       debug_return_int(1);
     }
-    return 0;
+    debug_return_int(0);
 }
 
 int
 term_copy(int src, int dst)
 {
     struct termios tt;
+    debug_decl(term_copy, SUDO_DEBUG_UTIL)
 
     if (tcgetattr(src, &tt) != 0)
-       return 0;
+       debug_return_int(0);
     if (tcsetattr(dst, TCSANOW|TCSASOFT, &tt) != 0)
-       return 0;
-    return 1;
+       debug_return_int(0);
+    debug_return_int(1);
 }
index 09a02b26a8c48cd54bede0dcc273d7efc286189a..6b6630e6741a96fe7229771c85f0c7e34dc98bbe 100644 (file)
@@ -25,6 +25,16 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 incdir = $(top_srcdir)/include
 
+# Where to install things...
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
+datarootdir = @datarootdir@
+localstatedir = @localstatedir@
+
 # Compiler & tools to use
 CC = @CC@
 LIBTOOL = @LIBTOOL@
@@ -38,11 +48,14 @@ CFLAGS = @CFLAGS@
 # OS dependent defines
 DEFS = @OSDEFS@
 
+# Set to non-empty for development mode
+DEVEL = @DEVEL@
+
 #### End of system configuration section. ####
 
 SHELL = @SHELL@
 
-TEST_PROGS = fnm_test globtest
+TEST_PROGS = @COMPAT_TEST_PROGS@
 
 LIBOBJDIR = 
 
@@ -76,8 +89,10 @@ fnm_test: fnm_test.o libreplace.la
 globtest: globtest.o libreplace.la
        $(LIBTOOL) --mode=link $(CC) -o $@ globtest.o libreplace.la
 
-@DEV@$(srcdir)/mksiglist.h: $(srcdir)/siglist.in
-@DEV@  awk 'BEGIN {print "/* public domain */\n"} /^    [A-Z]/ {printf("#ifdef SIG%s\n    if (my_sys_siglist[SIG%s] == NULL)\n\tmy_sys_siglist[SIG%s] = \"%s\";\n#endif\n", $$1, $$1, $$1, substr($$0, 13))}' < $(srcdir)/siglist.in > $@
+$(srcdir)/mksiglist.h: $(srcdir)/siglist.in
+       if [ -n "$(DEVEL)" ]; then \
+           awk 'BEGIN {print "/* public domain */\n"} /^    [A-Z]/ {printf("#ifdef SIG%s\n    if (my_sys_siglist[SIG%s] == NULL)\n\tmy_sys_siglist[SIG%s] = \"%s\";\n#endif\n", $$1, $$1, $$1, substr($$0, 13))}' < $(srcdir)/siglist.in > $@; \
+       fi
 
 pre-install:
 
@@ -96,14 +111,20 @@ install-plugin:
 uninstall:
 
 check: $(TEST_PROGS)
-       @./fnm_test $(srcdir)/regress/fnmatch/fnm_test.in
-       @mkdir -p `sed 's@/[^/]*$$@@' $(srcdir)/regress/glob/files | sort -u`
-       @touch `cat $(srcdir)/regress/glob/files`
-       @chmod 0755 `grep '/r[^/]*$$' $(srcdir)/regress/glob/files`
-       @chmod 0444 `grep '/s[^/]*$$' $(srcdir)/regress/glob/files`
-       @chmod 0711 `grep '/t[^/]*$$' $(srcdir)/regress/glob/files`
-       @./globtest $(srcdir)/regress/glob/globtest.in
-       @rm -rf fake
+       @if [ -f fnm_test ]; then \
+           ./fnm_test $(srcdir)/regress/fnmatch/fnm_test.in; \
+       fi
+       @if [ -f globtest ]; then \
+           mkdir -p `sed 's@/[^/]*$$@@' $(srcdir)/regress/glob/files | sort -u`; \
+           touch `cat $(srcdir)/regress/glob/files`; \
+           chmod 0755 `grep '/r[^/]*$$' $(srcdir)/regress/glob/files`; \
+           chmod 0444 `grep '/s[^/]*$$' $(srcdir)/regress/glob/files`; \
+           chmod 0711 `grep '/t[^/]*$$' $(srcdir)/regress/glob/files`; \
+           ./globtest $(srcdir)/regress/glob/globtest.in; \
+           rval=$$?; \
+           rm -rf fake; \
+           exit $$rval; \
+       fi
 
 clean:
        -$(LIBTOOL) --mode=clean rm -f $(TEST_PROGS) mksiglist siglist.c *.lo *.o *.la *.a stamp-* core *.core core.*
index 91ef81476a9d9f891a57189d3866528af369b753..1daaba2d008beceea7c1dc0ca3ae0c5259ae5110 100644 (file)
@@ -1,39 +1,72 @@
-/*
- * Copyright (c) 2008, 2010 Todd C. Miller <Todd.Miller@courtesan.com>
- * Copyright (c) 1989, 1993, 1994
- *     The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Guido van Rossum.
- *
+/*     $OpenBSD: fnmatch.c,v 1.15 2011/02/10 21:31:59 stsp Exp $       */
+
+/* Copyright (c) 2011, VMware, 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 the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of the VMware, 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 REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. 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.
  */
 
-/*
- * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
- * Compares a filename or pathname to a pattern.
+/* Authored by William A. Rowe Jr. <wrowe; apache.org, vmware.com>, April 2011
+ *
+ * Derived from The Open Group Base Specifications Issue 7, IEEE Std 1003.1-2008
+ * as described in;
+ *   http://pubs.opengroup.org/onlinepubs/9699919799/functions/fnmatch.html
+ *
+ * Filename pattern matches defined in section 2.13, "Pattern Matching Notation"
+ * from chapter 2. "Shell Command Language"
+ *   http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13
+ * where; 1. A bracket expression starting with an unquoted <circumflex> '^' 
+ * character CONTINUES to specify a non-matching list; 2. an explicit <period> '.' 
+ * in a bracket expression matching list, e.g. "[.abc]" does NOT match a leading 
+ * <period> in a filename; 3. a <left-square-bracket> '[' which does not introduce
+ * a valid bracket expression is treated as an ordinary character; 4. a differing
+ * number of consecutive slashes within pattern and string will NOT match;
+ * 5. a trailing '\' in FNM_ESCAPE mode is treated as an ordinary '\' character.
+ *
+ * Bracket expansion defined in section 9.3.5, "RE Bracket Expression",
+ * from chapter 9, "Regular Expressions"
+ *   http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_05
+ * with no support for collating symbols, equivalence class expressions or 
+ * character class expressions.  A partial range expression with a leading 
+ * hyphen following a valid range expression will match only the ordinary
+ * <hyphen> and the ending character (e.g. "[a-m-z]" will match characters 
+ * 'a' through 'm', a <hyphen> '-', or a 'z').
+ *
+ * Supports BSD extensions FNM_LEADING_DIR to match pattern to the end of one
+ * path segment of string, and FNM_CASEFOLD to ignore alpha case.
+ *
+ * NOTE: Only POSIX/C single byte locales are correctly supported at this time.
+ * Notably, non-POSIX locales with FNM_CASEFOLD produce undefined results,
+ * particularly in ranges of mixed case (e.g. "[A-z]") or spanning alpha and
+ * nonalpha characters within a range.
+ *
+ * XXX comments below indicate porting required for multi-byte character sets
+ * and non-POSIX locale collation orders; requires mbr* APIs to track shift
+ * state of pattern and string (rewinding pattern and string repeatedly).
+ *
+ * Certain parts of the code assume 0x00-0x3F are unique with any MBCS (e.g.
+ * UTF-8, SHIFT-JIS, etc).  Any implementation allowing '\' as an alternate
+ * path delimiter must be aware that 0x5C is NOT unique within SHIFT-JIS.
  */
 
 #include <config.h>
 #ifdef HAVE_STRINGS_H
 # include <strings.h>
 #endif /* HAVE_STRINGS_H */
+#include <limits.h>
 
 #include "missing.h"
 #include "compat/charclass.h"
 #include "compat/fnmatch.h"
 
-#undef EOS
-#define        EOS     '\0'
-
 #define        RANGE_MATCH     1
 #define        RANGE_NOMATCH   0
 #define        RANGE_ERROR     (-1)
 
-#if defined(LIBC_SCCS) && !defined(lint)
-__unused static const char rcsid[] = "$OpenBSD: fnmatch.c,v 1.6 1998/03/19 00:29:59 millert Exp $";
-#endif /* LIBC_SCCS and not lint */
-
-static int rangematch(const char *, int, int, char **);
-static int classmatch(const char *, int, int, const char **);
-
-int
-rpl_fnmatch(const char *pattern, const char *string, int flags)
-{
-       const char *stringstart;
-       char *newp;
-       char c, test;
-
-       for (stringstart = string;;)
-               switch (c = *pattern++) {
-               case EOS:
-                       if (ISSET(flags, FNM_LEADING_DIR) && *string == '/')
-                               return 0;
-                       return *string == EOS ? 0 : FNM_NOMATCH;
-               case '?':
-                       if (*string == EOS)
-                               return FNM_NOMATCH;
-                       if (*string == '/' && ISSET(flags, FNM_PATHNAME))
-                               return FNM_NOMATCH;
-                       if (*string == '.' && ISSET(flags, FNM_PERIOD) &&
-                           (string == stringstart ||
-                           (ISSET(flags, FNM_PATHNAME) && *(string - 1) == '/')))
-                               return FNM_NOMATCH;
-                       ++string;
-                       break;
-               case '*':
-                       c = *pattern;
-                       /* Collapse multiple stars. */
-                       while (c == '*')
-                               c = *++pattern;
-
-                       if (*string == '.' && ISSET(flags, FNM_PERIOD) &&
-                           (string == stringstart ||
-                           (ISSET(flags, FNM_PATHNAME) && *(string - 1) == '/')))
-                               return FNM_NOMATCH;
-
-                       /* Optimize for pattern with * at end or before /. */
-                       if (c == EOS) {
-                               if (ISSET(flags, FNM_PATHNAME))
-                                       return (ISSET(flags, FNM_LEADING_DIR) ||
-                                           strchr(string, '/') == NULL ?
-                                           0 : FNM_NOMATCH);
-                               else
-                                       return 0;
-                       } else if (c == '/' && ISSET(flags, FNM_PATHNAME)) {
-                               if ((string = strchr(string, '/')) == NULL)
-                                       return FNM_NOMATCH;
-                               break;
-                       }
-
-                       /* General case, use recursion. */
-                       while ((test = *string) != EOS) {
-                               if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
-                                       return 0;
-                               if (test == '/' && ISSET(flags, FNM_PATHNAME))
-                                       break;
-                               ++string;
-                       }
-                       return FNM_NOMATCH;
-               case '[':
-                       if (*string == EOS)
-                               return FNM_NOMATCH;
-                       if (*string == '/' && ISSET(flags, FNM_PATHNAME))
-                               return FNM_NOMATCH;
-                       if (*string == '.' && ISSET(flags, FNM_PERIOD) &&
-                           (string == stringstart ||
-                           (ISSET(flags, FNM_PATHNAME) && *(string - 1) == '/')))
-                               return FNM_NOMATCH;
-
-                       switch (rangematch(pattern, *string, flags, &newp)) {
-                       case RANGE_ERROR:
-                               /* not a good range, treat as normal text */
-                               goto normal;
-                       case RANGE_MATCH:
-                               pattern = newp;
-                               break;
-                       case RANGE_NOMATCH:
-                               return FNM_NOMATCH;
-                       }
-                       ++string;
-                       break;
-               case '\\':
-                       if (!ISSET(flags, FNM_NOESCAPE)) {
-                               if ((c = *pattern++) == EOS) {
-                                       c = '\\';
-                                       --pattern;
-                               }
-                       }
-                       /* FALLTHROUGH */
-               default:
-               normal:
-                       if (c != *string && !(ISSET(flags, FNM_CASEFOLD) &&
-                                (tolower((unsigned char)c) ==
-                                tolower((unsigned char)*string))))
-                               return FNM_NOMATCH;
-                       ++string;
-                       break;
-               }
-       /* NOTREACHED */
-}
-
 static int
-rangematch(const char *pattern, int test, int flags, char **newp)
+classmatch(const char *pattern, char test, int foldcase, const char **ep)
 {
-       int negate, ok, rv;
-       char c, c2;
-
-       /*
-        * A bracket expression starting with an unquoted circumflex
-        * character produces unspecified results (IEEE 1003.2-1992,
-        * 3.13.2).  This implementation treats it like '!', for
-        * consistency with the regular expression syntax.
-        * J.T. Conklin (conklin@ngai.kaleida.com)
-        */
-       if ((negate = (*pattern == '!' || *pattern == '^')))
-               ++pattern;
-
-       if (ISSET(flags, FNM_CASEFOLD))
-               test = tolower(test);
-
-       /*
-        * A right bracket shall lose its special meaning and represent
-        * itself in a bracket expression if it occurs first in the list.
-        * -- POSIX.2 2.8.3.2
-        */
-       ok = 0;
-       c = *pattern++;
-       do {
-               if (c == '[' && *pattern == ':') {
-                       do {
-                               rv = classmatch(pattern + 1, test,
-                                   (flags & FNM_CASEFOLD), &pattern);
-                               if (rv == RANGE_MATCH)
-                                       ok = 1;
-                               c = *pattern++;
-                       } while (rv != RANGE_ERROR && c == '[' && *pattern == ':');
-                       if (c == ']')
-                       break;
-               }
-               if (c == '\\' && !ISSET(flags, FNM_NOESCAPE))
-                       c = *pattern++;
-               if (c == EOS)
-                       return RANGE_ERROR;
-               if (c == '/' && ISSET(flags, FNM_PATHNAME))
-                       return RANGE_NOMATCH;
-               if (ISSET(flags, FNM_CASEFOLD))
-                       c = tolower((unsigned char)c);
-               if (*pattern == '-'
-                   && (c2 = *(pattern+1)) != EOS && c2 != ']') {
-                       pattern += 2;
-                       if (c2 == '\\' && !ISSET(flags, FNM_NOESCAPE))
-                               c2 = *pattern++;
-                       if (c2 == EOS)
-                               return RANGE_ERROR;
-                       if (ISSET(flags, FNM_CASEFOLD))
-                               c2 = tolower((unsigned char)c2);
-                       if (c <= test && test <= c2)
-                               ok = 1;
-               } else if (c == test)
-                       ok = 1;
-       } while ((c = *pattern++) != ']');
-
-       *newp = (char *)pattern;
-       return ok == negate ? RANGE_NOMATCH : RANGE_MATCH;
-}
-
-static int
-classmatch(const char *pattern, int test, int foldcase, const char **ep)
-{
-       struct cclass *cc;
+       const char * const mismatch = pattern;
        const char *colon;
-       size_t len;
+       struct cclass *cc;
        int rval = RANGE_NOMATCH;
+       size_t len;
+
+       if (pattern[0] != '[' || pattern[1] != ':') {
+               *ep = mismatch;
+               return RANGE_ERROR;
+       }
+       pattern += 2;
 
        if ((colon = strchr(pattern, ':')) == NULL || colon[1] != ']') {
-               *ep = pattern - 2;
+               *ep = mismatch;
                return RANGE_ERROR;
        }
        *ep = colon + 2;
@@ -251,15 +117,356 @@ classmatch(const char *pattern, int test, int foldcase, const char **ep)
                pattern = "lower:]";
        for (cc = cclasses; cc->name != NULL; cc++) {
                if (!strncmp(pattern, cc->name, len) && cc->name[len] == '\0') {
-                       if (cc->isctype(test))
+                       if (cc->isctype((unsigned char)test))
                                rval = RANGE_MATCH;
                        break;
                }
        }
        if (cc->name == NULL) {
-               /* invalid character class, return EOS */
-               *ep = colon + strlen(colon);
+               /* invalid character class, treat as normal text */
+               *ep = mismatch;
                rval = RANGE_ERROR;
        }
        return rval;
 }
+
+/* Most MBCS/collation/case issues handled here.  Wildcard '*' is not handled.
+ * EOS '\0' and the FNM_PATHNAME '/' delimiters are not advanced over, 
+ * however the "\/" sequence is advanced to '/'.
+ *
+ * Both pattern and string are **char to support pointer increment of arbitrary
+ * multibyte characters for the given locale, in a later iteration of this code
+ */
+static int fnmatch_ch(const char **pattern, const char **string, int flags)
+{
+    const char * const mismatch = *pattern;
+    const int nocase = !!(flags & FNM_CASEFOLD);
+    const int escape = !(flags & FNM_NOESCAPE);
+    const int slash = !!(flags & FNM_PATHNAME);
+    int result = FNM_NOMATCH;
+    const char *startch;
+    int negate;
+
+    if (**pattern == '[')
+    {
+        ++*pattern;
+
+        /* Handle negation, either leading ! or ^ operators (never both) */
+        negate = ((**pattern == '!') || (**pattern == '^'));
+        if (negate)
+            ++*pattern;
+
+        /* ']' is an ordinary character at the start of the range pattern */
+        if (**pattern == ']')
+            goto leadingclosebrace;
+
+        while (**pattern)
+        {
+            if (**pattern == ']') {
+                ++*pattern;
+                /* XXX: Fix for MBCS character width */
+                ++*string;
+                return (result ^ negate);
+            }
+
+            if (escape && (**pattern == '\\')) {
+                ++*pattern;
+
+                /* Patterns must be terminated with ']', not EOS */
+                if (!**pattern)
+                    break;
+            }
+
+            /* Patterns must be terminated with ']' not '/' */
+            if (slash && (**pattern == '/'))
+                break;
+
+            /* Match character classes. */
+            if (classmatch(*pattern, **string, nocase, pattern)
+                == RANGE_MATCH) {
+                result = 0;
+                continue;
+            }
+
+leadingclosebrace:
+            /* Look at only well-formed range patterns; 
+             * "x-]" is not allowed unless escaped ("x-\]")
+             * XXX: Fix for locale/MBCS character width
+             */
+            if (((*pattern)[1] == '-') && ((*pattern)[2] != ']'))
+            {
+                startch = *pattern;
+                *pattern += (escape && ((*pattern)[2] == '\\')) ? 3 : 2;
+
+                /* NOT a properly balanced [expr] pattern, EOS terminated 
+                 * or ranges containing a slash in FNM_PATHNAME mode pattern
+                 * fall out to to the rewind and test '[' literal code path
+                 */
+                if (!**pattern || (slash && (**pattern == '/')))
+                    break;
+
+                /* XXX: handle locale/MBCS comparison, advance by MBCS char width */
+                if ((**string >= *startch) && (**string <= **pattern))
+                    result = 0;
+                else if (nocase && (isupper(**string) || isupper(*startch)
+                                                      || isupper(**pattern))
+                            && (tolower(**string) >= tolower(*startch)) 
+                            && (tolower(**string) <= tolower(**pattern)))
+                    result = 0;
+
+                ++*pattern;
+                continue;
+            }
+
+            /* XXX: handle locale/MBCS comparison, advance by MBCS char width */
+            if ((**string == **pattern))
+                result = 0;
+            else if (nocase && (isupper(**string) || isupper(**pattern))
+                            && (tolower(**string) == tolower(**pattern)))
+                result = 0;
+
+            ++*pattern;
+        }
+
+        /* NOT a properly balanced [expr] pattern; Rewind
+         * and reset result to test '[' literal
+         */
+        *pattern = mismatch;
+        result = FNM_NOMATCH;
+    }
+    else if (**pattern == '?') {
+        /* Optimize '?' match before unescaping **pattern */
+        if (!**string || (slash && (**string == '/')))
+            return FNM_NOMATCH;
+        result = 0;
+        goto fnmatch_ch_success;
+    }
+    else if (escape && (**pattern == '\\') && (*pattern)[1]) {
+        ++*pattern;
+    }
+
+    /* XXX: handle locale/MBCS comparison, advance by the MBCS char width */
+    if (**string == **pattern)
+        result = 0;
+    else if (nocase && (isupper(**string) || isupper(**pattern))
+                    && (tolower(**string) == tolower(**pattern)))
+        result = 0;
+
+    /* Refuse to advance over trailing slash or nulls
+     */
+    if (!**string || !**pattern || (slash && ((**string == '/') || (**pattern == '/'))))
+        return result;
+
+fnmatch_ch_success:
+    ++*pattern;
+    ++*string;
+    return result;
+}
+
+int rpl_fnmatch(const char *pattern, const char *string, int flags)
+{
+    static const char dummystring[2] = {' ', 0};
+    const int escape = !(flags & FNM_NOESCAPE);
+    const int slash = !!(flags & FNM_PATHNAME);
+    const int leading_dir = !!(flags & FNM_LEADING_DIR);
+    const char *strendseg;
+    const char *dummyptr;
+    const char *matchptr;
+    int wild;
+    /* For '*' wild processing only; surpress 'used before initialization'
+     * warnings with dummy initialization values;
+     */
+    const char *strstartseg = NULL;
+    const char *mismatch = NULL;
+    int matchlen = 0;
+
+    if (strlen(pattern) > PATH_MAX || strlen(string) > PATH_MAX)
+       return FNM_NOMATCH;
+
+    if (*pattern == '*')
+        goto firstsegment;
+
+    while (*pattern && *string)
+    {
+        /* Pre-decode "\/" which has no special significance, and
+         * match balanced slashes, starting a new segment pattern
+         */
+        if (slash && escape && (*pattern == '\\') && (pattern[1] == '/'))
+            ++pattern;
+        if (slash && (*pattern == '/') && (*string == '/')) {
+            ++pattern;
+            ++string;
+        }            
+
+firstsegment:
+        /* At the beginning of each segment, validate leading period behavior.
+         */
+        if ((flags & FNM_PERIOD) && (*string == '.'))
+        {
+            if (*pattern == '.')
+                ++pattern;
+            else if (escape && (*pattern == '\\') && (pattern[1] == '.'))
+                pattern += 2;
+            else
+                return FNM_NOMATCH;
+            ++string;
+        }
+
+        /* Determine the end of string segment
+         *
+         * Presumes '/' character is unique, not composite in any MBCS encoding
+         */
+        if (slash) {
+            strendseg = strchr(string, '/');
+            if (!strendseg)
+                strendseg = strchr(string, '\0');
+        }
+        else {
+            strendseg = strchr(string, '\0');
+        }
+
+        /* Allow pattern '*' to be consumed even with no remaining string to match
+         */
+        while (*pattern)
+        {
+            if ((string > strendseg)
+                || ((string == strendseg) && (*pattern != '*')))
+                break;
+
+            if (slash && ((*pattern == '/')
+                           || (escape && (*pattern == '\\')
+                                      && (pattern[1] == '/'))))
+                break;
+
+            /* Reduce groups of '*' and '?' to n '?' matches
+             * followed by one '*' test for simplicity
+             */
+            for (wild = 0; ((*pattern == '*') || (*pattern == '?')); ++pattern)
+            {
+                if (*pattern == '*') {
+                    wild = 1;
+                }
+                else if (string < strendseg) {  /* && (*pattern == '?') */
+                    /* XXX: Advance 1 char for MBCS locale */
+                    ++string;
+                }
+                else {  /* (string >= strendseg) && (*pattern == '?') */
+                    return FNM_NOMATCH;
+                }
+            }
+
+            if (wild)
+            {
+                strstartseg = string;
+                mismatch = pattern;
+
+                /* Count fixed (non '*') char matches remaining in pattern
+                 * excluding '/' (or "\/") and '*'
+                 */
+                for (matchptr = pattern, matchlen = 0; 1; ++matchlen)
+                {
+                    if ((*matchptr == '\0') 
+                        || (slash && ((*matchptr == '/')
+                                      || (escape && (*matchptr == '\\')
+                                                 && (matchptr[1] == '/')))))
+                    {
+                        /* Compare precisely this many trailing string chars,
+                         * the resulting match needs no wildcard loop
+                         */
+                        /* XXX: Adjust for MBCS */
+                        if (string + matchlen > strendseg)
+                            return FNM_NOMATCH;
+
+                        string = strendseg - matchlen;
+                        wild = 0;
+                        break;
+                    }
+
+                    if (*matchptr == '*')
+                    {
+                        /* Ensure at least this many trailing string chars remain
+                         * for the first comparison
+                         */
+                        /* XXX: Adjust for MBCS */
+                        if (string + matchlen > strendseg)
+                            return FNM_NOMATCH;
+
+                        /* Begin first wild comparison at the current position */
+                        break;
+                    }
+
+                    /* Skip forward in pattern by a single character match
+                     * Use a dummy fnmatch_ch() test to count one "[range]" escape
+                     */ 
+                    /* XXX: Adjust for MBCS */
+                    if (escape && (*matchptr == '\\') && matchptr[1]) {
+                        matchptr += 2;
+                    }
+                    else if (*matchptr == '[') {
+                        dummyptr = dummystring;
+                        fnmatch_ch(&matchptr, &dummyptr, flags);
+                    }
+                    else {
+                        ++matchptr;
+                    }
+                }
+            }
+
+            /* Incrementally match string against the pattern
+             */
+            while (*pattern && (string < strendseg))
+            {
+                /* Success; begin a new wild pattern search
+                 */
+                if (*pattern == '*')
+                    break;
+
+                if (slash && ((*string == '/')
+                              || (*pattern == '/')
+                              || (escape && (*pattern == '\\')
+                                         && (pattern[1] == '/'))))
+                    break;
+
+                /* Compare ch's (the pattern is advanced over "\/" to the '/',
+                 * but slashes will mismatch, and are not consumed)
+                 */
+                if (!fnmatch_ch(&pattern, &string, flags))
+                    continue;
+
+                /* Failed to match, loop against next char offset of string segment 
+                 * until not enough string chars remain to match the fixed pattern
+                 */
+                if (wild) {
+                    /* XXX: Advance 1 char for MBCS locale */
+                    string = ++strstartseg;
+                    if (string + matchlen > strendseg)
+                        return FNM_NOMATCH;
+
+                    pattern = mismatch;
+                    continue;
+                }
+                else
+                    return FNM_NOMATCH;
+            }
+        }
+
+        if (*string && !((slash || leading_dir) && (*string == '/')))
+            return FNM_NOMATCH;
+
+        if (*pattern && !(slash && ((*pattern == '/')
+                                    || (escape && (*pattern == '\\')
+                                               && (pattern[1] == '/')))))
+            return FNM_NOMATCH;
+
+        if (leading_dir && !*pattern && *string == '/')
+            return 0;
+    }
+
+    /* Where both pattern and string are at EOS, declare success
+     */
+    if (!*string && !*pattern)
+        return 0;
+
+    /* pattern didn't match to the end of string */
+    return FNM_NOMATCH;
+}
index b7504ce460ab2a4b16f3ad65edfddca551571962..8cdaeed976a1dbd7226f477786c01d8ffaa86865 100644 (file)
@@ -1,48 +1,32 @@
-/*-
- * Copyright (c) 1992, 1993
- *     The Regents of the University of California.  All rights reserved.
+/*
+ * Copyright (c) 2011 Todd C. Miller <Todd.Miller@courtesan.com>
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
+ * 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.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *     @(#)fnmatch.h   8.1 (Berkeley) 6/2/93
- *     $OpenBSD: fnmatch.h,v 1.4 1997/09/22 05:25:32 millert Exp $
+ * 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        _FNMATCH_H_
-#define        _FNMATCH_H_
+#ifndef _FNMATCH_H
+#define _FNMATCH_H
 
-#define        FNM_NOMATCH     1       /* Match failed. */
+#define        FNM_NOMATCH     1               /* String does not match pattern */
 
-#define        FNM_NOESCAPE    0x01    /* Disable backslash escaping. */
-#define        FNM_PATHNAME    0x02    /* Slash must be matched by slash. */
-#define        FNM_PERIOD      0x04    /* Period must be matched by period. */
-#define        FNM_LEADING_DIR 0x08    /* Ignore /<tail> after Imatch. */
-#define        FNM_CASEFOLD    0x10    /* Case insensitive search. */
+#define        FNM_PATHNAME    (1 << 0)        /* Globbing chars don't match '/' */
+#define        FNM_PERIOD      (1 << 1)        /* Leading '.' in string must exactly */
+#define        FNM_NOESCAPE    (1 << 2)        /* Backslash treated as ordinary char */
+#define        FNM_LEADING_DIR (1 << 3)        /* Only match the leading directory */
+#define        FNM_CASEFOLD    (1 << 4)        /* Case insensitive matching */
 
-int     rpl_fnmatch(const char *, const char *, int);
+int rpl_fnmatch(const char *pattern, const char *string, int flags);
 
 #define fnmatch(_a, _b, _c)    rpl_fnmatch((_a), (_b), (_c))
 
-#endif /* !_FNMATCH_H_ */
+#endif /* _FNMATCH_H */
diff --git a/compat/getaddrinfo.c b/compat/getaddrinfo.c
new file mode 100644 (file)
index 0000000..9927587
--- /dev/null
@@ -0,0 +1,438 @@
+/*
+ * Replacement for a missing getaddrinfo.
+ *
+ * This is an implementation of getaddrinfo for systems that don't have one so
+ * that networking code can use a consistant interface without #ifdef.  It is
+ * a fairly minimal implementation, with the following limitations:
+ *
+ *   - IPv4 support only.  IPv6 is not supported.
+ *   - AI_ADDRCONFIG is ignored.
+ *   - Not thread-safe due to gethostbyname and getservbyname.
+ *   - SOCK_DGRAM and SOCK_STREAM only.
+ *   - Multiple possible socket types only generate one addrinfo struct.
+ *   - Protocol hints aren't used correctly.
+ *
+ * The last four issues could probably be easily remedied, but haven't been
+ * needed to date.  Adding IPv6 support isn't worth it; systems with IPv6
+ * support should already support getaddrinfo natively.
+ *
+ * The canonical version of this file is maintained in the rra-c-util package,
+ * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ *
+ * The authors hereby relinquish any claim to any copyright that they may have
+ * in this work, whether granted under contract or by operation of law or
+ * international treaty, and hereby commit to the public, at large, that they
+ * shall not, at any time in the future, seek to enforce any copyright in this
+ * work against any person or entity, or prevent any person or entity from
+ * copying, publishing, distributing or creating derivative works of this
+ * work.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <netdb.h>
+#include <errno.h>
+
+#include <netinet/in.h>
+
+#include "compat/getaddrinfo.h"
+#include "missing.h"
+
+/* We need access to h_errno to map errors from gethostbyname. */
+#if !HAVE_DECL_H_ERRNO
+extern int h_errno;
+#endif
+
+/*
+ * The netdb constants, which aren't always defined (particularly if h_errno
+ * isn't declared).  We also make sure that a few of the less-used ones are
+ * defined so that we can deal with them in case statements.
+ */
+#ifndef HOST_NOT_FOUND
+# define HOST_NOT_FOUND 1
+# define TRY_AGAIN      2
+# define NO_RECOVERY    3
+# define NO_DATA        4
+#endif
+#ifndef NETDB_INTERNAL
+# define NETDB_INTERNAL -1
+#endif
+
+/*
+ * If we're running the test suite, rename the functions to avoid conflicts
+ * with the system version.  Note that we don't rename the structures and
+ * constants, but that should be okay (except possibly for gai_strerror).
+ */
+#if TESTING
+# define gai_strerror test_gai_strerror
+# define freeaddrinfo test_freeaddrinfo
+# define getaddrinfo  test_getaddrinfo
+const char *test_gai_strerror(int);
+void test_freeaddrinfo(struct addrinfo *);
+int test_getaddrinfo(const char *, const char *, const struct addrinfo *,
+                     struct addrinfo **);
+#endif
+
+/*
+ * If the native platform doesn't support AI_NUMERICSERV or AI_NUMERICHOST,
+ * pick some other values for them.
+ */
+#if TESTING
+# if AI_NUMERICSERV == 0
+#  undef AI_NUMERICSERV
+#  define AI_NUMERICSERV 0x0080
+# endif
+# if AI_NUMERICHOST == 0
+#  undef AI_NUMERICHOST
+#  define AI_NUMERICHOST 0x0100
+# endif
+#endif
+
+/*
+ * Value representing all of the hint flags set.  Linux uses flags up to
+ * 0x0400, so be sure not to break when testing on that platform.
+ */
+#if TESTING
+# ifdef HAVE_GETADDRINFO
+#  define AI_INTERNAL_ALL 0x04ff
+# else
+#  define AI_INTERNAL_ALL 0x01ff
+# endif
+#else
+# define AI_INTERNAL_ALL 0x007f
+#endif
+
+/* Table of strings corresponding to the EAI_* error codes. */
+static const char * const gai_errors[] = {
+    "Host name lookup failure",         /*  1 EAI_AGAIN */
+    "Invalid flag value",               /*  2 EAI_BADFLAGS */
+    "Unknown server error",             /*  3 EAI_FAIL */
+    "Unsupported address family",       /*  4 EAI_FAMILY */
+    "Memory allocation failure",        /*  5 EAI_MEMORY */
+    "Host unknown or not given",        /*  6 EAI_NONAME */
+    "Service not supported for socket", /*  7 EAI_SERVICE */
+    "Unsupported socket type",          /*  8 EAI_SOCKTYPE */
+    "System error",                     /*  9 EAI_SYSTEM */
+    "Supplied buffer too small",        /* 10 EAI_OVERFLOW */
+};
+
+/* Macro to set the len attribute of sockaddr_in. */
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+# define sin_set_length(s) ((s)->sin_len = sizeof(struct sockaddr_in))
+#else
+# define sin_set_length(s) /* empty */
+#endif
+
+/*
+ * Used for iterating through arrays.  ARRAY_SIZE returns the number of
+ * elements in the array (useful for a < upper bound in a for loop).
+ */
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+
+
+/*
+ * Return a constant string for a given EAI_* error code or a string
+ * indicating an unknown error.
+ */
+const char *
+gai_strerror(int ecode)
+{
+    if (ecode < 1 || (size_t) ecode > ARRAY_SIZE(gai_errors))
+        return "Unknown error";
+    else
+        return gai_errors[ecode - 1];
+}
+
+
+/*
+ * Free a linked list of addrinfo structs.
+ */
+void
+freeaddrinfo(struct addrinfo *ai)
+{
+    struct addrinfo *next;
+
+    while (ai != NULL) {
+        next = ai->ai_next;
+        if (ai->ai_addr != NULL)
+            free(ai->ai_addr);
+        if (ai->ai_canonname != NULL)
+            free(ai->ai_canonname);
+        free(ai);
+        ai = next;
+    }
+}
+
+
+/*
+ * Convert a numeric service string to a number with error checking, returning
+ * true if the number was parsed correctly and false otherwise.  Stores the
+ * converted number in the second argument.  Equivalent to calling strtol, but
+ * with the base always fixed at 10, with checking of errno, ensuring that all
+ * of the string is consumed, and checking that the resulting number is
+ * positive.
+ */
+static int
+convert_service(const char *string, long *result)
+{
+    char *end;
+
+    if (*string == '\0')
+        return 0;
+    errno = 0;
+    *result = strtol(string, &end, 10);
+    if (errno != 0 || *end != '\0' || *result < 0)
+        return 0;
+    return 1;
+}
+
+
+/*
+ * Allocate a new addrinfo struct, setting some defaults given that this
+ * implementation is IPv4 only.  Also allocates an attached sockaddr_in and
+ * zeroes it, per the requirement for getaddrinfo.  Takes the socktype,
+ * canonical name (which is copied if not NULL), address, and port.  Returns
+ * NULL on a memory allocation failure.
+ */
+static struct addrinfo *
+gai_addrinfo_new(int socktype, const char *canonical, struct in_addr addr,
+                 unsigned short port)
+{
+    struct addrinfo *ai;
+
+    ai = malloc(sizeof(*ai));
+    if (ai == NULL)
+        return NULL;
+    ai->ai_addr = malloc(sizeof(struct sockaddr_in));
+    if (ai->ai_addr == NULL) {
+        free(ai);
+        return NULL;
+    }
+    ai->ai_next = NULL;
+    if (canonical == NULL)
+        ai->ai_canonname = NULL;
+    else {
+        ai->ai_canonname = strdup(canonical);
+        if (ai->ai_canonname == NULL) {
+            freeaddrinfo(ai);
+            return NULL;
+        }
+    }
+    memset(ai->ai_addr, 0, sizeof(struct sockaddr_in));
+    ai->ai_flags = 0;
+    ai->ai_family = AF_INET;
+    ai->ai_socktype = socktype;
+    ai->ai_protocol = (socktype == SOCK_DGRAM) ? IPPROTO_UDP : IPPROTO_TCP;
+    ai->ai_addrlen = sizeof(struct sockaddr_in);
+    ((struct sockaddr_in *) ai->ai_addr)->sin_family = AF_INET;
+    ((struct sockaddr_in *) ai->ai_addr)->sin_addr = addr;
+    ((struct sockaddr_in *) ai->ai_addr)->sin_port = htons(port);
+    sin_set_length((struct sockaddr_in *) ai->ai_addr);
+    return ai;
+}
+
+
+/*
+ * Look up a service.  Takes the service name (which may be numeric), the hint
+ * flags, a pointer to the socket type (used to determine whether TCP or UDP
+ * services are of interest and, if 0, is filled in with the result of
+ * getservbyname if the service was not numeric), and a pointer to the
+ * addrinfo struct to fill in.  Returns 0 on success or an EAI_* error on
+ * failure.
+ */
+static int
+gai_service(const char *servname, int flags, int *type, unsigned short *port)
+{
+    struct servent *servent;
+    const char *protocol;
+    long value;
+
+    if (convert_service(servname, &value)) {
+        if (value > (1L << 16) - 1)
+            return EAI_SERVICE;
+        *port = value;
+    } else {
+        if (flags & AI_NUMERICSERV)
+            return EAI_NONAME;
+        if (*type != 0)
+            protocol = (*type == SOCK_DGRAM) ? "udp" : "tcp";
+        else
+            protocol = NULL;
+
+        /*
+         * We really technically should be generating an addrinfo struct for
+         * each possible protocol unless type is set, but this works well
+         * enough for what I need this for.
+         */
+        servent = getservbyname(servname, protocol);
+        if (servent == NULL)
+            return EAI_NONAME;
+        if (strcmp(servent->s_proto, "udp") == 0)
+            *type = SOCK_DGRAM;
+        else if (strcmp(servent->s_proto, "tcp") == 0)
+            *type = SOCK_STREAM;
+        else
+            return EAI_SERVICE;
+        *port = htons(servent->s_port);
+    }
+    return 0;
+}
+
+
+/*
+ * Look up a host and fill in a linked list of addrinfo structs with the
+ * results, one per IP address of the returned host.  Takes the name or IP
+ * address of the host as a string, the lookup flags, the type of socket (to
+ * fill into the addrinfo structs), the port (likewise), and a pointer to
+ * where the head of the linked list should be put.  Returns 0 on success or
+ * the appropriate EAI_* error.
+ */
+static int
+gai_lookup(const char *nodename, int flags, int socktype, unsigned short port,
+           struct addrinfo **res)
+{
+    struct addrinfo *ai, *first, *prev;
+    struct in_addr addr;
+    struct hostent *host;
+    const char *canonical;
+    int i;
+
+    if (inet_aton(nodename, &addr)) {
+        canonical = (flags & AI_CANONNAME) ? nodename : NULL;
+        ai = gai_addrinfo_new(socktype, canonical, addr, port);
+        if (ai == NULL)
+            return EAI_MEMORY;
+        *res = ai;
+        return 0;
+    } else {
+        if (flags & AI_NUMERICHOST)
+            return EAI_NONAME;
+        host = gethostbyname(nodename);
+        if (host == NULL)
+            switch (h_errno) {
+            case HOST_NOT_FOUND:
+                return EAI_NONAME;
+            case TRY_AGAIN:
+            case NO_DATA:
+                return EAI_AGAIN;
+            case NO_RECOVERY:
+                return EAI_FAIL;
+            case NETDB_INTERNAL:
+            default:
+                return EAI_SYSTEM;
+            }
+        if (host->h_addr_list[0] == NULL)
+            return EAI_FAIL;
+        canonical = (flags & AI_CANONNAME)
+            ? ((host->h_name != NULL) ? host->h_name : nodename)
+            : NULL;
+        first = NULL;
+        prev = NULL;
+        for (i = 0; host->h_addr_list[i] != NULL; i++) {
+            if (host->h_length != sizeof(addr)) {
+                freeaddrinfo(first);
+                return EAI_FAIL;
+            }
+            memcpy(&addr, host->h_addr_list[i], sizeof(addr));
+            ai = gai_addrinfo_new(socktype, canonical, addr, port);
+            if (ai == NULL) {
+                freeaddrinfo(first);
+                return EAI_MEMORY;
+            }
+            if (first == NULL) {
+                first = ai;
+                prev = ai;
+            } else {
+                prev->ai_next = ai;
+                prev = ai;
+            }
+        }
+        *res = first;
+        return 0;
+    }
+}
+
+
+/*
+ * The actual getaddrinfo implementation.
+ */
+int
+getaddrinfo(const char *nodename, const char *servname,
+            const struct addrinfo *hints, struct addrinfo **res)
+{
+    struct addrinfo *ai;
+    struct in_addr addr;
+    int flags, socktype, status;
+    unsigned short port;
+
+    /* Take the hints into account and check them for validity. */
+    if (hints != NULL) {
+        flags = hints->ai_flags;
+        socktype = hints->ai_socktype;
+        if ((flags & AI_INTERNAL_ALL) != flags)
+            return EAI_BADFLAGS;
+        if (hints->ai_family != AF_UNSPEC && hints->ai_family != AF_INET)
+            return EAI_FAMILY;
+        if (socktype != 0 && socktype != SOCK_STREAM && socktype != SOCK_DGRAM)
+            return EAI_SOCKTYPE;
+
+        /* EAI_SOCKTYPE isn't quite right, but there isn't anything better. */
+        if (hints->ai_protocol != 0) {
+            int protocol = hints->ai_protocol;
+            if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP)
+                return EAI_SOCKTYPE;
+        }
+    } else {
+        flags = 0;
+        socktype = 0;
+    }
+
+    /*
+     * See what we're doing.  If nodename is null, either AI_PASSIVE is set or
+     * we're getting information for connecting to a service on the loopback
+     * address.  Otherwise, we're getting information for connecting to a
+     * remote system.
+     */
+    if (servname == NULL)
+        port = 0;
+    else {
+        status = gai_service(servname, flags, &socktype, &port);
+        if (status != 0)
+            return status;
+    }
+    if (nodename != NULL)
+        return gai_lookup(nodename, flags, socktype, port, res);
+    else {
+        if (servname == NULL)
+            return EAI_NONAME;
+        if ((flags & AI_PASSIVE) == AI_PASSIVE)
+            addr.s_addr = INADDR_ANY;
+        else
+            addr.s_addr = htonl(0x7f000001UL);
+        ai = gai_addrinfo_new(socktype, NULL, addr, port);
+        if (ai == NULL)
+            return EAI_MEMORY;
+        *res = ai;
+        return 0;
+    }
+}
diff --git a/compat/getaddrinfo.h b/compat/getaddrinfo.h
new file mode 100644 (file)
index 0000000..a8a4b69
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Replacement implementation of getaddrinfo.
+ *
+ * This is an implementation of the getaddrinfo family of functions for
+ * systems that lack it, so that code can use getaddrinfo always.  It provides
+ * IPv4 support only; for IPv6 support, a native getaddrinfo implemenation is
+ * required.
+ *
+ * The canonical version of this file is maintained in the rra-c-util package,
+ * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ *
+ * The authors hereby relinquish any claim to any copyright that they may have
+ * in this work, whether granted under contract or by operation of law or
+ * international treaty, and hereby commit to the public, at large, that they
+ * shall not, at any time in the future, seek to enforce any copyright in this
+ * work against any person or entity, or prevent any person or entity from
+ * copying, publishing, distributing or creating derivative works of this
+ * work.
+ */
+
+#ifndef _COMPAT_GETADDRINFO_H
+#define _COMPAT_GETADDRINFO_H
+
+#include <config.h>
+
+/* Skip this entire file if a system getaddrinfo was detected. */
+#ifndef HAVE_GETADDRINFO
+
+/* OpenBSD likes to have sys/types.h included before sys/socket.h. */
+#include <sys/types.h>
+#include <sys/socket.h>
+
+/* The struct returned by getaddrinfo, from RFC 3493. */
+struct addrinfo {
+    int ai_flags;               /* AI_PASSIVE, AI_CANONNAME, .. */
+    int ai_family;              /* AF_xxx */
+    int ai_socktype;            /* SOCK_xxx */
+    int ai_protocol;            /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+    socklen_t ai_addrlen;       /* Length of ai_addr */
+    char *ai_canonname;         /* Canonical name for nodename */
+    struct sockaddr *ai_addr;   /* Binary address */
+    struct addrinfo *ai_next;   /* Next structure in linked list */
+};
+
+/* Constants for ai_flags from RFC 3493, combined with binary or. */
+#define AI_PASSIVE      0x0001
+#define AI_CANONNAME    0x0002
+#define AI_NUMERICHOST  0x0004
+#define AI_NUMERICSERV  0x0008
+#define AI_V4MAPPED     0x0010
+#define AI_ALL          0x0020
+#define AI_ADDRCONFIG   0x0040
+
+/* Error return codes from RFC 3493. */
+#define EAI_AGAIN       1       /* Temporary name resolution failure */
+#define EAI_BADFLAGS    2       /* Invalid value in ai_flags parameter */
+#define EAI_FAIL        3       /* Permanent name resolution failure */
+#define EAI_FAMILY      4       /* Address family not recognized */
+#define EAI_MEMORY      5       /* Memory allocation failure */
+#define EAI_NONAME      6       /* nodename or servname unknown */
+#define EAI_SERVICE     7       /* Service not recognized for socket type */
+#define EAI_SOCKTYPE    8       /* Socket type not recognized */
+#define EAI_SYSTEM      9       /* System error occurred, see errno */
+#define EAI_OVERFLOW    10      /* An argument buffer overflowed */
+
+/* Function prototypes. */
+int getaddrinfo(const char *nodename, const char *servname,
+                const struct addrinfo *hints, struct addrinfo **res);
+void freeaddrinfo(struct addrinfo *ai);
+const char *gai_strerror(int ecode);
+
+#endif /* !HAVE_GETADDRINFO */
+#endif /* _COMPAT_GETADDRINFO_H */
index 9490d7217256f4b2115852f3778b617ecb5c97cf..23e3b9e16011cebe316c850a0f1632d3559a002d 100644 (file)
@@ -24,7 +24,7 @@
 #if TIME_WITH_SYS_TIME
 # include <time.h>
 #endif
-#ifndef HAVE_TIMESPEC
+#ifndef HAVE_STRUCT_TIMESPEC
 # include "compat/timespec.h"
 #endif
 #include <errno.h>
diff --git a/compat/pw_dup.c b/compat/pw_dup.c
new file mode 100644 (file)
index 0000000..ec56599
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2000, 2002, 2012 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.
+ */
+
+#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 HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
+# include <malloc.h>
+#endif /* HAVE_MALLOC_H && !STDC_HEADERS */
+#include <pwd.h>
+
+#define PW_SIZE(name, size)                            \
+do {                                                   \
+       if (pw->name) {                                 \
+               size = strlen(pw->name) + 1;            \
+               total += size;                          \
+       }                                               \
+} while (0)
+
+#define PW_COPY(name, size)                            \
+do {                                                   \
+       if (pw->name) {                                 \
+               (void)memcpy(cp, pw->name, size);       \
+               newpw->name = cp;                       \
+               cp += size;                             \
+       }                                               \
+} while (0)
+
+struct passwd *
+pw_dup(const struct passwd *pw)
+{
+       char            *cp;
+       size_t           nsize, psize, gsize, dsize, ssize, total;
+#ifdef HAVE_LOGIN_CAP_H
+       size_t           csize;
+#endif
+       struct passwd   *newpw;
+
+       /* Allocate in one big chunk for easy freeing */
+       total = sizeof(struct passwd);
+       PW_SIZE(pw_name, nsize);
+       PW_SIZE(pw_passwd, psize);
+#ifdef HAVE_LOGIN_CAP_H
+       PW_SIZE(pw_class, csize);
+#endif
+       PW_SIZE(pw_gecos, gsize);
+       PW_SIZE(pw_dir, dsize);
+       PW_SIZE(pw_shell, ssize);
+
+       if ((cp = malloc(total)) == NULL)
+               return (NULL);
+       newpw = (struct passwd *)cp;
+
+       /*
+        * Copy in passwd contents and make strings relative to space
+        * at the end of the buffer.
+        */
+       (void)memcpy(newpw, pw, sizeof(struct passwd));
+       cp += sizeof(struct passwd);
+
+       PW_COPY(pw_name, nsize);
+       PW_COPY(pw_passwd, psize);
+#ifdef HAVE_LOGIN_CAP_H
+       PW_COPY(pw_class, csize);
+#endif
+       PW_COPY(pw_gecos, gsize);
+       PW_COPY(pw_dir, dsize);
+       PW_COPY(pw_shell, ssize);
+
+       return newpw;
+}
diff --git a/compat/stdbool.h b/compat/stdbool.h
new file mode 100644 (file)
index 0000000..a6e65ea
--- /dev/null
@@ -0,0 +1,44 @@
+/* $OpenBSD: stdbool.h,v 1.5 2010/07/24 22:17:03 guenther Exp $ */
+
+/*
+ * Written by Marc Espie, September 25, 1999
+ * Public domain.
+ */
+
+#ifndef        _COMPAT_STDBOOL_H_
+#define        _COMPAT_STDBOOL_H_      
+
+#ifndef __cplusplus
+
+#if (defined(HAVE__BOOL) && HAVE__BOOL > 0) || defined(lint)
+/* Support for _C99: type _Bool is already built-in. */
+#define false  0
+#define true   1
+
+#else
+/* `_Bool' type must promote to `int' or `unsigned int'. */
+typedef enum {
+       false = 0,
+       true = 1
+} _Bool;
+
+/* And those constants must also be available as macros. */
+#define        false   false
+#define        true    true
+
+#endif
+
+/* User visible type `bool' is provided as a macro which may be redefined */
+#define bool _Bool
+
+#else /* __cplusplus */
+#define _Bool  bool
+#define bool   bool
+#define false  false
+#define true   true
+#endif /* __cplusplus */
+
+/* Inform that everything is fine */
+#define __bool_true_false_are_defined 1
+
+#endif /* _COMPAT_STDBOOL_H_ */
index 2852378467cace09473584342ae0246a5093a6fc..43f0cdbcfd2f2e72a2f1312cdbaced111bcaf351 100644 (file)
@@ -1,10 +1,10 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-#   Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011 Free Software Foundation, Inc.
 
-timestamp='2010-08-21'
+timestamp='2011-10-01'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -57,7 +57,7 @@ GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
 Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
@@ -92,7 +92,7 @@ if test $# != 0; then
   exit 1
 fi
 
-trap 'exit 1' HUP INT TERM
+trap 'exit 1' 1 2 15
 
 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a
 # compiler to aid in system detection is discouraged as it requires
@@ -106,7 +106,7 @@ trap 'exit 1' HUP INT TERM
 
 set_cc_for_build='
 trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" HUP INT PIPE TERM ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
 : ${TMPDIR=/tmp} ;
  { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
  { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
@@ -181,7 +181,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
                fi
                ;;
            *)
-               os=netbsd
+               os=netbsd
                ;;
        esac
        # The OS release
@@ -224,7 +224,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
                UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
                ;;
        *5.*)
-               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
                ;;
        esac
        # According to Compaq, /usr/sbin/psrinfo has been available on
@@ -270,7 +270,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        # A Xn.n version is an unreleased experimental baselevel.
        # 1.2 uses "1.2" for uname -r.
        echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-       exit ;;
+       # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+       exitcode=$?
+       trap '' 0
+       exit $exitcode ;;
     Alpha\ *:Windows_NT*:*)
        # How do we know it's Interix rather than the generic POSIX subsystem?
        # Should we change UNAME_MACHINE based on the output of uname instead
@@ -296,7 +299,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        echo s390-ibm-zvmoe
        exit ;;
     *:OS400:*:*)
-        echo powerpc-ibm-os400
+       echo powerpc-ibm-os400
        exit ;;
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
        echo arm-acorn-riscix${UNAME_RELEASE}
@@ -395,23 +398,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     # MiNT.  But MiNT is downward compatible to TOS, so this should
     # be no problem.
     atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
+       echo m68k-atari-mint${UNAME_RELEASE}
        exit ;;
     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
        echo m68k-atari-mint${UNAME_RELEASE}
-        exit ;;
+       exit ;;
     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
+       echo m68k-atari-mint${UNAME_RELEASE}
        exit ;;
     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-        echo m68k-milan-mint${UNAME_RELEASE}
-        exit ;;
+       echo m68k-milan-mint${UNAME_RELEASE}
+       exit ;;
     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-        echo m68k-hades-mint${UNAME_RELEASE}
-        exit ;;
+       echo m68k-hades-mint${UNAME_RELEASE}
+       exit ;;
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-        echo m68k-unknown-mint${UNAME_RELEASE}
-        exit ;;
+       echo m68k-unknown-mint${UNAME_RELEASE}
+       exit ;;
     m68k:machten:*:*)
        echo m68k-apple-machten${UNAME_RELEASE}
        exit ;;
@@ -481,8 +484,8 @@ EOF
        echo m88k-motorola-sysv3
        exit ;;
     AViiON:dgux:*:*)
-        # DG/UX returns AViiON for all architectures
-        UNAME_PROCESSOR=`/usr/bin/uname -p`
+       # DG/UX returns AViiON for all architectures
+       UNAME_PROCESSOR=`/usr/bin/uname -p`
        if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
        then
            if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@@ -495,7 +498,7 @@ EOF
        else
            echo i586-dg-dgux${UNAME_RELEASE}
        fi
-       exit ;;
+       exit ;;
     M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
        echo m88k-dolphin-sysv3
        exit ;;
@@ -595,52 +598,52 @@ EOF
            9000/[678][0-9][0-9])
                if [ -x /usr/bin/getconf ]; then
                    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
-                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
-                    case "${sc_cpu_version}" in
-                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
-                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
-                      532)                      # CPU_PA_RISC2_0
-                        case "${sc_kernel_bits}" in
-                          32) HP_ARCH="hppa2.0n" ;;
-                          64) HP_ARCH="hppa2.0w" ;;
+                   sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                   case "${sc_cpu_version}" in
+                     523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                     528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                     532)                      # CPU_PA_RISC2_0
+                       case "${sc_kernel_bits}" in
+                         32) HP_ARCH="hppa2.0n" ;;
+                         64) HP_ARCH="hppa2.0w" ;;
                          '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
-                        esac ;;
-                    esac
+                       esac ;;
+                   esac
                fi
                if [ "${HP_ARCH}" = "" ]; then
                    eval $set_cc_for_build
-                   sed 's/^              //' << EOF >$dummy.c
+                   sed 's/^            //' << EOF >$dummy.c
 
-              #define _HPUX_SOURCE
-              #include <stdlib.h>
-              #include <unistd.h>
+               #define _HPUX_SOURCE
+               #include <stdlib.h>
+               #include <unistd.h>
 
-              int main ()
-              {
-              #if defined(_SC_KERNEL_BITS)
-                  long bits = sysconf(_SC_KERNEL_BITS);
-              #endif
-                  long cpu  = sysconf (_SC_CPU_VERSION);
+               int main ()
+               {
+               #if defined(_SC_KERNEL_BITS)
+                   long bits = sysconf(_SC_KERNEL_BITS);
+               #endif
+                   long cpu  = sysconf (_SC_CPU_VERSION);
 
-                  switch (cpu)
-               {
-               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
-               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
-               case CPU_PA_RISC2_0:
-              #if defined(_SC_KERNEL_BITS)
-                   switch (bits)
-                       {
-                       case 64: puts ("hppa2.0w"); break;
-                       case 32: puts ("hppa2.0n"); break;
-                       default: puts ("hppa2.0"); break;
-                       } break;
-              #else  /* !defined(_SC_KERNEL_BITS) */
-                   puts ("hppa2.0"); break;
-              #endif
-               default: puts ("hppa1.0"); break;
-               }
-                  exit (0);
-              }
+                   switch (cpu)
+                       {
+                       case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+                       case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+                       case CPU_PA_RISC2_0:
+               #if defined(_SC_KERNEL_BITS)
+                           switch (bits)
+                               {
+                               case 64: puts ("hppa2.0w"); break;
+                               case 32: puts ("hppa2.0n"); break;
+                               default: puts ("hppa2.0"); break;
+                               } break;
+               #else  /* !defined(_SC_KERNEL_BITS) */
+                           puts ("hppa2.0"); break;
+               #endif
+                       default: puts ("hppa1.0"); break;
+                       }
+                   exit (0);
+               }
 EOF
                    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
                    test -z "$HP_ARCH" && HP_ARCH=hppa
@@ -731,22 +734,22 @@ EOF
        exit ;;
     C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
        echo c1-convex-bsd
-        exit ;;
+       exit ;;
     C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
        if getsysinfo -f scalar_acc
        then echo c32-convex-bsd
        else echo c2-convex-bsd
        fi
-        exit ;;
+       exit ;;
     C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
        echo c34-convex-bsd
-        exit ;;
+       exit ;;
     C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
        echo c38-convex-bsd
-        exit ;;
+       exit ;;
     C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
        echo c4-convex-bsd
-        exit ;;
+       exit ;;
     CRAY*Y-MP:*:*:*)
        echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
        exit ;;
@@ -770,14 +773,14 @@ EOF
        exit ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
        FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
-        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-        exit ;;
+       FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+       FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+       echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+       exit ;;
     5000:UNIX_System_V:4.*:*)
-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
-        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+       FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+       FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+       echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
        exit ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
        echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@@ -789,13 +792,12 @@ EOF
        echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
        exit ;;
     *:FreeBSD:*:*)
-       case ${UNAME_MACHINE} in
-           pc98)
-               echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+       UNAME_PROCESSOR=`/usr/bin/uname -p`
+       case ${UNAME_PROCESSOR} in
            amd64)
                echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
            *)
-               echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+               echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
        esac
        exit ;;
     i*:CYGWIN*:*)
@@ -805,14 +807,14 @@ EOF
        echo ${UNAME_MACHINE}-pc-mingw32
        exit ;;
     i*:windows32*:*)
-       # uname -m includes "-pc" on this system.
-       echo ${UNAME_MACHINE}-mingw32
+       # uname -m includes "-pc" on this system.
+       echo ${UNAME_MACHINE}-mingw32
        exit ;;
     i*:PW*:*)
        echo ${UNAME_MACHINE}-pc-pw32
        exit ;;
     *:Interix*:*)
-       case ${UNAME_MACHINE} in
+       case ${UNAME_MACHINE} in
            x86)
                echo i586-pc-interix${UNAME_RELEASE}
                exit ;;
@@ -867,7 +869,7 @@ EOF
          EV6)   UNAME_MACHINE=alphaev6 ;;
          EV67)  UNAME_MACHINE=alphaev67 ;;
          EV68*) UNAME_MACHINE=alphaev68 ;;
-        esac
+       esac
        objdump --private-headers /bin/sh | grep -q ld.so.1
        if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
        echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
@@ -879,7 +881,13 @@ EOF
        then
            echo ${UNAME_MACHINE}-unknown-linux-gnu
        else
-           echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+           if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+               | grep -q __ARM_PCS_VFP
+           then
+               echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+           else
+               echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+           fi
        fi
        exit ;;
     avr32*:Linux:*:*)
@@ -892,7 +900,10 @@ EOF
        echo crisv32-axis-linux-gnu
        exit ;;
     frv:Linux:*:*)
-       echo frv-unknown-linux-gnu
+       echo frv-unknown-linux-gnu
+       exit ;;
+    hexagon:Linux:*:*)
+       echo hexagon-unknown-linux-gnu
        exit ;;
     i*86:Linux:*:*)
        LIBC=gnu
@@ -960,7 +971,7 @@ EOF
        echo ${UNAME_MACHINE}-ibm-linux
        exit ;;
     sh64*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     sh*:Linux:*:*)
        echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -969,7 +980,7 @@ EOF
        echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     tile*:Linux:*:*)
-       echo ${UNAME_MACHINE}-tilera-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     vax:Linux:*:*)
        echo ${UNAME_MACHINE}-dec-linux-gnu
@@ -978,7 +989,7 @@ EOF
        echo x86_64-unknown-linux-gnu
        exit ;;
     xtensa*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     i*86:DYNIX/ptx:4*:*)
        # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@@ -987,11 +998,11 @@ EOF
        echo i386-sequent-sysv4
        exit ;;
     i*86:UNIX_SV:4.2MP:2.*)
-        # Unixware is an offshoot of SVR4, but it has its own version
-        # number series starting with 2...
-        # I am not positive that other SVR4 systems won't match this,
+       # Unixware is an offshoot of SVR4, but it has its own version
+       # number series starting with 2...
+       # I am not positive that other SVR4 systems won't match this,
        # I just have to hope.  -- rms.
-        # Use sysv4.2uw... so that sysv4* matches it.
+       # Use sysv4.2uw... so that sysv4* matches it.
        echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
        exit ;;
     i*86:OS/2:*:*)
@@ -1023,7 +1034,7 @@ EOF
        fi
        exit ;;
     i*86:*:5:[678]*)
-       # UnixWare 7.x, OpenUNIX and OpenServer 6.
+       # UnixWare 7.x, OpenUNIX and OpenServer 6.
        case `/bin/uname -X | grep "^Machine"` in
            *486*)           UNAME_MACHINE=i486 ;;
            *Pentium)        UNAME_MACHINE=i586 ;;
@@ -1051,13 +1062,13 @@ EOF
        exit ;;
     pc:*:*:*)
        # Left here for compatibility:
-        # uname -m prints for DJGPP always 'pc', but it prints nothing about
-        # the processor, so we play safe by assuming i586.
+       # uname -m prints for DJGPP always 'pc', but it prints nothing about
+       # the processor, so we play safe by assuming i586.
        # Note: whatever this is, it MUST be the same as what config.sub
        # prints for the "djgpp" host, or else GDB configury will decide that
        # this is a cross-build.
        echo i586-pc-msdosdjgpp
-        exit ;;
+       exit ;;
     Intel:Mach:3*:*)
        echo i386-pc-mach3
        exit ;;
@@ -1092,8 +1103,8 @@ EOF
        /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
          && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
-        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-          && { echo i486-ncr-sysv4; exit; } ;;
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && { echo i486-ncr-sysv4; exit; } ;;
     NCR*:*:4.2:* | MPRAS*:*:4.2:*)
        OS_REL='.3'
        test -r /etc/.relid \
@@ -1136,10 +1147,10 @@ EOF
                echo ns32k-sni-sysv
        fi
        exit ;;
-    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
-                      # says <Richard.M.Bartel@ccMail.Census.GOV>
-        echo i586-unisys-sysv4
-        exit ;;
+    PENTIUM:*:4.0*:*)  # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                       # says <Richard.M.Bartel@ccMail.Census.GOV>
+       echo i586-unisys-sysv4
+       exit ;;
     *:UNIX_System_V:4*:FTX*)
        # From Gerald Hewes <hewes@openmarket.com>.
        # How about differentiating between stratus architectures? -djm
@@ -1165,11 +1176,11 @@ EOF
        exit ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
        if [ -d /usr/nec ]; then
-               echo mips-nec-sysv${UNAME_RELEASE}
+               echo mips-nec-sysv${UNAME_RELEASE}
        else
-               echo mips-unknown-sysv${UNAME_RELEASE}
+               echo mips-unknown-sysv${UNAME_RELEASE}
        fi
-        exit ;;
+       exit ;;
     BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
        echo powerpc-be-beos
        exit ;;
@@ -1234,6 +1245,9 @@ EOF
     *:QNX:*:4*)
        echo i386-pc-qnx
        exit ;;
+    NEO-?:NONSTOP_KERNEL:*:*)
+       echo neo-tandem-nsk${UNAME_RELEASE}
+       exit ;;
     NSE-?:NONSTOP_KERNEL:*:*)
        echo nse-tandem-nsk${UNAME_RELEASE}
        exit ;;
@@ -1279,13 +1293,13 @@ EOF
        echo pdp10-unknown-its
        exit ;;
     SEI:*:*:SEIUX)
-        echo mips-sei-seiux${UNAME_RELEASE}
+       echo mips-sei-seiux${UNAME_RELEASE}
        exit ;;
     *:DragonFly:*:*)
        echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
        exit ;;
     *:*VMS:*:*)
-       UNAME_MACHINE=`(uname -p) 2>/dev/null`
+       UNAME_MACHINE=`(uname -p) 2>/dev/null`
        case "${UNAME_MACHINE}" in
            A*) echo alpha-dec-vms ; exit ;;
            I*) echo ia64-dec-vms ; exit ;;
@@ -1325,11 +1339,11 @@ main ()
 #include <sys/param.h>
   printf ("m68k-sony-newsos%s\n",
 #ifdef NEWSOS4
-          "4"
+       "4"
 #else
-         ""
+       ""
 #endif
-         ); exit (0);
+       ); exit (0);
 #endif
 #endif
 
index 7a9c248adcf534930d91f456598a76dc72b5e2c1..bef46b2a337c094049926f168a67a5d56331b37a 100644 (file)
    */
 #undef HAVE_DECL_ERRNO
 
+/* Define to 1 if you have the declaration of `h_errno', and to 0 if you
+   don't. */
+#undef HAVE_DECL_H_ERRNO
+
 /* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
    don't. */
 #undef HAVE_DECL_SYS_SIGLIST
 /* Define to 1 if your Kerberos is Heimdal. */
 #undef HAVE_HEIMDAL
 
-/* Define to 1 if <netinet/in.h> contains struct in6_addr. */
-#undef HAVE_IN6_ADDR
-
 /* Define to 1 if you have the `initprivs' function. */
 #undef HAVE_INITPRIVS
 
    shadow enabled) */
 #undef HAVE_ISSECURE
 
-/* Define to 1 if you use Kerberos IV. */
-#undef HAVE_KERB4
-
 /* Define to 1 if you use Kerberos V. */
 #undef HAVE_KERB5
 
 /* Define to 1 if you have the <pty.h> header file. */
 #undef HAVE_PTY_H
 
+/* Define to 1 if you have the `pw_dup' function. */
+#undef HAVE_PW_DUP
+
 /* Define to 1 if you have the `random' function. */
 #undef HAVE_RANDOM
 
 /* Define to 1 if you have the <sasl/sasl.h> header file. */
 #undef HAVE_SASL_SASL_H
 
-/* Define if your struct sockadr has an sa_len field. */
-#undef HAVE_SA_LEN
-
 /* Define to 1 if you use SecurID for authentication. */
 #undef HAVE_SECURID
 
 /* Define to 1 if you have the `sia_ses_init' function. */
 #undef HAVE_SIA_SES_INIT
 
-/* Define to 1 if <signal.h> has the sigaction_t typedef. */
+/* Define to 1 if the system has the type `sigaction_t'. */
 #undef HAVE_SIGACTION_T
 
 /* Define to 1 if you use S/Key. */
 /* Define to 1 if you have the `snprintf' function. */
 #undef HAVE_SNPRINTF
 
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_H
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
 /* Define to 1 if the system has the type `struct in6_addr'. */
 #undef HAVE_STRUCT_IN6_ADDR
 
+/* Define to 1 if `p_tdev' is a member of `struct kinfo_proc2'. */
+#undef HAVE_STRUCT_KINFO_PROC2_P_TDEV
+
+/* Define to 1 if `ki_tdev' is a member of `struct kinfo_proc'. */
+#undef HAVE_STRUCT_KINFO_PROC_KI_TDEV
+
+/* Define to 1 if `kp_eproc.e_tdev' is a member of `struct kinfo_proc'. */
+#undef HAVE_STRUCT_KINFO_PROC_KP_EPROC_E_TDEV
+
+/* Define to 1 if `p_tdev' is a member of `struct kinfo_proc'. */
+#undef HAVE_STRUCT_KINFO_PROC_P_TDEV
+
+/* Define if your struct sockadr has an sa_len field. */
+#undef HAVE_STRUCT_SOCKADDR_SA_LEN
+
+/* Define to 1 if the system has the type `struct timespec'. */
+#undef HAVE_STRUCT_TIMESPEC
+
 /* Define to 1 if `ut_exit' is a member of `struct utmpx'. */
 #undef HAVE_STRUCT_UTMPX_UT_EXIT
 
 /* Define to 1 if you have the <sys/types.h> header file. */
 #undef HAVE_SYS_TYPES_H
 
-/* Define to 1 if you have struct timespec in sys/time.h */
-#undef HAVE_TIMESPEC
-
 /* Define to 1 if you have the `ttyslot' function. */
 #undef HAVE_TTYSLOT
 
 /* Define to 1 if you have the <zlib.h> header file. */
 #undef HAVE_ZLIB_H
 
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
 /* Define to 1 if you have the `_getpty' function. */
 #undef HAVE__GETPTY
 
 /* Define to 1 if you have the `_innetgr' function. */
 #undef HAVE__INNETGR
 
+/* Define to 1 if the compiler supports the C99 __func__ variable. */
+#undef HAVE___FUNC__
+
 /* Define to 1 if your crt0.o defines the __progname symbol for you. */
 #undef HAVE___PROGNAME
 
 /* The name of the sudoers plugin, including extension. */
 #undef SUDOERS_PLUGIN
 
+/* An instance string to append to the username (separated by a slash) for
+   Kerberos V authentication */
+#undef SUDO_KRB5_INSTANCE
+
 /* The umask that the sudo-run prog should use. */
 #undef SUDO_UMASK
 
 /* Define for large files, on AIX-style hosts. */
 #undef _LARGE_FILES
 
+/* Define to __FUNCTION__ if your compiler support __FUNCTION__ but not
+   __func__ */
+#undef __func__
+
 /* Define to `signed' or nothing if compiler does not support a signed type
    qualifier. */
 #undef __signed
 /* Define to empty if `const' does not conform to ANSI C. */
 #undef const
 
-/* Define if your system lacks the dev_t type. */
+/* Define to `int' if <sys/types.h> does not define. */
 #undef dev_t
 
 /* Define to `int' if <sys/types.h> doesn't define. */
 #undef gid_t
 
-/* Define if your system lacks the ino_t type. */
+/* Define to `unsigned int' if <sys/types.h> does not define. */
 #undef ino_t
 
 /* Define to `int' if <sys/types.h> does not define. */
 /* Define to `unsigned int' if <sys/types.h> does not define. */
 #undef size_t
 
-/* Define if your system lacks the ssize_t type. */
+/* Define to `unsigned int' if <sys/socket.h> doesn't define. */
+#undef socklen_t
+
+/* Define to `int' if <sys/types.h> does not define. */
 #undef ssize_t
 
 /* Define to `int' if <sys/types.h> doesn't define. */
index 43e9be3fe2a23a946743e8c8687ad51ad458ba7e..a97ae6920ed93da941b60ff2508b2fd3152c8af3 100755 (executable)
@@ -1,10 +1,10 @@
 #! /bin/sh
 # Configuration validation subroutine script.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-#   Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011 Free Software Foundation, Inc.
 
-timestamp='2010-09-11'
+timestamp='2011-10-08'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -76,7 +76,7 @@ version="\
 GNU config.sub ($timestamp)
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
 Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
@@ -158,8 +158,8 @@ case $os in
                os=
                basic_machine=$1
                ;;
-        -bluegene*)
-               os=-cnk
+       -bluegene*)
+               os=-cnk
                ;;
        -sim | -cisco | -oki | -wec | -winbond)
                os=
@@ -175,10 +175,10 @@ case $os in
                os=-chorusos
                basic_machine=$1
                ;;
-       -chorusrdb)
-               os=-chorusrdb
+       -chorusrdb)
+               os=-chorusrdb
                basic_machine=$1
-               ;;
+               ;;
        -hiux*)
                os=-hiuxwe2
                ;;
@@ -251,13 +251,17 @@ case $basic_machine in
        | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
        | am33_2.0 \
        | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+        | be32 | be64 \
        | bfin \
        | c4x | clipper \
        | d10v | d30v | dlx | dsp16xx \
+       | epiphany \
        | fido | fr30 | frv \
        | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+       | hexagon \
        | i370 | i860 | i960 | ia64 \
        | ip2k | iq2000 \
+       | le32 | le64 \
        | lm32 \
        | m32c | m32r | m32rle | m68000 | m68k | m88k \
        | maxq | mb | microblaze | mcore | mep | metag \
@@ -286,9 +290,10 @@ case $basic_machine in
        | nds32 | nds32le | nds32be \
        | nios | nios2 \
        | ns16k | ns32k \
+       | open8 \
        | or32 \
        | pdp10 | pdp11 | pj | pjl \
-       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+       | powerpc | powerpc64 | powerpc64le | powerpcle \
        | pyramid \
        | rx \
        | score \
@@ -296,12 +301,12 @@ case $basic_machine in
        | sh64 | sh64le \
        | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
        | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-       | spu | strongarm \
-       | tahoe | thumb | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+       | spu \
+       | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
        | ubicom32 \
-       | v850 | v850e \
+       | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
        | we32k \
-       | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+       | x86 | xc16x | xstormy16 | xtensa \
        | z8k | z80)
                basic_machine=$basic_machine-unknown
                ;;
@@ -325,6 +330,18 @@ case $basic_machine in
                basic_machine=mt-unknown
                ;;
 
+       strongarm | thumb | xscale)
+               basic_machine=arm-unknown
+               ;;
+
+       xscaleeb)
+               basic_machine=armeb-unknown
+               ;;
+
+       xscaleel)
+               basic_machine=armel-unknown
+               ;;
+
        # We use `pc' rather than `unknown'
        # because (1) that's what they normally are, and
        # (2) the word "unknown" tends to confuse beginning users.
@@ -344,6 +361,7 @@ case $basic_machine in
        | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
        | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
        | avr-* | avr32-* \
+       | be32-* | be64-* \
        | bfin-* | bs2000-* \
        | c[123]* | c30-* | [cjt]90-* | c4x-* \
        | clipper-* | craynv-* | cydra-* \
@@ -352,8 +370,10 @@ case $basic_machine in
        | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
        | h8300-* | h8500-* \
        | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+       | hexagon-* \
        | i*86-* | i860-* | i960-* | ia64-* \
        | ip2k-* | iq2000-* \
+       | le32-* | le64-* \
        | lm32-* \
        | m32c-* | m32r-* | m32rle-* \
        | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
@@ -382,24 +402,26 @@ case $basic_machine in
        | nds32-* | nds32le-* | nds32be-* \
        | nios-* | nios2-* \
        | none-* | np1-* | ns16k-* | ns32k-* \
+       | open8-* \
        | orion-* \
        | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
        | pyramid-* \
        | romp-* | rs6000-* | rx-* \
        | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
        | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
        | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
        | sparclite-* \
-       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
-       | tahoe-* | thumb-* \
+       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+       | tahoe-* \
        | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
-       | tile-* | tilegx-* \
+       | tile*-* \
        | tron-* \
        | ubicom32-* \
-       | v850-* | v850e-* | vax-* \
+       | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+       | vax-* \
        | we32k-* \
-       | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+       | x86-* | x86_64-* | xc16x-* | xps100-* \
        | xstormy16-* | xtensa*-* \
        | ymp-* \
        | z8k-* | z80-*)
@@ -424,7 +446,7 @@ case $basic_machine in
                basic_machine=a29k-amd
                os=-udi
                ;;
-       abacus)
+       abacus)
                basic_machine=abacus-unknown
                ;;
        adobe68k)
@@ -507,7 +529,7 @@ case $basic_machine in
                basic_machine=c90-cray
                os=-unicos
                ;;
-        cegcc)
+       cegcc)
                basic_machine=arm-unknown
                os=-cegcc
                ;;
@@ -539,7 +561,7 @@ case $basic_machine in
                basic_machine=craynv-cray
                os=-unicosmp
                ;;
-       cr16)
+       cr16 | cr16-*)
                basic_machine=cr16-unknown
                os=-elf
                ;;
@@ -759,7 +781,7 @@ case $basic_machine in
                basic_machine=ns32k-utek
                os=-sysv
                ;;
-        microblaze)
+       microblaze)
                basic_machine=microblaze-xilinx
                ;;
        mingw32)
@@ -802,6 +824,10 @@ case $basic_machine in
                basic_machine=i370-ibm
                os=-mvs
                ;;
+       nacl)
+               basic_machine=le32-unknown
+               os=-nacl
+               ;;
        ncr3000)
                basic_machine=i486-ncr
                os=-sysv4
@@ -866,10 +892,10 @@ case $basic_machine in
        np1)
                basic_machine=np1-gould
                ;;
-        neo-tandem)
+       neo-tandem)
                basic_machine=neo-tandem
                ;;
-        nse-tandem)
+       nse-tandem)
                basic_machine=nse-tandem
                ;;
        nsr-tandem)
@@ -954,9 +980,10 @@ case $basic_machine in
                ;;
        power)  basic_machine=power-ibm
                ;;
-       ppc)    basic_machine=powerpc-unknown
+       ppc | ppcbe)    basic_machine=powerpc-unknown
                ;;
-       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+       ppc-* | ppcbe-*)
+               basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
                ;;
        ppcle | powerpclittle | ppc-le | powerpc-little)
                basic_machine=powerpcle-unknown
@@ -1050,6 +1077,9 @@ case $basic_machine in
                basic_machine=i860-stratus
                os=-sysv4
                ;;
+       strongarm-* | thumb-*)
+               basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
        sun2)
                basic_machine=m68000-sun
                ;;
@@ -1106,13 +1136,8 @@ case $basic_machine in
                basic_machine=t90-cray
                os=-unicos
                ;;
-        # This must be matched before tile*.
-        tilegx*)
-               basic_machine=tilegx-unknown
-               os=-linux-gnu
-               ;;
        tile*)
-               basic_machine=tile-unknown
+               basic_machine=$basic_machine-unknown
                os=-linux-gnu
                ;;
        tx39)
@@ -1182,6 +1207,9 @@ case $basic_machine in
        xps | xps100)
                basic_machine=xps100-honeywell
                ;;
+       xscale-* | xscalee[bl]-*)
+               basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+               ;;
        ymp)
                basic_machine=ymp-cray
                os=-unicos
@@ -1279,11 +1307,11 @@ esac
 if [ x"$os" != x"" ]
 then
 case $os in
-        # First match some system type aliases
-        # that might get confused with valid system types.
+       # First match some system type aliases
+       # that might get confused with valid system types.
        # -solaris* is a basic system type, with this one exception.
-        -auroraux)
-               os=-auroraux
+       -auroraux)
+               os=-auroraux
                ;;
        -solaris1 | -solaris1.*)
                os=`echo $os | sed -e 's|solaris1|sunos4|'`
@@ -1368,7 +1396,7 @@ case $os in
        -opened*)
                os=-openedition
                ;;
-        -os400*)
+       -os400*)
                os=-os400
                ;;
        -wince*)
@@ -1417,7 +1445,7 @@ case $os in
        -sinix*)
                os=-sysv4
                ;;
-        -tpf*)
+       -tpf*)
                os=-tpf
                ;;
        -triton*)
@@ -1462,8 +1490,8 @@ case $os in
        -dicos*)
                os=-dicos
                ;;
-        -nacl*)
-               ;;
+       -nacl*)
+               ;;
        -none)
                ;;
        *)
@@ -1486,10 +1514,10 @@ else
 # system, and we'll never get to this point.
 
 case $basic_machine in
-        score-*)
+       score-*)
                os=-elf
                ;;
-        spu-*)
+       spu-*)
                os=-elf
                ;;
        *-acorn)
@@ -1501,8 +1529,8 @@ case $basic_machine in
        arm*-semi)
                os=-aout
                ;;
-        c4x-* | tic4x-*)
-               os=-coff
+       c4x-* | tic4x-*)
+               os=-coff
                ;;
        tic54x-*)
                os=-coff
@@ -1538,7 +1566,7 @@ case $basic_machine in
        m68*-cisco)
                os=-aout
                ;;
-        mep-*)
+       mep-*)
                os=-elf
                ;;
        mips*-cisco)
@@ -1565,7 +1593,7 @@ case $basic_machine in
        *-ibm)
                os=-aix
                ;;
-       *-knuth)
+       *-knuth)
                os=-mmixware
                ;;
        *-wec)
index 7b4331466a23b776bedabf0fc61d1eadf8b21dda..934f846ddca0df735d18c718c9218f19a3977a8c 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for sudo 1.8.3p2.
+# Generated by GNU Autoconf 2.68 for sudo 1.8.4p4.
 #
 # Report bugs to <http://www.sudo.ws/bugs/>.
 #
@@ -570,8 +570,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='sudo'
 PACKAGE_TARNAME='sudo'
-PACKAGE_VERSION='1.8.3p2'
-PACKAGE_STRING='sudo 1.8.3p2'
+PACKAGE_VERSION='1.8.4p4'
+PACKAGE_STRING='sudo 1.8.4p4'
 PACKAGE_BUGREPORT='http://www.sudo.ws/bugs/'
 PACKAGE_URL=''
 
@@ -691,6 +691,7 @@ password_timeout
 timeout
 timedir
 iolog_dir
+COMPAT_TEST_PROGS
 SUDO_NLS
 LIBINTL
 LT_STATIC
@@ -718,7 +719,7 @@ devdir
 SEMAN
 LCMAN
 BAMAN
-DEV
+DEVEL
 SUDOERS_GID
 SUDOERS_UID
 SUDOERS_MODE
@@ -803,7 +804,6 @@ with_opie
 with_long_otp_prompt
 with_SecurID
 with_fwtk
-with_kerb4
 with_kerb5
 with_aixauth
 with_pam
@@ -892,6 +892,7 @@ enable_sia
 enable_largefile
 with_pam_login
 enable_pam_session
+enable_kerb5_instance
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1446,7 +1447,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.8.3p2 to adapt to many kinds of systems.
+\`configure' configures sudo 1.8.4p4 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1511,7 +1512,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of sudo 1.8.3p2:";;
+     short | recursive ) echo "Configuration of sudo 1.8.4p4:";;
    esac
   cat <<\_ACEOF
 
@@ -1548,6 +1549,8 @@ Optional Features:
   --disable-sia           Disable SIA on Digital UNIX
   --disable-largefile     omit support for large files
   --disable-pam-session   Disable PAM session support
+  --enable-kerb5-instance instance string to append to the username (separated
+                          by a slash)
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -1571,7 +1574,6 @@ Optional Packages:
   --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-aixauth          enable AIX general authentication support
   --with-pam              enable PAM support
@@ -1637,7 +1639,7 @@ Optional Packages:
   --with-askpass=PATH     Fully qualified pathname of askpass helper
   --with-plugindir        set directory to load plugins from
   --with-selinux          enable SELinux support
-  --with-pic              try to use only PIC/non-PIC objects [default=use
+  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
                           both]
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
   --with-sysroot=DIR Search for dependent libraries within DIR
@@ -1728,7 +1730,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-sudo configure 1.8.3p2
+sudo configure 1.8.4p4
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2003,6 +2005,60 @@ $as_echo "$ac_res" >&6; }
 
 } # ac_fn_c_check_func
 
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+        return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+           return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
 # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
 # -------------------------------------------------------
 # Tests whether HEADER exists, giving a warning if it cannot be compiled using
@@ -2094,60 +2150,6 @@ fi
 
 } # ac_fn_c_check_header_mongrel
 
-# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
-# -------------------------------------------
-# Tests whether TYPE exists after having included INCLUDES, setting cache
-# variable VAR accordingly.
-ac_fn_c_check_type ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  eval "$3=no"
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-if (sizeof ($2))
-        return 0;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-if (sizeof (($2)))
-           return 0;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
-  eval "$3=yes"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_type
-
 # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
 # --------------------------------------------
 # Tries to find the compile-time value of EXPR in a program that includes
@@ -2432,7 +2434,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.8.3p2, which was
+It was created by sudo $as_me 1.8.4p4, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -2869,6 +2871,7 @@ $as_echo "$as_me: Configuring Sudo version $PACKAGE_VERSION" >&6;}
 
 
 
+
 
 
 #
@@ -2921,7 +2924,7 @@ PROGS="sudo"
 : ${SUDOERS_MODE='0440'}
 : ${SUDOERS_UID='0'}
 : ${SUDOERS_GID='0'}
-DEV="#"
+DEVEL=
 LDAP="#"
 BAMAN=0
 LCMAN=0
@@ -2978,7 +2981,7 @@ if test "${with_devel+set}" = set; then :
     yes)       { $as_echo "$as_me:${as_lineno-$LINENO}: Setting up for development: -Wall, flex, yacc" >&5
 $as_echo "$as_me: Setting up for development: -Wall, flex, yacc" >&6;}
                OSDEFS="${OSDEFS} -DSUDO_DEVEL"
-               DEV=""
+               DEVEL="true"
                devdir=.
                ;;
     no)                ;;
@@ -4062,21 +4065,6 @@ fi
 
 
 
-# Check whether --with-kerb4 was given.
-if test "${with_kerb4+set}" = set; then :
-  withval=$with_kerb4; case $with_kerb4 in
-    no)                ;;
-    *)         { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to try kerberos IV authentication" >&5
-$as_echo_n "checking whether to try kerberos IV authentication... " >&6; }
-               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-               AUTH_REG="$AUTH_REG kerb4"
-               ;;
-esac
-fi
-
-
-
 # Check whether --with-kerb5 was given.
 if test "${with_kerb5+set}" = set; then :
   withval=$with_kerb5; case $with_kerb5 in
@@ -5478,12 +5466,12 @@ fi
 if test "$env_reset" = "on"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
-    $as_echo "#define ENV_RESET TRUE" >>confdefs.h
+    $as_echo "#define ENV_RESET 1" >>confdefs.h
 
 else
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-    $as_echo "#define ENV_RESET FALSE" >>confdefs.h
+    $as_echo "#define ENV_RESET 0" >>confdefs.h
 
 fi
 
@@ -6105,8 +6093,8 @@ esac
 
 
 
-macro_version='2.4'
-macro_revision='1.3293'
+macro_version='2.4.2'
+macro_revision='1.3337'
 
 
 
@@ -6880,6 +6868,11 @@ else
     lt_cv_sys_max_cmd_len=196608
     ;;
 
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
   osf*)
     # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
     # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
@@ -6919,7 +6912,7 @@ else
       # If test is not a shell built-in, we'll probably end up computing a
       # maximum length that is only half of the actual maximum length, but
       # we can't tell.
-      while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
                 = "X$teststring$teststring"; } >/dev/null 2>&1 &&
              test $i != 17 # 1/2 MB should be enough
       do
@@ -7348,7 +7341,7 @@ irix5* | irix6* | nonstopux*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-# This must be Linux ELF.
+# This must be glibc/ELF.
 linux* | k*bsd*-gnu | kopensolaris*-gnu)
   lt_cv_deplibs_check_method=pass_all
   ;;
@@ -7988,13 +7981,13 @@ old_postuninstall_cmds=
 if test -n "$RANLIB"; then
   case $host_os in
   openbsd*)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
     ;;
   *)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
     ;;
   esac
-  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
 fi
 
 case $host_os in
@@ -8183,6 +8176,7 @@ for ac_symprfx in "" "_"; do
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK '"\
 "     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
 "     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
 "     \$ 0!~/External *\|/{next};"\
 "     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
@@ -8571,7 +8565,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
     CFLAGS="$SAVE_CFLAGS"
   fi
   ;;
-sparc*-*solaris*)
+*-*solaris*)
   # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
@@ -8582,7 +8576,20 @@ sparc*-*solaris*)
     case `/usr/bin/file conftest.o` in
     *64-bit*)
       case $lt_cv_prog_gnu_ld in
-      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      yes*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
       *)
        if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
          LD="${LD-ld} -64"
@@ -9222,7 +9229,13 @@ else
        $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
          -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
         _lt_result=$?
-       if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+       # If there is a non-empty error log, and "single_module"
+       # appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+         cat conftest.err >&5
+       # Otherwise, if the output was created with a 0 exit code from
+       # the compiler, it worked.
+       elif test -f libconftest.dylib && test $_lt_result -eq 0; then
          lt_cv_apple_cc_single_mod=yes
        else
          cat conftest.err >&5
@@ -9233,6 +9246,7 @@ else
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
 $as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
 if ${lt_cv_ld_exported_symbols_list+:} false; then :
@@ -9265,6 +9279,7 @@ rm -f core conftest.err conftest.$ac_objext \
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
 $as_echo_n "checking for -force_load linker flag... " >&6; }
 if ${lt_cv_ld_force_load+:} false; then :
@@ -9286,7 +9301,9 @@ _LT_EOF
       echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
       $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
       _lt_result=$?
-      if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then
+      if test -s conftest.err && $GREP force_load conftest.err; then
+       cat conftest.err >&5
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
        lt_cv_ld_force_load=yes
       else
        cat conftest.err >&5
@@ -9553,7 +9570,22 @@ fi
 
 # Check whether --with-pic was given.
 if test "${with_pic+set}" = set; then :
-  withval=$with_pic; pic_mode="$withval"
+  withval=$with_pic; lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+       IFS="$lt_save_ifs"
+       if test "X$lt_pkg" = "X$lt_p"; then
+         pic_mode=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
 else
   pic_mode=default
 fi
@@ -9626,6 +9658,10 @@ LIBTOOL='$(SHELL) $(top_builddir)/libtool'
 
 
 
+
+
+
+
 
 
 
@@ -10090,7 +10126,9 @@ lt_prog_compiler_static=
     case $cc_basename in
     nvcc*) # Cuda Compiler Driver 2.2
       lt_prog_compiler_wl='-Xlinker '
-      lt_prog_compiler_pic='-Xcompiler -fPIC'
+      if test -n "$lt_prog_compiler_pic"; then
+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+      fi
       ;;
     esac
   else
@@ -10181,18 +10219,33 @@ lt_prog_compiler_static=
        ;;
       *)
        case `$CC -V 2>&1 | sed 5q` in
-       *Sun\ F* | *Sun*Fortran*)
+       *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
          # Sun Fortran 8.3 passes all unrecognized flags to the linker
          lt_prog_compiler_pic='-KPIC'
          lt_prog_compiler_static='-Bstatic'
          lt_prog_compiler_wl=''
          ;;
+       *Sun\ F* | *Sun*Fortran*)
+         lt_prog_compiler_pic='-KPIC'
+         lt_prog_compiler_static='-Bstatic'
+         lt_prog_compiler_wl='-Qoption ld '
+         ;;
        *Sun\ C*)
          # Sun C 5.9
          lt_prog_compiler_pic='-KPIC'
          lt_prog_compiler_static='-Bstatic'
          lt_prog_compiler_wl='-Wl,'
          ;;
+        *Intel*\ [CF]*Compiler*)
+         lt_prog_compiler_wl='-Wl,'
+         lt_prog_compiler_pic='-fPIC'
+         lt_prog_compiler_static='-static'
+         ;;
+       *Portland\ Group*)
+         lt_prog_compiler_wl='-Wl,'
+         lt_prog_compiler_pic='-fpic'
+         lt_prog_compiler_static='-Bstatic'
+         ;;
        esac
        ;;
       esac
@@ -10554,7 +10607,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   hardcode_direct=no
   hardcode_direct_absolute=no
   hardcode_libdir_flag_spec=
-  hardcode_libdir_flag_spec_ld=
   hardcode_libdir_separator=
   hardcode_minus_L=no
   hardcode_shlibpath_var=unsupported
@@ -10804,8 +10856,7 @@ _LT_EOF
        xlf* | bgf* | bgxlf* | mpixlf*)
          # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
          whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
-         hardcode_libdir_flag_spec=
-         hardcode_libdir_flag_spec_ld='-rpath $libdir'
+         hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
          archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
          if test "x$supports_anon_versioning" = xyes; then
            archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
@@ -11184,6 +11235,7 @@ fi
        # The linker will not automatically build a static lib if we build a DLL.
        # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
        enable_shared_with_static_runtimes=yes
+       exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
        export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
        # Don't use ranlib
        old_postinstall_cmds='chmod 644 $oldlib'
@@ -11229,6 +11281,7 @@ fi
   hardcode_shlibpath_var=unsupported
   if test "$lt_cv_ld_force_load" = "yes"; then
     whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
   else
     whole_archive_flag_spec=''
   fi
       hardcode_shlibpath_var=no
       ;;
 
-    freebsd1*)
-      ld_shlibs=no
-      ;;
-
     # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
     # support.  Future versions do this automatically, but an explicit c++rt0.o
     # does not break anything, and helps significantly (at the cost of a little
@@ -11273,7 +11322,7 @@ fi
       ;;
 
     # Unfortunately, older versions of FreeBSD 2 do not have this feature.
-    freebsd2*)
+    freebsd2.*)
       archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
       hardcode_direct=yes
       hardcode_minus_L=yes
@@ -11312,7 +11361,6 @@ fi
       fi
       if test "$with_gnu_ld" = no; then
        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
-       hardcode_libdir_flag_spec_ld='+b $libdir'
        hardcode_libdir_separator=:
        hardcode_direct=yes
        hardcode_direct_absolute=yes
@@ -11930,11 +11978,6 @@ esac
 
 
 
-
-
-
-
-
 
 
 
@@ -12030,7 +12073,7 @@ need_version=unknown
 
 case $host_os in
 aix3*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
@@ -12039,7 +12082,7 @@ aix3*)
   ;;
 
 aix[4-9]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
@@ -12104,7 +12147,7 @@ beos*)
   ;;
 
 bsdi[45]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
@@ -12243,7 +12286,7 @@ darwin* | rhapsody*)
   ;;
 
 dgux*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
@@ -12251,10 +12294,6 @@ dgux*)
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
-freebsd1*)
-  dynamic_linker=no
-  ;;
-
 freebsd* | dragonfly*)
   # DragonFly does not have aout.  When/if they implement a new
   # versioning mechanism, adjust this.
@@ -12262,7 +12301,7 @@ freebsd* | dragonfly*)
     objformat=`/usr/bin/objformat`
   else
     case $host_os in
-    freebsd[123]*) objformat=aout ;;
+    freebsd[23].*) objformat=aout ;;
     *) objformat=elf ;;
     esac
   fi
@@ -12280,7 +12319,7 @@ freebsd* | dragonfly*)
   esac
   shlibpath_var=LD_LIBRARY_PATH
   case $host_os in
-  freebsd2*)
+  freebsd2.*)
     shlibpath_overrides_runpath=yes
     ;;
   freebsd3.[01]* | freebsdelf3.[01]*)
@@ -12300,17 +12339,18 @@ freebsd* | dragonfly*)
   ;;
 
 gnu*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
   ;;
 
 haiku*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   dynamic_linker="$host_os runtime_loader"
@@ -12371,7 +12411,7 @@ hpux9* | hpux10* | hpux11*)
   ;;
 
 interix[3-9]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
@@ -12387,7 +12427,7 @@ irix5* | irix6* | nonstopux*)
     nonstopux*) version_type=nonstopux ;;
     *)
        if test "$lt_cv_prog_gnu_ld" = yes; then
-               version_type=linux
+               version_type=linux # correct to gnu/linux during the next big refactor
        else
                version_type=irix
        fi ;;
@@ -12424,9 +12464,9 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-# This must be Linux ELF.
+# This must be glibc/ELF.
 linux* | k*bsd*-gnu | kopensolaris*-gnu)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -12508,7 +12548,7 @@ netbsd*)
   ;;
 
 newsos6)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
@@ -12577,7 +12617,7 @@ rdos*)
   ;;
 
 solaris*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -12602,7 +12642,7 @@ sunos4*)
   ;;
 
 sysv4 | sysv4.3*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
@@ -12626,7 +12666,7 @@ sysv4 | sysv4.3*)
 
 sysv4*MP*)
   if test -d /usr/nec ;then
-    version_type=linux
+    version_type=linux # correct to gnu/linux during the next big refactor
     library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
     soname_spec='$libname${shared_ext}.$major'
     shlibpath_var=LD_LIBRARY_PATH
@@ -12657,7 +12697,7 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
 
 tpf*)
   # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -12667,7 +12707,7 @@ tpf*)
   ;;
 
 uts4*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
@@ -13449,6 +13489,8 @@ CC="$lt_save_CC"
 
 
 
+
+
         ac_config_commands="$ac_config_commands libtool"
 
 
@@ -13463,6 +13505,7 @@ if test "$enable_shared" = "no"; then
     enable_dlopen=no
     lt_cv_dlopen=none
     lt_cv_dlopen_libs=
+    ac_cv_func_dlopen=no
 else
     eval _shrext="$shrext_cmds"
     # Darwin uses .dylib for libraries but .so for modules
@@ -14495,6 +14538,31 @@ $as_echo "#define volatile /**/" >>confdefs.h
 
 fi
 
+# Check for variadic macro support in cpp
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+$ac_includes_default
+#if defined(__GNUC__) && __GNUC__ == 2
+# define sudo_fprintf(fp, fmt...) fprintf((fp), (fmt))
+#else
+# define sudo_fprintf(fp, ...) fprintf((fp), __VA_ARGS__)
+#endif
+
+int
+main ()
+{
+sudo_fprintf(stderr, "a %s", "test");
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  as_fn_error $? "Your C compiler doesn't support variadic macros, try building with gcc instead" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 if test X"$with_gnu_ld" != "yes" -a -n "$GCC"; then
     _CFLAGS="$CFLAGS"
     CFLAGS="$CFLAGS -static-libgcc"
@@ -15029,6 +15097,98 @@ $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
+$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
+if ${ac_cv_header_stdbool_h+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdbool.h>
+#ifndef bool
+ "error: bool is not defined"
+#endif
+#ifndef false
+ "error: false is not defined"
+#endif
+#if false
+ "error: false is not 0"
+#endif
+#ifndef true
+ "error: true is not defined"
+#endif
+#if true != 1
+ "error: true is not 1"
+#endif
+#ifndef __bool_true_false_are_defined
+ "error: __bool_true_false_are_defined is not defined"
+#endif
+
+       struct s { _Bool s: 1; _Bool t; } s;
+
+       char a[true == 1 ? 1 : -1];
+       char b[false == 0 ? 1 : -1];
+       char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+       char d[(bool) 0.5 == true ? 1 : -1];
+       /* See body of main program for 'e'.  */
+       char f[(_Bool) 0.0 == false ? 1 : -1];
+       char g[true];
+       char h[sizeof (_Bool)];
+       char i[sizeof s.t];
+       enum { j = false, k = true, l = false * true, m = true * 256 };
+       /* The following fails for
+          HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
+       _Bool n[m];
+       char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+       char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+       /* Catch a bug in an HP-UX C compiler.  See
+          http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+          http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+        */
+       _Bool q = true;
+       _Bool *pq = &q;
+
+int
+main ()
+{
+
+       bool e = &s;
+       *pq |= q;
+       *pq |= ! q;
+       /* Refer to every declared value, to avoid compiler optimizations.  */
+       return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
+               + !m + !n + !o + !p + !q + !pq);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdbool_h=yes
+else
+  ac_cv_header_stdbool_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
+$as_echo "$ac_cv_header_stdbool_h" >&6; }
+ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default"
+if test "x$ac_cv_type__Bool" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE__BOOL 1
+_ACEOF
+
+
+fi
+
+if test $ac_cv_header_stdbool_h = yes; then
+
+$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
+
+fi
+
 for ac_header in malloc.h paths.h utime.h netgroup.h utmpx.h sys/sockio.h sys/bsdtypes.h sys/select.h sys/stropts.h sys/sysmacros.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
@@ -15541,7 +15701,6 @@ cat >>confdefs.h <<_ACEOF
 #define HAVE_SIGACTION_T 1
 _ACEOF
 
-$as_echo "#define HAVE_SIGACTION_T 1" >>confdefs.h
 
 fi
 
@@ -15552,7 +15711,11 @@ ac_fn_c_check_type "$LINENO" "struct timespec" "ac_cv_type_struct_timespec" "#in
 #include <time.h>
 "
 if test "x$ac_cv_type_struct_timespec" = xyes; then :
-  $as_echo "#define HAVE_TIMESPEC 1" >>confdefs.h
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_TIMESPEC 1
+_ACEOF
+
 
 fi
 
@@ -15565,7 +15728,6 @@ cat >>confdefs.h <<_ACEOF
 #define HAVE_STRUCT_IN6_ADDR 1
 _ACEOF
 
-$as_echo "#define HAVE_IN6_ADDR 1" >>confdefs.h
 
 fi
 
@@ -15693,135 +15855,58 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for size_t" >&5
-$as_echo_n "checking for size_t... " >&6; }
-if ${sudo_cv_type_size_t+:} false; then :
-  $as_echo_n "(cached) " >&6
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/types.h>
-#include <stdio.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
 _ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "size_t" >/dev/null 2>&1; then :
-  sudo_cv_type_size_t=yes
-else
-  sudo_cv_type_size_t=no
-fi
-rm -f conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_type_size_t" >&5
-$as_echo "$sudo_cv_type_size_t" >&6; }
-if test $sudo_cv_type_size_t = no; then
 
-$as_echo "#define size_t int" >>confdefs.h
+ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default"
+if test "x$ac_cv_type_ssize_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define ssize_t int
+_ACEOF
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ssize_t" >&5
-$as_echo_n "checking for ssize_t... " >&6; }
-if ${sudo_cv_type_ssize_t+:} false; then :
-  $as_echo_n "(cached) " >&6
+ac_fn_c_check_type "$LINENO" "dev_t" "ac_cv_type_dev_t" "$ac_includes_default"
+if test "x$ac_cv_type_dev_t" = xyes; then :
+
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/types.h>
-#include <stdio.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+
+cat >>confdefs.h <<_ACEOF
+#define dev_t int
 _ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "ssize_t" >/dev/null 2>&1; then :
-  sudo_cv_type_ssize_t=yes
-else
-  sudo_cv_type_ssize_t=no
-fi
-rm -f conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_type_ssize_t" >&5
-$as_echo "$sudo_cv_type_ssize_t" >&6; }
-if test $sudo_cv_type_ssize_t = no; then
 
-$as_echo "#define ssize_t int" >>confdefs.h
-
-fi
+ac_fn_c_check_type "$LINENO" "ino_t" "ac_cv_type_ino_t" "$ac_includes_default"
+if test "x$ac_cv_type_ino_t" = xyes; then :
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dev_t" >&5
-$as_echo_n "checking for dev_t... " >&6; }
-if ${sudo_cv_type_dev_t+:} false; then :
-  $as_echo_n "(cached) " >&6
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/types.h>
-#include <stdio.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+
+cat >>confdefs.h <<_ACEOF
+#define ino_t unsigned int
 _ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "dev_t" >/dev/null 2>&1; then :
-  sudo_cv_type_dev_t=yes
-else
-  sudo_cv_type_dev_t=no
-fi
-rm -f conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_type_dev_t" >&5
-$as_echo "$sudo_cv_type_dev_t" >&6; }
-if test $sudo_cv_type_dev_t = no; then
-
-$as_echo "#define dev_t int" >>confdefs.h
 
-fi
+ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "
+$ac_includes_default
+#include <sys/socket.h>
+"
+if test "x$ac_cv_type_socklen_t" = xyes; then :
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ino_t" >&5
-$as_echo_n "checking for ino_t... " >&6; }
-if ${sudo_cv_type_ino_t+:} false; then :
-  $as_echo_n "(cached) " >&6
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/types.h>
-#include <stdio.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "ino_t" >/dev/null 2>&1; then :
-  sudo_cv_type_ino_t=yes
-else
-  sudo_cv_type_ino_t=no
-fi
-rm -f conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_type_ino_t" >&5
-$as_echo "$sudo_cv_type_ino_t" >&6; }
-if test $sudo_cv_type_ino_t = no; then
-
-$as_echo "#define ino_t unsigned int" >>confdefs.h
+  $as_echo "#define socklen_t unsigned int" >>confdefs.h
 
 fi
 
@@ -15884,7 +15969,7 @@ _ACEOF
 "
 if test "x$ac_cv_member_struct_sockaddr_sa_len" = xyes; then :
 
-$as_echo "#define HAVE_SA_LEN 1" >>confdefs.h
+$as_echo "#define HAVE_STRUCT_SOCKADDR_SA_LEN 1" >>confdefs.h
 
 fi
 
@@ -16258,8 +16343,8 @@ fi
 LIBS=$ac_save_LIBS
 
 for ac_func in strrchr sysconf tzset strftime \
-              regcomp setlocale nl_langinfo getaddrinfo mbr_check_membership \
-              setrlimit64 sysctl
+              regcomp setlocale nl_langinfo mbr_check_membership \
+              setrlimit64
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -16316,6 +16401,32 @@ done
 fi
 done
 
+O_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2"
+ac_fn_c_check_func "$LINENO" "__sprintf_chk" "ac_cv_func___sprintf_chk"
+if test "x$ac_cv_func___sprintf_chk" = xyes; then :
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+char buf[4]; (void)sprintf(buf, "%s", "foo");
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  OSDEFS="${OSDEFS} -D_FORTIFY_SOURCE=2"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+fi
+
+CPPFLAGS="$O_CPPFLAGS"
+
 utmp_style=LEGACY
 for ac_func in getutxid getutid
 do :
@@ -16344,6 +16455,84 @@ done
 
 fi
 
+for ac_func in sysctl
+do :
+  ac_fn_c_check_func "$LINENO" "sysctl" "ac_cv_func_sysctl"
+if test "x$ac_cv_func_sysctl" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYSCTL 1
+_ACEOF
+ ac_fn_c_check_member "$LINENO" "struct kinfo_proc" "ki_tdev" "ac_cv_member_struct_kinfo_proc_ki_tdev" "
+       #include <sys/param.h>
+       #include <sys/sysctl.h>
+       #include <sys/user.h>
+
+"
+if test "x$ac_cv_member_struct_kinfo_proc_ki_tdev" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_KINFO_PROC_KI_TDEV 1
+_ACEOF
+
+
+else
+
+       ac_fn_c_check_member "$LINENO" "struct kinfo_proc2" "p_tdev" "ac_cv_member_struct_kinfo_proc2_p_tdev" "
+           #include <sys/param.h>
+           #include <sys/sysctl.h>
+
+"
+if test "x$ac_cv_member_struct_kinfo_proc2_p_tdev" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_KINFO_PROC2_P_TDEV 1
+_ACEOF
+
+
+else
+
+           ac_fn_c_check_member "$LINENO" "struct kinfo_proc" "p_tdev" "ac_cv_member_struct_kinfo_proc_p_tdev" "
+               #include <sys/param.h>
+               #include <sys/sysctl.h>
+
+"
+if test "x$ac_cv_member_struct_kinfo_proc_p_tdev" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_KINFO_PROC_P_TDEV 1
+_ACEOF
+
+
+else
+
+               ac_fn_c_check_member "$LINENO" "struct kinfo_proc" "kp_eproc.e_tdev" "ac_cv_member_struct_kinfo_proc_kp_eproc_e_tdev" "
+                   #include <sys/param.h>
+                   #include <sys/sysctl.h>
+
+"
+if test "x$ac_cv_member_struct_kinfo_proc_kp_eproc_e_tdev" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_KINFO_PROC_KP_EPROC_E_TDEV 1
+_ACEOF
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
 for ac_func in openpty
 do :
   ac_fn_c_check_func "$LINENO" "openpty" "ac_cv_func_openpty"
@@ -16666,6 +16855,7 @@ else
  ;;
 esac
 
+    COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }globtest"
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
@@ -16677,6 +16867,8 @@ else
  ;;
 esac
 
+    COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }globtest"
+
 fi
 done
 
@@ -16809,6 +17001,8 @@ else
  ;;
 esac
 
+    COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }fnm_test"
+
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for isblank" >&5
 $as_echo_n "checking for isblank... " >&6; }
@@ -16863,6 +17057,19 @@ esac
 
 fi
 
+ac_fn_c_check_func "$LINENO" "pw_dup" "ac_cv_func_pw_dup"
+if test "x$ac_cv_func_pw_dup" = xyes; then :
+  $as_echo "#define HAVE_PW_DUP 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" pw_dup.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS pw_dup.$ac_objext"
+ ;;
+esac
+
+fi
+
 ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy"
 if test "x$ac_cv_func_strlcpy" = xyes; then :
   $as_echo "#define HAVE_STRLCPY 1" >>confdefs.h
@@ -17109,14 +17316,30 @@ ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket"
 if test "x$ac_cv_func_socket" = xyes; then :
 
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5
-$as_echo_n "checking for socket in -lsocket... " >&6; }
-if ${ac_cv_lib_socket_socket+:} false; then :
+
+    for libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+       _libs=
+       for lib in $libs; do
+           case "$NET_LIBS" in
+               *"$lib"*)   ;;
+               *)          _libs="$_libs $lib";;
+           esac
+       done
+       libs="${_libs# }"
+       test -z "$libs" && continue
+       lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+       extralibs="`echo \"$libs\"|sed 's/^-l[^ ]*//'`"
+
+    _sudo_check_lib_extras=`echo "$extralibs"|sed -e 's/       *//g' -e 's/-l/_/g'`
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -l$lib${5+ }$extralibs" >&5
+$as_echo_n "checking for socket in -l$lib${5+ }$extralibs... " >&6; }
+    if { as_var=sudo_cv_lib_$lib''_socket$_sudo_check_lib_extras; eval \${$as_var+:} false; }; then :
   $as_echo_n "(cached) " >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsocket  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+
+       SUDO_CHECK_LIB_OLIBS="$LIBS"
+       LIBS="$LIBS -l$lib${5+ }$extralibs"
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -17135,68 +17358,64 @@ return socket ();
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_socket_socket=yes
+  eval sudo_cv_lib_$lib''_socket$_sudo_check_lib_extras=yes
 else
-  ac_cv_lib_socket_socket=no
+  eval sudo_cv_lib_$lib''_socket$_sudo_check_lib_extras=no
+
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5
-$as_echo "$ac_cv_lib_socket_socket" >&6; }
-if test "x$ac_cv_lib_socket_socket" = xyes; then :
-  NET_LIBS="${NET_LIBS} -lsocket"; LIBS="${LIBS} -lsocket"
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -linet" >&5
-$as_echo_n "checking for socket in -linet... " >&6; }
-if ${ac_cv_lib_inet_socket+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-linet  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+       LIBS="$SUDO_CHECK_LIB_OLIBS"
 
-/* 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 socket ();
-int
-main ()
-{
-return socket ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_inet_socket=yes
-else
-  ac_cv_lib_inet_socket=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+
+    if eval test \$sudo_cv_lib_$lib''_socket$_sudo_check_lib_extras = "yes"; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+       NET_LIBS="${NET_LIBS} $libs"; LIBS="${LIBS} $libs"; break
+    else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+    fi
+
+    done
+
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_socket" >&5
-$as_echo "$ac_cv_lib_inet_socket" >&6; }
-if test "x$ac_cv_lib_inet_socket" = xyes; then :
-  NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet"
+
+ac_fn_c_check_func "$LINENO" "inet_addr" "ac_cv_func_inet_addr"
+if test "x$ac_cv_func_inet_addr" = xyes; then :
+
+else
+
+    ac_fn_c_check_func "$LINENO" "__inet_addr" "ac_cv_func___inet_addr"
+if test "x$ac_cv_func___inet_addr" = xyes; then :
+
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unable to find socket() trying -lsocket -lnsl" >&5
-$as_echo "$as_me: WARNING: unable to find socket() trying -lsocket -lnsl" >&2;}
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5
-$as_echo_n "checking for socket in -lsocket... " >&6; }
-if ${ac_cv_lib_socket_socket_lnsl+:} false; then :
+
+       for libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+           _libs=
+           for lib in $libs; do
+               case "$NET_LIBS" in
+                   *"$lib"*)   ;;
+                   *)          _libs="$_libs $lib";;
+               esac
+           done
+           libs="${_libs# }"
+           test -z "$libs" && continue
+           lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+           extralibs="`echo \"$libs\"|sed 's/^-l[^ ]*//'`"
+
+    _sudo_check_lib_extras=`echo "$extralibs"|sed -e 's/       *//g' -e 's/-l/_/g'`
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_addr in -l$lib${5+ }$extralibs" >&5
+$as_echo_n "checking for inet_addr in -l$lib${5+ }$extralibs... " >&6; }
+    if { as_var=sudo_cv_lib_$lib''_inet_addr$_sudo_check_lib_extras; eval \${$as_var+:} false; }; then :
   $as_echo_n "(cached) " >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsocket -lnsl $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+
+       SUDO_CHECK_LIB_OLIBS="$LIBS"
+       LIBS="$LIBS -l$lib${5+ }$extralibs"
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -17205,52 +17424,72 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 #ifdef __cplusplus
 extern "C"
 #endif
-char socket ();
+char inet_addr ();
 int
 main ()
 {
-return socket ();
+return inet_addr ();
   ;
   return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_socket_socket_lnsl=yes
+  eval sudo_cv_lib_$lib''_inet_addr$_sudo_check_lib_extras=yes
 else
-  ac_cv_lib_socket_socket_lnsl=no
+  eval sudo_cv_lib_$lib''_inet_addr$_sudo_check_lib_extras=no
+
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket_lnsl" >&5
-$as_echo "$ac_cv_lib_socket_socket_lnsl" >&6; }
-if test "x$ac_cv_lib_socket_socket_lnsl" = xyes; then :
-  NET_LIBS="${NET_LIBS} -lsocket -lnsl"; LIBS="${LIBS} -lsocket -lnsl"
-fi
+       LIBS="$SUDO_CHECK_LIB_OLIBS"
 
 fi
 
+    if eval test \$sudo_cv_lib_$lib''_inet_addr$_sudo_check_lib_extras = "yes"; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+       NET_LIBS="${NET_LIBS} $libs"; LIBS="${LIBS} $libs"; break
+    else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+    fi
+
+       done
+
 fi
 
+
 fi
 
-ac_fn_c_check_func "$LINENO" "inet_addr" "ac_cv_func_inet_addr"
-if test "x$ac_cv_func_inet_addr" = xyes; then :
+ac_fn_c_check_func "$LINENO" "syslog" "ac_cv_func_syslog"
+if test "x$ac_cv_func_syslog" = xyes; then :
 
 else
-  ac_fn_c_check_func "$LINENO" "__inet_addr" "ac_cv_func___inet_addr"
-if test "x$ac_cv_func___inet_addr" = xyes; then :
 
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_addr in -lnsl" >&5
-$as_echo_n "checking for inet_addr in -lnsl... " >&6; }
-if ${ac_cv_lib_nsl_inet_addr+:} false; then :
+    for libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+       _libs=
+       for lib in $libs; do
+           case "$NET_LIBS" in
+               *"$lib"*)   ;;
+               *)          _libs="$_libs $lib";;
+           esac
+       done
+       libs="${_libs# }"
+       test -z "$libs" && continue
+       lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+       extralibs="`echo \"$libs\"|sed 's/^-l[^ ]*//'`"
+
+    _sudo_check_lib_extras=`echo "$extralibs"|sed -e 's/       *//g' -e 's/-l/_/g'`
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for syslog in -l$lib${5+ }$extralibs" >&5
+$as_echo_n "checking for syslog in -l$lib${5+ }$extralibs... " >&6; }
+    if { as_var=sudo_cv_lib_$lib''_syslog$_sudo_check_lib_extras; eval \${$as_var+:} false; }; then :
   $as_echo_n "(cached) " >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lnsl  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+
+       SUDO_CHECK_LIB_OLIBS="$LIBS"
+       LIBS="$LIBS -l$lib${5+ }$extralibs"
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -17259,37 +17498,75 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 #ifdef __cplusplus
 extern "C"
 #endif
-char inet_addr ();
+char syslog ();
 int
 main ()
 {
-return inet_addr ();
+return syslog ();
   ;
   return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_nsl_inet_addr=yes
+  eval sudo_cv_lib_$lib''_syslog$_sudo_check_lib_extras=yes
 else
-  ac_cv_lib_nsl_inet_addr=no
+  eval sudo_cv_lib_$lib''_syslog$_sudo_check_lib_extras=no
+
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+       LIBS="$SUDO_CHECK_LIB_OLIBS"
+
+fi
+
+    if eval test \$sudo_cv_lib_$lib''_syslog$_sudo_check_lib_extras = "yes"; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+       NET_LIBS="${NET_LIBS} $libs"; LIBS="${LIBS} $libs"; break
+    else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+    fi
+
+    done
+
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_inet_addr" >&5
-$as_echo "$ac_cv_lib_nsl_inet_addr" >&6; }
-if test "x$ac_cv_lib_nsl_inet_addr" = xyes; then :
-  NET_LIBS="${NET_LIBS} -lnsl"; LIBS="${LIBS} -lnsl"
+
+for ac_func in getaddrinfo
+do :
+  ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo"
+if test "x$ac_cv_func_getaddrinfo" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GETADDRINFO 1
+_ACEOF
+
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_addr in -linet" >&5
-$as_echo_n "checking for inet_addr in -linet... " >&6; }
-if ${ac_cv_lib_inet_inet_addr+:} false; then :
+
+    found=no
+    for libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+       _libs=
+       for lib in $libs; do
+           case "$NET_LIBS" in
+               *"$lib"*)   ;;
+               *)          _libs="$_libs $lib";;
+           esac
+       done
+       libs="${_libs# }"
+       test -z "$libs" && continue
+       lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+       extralibs="`echo \"$libs\"|sed 's/^-l[^ ]*//'`"
+
+    _sudo_check_lib_extras=`echo "$extralibs"|sed -e 's/       *//g' -e 's/-l/_/g'`
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -l$lib${5+ }$extralibs" >&5
+$as_echo_n "checking for getaddrinfo in -l$lib${5+ }$extralibs... " >&6; }
+    if { as_var=sudo_cv_lib_$lib''_getaddrinfo$_sudo_check_lib_extras; eval \${$as_var+:} false; }; then :
   $as_echo_n "(cached) " >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-linet  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+
+       SUDO_CHECK_LIB_OLIBS="$LIBS"
+       LIBS="$LIBS -l$lib${5+ }$extralibs"
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -17298,220 +17575,134 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 #ifdef __cplusplus
 extern "C"
 #endif
-char inet_addr ();
+char getaddrinfo ();
 int
 main ()
 {
-return inet_addr ();
+return getaddrinfo ();
   ;
   return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_inet_inet_addr=yes
+  eval sudo_cv_lib_$lib''_getaddrinfo$_sudo_check_lib_extras=yes
 else
-  ac_cv_lib_inet_inet_addr=no
+  eval sudo_cv_lib_$lib''_getaddrinfo$_sudo_check_lib_extras=no
+
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+       LIBS="$SUDO_CHECK_LIB_OLIBS"
+
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_inet_addr" >&5
-$as_echo "$ac_cv_lib_inet_inet_addr" >&6; }
-if test "x$ac_cv_lib_inet_inet_addr" = xyes; then :
-  NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet"
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unable to find inet_addr() trying -lsocket -lnsl" >&5
-$as_echo "$as_me: WARNING: unable to find inet_addr() trying -lsocket -lnsl" >&2;}
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_addr in -lsocket" >&5
-$as_echo_n "checking for inet_addr in -lsocket... " >&6; }
-if ${ac_cv_lib_socket_inet_addr_lnsl+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsocket -lnsl $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
 
-/* 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 inet_addr ();
-int
-main ()
-{
-return inet_addr ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_socket_inet_addr_lnsl=yes
-else
-  ac_cv_lib_socket_inet_addr_lnsl=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_inet_addr_lnsl" >&5
-$as_echo "$ac_cv_lib_socket_inet_addr_lnsl" >&6; }
-if test "x$ac_cv_lib_socket_inet_addr_lnsl" = xyes; then :
-  NET_LIBS="${NET_LIBS} -lsocket -lnsl"; LIBS="${LIBS} -lsocket -lnsl"
-fi
+    if eval test \$sudo_cv_lib_$lib''_getaddrinfo$_sudo_check_lib_extras = "yes"; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+       NET_LIBS="${NET_LIBS} $libs"; LIBS="${LIBS} $libs"; found=yes; break
+    else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 
-fi
+    fi
 
-fi
+    done
+    if test X"$found" != X"no"; then
+       $as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
 
-fi
+    fi
 
 fi
+done
 
-ac_fn_c_check_func "$LINENO" "syslog" "ac_cv_func_syslog"
-if test "x$ac_cv_func_syslog" = xyes; then :
+for ac_func in getprogname
+do :
+  ac_fn_c_check_func "$LINENO" "getprogname" "ac_cv_func_getprogname"
+if test "x$ac_cv_func_getprogname" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GETPROGNAME 1
+_ACEOF
 
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for syslog in -lsocket" >&5
-$as_echo_n "checking for syslog in -lsocket... " >&6; }
-if ${ac_cv_lib_socket_syslog+:} false; then :
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __progname" >&5
+$as_echo_n "checking for __progname... " >&6; }
+    if ${sudo_cv___progname+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsocket  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-/* 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 syslog ();
 int
 main ()
 {
-return syslog ();
+extern char *__progname; (void)puts(__progname);
   ;
   return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_socket_syslog=yes
+  sudo_cv___progname=yes
 else
-  ac_cv_lib_socket_syslog=no
+  sudo_cv___progname=no
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_syslog" >&5
-$as_echo "$ac_cv_lib_socket_syslog" >&6; }
-if test "x$ac_cv_lib_socket_syslog" = xyes; then :
-  NET_LIBS="${NET_LIBS} -lsocket"; LIBS="${LIBS} -lsocket"
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for syslog in -lnsl" >&5
-$as_echo_n "checking for syslog in -lnsl... " >&6; }
-if ${ac_cv_lib_nsl_syslog+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lnsl  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
 
-/* 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 syslog ();
-int
-main ()
-{
-return syslog ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_nsl_syslog=yes
-else
-  ac_cv_lib_nsl_syslog=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+    if test "$sudo_cv___progname" = "yes"; then
+       $as_echo "#define HAVE___PROGNAME 1" >>confdefs.h
+
+    else
+       case " $LIBOBJS " in
+  *" getprogname.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS getprogname.$ac_objext"
+ ;;
+esac
+
+    fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv___progname" >&5
+$as_echo "$sudo_cv___progname" >&6; }
+
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_syslog" >&5
-$as_echo "$ac_cv_lib_nsl_syslog" >&6; }
-if test "x$ac_cv_lib_nsl_syslog" = xyes; then :
-  NET_LIBS="${NET_LIBS} -lnsl"; LIBS="${LIBS} -lnsl"
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for syslog in -linet" >&5
-$as_echo_n "checking for syslog in -linet... " >&6; }
-if ${ac_cv_lib_inet_syslog+:} false; then :
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __func__" >&5
+$as_echo_n "checking for __func__... " >&6; }
+if ${sudo_cv___func__+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-linet  $LIBS"
+
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-/* 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 syslog ();
 int
 main ()
 {
-return syslog ();
+(void)puts(__func__);
   ;
   return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_inet_syslog=yes
+  sudo_cv___func__=yes
 else
-  ac_cv_lib_inet_syslog=no
+  sudo_cv___func__=no
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_syslog" >&5
-$as_echo "$ac_cv_lib_inet_syslog" >&6; }
-if test "x$ac_cv_lib_inet_syslog" = xyes; then :
-  NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet"
-fi
-
-fi
-
-fi
-
 fi
 
-for ac_func in getprogname
-do :
-  ac_fn_c_check_func "$LINENO" "getprogname" "ac_cv_func_getprogname"
-if test "x$ac_cv_func_getprogname" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_GETPROGNAME 1
-_ACEOF
-
-else
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv___func__" >&5
+$as_echo "$sudo_cv___func__" >&6; }
+if test "$sudo_cv___func__" = "yes"; then
+    $as_echo "#define HAVE___FUNC__ 1" >>confdefs.h
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __progname" >&5
-$as_echo_n "checking for __progname... " >&6; }
-    if ${sudo_cv___progname+:} false; then :
+elif test -n "$GCC"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __FUNCTION__" >&5
+$as_echo_n "checking for __FUNCTION__... " >&6; }
+    if ${sudo_cv___FUNCTION__+:} false; then :
   $as_echo_n "(cached) " >&6
 else
 
@@ -17521,37 +17712,30 @@ else
 int
 main ()
 {
-extern char *__progname; (void)puts(__progname);
+(void)puts(__FUNCTION__);
   ;
   return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  sudo_cv___progname=yes
+  sudo_cv___FUNCTION__=yes
 else
-  sudo_cv___progname=no
+  sudo_cv___FUNCTION__=no
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
 fi
 
-    if test "$sudo_cv___progname" = "yes"; then
-       $as_echo "#define HAVE___PROGNAME 1" >>confdefs.h
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv___FUNCTION__" >&5
+$as_echo "$sudo_cv___FUNCTION__" >&6; }
+    if test "$sudo_cv___FUNCTION__" = "yes"; then
+       $as_echo "#define HAVE___FUNC__ 1" >>confdefs.h
 
-    else
-       case " $LIBOBJS " in
-  *" getprogname.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS getprogname.$ac_objext"
- ;;
-esac
 
-    fi
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv___progname" >&5
-$as_echo "$sudo_cv___progname" >&6; }
+$as_echo "#define __func__ __FUNCTION__" >>confdefs.h
 
+    fi
 fi
-done
-
 
 # gettext() and friends may be located in libc (Linux and Solaris)
 # or in libintl.  However, it is possible to have libintl installed
@@ -17764,6 +17948,22 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+ac_fn_c_check_decl "$LINENO" "h_errno" "ac_cv_have_decl_h_errno" "
+$ac_includes_default
+#include <netdb.h>
+
+"
+if test "x$ac_cv_have_decl_h_errno" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_H_ERRNO $ac_have_decl
+_ACEOF
+
+
 for ac_func in strsignal
 do :
   ac_fn_c_check_func "$LINENO" "strsignal" "ac_cv_func_strsignal"
@@ -17841,527 +18041,73 @@ if test $ac_have_decl = 1; then :
        break
 
 fi
-
-    if test "$HAVE_SIGLIST" != "true"; then
-       case " $LIBOBJS " in
-  *" siglist.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS siglist.$ac_objext"
- ;;
-esac
-
-    fi
-
-fi
-done
-
-
-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
-       case $auth in
-           AIX_AUTH)   with_aixauth=maybe;;
-           BSD_AUTH)   with_bsdauth=maybe;;
-           PAM)        with_pam=maybe;;
-           SIA)        CHECKSIA=true;;
-       esac
-    done
-fi
-
-if test ${with_pam-"no"} != "no"; then
-    # We already link with -ldl (see LIBDL below) so no need for that here.
-    SUDOERS_LIBS="${SUDOERS_LIBS} -lpam"
-
-                    for ac_header in security/pam_appl.h pam/pam_appl.h
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
- with_pam=yes; break
-fi
-
-done
-
-    if test "$with_pam" = "yes"; then
-       $as_echo "#define HAVE_PAM 1" >>confdefs.h
-
-       AUTH_OBJS="$AUTH_OBJS pam.lo";
-       AUTH_EXCL=PAM
-
-
-# Check whether --with-pam-login was given.
-if test "${with_pam_login+set}" = set; then :
-  withval=$with_pam_login; case $with_pam_login in
-           yes)        $as_echo "#define HAVE_PAM_LOGIN 1" >>confdefs.h
-
-                       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use PAM login" >&5
-$as_echo_n "checking whether to use PAM login... " >&6; }
-                       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-                       ;;
-           no)         ;;
-           *)          as_fn_error $? "\"--with-pam-login does not take an argument.\"" "$LINENO" 5
-                       ;;
-       esac
-fi
-
-
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use PAM session support" >&5
-$as_echo_n "checking whether to use PAM session support... " >&6; }
-       # Check whether --enable-pam_session was given.
-if test "${enable_pam_session+set}" = set; then :
-  enableval=$enable_pam_session;  case "$enableval" in
-               yes)    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-                       ;;
-               no)             { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-                           $as_echo "#define NO_PAM_SESSION 1" >>confdefs.h
-
-                           ;;
-               *)              { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-                           { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-pam-session: $enableval" >&5
-$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-pam-session: $enableval" >&2;}
-                           ;;
-           esac
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-fi
-
-    fi
-fi
-
-if test ${with_aixauth-'no'} != "no"; then
-    if test X"$with_aixauth" != X"maybe" -o X"$AUTH_EXCL" = X""; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: using AIX general authentication" >&5
-$as_echo "$as_me: using AIX general authentication" >&6;}
-       $as_echo "#define HAVE_AIXAUTH 1" >>confdefs.h
-
-       AUTH_OBJS="$AUTH_OBJS aix_auth.lo";
-       SUDOERS_LIBS="${SUDOERS_LIBS} -ls"
-       AUTH_EXCL=AIX_AUTH
-    fi
-fi
-
-if test ${with_bsdauth-'no'} != "no"; then
-    ac_fn_c_check_header_mongrel "$LINENO" "bsd_auth.h" "ac_cv_header_bsd_auth_h" "$ac_includes_default"
-if test "x$ac_cv_header_bsd_auth_h" = xyes; then :
-  $as_echo "#define HAVE_BSD_AUTH_H 1" >>confdefs.h
-
-       AUTH_OBJS="$AUTH_OBJS bsdauth.lo"
-       BSDAUTH_USAGE='[-a auth_type] '
-       AUTH_EXCL=BSD_AUTH; BAMAN=1
-else
-  as_fn_error $? "BSD authentication was specified but bsd_auth.h could not be found" "$LINENO" 5
-fi
-
-
-fi
-
-if test ${CHECKSIA-'false'} = "true"; then
-    for ac_func in sia_ses_init
-do :
-  ac_fn_c_check_func "$LINENO" "sia_ses_init" "ac_cv_func_sia_ses_init"
-if test "x$ac_cv_func_sia_ses_init" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_SIA_SES_INIT 1
-_ACEOF
- found=true
-else
-  found=false
-fi
-done
-
-    if test "$found" = "true"; then
-       AUTH_EXCL=SIA
-       AUTH_OBJS="$AUTH_OBJS sia.lo"
-    fi
-fi
-
-if test ${with_fwtk-'no'} != "no"; then
-    if test "$with_fwtk" != "yes"; then
-
-    if test X"$with_rpath" = X"yes"; then
-       case "$host" in
-           *-*-hpux*)  SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -L${with_fwtk} -Wl,+b,${with_fwtk}"
-                       ;;
-           *)          SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -L${with_fwtk} -Wl,-R${with_fwtk}"
-                       ;;
-       esac
-    else
-       SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -L${with_fwtk}"
-    fi
-    if test X"$blibpath" != X"" -a "SUDOERS_LDFLAGS" = "SUDO_LDFLAGS"; then
-       blibpath_add="${blibpath_add}:${with_fwtk}"
-    fi
-
-       CPPFLAGS="${CPPFLAGS} -I${with_fwtk}"
-       with_fwtk=yes
-    fi
-    SUDOERS_LIBS="${SUDOERS_LIBS} -lauth -lfwall"
-    AUTH_OBJS="$AUTH_OBJS fwtk.lo"
-fi
-
-if test ${with_SecurID-'no'} != "no"; then
-    if test "$with_SecurID" != "yes"; then
-       :
-    elif test -d /usr/ace/examples; then
-       with_SecurID=/usr/ace/examples
-    else
-       with_SecurID=/usr/ace
-    fi
-    CPPFLAGS="${CPPFLAGS} -I${with_SecurID}"
-    _LDFLAGS="${LDFLAGS}"
-
-    if test X"$with_rpath" = X"yes"; then
-       case "$host" in
-           *-*-hpux*)  LDFLAGS="${LDFLAGS} -L${with_SecurID} -Wl,+b,${with_SecurID}"
-                       ;;
-           *)          LDFLAGS="${LDFLAGS} -L${with_SecurID} -Wl,-R${with_SecurID}"
-                       ;;
-       esac
-    else
-       LDFLAGS="${LDFLAGS} -L${with_SecurID}"
-    fi
-    if test X"$blibpath" != X"" -a "LDFLAGS" = "SUDO_LDFLAGS"; then
-       blibpath_add="${blibpath_add}:${with_SecurID}"
-    fi
-
-    #
-    # Determine whether to use the new or old SecurID API
-    #
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SD_Init in -laceclnt" >&5
-$as_echo_n "checking for SD_Init in -laceclnt... " >&6; }
-if ${ac_cv_lib_aceclnt_SD_Init_______lpthread_______+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-laceclnt
-           -lpthread
-
-     $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* 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 SD_Init ();
-int
-main ()
-{
-return SD_Init ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_aceclnt_SD_Init_______lpthread_______=yes
-else
-  ac_cv_lib_aceclnt_SD_Init_______lpthread_______=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_aceclnt_SD_Init_______lpthread_______" >&5
-$as_echo "$ac_cv_lib_aceclnt_SD_Init_______lpthread_______" >&6; }
-if test "x$ac_cv_lib_aceclnt_SD_Init_______lpthread_______" = xyes; then :
-
-           AUTH_OBJS="$AUTH_OBJS securid5.lo";
-           SUDOERS_LIBS="${SUDOERS_LIBS} -laceclnt -lpthread"
-
-
-
-    if test X"$with_rpath" = X"yes"; then
-       case "$host" in
-           *-*-hpux*)  SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -L${with_SecurID} -Wl,+b,${with_SecurID}"
-                       ;;
-           *)          SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -L${with_SecurID} -Wl,-R${with_SecurID}"
-                       ;;
-       esac
-    else
-       SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -L${with_SecurID}"
-    fi
-    if test X"$blibpath" != X"" -a "SUDOERS_LDFLAGS" = "SUDO_LDFLAGS"; then
-       blibpath_add="${blibpath_add}:${with_SecurID}"
-    fi
-
-
-else
-
-           AUTH_OBJS="$AUTH_OBJS securid.lo";
-           SUDOERS_LIBS="${SUDOERS_LIBS} ${with_SecurID}/sdiclient.a"
-
-fi
-
-    LDFLAGS="${_LDFLAGS}"
-fi
-
-
-if test -z "${AUTH_EXCL}" -a -n "$AUTH_DEF"; then
-    for auth in $AUTH_DEF; do
-       case $auth in
-           passwd)     : ${with_passwd='maybe'};;
-       esac
-    done
-fi
-
-if test ${with_kerb4-'no'} != "no"; then
-    $as_echo "#define HAVE_KERB4 1" >>confdefs.h
-
-                O_LDFLAGS="$LDFLAGS"
-    if test "$with_kerb4" = "yes"; then
-       found=no
-       O_CPPFLAGS="$CPPFLAGS"
-       for dir in "" "kerberosIV/" "krb4/" "kerberos4/" "kerberosv4/"; do
-           CPPFLAGS="$O_CPPFLAGS -I/usr/include/${dir}"
-           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <krb.h>
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  found=yes; break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-       done
-       test X"$found" = X"no" && CPPFLAGS="$O_CPPFLAGS"
-    else
-
-    if test X"$with_rpath" = X"yes"; then
-       case "$host" in
-           *-*-hpux*)  LDFLAGS="${LDFLAGS} -L${with_kerb4}/lib -Wl,+b,${with_kerb4}/lib"
-                       ;;
-           *)          LDFLAGS="${LDFLAGS} -L${with_kerb4}/lib -Wl,-R${with_kerb4}/lib"
-                       ;;
-       esac
-    else
-       LDFLAGS="${LDFLAGS} -L${with_kerb4}/lib"
-    fi
-    if test X"$blibpath" != X"" -a "LDFLAGS" = "SUDO_LDFLAGS"; then
-       blibpath_add="${blibpath_add}:${with_kerb4}/lib"
-    fi
-
-
-    if test X"$with_rpath" = X"yes"; then
-       case "$host" in
-           *-*-hpux*)  SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -L${with_kerb4}/lib -Wl,+b,${with_kerb4}/lib"
-                       ;;
-           *)          SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -L${with_kerb4}/lib -Wl,-R${with_kerb4}/lib"
-                       ;;
-       esac
-    else
-       SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -L${with_kerb4}/lib"
-    fi
-    if test X"$blibpath" != X"" -a "SUDOERS_LDFLAGS" = "SUDO_LDFLAGS"; then
-       blibpath_add="${blibpath_add}:${with_kerb4}/lib"
-    fi
-
-       CPPFLAGS="$CPPFLAGS -I${with_kerb4}/include"
-       ac_fn_c_check_header_mongrel "$LINENO" "krb.h" "ac_cv_header_krb_h" "$ac_includes_default"
-if test "x$ac_cv_header_krb_h" = xyes; then :
-  found=yes
-else
-  found=no
-fi
-
-
-    fi
-    if test X"$found" = X"no"; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to locate Kerberos IV include files, you will have to edit the Makefile and add -I/path/to/krb/includes to CPPFLAGS" >&5
-$as_echo "$as_me: WARNING: Unable to locate Kerberos IV include files, you will have to edit the Makefile and add -I/path/to/krb/includes to CPPFLAGS" >&2;}
-    fi
-
-                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for des_cbc_encrypt in -ldes" >&5
-$as_echo_n "checking for des_cbc_encrypt in -ldes... " >&6; }
-if ${ac_cv_lib_des_des_cbc_encrypt+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldes  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* 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 des_cbc_encrypt ();
-int
-main ()
-{
-return des_cbc_encrypt ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_des_des_cbc_encrypt=yes
-else
-  ac_cv_lib_des_des_cbc_encrypt=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_des_des_cbc_encrypt" >&5
-$as_echo "$ac_cv_lib_des_des_cbc_encrypt" >&6; }
-if test "x$ac_cv_lib_des_des_cbc_encrypt" = xyes; then :
-  K4LIBS="-ldes"
-else
-
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for des_cbc_encrypt in -ldes425" >&5
-$as_echo_n "checking for des_cbc_encrypt in -ldes425... " >&6; }
-if ${ac_cv_lib_des425_des_cbc_encrypt+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldes425  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* 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 des_cbc_encrypt ();
-int
-main ()
-{
-return des_cbc_encrypt ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_des425_des_cbc_encrypt=yes
-else
-  ac_cv_lib_des425_des_cbc_encrypt=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_des425_des_cbc_encrypt" >&5
-$as_echo "$ac_cv_lib_des425_des_cbc_encrypt" >&6; }
-if test "x$ac_cv_lib_des425_des_cbc_encrypt" = xyes; then :
-  K4LIBS="-ldes425"
-else
-  K4LIBS=""
-fi
-
-
-fi
-
-                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using KTH Kerberos IV" >&5
-$as_echo_n "checking whether we are using KTH Kerberos IV... " >&6; }
-    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <krb.h>
-int
-main ()
-{
-const char *tmp = krb4_version;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-           { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-           K4LIBS="${K4LIBS} -lcom_err"
-           { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lroken" >&5
-$as_echo_n "checking for main in -lroken... " >&6; }
-if ${ac_cv_lib_roken_main+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lroken  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-
-int
-main ()
-{
-return main ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_roken_main=yes
-else
-  ac_cv_lib_roken_main=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_roken_main" >&5
-$as_echo "$ac_cv_lib_roken_main" >&6; }
-if test "x$ac_cv_lib_roken_main" = xyes; then :
-  K4LIBS="${K4LIBS} -lroken"
+
+    if test "$HAVE_SIGLIST" != "true"; then
+       case " $LIBOBJS " in
+  *" siglist.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS siglist.$ac_objext"
+ ;;
+esac
+
+    fi
+
 fi
+done
 
 
-else
+if test ${with_netsvc-"no"} != "no"; then
+    cat >>confdefs.h <<EOF
+#define _PATH_NETSVC_CONF "${with_netsvc-/etc/netsvc.conf}"
+EOF
 
-           { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+    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
+       case $auth in
+           AIX_AUTH)   with_aixauth=maybe;;
+           BSD_AUTH)   with_bsdauth=maybe;;
+           PAM)        with_pam=maybe;;
+           SIA)        CHECKSIA=true;;
+       esac
+    done
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-                as_ac_Lib=`$as_echo "ac_cv_lib_krb_main$K4LIBS" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lkrb" >&5
-$as_echo_n "checking for main in -lkrb... " >&6; }
+
+if test ${with_pam-"no"} != "no"; then
+    #
+    # Check for pam_start() in libpam first, then for pam_appl.h.
+    #
+    found_pam_lib=no
+    as_ac_Lib=`$as_echo "ac_cv_lib_pam_pam_start$lt_cv_dlopen_libs" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pam_start in -lpam" >&5
+$as_echo_n "checking for pam_start in -lpam... " >&6; }
 if eval \${$as_ac_Lib+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lkrb $K4LIBS $LIBS"
+LIBS="-lpam $lt_cv_dlopen_libs $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-
+/* 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 pam_start ();
 int
 main ()
 {
-return main ();
+return pam_start ();
   ;
   return 0;
 }
@@ -18379,56 +18125,205 @@ eval ac_res=\$$as_ac_Lib
               { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
 if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
-  K4LIBS="-lkrb $K4LIBS"
+  found_pam_lib=yes
+fi
+
+    #
+    # Some PAM implementations (MacOS X for example) put the PAM headers
+    # in /usr/include/pam instead of /usr/include/security...
+    #
+    found_pam_hdrs=no
+    for ac_header in security/pam_appl.h pam/pam_appl.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ found_pam_hdrs=yes; break
+fi
+
+done
+
+    if test "$found_pam_lib" = "yes" -a "$found_pam_hdrs" = "yes"; then
+       # Found both PAM libs and headers
+       with_pam=yes
+    elif test "$with_pam" = "yes"; then
+       if test "$found_pam_lib" = "no"; then
+           as_fn_error $? "\"--with-pam specified but unable to locate PAM development library.\"" "$LINENO" 5
+       fi
+       if test "$found_pam_hdrs" = "no"; then
+           as_fn_error $? "\"--with-pam specified but unable to locate PAM development headers.\"" "$LINENO" 5
+       fi
+    elif test "$found_pam_lib" != "$found_pam_hdrs"; then
+       if test "$found_pam_lib" = "no"; then
+           as_fn_error $? "\"found PAM headers but no PAM development library; specify --without-pam to build without PAM\"" "$LINENO" 5
+       fi
+       if test "$found_pam_hdrs" = "no"; then
+           as_fn_error $? "\"found PAM library but no PAM development headers; specify --without-pam to build without PAM\"" "$LINENO" 5
+       fi
+    fi
+
+    if test "$with_pam" = "yes"; then
+       # We already link with -ldl if needed (see LIBDL below)
+       SUDOERS_LIBS="${SUDOERS_LIBS} -lpam"
+       $as_echo "#define HAVE_PAM 1" >>confdefs.h
+
+       AUTH_OBJS="$AUTH_OBJS pam.lo";
+       AUTH_EXCL=PAM
+
+
+# Check whether --with-pam-login was given.
+if test "${with_pam_login+set}" = set; then :
+  withval=$with_pam_login; case $with_pam_login in
+           yes)        $as_echo "#define HAVE_PAM_LOGIN 1" >>confdefs.h
+
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use PAM login" >&5
+$as_echo_n "checking whether to use PAM login... " >&6; }
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+                       ;;
+           no)         ;;
+           *)          as_fn_error $? "\"--with-pam-login does not take an argument.\"" "$LINENO" 5
+                       ;;
+       esac
+fi
+
+
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use PAM session support" >&5
+$as_echo_n "checking whether to use PAM session support... " >&6; }
+       # Check whether --enable-pam_session was given.
+if test "${enable_pam_session+set}" = set; then :
+  enableval=$enable_pam_session;  case "$enableval" in
+               yes)    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+                       ;;
+               no)             { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+                           $as_echo "#define NO_PAM_SESSION 1" >>confdefs.h
+
+                           ;;
+               *)              { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+                           { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring unknown argument to --enable-pam-session: $enableval" >&5
+$as_echo "$as_me: WARNING: Ignoring unknown argument to --enable-pam-session: $enableval" >&2;}
+                           ;;
+           esac
 else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
 
-       as_ac_Lib=`$as_echo "ac_cv_lib_krb4_main$K4LIBS" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lkrb4" >&5
-$as_echo_n "checking for main in -lkrb4... " >&6; }
-if eval \${$as_ac_Lib+:} false; then :
-  $as_echo_n "(cached) " >&6
+    fi
+fi
+
+if test ${with_aixauth-'no'} != "no"; then
+    if test X"$with_aixauth" != X"maybe" -o X"$AUTH_EXCL" = X""; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: using AIX general authentication" >&5
+$as_echo "$as_me: using AIX general authentication" >&6;}
+       $as_echo "#define HAVE_AIXAUTH 1" >>confdefs.h
+
+       AUTH_OBJS="$AUTH_OBJS aix_auth.lo";
+       SUDOERS_LIBS="${SUDOERS_LIBS} -ls"
+       AUTH_EXCL=AIX_AUTH
+    fi
+fi
+
+if test ${with_bsdauth-'no'} != "no"; then
+    ac_fn_c_check_header_mongrel "$LINENO" "bsd_auth.h" "ac_cv_header_bsd_auth_h" "$ac_includes_default"
+if test "x$ac_cv_header_bsd_auth_h" = xyes; then :
+  $as_echo "#define HAVE_BSD_AUTH_H 1" >>confdefs.h
+
+       AUTH_OBJS="$AUTH_OBJS bsdauth.lo"
+       BSDAUTH_USAGE='[-a auth_type] '
+       AUTH_EXCL=BSD_AUTH; BAMAN=1
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lkrb4 $K4LIBS $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+  as_fn_error $? "BSD authentication was specified but bsd_auth.h could not be found" "$LINENO" 5
+fi
 
 
-int
-main ()
-{
-return main ();
-  ;
-  return 0;
-}
+fi
+
+if test ${CHECKSIA-'false'} = "true"; then
+    for ac_func in sia_ses_init
+do :
+  ac_fn_c_check_func "$LINENO" "sia_ses_init" "ac_cv_func_sia_ses_init"
+if test "x$ac_cv_func_sia_ses_init" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SIA_SES_INIT 1
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  eval "$as_ac_Lib=yes"
+ found=true
 else
-  eval "$as_ac_Lib=no"
+  found=false
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+done
+
+    if test "$found" = "true"; then
+       AUTH_EXCL=SIA
+       AUTH_OBJS="$AUTH_OBJS sia.lo"
+    fi
 fi
-eval ac_res=\$$as_ac_Lib
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
-  K4LIBS="-lkrb4 $K4LIBS"
-else
-  K4LIBS="-lkrb $K4LIBS"
-           { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to locate Kerberos IV libraries, you will have to edit the Makefile and add -L/path/to/krb/libs to SUDOERS_LDFLAGS and possibly add Kerberos libs to SUDOERS_LIBS" >&5
-$as_echo "$as_me: WARNING: Unable to locate Kerberos IV libraries, you will have to edit the Makefile and add -L/path/to/krb/libs to SUDOERS_LDFLAGS and possibly add Kerberos libs to SUDOERS_LIBS" >&2;}
 
+if test ${with_fwtk-'no'} != "no"; then
+    if test "$with_fwtk" != "yes"; then
+
+    if test X"$with_rpath" = X"yes"; then
+       case "$host" in
+           *-*-hpux*)  SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -L${with_fwtk} -Wl,+b,${with_fwtk}"
+                       ;;
+           *)          SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -L${with_fwtk} -Wl,-R${with_fwtk}"
+                       ;;
+       esac
+    else
+       SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -L${with_fwtk}"
+    fi
+    if test X"$blibpath" != X"" -a "SUDOERS_LDFLAGS" = "SUDO_LDFLAGS"; then
+       blibpath_add="${blibpath_add}:${with_fwtk}"
+    fi
+
+       CPPFLAGS="${CPPFLAGS} -I${with_fwtk}"
+       with_fwtk=yes
+    fi
+    SUDOERS_LIBS="${SUDOERS_LIBS} -lauth -lfwall"
+    AUTH_OBJS="$AUTH_OBJS fwtk.lo"
 fi
 
+if test ${with_SecurID-'no'} != "no"; then
+    if test "$with_SecurID" != "yes"; then
+       :
+    elif test -d /usr/ace/examples; then
+       with_SecurID=/usr/ace/examples
+    else
+       with_SecurID=/usr/ace
+    fi
+    CPPFLAGS="${CPPFLAGS} -I${with_SecurID}"
+
+    if test X"$with_rpath" = X"yes"; then
+       case "$host" in
+           *-*-hpux*)  LDFLAGS="${LDFLAGS} -L${with_SecurID} -Wl,+b,${with_SecurID}"
+                       ;;
+           *)          LDFLAGS="${LDFLAGS} -L${with_SecurID} -Wl,-R${with_SecurID}"
+                       ;;
+       esac
+    else
+       LDFLAGS="${LDFLAGS} -L${with_SecurID}"
+    fi
+    if test X"$blibpath" != X"" -a "LDFLAGS" = "SUDO_LDFLAGS"; then
+       blibpath_add="${blibpath_add}:${with_SecurID}"
+    fi
 
+    SUDOERS_LIBS="${SUDOERS_LIBS} -laceclnt -lpthread"
+    AUTH_OBJS="$AUTH_OBJS securid5.lo";
 fi
 
-    LDFLAGS="$O_LDFLAGS"
-    SUDOERS_LIBS="${SUDOERS_LIBS} $K4LIBS"
-    AUTH_OBJS="$AUTH_OBJS kerb4.lo"
+
+if test -z "${AUTH_EXCL}" -a -n "$AUTH_DEF"; then
+    for auth in $AUTH_DEF; do
+       case $auth in
+           passwd)     : ${with_passwd='maybe'};;
+       esac
+    done
 fi
 
 if test ${with_kerb5-'no'} != "no"; then
@@ -18713,6 +18608,29 @@ done
 
     fi
     LIBS="$_LIBS"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use an instance name for Kerberos V" >&5
+$as_echo_n "checking whether to use an instance name for Kerberos V... " >&6; }
+    # Check whether --enable-kerb5-instance was given.
+if test "${enable_kerb5_instance+set}" = set; then :
+  enableval=$enable_kerb5_instance;  case "$enableval" in
+           yes)        as_fn_error $? "\"must give --enable-kerb5-instance an argument.\"" "$LINENO" 5
+                       ;;
+           no)         { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+                       ;;
+           *)          cat >>confdefs.h <<EOF
+#define SUDO_KRB5_INSTANCE "$enableval"
+EOF
+
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
+$as_echo "$enableval" >&6; }
+                       ;;
+       esac
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
 fi
 
 if test ${with_AFS-'no'} = "yes"; then
@@ -20057,20 +19975,35 @@ if test X"$with_noexec" != X"no" -o X"$with_selinux" != X"no"; then
        PROGS="${PROGS} libsudo_noexec.la"
        INSTALL_NOEXEC="install-noexec"
 
-       eval noexec_file="$with_noexec"
+       noexec_file="$with_noexec"
+       _noexec_file=
+       while test X"$noexec_file" != X"$_noexec_file"; do
+           _noexec_file="$noexec_file"
+           eval noexec_file="$_noexec_file"
+       done
        cat >>confdefs.h <<EOF
 #define _PATH_SUDO_NOEXEC "$noexec_file"
 EOF
 
     fi
     if test X"$with_selinux" != X"no"; then
-       eval sesh_file="$libexecdir/sesh"
+       sesh_file="$libexecdir/sesh"
+       _sesh_file=
+       while test X"$sesh_file" != X"$_sesh_file"; do
+           _sesh_file="$sesh_file"
+           eval sesh_file="$_sesh_file"
+       done
        cat >>confdefs.h <<EOF
 #define _PATH_SUDO_SESH "$sesh_file"
 EOF
 
     fi
-    eval PLUGINDIR="$with_plugindir"
+    PLUGINDIR="$with_plugindir"
+    _PLUGINDIR=
+    while test X"$PLUGINDIR" != X"$_PLUGINDIR"; do
+       _PLUGINDIR="$PLUGINDIR"
+       eval PLUGINDIR="$_PLUGINDIR"
+    done
     cat >>confdefs.h <<EOF
 #define _PATH_SUDO_PLUGIN_DIR "$PLUGINDIR/"
 EOF
@@ -20615,7 +20548,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=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.8.3p2, which was
+This file was extended by sudo $as_me 1.8.4p4, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -20681,7 +20614,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-sudo config.status 1.8.3p2
+sudo config.status 1.8.4p4
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
@@ -20815,6 +20748,7 @@ pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
 enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
 SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
 ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
 host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
 host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
 host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
@@ -20897,7 +20831,6 @@ with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
 allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
 no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
 hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
-hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`'
 hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
 hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
 hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
@@ -20953,6 +20886,7 @@ _LTECHO_EOF'
 # Quote evaled strings.
 for var in SHELL \
 ECHO \
+PATH_SEPARATOR \
 SED \
 GREP \
 EGREP \
@@ -21003,7 +20937,6 @@ with_gnu_ld \
 allow_undefined_flag \
 no_undefined_flag \
 hardcode_libdir_flag_spec \
-hardcode_libdir_flag_spec_ld \
 hardcode_libdir_separator \
 exclude_expsyms \
 include_expsyms \
@@ -21671,8 +21604,8 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
 #
 #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
-#                 Inc.
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
 #   Written by Gordon Matzigkeit, 1996
 #
 #   This file is part of GNU Libtool.
@@ -21726,6 +21659,9 @@ SHELL=$lt_SHELL
 # An echo program that protects backslashes.
 ECHO=$lt_ECHO
 
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
 # The host system.
 host_alias=$host_alias
 host=$host
@@ -22027,10 +21963,6 @@ no_undefined_flag=$lt_no_undefined_flag
 # This must work even if \$libdir does not exist
 hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
 
-# If ld is used when linking, flag to hardcode \$libdir into a binary
-# during linking.  This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
-
 # Whether we need a single "-rpath" flag with a separated argument.
 hardcode_libdir_separator=$lt_hardcode_libdir_separator
 
 
 if test "$with_pam" = "yes"; then
     case $host in
+       *-*-hpux*)
+           if test -f /usr/lib/security/libpam_hpsec.so.1; then
+               { $as_echo "$as_me:${as_lineno-$LINENO}: You may wish to add the following line to /etc/pam.conf" >&5
+$as_echo "$as_me: You may wish to add the following line to /etc/pam.conf" >&6;}
+               { $as_echo "$as_me:${as_lineno-$LINENO}: sudo session required libpam_hpsec.so.1 bypass_umask bypass_last_login" >&5
+$as_echo "$as_me: sudo session required libpam_hpsec.so.1 bypass_umask bypass_last_login" >&6;}
+           fi
+           ;;
        *-*-linux*)
            { $as_echo "$as_me:${as_lineno-$LINENO}: You will need to customize sample.pam and install it as /etc/pam.d/sudo" >&5
 $as_echo "$as_me: You will need to customize sample.pam and install it as /etc/pam.d/sudo" >&6;}
@@ -22418,6 +22358,5 @@ fi
 
 
 
-
 
 
index 546ef9d59c7698b8951a81c021b7eaee3e0f6133..bdbc123245c2e7d1f4bb1dd13c837f6943e9b58c 100644 (file)
@@ -1,9 +1,9 @@
 dnl
 dnl Process this file with GNU autoconf to produce a configure script.
 dnl
-dnl Copyright (c) 1994-1996,1998-2011 Todd C. Miller <Todd.Miller@courtesan.com>
+dnl Copyright (c) 1994-1996,1998-2012 Todd C. Miller <Todd.Miller@courtesan.com>
 dnl
-AC_INIT([sudo], [1.8.3p2], [http://www.sudo.ws/bugs/], [sudo])
+AC_INIT([sudo], [1.8.4p4], [http://www.sudo.ws/bugs/], [sudo])
 AC_CONFIG_HEADER([config.h pathnames.h])
 dnl
 dnl Note: this must come after AC_INIT
@@ -38,7 +38,7 @@ AC_SUBST([MAN_POSTINSTALL])
 AC_SUBST([SUDOERS_MODE])
 AC_SUBST([SUDOERS_UID])
 AC_SUBST([SUDOERS_GID])
-AC_SUBST([DEV])
+AC_SUBST([DEVEL])
 AC_SUBST([BAMAN])
 AC_SUBST([LCMAN])
 AC_SUBST([SEMAN])
@@ -66,6 +66,7 @@ AC_SUBST([LIBDL])
 AC_SUBST([LT_STATIC])
 AC_SUBST([LIBINTL])
 AC_SUBST([SUDO_NLS])
+AC_SUBST([COMPAT_TEST_PROGS])
 dnl
 dnl Variables that get substituted in docs (not overridden by environment)
 dnl
@@ -158,7 +159,7 @@ PROGS="sudo"
 : ${SUDOERS_MODE='0440'}
 : ${SUDOERS_UID='0'}
 : ${SUDOERS_GID='0'}
-DEV="#"
+DEVEL=
 LDAP="#"
 BAMAN=0
 LCMAN=0
@@ -214,7 +215,7 @@ 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])
                OSDEFS="${OSDEFS} -DSUDO_DEVEL"
-               DEV=""
+               DEVEL="true"
                devdir=.
                ;;
     no)                ;;
@@ -402,15 +403,6 @@ AC_ARG_WITH(fwtk, [AS_HELP_STRING([--with-fwtk[[=DIR]]], [enable FWTK AuthSRV su
                ;;
 esac])
 
-AC_ARG_WITH(kerb4, [AS_HELP_STRING([--with-kerb4[[=DIR]]], [enable Kerberos IV support])],
-[case $with_kerb4 in
-    no)                ;;
-    *)         AC_MSG_CHECKING(whether to try kerberos IV authentication)
-               AC_MSG_RESULT(yes)
-               AUTH_REG="$AUTH_REG kerb4"
-               ;;
-esac])
-
 AC_ARG_WITH(kerb5, [AS_HELP_STRING([--with-kerb5[[=DIR]]], [enable Kerberos V support])],
 [case $with_kerb5 in
     no)                ;;
@@ -1281,10 +1273,10 @@ AC_ARG_ENABLE(env_reset,
 ])
 if test "$env_reset" = "on"; then
     AC_MSG_RESULT(yes)
-    AC_DEFINE(ENV_RESET, TRUE)
+    AC_DEFINE(ENV_RESET, 1)
 else
     AC_MSG_RESULT(no)
-    AC_DEFINE(ENV_RESET, FALSE)
+    AC_DEFINE(ENV_RESET, 0)
 fi
 
 AC_ARG_ENABLE(warnings,
@@ -1385,6 +1377,7 @@ if test "$enable_shared" = "no"; then
     enable_dlopen=no
     lt_cv_dlopen=none
     lt_cv_dlopen_libs=
+    ac_cv_func_dlopen=no
 else
     eval _shrext="$shrext_cmds"
     # Darwin uses .dylib for libraries but .so for modules
@@ -1920,6 +1913,15 @@ dnl
 AC_PROG_GCC_TRADITIONAL
 AC_C_CONST
 AC_C_VOLATILE
+# Check for variadic macro support in cpp
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
+AC_INCLUDES_DEFAULT
+#if defined(__GNUC__) && __GNUC__ == 2
+# define sudo_fprintf(fp, fmt...) fprintf((fp), (fmt))
+#else
+# define sudo_fprintf(fp, ...) fprintf((fp), __VA_ARGS__)
+#endif
+], [sudo_fprintf(stderr, "a %s", "test");])], [], [AC_MSG_ERROR([Your C compiler doesn't support variadic macros, try building with gcc instead])])
 if test X"$with_gnu_ld" != "yes" -a -n "$GCC"; then
     _CFLAGS="$CFLAGS"
     CFLAGS="$CFLAGS -static-libgcc"
@@ -1963,6 +1965,7 @@ dnl
 AC_HEADER_STDC
 AC_HEADER_DIRENT
 AC_HEADER_TIME
+AC_HEADER_STDBOOL
 AC_CHECK_HEADERS(malloc.h paths.h utime.h netgroup.h utmpx.h sys/sockio.h sys/bsdtypes.h sys/select.h sys/stropts.h sys/sysmacros.h)
 dnl
 dnl Check for large file support.  HP-UX 11.23 has a broken sys/type.h
@@ -2016,21 +2019,24 @@ AC_TYPE_UID_T
 AC_CHECK_TYPE([__signed char], [], [AC_CHECK_TYPE([signed char], [AC_DEFINE(__signed, signed)], [AC_DEFINE(__signed, [])])])
 AC_CHECK_TYPE([sig_atomic_t], [], [AC_DEFINE(sig_atomic_t, int)], [#include <sys/types.h>
 #include <signal.h>])
-AC_CHECK_TYPES([sigaction_t], [AC_DEFINE(HAVE_SIGACTION_T)], [], [#include <sys/types.h>
+AC_CHECK_TYPES([sigaction_t], [], [], [#include <sys/types.h>
 #include <signal.h>])
-AC_CHECK_TYPE([struct timespec], [AC_DEFINE(HAVE_TIMESPEC)], [], [#include <sys/types.h>
+AC_CHECK_TYPES([struct timespec], [], [], [#include <sys/types.h>
 #if TIME_WITH_SYS_TIME
 # include <sys/time.h>
 #endif
 #include <time.h>])
-AC_CHECK_TYPES([struct in6_addr], [AC_DEFINE(HAVE_IN6_ADDR)], [], [#include <sys/types.h>
+AC_CHECK_TYPES([struct in6_addr], [], [], [#include <sys/types.h>
 #include <netinet/in.h>])
 AC_TYPE_LONG_LONG_INT
 AC_CHECK_SIZEOF([long int])
-SUDO_TYPE_SIZE_T
-SUDO_TYPE_SSIZE_T
-SUDO_TYPE_DEV_T
-SUDO_TYPE_INO_T
+AC_CHECK_TYPE(size_t, unsigned int)
+AC_CHECK_TYPE(ssize_t, int)
+AC_CHECK_TYPE(dev_t, int)
+AC_CHECK_TYPE(ino_t, unsigned int)
+AC_CHECK_TYPE(socklen_t, [], [AC_DEFINE(socklen_t, unsigned int)], [
+AC_INCLUDES_DEFAULT
+#include <sys/socket.h>])
 SUDO_UID_T_LEN
 SUDO_SOCK_SA_LEN
 dnl
@@ -2082,19 +2088,54 @@ dnl Function checks
 dnl
 AC_FUNC_GETGROUPS
 AC_CHECK_FUNCS(strrchr sysconf tzset strftime \
-              regcomp setlocale nl_langinfo getaddrinfo mbr_check_membership \
-              setrlimit64 sysctl)
+              regcomp setlocale nl_langinfo mbr_check_membership \
+              setrlimit64)
 AC_REPLACE_FUNCS(getgrouplist)
 AC_CHECK_FUNCS(getline, [], [
     AC_LIBOBJ(getline)
     AC_CHECK_FUNCS(fgetln)
 ])
+dnl
+dnl If libc supports _FORTIFY_SOURCE check functions, use it.
+dnl
+O_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2"
+AC_CHECK_FUNC(__sprintf_chk, [
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[char buf[4]; (void)sprintf(buf, "%s", "foo");]])], [OSDEFS="${OSDEFS} -D_FORTIFY_SOURCE=2"], [])
+], [])
+CPPFLAGS="$O_CPPFLAGS"
+
 utmp_style=LEGACY
 AC_CHECK_FUNCS(getutxid getutid, [utmp_style=POSIX; break])
 if test "$utmp_style" = "LEGACY"; then
     AC_CHECK_FUNCS(getttyent ttyslot, [break])
 fi
 
+AC_CHECK_FUNCS(sysctl, [AC_CHECK_MEMBERS([struct kinfo_proc.ki_tdev], [],
+    [
+       AC_CHECK_MEMBERS([struct kinfo_proc2.p_tdev], [], [
+           AC_CHECK_MEMBERS([struct kinfo_proc.p_tdev], [], [
+               AC_CHECK_MEMBERS([struct kinfo_proc.kp_eproc.e_tdev], [], [], [
+                   #include <sys/param.h>
+                   #include <sys/sysctl.h>
+               ])
+           ], [
+               #include <sys/param.h>
+               #include <sys/sysctl.h>
+           ])
+       ],
+       [
+           #include <sys/param.h>
+           #include <sys/sysctl.h>
+       ])
+    ],
+    [
+       #include <sys/param.h>
+       #include <sys/sysctl.h>
+       #include <sys/user.h>
+    ])
+])
+
 AC_CHECK_FUNCS(openpty, [AC_CHECK_HEADERS(libutil.h util.h pty.h, [break])], [
     AC_CHECK_LIB(util, openpty, [
        AC_CHECK_HEADERS(libutil.h util.h pty.h, [break])
@@ -2135,14 +2176,19 @@ fi
 AC_CHECK_FUNCS(glob, [AC_MSG_CHECKING(for GLOB_BRACE and GLOB_TILDE in glob.h)
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <glob.h>]], [[int i = GLOB_BRACE | GLOB_TILDE; (void)i;]])], [AC_DEFINE(HAVE_EXTENDED_GLOB)
     AC_MSG_RESULT(yes)], [AC_LIBOBJ(glob)
-    AC_MSG_RESULT(no)])], [AC_LIBOBJ(glob)])
+    COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }globtest"
+    AC_MSG_RESULT(no)])], [AC_LIBOBJ(glob)]
+    COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }globtest"
+    )
 AC_CHECK_FUNCS(lockf flock, [break])
 AC_CHECK_FUNCS(innetgr _innetgr, [AC_CHECK_FUNCS(getdomainname) [break]])
 AC_CHECK_FUNCS(utimes, [AC_CHECK_FUNCS(futimes futimesat, [break])], [AC_CHECK_FUNCS(futime) AC_LIBOBJ(utimes)])
 AC_CHECK_FUNCS(killpg, [], [AC_LIBOBJ(killpg)])
-SUDO_FUNC_FNMATCH([AC_DEFINE(HAVE_FNMATCH)], [AC_LIBOBJ(fnmatch)])
+SUDO_FUNC_FNMATCH([AC_DEFINE(HAVE_FNMATCH)], [AC_LIBOBJ(fnmatch)
+    COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }fnm_test"
+])
 SUDO_FUNC_ISBLANK
-AC_REPLACE_FUNCS(memrchr strlcpy strlcat setenv)
+AC_REPLACE_FUNCS(memrchr pw_dup strlcpy strlcat setenv)
 AC_CHECK_FUNCS(nanosleep, [], [
     # On Solaris, nanosleep is in librt
     AC_CHECK_LIB(rt, nanosleep, [REPLAY_LIBS="${REPLAY_LIBS} -lrt"], [AC_LIBOBJ(nanosleep)])
@@ -2178,20 +2224,88 @@ fi
 dnl
 dnl If socket(2) not in libc, check -lsocket and -linet
 dnl May need to link with *both* -lnsl and -lsocket due to unresolved symbols
-dnl In this case we look for main(), not socket() to avoid using a cached value
 dnl
-AC_CHECK_FUNC(socket, , [AC_CHECK_LIB(socket, socket, [NET_LIBS="${NET_LIBS} -lsocket"; LIBS="${LIBS} -lsocket"], AC_CHECK_LIB(inet, socket, [NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet"], AC_MSG_WARN(unable to find socket() trying -lsocket -lnsl)
-AC_CHECK_LIB(socket, socket, [NET_LIBS="${NET_LIBS} -lsocket -lnsl"; LIBS="${LIBS} -lsocket -lnsl"], , -lnsl)))])
+AC_CHECK_FUNC(socket, [], [
+    for libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+       _libs=
+       for lib in $libs; do
+           case "$NET_LIBS" in
+               *"$lib"*)   ;;
+               *)          _libs="$_libs $lib";;
+           esac
+       done
+       libs="${_libs# }"
+       test -z "$libs" && continue
+       lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+       extralibs="`echo \"$libs\"|sed 's/^-l[[^ ]]*//'`"
+       SUDO_CHECK_LIB($lib, socket, [NET_LIBS="${NET_LIBS} $libs"; LIBS="${LIBS} $libs"; break], [], [$extralibs])
+    done
+])
 dnl
 dnl If inet_addr(3) not in libc, check -lnsl and -linet
 dnl May need to link with *both* -lnsl and -lsocket due to unresolved symbols
 dnl
-AC_CHECK_FUNC(inet_addr, , [AC_CHECK_FUNC(__inet_addr, , AC_CHECK_LIB(nsl, inet_addr, [NET_LIBS="${NET_LIBS} -lnsl"; LIBS="${LIBS} -lnsl"], AC_CHECK_LIB(inet, inet_addr, [NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet"], AC_MSG_WARN(unable to find inet_addr() trying -lsocket -lnsl)
-AC_CHECK_LIB(socket, inet_addr, [NET_LIBS="${NET_LIBS} -lsocket -lnsl"; LIBS="${LIBS} -lsocket -lnsl"], , -lnsl))))])
+AC_CHECK_FUNC(inet_addr, [], [
+    AC_CHECK_FUNC(__inet_addr, [], [
+       for libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+           _libs=
+           for lib in $libs; do
+               case "$NET_LIBS" in
+                   *"$lib"*)   ;;
+                   *)          _libs="$_libs $lib";;
+               esac
+           done
+           libs="${_libs# }"
+           test -z "$libs" && continue
+           lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+           extralibs="`echo \"$libs\"|sed 's/^-l[[^ ]]*//'`"
+           SUDO_CHECK_LIB($lib, inet_addr, [NET_LIBS="${NET_LIBS} $libs"; LIBS="${LIBS} $libs"; break], [], [$extralibs])
+       done
+    ])
+])
 dnl
 dnl If syslog(3) not in libc, check -lsocket, -lnsl and -linet
 dnl
-AC_CHECK_FUNC(syslog, , [AC_CHECK_LIB(socket, syslog, [NET_LIBS="${NET_LIBS} -lsocket"; LIBS="${LIBS} -lsocket"], AC_CHECK_LIB(nsl, syslog, [NET_LIBS="${NET_LIBS} -lnsl"; LIBS="${LIBS} -lnsl"], AC_CHECK_LIB(inet, syslog, [NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet"])))])
+AC_CHECK_FUNC(syslog, [], [
+    for libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+       _libs=
+       for lib in $libs; do
+           case "$NET_LIBS" in
+               *"$lib"*)   ;;
+               *)          _libs="$_libs $lib";;
+           esac
+       done
+       libs="${_libs# }"
+       test -z "$libs" && continue
+       lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+       extralibs="`echo \"$libs\"|sed 's/^-l[[^ ]]*//'`"
+       SUDO_CHECK_LIB($lib, syslog, [NET_LIBS="${NET_LIBS} $libs"; LIBS="${LIBS} $libs"; break], [], [$extralibs])
+    done
+])
+dnl
+dnl If getaddrinfo(3) not in libc, check -lsocket and -linet
+dnl May need to link with *both* -lnsl and -lsocket due to unresolved symbols.
+dnl
+AC_CHECK_FUNCS(getaddrinfo, [], [
+    found=no
+    for libs in "-lsocket" "-linet" "-lsocket -lnsl"; do
+       _libs=
+       for lib in $libs; do
+           case "$NET_LIBS" in
+               *"$lib"*)   ;;
+               *)          _libs="$_libs $lib";;
+           esac
+       done
+       libs="${_libs# }"
+       test -z "$libs" && continue
+       lib="`echo \"$libs\"|sed -e 's/^-l//' -e 's/ .*$//'`"
+       extralibs="`echo \"$libs\"|sed 's/^-l[[^ ]]*//'`"
+       SUDO_CHECK_LIB($lib, getaddrinfo, [NET_LIBS="${NET_LIBS} $libs"; LIBS="${LIBS} $libs"; found=yes; break], [], [$extralibs])
+    done
+    if test X"$found" != X"no"; then
+       AC_DEFINE(HAVE_GETADDRINFO)
+    fi
+])
 dnl
 dnl Check for getprogname() or __progname
 dnl
@@ -2206,6 +2320,25 @@ AC_CHECK_FUNCS(getprogname, , [
     fi
     AC_MSG_RESULT($sudo_cv___progname)
 ])
+dnl
+dnl Check for __func__ or __FUNCTION__
+dnl
+AC_MSG_CHECKING([for __func__])
+AC_CACHE_VAL(sudo_cv___func__, [
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[(void)puts(__func__);]])], [sudo_cv___func__=yes], [sudo_cv___func__=no])])
+AC_MSG_RESULT($sudo_cv___func__)
+if test "$sudo_cv___func__" = "yes"; then
+    AC_DEFINE(HAVE___FUNC__)
+elif test -n "$GCC"; then
+    AC_MSG_CHECKING([for __FUNCTION__])
+    AC_CACHE_VAL(sudo_cv___FUNCTION__, [
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[(void)puts(__FUNCTION__);]])], [sudo_cv___FUNCTION__=yes], [sudo_cv___FUNCTION__=no])])
+    AC_MSG_RESULT($sudo_cv___FUNCTION__)
+    if test "$sudo_cv___FUNCTION__" = "yes"; then
+       AC_DEFINE(HAVE___FUNC__)
+       AC_DEFINE(__func__, __FUNCTION__, [Define to __FUNCTION__ if your compiler support __FUNCTION__ but not __func__])
+    fi
+fi
 
 # gettext() and friends may be located in libc (Linux and Solaris)
 # or in libintl.  However, it is possible to have libintl installed
@@ -2302,6 +2435,14 @@ AC_INCLUDES_DEFAULT
 #include <errno.h>
 ])
 
+dnl
+dnl Check for h_errno declaration in netdb.h
+dnl
+AC_CHECK_DECLS([h_errno], [], [], [
+AC_INCLUDES_DEFAULT
+#include <netdb.h>
+])
+
 dnl
 dnl Check for strsignal() or sys_siglist
 dnl
@@ -2356,15 +2497,39 @@ dnl PAM support.  Systems that use PAM by default set with_pam=default
 dnl and we do the actual tests here.
 dnl
 if test ${with_pam-"no"} != "no"; then
-    # We already link with -ldl (see LIBDL below) so no need for that here.
-    SUDOERS_LIBS="${SUDOERS_LIBS} -lpam"
+    #
+    # Check for pam_start() in libpam first, then for pam_appl.h.
+    #
+    found_pam_lib=no
+    AC_CHECK_LIB(pam, pam_start, [found_pam_lib=yes], [], [$lt_cv_dlopen_libs])
+    #
+    # Some PAM implementations (MacOS X for example) put the PAM headers
+    # in /usr/include/pam instead of /usr/include/security...
+    #
+    found_pam_hdrs=no
+    AC_CHECK_HEADERS([security/pam_appl.h] [pam/pam_appl.h], [found_pam_hdrs=yes; break])
+    if test "$found_pam_lib" = "yes" -a "$found_pam_hdrs" = "yes"; then
+       # Found both PAM libs and headers
+       with_pam=yes
+    elif test "$with_pam" = "yes"; then
+       if test "$found_pam_lib" = "no"; then
+           AC_MSG_ERROR(["--with-pam specified but unable to locate PAM development library."])
+       fi
+       if test "$found_pam_hdrs" = "no"; then
+           AC_MSG_ERROR(["--with-pam specified but unable to locate PAM development headers."])
+       fi
+    elif test "$found_pam_lib" != "$found_pam_hdrs"; then
+       if test "$found_pam_lib" = "no"; then
+           AC_MSG_ERROR(["found PAM headers but no PAM development library; specify --without-pam to build without PAM"])
+       fi
+       if test "$found_pam_hdrs" = "no"; then
+           AC_MSG_ERROR(["found PAM library but no PAM development headers; specify --without-pam to build without PAM"])
+       fi
+    fi
 
-    dnl
-    dnl Some PAM implementations (MacOS X for example) put the PAM headers
-    dnl in /usr/include/pam instead of /usr/include/security...
-    dnl
-    AC_CHECK_HEADERS([security/pam_appl.h] [pam/pam_appl.h], [with_pam=yes; break])
     if test "$with_pam" = "yes"; then
+       # We already link with -ldl if needed (see LIBDL below)
+       SUDOERS_LIBS="${SUDOERS_LIBS} -lpam"
        AC_DEFINE(HAVE_PAM)
        AUTH_OBJS="$AUTH_OBJS pam.lo";
        AUTH_EXCL=PAM
@@ -2458,27 +2623,9 @@ if test ${with_SecurID-'no'} != "no"; then
        with_SecurID=/usr/ace
     fi
     CPPFLAGS="${CPPFLAGS} -I${with_SecurID}"
-    _LDFLAGS="${LDFLAGS}"
     SUDO_APPEND_LIBPATH(LDFLAGS, [${with_SecurID}])
-    #
-    # Determine whether to use the new or old SecurID API
-    #
-    AC_CHECK_LIB(aceclnt, SD_Init,
-       [
-           AUTH_OBJS="$AUTH_OBJS securid5.lo";
-           SUDOERS_LIBS="${SUDOERS_LIBS} -laceclnt -lpthread"
-       ]
-       [
-           SUDO_APPEND_LIBPATH(SUDOERS_LDFLAGS, [${with_SecurID}])
-       ], [
-           AUTH_OBJS="$AUTH_OBJS securid.lo";
-           SUDOERS_LIBS="${SUDOERS_LIBS} ${with_SecurID}/sdiclient.a"
-       ],
-       [
-           -lpthread
-       ]
-    )
-    LDFLAGS="${_LDFLAGS}"
+    SUDOERS_LIBS="${SUDOERS_LIBS} -laceclnt -lpthread"
+    AUTH_OBJS="$AUTH_OBJS securid5.lo";
 fi
 
 dnl
@@ -2498,65 +2645,6 @@ if test -z "${AUTH_EXCL}" -a -n "$AUTH_DEF"; then
     done
 fi
 
-dnl
-dnl Kerberos IV
-dnl
-if test ${with_kerb4-'no'} != "no"; then
-    AC_DEFINE(HAVE_KERB4)
-    dnl
-    dnl Use the specified directory, if any, else search for correct inc dir
-    dnl
-    O_LDFLAGS="$LDFLAGS"
-    if test "$with_kerb4" = "yes"; then
-       found=no
-       O_CPPFLAGS="$CPPFLAGS"
-       for dir in "" "kerberosIV/" "krb4/" "kerberos4/" "kerberosv4/"; do
-           CPPFLAGS="$O_CPPFLAGS -I/usr/include/${dir}"
-           AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#include <krb.h>]])], [found=yes; break])
-       done
-       test X"$found" = X"no" && CPPFLAGS="$O_CPPFLAGS"
-    else
-       SUDO_APPEND_LIBPATH(LDFLAGS, [${with_kerb4}/lib])
-       SUDO_APPEND_LIBPATH(SUDOERS_LDFLAGS, [${with_kerb4}/lib])
-       CPPFLAGS="$CPPFLAGS -I${with_kerb4}/include"
-       AC_CHECK_HEADER([krb.h], [found=yes], [found=no])
-    fi
-    if test X"$found" = X"no"; then
-       AC_MSG_WARN([Unable to locate Kerberos IV include files, you will have to edit the Makefile and add -I/path/to/krb/includes to CPPFLAGS])
-    fi
-
-    dnl
-    dnl Check for -ldes vs. -ldes425
-    dnl
-    AC_CHECK_LIB(des, des_cbc_encrypt, [K4LIBS="-ldes"], [
-       AC_CHECK_LIB(des425, des_cbc_encrypt, [K4LIBS="-ldes425"], [K4LIBS=""])
-    ])
-    dnl
-    dnl Try to determine whether we have KTH or MIT/CNS Kerberos IV
-    dnl
-    AC_MSG_CHECKING(whether we are using KTH Kerberos IV)
-    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <krb.h>]], [[const char *tmp = krb4_version;]])], [
-           AC_MSG_RESULT(yes)
-           K4LIBS="${K4LIBS} -lcom_err"
-           AC_CHECK_LIB(roken, main, [K4LIBS="${K4LIBS} -lroken"])
-       ], [
-           AC_MSG_RESULT(no)
-       ]
-    )
-    dnl
-    dnl The actual Kerberos IV lib might be -lkrb or -lkrb4
-    dnl
-    AC_CHECK_LIB(krb, main, [K4LIBS="-lkrb $K4LIBS"], [
-       AC_CHECK_LIB(krb4, main, [K4LIBS="-lkrb4 $K4LIBS"],
-           [K4LIBS="-lkrb $K4LIBS"]
-           [AC_MSG_WARN([Unable to locate Kerberos IV libraries, you will have to edit the Makefile and add -L/path/to/krb/libs to SUDOERS_LDFLAGS and possibly add Kerberos libs to SUDOERS_LIBS])]
-       , [$K4LIBS])
-    ], [$K4LIBS])
-    LDFLAGS="$O_LDFLAGS"
-    SUDOERS_LIBS="${SUDOERS_LIBS} $K4LIBS"
-    AUTH_OBJS="$AUTH_OBJS kerb4.lo"
-fi
-
 dnl
 dnl Kerberos V
 dnl There is an easy way and a hard way...
@@ -2639,6 +2727,18 @@ if test ${with_kerb5-'no'} != "no"; then
        AC_DEFINE(HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_TWO_ARGS)
     fi
     LIBS="$_LIBS"
+    AC_MSG_CHECKING(whether to use an instance name for Kerberos V)
+    AC_ARG_ENABLE(kerb5-instance,
+    [AS_HELP_STRING([--enable-kerb5-instance], [instance string to append to the username (separated by a slash)])],
+       [ case "$enableval" in
+           yes)        AC_MSG_ERROR(["must give --enable-kerb5-instance an argument."])
+                       ;;
+           no)         AC_MSG_RESULT(no)
+                       ;;
+           *)          SUDO_DEFINE_UNQUOTED(SUDO_KRB5_INSTANCE, "$enableval")
+                       AC_MSG_RESULT([$enableval])
+                       ;;
+       esac], AC_MSG_RESULT(no))
 fi
 
 dnl
@@ -3063,14 +3163,29 @@ if test X"$with_noexec" != X"no" -o X"$with_selinux" != X"no"; then
        PROGS="${PROGS} libsudo_noexec.la"
        INSTALL_NOEXEC="install-noexec"
 
-       eval noexec_file="$with_noexec"
+       noexec_file="$with_noexec"
+       _noexec_file=
+       while test X"$noexec_file" != X"$_noexec_file"; do
+           _noexec_file="$noexec_file"
+           eval noexec_file="$_noexec_file"
+       done
        SUDO_DEFINE_UNQUOTED(_PATH_SUDO_NOEXEC, "$noexec_file", [The fully qualified pathname of sudo_noexec.so])
     fi
     if test X"$with_selinux" != X"no"; then
-       eval sesh_file="$libexecdir/sesh"
+       sesh_file="$libexecdir/sesh"
+       _sesh_file=
+       while test X"$sesh_file" != X"$_sesh_file"; do
+           _sesh_file="$sesh_file"
+           eval sesh_file="$_sesh_file"
+       done
        SUDO_DEFINE_UNQUOTED(_PATH_SUDO_SESH, "$sesh_file", [The fully qualified pathname of sesh])
     fi
-    eval PLUGINDIR="$with_plugindir"
+    PLUGINDIR="$with_plugindir"
+    _PLUGINDIR=
+    while test X"$PLUGINDIR" != X"$_PLUGINDIR"; do
+       _PLUGINDIR="$PLUGINDIR"
+       eval PLUGINDIR="$_PLUGINDIR"
+    done
     SUDO_DEFINE_UNQUOTED(_PATH_SUDO_PLUGIN_DIR, "$PLUGINDIR/")
     SUDO_DEFINE_UNQUOTED(SUDOERS_PLUGIN, "sudoers${SOEXT}")
     exec_prefix="$oexec_prefix"
@@ -3104,6 +3219,12 @@ dnl Spew any text the user needs to know about
 dnl
 if test "$with_pam" = "yes"; then
     case $host in
+       *-*-hpux*)
+           if test -f /usr/lib/security/libpam_hpsec.so.1; then
+               AC_MSG_NOTICE([You may wish to add the following line to /etc/pam.conf])
+               AC_MSG_NOTICE([sudo session required libpam_hpsec.so.1 bypass_umask bypass_last_login])
+           fi
+           ;;
        *-*-linux*)
            AC_MSG_NOTICE([You will need to customize sample.pam and install it as /etc/pam.d/sudo])
            ;;
@@ -3144,10 +3265,8 @@ AH_TEMPLATE(HAVE_GETSPNAM, [Define to 1 if you have the `getspnam' function (SVR
 AH_TEMPLATE(HAVE_GETSPWUID, [Define to 1 if you have the `getspwuid' function. (HP-UX <= 9.X shadow passwords)])
 AH_TEMPLATE(HAVE_GSS_KRB5_CCACHE_NAME, [Define to 1 if you have the `gss_krb5_ccache_name' function.])
 AH_TEMPLATE(HAVE_HEIMDAL, [Define to 1 if your Kerberos is Heimdal.])
-AH_TEMPLATE(HAVE_IN6_ADDR, [Define to 1 if <netinet/in.h> contains struct in6_addr.])
 AH_TEMPLATE(HAVE_ISCOMSEC, [Define to 1 if you have the `iscomsec' function. (HP-UX >= 10.x check for shadow enabled)])
 AH_TEMPLATE(HAVE_ISSECURE, [Define to 1 if you have the `issecure' function. (SunOS 4.x check for shadow enabled)])
-AH_TEMPLATE(HAVE_KERB4, [Define to 1 if you use Kerberos IV.])
 AH_TEMPLATE(HAVE_KERB5, [Define to 1 if you use Kerberos V.])
 AH_TEMPLATE(HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC, [Define to 1 if you have the `krb5_get_init_creds_opt_alloc' function.])
 AH_TEMPLATE(HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_TWO_ARGS, [Define to 1 if your `krb5_get_init_creds_opt_free' function takes two arguments.])
@@ -3165,14 +3284,12 @@ AH_TEMPLATE(HAVE_SECURID, [Define to 1 if you use SecurID for authentication.])
 AH_TEMPLATE(HAVE_SELINUX, [Define to 1 to enable SELinux RBAC support.])
 AH_TEMPLATE(HAVE_SETKEYCREATECON, [Define to 1 if you have the `setkeycreatecon' function.])
 AH_TEMPLATE(HAVE_SHL_LOAD, [Define to 1 if you have the `shl_load' function.])
-AH_TEMPLATE(HAVE_SIGACTION_T, [Define to 1 if <signal.h> has the sigaction_t typedef.])
 AH_TEMPLATE(HAVE_SKEY, [Define to 1 if you use S/Key.])
 AH_TEMPLATE(HAVE_SKEYACCESS, [Define to 1 if your S/Key library has skeyaccess().])
 AH_TEMPLATE(HAVE_RFC1938_SKEYCHALLENGE, [Define to 1 if the skeychallenge() function is RFC1938-compliant and takes 4 arguments])
 AH_TEMPLATE(HAVE_ST__TIM, [Define to 1 if your struct stat uses an st__tim union])
 AH_TEMPLATE(HAVE_ST_MTIM, [Define to 1 if your struct stat has an st_mtim member])
 AH_TEMPLATE(HAVE_ST_MTIMESPEC, [Define to 1 if your struct stat has an st_mtimespec member])
-AH_TEMPLATE(HAVE_TIMESPEC, [Define to 1 if you have struct timespec in sys/time.h])
 AH_TEMPLATE(HAVE___PROGNAME, [Define to 1 if your crt0.o defines the __progname symbol for you.])
 AH_TEMPLATE(HOST_IN_LOG, [Define to 1 if you want the hostname to be entered into the log file.])
 AH_TEMPLATE(IGNORE_DOT_PATH, [Define to 1 if you want to ignore '.' and empty PATH elements])
@@ -3199,8 +3316,11 @@ AH_TEMPLATE(USE_STOW, [Define to 1 if you use GNU stow packaging.])
 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(socklen_t, [Define to `unsigned int' if <sys/socket.h> doesn't define.])
 AH_TEMPLATE(HAVE_STRUCT_UTMP_UT_EXIT, [Define to 1 if `ut_exit' is a member of `struct utmp'.])
 AH_TEMPLATE(HAVE_STRUCT_UTMPX_UT_EXIT, [Define to 1 if `ut_exit' is a member of `struct utmpx'.])
+AH_TEMPLATE(HAVE___FUNC__, [Define to 1 if the compiler supports the C99 __func__ variable.])
+AH_TEMPLATE(SUDO_KRB5_INSTANCE, [An instance string to append to the username (separated by a slash) for Kerberos V authentication])
 
 dnl
 dnl Bits to copy verbatim into config.h.in
index 4608cfc5671dd8ce51cfff07690d40a59034b5a8..165e1fa43b1a6625b6898c21b675715e75aab6cb 100644 (file)
@@ -4,23 +4,32 @@ maintaining it in 1993.  This list is known to be incomplete--if
 you believe you should be listed, please send a note to sudo@sudo.ws.
 
     Matt Ackeret
+    Mark Adler
+    Russ Allbery
     Nick Andrew
     Dimitry Andric
     Danny Barron
     Tom Bates
+    Zdenek Behan
     Ray Bellis
     Elias Benali
     Jamie Beverly
     Spider Boardman
-    Keith Garry Boyce
+    Jakub Bogusz
     P.J. Bostley
+    Keith Bowes
+    Keith Garry Boyce
     Michael Brantley
     Rob Braun
     Piete Brooks
     Jerry Brown
+    Michael E Burr
     Andreas Bussjaeger
     Gary Calvin
     Aaron Campbell
+    Milo Casagrande
+    Yuri Chornoivan
+    Vitezslav Cizek
     Chris Coleman
     Deven T. Corzine
     Frank Cusack
@@ -35,8 +44,11 @@ you believe you should be listed, please send a note to sudo@sudo.ws.
     Ariel Faigon
     Brian Farrell
     Steve Fobes
+    Mike Frysinger
+    Jean-loup Gailly
     Simon J. Gerraty
     B. Guillory
+    Joe Hansen
     Randy M. Hayman
     Joachim Henke
     YOSHIFUJI Hideaki
@@ -53,6 +65,7 @@ you believe you should be listed, please send a note to sudo@sudo.ws.
     Timo Juhani
     Ayamura KIKUCHI
     Kevin Kadow
+    Jorma Karvonen
     Stepan Kasal
     Mike Kienenberger
     Dale King
@@ -60,19 +73,21 @@ you believe you should be listed, please send a note to sudo@sudo.ws.
     Tim Knox
     Alek O. Komarnitsky
     Daniel Kopecek
+    Yuri Kozlov
     Paul Kranenburg
     David Krause
     Case Larsen
     Dmitry V. Levin
     Kendall Libby
     Phillip E. Lobbes
+    Jason McIntyre
     David J. MacKenzie
+    Tom McLaughlin
     Jeff Makey
     Michael D. Marchionna
     Paul Markham
     Emin Martinian
-    Jason McIntyre
-    Tom McLaughlin
+    Pavel Maryanov
     Michael Meskes
     Todd C. Miller
     Loic Minier
@@ -82,6 +97,7 @@ you believe you should be listed, please send a note to sudo@sudo.ws.
     Dworkin Muller
     Jeff Nieusma
     Peter A. Nikitser
+    Miroslav Nikolic
     Ludwig Nussel
     Eric Paquet
     Chantal Paradis
@@ -90,10 +106,13 @@ you believe you should be listed, please send a note to sudo@sudo.ws.
     Alexander Peslyak
     Toby Peterson
     Diego Elio Petteno
+    Joel Pickett
     Alex Plotnick
     Gudleik Rasch
     Matt Richards
+    Guido van Rossum
     John P. Rouillard
+    William A. Rowe Jr.
     Alain Roy
     Elan Ruusamae
     Eygene Ryabinkin
@@ -101,7 +120,9 @@ you believe you should be listed, please send a note to sudo@sudo.ws.
     Wilfredo Sanchez
     Jean-Francois Saucier
     Patrick Schoenfeld
+    Arno Schuring
     Dougal Scott
+    Abel Sendón
     Nick Sieger
     Thor Lancelot Simon
     Marc Slemko
@@ -114,17 +135,21 @@ you believe you should be listed, please send a note to sudo@sudo.ws.
     Russell Street
     Tilo Stritzky
     Michael Stroucken
+    Yasuaki Taniguchi
     Robert Tarrall
     Matthew Thomas
     Giles Todd
     Martin Toft
+    Chris Torek
     Darren Tucker
     Robert Uhl
+    Mikel Olasagasti Uranga
     Petr Uzel
     Reznic Valery
     Martynas Venckus
     Klaus Wagner
     Dan Walsh
+    Wylmer Wang
     John Warburton
     Kirk Webb
     Timm Wetzel
index f6c411f1cfa3e2b1e6caede57f56d1b7ec77fd7f..0bcd35b5d4c5cdd226468ad68500314be157e4d2 100644 (file)
@@ -1,6 +1,6 @@
-Sudo is distributed under the following ISC-style license:
+Sudo is distributed under the following license:
 
-   Copyright (c) 1994-1996, 1998-2011
+   Copyright (c) 1994-1996, 1998-2012
         Todd C. Miller <Todd.Miller@courtesan.com>
 
    Permission to use, copy, modify, and distribute this software for any
@@ -19,10 +19,31 @@ Sudo is distributed under the following ISC-style license:
    Agency (DARPA) and Air Force Research Laboratory, Air Force
    Materiel Command, USAF, under agreement number F39502-99-1-0512.
 
-The files fnmatch.c, fnmatch.h, getcwd.c, glob.c, glob.h and snprintf.c
-bear the following UCB license:
+The file redblack.c bears the following license:
 
-   Copyright (c) 1987, 1989, 1990, 1991, 1992, 1993, 1994
+   Copyright (c) 2001 Emin Martinian
+  
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that neither the name of Emin
+   Martinian nor the names of any contributors are 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.
+
+The files getcwd.c, glob.c, glob.h and snprintf.c bear the following license:
+
+   Copyright (c) 1989, 1990, 1991, 1993
         The Regents of the University of California.  All rights reserved.
 
    Redistribution and use in source and binary forms, with or without
@@ -49,6 +70,33 @@ bear the following UCB license:
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    SUCH DAMAGE.
 
+The file fnmatch.c bears the following license:
+
+   Copyright (c) 2011, VMware, 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:
+       * Redistributions of source code must retain the above copyright
+         notice, this list of conditions and the following disclaimer.
+       * 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.
+       * Neither the name of the VMware, 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 VMWARE, INC. 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.
+
 The embedded copy of zlib bears the following license:
 
   Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
index eadb05c15bcead6dcce75d0eb53af62a59115863..e334fba2c309bdfe1ebc210c66050e4f6a4fcf04 100644 (file)
@@ -32,6 +32,11 @@ INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
 
 # Where to install things...
 prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
 datarootdir = @datarootdir@
 localstatedir = @localstatedir@
 mandir = @mandir@
@@ -47,6 +52,9 @@ mandirform = $(mandir)/$(mantype)$(mansectform)
 install_uid = 0
 install_gid = 0
 
+# Set to non-empty for development mode
+DEVEL = @DEVEL@
+
 #### End of system configuration section. ####
 
 SHELL = @SHELL@
@@ -54,21 +62,21 @@ SHELL = @SHELL@
 DOCS = sudo.man visudo.man sudoers.man sudoers.ldap.man sudoers.man \
        sudoreplay.man sudo_plugin.man
 
-@DEV@DEVDOCS = $(srcdir)/sudo.man.in $(srcdir)/sudo.cat \
-@DEV@          $(srcdir)/visudo.man.in $(srcdir)/visudo.cat \
-@DEV@          $(srcdir)/sudoers.man.in $(srcdir)/sudoers.cat \
-@DEV@          $(srcdir)/sudoers.ldap.man.in $(srcdir)/sudoers.ldap.cat \
-@DEV@          $(srcdir)/sudoers.man.in $(srcdir)/sudoers.cat \
-@DEV@          $(srcdir)/sudoreplay.man.in $(srcdir)/sudoreplay.cat \
-@DEV@          $(srcdir)/sudo_plugin.man.in $(srcdir)/sudo_plugin.cat \
-@DEV@          $(srcdir)/HISTORY $(srcdir)/LICENSE $(srcdir)/CONTRIBUTORS
-
-OTHER_DOCS= $(top_srcdir)/ChangeLog $(top_srcdir)/README \
-           $(top_srcdir)/NEWS $(srcdir)/HISTORY $(srcdir)/CONTRIBUTORS \
-           $(srcdir)/LICENSE $(srcdir)/TROUBLESHOOTING $(srcdir)/UPGRADE \
-           $(srcdir)/sample.*
-
-OTHER_DOCS_LDAP= $(top_srcdir)/README.LDAP $(srcdir)/schema.*
+DEVDOCS = $(srcdir)/sudo.man.in $(srcdir)/sudo.cat \
+         $(srcdir)/visudo.man.in $(srcdir)/visudo.cat \
+         $(srcdir)/sudoers.man.in $(srcdir)/sudoers.cat \
+         $(srcdir)/sudoers.ldap.man.in $(srcdir)/sudoers.ldap.cat \
+         $(srcdir)/sudoers.man.in $(srcdir)/sudoers.cat \
+         $(srcdir)/sudoreplay.man.in $(srcdir)/sudoreplay.cat \
+         $(srcdir)/sudo_plugin.man.in $(srcdir)/sudo_plugin.cat \
+         $(srcdir)/HISTORY $(srcdir)/LICENSE $(srcdir)/CONTRIBUTORS
+
+OTHER_DOCS = $(top_srcdir)/ChangeLog $(top_srcdir)/README \
+            $(top_srcdir)/NEWS $(srcdir)/HISTORY $(srcdir)/CONTRIBUTORS \
+            $(srcdir)/LICENSE $(srcdir)/TROUBLESHOOTING $(srcdir)/UPGRADE \
+            $(srcdir)/sample.*
+OTHER_DOCS_LDAP = $(top_srcdir)/README.LDAP $(srcdir)/schema.*
 
 VERSION = @PACKAGE_VERSION@
 PACKAGE_TARNAME = @PACKAGE_TARNAME@
@@ -80,75 +88,141 @@ Makefile: $(srcdir)/Makefile.in
 
 .SUFFIXES: .man
 
-@DEV@varsub: $(top_srcdir)/configure.in
-@DEV@  printf 's#@%s@#1#\ns#@%s@#1#\ns#@%s@#1#\ns#@%s@#/etc#g\ns#@%s@#/usr/local#g\ns#@%s@#4#g\ns#@%s@#1m#g\n' SEMAN BAMAN LCMAN sysconfdir prefix mansectform mansectsu > $@; sed -n '/Begin initial values for man page substitution/,/End initial values for man page substitution/{;p;}' $(top_srcdir)/configure.in | sed -e '/^#/d' -e 's/^/s#@/' -e 's/=[\\"]*/@#/' -e 's/[\\"]*$$/#g/' >> $@
-
-@DEV@$(srcdir)/sudo.man.in: $(srcdir)/sudo.pod
-@DEV@  mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' $(srcdir)/sudo.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" $(srcdir)/sudo.pod | sed -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" | perl -p $(srcdir)/sudo.man.pl >> $@
+varsub: $(top_srcdir)/configure.in
+       @if [ -n "$(DEVEL)" ]; then \
+           printf 's#@%s@#1#\ns#@%s@#1#\ns#@%s@#1#\ns#@%s@#/etc#g\ns#@%s@#/usr/local#g\ns#@%s@#4#g\ns#@%s@#1m#g\n' SEMAN BAMAN LCMAN sysconfdir prefix mansectform mansectsu > $@; \
+           sed -n '/Begin initial values for man page substitution/,/End initial values for man page substitution/{;p;}' $(top_srcdir)/configure.in | sed -e '/^#/d' -e 's/^/s#@/' -e 's/=[\\"]*/@#/' -e 's/[\\"]*$$/#g/' >> $@; \
+       fi
+
+$(srcdir)/sudo.man.in: $(srcdir)/sudo.pod
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; \
+           mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; \
+           sed -n -e '/^=pod/q' -e 's/^/.\\" /p' $(srcdir)/sudo.pod > $@; \
+           pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" $(srcdir)/sudo.pod | sed -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" | perl -p $(srcdir)/sudo.man.pl >> $@; \
+       fi
 
 sudo.man: $(srcdir)/sudo.man.in
        (cd $(top_builddir) && $(SHELL) config.status --file=doc/$@)
 
-@DEV@$(srcdir)/sudo.cat: varsub $(srcdir)/sudo.man.in
-@DEV@  sed -f varsub $(srcdir)/sudo.man.in | $(NROFF) -man > $@
-
-@DEV@$(srcdir)/visudo.man.in: $(srcdir)/visudo.pod
-@DEV@  mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' $(srcdir)/visudo.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" $(srcdir)/visudo.pod | sed -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" -e 's|\\fI\\f\((CW*\)*I@\([^@]*\)\\fI@|\\fI@\2@|g' >> $@
+$(srcdir)/sudo.cat: varsub $(srcdir)/sudo.man.in
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           sed -f varsub $(srcdir)/sudo.man.in | $(NROFF) -man > $@; \
+       fi
+
+$(srcdir)/visudo.man.in: $(srcdir)/visudo.pod
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; \
+           mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; \
+           sed -n -e '/^=pod/q' -e 's/^/.\\" /p' $(srcdir)/visudo.pod > $@; \
+           pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" $(srcdir)/visudo.pod | sed -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" -e 's|\\fI\\f\((CW*\)*I@\([^@]*\)\\fI@|\\fI@\2@|g' >> $@; \
+       fi
 
 visudo.man: $(srcdir)/visudo.man.in
        (cd $(top_builddir) && $(SHELL) config.status --file=doc/$@)
 
-@DEV@$(srcdir)/visudo.cat: varsub $(srcdir)/visudo.man.in
-@DEV@  sed -f varsub $(srcdir)/visudo.man.in | $(NROFF) -man > $@
-
-@DEV@$(srcdir)/sudoers.man.in: $(srcdir)/sudoers.pod
-@DEV@  mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' $(srcdir)/sudoers.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectform --release=$(VERSION) --center="MAINTENANCE COMMANDS" $(srcdir)/sudoers.pod | sed -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" | perl -p $(srcdir)/sudoers.man.pl >> $@
+$(srcdir)/visudo.cat: varsub $(srcdir)/visudo.man.in
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           sed -f varsub $(srcdir)/visudo.man.in | $(NROFF) -man > $@; \
+       fi
+
+$(srcdir)/sudoers.man.in: $(srcdir)/sudoers.pod
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; \
+           mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; \
+           sed -n -e '/^=pod/q' -e 's/^/.\\" /p' $(srcdir)/sudoers.pod > $@; \
+           pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectform --release=$(VERSION) --center="MAINTENANCE COMMANDS" $(srcdir)/sudoers.pod | sed -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" | perl -p $(srcdir)/sudoers.man.pl >> $@; \
+       fi
 
 sudoers.man: $(srcdir)/sudoers.man.in
        (cd $(top_builddir) && $(SHELL) config.status --file=doc/$@)
 
-@DEV@$(srcdir)/sudoers.cat: varsub $(srcdir)/sudoers.man.in
-@DEV@  sed -f varsub $(srcdir)/sudoers.man.in | $(NROFF) -man > $@
-
-@DEV@$(srcdir)/sudoers.ldap.man.in: $(srcdir)/sudoers.ldap.pod
-@DEV@  mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' $(srcdir)/sudoers.ldap.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectform --release=$(VERSION) --center="MAINTENANCE COMMANDS" $(srcdir)/sudoers.ldap.pod | sed -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" -e 's|\\fI\\f\((CW*\)*I@\([^@]*\)\\fI@|\\fI@\2@|g' >> $@
+$(srcdir)/sudoers.cat: varsub $(srcdir)/sudoers.man.in
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           sed -f varsub $(srcdir)/sudoers.man.in | $(NROFF) -man > $@; \
+       fi
+
+$(srcdir)/sudoers.ldap.man.in: $(srcdir)/sudoers.ldap.pod
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; \
+           mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; \
+           sed -n -e '/^=pod/q' -e 's/^/.\\" /p' $(srcdir)/sudoers.ldap.pod > $@; \
+           pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectform --release=$(VERSION) --center="MAINTENANCE COMMANDS" $(srcdir)/sudoers.ldap.pod | sed -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" -e 's|\\fI\\f\((CW*\)*I@\([^@]*\)\\fI@|\\fI@\2@|g' >> $@; \
+       fi
 
 sudoers.ldap.man: $(srcdir)/sudoers.ldap.man.in
        (cd $(top_builddir) && $(SHELL) config.status --file=doc/$@)
 
-@DEV@$(srcdir)/sudoers.ldap.cat: varsub $(srcdir)/sudoers.ldap.man.in
-@DEV@  sed -f varsub $(srcdir)/sudoers.ldap.man.in | $(NROFF) -man > $@
-
-@DEV@$(srcdir)/sudoreplay.man.in: $(srcdir)/sudoreplay.pod
-@DEV@  mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' $(srcdir)/sudoreplay.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" $(srcdir)/sudoreplay.pod | sed -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" -e 's|\\fI\\f\((CW*\)*I@\([^@]*\)\\fI@|\\fI@\2@|g' >> $@
+$(srcdir)/sudoers.ldap.cat: varsub $(srcdir)/sudoers.ldap.man.in
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           sed -f varsub $(srcdir)/sudoers.ldap.man.in | $(NROFF) -man > $@; \
+       fi
+
+$(srcdir)/sudoreplay.man.in: $(srcdir)/sudoreplay.pod
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; \
+           mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; \
+           sed -n -e '/^=pod/q' -e 's/^/.\\" /p' $(srcdir)/sudoreplay.pod > $@; \
+           pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" $(srcdir)/sudoreplay.pod | sed -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" -e 's|\\fI\\f\((CW*\)*I@\([^@]*\)\\fI@|\\fI@\2@|g' >> $@; \
+       fi
 
 sudoreplay.man: $(srcdir)/sudoreplay.man.in
        (cd $(top_builddir) && $(SHELL) config.status --file=doc/$@)
 
-@DEV@$(srcdir)/sudoreplay.cat: varsub $(srcdir)/sudoreplay.man.in
-@DEV@  sed -f varsub $(srcdir)/sudoreplay.man.in | $(NROFF) -man > $@
-
-@DEV@$(srcdir)/sudo_plugin.man.in: $(srcdir)/sudo_plugin.pod
-@DEV@  mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' $(srcdir)/sudo_plugin.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" $(srcdir)/sudo_plugin.pod | sed -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" -e 's|\\fI\\f\((CW*\)*I@\([^@]*\)\\fI@|\\fI@\2@|g' >> $@
+$(srcdir)/sudoreplay.cat: varsub $(srcdir)/sudoreplay.man.in
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           sed -f varsub $(srcdir)/sudoreplay.man.in | $(NROFF) -man > $@; \
+       fi
+
+$(srcdir)/sudo_plugin.man.in: $(srcdir)/sudo_plugin.pod
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; \
+           mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; \
+           sed -n -e '/^=pod/q' -e 's/^/.\\" /p' $(srcdir)/sudo_plugin.pod > $@; \
+           pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" $(srcdir)/sudo_plugin.pod | sed -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" -e 's|\\fI\\f\((CW*\)*I@\([^@]*\)\\fI@|\\fI@\2@|g' >> $@; \
+       fi
 
 sudo_plugin.man: $(srcdir)/sudo_plugin.man.in
        (cd $(top_builddir) && $(SHELL) config.status --file=doc/$@)
 
-@DEV@$(srcdir)/sudo_plugin.cat: varsub $(srcdir)/sudo_plugin.man.in
-@DEV@  sed -f varsub $(srcdir)/sudo_plugin.man.in | $(NROFF) -man > $@
+$(srcdir)/sudo_plugin.cat: varsub $(srcdir)/sudo_plugin.man.in
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           sed -f varsub $(srcdir)/sudo_plugin.man.in | $(NROFF) -man > $@; \
+       fi
 
 CONTRIBUTORS: $(srcdir)/contributors.pod
-       pod2text -l -i0 $(srcdir)/contributors.pod | sed '1,3d' > $@
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           pod2text -l -i0 $(srcdir)/contributors.pod | sed '1,3d' > $@; \
+       fi
 
 HISTORY: $(srcdir)/history.pod
-       pod2text -l -i0 $(srcdir)/history.pod > $@
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           pod2text -l -i0 $(srcdir)/history.pod > $@; \
+       fi
 
 LICENSE: $(srcdir)/license.pod
-       pod2text -l -i0 $(srcdir)/license.pod | sed '1,3d' > $@
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "Generating $@"; \
+           pod2text -l -i0 $(srcdir)/license.pod | sed '1,3d' > $@; \
+       fi
 
 pre-install:
 
-install: install-dirs install-doc
+install: install-doc
 
 install-dirs:
        $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(docdir) \
@@ -159,16 +233,16 @@ install-binaries:
 install-includes:
 
 install-doc: install-dirs
-       for f in $(OTHER_DOCS); do $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 $$f $(DESTDIR)$(docdir); done
-       @LDAP@for f in $(OTHER_DOCS_LDAP); do $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 $$f $(DESTDIR)$(docdir); done
-       $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 @mansrcdir@/sudo.$(mantype) $(DESTDIR)$(mandirsu)/sudo.$(mansectsu)
+       for f in $(OTHER_DOCS); do $(INSTALL) -O $(install_uid) -G $(install_gid) -m 0444 $$f $(DESTDIR)$(docdir); done
+       @LDAP@for f in $(OTHER_DOCS_LDAP); do $(INSTALL) -O $(install_uid) -G $(install_gid) -m 0444 $$f $(DESTDIR)$(docdir); done
+       $(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)
-       $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 @mansrcdir@/sudo_plugin.$(mantype) $(DESTDIR)$(mandirsu)/sudo_plugin.$(mansectsu)
-       $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 @mansrcdir@/sudoreplay.$(mantype) $(DESTDIR)$(mandirsu)/sudoreplay.$(mansectsu)
-       $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 @mansrcdir@/visudo.$(mantype) $(DESTDIR)$(mandirsu)/visudo.$(mansectsu)
-       $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 @mansrcdir@/sudoers.$(mantype) $(DESTDIR)$(mandirform)/sudoers.$(mansectform)
-       @LDAP@$(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 @mansrcdir@/sudoers.ldap.$(mantype) $(DESTDIR)$(mandirform)/sudoers.ldap.$(mansectform)
+       $(INSTALL) -O $(install_uid) -G $(install_gid) -m 0444 @mansrcdir@/sudo_plugin.$(mantype) $(DESTDIR)$(mandirsu)/sudo_plugin.$(mansectsu)
+       $(INSTALL) -O $(install_uid) -G $(install_gid) -m 0444 @mansrcdir@/sudoreplay.$(mantype) $(DESTDIR)$(mandirsu)/sudoreplay.$(mansectsu)
+       $(INSTALL) -O $(install_uid) -G $(install_gid) -m 0444 @mansrcdir@/visudo.$(mantype) $(DESTDIR)$(mandirsu)/visudo.$(mansectsu)
+       $(INSTALL) -O $(install_uid) -G $(install_gid) -m 0444 @mansrcdir@/sudoers.$(mantype) $(DESTDIR)$(mandirform)/sudoers.$(mansectform)
+       @LDAP@$(INSTALL) -O $(install_uid) -G $(install_gid) -m 0444 @mansrcdir@/sudoers.ldap.$(mantype) $(DESTDIR)$(mandirform)/sudoers.ldap.$(mansectform)
 @MAN_POSTINSTALL@
 
 install-plugin:
index d1cd7289f9bb444b271a86a394f3a9a1b1f963ff..f12d6d954e333c979e70fafd4b059fbaafb26581 100644 (file)
@@ -121,9 +121,6 @@ A) Sudo removes the following "dangerous" environment variables
      _RLD_*
      SHLIB_PATH (HP-UX only)
      LIBPATH (AIX only)
-     KRB_CONF (kerb4 only)
-     KRBCONFDIR (kerb4 only)
-     KRBTKFILE (kerb4 only)
      KRB5_CONFIG (kerb5 only)
      VAR_ACE (SecurID only)
      USR_ACE (SecurID only)
@@ -205,6 +202,17 @@ A) ssh does not allocate a tty by default when running a remote command.
    Alternately, if you do not mind your password being echoed to the
    screen, you can use the "visiblepw" sudoers option to allow this.
 
+Q) When I run sudo on AIX I get the following error:
+    setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID): Operation not permitted.
+A) AIX's Enhanced RBAC is preventing sudo from running.  To fix
+   this, add the following entry to /etc/security/privcmds (adjust
+   the path to sudo as needed) and run the setkst command as root:
+
+    /usr/local/bin/sudo:
+           accessauths = ALLOW_ALL
+           innateprivs = PV_DAC_UID,PV_DAC_GID
+           secflags = FSF_EPS
+
 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 9ecab1227de552c856fff1a1adb25e7cb4932e2f..8c83aafe3accbd75236f3579aea7dd5378f20832 100644 (file)
@@ -140,7 +140,7 @@ o Upgrading from a version prior to 1.7.4:
     to preserve the old value of MAIL.
 
     NOTE: preserving HOME has security implications since many programs
-    use when searching for configuration files.  Adding HOME to env_keep
+    use it when searching for configuration files.  Adding HOME to env_keep
     may enable a user to run unrestricted commands via sudo.
 
     The default syslog facility has changed from "local2" to "authpriv"
index 0218d4b647422656e95761661d879aabfe48936f..7c9c657eb222491766029a9e835954016b78ef52 100644 (file)
@@ -7,23 +7,32 @@ maintaining it in 1993.  This list is known to be incomplete--if
 you believe you should be listed, please send a note to sudo@sudo.ws.
 
     Matt Ackeret
+    Mark Adler
+    Russ Allbery
     Nick Andrew
     Dimitry Andric
     Danny Barron
     Tom Bates
+    Zdenek Behan
     Ray Bellis
     Elias Benali
     Jamie Beverly
     Spider Boardman
-    Keith Garry Boyce
+    Jakub Bogusz
     P.J. Bostley
+    Keith Bowes
+    Keith Garry Boyce
     Michael Brantley
     Rob Braun
     Piete Brooks
     Jerry Brown
+    Michael E Burr
     Andreas Bussjaeger
     Gary Calvin
     Aaron Campbell
+    Milo Casagrande
+    Yuri Chornoivan
+    Vitezslav Cizek
     Chris Coleman
     Deven T. Corzine
     Frank Cusack
@@ -38,8 +47,11 @@ you believe you should be listed, please send a note to sudo@sudo.ws.
     Ariel Faigon
     Brian Farrell
     Steve Fobes
+    Mike Frysinger
+    Jean-loup Gailly
     Simon J. Gerraty
     B. Guillory
+    Joe Hansen
     Randy M. Hayman
     Joachim Henke
     YOSHIFUJI Hideaki
@@ -56,6 +68,7 @@ you believe you should be listed, please send a note to sudo@sudo.ws.
     Timo Juhani
     Ayamura KIKUCHI
     Kevin Kadow
+    Jorma Karvonen
     Stepan Kasal
     Mike Kienenberger
     Dale King
@@ -63,19 +76,21 @@ you believe you should be listed, please send a note to sudo@sudo.ws.
     Tim Knox
     Alek O. Komarnitsky
     Daniel Kopecek
+    Yuri Kozlov
     Paul Kranenburg
     David Krause
     Case Larsen
     Dmitry V. Levin
     Kendall Libby
     Phillip E. Lobbes
+    Jason McIntyre
     David J. MacKenzie
+    Tom McLaughlin
     Jeff Makey
     Michael D. Marchionna
     Paul Markham
     Emin Martinian
-    Jason McIntyre
-    Tom McLaughlin
+    Pavel Maryanov
     Michael Meskes
     Todd C. Miller
     Loic Minier
@@ -85,6 +100,7 @@ you believe you should be listed, please send a note to sudo@sudo.ws.
     Dworkin Muller
     Jeff Nieusma
     Peter A. Nikitser
+    Miroslav Nikolic
     Ludwig Nussel
     Eric Paquet
     Chantal Paradis
@@ -93,10 +109,13 @@ you believe you should be listed, please send a note to sudo@sudo.ws.
     Alexander Peslyak
     Toby Peterson
     Diego Elio Petteno
+    Joel Pickett
     Alex Plotnick
     Gudleik Rasch
     Matt Richards
+    Guido van Rossum
     John P. Rouillard
+    William A. Rowe Jr.
     Alain Roy
     Elan Ruusamae
     Eygene Ryabinkin
@@ -104,7 +123,9 @@ you believe you should be listed, please send a note to sudo@sudo.ws.
     Wilfredo Sanchez
     Jean-Francois Saucier
     Patrick Schoenfeld
+    Arno Schuring
     Dougal Scott
+    Abel Sendón
     Nick Sieger
     Thor Lancelot Simon
     Marc Slemko
@@ -117,17 +138,21 @@ you believe you should be listed, please send a note to sudo@sudo.ws.
     Russell Street
     Tilo Stritzky
     Michael Stroucken
+    Yasuaki Taniguchi
     Robert Tarrall
     Matthew Thomas
     Giles Todd
     Martin Toft
+    Chris Torek
     Darren Tucker
     Robert Uhl
+    Mikel Olasagasti Uranga
     Petr Uzel
     Reznic Valery
     Martynas Venckus
     Klaus Wagner
     Dan Walsh
+    Wylmer Wang
     John Warburton
     Kirk Webb
     Timm Wetzel
index 18baa59bb02d09dc907ea57676c2e0256d674a3d..529602fb10fe2827a7606f3923891dae86309fb3 100644 (file)
@@ -5,6 +5,8 @@
 #   Plugin plugin_name plugin_path
 #   Path askpass /path/to/askpass
 #   Path noexec /path/to/noexec.so
+#   Debug sudo /var/log/sudo_debug all@warn
+#   Set disable_coredump true
 #
 # Sudo plugins:
 #
@@ -40,3 +42,13 @@ Plugin sudoers_io sudoers.so
 # if you rename or move the sudo_noexec.so file.
 #
 #Path noexec /usr/libexec/sudo_noexec.so
+
+#
+# Core dumps:
+#
+# By default, sudo disables core dumps while it is executing (they
+# are re-enabled for the command that is run).
+# To aid in debugging sudo problems, you may wish to enable core
+# dumps by setting "disable_coredump" to false.
+#
+#Set disable_coredump false
index ed8a69e8ca2f93bf3f8bf80ecca05094a3d24e9e..b01a63d1259c7da960898a9651c4ca507edff9ee 100644 (file)
@@ -6,19 +6,19 @@ 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-D\bD _\bl_\be_\bv_\be_\bl] -\b-h\bh | -\b-K\bK | -\b-k\bk | -\b-V\bV
+       s\bsu\bud\bdo\bo -\b-h\bh | -\b-K\bK | -\b-k\bk | -\b-V\bV
 
-       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-D\bD _\bl_\be_\bv_\be_\bl] [-\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]
+       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-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]
 
-       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-D\bD _\bl_\be_\bv_\be_\bl] [-\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-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-D\bD _\bl_\be_\bv_\be_\bl] [-\b-c\bc _\bc_\bl_\ba_\bs_\bs|_\b-]
+       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-r\br _\br_\bo_\bl_\be] [-\b-t\bt _\bt_\by_\bp_\be]
        [-\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]
 
-       s\bsu\bud\bdo\boe\bed\bdi\bit\bt [-\b-A\bAn\bnS\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-D\bD _\bl_\be_\bv_\be_\bl]
+       s\bsu\bud\bdo\boe\bed\bdi\bit\bt [-\b-A\bAn\bnS\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] file ...
 
 D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
@@ -30,7 +30,7 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
 
        s\bsu\bud\bdo\bo supports a plugin architecture for security policies and
        input/output logging.  Third parties can develop and distribute their
-       own policy and I/O logging modules to work seemlessly with the s\bsu\bud\bdo\bo
+       own policy and I/O logging modules to work seamlessly with the s\bsu\bud\bdo\bo
        front end.  The default security policy is _\bs_\bu_\bd_\bo_\be_\br_\bs, which is configured
        via the file _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs, or via LDAP.  See the PLUGINS section for
        more information.
@@ -110,9 +110,6 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
                    is already root.  This option is only available on systems
                    with BSD login classes.
 
-       -D _\bl_\be_\bv_\be_\bl    Enable debugging of s\bsu\bud\bdo\bo plugins and s\bsu\bud\bdo\bo itself.  The
-                   _\bl_\be_\bv_\be_\bl may be a value from 1 through 9.
-
        -E          The -\b-E\bE (_\bp_\br_\be_\bs_\be_\br_\bv_\be _\be_\bn_\bv_\bi_\br_\bo_\bn_\bm_\be_\bn_\bt) option indicates to the
                    security policy that the user wishes to preserve their
                    existing environment variables.  The security policy may
@@ -315,7 +312,7 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
        line are subject to the same restrictions as normal environment
        variables with one important exception.  If the _\bs_\be_\bt_\be_\bn_\bv option is set in
        _\bs_\bu_\bd_\bo_\be_\br_\bs, the command to be run has the SETENV tag set or the command
-       matched is ALL, the user may set variables that would overwise be
+       matched is ALL, the user may set variables that would otherwise be
        forbidden.  See _\bs_\bu_\bd_\bo_\be_\br_\bs(4) for more information.
 
 P\bPL\bLU\bUG\bGI\bIN\bNS\bS
@@ -332,6 +329,8 @@ P\bPL\bLU\bUG\bGI\bIN\bNS\bS
         #   Plugin plugin_name plugin_path
         #   Path askpass /path/to/askpass
         #   Path noexec /path/to/noexec.so
+        #   Debug sudo /var/log/sudo_debug all@warn
+        #   Set disable_coredump true
         #
         # The plugin_path is relative to /usr/local/libexec unless
         #   fully qualified.
@@ -379,6 +378,64 @@ P\bPA\bAT\bTH\bHS\bS
                        that support LD_PRELOAD or its equivalent.  Defaults to
                        _\b/_\bu_\bs_\br_\b/_\bl_\bo_\bc_\ba_\bl_\b/_\bl_\bi_\bb_\be_\bx_\be_\bc_\b/_\bs_\bu_\bd_\bo_\b__\bn_\bo_\be_\bx_\be_\bc_\b._\bs_\bo.
 
+D\bDE\bEB\bBU\bUG\bG F\bFL\bLA\bAG\bGS\bS
+       s\bsu\bud\bdo\bo versions 1.8.4 and higher support a flexible debugging framework
+       that can help track down what s\bsu\bud\bdo\bo is doing internally if there is a
+       problem.
+
+       A Debug line consists of the Debug keyword, followed by the name of the
+       program to debug (s\bsu\bud\bdo\bo, v\bvi\bis\bsu\bud\bdo\bo, s\bsu\bud\bdo\bor\bre\bep\bpl\bla\bay\by), the debug file name and a
+       comma-separated list of debug flags.  The debug flag syntax used by
+       s\bsu\bud\bdo\bo and the _\bs_\bu_\bd_\bo_\be_\br_\bs plugin is _\bs_\bu_\bb_\bs_\by_\bs_\bt_\be_\bm@_\bp_\br_\bi_\bo_\br_\bi_\bt_\by but the plugin is
+       free to use a different format so long as it does not include a command
+       ,.
+
+       For instance:
+
+        Debug sudo /var/log/sudo_debug all@warn,plugin@info
+
+       would log all debugging statements at the _\bw_\ba_\br_\bn level and higher in
+       addition to those at the _\bi_\bn_\bf_\bo level for the plugin subsystem.
+
+       Currently, only one Debug entry per program is supported.  The sudo
+       Debug entry is shared by the s\bsu\bud\bdo\bo front end, s\bsu\bud\bdo\boe\bed\bdi\bit\bt and the plugins.
+       A future release may add support for per-plugin Debug lines and/or
+       support for multiple debugging files for a single program.
+
+       The priorities used by the s\bsu\bud\bdo\bo front end, in order of decreasing
+       severity, are: _\bc_\br_\bi_\bt, _\be_\br_\br, _\bw_\ba_\br_\bn, _\bn_\bo_\bt_\bi_\bc_\be, _\bd_\bi_\ba_\bg, _\bi_\bn_\bf_\bo, _\bt_\br_\ba_\bc_\be and _\bd_\be_\bb_\bu_\bg.
+       Each priority, when specified, also includes all priorities higher than
+       it.  For example, a priority of _\bn_\bo_\bt_\bi_\bc_\be would include debug messages
+       logged at _\bn_\bo_\bt_\bi_\bc_\be and higher.
+
+       The following subsystems are used by s\bsu\bud\bdo\bo:
+
+       _\ba_\bl_\bl       matches every subsystem
+
+       _\ba_\br_\bg_\bs      command line argument processing
+
+       _\bc_\bo_\bn_\bv      user conversation
+
+       _\be_\bd_\bi_\bt      sudoedit
+
+       _\be_\bx_\be_\bc      command execution
+
+       _\bm_\ba_\bi_\bn      s\bsu\bud\bdo\bo main function
+
+       _\bn_\be_\bt_\bi_\bf     network interface handling
+
+       _\bp_\bc_\bo_\bm_\bm     communication with the plugin
+
+       _\bp_\bl_\bu_\bg_\bi_\bn    plugin configuration
+
+       _\bp_\bt_\by       pseudo-tty related code
+
+       _\bs_\be_\bl_\bi_\bn_\bu_\bx   SELinux-specific handling
+
+       _\bu_\bt_\bi_\bl      utility functions
+
+       _\bu_\bt_\bm_\bp      utmp handling
+
 R\bRE\bET\bTU\bUR\bRN\bN V\bVA\bAL\bLU\bUE\bES\bS
        Upon successful execution of a program, the exit status from s\bsu\bud\bdo\bo will
        simply be the exit status of the program that was executed.
@@ -415,6 +472,20 @@ S\bSE\bEC\bCU\bUR\bRI\bIT\bTY\bY N\bNO\bOT\bTE\bES\bS
        information, please see the PREVENTING SHELL ESCAPES section in
        _\bs_\bu_\bd_\bo_\be_\br_\bs(4).
 
+       To prevent the disclosure of potentially sensitive information, s\bsu\bud\bdo\bo
+       disables core dumps by default while it is executing (they are re-
+       enabled for the command that is run).  To aid in debugging s\bsu\bud\bdo\bo
+       crashes, you may wish to re-enable core dumps by setting
+       "disable_coredump" to false in the _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf file.
+
+        Set disable_coredump false
+
+       Note that by default, most operating systems disable core dumps from
+       setuid programs, which includes s\bsu\bud\bdo\bo.  To actually get a s\bsu\bud\bdo\bo core file
+       you may need to enable core dumps for setuid processes.  On BSD and
+       Linux systems this is accomplished via the sysctl command, on Solaris
+       the coreadm command can be used.
+
 E\bEN\bNV\bVI\bIR\bRO\bON\bNM\bME\bEN\bNT\bT
        s\bsu\bud\bdo\bo utilizes the following environment variables.  The security policy
        has control over the content of the command's environment.
@@ -460,7 +531,7 @@ E\bEN\bNV\bVI\bIR\bRO\bON\bNM\bME\bEN\bNT\bT
                        SUDO_EDITOR is not set
 
 F\bFI\bIL\bLE\bES\bS
-       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf          s\bsu\bud\bdo\bplugin and path configuration
+       _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf          s\bsu\bud\bdo\bfront end configuration
 
 E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
        Note: the following examples assume a properly configured security
@@ -507,8 +578,13 @@ A\bAU\bUT\bTH\bHO\bOR\bRS\bS
 
                Todd C. Miller
 
-       See the HISTORY file in the s\bsu\bud\bdo\bo distribution or visit
-       http://www.sudo.ws/sudo/history.html for a short history of s\bsu\bud\bdo\bo.
+       See the CONTRIBUTORS file in the s\bsu\bud\bdo\bo distribution
+       (http://www.sudo.ws/sudo/contributors.html) for a list of people who
+       have contributed to s\bsu\bud\bdo\bo.
+
+H\bHI\bIS\bST\bTO\bOR\bRY\bY
+       See the HISTORY file in the s\bsu\bud\bdo\bo distribution
+       (http://www.sudo.ws/sudo/history.html) for a brief history of sudo.
 
 C\bCA\bAV\bVE\bEA\bAT\bTS\bS
        There is no easy way to prevent a user from gaining a root shell if
@@ -547,4 +623,4 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
 
 
 
-1.8.3                         September 16, 2011                      SUDO(1m)
+1.8.4                          February  5, 2012                      SUDO(1m)
index c36d63b6427c924a1e72c1c2252824bb24c80f28..76931336cd7d711df180ab6a6f639bb585d3300d 100644 (file)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 1994-1996, 1998-2005, 2007-2011
+.\" Copyright (c) 1994-1996, 1998-2005, 2007-2012
 .\"    Todd C. Miller <Todd.Miller@courtesan.com>
 .\" 
 .\" Permission to use, copy, modify, and distribute this software for any
 .\" ========================================================================
 .\"
 .IX Title "SUDO @mansectsu@"
-.TH SUDO @mansectsu@ "September 16, 2011" "1.8.3" "MAINTENANCE COMMANDS"
+.TH SUDO @mansectsu@ "February  5, 2012" "1.8.4" "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\-D\fR\ \fIlevel\fR] \fB\-h\fR | \fB\-K\fR | \fB\-k\fR | \fB\-V\fR
+\&\fBsudo\fR \fB\-h\fR | \fB\-K\fR | \fB\-k\fR | \fB\-V\fR
 .PP
 \&\fBsudo\fR \fB\-v\fR [\fB\-AknS\fR]
 .if \n(BA [\fB\-a\fR\ \fIauth_type\fR]
-[\fB\-D\fR\ \fIlevel\fR]
 [\fB\-g\fR\ \fIgroup\ name\fR|\fI#gid\fR] [\fB\-p\fR\ \fIprompt\fR]
 [\fB\-u\fR\ \fIuser\ name\fR|\fI#uid\fR]
 .PP
 \&\fBsudo\fR \fB\-l[l]\fR [\fB\-AknS\fR]
 .if \n(BA [\fB\-a\fR\ \fIauth_type\fR]
-[\fB\-D\fR\ \fIlevel\fR]
 [\fB\-g\fR\ \fIgroup\ name\fR|\fI#gid\fR] [\fB\-p\fR\ \fIprompt\fR]
 [\fB\-U\fR\ \fIuser\ name\fR] [\fB\-u\fR\ \fIuser\ name\fR|\fI#uid\fR] [\fIcommand\fR]
 .PP
 \&\fBsudo\fR [\fB\-AbEHnPS\fR]
 .if \n(BA [\fB\-a\fR\ \fIauth_type\fR]
 [\fB\-C\fR\ \fIfd\fR]
-[\fB\-D\fR\ \fIlevel\fR]
 .if \n(LC [\fB\-c\fR\ \fIclass\fR|\fI\-\fR]
 [\fB\-g\fR\ \fIgroup\ name\fR|\fI#gid\fR] [\fB\-p\fR\ \fIprompt\fR]
 .if \n(SL [\fB\-r\fR\ \fIrole\fR] [\fB\-t\fR\ \fItype\fR]
@@ -186,7 +183,6 @@ sudo, sudoedit \- execute a command as another user
 .if \n(BA [\fB\-a\fR\ \fIauth_type\fR]
 [\fB\-C\fR\ \fIfd\fR]
 .if \n(LC [\fB\-c\fR\ \fIclass\fR|\fI\-\fR]
-[\fB\-D\fR\ \fIlevel\fR]
 [\fB\-g\fR\ \fIgroup\ name\fR|\fI#gid\fR] [\fB\-p\fR\ \fIprompt\fR]
 [\fB\-u\fR\ \fIuser\ name\fR|\fI#uid\fR] file ...
 .SH "DESCRIPTION"
@@ -200,7 +196,7 @@ option was specified).
 .PP
 \&\fBsudo\fR supports a plugin architecture for security policies and
 input/output logging.  Third parties can develop and distribute
-their own policy and I/O logging modules to work seemlessly with
+their own policy and I/O logging modules to work seamlessly with
 the \fBsudo\fR front end.  The default security policy is \fIsudoers\fR,
 which is configured via the file \fI@sysconfdir@/sudoers\fR, or via
 \&\s-1LDAP\s0.  See the \s-1PLUGINS\s0 section for more information.
@@ -288,10 +284,6 @@ argument specifies an existing user class, the command must be run
 as root, or the \fBsudo\fR command must be run from a shell that is already
 root.  This option is only available on systems with \s-1BSD\s0 login classes.
 \}
-.IP "\-D \fIlevel\fR" 12
-.IX Item "-D level"
-Enable debugging of \fBsudo\fR plugins and \fBsudo\fR itself.  The \fIlevel\fR
-may be a value from 1 through 9.
 .IP "\-E" 12
 .IX Item "-E"
 The \fB\-E\fR (\fIpreserve\fR \fIenvironment\fR) option indicates to the
@@ -520,7 +512,7 @@ command line are subject to the same restrictions as normal environment
 variables with one important exception.  If the \fIsetenv\fR option
 is set in \fIsudoers\fR, the command to be run has the \f(CW\*(C`SETENV\*(C'\fR tag
 set or the command matched is \f(CW\*(C`ALL\*(C'\fR, the user may set variables
-that would overwise be forbidden.  See \fIsudoers\fR\|(@mansectform@) for more information.
+that would otherwise be forbidden.  See \fIsudoers\fR\|(@mansectform@) for more information.
 .SH "PLUGINS"
 .IX Header "PLUGINS"
 Plugins are dynamically loaded based on the contents of the
@@ -537,6 +529,8 @@ which corresponds to the following \fI@sysconfdir@/sudo.conf\fR file.
 \& #   Plugin plugin_name plugin_path
 \& #   Path askpass /path/to/askpass
 \& #   Path noexec /path/to/noexec.so
+\& #   Debug sudo /var/log/sudo_debug all@warn
+\& #   Set disable_coredump true
 \& #
 \& # The plugin_path is relative to @prefix@/libexec unless
 \& #   fully qualified.
@@ -585,6 +579,80 @@ versions of the \fIexecv()\fR, \fIexecve()\fR and \fIfexecve()\fR library functi
 that just return an error.  This is used to implement the \fInoexec\fR
 functionality on systems that support \f(CW\*(C`LD_PRELOAD\*(C'\fR or its equivalent.
 Defaults to \fI@noexec_file@\fR.
+.SH "DEBUG FLAGS"
+.IX Header "DEBUG FLAGS"
+\&\fBsudo\fR versions 1.8.4 and higher support a flexible debugging
+framework that can help track down what \fBsudo\fR is doing internally
+if there is a problem.
+.PP
+A \f(CW\*(C`Debug\*(C'\fR line consists of the \f(CW\*(C`Debug\*(C'\fR keyword, followed by the
+name of the program to debug (\fBsudo\fR, \fBvisudo\fR, \fBsudoreplay\fR),
+the debug file name and a comma-separated list of debug flags.
+The debug flag syntax used by \fBsudo\fR and the \fIsudoers\fR plugin is
+\&\fIsubsystem\fR@\fIpriority\fR but the plugin is free to use a different
+format so long as it does not include a command \f(CW\*(C`,\*(C'\fR.
+.PP
+For instance:
+.PP
+.Vb 1
+\& Debug sudo /var/log/sudo_debug all@warn,plugin@info
+.Ve
+.PP
+would log all debugging statements at the \fIwarn\fR level and higher
+in addition to those at the \fIinfo\fR level for the plugin subsystem.
+.PP
+Currently, only one \f(CW\*(C`Debug\*(C'\fR entry per program is supported.  The
+\&\f(CW\*(C`sudo\*(C'\fR \f(CW\*(C`Debug\*(C'\fR entry is shared by the \fBsudo\fR front end, \fBsudoedit\fR
+and the plugins.  A future release may add support for per-plugin
+\&\f(CW\*(C`Debug\*(C'\fR lines and/or support for multiple debugging files for a
+single program.
+.PP
+The priorities used by the \fBsudo\fR front end, in order of decreasing
+severity, are: \fIcrit\fR, \fIerr\fR, \fIwarn\fR, \fInotice\fR, \fIdiag\fR, \fIinfo\fR,
+\&\fItrace\fR and \fIdebug\fR.  Each priority, when specified, also includes
+all priorities higher than it.  For example, a priority of \fInotice\fR
+would include debug messages logged at \fInotice\fR and higher.
+.PP
+The following subsystems are used by \fBsudo\fR:
+.IP "\fIall\fR" 10
+.IX Item "all"
+matches every subsystem
+.IP "\fIargs\fR" 10
+.IX Item "args"
+command line argument processing
+.IP "\fIconv\fR" 10
+.IX Item "conv"
+user conversation
+.IP "\fIedit\fR" 10
+.IX Item "edit"
+sudoedit
+.IP "\fIexec\fR" 10
+.IX Item "exec"
+command execution
+.IP "\fImain\fR" 10
+.IX Item "main"
+\&\fBsudo\fR main function
+.IP "\fInetif\fR" 10
+.IX Item "netif"
+network interface handling
+.IP "\fIpcomm\fR" 10
+.IX Item "pcomm"
+communication with the plugin
+.IP "\fIplugin\fR" 10
+.IX Item "plugin"
+plugin configuration
+.IP "\fIpty\fR" 10
+.IX Item "pty"
+pseudo-tty related code
+.IP "\fIselinux\fR" 10
+.IX Item "selinux"
+SELinux-specific handling
+.IP "\fIutil\fR" 10
+.IX Item "util"
+utility functions
+.IP "\fIutmp\fR" 10
+.IX Item "utmp"
+utmp handling
 .SH "RETURN VALUES"
 .IX Header "RETURN VALUES"
 Upon successful execution of a program, the exit status from \fBsudo\fR
@@ -622,6 +690,22 @@ Because of this, care must be taken when giving users access to
 commands via \fBsudo\fR to verify that the command does not inadvertently
 give the user an effective root shell.  For more information, please
 see the \f(CW\*(C`PREVENTING SHELL ESCAPES\*(C'\fR section in \fIsudoers\fR\|(@mansectform@).
+.PP
+To prevent the disclosure of potentially sensitive information,
+\&\fBsudo\fR disables core dumps by default while it is executing (they
+are re-enabled for the command that is run).  To aid in debugging
+\&\fBsudo\fR crashes, you may wish to re-enable core dumps by setting
+\&\*(L"disable_coredump\*(R" to false in the \fI@sysconfdir@/sudo.conf\fR file.
+.PP
+.Vb 1
+\& Set disable_coredump false
+.Ve
+.PP
+Note that by default, most operating systems disable core dumps
+from setuid programs, which includes \fBsudo\fR.  To actually get a
+\&\fBsudo\fR core file you may need to enable core dumps for setuid
+processes.  On \s-1BSD\s0 and Linux systems this is accomplished via the
+sysctl command, on Solaris the coreadm command can be used.
 .SH "ENVIRONMENT"
 .IX Header "ENVIRONMENT"
 \&\fBsudo\fR utilizes the following environment variables.  The security
@@ -698,7 +782,7 @@ is not set
 .ie n .IP "\fI@sysconfdir@/sudo.conf\fR" 24
 .el .IP "\fI@sysconfdir@/sudo.conf\fR" 24
 .IX Item "@sysconfdir@/sudo.conf"
-\&\fBsudo\fR plugin and path configuration
+\&\fBsudo\fR front end configuration
 .SH "EXAMPLES"
 .IX Header "EXAMPLES"
 Note: the following examples assume a properly configured security policy.
@@ -761,9 +845,13 @@ version consists of code written primarily by:
 \&        Todd C. Miller
 .Ve
 .PP
-See the \s-1HISTORY\s0 file in the \fBsudo\fR distribution or visit
-http://www.sudo.ws/sudo/history.html for a short history
-of \fBsudo\fR.
+See the \s-1CONTRIBUTORS\s0 file in the \fBsudo\fR distribution
+(http://www.sudo.ws/sudo/contributors.html) for a list of people
+who have contributed to \fBsudo\fR.
+.SH "HISTORY"
+.IX Header "HISTORY"
+See the \s-1HISTORY\s0 file in the \fBsudo\fR distribution
+(http://www.sudo.ws/sudo/history.html) for a brief history of sudo.
 .SH "CAVEATS"
 .IX Header "CAVEATS"
 There is no easy way to prevent a user from gaining a root shell
index 092146046983b0fc07c9090067111f7740d363be..13b1b84af76c1a89d817b647ba65c56df54b8a92 100644 (file)
@@ -1,4 +1,4 @@
-Copyright (c) 1994-1996, 1998-2005, 2007-2011
+Copyright (c) 1994-1996, 1998-2005, 2007-2012
        Todd C. Miller <Todd.Miller@courtesan.com>
 
 Permission to use, copy, modify, and distribute this software for any
@@ -26,24 +26,21 @@ sudo, sudoedit - execute a command as another user
 
 =head1 SYNOPSIS
 
-B<sudo> S<[B<-D> I<level>]> B<-h> | B<-K> | B<-k> | B<-V>
+B<sudo> B<-h> | B<-K> | B<-k> | B<-V>
 
 B<sudo> B<-v> [B<-AknS>]
 S<[B<-a> I<auth_type>]>
-S<[B<-D> I<level>]>
 S<[B<-g> I<group name>|I<#gid>]> S<[B<-p> I<prompt>]>
 S<[B<-u> I<user name>|I<#uid>]>
 
 B<sudo> B<-l[l]> [B<-AknS>]
 S<[B<-a> I<auth_type>]>
-S<[B<-D> I<level>]>
 S<[B<-g> I<group name>|I<#gid>]> S<[B<-p> I<prompt>]>
 S<[B<-U> I<user name>]> S<[B<-u> I<user name>|I<#uid>]> [I<command>]
 
 B<sudo> [B<-AbEHnPS>]
 S<[B<-a> I<auth_type>]>
 S<[B<-C> I<fd>]>
-S<[B<-D> I<level>]>
 S<[B<-c> I<class>|I<->]>
 S<[B<-g> I<group name>|I<#gid>]> S<[B<-p> I<prompt>]>
 S<[B<-r> I<role>]> S<[B<-t> I<type>]>
@@ -54,7 +51,6 @@ B<sudoedit> [B<-AnS>]
 S<[B<-a> I<auth_type>]>
 S<[B<-C> I<fd>]>
 S<[B<-c> I<class>|I<->]>
-S<[B<-D> I<level>]>
 S<[B<-g> I<group name>|I<#gid>]> S<[B<-p> I<prompt>]>
 S<[B<-u> I<user name>|I<#uid>]> file ...
 
@@ -69,7 +65,7 @@ option was specified).
 
 B<sudo> supports a plugin architecture for security policies and
 input/output logging.  Third parties can develop and distribute
-their own policy and I/O logging modules to work seemlessly with
+their own policy and I/O logging modules to work seamlessly with
 the B<sudo> front end.  The default security policy is I<sudoers>,
 which is configured via the file F<@sysconfdir@/sudoers>, or via
 LDAP.  See the L<PLUGINS> section for more information.
@@ -158,11 +154,6 @@ argument specifies an existing user class, the command must be run
 as root, or the B<sudo> command must be run from a shell that is already
 root.  This option is only available on systems with BSD login classes.
 
-=item -D I<level>
-
-Enable debugging of B<sudo> plugins and B<sudo> itself.  The I<level>
-may be a value from 1 through 9.
-
 =item -E
 
 The B<-E> (I<preserve> I<environment>) option indicates to the
@@ -416,7 +407,7 @@ command line are subject to the same restrictions as normal environment
 variables with one important exception.  If the I<setenv> option
 is set in I<sudoers>, the command to be run has the C<SETENV> tag
 set or the command matched is C<ALL>, the user may set variables
-that would overwise be forbidden.  See L<sudoers(5)> for more information.
+that would otherwise be forbidden.  See L<sudoers(5)> for more information.
 
 =head1 PLUGINS
 
@@ -433,6 +424,8 @@ which corresponds to the following F<@sysconfdir@/sudo.conf> file.
  #   Plugin plugin_name plugin_path
  #   Path askpass /path/to/askpass
  #   Path noexec /path/to/noexec.so
+ #   Debug sudo /var/log/sudo_debug all@warn
+ #   Set disable_coredump true
  #
  # The plugin_path is relative to @prefix@/libexec unless
  #   fully qualified.
@@ -486,6 +479,96 @@ Defaults to F<@noexec_file@>.
 
 =back
 
+=head1 DEBUG FLAGS
+
+B<sudo> versions 1.8.4 and higher support a flexible debugging
+framework that can help track down what B<sudo> is doing internally
+if there is a problem.
+
+A C<Debug> line consists of the C<Debug> keyword, followed by the
+name of the program to debug (B<sudo>, B<visudo>, B<sudoreplay>),
+the debug file name and a comma-separated list of debug flags.
+The debug flag syntax used by B<sudo> and the I<sudoers> plugin is
+I<subsystem>@I<priority> but the plugin is free to use a different
+format so long as it does not include a command C<,>.
+
+For instance:
+
+ Debug sudo /var/log/sudo_debug all@warn,plugin@info
+
+would log all debugging statements at the I<warn> level and higher
+in addition to those at the I<info> level for the plugin subsystem.
+
+Currently, only one C<Debug> entry per program is supported.  The
+C<sudo> C<Debug> entry is shared by the B<sudo> front end, B<sudoedit>
+and the plugins.  A future release may add support for per-plugin
+C<Debug> lines and/or support for multiple debugging files for a
+single program.
+
+The priorities used by the B<sudo> front end, in order of decreasing
+severity, are: I<crit>, I<err>, I<warn>, I<notice>, I<diag>, I<info>,
+I<trace> and I<debug>.  Each priority, when specified, also includes
+all priorities higher than it.  For example, a priority of I<notice>
+would include debug messages logged at I<notice> and higher.
+
+The following subsystems are used by B<sudo>:
+
+=over 10
+
+=item I<all>
+
+matches every subsystem
+
+=item I<args>
+
+command line argument processing
+
+=item I<conv>
+
+user conversation
+
+=item I<edit>
+
+sudoedit
+
+=item I<exec>
+
+command execution
+
+=item I<main>
+
+B<sudo> main function
+
+=item I<netif>
+
+network interface handling
+
+=item I<pcomm>
+
+communication with the plugin
+
+=item I<plugin>
+
+plugin configuration
+
+=item I<pty>
+
+pseudo-tty related code
+
+=item I<selinux>
+
+SELinux-specific handling
+
+=item I<util>
+
+utility functions
+
+=item I<utmp>
+
+utmp handling
+
+=back
+
 =head1 RETURN VALUES
 
 Upon successful execution of a program, the exit status from B<sudo>
@@ -525,6 +608,20 @@ commands via B<sudo> to verify that the command does not inadvertently
 give the user an effective root shell.  For more information, please
 see the C<PREVENTING SHELL ESCAPES> section in L<sudoers(5)>.
 
+To prevent the disclosure of potentially sensitive information,
+B<sudo> disables core dumps by default while it is executing (they
+are re-enabled for the command that is run).  To aid in debugging
+B<sudo> crashes, you may wish to re-enable core dumps by setting
+"disable_coredump" to false in the F<@sysconfdir@/sudo.conf> file.
+
+ Set disable_coredump false
+
+Note that by default, most operating systems disable core dumps
+from setuid programs, which includes B<sudo>.  To actually get a
+B<sudo> core file you may need to enable core dumps for setuid
+processes.  On BSD and Linux systems this is accomplished via the
+sysctl command, on Solaris the coreadm command can be used.
+
 =head1 ENVIRONMENT
 
 B<sudo> utilizes the following environment variables.  The security
@@ -607,7 +704,7 @@ is not set
 
 =item F<@sysconfdir@/sudo.conf>
 
-B<sudo> plugin and path configuration
+B<sudo> front end configuration
 
 =back
 
@@ -659,9 +756,14 @@ version consists of code written primarily by:
 
        Todd C. Miller
 
-See the HISTORY file in the B<sudo> distribution or visit
-http://www.sudo.ws/sudo/history.html for a short history
-of B<sudo>.
+See the CONTRIBUTORS file in the B<sudo> distribution
+(http://www.sudo.ws/sudo/contributors.html) for a list of people
+who have contributed to B<sudo>.
+
+=head1 HISTORY
+
+See the HISTORY file in the B<sudo> distribution
+(http://www.sudo.ws/sudo/history.html) for a brief history of sudo.
 
 =head1 CAVEATS
 
index 20cba64b64d421328a65ee5e41f15b471fb9b05e..54e13e1eb5e3d7a76b95cc47b8ea1c2ff9ad8458 100644 (file)
@@ -133,9 +133,31 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
                equal sign ('=') since the _\bn_\ba_\bm_\be field will never include one
                itself but the _\bv_\ba_\bl_\bu_\be might.
 
+               debug_flags=string
+                   A comma-separated list of debug flags that correspond to
+                   s\bsu\bud\bdo\bo's Debug entry in _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf, if there is one.  The
+                   flags are passed to the plugin as they appear in
+                   _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf.  The syntax used by s\bsu\bud\bdo\bo and the _\bs_\bu_\bd_\bo_\be_\br_\bs
+                   plugin is _\bs_\bu_\bb_\bs_\by_\bs_\bt_\be_\bm@_\bp_\br_\bi_\bo_\br_\bi_\bt_\by but the plugin is free to use
+                   a different format so long as it does not include a command
+                   ,.
+
+                   For reference, the priorities supported by the s\bsu\bud\bdo\bo front
+                   end and _\bs_\bu_\bd_\bo_\be_\br_\bs are: _\bc_\br_\bi_\bt, _\be_\br_\br, _\bw_\ba_\br_\bn, _\bn_\bo_\bt_\bi_\bc_\be, _\bd_\bi_\ba_\bg, _\bi_\bn_\bf_\bo,
+                   _\bt_\br_\ba_\bc_\be and _\bd_\be_\bb_\bu_\bg.
+
+                   The following subsystems are defined: _\bm_\ba_\bi_\bn, _\bm_\be_\bm_\bo_\br_\by, _\ba_\br_\bg_\bs,
+                   _\be_\bx_\be_\bc, _\bp_\bt_\by, _\bu_\bt_\bm_\bp, _\bc_\bo_\bn_\bv, _\bp_\bc_\bo_\bm_\bm, _\bu_\bt_\bi_\bl, _\bl_\bi_\bs_\bt, _\bn_\be_\bt_\bi_\bf, _\ba_\bu_\bd_\bi_\bt,
+                   _\be_\bd_\bi_\bt, _\bs_\be_\bl_\bi_\bn_\bu_\bx, _\bl_\bd_\ba_\bp, _\bm_\ba_\bt_\bc_\bh, _\bp_\ba_\br_\bs_\be_\br, _\ba_\bl_\bi_\ba_\bs, _\bd_\be_\bf_\ba_\bu_\bl_\bt_\bs, _\ba_\bu_\bt_\bh,
+                   _\be_\bn_\bv, _\bl_\bo_\bg_\bg_\bi_\bn_\bg, _\bn_\bs_\bs, _\br_\bb_\bt_\br_\be_\be, _\bp_\be_\br_\bm_\bs, _\bp_\bl_\bu_\bg_\bi_\bn.  The subsystem
+                   _\ba_\bl_\bl includes every subsystem.
+
+                   There is not currently a way to specify a set of debug
+                   flags specific to the plugin--the flags are shared by s\bsu\bud\bdo\bo
+                   and the plugin.
+
                debug_level=number
-                   A numeric debug level, from 1-9, if specified via the -D
-                   flag.
+                   This setting has been deprecated in favor of _\bd_\be_\bb_\bu_\bg_\b__\bf_\bl_\ba_\bg_\bs.
 
                runas_user=string
                    The user name or uid to to run the command as, if specified
@@ -875,6 +897,7 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
         #define SUDO_CONV_ERROR_MSG        0x0003 /* error message */
         #define SUDO_CONV_INFO_MSG         0x0004 /* informational message */
         #define SUDO_CONV_PROMPT_MASK      0x0005 /* mask user input */
+        #define SUDO_CONV_DEBUG_MSG        0x0006 /* debugging message */
         #define SUDO_CONV_PROMPT_ECHO_OK   0x1000 /* flag: allow echo if no tty */
             int msg_type;
             int timeout;
@@ -901,10 +924,17 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
        buffer filled in to the struct sudo_conv_reply, if any.
 
        The printf-style function uses the same underlying mechanism as the
-       conversation function but only supports SUDO_CONV_INFO_MSG and
-       SUDO_CONV_ERROR_MSG for the _\bm_\bs_\bg_\b__\bt_\by_\bp_\be parameter.  It can be more
-       convenient than using the conversation function if no user reply is
-       needed and supports standard _\bp_\br_\bi_\bn_\bt_\bf_\b(_\b) escape sequences.
+       conversation function but only supports SUDO_CONV_INFO_MSG,
+       SUDO_CONV_ERROR_MSG and SUDO_CONV_DEBUG_MSG for the _\bm_\bs_\bg_\b__\bt_\by_\bp_\be parameter.
+       It can be more convenient than using the conversation function if no
+       user reply is needed and supports standard _\bp_\br_\bi_\bn_\bt_\bf_\b(_\b) escape sequences.
+
+       Unlike, SUDO_CONV_INFO_MSG and SUDO_CONV_ERROR_MSG, messages sent with
+       the <SUDO_CONV_DEBUG_MSG> _\bm_\bs_\bg_\b__\bt_\by_\bp_\be are not directly user-visible.
+       Instead, they are logged to the file specified in the Debug statement
+       (if any) in the _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf file.  This allows a plugin to log
+       debugging information and is intended to be used in conjunction with
+       the _\bd_\be_\bb_\bu_\bg_\b__\bf_\bl_\ba_\bg_\bs setting.
 
        See the sample plugin for an example of the conversation function
        usage.
@@ -1030,4 +1060,4 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
 
 
 
-1.8.3                         September 16, 2011               SUDO_PLUGIN(1m)
+1.8.4                          January  6, 2012                SUDO_PLUGIN(1m)
index 7a161abdc2145e50be7526c0f3594993ab393092..5ae0118ac07403418c79fbb95194344514c52008 100644 (file)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2009-2011 Todd C. Miller <Todd.Miller@courtesan.com>
+.\" Copyright (c) 2009-2012 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
 .\" ========================================================================
 .\"
 .IX Title "SUDO_PLUGIN @mansectsu@"
-.TH SUDO_PLUGIN @mansectsu@ "September 16, 2011" "1.8.3" "MAINTENANCE COMMANDS"
+.TH SUDO_PLUGIN @mansectsu@ "January  6, 2012" "1.8.4" "MAINTENANCE COMMANDS"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -282,9 +282,30 @@ When parsing \fIsettings\fR, the plugin should split on the \fBfirst\fR
 equal sign ('=') since the \fIname\fR field will never include one
 itself but the \fIvalue\fR might.
 .RS 4
+.IP "debug_flags=string" 4
+.IX Item "debug_flags=string"
+A comma-separated list of debug flags that correspond to \fBsudo\fR's
+\&\f(CW\*(C`Debug\*(C'\fR entry in \fI@sysconfdir@/sudo.conf\fR, if there is one.  The
+flags are passed to the plugin as they appear in \fI@sysconfdir@/sudo.conf\fR.
+The syntax used by \fBsudo\fR and the \fIsudoers\fR plugin is
+\&\fIsubsystem\fR@\fIpriority\fR but the plugin is free to use a different
+format so long as it does not include a command \f(CW\*(C`,\*(C'\fR.
+.Sp
+For reference, the priorities supported by the \fBsudo\fR front end and
+\&\fIsudoers\fR are: \fIcrit\fR, \fIerr\fR, \fIwarn\fR, \fInotice\fR, \fIdiag\fR,
+\&\fIinfo\fR, \fItrace\fR and \fIdebug\fR.
+.Sp
+The following subsystems are defined: \fImain\fR, \fImemory\fR, \fIargs\fR,
+\&\fIexec\fR, \fIpty\fR, \fIutmp\fR, \fIconv\fR, \fIpcomm\fR, \fIutil\fR, \fIlist\fR,
+\&\fInetif\fR, \fIaudit\fR, \fIedit\fR, \fIselinux\fR, \fIldap\fR, \fImatch\fR, \fIparser\fR,
+\&\fIalias\fR, \fIdefaults\fR, \fIauth\fR, \fIenv\fR, \fIlogging\fR, \fInss\fR, \fIrbtree\fR,
+\&\fIperms\fR, \fIplugin\fR.  The subsystem \fIall\fR includes every subsystem.
+.Sp
+There is not currently a way to specify a set of debug flags specific
+to the plugin\*(--the flags are shared by \fBsudo\fR and the plugin.
 .IP "debug_level=number" 4
 .IX Item "debug_level=number"
-A numeric debug level, from 1\-9, if specified via the \f(CW\*(C`\-D\*(C'\fR flag.
+This setting has been deprecated in favor of \fIdebug_flags\fR.
 .IP "runas_user=string" 4
 .IX Item "runas_user=string"
 The user name or uid to to run the command as, if specified via the
@@ -1100,13 +1121,14 @@ A printf-style function is also available that can be used to display
 informational or error messages to the user, which is usually more
 convenient for simple messages where no use input is required.
 .PP
-.Vb 11
+.Vb 12
 \& struct sudo_conv_message {
 \& #define SUDO_CONV_PROMPT_ECHO_OFF  0x0001 /* do not echo user input */
 \& #define SUDO_CONV_PROMPT_ECHO_ON   0x0002 /* echo user input */
 \& #define SUDO_CONV_ERROR_MSG        0x0003 /* error message */
 \& #define SUDO_CONV_INFO_MSG         0x0004 /* informational message */
 \& #define SUDO_CONV_PROMPT_MASK      0x0005 /* mask user input */
+\& #define SUDO_CONV_DEBUG_MSG        0x0006 /* debugging message */
 \& #define SUDO_CONV_PROMPT_ECHO_OK   0x1000 /* flag: allow echo if no tty */
 \&     int msg_type;
 \&     int timeout;
@@ -1135,10 +1157,18 @@ freeing the reply buffer filled in to the \f(CW\*(C`struct sudo_conv_reply\*(C'\
 if any.
 .PP
 The printf-style function uses the same underlying mechanism as the
-conversation function but only supports \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR and
-\&\f(CW\*(C`SUDO_CONV_ERROR_MSG\*(C'\fR for the \fImsg_type\fR parameter.  It can be
-more convenient than using the conversation function if no user
-reply is needed and supports standard \fIprintf()\fR escape sequences.
+conversation function but only supports \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR,
+\&\f(CW\*(C`SUDO_CONV_ERROR_MSG\*(C'\fR and \f(CW\*(C`SUDO_CONV_DEBUG_MSG\*(C'\fR for the \fImsg_type\fR
+parameter.  It can be more convenient than using the conversation
+function if no user reply is needed and supports standard \fIprintf()\fR
+escape sequences.
+.PP
+Unlike, \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR and \f(CW\*(C`SUDO_CONV_ERROR_MSG\*(C'\fR, messages
+sent with the <\s-1SUDO_CONV_DEBUG_MSG\s0> \fImsg_type\fR are not directly
+user-visible.  Instead, they are logged to the file specified in
+the \f(CW\*(C`Debug\*(C'\fR statement (if any) in the \fI@sysconfdir@/sudo.conf\fR
+file.  This allows a plugin to log debugging information and is
+intended to be used in conjunction with the \fIdebug_flags\fR setting.
 .PP
 See the sample plugin for an example of the conversation function usage.
 .SS "Sudoers Group Plugin \s-1API\s0"
index 57021808852d5193c642fdbd0b715d2d752a5d27..3513cae0a27d03a67304451a6317c529010e04f2 100644 (file)
@@ -1,4 +1,4 @@
-Copyright (c) 2009-2011 Todd C. Miller <Todd.Miller@courtesan.com>
+Copyright (c) 2009-2012 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
@@ -163,9 +163,31 @@ itself but the I<value> might.
 
 =over 4
 
+=item debug_flags=string
+
+A comma-separated list of debug flags that correspond to B<sudo>'s
+C<Debug> entry in F<@sysconfdir@/sudo.conf>, if there is one.  The
+flags are passed to the plugin as they appear in F<@sysconfdir@/sudo.conf>.
+The syntax used by B<sudo> and the I<sudoers> plugin is
+I<subsystem>@I<priority> but the plugin is free to use a different
+format so long as it does not include a command C<,>.
+
+For reference, the priorities supported by the B<sudo> front end and
+I<sudoers> are: I<crit>, I<err>, I<warn>, I<notice>, I<diag>,
+I<info>, I<trace> and I<debug>.
+
+The following subsystems are defined: I<main>, I<memory>, I<args>,
+I<exec>, I<pty>, I<utmp>, I<conv>, I<pcomm>, I<util>, I<list>,
+I<netif>, I<audit>, I<edit>, I<selinux>, I<ldap>, I<match>, I<parser>,
+I<alias>, I<defaults>, I<auth>, I<env>, I<logging>, I<nss>, I<rbtree>,
+I<perms>, I<plugin>.  The subsystem I<all> includes every subsystem.
+
+There is not currently a way to specify a set of debug flags specific
+to the plugin--the flags are shared by B<sudo> and the plugin.
+
 =item debug_level=number
 
-A numeric debug level, from 1-9, if specified via the C<-D> flag.
+This setting has been deprecated in favor of I<debug_flags>.
 
 =item runas_user=string
 
@@ -1064,6 +1086,7 @@ convenient for simple messages where no use input is required.
  #define SUDO_CONV_ERROR_MSG       0x0003 /* error message */
  #define SUDO_CONV_INFO_MSG        0x0004 /* informational message */
  #define SUDO_CONV_PROMPT_MASK     0x0005 /* mask user input */
+ #define SUDO_CONV_DEBUG_MSG       0x0006 /* debugging message */
  #define SUDO_CONV_PROMPT_ECHO_OK   0x1000 /* flag: allow echo if no tty */
      int msg_type;
      int timeout;
@@ -1091,10 +1114,18 @@ freeing the reply buffer filled in to the C<struct sudo_conv_reply>,
 if any.
 
 The printf-style function uses the same underlying mechanism as the
-conversation function but only supports C<SUDO_CONV_INFO_MSG> and
-C<SUDO_CONV_ERROR_MSG> for the I<msg_type> parameter.  It can be
-more convenient than using the conversation function if no user
-reply is needed and supports standard printf() escape sequences.
+conversation function but only supports C<SUDO_CONV_INFO_MSG>,
+C<SUDO_CONV_ERROR_MSG> and C<SUDO_CONV_DEBUG_MSG> for the I<msg_type>
+parameter.  It can be more convenient than using the conversation
+function if no user reply is needed and supports standard printf()
+escape sequences.
+
+Unlike, C<SUDO_CONV_INFO_MSG> and C<SUDO_CONV_ERROR_MSG>, messages
+sent with the <SUDO_CONV_DEBUG_MSG> I<msg_type> are not directly
+user-visible.  Instead, they are logged to the file specified in
+the C<Debug> statement (if any) in the F<@sysconfdir@/sudo.conf>
+file.  This allows a plugin to log debugging information and is
+intended to be used in conjunction with the I<debug_flags> setting.
 
 See the sample plugin for an example of the conversation function usage.
 
index 2459758172ab19510b3a17915ee3c2e4a2fae192..b98c1e5afe5e9d9274d9ccb25358ae8c305b3478 100644 (file)
@@ -65,10 +65,11 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
        distinct ways _\bs_\bu_\bd_\bo_\be_\br_\bs can deal with environment variables.
 
        By default, the _\be_\bn_\bv_\b__\br_\be_\bs_\be_\bt option is enabled.  This causes commands to
-       be executed with a minimal environment containing TERM, PATH, HOME,
-       MAIL, SHELL, LOGNAME, USER and USERNAME in addition to variables from
-       the invoking process permitted by the _\be_\bn_\bv_\b__\bc_\bh_\be_\bc_\bk and _\be_\bn_\bv_\b__\bk_\be_\be_\bp options.
-       This is effectively a whitelist for environment variables.
+       be executed with a minimal environment containing the TERM, PATH, HOME,
+       MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables in addition
+       to variables from the invoking process permitted by the _\be_\bn_\bv_\b__\bc_\bh_\be_\bc_\bk and
+       _\be_\bn_\bv_\b__\bk_\be_\be_\bp options.  This is effectively a whitelist for environment
+       variables.
 
        If, however, the _\be_\bn_\bv_\b__\br_\be_\bs_\be_\bt option is disabled, any variables not
        explicitly denied by the _\be_\bn_\bv_\b__\bc_\bh_\be_\bc_\bk and _\be_\bn_\bv_\b__\bd_\be_\bl_\be_\bt_\be options are inherited
@@ -97,6 +98,9 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
        On Linux and AIX systems the contents of _\b/_\be_\bt_\bc_\b/_\be_\bn_\bv_\bi_\br_\bo_\bn_\bm_\be_\bn_\bt are also
        included.  All other environment variables are removed.
 
+       Lastly, if the _\be_\bn_\bv_\b__\bf_\bi_\bl_\be option is defined, any variables present in
+       that file will be set to their specified values.
+
 S\bSU\bUD\bDO\bOE\bER\bRS\bS F\bFI\bIL\bLE\bE F\bFO\bOR\bRM\bMA\bAT\bT
        The _\bs_\bu_\bd_\bo_\be_\br_\bs file is composed of two types of entries: aliases
        (basically variables) and user specifications (which specify who may
@@ -560,8 +564,16 @@ S\bSU\bUD\bDO\bOE\bER\bRS\bS F\bFI\bIL\bLE\bE F\bFO\bOR\bRM\bMA\bAT\bT
        A hard limit of 128 nested include files is enforced to prevent include
        file loops.
 
-       The file name may include the %h escape, signifying the short form of
-       the host name.  I.e., if the machine's host name is "xerxes", then
+       If the path to the include file is not fully-qualified (does not begin
+       with a _\b/), it must be located in the same directory as the sudoers file
+       it was included from.  For example, if _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs contains the line:
+
+           #include sudoers.local
+
+       the file that will be included is _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bl_\bo_\bc_\ba_\bl.
+
+       The file name may also include the %h escape, signifying the short form
+       of the host name.  I.e., if the machine's host name is "xerxes", then
 
        #include /etc/sudoers.%h
 
@@ -662,15 +674,18 @@ S\bSU\bUD\bDO\bOE\bER\bRS\bS O\bOP\bPT\bTI\bIO\bON\bNS\bS
                        use the EDITOR or VISUAL if they match a value
                        specified in editor.  This flag is _\bo_\bf_\bf by default.
 
-       env_reset       If set, s\bsu\bud\bdo\bo will reset the environment to only contain
-                       the LOGNAME, MAIL, SHELL, USER, USERNAME and the SUDO_*
-                       variables.  Any variables in the caller's environment
-                       that match the env_keep and env_check lists are then
-                       added.  The default contents of the env_keep and
-                       env_check lists are displayed when s\bsu\bud\bdo\bo is run by root
-                       with the _\b-_\bV option.  If the _\bs_\be_\bc_\bu_\br_\be_\b__\bp_\ba_\bt_\bh option is set,
-                       its value will be used for the PATH environment
-                       variable.  This flag is _\bo_\bn by default.
+       env_reset       If set, s\bsu\bud\bdo\bo will run the command in a minimal
+                       environment containing the TERM, PATH, HOME, MAIL,
+                       SHELL, LOGNAME, USER, USERNAME and SUDO_* variables.
+                       Any variables in the caller's environment that match
+                       the env_keep and env_check lists are then added,
+                       followed by any variables present in the file specified
+                       by the _\be_\bn_\bv_\b__\bf_\bi_\bl_\be option (if any).  The default contents
+                       of the env_keep and env_check lists are displayed when
+                       s\bsu\bud\bdo\bo is run by root with the _\b-_\bV option.  If the
+                       _\bs_\be_\bc_\bu_\br_\be_\b__\bp_\ba_\bt_\bh option is set, its value will be used for
+                       the PATH environment variable.  This flag is _\bo_\bn 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 path names.  However,
@@ -1087,9 +1102,9 @@ S\bSU\bUD\bDO\bOE\bER\bRS\bS O\bOP\bPT\bTI\bIO\bON\bNS\bS
                        %h will expand to the host name of the machine.
                        Default is *** SECURITY information for %h ***.
 
-       noexec_file     This option is deprecated and will be removed in a
-                       future release of s\bsu\bud\bdo\bo.  The path to the noexec file
-                       should now be set in the _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bfile.
+       noexec_file     This option is no longer supported.  The path to the
+                       noexec file should now be set in the _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf
+                       file.
 
        passprompt      The default prompt to use when asking for a password;
                        can be overridden via the -\b-p\bp option or the SUDO_PROMPT
@@ -1158,8 +1173,8 @@ S\bSU\bUD\bDO\bOE\bER\bRS\bS O\bOP\bPT\bTI\bIO\bON\bNS\bS
 
        S\bSt\btr\bri\bin\bng\bgs\bs t\bth\bha\bat\bt c\bca\ban\bn b\bbe\be u\bus\bse\bed\bd i\bin\bn a\ba b\bbo\boo\bol\ble\bea\ban\bn c\bco\bon\bnt\bte\bex\bxt\bt:
 
-       env_file    The _\be_\bn_\bv_\b__\bf_\bi_\bl_\be options specifies the fully qualified path to
-                   file containing variables to be set in the environment of
+       env_file    The _\be_\bn_\bv_\b__\bf_\bi_\bl_\be option 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 VARIABLE=value or export VARIABLE=value.
                    The value may optionally be surrounded by single or double
@@ -1606,6 +1621,57 @@ 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
        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.
 
+D\bDE\bEB\bBU\bUG\bG F\bFL\bLA\bAG\bGS\bS
+       Versions 1.8.4 and higher of the _\bs_\bu_\bd_\bo_\be_\br_\bs plugin supports a debugging
+       framework that can help track down what the plugin is doing internally
+       if there is a problem.  This can be configured in the _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf
+       file as described in _\bs_\bu_\bd_\bo(1m).
+
+       The _\bs_\bu_\bd_\bo_\be_\br_\bs plugin uses the same debug flag format as s\bsu\bud\bdo\bo itself:
+       _\bs_\bu_\bb_\bs_\by_\bs_\bt_\be_\bm@_\bp_\br_\bi_\bo_\br_\bi_\bt_\by.
+
+       The priorities used by _\bs_\bu_\bd_\bo_\be_\br_\bs, in order of decreasing severity, are:
+       _\bc_\br_\bi_\bt, _\be_\br_\br, _\bw_\ba_\br_\bn, _\bn_\bo_\bt_\bi_\bc_\be, _\bd_\bi_\ba_\bg, _\bi_\bn_\bf_\bo, _\bt_\br_\ba_\bc_\be and _\bd_\be_\bb_\bu_\bg.  Each priority,
+       when specified, also includes all priorities higher than it.  For
+       example, a priority of _\bn_\bo_\bt_\bi_\bc_\be would include debug messages logged at
+       _\bn_\bo_\bt_\bi_\bc_\be and higher.
+
+       The following subsystems are used by _\bs_\bu_\bd_\bo_\be_\br_\bs:
+
+       _\ba_\bl_\bi_\ba_\bs     User_Alias, Runas_Alias, Host_Alias and Cmnd_Alias processing
+
+       _\ba_\bl_\bl       matches every subsystem
+
+       _\ba_\bu_\bd_\bi_\bt     BSM and Linux audit code
+
+       _\ba_\bu_\bt_\bh      user authentication
+
+       _\bd_\be_\bf_\ba_\bu_\bl_\bt_\bs  _\bs_\bu_\bd_\bo_\be_\br_\bs _\bD_\be_\bf_\ba_\bu_\bl_\bt_\bs settings
+
+       _\be_\bn_\bv       environment handling
+
+       _\bl_\bd_\ba_\bp      LDAP-based sudoers
+
+       _\bl_\bo_\bg_\bg_\bi_\bn_\bg   logging support
+
+       _\bm_\ba_\bt_\bc_\bh     matching of users, groups, hosts and netgroups in _\bs_\bu_\bd_\bo_\be_\br_\bs
+
+       _\bn_\be_\bt_\bi_\bf     network interface handling
+
+       _\bn_\bs_\bs       network service switch handling in _\bs_\bu_\bd_\bo_\be_\br_\bs
+
+       _\bp_\ba_\br_\bs_\be_\br    _\bs_\bu_\bd_\bo_\be_\br_\bs file parsing
+
+       _\bp_\be_\br_\bm_\bs     permission setting
+
+       _\bp_\bl_\bu_\bg_\bi_\bn    The equivalent of _\bm_\ba_\bi_\bn for the plugin.
+
+       _\bp_\bt_\by       pseudo-tty related code
+
+       _\br_\bb_\bt_\br_\be_\be    redblack tree internals
+
+       _\bu_\bt_\bi_\bl      utility functions
+
 S\bSE\bEC\bCU\bUR\bRI\bIT\bTY\bY N\bNO\bOT\bTE\bES\bS
        _\bs_\bu_\bd_\bo_\be_\br_\bs will check the ownership of its time stamp directory
        (_\b/_\bv_\ba_\br_\b/_\ba_\bd_\bm_\b/_\bs_\bu_\bd_\bo by default) and ignore the directory's contents if it is
@@ -1683,4 +1749,4 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
 
 
 
-1.8.3                         September 16, 2011                    SUDOERS(4)
+1.8.4                          February  5, 2012                    SUDOERS(4)
index 2b5e854592aea04036019c7db654183af35adf11..fcbc56a03d0af998d48630125d805ddaf709a3f3 100644 (file)
@@ -71,8 +71,9 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
        following attributes:
 
        s\bsu\bud\bdo\boU\bUs\bse\ber\br
-           A user name, uid (prefixed with '#'), Unix group (prefixed with a
-           '%') or user netgroup (prefixed with a '+').
+           A user name, user ID (prefixed with '#'), Unix group (prefixed with
+           '%'), Unix group ID (prefixed with '%#'), or user netgroup
+           (prefixed with '+').
 
        s\bsu\bud\bdo\boH\bHo\bos\bst\bt
            A host name, IP address, IP network, or host netgroup (prefixed
@@ -746,4 +747,4 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
 
 
 
-1.8.3                         September 16, 2011               SUDOERS.LDAP(4)
+1.8.4                          January  6, 2012                SUDOERS.LDAP(4)
index 7732d38be9b32970f9193ad7847ade3bf1a8be2a..b7d38c278996f7fc51bfb86aabeab9213f346a56 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "SUDOERS.LDAP @mansectform@"
-.TH SUDOERS.LDAP @mansectform@ "September 16, 2011" "1.8.3" "MAINTENANCE COMMANDS"
+.TH SUDOERS.LDAP @mansectform@ "January  6, 2012" "1.8.4" "MAINTENANCE COMMANDS"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -216,8 +216,9 @@ The equivalent of a sudoer in \s-1LDAP\s0 is a \f(CW\*(C`sudoRole\*(C'\fR.  It c
 the following attributes:
 .IP "\fBsudoUser\fR" 4
 .IX Item "sudoUser"
-A user name, uid (prefixed with \f(CW\*(Aq#\*(Aq\fR), Unix group (prefixed with
-a \f(CW\*(Aq%\*(Aq\fR) or user netgroup (prefixed with a \f(CW\*(Aq+\*(Aq\fR).
+A user name, user \s-1ID\s0 (prefixed with \f(CW\*(Aq#\*(Aq\fR), Unix group (prefixed with
+\&\f(CW\*(Aq%\*(Aq\fR), Unix group \s-1ID\s0 (prefixed with \f(CW\*(Aq%#\*(Aq\fR), or user netgroup
+(prefixed with \f(CW\*(Aq+\*(Aq\fR).
 .IP "\fBsudoHost\fR" 4
 .IX Item "sudoHost"
 A host name, \s-1IP\s0 address, \s-1IP\s0 network, or host netgroup (prefixed
index 88c60155ceabe3bd1ae65f937ebc595c2600724a..f6a2beed212bf4c281fc990207d6351c5740a87d 100644 (file)
@@ -103,8 +103,9 @@ the following attributes:
 
 =item B<sudoUser>
 
-A user name, uid (prefixed with C<'#'>), Unix group (prefixed with
-a C<'%'>) or user netgroup (prefixed with a C<'+'>).
+A user name, user ID (prefixed with C<'#'>), Unix group (prefixed with
+C<'%'>), Unix group ID (prefixed with C<'%#'>), or user netgroup
+(prefixed with C<'+'>).
 
 =item B<sudoHost>
 
index 59e9a31fbd98bf1fd2c8e44ebe9485220968110a..ef7ddd67c1b7c8c446a916693f7e45f262e77ef3 100644 (file)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 1994-1996, 1998-2005, 2007-2011
+.\" Copyright (c) 1994-1996, 1998-2005, 2007-2012
 .\"    Todd C. Miller <Todd.Miller@courtesan.com>
 .\" 
 .\" Permission to use, copy, modify, and distribute this software for any
 .\" ========================================================================
 .\"
 .IX Title "SUDOERS @mansectform@"
-.TH SUDOERS @mansectform@ "September 16, 2011" "1.8.3" "MAINTENANCE COMMANDS"
+.TH SUDOERS @mansectform@ "February  5, 2012" "1.8.4" "MAINTENANCE COMMANDS"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -218,11 +218,11 @@ environment are inherited by the command to be run.  There are two
 distinct ways \fIsudoers\fR can deal with environment variables.
 .PP
 By default, the \fIenv_reset\fR option is enabled.  This causes commands
-to be executed with a minimal environment containing \f(CW\*(C`TERM\*(C'\fR,
-\&\f(CW\*(C`PATH\*(C'\fR, \f(CW\*(C`HOME\*(C'\fR, \f(CW\*(C`MAIL\*(C'\fR, \f(CW\*(C`SHELL\*(C'\fR, \f(CW\*(C`LOGNAME\*(C'\fR, \f(CW\*(C`USER\*(C'\fR and \f(CW\*(C`USERNAME\*(C'\fR in
-addition to variables from the invoking process permitted by the
-\&\fIenv_check\fR and \fIenv_keep\fR options.  This is effectively a whitelist
-for environment variables.
+to be executed with a minimal environment containing the \f(CW\*(C`TERM\*(C'\fR,
+\&\f(CW\*(C`PATH\*(C'\fR, \f(CW\*(C`HOME\*(C'\fR, \f(CW\*(C`MAIL\*(C'\fR, \f(CW\*(C`SHELL\*(C'\fR, \f(CW\*(C`LOGNAME\*(C'\fR, \f(CW\*(C`USER\*(C'\fR, \f(CW\*(C`USERNAME\*(C'\fR
+and \f(CW\*(C`SUDO_*\*(C'\fR variables in addition to variables from the
+invoking process permitted by the \fIenv_check\fR and \fIenv_keep\fR
+options.  This is effectively a whitelist for environment variables.
 .PP
 If, however, the \fIenv_reset\fR option is disabled, any variables not
 explicitly denied by the \fIenv_check\fR and \fIenv_delete\fR options are
@@ -251,6 +251,9 @@ variables remain unchanged; \fI\s-1HOME\s0\fR, \fI\s-1MAIL\s0\fR, \fI\s-1SHELL\s
 and \fI\s-1LOGNAME\s0\fR are set based on the target user.  On Linux and \s-1AIX\s0
 systems the contents of \fI/etc/environment\fR are also included.  All
 other environment variables are removed.
+.PP
+Lastly, if the \fIenv_file\fR option is defined, any variables present
+in that file will be set to their specified values.
 .SH "SUDOERS FILE FORMAT"
 .IX Header "SUDOERS FILE FORMAT"
 The \fIsudoers\fR file is composed of two types of entries: aliases
@@ -805,7 +808,18 @@ Upon reaching the end of \fI/etc/sudoers.local\fR, the rest of
 themselves include other files.  A hard limit of 128 nested include
 files is enforced to prevent include file loops.
 .PP
-The file name may include the \f(CW%h\fR escape, signifying the short form
+If the path to the include file is not fully-qualified (does not
+begin with a \fI/\fR), it must be located in the same directory as the
+sudoers file it was included from.  For example, if \fI/etc/sudoers\fR
+contains the line:
+.Sp
+.RS 4
+\&\f(CW\*(C`#include sudoers.local\*(C'\fR
+.RE
+.PP
+the file that will be included is \fI/etc/sudoers.local\fR.
+.PP
+The file name may also include the \f(CW%h\fR escape, signifying the short form
 of the host name.  I.e., if the machine's host name is \*(L"xerxes\*(R", then
 .PP
 \&\f(CW\*(C`#include /etc/sudoers.%h\*(C'\fR
@@ -910,14 +924,17 @@ they match a value specified in \f(CW\*(C`editor\*(C'\fR.  This flag is \fI@env_
 default.
 .IP "env_reset" 16
 .IX Item "env_reset"
-If set, \fBsudo\fR will reset the environment to only contain the
-\&\s-1LOGNAME\s0, \s-1MAIL\s0, \s-1SHELL\s0, \s-1USER\s0, \s-1USERNAME\s0 and the \f(CW\*(C`SUDO_*\*(C'\fR variables.  Any
+If set, \fBsudo\fR will run the command in a minimal environment
+containing the \f(CW\*(C`TERM\*(C'\fR, \f(CW\*(C`PATH\*(C'\fR, \f(CW\*(C`HOME\*(C'\fR, \f(CW\*(C`MAIL\*(C'\fR, \f(CW\*(C`SHELL\*(C'\fR,
+\&\f(CW\*(C`LOGNAME\*(C'\fR, \f(CW\*(C`USER\*(C'\fR, \f(CW\*(C`USERNAME\*(C'\fR and \f(CW\*(C`SUDO_*\*(C'\fR variables.  Any
 variables in the caller's environment that match the \f(CW\*(C`env_keep\*(C'\fR
-and \f(CW\*(C`env_check\*(C'\fR lists are then added.  The default contents of the
-\&\f(CW\*(C`env_keep\*(C'\fR and \f(CW\*(C`env_check\*(C'\fR lists are displayed when \fBsudo\fR is
-run by root with the \fI\-V\fR option.  If the \fIsecure_path\fR option
-is set, its value will be used for the \f(CW\*(C`PATH\*(C'\fR environment variable.
-This flag is \fI@env_reset@\fR by default.
+and \f(CW\*(C`env_check\*(C'\fR lists are then added, followed by any variables
+present in the file specified by the \fIenv_file\fR option (if any).
+The default contents of the \f(CW\*(C`env_keep\*(C'\fR and \f(CW\*(C`env_check\*(C'\fR lists are
+displayed when \fBsudo\fR is run by root with the \fI\-V\fR option.  If
+the \fIsecure_path\fR option is set, its value will be used for the
+\&\f(CW\*(C`PATH\*(C'\fR environment variable.  This flag is \fI@env_reset@\fR by
+default.
 .IP "fast_glob" 16
 .IX Item "fast_glob"
 Normally, \fBsudo\fR uses the \fIglob\fR\|(3) function to do shell-style
@@ -1337,9 +1354,8 @@ will expand to the host name of the machine.
 Default is \f(CW\*(C`@mailsub@\*(C'\fR.
 .IP "noexec_file" 16
 .IX Item "noexec_file"
-This option is deprecated and will be removed in a future release
-of \fBsudo\fR.  The path to the noexec file should now be set in the
-\&\fI@sysconfdir@/sudo.conf\fR file.
+This option is no longer supported.  The path to the noexec file
+should now be set in the \fI@sysconfdir@/sudo.conf\fR file.
 .IP "passprompt" 16
 .IX Item "passprompt"
 The default prompt to use when asking for a password; can be overridden
@@ -1429,7 +1445,7 @@ This option is only available whe \fBsudo\fR is built with SELinux support.
 \&\fBStrings that can be used in a boolean context\fR:
 .IP "env_file" 12
 .IX Item "env_file"
-The \fIenv_file\fR options specifies the fully qualified path to a
+The \fIenv_file\fR option 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
@@ -1956,6 +1972,74 @@ operations (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
 \&\fBsudoedit\fR.
+.SH "DEBUG FLAGS"
+.IX Header "DEBUG FLAGS"
+Versions 1.8.4 and higher of the \fIsudoers\fR plugin supports a
+debugging framework that can help track down what the plugin is
+doing internally if there is a problem.  This can be configured in
+the \fI@sysconfdir@/sudo.conf\fR file as described in \fIsudo\fR\|(@mansectsu@).
+.PP
+The \fIsudoers\fR plugin uses the same debug flag format as \fBsudo\fR
+itself: \fIsubsystem\fR@\fIpriority\fR.
+.PP
+The priorities used by \fIsudoers\fR, in order of decreasing severity,
+are: \fIcrit\fR, \fIerr\fR, \fIwarn\fR, \fInotice\fR, \fIdiag\fR, \fIinfo\fR, \fItrace\fR
+and \fIdebug\fR.  Each priority, when specified, also includes all
+priorities higher than it.  For example, a priority of \fInotice\fR
+would include debug messages logged at \fInotice\fR and higher.
+.PP
+The following subsystems are used by \fIsudoers\fR:
+.IP "\fIalias\fR" 10
+.IX Item "alias"
+\&\f(CW\*(C`User_Alias\*(C'\fR, \f(CW\*(C`Runas_Alias\*(C'\fR, \f(CW\*(C`Host_Alias\*(C'\fR and \f(CW\*(C`Cmnd_Alias\*(C'\fR processing
+.IP "\fIall\fR" 10
+.IX Item "all"
+matches every subsystem
+.IP "\fIaudit\fR" 10
+.IX Item "audit"
+\&\s-1BSM\s0 and Linux audit code
+.IP "\fIauth\fR" 10
+.IX Item "auth"
+user authentication
+.IP "\fIdefaults\fR" 10
+.IX Item "defaults"
+\&\fIsudoers\fR \fIDefaults\fR settings
+.IP "\fIenv\fR" 10
+.IX Item "env"
+environment handling
+.IP "\fIldap\fR" 10
+.IX Item "ldap"
+LDAP-based sudoers
+.IP "\fIlogging\fR" 10
+.IX Item "logging"
+logging support
+.IP "\fImatch\fR" 10
+.IX Item "match"
+matching of users, groups, hosts and netgroups in \fIsudoers\fR
+.IP "\fInetif\fR" 10
+.IX Item "netif"
+network interface handling
+.IP "\fInss\fR" 10
+.IX Item "nss"
+network service switch handling in \fIsudoers\fR
+.IP "\fIparser\fR" 10
+.IX Item "parser"
+\&\fIsudoers\fR file parsing
+.IP "\fIperms\fR" 10
+.IX Item "perms"
+permission setting
+.IP "\fIplugin\fR" 10
+.IX Item "plugin"
+The equivalent of \fImain\fR for the plugin.
+.IP "\fIpty\fR" 10
+.IX Item "pty"
+pseudo-tty related code
+.IP "\fIrbtree\fR" 10
+.IX Item "rbtree"
+redblack tree internals
+.IP "\fIutil\fR" 10
+.IX Item "util"
+utility functions
 .SH "SECURITY NOTES"
 .IX Header "SECURITY NOTES"
 \&\fIsudoers\fR will check the ownership of its time stamp directory
index 0ecb74c811461851d45fbb0d520ba9500aa4215e..32c39bce2f02edf9719205ebc552e2de263554bc 100644 (file)
@@ -1,4 +1,4 @@
-Copyright (c) 1994-1996, 1998-2005, 2007-2011
+Copyright (c) 1994-1996, 1998-2005, 2007-2012
        Todd C. Miller <Todd.Miller@courtesan.com>
 
 Permission to use, copy, modify, and distribute this software for any
@@ -89,11 +89,11 @@ environment are inherited by the command to be run.  There are two
 distinct ways I<sudoers> can deal with environment variables.
 
 By default, the I<env_reset> option is enabled.  This causes commands
-to be executed with a minimal environment containing C<TERM>,
-C<PATH>, C<HOME>, C<MAIL>, C<SHELL>, C<LOGNAME>, C<USER> and C<USERNAME> in
-addition to variables from the invoking process permitted by the
-I<env_check> and I<env_keep> options.  This is effectively a whitelist
-for environment variables.
+to be executed with a minimal environment containing the C<TERM>,
+C<PATH>, C<HOME>, C<MAIL>, C<SHELL>, C<LOGNAME>, C<USER>, C<USERNAME>
+and C<SUDO_*> variables in addition to variables from the
+invoking process permitted by the I<env_check> and I<env_keep>
+options.  This is effectively a whitelist for environment variables.
 
 If, however, the I<env_reset> option is disabled, any variables not
 explicitly denied by the I<env_check> and I<env_delete> options are
@@ -123,6 +123,9 @@ and I<LOGNAME> are set based on the target user.  On Linux and AIX
 systems the contents of F</etc/environment> are also included.  All
 other environment variables are removed.
 
+Lastly, if the I<env_file> option is defined, any variables present
+in that file will be set to their specified values.
+
 =head1 SUDOERS FILE FORMAT
 
 The I<sudoers> file is composed of two types of entries: aliases
@@ -655,7 +658,20 @@ 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 file name may include the C<%h> escape, signifying the short form
+If the path to the include file is not fully-qualified (does not
+begin with a F</>), it must be located in the same directory as the
+sudoers file it was included from.  For example, if F</etc/sudoers>
+contains the line:
+
+=over 4
+
+C<#include sudoers.local>
+
+=back
+
+the file that will be included is F</etc/sudoers.local>.
+
+The file name may also include the C<%h> escape, signifying the short form
 of the host name.  I.e., if the machine's host name is "xerxes", then
 
 C<#include /etc/sudoers.%h>
@@ -770,14 +786,17 @@ default.
 
 =item env_reset
 
-If set, B<sudo> will reset the environment to only contain the
-LOGNAME, MAIL, SHELL, USER, USERNAME and the C<SUDO_*> variables.  Any
+If set, B<sudo> will run the command in a minimal environment
+containing the C<TERM>, C<PATH>, C<HOME>, C<MAIL>, C<SHELL>,
+C<LOGNAME>, C<USER>, C<USERNAME> and C<SUDO_*> variables.  Any
 variables in the caller's environment that match the C<env_keep>
-and C<env_check> lists are then added.  The default contents of the
-C<env_keep> and C<env_check> lists are displayed when B<sudo> is
-run by root with the I<-V> option.  If the I<secure_path> option
-is set, its value will be used for the C<PATH> environment variable.
-This flag is I<@env_reset@> by default.
+and C<env_check> lists are then added, followed by any variables
+present in the file specified by the I<env_file> option (if any).
+The default contents of the C<env_keep> and C<env_check> lists are
+displayed when B<sudo> is run by root with the I<-V> option.  If
+the I<secure_path> option is set, its value will be used for the
+C<PATH> environment variable.  This flag is I<@env_reset@> by
+default.
 
 =item fast_glob
 
@@ -1256,9 +1275,8 @@ Default is C<@mailsub@>.
 
 =item noexec_file
 
-This option is deprecated and will be removed in a future release
-of B<sudo>.  The path to the noexec file should now be set in the
-F<@sysconfdir@/sudo.conf> file.
+This option is no longer supported.  The path to the noexec file
+should now be set in the F<@sysconfdir@/sudo.conf> file.
 
 =item passprompt
 
@@ -1358,7 +1376,7 @@ B<Strings that can be used in a boolean context>:
 
 =item env_file
 
-The I<env_file> options specifies the fully qualified path to a
+The I<env_file> option 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
@@ -1885,6 +1903,96 @@ to unintended privilege escalation.  In the specific case of an
 editor, a safer approach is to give the user permission to run
 B<sudoedit>.
 
+=head1 DEBUG FLAGS
+
+Versions 1.8.4 and higher of the I<sudoers> plugin supports a
+debugging framework that can help track down what the plugin is
+doing internally if there is a problem.  This can be configured in
+the F<@sysconfdir@/sudo.conf> file as described in L<sudo(8)>.
+
+The I<sudoers> plugin uses the same debug flag format as B<sudo>
+itself: I<subsystem>@I<priority>.
+
+The priorities used by I<sudoers>, in order of decreasing severity,
+are: I<crit>, I<err>, I<warn>, I<notice>, I<diag>, I<info>, I<trace>
+and I<debug>.  Each priority, when specified, also includes all
+priorities higher than it.  For example, a priority of I<notice>
+would include debug messages logged at I<notice> and higher.
+
+The following subsystems are used by I<sudoers>:
+
+=over 10
+
+=item I<alias>
+
+C<User_Alias>, C<Runas_Alias>, C<Host_Alias> and C<Cmnd_Alias> processing
+
+=item I<all>
+
+matches every subsystem
+
+=item I<audit>
+
+BSM and Linux audit code
+
+=item I<auth>
+
+user authentication
+
+=item I<defaults>
+
+I<sudoers> I<Defaults> settings
+
+=item I<env>
+
+environment handling
+
+=item I<ldap>
+
+LDAP-based sudoers
+
+=item I<logging>
+
+logging support
+
+=item I<match>
+
+matching of users, groups, hosts and netgroups in I<sudoers>
+
+=item I<netif>
+
+network interface handling
+
+=item I<nss>
+
+network service switch handling in I<sudoers>
+
+=item I<parser>
+
+I<sudoers> file parsing
+
+=item I<perms>
+
+permission setting
+
+=item I<plugin>
+
+The equivalent of I<main> for the plugin.
+
+=item I<pty>
+
+pseudo-tty related code
+
+=item I<rbtree>
+
+redblack tree internals
+
+=item I<util>
+
+utility functions 
+
+=back
+
 =head1 SECURITY NOTES
 
 I<sudoers> will check the ownership of its time stamp directory
index f8751eb0e148353b542a54707fcf30101570be82..6195fda25a8b99125c74852cf6f53fa98456dab9 100644 (file)
@@ -260,4 +260,4 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
 
 
 
-1.8.3                         September 16, 2011                SUDOREPLAY(1m)
+1.8.4                          January  6, 2012                 SUDOREPLAY(1m)
index fcce5ef1b5d60df9bb5459d785ca2d252022558c..277d42e15db20531cf048d88479d7fb3f1f4d8cb 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "SUDOREPLAY @mansectsu@"
-.TH SUDOREPLAY @mansectsu@ "September 16, 2011" "1.8.3" "MAINTENANCE COMMANDS"
+.TH SUDOREPLAY @mansectsu@ "January  6, 2012" "1.8.4" "MAINTENANCE COMMANDS"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
index e66435ded9d364f3ffbe3c188dcfebedb6a54c00..33eee63e954d41d93399129c1f6747a5f2a23eb8 100644 (file)
@@ -42,11 +42,12 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
        v\bvi\bis\bsu\bud\bdo\bo accepts the following command line options:
 
        -c          Enable c\bch\bhe\bec\bck\bk-\b-o\bon\bnl\bly\by mode.  The existing _\bs_\bu_\bd_\bo_\be_\br_\bs file will be
-                   checked for syntax and a message will be printed to the
-                   standard output detailing the status of _\bs_\bu_\bd_\bo_\be_\br_\bs.  If the
-                   syntax check completes successfully, v\bvi\bis\bsu\bud\bdo\bo will exit with
-                   a value of 0.  If a syntax error is encountered, v\bvi\bis\bsu\bud\bdo\bo
-                   will exit with a value of 1.
+                   checked for syntax errors, owner and mode.  A message will
+                   be printed to the standard output describing the status of
+                   _\bs_\bu_\bd_\bo_\be_\br_\bs unless the -\b-q\bq option was specified.  If the check
+                   completes successfully, v\bvi\bis\bsu\bud\bdo\bo will exit with a value of 0.
+                   If an error is encountered, v\bvi\bis\bsu\bud\bdo\bo will exit with a value
+                   of 1.
 
        -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
@@ -119,13 +120,14 @@ 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(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
+       Many people have worked on s\bsu\bud\bdo\bo over the years; this version of v\bvi\bis\bsu\bud\bdo\bo
        was written by:
 
         Todd Miller
 
-       See the HISTORY file in the sudo distribution or visit
-       http://www.sudo.ws/sudo/history.html for more details.
+       See the CONTRIBUTORS file in the s\bsu\bud\bdo\bo distribution
+       (http://www.sudo.ws/sudo/contributors.html) for a list of people who
+       have contributed to s\bsu\bud\bdo\bo.
 
 C\bCA\bAV\bVE\bEA\bAT\bTS\bS
        There is no easy way to prevent a user from gaining a root shell if the
@@ -149,4 +151,4 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
 
 
 
-1.8.3                         September 16, 2011                    VISUDO(1m)
+1.8.4                           March 12, 2012                      VISUDO(1m)
index 0aaa96cf19a11c80774d34e600ab9764a5e8c2fa..a445851348231c7023c5e0025834cf6778ed2994 100644 (file)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 1996,1998-2005, 2007-2011
+.\" Copyright (c) 1996,1998-2005, 2007-2012
 .\"    Todd C. Miller <Todd.Miller@courtesan.com>
 .\" 
 .\" Permission to use, copy, modify, and distribute this software for any
 .\" ========================================================================
 .\"
 .IX Title "VISUDO @mansectsu@"
-.TH VISUDO @mansectsu@ "September 16, 2011" "1.8.3" "MAINTENANCE COMMANDS"
+.TH VISUDO @mansectsu@ "March 12, 2012" "1.8.4" "MAINTENANCE COMMANDS"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -192,10 +192,10 @@ error occurred (if the editor supports this feature).
 .IP "\-c" 12
 .IX Item "-c"
 Enable \fBcheck-only\fR mode.  The existing \fIsudoers\fR file will be
-checked for syntax and a message will be printed to the
-standard output detailing the status of \fIsudoers\fR.
-If the syntax check completes successfully, \fBvisudo\fR will
-exit with a value of 0.  If a syntax error is encountered,
+checked for syntax errors, owner and mode.  A message will be printed
+to the standard output describing the status of \fIsudoers\fR unless
+the \fB\-q\fR option was specified.  If the check completes successfully,
+\&\fBvisudo\fR will exit with a value of 0.  If an error is encountered,
 \&\fBvisudo\fR will exit with a value of 1.
 .IP "\-f \fIsudoers\fR" 12
 .IX Item "-f sudoers"
@@ -282,15 +282,16 @@ the \fIsudoers\fR file.
 \&\fIvi\fR\|(1), \fIsudoers\fR\|(@mansectform@), \fIsudo\fR\|(@mansectsu@), \fIvipw\fR\|(@mansectsu@)
 .SH "AUTHOR"
 .IX Header "AUTHOR"
-Many people have worked on \fIsudo\fR over the years; this version of
+Many people have worked on \fBsudo\fR over the years; this version of
 \&\fBvisudo\fR was written by:
 .PP
 .Vb 1
 \& Todd Miller
 .Ve
 .PP
-See the \s-1HISTORY\s0 file in the sudo distribution or visit
-http://www.sudo.ws/sudo/history.html for more details.
+See the \s-1CONTRIBUTORS\s0 file in the \fBsudo\fR distribution
+(http://www.sudo.ws/sudo/contributors.html) for a list of people
+who have contributed to \fBsudo\fR.
 .SH "CAVEATS"
 .IX Header "CAVEATS"
 There is no easy way to prevent a user from gaining a root shell if 
index 281210932b0b2b234f26db5c89da5f89547a9284..c3e9ba74bbd3df22fc7704bcc2d7e0599e089a4c 100644 (file)
@@ -1,4 +1,4 @@
-Copyright (c) 1996,1998-2005, 2007-2011
+Copyright (c) 1996,1998-2005, 2007-2012
        Todd C. Miller <Todd.Miller@courtesan.com>
 
 Permission to use, copy, modify, and distribute this software for any
@@ -70,10 +70,10 @@ B<visudo> accepts the following command line options:
 =item -c
 
 Enable B<check-only> mode.  The existing I<sudoers> file will be
-checked for syntax and a message will be printed to the
-standard output detailing the status of I<sudoers>.
-If the syntax check completes successfully, B<visudo> will
-exit with a value of 0.  If a syntax error is encountered,
+checked for syntax errors, owner and mode.  A message will be printed
+to the standard output describing the status of I<sudoers> unless
+the B<-q> option was specified.  If the check completes successfully,
+B<visudo> will exit with a value of 0.  If an error is encountered,
 B<visudo> will exit with a value of 1.
 
 =item -f I<sudoers>
@@ -187,13 +187,14 @@ L<vi(1)>, L<sudoers(5)>, L<sudo(8)>, L<vipw(8)>
 
 =head1 AUTHOR
 
-Many people have worked on I<sudo> over the years; this version of
+Many people have worked on B<sudo> over the years; this version of
 B<visudo> was written by:
 
  Todd Miller
 
-See the HISTORY file in the sudo distribution or visit
-http://www.sudo.ws/sudo/history.html for more details.
+See the CONTRIBUTORS file in the B<sudo> distribution
+(http://www.sudo.ws/sudo/contributors.html) for a list of people
+who have contributed to B<sudo>.
 
 =head1 CAVEATS
 
index 150ca621d0c8e3ca2b38fddb41da2af820cbbc13..9dbe4c4629225fccda407e4b203d131eb0420f54 100644 (file)
@@ -29,6 +29,11 @@ INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
 
 # Where to install things...
 prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+sysconfdir = @sysconfdir@
+libexecdir = @libexecdir@
 datarootdir = @datarootdir@
 localstatedir = @localstatedir@
 
@@ -49,7 +54,7 @@ Makefile: $(srcdir)/Makefile.in
 
 pre-install:
 
-install: install-dirs install-includes
+install: install-includes
 
 install-dirs:
        $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(includedir)
@@ -59,7 +64,7 @@ install-binaries:
 install-doc:
 
 install-includes: install-dirs
-       $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0444 $(srcdir)/sudo_plugin.h $(DESTDIR)$(includedir)
+       $(INSTALL) -O $(install_uid) -G $(install_gid) -m 0444 $(srcdir)/sudo_plugin.h $(DESTDIR)$(includedir)
 
 install-plugin:
 
index e64afdfb228969a76f750a07a99139429e7795bb..fdc1e08bf1d45657e43cda88b9195f764d7da67e 100644 (file)
 
 #include <stdarg.h>
 
-void   error(int, const char *, ...)  __printflike(2, 3) __attribute__((__noreturn__));
-void   errorx(int, const char *, ...)  __printflike(2, 3) __attribute__((__noreturn__));
-void   warning(const char *, ...) __printflike(1, 2);
-void   warningx(const char *, ...) __printflike(1, 2);
+/*
+ * We wrap error/errorx and warn/warnx so that the same output can
+ * go to the debug file, if there is one.
+ */
+#if defined(SUDO_ERROR_WRAP) && SUDO_ERROR_WRAP == 0
+# if defined(__GNUC__) && __GNUC__ == 2
+#  define error(rval, fmt...) error2((rval), (fmt))
+#  define errorx(rval, fmt...) errorx2((rval), (fmt))
+#  define warning(fmt...) warning2((fmt))
+#  define warningx(fmt...) warningx2((fmt))
+# else
+#  define error(rval, ...) error2((rval), __VA_ARGS__)
+#  define errorx(rval, ...) errorx2((rval), __VA_ARGS__)
+#  define warning(...) warning2(__VA_ARGS__)
+#  define warningx(...) warningx2(__VA_ARGS__)
+# endif /* __GNUC__ == 2 */
+#else /* SUDO_ERROR_WRAP */
+# if defined(__GNUC__) && __GNUC__ == 2
+#  define error(rval, fmt...) do {                                            \
+    sudo_debug_printf2(SUDO_DEBUG_ERROR|sudo_debug_subsys, (fmt));            \
+    error2((rval), (fmt));                                                    \
+} while (0)
+#  define errorx(rval, fmt...) do {                                           \
+    sudo_debug_printf2(SUDO_DEBUG_ERROR|sudo_debug_subsys, (fmt));            \
+    errorx2((rval), (fmt));                                                   \
+} while (0)
+#  define warning(fmt...) do {                                                \
+    sudo_debug_printf2(SUDO_DEBUG_ERROR|sudo_debug_subsys, (fmt));            \
+    warning2((fmt));                                                          \
+} while (0)
+#  define warningx(fmt...) do {                                                       \
+    sudo_debug_printf2(SUDO_DEBUG_ERROR|sudo_debug_subsys, (fmt));            \
+    warningx2((fmt));                                                         \
+} while (0)
+# else
+#  define error(rval, ...) do {                                                       \
+    sudo_debug_printf2(SUDO_DEBUG_ERROR|sudo_debug_subsys, __VA_ARGS__);      \
+    error2((rval), __VA_ARGS__);                                              \
+} while (0)
+#  define errorx(rval, ...) do {                                              \
+    sudo_debug_printf2(SUDO_DEBUG_ERROR|sudo_debug_subsys, __VA_ARGS__);     \
+    errorx2((rval), __VA_ARGS__);                                             \
+} while (0)
+#  define warning(...) do {                                                   \
+    sudo_debug_printf2(SUDO_DEBUG_ERROR|sudo_debug_subsys, __VA_ARGS__);      \
+    warning2(__VA_ARGS__);                                                    \
+} while (0)
+#  define warningx(...) do {                                                  \
+    sudo_debug_printf2(SUDO_DEBUG_ERROR|sudo_debug_subsys, __VA_ARGS__);     \
+    warningx2(__VA_ARGS__);                                                   \
+} while (0)
+# endif /* __GNUC__ == 2 */
+#endif /* SUDO_ERROR_WRAP */
+
+void   error2(int, const char *, ...)  __printflike(2, 3) __attribute__((__noreturn__));
+void   errorx2(int, const char *, ...)  __printflike(2, 3) __attribute__((__noreturn__));
+void   warning2(const char *, ...) __printflike(1, 2);
+void   warningx2(const char *, ...) __printflike(1, 2);
 
 #endif /* _SUDO_ERROR_H_ */
index e1c93a69f12ccaf923f09064e55631890551bd5e..cd0a0dfe82813ef14c5b79f5539390c49b8229ea 100644 (file)
@@ -26,7 +26,7 @@
 
 struct timeval;
 
-int lock_file(int, int);
+bool lock_file(int, int);
 int touch(int, char *, struct timeval *);
 char *sudo_parseln(FILE *);
 
index 7ac9588cd903b6fec0c600a807029c49dc4366c9..f05ac0de12ad7a569d483d0663a642322f60e17e 100644 (file)
@@ -335,6 +335,9 @@ int mkstemps(char *, int);
 #ifndef HAVE_NANOSLEEP
 int nanosleep(const struct timespec *, struct timespec *);
 #endif
+#ifndef HAVE_PW_DUP
+struct passwd *pw_dup(const struct passwd *);
+#endif
 #ifndef HAVE_SETENV
 int setenv(const char *, const char *, int);
 #endif
diff --git a/include/sudo_conf.h b/include/sudo_conf.h
new file mode 100644 (file)
index 0000000..6efc302
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011 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.
+ */
+
+#ifndef _SUDO_CONF_H
+#define _SUDO_CONF_H
+
+#include "list.h"
+
+struct plugin_info {
+    struct plugin_info *prev; /* required */
+    struct plugin_info *next; /* required */
+    const char *path;
+    const char *symbol_name;
+};
+TQ_DECLARE(plugin_info)
+
+/* Read main sudo.conf file. */
+void sudo_conf_read(void);
+
+/* Accessor functions. */
+const char *sudo_conf_askpass_path(void);
+const char *sudo_conf_noexec_path(void);
+const char *sudo_conf_debug_flags(void);
+struct plugin_info_list *sudo_conf_plugins(void);
+bool sudo_conf_disable_coredump(void);
+
+#endif /* _SUDO_CONF_H */
diff --git a/include/sudo_debug.h b/include/sudo_debug.h
new file mode 100644 (file)
index 0000000..81fbfac
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2011 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.
+ */
+
+#ifndef _SUDO_DEBUG_H
+#define _SUDO_DEBUG_H
+
+#include <stdarg.h>
+
+/*
+ * The priority and subsystem are encoded in a single 32-bit value.
+ * The lower 4 bits are the priority and the top 28 bits are the subsystem.
+ * This allows for 16 priorities and a very large number of subsystems.
+ */
+
+/*
+ * Sudo debug priorities, ordered least to most verbose,
+ * in other words, highest to lowest priority.  Max pri is 15.
+ * Note: order must match sudo_debug_priorities[]
+ */
+#define SUDO_DEBUG_CRIT                1       /* critical errors */
+#define SUDO_DEBUG_ERROR       2       /* non-critical errors */
+#define SUDO_DEBUG_WARN                3       /* non-fatal warnings */
+#define SUDO_DEBUG_NOTICE      4       /* non-error condition notices */
+#define SUDO_DEBUG_DIAG                5       /* diagnostic messages */
+#define SUDO_DEBUG_INFO                6       /* informational message */
+#define SUDO_DEBUG_TRACE       7       /* log function enter/exit */
+#define SUDO_DEBUG_DEBUG       8       /* very verbose debugging */
+
+/*
+ * Sudo debug subsystems.
+ * This includes subsystems in the sudoers plugin.
+ * Note: order must match sudo_debug_subsystems[]
+ */
+#define SUDO_DEBUG_MAIN                (1<<4)  /* sudo main() */
+#define SUDO_DEBUG_ARGS                (2<<4)  /* command line argument processing */
+#define SUDO_DEBUG_EXEC                (3<<4)  /* command execution */
+#define SUDO_DEBUG_PTY         (4<<4)  /* pseudo-tty */
+#define SUDO_DEBUG_UTMP                (5<<4)  /* utmp file ops */
+#define SUDO_DEBUG_CONV                (6<<4)  /* user conversation */
+#define SUDO_DEBUG_PCOMM       (7<<4)  /* plugin communications */
+#define SUDO_DEBUG_UTIL                (8<<4)  /* utility functions */
+#define SUDO_DEBUG_NETIF       (9<<4)  /* network interface functions */
+#define SUDO_DEBUG_AUDIT       (10<<4) /* audit */
+#define SUDO_DEBUG_EDIT                (11<<4) /* sudoedit */
+#define SUDO_DEBUG_SELINUX     (12<<4) /* selinux */
+#define SUDO_DEBUG_LDAP                (13<<4) /* sudoers LDAP */
+#define SUDO_DEBUG_MATCH       (14<<4) /* sudoers matching */
+#define SUDO_DEBUG_PARSER      (15<<4) /* sudoers parser */
+#define SUDO_DEBUG_ALIAS       (16<<4) /* sudoers alias functions */
+#define SUDO_DEBUG_DEFAULTS    (17<<4) /* sudoers defaults settings */
+#define SUDO_DEBUG_AUTH                (18<<4) /* authentication functions */
+#define SUDO_DEBUG_ENV         (19<<4) /* environment handling */
+#define SUDO_DEBUG_LOGGING     (20<<4) /* logging functions */
+#define SUDO_DEBUG_NSS         (21<<4) /* network service switch */
+#define SUDO_DEBUG_RBTREE      (22<<4) /* red-black tree functions */
+#define SUDO_DEBUG_PERMS       (23<<4) /* uid/gid swapping functions */
+#define SUDO_DEBUG_PLUGIN      (24<<4) /* main plugin functions */
+#define SUDO_DEBUG_ALL         0xfff0  /* all subsystems */
+
+/* Extract priority and convert to an index. */
+#define SUDO_DEBUG_PRI(n) (((n) & 0xf) - 1)
+
+/* Extract subsystem and convert to an index. */
+#define SUDO_DEBUG_SUBSYS(n) (((n) >> 4) - 1)
+
+/*
+ * Wrapper for sudo_debug_enter() that declares __func__ as needed
+ * and sets sudo_debug_subsys for sudo_debug_exit().
+ */
+#ifdef HAVE___FUNC__
+# define debug_decl(funcname, subsys)                                         \
+    const int sudo_debug_subsys = (subsys);                                   \
+    sudo_debug_enter(__func__, __FILE__, __LINE__, sudo_debug_subsys);
+#else
+# define debug_decl(funcname, subsys)                                         \
+    const int sudo_debug_subsys = (subsys);                                   \
+    const char *__func__ = #funcname;                                         \
+    sudo_debug_enter(__func__, __FILE__, __LINE__, sudo_debug_subsys);
+#endif
+
+/*
+ * Wrappers for sudo_debug_exit() and friends.
+ */
+#define debug_return                                                          \
+    do {                                                                      \
+       sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);      \
+       return;                                                                \
+    } while (0)
+
+#define debug_return_int(rval)                                                \
+    do {                                                                      \
+       int sudo_debug_rval = (rval);                                          \
+       sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys,   \
+           sudo_debug_rval);                                                  \
+       return sudo_debug_rval;                                                \
+    } while (0)
+
+#define debug_return_size_t(rval)                                             \
+    do {                                                                      \
+       size_t sudo_debug_rval = (rval);                                       \
+       sudo_debug_exit_size_t(__func__, __FILE__, __LINE__, sudo_debug_subsys,\
+           sudo_debug_rval);                                                  \
+       return sudo_debug_rval;                                                \
+    } while (0)
+
+#define debug_return_long(rval)                                                       \
+    do {                                                                      \
+       long sudo_debug_rval = (rval);                                         \
+       sudo_debug_exit_long(__func__, __FILE__, __LINE__, sudo_debug_subsys,  \
+           sudo_debug_rval);                                                  \
+       return sudo_debug_rval;                                                \
+    } while (0)
+
+#define debug_return_bool(rval)                                                       \
+    do {                                                                      \
+       int sudo_debug_rval = (rval);                                          \
+       sudo_debug_exit_bool(__func__, __FILE__, __LINE__, sudo_debug_subsys,  \
+           sudo_debug_rval);                                                  \
+       return sudo_debug_rval;                                                \
+    } while (0)
+
+#define debug_return_str(rval)                                                \
+    do {                                                                      \
+       const char *sudo_debug_rval = (rval);                                  \
+       sudo_debug_exit_str(__func__, __FILE__, __LINE__, sudo_debug_subsys,   \
+           sudo_debug_rval);                                                  \
+       return (char *)sudo_debug_rval;                                        \
+    } while (0)
+
+#define debug_return_str_masked(rval)                                                 \
+    do {                                                                      \
+       const char *sudo_debug_rval = (rval);                                  \
+       sudo_debug_exit_str_masked(__func__, __FILE__, __LINE__,               \
+           sudo_debug_subsys, sudo_debug_rval);                               \
+       return (char *)sudo_debug_rval;                                        \
+    } while (0)
+
+#define debug_return_ptr(rval)                                                \
+    do {                                                                      \
+       const void *sudo_debug_rval = (rval);                                  \
+       sudo_debug_exit_ptr(__func__, __FILE__, __LINE__, sudo_debug_subsys,   \
+           sudo_debug_rval);                                                  \
+       return (void *)sudo_debug_rval;                                        \
+    } while (0)
+
+/*
+ * Variadic macros are a C99 feature but GNU cpp has supported
+ * a (different) version of them for a long time.
+ */
+#if defined(__GNUC__) && __GNUC__ == 2
+# define sudo_debug_printf(pri, fmt...) \
+    sudo_debug_printf2((pri)|sudo_debug_subsys, (fmt))
+#else
+# define sudo_debug_printf(pri, ...) \
+    sudo_debug_printf2((pri)|sudo_debug_subsys, __VA_ARGS__)
+#endif
+
+#define sudo_debug_execve(pri, path, argv, envp) \
+    sudo_debug_execve2((pri)|sudo_debug_subsys, (path), (argv), (envp))
+
+/*
+ * NULL-terminated string lists of priorities and subsystems.
+ */
+extern const char *const sudo_debug_priorities[];
+extern const char *const sudo_debug_subsystems[];
+
+void sudo_debug_enter(const char *func, const char *file, int line, int subsys);
+void sudo_debug_execve2(int level, const char *path, char *const argv[], char *const envp[]);
+void sudo_debug_exit(const char *func, const char *file, int line, int subsys);
+void sudo_debug_exit_int(const char *func, const char *file, int line, int subsys, int rval);
+void sudo_debug_exit_long(const char *func, const char *file, int line, int subsys, long rval);
+void sudo_debug_exit_size_t(const char *func, const char *file, int line, int subsys, size_t rval);
+void sudo_debug_exit_bool(const char *func, const char *file, int line, int subsys, int rval);
+void sudo_debug_exit_str(const char *func, const char *file, int line, int subsys, const char *rval);
+void sudo_debug_exit_str_masked(const char *func, const char *file, int line, int subsys, const char *rval);
+void sudo_debug_exit_ptr(const char *func, const char *file, int line, int subsys, const void *rval);
+int sudo_debug_fd_set(int fd);
+int sudo_debug_init(const char *debugfile, const char *settings);
+void sudo_debug_printf2(int level, const char *format, ...) __printflike(2, 3);
+void sudo_debug_write(const char *str, int len);
+
+#endif /* _SUDO_DEBUG_H */
index 2306503324cd67beabfdd39eda759fa8cfc7000a..6fd3e6794b7d3c205ee7bb052357722931e5bdf8 100644 (file)
@@ -40,6 +40,7 @@ struct sudo_conv_message {
 #define SUDO_CONV_ERROR_MSG        0x0003  /* error message */
 #define SUDO_CONV_INFO_MSG         0x0004  /* informational message */
 #define SUDO_CONV_PROMPT_MASK      0x0005  /* mask user input */
+#define SUDO_CONV_DEBUG_MSG        0x0006  /* debugging message */
 #define SUDO_CONV_PROMPT_ECHO_OK    0x1000  /* flag: allow echo if no tty */
     int msg_type;
     int timeout;
index 3061e3c5a2f71da20e6715700280d02e4db3bdea..63ae69dc6fecaf83c52fba2ad334f4b1369fb1cd 100755 (executable)
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -1,9 +1,9 @@
 
-# libtool (GNU libtool) 2.4
+# libtool (GNU libtool) 2.4.2
 # Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
-# 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 # This is free software; see the source for copying conditions.  There is NO
 # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
@@ -41,6 +41,7 @@
 #       --quiet, --silent    don't print informational messages
 #       --no-quiet, --no-silent
 #                            print informational messages (default)
+#       --no-warn            don't display warning messages
 #       --tag=TAG            use configuration variables from tag TAG
 #   -v, --verbose            print more informational messages than default
 #       --no-verbose         don't print the extra informational messages
@@ -69,7 +70,7 @@
 #         compiler:            $LTCC
 #         compiler flags:              $LTCFLAGS
 #         linker:              $LD (gnu? $with_gnu_ld)
-#         $progname:   (GNU libtool) 2.4
+#         $progname:   (GNU libtool) 2.4.2
 #         automake:    $automake_version
 #         autoconf:    $autoconf_version
 #
@@ -79,9 +80,9 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION=2.4
+VERSION=2.4.2
 TIMESTAMP=""
-package_revision=1.3293
+package_revision=1.3337
 
 # Be Bourne compatible
 if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
@@ -136,15 +137,10 @@ progpath="$0"
 
 : ${CP="cp -f"}
 test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
-: ${EGREP="grep -E"}
-: ${FGREP="grep -F"}
-: ${GREP="grep"}
-: ${LN_S="ln -s"}
 : ${MAKE="make"}
 : ${MKDIR="mkdir"}
 : ${MV="mv -f"}
 : ${RM="rm -f"}
-: ${SED="sed"}
 : ${SHELL="${CONFIG_SHELL-/bin/sh}"}
 : ${Xsed="$SED -e 1s/^X//"}
 
@@ -387,7 +383,7 @@ case $progpath in
      ;;
   *)
      save_IFS="$IFS"
-     IFS=:
+     IFS=${PATH_SEPARATOR-:}
      for progdir in $PATH; do
        IFS="$save_IFS"
        test -x "$progdir/$progname" && break
@@ -771,8 +767,8 @@ func_help ()
        s*\$LTCFLAGS*'"$LTCFLAGS"'*
        s*\$LD*'"$LD"'*
        s/\$with_gnu_ld/'"$with_gnu_ld"'/
-       s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
-       s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
+       s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+       s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
        p
        d
      }
@@ -1052,6 +1048,7 @@ opt_finish=false
 opt_help=false
 opt_help_all=false
 opt_silent=:
+opt_warning=:
 opt_verbose=:
 opt_silent=false
 opt_verbose=false
@@ -1118,6 +1115,10 @@ esac
                        ;;
       --no-silent|--no-quiet)
                        opt_silent=false
+func_append preserve_args " $opt"
+                       ;;
+      --no-warning|--no-warn)
+                       opt_warning=false
 func_append preserve_args " $opt"
                        ;;
       --no-verbose)
@@ -2059,7 +2060,7 @@ func_mode_compile ()
     *.[cCFSifmso] | \
     *.ada | *.adb | *.ads | *.asm | \
     *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
-    *.[fF][09]? | *.for | *.java | *.obj | *.sx | *.cu | *.cup)
+    *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
       func_xform "$libobj"
       libobj=$func_xform_result
       ;;
@@ -3201,11 +3202,13 @@ func_mode_install ()
 
       # Set up the ranlib parameters.
       oldlib="$destdir/$name"
+      func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+      tool_oldlib=$func_to_tool_file_result
 
       func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
 
       if test -n "$stripme" && test -n "$old_striplib"; then
-       func_show_eval "$old_striplib $oldlib" 'exit $?'
+       func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
       fi
 
       # Do each command in the postinstall commands.
@@ -3470,7 +3473,7 @@ static const void *lt_preloaded_setup() {
          # linked before any other PIC object.  But we must not use
          # pic_flag when linking with -static.  The problem exists in
          # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
-         *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+         *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
            pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
          *-*-hpux*)
            pic_flag_for_symtable=" $pic_flag"  ;;
@@ -3982,14 +3985,17 @@ func_exec_program_core ()
 # launches target application with the remaining arguments.
 func_exec_program ()
 {
-  for lt_wr_arg
-  do
-    case \$lt_wr_arg in
-    --lt-*) ;;
-    *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
-    esac
-    shift
-  done
+  case \" \$* \" in
+  *\\ --lt-*)
+    for lt_wr_arg
+    do
+      case \$lt_wr_arg in
+      --lt-*) ;;
+      *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+      esac
+      shift
+    done ;;
+  esac
   func_exec_program_core \${1+\"\$@\"}
 }
 
@@ -5057,9 +5063,15 @@ void lt_dump_script (FILE* f)
 {
 EOF
            func_emit_wrapper yes |
-              $SED -e 's/\([\\"]\)/\\\1/g' \
-                  -e 's/^/  fputs ("/' -e 's/$/\\n", f);/'
-
+             $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/  fputs ("\1", f);/p
+g
+D'
             cat <<"EOF"
 }
 EOF
@@ -5643,7 +5655,8 @@ func_mode_link ()
        continue
        ;;
 
-      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+      |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
        func_append compiler_flags " $arg"
        func_append compile_command " $arg"
        func_append finalize_command " $arg"
@@ -6147,7 +6160,8 @@ func_mode_link ()
        lib=
        found=no
        case $deplib in
-       -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+       -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+        |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
          if test "$linkmode,$pass" = "prog,link"; then
            compile_deplibs="$deplib $compile_deplibs"
            finalize_deplibs="$deplib $finalize_deplibs"
@@ -6831,7 +6845,7 @@ func_mode_link ()
                 test "$hardcode_direct_absolute" = no; then
                add="$dir/$linklib"
              elif test "$hardcode_minus_L" = yes; then
-               add_dir="-L$dir"
+               add_dir="-L$absdir"
                # Try looking first in the location we're being installed to.
                if test -n "$inst_prefix_dir"; then
                  case $libdir in
@@ -7316,6 +7330,7 @@ func_mode_link ()
          # which has an extra 1 added just for fun
          #
          case $version_type in
+         # correct linux to gnu/linux during the next big refactor
          darwin|linux|osf|windows|none)
            func_arith $number_major + $number_minor
            current=$func_arith_result
@@ -7432,7 +7447,7 @@ func_mode_link ()
          versuffix="$major.$revision"
          ;;
 
-       linux)
+       linux) # correct to gnu/linux during the next big refactor
          func_arith $current - $age
          major=.$func_arith_result
          versuffix="$major.$age.$revision"
@@ -8020,6 +8035,11 @@ EOF
 
       # Test again, we may have decided not to build it any more
       if test "$build_libtool_libs" = yes; then
+       # Remove ${wl} instances when linking with ld.
+       # FIXME: should test the right _cmds variable.
+       case $archive_cmds in
+         *\$LD\ *) wl= ;;
+        esac
        if test "$hardcode_into_libs" = yes; then
          # Hardcode the library paths
          hardcode_libdirs=
@@ -8050,7 +8070,7 @@ EOF
            elif test -n "$runpath_var"; then
              case "$perm_rpath " in
              *" $libdir "*) ;;
-             *) func_apped perm_rpath " $libdir" ;;
+             *) func_append perm_rpath " $libdir" ;;
              esac
            fi
          done
@@ -8058,11 +8078,7 @@ EOF
          if test -n "$hardcode_libdir_separator" &&
             test -n "$hardcode_libdirs"; then
            libdir="$hardcode_libdirs"
-           if test -n "$hardcode_libdir_flag_spec_ld"; then
-             eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
-           else
-             eval dep_rpath=\"$hardcode_libdir_flag_spec\"
-           fi
+           eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
          fi
          if test -n "$runpath_var" && test -n "$perm_rpath"; then
            # We should set the runpath_var.
@@ -9152,6 +9168,8 @@ EOF
            esac
          done
        fi
+       func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+       tool_oldlib=$func_to_tool_file_result
        eval cmds=\"$old_archive_cmds\"
 
        func_len " $cmds"
@@ -9261,7 +9279,8 @@ EOF
              *.la)
                func_basename "$deplib"
                name="$func_basename_result"
-               eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+               func_resolve_sysroot "$deplib"
+               eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
                test -z "$libdir" && \
                  func_fatal_error "\`$deplib' is not a valid libtool archive"
                func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
index d8125842f0a8a5e3a7d2d30a08f8909befa9aeca..44e0ecff11e3a16ca7656be45268d0bd597afc51 100644 (file)
@@ -1,8 +1,8 @@
 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
 #
 #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
-#                 Inc.
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
 #   Written by Gordon Matzigkeit, 1996
 #
 # This file is free software; the Free Software Foundation gives
@@ -11,8 +11,8 @@
 
 m4_define([_LT_COPYING], [dnl
 #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
-#                 Inc.
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
 #   Written by Gordon Matzigkeit, 1996
 #
 #   This file is part of GNU Libtool.
@@ -146,6 +146,8 @@ AC_REQUIRE([AC_CANONICAL_BUILD])dnl
 AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
 AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
 
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
 _LT_DECL([], [host_alias], [0], [The host system])dnl
 _LT_DECL([], [host], [0])dnl
 _LT_DECL([], [host_os], [0])dnl
@@ -637,7 +639,7 @@ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
 m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
 configured by $[0], generated by m4_PACKAGE_STRING.
 
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2011 Free Software Foundation, Inc.
 This config.lt script is free software; the Free Software Foundation
 gives unlimited permision to copy, distribute and modify it."
 
@@ -801,6 +803,7 @@ AC_DEFUN([LT_LANG],
 m4_case([$1],
   [C],                 [_LT_LANG(C)],
   [C++],               [_LT_LANG(CXX)],
+  [Go],                        [_LT_LANG(GO)],
   [Java],              [_LT_LANG(GCJ)],
   [Fortran 77],                [_LT_LANG(F77)],
   [Fortran],           [_LT_LANG(FC)],
@@ -822,6 +825,31 @@ m4_defun([_LT_LANG],
 ])# _LT_LANG
 
 
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_GO.  When it is available in    #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC],     [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+  fi
+fi
+if test -z "$GOC"; then
+  AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
 # _LT_LANG_DEFAULT_CONFIG
 # -----------------------
 m4_defun([_LT_LANG_DEFAULT_CONFIG],
@@ -852,6 +880,10 @@ AC_PROVIDE_IFELSE([AC_PROG_GCJ],
        m4_ifdef([LT_PROG_GCJ],
        [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
 
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+  [LT_LANG(GO)],
+  [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
 AC_PROVIDE_IFELSE([LT_PROG_RC],
   [LT_LANG(RC)],
   [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
@@ -954,7 +986,13 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
        $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
          -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
         _lt_result=$?
-       if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+       # If there is a non-empty error log, and "single_module"
+       # appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+         cat conftest.err >&AS_MESSAGE_LOG_FD
+       # Otherwise, if the output was created with a 0 exit code from
+       # the compiler, it worked.
+       elif test -f libconftest.dylib && test $_lt_result -eq 0; then
          lt_cv_apple_cc_single_mod=yes
        else
          cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -962,6 +1000,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
        rm -rf libconftest.dylib*
        rm -f conftest.*
       fi])
+
     AC_CACHE_CHECK([for -exported_symbols_list linker flag],
       [lt_cv_ld_exported_symbols_list],
       [lt_cv_ld_exported_symbols_list=no
@@ -973,6 +1012,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
        [lt_cv_ld_exported_symbols_list=no])
        LDFLAGS="$save_LDFLAGS"
     ])
+
     AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
       [lt_cv_ld_force_load=no
       cat > conftest.c << _LT_EOF
@@ -990,7 +1030,9 @@ _LT_EOF
       echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
       $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
       _lt_result=$?
-      if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then
+      if test -s conftest.err && $GREP force_load conftest.err; then
+       cat conftest.err >&AS_MESSAGE_LOG_FD
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
        lt_cv_ld_force_load=yes
       else
        cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -1035,8 +1077,8 @@ _LT_EOF
 ])
 
 
-# _LT_DARWIN_LINKER_FEATURES
-# --------------------------
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
 # Checks for linker and compiler features on darwin
 m4_defun([_LT_DARWIN_LINKER_FEATURES],
 [
@@ -1047,6 +1089,8 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
   _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
   if test "$lt_cv_ld_force_load" = "yes"; then
     _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+    m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+                  [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])
   else
     _LT_TAGVAR(whole_archive_flag_spec, $1)=''
   fi
@@ -1330,14 +1374,27 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
     CFLAGS="$SAVE_CFLAGS"
   fi
   ;;
-sparc*-*solaris*)
+*-*solaris*)
   # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case `/usr/bin/file conftest.o` in
     *64-bit*)
       case $lt_cv_prog_gnu_ld in
-      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      yes*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
       *)
        if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
          LD="${LD-ld} -64"
@@ -1414,13 +1471,13 @@ old_postuninstall_cmds=
 if test -n "$RANLIB"; then
   case $host_os in
   openbsd*)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
     ;;
   *)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
     ;;
   esac
-  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
 fi
 
 case $host_os in
@@ -1600,6 +1657,11 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     lt_cv_sys_max_cmd_len=196608
     ;;
 
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
   osf*)
     # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
     # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
@@ -1639,7 +1701,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
       # If test is not a shell built-in, we'll probably end up computing a
       # maximum length that is only half of the actual maximum length, but
       # we can't tell.
-      while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
                 = "X$teststring$teststring"; } >/dev/null 2>&1 &&
              test $i != 17 # 1/2 MB should be enough
       do
@@ -2185,7 +2247,7 @@ need_version=unknown
 
 case $host_os in
 aix3*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
@@ -2194,7 +2256,7 @@ aix3*)
   ;;
 
 aix[[4-9]]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
@@ -2259,7 +2321,7 @@ beos*)
   ;;
 
 bsdi[[45]]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
@@ -2398,7 +2460,7 @@ m4_if([$1], [],[
   ;;
 
 dgux*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
@@ -2406,10 +2468,6 @@ dgux*)
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
-freebsd1*)
-  dynamic_linker=no
-  ;;
-
 freebsd* | dragonfly*)
   # DragonFly does not have aout.  When/if they implement a new
   # versioning mechanism, adjust this.
@@ -2417,7 +2475,7 @@ freebsd* | dragonfly*)
     objformat=`/usr/bin/objformat`
   else
     case $host_os in
-    freebsd[[123]]*) objformat=aout ;;
+    freebsd[[23]].*) objformat=aout ;;
     *) objformat=elf ;;
     esac
   fi
@@ -2435,7 +2493,7 @@ freebsd* | dragonfly*)
   esac
   shlibpath_var=LD_LIBRARY_PATH
   case $host_os in
-  freebsd2*)
+  freebsd2.*)
     shlibpath_overrides_runpath=yes
     ;;
   freebsd3.[[01]]* | freebsdelf3.[[01]]*)
@@ -2455,17 +2513,18 @@ freebsd* | dragonfly*)
   ;;
 
 gnu*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
   ;;
 
 haiku*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   dynamic_linker="$host_os runtime_loader"
@@ -2526,7 +2585,7 @@ hpux9* | hpux10* | hpux11*)
   ;;
 
 interix[[3-9]]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
@@ -2542,7 +2601,7 @@ irix5* | irix6* | nonstopux*)
     nonstopux*) version_type=nonstopux ;;
     *)
        if test "$lt_cv_prog_gnu_ld" = yes; then
-               version_type=linux
+               version_type=linux # correct to gnu/linux during the next big refactor
        else
                version_type=irix
        fi ;;
@@ -2579,9 +2638,9 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-# This must be Linux ELF.
+# This must be glibc/ELF.
 linux* | k*bsd*-gnu | kopensolaris*-gnu)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -2644,7 +2703,7 @@ netbsd*)
   ;;
 
 newsos6)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
@@ -2713,7 +2772,7 @@ rdos*)
   ;;
 
 solaris*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -2738,7 +2797,7 @@ sunos4*)
   ;;
 
 sysv4 | sysv4.3*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
@@ -2762,7 +2821,7 @@ sysv4 | sysv4.3*)
 
 sysv4*MP*)
   if test -d /usr/nec ;then
-    version_type=linux
+    version_type=linux # correct to gnu/linux during the next big refactor
     library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
     soname_spec='$libname${shared_ext}.$major'
     shlibpath_var=LD_LIBRARY_PATH
@@ -2793,7 +2852,7 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
 
 tpf*)
   # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -2803,7 +2862,7 @@ tpf*)
   ;;
 
 uts4*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
@@ -3225,7 +3284,7 @@ irix5* | irix6* | nonstopux*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-# This must be Linux ELF.
+# This must be glibc/ELF.
 linux* | k*bsd*-gnu | kopensolaris*-gnu)
   lt_cv_deplibs_check_method=pass_all
   ;;
@@ -3645,6 +3704,7 @@ for ac_symprfx in "" "_"; do
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK ['"\
 "     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
 "     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
 "     \$ 0!~/External *\|/{next};"\
 "     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
@@ -4229,7 +4289,9 @@ m4_if([$1], [CXX], [
     case $cc_basename in
     nvcc*) # Cuda Compiler Driver 2.2
       _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
-      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Xcompiler -fPIC'
+      if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+      fi
       ;;
     esac
   else
@@ -4321,18 +4383,33 @@ m4_if([$1], [CXX], [
        ;;
       *)
        case `$CC -V 2>&1 | sed 5q` in
-       *Sun\ F* | *Sun*Fortran*)
+       *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
          # Sun Fortran 8.3 passes all unrecognized flags to the linker
          _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
          _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
          _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
          ;;
+       *Sun\ F* | *Sun*Fortran*)
+         _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+         _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+         _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+         ;;
        *Sun\ C*)
          # Sun C 5.9
          _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
          _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
          _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
          ;;
+        *Intel*\ [[CF]]*Compiler*)
+         _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+         _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+         _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+         ;;
+       *Portland\ Group*)
+         _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+         _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+         _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+         ;;
        esac
        ;;
       esac
@@ -4492,7 +4569,9 @@ m4_if([$1], [CXX], [
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
-    cl*) ;;
+    cl*)
+      _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
     *)
       _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
       _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
@@ -4517,7 +4596,6 @@ m4_if([$1], [CXX], [
   _LT_TAGVAR(hardcode_direct, $1)=no
   _LT_TAGVAR(hardcode_direct_absolute, $1)=no
   _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
   _LT_TAGVAR(hardcode_libdir_separator, $1)=
   _LT_TAGVAR(hardcode_minus_L, $1)=no
   _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
@@ -4768,8 +4846,7 @@ _LT_EOF
        xlf* | bgf* | bgxlf* | mpixlf*)
          # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
          _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
-         _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-         _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+         _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
          _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
          if test "x$supports_anon_versioning" = xyes; then
            _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
@@ -5064,6 +5141,7 @@ _LT_EOF
        # The linker will not automatically build a static lib if we build a DLL.
        # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
        _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+       _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
        _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
        # Don't use ranlib
        _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
@@ -5110,10 +5188,6 @@ _LT_EOF
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
       ;;
 
-    freebsd1*)
-      _LT_TAGVAR(ld_shlibs, $1)=no
-      ;;
-
     # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
     # support.  Future versions do this automatically, but an explicit c++rt0.o
     # does not break anything, and helps significantly (at the cost of a little
@@ -5126,7 +5200,7 @@ _LT_EOF
       ;;
 
     # Unfortunately, older versions of FreeBSD 2 do not have this feature.
-    freebsd2*)
+    freebsd2.*)
       _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
       _LT_TAGVAR(hardcode_direct, $1)=yes
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
@@ -5165,7 +5239,6 @@ _LT_EOF
       fi
       if test "$with_gnu_ld" = no; then
        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
-       _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
        _LT_TAGVAR(hardcode_direct, $1)=yes
        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
@@ -5607,9 +5680,6 @@ _LT_TAGDECL([], [no_undefined_flag], [1],
 _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
     [Flag to hardcode $libdir into a binary during linking.
     This must work even if $libdir does not exist])
-_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],
-    [[If ld is used when linking, flag to hardcode $libdir into a binary
-    during linking.  This must work even if $libdir does not exist]])
 _LT_TAGDECL([], [hardcode_libdir_separator], [1],
     [Whether we need a single "-rpath" flag with a separated argument])
 _LT_TAGDECL([], [hardcode_direct], [0],
@@ -5767,7 +5837,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
 _LT_TAGVAR(hardcode_direct, $1)=no
 _LT_TAGVAR(hardcode_direct_absolute, $1)=no
 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
 _LT_TAGVAR(hardcode_libdir_separator, $1)=
 _LT_TAGVAR(hardcode_minus_L, $1)=no
 _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
@@ -6137,7 +6206,7 @@ if test "$_lt_caught_CXX_error" != yes; then
         esac
         ;;
 
-      freebsd[[12]]*)
+      freebsd2.*)
         # C++ shared libraries reported to be fairly broken before
        # switch to ELF
         _LT_TAGVAR(ld_shlibs, $1)=no
@@ -6898,12 +6967,18 @@ public class foo {
   }
 };
 _LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
 ])
 
 _lt_libdeps_save_CFLAGS=$CFLAGS
 case "$CC $CFLAGS " in #(
 *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
 *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
 esac
 
 dnl Parse the compiler output and extract the necessary
@@ -7100,7 +7175,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
 _LT_TAGVAR(hardcode_direct, $1)=no
 _LT_TAGVAR(hardcode_direct_absolute, $1)=no
 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
 _LT_TAGVAR(hardcode_libdir_separator, $1)=
 _LT_TAGVAR(hardcode_minus_L, $1)=no
 _LT_TAGVAR(hardcode_automatic, $1)=no
@@ -7233,7 +7307,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
 _LT_TAGVAR(hardcode_direct, $1)=no
 _LT_TAGVAR(hardcode_direct_absolute, $1)=no
 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
 _LT_TAGVAR(hardcode_libdir_separator, $1)=
 _LT_TAGVAR(hardcode_minus_L, $1)=no
 _LT_TAGVAR(hardcode_automatic, $1)=no
@@ -7420,6 +7493,77 @@ CFLAGS=$lt_save_CFLAGS
 ])# _LT_LANG_GCJ_CONFIG
 
 
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
 # _LT_LANG_RC_CONFIG([TAG])
 # -------------------------
 # Ensure that the configuration variables for the Windows resource compiler
@@ -7489,6 +7633,13 @@ dnl aclocal-1.4 backwards compatibility:
 dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
 
 
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
 # LT_PROG_RC
 # ----------
 AC_DEFUN([LT_PROG_RC],
index 17cfd51c0b34ed2f118b8b5d4d28947889eec9c3..5d9acd8e23bcfd20d353804aff13666ecbed54f4 100644 (file)
@@ -326,9 +326,24 @@ dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
 # MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
 m4_define([_LT_WITH_PIC],
 [AC_ARG_WITH([pic],
-    [AS_HELP_STRING([--with-pic],
+    [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
        [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
-    [pic_mode="$withval"],
+    [lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+       IFS="$lt_save_ifs"
+       if test "X$lt_pkg" = "X$lt_p"; then
+         pic_mode=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
     [pic_mode=default])
 
 test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
index 9c7b5d4118584728f6ebb2d6f461378be0e872f2..07a8602d48d615a65800b14446d8c8c8694f2818 100644 (file)
@@ -9,15 +9,15 @@
 
 # @configure_input@
 
-# serial 3293 ltversion.m4
+# serial 3337 ltversion.m4
 # This file is part of GNU Libtool
 
-m4_define([LT_PACKAGE_VERSION], [2.4])
-m4_define([LT_PACKAGE_REVISION], [1.3293])
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
 
 AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.4'
-macro_revision='1.3293'
+[macro_version='2.4.2'
+macro_revision='1.3337'
 _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
 _LT_DECL(, macro_revision, 0)
 ])
index 67acbd4bd5c8c8e7890baa2c5edd0298a29a027f..55006ba998b637ce1b902cd873d892166d24b845 100755 (executable)
--- a/mkdep.pl
+++ b/mkdep.pl
@@ -9,6 +9,7 @@ die "usage: $0 Makefile ...\n" unless $#ARGV >= 0;
 my @incpaths;
 my %dir_vars;
 my %implicit;
+my %generated;
 
 # Read in MANIFEST fail if present
 my %manifest;
@@ -48,11 +49,12 @@ sub mkdep {
     $makefile =~ s/\\\n//mg;
 
     # Expand some configure bits
+    $makefile =~ s:\@DEV\@::g;
     $makefile =~ s:\@COMMON_OBJS\@:aix.lo:;
     $makefile =~ s:\@SUDO_OBJS\@:preload.o selinux.o sesh.o sudo_noexec.lo:;
     $makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo plugin_error.lo:;
     # XXX - fill in AUTH_OBJS from contents of the auth dir instead
-    $makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb4.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid.lo securid5.lo sia.lo:;
+    $makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
     $makefile =~ s:\@LTLIBOBJS\@:closefrom.lo dlopen.lo fnmatch.lo getcwd.lo getgrouplist.lo getline.lo getprogname.lo glob.lo isblank.lo memrchr.lo mksiglist.lo mktemp.lo nanosleep.lo setenv.lo siglist.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo unsetenv.lo utimes.lo globtest.o fnm_test.o:;
 
     # Parse OBJS lines
@@ -70,6 +72,13 @@ sub mkdep {
        push(@incpaths, $1) unless $1 eq ".";
     }
 
+    # Check for generated files
+    if ($makefile =~ /GENERATED\s*=\s*(.+)$/m) {
+       foreach (split(/\s+/, $1)) {
+           $generated{$_} = 1;
+       }
+    }
+
     # Values of srcdir, top_srcdir, top_builddir, incdir
     %dir_vars = ();
     $file =~ m:^(.*)/+[^/]+:;
@@ -108,6 +117,7 @@ sub mkdep {
            } elsif (exists $manifest{$src}) {
                $src = $manifest{$src};
                foreach (sort { length($b) <=> length($a) } keys %dir_vars) {
+                   next if $_ eq "devdir";
                    last if $src =~ s:^\Q$dir_vars{$_}/\E:\$\($_\)/:;
                }
            } else {
@@ -141,13 +151,13 @@ sub mkdep {
        }
     }
 
-    rename($file, $file . ".old");
-    if (!open(MF, ">$file")) {
-       warn("cannot open $file: $!\n");
-       rename($file . ".old", $file);
+    my $newfile = $file . ".new";
+    if (!open(MF, ">$newfile")) {
+       warn("cannot open $newfile: $!\n");
     } else {
-       print MF $new_makefile || warn("cannot write $file: $!\n");
-       close(MF);
+       print MF $new_makefile || warn("cannot write $newfile: $!\n");
+       close(MF) || warn("cannot close $newfile: $!\n");;
+       rename($newfile, $file);
     }
 }
 
@@ -198,10 +208,15 @@ sub find_header {
     return ("\$(top_builddir\)/$hdr", "./${hdr}.in") if -r "./${hdr}.in";
     return ("./$hdr", "$dir_vars{'srcdir'}/${hdr}.in") if -r "$dir_vars{'srcdir'}/${hdr}.in";
 
+    if (exists $generated{$hdr}) {
+       my $hdr_path = $dir_vars{'devdir'} . '/' . $hdr;
+       return ('$(devdir)/' . $hdr, $hdr_path) if -r $hdr_path;
+    }
     foreach my $inc (@incpaths) {
        my $hdr_path = "$inc/$hdr";
        # resolve variables in include path
        foreach (keys %dir_vars) {
+           next if $_ eq "devdir";
            $hdr_path =~ s/\$[\(\{]$_[\)\}]/$dir_vars{$_}/g;
        }
        return ("$inc/$hdr", $hdr_path) if -r $hdr_path;
diff --git a/mkpkg b/mkpkg
index ad4eca3033c12b7ac618c9a034f4030469e54cc6..c1ea8ed3caf87d40da6c4ecd42ed424e6cd76566 100755 (executable)
--- a/mkpkg
+++ b/mkpkg
@@ -189,6 +189,14 @@ case "$osversion" in
        case "$osversion" in
            ubu*)
                configure_opts="${configure_opts}${configure_opts+$tab}--enable-admin-flag${tab}--without-lecture"
+               if [ $osrelease -ge 1004 ]; then
+                   export CFLAGS="-O2 -g $F_PIE" LDFLAGS="-pie"
+               fi
+               ;;
+           deb*)
+               if [ $osrelease -ge 600 ]; then
+                   export CFLAGS="-O2 -g $F_PIE" LDFLAGS="-pie"
+               fi
                ;;
        esac
        # Note, must indent with tabs, not spaces due to IFS trickery
@@ -218,6 +226,25 @@ case "$osversion" in
                --with-secure-path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin
                $configure_opts"
        ;;
+    macos*)
+       # Build universal binaries (intel-only) targetting Mac OS X 10.5
+       ARCH_FLAGS="-arch i386 -arch x86_64"
+       SDK_FLAGS="-isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5"
+       export CFLAGS="-O2 -g $ARCH_FLAGS $SDK_FLAGS"
+       export LDFLAGS="$ARCH_FLAGS $SDK_FLAGS"
+       # Note, must indent with tabs, not spaces due to IFS trickery
+       configure_opts="--prefix=$prefix
+               --with-pam
+               --without-tty-tickets
+               --enable-zlib=system
+               --with-ldap
+               --with-insults=disabled
+               --with-logging=syslog
+               --with-logfac=authpriv
+               --with-editor=/usr/bin/vim
+               --with-env-editor
+               $configure_opts"
+       ;;
     *)
        # For Solaris, add project support and use let configure choose zlib.
        # For all others, use the builtin zlib and disable NLS support.
index 12d77d48e0aa8e26876adef67eac77480ad2af84..1e7147c0d33ce441163893d90e542886f7ad9b3d 100644 (file)
@@ -36,7 +36,7 @@ INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
 LIBS = $(LIBOBJDIR)/libreplace.la
 
 # C preprocessor flags
-CPPFLAGS = -I$(incdir) -I$(top_builddir) @CPPFLAGS@
+CPPFLAGS = -I$(incdir) -I$(top_builddir) -I$(top_srcdir) @CPPFLAGS@
 
 # Usually -O and/or -g
 CFLAGS = @CFLAGS@
@@ -85,7 +85,7 @@ sample_plugin.la: $(OBJS)
 
 pre-install:
 
-install: install-dirs install-plugin
+install: install-plugin
 
 install-dirs:
        $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(plugindir)
@@ -97,7 +97,7 @@ install-includes:
 install-doc:
 
 install-plugin: install-dirs sample_plugin.la
-       $(INSTALL) -b~ -M 0755 .libs/sample_plugin$(soext) $(DESTDIR)$(plugindir)
+       $(INSTALL) -b~ -m 0755 .libs/sample_plugin$(soext) $(DESTDIR)$(plugindir)
 
 uninstall:
        -rm -f $(DESTDIR)$(plugindir)/sample_plugin$(soext)
@@ -121,6 +121,6 @@ cleandir: realclean
 
 # Autogenerated dependencies, do not modify
 sample_plugin.lo: $(srcdir)/sample_plugin.c $(top_builddir)/config.h \
-                  $(top_builddir)/pathnames.h $(incdir)/sudo_plugin.h \
-                  $(incdir)/missing.h
+                  $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+                  $(incdir)/sudo_plugin.h $(incdir)/missing.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/sample_plugin.c
index 5ac19a42bd29b8757df652eb98d2ca0c2ee50473..51ec2451a41b09d1f6a490694ccbb1a6468dadfd 100644 (file)
 #  include <stdlib.h>
 # endif
 #endif /* STDC_HEADERS */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
 #ifdef HAVE_STRING_H
 # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
 #  include <memory.h>
 # define ROOT_UID       0
 #endif
 
-#undef TRUE
-#define TRUE 1
-#undef FALSE
-#define FALSE 0
-#undef ERROR
-#define ERROR -1
-
 static struct plugin_state {
     char **envp;
     char * const *settings;
@@ -82,7 +80,7 @@ static sudo_printf_t sudo_log;
 static FILE *input, *output;
 static uid_t runas_uid = ROOT_UID;
 static gid_t runas_gid = -1;
-static int use_sudoedit = FALSE;
+static int use_sudoedit = false;
 
 /*
  * Allocate storage for a name=value string and return it.
@@ -130,7 +128,7 @@ policy_open(unsigned int version, sudo_conv_t conversation,
        sudo_log(SUDO_CONV_ERROR_MSG,
            "the sample plugin requires API version %d.x\n",
            SUDO_API_VERSION_MAJOR);
-       return ERROR;
+       return -1;
     }
 
     /* Only allow commands to be run as root. */
@@ -149,7 +147,7 @@ policy_open(unsigned int version, sudo_conv_t conversation,
        /* Check to see if sudo was called as sudoedit or with -e flag. */
        if (strncmp(*ui, "sudoedit=", sizeof("sudoedit=") - 1) == 0) {
            if (strcasecmp(*ui + sizeof("sudoedit=") - 1, "true") == 0)
-               use_sudoedit = TRUE;
+               use_sudoedit = true;
        }
        /* This plugin doesn't support running sudo with no arguments. */
        if (strncmp(*ui, "implied_shell=", sizeof("implied_shell=") - 1) == 0) {
@@ -229,13 +227,13 @@ check_passwd(void)
     sudo_conv(1, &msg, &repl);
     if (repl.reply == NULL) {
        sudo_log(SUDO_CONV_ERROR_MSG, "missing password\n");
-       return FALSE;
+       return false;
     }
     if (strcmp(repl.reply, "test") != 0) {
        sudo_log(SUDO_CONV_ERROR_MSG, "incorrect password\n");
-       return FALSE;
+       return false;
     }
-    return TRUE;
+    return true;
 }
 
 static char **
@@ -341,30 +339,30 @@ policy_check(int argc, char * const argv[],
 
     if (!argc || argv[0] == NULL) {
        sudo_log(SUDO_CONV_ERROR_MSG, "no command specified\n");
-       return FALSE;
+       return false;
     }
 
     if (!check_passwd())
-       return FALSE;
+       return false;
 
     command = find_in_path(argv[0], plugin_state.envp);
     if (command == NULL) {
        sudo_log(SUDO_CONV_ERROR_MSG, "%s: command not found\n", argv[0]);
-       return FALSE;
+       return false;
     }
 
     /* If "sudo vi" is run, auto-convert to sudoedit.  */
     if (strcmp(command, _PATH_VI) == 0)
-       use_sudoedit = TRUE;
+       use_sudoedit = true;
 
     if (use_sudoedit) {
        /* Rebuild argv using editor */
        command = find_editor(argc - 1, argv + 1, argv_out);
        if (command == NULL) {
            sudo_log(SUDO_CONV_ERROR_MSG, "unable to find valid editor\n");
-           return ERROR;
+           return -1;
        }
-       use_sudoedit = TRUE;
+       use_sudoedit = true;
     } else {
        /* No changes needd to argv */
        *argv_out = (char **)argv;
@@ -377,10 +375,10 @@ policy_check(int argc, char * const argv[],
     *command_info_out = build_command_info(command);
     if (*command_info_out == NULL) {
        sudo_log(SUDO_CONV_ERROR_MSG, "out of memory\n");
-       return ERROR;
+       return -1;
     }
 
-    return TRUE;
+    return true;
 }
 
 static int
@@ -390,14 +388,14 @@ policy_list(int argc, char * const argv[], int verbose, const char *list_user)
      * List user's capabilities.
      */
     sudo_log(SUDO_CONV_INFO_MSG, "Validated users may run any command\n");
-    return TRUE;
+    return true;
 }
 
 static int
 policy_version(int verbose)
 {
     sudo_log(SUDO_CONV_INFO_MSG, "Sample policy plugin version %s\n", PACKAGE_VERSION);
-    return TRUE;
+    return true;
 }
 
 static void
@@ -439,17 +437,17 @@ io_open(unsigned int version, sudo_conv_t conversation,
        (unsigned int)getpid());
     fd = open(path, O_WRONLY|O_CREAT|O_EXCL, 0644);
     if (fd == -1)
-       return FALSE;
+       return false;
     output = fdopen(fd, "w");
 
     snprintf(path, sizeof(path), "/var/tmp/sample-%u.input",
        (unsigned int)getpid());
     fd = open(path, O_WRONLY|O_CREAT|O_EXCL, 0644);
     if (fd == -1)
-       return FALSE;
+       return false;
     input = fdopen(fd, "w");
 
-    return TRUE;
+    return true;
 }
 
 static void
@@ -464,21 +462,21 @@ io_version(int verbose)
 {
     sudo_log(SUDO_CONV_INFO_MSG, "Sample I/O plugin version %s\n",
        PACKAGE_VERSION);
-    return TRUE;
+    return true;
 }
 
 static int
 io_log_input(const char *buf, unsigned int len)
 {
     fwrite(buf, len, 1, input);
-    return TRUE;
+    return true;
 }
 
 static int
 io_log_output(const char *buf, unsigned int len)
 {
     fwrite(buf, len, 1, output);
-    return TRUE;
+    return true;
 }
 
 struct policy_plugin sample_policy = {
index 9c4207ad72f570eb8a602558072530f93757ebb9..b9812b50d8304ce34dcaf9cd9606b4edf7c2f631 100644 (file)
@@ -36,7 +36,7 @@ INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
 LIBS = $(LIBOBJDIR)/libreplace.la
 
 # C preprocessor flags
-CPPFLAGS = -I$(incdir) -I$(top_builddir) @CPPFLAGS@
+CPPFLAGS = -I$(incdir) -I$(top_builddir) -I$(top_srcdir) @CPPFLAGS@
 
 # Usually -O and/or -g
 CFLAGS = @CFLAGS@
@@ -85,7 +85,7 @@ sample_group.la: $(OBJS)
 
 pre-install:
 
-install: install-dirs install-plugin
+install: install-plugin
 
 install-dirs:
        $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(plugindir)
@@ -97,7 +97,7 @@ install-includes:
 install-doc:
 
 install-plugin: install-dirs sample_group.la
-       $(INSTALL) -b~ -M 0755 .libs/sample_group$(soext) $(DESTDIR)$(plugindir)
+       $(INSTALL) -b~ -m 0755 .libs/sample_group$(soext) $(DESTDIR)$(plugindir)
 
 uninstall:
        -rm -f $(DESTDIR)$(plugindir)/sample_group$(soext)
@@ -123,5 +123,6 @@ cleandir: realclean
 getgrent.lo: $(srcdir)/getgrent.c $(top_builddir)/config.h $(incdir)/missing.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/getgrent.c
 sample_group.lo: $(srcdir)/sample_group.c $(top_builddir)/config.h \
-                 $(incdir)/sudo_plugin.h $(incdir)/missing.h
+                 $(top_srcdir)/compat/stdbool.h $(incdir)/sudo_plugin.h \
+                 $(incdir)/missing.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/sample_group.c
index dbd1c27094ecf61cb7fe9980c383c146b92200cb..2e3628d24172ecf4b4c3aeaeb68367f9c50730e8 100644 (file)
 #  include <stdlib.h>
 # endif
 #endif /* STDC_HEADERS */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
 #ifdef HAVE_STRING_H
 # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
 #  include <memory.h>
  * same format as /etc/group.
  */
 
-#undef TRUE
-#define TRUE 1
-#undef FALSE
-#define FALSE 0
-#undef ERROR
-#define ERROR -1
-
 static sudo_printf_t sudo_log;
 
 extern void mysetgrfile(const char *);
@@ -82,30 +80,30 @@ sample_init(int version, sudo_printf_t sudo_printf, char *const argv[])
            "sample_group: incompatible major version %d, expected %d\n",
            GROUP_API_VERSION_GET_MAJOR(version),
            GROUP_API_VERSION_MAJOR);
-       return ERROR;
+       return -1;
     }
 
     /* Sanity check the specified group file. */
     if (argv == NULL || argv[0] == NULL) {
        sudo_log(SUDO_CONV_ERROR_MSG,
            "sample_group: path to group file not specified\n");
-       return ERROR;
+       return -1;
     }
     if (stat(argv[0], &sb) != 0) {
        sudo_log(SUDO_CONV_ERROR_MSG,
            "sample_group: %s: %s\n", argv[0], strerror(errno));
-       return ERROR;
+       return -1;
     }
     if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
        sudo_log(SUDO_CONV_ERROR_MSG,
            "%s must be only be writable by owner\n", argv[0]);
-       return ERROR;
+       return -1;
     }
 
     mysetgrfile(argv[0]);
     mysetgrent();
 
-    return TRUE;
+    return true;
 }
 
 static void
@@ -115,7 +113,7 @@ sample_cleanup(void)
 }
 
 /*
- * Returns TRUE if "user" is a member of "group", else FALSE.
+ * Returns true if "user" is a member of "group", else false.
  */
 static int
 sample_query(const char *user, const char *group, const struct passwd *pwd)
@@ -127,11 +125,11 @@ sample_query(const char *user, const char *group, const struct passwd *pwd)
     if (grp != NULL) {
        for (member = grp->gr_mem; *member != NULL; member++) {
            if (strcasecmp(user, *member) == 0)
-               return TRUE;
+               return true;
        }
     }
 
-    return FALSE;
+    return false;
 }
 
 struct sudoers_group_plugin group_plugin = {
index 6c3c35c79451a6b2989f49c74ade0ba8bb0f4ede..c338e5592846b476694d4ab86d8a94a2980dc1cf 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1996, 1998-2005, 2007-2011
+# Copyright (c) 1996, 1998-2005, 2007-2012
 #       Todd C. Miller <Todd.Miller@courtesan.com>
 #
 # Permission to use, copy, modify, and distribute this software for any
@@ -38,6 +38,7 @@ CC = @CC@
 LIBTOOL = @LIBTOOL@
 FLEX = @FLEX@
 YACC = @YACC@
+PERL = perl
 
 # Our install program supports extra flags...
 INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
@@ -50,7 +51,7 @@ SUDOERS_LIBS = @SUDOERS_LIBS@ @AFS_LIBS@ @GETGROUPS_LIB@ $(LIBS) $(NET_LIBS) @ZL
 REPLAY_LIBS = @REPLAY_LIBS@ @ZLIB@
 
 # C preprocessor flags
-CPPFLAGS = -I$(incdir) -I$(top_builddir) -I$(srcdir) -I$(top_srcdir) @CPPFLAGS@
+CPPFLAGS = -I$(incdir) -I$(top_builddir) -I$(devdir) -I$(srcdir) -I$(top_srcdir) @CPPFLAGS@
 
 # Usually -O and/or -g
 CFLAGS = @CFLAGS@
@@ -100,6 +101,9 @@ DEFS = @OSDEFS@ -D_PATH_SUDOERS=\"$(sudoersdir)/sudoers\" \
        -DSUDOERS_UID=$(sudoers_uid) -DSUDOERS_GID=$(sudoers_gid) \
        -DSUDOERS_MODE=$(sudoers_mode) -DLOCALEDIR=\"$(localedir)\"
 
+# Set to non-empty for development mode
+DEVEL = @DEVEL@
+
 #### End of system configuration section. ####
 
 SHELL = @SHELL@
@@ -185,38 +189,49 @@ check_fill: $(CHECK_FILL_OBJS) $(LT_LIBS)
 check_wrap: $(CHECK_WRAP_OBJS) $(LT_LIBS)
        $(LIBTOOL) --mode=link $(CC) -o $@ $(CHECK_WRAP_OBJS) $(LDFLAGS) $(LIBS)
 
-# Uncomment the following if you want "make distclean" to clean the parser
-@DEV@GENERATED = gram.h gram.c toke.c def_data.c def_data.h getdate.c
+GENERATED = gram.h gram.c toke.c def_data.c def_data.h getdate.c
 
-# Uncomment the lines before -@true if you intend to modify gram.y
 $(devdir)/gram.c $(devdir)/gram.h: $(srcdir)/gram.y
-@DEV@  $(YACC) -d $(srcdir)/gram.y
-@DEV@  echo "#include <config.h>" > $(devdir)/gram.c
-@DEV@  cat y.tab.c >> $(devdir)/gram.c
-@DEV@  rm -f y.tab.c
-@DEV@  mv -f y.tab.h $(devdir)/gram.h
-       -@true
-
-# Uncomment the lines before -@true if you intend to modify toke.l
+       @if [ -n "$(DEVEL)" ]; then \
+           if test "$(srcdir)" = "."; then \
+               gram_y="gram.y"; \
+           else \
+               gram_y="$(srcdir)/gram.y"; \
+           fi; \
+           cmd='$(YACC) -d '"$$gram_y"'; echo "#include <config.h>" > $(devdir)/gram.c; sed "s/^\\(#line .*\\) \"y\\.tab\\.c\"/\1 \"gram.c\"/" y.tab.c >> $(devdir)/gram.c; rm -f y.tab.c; mv -f y.tab.h $(devdir)/gram.h'; \
+           echo "$$cmd"; eval $$cmd; \
+       fi
+
 $(devdir)/toke.c: $(srcdir)/toke.l
-@DEV@  $(FLEX) $(srcdir)/toke.l
-@DEV@  echo "#include <config.h>" > $(devdir)/toke.c
-@DEV@  cat lex.yy.c >> $(devdir)/toke.c
-@DEV@  rm -f lex.yy.c
-       -@true
+       @if [ -n "$(DEVEL)" ]; then \
+           if test "$(srcdir)" = "."; then \
+               toke_l="toke.l"; \
+           else \
+               toke_l="$(srcdir)/toke.l"; \
+           fi; \
+           cmd='$(FLEX) '"$$toke_l"'; echo "#include <config.h>" > $(devdir)/toke.c; cat lex.yy.c >> $(devdir)/toke.c'; \
+           echo "$$cmd"; eval $$cmd; \
+       fi
 
 # Uncomment the lines before -@true if you intend to modify getdate.y
 $(devdir)/getdate.c: $(srcdir)/getdate.y
-@DEV@  echo "expect 10 shift/reduce conflicts"
-@DEV@  $(YACC) $(srcdir)/getdate.y
-@DEV@  echo "#include <config.h>" > $(devdir)/getdate.c
-@DEV@  cat y.tab.c >> $(devdir)/getdate.c
-@DEV@  rm -f y.tab.c
-       -@true
+       @if [ -n "$(DEVEL)" ]; then \
+           echo "expect 10 shift/reduce conflicts"; \
+           if test "$(srcdir)" = "."; then \
+               getdate_y="getdate.y"; \
+           else \
+               getdate_y="$(srcdir)/getdate.y"; \
+           fi; \
+           cmd='$(YACC) '"$$getdate_y"'; echo "#include <config.h>" > $(devdir)/getdate.c; sed "s/^\\(#line .*\\) \"y\\.tab\\.c\"/\1 \"getdate.c\"/" y.tab.c >> $(devdir)/getdate.c; rm -f y.tab.c'; \
+           echo "$$cmd"; eval $$cmd; \
+       fi
 
 # Uncomment the following if you intend to modify def_data.in
-@DEV@$(devdir)/def_data.c $(devdir)/def_data.h: $(srcdir)/def_data.in
-@DEV@  perl $(srcdir)/mkdefaults -o $(devdir)/def_data $(srcdir)/def_data.in
+$(devdir)/def_data.c $(devdir)/def_data.h: $(srcdir)/def_data.in
+       @if [ -n "$(DEVEL)" ]; then \
+           cmd='$(PERL) $(srcdir)/mkdefaults -o $(devdir)/def_data $(srcdir)/def_data.in'; \
+           echo "$$cmd"; eval $$cmd; \
+       fi
 
 sudoers: $(srcdir)/sudoers.in
        (cd $(top_builddir) && $(SHELL) config.status --file=plugins/sudoers/$@)
@@ -227,13 +242,14 @@ pre-install:
            ./visudo -c -f $(DESTDIR)$(sudoersdir)/sudoers; \
        fi
 
-install: install-dirs install-plugin install-binaries install-sudoers install-doc
+install: install-plugin install-binaries install-sudoers install-doc
 
 install-dirs:
        $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(plugindir) \
            $(DESTDIR)$(visudodir) $(DESTDIR)$(replaydir) \
-           $(DESTDIR)$(sudoersdir) $(DESTDIR)$(docdir)
-       $(SHELL) $(top_srcdir)/mkinstalldirs -m 0700 $(DESTDIR)$(timedir)
+           $(DESTDIR)$(sudoersdir) $(DESTDIR)$(docdir) \
+           `echo $(DESTDIR)$(timedir)|sed 's,/[^/]*$$,,'`
+       $(INSTALL) -d -O $(install_uid) -G $(install_gid) -m 0700 $(DESTDIR)$(timedir)
 
 install-binaries: visudo sudoreplay install-dirs
        $(INSTALL) -b~ -O $(install_uid) -G $(install_gid) -M 0111 sudoreplay $(DESTDIR)$(replaydir)/sudoreplay
@@ -242,16 +258,18 @@ install-binaries: visudo sudoreplay install-dirs
 install-includes:
 
 install-doc: install-dirs
-       @LDAP@$(INSTALL) -O $(install_uid) -G $(install_gid) -M 0555 $(srcdir)/sudoers2ldif $(DESTDIR)$(docdir)
+       @LDAP@$(INSTALL) -O $(install_uid) -G $(install_gid) -m 0555 $(srcdir)/sudoers2ldif $(DESTDIR)$(docdir)
 
 install-plugin: sudoers.la install-dirs
-       $(INSTALL) -b~ -O $(install_uid) -G $(install_gid) -M 0755 .libs/sudoers$(soext) $(DESTDIR)$(plugindir)
+       if [ X"$(soext)" != X"" ]; then \
+           $(INSTALL) -b~ -O $(install_uid) -G $(install_gid) -m 0755 .libs/sudoers$(soext) $(DESTDIR)$(plugindir); \
+       fi
 
 install-sudoers: install-dirs
-       $(INSTALL) -d -O $(sudoers_uid) -G $(sudoers_gid) -M 0750 \
+       $(INSTALL) -d -O $(sudoers_uid) -G $(sudoers_gid) -m 0750 \
            $(DESTDIR)$(sudoersdir)/sudoers.d
        test -r $(DESTDIR)$(sudoersdir)/sudoers || \
-           $(INSTALL) -O $(sudoers_uid) -G $(sudoers_gid) -M $(sudoers_mode) \
+           $(INSTALL) -O $(sudoers_uid) -G $(sudoers_gid) -m $(sudoers_mode) \
                sudoers $(DESTDIR)$(sudoersdir)/sudoers
 
 uninstall:
@@ -342,6 +360,10 @@ mostlyclean: clean
 
 distclean: clean
        -rm -rf Makefile sudoers sudoers.lo .libs $(LINKS)
+       @if [ -n "$(DEVEL)" -a "$(devdir)" != "$(srcdir)" ]; then \
+           cmd='rm -rf $(GENERATED)'; \
+           echo "$$cmd"; eval $$cmd; \
+       fi
 
 clobber: distclean
 
@@ -352,362 +374,404 @@ cleandir: realclean
 
 # Autogenerated dependencies, do not modify
 afs.lo: $(authdir)/afs.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-        $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-        $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-        $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-        $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+        $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+        $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+        $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+        $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+        $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/afs.c
 aix_auth.lo: $(authdir)/aix_auth.c $(top_builddir)/config.h \
-             $(srcdir)/sudoers.h $(top_builddir)/pathnames.h \
-             $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
-             $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
-             $(srcdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-             $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+             $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+             $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
+             $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
+             $(srcdir)/defaults.h $(devdir)/def_data.h $(srcdir)/logging.h \
+             $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
+             $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/aix_auth.c
 alias.lo: $(srcdir)/alias.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-          $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-          $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-          $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-          $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h \
-          $(srcdir)/parse.h $(srcdir)/redblack.h $(srcdir)/gram.h
+          $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+          $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+          $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+          $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+          $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
+          $(srcdir)/parse.h $(srcdir)/redblack.h $(devdir)/gram.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/alias.c
 audit.lo: $(srcdir)/audit.c $(top_builddir)/config.h $(incdir)/missing.h \
-          $(srcdir)/logging.h $(srcdir)/bsm_audit.h $(srcdir)/linux_audit.h
+          $(srcdir)/logging.h $(incdir)/sudo_debug.h $(srcdir)/bsm_audit.h \
+          $(srcdir)/linux_audit.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/audit.c
-boottime.lo: $(srcdir)/boottime.c $(top_builddir)/config.h $(incdir)/missing.h
+boottime.lo: $(srcdir)/boottime.c $(top_builddir)/config.h $(incdir)/missing.h \
+             $(incdir)/sudo_debug.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/boottime.c
 bsdauth.lo: $(authdir)/bsdauth.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-            $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-            $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-            $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-            $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+            $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+            $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+            $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+            $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+            $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/bsdauth.c
 bsm_audit.lo: $(srcdir)/bsm_audit.c $(top_builddir)/config.h \
-              $(srcdir)/bsm_audit.h
+              $(incdir)/gettext.h $(incdir)/sudo_debug.h $(srcdir)/bsm_audit.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/bsm_audit.c
 check.lo: $(srcdir)/check.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-          $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-          $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-          $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-          $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+          $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+          $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+          $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+          $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+          $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/check.c
 check_addr.o: $(srcdir)/regress/parser/check_addr.c $(top_builddir)/config.h \
-              $(srcdir)/sudoers.h $(top_builddir)/pathnames.h \
-              $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
-              $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
-              $(srcdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-              $(incdir)/sudo_plugin.h $(incdir)/gettext.h $(srcdir)/parse.h \
+              $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+              $(top_builddir)/pathnames.h $(incdir)/missing.h \
+              $(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
+              $(incdir)/fileops.h $(srcdir)/defaults.h $(devdir)/def_data.h \
+              $(srcdir)/logging.h $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
+              $(incdir)/sudo_debug.h $(incdir)/gettext.h $(srcdir)/parse.h \
               $(srcdir)/interfaces.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/regress/parser/check_addr.c
 check_fill.o: $(srcdir)/regress/parser/check_fill.c $(top_builddir)/config.h \
-              $(incdir)/list.h $(srcdir)/parse.h $(srcdir)/toke.h \
-              $(srcdir)/gram.h
+              $(top_srcdir)/compat/stdbool.h $(incdir)/list.h \
+              $(srcdir)/parse.h $(srcdir)/toke.h $(incdir)/sudo_plugin.h \
+              $(devdir)/gram.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/regress/parser/check_fill.c
 check_iolog_path.o: $(srcdir)/regress/iolog_path/check_iolog_path.c \
                     $(top_builddir)/config.h $(srcdir)/sudoers.h \
-                    $(top_builddir)/pathnames.h $(incdir)/missing.h \
-                    $(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
-                    $(incdir)/fileops.h $(srcdir)/defaults.h \
-                    $(srcdir)/def_data.h $(srcdir)/logging.h \
+                    $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+                    $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+                    $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+                    $(devdir)/def_data.h $(srcdir)/logging.h \
                     $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
-                    $(incdir)/gettext.h $(srcdir)/def_data.c
+                    $(incdir)/sudo_debug.h $(incdir)/gettext.h \
+                    $(devdir)/def_data.c
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/regress/iolog_path/check_iolog_path.c
 check_wrap.o: $(srcdir)/regress/logging/check_wrap.c $(top_builddir)/config.h \
-              $(incdir)/missing.h $(incdir)/error.h
+              $(incdir)/missing.h $(incdir)/error.h $(incdir)/sudo_plugin.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/regress/logging/check_wrap.c
 dce.lo: $(authdir)/dce.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-        $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-        $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-        $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-        $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+        $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+        $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+        $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+        $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+        $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/dce.c
 defaults.lo: $(srcdir)/defaults.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-             $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-             $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-             $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-             $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h \
-             $(srcdir)/parse.h $(srcdir)/gram.h $(srcdir)/def_data.c
+             $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+             $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+             $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+             $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+             $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
+             $(incdir)/gettext.h $(srcdir)/parse.h $(devdir)/gram.h \
+             $(devdir)/def_data.c
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/defaults.c
 env.lo: $(srcdir)/env.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-        $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-        $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-        $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-        $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+        $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+        $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+        $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+        $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+        $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/env.c
 error.o: $(top_srcdir)/src/error.c $(top_builddir)/config.h \
          $(incdir)/missing.h $(incdir)/error.h $(incdir)/gettext.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(top_srcdir)/src/error.c
 find_path.lo: $(srcdir)/find_path.c $(top_builddir)/config.h \
-              $(srcdir)/sudoers.h $(top_builddir)/pathnames.h \
-              $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
-              $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
-              $(srcdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-              $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+              $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+              $(top_builddir)/pathnames.h $(incdir)/missing.h \
+              $(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
+              $(incdir)/fileops.h $(srcdir)/defaults.h $(devdir)/def_data.h \
+              $(srcdir)/logging.h $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
+              $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/find_path.c
 find_path.o: find_path.lo
 fwtk.lo: $(authdir)/fwtk.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-         $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-         $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-         $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-         $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+         $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+         $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+         $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+         $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+         $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/fwtk.c
 getdate.o: $(devdir)/getdate.c $(top_builddir)/config.h \
            $(top_builddir)/config.h $(incdir)/missing.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(devdir)/getdate.c
 getspwuid.lo: $(srcdir)/getspwuid.c $(top_builddir)/config.h \
-              $(srcdir)/sudoers.h $(top_builddir)/pathnames.h \
-              $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
-              $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
-              $(srcdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-              $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+              $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+              $(top_builddir)/pathnames.h $(incdir)/missing.h \
+              $(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
+              $(incdir)/fileops.h $(srcdir)/defaults.h $(devdir)/def_data.h \
+              $(srcdir)/logging.h $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
+              $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/getspwuid.c
 goodpath.lo: $(srcdir)/goodpath.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-             $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-             $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-             $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-             $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+             $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+             $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+             $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+             $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+             $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/goodpath.c
 goodpath.o: goodpath.lo
 gram.lo: $(devdir)/gram.c $(top_builddir)/config.h $(top_builddir)/config.h \
-         $(srcdir)/sudoers.h $(top_builddir)/pathnames.h $(incdir)/missing.h \
-         $(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
-         $(incdir)/fileops.h $(srcdir)/defaults.h $(srcdir)/def_data.h \
-         $(srcdir)/logging.h $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
-         $(incdir)/gettext.h $(srcdir)/parse.h $(srcdir)/toke.h
+         $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+         $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
+         $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
+         $(srcdir)/defaults.h $(devdir)/def_data.h $(srcdir)/logging.h \
+         $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
+         $(incdir)/gettext.h $(srcdir)/parse.h $(srcdir)/toke.h $(devdir)/gram.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(devdir)/gram.c
 group_plugin.lo: $(srcdir)/group_plugin.c $(top_builddir)/config.h \
                  $(top_srcdir)/compat/dlfcn.h $(srcdir)/sudoers.h \
-                 $(top_builddir)/pathnames.h $(incdir)/missing.h \
-                 $(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
-                 $(incdir)/fileops.h $(srcdir)/defaults.h $(srcdir)/def_data.h \
-                 $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-                 $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+                 $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+                 $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+                 $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+                 $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+                 $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
+                 $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/group_plugin.c
 group_plugin.o: group_plugin.lo
 interfaces.lo: $(srcdir)/interfaces.c $(top_builddir)/config.h \
-               $(srcdir)/sudoers.h $(top_builddir)/pathnames.h \
-               $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
-               $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
-               $(srcdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-               $(incdir)/sudo_plugin.h $(incdir)/gettext.h \
-               $(srcdir)/interfaces.h
+               $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+               $(top_builddir)/pathnames.h $(incdir)/missing.h \
+               $(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
+               $(incdir)/fileops.h $(srcdir)/defaults.h $(devdir)/def_data.h \
+               $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+               $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
+               $(incdir)/gettext.h $(srcdir)/interfaces.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/interfaces.c
 interfaces.o: interfaces.lo
 iolog.lo: $(srcdir)/iolog.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-          $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-          $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-          $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-          $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+          $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+          $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+          $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+          $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+          $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/iolog.c
 iolog_path.lo: $(srcdir)/iolog_path.c $(top_builddir)/config.h \
-               $(srcdir)/sudoers.h $(top_builddir)/pathnames.h \
-               $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
-               $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
-               $(srcdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-               $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+               $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+               $(top_builddir)/pathnames.h $(incdir)/missing.h \
+               $(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
+               $(incdir)/fileops.h $(srcdir)/defaults.h $(devdir)/def_data.h \
+               $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+               $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
+               $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/iolog_path.c
 iolog_path.o: iolog_path.lo
-kerb4.lo: $(authdir)/kerb4.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-          $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-          $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-          $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-          $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
-       $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/kerb4.c
 kerb5.lo: $(authdir)/kerb5.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-          $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-          $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-          $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-          $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+          $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+          $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+          $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+          $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+          $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/kerb5.c
 ldap.lo: $(srcdir)/ldap.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-         $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-         $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-         $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-         $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h \
+         $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+         $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+         $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+         $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+         $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
          $(srcdir)/parse.h $(incdir)/lbuf.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/ldap.c
 linux_audit.lo: $(srcdir)/linux_audit.c $(top_builddir)/config.h \
                 $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
-                $(incdir)/gettext.h $(srcdir)/linux_audit.h
+                $(incdir)/gettext.h $(incdir)/sudo_debug.h \
+                $(srcdir)/linux_audit.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/linux_audit.c
 logging.lo: $(srcdir)/logging.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-            $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-            $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-            $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-            $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+            $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+            $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+            $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+            $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+            $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/logging.c
 logwrap.lo: $(srcdir)/logwrap.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-            $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-            $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-            $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-            $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+            $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+            $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+            $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+            $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+            $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/logwrap.c
 logwrap.o: logwrap.lo
 match.lo: $(srcdir)/match.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-          $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-          $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-          $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-          $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h \
-          $(srcdir)/parse.h $(srcdir)/gram.h $(top_srcdir)/compat/fnmatch.h \
+          $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+          $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+          $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+          $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+          $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
+          $(srcdir)/parse.h $(devdir)/gram.h $(top_srcdir)/compat/fnmatch.h \
           $(top_srcdir)/compat/glob.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/match.c
 match_addr.lo: $(srcdir)/match_addr.c $(top_builddir)/config.h \
-               $(srcdir)/sudoers.h $(top_builddir)/pathnames.h \
-               $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
-               $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
-               $(srcdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-               $(incdir)/sudo_plugin.h $(incdir)/gettext.h \
-               $(srcdir)/interfaces.h
+               $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+               $(top_builddir)/pathnames.h $(incdir)/missing.h \
+               $(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
+               $(incdir)/fileops.h $(srcdir)/defaults.h $(devdir)/def_data.h \
+               $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+               $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
+               $(incdir)/gettext.h $(srcdir)/interfaces.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/match_addr.c
 match_addr.o: match_addr.lo
 net_ifs.o: $(top_srcdir)/src/net_ifs.c $(top_builddir)/config.h \
            $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
-           $(incdir)/gettext.h
+           $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(top_srcdir)/src/net_ifs.c
 pam.lo: $(authdir)/pam.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-        $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-        $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-        $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-        $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+        $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+        $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+        $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+        $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+        $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/pam.c
 parse.lo: $(srcdir)/parse.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-          $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-          $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-          $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-          $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h \
-          $(srcdir)/parse.h $(incdir)/lbuf.h $(srcdir)/gram.h
+          $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+          $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+          $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+          $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+          $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
+          $(srcdir)/parse.h $(incdir)/lbuf.h $(devdir)/gram.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/parse.c
 passwd.lo: $(authdir)/passwd.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-           $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-           $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-           $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-           $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+           $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+           $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+           $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+           $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+           $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/passwd.c
 plugin_error.lo: $(srcdir)/plugin_error.c $(top_builddir)/config.h \
                  $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
                  $(incdir)/sudo_plugin.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/plugin_error.c
 pwutil.lo: $(srcdir)/pwutil.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-           $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-           $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-           $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-           $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h \
+           $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+           $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+           $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+           $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+           $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
            $(srcdir)/redblack.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/pwutil.c
 pwutil.o: pwutil.lo
 redblack.lo: $(srcdir)/redblack.c $(top_builddir)/config.h $(incdir)/missing.h \
-             $(incdir)/alloc.h $(srcdir)/redblack.h
+             $(incdir)/alloc.h $(incdir)/sudo_debug.h $(srcdir)/redblack.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/redblack.c
 redblack.o: redblack.lo
 rfc1938.lo: $(authdir)/rfc1938.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-            $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-            $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-            $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-            $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+            $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+            $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+            $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+            $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+            $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/rfc1938.c
 secureware.lo: $(authdir)/secureware.c $(top_builddir)/config.h \
-               $(srcdir)/sudoers.h $(top_builddir)/pathnames.h \
-               $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
-               $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
-               $(srcdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-               $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+               $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+               $(top_builddir)/pathnames.h $(incdir)/missing.h \
+               $(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
+               $(incdir)/fileops.h $(srcdir)/defaults.h $(devdir)/def_data.h \
+               $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+               $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
+               $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/secureware.c
-securid.lo: $(authdir)/securid.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-            $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-            $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-            $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-            $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
-       $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/securid.c
 securid5.lo: $(authdir)/securid5.c $(top_builddir)/config.h \
-             $(srcdir)/sudoers.h $(top_builddir)/pathnames.h \
-             $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
-             $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
-             $(srcdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-             $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+             $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+             $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
+             $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
+             $(srcdir)/defaults.h $(devdir)/def_data.h $(srcdir)/logging.h \
+             $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
+             $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/securid5.c
 set_perms.lo: $(srcdir)/set_perms.c $(top_builddir)/config.h \
-              $(srcdir)/sudoers.h $(top_builddir)/pathnames.h \
-              $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
-              $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
-              $(srcdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-              $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+              $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+              $(top_builddir)/pathnames.h $(incdir)/missing.h \
+              $(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
+              $(incdir)/fileops.h $(srcdir)/defaults.h $(devdir)/def_data.h \
+              $(srcdir)/logging.h $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
+              $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/set_perms.c
 sia.lo: $(authdir)/sia.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-        $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-        $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-        $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-        $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+        $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+        $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+        $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+        $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+        $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/sia.c
 sudo_auth.lo: $(authdir)/sudo_auth.c $(top_builddir)/config.h \
-              $(srcdir)/sudoers.h $(top_builddir)/pathnames.h \
-              $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
-              $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
-              $(srcdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-              $(incdir)/sudo_plugin.h $(incdir)/gettext.h $(srcdir)/insults.h \
+              $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+              $(top_builddir)/pathnames.h $(incdir)/missing.h \
+              $(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
+              $(incdir)/fileops.h $(srcdir)/defaults.h $(devdir)/def_data.h \
+              $(srcdir)/logging.h $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
+              $(incdir)/sudo_debug.h $(incdir)/gettext.h $(srcdir)/insults.h \
               $(srcdir)/ins_2001.h $(srcdir)/ins_goons.h \
               $(srcdir)/ins_classic.h $(srcdir)/ins_csops.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(authdir)/sudo_auth.c
 sudo_nss.lo: $(srcdir)/sudo_nss.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-             $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-             $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-             $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-             $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h \
-             $(incdir)/lbuf.h
+             $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+             $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+             $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+             $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+             $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
+             $(incdir)/gettext.h $(incdir)/lbuf.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/sudo_nss.c
-sudoers.lo: $(srcdir)/sudoers.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
+sudoers.lo: $(srcdir)/sudoers.c $(top_builddir)/config.h \
+            $(top_srcdir)/compat/getaddrinfo.h $(top_builddir)/config.h \
+            $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
             $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
             $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-            $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-            $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h \
-            $(srcdir)/interfaces.h $(srcdir)/sudoers_version.h \
-            $(srcdir)/auth/sudo_auth.h
+            $(srcdir)/defaults.h $(devdir)/def_data.h $(srcdir)/logging.h \
+            $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
+            $(incdir)/sudo_debug.h $(incdir)/gettext.h $(srcdir)/interfaces.h \
+            $(srcdir)/sudoers_version.h $(srcdir)/auth/sudo_auth.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/sudoers.c
 sudoreplay.o: $(srcdir)/sudoreplay.c $(top_builddir)/config.h \
-              $(top_srcdir)/compat/timespec.h $(top_builddir)/pathnames.h \
-              $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
-              $(incdir)/gettext.h
+              $(top_srcdir)/compat/timespec.h $(top_srcdir)/compat/stdbool.h \
+              $(top_builddir)/pathnames.h $(incdir)/missing.h \
+              $(incdir)/alloc.h $(incdir)/error.h $(incdir)/gettext.h \
+              $(incdir)/sudo_plugin.h $(incdir)/sudo_conf.h $(incdir)/list.h \
+              $(incdir)/sudo_debug.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/sudoreplay.c
 testsudoers.o: $(srcdir)/testsudoers.c $(top_builddir)/config.h \
-               $(srcdir)/tsgetgrpw.h $(top_builddir)/config.h \
-               $(srcdir)/sudoers.h $(top_builddir)/pathnames.h \
+               $(top_srcdir)/compat/fnmatch.h $(srcdir)/tsgetgrpw.h \
+               $(top_builddir)/config.h $(srcdir)/sudoers.h \
+               $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
                $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
                $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
-               $(srcdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-               $(incdir)/sudo_plugin.h $(incdir)/gettext.h \
-               $(srcdir)/interfaces.h $(srcdir)/parse.h $(srcdir)/gram.h \
-               $(top_srcdir)/compat/fnmatch.h
+               $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+               $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
+               $(incdir)/gettext.h $(srcdir)/interfaces.h $(srcdir)/parse.h \
+               $(incdir)/sudo_conf.h $(incdir)/list.h $(devdir)/gram.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/testsudoers.c
 timestr.lo: $(srcdir)/timestr.c $(top_builddir)/config.h $(incdir)/missing.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/timestr.c
 toke.lo: $(devdir)/toke.c $(top_builddir)/config.h $(top_builddir)/config.h \
-         $(srcdir)/sudoers.h $(top_builddir)/pathnames.h $(incdir)/missing.h \
-         $(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
-         $(incdir)/fileops.h $(srcdir)/defaults.h $(srcdir)/def_data.h \
-         $(srcdir)/logging.h $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
-         $(incdir)/gettext.h $(srcdir)/parse.h $(srcdir)/toke.h $(srcdir)/gram.h
+         $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+         $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
+         $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
+         $(srcdir)/defaults.h $(devdir)/def_data.h $(srcdir)/logging.h \
+         $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
+         $(incdir)/gettext.h $(srcdir)/parse.h $(srcdir)/toke.h \
+         $(devdir)/gram.h $(incdir)/lbuf.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(devdir)/toke.c
 toke_util.lo: $(srcdir)/toke_util.c $(top_builddir)/config.h \
-              $(srcdir)/sudoers.h $(top_builddir)/pathnames.h \
-              $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
-              $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
-              $(srcdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-              $(incdir)/sudo_plugin.h $(incdir)/gettext.h $(srcdir)/parse.h \
-              $(srcdir)/toke.h $(srcdir)/gram.h
+              $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+              $(top_builddir)/pathnames.h $(incdir)/missing.h \
+              $(incdir)/error.h $(incdir)/alloc.h $(incdir)/list.h \
+              $(incdir)/fileops.h $(srcdir)/defaults.h $(devdir)/def_data.h \
+              $(srcdir)/logging.h $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
+              $(incdir)/sudo_debug.h $(incdir)/gettext.h $(srcdir)/parse.h \
+              $(srcdir)/toke.h $(devdir)/gram.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/toke_util.c
 toke_util.o: toke_util.lo
 tsgetgrpw.o: $(srcdir)/tsgetgrpw.c $(top_builddir)/config.h \
              $(srcdir)/tsgetgrpw.h $(top_builddir)/config.h \
-             $(srcdir)/sudoers.h $(top_builddir)/pathnames.h \
-             $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
-             $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
-             $(srcdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
-             $(incdir)/sudo_plugin.h $(incdir)/gettext.h
+             $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
+             $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
+             $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
+             $(srcdir)/defaults.h $(devdir)/def_data.h $(srcdir)/logging.h \
+             $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
+             $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/tsgetgrpw.c
 visudo.o: $(srcdir)/visudo.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
-          $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/error.h \
-          $(incdir)/alloc.h $(incdir)/list.h $(incdir)/fileops.h \
-          $(srcdir)/defaults.h $(srcdir)/def_data.h $(srcdir)/logging.h \
-          $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/gettext.h \
+          $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+          $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+          $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+          $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+          $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
           $(srcdir)/interfaces.h $(srcdir)/parse.h $(srcdir)/redblack.h \
-          $(incdir)/gettext.h $(srcdir)/sudoers_version.h $(srcdir)/gram.h
+          $(incdir)/gettext.h $(srcdir)/sudoers_version.h \
+          $(incdir)/sudo_conf.h $(incdir)/list.h $(devdir)/gram.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/visudo.c
index 20f26451c559fa849b86e472229382d1fef2c37c..aaba72881d809c065f43866f7e7a09e33dc8759f 100644 (file)
@@ -62,6 +62,7 @@ alias_compare(const void *v1, const void *v2)
     const struct alias *a1 = (const struct alias *)v1;
     const struct alias *a2 = (const struct alias *)v2;
     int res;
+    debug_decl(alias_compare, SUDO_DEBUG_ALIAS)
 
     if (v1 == NULL)
        res = -1;
@@ -69,7 +70,7 @@ alias_compare(const void *v1, const void *v2)
        res = 1;
     else if ((res = strcmp(a1->name, a2->name)) == 0)
        res = a1->type - a2->type;
-    return res;
+    debug_return_int(res);
 }
 
 /*
@@ -82,6 +83,7 @@ alias_find(char *name, int type)
     struct alias key;
     struct rbnode *node;
     struct alias *a = NULL;
+    debug_decl(alias_find, SUDO_DEBUG_ALIAS)
 
     key.name = name;
     key.type = type;
@@ -94,13 +96,13 @@ alias_find(char *name, int type)
        a = node->data;
        if (a->seqno == alias_seqno) {
            errno = ELOOP;
-           return NULL;
+           debug_return_ptr(NULL);
        }
        a->seqno = alias_seqno;
     } else {
        errno = ENOENT;
     }
-    return a;
+    debug_return_ptr(a);
 }
 
 /*
@@ -112,6 +114,7 @@ alias_add(char *name, int type, struct member *members)
 {
     static char errbuf[512];
     struct alias *a;
+    debug_decl(alias_add, SUDO_DEBUG_ALIAS)
 
     a = emalloc(sizeof(*a));
     a->name = name;
@@ -121,9 +124,9 @@ alias_add(char *name, int type, struct member *members)
     if (rbinsert(aliases, a)) {
        snprintf(errbuf, sizeof(errbuf), _("Alias `%s' already defined"), name);
        alias_free(a);
-       return errbuf;
+       debug_return_str(errbuf);
     }
-    return NULL;
+    debug_return_str(NULL);
 }
 
 /*
@@ -132,16 +135,21 @@ alias_add(char *name, int type, struct member *members)
 void
 alias_apply(int (*func)(void *, void *), void *cookie)
 {
+    debug_decl(alias_apply, SUDO_DEBUG_ALIAS)
+
     rbapply(aliases, func, cookie, inorder);
+
+    debug_return;
 }
 
 /*
- * Returns TRUE if there are no aliases, else FALSE.
+ * Returns true if there are no aliases, else false.
  */
-int
+bool
 no_aliases(void)
 {
-    return rbisempty(aliases);
+    debug_decl(no_aliases, SUDO_DEBUG_ALIAS)
+    debug_return_bool(rbisempty(aliases));
 }
 
 /*
@@ -154,6 +162,7 @@ alias_free(void *v)
     struct member *m;
     struct sudo_command *c;
     void *next;
+    debug_decl(alias_free, SUDO_DEBUG_ALIAS)
 
     efree(a->name);
     for (m = a->members.first; m != NULL; m = next) {
@@ -167,6 +176,8 @@ alias_free(void *v)
        efree(m);
     }
     efree(a);
+
+    debug_return;
 }
 
 /*
@@ -177,6 +188,7 @@ alias_remove(char *name, int type)
 {
     struct rbnode *node;
     struct alias key;
+    debug_decl(alias_remove, SUDO_DEBUG_ALIAS)
 
     key.name = name;
     key.type = type;
@@ -184,13 +196,17 @@ alias_remove(char *name, int type)
        errno = ENOENT;
        return NULL;
     }
-    return rbdelete(aliases, node);
+    debug_return_ptr(rbdelete(aliases, node));
 }
 
 void
 init_aliases(void)
 {
+    debug_decl(init_aliases, SUDO_DEBUG_ALIAS)
+
     if (aliases != NULL)
        rbdestroy(aliases, alias_free);
     aliases = rbcreate(alias_compare);
+
+    debug_return;
 }
index c3d35a27946df8c05427dd32a9554fd5a1315cf2..d2dcca3536b89553293b3abc9a8be57c78862c86 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "missing.h"
 #include "logging.h"
+#include "sudo_debug.h"
 
 #ifdef HAVE_BSM_AUDIT
 # include "bsm_audit.h"
 void
 audit_success(char *exec_args[])
 {
-    if (exec_args == NULL)
-       return;
+    debug_decl(audit_success, SUDO_DEBUG_AUDIT)
 
+    if (exec_args != NULL) {
 #ifdef HAVE_BSM_AUDIT
-    bsm_audit_success(exec_args);
+       bsm_audit_success(exec_args);
 #endif
 #ifdef HAVE_LINUX_AUDIT
-    linux_audit_command(exec_args, 1);
+       linux_audit_command(exec_args, 1);
 #endif
+    }
+
+    debug_return;
 }
 
 void
 audit_failure(char *exec_args[], char const *const fmt, ...)
 {
     va_list ap;
+    debug_decl(audit_success, SUDO_DEBUG_AUDIT)
 
-    if (exec_args == NULL)
-       return;
-
-    va_start(ap, fmt);
+    if (exec_args != NULL) {
+       va_start(ap, fmt);
 #ifdef HAVE_BSM_AUDIT
-    bsm_audit_failure(exec_args, fmt, ap);
+       bsm_audit_failure(exec_args, fmt, ap);
 #endif
 #ifdef HAVE_LINUX_AUDIT
-    linux_audit_command(exec_args, 0);
+       linux_audit_command(exec_args, 0);
 #endif
-    va_end(ap);
+       va_end(ap);
+    }
+
+    debug_return;
 }
index 389bd9d59f270c1de5c9fd27d4cc36f7d75b465d..f9693d04f348fa5bcd75737e15fd9c5d0d0575b4 100644 (file)
 #include "sudo_auth.h"
 
 int
-afs_verify(struct passwd *pw, char *pass, sudo_auth *auth)
+sudo_afs_verify(struct passwd *pw, char *pass, sudo_auth *auth)
 {
     struct ktc_encryptionKey afs_key;
     struct ktc_token afs_token;
+    debug_decl(sudo_afs_verify, SUDO_DEBUG_AUTH)
 
     /* Try to just check the password */
     ka_StringToKey(pass, NULL, &afs_key);
@@ -64,7 +65,7 @@ afs_verify(struct passwd *pw, char *pass, sudo_auth *auth)
                         0,                     /* lifetime */
                         &afs_token,            /* token */
                         0) == 0)               /* new */
-       return AUTH_SUCCESS;
+       debug_return_int(AUTH_SUCCESS);
 
     /* Fall back on old method XXX - needed? */
     setpag();
@@ -77,7 +78,7 @@ afs_verify(struct passwd *pw, char *pass, sudo_auth *auth)
                                   NULL,        /* expiration ptr (unused) */
                                   0,           /* spare */
                                   NULL) == 0)  /* reason */
-       return AUTH_SUCCESS;
+       debug_return_int(AUTH_SUCCESS);
 
-    return AUTH_FAILURE;
+    debug_return_int(AUTH_FAILURE);
 }
index 6abc48cc12ce85b213779b401a1b84fe3f9625fd..be7ba46cc2976be2c3b45065f4b3aca310fb93e2 100644 (file)
  * http://publib16.boulder.ibm.com/doc_link/en_US/a_doc_lib/libs/basetrf1/authenticate.htm
  */
 int
-aixauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
+sudo_aix_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
 {
     char *pass, *message = NULL;
     int result = 1, reenter = 0;
     int rval = AUTH_SUCCESS;
+    debug_decl(sudo_aix_verify, SUDO_DEBUG_AUTH)
 
     do {
        pass = auth_getpass(prompt, def_passwd_timeout * 60,
@@ -84,14 +85,16 @@ aixauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
        rval = pass ? AUTH_FAILURE : AUTH_INTR;
     }
     efree(message);
-    return rval;
+    debug_return_int(rval);
 }
 
 int
-aixauth_cleanup(struct passwd *pw, sudo_auth *auth)
+sudo_aix_cleanup(struct passwd *pw, sudo_auth *auth)
 {
+    debug_decl(sudo_aix_cleanup, SUDO_DEBUG_AUTH)
+
     /* Unset AUTHSTATE as it may not be correct for the runas user. */
     unsetenv("AUTHSTATE");
 
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }
index 60616e2bb106e46a820dd55d1be1944c7ec998b9..5e90898aa8a4836d22435753ca0b6e32e06b0475 100644 (file)
 #include "sudoers.h"
 #include "sudo_auth.h"
 
-extern char *login_style;              /* from sudo.c */
+# ifndef LOGIN_DEFROOTCLASS
+#  define LOGIN_DEFROOTCLASS   "daemon"
+# endif
+
+extern char *login_style;              /* from sudoers.c */
+
+struct bsdauth_state {
+    auth_session_t *as;
+    login_cap_t *lc;
+};
 
 int
 bsdauth_init(struct passwd *pw, sudo_auth *auth)
 {
-    static auth_session_t *as;
-    extern login_cap_t *lc;                    /* from sudo.c */
+    static struct bsdauth_state state;
+    debug_decl(bsdauth_init, SUDO_DEBUG_AUTH)
+
+    /* Get login class based on auth user, which may not be invoking user. */
+    if (pw->pw_class && *pw->pw_class)
+       state.lc = login_getclass(pw->pw_class);
+    else
+       state.lc = login_getclass(pw->pw_uid ? LOGIN_DEFCLASS : LOGIN_DEFROOTCLASS);
+    if (state.lc == NULL) {
+       log_error(USE_ERRNO|NO_EXIT|NO_MAIL,
+           _("unable to get login class for user %s"), pw->pw_name);
+       debug_return_int(AUTH_FATAL);
+    }
 
-    if ((as = auth_open()) == NULL) {
+    if ((state.as = auth_open()) == NULL) {
        log_error(USE_ERRNO|NO_EXIT|NO_MAIL,
            _("unable to begin bsd authentication"));
-       return AUTH_FATAL;
+       login_close(state.lc);
+       debug_return_int(AUTH_FATAL);
     }
 
     /* XXX - maybe sanity check the auth style earlier? */
-    login_style = login_getstyle(lc, login_style, "auth-sudo");
+    login_style = login_getstyle(state.lc, login_style, "auth-sudo");
     if (login_style == NULL) {
        log_error(NO_EXIT|NO_MAIL, _("invalid authentication type"));
-       auth_close(as);
-       return AUTH_FATAL;
+       auth_close(state.as);
+       login_close(state.lc);
+       debug_return_int(AUTH_FATAL);
     }
 
-     if (auth_setitem(as, AUTHV_STYLE, login_style) < 0 ||
-       auth_setitem(as, AUTHV_NAME, pw->pw_name) < 0 ||
-       auth_setitem(as, AUTHV_CLASS, login_class) < 0) {
+     if (auth_setitem(state.as, AUTHV_STYLE, login_style) < 0 ||
+       auth_setitem(state.as, AUTHV_NAME, pw->pw_name) < 0 ||
+       auth_setitem(state.as, AUTHV_CLASS, login_class) < 0) {
        log_error(NO_EXIT|NO_MAIL, _("unable to setup authentication"));
-       auth_close(as);
-       return AUTH_FATAL;
+       auth_close(state.as);
+       login_close(state.lc);
+       debug_return_int(AUTH_FATAL);
     }
 
-    auth->data = (void *) as;
-    return AUTH_SUCCESS;
+    auth->data = (void *) &state;
+    debug_return_int(AUTH_SUCCESS);
 }
 
 int
@@ -93,7 +116,8 @@ bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
     size_t len;
     int authok = 0;
     sigaction_t sa, osa;
-    auth_session_t *as = (auth_session_t *) auth->data;
+    auth_session_t *as = ((struct bsdauth_state *) auth->data)->as;
+    debug_decl(bsdauth_verify, SUDO_DEBUG_AUTH)
 
     /* save old signal handler */
     sigemptyset(&sa.sa_mask);
@@ -140,22 +164,26 @@ bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
     (void) sigaction(SIGCHLD, &osa, NULL);
 
     if (authok)
-       return AUTH_SUCCESS;
+       debug_return_int(AUTH_SUCCESS);
 
     if (!pass)
-       return AUTH_INTR;
+       debug_return_int(AUTH_INTR);
 
     if ((s = auth_getvalue(as, "errormsg")) != NULL)
        log_error(NO_EXIT|NO_MAIL, "%s", s);
-    return AUTH_FAILURE;
+    debug_return_int(AUTH_FAILURE);
 }
 
 int
 bsdauth_cleanup(struct passwd *pw, sudo_auth *auth)
 {
-    auth_session_t *as = (auth_session_t *) auth->data;
+    struct bsdauth_state *state = auth->data;
+    debug_decl(bsdauth_cleanup, SUDO_DEBUG_AUTH)
 
-    auth_close(as);
+    if (state != NULL) {
+       auth_close(state->as);
+       login_close(state->lc);
+    }
 
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }
index a4ffd34ee2fd2ab47b8237c4f491b3413fbf960a..467c08fe956cfd7c7a0fe30b112a9ffb3318c88c 100644 (file)
@@ -67,7 +67,7 @@
 static int check_dce_status(error_status_t, char *);
 
 int
-dce_verify(struct passwd *pw, char *plain_pw, sudo_auth *auth)
+sudo_dce_verify(struct passwd *pw, char *plain_pw, sudo_auth *auth)
 {
     struct passwd              temp_pw;
     sec_passwd_rec_t           password_rec;
@@ -75,6 +75,7 @@ dce_verify(struct passwd *pw, char *plain_pw, sudo_auth *auth)
     boolean32                  reset_passwd;
     sec_login_auth_src_t       auth_src;
     error_status_t             status;
+    debug_decl(sudo_dce_verify, SUDO_DEBUG_AUTH)
 
     /*
      * Create the local context of the DCE principal necessary
@@ -86,7 +87,7 @@ dce_verify(struct passwd *pw, char *plain_pw, sudo_auth *auth)
        sec_login_no_flags, &login_context, &status)) {
 
        if (check_dce_status(status, "sec_login_setup_identity(1):"))
-           return AUTH_FAILURE;
+           debug_return_int(AUTH_FAILURE);
 
        password_rec.key.key_type = sec_passwd_plain;
        password_rec.key.tagged_union.plain = (idl_char *) plain_pw;
@@ -98,7 +99,7 @@ dce_verify(struct passwd *pw, char *plain_pw, sudo_auth *auth)
            &reset_passwd, &auth_src, &status)) {
 
            if (check_dce_status(status, "sec_login_validate_identity(1):"))
-               return AUTH_FAILURE;
+               debug_return_int(AUTH_FAILURE);
 
            /*
             * Certify that the DCE Security Server used to set
@@ -108,10 +109,10 @@ dce_verify(struct passwd *pw, char *plain_pw, sudo_auth *auth)
            if (!sec_login_certify_identity(login_context, &status)) {
                (void) fprintf(stderr, "Whoa! Bogus authentication server!\n");
                (void) check_dce_status(status,"sec_login_certify_identity(1):");
-               return AUTH_FAILURE;
+               debug_return_int(AUTH_FAILURE);
            }
            if (check_dce_status(status, "sec_login_certify_identity(2):"))
-               return AUTH_FAILURE;
+               debug_return_int(AUTH_FAILURE);
 
            /*
             * Sets the network credentials to those specified
@@ -119,7 +120,7 @@ dce_verify(struct passwd *pw, char *plain_pw, sudo_auth *auth)
             */
            sec_login_set_context(login_context, &status);
            if (check_dce_status(status, "sec_login_set_context:"))
-               return AUTH_FAILURE;
+               debug_return_int(AUTH_FAILURE);
 
            /*
             * Oops, your credentials were no good. Possibly
@@ -129,13 +130,13 @@ dce_verify(struct passwd *pw, char *plain_pw, sudo_auth *auth)
            if (auth_src != sec_login_auth_src_network) {
                    (void) fprintf(stderr,
                        "You have no network credentials.\n");
-                   return AUTH_FAILURE;
+                   debug_return_int(AUTH_FAILURE);
            }
            /* Check if the password has aged and is thus no good */
            if (reset_passwd) {
                    (void) fprintf(stderr,
                        "Your DCE password needs resetting.\n");
-                   return AUTH_FAILURE;
+                   debug_return_int(AUTH_FAILURE);
            }
 
            /*
@@ -147,7 +148,7 @@ dce_verify(struct passwd *pw, char *plain_pw, sudo_auth *auth)
            sec_login_get_pwent(login_context, (sec_login_passwd_t) &temp_pw,
                &status);
            if (check_dce_status(status, "sec_login_get_pwent:"))
-               return AUTH_FAILURE;
+               debug_return_int(AUTH_FAILURE);
 
            /*
             * If we get to here, then the pwent above properly fetched
@@ -169,17 +170,17 @@ dce_verify(struct passwd *pw, char *plain_pw, sudo_auth *auth)
             * somewhere later in the program.
             */
            sec_login_purge_context(&login_context, &status);
-           return AUTH_SUCCESS;
+           debug_return_int(AUTH_SUCCESS);
        } else {
            if(check_dce_status(status, "sec_login_validate_identity(2):"))
-               return AUTH_FAILURE;
+               debug_return_int(AUTH_FAILURE);
            sec_login_purge_context(&login_context, &status);
            if(check_dce_status(status, "sec_login_purge_context:"))
-               return AUTH_FAILURE;
+               debug_return_int(AUTH_FAILURE);
        }
     }
     (void) check_dce_status(status, "sec_login_setup_identity(2):");
-    return AUTH_FAILURE;
+    debug_return_int(AUTH_FAILURE);
 }
 
 /* Returns 0 for DCE "ok" status, 1 otherwise */
@@ -188,10 +189,11 @@ check_dce_status(error_status_t input_status, char *comment)
 {
     int error_stat;
     unsigned char error_string[dce_c_error_string_len];
+    debug_decl(check_dce_status, SUDO_DEBUG_AUTH)
 
     if (input_status == rpc_s_ok)
-       return 0;
+       debug_return_bool(0);
     dce_error_inq_text(input_status, error_string, &error_stat);
     (void) fprintf(stderr, "%s %s\n", comment, error_string);
-    return 1;
+    debug_return_bool(1);
 }
index ebab9154a5bd00bf1acfc2fc483c91baec7f0414..48556237c9f9ad067a15cf8cbd6721fe8b1799a2 100644 (file)
 #include "sudo_auth.h"
 
 int
-fwtk_init(struct passwd *pw, sudo_auth *auth)
+sudo_fwtk_init(struct passwd *pw, sudo_auth *auth)
 {
     static Cfg *confp;                 /* Configuration entry struct */
     char resp[128];                    /* Response from the server */
+    debug_decl(sudo_fwtk_init, SUDO_DEBUG_AUTH)
 
     if ((confp = cfg_read("sudo")) == (Cfg *)-1) {
        warningx(_("unable to read fwtk config"));
-       return AUTH_FATAL;
+       debug_return_int(AUTH_FATAL);
     }
 
     if (auth_open(confp)) {
        warningx(_("unable to connect to authentication server"));
-       return AUTH_FATAL;
+       debug_return_int(AUTH_FATAL);
     }
 
     /* Get welcome message from auth server */
     if (auth_recv(resp, sizeof(resp))) {
        warningx(_("lost connection to authentication server"));
-       return AUTH_FATAL;
+       debug_return_int(AUTH_FATAL);
     }
     if (strncmp(resp, "Authsrv ready", 13) != 0) {
        warningx(_("authentication server error:\n%s"), resp);
-       return AUTH_FATAL;
+       debug_return_int(AUTH_FATAL);
     }
 
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }
 
 int
-fwtk_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
+sudo_fwtk_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
 {
     char *pass;                                /* Password from the user */
     char buf[SUDO_PASS_MAX + 12];      /* General prupose buffer */
     char resp[128];                    /* Response from the server */
     int error;
+    debug_decl(sudo_fwtk_verify, SUDO_DEBUG_AUTH)
 
     /* Send username to authentication server. */
     (void) snprintf(buf, sizeof(buf), "authorize %s 'sudo'", pw->pw_name);
 restart:
     if (auth_send(buf) || auth_recv(resp, sizeof(resp))) {
        warningx(_("lost connection to authentication server"));
-       return AUTH_FATAL;
+       debug_return_int(AUTH_FATAL);
     }
 
     /* Get the password/response from the user. */
@@ -114,10 +116,10 @@ restart:
        goto restart;
     } else {
        warningx("%s", resp);
-       return AUTH_FATAL;
+       debug_return_int(AUTH_FATAL);
     }
     if (!pass) {                       /* ^C or error */
-       return AUTH_INTR;
+       debug_return_int(AUTH_INTR);
     }
 
     /* Send the user's response to the server */
@@ -140,13 +142,14 @@ restart:
 done:
     zero_bytes(pass, strlen(pass));
     zero_bytes(buf, strlen(buf));
-    return error;
+    debug_return_int(error);
 }
 
 int
-fwtk_cleanup(struct passwd *pw, sudo_auth *auth)
+sudo_fwtk_cleanup(struct passwd *pw, sudo_auth *auth)
 {
+    debug_decl(sudo_fwtk_cleanup, SUDO_DEBUG_AUTH)
 
     auth_close();
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }
diff --git a/plugins/sudoers/auth/kerb4.c b/plugins/sudoers/auth/kerb4.c
deleted file mode 100644 (file)
index c16739a..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 1999-2005, 2007, 2010-2011
- *     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.
- */
-
-#include <config.h>
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <stdio.h>
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-# endif
-#endif /* STDC_HEADERS */
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif /* HAVE_STRING_H */
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif /* HAVE_STRING_H */
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#include <pwd.h>
-#include <krb.h>
-
-#include "sudoers.h"
-#include "sudo_auth.h"
-
-int
-kerb4_init(struct passwd *pw, sudo_auth *auth)
-{
-    static char realm[REALM_SZ];
-
-    /* Don't try to verify root */
-    if (pw->pw_uid == 0)
-       return AUTH_FAILURE;
-
-    /* Get the local realm, or retrun failure (no krb.conf) */
-    if (krb_get_lrealm(realm, 1) != KSUCCESS)
-       return AUTH_FAILURE;
-
-    /* Stash a pointer to the realm (used in kerb4_verify) */
-    auth->data = (void *) realm;
-
-    return AUTH_SUCCESS;
-}
-
-int
-kerb4_verify(struct passwd *pw, char *pass, sudo_auth *auth)
-{
-    char tkfile[sizeof(_PATH_SUDO_TIMEDIR) + 4 + MAX_UID_T_LEN];
-    char *realm = (char *) auth->data;
-    int error;
-
-    /*
-     * Set the ticket file to be in sudo sudo timedir so we don't
-     * wipe out other (real) kerberos tickets.
-     */
-    (void) snprintf(tkfile, sizeof(tkfile), "%s/tkt%u",
-       _PATH_SUDO_TIMEDIR, (unsigned int) pw->pw_uid);
-    (void) krb_set_tkt_string(tkfile);
-
-    /* Convert the password to a ticket given. */
-    error = krb_get_pw_in_tkt(pw->pw_name, "", realm, "krbtgt", realm,
-       DEFAULT_TKT_LIFE, pass);
-
-    switch (error) {
-       case INTK_OK:
-           dest_tkt();                 /* we are done with the temp ticket */
-           return AUTH_SUCCESS;
-           break;
-       case INTK_BADPW:
-       case KDC_PR_UNKNOWN:
-           break;
-       default:
-           (void) fprintf(stderr, "Warning: Kerberos error: %s\n",
-               krb_err_txt[error]);
-    }
-
-    return AUTH_FAILURE;
-}
index f94865dd4e9ed8ef9851553f2fa4d94b725d33c1..3ba7b8c5b81e4f20d4547bf1e2348b14d0c67207 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2005, 2007-2008, 2010-2011
+ * Copyright (c) 1999-2005, 2007-2008, 2010-2012
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -70,6 +70,12 @@ static struct _sudo_krb5_data {
 } sudo_krb5_data = { NULL, NULL, NULL };
 typedef struct _sudo_krb5_data *sudo_krb5_datap;
 
+#ifdef SUDO_KRB5_INSTANCE
+static const char *sudo_krb5_instance = SUDO_KRB5_INSTANCE;
+#else
+static const char *sudo_krb5_instance = NULL;
+#endif
+
 #ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
 static krb5_error_code
 krb5_get_init_creds_opt_alloc(krb5_context context,
@@ -88,9 +94,10 @@ krb5_get_init_creds_opt_free(krb5_get_init_creds_opt *opts)
 #endif
 
 int
-kerb5_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
+sudo_krb5_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
 {
     static char        *krb5_prompt;
+    debug_decl(sudo_krb5_init, SUDO_DEBUG_AUTH)
 
     if (krb5_prompt == NULL) {
        krb5_context    sudo_context;
@@ -109,7 +116,7 @@ kerb5_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
            log_error(NO_EXIT|NO_MAIL,
                      _("%s: unable to unparse princ ('%s'): %s"), auth->name,
                      pw->pw_name, error_message(error));
-           return AUTH_FAILURE;
+           debug_return_int(AUTH_FAILURE);
        }
 
        /* Only rewrite prompt if user didn't specify their own. */
@@ -120,37 +127,40 @@ kerb5_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
     }
     *promptp = krb5_prompt;
 
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }
 
 int
-kerb5_init(struct passwd *pw, sudo_auth *auth)
+sudo_krb5_init(struct passwd *pw, sudo_auth *auth)
 {
     krb5_context       sudo_context;
-    krb5_ccache                ccache;
-    krb5_principal     princ;
     krb5_error_code    error;
-    char               cache_name[64];
+    char               cache_name[64], *pname = pw->pw_name;
+    debug_decl(sudo_krb5_init, SUDO_DEBUG_AUTH)
 
     auth->data = (void *) &sudo_krb5_data; /* Stash all our data here */
 
+    if (sudo_krb5_instance != NULL) {
+       easprintf(&pname, "%s%s%s", pw->pw_name,
+           sudo_krb5_instance[0] != '/' ? "/" : "", sudo_krb5_instance);
+    }
+
 #ifdef HAVE_KRB5_INIT_SECURE_CONTEXT
     error = krb5_init_secure_context(&(sudo_krb5_data.sudo_context));
 #else
     error = krb5_init_context(&(sudo_krb5_data.sudo_context));
 #endif
     if (error)
-       return AUTH_FAILURE;
+       goto done;
     sudo_context = sudo_krb5_data.sudo_context;
 
-    if ((error = krb5_parse_name(sudo_context, pw->pw_name,
-       &(sudo_krb5_data.princ)))) {
+    error = krb5_parse_name(sudo_context, pname, &(sudo_krb5_data.princ));
+    if (error) {
        log_error(NO_EXIT|NO_MAIL,
-                 _("%s: unable to parse '%s': %s"), auth->name, pw->pw_name,
+                 _("%s: unable to parse '%s': %s"), auth->name, pname,
                  error_message(error));
-       return AUTH_FAILURE;
+       goto done;
     }
-    princ = sudo_krb5_data.princ;
 
     (void) snprintf(cache_name, sizeof(cache_name), "MEMORY:sudocc_%ld",
                    (long) getpid());
@@ -159,32 +169,35 @@ kerb5_init(struct passwd *pw, sudo_auth *auth)
        log_error(NO_EXIT|NO_MAIL,
                  _("%s: unable to resolve ccache: %s"), auth->name,
                  error_message(error));
-       return AUTH_FAILURE;
+       goto done;
     }
-    ccache = sudo_krb5_data.ccache;
 
-    return AUTH_SUCCESS;
+done:
+    if (sudo_krb5_instance != NULL)
+       efree(pname);
+    debug_return_int(error ? AUTH_FAILURE : AUTH_SUCCESS);
 }
 
 #ifdef HAVE_KRB5_VERIFY_USER
 int
-kerb5_verify(struct passwd *pw, char *pass, sudo_auth *auth)
+sudo_krb5_verify(struct passwd *pw, char *pass, sudo_auth *auth)
 {
     krb5_context       sudo_context;
     krb5_principal     princ;
     krb5_ccache                ccache;
     krb5_error_code    error;
+    debug_decl(sudo_krb5_verify, SUDO_DEBUG_AUTH)
 
     sudo_context = ((sudo_krb5_datap) auth->data)->sudo_context;
     princ = ((sudo_krb5_datap) auth->data)->princ;
     ccache = ((sudo_krb5_datap) auth->data)->ccache;
 
     error = krb5_verify_user(sudo_context, princ, ccache, pass, 1, NULL);
-    return error ? AUTH_FAILURE : AUTH_SUCCESS;
+    debug_return_int(error ? AUTH_FAILURE : AUTH_SUCCESS);
 }
 #else
 int
-kerb5_verify(struct passwd *pw, char *pass, sudo_auth *auth)
+sudo_krb5_verify(struct passwd *pw, char *pass, sudo_auth *auth)
 {
     krb5_context       sudo_context;
     krb5_principal     princ;
@@ -192,6 +205,7 @@ kerb5_verify(struct passwd *pw, char *pass, sudo_auth *auth)
     krb5_ccache                ccache;
     krb5_error_code    error;
     krb5_get_init_creds_opt *opts = NULL;
+    debug_decl(sudo_krb5_verify, SUDO_DEBUG_AUTH)
 
     sudo_context = ((sudo_krb5_datap) auth->data)->sudo_context;
     princ = ((sudo_krb5_datap) auth->data)->princ;
@@ -248,16 +262,17 @@ done:
     }
     if (creds)
        krb5_free_cred_contents(sudo_context, creds);
-    return error ? AUTH_FAILURE : AUTH_SUCCESS;
+    debug_return_int(error ? AUTH_FAILURE : AUTH_SUCCESS);
 }
 #endif
 
 int
-kerb5_cleanup(struct passwd *pw, sudo_auth *auth)
+sudo_krb5_cleanup(struct passwd *pw, sudo_auth *auth)
 {
     krb5_context       sudo_context;
     krb5_principal     princ;
     krb5_ccache                ccache;
+    debug_decl(sudo_krb5_cleanup, SUDO_DEBUG_AUTH)
 
     sudo_context = ((sudo_krb5_datap) auth->data)->sudo_context;
     princ = ((sudo_krb5_datap) auth->data)->princ;
@@ -271,7 +286,7 @@ kerb5_cleanup(struct passwd *pw, sudo_auth *auth)
        krb5_free_context(sudo_context);
     }
 
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }
 
 #ifndef HAVE_KRB5_VERIFY_USER
@@ -289,6 +304,7 @@ verify_krb_v5_tgt(krb5_context sudo_context, krb5_creds *cred, char *auth_name)
     krb5_error_code    error;
     krb5_principal     server;
     krb5_verify_init_creds_opt vopt;
+    debug_decl(verify_krb_v5_tgt, SUDO_DEBUG_AUTH)
 
     /*
      * Get the server principal for the local host.
@@ -299,7 +315,7 @@ verify_krb_v5_tgt(krb5_context sudo_context, krb5_creds *cred, char *auth_name)
        log_error(NO_EXIT|NO_MAIL,
                  _("%s: unable to get host principal: %s"), auth_name,
                  error_message(error));
-       return -1;
+       debug_return_int(-1);
     }
 
     /* Initialize verify opts and set secure mode */
@@ -314,6 +330,6 @@ verify_krb_v5_tgt(krb5_context sudo_context, krb5_creds *cred, char *auth_name)
        log_error(NO_EXIT|NO_MAIL,
                  _("%s: Cannot verify TGT! Possible attack!: %s"),
                  auth_name, error_message(error));
-    return error;
+    debug_return_int(error);
 }
 #endif
index 70e916e0ef2ddb643b8bda817e88f3116451b0f9..74a7ea55c980e44806366553017b9e898271d700 100644 (file)
@@ -80,10 +80,11 @@ static int gotintr;
 static pam_handle_t *pamh;
 
 int
-pam_init(struct passwd *pw, sudo_auth *auth)
+sudo_pam_init(struct passwd *pw, sudo_auth *auth)
 {
     static struct pam_conv pam_conv;
     static int pam_status;
+    debug_decl(sudo_pam_init, SUDO_DEBUG_AUTH)
 
     /* Initial PAM setup */
     if (auth != NULL)
@@ -97,7 +98,7 @@ pam_init(struct passwd *pw, sudo_auth *auth)
        pam_status = pam_start("sudo", pw->pw_name, &pam_conv, &pamh);
     if (pam_status != PAM_SUCCESS) {
        log_error(USE_ERRNO|NO_EXIT|NO_MAIL, _("unable to initialize PAM"));
-       return AUTH_FATAL;
+       debug_return_int(AUTH_FATAL);
     }
 
     /*
@@ -119,14 +120,15 @@ pam_init(struct passwd *pw, sudo_auth *auth)
     else
        (void) pam_set_item(pamh, PAM_TTY, user_ttypath);
 
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }
 
 int
-pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
+sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
 {
     const char *s;
     int *pam_status = (int *) auth->data;
+    debug_decl(sudo_pam_verify, SUDO_DEBUG_AUTH)
 
     def_prompt = prompt;       /* for converse */
 
@@ -137,65 +139,67 @@ pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
            *pam_status = pam_acct_mgmt(pamh, PAM_SILENT);
            switch (*pam_status) {
                case PAM_SUCCESS:
-                   return AUTH_SUCCESS;
+                   debug_return_int(AUTH_SUCCESS);
                case PAM_AUTH_ERR:
                    log_error(NO_EXIT|NO_MAIL, _("account validation failure, "
                        "is your account locked?"));
-                   return AUTH_FATAL;
+                   debug_return_int(AUTH_FATAL);
                case PAM_NEW_AUTHTOK_REQD:
                    log_error(NO_EXIT|NO_MAIL, _("Account or password is "
                        "expired, reset your password and try again"));
                    *pam_status = pam_chauthtok(pamh,
                        PAM_CHANGE_EXPIRED_AUTHTOK);
                    if (*pam_status == PAM_SUCCESS)
-                       return AUTH_SUCCESS;
+                       debug_return_int(AUTH_SUCCESS);
                    if ((s = pam_strerror(pamh, *pam_status)))
                        log_error(NO_EXIT|NO_MAIL, _("pam_chauthtok: %s"), s);
-                   return AUTH_FAILURE;
+                   debug_return_int(AUTH_FAILURE);
                case PAM_AUTHTOK_EXPIRED:
                    log_error(NO_EXIT|NO_MAIL,
                        _("Password expired, contact your system administrator"));
-                   return AUTH_FATAL;
+                   debug_return_int(AUTH_FATAL);
                case PAM_ACCT_EXPIRED:
                    log_error(NO_EXIT|NO_MAIL,
                        _("Account expired or PAM config lacks an \"account\" "
                        "section for sudo, contact your system administrator"));
-                   return AUTH_FATAL;
+                   debug_return_int(AUTH_FATAL);
            }
            /* FALLTHROUGH */
        case PAM_AUTH_ERR:
            if (gotintr) {
                /* error or ^C from tgetpass() */
-               return AUTH_INTR;
+               debug_return_int(AUTH_INTR);
            }
        case PAM_MAXTRIES:
        case PAM_PERM_DENIED:
-           return AUTH_FAILURE;
+           debug_return_int(AUTH_FAILURE);
        default:
            if ((s = pam_strerror(pamh, *pam_status)))
                log_error(NO_EXIT|NO_MAIL, _("pam_authenticate: %s"), s);
-           return AUTH_FATAL;
+           debug_return_int(AUTH_FATAL);
     }
 }
 
 int
-pam_cleanup(struct passwd *pw, sudo_auth *auth)
+sudo_pam_cleanup(struct passwd *pw, sudo_auth *auth)
 {
     int *pam_status = (int *) auth->data;
+    debug_decl(sudo_pam_cleanup, SUDO_DEBUG_AUTH)
 
     /* If successful, we can't close the session until pam_end_session() */
     if (*pam_status == AUTH_SUCCESS)
-       return AUTH_SUCCESS;
+       debug_return_int(AUTH_SUCCESS);
 
     *pam_status = pam_end(pamh, *pam_status | PAM_DATA_SILENT);
     pamh = NULL;
-    return *pam_status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE;
+    debug_return_int(*pam_status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE);
 }
 
 int
-pam_begin_session(struct passwd *pw, sudo_auth *auth)
+sudo_pam_begin_session(struct passwd *pw, sudo_auth *auth)
 {
     int status = PAM_SUCCESS;
+    debug_decl(sudo_pam_begin_session, SUDO_DEBUG_AUTH)
 
     /*
      * If there is no valid user we cannot open a PAM session.
@@ -235,13 +239,14 @@ pam_begin_session(struct passwd *pw, sudo_auth *auth)
 #endif
 
 done:
-    return status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE;
+    debug_return_int(status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE);
 }
 
 int
-pam_end_session(struct passwd *pw, sudo_auth *auth)
+sudo_pam_end_session(struct passwd *pw, sudo_auth *auth)
 {
     int status = PAM_SUCCESS;
+    debug_decl(sudo_pam_end_session, SUDO_DEBUG_AUTH)
 
     if (pamh != NULL) {
 #ifndef NO_PAM_SESSION
@@ -256,7 +261,7 @@ pam_end_session(struct passwd *pw, sudo_auth *auth)
        pamh = NULL;
     }
 
-    return status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE;
+    debug_return_int(status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE);
 }
 
 /*
@@ -272,9 +277,10 @@ converse(int num_msg, PAM_CONST struct pam_message **msg,
     const char *prompt;
     char *pass;
     int n, type, std_prompt;
+    debug_decl(converse, SUDO_DEBUG_AUTH)
 
     if ((*response = malloc(num_msg * sizeof(struct pam_response))) == NULL)
-       return PAM_SYSTEM_ERR;
+       debug_return_int(PAM_SYSTEM_ERR);
     zero_bytes(*response, num_msg * sizeof(struct pam_response));
 
     for (pr = *response, pm = *msg, n = num_msg; n--; pr++, pm++) {
@@ -336,7 +342,7 @@ converse(int num_msg, PAM_CONST struct pam_message **msg,
        }
     }
 
-    return PAM_SUCCESS;
+    debug_return_int(PAM_SUCCESS);
 
 err:
     /* Zero and free allocated memory and return an error. */
@@ -350,5 +356,5 @@ err:
     zero_bytes(*response, num_msg * sizeof(struct pam_response));
     free(*response);
     *response = NULL;
-    return gotintr ? PAM_AUTH_ERR : PAM_CONV_ERR;
+    debug_return_int(gotintr ? PAM_AUTH_ERR : PAM_CONV_ERR);
 }
index 1316acdae7f8224b6d4b4f2ae63c6005f29e6612..1736f30668cb3466fd26ba430b420bf521384d58 100644 (file)
 #define HAS_AGEINFO(p, l)      (l == 18 && p[DESLEN] == ',')
 
 int
-passwd_init(struct passwd *pw, sudo_auth *auth)
+sudo_passwd_init(struct passwd *pw, sudo_auth *auth)
 {
+    debug_decl(sudo_passwd_init, SUDO_DEBUG_AUTH)
+
 #ifdef HAVE_SKEYACCESS
     if (skeyaccess(pw, user_tty, NULL, NULL) == 0)
-       return AUTH_FAILURE;
+       debug_return_int(AUTH_FAILURE);
 #endif
     sudo_setspent();
     auth->data = sudo_getepw(pw);
     sudo_endspent();
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }
 
 int
-passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth)
+sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth)
 {
     char sav, *epass;
     char *pw_epasswd = auth->data;
     size_t pw_len;
     int error;
+    debug_decl(sudo_passwd_verify, SUDO_DEBUG_AUTH)
 
     pw_len = strlen(pw_epasswd);
 
@@ -75,7 +78,7 @@ passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth)
     /* Ultrix shadow passwords may use crypt16() */
     error = strcmp(pw_epasswd, (char *) crypt16(pass, pw_epasswd));
     if (!error)
-       return AUTH_SUCCESS;
+       debug_return_int(AUTH_SUCCESS);
 #endif /* HAVE_GETAUTHUID */
 
     /*
@@ -98,19 +101,20 @@ passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth)
     else
        error = strcmp(pw_epasswd, epass);
 
-    return error ? AUTH_FAILURE : AUTH_SUCCESS;
+    debug_return_int(error ? AUTH_FAILURE : AUTH_SUCCESS);
 }
 
 int
-passwd_cleanup(pw, auth)
+sudo_passwd_cleanup(pw, auth)
     struct passwd *pw;
     sudo_auth *auth;
 {
     char *pw_epasswd = auth->data;
+    debug_decl(sudo_passwd_cleanup, SUDO_DEBUG_AUTH)
 
     if (pw_epasswd != NULL) {
        zero_bytes(pw_epasswd, strlen(pw_epasswd));
        efree(pw_epasswd);
     }
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }
index fe5b28f372c4dd8223eb5180b445c065235eac3b..f4ed7c0f6de2ff9b11af2cec93d35279ca8d1052 100644 (file)
 #include "sudo_auth.h"
 
 int
-rfc1938_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
+sudo_rfc1938_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
 {
     char challenge[256];
     static char *orig_prompt = NULL, *new_prompt = NULL;
     static int op_len, np_size;
     static struct RFC1938 rfc1938;
+    debug_decl(sudo_rfc1938_setup, SUDO_DEBUG_AUTH)
 
     /* Stash a pointer to the rfc1938 struct if we have not initialized */
     if (!auth->data)
@@ -101,9 +102,9 @@ rfc1938_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
     if (rfc1938challenge(&rfc1938, pw->pw_name, challenge, sizeof(challenge))) {
        if (IS_ONEANDONLY(auth)) {
            warningx(_("you do not exist in the %s database"), auth->name);
-           return AUTH_FATAL;
+           debug_return_int(AUTH_FATAL);
        } else {
-           return AUTH_FAILURE;
+           debug_return_int(AUTH_FAILURE);
        }
     }
 
@@ -120,15 +121,16 @@ rfc1938_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
            orig_prompt, challenge);
 
     *promptp = new_prompt;
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }
 
 int
-rfc1938_verify(struct passwd *pw, char *pass, sudo_auth *auth)
+sudo_rfc1938_verify(struct passwd *pw, char *pass, sudo_auth *auth)
 {
+    debug_decl(sudo_rfc1938_verify, SUDO_DEBUG_AUTH)
 
     if (rfc1938verify((struct RFC1938 *) auth->data, pass) == 0)
-       return AUTH_SUCCESS;
+       debug_return_int(AUTH_SUCCESS);
     else
-       return AUTH_FAILURE;
+       debug_return_int(AUTH_FAILURE);
 }
index 8a08da79f209402994adb2a165d116dfe8a81ffc..776b5dd700d025e859129cc4919ca6589a458299 100644 (file)
 #include "sudo_auth.h"
 
 int
-secureware_init(struct passwd *pw, sudo_auth *auth)
+sudo_secureware_init(struct passwd *pw, sudo_auth *auth)
 {
 #ifdef __alpha
     extern int crypt_type;
+    debug_decl(sudo_secureware_init, SUDO_DEBUG_AUTH)
 
     if (crypt_type == INT_MAX)
-       return AUTH_FAILURE;                    /* no shadow */
+       debug_return_int(AUTH_FAILURE);                 /* no shadow */
+#else
+    debug_decl(secureware_init, SUDO_DEBUG_AUTH)
 #endif
     sudo_setspent();
     auth->data = sudo_getepw(pw);
     sudo_endspent();
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }
 
 int
-secureware_verify(struct passwd *pw, char *pass, sudo_auth *auth)
+sudo_secureware_verify(struct passwd *pw, char *pass, sudo_auth *auth)
 {
     char *pw_epasswd = auth->data;
+    debug_decl(sudo_secureware_verify, SUDO_DEBUG_AUTH)
 #ifdef __alpha
-    extern int crypt_type;
+    {
+       extern int crypt_type;
 
 #  ifdef HAVE_DISPCRYPT
-    if (strcmp(pw_epasswd, dispcrypt(pass, pw_epasswd, crypt_type)) == 0)
-       return AUTH_SUCCESS;
+       if (strcmp(pw_epasswd, dispcrypt(pass, pw_epasswd, crypt_type)) == 0)
+           debug_return_int(AUTH_SUCCESS);
 #  else
-    if (crypt_type == AUTH_CRYPT_BIGCRYPT) {
-       if (strcmp(pw_epasswd, bigcrypt(pass, pw_epasswd)) == 0)
-           return AUTH_SUCCESS;
-    } else if (crypt_type == AUTH_CRYPT_CRYPT16) {
-       if (strcmp(pw_epasswd, crypt(pass, pw_epasswd)) == 0)
-           return AUTH_SUCCESS;
+       if (crypt_type == AUTH_CRYPT_BIGCRYPT) {
+           if (strcmp(pw_epasswd, bigcrypt(pass, pw_epasswd)) == 0)
+               debug_return_int(AUTH_SUCCESS);
+       } else if (crypt_type == AUTH_CRYPT_CRYPT16) {
+           if (strcmp(pw_epasswd, crypt(pass, pw_epasswd)) == 0)
+               debug_return_int(AUTH_SUCCESS);
+       }
     }
 #  endif /* HAVE_DISPCRYPT */
 #elif defined(HAVE_BIGCRYPT)
     if (strcmp(pw_epasswd, bigcrypt(pass, pw_epasswd)) == 0)
-       return AUTH_SUCCESS;
+       debug_return_int(AUTH_SUCCESS);
 #endif /* __alpha */
 
-       return AUTH_FAILURE;
+       debug_return_int(AUTH_FAILURE);
 }
 
 int
-secureware_cleanup(pw, auth)
+sudo_secureware_cleanup(pw, auth)
     struct passwd *pw;
     sudo_auth *auth;
 {
     char *pw_epasswd = auth->data;
+    debug_decl(sudo_secureware_cleanup, SUDO_DEBUG_AUTH)
 
     if (pw_epasswd != NULL) {
        zero_bytes(pw_epasswd, strlen(pw_epasswd));
        efree(pw_epasswd);
     }
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }
diff --git a/plugins/sudoers/auth/securid.c b/plugins/sudoers/auth/securid.c
deleted file mode 100644 (file)
index 2c3796c..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 1999-2005, 2007, 2010-2011
- *     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.
- * 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.
- *
- * 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.
- */
-
-#include <config.h>
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <stdio.h>
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-# endif
-#endif /* STDC_HEADERS */
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif /* HAVE_STRING_H */
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif /* HAVE_STRINGS_H */
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#include <pwd.h>
-
-#include <sdi_athd.h>
-#include <sdconf.h>
-#include <sdacmvls.h>
-
-#include "sudoers.h"
-#include "sudo_auth.h"
-
-union config_record configure;
-
-int
-securid_init(struct passwd *pw, sudo_auth *auth)
-{
-    static struct SD_CLIENT sd_dat;            /* SecurID data block */
-
-    auth->data = (void *) &sd_dat;             /* For method-specific data */
-
-    if (creadcfg() == 0)
-       return AUTH_SUCCESS;
-    else
-       return AUTH_FATAL;
-}
-
-int
-securid_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
-{
-    struct SD_CLIENT *sd = (struct SD_CLIENT *) auth->data;
-
-    /* Re-initialize SecurID every time. */
-    if (sd_init(sd) == 0) {
-       /* The programmer's guide says username is 32 bytes */
-       strlcpy(sd->username, pw->pw_name, 32);
-       return AUTH_SUCCESS;
-    } else {
-       warningx(_("unable to contact the SecurID server"));
-       return AUTH_FATAL;
-    }
-}
-
-int
-securid_verify(struct passwd *pw, char *pass, sudo_auth *auth)
-{
-    struct SD_CLIENT *sd = (struct SD_CLIENT *) auth->data;
-    int rval;
-
-    rval = sd_auth(sd);
-    sd_close();
-    if (rval == ACM_OK)
-       return AUTH_SUCCESS;
-    else
-       return AUTH_FAILURE;
-}
index cf022d2f880293f5cdb359e16d919fcd9f0b5c6f..6fe7dcbd079f7e0d01070805ee858957d3a17edf 100644 (file)
  *                   success.
  */
 int
-securid_init(struct passwd *pw, sudo_auth *auth)
+sudo_securid_init(struct passwd *pw, sudo_auth *auth)
 {
     static SDI_HANDLE sd_dat;                  /* SecurID handle */
+    debug_decl(sudo_securid_init, SUDO_DEBUG_AUTH)
 
     auth->data = (void *) &sd_dat;             /* For method-specific data */
 
     /* Start communications */
     if (AceInitialize() != SD_FALSE)
-       return AUTH_SUCCESS;
+       debug_return_int(AUTH_SUCCESS);
 
     warningx(_("failed to initialise the ACE API library"));
-    return AUTH_FATAL;
+    debug_return_int(AUTH_FATAL);
 }
 
 /*
@@ -95,15 +96,16 @@ securid_init(struct passwd *pw, sudo_auth *auth)
  *                   otherwise
  */
 int
-securid_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
+sudo_securid_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
 {
     SDI_HANDLE *sd = (SDI_HANDLE *) auth->data;
     int retval;
+    debug_decl(sudo_securid_setup, SUDO_DEBUG_AUTH)
 
     /* Re-initialize SecurID every time. */
     if (SD_Init(sd) != ACM_OK) {
        warningx(_("unable to contact the SecurID server"));
-       return AUTH_FATAL;
+       debug_return_int(AUTH_FATAL);
     }
 
     /* Lock new PIN code */
@@ -112,23 +114,23 @@ securid_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
     switch (retval) {
        case ACM_OK:
                warningx(_("User ID locked for SecurID Authentication"));
-               return AUTH_SUCCESS;
+               debug_return_int(AUTH_SUCCESS);
 
         case ACE_UNDEFINED_USERNAME:
                warningx(_("invalid username length for SecurID"));
-               return AUTH_FATAL;
+               debug_return_int(AUTH_FATAL);
 
        case ACE_ERR_INVALID_HANDLE:
                warningx(_("invalid Authentication Handle for SecurID"));
-               return AUTH_FATAL;
+               debug_return_int(AUTH_FATAL);
 
        case ACM_ACCESS_DENIED:
                warningx(_("SecurID communication failed"));
-               return AUTH_FATAL;
+               debug_return_int(AUTH_FATAL);
 
        default:
                warningx(_("unknown SecurID error"));
-               return AUTH_FATAL;
+               debug_return_int(AUTH_FATAL);
        }
 }
 
@@ -145,10 +147,11 @@ securid_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
  *                   incorrect authentication, fatal on errors
  */
 int
-securid_verify(struct passwd *pw, char *pass, sudo_auth *auth)
+sudo_securid_verify(struct passwd *pw, char *pass, sudo_auth *auth)
 {
     SDI_HANDLE *sd = (SDI_HANDLE *) auth->data;
     int rval;
+    debug_decl(sudo_securid_verify, SUDO_DEBUG_AUTH)
 
     pass = auth_getpass("Enter your PASSCODE: ",
        def_passwd_timeout * 60, SUDO_CONV_PROMPT_ECHO_OFF);
@@ -218,5 +221,5 @@ then enter the new token code.\n", \
     SD_Close(*sd);
 
     /* Return stored state to calling process */
-    return rval;
+    debug_return_int(rval);
 }
index 20d0c14aa70008f245fe5e9ca63003ec5bde5706..c5b93926f53a45ffd684593d8bac622972394c55 100644 (file)
@@ -63,6 +63,8 @@ static int
 sudo_collect(int timeout, int rendition, uchar_t *title, int nprompts,
     prompt_t *prompts)
 {
+    debug_decl(sudo_collect, SUDO_DEBUG_AUTH)
+
     switch (rendition) {
        case SIAFORM:
        case SIAONELINER:
@@ -81,16 +83,17 @@ sudo_collect(int timeout, int rendition, uchar_t *title, int nprompts,
            break;
     }
 
-    return sia_collect_trm(timeout, rendition, title, nprompts, prompts);
+    debug_return_int(sia_collect_trm(timeout, rendition, title, nprompts, prompts));
 }
 
 int
-sia_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
+sudo_sia_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
 {
     SIAENTITY *siah = NULL;
     int i;
     extern int NewArgc;
     extern char **NewArgv;
+    debug_decl(sudo_sia_setup, SUDO_DEBUG_AUTH)
 
     /* Rebuild argv for sia_ses_init() */
     sudo_argc = NewArgc + 1;
@@ -104,33 +107,35 @@ sia_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
 
        log_error(USE_ERRNO|NO_EXIT|NO_MAIL,
            _("unable to initialize SIA session"));
-       return AUTH_FATAL;
+       debug_return_int(AUTH_FATAL);
     }
 
     auth->data = (void *) siah;
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }
 
 int
-sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
+sudo_sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
 {
     SIAENTITY *siah = (SIAENTITY *) auth->data;
+    debug_decl(sudo_sia_verify, SUDO_DEBUG_AUTH)
 
     def_prompt = prompt;               /* for sudo_collect */
 
     /* XXX - need a way to detect user hitting return or EOF at prompt */
     if (sia_ses_reauthent(sudo_collect, siah) == SIASUCCESS)
-       return AUTH_SUCCESS;
+       debug_return_int(AUTH_SUCCESS);
     else
-       return AUTH_FAILURE;
+       debug_return_int(AUTH_FAILURE);
 }
 
 int
-sia_cleanup(struct passwd *pw, sudo_auth *auth)
+sudo_sia_cleanup(struct passwd *pw, sudo_auth *auth)
 {
     SIAENTITY *siah = (SIAENTITY *) auth->data;
+    debug_decl(sudo_sia_cleanup, SUDO_DEBUG_AUTH)
 
     (void) sia_ses_release(&siah);
     efree(sudo_argv);
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }
index cd0408394d005c0fe38617091dd0f5f6c24b4e6d..dded9cc531dc6b017c9d82e43f76cdc860cedee8 100644 (file)
 static sudo_auth auth_switch[] = {
 /* Standalone entries first */
 #ifdef HAVE_PAM
-    AUTH_ENTRY("pam", FLAG_STANDALONE, pam_init, NULL, pam_verify, pam_cleanup, pam_begin_session, pam_end_session)
+    AUTH_ENTRY("pam", FLAG_STANDALONE, sudo_pam_init, NULL, sudo_pam_verify, sudo_pam_cleanup, sudo_pam_begin_session, sudo_pam_end_session)
 #endif
 #ifdef HAVE_SECURID
-    AUTH_ENTRY("SecurId", FLAG_STANDALONE, securid_init, securid_setup, securid_verify, NULL, NULL, NULL)
+    AUTH_ENTRY("SecurId", FLAG_STANDALONE, sudo_securid_init, sudo_securid_setup, sudo_securid_verify, NULL, NULL, NULL)
 #endif
 #ifdef HAVE_SIA_SES_INIT
-    AUTH_ENTRY("sia", FLAG_STANDALONE, NULL, sia_setup, sia_verify, sia_cleanup, NULL, NULL)
+    AUTH_ENTRY("sia", FLAG_STANDALONE, NULL, sudo_sia_setup, sudo_sia_verify, sudo_sia_cleanup, NULL, NULL)
 #endif
 #ifdef HAVE_AIXAUTH
-    AUTH_ENTRY("aixauth", FLAG_STANDALONE, NULL, NULL, aixauth_verify, aixauth_cleanup, NULL, NULL)
+    AUTH_ENTRY("aixauth", FLAG_STANDALONE, NULL, NULL, sudo_aix_verify, sudo_aix_cleanup, NULL, NULL)
 #endif
 #ifdef HAVE_FWTK
-    AUTH_ENTRY("fwtk", FLAG_STANDALONE, fwtk_init, NULL, fwtk_verify, fwtk_cleanup, NULL, NULL)
+    AUTH_ENTRY("fwtk", FLAG_STANDALONE, sudo_fwtk_init, NULL, sudo_fwtk_verify, sudo_fwtk_cleanup, NULL, NULL)
 #endif
 #ifdef HAVE_BSD_AUTH_H
     AUTH_ENTRY("bsdauth", FLAG_STANDALONE, bsdauth_init, NULL, bsdauth_verify, bsdauth_cleanup, NULL, NULL)
@@ -71,28 +71,25 @@ static sudo_auth auth_switch[] = {
 
 /* Non-standalone entries */
 #ifndef WITHOUT_PASSWD
-    AUTH_ENTRY("passwd", 0, passwd_init, NULL, passwd_verify, passwd_cleanup, NULL, NULL)
+    AUTH_ENTRY("passwd", 0, sudo_passwd_init, NULL, sudo_passwd_verify, sudo_passwd_cleanup, NULL, NULL)
 #endif
 #if defined(HAVE_GETPRPWNAM) && !defined(WITHOUT_PASSWD)
-    AUTH_ENTRY("secureware", 0, secureware_init, NULL, secureware_verify, secureware_cleanup, NULL, NULL)
+    AUTH_ENTRY("secureware", 0, sudo_secureware_init, NULL, sudo_secureware_verify, sudo_secureware_cleanup, NULL, NULL)
 #endif
 #ifdef HAVE_AFS
-    AUTH_ENTRY("afs", 0, NULL, NULL, afs_verify, NULL, NULL, NULL)
+    AUTH_ENTRY("afs", 0, NULL, NULL, sudo_afs_verify, NULL, NULL, NULL)
 #endif
 #ifdef HAVE_DCE
-    AUTH_ENTRY("dce", 0, NULL, NULL, dce_verify, NULL, NULL, NULL)
-#endif
-#ifdef HAVE_KERB4
-    AUTH_ENTRY("kerb4", 0, kerb4_init, NULL, kerb4_verify, NULL, NULL, NULL)
+    AUTH_ENTRY("dce", 0, NULL, NULL, sudo_dce_verify, NULL, NULL, NULL)
 #endif
 #ifdef HAVE_KERB5
-    AUTH_ENTRY("kerb5", 0, kerb5_init, kerb5_setup, kerb5_verify, kerb5_cleanup, NULL, NULL)
+    AUTH_ENTRY("kerb5", 0, sudo_krb5_init, sudo_krb5_setup, sudo_krb5_verify, sudo_krb5_cleanup, NULL, NULL)
 #endif
 #ifdef HAVE_SKEY
-    AUTH_ENTRY("S/Key", 0, NULL, rfc1938_setup, rfc1938_verify, NULL, NULL, NULL)
+    AUTH_ENTRY("S/Key", 0, NULL, sudo_rfc1938_setup, sudo_rfc1938_verify, NULL, NULL, NULL)
 #endif
 #ifdef HAVE_OPIE
-    AUTH_ENTRY("OPIE", 0, NULL, rfc1938_setup, rfc1938_verify, NULL, NULL, NULL)
+    AUTH_ENTRY("OPIE", 0, NULL, sudo_rfc1938_setup, sudo_rfc1938_verify, NULL, NULL, NULL)
 #endif
     AUTH_ENTRY(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL)
 };
@@ -108,9 +105,10 @@ sudo_auth_init(struct passwd *pw)
 {
     sudo_auth *auth;
     int status = AUTH_SUCCESS;
+    debug_decl(sudo_auth_init, SUDO_DEBUG_AUTH)
 
     if (auth_switch[0].name == NULL)
-       return TRUE;
+       debug_return_int(true);
 
     /* Make sure we haven't mixed standalone and shared auth methods. */
     standalone = IS_STANDALONE(&auth_switch[0]);
@@ -118,7 +116,7 @@ sudo_auth_init(struct passwd *pw)
        audit_failure(NewArgv, "invalid authentication methods");
        log_error(0, _("Invalid authentication methods compiled into sudo!  "
            "You may mix standalone and non-standalone authentication."));
-       return -1;
+       debug_return_int(-1);
     }
 
     /* Set FLAG_ONEANDONLY if there is only one auth method. */
@@ -145,7 +143,7 @@ sudo_auth_init(struct passwd *pw)
            }
        }
     }
-    return status == AUTH_FATAL ? -1 : TRUE;
+    debug_return_int(status == AUTH_FATAL ? -1 : true);
 }
 
 int
@@ -153,6 +151,7 @@ sudo_auth_cleanup(struct passwd *pw)
 {
     sudo_auth *auth;
     int status = AUTH_SUCCESS;
+    debug_decl(sudo_auth_cleanup, SUDO_DEBUG_AUTH)
 
     /* Call cleanup routines. */
     for (auth = auth_switch; auth->name; auth++) {
@@ -172,7 +171,7 @@ sudo_auth_cleanup(struct passwd *pw)
            }
        }
     }
-    return status == AUTH_FATAL ? -1 : TRUE;
+    debug_return_int(status == AUTH_FATAL ? -1 : true);
 }
 
 int
@@ -184,6 +183,7 @@ verify_user(struct passwd *pw, char *prompt)
     char *p;
     sudo_auth *auth;
     sigaction_t sa, osa;
+    debug_decl(verify_user, SUDO_DEBUG_AUTH)
 
     /* Enable suspend during password entry. */
     sigemptyset(&sa.sa_mask);
@@ -199,7 +199,7 @@ verify_user(struct passwd *pw, char *prompt)
            _("There are no authentication methods compiled into sudo!  "
            "If you want to turn off authentication, use the "
            "--disable-authentication configure option."));
-       return -1;
+       debug_return_int(-1);
     }
 
     while (--counter) {
@@ -219,7 +219,7 @@ verify_user(struct passwd *pw, char *prompt)
                else if (status == AUTH_FATAL) {
                    /* XXX log */
                    audit_failure(NewArgv, "authentication failure");
-                   return -1;          /* assume error msg already printed */
+                   debug_return_int(-1);/* assume error msg already printed */
                }
            }
        }
@@ -259,7 +259,7 @@ done:
     switch (success) {
        case AUTH_SUCCESS:
            (void) sigaction(SIGTSTP, &osa, NULL);
-           rval = TRUE;
+           rval = true;
            break;
        case AUTH_INTR:
        case AUTH_FAILURE:
@@ -273,7 +273,7 @@ done:
                    def_passwd_tries - counter), def_passwd_tries - counter);
            }
            audit_failure(NewArgv, "authentication failure");
-           rval = FALSE;
+           rval = false;
            break;
        case AUTH_FATAL:
        default:
@@ -282,7 +282,7 @@ done:
            break;
     }
 
-    return rval;
+    debug_return_int(rval);
 }
 
 int
@@ -290,6 +290,7 @@ sudo_auth_begin_session(struct passwd *pw)
 {
     sudo_auth *auth;
     int status;
+    debug_decl(auth_begin_session, SUDO_DEBUG_AUTH)
 
     for (auth = auth_switch; auth->name; auth++) {
        if (auth->begin_session && !IS_DISABLED(auth)) {
@@ -297,11 +298,11 @@ sudo_auth_begin_session(struct passwd *pw)
            if (status == AUTH_FATAL) {
                /* XXX log */
                audit_failure(NewArgv, "authentication failure");
-               return -1;              /* assume error msg already printed */
+               debug_return_bool(-1);  /* assume error msg already printed */
            }
        }
     }
-    return TRUE;
+    debug_return_bool(true);
 }
 
 int
@@ -309,29 +310,33 @@ sudo_auth_end_session(struct passwd *pw)
 {
     sudo_auth *auth;
     int status;
+    debug_decl(auth_end_session, SUDO_DEBUG_AUTH)
 
     for (auth = auth_switch; auth->name; auth++) {
        if (auth->end_session && !IS_DISABLED(auth)) {
            status = (auth->end_session)(pw, auth);
            if (status == AUTH_FATAL) {
                /* XXX log */
-               return -1;              /* assume error msg already printed */
+               debug_return_bool(-1);  /* assume error msg already printed */
            }
        }
     }
-    return TRUE;
+    debug_return_bool(true);
 }
 
 static void
 pass_warn(void)
 {
     const char *warning = def_badpass_message;
+    debug_decl(pass_warn, SUDO_DEBUG_AUTH)
 
 #ifdef INSULT
     if (def_insults)
        warning = INSULT;
 #endif
     sudo_printf(SUDO_CONV_ERROR_MSG, "%s\n", warning);
+
+    debug_return;
 }
 
 char *
@@ -339,6 +344,7 @@ auth_getpass(const char *prompt, int timeout, int type)
 {
     struct sudo_conv_message msg;
     struct sudo_conv_reply repl;
+    debug_decl(auth_getpass, SUDO_DEBUG_AUTH)
 
     /* Mask user input if pwfeedback set and echo is off. */
     if (type == SUDO_CONV_PROMPT_ECHO_OFF && def_pwfeedback)
@@ -356,16 +362,19 @@ auth_getpass(const char *prompt, int timeout, int type)
     memset(&repl, 0, sizeof(repl));
     sudo_conv(1, &msg, &repl);
     /* XXX - check for ENOTTY? */
-    return repl.reply;
+    debug_return_str_masked(repl.reply);
 }
 
 void
 dump_auth_methods(void)
 {
     sudo_auth *auth;
+    debug_decl(dump_auth_methods, SUDO_DEBUG_AUTH)
 
     sudo_printf(SUDO_CONV_INFO_MSG, _("Authentication methods:"));
     for (auth = auth_switch; auth->name; auth++)
        sudo_printf(SUDO_CONV_INFO_MSG, " '%s'", auth->name);
     sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+
+    debug_return;
 }
index 995edb71a6a79fad42f053fbf27a7e3018cb5539..7259f22b5ddd5fe02309b8e3078fff601a036a24 100644 (file)
@@ -55,43 +55,41 @@ char *auth_getpass(const char *prompt, int timeout, int type);
 extern sudo_conv_t sudo_conv;
 
 /* Prototypes for standalone methods */
-int fwtk_init(struct passwd *pw, sudo_auth *auth);
-int fwtk_verify(struct passwd *pw, char *prompt, sudo_auth *auth);
-int fwtk_cleanup(struct passwd *pw, sudo_auth *auth);
-int pam_init(struct passwd *pw, sudo_auth *auth);
-int pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth);
-int pam_cleanup(struct passwd *pw, sudo_auth *auth);
-int pam_begin_session(struct passwd *pw, sudo_auth *auth);
-int pam_end_session(struct passwd *pw, sudo_auth *auth);
-int sia_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
-int sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth);
-int sia_cleanup(struct passwd *pw, sudo_auth *auth);
-int aixauth_verify(struct passwd *pw, char *pass, sudo_auth *auth);
-int aixauth_cleanup(struct passwd *pw, sudo_auth *auth);
 int bsdauth_init(struct passwd *pw, sudo_auth *auth);
 int bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth);
 int bsdauth_cleanup(struct passwd *pw, sudo_auth *auth);
+int sudo_aix_verify(struct passwd *pw, char *pass, sudo_auth *auth);
+int sudo_aix_cleanup(struct passwd *pw, sudo_auth *auth);
+int sudo_fwtk_init(struct passwd *pw, sudo_auth *auth);
+int sudo_fwtk_verify(struct passwd *pw, char *prompt, sudo_auth *auth);
+int sudo_fwtk_cleanup(struct passwd *pw, sudo_auth *auth);
+int sudo_pam_init(struct passwd *pw, sudo_auth *auth);
+int sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth);
+int sudo_pam_cleanup(struct passwd *pw, sudo_auth *auth);
+int sudo_pam_begin_session(struct passwd *pw, sudo_auth *auth);
+int sudo_pam_end_session(struct passwd *pw, sudo_auth *auth);
+int sudo_securid_init(struct passwd *pw, sudo_auth *auth);
+int sudo_securid_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
+int sudo_securid_verify(struct passwd *pw, char *pass, sudo_auth *auth);
+int sudo_sia_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
+int sudo_sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth);
+int sudo_sia_cleanup(struct passwd *pw, sudo_auth *auth);
 
 /* Prototypes for normal methods */
-int passwd_init(struct passwd *pw, sudo_auth *auth);
-int passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth);
-int passwd_cleanup(struct passwd *pw, sudo_auth *auth);
-int secureware_init(struct passwd *pw, sudo_auth *auth);
-int secureware_verify(struct passwd *pw, char *pass, sudo_auth *auth);
-int secureware_cleanup(struct passwd *pw, sudo_auth *auth);
-int rfc1938_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
-int rfc1938_verify(struct passwd *pw, char *pass, sudo_auth *auth);
-int afs_verify(struct passwd *pw, char *pass, sudo_auth *auth);
-int dce_verify(struct passwd *pw, char *pass, sudo_auth *auth);
-int kerb4_init(struct passwd *pw, sudo_auth *auth);
-int kerb4_verify(struct passwd *pw, char *pass, sudo_auth *auth);
-int kerb5_init(struct passwd *pw, sudo_auth *auth);
-int kerb5_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
-int kerb5_verify(struct passwd *pw, char *pass, sudo_auth *auth);
-int kerb5_cleanup(struct passwd *pw, sudo_auth *auth);
-int securid_init(struct passwd *pw, sudo_auth *auth);
-int securid_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
-int securid_verify(struct passwd *pw, char *pass, sudo_auth *auth);
+int sudo_afs_verify(struct passwd *pw, char *pass, sudo_auth *auth);
+int sudo_dce_verify(struct passwd *pw, char *pass, sudo_auth *auth);
+int sudo_krb5_init(struct passwd *pw, sudo_auth *auth);
+int sudo_krb5_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
+int sudo_krb5_verify(struct passwd *pw, char *pass, sudo_auth *auth);
+int sudo_krb5_cleanup(struct passwd *pw, sudo_auth *auth);
+int sudo_passwd_init(struct passwd *pw, sudo_auth *auth);
+int sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth);
+int sudo_passwd_cleanup(struct passwd *pw, sudo_auth *auth);
+int sudo_rfc1938_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
+int sudo_rfc1938_verify(struct passwd *pw, char *pass, sudo_auth *auth);
+int sudo_secureware_init(struct passwd *pw, sudo_auth *auth);
+int sudo_secureware_verify(struct passwd *pw, char *pass, sudo_auth *auth);
+int sudo_secureware_cleanup(struct passwd *pw, sudo_auth *auth);
 
 /* Fields: name, flags, init, setup, verify, cleanup, begin_sess, end_sess */
 #define AUTH_ENTRY(n, f, i, s, v, c, b, e) \
index 96576f84e6b139e751e760261db4c8d0836f4af6..2c9c07467a65961b756cdc61931c5ca0f327dcae 100644 (file)
@@ -53,6 +53,7 @@
 #endif /* !__linux__ */
 
 #include "missing.h"
+#include "sudo_debug.h"
 
 /*
  * Fill in a struct timeval with the time the system booted.
@@ -67,6 +68,7 @@ get_boottime(struct timeval *tv)
     size_t linesize = 0;
     ssize_t len;
     FILE * fp;
+    debug_decl(get_boottime, SUDO_DEBUG_UTIL)
 
     /* read btime from /proc/stat */
     fp = fopen("/proc/stat", "r");
@@ -75,14 +77,14 @@ get_boottime(struct timeval *tv)
            if (strncmp(line, "btime ", 6) == 0) {
                tv->tv_sec = atoi(line + 6);
                tv->tv_usec = 0;
-               return 1;
+               debug_return_bool(1);
            }
        }
        fclose(fp);
        free(line);
     }
 
-    return 0;
+    debug_return_bool(0);
 }
 
 #elif defined(HAVE_SYSCTL) && defined(KERN_BOOTTIME)
@@ -92,14 +94,15 @@ get_boottime(struct timeval *tv)
 {
     size_t size;
     int mib[2];
+    debug_decl(get_boottime, SUDO_DEBUG_UTIL)
 
     mib[0] = CTL_KERN;
     mib[1] = KERN_BOOTTIME;
     size = sizeof(*tv);
     if (sysctl(mib, 2, tv, &size, NULL, 0) != -1)
-       return 1;
+       debug_return_bool(1);
 
-    return 0;
+    debug_return_bool(0);
 }
 
 #elif defined(HAVE_GETUTXID)
@@ -108,6 +111,7 @@ int
 get_boottime(struct timeval *tv)
 {
     struct utmpx *ut, key;
+    debug_decl(get_boottime, SUDO_DEBUG_UTIL)
 
     memset(&key, 0, sizeof(key));
     key.ut_type = BOOT_TIME;
@@ -117,7 +121,7 @@ get_boottime(struct timeval *tv)
        tv->tv_usec = ut->ut_tv.tv_usec;
     }
     endutxent();
-    return ut != NULL;
+    debug_return_bool(ut != NULL);
 }
 
 #elif defined(HAVE_GETUTID)
@@ -126,6 +130,7 @@ int
 get_boottime(struct timeval *tv)
 {
     struct utmp *ut, key;
+    debug_decl(get_boottime, SUDO_DEBUG_UTIL)
 
     memset(&key, 0, sizeof(key));
     key.ut_type = BOOT_TIME;
@@ -135,7 +140,7 @@ get_boottime(struct timeval *tv)
        tv->tv_usec = 0;
     }
     endutent();
-    return ut != NULL;
+    debug_return_bool(ut != NULL);
 }
 
 #else
@@ -143,6 +148,7 @@ get_boottime(struct timeval *tv)
 int
 get_boottime(struct timeval *tv)
 {
-    return 0;
+    debug_decl(get_boottime, SUDO_DEBUG_UTIL)
+    debug_return_bool(0);
 }
 #endif
index df53ea0c791844862e46fb3fbfa2ad6b85a87004..0ce6caf710b9bffb10a3ca6d936cd79a7d188fac 100644 (file)
@@ -30,6 +30,8 @@
 #include <errno.h>
 #include <unistd.h>
 
+#include "gettext.h"
+#include "sudo_debug.h"
 #include "bsm_audit.h"
 
 /*
@@ -51,6 +53,7 @@ audit_sudo_selected(int sf)
        struct au_mask *mask;
        auditinfo_t ainfo;
        int rc, sorf;
+       debug_decl(audit_sudo_selected, SUDO_DEBUG_AUDIT)
 
        if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) < 0) {
                if (errno == ENOSYS) {
@@ -63,7 +66,7 @@ audit_sudo_selected(int sf)
                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;
+        debug_return_int(rc);
 }
 
 void
@@ -76,6 +79,7 @@ bsm_audit_success(char **exec_args)
        long au_cond;
        int aufd;
        pid_t pid;
+       debug_decl(bsm_audit_success, SUDO_DEBUG_AUDIT)
 
        pid = getpid();
        /*
@@ -87,13 +91,13 @@ bsm_audit_success(char **exec_args)
                log_error(0, _("Could not determine audit condition"));
        }
        if (au_cond == AUC_NOAUDIT)
-               return;
+               debug_return;
        /*
         * Check to see if the preselection masks are interested in seeing
         * this event.
         */
        if (!audit_sudo_selected(0))
-               return;
+               debug_return;
        if (getauid(&auid) < 0)
                log_error(0, _("getauid failed"));
        if ((aufd = au_open()) == -1)
@@ -124,6 +128,7 @@ bsm_audit_success(char **exec_args)
        au_write(aufd, tok);
        if (au_close(aufd, 1, AUE_sudo) == -1)
                log_error(0, _("unable to commit audit record"));
+       debug_return;
 }
 
 void
@@ -137,6 +142,7 @@ bsm_audit_failure(char **exec_args, char const *const fmt, va_list ap)
        au_id_t auid;
        pid_t pid;
        int aufd;
+       debug_decl(bsm_audit_success, SUDO_DEBUG_AUDIT)
 
        pid = getpid();
        /*
@@ -144,13 +150,13 @@ bsm_audit_failure(char **exec_args, char const *const fmt, va_list ap)
         */
        if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
                if (errno == AUDIT_NOT_CONFIGURED)
-                       return;
+                       debug_return;
                log_error(0, _("Could not determine audit condition"));
        }
        if (au_cond == AUC_NOAUDIT)
-               return;
+               debug_return;
        if (!audit_sudo_selected(1))
-               return;
+               debug_return;
        if (getauid(&auid) < 0)
                log_error(0, _("getauid: failed"));
        if ((aufd = au_open()) == -1)
@@ -183,4 +189,5 @@ bsm_audit_failure(char **exec_args, char const *const fmt, va_list ap)
        au_write(aufd, tok);
        if (au_close(aufd, 1, AUE_sudo) == -1)
                log_error(0, _("unable to commit audit record"));
+       debug_return;
 }
index 20cba077c64d4269eb0739797375d234390aea13..2850fe83a197987de17ab3ddab7c1103376ccd96 100644 (file)
@@ -89,11 +89,11 @@ static int   timestamp_status(char *, char *, char *, int);
 static char *expand_prompt(char *, char *, char *);
 static void  lecture(int);
 static void  update_timestamp(char *, char *);
-static int   tty_is_devpts(const char *);
+static bool  tty_is_devpts(const char *);
 static struct passwd *get_authpw(void);
 
 /*
- * Returns TRUE if the user successfully authenticates, else FALSE.
+ * Returns true if the user successfully authenticates, else false.
  */
 int
 check_user(int validated, int mode)
@@ -103,8 +103,9 @@ check_user(int validated, int mode)
     char *timestampfile = NULL;
     char *prompt;
     struct stat sb;
-    int status, rval = TRUE;
-    int need_pass = def_authenticate;
+    int status, rval = true;
+    bool need_pass = def_authenticate;
+    debug_decl(check_user, SUDO_DEBUG_AUTH)
 
     /*
      * Init authentication system regardless of whether we need a password.
@@ -128,7 +129,7 @@ check_user(int validated, int mode)
            if (user_uid == 0 || (user_uid == runas_pw->pw_uid &&
                (!runas_gr || user_in_group(sudo_user.pw, runas_gr->gr_name)))
                || user_is_exempt())
-               need_pass = FALSE;
+               need_pass = false;
        }
     }
     if (!need_pass)
@@ -169,7 +170,7 @@ check_user(int validated, int mode)
        rval = verify_user(auth_pw, prompt);
     }
     /* Only update timestamp if user was validated. */
-    if (rval == TRUE && ISSET(validated, VALIDATE_OK) &&
+    if (rval == true && ISSET(validated, VALIDATE_OK) &&
        !ISSET(mode, MODE_IGNORE_TICKET) && status != TS_ERROR)
        update_timestamp(timestampdir, timestampfile);
     efree(timestampdir);
@@ -179,7 +180,7 @@ done:
     sudo_auth_cleanup(auth_pw);
     pw_delref(auth_pw);
 
-    return rval;
+    debug_return_bool(rval);
 }
 
 #define DEFAULT_LECTURE "\n" \
@@ -200,17 +201,18 @@ lecture(int status)
     ssize_t nread;
     struct sudo_conv_message msg;
     struct sudo_conv_reply repl;
+    debug_decl(lecture, SUDO_DEBUG_AUTH)
 
     if (def_lecture == never ||
        (def_lecture == once && status != TS_MISSING && status != TS_ERROR))
-       return;
+       debug_return;
 
     memset(&msg, 0, sizeof(msg));
     memset(&repl, 0, sizeof(repl));
 
     if (def_lecture_file && (fp = fopen(def_lecture_file, "r")) != NULL) {
        while ((nread = fread(buf, sizeof(char), sizeof(buf) - 1, fp)) != 0) {
-           buf[sizeof(buf) - 1] = '\0';
+           buf[nread] = '\0';
            msg.msg_type = SUDO_CONV_ERROR_MSG;
            msg.msg = buf;
            sudo_conv(1, &msg, &repl);
@@ -221,6 +223,7 @@ lecture(int status)
        msg.msg = _(DEFAULT_LECTURE);
        sudo_conv(1, &msg, &repl);
     }
+    debug_return;
 }
 
 /*
@@ -229,9 +232,11 @@ lecture(int status)
 static void
 update_timestamp(char *timestampdir, char *timestampfile)
 {
+    debug_decl(update_timestamp, SUDO_DEBUG_AUTH)
+
     /* If using tty timestamps but we have no tty there is nothing to do. */
     if (def_tty_tickets && !user_ttypath)
-       return;
+       debug_return;
 
     if (timestamp_uid != 0)
        set_perms(PERM_TIMESTAMP);
@@ -260,6 +265,7 @@ update_timestamp(char *timestampdir, char *timestampfile)
     }
     if (timestamp_uid != 0)
        restore_perms();
+    debug_return;
 }
 
 /*
@@ -272,6 +278,7 @@ expand_prompt(char *old_prompt, char *user, char *host)
     size_t len, n;
     int subst;
     char *p, *np, *new_prompt, *endp;
+    debug_decl(expand_prompt, SUDO_DEBUG_AUTH)
 
     /* How much space do we need to malloc for the prompt? */
     subst = 0;
@@ -382,7 +389,7 @@ expand_prompt(char *old_prompt, char *user, char *host)
     } else
        new_prompt = old_prompt;
 
-    return new_prompt;
+    debug_return_str(new_prompt);
 
 oflow:
     /* We pre-allocate enough space, so this should never happen. */
@@ -392,12 +399,15 @@ oflow:
 /*
  * Checks if the user is exempt from supplying a password.
  */
-int
+bool
 user_is_exempt(void)
 {
-    if (!def_exempt_group)
-       return FALSE;
-    return user_in_group(sudo_user.pw, def_exempt_group);
+    bool rval = false;
+    debug_decl(user_is_exempt, SUDO_DEBUG_AUTH)
+
+    if (def_exempt_group)
+       rval = user_in_group(sudo_user.pw, def_exempt_group);
+    debug_return_bool(rval);
 }
 
 /*
@@ -408,6 +418,7 @@ build_timestamp(char **timestampdir, char **timestampfile)
 {
     char *dirparent;
     int len;
+    debug_decl(build_timestamp, SUDO_DEBUG_AUTH)
 
     dirparent = def_timestampdir;
     len = easprintf(timestampdir, "%s/%s", dirparent, user_name);
@@ -440,10 +451,10 @@ build_timestamp(char **timestampdir, char **timestampfile)
     } else
        *timestampfile = NULL;
 
-    return len;
+    debug_return_int(len);
 bad:
     log_error(0, _("timestamp path too long: %s"), *timestampfile);
-    return -1;
+    debug_return_int(-1);
 }
 
 /*
@@ -457,6 +468,7 @@ timestamp_status(char *timestampdir, char *timestampfile, char *user, int flags)
     time_t now;
     char *dirparent = def_timestampdir;
     int status = TS_ERROR;             /* assume the worst */
+    debug_decl(timestamp_status, SUDO_DEBUG_AUTH)
 
     if (timestamp_uid != 0)
        set_perms(PERM_TIMESTAMP);
@@ -641,21 +653,22 @@ timestamp_status(char *timestampdir, char *timestampfile, char *user, int flags)
 done:
     if (timestamp_uid != 0)
        restore_perms();
-    return status;
+    debug_return_int(status);
 }
 
 /*
  * Remove the timestamp ticket file/dir.
  */
 void
-remove_timestamp(int remove)
+remove_timestamp(bool remove)
 {
     struct timeval tv;
     char *timestampdir, *timestampfile, *path;
     int status;
+    debug_decl(remove_timestamp, SUDO_DEBUG_AUTH)
 
     if (build_timestamp(&timestampdir, &timestampfile) == -1)
-       return;
+       debug_return;
 
     status = timestamp_status(timestampdir, timestampfile, user_name,
        TS_REMOVE);
@@ -670,7 +683,7 @@ remove_timestamp(int remove)
                log_error(NO_EXIT,
                    _("unable to remove %s (%s), will reset to the epoch"),
                    path, strerror(errno));
-               remove = FALSE;
+               remove = false;
            }
        }
        if (!remove) {
@@ -679,25 +692,27 @@ remove_timestamp(int remove)
                error(1, _("unable to reset %s to the epoch"), path);
        }
     }
-
     efree(timestampdir);
     efree(timestampfile);
+
+    debug_return;
 }
 
 /*
- * Returns TRUE if tty lives on a devpts or /devices filesystem, else FALSE.
+ * Returns true if tty lives on a devpts or /devices filesystem, else false.
  * Unlike most filesystems, the ctime of devpts nodes is not updated when
  * the device node is written to, only when the inode's status changes,
  * typically via the chmod, chown, link, rename, or utimes system calls.
  * Since the ctime is "stable" in this case, we can stash it the tty ticket
  * file and use it to determine whether the tty ticket file is stale.
  */
-static int
+static bool
 tty_is_devpts(const char *tty)
 {
-    int retval = FALSE;
+    bool retval = false;
 #ifdef __linux__
     struct statfs sfs;
+    debug_decl(tty_is_devpts, SUDO_DEBUG_PTY)
 
 #ifndef DEVPTS_SUPER_MAGIC
 # define DEVPTS_SUPER_MAGIC 0x1cd1
@@ -705,17 +720,20 @@ tty_is_devpts(const char *tty)
 
     if (statfs(tty, &sfs) == 0) {
        if (sfs.f_type == DEVPTS_SUPER_MAGIC)
-           retval = TRUE;
+           retval = true;
     }
 #elif defined(__sun) && defined(__SVR4)
     struct statvfs sfs;
+    debug_decl(tty_is_devpts, SUDO_DEBUG_PTY)
 
     if (statvfs(tty, &sfs) == 0) {
        if (strcmp(sfs.f_fstr, "devices") == 0)
-           retval = TRUE;
+           retval = true;
     }
+#else
+    debug_decl(tty_is_devpts, SUDO_DEBUG_PTY)
 #endif /* __linux__ */
-    return retval;
+    debug_return_bool(retval);
 }
 
 /*
@@ -727,6 +745,7 @@ static struct passwd *
 get_authpw(void)
 {
     struct passwd *pw;
+    debug_decl(get_authpw, SUDO_DEBUG_AUTH)
 
     if (def_rootpw) {
        if ((pw = sudo_getpwuid(ROOT_UID)) == NULL)
@@ -745,5 +764,5 @@ get_authpw(void)
        pw = sudo_user.pw;
     }
 
-    return pw;
+    debug_return_ptr(pw);
 }
index 200d76a654cce7064d4c4b928eadd395548f6b88..3119df8e5e5cf7661427b4394ef2519b1a090b5f 100644 (file)
@@ -240,11 +240,7 @@ struct sudo_defs_types sudo_defs_table[] = {
        def_data_verifypw,
     }, {
        "noexec", T_FLAG,
-       N_("Preload the dummy exec functions contained in 'noexec_file'"),
-       NULL,
-    }, {
-       "noexec_file", T_STR|T_PATH,
-       N_("File containing dummy exec functions: %s"),
+       N_("Preload the dummy exec functions contained in the sudo_noexec library"),
        NULL,
     }, {
        "ignore_local_sudoers", T_FLAG,
@@ -296,7 +292,7 @@ struct sudo_defs_types sudo_defs_table[] = {
        NULL,
     }, {
        "visiblepw", T_FLAG,
-       N_("Allow sudo to prompt for a password even if it would be visisble"),
+       N_("Allow sudo to prompt for a password even if it would be visible"),
        NULL,
     }, {
        "pwfeedback", T_FLAG,
@@ -328,15 +324,15 @@ struct sudo_defs_types sudo_defs_table[] = {
        NULL,
     }, {
        "group_plugin", T_STR,
-       N_("Plugin for non-Unix group support"),
+       N_("Plugin for non-Unix group support: %s"),
        NULL,
     }, {
        "iolog_dir", T_STR|T_PATH,
-       N_("Directory in which to store input/output logs"),
+       N_("Directory in which to store input/output logs: %s"),
        NULL,
     }, {
        "iolog_file", T_STR,
-       N_("File in which to store the input/output log"),
+       N_("File in which to store the input/output log: %s"),
        NULL,
     }, {
        "set_utmp", T_FLAG,
index f41f7cdd538e6b7d9aa81cd05ce435ce4cf79479..43c2b96a656b5cbfc5e6acc0dcbb23e41ea78d03 100644 (file)
 #define I_VERIFYPW              53
 #define def_noexec              (sudo_defs_table[54].sd_un.flag)
 #define I_NOEXEC                54
-#define def_noexec_file         (sudo_defs_table[55].sd_un.str)
-#define I_NOEXEC_FILE           55
-#define def_ignore_local_sudoers (sudo_defs_table[56].sd_un.flag)
-#define I_IGNORE_LOCAL_SUDOERS  56
-#define def_closefrom           (sudo_defs_table[57].sd_un.ival)
-#define I_CLOSEFROM             57
-#define def_closefrom_override  (sudo_defs_table[58].sd_un.flag)
-#define I_CLOSEFROM_OVERRIDE    58
-#define def_setenv              (sudo_defs_table[59].sd_un.flag)
-#define I_SETENV                59
-#define def_env_reset           (sudo_defs_table[60].sd_un.flag)
-#define I_ENV_RESET             60
-#define def_env_check           (sudo_defs_table[61].sd_un.list)
-#define I_ENV_CHECK             61
-#define def_env_delete          (sudo_defs_table[62].sd_un.list)
-#define I_ENV_DELETE            62
-#define def_env_keep            (sudo_defs_table[63].sd_un.list)
-#define I_ENV_KEEP              63
-#define def_role                (sudo_defs_table[64].sd_un.str)
-#define I_ROLE                  64
-#define def_type                (sudo_defs_table[65].sd_un.str)
-#define I_TYPE                  65
-#define def_env_file            (sudo_defs_table[66].sd_un.str)
-#define I_ENV_FILE              66
-#define def_sudoers_locale      (sudo_defs_table[67].sd_un.str)
-#define I_SUDOERS_LOCALE        67
-#define def_visiblepw           (sudo_defs_table[68].sd_un.flag)
-#define I_VISIBLEPW             68
-#define def_pwfeedback          (sudo_defs_table[69].sd_un.flag)
-#define I_PWFEEDBACK            69
-#define def_fast_glob           (sudo_defs_table[70].sd_un.flag)
-#define I_FAST_GLOB             70
-#define def_umask_override      (sudo_defs_table[71].sd_un.flag)
-#define I_UMASK_OVERRIDE        71
-#define def_log_input           (sudo_defs_table[72].sd_un.flag)
-#define I_LOG_INPUT             72
-#define def_log_output          (sudo_defs_table[73].sd_un.flag)
-#define I_LOG_OUTPUT            73
-#define def_compress_io         (sudo_defs_table[74].sd_un.flag)
-#define I_COMPRESS_IO           74
-#define def_use_pty             (sudo_defs_table[75].sd_un.flag)
-#define I_USE_PTY               75
-#define def_group_plugin        (sudo_defs_table[76].sd_un.str)
-#define I_GROUP_PLUGIN          76
-#define def_iolog_dir           (sudo_defs_table[77].sd_un.str)
-#define I_IOLOG_DIR             77
-#define def_iolog_file          (sudo_defs_table[78].sd_un.str)
-#define I_IOLOG_FILE            78
-#define def_set_utmp            (sudo_defs_table[79].sd_un.flag)
-#define I_SET_UTMP              79
-#define def_utmp_runas          (sudo_defs_table[80].sd_un.flag)
-#define I_UTMP_RUNAS            80
+#define def_ignore_local_sudoers (sudo_defs_table[55].sd_un.flag)
+#define I_IGNORE_LOCAL_SUDOERS  55
+#define def_closefrom           (sudo_defs_table[56].sd_un.ival)
+#define I_CLOSEFROM             56
+#define def_closefrom_override  (sudo_defs_table[57].sd_un.flag)
+#define I_CLOSEFROM_OVERRIDE    57
+#define def_setenv              (sudo_defs_table[58].sd_un.flag)
+#define I_SETENV                58
+#define def_env_reset           (sudo_defs_table[59].sd_un.flag)
+#define I_ENV_RESET             59
+#define def_env_check           (sudo_defs_table[60].sd_un.list)
+#define I_ENV_CHECK             60
+#define def_env_delete          (sudo_defs_table[61].sd_un.list)
+#define I_ENV_DELETE            61
+#define def_env_keep            (sudo_defs_table[62].sd_un.list)
+#define I_ENV_KEEP              62
+#define def_role                (sudo_defs_table[63].sd_un.str)
+#define I_ROLE                  63
+#define def_type                (sudo_defs_table[64].sd_un.str)
+#define I_TYPE                  64
+#define def_env_file            (sudo_defs_table[65].sd_un.str)
+#define I_ENV_FILE              65
+#define def_sudoers_locale      (sudo_defs_table[66].sd_un.str)
+#define I_SUDOERS_LOCALE        66
+#define def_visiblepw           (sudo_defs_table[67].sd_un.flag)
+#define I_VISIBLEPW             67
+#define def_pwfeedback          (sudo_defs_table[68].sd_un.flag)
+#define I_PWFEEDBACK            68
+#define def_fast_glob           (sudo_defs_table[69].sd_un.flag)
+#define I_FAST_GLOB             69
+#define def_umask_override      (sudo_defs_table[70].sd_un.flag)
+#define I_UMASK_OVERRIDE        70
+#define def_log_input           (sudo_defs_table[71].sd_un.flag)
+#define I_LOG_INPUT             71
+#define def_log_output          (sudo_defs_table[72].sd_un.flag)
+#define I_LOG_OUTPUT            72
+#define def_compress_io         (sudo_defs_table[73].sd_un.flag)
+#define I_COMPRESS_IO           73
+#define def_use_pty             (sudo_defs_table[74].sd_un.flag)
+#define I_USE_PTY               74
+#define def_group_plugin        (sudo_defs_table[75].sd_un.str)
+#define I_GROUP_PLUGIN          75
+#define def_iolog_dir           (sudo_defs_table[76].sd_un.str)
+#define I_IOLOG_DIR             76
+#define def_iolog_file          (sudo_defs_table[77].sd_un.str)
+#define I_IOLOG_FILE            77
+#define def_set_utmp            (sudo_defs_table[78].sd_un.flag)
+#define I_SET_UTMP              78
+#define def_utmp_runas          (sudo_defs_table[79].sd_un.flag)
+#define I_UTMP_RUNAS            79
 
 enum def_tuple {
        never,
index 340a5e489a7218ce64a7cba74544f351cb40d18a..7b9d4e4b9d576a98b1b5b7cf573e2c28431a7f5d 100644 (file)
@@ -177,10 +177,7 @@ verifypw
        never all any always
 noexec
        T_FLAG
-       "Preload the dummy exec functions contained in 'noexec_file'"
-noexec_file
-       T_STR|T_PATH
-       "File containing dummy exec functions: %s"
+       "Preload the dummy exec functions contained in the sudo_noexec library"
 ignore_local_sudoers
        T_FLAG
        "If LDAP directory is up, do we ignore local sudoers file"
@@ -219,7 +216,7 @@ sudoers_locale
        "Locale to use while parsing sudoers: %s"
 visiblepw
        T_FLAG
-       "Allow sudo to prompt for a password even if it would be visisble"
+       "Allow sudo to prompt for a password even if it would be visible"
 pwfeedback
        T_FLAG
        "Provide visual feedback at the password prompt when there is user input"
@@ -243,13 +240,13 @@ use_pty
        "Always run commands in a pseudo-tty"
 group_plugin
        T_STR
-       "Plugin for non-Unix group support"
+       "Plugin for non-Unix group support: %s"
 iolog_dir
        T_STR|T_PATH
-       "Directory in which to store input/output logs"
+       "Directory in which to store input/output logs: %s"
 iolog_file
        T_STR
-       "File in which to store the input/output log"
+       "File in which to store the input/output log: %s"
 set_utmp
        T_FLAG
        "Add an entry to the utmp/utmpx file when allocating a pty"
index dd404f5bf70da00ce559466d42a329ba7d890cf9..5046ec2e70ebfefebdf826af4813b0ec8ff69498 100644 (file)
@@ -91,15 +91,15 @@ static struct strmap priorities[] = {
 /*
  * Local prototypes.
  */
-static int store_int(char *, struct sudo_defs_types *, int);
-static int store_list(char *, struct sudo_defs_types *, int);
-static int store_mode(char *, struct sudo_defs_types *, int);
-static int store_str(char *, struct sudo_defs_types *, int);
-static int store_syslogfac(char *, struct sudo_defs_types *, int);
-static int store_syslogpri(char *, struct sudo_defs_types *, int);
-static int store_tuple(char *, struct sudo_defs_types *, int);
-static int store_uint(char *, struct sudo_defs_types *, int);
-static int store_float(char *, struct sudo_defs_types *, int);
+static bool store_int(char *, struct sudo_defs_types *, int);
+static bool store_list(char *, struct sudo_defs_types *, int);
+static bool store_mode(char *, struct sudo_defs_types *, int);
+static bool store_str(char *, struct sudo_defs_types *, int);
+static bool store_syslogfac(char *, struct sudo_defs_types *, int);
+static bool store_syslogpri(char *, struct sudo_defs_types *, int);
+static bool store_tuple(char *, struct sudo_defs_types *, int);
+static bool store_uint(char *, struct sudo_defs_types *, int);
+static bool store_float(char *, struct sudo_defs_types *, int);
 static void list_op(char *, size_t, struct sudo_defs_types *, enum list_ops);
 static const char *logfac2str(int);
 static const char *logpri2str(int);
@@ -119,6 +119,7 @@ dump_defaults(void)
     struct list_member *item;
     struct def_values *def;
     char *desc;
+    debug_decl(dump_defaults, SUDO_DEBUG_DEFAULTS)
 
     for (cur = sudo_defs_table; cur->name; cur++) {
        if (cur->desc) {
@@ -182,6 +183,7 @@ dump_defaults(void)
            }
        }
     }
+    debug_return;
 }
 
 /*
@@ -191,11 +193,12 @@ dump_defaults(void)
  * Eg. you may want to turn off logging to a file for some hosts.
  * This is only meaningful for variables that are *optional*.
  */
-int
+bool
 set_default(char *var, char *val, int op)
 {
     struct sudo_defs_types *cur;
     int num;
+    debug_decl(set_default, SUDO_DEBUG_DEFAULTS)
 
     for (cur = sudo_defs_table, num = 0; cur->name; cur++, num++) {
        if (strcmp(var, cur->name) == 0)
@@ -203,7 +206,7 @@ set_default(char *var, char *val, int op)
     }
     if (!cur->name) {
        warningx(_("unknown defaults entry `%s'"), var);
-       return FALSE;
+       debug_return_bool(false);
     }
 
     switch (cur->type & T_MASK) {
@@ -214,7 +217,7 @@ set_default(char *var, char *val, int op)
                        val, var);
                else
                    warningx(_("no value specified for `%s'"), var);
-               return FALSE;
+               debug_return_bool(false);
            }
            break;
        case T_LOGPRI:
@@ -224,111 +227,111 @@ set_default(char *var, char *val, int op)
                        val, var);
                else
                    warningx(_("no value specified for `%s'"), var);
-               return FALSE;
+               debug_return_bool(false);
            }
            break;
        case T_STR:
            if (!val) {
                /* Check for bogus boolean usage or lack of a value. */
-               if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
+               if (!ISSET(cur->type, T_BOOL) || op != false) {
                    warningx(_("no value specified for `%s'"), var);
-                   return FALSE;
+                   debug_return_bool(false);
                }
            }
            if (ISSET(cur->type, T_PATH) && val && *val != '/') {
                warningx(_("values for `%s' must start with a '/'"), var);
-               return FALSE;
+               debug_return_bool(false);
            }
            if (!store_str(val, cur, op)) {
                warningx(_("value `%s' is invalid for option `%s'"), val, var);
-               return FALSE;
+               debug_return_bool(false);
            }
            break;
        case T_INT:
            if (!val) {
                /* Check for bogus boolean usage or lack of a value. */
-               if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
+               if (!ISSET(cur->type, T_BOOL) || op != false) {
                    warningx(_("no value specified for `%s'"), var);
-                   return FALSE;
+                   debug_return_bool(false);
                }
            }
            if (!store_int(val, cur, op)) {
                warningx(_("value `%s' is invalid for option `%s'"), val, var);
-               return FALSE;
+               debug_return_bool(false);
            }
            break;
        case T_UINT:
            if (!val) {
                /* Check for bogus boolean usage or lack of a value. */
-               if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
+               if (!ISSET(cur->type, T_BOOL) || op != false) {
                    warningx(_("no value specified for `%s'"), var);
-                   return FALSE;
+                   debug_return_bool(false);
                }
            }
            if (!store_uint(val, cur, op)) {
                warningx(_("value `%s' is invalid for option `%s'"), val, var);
-               return FALSE;
+               debug_return_bool(false);
            }
            break;
        case T_FLOAT:
            if (!val) {
                /* Check for bogus boolean usage or lack of a value. */
-               if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
+               if (!ISSET(cur->type, T_BOOL) || op != false) {
                    warningx(_("no value specified for `%s'"), var);
-                   return FALSE;
+                   debug_return_bool(false);
                }
            }
            if (!store_float(val, cur, op)) {
                warningx(_("value `%s' is invalid for option `%s'"), val, var);
-               return FALSE;
+               debug_return_bool(false);
            }
            break;
        case T_MODE:
            if (!val) {
                /* Check for bogus boolean usage or lack of a value. */
-               if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
+               if (!ISSET(cur->type, T_BOOL) || op != false) {
                    warningx(_("no value specified for `%s'"), var);
-                   return FALSE;
+                   debug_return_bool(false);
                }
            }
            if (!store_mode(val, cur, op)) {
                warningx(_("value `%s' is invalid for option `%s'"), val, var);
-               return FALSE;
+               debug_return_bool(false);
            }
            break;
        case T_FLAG:
            if (val) {
                warningx(_("option `%s' does not take a value"), var);
-               return FALSE;
+               debug_return_bool(false);
            }
            cur->sd_un.flag = op;
            break;
        case T_LIST:
            if (!val) {
                /* Check for bogus boolean usage or lack of a value. */
-               if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
+               if (!ISSET(cur->type, T_BOOL) || op != false) {
                    warningx(_("no value specified for `%s'"), var);
-                   return FALSE;
+                   debug_return_bool(false);
                }
            }
            if (!store_list(val, cur, op)) {
                warningx(_("value `%s' is invalid for option `%s'"), val, var);
-               return FALSE;
+               debug_return_bool(false);
            }
            break;
        case T_TUPLE:
            if (!val && !ISSET(cur->type, T_BOOL)) {
                warningx(_("no value specified for `%s'"), var);
-               return FALSE;
+               debug_return_bool(false);
            }
            if (!store_tuple(val, cur, op)) {
                warningx(_("value `%s' is invalid for option `%s'"), val, var);
-               return FALSE;
+               debug_return_bool(false);
            }
            break;
     }
 
-    return TRUE;
+    debug_return_bool(true);
 }
 
 /*
@@ -340,6 +343,7 @@ init_defaults(void)
 {
     static int firsttime = 1;
     struct sudo_defs_types *def;
+    debug_decl(init_defaults, SUDO_DEBUG_DEFAULTS)
 
     /* Clear any old settings. */
     if (!firsttime) {
@@ -359,78 +363,78 @@ init_defaults(void)
 
     /* First initialize the flags. */
 #ifdef LONG_OTP_PROMPT
-    def_long_otp_prompt = TRUE;
+    def_long_otp_prompt = true;
 #endif
 #ifdef IGNORE_DOT_PATH
-    def_ignore_dot = TRUE;
+    def_ignore_dot = true;
 #endif
 #ifdef ALWAYS_SEND_MAIL
-    def_mail_always = TRUE;
+    def_mail_always = true;
 #endif
 #ifdef SEND_MAIL_WHEN_NO_USER
-    def_mail_no_user = TRUE;
+    def_mail_no_user = true;
 #endif
 #ifdef SEND_MAIL_WHEN_NO_HOST
-    def_mail_no_host = TRUE;
+    def_mail_no_host = true;
 #endif
 #ifdef SEND_MAIL_WHEN_NOT_OK
-    def_mail_no_perms = TRUE;
+    def_mail_no_perms = true;
 #endif
 #ifndef NO_TTY_TICKETS
-    def_tty_tickets = TRUE;
+    def_tty_tickets = true;
 #endif
 #ifndef NO_LECTURE
     def_lecture = once;
 #endif
 #ifndef NO_AUTHENTICATION
-    def_authenticate = TRUE;
+    def_authenticate = true;
 #endif
 #ifndef NO_ROOT_SUDO
-    def_root_sudo = TRUE;
+    def_root_sudo = true;
 #endif
 #ifdef HOST_IN_LOG
-    def_log_host = TRUE;
+    def_log_host = true;
 #endif
 #ifdef SHELL_IF_NO_ARGS
-    def_shell_noargs = TRUE;
+    def_shell_noargs = true;
 #endif
 #ifdef SHELL_SETS_HOME
-    def_set_home = TRUE;
+    def_set_home = true;
 #endif
 #ifndef DONT_LEAK_PATH_INFO
-    def_path_info = TRUE;
+    def_path_info = true;
 #endif
 #ifdef FQDN
-    def_fqdn = TRUE;
+    def_fqdn = true;
 #endif
 #ifdef USE_INSULTS
-    def_insults = TRUE;
+    def_insults = true;
 #endif
 #ifdef ENV_EDITOR
-    def_env_editor = TRUE;
+    def_env_editor = true;
 #endif
 #ifdef UMASK_OVERRIDE
-    def_umask_override = TRUE;
+    def_umask_override = true;
 #endif
     def_iolog_file = estrdup("%{seq}");
     def_iolog_dir = estrdup(_PATH_SUDO_IO_LOGDIR);
     def_sudoers_locale = estrdup("C");
     def_env_reset = ENV_RESET;
-    def_set_logname = TRUE;
+    def_set_logname = true;
     def_closefrom = STDERR_FILENO + 1;
 
     /* Syslog options need special care since they both strings and ints */
 #if (LOGGING & SLOG_SYSLOG)
-    (void) store_syslogfac(LOGFAC, &sudo_defs_table[I_SYSLOG], TRUE);
+    (void) store_syslogfac(LOGFAC, &sudo_defs_table[I_SYSLOG], true);
     (void) store_syslogpri(PRI_SUCCESS, &sudo_defs_table[I_SYSLOG_GOODPRI],
-       TRUE);
+       true);
     (void) store_syslogpri(PRI_FAILURE, &sudo_defs_table[I_SYSLOG_BADPRI],
-       TRUE);
+       true);
 #endif
 
     /* Password flags also have a string and integer component. */
-    (void) store_tuple("any", &sudo_defs_table[I_LISTPW], TRUE);
-    (void) store_tuple("all", &sudo_defs_table[I_VERIFYPW], TRUE);
+    (void) store_tuple("any", &sudo_defs_table[I_LISTPW], true);
+    (void) store_tuple("all", &sudo_defs_table[I_VERIFYPW], true);
 
     /* Then initialize the int-like things. */
 #ifdef SUDO_UMASK
@@ -443,7 +447,7 @@ init_defaults(void)
     def_passwd_timeout = PASSWORD_TIMEOUT;
     def_passwd_tries = TRIES_FOR_PASSWORD;
 #ifdef HAVE_ZLIB_H
-    def_compress_io = TRUE;
+    def_compress_io = true;
 #endif
 
     /* Now do the strings */
@@ -467,12 +471,14 @@ init_defaults(void)
     def_secure_path = estrdup(SECURE_PATH);
 #endif
     def_editor = estrdup(EDITOR);
-    def_set_utmp = TRUE;
+    def_set_utmp = true;
 
     /* Finally do the lists (currently just environment tables). */
     init_envtables();
 
     firsttime = 0;
+
+    debug_return;
 }
 
 /*
@@ -483,108 +489,113 @@ int
 update_defaults(int what)
 {
     struct defaults *def;
-    int rc = TRUE;
+    bool rc = true;
+    debug_decl(update_defaults, SUDO_DEBUG_DEFAULTS)
 
     tq_foreach_fwd(&defaults, def) {
        switch (def->type) {
            case DEFAULTS:
                if (ISSET(what, SETDEF_GENERIC) &&
                    !set_default(def->var, def->val, def->op))
-                   rc = FALSE;
+                   rc = false;
                break;
            case DEFAULTS_USER:
                if (ISSET(what, SETDEF_USER) &&
                    userlist_matches(sudo_user.pw, &def->binding) == ALLOW &&
                    !set_default(def->var, def->val, def->op))
-                   rc = FALSE;
+                   rc = false;
                break;
            case DEFAULTS_RUNAS:
                if (ISSET(what, SETDEF_RUNAS) &&
                    runaslist_matches(&def->binding, NULL) == ALLOW &&
                    !set_default(def->var, def->val, def->op))
-                   rc = FALSE;
+                   rc = false;
                break;
            case DEFAULTS_HOST:
                if (ISSET(what, SETDEF_HOST) &&
                    hostlist_matches(&def->binding) == ALLOW &&
                    !set_default(def->var, def->val, def->op))
-                   rc = FALSE;
+                   rc = false;
                break;
            case DEFAULTS_CMND:
                if (ISSET(what, SETDEF_CMND) &&
                    cmndlist_matches(&def->binding) == ALLOW &&
                    !set_default(def->var, def->val, def->op))
-                   rc = FALSE;
+                   rc = false;
                break;
        }
     }
-    return rc;
+    debug_return_bool(rc);
 }
 
-static int
+static bool
 store_int(char *val, struct sudo_defs_types *def, int op)
 {
     char *endp;
     long l;
+    debug_decl(store_int, SUDO_DEBUG_DEFAULTS)
 
-    if (op == FALSE) {
+    if (op == false) {
        def->sd_un.ival = 0;
     } else {
        l = strtol(val, &endp, 10);
        if (*endp != '\0')
-           return FALSE;
+           debug_return_bool(false);
        /* XXX - should check against INT_MAX */
        def->sd_un.ival = (int)l;
     }
     if (def->callback)
-       return def->callback(val);
-    return TRUE;
+       debug_return_bool(def->callback(val));
+    debug_return_bool(true);
 }
 
-static int
+static bool
 store_uint(char *val, struct sudo_defs_types *def, int op)
 {
     char *endp;
     long l;
+    debug_decl(store_uint, SUDO_DEBUG_DEFAULTS)
 
-    if (op == FALSE) {
+    if (op == false) {
        def->sd_un.ival = 0;
     } else {
        l = strtol(val, &endp, 10);
        if (*endp != '\0' || l < 0)
-           return FALSE;
+           debug_return_bool(false);
        /* XXX - should check against INT_MAX */
        def->sd_un.ival = (unsigned int)l;
     }
     if (def->callback)
-       return def->callback(val);
-    return TRUE;
+       debug_return_bool(def->callback(val));
+    debug_return_bool(true);
 }
 
-static int
+static bool
 store_float(char *val, struct sudo_defs_types *def, int op)
 {
     char *endp;
     double d;
+    debug_decl(store_float, SUDO_DEBUG_DEFAULTS)
 
-    if (op == FALSE) {
+    if (op == false) {
        def->sd_un.fval = 0.0;
     } else {
        d = strtod(val, &endp);
        if (*endp != '\0')
-           return FALSE;
+           debug_return_bool(false);
        /* XXX - should check against HUGE_VAL */
        def->sd_un.fval = d;
     }
     if (def->callback)
-       return def->callback(val);
-    return TRUE;
+       debug_return_bool(def->callback(val));
+    debug_return_bool(true);
 }
 
-static int
+static bool
 store_tuple(char *val, struct sudo_defs_types *def, int op)
 {
     struct def_values *v;
+    debug_decl(store_tuple, SUDO_DEBUG_DEFAULTS)
 
     /*
      * Since enums are really just ints we store the value as an ival.
@@ -594,7 +605,7 @@ store_tuple(char *val, struct sudo_defs_types *def, int op)
      * be the equivalent to a boolean "false".
      */
     if (!val) {
-       def->sd_un.ival = (op == FALSE) ? 0 : 1;
+       def->sd_un.ival = (op == false) ? 0 : 1;
     } else {
        for (v = def->values; v->sval != NULL; v++) {
            if (strcmp(v->sval, val) == 0) {
@@ -603,38 +614,40 @@ store_tuple(char *val, struct sudo_defs_types *def, int op)
            }
        }
        if (v->sval == NULL)
-           return FALSE;
+           debug_return_bool(false);
     }
     if (def->callback)
-       return def->callback(val);
-    return TRUE;
+       debug_return_bool(def->callback(val));
+    debug_return_bool(true);
 }
 
-static int
+static bool
 store_str(char *val, struct sudo_defs_types *def, int op)
 {
+    debug_decl(store_str, SUDO_DEBUG_DEFAULTS)
 
     efree(def->sd_un.str);
-    if (op == FALSE)
+    if (op == false)
        def->sd_un.str = NULL;
     else
        def->sd_un.str = estrdup(val);
     if (def->callback)
-       return def->callback(val);
-    return TRUE;
+       debug_return_bool(def->callback(val));
+    debug_return_bool(true);
 }
 
-static int
+static bool
 store_list(char *str, struct sudo_defs_types *def, int op)
 {
     char *start, *end;
+    debug_decl(store_list, SUDO_DEBUG_DEFAULTS)
 
     /* Remove all old members. */
-    if (op == FALSE || op == TRUE)
+    if (op == false || op == true)
        list_op(NULL, 0, def, freeall);
 
     /* Split str into multiple space-separated words and act on each one. */
-    if (op != FALSE) {
+    if (op != false) {
        end = str;
        do {
            /* Remove leading blanks, if nothing but blanks we are done. */
@@ -649,31 +662,32 @@ store_list(char *str, struct sudo_defs_types *def, int op)
            list_op(start, end - start, def, op == '-' ? delete : add);
        } while (*end++ != '\0');
     }
-    return TRUE;
+    debug_return_bool(true);
 }
 
-static int
+static bool
 store_syslogfac(char *val, struct sudo_defs_types *def, int op)
 {
     struct strmap *fac;
+    debug_decl(store_syslogfac, SUDO_DEBUG_DEFAULTS)
 
-    if (op == FALSE) {
-       def->sd_un.ival = FALSE;
-       return TRUE;
+    if (op == false) {
+       def->sd_un.ival = false;
+       debug_return_bool(true);
     }
 #ifdef LOG_NFACILITIES
     if (!val)
-       return FALSE;
+       debug_return_bool(false);
     for (fac = facilities; fac->name && strcmp(val, fac->name); fac++)
        ;
     if (fac->name == NULL)
-       return FALSE;                           /* not found */
+       debug_return_bool(false);               /* not found */
 
     def->sd_un.ival = fac->num;
 #else
     def->sd_un.ival = -1;
 #endif /* LOG_NFACILITIES */
-    return TRUE;
+    debug_return_bool(true);
 }
 
 static const char *
@@ -681,65 +695,70 @@ logfac2str(int n)
 {
 #ifdef LOG_NFACILITIES
     struct strmap *fac;
+    debug_decl(logfac2str, SUDO_DEBUG_DEFAULTS)
 
     for (fac = facilities; fac->name && fac->num != n; fac++)
        ;
-    return fac->name;
+    debug_return_str(fac->name);
 #else
     return "default";
 #endif /* LOG_NFACILITIES */
 }
 
-static int
+static bool
 store_syslogpri(char *val, struct sudo_defs_types *def, int op)
 {
     struct strmap *pri;
+    debug_decl(store_syslogpri, SUDO_DEBUG_DEFAULTS)
 
-    if (op == FALSE || !val)
-       return FALSE;
+    if (op == false || !val)
+       debug_return_bool(false);
 
     for (pri = priorities; pri->name && strcmp(val, pri->name); pri++)
        ;
     if (pri->name == NULL)
-       return FALSE;                           /* not found */
+       debug_return_bool(false);       /* not found */
 
     def->sd_un.ival = pri->num;
-    return TRUE;
+    debug_return_bool(true);
 }
 
 static const char *
 logpri2str(int n)
 {
     struct strmap *pri;
+    debug_decl(logpri2str, SUDO_DEBUG_DEFAULTS)
 
     for (pri = priorities; pri->name && pri->num != n; pri++)
        ;
-    return pri->name;
+    debug_return_str(pri->name);
 }
 
-static int
+static bool
 store_mode(char *val, struct sudo_defs_types *def, int op)
 {
     char *endp;
     long l;
+    debug_decl(store_mode, SUDO_DEBUG_DEFAULTS)
 
-    if (op == FALSE) {
+    if (op == false) {
        def->sd_un.mode = (mode_t)0777;
     } else {
        l = strtol(val, &endp, 8);
        if (*endp != '\0' || l < 0 || l > 0777)
-           return FALSE;
+           debug_return_bool(false);
        def->sd_un.mode = (mode_t)l;
     }
     if (def->callback)
-       return def->callback(val);
-    return TRUE;
+       debug_return_bool(def->callback(val));
+    debug_return_bool(true);
 }
 
 static void
 list_op(char *val, size_t len, struct sudo_defs_types *def, enum list_ops op)
 {
     struct list_member *cur, *prev, *tmp;
+    debug_decl(list_op, SUDO_DEBUG_DEFAULTS)
 
     if (op == freeall) {
        for (cur = def->sd_un.list; cur; ) {
@@ -749,14 +768,14 @@ list_op(char *val, size_t len, struct sudo_defs_types *def, enum list_ops op)
            efree(tmp);
        }
        def->sd_un.list = NULL;
-       return;
+       debug_return;
     }
 
     for (cur = def->sd_un.list, prev = NULL; cur; prev = cur, cur = cur->next) {
        if ((strncmp(cur->value, val, len) == 0 && cur->value[len] == '\0')) {
 
            if (op == add)
-               return;                 /* already exists */
+               debug_return;           /* already exists */
 
            /* Delete node */
            if (prev != NULL)
@@ -778,4 +797,5 @@ list_op(char *val, size_t len, struct sudo_defs_types *def, enum list_ops op)
        cur->next = def->sd_un.list;
        def->sd_un.list = cur;
     }
+    debug_return;
 }
index 05e2b6f499e999a122be7545196356a466409da3..d6231c75156578b6a58995902a04c8724982c875 100644 (file)
@@ -107,7 +107,7 @@ struct sudo_defs_types {
  */
 void dump_default(void);
 void init_defaults(void);
-int  set_default(char *, char *, int);
+bool set_default(char *, char *, int);
 int  update_defaults(int);
 
 extern struct sudo_defs_types sudo_defs_table[];
index d7c15829044847a5f60a32efd0c597970ed06d83..15997fa1c2ab54e0161efb5c82aa7e3dccca73ef 100644 (file)
@@ -131,11 +131,6 @@ static const char *initial_badenv_table[] = {
 #ifdef __APPLE__
     "DYLD_*",
 #endif
-#ifdef HAVE_KERB4
-    "KRB_CONF*",
-    "KRBCONFDIR",
-    "KRBTKFILE",
-#endif /* HAVE_KERB4 */
 #ifdef HAVE_KERB5
     "KRB5_CONFIG*",
     "KRB5_KTNAME",
@@ -216,6 +211,7 @@ env_init(char * const envp[])
 {
     char * const *ep;
     size_t len;
+    debug_decl(env_init, SUDO_DEBUG_ENV)
 
     for (ep = envp; *ep != NULL; ep++)
        continue;
@@ -229,6 +225,8 @@ env_init(char * const envp[])
 #endif
     memcpy(env.envp, envp, len * sizeof(char *));
     env.envp[len] = '\0';
+
+    debug_return;
 }
 
 char **
@@ -247,6 +245,7 @@ sudo_setenv(const char *var, const char *val, int dupcheck)
 {
     char *estring;
     size_t esize;
+    debug_decl(sudo_setenv, SUDO_DEBUG_ENV)
 
     esize = strlen(var) + 1 + strlen(val) + 1;
     estring = emalloc(esize);
@@ -258,7 +257,9 @@ sudo_setenv(const char *var, const char *val, int dupcheck)
 
        errorx(1, _("internal error, sudo_setenv() overflow"));
     }
-    sudo_putenv(estring, dupcheck, TRUE);
+    sudo_putenv(estring, dupcheck, true);
+
+    debug_return;
 }
 
 /*
@@ -272,7 +273,8 @@ sudo_putenv(char *str, int dupcheck, int overwrite)
 {
     char **ep;
     size_t len;
-    int found = FALSE;
+    bool found = false;
+    debug_decl(sudo_putenv, SUDO_DEBUG_ENV)
 
     /* Make sure there is room for the new entry plus a NULL. */
     if (env.env_len + 2 > env.env_size) {
@@ -295,7 +297,7 @@ sudo_putenv(char *str, int dupcheck, int overwrite)
            if (strncmp(str, *ep, len) == 0) {
                if (overwrite)
                    *ep = str;
-               found = TRUE;
+               found = true;
            }
        }
        /* Prune out duplicate variables. */
@@ -319,18 +321,21 @@ sudo_putenv(char *str, int dupcheck, int overwrite)
        *ep++ = str;
        *ep = NULL;
     }
+    debug_return;
 }
 
 /*
  * Check the env_delete blacklist.
- * Returns TRUE if the variable was found, else false.
+ * Returns true if the variable was found, else false.
  */
-static int
+static bool
 matches_env_delete(const char *var)
 {
     struct list_member *cur;
     size_t len;
-    int iswild, match = FALSE;
+    bool iswild;
+    bool match = false;
+    debug_decl(matches_env_delete, SUDO_DEBUG_ENV)
 
     /* Skip anything listed in env_delete. */
     for (cur = def_env_delete; cur; cur = cur->next) {
@@ -338,21 +343,21 @@ matches_env_delete(const char *var)
        /* Deal with '*' wildcard */
        if (cur->value[len - 1] == '*') {
            len--;
-           iswild = TRUE;
+           iswild = true;
        } else
-           iswild = FALSE;
+           iswild = false;
        if (strncmp(cur->value, var, len) == 0 &&
            (iswild || var[len] == '=')) {
-           match = TRUE;
+           match = true;
            break;
        }
     }
-    return match;
+    debug_return_bool(match);
 }
 
 /*
  * Apply the env_check list.
- * Returns TRUE if the variable is allowed, FALSE if denied
+ * Returns true if the variable is allowed, false if denied
  * or -1 if no match.
  */
 static int
@@ -360,51 +365,53 @@ matches_env_check(const char *var)
 {
     struct list_member *cur;
     size_t len;
-    int iswild, keepit = -1;
+    bool iswild;
+    int keepit = -1;
+    debug_decl(matches_env_check, SUDO_DEBUG_ENV)
 
     for (cur = def_env_check; cur; cur = cur->next) {
        len = strlen(cur->value);
        /* Deal with '*' wildcard */
        if (cur->value[len - 1] == '*') {
            len--;
-           iswild = TRUE;
+           iswild = true;
        } else
-           iswild = FALSE;
+           iswild = false;
        if (strncmp(cur->value, var, len) == 0 &&
            (iswild || var[len] == '=')) {
            keepit = !strpbrk(var, "/%");
            break;
        }
     }
-    return keepit;
+    debug_return_bool(keepit);
 }
 
 /*
  * Check the env_keep list.
- * Returns TRUE if the variable is allowed else FALSE.
+ * Returns true if the variable is allowed else false.
  */
-static int
+static bool
 matches_env_keep(const char *var)
 {
     struct list_member *cur;
     size_t len;
-    int iswild, keepit = FALSE;
+    bool iswild, keepit = false;
 
     /* Preserve SHELL variable for "sudo -s". */
     if (ISSET(sudo_mode, MODE_SHELL) && strncmp(var, "SHELL=", 6) == 0)
-       return TRUE;
+       return true;
 
     for (cur = def_env_keep; cur; cur = cur->next) {
        len = strlen(cur->value);
        /* Deal with '*' wildcard */
        if (cur->value[len - 1] == '*') {
            len--;
-           iswild = TRUE;
+           iswild = true;
        } else
-           iswild = FALSE;
+           iswild = false;
        if (strncmp(cur->value, var, len) == 0 &&
            (iswild || var[len] == '=')) {
-           keepit = TRUE;
+           keepit = true;
            break;
        }
     }
@@ -422,7 +429,7 @@ rebuild_env(void)
     char **old_envp, **ep, *cp, *ps1;
     char idbuf[MAX_UID_T_LEN];
     unsigned int didvar;
-    int reset_home = FALSE;
+    bool reset_home = false;
 
     /*
      * Either clean out the environment or reset to a safe default.
@@ -442,7 +449,7 @@ rebuild_env(void)
        if (def_always_set_home ||
            ISSET(sudo_mode, MODE_RESET_HOME | MODE_LOGIN_SHELL) || 
            (ISSET(sudo_mode, MODE_SHELL) && def_set_home))
-           reset_home = TRUE;
+           reset_home = true;
     }
 
     if (def_env_reset || ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
@@ -503,7 +510,7 @@ rebuild_env(void)
                            SET(didvar, DID_USERNAME);
                        break;
                }
-               sudo_putenv(*ep, FALSE, FALSE);
+               sudo_putenv(*ep, false, false);
            }
        }
        didvar |= didvar << 8;          /* convert DID_* to KEPT_* */
@@ -522,18 +529,18 @@ rebuild_env(void)
                ISSET(didvar, DID_USERNAME));
        } else {
            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);
        }
 
        /* If we didn't keep HOME, reset it based on target user. */
        if (!ISSET(didvar, KEPT_HOME))
-           reset_home = TRUE;
+           reset_home = true;
 
        /*
         * Set MAIL to target user in -i mode or if MAIL is not preserved
@@ -545,7 +552,7 @@ rebuild_env(void)
                easprintf(&cp, "MAIL=%s%s", _PATH_MAILDIR, runas_pw->pw_name);
            else
                easprintf(&cp, "MAIL=%s/%s", _PATH_MAILDIR, runas_pw->pw_name);
-           sudo_putenv(cp, ISSET(didvar, DID_MAIL), TRUE);
+           sudo_putenv(cp, ISSET(didvar, DID_MAIL), true);
        }
     } else {
        /*
@@ -553,7 +560,7 @@ rebuild_env(void)
         * env_check.
         */
        for (ep = old_envp; *ep; ep++) {
-           int okvar;
+           bool okvar;
 
            /* Skip variables with values beginning with () (bash functions) */
            if ((cp = strchr(*ep, '=')) != NULL) {
@@ -565,9 +572,9 @@ rebuild_env(void)
             * First check variables against the blacklist in env_delete.
             * If no match there check for '%' and '/' characters.
             */
-           okvar = matches_env_delete(*ep) != TRUE;
+           okvar = matches_env_delete(*ep) != true;
            if (okvar)
-               okvar = matches_env_check(*ep) != FALSE;
+               okvar = matches_env_check(*ep) != false;
 
            if (okvar) {
                if (strncmp(*ep, "SUDO_PS1=", 9) == 0)
@@ -576,13 +583,13 @@ rebuild_env(void)
                    SET(didvar, DID_PATH);
                else if (strncmp(*ep, "TERM=", 5) == 0)
                    SET(didvar, DID_TERM);
-               sudo_putenv(*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);
     }
 
@@ -594,42 +601,42 @@ rebuild_env(void)
      */
     if (def_set_logname && !ISSET(sudo_mode, MODE_LOGIN_SHELL|MODE_EDIT)) {
        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 to target user if not preserving user's value. */
     if (reset_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))
-       sudo_putenv("TERM=unknown", FALSE, FALSE);
+       sudo_putenv("TERM=unknown", false, false);
     if (!ISSET(didvar, DID_PATH))
-       sudo_setenv("PATH", _PATH_STDPATH, FALSE);
+       sudo_setenv("PATH", _PATH_STDPATH, false);
 
     /* Set PS1 if SUDO_PS1 is set. */
     if (ps1 != NULL)
-       sudo_putenv(ps1, TRUE, TRUE);
+       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), "%u", (unsigned int) user_uid);
-    sudo_setenv("SUDO_UID", idbuf, TRUE);
+    sudo_setenv("SUDO_UID", idbuf, true);
     snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int) user_gid);
-    sudo_setenv("SUDO_GID", idbuf, TRUE);
+    sudo_setenv("SUDO_GID", idbuf, true);
 
     /* Free old environment. */
     efree(old_envp);
@@ -645,7 +652,7 @@ insert_env_vars(char * const envp[])
 
     /* Add user-specified environment variables. */
     for (ep = envp; *ep != NULL; ep++)
-       sudo_putenv(*ep, TRUE, TRUE);
+       sudo_putenv(*ep, true, true);
 }
 
 /*
@@ -668,17 +675,17 @@ validate_env_vars(char * const env_vars[])
     for (ep = env_vars; *ep != NULL; ep++) {
        if (def_secure_path && !user_is_exempt() &&
            strncmp(*ep, "PATH=", 5) == 0) {
-           okvar = FALSE;
+           okvar = false;
        } else if (def_env_reset) {
            okvar = matches_env_check(*ep);
            if (okvar == -1)
                okvar = matches_env_keep(*ep);
        } else {
-           okvar = matches_env_delete(*ep) == FALSE;
-           if (okvar == FALSE)
-               okvar = matches_env_check(*ep) != FALSE;
+           okvar = matches_env_delete(*ep) == false;
+           if (okvar == false)
+               okvar = matches_env_check(*ep) != false;
        }
-       if (okvar == FALSE) {
+       if (okvar == false) {
            /* Not allowed, add to error string, allocating as needed. */
            if ((eq = strchr(*ep, '=')) != NULL)
                *eq = '\0';
@@ -758,7 +765,7 @@ read_env_file(const char *path, int overwrite)
        memcpy(cp, var, var_len + 1); /* includes '=' */
        memcpy(cp + var_len + 1, val, val_len + 1); /* includes NUL */
 
-       sudo_putenv(cp, TRUE, overwrite);
+       sudo_putenv(cp, true, overwrite);
     }
     fclose(fp);
 }
index 4064248e3d181e06ae927e2c1b731e3737e49828..208b88e40e090bb31731307c33ca2a3acaca90b6 100644 (file)
@@ -60,9 +60,10 @@ find_path(char *infile, char **outfile, struct stat *sbp, char *path,
     static char command[PATH_MAX]; /* qualified filename */
     char *n;                   /* for traversing path */
     char *origpath;            /* so we can free path later */
-    char *result = NULL;       /* result of path/file lookup */
-    int checkdot = 0;          /* check current dir? */
+    bool found = false;                /* did we find the command? */
+    bool checkdot = false;     /* check current dir? */
     int len;                   /* length parameter */
+    debug_decl(find_path, SUDO_DEBUG_UTIL)
 
     if (strlen(infile) >= PATH_MAX)
        errorx(1, _("%s: %s"), infile, strerror(ENAMETOOLONG));
@@ -75,13 +76,13 @@ find_path(char *infile, char **outfile, struct stat *sbp, char *path,
        strlcpy(command, infile, sizeof(command));      /* paranoia */
        if (sudo_goodpath(command, sbp)) {
            *outfile = command;
-           return FOUND;
+           debug_return_int(FOUND);
        } else
-           return NOT_FOUND;
+           debug_return_int(NOT_FOUND);
     }
 
     if (path == NULL)
-       return NOT_FOUND;
+       debug_return_int(NOT_FOUND);
     path = estrdup(path);
     origpath = path;
 
@@ -105,7 +106,7 @@ find_path(char *infile, char **outfile, struct stat *sbp, char *path,
        len = snprintf(command, sizeof(command), "%s/%s", path, infile);
        if (len <= 0 || len >= sizeof(command))
            errorx(1, _("%s: %s"), infile, strerror(ENAMETOOLONG));
-       if ((result = sudo_goodpath(command, sbp)))
+       if ((found = sudo_goodpath(command, sbp)))
            break;
 
        path = n + 1;
@@ -116,18 +117,18 @@ find_path(char *infile, char **outfile, struct stat *sbp, char *path,
     /*
      * Check current dir if dot was in the PATH
      */
-    if (!result && checkdot) {
+    if (!found && checkdot) {
        len = snprintf(command, sizeof(command), "./%s", infile);
        if (len <= 0 || len >= sizeof(command))
            errorx(1, _("%s: %s"), infile, strerror(ENAMETOOLONG));
-       result = sudo_goodpath(command, sbp);
-       if (result && ignore_dot)
-           return NOT_FOUND_DOT;
+       found = sudo_goodpath(command, sbp);
+       if (found && ignore_dot)
+           debug_return_int(NOT_FOUND_DOT);
     }
 
-    if (result) {
-       *outfile = result;
-       return FOUND;
+    if (found) {
+       *outfile = command;
+       debug_return_int(FOUND);
     } else
-       return NOT_FOUND;
+       debug_return_int(NOT_FOUND);
 }
index f12d3940ee8e958f1ec9ae2911ed398441e5ce8e..f8e8fc6dc4b1e0a752128ba8a7ecca6332f1d104 100644 (file)
@@ -122,7 +122,7 @@ typedef union {
     enum _MERIDIAN     Meridian;
 } YYSTYPE;
 #endif /* YYSTYPE_DEFINED */
-#line 125 "y.tab.c"
+#line 125 "getdate.c"
 #define tAGO 257
 #define tDAY 258
 #define tDAYZONE 259
@@ -1028,7 +1028,7 @@ main(ac, av)
     /* NOTREACHED */
 }
 #endif /* defined(TEST) */
-#line 979 "y.tab.c"
+#line 979 "getdate.c"
 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
 #if defined(__cplusplus) || defined(__STDC__)
 static int yygrowstack(void)
@@ -1523,7 +1523,7 @@ case 41:
            yyval.Meridian = yyvsp[0].Meridian;
        }
 break;
-#line 1474 "y.tab.c"
+#line 1474 "getdate.c"
     }
     yyssp -= yym;
     yystate = *yyssp;
index 01f488525178c9aae2d5f1b4c4602cc7e0270ce7..e98db83582b98e71262a7020aab35c15d0f1a622 100644 (file)
@@ -82,6 +82,7 @@ char *
 sudo_getepw(const struct passwd *pw)
 {
     char *epw = NULL;
+    debug_decl(sudo_getepw, SUDO_DEBUG_AUTH)
 
     /* If there is a function to check for shadow enabled, use it... */
 #ifdef HAVE_ISCOMSEC
@@ -142,12 +143,14 @@ sudo_getepw(const struct passwd *pw)
 done:
 #endif
     /* If no shadow password, fall back on regular password. */
-    return estrdup(epw ? epw : pw->pw_passwd);
+    debug_return_str(estrdup(epw ? epw : pw->pw_passwd));
 }
 
 void
 sudo_setspent(void)
 {
+    debug_decl(sudo_setspent, SUDO_DEBUG_AUTH)
+
 #ifdef HAVE_GETPRPWNAM
     setprpwent();
 #endif
@@ -163,11 +166,14 @@ sudo_setspent(void)
 #ifdef HAVE_GETAUTHUID
     setauthent();
 #endif
+    debug_return;
 }
 
 void
 sudo_endspent(void)
 {
+    debug_decl(sudo_endspent, SUDO_DEBUG_AUTH)
+
 #ifdef HAVE_GETPRPWNAM
     endprpwent();
 #endif
@@ -183,4 +189,5 @@ sudo_endspent(void)
 #ifdef HAVE_GETAUTHUID
     endauthent();
 #endif
+    debug_return;
 }
index 8d02028197a6c0790528e7d0dc760a48ef0b424e..2a8446b1cd0eaf93acf44774dcfaa570a3672077 100644 (file)
 /*
  * Verify that path is a normal file and executable by root.
  */
-char *
+bool
 sudo_goodpath(const char *path, struct stat *sbp)
 {
     struct stat sb;
-
-    /* Check for brain damage */
-    if (path == NULL || path[0] == '\0')
-       return NULL;
-
-    if (stat(path, &sb))
-       return NULL;
-
-    /* Make sure path describes an executable regular file. */
-    if (!S_ISREG(sb.st_mode) || !(sb.st_mode & 0000111)) {
-       errno = EACCES;
-       return NULL;
+    bool rval = false;
+    debug_decl(sudo_goodpath, SUDO_DEBUG_UTIL)
+
+    if (path != NULL && stat(path, &sb) == 0) {
+       /* Make sure path describes an executable regular file. */
+       if (S_ISREG(sb.st_mode) && ISSET(sb.st_mode, 0111))
+           rval = true;
+       else
+           errno = EACCES;
+       if (sbp)
+           (void) memcpy(sbp, &sb, sizeof(struct stat));
     }
 
-    if (sbp != NULL)
-       (void) memcpy(sbp, &sb, sizeof(struct stat));
-    return (char *)path;
+    debug_return_bool(rval);
 }
index 8c0a73d62676d3fd115a5f25856125e997179155..e8fe89761b38f2df2b7442f1f6604b48257f98a0 100644 (file)
@@ -64,6 +64,7 @@
 #include "sudoers.h" /* XXX */
 #include "parse.h"
 #include "toke.h"
+#include "gram.h"
 
 /*
  * We must define SIZE_MAX for yacc's skeleton.c.
  * Globals
  */
 extern int sudolineno;
+extern int last_token;
 extern char *sudoers;
-static int verbose = FALSE;
-int parse_error = FALSE;
-int pedantic = FALSE;
+static bool verbose = false;
+bool parse_error = false;
 int errorlineno = -1;
 char *errorfile = NULL;
 
@@ -104,20 +105,26 @@ static struct member *new_member(char *, int);
 void
 yyerror(const char *s)
 {
+    debug_decl(yyerror, SUDO_DEBUG_PARSER)
+
+    /* If we last saw a newline the error is on the preceding line. */
+    if (last_token == COMMENT)
+       sudolineno--;
+
     /* Save the line the first error occurred on. */
     if (errorlineno == -1) {
-       errorlineno = sudolineno ? sudolineno - 1 : 0;
+       errorlineno = sudolineno;
        errorfile = estrdup(sudoers);
     }
     if (trace_print != NULL) {
        LEXTRACE("<*> ");
     } else if (verbose && s != NULL) {
-       warningx(_(">>> %s: %s near line %d <<<"), sudoers, s,
-           sudolineno ? sudolineno - 1 : 0);
+       warningx(_(">>> %s: %s near line %d <<<"), sudoers, s, sudolineno);
     }
-    parse_error = TRUE;
+    parse_error = true;
+    debug_return;
 }
-#line 110 "gram.y"
+#line 117 "gram.y"
 #ifndef YYSTYPE_DEFINED
 #define YYSTYPE_DEFINED
 typedef union {
@@ -133,7 +140,7 @@ typedef union {
     int tok;
 } YYSTYPE;
 #endif /* YYSTYPE_DEFINED */
-#line 136 "y.tab.c"
+#line 143 "gram.c"
 #define COMMAND 257
 #define ALIAS 258
 #define DEFVAR 259
@@ -631,11 +638,12 @@ short *yyss;
 short *yysslim;
 YYSTYPE *yyvs;
 int yystacksize;
-#line 604 "gram.y"
+#line 611 "gram.y"
 static struct defaults *
 new_default(char *var, char *val, int op)
 {
     struct defaults *d;
+    debug_decl(new_default, SUDO_DEBUG_PARSER)
 
     d = emalloc(sizeof(struct defaults));
     d->var = var;
@@ -646,13 +654,14 @@ new_default(char *var, char *val, int op)
     d->prev = d;
     d->next = NULL;
 
-    return d;
+    debug_return_ptr(d);
 }
 
 static struct member *
 new_member(char *name, int type)
 {
     struct member *m;
+    debug_decl(new_member, SUDO_DEBUG_PARSER)
 
     m = emalloc(sizeof(struct member));
     m->name = name;
@@ -660,7 +669,7 @@ new_member(char *name, int type)
     m->prev = m;
     m->next = NULL;
 
-    return m;
+    debug_return_ptr(m);
 }
 
 /*
@@ -673,6 +682,7 @@ add_defaults(int type, struct member *bmem, struct defaults *defs)
 {
     struct defaults *d;
     struct member_list binding;
+    debug_decl(add_defaults, SUDO_DEBUG_PARSER)
 
     /*
      * We can only call list2tq once on bmem as it will zero
@@ -688,6 +698,8 @@ add_defaults(int type, struct member *bmem, struct defaults *defs)
        d->binding = binding;
     }
     tq_append(&defaults, defs);
+
+    debug_return;
 }
 
 /*
@@ -698,6 +710,7 @@ static void
 add_userspec(struct member *members, struct privilege *privs)
 {
     struct userspec *u;
+    debug_decl(add_userspec, SUDO_DEBUG_PARSER)
 
     u = emalloc(sizeof(*u));
     list2tq(&u->users, members);
@@ -705,6 +718,8 @@ add_userspec(struct member *members, struct privilege *privs)
     u->prev = u;
     u->next = NULL;
     tq_append(&userspecs, u);
+
+    debug_return;
 }
 
 /*
@@ -720,6 +735,7 @@ init_parser(const char *path, int quiet)
     struct privilege *priv;
     struct cmndspec *cs;
     struct sudo_command *c;
+    debug_decl(init_parser, SUDO_DEBUG_PARSER)
 
     while ((us = tq_pop(&userspecs)) != NULL) {
        while ((m = tq_pop(&us->users)) != NULL) {
@@ -804,12 +820,14 @@ init_parser(const char *path, int quiet)
     efree(sudoers);
     sudoers = path ? estrdup(path) : NULL;
 
-    parse_error = FALSE;
+    parse_error = false;
     errorlineno = -1;
-    errorfile = NULL;
+    errorfile = sudoers;
     verbose = !quiet;
+
+    debug_return;
 }
-#line 760 "y.tab.c"
+#line 778 "gram.c"
 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
 #if defined(__cplusplus) || defined(__STDC__)
 static int yygrowstack(void)
@@ -1015,127 +1033,127 @@ yyreduce:
     switch (yyn)
     {
 case 1:
-#line 185 "gram.y"
+#line 192 "gram.y"
 { ; }
 break;
 case 5:
-#line 193 "gram.y"
+#line 200 "gram.y"
 {
                            ;
                        }
 break;
 case 6:
-#line 196 "gram.y"
+#line 203 "gram.y"
 {
                            yyerrok;
                        }
 break;
 case 7:
-#line 199 "gram.y"
+#line 206 "gram.y"
 {
                            add_userspec(yyvsp[-1].member, yyvsp[0].privilege);
                        }
 break;
 case 8:
-#line 202 "gram.y"
+#line 209 "gram.y"
 {
                            ;
                        }
 break;
 case 9:
-#line 205 "gram.y"
+#line 212 "gram.y"
 {
                            ;
                        }
 break;
 case 10:
-#line 208 "gram.y"
+#line 215 "gram.y"
 {
                            ;
                        }
 break;
 case 11:
-#line 211 "gram.y"
+#line 218 "gram.y"
 {
                            ;
                        }
 break;
 case 12:
-#line 214 "gram.y"
+#line 221 "gram.y"
 {
                            add_defaults(DEFAULTS, NULL, yyvsp[0].defaults);
                        }
 break;
 case 13:
-#line 217 "gram.y"
+#line 224 "gram.y"
 {
                            add_defaults(DEFAULTS_USER, yyvsp[-1].member, yyvsp[0].defaults);
                        }
 break;
 case 14:
-#line 220 "gram.y"
+#line 227 "gram.y"
 {
                            add_defaults(DEFAULTS_RUNAS, yyvsp[-1].member, yyvsp[0].defaults);
                        }
 break;
 case 15:
-#line 223 "gram.y"
+#line 230 "gram.y"
 {
                            add_defaults(DEFAULTS_HOST, yyvsp[-1].member, yyvsp[0].defaults);
                        }
 break;
 case 16:
-#line 226 "gram.y"
+#line 233 "gram.y"
 {
                            add_defaults(DEFAULTS_CMND, yyvsp[-1].member, yyvsp[0].defaults);
                        }
 break;
 case 18:
-#line 232 "gram.y"
+#line 239 "gram.y"
 {
                            list_append(yyvsp[-2].defaults, yyvsp[0].defaults);
                            yyval.defaults = yyvsp[-2].defaults;
                        }
 break;
 case 19:
-#line 238 "gram.y"
+#line 245 "gram.y"
 {
-                           yyval.defaults = new_default(yyvsp[0].string, NULL, TRUE);
+                           yyval.defaults = new_default(yyvsp[0].string, NULL, true);
                        }
 break;
 case 20:
-#line 241 "gram.y"
+#line 248 "gram.y"
 {
-                           yyval.defaults = new_default(yyvsp[0].string, NULL, FALSE);
+                           yyval.defaults = new_default(yyvsp[0].string, NULL, false);
                        }
 break;
 case 21:
-#line 244 "gram.y"
+#line 251 "gram.y"
 {
-                           yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, TRUE);
+                           yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, true);
                        }
 break;
 case 22:
-#line 247 "gram.y"
+#line 254 "gram.y"
 {
                            yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '+');
                        }
 break;
 case 23:
-#line 250 "gram.y"
+#line 257 "gram.y"
 {
                            yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '-');
                        }
 break;
 case 25:
-#line 256 "gram.y"
+#line 263 "gram.y"
 {
                            list_append(yyvsp[-2].privilege, yyvsp[0].privilege);
                            yyval.privilege = yyvsp[-2].privilege;
                        }
 break;
 case 26:
-#line 262 "gram.y"
+#line 269 "gram.y"
 {
                            struct privilege *p = emalloc(sizeof(*p));
                            list2tq(&p->hostlist, yyvsp[-2].member);
@@ -1146,51 +1164,51 @@ case 26:
                        }
 break;
 case 27:
-#line 272 "gram.y"
+#line 279 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
-                           yyval.member->negated = FALSE;
+                           yyval.member->negated = false;
                        }
 break;
 case 28:
-#line 276 "gram.y"
+#line 283 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
-                           yyval.member->negated = TRUE;
+                           yyval.member->negated = true;
                        }
 break;
 case 29:
-#line 282 "gram.y"
+#line 289 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, ALIAS);
                        }
 break;
 case 30:
-#line 285 "gram.y"
+#line 292 "gram.y"
 {
                            yyval.member = new_member(NULL, ALL);
                        }
 break;
 case 31:
-#line 288 "gram.y"
+#line 295 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, NETGROUP);
                        }
 break;
 case 32:
-#line 291 "gram.y"
+#line 298 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, NTWKADDR);
                        }
 break;
 case 33:
-#line 294 "gram.y"
+#line 301 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, WORD);
                        }
 break;
 case 35:
-#line 300 "gram.y"
+#line 307 "gram.y"
 {
                            list_append(yyvsp[-2].cmndspec, yyvsp[0].cmndspec);
 #ifdef HAVE_SELINUX
@@ -1223,7 +1241,7 @@ case 35:
                        }
 break;
 case 36:
-#line 332 "gram.y"
+#line 339 "gram.y"
 {
                            struct cmndspec *cs = emalloc(sizeof(*cs));
                            if (yyvsp[-3].runas != NULL) {
@@ -1250,80 +1268,80 @@ case 36:
                        }
 break;
 case 37:
-#line 358 "gram.y"
+#line 365 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
-                           yyval.member->negated = FALSE;
+                           yyval.member->negated = false;
                        }
 break;
 case 38:
-#line 362 "gram.y"
+#line 369 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
-                           yyval.member->negated = TRUE;
+                           yyval.member->negated = true;
                        }
 break;
 case 39:
-#line 368 "gram.y"
+#line 375 "gram.y"
 {
                            yyval.string = yyvsp[0].string;
                        }
 break;
 case 40:
-#line 373 "gram.y"
+#line 380 "gram.y"
 {
                            yyval.string = yyvsp[0].string;
                        }
 break;
 case 41:
-#line 378 "gram.y"
+#line 385 "gram.y"
 {
                            yyval.seinfo.role = NULL;
                            yyval.seinfo.type = NULL;
                        }
 break;
 case 42:
-#line 382 "gram.y"
+#line 389 "gram.y"
 {
                            yyval.seinfo.role = yyvsp[0].string;
                            yyval.seinfo.type = NULL;
                        }
 break;
 case 43:
-#line 386 "gram.y"
+#line 393 "gram.y"
 {
                            yyval.seinfo.type = yyvsp[0].string;
                            yyval.seinfo.role = NULL;
                        }
 break;
 case 44:
-#line 390 "gram.y"
+#line 397 "gram.y"
 {
                            yyval.seinfo.role = yyvsp[-1].string;
                            yyval.seinfo.type = yyvsp[0].string;
                        }
 break;
 case 45:
-#line 394 "gram.y"
+#line 401 "gram.y"
 {
                            yyval.seinfo.type = yyvsp[-1].string;
                            yyval.seinfo.role = yyvsp[0].string;
                        }
 break;
 case 46:
-#line 400 "gram.y"
+#line 407 "gram.y"
 {
                            yyval.runas = NULL;
                        }
 break;
 case 47:
-#line 403 "gram.y"
+#line 410 "gram.y"
 {
                            yyval.runas = yyvsp[-1].runas;
                        }
 break;
 case 48:
-#line 408 "gram.y"
+#line 415 "gram.y"
 {
                            yyval.runas = emalloc(sizeof(struct runascontainer));
                            yyval.runas->runasusers = yyvsp[0].member;
@@ -1331,7 +1349,7 @@ case 48:
                        }
 break;
 case 49:
-#line 413 "gram.y"
+#line 420 "gram.y"
 {
                            yyval.runas = emalloc(sizeof(struct runascontainer));
                            yyval.runas->runasusers = yyvsp[-2].member;
@@ -1339,7 +1357,7 @@ case 49:
                        }
 break;
 case 50:
-#line 418 "gram.y"
+#line 425 "gram.y"
 {
                            yyval.runas = emalloc(sizeof(struct runascontainer));
                            yyval.runas->runasusers = NULL;
@@ -1347,86 +1365,86 @@ case 50:
                        }
 break;
 case 51:
-#line 425 "gram.y"
+#line 432 "gram.y"
 {
                            yyval.tag.nopasswd = yyval.tag.noexec = yyval.tag.setenv =
                                yyval.tag.log_input = yyval.tag.log_output = UNSPEC;
                        }
 break;
 case 52:
-#line 429 "gram.y"
+#line 436 "gram.y"
 {
-                           yyval.tag.nopasswd = TRUE;
+                           yyval.tag.nopasswd = true;
                        }
 break;
 case 53:
-#line 432 "gram.y"
+#line 439 "gram.y"
 {
-                           yyval.tag.nopasswd = FALSE;
+                           yyval.tag.nopasswd = false;
                        }
 break;
 case 54:
-#line 435 "gram.y"
+#line 442 "gram.y"
 {
-                           yyval.tag.noexec = TRUE;
+                           yyval.tag.noexec = true;
                        }
 break;
 case 55:
-#line 438 "gram.y"
+#line 445 "gram.y"
 {
-                           yyval.tag.noexec = FALSE;
+                           yyval.tag.noexec = false;
                        }
 break;
 case 56:
-#line 441 "gram.y"
+#line 448 "gram.y"
 {
-                           yyval.tag.setenv = TRUE;
+                           yyval.tag.setenv = true;
                        }
 break;
 case 57:
-#line 444 "gram.y"
+#line 451 "gram.y"
 {
-                           yyval.tag.setenv = FALSE;
+                           yyval.tag.setenv = false;
                        }
 break;
 case 58:
-#line 447 "gram.y"
+#line 454 "gram.y"
 {
-                           yyval.tag.log_input = TRUE;
+                           yyval.tag.log_input = true;
                        }
 break;
 case 59:
-#line 450 "gram.y"
+#line 457 "gram.y"
 {
-                           yyval.tag.log_input = FALSE;
+                           yyval.tag.log_input = false;
                        }
 break;
 case 60:
-#line 453 "gram.y"
+#line 460 "gram.y"
 {
-                           yyval.tag.log_output = TRUE;
+                           yyval.tag.log_output = true;
                        }
 break;
 case 61:
-#line 456 "gram.y"
+#line 463 "gram.y"
 {
-                           yyval.tag.log_output = FALSE;
+                           yyval.tag.log_output = false;
                        }
 break;
 case 62:
-#line 461 "gram.y"
+#line 468 "gram.y"
 {
                            yyval.member = new_member(NULL, ALL);
                        }
 break;
 case 63:
-#line 464 "gram.y"
+#line 471 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, ALIAS);
                        }
 break;
 case 64:
-#line 467 "gram.y"
+#line 474 "gram.y"
 {
                            struct sudo_command *c = emalloc(sizeof(*c));
                            c->cmnd = yyvsp[0].command.cmnd;
@@ -1435,7 +1453,7 @@ case 64:
                        }
 break;
 case 67:
-#line 479 "gram.y"
+#line 486 "gram.y"
 {
                            char *s;
                            if ((s = alias_add(yyvsp[-2].string, HOSTALIAS, yyvsp[0].member)) != NULL) {
@@ -1445,14 +1463,14 @@ case 67:
                        }
 break;
 case 69:
-#line 489 "gram.y"
+#line 496 "gram.y"
 {
                            list_append(yyvsp[-2].member, yyvsp[0].member);
                            yyval.member = yyvsp[-2].member;
                        }
 break;
 case 72:
-#line 499 "gram.y"
+#line 506 "gram.y"
 {
                            char *s;
                            if ((s = alias_add(yyvsp[-2].string, CMNDALIAS, yyvsp[0].member)) != NULL) {
@@ -1462,14 +1480,14 @@ case 72:
                        }
 break;
 case 74:
-#line 509 "gram.y"
+#line 516 "gram.y"
 {
                            list_append(yyvsp[-2].member, yyvsp[0].member);
                            yyval.member = yyvsp[-2].member;
                        }
 break;
 case 77:
-#line 519 "gram.y"
+#line 526 "gram.y"
 {
                            char *s;
                            if ((s = alias_add(yyvsp[-2].string, RUNASALIAS, yyvsp[0].member)) != NULL) {
@@ -1479,7 +1497,7 @@ case 77:
                        }
 break;
 case 80:
-#line 532 "gram.y"
+#line 539 "gram.y"
 {
                            char *s;
                            if ((s = alias_add(yyvsp[-2].string, USERALIAS, yyvsp[0].member)) != NULL) {
@@ -1489,96 +1507,96 @@ case 80:
                        }
 break;
 case 82:
-#line 542 "gram.y"
+#line 549 "gram.y"
 {
                            list_append(yyvsp[-2].member, yyvsp[0].member);
                            yyval.member = yyvsp[-2].member;
                        }
 break;
 case 83:
-#line 548 "gram.y"
+#line 555 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
-                           yyval.member->negated = FALSE;
+                           yyval.member->negated = false;
                        }
 break;
 case 84:
-#line 552 "gram.y"
+#line 559 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
-                           yyval.member->negated = TRUE;
+                           yyval.member->negated = true;
                        }
 break;
 case 85:
-#line 558 "gram.y"
+#line 565 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, ALIAS);
                        }
 break;
 case 86:
-#line 561 "gram.y"
+#line 568 "gram.y"
 {
                            yyval.member = new_member(NULL, ALL);
                        }
 break;
 case 87:
-#line 564 "gram.y"
+#line 571 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, NETGROUP);
                        }
 break;
 case 88:
-#line 567 "gram.y"
+#line 574 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, USERGROUP);
                        }
 break;
 case 89:
-#line 570 "gram.y"
+#line 577 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, WORD);
                        }
 break;
 case 91:
-#line 576 "gram.y"
+#line 583 "gram.y"
 {
                            list_append(yyvsp[-2].member, yyvsp[0].member);
                            yyval.member = yyvsp[-2].member;
                        }
 break;
 case 92:
-#line 582 "gram.y"
+#line 589 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
-                           yyval.member->negated = FALSE;
+                           yyval.member->negated = false;
                        }
 break;
 case 93:
-#line 586 "gram.y"
+#line 593 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
-                           yyval.member->negated = TRUE;
+                           yyval.member->negated = true;
                        }
 break;
 case 94:
-#line 592 "gram.y"
+#line 599 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, ALIAS);
                        }
 break;
 case 95:
-#line 595 "gram.y"
+#line 602 "gram.y"
 {
                            yyval.member = new_member(NULL, ALL);
                        }
 break;
 case 96:
-#line 598 "gram.y"
+#line 605 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, WORD);
                        }
 break;
-#line 1529 "y.tab.c"
+#line 1547 "gram.c"
     }
     yyssp -= yym;
     yystate = *yyssp;
index f3f0aace351b2ab4c4d253ca30c08a58e0cb8a0b..483d0c3a8627c7dc412327dbc87907db24391e86 100644 (file)
@@ -1,6 +1,6 @@
 %{
 /*
- * Copyright (c) 1996, 1998-2005, 2007-2011
+ * Copyright (c) 1996, 1998-2005, 2007-2012
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -52,6 +52,7 @@
 #include "sudoers.h" /* XXX */
 #include "parse.h"
 #include "toke.h"
+#include "gram.h"
 
 /*
  * We must define SIZE_MAX for yacc's skeleton.c.
  * Globals
  */
 extern int sudolineno;
+extern int last_token;
 extern char *sudoers;
-static int verbose = FALSE;
-int parse_error = FALSE;
-int pedantic = FALSE;
+static bool verbose = false;
+bool parse_error = false;
 int errorlineno = -1;
 char *errorfile = NULL;
 
@@ -92,18 +93,24 @@ static struct member *new_member(char *, int);
 void
 yyerror(const char *s)
 {
+    debug_decl(yyerror, SUDO_DEBUG_PARSER)
+
+    /* If we last saw a newline the error is on the preceding line. */
+    if (last_token == COMMENT)
+       sudolineno--;
+
     /* Save the line the first error occurred on. */
     if (errorlineno == -1) {
-       errorlineno = sudolineno ? sudolineno - 1 : 0;
+       errorlineno = sudolineno;
        errorfile = estrdup(sudoers);
     }
     if (trace_print != NULL) {
        LEXTRACE("<*> ");
     } else if (verbose && s != NULL) {
-       warningx(_(">>> %s: %s near line %d <<<"), sudoers, s,
-           sudolineno ? sudolineno - 1 : 0);
+       warningx(_(">>> %s: %s near line %d <<<"), sudoers, s, sudolineno);
     }
-    parse_error = TRUE;
+    parse_error = true;
+    debug_return;
 }
 %}
 
@@ -236,13 +243,13 @@ defaults_list     :       defaults_entry
                ;
 
 defaults_entry :       DEFVAR {
-                           $$ = new_default($1, NULL, TRUE);
+                           $$ = new_default($1, NULL, true);
                        }
                |       '!' DEFVAR {
-                           $$ = new_default($2, NULL, FALSE);
+                           $$ = new_default($2, NULL, false);
                        }
                |       DEFVAR '=' WORD {
-                           $$ = new_default($1, $3, TRUE);
+                           $$ = new_default($1, $3, true);
                        }
                |       DEFVAR '+' WORD {
                            $$ = new_default($1, $3, '+');
@@ -271,11 +278,11 @@ privilege :       hostlist '=' cmndspeclist {
 
 ophost         :       host {
                            $$ = $1;
-                           $$->negated = FALSE;
+                           $$->negated = false;
                        }
                |       '!' host {
                            $$ = $2;
-                           $$->negated = TRUE;
+                           $$->negated = true;
                        }
                ;
 
@@ -357,11 +364,11 @@ cmndspec  :       runasspec selinux cmndtag opcmnd {
 
 opcmnd         :       cmnd {
                            $$ = $1;
-                           $$->negated = FALSE;
+                           $$->negated = false;
                        }
                |       '!' cmnd {
                            $$ = $2;
-                           $$->negated = TRUE;
+                           $$->negated = true;
                        }
                ;
 
@@ -427,34 +434,34 @@ cmndtag           :       /* empty */ {
                                $$.log_input = $$.log_output = UNSPEC;
                        }
                |       cmndtag NOPASSWD {
-                           $$.nopasswd = TRUE;
+                           $$.nopasswd = true;
                        }
                |       cmndtag PASSWD {
-                           $$.nopasswd = FALSE;
+                           $$.nopasswd = false;
                        }
                |       cmndtag NOEXEC {
-                           $$.noexec = TRUE;
+                           $$.noexec = true;
                        }
                |       cmndtag EXEC {
-                           $$.noexec = FALSE;
+                           $$.noexec = false;
                        }
                |       cmndtag SETENV {
-                           $$.setenv = TRUE;
+                           $$.setenv = true;
                        }
                |       cmndtag NOSETENV {
-                           $$.setenv = FALSE;
+                           $$.setenv = false;
                        }
                |       cmndtag LOG_INPUT {
-                           $$.log_input = TRUE;
+                           $$.log_input = true;
                        }
                |       cmndtag NOLOG_INPUT {
-                           $$.log_input = FALSE;
+                           $$.log_input = false;
                        }
                |       cmndtag LOG_OUTPUT {
-                           $$.log_output = TRUE;
+                           $$.log_output = true;
                        }
                |       cmndtag NOLOG_OUTPUT {
-                           $$.log_output = FALSE;
+                           $$.log_output = false;
                        }
                ;
 
@@ -547,11 +554,11 @@ userlist  :       opuser
 
 opuser         :       user {
                            $$ = $1;
-                           $$->negated = FALSE;
+                           $$->negated = false;
                        }
                |       '!' user {
                            $$ = $2;
-                           $$->negated = TRUE;
+                           $$->negated = true;
                        }
                ;
 
@@ -581,11 +588,11 @@ grouplist :       opgroup
 
 opgroup                :       group {
                            $$ = $1;
-                           $$->negated = FALSE;
+                           $$->negated = false;
                        }
                |       '!' group {
                            $$ = $2;
-                           $$->negated = TRUE;
+                           $$->negated = true;
                        }
                ;
 
@@ -605,6 +612,7 @@ static struct defaults *
 new_default(char *var, char *val, int op)
 {
     struct defaults *d;
+    debug_decl(new_default, SUDO_DEBUG_PARSER)
 
     d = emalloc(sizeof(struct defaults));
     d->var = var;
@@ -615,13 +623,14 @@ new_default(char *var, char *val, int op)
     d->prev = d;
     d->next = NULL;
 
-    return d;
+    debug_return_ptr(d);
 }
 
 static struct member *
 new_member(char *name, int type)
 {
     struct member *m;
+    debug_decl(new_member, SUDO_DEBUG_PARSER)
 
     m = emalloc(sizeof(struct member));
     m->name = name;
@@ -629,7 +638,7 @@ new_member(char *name, int type)
     m->prev = m;
     m->next = NULL;
 
-    return m;
+    debug_return_ptr(m);
 }
 
 /*
@@ -642,6 +651,7 @@ add_defaults(int type, struct member *bmem, struct defaults *defs)
 {
     struct defaults *d;
     struct member_list binding;
+    debug_decl(add_defaults, SUDO_DEBUG_PARSER)
 
     /*
      * We can only call list2tq once on bmem as it will zero
@@ -657,6 +667,8 @@ add_defaults(int type, struct member *bmem, struct defaults *defs)
        d->binding = binding;
     }
     tq_append(&defaults, defs);
+
+    debug_return;
 }
 
 /*
@@ -667,6 +679,7 @@ static void
 add_userspec(struct member *members, struct privilege *privs)
 {
     struct userspec *u;
+    debug_decl(add_userspec, SUDO_DEBUG_PARSER)
 
     u = emalloc(sizeof(*u));
     list2tq(&u->users, members);
@@ -674,6 +687,8 @@ add_userspec(struct member *members, struct privilege *privs)
     u->prev = u;
     u->next = NULL;
     tq_append(&userspecs, u);
+
+    debug_return;
 }
 
 /*
@@ -689,6 +704,7 @@ init_parser(const char *path, int quiet)
     struct privilege *priv;
     struct cmndspec *cs;
     struct sudo_command *c;
+    debug_decl(init_parser, SUDO_DEBUG_PARSER)
 
     while ((us = tq_pop(&userspecs)) != NULL) {
        while ((m = tq_pop(&us->users)) != NULL) {
@@ -773,8 +789,10 @@ init_parser(const char *path, int quiet)
     efree(sudoers);
     sudoers = path ? estrdup(path) : NULL;
 
-    parse_error = FALSE;
+    parse_error = false;
     errorlineno = -1;
-    errorfile = NULL;
+    errorfile = sudoers;
     verbose = !quiet;
+
+    debug_return;
 }
index a60a87dc7e848f9b6cef2c89954c6e7912c13b4f..b7ffcd9e641aaf1010143627d7487126284ab747 100644 (file)
@@ -16,8 +16,6 @@
 
 #include <config.h>
 
-#if defined(HAVE_DLOPEN) || defined(HAVE_SHL_LOAD)
-
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/stat.h>
@@ -58,6 +56,8 @@
 # define RTLD_GLOBAL   0
 #endif
 
+#if defined(HAVE_DLOPEN) || defined(HAVE_SHL_LOAD)
+
 static void *group_handle;
 static struct sudoers_group_plugin *group_plugin;
 
@@ -73,6 +73,7 @@ group_plugin_load(char *plugin_info)
     char *args, path[PATH_MAX];
     char **argv = NULL;
     int len, rc = -1;
+    debug_decl(group_plugin_load, SUDO_DEBUG_UTIL)
 
     /*
      * Fill in .so path and split out args (if any).
@@ -130,14 +131,15 @@ group_plugin_load(char *plugin_info)
      * Split args into a vector if specified.
      */
     if (args != NULL) {
-       int ac = 0, wasblank = TRUE;
+       int ac = 0;
+       bool wasblank = true;
        char *cp;
 
         for (cp = args; *cp != '\0'; cp++) {
             if (isblank((unsigned char)*cp)) {
-                wasblank = TRUE;
+                wasblank = true;
             } else if (wasblank) {
-                wasblank = FALSE;
+                wasblank = false;
                 ac++;
             }
         }
@@ -154,7 +156,7 @@ group_plugin_load(char *plugin_info)
 done:
     efree(argv);
 
-    if (rc != TRUE) {
+    if (rc != true) {
        if (group_handle != NULL) {
            dlclose(group_handle);
            group_handle = NULL;
@@ -162,12 +164,14 @@ done:
        }
     }
 
-    return rc;
+    debug_return_bool(rc);
 }
 
 void
 group_plugin_unload(void)
 {
+    debug_decl(group_plugin_unload, SUDO_DEBUG_UTIL)
+
     if (group_plugin != NULL) {
        (group_plugin->cleanup)();
        group_plugin = NULL;
@@ -176,15 +180,18 @@ group_plugin_unload(void)
        dlclose(group_handle);
        group_handle = NULL;
     }
+    debug_return;
 }
 
 int
 group_plugin_query(const char *user, const char *group,
     const struct passwd *pwd)
 {
+    debug_decl(group_plugin_query, SUDO_DEBUG_UTIL)
+
     if (group_plugin == NULL)
-       return FALSE;
-    return (group_plugin->query)(user, group, pwd);
+       debug_return_bool(false);
+    debug_return_bool((group_plugin->query)(user, group, pwd));
 }
 
 #else /* !HAVE_DLOPEN && !HAVE_SHL_LOAD */
@@ -193,29 +200,26 @@ group_plugin_query(const char *user, const char *group,
  * No loadable shared object support.
  */
 
-#ifndef FALSE
-#define FALSE  0
-#endif
-
-struct passwd;
-
 int
 group_plugin_load(char *plugin_info)
 {
-    return FALSE;
+    debug_decl(group_plugin_load, SUDO_DEBUG_UTIL)
+    debug_return_bool(false);
 }
 
 void
 group_plugin_unload(void)
 {
-    return;
+    debug_decl(group_plugin_unload, SUDO_DEBUG_UTIL)
+    debug_return;
 }
 
 int
 group_plugin_query(const char *user, const char *group,
     const struct passwd *pwd)
 {
-    return FALSE;
+    debug_decl(group_plugin_query, SUDO_DEBUG_UTIL)
+    debug_return_bool(false);
 }
 
 #endif /* HAVE_DLOPEN || HAVE_SHL_LOAD */
index 10963589ac827bd18ce9dd4a0b744b6737d0f34f..04d5b6704fb8cda7e8ba976313ca47844bb1d80e 100644 (file)
@@ -61,6 +61,7 @@ set_interfaces(const char *ai)
 {
     char *addrinfo, *addr, *mask;
     struct interface *ifp;
+    debug_decl(set_interfaces, SUDO_DEBUG_NETIF)
 
     addrinfo = estrdup(ai);
     for (addr = strtok(addrinfo, " \t"); addr != NULL; addr = strtok(NULL, " \t")) {
@@ -73,7 +74,7 @@ set_interfaces(const char *ai)
        ifp = emalloc(sizeof(*ifp));
        if (strchr(addr, ':')) {
            /* IPv6 */
-#ifdef HAVE_IN6_ADDR
+#ifdef HAVE_STRUCT_IN6_ADDR
            ifp->family = AF_INET6;
            if (inet_pton(AF_INET6, addr, &ifp->addr.ip6) != 1 ||
                inet_pton(AF_INET6, mask, &ifp->netmask.ip6) != 1)
@@ -97,12 +98,14 @@ set_interfaces(const char *ai)
        interfaces = ifp;
     }
     efree(addrinfo);
+    debug_return;
 }
 
 void
 dump_interfaces(const char *ai)
 {
     char *cp, *addrinfo;
+    debug_decl(set_interfaces, SUDO_DEBUG_NETIF)
 
     addrinfo = estrdup(ai);
 
@@ -111,4 +114,5 @@ dump_interfaces(const char *ai)
        sudo_printf(SUDO_CONV_INFO_MSG, "\t%s\n", cp);
 
     efree(addrinfo);
+    debug_return;
 }
index 234d31df9399a3a5faa3616187bca9109cb4cab8..e3a13bfd6bc2ab656f90b2dfd7bf38b25ba59350 100644 (file)
@@ -27,7 +27,7 @@
  */
 union sudo_in_addr_un {
     struct in_addr ip4;
-#ifdef HAVE_IN6_ADDR
+#ifdef HAVE_STRUCT_IN6_ADDR
     struct in6_addr ip6;
 #endif
 };
index 00fd7ea80dccfe071c882bbbe2ade4b13d50f873..11622cb5e12aee189699ff8d22ff2407f18ea5d3 100644 (file)
@@ -112,6 +112,7 @@ mkdir_parents(char *path)
 {
     struct stat sb;
     char *slash = path;
+    debug_decl(mkdir_parents, SUDO_DEBUG_UTIL)
 
     for (;;) {
        if ((slash = strchr(slash + 1, '/')) == NULL)
@@ -125,6 +126,7 @@ mkdir_parents(char *path)
        }
        *slash = '/';
     }
+    debug_return;
 }
 
 /*
@@ -143,6 +145,7 @@ io_nextid(char *iolog_dir, char sessid[7])
     ssize_t nread;
     char pathbuf[PATH_MAX];
     static const char b36char[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    debug_decl(io_nextid, SUDO_DEBUG_UTIL)
 
     /*
      * Create I/O log directory if it doesn't already exist.
@@ -198,6 +201,8 @@ io_nextid(char *iolog_dir, char sessid[7])
     if (lseek(fd, 0, SEEK_SET) == (off_t)-1 || write(fd, buf, 7) != 7)
        log_error(USE_ERRNO, _("unable to write to %s"), pathbuf);
     close(fd);
+
+    debug_return;
 }
 
 /*
@@ -208,6 +213,7 @@ static size_t
 mkdir_iopath(const char *iolog_path, char *pathbuf, size_t pathsize)
 {
     size_t len;
+    debug_decl(mkdir_iopath, SUDO_DEBUG_UTIL)
 
     len = strlcpy(pathbuf, iolog_path, pathsize);
     if (len >= pathsize) {
@@ -228,20 +234,21 @@ mkdir_iopath(const char *iolog_path, char *pathbuf, size_t pathsize)
            log_error(USE_ERRNO, _("unable to create %s"), pathbuf);
     }
 
-    return len;
+    debug_return_size_t(len);
 }
 
 /*
  * Append suffix to pathbuf after len chars and open the resulting file.
  * Note that the size of pathbuf is assumed to be PATH_MAX.
- * Uses zlib if docompress is TRUE.
+ * Uses zlib if docompress is true.
  * Returns the open file handle which has the close-on-exec flag set.
  */
 static void *
-open_io_fd(char *pathbuf, size_t len, const char *suffix, int docompress)
+open_io_fd(char *pathbuf, size_t len, const char *suffix, bool docompress)
 {
     void *vfd = NULL;
     int fd;
+    debug_decl(open_io_fd, SUDO_DEBUG_UTIL)
 
     pathbuf[len] = '\0';
     strlcat(pathbuf, suffix, PATH_MAX);
@@ -255,7 +262,7 @@ open_io_fd(char *pathbuf, size_t len, const char *suffix, int docompress)
 #endif
            vfd = fdopen(fd, "w");
     }
-    return vfd;
+    debug_return_ptr(vfd);
 }
 
 /*
@@ -272,6 +279,7 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
     unsigned long ulval;
     uid_t runas_uid = 0;
     gid_t runas_gid = 0;
+    debug_decl(iolog_deserialize_info, SUDO_DEBUG_UTIL)
 
     memset(details, 0, sizeof(*details));
 
@@ -312,33 +320,33 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
                continue;
            }
            if (strncmp(*cur, "iolog_stdin=", sizeof("iolog_stdin=") - 1) == 0) {
-               if (atobool(*cur + sizeof("iolog_stdin=") - 1) == TRUE)
-                   details->iolog_stdin = TRUE;
+               if (atobool(*cur + sizeof("iolog_stdin=") - 1) == true)
+                   details->iolog_stdin = true;
                continue;
            }
            if (strncmp(*cur, "iolog_stdout=", sizeof("iolog_stdout=") - 1) == 0) {
-               if (atobool(*cur + sizeof("iolog_stdout=") - 1) == TRUE)
-                   details->iolog_stdout = TRUE;
+               if (atobool(*cur + sizeof("iolog_stdout=") - 1) == true)
+                   details->iolog_stdout = true;
                continue;
            }
            if (strncmp(*cur, "iolog_stderr=", sizeof("iolog_stderr=") - 1) == 0) {
-               if (atobool(*cur + sizeof("iolog_stderr=") - 1) == TRUE)
-                   details->iolog_stderr = TRUE;
+               if (atobool(*cur + sizeof("iolog_stderr=") - 1) == true)
+                   details->iolog_stderr = true;
                continue;
            }
            if (strncmp(*cur, "iolog_ttyin=", sizeof("iolog_ttyin=") - 1) == 0) {
-               if (atobool(*cur + sizeof("iolog_ttyin=") - 1) == TRUE)
-                   details->iolog_ttyin = TRUE;
+               if (atobool(*cur + sizeof("iolog_ttyin=") - 1) == true)
+                   details->iolog_ttyin = true;
                continue;
            }
            if (strncmp(*cur, "iolog_ttyout=", sizeof("iolog_ttyout=") - 1) == 0) {
-               if (atobool(*cur + sizeof("iolog_ttyout=") - 1) == TRUE)
-                   details->iolog_ttyout = TRUE;
+               if (atobool(*cur + sizeof("iolog_ttyout=") - 1) == true)
+                   details->iolog_ttyout = true;
                continue;
            }
            if (strncmp(*cur, "iolog_compress=", sizeof("iolog_compress=") - 1) == 0) {
-               if (atobool(*cur + sizeof("iolog_compress=") - 1) == TRUE)
-                   iolog_compress = TRUE; /* must be global */
+               if (atobool(*cur + sizeof("iolog_compress=") - 1) == true)
+                   iolog_compress = true; /* must be global */
                continue;
            }
            break;
@@ -402,6 +410,7 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
            details->runas_gr = sudo_fakegrnam(id);
        }
     }
+    debug_return;
 }
 
 static int
@@ -414,9 +423,11 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     char pathbuf[PATH_MAX], sessid[7];
     char *tofree = NULL;
     char * const *cur;
+    const char *debug_flags = NULL;
     FILE *io_logfile;
     size_t len;
     int rval = -1;
+    debug_decl(sudoers_io_open, SUDO_DEBUG_PLUGIN)
 
     if (!sudo_conv)
        sudo_conv = conversation;
@@ -425,7 +436,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
 
     /* If we have no command (because -V was specified) just return. */
     if (argc == 0)
-       return TRUE;
+       debug_return_bool(true);
 
     if (sigsetjmp(error_jmp, 1)) {
        /* called via error(), errorx() or log_error() */
@@ -438,6 +449,16 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     sudo_setpwent();
     sudo_setgrent();
 
+    /*
+     * Check for debug flags in settings list.
+     */
+    for (cur = settings; *cur != NULL; cur++) {
+       if (strncmp(*cur, "debug_flags=", sizeof("debug_flags=") - 1) == 0)
+           debug_flags = *cur + sizeof("debug_flags=") - 1;
+    }
+    if (debug_flags != NULL)
+       sudo_debug_init(NULL, debug_flags);
+
     /*
      * Pull iolog settings out of command_info, if any.
      */
@@ -446,7 +467,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     if (!details.iolog_stdin && !details.iolog_ttyin &&
        !details.iolog_stdout && !details.iolog_stderr &&
        !details.iolog_ttyout) {
-       rval = FALSE;
+       rval = false;
        goto done;
     }
 
@@ -473,7 +494,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     /*
      * We create 7 files: a log file, a timing file and 5 for input/output.
      */
-    io_logfile = open_io_fd(pathbuf, len, "/log", FALSE);
+    io_logfile = open_io_fd(pathbuf, len, "/log", false);
     if (io_logfile == NULL)
        log_error(USE_ERRNO, _("unable to create %s"), pathbuf);
 
@@ -539,7 +560,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     fputc('\n', io_logfile);
     fclose(io_logfile);
 
-    rval = TRUE;
+    rval = true;
 
 done:
     efree(tofree);
@@ -550,17 +571,18 @@ done:
        gr_delref(details.runas_gr);
     sudo_endgrent();
 
-    return rval;
+    debug_return_bool(rval);
 }
 
 static void
 sudoers_io_close(int exit_status, int error)
 {
     int i;
+    debug_decl(sudoers_io_close, SUDO_DEBUG_PLUGIN)
 
     if (sigsetjmp(error_jmp, 1)) {
        /* called via error(), errorx() or log_error() */
-       return;
+       debug_return;
     }
 
     for (i = 0; i < IOFD_MAX; i++) {
@@ -573,20 +595,23 @@ sudoers_io_close(int exit_status, int error)
 #endif
            fclose(io_fds[i].f);
     }
+    debug_return;
 }
 
 static int
 sudoers_io_version(int verbose)
 {
+    debug_decl(sudoers_io_version, SUDO_DEBUG_PLUGIN)
+
     if (sigsetjmp(error_jmp, 1)) {
        /* called via error(), errorx() or log_error() */
-       return -1;
+       debug_return_bool(-1);
     }
 
     sudo_printf(SUDO_CONV_INFO_MSG, "Sudoers I/O plugin version %s\n",
        PACKAGE_VERSION);
 
-    return TRUE;
+    debug_return_bool(true);
 }
 
 /*
@@ -596,12 +621,13 @@ static int
 sudoers_io_log(const char *buf, unsigned int len, int idx)
 {
     struct timeval now, delay;
+    debug_decl(sudoers_io_version, SUDO_DEBUG_PLUGIN)
 
     gettimeofday(&now, NULL);
 
     if (sigsetjmp(error_jmp, 1)) {
        /* called via error(), errorx() or log_error() */
-       return -1;
+       debug_return_bool(-1);
     }
 
 #ifdef HAVE_ZLIB_H
@@ -624,7 +650,7 @@ sudoers_io_log(const char *buf, unsigned int len, int idx)
     last_time.tv_sec = now.tv_sec;
     last_time.tv_usec = now.tv_usec;
 
-    return TRUE;
+    debug_return_bool(true);
 }
 
 static int
index 0f1044f20337f0c6019c00d422c1604d9cbb57e3..964068009f23c4e8aab19e08631812f36e828223 100644 (file)
@@ -73,6 +73,7 @@ fill_seq(char *str, size_t strsize)
 {
     static char sessid[7];
     int len;
+    debug_decl(sudoers_io_version, SUDO_DEBUG_UTIL)
 
     if (sessid[0] == '\0')
        io_nextid(def_iolog_dir, sessid);
@@ -81,14 +82,15 @@ fill_seq(char *str, size_t strsize)
     len = snprintf(str, strsize, "%c%c/%c%c/%c%c", sessid[0],
        sessid[1], sessid[2], sessid[3], sessid[4], sessid[5]);
     if (len < 0)
-       return strsize; /* handle non-standard snprintf() */
-    return (size_t)len;
+       debug_return_size_t(strsize); /* handle non-standard snprintf() */
+    debug_return_size_t(len);
 }
 
 static size_t
 fill_user(char *str, size_t strsize)
 {
-    return strlcpy(str, user_name, strsize);
+    debug_decl(fill_user, SUDO_DEBUG_UTIL)
+    debug_return_size_t(strlcpy(str, user_name, strsize));
 }
 
 static size_t
@@ -96,6 +98,7 @@ fill_group(char *str, size_t strsize)
 {
     struct group *grp;
     size_t len;
+    debug_decl(fill_group, SUDO_DEBUG_UTIL)
 
     if ((grp = sudo_getgrgid(user_gid)) != NULL) {
        len = strlcpy(str, grp->gr_name, strsize);
@@ -105,13 +108,14 @@ fill_group(char *str, size_t strsize)
        len = snprintf(str + len, strsize - len, "#%u",
            (unsigned int) user_gid);
     }
-    return len;
+    debug_return_size_t(len);
 }
 
 static size_t
 fill_runas_user(char *str, size_t strsize)
 {
-    return strlcpy(str, runas_pw->pw_name, strsize);
+    debug_decl(fill_runas_user, SUDO_DEBUG_UTIL)
+    debug_return_size_t(strlcpy(str, runas_pw->pw_name, strsize));
 }
 
 static size_t
@@ -119,6 +123,7 @@ fill_runas_group(char *str, size_t strsize)
 {
     struct group *grp;
     size_t len;
+    debug_decl(fill_runas_group, SUDO_DEBUG_UTIL)
 
     if (runas_gr != NULL) {
        len = strlcpy(str, runas_gr->gr_name, strsize);
@@ -132,19 +137,21 @@ fill_runas_group(char *str, size_t strsize)
                (unsigned int) runas_pw->pw_gid);
        }
     }
-    return len;
+    debug_return_size_t(len);
 }
 
 static size_t
 fill_hostname(char *str, size_t strsize)
 {
-    return strlcpy(str, user_shost, strsize);
+    debug_decl(fill_hostname, SUDO_DEBUG_UTIL)
+    debug_return_size_t(strlcpy(str, user_shost, strsize));
 }
 
 static size_t
 fill_command(char *str, size_t strsize)
 {
-    return strlcpy(str, user_base, strsize);
+    debug_decl(fill_command, SUDO_DEBUG_UTIL)
+    debug_return_size_t(strlcpy(str, user_base, strsize));
 }
 
 /*
@@ -159,7 +166,9 @@ expand_iolog_path(const char *prefix, const char *dir, const char *file,
     size_t len, prelen = 0;
     char *dst, *dst0, *path, *pathend, tmpbuf[PATH_MAX];
     const char *endbrace, *src = dir;
-    int pass, strfit;
+    int pass;
+    bool strfit;
+    debug_decl(expand_iolog_path, SUDO_DEBUG_UTIL)
 
     /* Expanded path must be <= PATH_MAX */
     if (prefix != NULL)
@@ -180,7 +189,7 @@ expand_iolog_path(const char *prefix, const char *dir, const char *file,
        file++;
 
     for (pass = 0; pass < 3; pass++) {
-       strfit = FALSE;
+       strfit = false;
        switch (pass) {
        case 0:
            src = dir;
@@ -267,8 +276,8 @@ expand_iolog_path(const char *prefix, const char *dir, const char *file,
        }
     }
 
-    return path;
+    debug_return_str(path);
 bad:
     efree(path);
-    return NULL;
+    debug_return_str(NULL);
 }
index e8e63117dea93a373b91920887df9dae6de3462a..a46ba1519032eb858c2652e99cad89015edaa220 100644 (file)
 #include "parse.h"
 #include "lbuf.h"
 
+/* Older Netscape LDAP SDKs don't prototype ldapssl_set_strength() */
+#if defined(HAVE_LDAPSSL_SET_STRENGTH) && !defined(HAVE_LDAP_SSL_H) && !defined(HAVE_MPS_LDAP_SSL_H)
+extern int ldapssl_set_strength(LDAP *ldap, int strength);
+#endif
+
 #ifndef LDAP_OPT_SUCCESS
 # define LDAP_OPT_SUCCESS LDAP_SUCCESS
 #endif
@@ -218,90 +223,90 @@ static struct ldap_config {
 } ldap_conf;
 
 static struct ldap_config_table ldap_conf_table[] = {
-    { "sudoers_debug", CONF_INT, FALSE, -1, &ldap_conf.debug },
-    { "host", CONF_STR, FALSE, -1, &ldap_conf.host },
-    { "port", CONF_INT, FALSE, -1, &ldap_conf.port },
-    { "ssl", CONF_STR, FALSE, -1, &ldap_conf.ssl },
-    { "sslpath", CONF_STR, FALSE, -1, &ldap_conf.tls_certfile },
-    { "uri", CONF_LIST_STR, FALSE, -1, &ldap_conf.uri },
+    { "sudoers_debug", CONF_INT, false, -1, &ldap_conf.debug },
+    { "host", CONF_STR, false, -1, &ldap_conf.host },
+    { "port", CONF_INT, false, -1, &ldap_conf.port },
+    { "ssl", CONF_STR, false, -1, &ldap_conf.ssl },
+    { "sslpath", CONF_STR, false, -1, &ldap_conf.tls_certfile },
+    { "uri", CONF_LIST_STR, false, -1, &ldap_conf.uri },
 #ifdef LDAP_OPT_DEBUG_LEVEL
-    { "debug", CONF_INT, FALSE, LDAP_OPT_DEBUG_LEVEL, &ldap_conf.ldap_debug },
+    { "debug", CONF_INT, false, LDAP_OPT_DEBUG_LEVEL, &ldap_conf.ldap_debug },
 #endif
 #ifdef LDAP_OPT_PROTOCOL_VERSION
-    { "ldap_version", CONF_INT, TRUE, LDAP_OPT_PROTOCOL_VERSION,
+    { "ldap_version", CONF_INT, true, LDAP_OPT_PROTOCOL_VERSION,
        &ldap_conf.version },
 #endif
 #ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
-    { "tls_checkpeer", CONF_BOOL, FALSE, LDAP_OPT_X_TLS_REQUIRE_CERT,
+    { "tls_checkpeer", CONF_BOOL, false, LDAP_OPT_X_TLS_REQUIRE_CERT,
        &ldap_conf.tls_checkpeer },
 #else
-    { "tls_checkpeer", CONF_BOOL, FALSE, -1, &ldap_conf.tls_checkpeer },
+    { "tls_checkpeer", CONF_BOOL, false, -1, &ldap_conf.tls_checkpeer },
 #endif
 #ifdef LDAP_OPT_X_TLS_CACERTFILE
-    { "tls_cacertfile", CONF_STR, FALSE, LDAP_OPT_X_TLS_CACERTFILE,
+    { "tls_cacertfile", CONF_STR, false, LDAP_OPT_X_TLS_CACERTFILE,
        &ldap_conf.tls_cacertfile },
-    { "tls_cacert", CONF_STR, FALSE, LDAP_OPT_X_TLS_CACERTFILE,
+    { "tls_cacert", CONF_STR, false, LDAP_OPT_X_TLS_CACERTFILE,
        &ldap_conf.tls_cacertfile },
 #endif
 #ifdef LDAP_OPT_X_TLS_CACERTDIR
-    { "tls_cacertdir", CONF_STR, FALSE, LDAP_OPT_X_TLS_CACERTDIR,
+    { "tls_cacertdir", CONF_STR, false, LDAP_OPT_X_TLS_CACERTDIR,
        &ldap_conf.tls_cacertdir },
 #endif
 #ifdef LDAP_OPT_X_TLS_RANDOM_FILE
-    { "tls_randfile", CONF_STR, FALSE, LDAP_OPT_X_TLS_RANDOM_FILE,
+    { "tls_randfile", CONF_STR, false, LDAP_OPT_X_TLS_RANDOM_FILE,
        &ldap_conf.tls_random_file },
 #endif
 #ifdef LDAP_OPT_X_TLS_CIPHER_SUITE
-    { "tls_ciphers", CONF_STR, FALSE, LDAP_OPT_X_TLS_CIPHER_SUITE,
+    { "tls_ciphers", CONF_STR, false, LDAP_OPT_X_TLS_CIPHER_SUITE,
        &ldap_conf.tls_cipher_suite },
 #endif
 #ifdef LDAP_OPT_X_TLS_CERTFILE
-    { "tls_cert", CONF_STR, FALSE, LDAP_OPT_X_TLS_CERTFILE,
+    { "tls_cert", CONF_STR, false, LDAP_OPT_X_TLS_CERTFILE,
        &ldap_conf.tls_certfile },
 #else
-    { "tls_cert", CONF_STR, FALSE, -1, &ldap_conf.tls_certfile },
+    { "tls_cert", CONF_STR, false, -1, &ldap_conf.tls_certfile },
 #endif
 #ifdef LDAP_OPT_X_TLS_KEYFILE
-    { "tls_key", CONF_STR, FALSE, LDAP_OPT_X_TLS_KEYFILE,
+    { "tls_key", CONF_STR, false, LDAP_OPT_X_TLS_KEYFILE,
        &ldap_conf.tls_keyfile },
 #else
-    { "tls_key", CONF_STR, FALSE, -1, &ldap_conf.tls_keyfile },
+    { "tls_key", CONF_STR, false, -1, &ldap_conf.tls_keyfile },
 #endif
 #ifdef LDAP_OPT_NETWORK_TIMEOUT
-    { "bind_timelimit", CONF_INT, TRUE, -1 /* needs timeval, set manually */,
+    { "bind_timelimit", CONF_INT, true, -1 /* needs timeval, set manually */,
        &ldap_conf.bind_timelimit },
-    { "network_timeout", CONF_INT, TRUE, -1 /* needs timeval, set manually */,
+    { "network_timeout", CONF_INT, true, -1 /* needs timeval, set manually */,
        &ldap_conf.bind_timelimit },
 #elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
-    { "bind_timelimit", CONF_INT, TRUE, LDAP_X_OPT_CONNECT_TIMEOUT,
+    { "bind_timelimit", CONF_INT, true, LDAP_X_OPT_CONNECT_TIMEOUT,
        &ldap_conf.bind_timelimit },
-    { "network_timeout", CONF_INT, TRUE, LDAP_X_OPT_CONNECT_TIMEOUT,
+    { "network_timeout", CONF_INT, true, LDAP_X_OPT_CONNECT_TIMEOUT,
        &ldap_conf.bind_timelimit },
 #endif
-    { "timelimit", CONF_INT, TRUE, LDAP_OPT_TIMELIMIT, &ldap_conf.timelimit },
+    { "timelimit", CONF_INT, true, LDAP_OPT_TIMELIMIT, &ldap_conf.timelimit },
 #ifdef LDAP_OPT_TIMEOUT
-    { "timeout", CONF_INT, TRUE, -1 /* needs timeval, set manually */,
+    { "timeout", CONF_INT, true, -1 /* needs timeval, set manually */,
        &ldap_conf.timeout },
 #endif
 #ifdef LDAP_OPT_DEREF
-    { "deref", CONF_DEREF_VAL, TRUE, LDAP_OPT_DEREF, &ldap_conf.deref },
+    { "deref", CONF_DEREF_VAL, true, LDAP_OPT_DEREF, &ldap_conf.deref },
 #endif
-    { "binddn", CONF_STR, FALSE, -1, &ldap_conf.binddn },
-    { "bindpw", CONF_STR, FALSE, -1, &ldap_conf.bindpw },
-    { "rootbinddn", CONF_STR, FALSE, -1, &ldap_conf.rootbinddn },
-    { "sudoers_base", CONF_LIST_STR, FALSE, -1, &ldap_conf.base },
-    { "sudoers_timed", CONF_BOOL, FALSE, -1, &ldap_conf.timed },
-    { "sudoers_search_filter", CONF_STR, FALSE, -1, &ldap_conf.search_filter },
+    { "binddn", CONF_STR, false, -1, &ldap_conf.binddn },
+    { "bindpw", CONF_STR, false, -1, &ldap_conf.bindpw },
+    { "rootbinddn", CONF_STR, false, -1, &ldap_conf.rootbinddn },
+    { "sudoers_base", CONF_LIST_STR, false, -1, &ldap_conf.base },
+    { "sudoers_timed", CONF_BOOL, false, -1, &ldap_conf.timed },
+    { "sudoers_search_filter", CONF_STR, false, -1, &ldap_conf.search_filter },
 #ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S
-    { "use_sasl", CONF_BOOL, FALSE, -1, &ldap_conf.use_sasl },
-    { "sasl_auth_id", CONF_STR, FALSE, -1, &ldap_conf.sasl_auth_id },
-    { "rootuse_sasl", CONF_BOOL, FALSE, -1, &ldap_conf.rootuse_sasl },
-    { "rootsasl_auth_id", CONF_STR, FALSE, -1, &ldap_conf.rootsasl_auth_id },
+    { "use_sasl", CONF_BOOL, false, -1, &ldap_conf.use_sasl },
+    { "sasl_auth_id", CONF_STR, false, -1, &ldap_conf.sasl_auth_id },
+    { "rootuse_sasl", CONF_BOOL, false, -1, &ldap_conf.rootuse_sasl },
+    { "rootsasl_auth_id", CONF_STR, false, -1, &ldap_conf.rootsasl_auth_id },
 # ifdef LDAP_OPT_X_SASL_SECPROPS
-    { "sasl_secprops", CONF_STR, TRUE, LDAP_OPT_X_SASL_SECPROPS,
+    { "sasl_secprops", CONF_STR, true, LDAP_OPT_X_SASL_SECPROPS,
        &ldap_conf.sasl_secprops },
 # endif
-    { "krb5_ccname", CONF_STR, FALSE, -1, &ldap_conf.krb5_ccname },
+    { "krb5_ccname", CONF_STR, false, -1, &ldap_conf.krb5_ccname },
 #endif /* HAVE_LDAP_SASL_INTERACTIVE_BIND_S */
     { NULL }
 };
@@ -362,6 +367,7 @@ sudo_ldap_conf_add_ports(void)
 
     char *host, *port, defport[13];
     char hostbuf[LINE_MAX * 2];
+    debug_decl(sudo_ldap_conf_add_ports, SUDO_DEBUG_LDAP)
 
     hostbuf[0] = '\0';
     if (snprintf(defport, sizeof(defport), ":%d", ldap_conf.port) >= sizeof(defport))
@@ -385,7 +391,7 @@ sudo_ldap_conf_add_ports(void)
 
     efree(ldap_conf.host);
     ldap_conf.host = estrdup(hostbuf);
-    return;
+    debug_return;
 
 toobig:
     errorx(1, _("sudo_ldap_conf_add_ports: out of space expanding hostbuf"));
@@ -405,6 +411,7 @@ sudo_ldap_parse_uri(const struct ldap_config_list_str *uri_list)
     char hostbuf[LINE_MAX];
     int nldap = 0, nldaps = 0;
     int rc = -1;
+    debug_decl(sudo_ldap_parse_uri, SUDO_DEBUG_LDAP)
 
     do {
        buf = estrdup(uri_list->val);
@@ -472,7 +479,7 @@ sudo_ldap_parse_uri(const struct ldap_config_list_str *uri_list)
 
 done:
     efree(buf);
-    return rc;
+    debug_return_int(rc);
 
 toobig:
     errorx(1, _("sudo_ldap_parse_uri: out of space building hostbuf"));
@@ -484,10 +491,11 @@ sudo_ldap_join_uri(struct ldap_config_list_str *uri_list)
     struct ldap_config_list_str *uri;
     size_t len = 0;
     char *buf, *cp;
+    debug_decl(sudo_ldap_join_uri, SUDO_DEBUG_LDAP)
 
     /* Usually just a single entry. */
     if (uri_list->next == NULL)
-       return estrdup(uri_list->val);
+       debug_return_str(estrdup(uri_list->val));
 
     for (uri = uri_list; uri != NULL; uri = uri->next) {
        len += strlen(uri->val) + 1;
@@ -499,7 +507,7 @@ sudo_ldap_join_uri(struct ldap_config_list_str *uri_list)
        *cp++ = ' ';
     }
     cp[-1] = '\0';
-    return buf;
+    debug_return_str(buf);
 }
 #endif /* HAVE_LDAP_INITIALIZE */
 
@@ -508,6 +516,7 @@ sudo_ldap_init(LDAP **ldp, const char *host, int port)
 {
     LDAP *ld = NULL;
     int rc = LDAP_CONNECT_ERROR;
+    debug_decl(sudo_ldap_init, SUDO_DEBUG_LDAP)
 
 #ifdef HAVE_LDAPSSL_INIT
     if (ldap_conf.ssl_mode == SUDO_LDAP_SSL) {
@@ -565,61 +574,63 @@ sudo_ldap_init(LDAP **ldp, const char *host, int port)
 
 done:
     *ldp = ld;
-    return rc;
+    debug_return_int(rc);
 }
 
 /*
- * Walk through search results and return TRUE if we have a matching
- * netgroup, else FALSE.
+ * Walk through search results and return true if we have a matching
+ * netgroup, else false.
  */
-static int
+static bool
 sudo_ldap_check_user_netgroup(LDAP *ld, LDAPMessage *entry, char *user)
 {
     struct berval **bv, **p;
     char *val;
-    int ret = FALSE;
+    int ret = false;
+    debug_decl(sudo_ldap_check_user_netgroup, SUDO_DEBUG_LDAP)
 
     if (!entry)
-       return ret;
+       debug_return_bool(ret);
 
     /* get the values from the entry */
     bv = ldap_get_values_len(ld, entry, "sudoUser");
     if (bv == NULL)
-       return ret;
+       debug_return_bool(ret);
 
     /* walk through values */
     for (p = bv; *p != NULL && !ret; p++) {
        val = (*p)->bv_val;
        /* match any */
        if (netgr_matches(val, NULL, NULL, user))
-           ret = TRUE;
+           ret = true;
        DPRINTF(("ldap sudoUser netgroup '%s' ... %s", val,
            ret ? "MATCH!" : "not"), 2 + ((ret) ? 0 : 1));
     }
 
     ldap_value_free_len(bv);   /* cleanup */
 
-    return ret;
+    debug_return_bool(ret);
 }
 
 /*
- * Walk through search results and return TRUE if we have a
- * host match, else FALSE.
- */
-static int
+* Walk through search results and return true if we have a
+* host match, else false.
+*/
+static bool
 sudo_ldap_check_host(LDAP *ld, LDAPMessage *entry)
 {
     struct berval **bv, **p;
     char *val;
-    int ret = FALSE;
+    bool ret = false;
+    debug_decl(sudo_ldap_check_host, SUDO_DEBUG_LDAP)
 
     if (!entry)
-       return ret;
+       debug_return_bool(ret);
 
     /* get the values from the entry */
     bv = ldap_get_values_len(ld, entry, "sudoHost");
     if (bv == NULL)
-       return ret;
+       debug_return_bool(ret);
 
     /* walk through values */
     for (p = bv; *p != NULL && !ret; p++) {
@@ -628,14 +639,14 @@ sudo_ldap_check_host(LDAP *ld, LDAPMessage *entry)
        if (!strcmp(val, "ALL") || addr_matches(val) ||
            netgr_matches(val, user_host, user_shost, NULL) ||
            hostname_matches(user_shost, user_host, val))
-           ret = TRUE;
+           ret = true;
        DPRINTF(("ldap sudoHost '%s' ... %s", val,
            ret ? "MATCH!" : "not"), 2);
     }
 
     ldap_value_free_len(bv);   /* cleanup */
 
-    return ret;
+    debug_return_bool(ret);
 }
 
 static int
@@ -643,10 +654,11 @@ sudo_ldap_check_runas_user(LDAP *ld, LDAPMessage *entry)
 {
     struct berval **bv, **p;
     char *val;
-    int ret = FALSE;
+    bool ret = false;
+    debug_decl(sudo_ldap_check_runas_user, SUDO_DEBUG_LDAP)
 
     if (!runas_pw)
-       return UNSPEC;
+       debug_return_bool(UNSPEC);
 
     /* get the runas user from the entry */
     bv = ldap_get_values_len(ld, entry, "sudoRunAsUser");
@@ -675,7 +687,7 @@ sudo_ldap_check_runas_user(LDAP *ld, LDAPMessage *entry)
      * what the user specified on the command line.
      */
     if (bv == NULL)
-       return !strcasecmp(runas_pw->pw_name, def_runas_default);
+       debug_return_bool(!strcasecmp(runas_pw->pw_name, def_runas_default));
 
     /* walk through values returned, looking for a match */
     for (p = bv; *p != NULL && !ret; p++) {
@@ -683,21 +695,21 @@ sudo_ldap_check_runas_user(LDAP *ld, LDAPMessage *entry)
        switch (val[0]) {
        case '+':
            if (netgr_matches(val, NULL, NULL, runas_pw->pw_name))
-               ret = TRUE;
+               ret = true;
            break;
        case '%':
            if (usergr_matches(val, runas_pw->pw_name, runas_pw))
-               ret = TRUE;
+               ret = true;
            break;
        case 'A':
            if (strcmp(val, "ALL") == 0) {
-               ret = TRUE;
+               ret = true;
                break;
            }
            /* FALLTHROUGH */
        default:
            if (strcasecmp(val, runas_pw->pw_name) == 0)
-               ret = TRUE;
+               ret = true;
            break;
        }
        DPRINTF(("ldap sudoRunAsUser '%s' ... %s", val,
@@ -706,7 +718,7 @@ sudo_ldap_check_runas_user(LDAP *ld, LDAPMessage *entry)
 
     ldap_value_free_len(bv);   /* cleanup */
 
-    return ret;
+    debug_return_bool(ret);
 }
 
 static int
@@ -714,84 +726,88 @@ sudo_ldap_check_runas_group(LDAP *ld, LDAPMessage *entry)
 {
     struct berval **bv, **p;
     char *val;
-    int ret = FALSE;
+    bool ret = false;
+    debug_decl(sudo_ldap_check_runas_group, SUDO_DEBUG_LDAP)
 
     /* runas_gr is only set if the user specified the -g flag */
     if (!runas_gr)
-       return UNSPEC;
+       debug_return_bool(UNSPEC);
 
     /* get the values from the entry */
     bv = ldap_get_values_len(ld, entry, "sudoRunAsGroup");
     if (bv == NULL)
-       return ret;
+       debug_return_bool(ret);
 
     /* walk through values returned, looking for a match */
     for (p = bv; *p != NULL && !ret; p++) {
        val = (*p)->bv_val;
        if (strcmp(val, "ALL") == 0 || group_matches(val, runas_gr))
-           ret = TRUE;
+           ret = true;
        DPRINTF(("ldap sudoRunAsGroup '%s' ... %s", val,
            ret ? "MATCH!" : "not"), 2);
     }
 
     ldap_value_free_len(bv);   /* cleanup */
 
-    return ret;
+    debug_return_bool(ret);
 }
 
 /*
- * Walk through search results and return TRUE if we have a runas match,
- * else FALSE.  RunAs info is optional.
+ * Walk through search results and return true if we have a runas match,
+ * else false.  RunAs info is optional.
  */
-static int
+static bool
 sudo_ldap_check_runas(LDAP *ld, LDAPMessage *entry)
 {
-    int ret;
+    bool ret;
+    debug_decl(sudo_ldap_check_runas, SUDO_DEBUG_LDAP)
 
     if (!entry)
-       return FALSE;
+       debug_return_bool(false);
 
-    ret = sudo_ldap_check_runas_user(ld, entry) != FALSE &&
-       sudo_ldap_check_runas_group(ld, entry) != FALSE;
+    ret = sudo_ldap_check_runas_user(ld, entry) != false &&
+       sudo_ldap_check_runas_group(ld, entry) != false;
 
-    return ret;
+    debug_return_bool(ret);
 }
 
 /*
- * Walk through search results and return TRUE if we have a command match,
- * FALSE if disallowed and UNSPEC if not matched.
+ * Walk through search results and return true if we have a command match,
+ * false if disallowed and UNSPEC if not matched.
  */
 static int
 sudo_ldap_check_command(LDAP *ld, LDAPMessage *entry, int *setenv_implied)
 {
     struct berval **bv, **p;
     char *allowed_cmnd, *allowed_args, *val;
-    int foundbang, ret = UNSPEC;
+    bool foundbang;
+    int ret = UNSPEC;
+    debug_decl(sudo_ldap_check_command, SUDO_DEBUG_LDAP)
 
     if (!entry)
-       return ret;
+       debug_return_bool(ret);
 
     bv = ldap_get_values_len(ld, entry, "sudoCommand");
     if (bv == NULL)
-       return ret;
+       debug_return_bool(ret);
 
-    for (p = bv; *p != NULL && ret != FALSE; p++) {
+    for (p = bv; *p != NULL && ret != false; p++) {
        val = (*p)->bv_val;
        /* Match against ALL ? */
        if (!strcmp(val, "ALL")) {
-           ret = TRUE;
+           ret = true;
            if (setenv_implied != NULL)
-               *setenv_implied = TRUE;
+               *setenv_implied = true;
            DPRINTF(("ldap sudoCommand '%s' ... MATCH!", val), 2);
            continue;
        }
 
        /* check for !command */
        if (*val == '!') {
-           foundbang = TRUE;
+           foundbang = true;
            allowed_cmnd = estrdup(1 + val);    /* !command */
        } else {
-           foundbang = FALSE;
+           foundbang = false;
            allowed_cmnd = estrdup(val);        /* command */
        }
 
@@ -806,22 +822,22 @@ sudo_ldap_check_command(LDAP *ld, LDAPMessage *entry, int *setenv_implied)
             * If allowed (no bang) set ret but keep on checking.
             * If disallowed (bang), exit loop.
             */
-           ret = foundbang ? FALSE : TRUE;
+           ret = foundbang ? false : true;
        }
        DPRINTF(("ldap sudoCommand '%s' ... %s", val,
-           ret == TRUE ? "MATCH!" : "not"), 2);
+           ret == true ? "MATCH!" : "not"), 2);
 
        efree(allowed_cmnd);    /* cleanup */
     }
 
     ldap_value_free_len(bv);   /* more cleanup */
 
-    return ret;
+    debug_return_bool(ret);
 }
 
 /*
  * Search for boolean "option" in sudoOption.
- * Returns TRUE if found and allowed, FALSE if negated, else UNSPEC.
+ * Returns true if found and allowed, false if negated, else UNSPEC.
  */
 static int
 sudo_ldap_check_bool(LDAP *ld, LDAPMessage *entry, char *option)
@@ -829,13 +845,14 @@ sudo_ldap_check_bool(LDAP *ld, LDAPMessage *entry, char *option)
     struct berval **bv, **p;
     char ch, *var;
     int ret = UNSPEC;
+    debug_decl(sudo_ldap_check_bool, SUDO_DEBUG_LDAP)
 
     if (entry == NULL)
-       return UNSPEC;
+       debug_return_bool(ret);
 
     bv = ldap_get_values_len(ld, entry, "sudoOption");
     if (bv == NULL)
-       return ret;
+       debug_return_bool(ret);
 
     /* walk through options */
     for (p = bv; *p != NULL; p++) {
@@ -850,7 +867,7 @@ sudo_ldap_check_bool(LDAP *ld, LDAPMessage *entry, char *option)
 
     ldap_value_free_len(bv);
 
-    return ret;
+    debug_return_bool(ret);
 }
 
 /*
@@ -862,13 +879,14 @@ sudo_ldap_parse_options(LDAP *ld, LDAPMessage *entry)
 {
     struct berval **bv, **p;
     char op, *var, *val;
+    debug_decl(sudo_ldap_parse_options, SUDO_DEBUG_LDAP)
 
     if (entry == NULL)
-       return;
+       debug_return;
 
     bv = ldap_get_values_len(ld, entry, "sudoOption");
     if (bv == NULL)
-       return;
+       debug_return;
 
     /* walk through options */
     for (p = bv; *p != NULL; p++) {
@@ -886,19 +904,21 @@ sudo_ldap_parse_options(LDAP *ld, LDAPMessage *entry)
                set_default(var, val, (int) op);
            } else {
                /* case var=val */
-               set_default(var, val, TRUE);
+               set_default(var, val, true);
            }
        } else if (*var == '!') {
            /* case !var Boolean False */
-           set_default(var + 1, NULL, FALSE);
+           set_default(var + 1, NULL, false);
        } else {
            /* case var Boolean True */
-           set_default(var, NULL, TRUE);
+           set_default(var, NULL, true);
        }
        efree(var);
     }
 
     ldap_value_free_len(bv);
+
+    debug_return;
 }
 
 /*
@@ -930,6 +950,7 @@ sudo_ldap_timefilter(char *buffer, size_t buffersize)
     time_t now;
     char timebuffer[16];
     int bytes = 0;
+    debug_decl(sudo_ldap_timefilter, SUDO_DEBUG_LDAP)
 
     /* Make sure we have a formatted timestamp for __now__. */
     time(&now);
@@ -953,22 +974,116 @@ sudo_ldap_timefilter(char *buffer, size_t buffersize)
     }
 
 done:
-    return bytes;
+    debug_return_int(bytes);
 }
 
 /*
  * Builds up a filter to search for default settings
  */
 static char *
-sudo_ldap_build_default_filter()
+sudo_ldap_build_default_filter(void)
 {
     char *filt;
+    debug_decl(sudo_ldap_build_default_filter, SUDO_DEBUG_LDAP)
 
     if (ldap_conf.search_filter)
        easprintf(&filt, "(&%s(cn=defaults))", ldap_conf.search_filter);
     else
        filt = estrdup("cn=defaults");
-    return filt;
+    debug_return_str(filt);
+}
+
+/*
+ * Determine length of query value after escaping characters
+ * as per RFC 4515.
+ */
+static size_t
+sudo_ldap_value_len(const char *value)
+{
+    const char *s;
+    size_t len = 0;
+
+    for (s = value; *s != '\0'; s++) {
+       switch (*s) {
+       case '\\':
+       case '(':
+       case ')':
+       case '*':
+           len += 2;
+           break;
+       }
+    }
+    len += (size_t)(s - value);
+    return len;
+}
+
+/*
+ * Like strlcat() but escapes characters as per RFC 4515.
+ */
+static size_t
+sudo_ldap_value_cat(char *dst, const char *src, size_t size)
+{
+    char *d = dst;
+    const char *s = src;
+    size_t n = size;
+    size_t dlen;
+
+    /* Find the end of dst and adjust bytes left but don't go past end */
+    while (n-- != 0 && *d != '\0')
+       d++;
+    dlen = d - dst;
+    n = size - dlen;
+
+    if (n == 0)
+       return dlen + strlen(s);
+    while (*s != '\0') {
+       switch (*s) {
+       case '\\':
+           if (n < 3)
+               goto done;
+           *d++ = '\\';
+           *d++ = '5';
+           *d++ = 'c';
+           n -= 3;
+           break;
+       case '(':
+           if (n < 3)
+               goto done;
+           *d++ = '\\';
+           *d++ = '2';
+           *d++ = '8';
+           n -= 3;
+           break;
+       case ')':
+           if (n < 3)
+               goto done;
+           *d++ = '\\';
+           *d++ = '2';
+           *d++ = '9';
+           n -= 3;
+           break;
+       case '*':
+           if (n < 3)
+               goto done;
+           *d++ = '\\';
+           *d++ = '2';
+           *d++ = 'a';
+           n -= 3;
+           break;
+       default:
+           if (n < 1)
+               goto done;
+           *d++ = *s;
+           n--;
+           break;
+       }
+       s++;
+    }
+done:
+    *d = '\0';
+    while (*s != '\0')
+       s++;
+    return dlen + (s - src);   /* count does not include NUL */
 }
 
 /*
@@ -978,27 +1093,34 @@ static char *
 sudo_ldap_build_pass1(struct passwd *pw)
 {
     struct group *grp;
-    char *buf, timebuffer[TIMEFILTER_LENGTH];
+    char *buf, timebuffer[TIMEFILTER_LENGTH], gidbuf[MAX_UID_T_LEN];
     struct group_list *grlist;
     size_t sz = 0;
     int i;
+    debug_decl(sudo_ldap_build_pass1, SUDO_DEBUG_LDAP)
 
     /* Start with LDAP search filter length + 3 */
     if (ldap_conf.search_filter)
        sz += strlen(ldap_conf.search_filter) + 3;
 
     /* Then add (|(sudoUser=USERNAME)(sudoUser=ALL)) + NUL */
-    sz += 29 + strlen(pw->pw_name);
+    sz += 29 + sudo_ldap_value_len(pw->pw_name);
 
-    /* Add space for primary and supplementary groups */
+    /* Add space for primary and supplementary groups and gids */
     if ((grp = sudo_getgrgid(pw->pw_gid)) != NULL) {
-       sz += 12 + strlen(grp->gr_name);
+       sz += 12 + sudo_ldap_value_len(grp->gr_name);
     }
+    sz += 13 + MAX_UID_T_LEN;
     if ((grlist = get_group_list(pw)) != NULL) {
        for (i = 0; i < grlist->ngroups; i++) {
            if (grp != NULL && strcasecmp(grlist->groups[i], grp->gr_name) == 0)
                continue;
-           sz += 12 + strlen(grlist->groups[i]);
+           sz += 12 + sudo_ldap_value_len(grlist->groups[i]);
+       }
+       for (i = 0; i < grlist->ngids; i++) {
+           if (pw->pw_gid == grlist->gids[i])
+               continue;
+           sz += 13 + MAX_UID_T_LEN;
        }
     }
 
@@ -1020,23 +1142,36 @@ sudo_ldap_build_pass1(struct passwd *pw)
 
     /* Global OR + sudoUser=user_name filter */
     (void) strlcat(buf, "(|(sudoUser=", sz);
-    (void) strlcat(buf, pw->pw_name, sz);
+    (void) sudo_ldap_value_cat(buf, pw->pw_name, sz);
     (void) strlcat(buf, ")", sz);
 
-    /* Append primary group */
+    /* Append primary group and gid */
     if (grp != NULL) {
        (void) strlcat(buf, "(sudoUser=%", sz);
-       (void) strlcat(buf, grp->gr_name, sz);
+       (void) sudo_ldap_value_cat(buf, grp->gr_name, sz);
        (void) strlcat(buf, ")", sz);
     }
+    (void) snprintf(gidbuf, sizeof(gidbuf), "%u", (unsigned int)pw->pw_gid);
+    (void) strlcat(buf, "(sudoUser=%#", sz);
+    (void) strlcat(buf, gidbuf, sz);
+    (void) strlcat(buf, ")", sz);
 
-    /* Append supplementary groups */
+    /* Append supplementary groups and gids */
     if (grlist != NULL) {
        for (i = 0; i < grlist->ngroups; i++) {
            if (grp != NULL && strcasecmp(grlist->groups[i], grp->gr_name) == 0)
                continue;
            (void) strlcat(buf, "(sudoUser=%", sz);
-           (void) strlcat(buf, grlist->groups[i], sz);
+           (void) sudo_ldap_value_cat(buf, grlist->groups[i], sz);
+           (void) strlcat(buf, ")", sz);
+       }
+       for (i = 0; i < grlist->ngids; i++) {
+           if (pw->pw_gid == grlist->gids[i])
+               continue;
+           (void) snprintf(gidbuf, sizeof(gidbuf), "%u",
+               (unsigned int)grlist->gids[i]);
+           (void) strlcat(buf, "(sudoUser=%#", sz);
+           (void) strlcat(buf, gidbuf, sz);
            (void) strlcat(buf, ")", sz);
        }
     }
@@ -1061,7 +1196,7 @@ sudo_ldap_build_pass1(struct passwd *pw)
     }
     strlcat(buf, ")", sz); /* closes the global OR or the global AND */
 
-    return buf;
+    debug_return_str(buf);
 }
 
 /*
@@ -1071,6 +1206,7 @@ static char *
 sudo_ldap_build_pass2(void)
 {
     char *filt, timebuffer[TIMEFILTER_LENGTH];
+    debug_decl(sudo_ldap_build_pass2, SUDO_DEBUG_LDAP)
 
     if (ldap_conf.timed)
        sudo_ldap_timefilter(timebuffer, sizeof(timebuffer));
@@ -1086,7 +1222,7 @@ sudo_ldap_build_pass2(void)
        ldap_conf.timed ? timebuffer : "",
        (ldap_conf.timed || ldap_conf.search_filter) ? ")" : "");
 
-    return filt;
+    debug_return_str(filt);
 }
 
 static void
@@ -1094,6 +1230,7 @@ sudo_ldap_read_secret(const char *path)
 {
     FILE *fp;
     char buf[LINE_MAX], *cp;
+    debug_decl(sudo_ldap_read_secret, SUDO_DEBUG_LDAP)
 
     if ((fp = fopen(_PATH_LDAP_SECRET, "r")) != NULL) {
        if (fgets(buf, sizeof(buf), fp) != NULL) {
@@ -1108,14 +1245,16 @@ sudo_ldap_read_secret(const char *path)
        }
        fclose(fp);
     }
+    debug_return;
 }
 
-static int
+static bool
 sudo_ldap_read_config(void)
 {
     FILE *fp;
     char *cp, *keyword, *value;
     struct ldap_config_table *cur;
+    debug_decl(sudo_ldap_read_config, SUDO_DEBUG_LDAP)
 
     /* defaults */
     ldap_conf.version = 3;
@@ -1129,7 +1268,7 @@ sudo_ldap_read_config(void)
     ldap_conf.deref = -1;
 
     if ((fp = fopen(_PATH_LDAP_CONF, "r")) == NULL)
-       return FALSE;
+       debug_return_bool(false);
 
     while ((cp = sudo_parseln(fp)) != NULL) {
        if (*cp == '\0')
@@ -1162,7 +1301,7 @@ sudo_ldap_read_config(void)
                        *(int *)(cur->valp) = LDAP_DEREF_NEVER;
                    break;
                case CONF_BOOL:
-                   *(int *)(cur->valp) = atobool(value) == TRUE;
+                   *(int *)(cur->valp) = atobool(value) == true;
                    break;
                case CONF_INT:
                    *(int *)(cur->valp) = atoi(value);
@@ -1294,7 +1433,7 @@ sudo_ldap_read_config(void)
        sudo_printf(SUDO_CONV_ERROR_MSG, "===================\n");
     }
     if (!ldap_conf.base)
-       return FALSE;           /* if no base is defined, ignore LDAP */
+       debug_return_bool(false);       /* if no base is defined, ignore LDAP */
 
     if (ldap_conf.bind_timelimit > 0)
        ldap_conf.bind_timelimit *= 1000;       /* convert to ms */
@@ -1305,7 +1444,7 @@ sudo_ldap_read_config(void)
     if (ldap_conf.ssl != NULL) {
        if (strcasecmp(ldap_conf.ssl, "start_tls") == 0)
            ldap_conf.ssl_mode = SUDO_LDAP_STARTTLS;
-       else if (atobool(ldap_conf.ssl) == TRUE)
+       else if (atobool(ldap_conf.ssl) == true)
            ldap_conf.ssl_mode = SUDO_LDAP_SSL;
     }
 
@@ -1321,7 +1460,7 @@ sudo_ldap_read_config(void)
     if (ldap_conf.uri) {
        struct ldap_config_list_str *uri = ldap_conf.uri;
        if (sudo_ldap_parse_uri(uri) != 0)
-           return FALSE;
+           debug_return_bool(false);
        do {
            ldap_conf.uri = uri->next;
            efree(uri);
@@ -1383,7 +1522,7 @@ sudo_ldap_read_config(void)
        }
     }
 #endif
-    return TRUE;
+    debug_return_bool(true);
 }
 
 /*
@@ -1395,23 +1534,25 @@ sudo_ldap_get_first_rdn(LDAP *ld, LDAPMessage *entry)
 #ifdef HAVE_LDAP_STR2DN
     char *dn, *rdn = NULL;
     LDAPDN tmpDN;
+    debug_decl(sudo_ldap_get_first_rdn, SUDO_DEBUG_LDAP)
 
     if ((dn = ldap_get_dn(ld, entry)) == NULL)
-       return NULL;
+       debug_return_str(NULL);
     if (ldap_str2dn(dn, &tmpDN, LDAP_DN_FORMAT_LDAP) == LDAP_SUCCESS) {
        ldap_rdn2str(tmpDN[0], &rdn, LDAP_DN_FORMAT_UFN);
        ldap_dnfree(tmpDN);
     }
     ldap_memfree(dn);
-    return rdn;
+    debug_return_str(rdn);
 #else
     char *dn, **edn;
+    debug_decl(sudo_ldap_get_first_rdn, SUDO_DEBUG_LDAP)
 
     if ((dn = ldap_get_dn(ld, entry)) == NULL)
        return NULL;
     edn = ldap_explode_dn(dn, 1);
     ldap_memfree(dn);
-    return edn ? edn[0] : NULL;
+    debug_return_str(edn ? edn[0] : NULL);
 #endif
 }
 
@@ -1430,6 +1571,7 @@ sudo_ldap_display_defaults(struct sudo_nss *nss, struct passwd *pw,
     LDAPMessage *entry, *result;
     char *prefix, *filt;
     int rc, count = 0;
+    debug_decl(sudo_ldap_display_defaults, SUDO_DEBUG_LDAP)
 
     if (handle == NULL || handle->ld == NULL)
        goto done;
@@ -1465,7 +1607,7 @@ sudo_ldap_display_defaults(struct sudo_nss *nss, struct passwd *pw,
     }
     efree(filt);
 done:
-    return count;
+    debug_return_int(count);
 }
 
 /*
@@ -1475,7 +1617,8 @@ static int
 sudo_ldap_display_bound_defaults(struct sudo_nss *nss, struct passwd *pw,
     struct lbuf *lbuf)
 {
-    return 0;
+    debug_decl(sudo_ldap_display_bound_defaults, SUDO_DEBUG_LDAP)
+    debug_return_int(0);
 }
 
 /*
@@ -1486,6 +1629,7 @@ sudo_ldap_display_entry_short(LDAP *ld, LDAPMessage *entry, struct lbuf *lbuf)
 {
     struct berval **bv, **p;
     int count = 0;
+    debug_decl(sudo_ldap_display_entry_short, SUDO_DEBUG_LDAP)
 
     lbuf_append(lbuf, "    (");
 
@@ -1543,7 +1687,7 @@ sudo_ldap_display_entry_short(LDAP *ld, LDAPMessage *entry, struct lbuf *lbuf)
     }
     lbuf_append(lbuf, "\n");
 
-    return count;
+    debug_return_int(count);
 }
 
 /*
@@ -1555,6 +1699,7 @@ sudo_ldap_display_entry_long(LDAP *ld, LDAPMessage *entry, struct lbuf *lbuf)
     struct berval **bv, **p;
     char *rdn;
     int count = 0;
+    debug_decl(sudo_ldap_display_entry_long, SUDO_DEBUG_LDAP)
 
     /* extract the dn, only show the first rdn */
     rdn = sudo_ldap_get_first_rdn(ld, entry);
@@ -1624,7 +1769,7 @@ sudo_ldap_display_entry_long(LDAP *ld, LDAPMessage *entry, struct lbuf *lbuf)
        ldap_value_free_len(bv);
     }
 
-    return count;
+    debug_return_int(count);
 }
 
 /*
@@ -1639,6 +1784,7 @@ sudo_ldap_display_privs(struct sudo_nss *nss, struct passwd *pw,
     struct ldap_result *lres;
     LDAPMessage *entry;
     int i, count = 0;
+    debug_decl(sudo_ldap_display_privs, SUDO_DEBUG_LDAP)
 
     if (handle == NULL || handle->ld == NULL)
        goto done;
@@ -1657,7 +1803,7 @@ sudo_ldap_display_privs(struct sudo_nss *nss, struct passwd *pw,
     }
 
 done:
-    return count;
+    debug_return_int(count);
 }
 
 static int
@@ -1667,7 +1813,9 @@ sudo_ldap_display_cmnd(struct sudo_nss *nss, struct passwd *pw)
     LDAP *ld;
     struct ldap_result *lres;
     LDAPMessage *entry;
-    int i, found = FALSE;
+    bool found = false;
+    int i;
+    debug_decl(sudo_ldap_display_cmnd, SUDO_DEBUG_LDAP)
 
     if (handle == NULL || handle->ld == NULL)
        goto done;
@@ -1683,7 +1831,7 @@ sudo_ldap_display_cmnd(struct sudo_nss *nss, struct passwd *pw)
        entry = lres->entries[i].entry;
        if (sudo_ldap_check_command(ld, entry, NULL) &&
            sudo_ldap_check_runas(ld, entry)) {
-           found = TRUE;
+           found = true;
            goto done;
        }
     }
@@ -1692,7 +1840,7 @@ done:
     if (found)
        printf("%s%s%s\n", safe_cmnd ? safe_cmnd : user_cmnd,
            user_args ? " " : "", user_args ? user_args : "");
-   return !found;
+   debug_return_bool(!found);
 }
 
 #ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S
@@ -1702,10 +1850,11 @@ sudo_ldap_sasl_interact(LDAP *ld, unsigned int flags, void *_auth_id,
 {
     char *auth_id = (char *)_auth_id;
     sasl_interact_t *interact = (sasl_interact_t *)_interact;
+    debug_decl(sudo_ldap_sasl_interact, SUDO_DEBUG_LDAP)
 
     for (; interact->id != SASL_CB_LIST_END; interact++) {
        if (interact->id != SASL_CB_USER)
-           return LDAP_PARAM_ERROR;
+           debug_return_int(LDAP_PARAM_ERROR);
 
        if (auth_id != NULL)
            interact->result = auth_id;
@@ -1719,7 +1868,7 @@ sudo_ldap_sasl_interact(LDAP *ld, unsigned int flags, void *_auth_id,
        interact->result = estrdup(interact->result);
 #endif /* SASL_VERSION_MAJOR < 2 */
     }
-    return LDAP_SUCCESS;
+    debug_return_int(LDAP_SUCCESS);
 }
 #endif /* HAVE_LDAP_SASL_INTERACTIVE_BIND_S */
 
@@ -1731,6 +1880,7 @@ sudo_ldap_set_options(LDAP *ld)
 {
     struct ldap_config_table *cur;
     int rc;
+    debug_decl(sudo_ldap_set_options, SUDO_DEBUG_LDAP)
 
     /* Set ber options */
 #ifdef LBER_OPT_DEBUG_LEVEL
@@ -1757,7 +1907,7 @@ sudo_ldap_set_options(LDAP *ld)
                if (rc != LDAP_OPT_SUCCESS) {
                    warningx("ldap_set_option: %s -> %d: %s",
                        cur->conf_str, ival, ldap_err2string(rc));
-                   return -1;
+                   debug_return_int(-1);
                }
                DPRINTF(("ldap_set_option: %s -> %d", cur->conf_str, ival), 1);
            }
@@ -1769,7 +1919,7 @@ sudo_ldap_set_options(LDAP *ld)
                if (rc != LDAP_OPT_SUCCESS) {
                    warningx("ldap_set_option: %s -> %s: %s",
                        cur->conf_str, sval, ldap_err2string(rc));
-                   return -1;
+                   debug_return_int(-1);
                }
                DPRINTF(("ldap_set_option: %s -> %s", cur->conf_str, sval), 1);
            }
@@ -1787,7 +1937,7 @@ sudo_ldap_set_options(LDAP *ld)
        if (rc != LDAP_OPT_SUCCESS) {
            warningx("ldap_set_option(TIMEOUT, %ld): %s",
                (long)tv.tv_sec, ldap_err2string(rc));
-           return -1;
+           debug_return_int(-1);
        }
        DPRINTF(("ldap_set_option(LDAP_OPT_TIMEOUT, %ld)",
            (long)tv.tv_sec), 1);
@@ -1803,7 +1953,7 @@ sudo_ldap_set_options(LDAP *ld)
        if (rc != LDAP_OPT_SUCCESS) {
            warningx("ldap_set_option(NETWORK_TIMEOUT, %ld): %s",
                (long)tv.tv_sec, ldap_err2string(rc));
-           return -1;
+           debug_return_int(-1);
        }
        DPRINTF(("ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT, %ld)",
            (long)tv.tv_sec), 1);
@@ -1817,12 +1967,12 @@ sudo_ldap_set_options(LDAP *ld)
        if (rc != LDAP_SUCCESS) {
            warningx("ldap_set_option(LDAP_OPT_X_TLS, LDAP_OPT_X_TLS_HARD): %s",
                ldap_err2string(rc));
-           return -1;
+           debug_return_int(-1);
        }
        DPRINTF(("ldap_set_option(LDAP_OPT_X_TLS, LDAP_OPT_X_TLS_HARD)"), 1);
     }
 #endif
-    return 0;
+    debug_return_int(0);
 }
 
 /*
@@ -1832,15 +1982,16 @@ static struct ldap_result *
 sudo_ldap_result_alloc(void)
 {
     struct ldap_result *result;
+    debug_decl(sudo_ldap_result_alloc, SUDO_DEBUG_LDAP)
 
     result = emalloc(sizeof(*result));
     result->searches = NULL;
     result->nentries = 0;
     result->entries = NULL;
     result->allocated_entries = 0;
-    result->user_matches = FALSE;
-    result->host_matches = FALSE;
-    return result;
+    result->user_matches = false;
+    result->host_matches = false;
+    debug_return_ptr(result);
 }
 
 /*
@@ -1850,6 +2001,7 @@ static void
 sudo_ldap_result_free(struct ldap_result *lres)
 {
     struct ldap_search_list *s;
+    debug_decl(sudo_ldap_result_free, SUDO_DEBUG_LDAP)
 
     if (lres != NULL) {
        if (lres->nentries) {
@@ -1865,6 +2017,7 @@ sudo_ldap_result_free(struct ldap_result *lres)
        }
        efree(lres);
     }
+    debug_return;
 }
 
 /*
@@ -1875,6 +2028,7 @@ sudo_ldap_result_add_search(struct ldap_result *lres, LDAP *ldap,
     LDAPMessage *searchresult)
 {
     struct ldap_search_list *s, *news;
+    debug_decl(sudo_ldap_result_add_search, SUDO_DEBUG_LDAP)
 
     news = emalloc(sizeof(struct ldap_search_list));
     news->next = NULL;
@@ -1889,7 +2043,7 @@ sudo_ldap_result_add_search(struct ldap_result *lres, LDAP *ldap,
     } else {
        lres->searches = news;
     }
-    return news;
+    debug_return_ptr(news);
 }
 
 /*
@@ -1905,10 +2059,11 @@ sudo_ldap_bind_s(LDAP *ld)
     unsigned int status;
 # endif
 #endif
+    debug_decl(sudo_ldap_bind_s, SUDO_DEBUG_LDAP)
 
 #ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S
-    if (ldap_conf.rootuse_sasl == TRUE ||
-       (ldap_conf.rootuse_sasl != FALSE && ldap_conf.use_sasl == TRUE)) {
+    if (ldap_conf.rootuse_sasl == true ||
+       (ldap_conf.rootuse_sasl != false && ldap_conf.use_sasl == true)) {
        void *auth_id = ldap_conf.rootsasl_auth_id ?
            ldap_conf.rootsasl_auth_id : ldap_conf.sasl_auth_id;
 
@@ -1920,7 +2075,7 @@ sudo_ldap_bind_s(LDAP *ld)
                DPRINTF(("gss_krb5_ccache_name() failed: %d", status), 1);
            }
 # else
-           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",
@@ -1931,7 +2086,7 @@ sudo_ldap_bind_s(LDAP *ld)
                    DPRINTF(("gss_krb5_ccache_name() failed: %d", status), 1);
 # else
            if (old_ccname != NULL)
-               setenv("KRB5CCNAME", old_ccname, TRUE);
+               setenv("KRB5CCNAME", old_ccname, true);
            else
                unsetenv("KRB5CCNAME");
 # endif
@@ -1939,7 +2094,7 @@ sudo_ldap_bind_s(LDAP *ld)
        if (rc != LDAP_SUCCESS) {
            warningx("ldap_sasl_interactive_bind_s(): %s",
                ldap_err2string(rc));
-           return -1;
+           debug_return_int(-1);
        }
        DPRINTF(("ldap_sasl_interactive_bind_s() ok"), 1);
     } else
@@ -1955,7 +2110,7 @@ sudo_ldap_bind_s(LDAP *ld)
            NULL, NULL, NULL);
        if (rc != LDAP_SUCCESS) {
            warningx("ldap_sasl_bind_s(): %s", ldap_err2string(rc));
-           return -1;
+           debug_return_int(-1);
        }
        DPRINTF(("ldap_sasl_bind_s() ok"), 1);
     }
@@ -1964,12 +2119,12 @@ sudo_ldap_bind_s(LDAP *ld)
        rc = ldap_simple_bind_s(ld, ldap_conf.binddn, ldap_conf.bindpw);
        if (rc != LDAP_SUCCESS) {
            warningx("ldap_simple_bind_s(): %s", ldap_err2string(rc));
-           return -1;
+           debug_return_int(-1);
        }
        DPRINTF(("ldap_simple_bind_s() ok"), 1);
     }
 #endif
-    return 0;
+    debug_return_int(0);
 }
 
 /*
@@ -1980,16 +2135,18 @@ static int
 sudo_ldap_open(struct sudo_nss *nss)
 {
     LDAP *ld;
-    int rc, ldapnoinit = FALSE;
-    struct sudo_ldap_handle    *handle;
+    int rc;
+    bool ldapnoinit = false;
+    struct sudo_ldap_handle *handle;
+    debug_decl(sudo_ldap_open, SUDO_DEBUG_LDAP)
 
     if (!sudo_ldap_read_config())
-       return -1;
+       debug_return_int(-1);
 
     /* Prevent reading of user ldaprc and system defaults. */
     if (getenv("LDAPNOINIT") == NULL) {
-       ldapnoinit = TRUE;
-       setenv("LDAPNOINIT", "1", TRUE);
+       ldapnoinit = true;
+       setenv("LDAPNOINIT", "1", true);
     }
 
     /* Connect to LDAP server */
@@ -2004,7 +2161,7 @@ sudo_ldap_open(struct sudo_nss *nss)
        rc = sudo_ldap_init(&ld, ldap_conf.host, ldap_conf.port);
     if (rc != LDAP_SUCCESS) {
        warningx(_("unable to initialize LDAP: %s"), ldap_err2string(rc));
-       return -1;
+       debug_return_int(-1);
     }
 
     if (ldapnoinit)
@@ -2012,25 +2169,25 @@ sudo_ldap_open(struct sudo_nss *nss)
 
     /* Set LDAP options */
     if (sudo_ldap_set_options(ld) < 0)
-       return -1;
+       debug_return_int(-1);
 
     if (ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS) {
 #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;
+           debug_return_int(-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;
+           debug_return_int(-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;
+           debug_return_int(-1);
        }
        DPRINTF(("ldap_start_tls_s_np() ok"), 1);
 #else
@@ -2040,7 +2197,7 @@ sudo_ldap_open(struct sudo_nss *nss)
 
     /* Actually connect */
     if (sudo_ldap_bind_s(ld) != 0)
-       return -1;
+       debug_return_int(-1);
 
     /* Create a handle container. */
     handle = emalloc(sizeof(struct sudo_ldap_handle));
@@ -2050,7 +2207,7 @@ sudo_ldap_open(struct sudo_nss *nss)
     handle->grlist = NULL;
     nss->handle = handle;
 
-    return 0;
+    debug_return_int(0);
 }
 
 static int
@@ -2063,9 +2220,10 @@ sudo_ldap_setdefs(struct sudo_nss *nss)
     LDAPMessage *entry, *result;
     char *filt;
     int rc;
+    debug_decl(sudo_ldap_setdefs, SUDO_DEBUG_LDAP)
 
     if (handle == NULL || handle->ld == NULL)
-       return -1;
+       debug_return_int(-1);
     ld = handle->ld;
 
     filt = sudo_ldap_build_default_filter();
@@ -2091,7 +2249,7 @@ sudo_ldap_setdefs(struct sudo_nss *nss)
     }
     efree(filt);
 
-    return 0;
+    debug_return_int(0);
 }
 
 /*
@@ -2105,9 +2263,10 @@ sudo_ldap_lookup(struct sudo_nss *nss, int ret, int pwflag)
     LDAPMessage *entry;
     int i, rc, setenv_implied;
     struct ldap_result *lres = NULL;
+    debug_decl(sudo_ldap_lookup, SUDO_DEBUG_LDAP)
 
     if (handle == NULL || handle->ld == NULL)
-       return ret;
+       debug_return_int(ret);
     ld = handle->ld;
 
     /* Fetch list of sudoRole entries that match user and host. */
@@ -2126,15 +2285,15 @@ sudo_ldap_lookup(struct sudo_nss *nss, int ret, int pwflag)
        DPRINTF(("perform search for pwflag %d", pwflag), 1);
        for (i = 0; i < lres->nentries; i++) {
            entry = lres->entries[i].entry;
-           if ((pwcheck == any && doauth != FALSE) ||
-               (pwcheck == all && doauth == FALSE)) {
+           if ((pwcheck == any && doauth != false) ||
+               (pwcheck == all && doauth == false)) {
                doauth = sudo_ldap_check_bool(ld, entry, "authenticate");
            }
            /* Only check the command when listing another user. */
            if (user_uid == 0 || list_pw == NULL ||
                user_uid == list_pw->pw_uid ||
                sudo_ldap_check_command(ld, entry, NULL)) {
-               matched = TRUE;
+               matched = true;
                break;
            }
        }
@@ -2148,11 +2307,11 @@ sudo_ldap_lookup(struct sudo_nss *nss, int ret, int pwflag)
                        break;
                    case all:
                    case any:
-                       if (doauth == FALSE)
-                           def_authenticate = FALSE;
+                       if (doauth == false)
+                           def_authenticate = false;
                        break;
                    case never:
-                       def_authenticate = FALSE;
+                       def_authenticate = false;
                        break;
                    default:
                        break;
@@ -2164,7 +2323,7 @@ sudo_ldap_lookup(struct sudo_nss *nss, int ret, int pwflag)
 
     DPRINTF(("searching LDAP for sudoers entries"), 1);
 
-    setenv_implied = FALSE;
+    setenv_implied = false;
     for (i = 0; i < lres->nentries; i++) {
        entry = lres->entries[i].entry;
        if (!sudo_ldap_check_runas(ld, entry))
@@ -2172,12 +2331,12 @@ sudo_ldap_lookup(struct sudo_nss *nss, int ret, int pwflag)
        rc = sudo_ldap_check_command(ld, entry, &setenv_implied);
        if (rc != UNSPEC) {
            /* We have a match. */
-           DPRINTF(("Command %sallowed", rc == TRUE ? "" : "NOT "), 1);
-           if (rc == TRUE) {
+           DPRINTF(("Command %sallowed", rc == true ? "" : "NOT "), 1);
+           if (rc == true) {
                DPRINTF(("LDAP entry: %p", entry), 1);
                /* Apply entry-specific options. */
                if (setenv_implied)
-                   def_setenv = TRUE;
+                   def_setenv = true;
                sudo_ldap_parse_options(ld, entry);
 #ifdef HAVE_SELINUX
                /* Set role and type if not specified on command line. */
@@ -2212,7 +2371,7 @@ done:
        CLR(ret, FLAG_NO_HOST);
     DPRINTF(("sudo_ldap_lookup(%d)=0x%02x", pwflag, ret), 1);
 
-    return ret;
+    debug_return_int(ret);
 }
 
 /*
@@ -2223,9 +2382,10 @@ ldap_entry_compare(const void *a, const void *b)
 {
     const struct ldap_entry_wrapper *aw = a;
     const struct ldap_entry_wrapper *bw = b;
+    debug_decl(ldap_entry_compare, SUDO_DEBUG_LDAP)
 
-    return bw->order < aw->order ? -1 :
-       (bw->order > aw->order ? 1 : 0);
+    debug_return_int(bw->order < aw->order ? -1 :
+       (bw->order > aw->order ? 1 : 0));
 }
 
 /*
@@ -2237,12 +2397,13 @@ static struct ldap_search_list *
 sudo_ldap_result_last_search(struct ldap_result *lres)
 {
     struct ldap_search_list *result = lres->searches;
+    debug_decl(sudo_ldap_result_last_search, SUDO_DEBUG_LDAP)
 
     if (result) {
        while (result->next)
            result = result->next;
     }
-    return result;
+    debug_return_ptr(result);
 }
 
 /*
@@ -2255,6 +2416,7 @@ sudo_ldap_result_add_entry(struct ldap_result *lres, LDAPMessage *entry)
     struct berval **bv;
     double order = 0.0;
     char *ep;
+    debug_decl(sudo_ldap_result_add_entry, SUDO_DEBUG_LDAP)
 
     /* Determine whether the entry has the sudoOrder attribute. */
     last = sudo_ldap_result_last_search(lres);
@@ -2287,7 +2449,7 @@ sudo_ldap_result_add_entry(struct ldap_result *lres, LDAPMessage *entry)
     lres->entries[lres->nentries - 1].entry = entry;
     lres->entries[lres->nentries - 1].order = order;
 
-    return &lres->entries[lres->nentries - 1];
+    debug_return_ptr(&lres->entries[lres->nentries - 1]);
 }
 
 /*
@@ -2297,6 +2459,7 @@ static void
 sudo_ldap_result_free_nss(struct sudo_nss *nss)
 {
     struct sudo_ldap_handle *handle = nss->handle;
+    debug_decl(sudo_ldap_result_free_nss, SUDO_DEBUG_LDAP)
 
     if (handle->result != NULL) {
        DPRINTF(("removing reusable search result"), 1);
@@ -2308,6 +2471,7 @@ sudo_ldap_result_free_nss(struct sudo_nss *nss)
        handle->grlist = NULL;
        handle->result = NULL;
     }
+    debug_return;
 }
 
 /*
@@ -2325,6 +2489,7 @@ sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw)
     LDAP *ld = handle->ld;
     int do_netgr, rc;
     char *filt;
+    debug_decl(sudo_ldap_result_get, SUDO_DEBUG_LDAP)
 
     /*
      * If we already have a cached result, return it so we don't have to
@@ -2335,7 +2500,7 @@ sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw)
            strcmp(pw->pw_name, handle->username) == 0) {
            DPRINTF(("reusing previous result (user %s) with %d entries",
                handle->username, handle->result->nentries), 1);
-           return handle->result;
+           debug_return_ptr(handle->result);
        }
        /* User mismatch, cached result cannot be used. */
        DPRINTF(("removing result (user %s), new search (user %s)",
@@ -2379,7 +2544,7 @@ sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw)
                DPRINTF(("nothing found for '%s'", filt), 1);
                continue;
            }
-           lres->user_matches = TRUE;
+           lres->user_matches = true;
 
            /* Add the seach result to list of search results. */
            DPRINTF(("adding search result"), 1);
@@ -2388,7 +2553,7 @@ sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw)
                if ((!do_netgr ||
                    sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name)) &&
                    sudo_ldap_check_host(ld, entry)) {
-                   lres->host_matches = TRUE;
+                   lres->host_matches = true;
                    sudo_ldap_result_add_entry(lres, entry);
                }
            }
@@ -2407,7 +2572,7 @@ sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw)
     handle->username = estrdup(pw->pw_name);
     handle->grlist = user_group_list;
 
-    return lres;
+    debug_return_ptr(lres);
 }
 
 /*
@@ -2417,6 +2582,7 @@ static int
 sudo_ldap_close(struct sudo_nss *nss)
 {
     struct sudo_ldap_handle *handle = nss->handle;
+    debug_decl(sudo_ldap_close, SUDO_DEBUG_LDAP)
 
     if (handle != NULL) {
        /* Free the result before unbinding; it may use the LDAP connection. */
@@ -2432,7 +2598,7 @@ sudo_ldap_close(struct sudo_nss *nss)
        efree(nss->handle);
        nss->handle = NULL;
     }
-    return 0;
+    debug_return_int(0);
 }
 
 /*
index e8e25aab287ab3b46048797fc3c15fe84af38ce3..71f9e5e73526f274d0c9f495b225d1b5a776be36 100644 (file)
 #include "error.h"
 #include "alloc.h"
 #include "gettext.h"
+#include "sudo_debug.h"
 #include "linux_audit.h"
 
 /*
  * Open audit connection if possible.
  * Returns audit fd on success and -1 on failure.
  */
-static int
-linux_audit_open(void)
+int
+static linux_audit_open(void)
 {
     static int au_fd = -1;
+    debug_decl(linux_audit_open, SUDO_DEBUG_AUDIT)
 
     if (au_fd != -1)
-       return au_fd;
+       debug_return_int(au_fd);
     au_fd = audit_open();
     if (au_fd == -1) {
        /* Kernel may not have audit support. */
@@ -56,7 +58,7 @@ linux_audit_open(void)
     } else {
        (void)fcntl(au_fd, F_SETFD, FD_CLOEXEC);
     }
-    return au_fd;
+    debug_return_int(au_fd);
 }
 
 int
@@ -65,9 +67,10 @@ linux_audit_command(char *argv[], int result)
     int au_fd, rc;
     char *command, *cp, **av;
     size_t size, n;
+    debug_decl(linux_audit_command, SUDO_DEBUG_AUDIT)
 
     if ((au_fd = linux_audit_open()) == -1)
-       return -1;
+       debug_return_int(-1);
 
     /* Convert argv to a flat string. */
     for (size = 0, av = argv; *av != NULL; av++)
@@ -89,5 +92,5 @@ linux_audit_command(char *argv[], int result)
 
     efree(command);
 
-    return rc;
+    debug_return_int(rc);
 }
index 35d6a00fd2d47909652258d2d4e5b9793e9efb29..395f83b41f8b517ed84eb5e885c0270e473686ec 100644 (file)
@@ -91,6 +91,7 @@ mysyslog(int pri, const char *fmt, ...)
 #endif
     char buf[MAXSYSLOGLEN+1];
     va_list ap;
+    debug_decl(mysyslog, SUDO_DEBUG_LOGGING)
 
     va_start(ap, fmt);
 #ifdef LOG_NFACILITIES
@@ -113,6 +114,7 @@ mysyslog(int pri, const char *fmt, ...)
 #endif /* BROKEN_SYSLOG */
     va_end(ap);
     closelog();
+    debug_return;
 }
 
 #define FMT_FIRST "%8s : %s"
@@ -128,6 +130,7 @@ do_syslog(int pri, char *msg)
     size_t len, maxlen;
     char *p, *tmp, save;
     const char *fmt;
+    debug_decl(do_syslog, SUDO_DEBUG_LOGGING)
 
 #ifdef HAVE_SETLOCALE
     const char *old_locale = estrdup(setlocale(LC_ALL, NULL));
@@ -174,6 +177,8 @@ do_syslog(int pri, char *msg)
     setlocale(LC_ALL, old_locale);
     efree((void *)old_locale);
 #endif /* HAVE_SETLOCALE */
+
+    debug_return;
 }
 
 static void
@@ -184,6 +189,7 @@ do_logfile(char *msg)
     mode_t oldmask;
     time_t now;
     FILE *fp;
+    debug_decl(do_logfile, SUDO_DEBUG_LOGGING)
 
     oldmask = umask(077);
     fp = fopen(def_logfile, "a");
@@ -233,6 +239,7 @@ do_logfile(char *msg)
        efree((void *)old_locale);
 #endif /* HAVE_SETLOCALE */
     }
+    debug_return;
 }
 
 /*
@@ -241,8 +248,8 @@ do_logfile(char *msg)
 void
 log_denial(int status, int inform_user)
 {
-    char *message;
-    char *logline;
+    char *logline, *message;
+    debug_decl(log_denial, SUDO_DEBUG_LOGGING)
 
     /* Set error message. */
     if (ISSET(status, FLAG_NO_USER))
@@ -289,6 +296,7 @@ log_denial(int status, int inform_user)
        do_logfile(logline);
 
     efree(logline);
+    debug_return;
 }
 
 /*
@@ -298,6 +306,7 @@ void
 log_allowed(int status)
 {
     char *logline;
+    debug_decl(log_allowed, SUDO_DEBUG_LOGGING)
 
     logline = new_logline(NULL, 0);
 
@@ -313,15 +322,16 @@ log_allowed(int status)
        do_logfile(logline);
 
     efree(logline);
+    debug_return;
 }
 
 void
 log_error(int flags, const char *fmt, ...)
 {
     int serrno = errno;
-    char *message;
-    char *logline;
+    char *logline, *message;
     va_list ap;
+    debug_decl(log_error, SUDO_DEBUG_LOGGING)
 
     /* Expand printf-style format + args. */
     va_start(ap, fmt);
@@ -370,6 +380,7 @@ log_error(int flags, const char *fmt, ...)
        plugin_cleanup(0);
        siglongjmp(error_jmp, 1);
     }
+    debug_return;
 }
 
 #define MAX_MAILFLAGS  63
@@ -396,10 +407,11 @@ send_mail(const char *fmt, ...)
        NULL
     };
 #endif /* NO_ROOT_MAILER */
+    debug_decl(send_mail, SUDO_DEBUG_LOGGING)
 
     /* Just return if mailer is disabled. */
     if (!def_mailerpath || !def_mailto)
-       return;
+       debug_return;
 
     /* Fork and return, child will daemonize. */
     switch (pid = fork()) {
@@ -413,6 +425,8 @@ send_mail(const char *fmt, ...)
                case -1:
                    /* Error. */
                    mysyslog(LOG_ERR, _("unable to fork: %m"));
+                   sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to fork: %s",
+                       strerror(errno));
                    _exit(1);
                case 0:
                    /* Grandchild continues below. */
@@ -427,7 +441,7 @@ send_mail(const char *fmt, ...)
            do {
                rv = waitpid(pid, &status, 0);
            } while (rv == -1 && errno == EINTR);
-           return;
+           return; /* not debug */
     }
 
     /* Daemonize - disassociate from session/tty. */
@@ -463,6 +477,9 @@ send_mail(const char *fmt, ...)
 
     if (pipe(pfd) == -1) {
        mysyslog(LOG_ERR, _("unable to open pipe: %m"));
+       sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to open pipe: %s",
+           strerror(errno));
+       sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
        _exit(1);
     }
 
@@ -470,6 +487,9 @@ send_mail(const char *fmt, ...)
        case -1:
            /* Error. */
            mysyslog(LOG_ERR, _("unable to fork: %m"));
+           sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to fork: %s",
+               strerror(errno));
+           sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
            _exit(1);
            break;
        case 0:
@@ -482,6 +502,8 @@ send_mail(const char *fmt, ...)
                if (pfd[0] != STDIN_FILENO) {
                    if (dup2(pfd[0], STDIN_FILENO) == -1) {
                        mysyslog(LOG_ERR, _("unable to dup stdin: %m"));
+                       sudo_debug_printf(SUDO_DEBUG_ERROR,
+                           "unable to dup stdin: %s", strerror(errno));
                        _exit(127);
                    }
                    (void) close(pfd[0]);
@@ -516,6 +538,8 @@ send_mail(const char *fmt, ...)
                execv(mpath, argv);
 #endif /* NO_ROOT_MAILER */
                mysyslog(LOG_ERR, _("unable to execute %s: %m"), mpath);
+               sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to execute %s: %s",
+                   mpath, strerror(errno));
                _exit(127);
            }
            break;
@@ -561,6 +585,7 @@ send_mail(const char *fmt, ...)
     do {
         rv = waitpid(pid, &status, 0);
     } while (rv == -1 && errno == EINTR);
+    sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
     _exit(0);
 }
 
@@ -570,11 +595,12 @@ send_mail(const char *fmt, ...)
 static int
 should_mail(int status)
 {
+    debug_decl(should_mail, SUDO_DEBUG_LOGGING)
 
-    return def_mail_always || ISSET(status, VALIDATE_ERROR) ||
+    debug_return_bool(def_mail_always || ISSET(status, VALIDATE_ERROR) ||
        (def_mail_no_user && ISSET(status, FLAG_NO_USER)) ||
        (def_mail_no_host && ISSET(status, FLAG_NO_HOST)) ||
-       (def_mail_no_perms && !ISSET(status, VALIDATE_OK));
+       (def_mail_no_perms && !ISSET(status, VALIDATE_OK)));
 }
 
 #define        LL_TTY_STR      "TTY="
@@ -603,6 +629,7 @@ new_logline(const char *message, int serrno)
     char *errstr = NULL;
     char *evstr = NULL;
     char *line, sessid[7], *tsid = NULL;
+    debug_decl(new_logline, SUDO_DEBUG_LOGGING)
 
     /* A TSID may be a sudoers-style session ID or a free-form string. */
     if (sudo_user.iolog_file != NULL) {
@@ -723,7 +750,7 @@ new_logline(const char *message, int serrno)
        }
     }
 
-    return line;
+    debug_return_str(line);
 toobig:
     errorx(1, _("internal error: insufficient space for log line"));
 }
index 054b9ac1ae6b046b66819299dfaa25f21579b817..4adfc94b9a0d645dfb3b268fd3672469f70bf47a 100644 (file)
@@ -41,6 +41,7 @@ writeln_wrap(FILE *fp, char *line, size_t len, size_t maxlen)
     char *indent = "";
     char *beg = line;
     char *end;
+    debug_decl(writeln_wrap, SUDO_DEBUG_LOGGING)
 
     /*
      * Print out line with word wrap around maxlen characters.
@@ -69,4 +70,6 @@ writeln_wrap(FILE *fp, char *line, size_t len, size_t maxlen)
     /* Print remainder, if any. */
     if (len)
        fprintf(fp, "%s%s\n", indent, beg);
+
+    debug_return;
 }
index b0ff377fc645912f43f6431e41f45dcaaedeadd2..0fcf57dc0ec5b039fdfe8a2966a73d84cfa167ec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1998-2005, 2007-2011
+ * Copyright (c) 1996, 1998-2005, 2007-2012
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
 
 static struct member_list empty;
 
-static int command_matches_dir(char *, size_t);
-static int command_matches_glob(char *, char *);
-static int command_matches_fnmatch(char *, char *);
-static int command_matches_normal(char *, char *);
+static bool command_matches_dir(char *, size_t);
+static bool command_matches_glob(char *, char *);
+static bool command_matches_fnmatch(char *, char *);
+static bool command_matches_normal(char *, char *);
 
 /*
- * Returns TRUE if string 's' contains meta characters.
+ * Returns true if string 's' contains meta characters.
  */
 #define has_meta(s)    (strpbrk(s, "\\?*[]") != NULL)
 
@@ -107,6 +107,7 @@ _userlist_matches(struct passwd *pw, struct member_list *list)
     struct member *m;
     struct alias *a;
     int rval, matched = UNSPEC;
+    debug_decl(_userlist_matches, SUDO_DEBUG_MATCH)
 
     tq_foreach_rev(list, m) {
        switch (m->type) {
@@ -137,7 +138,7 @@ _userlist_matches(struct passwd *pw, struct member_list *list)
        if (matched != UNSPEC)
            break;
     }
-    return matched;
+    debug_return_bool(matched);
 }
 
 int
@@ -160,11 +161,12 @@ _runaslist_matches(struct member_list *user_list, struct member_list *group_list
     int rval;
     int user_matched = UNSPEC;
     int group_matched = UNSPEC;
+    debug_decl(_runaslist_matches, SUDO_DEBUG_MATCH)
 
     if (runas_pw != NULL) {
        /* If no runas user or runas group listed in sudoers, use default. */
        if (tq_empty(user_list) && tq_empty(group_list))
-           return userpw_matches(def_runas_default, runas_pw->pw_name, runas_pw);
+           debug_return_int(userpw_matches(def_runas_default, runas_pw->pw_name, runas_pw));
 
        tq_foreach_rev(user_list, m) {
            switch (m->type) {
@@ -230,10 +232,10 @@ _runaslist_matches(struct member_list *user_list, struct member_list *group_list
     }
 
     if (user_matched == DENY || group_matched == DENY)
-       return DENY;
+       debug_return_int(DENY);
     if (user_matched == group_matched || runas_gr == NULL)
-       return user_matched;
-    return UNSPEC;
+       debug_return_int(user_matched);
+    debug_return_int(UNSPEC);
 }
 
 int
@@ -254,6 +256,7 @@ _hostlist_matches(struct member_list *list)
     struct member *m;
     struct alias *a;
     int rval, matched = UNSPEC;
+    debug_decl(_hostlist_matches, SUDO_DEBUG_MATCH)
 
     tq_foreach_rev(list, m) {
        switch (m->type) {
@@ -284,7 +287,7 @@ _hostlist_matches(struct member_list *list)
        if (matched != UNSPEC)
            break;
     }
-    return matched;
+    debug_return_bool(matched);
 }
 
 int
@@ -303,13 +306,14 @@ _cmndlist_matches(struct member_list *list)
 {
     struct member *m;
     int matched = UNSPEC;
+    debug_decl(_cmndlist_matches, SUDO_DEBUG_MATCH)
 
     tq_foreach_rev(list, m) {
        matched = cmnd_matches(m);
        if (matched != UNSPEC)
            break;
     }
-    return matched;
+    debug_return_bool(matched);
 }
 
 int
@@ -329,6 +333,7 @@ cmnd_matches(struct member *m)
     struct alias *a;
     struct sudo_command *c;
     int rval, matched = UNSPEC;
+    debug_decl(cmnd_matches, SUDO_DEBUG_MATCH)
 
     switch (m->type) {
        case ALL:
@@ -348,15 +353,16 @@ cmnd_matches(struct member *m)
                matched = !m->negated;
            break;
     }
-    return matched;
+    debug_return_bool(matched);
 }
 
-static int
+static bool
 command_args_match(sudoers_cmnd, sudoers_args)
     char *sudoers_cmnd;
     char *sudoers_args;
 {
     int flags = 0;
+    debug_decl(command_args_match, SUDO_DEBUG_MATCH)
 
     /*
      * If no args specified in sudoers, any user args are allowed.
@@ -364,7 +370,7 @@ command_args_match(sudoers_cmnd, sudoers_args)
      */
     if (!sudoers_args ||
        (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args)))
-       return TRUE;
+       debug_return_bool(true);
     /*
      * If args are specified in sudoers, they must match the user args.
      * If running as sudoedit, all args are assumed to be paths.
@@ -374,18 +380,20 @@ command_args_match(sudoers_cmnd, sudoers_args)
        if (strcmp(sudoers_cmnd, "sudoedit") == 0)
            flags = FNM_PATHNAME;
        if (fnmatch(sudoers_args, user_args ? user_args : "", flags) == 0)
-           return TRUE;
+           debug_return_bool(true);
     }
-    return FALSE;
+    debug_return_bool(false);
 }
 
 /*
- * If path doesn't end in /, return TRUE iff cmnd & path name the same inode;
- * otherwise, return TRUE if user_cmnd names one of the inodes in path.
+ * If path doesn't end in /, return true iff cmnd & path name the same inode;
+ * otherwise, return true if user_cmnd names one of the inodes in path.
  */
-int
+bool
 command_matches(char *sudoers_cmnd, char *sudoers_args)
 {
+    debug_decl(command_matches, SUDO_DEBUG_MATCH)
+
     /* Check for pseudo-commands */
     if (sudoers_cmnd[0] != '/') {
        /*
@@ -396,13 +404,13 @@ command_matches(char *sudoers_cmnd, char *sudoers_args)
         */
        if (strcmp(sudoers_cmnd, "sudoedit") != 0 ||
            strcmp(user_cmnd, "sudoedit") != 0)
-           return FALSE;
+           debug_return_bool(false);
        if (command_args_match(sudoers_cmnd, sudoers_args)) {
            efree(safe_cmnd);
            safe_cmnd = estrdup(sudoers_cmnd);
-           return TRUE;
+           debug_return_bool(true);
        } else
-           return FALSE;
+           debug_return_bool(false);
     }
 
     if (has_meta(sudoers_cmnd)) {
@@ -411,15 +419,17 @@ command_matches(char *sudoers_cmnd, char *sudoers_args)
         * use glob(3) and/or fnmatch(3) to do the matching.
         */
        if (def_fast_glob)
-           return command_matches_fnmatch(sudoers_cmnd, sudoers_args);
-       return command_matches_glob(sudoers_cmnd, sudoers_args);
+           debug_return_bool(command_matches_fnmatch(sudoers_cmnd, sudoers_args));
+       debug_return_bool(command_matches_glob(sudoers_cmnd, sudoers_args));
     }
-    return command_matches_normal(sudoers_cmnd, sudoers_args);
+    debug_return_bool(command_matches_normal(sudoers_cmnd, sudoers_args));
 }
 
-static int
+static bool
 command_matches_fnmatch(char *sudoers_cmnd, char *sudoers_args)
 {
+    debug_decl(command_matches_fnmatch, SUDO_DEBUG_MATCH)
+
     /*
      * Return true if fnmatch(3) succeeds AND
      *  a) there are no args in sudoers OR
@@ -428,23 +438,24 @@ command_matches_fnmatch(char *sudoers_cmnd, char *sudoers_args)
      * else return false.
      */
     if (fnmatch(sudoers_cmnd, user_cmnd, FNM_PATHNAME) != 0)
-       return FALSE;
+       debug_return_bool(false);
     if (command_args_match(sudoers_cmnd, sudoers_args)) {
        if (safe_cmnd)
            free(safe_cmnd);
        safe_cmnd = estrdup(user_cmnd);
-       return TRUE;
-    } else
-       return FALSE;
+       debug_return_bool(true);
+    }
+    debug_return_bool(false);
 }
 
-static int
+static bool
 command_matches_glob(char *sudoers_cmnd, char *sudoers_args)
 {
     struct stat sudoers_stat;
     size_t dlen;
     char **ap, *base, *cp;
     glob_t gl;
+    debug_decl(command_matches_glob, SUDO_DEBUG_MATCH)
 
     /*
      * First check to see if we can avoid the call to glob(3).
@@ -456,7 +467,7 @@ command_matches_glob(char *sudoers_cmnd, char *sudoers_args)
        if ((base = strrchr(sudoers_cmnd, '/')) != NULL) {
            base++;
            if (!has_meta(base) && strcmp(user_base, base) != 0)
-               return FALSE;
+               debug_return_bool(false);
        }
     }
     /*
@@ -466,10 +477,10 @@ command_matches_glob(char *sudoers_cmnd, char *sudoers_args)
      *  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)
+#define GLOB_FLAGS     (GLOB_NOSORT | GLOB_BRACE | GLOB_TILDE)
     if (glob(sudoers_cmnd, GLOB_FLAGS, NULL, &gl) != 0 || gl.gl_pathc == 0) {
        globfree(&gl);
-       return FALSE;
+       debug_return_bool(false);
     }
     /* For each glob match, compare basename, st_dev and st_ino. */
     for (ap = gl.gl_pathv; (cp = *ap) != NULL; ap++) {
@@ -477,7 +488,7 @@ command_matches_glob(char *sudoers_cmnd, char *sudoers_args)
        dlen = strlen(cp);
        if (cp[dlen - 1] == '/') {
            if (command_matches_dir(cp, dlen))
-               return TRUE;
+               debug_return_bool(true);
            continue;
        }
 
@@ -499,27 +510,28 @@ command_matches_glob(char *sudoers_cmnd, char *sudoers_args)
     }
     globfree(&gl);
     if (cp == NULL)
-       return FALSE;
+       debug_return_bool(false);
 
     if (command_args_match(sudoers_cmnd, sudoers_args)) {
        efree(safe_cmnd);
        safe_cmnd = estrdup(user_cmnd);
-       return TRUE;
+       debug_return_bool(true);
     }
-    return FALSE;
+    debug_return_bool(false);
 }
 
-static int
+static bool
 command_matches_normal(char *sudoers_cmnd, char *sudoers_args)
 {
     struct stat sudoers_stat;
     char *base;
     size_t dlen;
+    debug_decl(command_matches_normal, SUDO_DEBUG_MATCH)
 
     /* 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);
+       debug_return_bool(command_matches_dir(sudoers_cmnd, dlen));
 
     /* Only proceed if user_base and basename(sudoers_cmnd) match */
     if ((base = strrchr(sudoers_cmnd, '/')) == NULL)
@@ -528,7 +540,7 @@ command_matches_normal(char *sudoers_cmnd, char *sudoers_args)
        base++;
     if (strcmp(user_base, base) != 0 ||
        stat(sudoers_cmnd, &sudoers_stat) == -1)
-       return FALSE;
+       debug_return_bool(false);
 
     /*
      * Return true if inode/device matches AND
@@ -539,36 +551,37 @@ command_matches_normal(char *sudoers_cmnd, char *sudoers_args)
     if (user_stat != NULL &&
        (user_stat->st_dev != sudoers_stat.st_dev ||
        user_stat->st_ino != sudoers_stat.st_ino))
-       return FALSE;
+       debug_return_bool(false);
     if (command_args_match(sudoers_cmnd, sudoers_args)) {
        efree(safe_cmnd);
        safe_cmnd = estrdup(sudoers_cmnd);
-       return TRUE;
+       debug_return_bool(true);
     }
-    return FALSE;
+    debug_return_bool(false);
 }
 
 /*
- * Return TRUE if user_cmnd names one of the inodes in dir, else FALSE.
+ * Return true if user_cmnd names one of the inodes in dir, else false.
  */
-static int
+static bool
 command_matches_dir(char *sudoers_dir, size_t dlen)
 {
     struct stat sudoers_stat;
     struct dirent *dent;
     char buf[PATH_MAX];
     DIR *dirp;
+    debug_decl(command_matches_dir, SUDO_DEBUG_MATCH)
 
     /*
      * Grot through directory entries, looking for user_base.
      */
     dirp = opendir(sudoers_dir);
     if (dirp == NULL)
-       return FALSE;
+       debug_return_bool(false);
 
     if (strlcpy(buf, sudoers_dir, sizeof(buf)) >= sizeof(buf)) {
        closedir(dirp);
-       return FALSE;
+       debug_return_bool(false);
     }
     while ((dent = readdir(dirp)) != NULL) {
        /* ignore paths > PATH_MAX (XXX - log) */
@@ -590,67 +603,74 @@ command_matches_dir(char *sudoers_dir, size_t dlen)
     }
 
     closedir(dirp);
-    return dent != NULL;
+    debug_return_bool(dent != NULL);
 }
 
 /*
- * Returns TRUE if the hostname matches the pattern, else FALSE
+ * Returns true if the hostname matches the pattern, else false
  */
-int
+bool
 hostname_matches(char *shost, char *lhost, char *pattern)
 {
+    debug_decl(hostname_matches, SUDO_DEBUG_MATCH)
+
     if (has_meta(pattern)) {
        if (strchr(pattern, '.'))
-           return !fnmatch(pattern, lhost, FNM_CASEFOLD);
+           debug_return_bool(!fnmatch(pattern, lhost, FNM_CASEFOLD));
        else
-           return !fnmatch(pattern, shost, FNM_CASEFOLD);
+           debug_return_bool(!fnmatch(pattern, shost, FNM_CASEFOLD));
     } else {
        if (strchr(pattern, '.'))
-           return !strcasecmp(lhost, pattern);
+           debug_return_bool(!strcasecmp(lhost, pattern));
        else
-           return !strcasecmp(shost, pattern);
+           debug_return_bool(!strcasecmp(shost, pattern));
     }
 }
 
 /*
- *  Returns TRUE if the user/uid from sudoers matches the specified user/uid,
- *  else returns FALSE.
+ *  Returns true if the user/uid from sudoers matches the specified user/uid,
+ *  else returns false.
  */
-int
+bool
 userpw_matches(char *sudoers_user, char *user, struct passwd *pw)
 {
+    debug_decl(userpw_matches, SUDO_DEBUG_MATCH)
+
     if (pw != NULL && *sudoers_user == '#') {
        uid_t uid = (uid_t) atoi(sudoers_user + 1);
        if (uid == pw->pw_uid)
-           return TRUE;
+           debug_return_bool(true);
     }
-    return strcmp(sudoers_user, user) == 0;
+    debug_return_bool(strcmp(sudoers_user, user) == 0);
 }
 
 /*
- *  Returns TRUE if the group/gid from sudoers matches the specified group/gid,
- *  else returns FALSE.
+ *  Returns true if the group/gid from sudoers matches the specified group/gid,
+ *  else returns false.
  */
-int
+bool
 group_matches(char *sudoers_group, struct group *gr)
 {
+    debug_decl(group_matches, SUDO_DEBUG_MATCH)
+
     if (*sudoers_group == '#') {
        gid_t gid = (gid_t) atoi(sudoers_group + 1);
        if (gid == gr->gr_gid)
-           return TRUE;
+           debug_return_bool(true);
     }
-    return strcmp(gr->gr_name, sudoers_group) == 0;
+    debug_return_bool(strcmp(gr->gr_name, sudoers_group) == 0);
 }
 
 /*
- *  Returns TRUE if the given user belongs to the named group,
- *  else returns FALSE.
+ *  Returns true if the given user belongs to the named group,
+ *  else returns false.
  */
-int
+bool
 usergr_matches(char *group, char *user, struct passwd *pw)
 {
-    int matched = FALSE;
+    int matched = false;
     struct passwd *pw0 = NULL;
+    debug_decl(usergr_matches, SUDO_DEBUG_MATCH)
 
     /* make sure we have a valid usergroup, sudo style */
     if (*group++ != '%')
@@ -669,13 +689,13 @@ usergr_matches(char *group, char *user, struct passwd *pw)
     }
 
     if (user_in_group(pw, group)) {
-       matched = TRUE;
+       matched = true;
        goto done;
     }
 
     /* not a Unix group, could be an external group */
     if (def_group_plugin && group_plugin_query(user, group, pw)) {
-       matched = TRUE;
+       matched = true;
        goto done;
     }
 
@@ -683,27 +703,28 @@ done:
     if (pw0 != NULL)
        pw_delref(pw0);
 
-    return matched;
+    debug_return_bool(matched);
 }
 
 /*
- * Returns TRUE if "host" and "user" belong to the netgroup "netgr",
- * else return FALSE.  Either of "host", "shost" or "user" may be NULL
+ * Returns true if "host" and "user" belong to the netgroup "netgr",
+ * else return false.  Either of "host", "shost" or "user" may be NULL
  * in which case that argument is not checked...
  *
  * XXX - swap order of host & shost
  */
-int
+bool
 netgr_matches(char *netgr, char *lhost, char *shost, char *user)
 {
     static char *domain;
 #ifdef HAVE_GETDOMAINNAME
     static int initialized;
 #endif
+    debug_decl(netgr_matches, SUDO_DEBUG_MATCH)
 
     /* make sure we have a valid netgroup, sudo style */
     if (*netgr++ != '+')
-       return FALSE;
+       debug_return_bool(false);
 
 #ifdef HAVE_GETDOMAINNAME
     /* get the domain name (if any) */
@@ -719,10 +740,10 @@ netgr_matches(char *netgr, char *lhost, char *shost, char *user)
 
 #ifdef HAVE_INNETGR
     if (innetgr(netgr, lhost, user, domain))
-       return TRUE;
+       debug_return_bool(true);
     else if (lhost != shost && innetgr(netgr, shost, user, domain))
-       return TRUE;
+       debug_return_bool(true);
 #endif /* HAVE_INNETGR */
 
-    return FALSE;
+    debug_return_bool(false);
 }
index f4bc731504d49a91e415552a729c145a8aee5d77..9634eaca828f415954fd210b45d61f5bcc7609ae 100644 (file)
 #include "sudoers.h"
 #include "interfaces.h"
 
-static int
+static bool
 addr_matches_if(char *n)
 {
     union sudo_in_addr_un addr;
     struct interface *ifp;
-#ifdef HAVE_IN6_ADDR
+#ifdef HAVE_STRUCT_IN6_ADDR
     int j;
 #endif
     int family;
+    debug_decl(addr_matches_if, SUDO_DEBUG_MATCH)
 
-#ifdef HAVE_IN6_ADDR
+#ifdef HAVE_STRUCT_IN6_ADDR
     if (inet_pton(AF_INET6, n, &addr.ip6) > 0) {
        family = AF_INET6;
     } else
-#endif
+#endif /* HAVE_STRUCT_IN6_ADDR */
     {
        family = AF_INET;
        addr.ip4.s_addr = inet_addr(n);
@@ -78,42 +79,43 @@ addr_matches_if(char *n)
                if (ifp->addr.ip4.s_addr == addr.ip4.s_addr ||
                    (ifp->addr.ip4.s_addr & ifp->netmask.ip4.s_addr)
                    == addr.ip4.s_addr)
-                   return TRUE;
+                   debug_return_bool(true);
                break;
-#ifdef HAVE_IN6_ADDR
+#ifdef HAVE_STRUCT_IN6_ADDR
            case AF_INET6:
                if (memcmp(ifp->addr.ip6.s6_addr, addr.ip6.s6_addr,
                    sizeof(addr.ip6.s6_addr)) == 0)
-                   return TRUE;
+                   debug_return_bool(true);
                for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) {
                    if ((ifp->addr.ip6.s6_addr[j] & ifp->netmask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j])
                        break;
                }
                if (j == sizeof(addr.ip6.s6_addr))
-                   return TRUE;
-#endif
+                   debug_return_bool(true);
+#endif /* HAVE_STRUCT_IN6_ADDR */
        }
     }
 
-    return FALSE;
+    debug_return_bool(false);
 }
 
-static int
+static bool
 addr_matches_if_netmask(char *n, char *m)
 {
     int i;
     union sudo_in_addr_un addr, mask;
     struct interface *ifp;
-#ifdef HAVE_IN6_ADDR
+#ifdef HAVE_STRUCT_IN6_ADDR
     int j;
 #endif
     int family;
+    debug_decl(addr_matches_if, SUDO_DEBUG_MATCH)
 
-#ifdef HAVE_IN6_ADDR
+#ifdef HAVE_STRUCT_IN6_ADDR
     if (inet_pton(AF_INET6, n, &addr.ip6) > 0)
        family = AF_INET6;
     else
-#endif
+#endif /* HAVE_STRUCT_IN6_ADDR */
     {
        family = AF_INET;
        addr.ip4.s_addr = inet_addr(n);
@@ -134,7 +136,7 @@ addr_matches_if_netmask(char *n, char *m)
        }
        addr.ip4.s_addr &= mask.ip4.s_addr;
     }
-#ifdef HAVE_IN6_ADDR
+#ifdef HAVE_STRUCT_IN6_ADDR
     else {
        if (inet_pton(AF_INET6, m, &mask.ip6) <= 0) {
            j = atoi(m);
@@ -149,7 +151,7 @@ addr_matches_if_netmask(char *n, char *m)
            }
        }
     }
-#endif /* HAVE_IN6_ADDR */
+#endif /* HAVE_STRUCT_IN6_ADDR */
 
     for (ifp = interfaces; ifp != NULL; ifp = ifp->next) {
        if (ifp->family != family)
@@ -157,31 +159,32 @@ addr_matches_if_netmask(char *n, char *m)
        switch(family) {
            case AF_INET:
                if ((ifp->addr.ip4.s_addr & mask.ip4.s_addr) == addr.ip4.s_addr)
-                   return TRUE;
-#ifdef HAVE_IN6_ADDR
+                   debug_return_bool(true);
+#ifdef HAVE_STRUCT_IN6_ADDR
            case AF_INET6:
                for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) {
                    if ((ifp->addr.ip6.s6_addr[j] & mask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j])
                        break;
                }
                if (j == sizeof(addr.ip6.s6_addr))
-                   return TRUE;
-#endif /* HAVE_IN6_ADDR */
+                   debug_return_bool(true);
+#endif /* HAVE_STRUCT_IN6_ADDR */
        }
     }
 
-    return FALSE;
+    debug_return_bool(false);
 }
 
 /*
- * Returns TRUE if "n" is one of our ip addresses or if
- * "n" is a network that we are on, else returns FALSE.
+ * Returns true if "n" is one of our ip addresses or if
+ * "n" is a network that we are on, else returns false.
  */
-int
+bool
 addr_matches(char *n)
 {
     char *m;
-    int retval;
+    bool retval;
+    debug_decl(addr_matches, SUDO_DEBUG_MATCH)
 
     /* If there's an explicit netmask, use it. */
     if ((m = strchr(n, '/'))) {
@@ -191,5 +194,5 @@ addr_matches(char *n)
     } else
        retval = addr_matches_if(n);
 
-    return retval;
+    debug_return_bool(retval);
 }
index 8ce68584bf19f1c4cf586179608f7154e73209f5..66385f07a8768989c1ff7f1ba0b85e3e199bc6cc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2005, 2007-2011 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2004-2005, 2007-2012 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
@@ -70,7 +70,8 @@ struct sudo_nss sudo_nss_file = {
  */
 extern FILE *yyin;
 extern char *errorfile;
-extern int errorlineno, parse_error;
+extern int errorlineno;
+extern bool parse_error;
 
 /*
  * Local prototypes.
@@ -81,15 +82,19 @@ static int display_bound_defaults(int, struct lbuf *);
 int
 sudo_file_open(struct sudo_nss *nss)
 {
+    debug_decl(sudo_file_open, SUDO_DEBUG_NSS)
+
     if (def_ignore_local_sudoers)
-       return -1;
-    nss->handle = open_sudoers(sudoers_file, FALSE, NULL);
-    return nss->handle ? 0 : -1;
+       debug_return_int(-1);
+    nss->handle = open_sudoers(sudoers_file, false, NULL);
+    debug_return_int(nss->handle ? 0 : -1);
 }
 
 int
 sudo_file_close(struct sudo_nss *nss)
 {
+    debug_decl(sudo_file_close, SUDO_DEBUG_NSS)
+
     /* Free parser data structures and close sudoers file. */
     init_parser(NULL, 0);
     if (nss->handle != NULL) {
@@ -97,7 +102,7 @@ sudo_file_close(struct sudo_nss *nss)
        nss->handle = NULL;
        yyin = NULL;
     }
-    return 0;
+    debug_return_int(0);
 }
 
 /*
@@ -106,17 +111,23 @@ sudo_file_close(struct sudo_nss *nss)
 int
 sudo_file_parse(struct sudo_nss *nss)
 {
+    debug_decl(sudo_file_close, SUDO_DEBUG_NSS)
+
     if (nss->handle == NULL)
-       return -1;
+       debug_return_int(-1);
 
     init_parser(sudoers_file, 0);
     yyin = nss->handle;
     if (yyparse() != 0 || parse_error) {
-       log_error(NO_EXIT, _("parse error in %s near line %d"),
-           errorfile, errorlineno);
-       return -1;
+       if (errorlineno != -1) {
+           log_error(NO_EXIT, _("parse error in %s near line %d"),
+               errorfile, errorlineno);
+       } else {
+           log_error(NO_EXIT, _("parse error in %s"), errorfile);
+       }
+       debug_return_int(-1);
     }
-    return 0;
+    debug_return_int(0);
 }
 
 /*
@@ -125,12 +136,14 @@ sudo_file_parse(struct sudo_nss *nss)
 int
 sudo_file_setdefs(struct sudo_nss *nss)
 {
+    debug_decl(sudo_file_setdefs, SUDO_DEBUG_NSS)
+
     if (nss->handle == NULL)
-       return -1;
+       debug_return_int(-1);
 
     if (!update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER))
-       return -1;
-    return 0;
+       debug_return_int(-1);
+    debug_return_int(0);
 }
 
 /*
@@ -145,9 +158,10 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
     struct cmndtag *tags = NULL;
     struct privilege *priv;
     struct userspec *us;
+    debug_decl(sudo_file_lookup, SUDO_DEBUG_NSS)
 
     if (nss->handle == NULL)
-       return validated;
+       debug_return_int(validated);
 
     /*
      * Only check the actual command if pwflag is not set.
@@ -159,7 +173,7 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
        enum def_tuple pwcheck;
 
        pwcheck = (pwflag == -1) ? never : sudo_defs_table[pwflag].sd_un.tuple;
-       nopass = (pwcheck == all) ? TRUE : FALSE;
+       nopass = (pwcheck == all) ? true : false;
 
        if (list_pw == NULL)
            SET(validated, FLAG_NO_CHECK);
@@ -178,8 +192,8 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
                        user_uid == list_pw->pw_uid ||
                        cmnd_matches(cs->cmnd) == ALLOW)
                            match = ALLOW;
-                   if ((pwcheck == any && cs->tags.nopasswd == TRUE) ||
-                       (pwcheck == all && cs->tags.nopasswd != TRUE))
+                   if ((pwcheck == any && cs->tags.nopasswd == true) ||
+                       (pwcheck == all && cs->tags.nopasswd != true))
                        nopass = cs->tags.nopasswd;
                }
            }
@@ -191,9 +205,9 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
            SET(validated, VALIDATE_NOT_OK);
        if (pwcheck == always && def_authenticate)
            SET(validated, FLAG_CHECK_USER);
-       else if (pwcheck == never || nopass == TRUE)
-           def_authenticate = FALSE;
-       return validated;
+       else if (pwcheck == never || nopass == true)
+           def_authenticate = false;
+       debug_return_int(validated);
     }
 
     /* Need to be runas user while stat'ing things. */
@@ -254,7 +268,7 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
            def_authenticate = !tags->nopasswd;
     }
     restore_perms();
-    return validated;
+    debug_return_int(validated);
 }
 
 #define        TAG_CHANGED(t) \
@@ -265,6 +279,7 @@ sudo_file_append_cmnd(struct cmndspec *cs, struct cmndtag *tags,
     struct lbuf *lbuf)
 {
     struct member *m;
+    debug_decl(sudo_file_append_cmnd, SUDO_DEBUG_NSS)
 
 #ifdef HAVE_SELINUX
     if (cs->role)
@@ -295,6 +310,7 @@ sudo_file_append_cmnd(struct cmndspec *cs, struct cmndtag *tags,
     m = cs->cmnd;
     print_member(lbuf, m->name, m->type, m->negated,
        CMNDALIAS);
+    debug_return;
 }
 
 static int
@@ -306,6 +322,7 @@ sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
     struct privilege *priv;
     struct cmndtag tags;
     int nfound = 0;
+    debug_decl(sudo_file_display_priv_short, SUDO_DEBUG_NSS)
 
     tq_foreach_fwd(&us->privileges, priv) {
        if (hostlist_matches(&priv->hostlist) != ALLOW)
@@ -347,7 +364,7 @@ sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
        }
        lbuf_append(lbuf, "\n");
     }
-    return nfound;
+    debug_return_int(nfound);
 }
 
 static int
@@ -359,6 +376,7 @@ sudo_file_display_priv_long(struct passwd *pw, struct userspec *us,
     struct privilege *priv;
     struct cmndtag tags;
     int nfound = 0;
+    debug_decl(sudo_file_display_priv_long, SUDO_DEBUG_NSS)
 
     tq_foreach_fwd(&us->privileges, priv) {
        if (hostlist_matches(&priv->hostlist) != ALLOW)
@@ -400,7 +418,7 @@ sudo_file_display_priv_long(struct passwd *pw, struct userspec *us,
            nfound++;
        }
     }
-    return nfound;
+    debug_return_int(nfound);
 }
 
 int
@@ -409,6 +427,7 @@ sudo_file_display_privs(struct sudo_nss *nss, struct passwd *pw,
 {
     struct userspec *us;
     int nfound = 0;
+    debug_decl(sudo_file_display_priv, SUDO_DEBUG_NSS)
 
     if (nss->handle == NULL)
        goto done;
@@ -423,7 +442,7 @@ sudo_file_display_privs(struct sudo_nss *nss, struct passwd *pw,
            nfound += sudo_file_display_priv_short(pw, us, lbuf);
     }
 done:
-    return nfound;
+    debug_return_int(nfound);
 }
 
 /*
@@ -436,6 +455,7 @@ sudo_file_display_defaults(struct sudo_nss *nss, struct passwd *pw,
     struct defaults *d;
     char *prefix;
     int nfound = 0;
+    debug_decl(sudo_file_display_defaults, SUDO_DEBUG_NSS)
 
     if (nss->handle == NULL)
        goto done;
@@ -470,12 +490,12 @@ sudo_file_display_defaults(struct sudo_nss *nss, struct passwd *pw,
                lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", d->val);
        } else
            lbuf_append(lbuf, "%s%s%s", prefix,
-               d->op == FALSE ? "!" : "", d->var);
+               d->op == false ? "!" : "", d->var);
        prefix = ", ";
        nfound++;
     }
 done:
-    return nfound;
+    debug_return_int(nfound);
 }
 
 /*
@@ -486,12 +506,13 @@ sudo_file_display_bound_defaults(struct sudo_nss *nss, struct passwd *pw,
     struct lbuf *lbuf)
 {
     int nfound = 0;
+    debug_decl(sudo_file_display_bound_defaults, SUDO_DEBUG_NSS)
 
     /* XXX - should only print ones that match what the user can do. */
     nfound += display_bound_defaults(DEFAULTS_RUNAS, lbuf);
     nfound += display_bound_defaults(DEFAULTS_CMND, lbuf);
 
-    return nfound;
+    debug_return_int(nfound);
 }
 
 /*
@@ -504,6 +525,7 @@ display_bound_defaults(int dtype, struct lbuf *lbuf)
     struct member *m, *binding = NULL;
     char *dsep;
     int atype, nfound = 0;
+    debug_decl(display_bound_defaults, SUDO_DEBUG_NSS)
 
     switch (dtype) {
        case DEFAULTS_HOST:
@@ -523,7 +545,7 @@ display_bound_defaults(int dtype, struct lbuf *lbuf)
            dsep = "!";
            break;
        default:
-           return -1;
+           debug_return_int(-1);
     }
     tq_foreach_fwd(&defaults, d) {
        if (d->type != dtype)
@@ -547,10 +569,10 @@ display_bound_defaults(int dtype, struct lbuf *lbuf)
            lbuf_append(lbuf, "%s%s%s", d->var, d->op == '+' ? "+=" :
                d->op == '-' ? "-=" : "=", d->val);
        } else
-           lbuf_append(lbuf, "%s%s", d->op == FALSE ? "!" : "", d->var);
+           lbuf_append(lbuf, "%s%s", d->op == false ? "!" : "", d->var);
     }
 
-    return nfound;
+    debug_return_int(nfound);
 }
 
 int
@@ -562,6 +584,7 @@ sudo_file_display_cmnd(struct sudo_nss *nss, struct passwd *pw)
     struct userspec *us;
     int rval = 1;
     int host_match, runas_match, cmnd_match;
+    debug_decl(sudo_file_display_cmnd, SUDO_DEBUG_NSS)
 
     if (nss->handle == NULL)
        goto done;
@@ -595,7 +618,7 @@ sudo_file_display_cmnd(struct sudo_nss *nss, struct passwd *pw)
        rval = 0;
     }
 done:
-    return rval;
+    debug_return_int(rval);
 }
 
 /*
@@ -608,6 +631,7 @@ _print_member(struct lbuf *lbuf, char *name, int type, int negated,
     struct alias *a;
     struct member *m;
     struct sudo_command *c;
+    debug_decl(_print_member, SUDO_DEBUG_NSS)
 
     switch (type) {
        case ALL:
@@ -638,6 +662,7 @@ _print_member(struct lbuf *lbuf, char *name, int type, int negated,
            lbuf_append(lbuf, "%s%s", negated ? "!" : "", name);
            break;
     }
+    debug_return;
 }
 
 static void
index 6976b16d5df9c27f40584d4e306b0699806f6226..3b1a5b50dd2a265b420853751f7e91a71b7953d7 100644 (file)
@@ -37,7 +37,7 @@ struct sudo_command {
 
 /*
  * Tags associated with a command.
- * Possible valus: TRUE, FALSE, UNSPEC.
+ * Possible values: true, false, UNSPEC.
  */
 struct cmndtag {
     __signed int nopasswd: 3;
@@ -148,7 +148,7 @@ struct defaults {
     char *val;                         /* variable value */
     struct member_list binding;                /* user/host/runas binding */
     int type;                          /* DEFAULTS{,_USER,_RUNAS,_HOST} */
-    int op;                            /* TRUE, FALSE, '+', '-' */
+    int op;                            /* true, false, '+', '-' */
 };
 
 /*
@@ -166,19 +166,19 @@ extern unsigned int alias_seqno;
  * Prototypes
  */
 char *alias_add(char *, int, struct member *);
-int addr_matches(char *);
+bool addr_matches(char *);
 int cmnd_matches(struct member *);
 int cmndlist_matches(struct member_list *);
-int command_matches(char *, char *);
+bool command_matches(char *, char *);
 int hostlist_matches(struct member_list *);
-int hostname_matches(char *, char *, char *);
-int netgr_matches(char *, char *, char *, char *);
-int no_aliases(void);
+bool hostname_matches(char *, char *, char *);
+bool netgr_matches(char *, char *, char *, char *);
+bool no_aliases(void);
 int runaslist_matches(struct member_list *, struct member_list *);
 int userlist_matches(struct passwd *, struct member_list *);
-int usergr_matches(char *, char *, struct passwd *);
-int userpw_matches(char *, char *, struct passwd *);
-int group_matches(char *, struct group *);
+bool usergr_matches(char *, char *, struct passwd *);
+bool userpw_matches(char *, char *, struct passwd *);
+bool group_matches(char *, struct group *);
 struct alias *alias_find(char *, int);
 struct alias *alias_remove(char *, int);
 void alias_free(void *);
index 3d9f84cd64e0e11ab9430cb8ea4d306bb411d653..142eddc1d5ec4b2f9a36bc0a560ab9dc09988bcd 100644 (file)
 static void _warning(int, const char *, va_list);
        void plugin_cleanup(int);
 
-sigjmp_buf error_jmp;
+extern sigjmp_buf error_jmp;
 
 extern sudo_conv_t sudo_conv;
 
 void
-error(int eval, const char *fmt, ...)
+error2(int eval, const char *fmt, ...)
 {
     va_list ap;
 
@@ -52,7 +52,7 @@ error(int eval, const char *fmt, ...)
 }
 
 void
-errorx(int eval, const char *fmt, ...)
+errorx2(int eval, const char *fmt, ...)
 {
     va_list ap;
 
@@ -64,7 +64,7 @@ errorx(int eval, const char *fmt, ...)
 }
 
 void
-warning(const char *fmt, ...)
+warning2(const char *fmt, ...)
 {
     va_list ap;
 
@@ -74,7 +74,7 @@ warning(const char *fmt, ...)
 }
 
 void
-warningx(const char *fmt, ...)
+warningx2(const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
index fd670457cc561589f11dcd602994c2e8ec16a642..1c6c9fdd4bde54178ff47bc10618e063f5b41e9e 100644 (file)
Binary files a/plugins/sudoers/po/da.mo and b/plugins/sudoers/po/da.mo differ
index da6368a4891e0aa97872c4a990c3350a676bbc52..a795044f28ed909ae034baea5a271f281f18b346 100644 (file)
@@ -1,6 +1,6 @@
 # Danish translation of sudoers.
 # This file is put in the public domain.
-# Joe Hansen <joedalton2@yahoo.dk>, 2011.
+# Joe Hansen <joedalton2@yahoo.dk>, 2011, 2012.
 #
 # audit -> overvågning
 # dummy -> attrap
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: sudoers 1.8.3rc1\n"
+"Project-Id-Version: sudoers 1.8.4rc1\n"
 "Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
-"POT-Creation-Date: 2011-09-16 16:52-0400\n"
-"PO-Revision-Date: 2011-09-17 23:06+0100\n"
+"POT-Creation-Date: 2012-02-06 15:48-0500\n"
+"PO-Revision-Date: 2012-02-08 23:06+0100\n"
 "Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n"
 "Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
 "Language: da\n"
@@ -27,146 +27,146 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms:  nplurals=2; plural=(n != 1);\n"
 
-#: plugins/sudoers/alias.c:122
+#: plugins/sudoers/alias.c:125
 #, c-format
 msgid "Alias `%s' already defined"
 msgstr "Alias »%s« er allerede defineret"
 
-#: plugins/sudoers/bsm_audit.c:58 plugins/sudoers/bsm_audit.c:61
-#: plugins/sudoers/bsm_audit.c:109 plugins/sudoers/bsm_audit.c:113
-#: plugins/sudoers/bsm_audit.c:163 plugins/sudoers/bsm_audit.c:167
+#: plugins/sudoers/bsm_audit.c:61 plugins/sudoers/bsm_audit.c:64
+#: plugins/sudoers/bsm_audit.c:113 plugins/sudoers/bsm_audit.c:117
+#: plugins/sudoers/bsm_audit.c:169 plugins/sudoers/bsm_audit.c:173
 msgid "getaudit: failed"
 msgstr "getaudit: fejlede"
 
-#: plugins/sudoers/bsm_audit.c:87 plugins/sudoers/bsm_audit.c:148
+#: plugins/sudoers/bsm_audit.c:91 plugins/sudoers/bsm_audit.c:154
 msgid "Could not determine audit condition"
 msgstr "Kunne ikke bestemme overvågningsbetingelse"
 
-#: plugins/sudoers/bsm_audit.c:98
+#: plugins/sudoers/bsm_audit.c:102
 msgid "getauid failed"
 msgstr "getauid fejlede"
 
-#: plugins/sudoers/bsm_audit.c:100 plugins/sudoers/bsm_audit.c:157
+#: plugins/sudoers/bsm_audit.c:104 plugins/sudoers/bsm_audit.c:163
 msgid "au_open: failed"
 msgstr "au_open: fejlede"
 
-#: plugins/sudoers/bsm_audit.c:115 plugins/sudoers/bsm_audit.c:169
+#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:175
 msgid "au_to_subject: failed"
 msgstr "au_to_subject: fejlede"
 
-#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:173
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:179
 msgid "au_to_exec_args: failed"
 msgstr "au_to_exec_args: fejlede"
 
-#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:182
+#: plugins/sudoers/bsm_audit.c:127 plugins/sudoers/bsm_audit.c:188
 msgid "au_to_return32: failed"
 msgstr "au_to_return32: fejlede"
 
-#: plugins/sudoers/bsm_audit.c:126 plugins/sudoers/bsm_audit.c:185
+#: plugins/sudoers/bsm_audit.c:130 plugins/sudoers/bsm_audit.c:191
 msgid "unable to commit audit record"
-msgstr "Kan ikke indsende overvågningspost"
+msgstr "kan ikke indsende overvågningspost"
 
-#: plugins/sudoers/bsm_audit.c:155
+#: plugins/sudoers/bsm_audit.c:161
 msgid "getauid: failed"
 msgstr "getauid: fejlede"
 
-#: plugins/sudoers/bsm_audit.c:178
+#: plugins/sudoers/bsm_audit.c:184
 msgid "au_to_text: failed"
 msgstr "au_to_text: fejlede"
 
-#: plugins/sudoers/check.c:141
+#: plugins/sudoers/check.c:158
 #, c-format
 msgid "sorry, a password is required to run %s"
 msgstr "beklager men en adgangskode er krævet for at køre %s"
 
-#: plugins/sudoers/check.c:225 plugins/sudoers/iolog.c:169
-#: plugins/sudoers/sudoers.c:971 plugins/sudoers/sudoreplay.c:325
-#: plugins/sudoers/sudoreplay.c:334 plugins/sudoers/sudoreplay.c:675
-#: plugins/sudoers/sudoreplay.c:767 plugins/sudoers/visudo.c:744
+#: plugins/sudoers/check.c:249 plugins/sudoers/iolog.c:172
+#: plugins/sudoers/sudoers.c:992 plugins/sudoers/sudoreplay.c:348
+#: plugins/sudoers/sudoreplay.c:357 plugins/sudoers/sudoreplay.c:703
+#: plugins/sudoers/sudoreplay.c:797 plugins/sudoers/visudo.c:790
 #, c-format
 msgid "unable to open %s"
 msgstr "kan ikke åbne %s"
 
-#: plugins/sudoers/check.c:229 plugins/sudoers/iolog.c:199
+#: plugins/sudoers/check.c:253 plugins/sudoers/iolog.c:202
 #, c-format
 msgid "unable to write to %s"
 msgstr "kan ikke skrive til %s"
 
-#: plugins/sudoers/check.c:237 plugins/sudoers/check.c:475
-#: plugins/sudoers/check.c:525 plugins/sudoers/iolog.c:122
-#: plugins/sudoers/iolog.c:153
+#: plugins/sudoers/check.c:261 plugins/sudoers/check.c:506
+#: plugins/sudoers/check.c:556 plugins/sudoers/iolog.c:123
+#: plugins/sudoers/iolog.c:156
 #, c-format
 msgid "unable to mkdir %s"
 msgstr "kan ikke mkdir %s"
 
-#: plugins/sudoers/check.c:370
+#: plugins/sudoers/check.c:396
 #, c-format
 msgid "internal error, expand_prompt() overflow"
 msgstr "intern fejl, expand_prompt()-overløb"
 
-#: plugins/sudoers/check.c:426
+#: plugins/sudoers/check.c:456
 #, c-format
 msgid "timestamp path too long: %s"
 msgstr "tidsstempelsti er for lang: %s"
 
-#: plugins/sudoers/check.c:454 plugins/sudoers/check.c:498
-#: plugins/sudoers/iolog.c:155
+#: plugins/sudoers/check.c:485 plugins/sudoers/check.c:529
+#: plugins/sudoers/iolog.c:158
 #, c-format
 msgid "%s exists but is not a directory (0%o)"
 msgstr "%s findes men er ikke en mappe (0%o)"
 
-#: plugins/sudoers/check.c:457 plugins/sudoers/check.c:501
-#: plugins/sudoers/check.c:546
+#: plugins/sudoers/check.c:488 plugins/sudoers/check.c:532
+#: plugins/sudoers/check.c:577
 #, c-format
 msgid "%s owned by uid %u, should be uid %u"
 msgstr "%s ejet af uid %u, bør være uid %u"
 
-#: plugins/sudoers/check.c:462 plugins/sudoers/check.c:506
+#: plugins/sudoers/check.c:493 plugins/sudoers/check.c:537
 #, c-format
 msgid "%s writable by non-owner (0%o), should be mode 0700"
 msgstr "%s er skrivbar for ikkeejer (0%o), bør være tilstand 0700"
 
-#: plugins/sudoers/check.c:470 plugins/sudoers/check.c:514
-#: plugins/sudoers/check.c:582 plugins/sudoers/sudoers.c:957
-#: plugins/sudoers/visudo.c:304 plugins/sudoers/visudo.c:544
+#: plugins/sudoers/check.c:501 plugins/sudoers/check.c:545
+#: plugins/sudoers/check.c:613 plugins/sudoers/sudoers.c:978
+#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:582
 #, c-format
 msgid "unable to stat %s"
 msgstr "kan ikke stat %s"
 
-#: plugins/sudoers/check.c:540
+#: plugins/sudoers/check.c:571
 #, c-format
 msgid "%s exists but is not a regular file (0%o)"
 msgstr "%s findes men er ikke en regulær fil (0%o)"
 
-#: plugins/sudoers/check.c:552
+#: plugins/sudoers/check.c:583
 #, c-format
 msgid "%s writable by non-owner (0%o), should be mode 0600"
 msgstr "%s skrivbar af ikkeejer (0%o), bør være tilstand 0600"
 
-#: plugins/sudoers/check.c:606
+#: plugins/sudoers/check.c:637
 #, c-format
 msgid "timestamp too far in the future: %20.20s"
 msgstr "tidsstempel for langt ude i fremtiden: %20.20s"
 
-#: plugins/sudoers/check.c:652
+#: plugins/sudoers/check.c:684
 #, c-format
 msgid "unable to remove %s (%s), will reset to the epoch"
 msgstr "kan ikke fjerne %s (%s), vil nulstille til epoken"
 
-#: plugins/sudoers/check.c:660
+#: plugins/sudoers/check.c:692
 #, c-format
 msgid "unable to reset %s to the epoch"
 msgstr "kan ikke nulstille %s til epoken"
 
-#: plugins/sudoers/check.c:714 plugins/sudoers/check.c:720
+#: plugins/sudoers/check.c:752 plugins/sudoers/check.c:758
+#: plugins/sudoers/sudoers.c:829 plugins/sudoers/sudoers.c:833
 #, c-format
 msgid "unknown uid: %u"
 msgstr "ukendt uid: %u"
 
-#: plugins/sudoers/check.c:717 plugins/sudoers/sudoers.c:748
-#: plugins/sudoers/sudoers.c:814 plugins/sudoers/sudoers.c:815
-#: plugins/sudoers/sudoers.c:1088 plugins/sudoers/testsudoers.c:202
-#: plugins/sudoers/testsudoers.c:337
+#: plugins/sudoers/check.c:755 plugins/sudoers/sudoers.c:770
+#: plugins/sudoers/sudoers.c:1108 plugins/sudoers/testsudoers.c:218
+#: plugins/sudoers/testsudoers.c:362
 #, c-format
 msgid "unknown user: %s"
 msgstr "ukendt bruger: %s"
@@ -412,299 +412,298 @@ msgstr "Hvornår der skal kræves en adgangskode for »list« pseudokommando: %s
 msgid "When to require a password for 'verify' pseudocommand: %s"
 msgstr "Hvornår der skal kræves en adgangskode for »verify« pseudokommando: %s"
 
+# engelsk fejl mangler \" til sidst
 #: plugins/sudoers/def_data.c:243
-msgid "Preload the dummy exec functions contained in 'noexec_file'"
-msgstr "Præindlæs attrap-udførelsesfunktioner indeholdt i »noexec_file«"
+msgid "Preload the dummy exec functions contained in \"_PATH_SUDO_NOEXEC"
+msgstr "Præindlæs attrap-udførelsesfunktioner indeholdt i »_PATH_SUDO_NOEXEC«"
 
 #: plugins/sudoers/def_data.c:247
-#, c-format
-msgid "File containing dummy exec functions: %s"
-msgstr "Fil der indeholder attrap-udførelsesfunktioner: %s"
-
-#: plugins/sudoers/def_data.c:251
 msgid "If LDAP directory is up, do we ignore local sudoers file"
 msgstr "Hvis LDAP-mappe er sat op, ignorer vi så lokal sudoersfil"
 
-#: plugins/sudoers/def_data.c:255
+#: plugins/sudoers/def_data.c:251
 #, c-format
 msgid "File descriptors >= %d will be closed before executing a command"
 msgstr "Filbeskrivelser >= %d vil blive lukket før udførelse af en kommando"
 
-#: plugins/sudoers/def_data.c:259
+#: plugins/sudoers/def_data.c:255
 msgid "If set, users may override the value of `closefrom' with the -C option"
 msgstr "Hvis angivet kan brugere overskrive værdien af »closeform« med tilvalget -C"
 
-#: plugins/sudoers/def_data.c:263
+#: plugins/sudoers/def_data.c:259
 msgid "Allow users to set arbitrary environment variables"
 msgstr "Tillad at brugere kan angive arbitrære miljøvariabler"
 
-#: plugins/sudoers/def_data.c:267
+#: plugins/sudoers/def_data.c:263
 msgid "Reset the environment to a default set of variables"
 msgstr "Nulstil miljøet til et standardsæt af variabler"
 
-#: plugins/sudoers/def_data.c:271
+#: plugins/sudoers/def_data.c:267
 msgid "Environment variables to check for sanity:"
 msgstr "Miljøvariabler at indstillingskontrollere:"
 
-#: plugins/sudoers/def_data.c:275
+#: plugins/sudoers/def_data.c:271
 msgid "Environment variables to remove:"
 msgstr "Miljøvariabler at fjerne:"
 
-#: plugins/sudoers/def_data.c:279
+#: plugins/sudoers/def_data.c:275
 msgid "Environment variables to preserve:"
 msgstr "Miljøvariabler at bevare:"
 
-#: plugins/sudoers/def_data.c:283
+#: plugins/sudoers/def_data.c:279
 #, c-format
 msgid "SELinux role to use in the new security context: %s"
 msgstr "SELinux-rolle at bruge i den nye sikkerhedskontekst: %s"
 
-#: plugins/sudoers/def_data.c:287
+#: plugins/sudoers/def_data.c:283
 #, c-format
 msgid "SELinux type to use in the new security context: %s"
 msgstr "SELinux-type at bruge i den nye sikkerhedskontekst: %s"
 
-#: plugins/sudoers/def_data.c:291
+#: plugins/sudoers/def_data.c:287
 #, c-format
 msgid "Path to the sudo-specific environment file: %s"
 msgstr "Sti til den sudo-specifikke miljøfil: %s"
 
-#: plugins/sudoers/def_data.c:295
+#: plugins/sudoers/def_data.c:291
 #, c-format
 msgid "Locale to use while parsing sudoers: %s"
 msgstr "Sprog at bruge under fortolkning af sudoers: %s"
 
-#: plugins/sudoers/def_data.c:299
-msgid "Allow sudo to prompt for a password even if it would be visisble"
+#: plugins/sudoers/def_data.c:295
+msgid "Allow sudo to prompt for a password even if it would be visible"
 msgstr "Tillad at sudo spørger om en adgangskode selv om den vil være synlig"
 
-#: plugins/sudoers/def_data.c:303
+#: plugins/sudoers/def_data.c:299
 msgid "Provide visual feedback at the password prompt when there is user input"
 msgstr "Tilbyd visuel tilbagemeldning ved adgangskodeprompten når der er brugerinddata"
 
-#: plugins/sudoers/def_data.c:307
+#: plugins/sudoers/def_data.c:303
 msgid "Use faster globbing that is less accurate but does not access the filesystem"
 msgstr "Brug hurtigere globbing som er mindre præcis, men som ikke tilgår filsystemet"
 
-#: plugins/sudoers/def_data.c:311
+#: plugins/sudoers/def_data.c:307
 msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
 msgstr "Umask'en angivet i sudoers vil overskrive brugerens, også selv om den er mere tilladende"
 
-#: plugins/sudoers/def_data.c:315
+#: plugins/sudoers/def_data.c:311
 msgid "Log user's input for the command being run"
 msgstr "Log brugers inddata for kommandoen der bliver kørt"
 
-#: plugins/sudoers/def_data.c:319
+#: plugins/sudoers/def_data.c:315
 msgid "Log the output of the command being run"
 msgstr "Log uddata for kommandoen der bliver kørt"
 
-#: plugins/sudoers/def_data.c:323
+#: plugins/sudoers/def_data.c:319
 msgid "Compress I/O logs using zlib"
 msgstr "Komprimer I/O-log med brug af zlib"
 
-#: plugins/sudoers/def_data.c:327
+#: plugins/sudoers/def_data.c:323
 msgid "Always run commands in a pseudo-tty"
 msgstr "Kør altid kommandoer i en pseudo-tty"
 
+#: plugins/sudoers/def_data.c:327
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Udvidelsesmodul for ikke-Unix-gruppeunderstøttelse: %s"
+
 #: plugins/sudoers/def_data.c:331
-msgid "Plugin for non-Unix group support"
-msgstr "Udvidelsesmodul for ikke-Unix-gruppeunderstøttelse"
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Mappe at gemme inddata-/uddatalogge i: %s"
 
 #: plugins/sudoers/def_data.c:335
-msgid "Directory in which to store input/output logs"
-msgstr "Mappe at gemme inddata-/uddatalog i"
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Fil at gemme inddata-/uddatalog i: %s"
 
 #: plugins/sudoers/def_data.c:339
-msgid "File in which to store the input/output log"
-msgstr "Fil at gemme inddata-/uddatalog i"
-
-#: plugins/sudoers/def_data.c:343
 msgid "Add an entry to the utmp/utmpx file when allocating a pty"
 msgstr "Tilføjer et punkt til utmp/utmpx-filen når der allokeres en pty"
 
-#: plugins/sudoers/def_data.c:347
+#: plugins/sudoers/def_data.c:343
 msgid "Set the user in utmp to the runas user, not the invoking user"
 msgstr "Angiv brugeren i utmp til brugeren kør som, ikke den opstartende bruger"
 
-#: plugins/sudoers/defaults.c:205
+#: plugins/sudoers/defaults.c:208
 #, c-format
 msgid "unknown defaults entry `%s'"
 msgstr "ukendt standardpunkt »%s«"
 
-#: plugins/sudoers/defaults.c:213 plugins/sudoers/defaults.c:223
-#: plugins/sudoers/defaults.c:243 plugins/sudoers/defaults.c:256
-#: plugins/sudoers/defaults.c:269 plugins/sudoers/defaults.c:282
-#: plugins/sudoers/defaults.c:295 plugins/sudoers/defaults.c:315
-#: plugins/sudoers/defaults.c:325
+#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
+#: plugins/sudoers/defaults.c:246 plugins/sudoers/defaults.c:259
+#: plugins/sudoers/defaults.c:272 plugins/sudoers/defaults.c:285
+#: plugins/sudoers/defaults.c:298 plugins/sudoers/defaults.c:318
+#: plugins/sudoers/defaults.c:328
 #, c-format
 msgid "value `%s' is invalid for option `%s'"
 msgstr "værdi »%s« er ugyldig for indstilling »%s«"
 
-#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
-#: plugins/sudoers/defaults.c:234 plugins/sudoers/defaults.c:251
-#: plugins/sudoers/defaults.c:264 plugins/sudoers/defaults.c:277
-#: plugins/sudoers/defaults.c:290 plugins/sudoers/defaults.c:310
-#: plugins/sudoers/defaults.c:321
+#: plugins/sudoers/defaults.c:219 plugins/sudoers/defaults.c:229
+#: plugins/sudoers/defaults.c:237 plugins/sudoers/defaults.c:254
+#: plugins/sudoers/defaults.c:267 plugins/sudoers/defaults.c:280
+#: plugins/sudoers/defaults.c:293 plugins/sudoers/defaults.c:313
+#: plugins/sudoers/defaults.c:324
 #, c-format
 msgid "no value specified for `%s'"
 msgstr "ingen værdi angivet for »%s«"
 
-#: plugins/sudoers/defaults.c:239
+#: plugins/sudoers/defaults.c:242
 #, c-format
 msgid "values for `%s' must start with a '/'"
 msgstr "værdier for »%s« skal begynde med en »/«"
 
-#: plugins/sudoers/defaults.c:301
+#: plugins/sudoers/defaults.c:304
 #, c-format
 msgid "option `%s' does not take a value"
 msgstr "indstilling »%s« kan ikke modtage en værdi"
 
-#: plugins/sudoers/env.c:259
+#: plugins/sudoers/env.c:258
 #, c-format
 msgid "internal error, sudo_setenv() overflow"
 msgstr "intern fejl, sudo_setenv()-overløb"
 
-#: plugins/sudoers/env.c:289
+#: plugins/sudoers/env.c:291
 #, c-format
 msgid "sudo_putenv: corrupted envp, length mismatch"
 msgstr "sudo_putenv: ødelagt envp, forskellig længde"
 
-#: plugins/sudoers/env.c:698
+#: plugins/sudoers/env.c:710
 #, c-format
 msgid "sorry, you are not allowed to set the following environment variables: %s"
 msgstr "beklager, du har ikke tilladelse til at angive de følgende miljøvariabler: %s"
 
-#: plugins/sudoers/find_path.c:68 plugins/sudoers/find_path.c:107
-#: plugins/sudoers/find_path.c:122 plugins/sudoers/iolog.c:124
-#: plugins/sudoers/sudoers.c:903 toke.l:663 toke.l:814
+#: plugins/sudoers/find_path.c:69 plugins/sudoers/find_path.c:108
+#: plugins/sudoers/find_path.c:123 plugins/sudoers/iolog.c:125
+#: plugins/sudoers/sudoers.c:923 toke.l:668 toke.l:823
 #, c-format
 msgid "%s: %s"
 msgstr "%s: %s"
 
-#: gram.y:103
+#: gram.y:110
 #, c-format
 msgid ">>> %s: %s near line %d <<<"
 msgstr ">>> %s: %s nær linje %d <<<"
 
-#: plugins/sudoers/group_plugin.c:90
+#: plugins/sudoers/group_plugin.c:91
 #, c-format
 msgid "%s%s: %s"
 msgstr "%s%s: %s"
 
-#: plugins/sudoers/group_plugin.c:102
+#: plugins/sudoers/group_plugin.c:103
 #, c-format
 msgid "%s must be owned by uid %d"
 msgstr "%s skal være ejet af uid %d"
 
-#: plugins/sudoers/group_plugin.c:106
+#: plugins/sudoers/group_plugin.c:107
 #, c-format
 msgid "%s must only be writable by owner"
 msgstr "%s skal være skrivbar af ejer"
 
-#: plugins/sudoers/group_plugin.c:113
+#: plugins/sudoers/group_plugin.c:114
 #, c-format
 msgid "unable to dlopen %s: %s"
 msgstr "kan ikke dlopen %s: %s"
 
-#: plugins/sudoers/group_plugin.c:118
+#: plugins/sudoers/group_plugin.c:119
 #, c-format
 msgid "unable to find symbol \"group_plugin\" in %s"
 msgstr "kan ikke finde symbol »group_plugin« i %s"
 
-#: plugins/sudoers/group_plugin.c:123
+#: plugins/sudoers/group_plugin.c:124
 #, c-format
 msgid "%s: incompatible group plugin major version %d, expected %d"
 msgstr "%s: inkompatibel gruppeudvidelsesmodul for hovedversion %d, forventede %d"
 
-#: plugins/sudoers/interfaces.c:109
+#: plugins/sudoers/interfaces.c:112
 msgid "Local IP address and netmask pairs:\n"
 msgstr "Lokal IP-adresse og netmaskepar:\n"
 
-#: plugins/sudoers/iolog.c:176 plugins/sudoers/sudoers.c:978
+#: plugins/sudoers/iolog.c:179 plugins/sudoers/sudoers.c:999
 #, c-format
 msgid "unable to read %s"
 msgstr "kan ikke læse %s"
 
-#: plugins/sudoers/iolog.c:179
+#: plugins/sudoers/iolog.c:182
 #, c-format
 msgid "invalid sequence number %s"
 msgstr "ugyldig sekvenstal %s"
 
-#: plugins/sudoers/iolog.c:225 plugins/sudoers/iolog.c:228
-#: plugins/sudoers/iolog.c:478 plugins/sudoers/iolog.c:483
-#: plugins/sudoers/iolog.c:489 plugins/sudoers/iolog.c:497
-#: plugins/sudoers/iolog.c:505 plugins/sudoers/iolog.c:513
-#: plugins/sudoers/iolog.c:521
+#: plugins/sudoers/iolog.c:231 plugins/sudoers/iolog.c:234
+#: plugins/sudoers/iolog.c:499 plugins/sudoers/iolog.c:504
+#: plugins/sudoers/iolog.c:510 plugins/sudoers/iolog.c:518
+#: plugins/sudoers/iolog.c:526 plugins/sudoers/iolog.c:534
+#: plugins/sudoers/iolog.c:542
 #, c-format
 msgid "unable to create %s"
 msgstr "kan ikke oprette %s"
 
-#: plugins/sudoers/iolog_path.c:247 plugins/sudoers/sudoers.c:357
+#: plugins/sudoers/iolog_path.c:256 plugins/sudoers/sudoers.c:362
 #, c-format
 msgid "unable to set locale to \"%s\", using \"C\""
 msgstr "kan ikke angive sprog til »%s«, bruger »C«"
 
-#: plugins/sudoers/ldap.c:368
+#: plugins/sudoers/ldap.c:374
 #, c-format
 msgid "sudo_ldap_conf_add_ports: port too large"
 msgstr "sudo_ldap_conf_add_ports: port for stor"
 
-#: plugins/sudoers/ldap.c:391
+#: plugins/sudoers/ldap.c:397
 #, c-format
 msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
 msgstr "sudo_ldap_conf_add_ports: stigende mellemlager for vært (hostbuf) har ikke nok plads"
 
-#: plugins/sudoers/ldap.c:420
+#: plugins/sudoers/ldap.c:427
 #, c-format
 msgid "unsupported LDAP uri type: %s"
 msgstr "ikkeunderstøttet LDAP uri-type: %s"
 
-#: plugins/sudoers/ldap.c:449
+#: plugins/sudoers/ldap.c:456
 #, c-format
 msgid "invalid uri: %s"
 msgstr "ugyldig uri: %s"
 
-#: plugins/sudoers/ldap.c:455
+#: plugins/sudoers/ldap.c:462
 #, c-format
 msgid "unable to mix ldap and ldaps URIs"
 msgstr "kan ikke blande ldap og ldaps URI'er"
 
-#: plugins/sudoers/ldap.c:459
+#: plugins/sudoers/ldap.c:466
 #, c-format
 msgid "unable to mix ldaps and starttls"
 msgstr "kan ikke blande ldaps og starttls"
 
-#: plugins/sudoers/ldap.c:478
+#: plugins/sudoers/ldap.c:485
 #, c-format
 msgid "sudo_ldap_parse_uri: out of space building hostbuf"
 msgstr "sudo_ldap_parse_uri: opbyggende mellemlager for vært (hostbuf) har ikke nok plads"
 
-#: plugins/sudoers/ldap.c:541
+#: plugins/sudoers/ldap.c:550
 #, c-format
 msgid "unable to initialize SSL cert and key db: %s"
 msgstr "kan ikke initialisere SSL-cert og key db: %s"
 
-#: plugins/sudoers/ldap.c:937
+#: plugins/sudoers/ldap.c:958
 #, c-format
 msgid "unable to get GMT time"
 msgstr "kan ikke indhente GMT-tid"
 
-#: plugins/sudoers/ldap.c:943
+#: plugins/sudoers/ldap.c:964
 #, c-format
 msgid "unable to format timestamp"
 msgstr "kan ikke formatere tidsstempel"
 
-#: plugins/sudoers/ldap.c:951
+#: plugins/sudoers/ldap.c:972
 #, c-format
 msgid "unable to build time filter"
 msgstr "kan ikke bygge tidsfilter"
 
-#: plugins/sudoers/ldap.c:1052
+#: plugins/sudoers/ldap.c:1185
 #, c-format
 msgid "sudo_ldap_build_pass1 allocation mismatch"
 msgstr "sudo_ldap_build_pass1 forskellige allokeringer"
 
-#: plugins/sudoers/ldap.c:1562
+#: plugins/sudoers/ldap.c:1705
 #, c-format
 msgid ""
 "\n"
@@ -713,7 +712,7 @@ msgstr ""
 "\n"
 "LDAP-rolle: %s\n"
 
-#: plugins/sudoers/ldap.c:1564
+#: plugins/sudoers/ldap.c:1707
 #, c-format
 msgid ""
 "\n"
@@ -722,124 +721,129 @@ msgstr ""
 "\n"
 "LDAP-rolle: UKENDT\n"
 
-#: plugins/sudoers/ldap.c:1611
+#: plugins/sudoers/ldap.c:1754
 #, c-format
 msgid "    Order: %s\n"
 msgstr "    Rækkefølge: %s\n"
 
-#: plugins/sudoers/ldap.c:1619
+#: plugins/sudoers/ldap.c:1762
 #, c-format
 msgid "    Commands:\n"
 msgstr "    Kommandoer:\n"
 
-#: plugins/sudoers/ldap.c:2006
+#: plugins/sudoers/ldap.c:2161
 #, c-format
 msgid "unable to initialize LDAP: %s"
 msgstr "kan ikke initialisere LDAP: %s"
 
-#: plugins/sudoers/ldap.c:2037
+#: plugins/sudoers/ldap.c:2192
 #, c-format
 msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
 msgstr "start_tls angivet men LDAP libs understøtter ikke ldap_start_tls_s() eller ldap_start_tls_s_np()"
 
-#: plugins/sudoers/ldap.c:2268
+#: plugins/sudoers/ldap.c:2428
 #, c-format
 msgid "invalid sudoOrder attribute: %s"
 msgstr "ugyldig sudoOrder-attribut: %s"
 
-#: plugins/sudoers/linux_audit.c:55
+#: plugins/sudoers/linux_audit.c:57
 #, c-format
 msgid "unable to open audit system"
 msgstr "kan ikke åbne overvågningssystem"
 
-#: plugins/sudoers/linux_audit.c:79
+#: plugins/sudoers/linux_audit.c:82
 #, c-format
 msgid "internal error, linux_audit_command() overflow"
 msgstr "intern fejl, linux_audit_command()-overløb"
 
-#: plugins/sudoers/linux_audit.c:88
+#: plugins/sudoers/linux_audit.c:91
 #, c-format
 msgid "unable to send audit message"
 msgstr "kan ikke sende overvågningsbesked"
 
-#: plugins/sudoers/logging.c:192
+#: plugins/sudoers/logging.c:198
 #, c-format
 msgid "unable to open log file: %s: %s"
 msgstr "kan ikke åbne logfil: %s: %s"
 
-#: plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:201
 #, c-format
 msgid "unable to lock log file: %s: %s"
 msgstr "kan ikke låse logfil: %s: %s"
 
-#: plugins/sudoers/logging.c:249
+#: plugins/sudoers/logging.c:256
 msgid "user NOT in sudoers"
 msgstr "bruger IKKE i sudoers"
 
-#: plugins/sudoers/logging.c:251
+#: plugins/sudoers/logging.c:258
 msgid "user NOT authorized on host"
 msgstr "bruger IKKE autoriseret på vært"
 
-#: plugins/sudoers/logging.c:253
+#: plugins/sudoers/logging.c:260
 msgid "command not allowed"
 msgstr "kommando ikke tilladt"
 
-#: plugins/sudoers/logging.c:263
+#: plugins/sudoers/logging.c:270
 #, c-format
 msgid "%s is not in the sudoers file.  This incident will be reported.\n"
 msgstr "%s er ikke sudoersfilen. Denne handling vil blive rapporteret.\n"
 
-#: plugins/sudoers/logging.c:266
+#: plugins/sudoers/logging.c:273
 #, c-format
 msgid "%s is not allowed to run sudo on %s.  This incident will be reported.\n"
 msgstr "%s har ikke tilladelse til at køre sudo på %s. Denne handling vil blive rapporteret.\n"
 
-#: plugins/sudoers/logging.c:270
+#: plugins/sudoers/logging.c:277
 #, c-format
 msgid "Sorry, user %s may not run sudo on %s.\n"
 msgstr "Beklager. Bruger %s må ikke køre sudo på %s.\n"
 
-#: plugins/sudoers/logging.c:273
+#: plugins/sudoers/logging.c:280
 #, c-format
 msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
 msgstr "Beklager. Bruger %s har ikke tilladelse til at køre »%s%s%s« som %s%s%s på %s.\n"
 
-#: plugins/sudoers/logging.c:408
+#: plugins/sudoers/logging.c:420
 #, c-format
 msgid "unable to fork"
 msgstr "kan ikke forgrene"
 
-#: plugins/sudoers/logging.c:415 plugins/sudoers/logging.c:472
+#: plugins/sudoers/logging.c:427 plugins/sudoers/logging.c:489
 #, c-format
 msgid "unable to fork: %m"
 msgstr "kan ikke forgrene: %m"
 
-#: plugins/sudoers/logging.c:465
+#: plugins/sudoers/logging.c:479
 #, c-format
 msgid "unable to open pipe: %m"
 msgstr "kan ikke åbne datakanal: %m"
 
-#: plugins/sudoers/logging.c:484
+#: plugins/sudoers/logging.c:504
 #, c-format
 msgid "unable to dup stdin: %m"
 msgstr "kan ikke dup stdin: %m"
 
-#: plugins/sudoers/logging.c:518
+#: plugins/sudoers/logging.c:540
 #, c-format
 msgid "unable to execute %s: %m"
 msgstr "kan ikke køre %s: %m"
 
-#: plugins/sudoers/logging.c:728
+#: plugins/sudoers/logging.c:755
 #, c-format
 msgid "internal error: insufficient space for log line"
 msgstr "intern fejl: utilstrækkelig plads for loglinje"
 
-#: plugins/sudoers/parse.c:115
+#: plugins/sudoers/parse.c:123
 #, c-format
 msgid "parse error in %s near line %d"
 msgstr "fortolkningsfejl i %s nær linje %d"
 
-#: plugins/sudoers/parse.c:371
+#: plugins/sudoers/parse.c:126
+#, c-format
+msgid "parse error in %s"
+msgstr "fortolkningsfejl i %s"
+
+#: plugins/sudoers/parse.c:389
 #, c-format
 msgid ""
 "\n"
@@ -848,17 +852,17 @@ msgstr ""
 "\n"
 "Sudoers-punkt:\n"
 
-#: plugins/sudoers/parse.c:373
+#: plugins/sudoers/parse.c:391
 #, c-format
 msgid "    RunAsUsers: "
 msgstr "    KørSomBrugere: "
 
-#: plugins/sudoers/parse.c:388
+#: plugins/sudoers/parse.c:406
 #, c-format
 msgid "    RunAsGroups: "
 msgstr "    KørSomGrupper: "
 
-#: plugins/sudoers/parse.c:397
+#: plugins/sudoers/parse.c:415
 #, c-format
 msgid ""
 "    Commands:\n"
@@ -871,97 +875,97 @@ msgstr ""
 msgid ": "
 msgstr ": "
 
-#: plugins/sudoers/pwutil.c:251
+#: plugins/sudoers/pwutil.c:260
 #, c-format
 msgid "unable to cache uid %u (%s), already exists"
 msgstr "kan ikke cache uid %u (%s), findes allerede"
 
-#: plugins/sudoers/pwutil.c:259
+#: plugins/sudoers/pwutil.c:268
 #, c-format
 msgid "unable to cache uid %u, already exists"
 msgstr "kan ikke cache uid %u, findes allerede"
 
-#: plugins/sudoers/pwutil.c:295 plugins/sudoers/pwutil.c:304
+#: plugins/sudoers/pwutil.c:305 plugins/sudoers/pwutil.c:314
 #, c-format
 msgid "unable to cache user %s, already exists"
 msgstr "kan ikke cache bruger %s, findes allerede"
 
-#: plugins/sudoers/pwutil.c:607
+#: plugins/sudoers/pwutil.c:655
 #, c-format
 msgid "unable to cache gid %u (%s), already exists"
 msgstr "kan ikke cache gid %u (%s), findes allerede"
 
-#: plugins/sudoers/pwutil.c:615
+#: plugins/sudoers/pwutil.c:663
 #, c-format
 msgid "unable to cache gid %u, already exists"
 msgstr "kan ikke cache gid %u, findes allerede"
 
-#: plugins/sudoers/pwutil.c:644 plugins/sudoers/pwutil.c:653
+#: plugins/sudoers/pwutil.c:693 plugins/sudoers/pwutil.c:702
 #, c-format
 msgid "unable to cache group %s, already exists"
 msgstr "kan ikke cache gruppe %s, findes allerede"
 
-#: plugins/sudoers/set_perms.c:109 plugins/sudoers/set_perms.c:358
-#: plugins/sudoers/set_perms.c:590 plugins/sudoers/set_perms.c:824
+#: plugins/sudoers/set_perms.c:114 plugins/sudoers/set_perms.c:365
+#: plugins/sudoers/set_perms.c:601 plugins/sudoers/set_perms.c:837
 msgid "perm stack overflow"
 msgstr "permanent stakoverløb"
 
-#: plugins/sudoers/set_perms.c:117 plugins/sudoers/set_perms.c:366
-#: plugins/sudoers/set_perms.c:598 plugins/sudoers/set_perms.c:832
+#: plugins/sudoers/set_perms.c:122 plugins/sudoers/set_perms.c:373
+#: plugins/sudoers/set_perms.c:609 plugins/sudoers/set_perms.c:845
 msgid "perm stack underflow"
 msgstr "permanent stakunderløb"
 
-#: plugins/sudoers/set_perms.c:223 plugins/sudoers/set_perms.c:458
-#: plugins/sudoers/set_perms.c:695
+#: plugins/sudoers/set_perms.c:228 plugins/sudoers/set_perms.c:466
+#: plugins/sudoers/set_perms.c:706
 msgid "unable to change to runas gid"
 msgstr "kan ikke ændre til kør som gid"
 
-#: plugins/sudoers/set_perms.c:231 plugins/sudoers/set_perms.c:465
-#: plugins/sudoers/set_perms.c:702
+#: plugins/sudoers/set_perms.c:236 plugins/sudoers/set_perms.c:473
+#: plugins/sudoers/set_perms.c:713
 msgid "unable to change to runas uid"
 msgstr "kan ikke ændre til kør som uid"
 
-#: plugins/sudoers/set_perms.c:245 plugins/sudoers/set_perms.c:478
-#: plugins/sudoers/set_perms.c:715
+#: plugins/sudoers/set_perms.c:250 plugins/sudoers/set_perms.c:486
+#: plugins/sudoers/set_perms.c:726
 #, c-format
 msgid "unable to change to sudoers gid"
 msgstr "kan ikke ændre til sudoers gid"
 
-#: plugins/sudoers/set_perms.c:286 plugins/sudoers/set_perms.c:516
-#: plugins/sudoers/set_perms.c:753 plugins/sudoers/set_perms.c:893
+#: plugins/sudoers/set_perms.c:291 plugins/sudoers/set_perms.c:524
+#: plugins/sudoers/set_perms.c:764 plugins/sudoers/set_perms.c:906
 msgid "too many processes"
 msgstr "for mange processer"
 
-#: plugins/sudoers/set_perms.c:955
+#: plugins/sudoers/set_perms.c:970
 msgid "unable to set runas group vector"
 msgstr "kan ikke angive kør som gruppevektor"
 
-#: plugins/sudoers/sudo_nss.c:238
+#: plugins/sudoers/sudo_nss.c:243
 #, c-format
 msgid "Matching Defaults entries for %s on this host:\n"
 msgstr "Matchende standardpunkter for %s på denne vært:\n"
 
-#: plugins/sudoers/sudo_nss.c:251
+#: plugins/sudoers/sudo_nss.c:256
 #, c-format
 msgid "Runas and Command-specific defaults for %s:\n"
 msgstr "Kør som og kommandospecifikke standarder for %s:\n"
 
-#: plugins/sudoers/sudo_nss.c:264
+#: plugins/sudoers/sudo_nss.c:269
 #, c-format
 msgid "User %s may run the following commands on this host:\n"
 msgstr "Bruger %s må ikke køre de følgende kommandoer på denne vært:\n"
 
-#: plugins/sudoers/sudo_nss.c:274
+#: plugins/sudoers/sudo_nss.c:279
 #, c-format
 msgid "User %s is not allowed to run sudo on %s.\n"
 msgstr "Bruger %s har ikke tilladelse til at køre sudo på %s.\n"
 
-#: plugins/sudoers/sudoers.c:199 plugins/sudoers/sudoers.c:234
-#: plugins/sudoers/sudoers.c:911
+#: plugins/sudoers/sudoers.c:201 plugins/sudoers/sudoers.c:232
+#: plugins/sudoers/sudoers.c:931
 msgid "problem with defaults entries"
 msgstr "problem med standardpunkter"
 
-#: plugins/sudoers/sudoers.c:203
+#: plugins/sudoers/sudoers.c:205
 #, c-format
 msgid "no valid sudoers sources found, quitting"
 msgstr "ingen gyldige sudoerskilder fundet, afslutter"
@@ -971,42 +975,42 @@ msgstr "ingen gyldige sudoerskilder fundet, afslutter"
 msgid "unable to execute %s: %s"
 msgstr "kan ikke udføre %s: %s"
 
-#: plugins/sudoers/sudoers.c:306
+#: plugins/sudoers/sudoers.c:311
 #, c-format
 msgid "sudoers specifies that root is not allowed to sudo"
 msgstr "sudoers angiver at administrator (root) ikke har tilladelse til sudo"
 
-#: plugins/sudoers/sudoers.c:313
+#: plugins/sudoers/sudoers.c:318
 #, c-format
 msgid "you are not permitted to use the -C option"
 msgstr "du har ikke tilladelse til at bruge tilvalget -C"
 
-#: plugins/sudoers/sudoers.c:403
+#: plugins/sudoers/sudoers.c:408
 #, c-format
 msgid "timestamp owner (%s): No such user"
 msgstr "tidsstempelejer (%s): Ingen sådan bruger"
 
-#: plugins/sudoers/sudoers.c:419
+#: plugins/sudoers/sudoers.c:424
 msgid "no tty"
 msgstr "ingen tty"
 
-#: plugins/sudoers/sudoers.c:420
+#: plugins/sudoers/sudoers.c:425
 #, c-format
 msgid "sorry, you must have a tty to run sudo"
 msgstr "beklager, du skal bruge en tty for at køre sudo"
 
-#: plugins/sudoers/sudoers.c:463
+#: plugins/sudoers/sudoers.c:464
 msgid "No user or host"
 msgstr "Ingen bruger eller vært"
 
-#: plugins/sudoers/sudoers.c:477 plugins/sudoers/sudoers.c:498
-#: plugins/sudoers/sudoers.c:499 plugins/sudoers/sudoers.c:1465
-#: plugins/sudoers/sudoers.c:1466
+#: plugins/sudoers/sudoers.c:478 plugins/sudoers/sudoers.c:499
+#: plugins/sudoers/sudoers.c:500 plugins/sudoers/sudoers.c:1509
+#: plugins/sudoers/sudoers.c:1510
 #, c-format
 msgid "%s: command not found"
 msgstr "%s: Kommando ikke fundet"
 
-#: plugins/sudoers/sudoers.c:479 plugins/sudoers/sudoers.c:495
+#: plugins/sudoers/sudoers.c:480 plugins/sudoers/sudoers.c:496
 #, c-format
 msgid ""
 "ignoring `%s' found in '.'\n"
@@ -1015,95 +1019,100 @@ msgstr ""
 "ignorerer »%s« fundet i ».«\n"
 "Brug »sudo ./%s« hvis dette er »%s«, du ønsker at køre."
 
-#: plugins/sudoers/sudoers.c:484
+#: plugins/sudoers/sudoers.c:485
 msgid "validation failure"
 msgstr "valideringsfejl"
 
-#: plugins/sudoers/sudoers.c:494
+#: plugins/sudoers/sudoers.c:495
 msgid "command in current directory"
 msgstr "kommando i aktuel mappe"
 
-#: plugins/sudoers/sudoers.c:506
+#: plugins/sudoers/sudoers.c:507
 #, c-format
 msgid "sorry, you are not allowed to preserve the environment"
 msgstr "beklager men du har ikke tilladelse til at bevare miljøet"
 
-#: plugins/sudoers/sudoers.c:894
+#: plugins/sudoers/sudoers.c:657 plugins/sudoers/sudoers.c:664
+#, c-format
+msgid "internal error, runas_groups overflow"
+msgstr "intern fejl, runas_groups-overløb"
+
+#: plugins/sudoers/sudoers.c:914
 #, c-format
 msgid "internal error, set_cmnd() overflow"
 msgstr "intern fejl, set_cmnd()-overløb"
 
-#: plugins/sudoers/sudoers.c:936
+#: plugins/sudoers/sudoers.c:957
 #, c-format
 msgid "fixed mode on %s"
 msgstr "fast tilstand på %s"
 
-#: plugins/sudoers/sudoers.c:940
+#: plugins/sudoers/sudoers.c:961
 #, c-format
 msgid "set group on %s"
 msgstr "angiv gruppe på %s"
 
-#: plugins/sudoers/sudoers.c:943
+#: plugins/sudoers/sudoers.c:964
 #, c-format
 msgid "unable to set group on %s"
 msgstr "kan ikke angive gruppe på %s"
 
-#: plugins/sudoers/sudoers.c:946
+#: plugins/sudoers/sudoers.c:967
 #, c-format
 msgid "unable to fix mode on %s"
 msgstr "kan ikke rette tilstand på %s"
 
-#: plugins/sudoers/sudoers.c:959
+#: plugins/sudoers/sudoers.c:980
 #, c-format
 msgid "%s is not a regular file"
 msgstr "%s er ikke en regulær fil"
 
-#: plugins/sudoers/sudoers.c:961
+#: plugins/sudoers/sudoers.c:982
 #, c-format
 msgid "%s is mode 0%o, should be 0%o"
 msgstr "%s er tilstand 0%o, bør være 0%o"
 
-#: plugins/sudoers/sudoers.c:965
+#: plugins/sudoers/sudoers.c:986
 #, c-format
 msgid "%s is owned by uid %u, should be %u"
 msgstr "%s er ejet af uid %u, bør være %u"
 
-#: plugins/sudoers/sudoers.c:968
+#: plugins/sudoers/sudoers.c:989
 #, c-format
 msgid "%s is owned by gid %u, should be %u"
 msgstr "%s er eget af gid %u, bør være %u"
 
-#: plugins/sudoers/sudoers.c:1012
+#: plugins/sudoers/sudoers.c:1038
 #, c-format
 msgid "only root can use `-c %s'"
 msgstr "kun administrator (root) kan bruge »-c %s«"
 
-#: plugins/sudoers/sudoers.c:1022
+#: plugins/sudoers/sudoers.c:1049
 #, c-format
 msgid "unknown login class: %s"
 msgstr "ukendt logindklasse: %s"
 
-#: plugins/sudoers/sudoers.c:1056
+#: plugins/sudoers/sudoers.c:1077
 #, c-format
 msgid "unable to resolve host %s"
 msgstr "kan ikke slå vært %s op"
 
-#: plugins/sudoers/sudoers.c:1106 plugins/sudoers/testsudoers.c:351
+#: plugins/sudoers/sudoers.c:1129 plugins/sudoers/testsudoers.c:380
 #, c-format
 msgid "unknown group: %s"
 msgstr "ukendt gruppe: %s"
 
-#: plugins/sudoers/sudoers.c:1150
+#: plugins/sudoers/sudoers.c:1178
 #, c-format
 msgid "Sudoers policy plugin version %s\n"
 msgstr "Udvidelsesmodulversion %s for sudoerspolitik\n"
 
-#: plugins/sudoers/sudoers.c:1152
+#: plugins/sudoers/sudoers.c:1180
 #, c-format
 msgid "Sudoers file grammar version %d\n"
 msgstr "Grammatikversion %d for sudoersfil\n"
 
-#: plugins/sudoers/sudoers.c:1156
+#: plugins/sudoers/sudoers.c:1184
 #, c-format
 msgid ""
 "\n"
@@ -1112,147 +1121,147 @@ msgstr ""
 "\n"
 "Sudoers-sti: %s\n"
 
-#: plugins/sudoers/sudoers.c:1159
+#: plugins/sudoers/sudoers.c:1187
 #, c-format
 msgid "nsswitch path: %s\n"
 msgstr "nsswitch-sti: %s\n"
 
-#: plugins/sudoers/sudoers.c:1161
+#: plugins/sudoers/sudoers.c:1189
 #, c-format
 msgid "ldap.conf path: %s\n"
 msgstr "ldap.conf-sti: %s\n"
 
-#: plugins/sudoers/sudoers.c:1162
+#: plugins/sudoers/sudoers.c:1190
 #, c-format
 msgid "ldap.secret path: %s\n"
 msgstr "ldap.secret-sti: %s\n"
 
-#: plugins/sudoers/sudoreplay.c:265
+#: plugins/sudoers/sudoreplay.c:286
 #, c-format
 msgid "invalid filter option: %s"
 msgstr "ugyldigt filtertilvalg: %s"
 
-#: plugins/sudoers/sudoreplay.c:278
+#: plugins/sudoers/sudoreplay.c:299
 #, c-format
 msgid "invalid max wait: %s"
 msgstr "ugyldig maks ventetid: %s"
 
-#: plugins/sudoers/sudoreplay.c:284
+#: plugins/sudoers/sudoreplay.c:305
 #, c-format
 msgid "invalid speed factor: %s"
 msgstr "ugyldig hastighedsfaktor: %s"
 
-#: plugins/sudoers/sudoreplay.c:287 plugins/sudoers/visudo.c:174
+#: plugins/sudoers/sudoreplay.c:308 plugins/sudoers/visudo.c:187
 #, c-format
 msgid "%s version %s\n"
 msgstr "%s version %s\n"
 
-#: plugins/sudoers/sudoreplay.c:310
+#: plugins/sudoers/sudoreplay.c:333
 #, c-format
 msgid "%s/%.2s/%.2s/%.2s/timing: %s"
 msgstr "%s/%.2s/%.2s/%.2s/timing: %s"
 
-#: plugins/sudoers/sudoreplay.c:316
+#: plugins/sudoers/sudoreplay.c:339
 #, c-format
 msgid "%s/%s/timing: %s"
 msgstr "%s/%s/timing: %s"
 
-#: plugins/sudoers/sudoreplay.c:341
+#: plugins/sudoers/sudoreplay.c:364
 #, c-format
 msgid "invalid log file %s"
 msgstr "ugyldig logfil %s"
 
-#: plugins/sudoers/sudoreplay.c:343
+#: plugins/sudoers/sudoreplay.c:366
 #, c-format
 msgid "Replaying sudo session: %s"
 msgstr "Genafspiller sudosession: %s"
 
-#: plugins/sudoers/sudoreplay.c:369
+#: plugins/sudoers/sudoreplay.c:392
 #, c-format
 msgid "unable to set tty to raw mode"
 msgstr "kan ikke angive tty til rå (raw) tilstand"
 
-#: plugins/sudoers/sudoreplay.c:383
+#: plugins/sudoers/sudoreplay.c:406
 #, c-format
 msgid "invalid timing file line: %s"
 msgstr "ugyldig timingfillinje: %s"
 
-#: plugins/sudoers/sudoreplay.c:425
+#: plugins/sudoers/sudoreplay.c:448
 #, c-format
 msgid "writing to standard output"
 msgstr "skriver til standarduddata"
 
-#: plugins/sudoers/sudoreplay.c:455
+#: plugins/sudoers/sudoreplay.c:480
 #, c-format
 msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
 msgstr "nanosleep: tv_sec %ld, tv_nsec %ld"
 
-#: plugins/sudoers/sudoreplay.c:503 plugins/sudoers/sudoreplay.c:528
+#: plugins/sudoers/sudoreplay.c:529 plugins/sudoers/sudoreplay.c:554
 #, c-format
 msgid "ambiguous expression \"%s\""
 msgstr "tvetydigt udtryk »%s«"
 
-#: plugins/sudoers/sudoreplay.c:545
+#: plugins/sudoers/sudoreplay.c:571
 #, c-format
 msgid "too many parenthesized expressions, max %d"
 msgstr "for mange udtryk i parentes, maks %d"
 
-#: plugins/sudoers/sudoreplay.c:556
+#: plugins/sudoers/sudoreplay.c:582
 #, c-format
 msgid "unmatched ')' in expression"
 msgstr "manglende »)« i udtryk"
 
-#: plugins/sudoers/sudoreplay.c:562
+#: plugins/sudoers/sudoreplay.c:588
 #, c-format
 msgid "unknown search term \"%s\""
 msgstr "ukendt søgeterm »%s«"
 
-#: plugins/sudoers/sudoreplay.c:576
+#: plugins/sudoers/sudoreplay.c:602
 #, c-format
 msgid "%s requires an argument"
 msgstr "%s kræver et argument"
 
-#: plugins/sudoers/sudoreplay.c:580
+#: plugins/sudoers/sudoreplay.c:606
 #, c-format
 msgid "invalid regular expression: %s"
 msgstr "ugyldigt regulært udtryk: %s"
 
-#: plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:612
 #, c-format
 msgid "could not parse date \"%s\""
 msgstr "kunne ikke fortolke dato »%s«"
 
-#: plugins/sudoers/sudoreplay.c:599
+#: plugins/sudoers/sudoreplay.c:625
 #, c-format
 msgid "unmatched '(' in expression"
 msgstr "mangler »(« i udtryk"
 
-#: plugins/sudoers/sudoreplay.c:601
+#: plugins/sudoers/sudoreplay.c:627
 #, c-format
 msgid "illegal trailing \"or\""
 msgstr "ugyldig kæde »or« (eller)"
 
-#: plugins/sudoers/sudoreplay.c:603
+#: plugins/sudoers/sudoreplay.c:629
 #, c-format
 msgid "illegal trailing \"!\""
 msgstr "ugyldig kæde »!«"
 
-#: plugins/sudoers/sudoreplay.c:819
+#: plugins/sudoers/sudoreplay.c:851
 #, c-format
 msgid "invalid regex: %s"
 msgstr "ugyldigt regulært udtryk: %s"
 
-#: plugins/sudoers/sudoreplay.c:941
+#: plugins/sudoers/sudoreplay.c:976
 #, c-format
 msgid "usage: %s [-h] [-d directory] [-m max_wait] [-s speed_factor] ID\n"
 msgstr "brug: %s [-h] [-d mappe] [-m maks_ventetid] [-s hastighedsfaktor] ID\n"
 
-#: plugins/sudoers/sudoreplay.c:944
+#: plugins/sudoers/sudoreplay.c:979
 #, c-format
 msgid "usage: %s [-h] [-d directory] -l [search expression]\n"
 msgstr "brug: %s [-h] [-d mappe] -l [søgeudtryk]\n"
 
-#: plugins/sudoers/sudoreplay.c:953
+#: plugins/sudoers/sudoreplay.c:988
 #, c-format
 msgid ""
 "%s - replay sudo session logs\n"
@@ -1261,7 +1270,7 @@ msgstr ""
 "%s - genafspil sudosessionslogge\n"
 "\n"
 
-#: plugins/sudoers/sudoreplay.c:955
+#: plugins/sudoers/sudoreplay.c:990
 msgid ""
 "\n"
 "Options:\n"
@@ -1284,16 +1293,16 @@ msgstr ""
 "  -s hastighedsfaktor øg eller sænk uddata\n"
 "  -V                  vis versionsinformation og afslut"
 
-#: plugins/sudoers/testsudoers.c:230
+#: plugins/sudoers/testsudoers.c:246
 #, c-format
 msgid "internal error, init_vars() overflow"
 msgstr "intern fejl, init_vars()-overløb"
 
-#: plugins/sudoers/testsudoers.c:309
+#: plugins/sudoers/testsudoers.c:331
 msgid "\thost  unmatched"
 msgstr "\thost  matchede ikke"
 
-#: plugins/sudoers/testsudoers.c:312
+#: plugins/sudoers/testsudoers.c:334
 msgid ""
 "\n"
 "Command allowed"
@@ -1301,7 +1310,7 @@ msgstr ""
 "\n"
 "Kommando tilladt"
 
-#: plugins/sudoers/testsudoers.c:313
+#: plugins/sudoers/testsudoers.c:335
 msgid ""
 "\n"
 "Command denied"
@@ -1309,7 +1318,7 @@ msgstr ""
 "\n"
 "Kommando nægtet"
 
-#: plugins/sudoers/testsudoers.c:313
+#: plugins/sudoers/testsudoers.c:335
 msgid ""
 "\n"
 "Command unmatched"
@@ -1317,104 +1326,104 @@ msgstr ""
 "\n"
 "Kommando ikke matchet"
 
-#: toke.l:667 toke.l:793 toke.l:818 toke.l:904 plugins/sudoers/toke_util.c:111
-#: plugins/sudoers/toke_util.c:163 plugins/sudoers/toke_util.c:202
+#: toke.l:672 toke.l:802 toke.l:827 toke.l:923 plugins/sudoers/toke_util.c:113
+#: plugins/sudoers/toke_util.c:167 plugins/sudoers/toke_util.c:207
 msgid "unable to allocate memory"
 msgstr "kan ikke allokere hukommelse"
 
-#: toke.l:786
+#: toke.l:795
 msgid "too many levels of includes"
 msgstr "for mange niveauer af includes (inkluderinger)"
 
-#: plugins/sudoers/toke_util.c:213
+#: plugins/sudoers/toke_util.c:218
 msgid "fill_args: buffer overflow"
 msgstr "fill_args: overløb for mellemlager"
 
-#: plugins/sudoers/visudo.c:175
+#: plugins/sudoers/visudo.c:188
 #, c-format
 msgid "%s grammar version %d\n"
 msgstr "%s grammatikversion %d\n"
 
-#: plugins/sudoers/visudo.c:208 plugins/sudoers/auth/rfc1938.c:103
+#: plugins/sudoers/visudo.c:221 plugins/sudoers/auth/rfc1938.c:104
 #, c-format
 msgid "you do not exist in the %s database"
 msgstr "du findes ikke i %s-databasen"
 
-#: plugins/sudoers/visudo.c:238 plugins/sudoers/visudo.c:518
+#: plugins/sudoers/visudo.c:253 plugins/sudoers/visudo.c:539
 #, c-format
 msgid "press return to edit %s: "
 msgstr "tryk retur for at redigere %s: "
 
-#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:326
+#: plugins/sudoers/visudo.c:336 plugins/sudoers/visudo.c:342
 #, c-format
 msgid "write error"
 msgstr "skrivefejl"
 
-#: plugins/sudoers/visudo.c:408
+#: plugins/sudoers/visudo.c:424
 #, c-format
 msgid "unable to stat temporary file (%s), %s unchanged"
 msgstr "kan ikke stat midlertidig fil (%s), %s unchanged"
 
-#: plugins/sudoers/visudo.c:413
+#: plugins/sudoers/visudo.c:429
 #, c-format
 msgid "zero length temporary file (%s), %s unchanged"
 msgstr "midlertidig fil med nullængde (%s), %s uændret"
 
-#: plugins/sudoers/visudo.c:419
+#: plugins/sudoers/visudo.c:435
 #, c-format
 msgid "editor (%s) failed, %s unchanged"
 msgstr "redigeringsprogram (%s) fejlede, %s uændret"
 
-#: plugins/sudoers/visudo.c:442
+#: plugins/sudoers/visudo.c:458
 #, c-format
 msgid "%s unchanged"
 msgstr "%s uændret"
 
-#: plugins/sudoers/visudo.c:466
+#: plugins/sudoers/visudo.c:484
 #, c-format
 msgid "unable to re-open temporary file (%s), %s unchanged."
 msgstr "kan ikke genåbne midlertidig fil (%s), %s uændrede."
 
-#: plugins/sudoers/visudo.c:476
+#: plugins/sudoers/visudo.c:494
 #, c-format
 msgid "unabled to parse temporary file (%s), unknown error"
 msgstr "kan ikke fortolke midlertidig fil (%s), ukendt fejl"
 
-#: plugins/sudoers/visudo.c:511
+#: plugins/sudoers/visudo.c:532
 #, c-format
 msgid "internal error, unable to find %s in list!"
 msgstr "intern fejl, kan ikke finde %s på listen!"
 
-#: plugins/sudoers/visudo.c:546 plugins/sudoers/visudo.c:555
+#: plugins/sudoers/visudo.c:584 plugins/sudoers/visudo.c:593
 #, c-format
 msgid "unable to set (uid, gid) of %s to (%u, %u)"
 msgstr "kan ikke angive (uid, gid) af %s til (%u, %u)"
 
-#: plugins/sudoers/visudo.c:550 plugins/sudoers/visudo.c:560
+#: plugins/sudoers/visudo.c:588 plugins/sudoers/visudo.c:598
 #, c-format
 msgid "unable to change mode of %s to 0%o"
 msgstr "kan ikke ændre tilstand på %s til 0%o"
 
-#: plugins/sudoers/visudo.c:577
+#: plugins/sudoers/visudo.c:615
 #, c-format
 msgid "%s and %s not on the same file system, using mv to rename"
 msgstr "%s og %s er ikke på det samme filsystem, bruger mv til at omdøbe"
 
-#: plugins/sudoers/visudo.c:591
+#: plugins/sudoers/visudo.c:629
 #, c-format
 msgid "command failed: '%s %s %s', %s unchanged"
 msgstr "kommando fejlede: »%s %s %s«, %s uændret"
 
-#: plugins/sudoers/visudo.c:601
+#: plugins/sudoers/visudo.c:639
 #, c-format
 msgid "error renaming %s, %s unchanged"
 msgstr "fejl under omdøbing af %s, %s uændret"
 
-#: plugins/sudoers/visudo.c:661
+#: plugins/sudoers/visudo.c:702
 msgid "What now? "
 msgstr "Hvad nu? "
 
-#: plugins/sudoers/visudo.c:675
+#: plugins/sudoers/visudo.c:716
 msgid ""
 "Options are:\n"
 "  (e)dit sudoers file again\n"
@@ -1426,92 +1435,92 @@ msgstr ""
 "  afslut(x) uden at gemme ændringer til sudoersfil\n"
 "  afslut(Q) og gem ændringer til sudoersfil (FARLIGT!)\n"
 
-#: plugins/sudoers/visudo.c:712
+#: plugins/sudoers/visudo.c:757
 #, c-format
 msgid "unable to execute %s"
 msgstr "kan ikke udføre %s"
 
-#: plugins/sudoers/visudo.c:719
+#: plugins/sudoers/visudo.c:764
 #, c-format
 msgid "unable to run %s"
 msgstr "kan ikke køre %s"
 
-#: plugins/sudoers/visudo.c:750
+#: plugins/sudoers/visudo.c:796
 #, c-format
 msgid "failed to parse %s file, unknown error"
 msgstr "kunne ikke fortolke %s-fil, ukendt fejl"
 
-#: plugins/sudoers/visudo.c:762
+#: plugins/sudoers/visudo.c:808
 #, c-format
 msgid "parse error in %s near line %d\n"
 msgstr "fortolkningsfejl i %s nær linje %d\n"
 
-#: plugins/sudoers/visudo.c:765
+#: plugins/sudoers/visudo.c:811
 #, c-format
 msgid "parse error in %s\n"
 msgstr "fortolkningsfejl i %s\n"
 
-#: plugins/sudoers/visudo.c:767
+#: plugins/sudoers/visudo.c:814 plugins/sudoers/visudo.c:816
 #, c-format
 msgid "%s: parsed OK\n"
 msgstr "%s: fortolket o.k.\n"
 
-#: plugins/sudoers/visudo.c:776
+#: plugins/sudoers/visudo.c:826
 #, c-format
 msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
 msgstr "%s: forkert ejer (uid, gid) bør være (%u, %u)\n"
 
-#: plugins/sudoers/visudo.c:783
+#: plugins/sudoers/visudo.c:833
 #, c-format
 msgid "%s: bad permissions, should be mode 0%o\n"
 msgstr "%s: ugyldige rettigheder, bør være tilstand 0%o\n"
 
-#: plugins/sudoers/visudo.c:822
+#: plugins/sudoers/visudo.c:880
 #, c-format
 msgid "%s busy, try again later"
 msgstr "%s travl, forsøg igen senere"
 
-#: plugins/sudoers/visudo.c:865
+#: plugins/sudoers/visudo.c:924
 #, c-format
 msgid "specified editor (%s) doesn't exist"
 msgstr "angivet redigeringsprogram (%s) findes ikke"
 
-#: plugins/sudoers/visudo.c:888
+#: plugins/sudoers/visudo.c:947
 #, c-format
 msgid "unable to stat editor (%s)"
 msgstr "kan ikke stat redigeringsprogram (%s)"
 
-#: plugins/sudoers/visudo.c:936
+#: plugins/sudoers/visudo.c:995
 #, c-format
 msgid "no editor found (editor path = %s)"
 msgstr "intet redigeringsprogram fundet (sti for redigeringsprogram = %s)"
 
-#: plugins/sudoers/visudo.c:1025
+#: plugins/sudoers/visudo.c:1089
 #, c-format
 msgid "Error: cycle in %s_Alias `%s'"
 msgstr "Fejl: Cyklus i %s_Alias »%s«"
 
-#: plugins/sudoers/visudo.c:1026
+#: plugins/sudoers/visudo.c:1090
 #, c-format
 msgid "Warning: cycle in %s_Alias `%s'"
 msgstr "Advarsel: Cyklus i %s_Alias »%s«"
 
-#: plugins/sudoers/visudo.c:1029
+#: plugins/sudoers/visudo.c:1093
 #, c-format
 msgid "Error: %s_Alias `%s' referenced but not defined"
 msgstr "Fejl: %s_Alias »%s« refereret men ikke defineret"
 
-#: plugins/sudoers/visudo.c:1030
+#: plugins/sudoers/visudo.c:1094
 #, c-format
 msgid "Warning: %s_Alias `%s' referenced but not defined"
 msgstr "Advarsel: %s_Alias »%s« refereret men ikke defineret"
 
-#: plugins/sudoers/visudo.c:1167
+#: plugins/sudoers/visudo.c:1229
 #, c-format
 msgid "%s: unused %s_Alias %s"
 msgstr "%s: ubrugt %s_Alias %s"
 
-#: plugins/sudoers/visudo.c:1224
+#: plugins/sudoers/visudo.c:1286
 #, c-format
 msgid ""
 "%s - safely edit the sudoers file\n"
@@ -1520,7 +1529,7 @@ msgstr ""
 "%s - rediger sikkert sudoersfilen\n"
 "\n"
 
-#: plugins/sudoers/visudo.c:1226
+#: plugins/sudoers/visudo.c:1288
 msgid ""
 "\n"
 "Options:\n"
@@ -1540,35 +1549,40 @@ msgstr ""
 "  -s          streng syntakskontrol\n"
 "  -V          vis information om version og afslut"
 
-#: plugins/sudoers/auth/bsdauth.c:64
+#: plugins/sudoers/auth/bsdauth.c:78
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "kan ikke hente logindklasse for bruger %s"
+
+#: plugins/sudoers/auth/bsdauth.c:84
 msgid "unable to begin bsd authentication"
 msgstr "kan ikke starte bsd-godkendelse"
 
-#: plugins/sudoers/auth/bsdauth.c:71
+#: plugins/sudoers/auth/bsdauth.c:92
 msgid "invalid authentication type"
 msgstr "ugyldig godkendelsestype"
 
-#: plugins/sudoers/auth/bsdauth.c:79
+#: plugins/sudoers/auth/bsdauth.c:101
 msgid "unable to setup authentication"
 msgstr "kan ikke opsætte godkendelse"
 
-#: plugins/sudoers/auth/fwtk.c:59
+#: plugins/sudoers/auth/fwtk.c:60
 #, c-format
 msgid "unable to read fwtk config"
 msgstr "kan ikke læse fwtk-konfiguration"
 
-#: plugins/sudoers/auth/fwtk.c:64
+#: plugins/sudoers/auth/fwtk.c:65
 #, c-format
 msgid "unable to connect to authentication server"
 msgstr "kan ikke forbinde til godkendelsesserver"
 
-#: plugins/sudoers/auth/fwtk.c:70 plugins/sudoers/auth/fwtk.c:93
-#: plugins/sudoers/auth/fwtk.c:126
+#: plugins/sudoers/auth/fwtk.c:71 plugins/sudoers/auth/fwtk.c:95
+#: plugins/sudoers/auth/fwtk.c:128
 #, c-format
 msgid "lost connection to authentication server"
 msgstr "mistede forbindelsen til godkendelseserveren"
 
-#: plugins/sudoers/auth/fwtk.c:74
+#: plugins/sudoers/auth/fwtk.c:75
 #, c-format
 msgid ""
 "authentication server error:\n"
@@ -1577,152 +1591,155 @@ msgstr ""
 "godkendelsesserverfejl:\n"
 "%s"
 
-#: plugins/sudoers/auth/kerb5.c:114
-#, c-format
-msgid "%s: unable to parse '%s': %s"
-msgstr "%s: Kan ikke fortolke »%s«: %s"
-
-#: plugins/sudoers/auth/kerb5.c:127
+#: plugins/sudoers/auth/kerb5.c:117
 #, c-format
 msgid "%s: unable to unparse princ ('%s'): %s"
 msgstr "%s: Kan ikke fjerne fortolkning af princ (»%s«): %s"
 
-#: plugins/sudoers/auth/kerb5.c:144
+#: plugins/sudoers/auth/kerb5.c:160
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: Kan ikke fortolke »%s«: %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
 #, c-format
 msgid "%s: unable to resolve ccache: %s"
 msgstr "%s: Kan ikke løse ccache: %s"
 
-#: plugins/sudoers/auth/kerb5.c:188
+#: plugins/sudoers/auth/kerb5.c:218
 #, c-format
 msgid "%s: unable to allocate options: %s"
 msgstr "%s: Kan ikke allokere tilvalg: %s"
 
-#: plugins/sudoers/auth/kerb5.c:204
+#: plugins/sudoers/auth/kerb5.c:234
 #, c-format
 msgid "%s: unable to get credentials: %s"
 msgstr "%s: Kan ikke indhente akkreditiver: %s"
 
-#: plugins/sudoers/auth/kerb5.c:217
+#: plugins/sudoers/auth/kerb5.c:247
 #, c-format
 msgid "%s: unable to initialize ccache: %s"
 msgstr "%s: Kan ikke initialisere ccache: %s"
 
-#: plugins/sudoers/auth/kerb5.c:221
+#: plugins/sudoers/auth/kerb5.c:251
 #, c-format
 msgid "%s: unable to store cred in ccache: %s"
 msgstr "%s: Kan ikke gemme cred i ccache: %s"
 
-#: plugins/sudoers/auth/kerb5.c:284
+#: plugins/sudoers/auth/kerb5.c:316
 #, c-format
 msgid "%s: unable to get host principal: %s"
 msgstr "%s: Kan ikke indhente værtshovedstol: %s"
 
-#: plugins/sudoers/auth/kerb5.c:299
+#: plugins/sudoers/auth/kerb5.c:331
 #, c-format
 msgid "%s: Cannot verify TGT! Possible attack!: %s"
 msgstr "%s: Kan ikke verifiere TGT! Muligt angreb!: %s"
 
-#: plugins/sudoers/auth/pam.c:99
+#: plugins/sudoers/auth/pam.c:100
 msgid "unable to initialize PAM"
 msgstr "kan ikke initialisere PAM"
 
-#: plugins/sudoers/auth/pam.c:142
+#: plugins/sudoers/auth/pam.c:144
 msgid "account validation failure, is your account locked?"
 msgstr "valideringsfejl for konto, er din konto låst?"
 
-#: plugins/sudoers/auth/pam.c:146
+#: plugins/sudoers/auth/pam.c:148
 msgid "Account or password is expired, reset your password and try again"
 msgstr "Konto eller adgangskoder er udløbet, nulstil din adgangskode og forsøg igen"
 
-#: plugins/sudoers/auth/pam.c:153
+#: plugins/sudoers/auth/pam.c:155
 #, c-format
 msgid "pam_chauthtok: %s"
 msgstr "pam_chauthtok: %s"
 
-#: plugins/sudoers/auth/pam.c:157
+#: plugins/sudoers/auth/pam.c:159
 msgid "Password expired, contact your system administrator"
 msgstr "Adgangskode udløbet, kontakt din systemadministrator"
 
-#: plugins/sudoers/auth/pam.c:161
+#: plugins/sudoers/auth/pam.c:163
 msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
 msgstr "Konto udløbet eller PAM-konfiguration mangler et »kontoafsnit« for sudo. Kontakt din systemadministrator"
 
-#: plugins/sudoers/auth/pam.c:176
+#: plugins/sudoers/auth/pam.c:178
 #, c-format
 msgid "pam_authenticate: %s"
 msgstr "pam_authenticate: %s"
 
-#: plugins/sudoers/auth/pam.c:296
+#: plugins/sudoers/auth/pam.c:306
 msgid "Password: "
 msgstr "Adgangskode: "
 
-#: plugins/sudoers/auth/pam.c:297
+#: plugins/sudoers/auth/pam.c:307
 msgid "Password:"
 msgstr "Adgangskode:"
 
-#: plugins/sudoers/auth/securid.c:82 plugins/sudoers/auth/securid5.c:106
-#, c-format
-msgid "unable to contact the SecurID server"
-msgstr "kan ikke kontakte SecurID-serveren"
-
 #: plugins/sudoers/auth/securid5.c:81
 #, c-format
 msgid "failed to initialise the ACE API library"
 msgstr "kunne ikke initialisere ACE API-biblioteket"
 
-#: plugins/sudoers/auth/securid5.c:115
+#: plugins/sudoers/auth/securid5.c:107
+#, c-format
+msgid "unable to contact the SecurID server"
+msgstr "kan ikke kontakte SecurID-serveren"
+
+#: plugins/sudoers/auth/securid5.c:116
 #, c-format
 msgid "User ID locked for SecurID Authentication"
 msgstr "Bruger-ID låst for SecurID-godkendelse"
 
-#: plugins/sudoers/auth/securid5.c:119 plugins/sudoers/auth/securid5.c:169
+#: plugins/sudoers/auth/securid5.c:120 plugins/sudoers/auth/securid5.c:171
 #, c-format
 msgid "invalid username length for SecurID"
 msgstr "ugyldigt brugernavnslængde for SecurID"
 
-#: plugins/sudoers/auth/securid5.c:123 plugins/sudoers/auth/securid5.c:174
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:176
 #, c-format
 msgid "invalid Authentication Handle for SecurID"
 msgstr "ugyldigt godkendelseshåndtag for SecurID"
 
-#: plugins/sudoers/auth/securid5.c:127
+#: plugins/sudoers/auth/securid5.c:128
 #, c-format
 msgid "SecurID communication failed"
 msgstr "SecurID-kommunikation fejlede"
 
-#: plugins/sudoers/auth/securid5.c:131 plugins/sudoers/auth/securid5.c:213
+#: plugins/sudoers/auth/securid5.c:132 plugins/sudoers/auth/securid5.c:215
 #, c-format
 msgid "unknown SecurID error"
 msgstr "ukendt SecurID-fejl"
 
-#: plugins/sudoers/auth/securid5.c:164
+#: plugins/sudoers/auth/securid5.c:166
 #, c-format
 msgid "invalid passcode length for SecurID"
 msgstr "ugyldig adgangskodelængde for SecurID"
 
-#: plugins/sudoers/auth/sia.c:106
+#: plugins/sudoers/auth/sia.c:109
 msgid "unable to initialize SIA session"
 msgstr "kan ikke initialisere SIA-session"
 
-#: plugins/sudoers/auth/sudo_auth.c:124
-msgid "There are no authentication methods compiled into sudo!  If you want to turn off authentication, use the --disable-authentication configure option."
-msgstr "Der er ingen godkendelsesmetoder kompileret ind i sudo! Hvis du ønsker at fravælge godkendelse så brug konfigurationstilvalget --disable-authentication."
-
-#: plugins/sudoers/auth/sudo_auth.c:134
+#: plugins/sudoers/auth/sudo_auth.c:117
 msgid "Invalid authentication methods compiled into sudo!  You may mix standalone and non-standalone authentication."
 msgstr "Ugyldige godkendelsesmetoder kompileret ind i sudo! Du kan blande alenestående og ikkealenestående godkendelse."
 
-#: plugins/sudoers/auth/sudo_auth.c:243
+#: plugins/sudoers/auth/sudo_auth.c:199
+msgid "There are no authentication methods compiled into sudo!  If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Der er ingen godkendelsesmetoder kompileret ind i sudo! Hvis du ønsker at fravælge godkendelse så brug konfigurationstilvalget --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:271
 #, c-format
 msgid "%d incorrect password attempt"
 msgid_plural "%d incorrect password attempts"
 msgstr[0] "%d ukorrekt adgangskodeforsøg"
 msgstr[1] "%d ukorrekte adgangskodeforsøg"
 
-#: plugins/sudoers/auth/sudo_auth.c:335
+#: plugins/sudoers/auth/sudo_auth.c:374
 msgid "Authentication methods:"
 msgstr "Godkendelsesmetoder:"
 
+#~ msgid "File containing dummy exec functions: %s"
+#~ msgstr "Fil der indeholder attrap-udførelsesfunktioner: %s"
+
 #~ msgid ""
 #~ "Available options in a sudoers ``Defaults'' line:\n"
 #~ "\n"
index fc6748a9f3a88a46af105ff8fc8820b19a4f3f7e..4cbf61286b531ab94d512c4c3232c2cc21912708 100644 (file)
Binary files a/plugins/sudoers/po/eo.mo and b/plugins/sudoers/po/eo.mo differ
index d73936ba1001b25be2d2fd44cc0e2976ffba3bd7..d59332d265bdf5de48216e44e7184b0d64f95380 100644 (file)
@@ -1,13 +1,13 @@
 # Esperanto translations for sudo package.
 # This file is put in the public domain.
-# Keith Bowes <zooplah@gmail.com>, 2011.
+# Keith Bowes <zooplah@gmail.com>, 2012.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: sudoers 1.8.3rc1\n"
+"Project-Id-Version: sudoers 1.8.4rc1\n"
 "Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
-"POT-Creation-Date: 2011-09-16 16:52-0400\n"
-"PO-Revision-Date: 2011-09-17 20:40-0400\n"
+"POT-Creation-Date: 2012-02-06 15:48-0500\n"
+"PO-Revision-Date: 2012-02-09 20:56-0500\n"
 "Last-Translator: Keith Bowes <zooplah@gmail.com>\n"
 "Language-Team: Esperanto <translation-team-eo@lists.sourceforge.net>\n"
 "Language: eo\n"
@@ -16,146 +16,146 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: plugins/sudoers/alias.c:122
+#: plugins/sudoers/alias.c:125
 #, c-format
 msgid "Alias `%s' already defined"
 msgstr "Kromnomo '%s' jam ekzistas"
 
-#: plugins/sudoers/bsm_audit.c:58 plugins/sudoers/bsm_audit.c:61
-#: plugins/sudoers/bsm_audit.c:109 plugins/sudoers/bsm_audit.c:113
-#: plugins/sudoers/bsm_audit.c:163 plugins/sudoers/bsm_audit.c:167
+#: plugins/sudoers/bsm_audit.c:61 plugins/sudoers/bsm_audit.c:64
+#: plugins/sudoers/bsm_audit.c:113 plugins/sudoers/bsm_audit.c:117
+#: plugins/sudoers/bsm_audit.c:169 plugins/sudoers/bsm_audit.c:173
 msgid "getaudit: failed"
 msgstr "getaudit: malsukcesis"
 
-#: plugins/sudoers/bsm_audit.c:87 plugins/sudoers/bsm_audit.c:148
+#: plugins/sudoers/bsm_audit.c:91 plugins/sudoers/bsm_audit.c:154
 msgid "Could not determine audit condition"
-msgstr "Ne eblis determini aŭdan kondiĉon"
+msgstr "Ne eblis determini revizian kondiĉon"
 
-#: plugins/sudoers/bsm_audit.c:98
+#: plugins/sudoers/bsm_audit.c:102
 msgid "getauid failed"
 msgstr "getauid: malsukcesis"
 
-#: plugins/sudoers/bsm_audit.c:100 plugins/sudoers/bsm_audit.c:157
+#: plugins/sudoers/bsm_audit.c:104 plugins/sudoers/bsm_audit.c:163
 msgid "au_open: failed"
 msgstr "au_open: malsukcesis"
 
-#: plugins/sudoers/bsm_audit.c:115 plugins/sudoers/bsm_audit.c:169
+#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:175
 msgid "au_to_subject: failed"
 msgstr "au_to_subject: malsukcesis"
 
-#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:173
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:179
 msgid "au_to_exec_args: failed"
 msgstr "au_to_exec_args: malsukcesis"
 
-#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:182
+#: plugins/sudoers/bsm_audit.c:127 plugins/sudoers/bsm_audit.c:188
 msgid "au_to_return32: failed"
 msgstr "getaudit: malsukcesis"
 
-#: plugins/sudoers/bsm_audit.c:126 plugins/sudoers/bsm_audit.c:185
+#: plugins/sudoers/bsm_audit.c:130 plugins/sudoers/bsm_audit.c:191
 msgid "unable to commit audit record"
-msgstr "ne eblis konservi aŭdan rekordon"
+msgstr "ne eblis konservi revizian rekordon"
 
-#: plugins/sudoers/bsm_audit.c:155
+#: plugins/sudoers/bsm_audit.c:161
 msgid "getauid: failed"
 msgstr "getauid: malsukcesis"
 
-#: plugins/sudoers/bsm_audit.c:178
+#: plugins/sudoers/bsm_audit.c:184
 msgid "au_to_text: failed"
 msgstr "au_to_text: malsukcesis"
 
-#: plugins/sudoers/check.c:141
+#: plugins/sudoers/check.c:158
 #, c-format
 msgid "sorry, a password is required to run %s"
 msgstr "bedaŭri pasvorto estas bezonata por plenumi: %s"
 
-#: plugins/sudoers/check.c:225 plugins/sudoers/iolog.c:169
-#: plugins/sudoers/sudoers.c:971 plugins/sudoers/sudoreplay.c:325
-#: plugins/sudoers/sudoreplay.c:334 plugins/sudoers/sudoreplay.c:675
-#: plugins/sudoers/sudoreplay.c:767 plugins/sudoers/visudo.c:744
+#: plugins/sudoers/check.c:249 plugins/sudoers/iolog.c:172
+#: plugins/sudoers/sudoers.c:992 plugins/sudoers/sudoreplay.c:348
+#: plugins/sudoers/sudoreplay.c:357 plugins/sudoers/sudoreplay.c:703
+#: plugins/sudoers/sudoreplay.c:797 plugins/sudoers/visudo.c:790
 #, c-format
 msgid "unable to open %s"
 msgstr "ne eblas malfermi: %s"
 
-#: plugins/sudoers/check.c:229 plugins/sudoers/iolog.c:199
+#: plugins/sudoers/check.c:253 plugins/sudoers/iolog.c:202
 #, c-format
 msgid "unable to write to %s"
 msgstr "ne eblas skribi al %s"
 
-#: plugins/sudoers/check.c:237 plugins/sudoers/check.c:475
-#: plugins/sudoers/check.c:525 plugins/sudoers/iolog.c:122
-#: plugins/sudoers/iolog.c:153
+#: plugins/sudoers/check.c:261 plugins/sudoers/check.c:506
+#: plugins/sudoers/check.c:556 plugins/sudoers/iolog.c:123
+#: plugins/sudoers/iolog.c:156
 #, c-format
 msgid "unable to mkdir %s"
 msgstr "ne eblas mkdir-i: %s"
 
-#: plugins/sudoers/check.c:370
+#: plugins/sudoers/check.c:396
 #, c-format
 msgid "internal error, expand_prompt() overflow"
-msgstr "ena eraro, expand_prompte() superfluo"
+msgstr "ena eraro, superfluo en expand_prompt()"
 
-#: plugins/sudoers/check.c:426
+#: plugins/sudoers/check.c:456
 #, c-format
 msgid "timestamp path too long: %s"
 msgstr "tempo-indikila pado tro longa: %s"
 
-#: plugins/sudoers/check.c:454 plugins/sudoers/check.c:498
-#: plugins/sudoers/iolog.c:155
+#: plugins/sudoers/check.c:485 plugins/sudoers/check.c:529
+#: plugins/sudoers/iolog.c:158
 #, c-format
 msgid "%s exists but is not a directory (0%o)"
 msgstr "%s ekzistas sed ne dosierujo (0%o)"
 
-#: plugins/sudoers/check.c:457 plugins/sudoers/check.c:501
-#: plugins/sudoers/check.c:546
+#: plugins/sudoers/check.c:488 plugins/sudoers/check.c:532
+#: plugins/sudoers/check.c:577
 #, c-format
 msgid "%s owned by uid %u, should be uid %u"
 msgstr "%s estas estrita de uid %u, devas esti uid %u"
 
-#: plugins/sudoers/check.c:462 plugins/sudoers/check.c:506
+#: plugins/sudoers/check.c:493 plugins/sudoers/check.c:537
 #, c-format
 msgid "%s writable by non-owner (0%o), should be mode 0700"
 msgstr "%s skribebla de ne-estro (0%o), devas esti reĝimo 0700"
 
-#: plugins/sudoers/check.c:470 plugins/sudoers/check.c:514
-#: plugins/sudoers/check.c:582 plugins/sudoers/sudoers.c:957
-#: plugins/sudoers/visudo.c:304 plugins/sudoers/visudo.c:544
+#: plugins/sudoers/check.c:501 plugins/sudoers/check.c:545
+#: plugins/sudoers/check.c:613 plugins/sudoers/sudoers.c:978
+#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:582
 #, c-format
 msgid "unable to stat %s"
 msgstr "ne eblas stat-i: %s"
 
-#: plugins/sudoers/check.c:540
+#: plugins/sudoers/check.c:571
 #, c-format
 msgid "%s exists but is not a regular file (0%o)"
-msgstr "%s ekzistas sed ne estas regula dosiero (0%o)"
+msgstr "%s ekzistas sed ne estas normala dosiero (0%o)"
 
-#: plugins/sudoers/check.c:552
+#: plugins/sudoers/check.c:583
 #, c-format
 msgid "%s writable by non-owner (0%o), should be mode 0600"
 msgstr "%s skribebla de ne-estro (0%o), devas esti reĝimo 0600"
 
-#: plugins/sudoers/check.c:606
+#: plugins/sudoers/check.c:637
 #, c-format
 msgid "timestamp too far in the future: %20.20s"
 msgstr "tempo-indikilo tro estonte: %20.20s"
 
-#: plugins/sudoers/check.c:652
+#: plugins/sudoers/check.c:684
 #, c-format
 msgid "unable to remove %s (%s), will reset to the epoch"
 msgstr "ne eblas forigi: %s (%s); restarigos al la epoko"
 
-#: plugins/sudoers/check.c:660
+#: plugins/sudoers/check.c:692
 #, c-format
 msgid "unable to reset %s to the epoch"
 msgstr "ne eblas restarigi al la epoko: %s"
 
-#: plugins/sudoers/check.c:714 plugins/sudoers/check.c:720
+#: plugins/sudoers/check.c:752 plugins/sudoers/check.c:758
+#: plugins/sudoers/sudoers.c:829 plugins/sudoers/sudoers.c:833
 #, c-format
 msgid "unknown uid: %u"
 msgstr "nekonata uid: %u"
 
-#: plugins/sudoers/check.c:717 plugins/sudoers/sudoers.c:748
-#: plugins/sudoers/sudoers.c:814 plugins/sudoers/sudoers.c:815
-#: plugins/sudoers/sudoers.c:1088 plugins/sudoers/testsudoers.c:202
-#: plugins/sudoers/testsudoers.c:337
+#: plugins/sudoers/check.c:755 plugins/sudoers/sudoers.c:770
+#: plugins/sudoers/sudoers.c:1108 plugins/sudoers/testsudoers.c:218
+#: plugins/sudoers/testsudoers.c:362
 #, c-format
 msgid "unknown user: %s"
 msgstr "nekonata uzanto: %s"
@@ -222,7 +222,7 @@ msgstr "Postulas, ke uzantoj konstatas aŭtomate"
 
 #: plugins/sudoers/def_data.c:83
 msgid "Root may run sudo"
-msgstr "Radiko rajtas plenumigi: sudo"
+msgstr "Ĉefuzanto rajtas plenumigi: sudo"
 
 #: plugins/sudoers/def_data.c:87
 msgid "Log the hostname in the (non-syslog) log file"
@@ -402,298 +402,296 @@ msgid "When to require a password for 'verify' pseudocommand: %s"
 msgstr "Kiam postuli pasvorton por la pseŭdokamando 'verify': %s"
 
 #: plugins/sudoers/def_data.c:243
-msgid "Preload the dummy exec functions contained in 'noexec_file'"
-msgstr "Anstaŭŝargi la falsan exec-funkciojn enhavatajn en 'noexec_file'"
+msgid "Preload the dummy exec functions contained in \"_PATH_SUDO_NOEXEC"
+msgstr "Anstaŭŝargi la falsan exec-funkciojn enhavatajn en \"_PATH_SUDO_NOEXEC"
 
 #: plugins/sudoers/def_data.c:247
-#, c-format
-msgid "File containing dummy exec functions: %s"
-msgstr "Dosiero enhavantaj falsajn exec-funkciojn: %s"
-
-#: plugins/sudoers/def_data.c:251
 msgid "If LDAP directory is up, do we ignore local sudoers file"
 msgstr "Se LDAP-dosierujo estas aktiva, ni ignoru la lokan suders-dosieron"
 
-#: plugins/sudoers/def_data.c:255
+#: plugins/sudoers/def_data.c:251
 #, c-format
 msgid "File descriptors >= %d will be closed before executing a command"
 msgstr "Dosiero-priskribiloj >= %d fermiĝos antaŭ ol plenumigi komandon"
 
-#: plugins/sudoers/def_data.c:259
+#: plugins/sudoers/def_data.c:255
 msgid "If set, users may override the value of `closefrom' with the -C option"
 msgstr "Se aktiva, uzantoj rajtas superregi la voloron de 'closefrom' per la parametro -C"
 
-#: plugins/sudoers/def_data.c:263
+#: plugins/sudoers/def_data.c:259
 msgid "Allow users to set arbitrary environment variables"
 msgstr "Permesi, ke uzantoj valorizu arbitrajn medivariablojn"
 
-#: plugins/sudoers/def_data.c:267
+#: plugins/sudoers/def_data.c:263
 msgid "Reset the environment to a default set of variables"
 msgstr "Restarigi la medion al apriora aro da variabloj"
 
-#: plugins/sudoers/def_data.c:271
+#: plugins/sudoers/def_data.c:267
 msgid "Environment variables to check for sanity:"
 msgstr "Medivariabloj por kontroli por sano:"
 
-#: plugins/sudoers/def_data.c:275
+#: plugins/sudoers/def_data.c:271
 msgid "Environment variables to remove:"
 msgstr "Medivariabloj por forigi:"
 
-#: plugins/sudoers/def_data.c:279
+#: plugins/sudoers/def_data.c:275
 msgid "Environment variables to preserve:"
 msgstr "Medivariabloj konservi:"
 
-#: plugins/sudoers/def_data.c:283
+#: plugins/sudoers/def_data.c:279
 #, c-format
 msgid "SELinux role to use in the new security context: %s"
 msgstr "SELinux-rolo por uzi en la nova sekureca kunteksto: %s"
 
-#: plugins/sudoers/def_data.c:287
+#: plugins/sudoers/def_data.c:283
 #, c-format
 msgid "SELinux type to use in the new security context: %s"
 msgstr "SELinux-tipo por uzi en la nova sekureca kunteksto: %s"
 
-#: plugins/sudoers/def_data.c:291
+#: plugins/sudoers/def_data.c:287
 #, c-format
 msgid "Path to the sudo-specific environment file: %s"
 msgstr "Pado al media dosiero specifa al sudo: %s"
 
-#: plugins/sudoers/def_data.c:295
+#: plugins/sudoers/def_data.c:291
 #, c-format
 msgid "Locale to use while parsing sudoers: %s"
 msgstr "Lokaĵaro por uzi dum analizi dosieron sudoers: %s"
 
-#: plugins/sudoers/def_data.c:299
-msgid "Allow sudo to prompt for a password even if it would be visisble"
-msgstr "Permesi, ke sudo peti pasvorton eĉ se ĝi estus nevidebla"
+#: plugins/sudoers/def_data.c:295
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Permesi, ke sudo peti pasvorton eĉ se ĝi estus videbla"
 
-#: plugins/sudoers/def_data.c:303
+#: plugins/sudoers/def_data.c:299
 msgid "Provide visual feedback at the password prompt when there is user input"
 msgstr "Doni vidajn indikojn je la pasvorta enmetanta kiam ekzistas enmeto"
 
-#: plugins/sudoers/def_data.c:307
+#: plugins/sudoers/def_data.c:303
 msgid "Use faster globbing that is less accurate but does not access the filesystem"
 msgstr "Uzi pli rapida kunigo, kiu estas malpli ĝusta sed ne atingas la dosiersistemon"
 
-#: plugins/sudoers/def_data.c:311
+#: plugins/sudoers/def_data.c:307
 msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
 msgstr "La umask specifa en sudors superregos tio de la uzanto, eĉ se ĝi estas pli permesema."
 
-#: plugins/sudoers/def_data.c:315
+#: plugins/sudoers/def_data.c:311
 msgid "Log user's input for the command being run"
 msgstr "Protokoli enmeton de uzanto por la komando, kiun si plenumigas"
 
-#: plugins/sudoers/def_data.c:319
+#: plugins/sudoers/def_data.c:315
 msgid "Log the output of the command being run"
 msgstr "Protokoli la eligon de la komando, kiu estas plenumiĝi"
 
-#: plugins/sudoers/def_data.c:323
+#: plugins/sudoers/def_data.c:319
 msgid "Compress I/O logs using zlib"
 msgstr "Kunpremi eneligaj protokoloj per  zlib"
 
-#: plugins/sudoers/def_data.c:327
+#: plugins/sudoers/def_data.c:323
 msgid "Always run commands in a pseudo-tty"
 msgstr "Ĉiam protokoli komandojn en pseŭda tty"
 
+#: plugins/sudoers/def_data.c:327
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Kromprogramo por kompreno de ne-uniksaj grupoj: %s"
+
 #: plugins/sudoers/def_data.c:331
-msgid "Plugin for non-Unix group support"
-msgstr "Kromprogramo por kompreno de ne-uniksaj grupoj"
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Dosierujo en kiu konservi eneligaj protokoloj: %s"
 
 #: plugins/sudoers/def_data.c:335
-msgid "Directory in which to store input/output logs"
-msgstr "Dosierujo en kiu konservi eneligaj protokoloj"
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Dosiero en kiu konservi la eneliga protokolo: %s"
 
 #: plugins/sudoers/def_data.c:339
-msgid "File in which to store the input/output log"
-msgstr "Dosiero en kiu konservi la eneliga protokolo"
-
-#: plugins/sudoers/def_data.c:343
 msgid "Add an entry to the utmp/utmpx file when allocating a pty"
 msgstr "Aldoni eron al la utmp/utmpx-dosiero dum generi pty-on"
 
-#: plugins/sudoers/def_data.c:347
+#: plugins/sudoers/def_data.c:343
 msgid "Set the user in utmp to the runas user, not the invoking user"
 msgstr "Valorizi uzanton en utmp al la plenumigkiela uzanto, ne la vokanta uzanto"
 
-#: plugins/sudoers/defaults.c:205
+#: plugins/sudoers/defaults.c:208
 #, c-format
 msgid "unknown defaults entry `%s'"
 msgstr "nekonata ero '%s' en defaults"
 
-#: plugins/sudoers/defaults.c:213 plugins/sudoers/defaults.c:223
-#: plugins/sudoers/defaults.c:243 plugins/sudoers/defaults.c:256
-#: plugins/sudoers/defaults.c:269 plugins/sudoers/defaults.c:282
-#: plugins/sudoers/defaults.c:295 plugins/sudoers/defaults.c:315
-#: plugins/sudoers/defaults.c:325
+#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
+#: plugins/sudoers/defaults.c:246 plugins/sudoers/defaults.c:259
+#: plugins/sudoers/defaults.c:272 plugins/sudoers/defaults.c:285
+#: plugins/sudoers/defaults.c:298 plugins/sudoers/defaults.c:318
+#: plugins/sudoers/defaults.c:328
 #, c-format
 msgid "value `%s' is invalid for option `%s'"
 msgstr "valoro '%s' estas nevalida por parametro '%s'"
 
-#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
-#: plugins/sudoers/defaults.c:234 plugins/sudoers/defaults.c:251
-#: plugins/sudoers/defaults.c:264 plugins/sudoers/defaults.c:277
-#: plugins/sudoers/defaults.c:290 plugins/sudoers/defaults.c:310
-#: plugins/sudoers/defaults.c:321
+#: plugins/sudoers/defaults.c:219 plugins/sudoers/defaults.c:229
+#: plugins/sudoers/defaults.c:237 plugins/sudoers/defaults.c:254
+#: plugins/sudoers/defaults.c:267 plugins/sudoers/defaults.c:280
+#: plugins/sudoers/defaults.c:293 plugins/sudoers/defaults.c:313
+#: plugins/sudoers/defaults.c:324
 #, c-format
 msgid "no value specified for `%s'"
 msgstr "neniu valoro specifita por '%s'"
 
-#: plugins/sudoers/defaults.c:239
+#: plugins/sudoers/defaults.c:242
 #, c-format
 msgid "values for `%s' must start with a '/'"
 msgstr "Valoroj por '%s' devas komenciĝi per '/'"
 
-#: plugins/sudoers/defaults.c:301
+#: plugins/sudoers/defaults.c:304
 #, c-format
 msgid "option `%s' does not take a value"
 msgstr "parametro '%s' ne povas havi valoron"
 
-#: plugins/sudoers/env.c:259
+#: plugins/sudoers/env.c:258
 #, c-format
 msgid "internal error, sudo_setenv() overflow"
-msgstr "ena eraro, sudo_setenv() superfluo"
+msgstr "ena eraro, superfluo en sudo_setenv()"
 
-#: plugins/sudoers/env.c:289
+#: plugins/sudoers/env.c:291
 #, c-format
 msgid "sudo_putenv: corrupted envp, length mismatch"
 msgstr "sudo_putenv: medio tro granda"
 
-#: plugins/sudoers/env.c:698
+#: plugins/sudoers/env.c:710
 #, c-format
 msgid "sorry, you are not allowed to set the following environment variables: %s"
 msgstr "bedaŭre vi ne estas permesata valorizi la jenajn medivariablojn: %s"
 
-#: plugins/sudoers/find_path.c:68 plugins/sudoers/find_path.c:107
-#: plugins/sudoers/find_path.c:122 plugins/sudoers/iolog.c:124
-#: plugins/sudoers/sudoers.c:903 toke.l:663 toke.l:814
+#: plugins/sudoers/find_path.c:69 plugins/sudoers/find_path.c:108
+#: plugins/sudoers/find_path.c:123 plugins/sudoers/iolog.c:125
+#: plugins/sudoers/sudoers.c:923 toke.l:668 toke.l:823
 #, c-format
 msgid "%s: %s"
 msgstr "%s: %s"
 
-#: gram.y:103
+#: gram.y:110
 #, c-format
 msgid ">>> %s: %s near line %d <<<"
 msgstr ">>> %s: %s apud linio %d <<<"
 
-#: plugins/sudoers/group_plugin.c:90
+#: plugins/sudoers/group_plugin.c:91
 #, c-format
 msgid "%s%s: %s"
 msgstr "%s%s: %s"
 
-#: plugins/sudoers/group_plugin.c:102
+#: plugins/sudoers/group_plugin.c:103
 #, c-format
 msgid "%s must be owned by uid %d"
 msgstr "%s devas esti estrata de uid %d"
 
-#: plugins/sudoers/group_plugin.c:106
+#: plugins/sudoers/group_plugin.c:107
 #, c-format
 msgid "%s must only be writable by owner"
 msgstr "%s devas esti skribebla nur de estro"
 
-#: plugins/sudoers/group_plugin.c:113
+#: plugins/sudoers/group_plugin.c:114
 #, c-format
 msgid "unable to dlopen %s: %s"
 msgstr "ne eblas dlopen: %s: %s"
 
-#: plugins/sudoers/group_plugin.c:118
+#: plugins/sudoers/group_plugin.c:119
 #, c-format
 msgid "unable to find symbol \"group_plugin\" in %s"
 msgstr "ne eblas trovi simbolon \"group_plugin\" en %s"
 
-#: plugins/sudoers/group_plugin.c:123
+#: plugins/sudoers/group_plugin.c:124
 #, c-format
 msgid "%s: incompatible group plugin major version %d, expected %d"
 msgstr "%s: nekongrua grupa kromprogramo: ĉefa eldono %d, atendita %d"
 
-#: plugins/sudoers/interfaces.c:109
+#: plugins/sudoers/interfaces.c:112
 msgid "Local IP address and netmask pairs:\n"
 msgstr "Loka IP-adresa kaj retmaska paroj:\n"
 
-#: plugins/sudoers/iolog.c:176 plugins/sudoers/sudoers.c:978
+#: plugins/sudoers/iolog.c:179 plugins/sudoers/sudoers.c:999
 #, c-format
 msgid "unable to read %s"
 msgstr "ne eblas legi %s"
 
-#: plugins/sudoers/iolog.c:179
+#: plugins/sudoers/iolog.c:182
 #, c-format
 msgid "invalid sequence number %s"
 msgstr "nevalida sinsekva numero %s"
 
-#: plugins/sudoers/iolog.c:225 plugins/sudoers/iolog.c:228
-#: plugins/sudoers/iolog.c:478 plugins/sudoers/iolog.c:483
-#: plugins/sudoers/iolog.c:489 plugins/sudoers/iolog.c:497
-#: plugins/sudoers/iolog.c:505 plugins/sudoers/iolog.c:513
-#: plugins/sudoers/iolog.c:521
+#: plugins/sudoers/iolog.c:231 plugins/sudoers/iolog.c:234
+#: plugins/sudoers/iolog.c:499 plugins/sudoers/iolog.c:504
+#: plugins/sudoers/iolog.c:510 plugins/sudoers/iolog.c:518
+#: plugins/sudoers/iolog.c:526 plugins/sudoers/iolog.c:534
+#: plugins/sudoers/iolog.c:542
 #, c-format
 msgid "unable to create %s"
 msgstr "ne eblas krei: %s"
 
-#: plugins/sudoers/iolog_path.c:247 plugins/sudoers/sudoers.c:357
+#: plugins/sudoers/iolog_path.c:256 plugins/sudoers/sudoers.c:362
 #, c-format
 msgid "unable to set locale to \"%s\", using \"C\""
 msgstr "ne eblas elekti lokaĵaron \"%s\", uzanta lokaĵaron \"C\""
 
-#: plugins/sudoers/ldap.c:368
+#: plugins/sudoers/ldap.c:374
 #, c-format
 msgid "sudo_ldap_conf_add_ports: port too large"
 msgstr "sudo_ldap_conf_add_ports: pordo tro granda"
 
-#: plugins/sudoers/ldap.c:391
+#: plugins/sudoers/ldap.c:397
 #, c-format
 msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
 msgstr "sudo_ldap_conf_add_ports: eluzis spacon etendanta la bufron"
 
-#: plugins/sudoers/ldap.c:420
+#: plugins/sudoers/ldap.c:427
 #, c-format
 msgid "unsupported LDAP uri type: %s"
 msgstr "nekonata retadresa tipo de LDAP: %s"
 
-#: plugins/sudoers/ldap.c:449
+#: plugins/sudoers/ldap.c:456
 #, c-format
 msgid "invalid uri: %s"
 msgstr "nevalida retadreso: %s"
 
-#: plugins/sudoers/ldap.c:455
+#: plugins/sudoers/ldap.c:462
 #, c-format
 msgid "unable to mix ldap and ldaps URIs"
 msgstr "ne eblas miksi sekurajn kaj nesekurajn retadresojn de LDAP"
 
-#: plugins/sudoers/ldap.c:459
+#: plugins/sudoers/ldap.c:466
 #, c-format
 msgid "unable to mix ldaps and starttls"
 msgstr "ne eblas miksi protokolojn ldaps kaj starttls"
 
-#: plugins/sudoers/ldap.c:478
+#: plugins/sudoers/ldap.c:485
 #, c-format
 msgid "sudo_ldap_parse_uri: out of space building hostbuf"
 msgstr "sudo_ldap_parse_uri: eluzis spacon muntanta la bufron"
 
-#: plugins/sudoers/ldap.c:541
+#: plugins/sudoers/ldap.c:550
 #, c-format
 msgid "unable to initialize SSL cert and key db: %s"
 msgstr "ne eblas iniciati SSL-asertilon kaj ŝlosilan datumbazon: %s"
 
-#: plugins/sudoers/ldap.c:937
+#: plugins/sudoers/ldap.c:958
 #, c-format
 msgid "unable to get GMT time"
 msgstr "ne eblas atingi GMT-tempon"
 
-#: plugins/sudoers/ldap.c:943
+#: plugins/sudoers/ldap.c:964
 #, c-format
 msgid "unable to format timestamp"
 msgstr "ne eblas aranĝi tempostampon"
 
-#: plugins/sudoers/ldap.c:951
+#: plugins/sudoers/ldap.c:972
 #, c-format
 msgid "unable to build time filter"
 msgstr "ne eblas munti tempan filtrilon"
 
-#: plugins/sudoers/ldap.c:1052
+#: plugins/sudoers/ldap.c:1185
 #, c-format
 msgid "sudo_ldap_build_pass1 allocation mismatch"
 msgstr "sudo_ldap_build_pass1: genra malkongruaĵo"
 
-#: plugins/sudoers/ldap.c:1562
+#: plugins/sudoers/ldap.c:1705
 #, c-format
 msgid ""
 "\n"
@@ -702,7 +700,7 @@ msgstr ""
 "\n"
 "LDAP-rolo: %s\n"
 
-#: plugins/sudoers/ldap.c:1564
+#: plugins/sudoers/ldap.c:1707
 #, c-format
 msgid ""
 "\n"
@@ -711,124 +709,129 @@ msgstr ""
 "\n"
 "LDAP-rolo: NEKONATA\n"
 
-#: plugins/sudoers/ldap.c:1611
+#: plugins/sudoers/ldap.c:1754
 #, c-format
 msgid "    Order: %s\n"
 msgstr "    Ordo: %s\n"
 
-#: plugins/sudoers/ldap.c:1619
+#: plugins/sudoers/ldap.c:1762
 #, c-format
 msgid "    Commands:\n"
 msgstr "    Komandoj:\n"
 
-#: plugins/sudoers/ldap.c:2006
+#: plugins/sudoers/ldap.c:2161
 #, c-format
 msgid "unable to initialize LDAP: %s"
 msgstr "ne eblas iniciati LDAP-on: %s"
 
-#: plugins/sudoers/ldap.c:2037
+#: plugins/sudoers/ldap.c:2192
 #, c-format
 msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
 msgstr "start_tls specifita sed LDAP-bibliotekoj ne havas la funkciojn ldap_start_tls_s() kaj ldap_start_tls_s_np()"
 
-#: plugins/sudoers/ldap.c:2268
+#: plugins/sudoers/ldap.c:2428
 #, c-format
 msgid "invalid sudoOrder attribute: %s"
 msgstr "nevalida atributo de sudoOrdo: %s"
 
-#: plugins/sudoers/linux_audit.c:55
+#: plugins/sudoers/linux_audit.c:57
 #, c-format
 msgid "unable to open audit system"
-msgstr "ne eblas malfermi aŭdan sistemon"
+msgstr "ne eblas malfermi revizian sistemon"
 
-#: plugins/sudoers/linux_audit.c:79
+#: plugins/sudoers/linux_audit.c:82
 #, c-format
 msgid "internal error, linux_audit_command() overflow"
-msgstr "ena eraro, linux_audit_command() superfluo"
+msgstr "ena eraro, superfluo en linux_audit_command()"
 
-#: plugins/sudoers/linux_audit.c:88
+#: plugins/sudoers/linux_audit.c:91
 #, c-format
 msgid "unable to send audit message"
-msgstr "ne eblas sendi aŭdan mesaĝon"
+msgstr "ne eblas sendi revizian mesaĝon"
 
-#: plugins/sudoers/logging.c:192
+#: plugins/sudoers/logging.c:198
 #, c-format
 msgid "unable to open log file: %s: %s"
 msgstr "ne eblas malfermi protokolon: %s: %s"
 
-#: plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:201
 #, c-format
 msgid "unable to lock log file: %s: %s"
 msgstr "ne eblas ŝlosi protokolon: %s: %s"
 
-#: plugins/sudoers/logging.c:249
+#: plugins/sudoers/logging.c:256
 msgid "user NOT in sudoers"
-msgstr "uzanto NE en sudoers"
+msgstr "uzanto NE estas en sudoers"
 
-#: plugins/sudoers/logging.c:251
+#: plugins/sudoers/logging.c:258
 msgid "user NOT authorized on host"
 msgstr "uzanto NE permesata en gastiganto"
 
-#: plugins/sudoers/logging.c:253
+#: plugins/sudoers/logging.c:260
 msgid "command not allowed"
 msgstr "komando ne permesata"
 
-#: plugins/sudoers/logging.c:263
+#: plugins/sudoers/logging.c:270
 #, c-format
 msgid "%s is not in the sudoers file.  This incident will be reported.\n"
 msgstr "%s ne estas en la dosiero sudoers. Ĉi tiu estos raportita.\n"
 
-#: plugins/sudoers/logging.c:266
+#: plugins/sudoers/logging.c:273
 #, c-format
 msgid "%s is not allowed to run sudo on %s.  This incident will be reported.\n"
 msgstr "%s estas ne permesata plenumigi sudo-on en %s. Ĉi tio estos raportita\n"
 
-#: plugins/sudoers/logging.c:270
+#: plugins/sudoers/logging.c:277
 #, c-format
 msgid "Sorry, user %s may not run sudo on %s.\n"
 msgstr "Bedaŭre uzanto %s ne rajtas plenumigi  sudo-on en %s.\n"
 
-#: plugins/sudoers/logging.c:273
+#: plugins/sudoers/logging.c:280
 #, c-format
 msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
 msgstr "Bedaŭre uzanto %s ne rajtas plenumigi '%s%s%s'-on kiel %s%s%s en %s.\n"
 
-#: plugins/sudoers/logging.c:408
+#: plugins/sudoers/logging.c:420
 #, c-format
 msgid "unable to fork"
 msgstr "ne eblas forki"
 
-#: plugins/sudoers/logging.c:415 plugins/sudoers/logging.c:472
+#: plugins/sudoers/logging.c:427 plugins/sudoers/logging.c:489
 #, c-format
 msgid "unable to fork: %m"
 msgstr "ne eblas forki: %m"
 
-#: plugins/sudoers/logging.c:465
+#: plugins/sudoers/logging.c:479
 #, c-format
 msgid "unable to open pipe: %m"
 msgstr "ne eblas malfermi tubon: %m"
 
-#: plugins/sudoers/logging.c:484
+#: plugins/sudoers/logging.c:504
 #, c-format
 msgid "unable to dup stdin: %m"
 msgstr "ne eblas kopii enigon: %m"
 
-#: plugins/sudoers/logging.c:518
+#: plugins/sudoers/logging.c:540
 #, c-format
 msgid "unable to execute %s: %m"
 msgstr "ne eblas plenumigi %s-on: %m"
 
-#: plugins/sudoers/logging.c:728
+#: plugins/sudoers/logging.c:755
 #, c-format
 msgid "internal error: insufficient space for log line"
 msgstr "ena eraro: nesufiĉa spaco por protokola linio"
 
-#: plugins/sudoers/parse.c:115
+#: plugins/sudoers/parse.c:123
 #, c-format
 msgid "parse error in %s near line %d"
 msgstr "analiza eraro en %s proksime al linio %d"
 
-#: plugins/sudoers/parse.c:371
+#: plugins/sudoers/parse.c:126
+#, c-format
+msgid "parse error in %s"
+msgstr "analiza eraro en %s"
+
+#: plugins/sudoers/parse.c:389
 #, c-format
 msgid ""
 "\n"
@@ -837,17 +840,17 @@ msgstr ""
 "\n"
 "Ero en sudoers:\n"
 
-#: plugins/sudoers/parse.c:373
+#: plugins/sudoers/parse.c:391
 #, c-format
 msgid "    RunAsUsers: "
 msgstr "    RunAsUsers: "
 
-#: plugins/sudoers/parse.c:388
+#: plugins/sudoers/parse.c:406
 #, c-format
 msgid "    RunAsGroups: "
 msgstr "    RunAsGroups: "
 
-#: plugins/sudoers/parse.c:397
+#: plugins/sudoers/parse.c:415
 #, c-format
 msgid ""
 "    Commands:\n"
@@ -860,97 +863,97 @@ msgstr ""
 msgid ": "
 msgstr ": "
 
-#: plugins/sudoers/pwutil.c:251
+#: plugins/sudoers/pwutil.c:260
 #, c-format
 msgid "unable to cache uid %u (%s), already exists"
 msgstr "ne eblas konservi uid-on %u (%s), jam ekzistas"
 
-#: plugins/sudoers/pwutil.c:259
+#: plugins/sudoers/pwutil.c:268
 #, c-format
 msgid "unable to cache uid %u, already exists"
 msgstr "ne eblas konservi uid-on %u, jam ekzistas"
 
-#: plugins/sudoers/pwutil.c:295 plugins/sudoers/pwutil.c:304
+#: plugins/sudoers/pwutil.c:305 plugins/sudoers/pwutil.c:314
 #, c-format
 msgid "unable to cache user %s, already exists"
 msgstr "ne eblas konservi uzanton %s, jam ekzistas"
 
-#: plugins/sudoers/pwutil.c:607
+#: plugins/sudoers/pwutil.c:655
 #, c-format
 msgid "unable to cache gid %u (%s), already exists"
 msgstr "ne eblas konservi gid-on %u (%s), jam ekzistas"
 
-#: plugins/sudoers/pwutil.c:615
+#: plugins/sudoers/pwutil.c:663
 #, c-format
 msgid "unable to cache gid %u, already exists"
 msgstr "ne eblas konservi gid-on %u, jam ekzistas"
 
-#: plugins/sudoers/pwutil.c:644 plugins/sudoers/pwutil.c:653
+#: plugins/sudoers/pwutil.c:693 plugins/sudoers/pwutil.c:702
 #, c-format
 msgid "unable to cache group %s, already exists"
 msgstr "ne eblas konservi grupon %s, jam ekzistas"
 
-#: plugins/sudoers/set_perms.c:109 plugins/sudoers/set_perms.c:358
-#: plugins/sudoers/set_perms.c:590 plugins/sudoers/set_perms.c:824
+#: plugins/sudoers/set_perms.c:114 plugins/sudoers/set_perms.c:365
+#: plugins/sudoers/set_perms.c:601 plugins/sudoers/set_perms.c:837
 msgid "perm stack overflow"
 msgstr "permeso-staka superfluo"
 
-#: plugins/sudoers/set_perms.c:117 plugins/sudoers/set_perms.c:366
-#: plugins/sudoers/set_perms.c:598 plugins/sudoers/set_perms.c:832
+#: plugins/sudoers/set_perms.c:122 plugins/sudoers/set_perms.c:373
+#: plugins/sudoers/set_perms.c:609 plugins/sudoers/set_perms.c:845
 msgid "perm stack underflow"
 msgstr "permeso-staka subfluo"
 
-#: plugins/sudoers/set_perms.c:223 plugins/sudoers/set_perms.c:458
-#: plugins/sudoers/set_perms.c:695
+#: plugins/sudoers/set_perms.c:228 plugins/sudoers/set_perms.c:466
+#: plugins/sudoers/set_perms.c:706
 msgid "unable to change to runas gid"
 msgstr "ne eblas ŝanĝi al plenumigkiela gid"
 
-#: plugins/sudoers/set_perms.c:231 plugins/sudoers/set_perms.c:465
-#: plugins/sudoers/set_perms.c:702
+#: plugins/sudoers/set_perms.c:236 plugins/sudoers/set_perms.c:473
+#: plugins/sudoers/set_perms.c:713
 msgid "unable to change to runas uid"
 msgstr "ne eblas ŝanĝi al plenumigkiela uid"
 
-#: plugins/sudoers/set_perms.c:245 plugins/sudoers/set_perms.c:478
-#: plugins/sudoers/set_perms.c:715
+#: plugins/sudoers/set_perms.c:250 plugins/sudoers/set_perms.c:486
+#: plugins/sudoers/set_perms.c:726
 #, c-format
 msgid "unable to change to sudoers gid"
 msgstr "ne eblas ŝanĝi al gid de sudo-redaktantoj"
 
-#: plugins/sudoers/set_perms.c:286 plugins/sudoers/set_perms.c:516
-#: plugins/sudoers/set_perms.c:753 plugins/sudoers/set_perms.c:893
+#: plugins/sudoers/set_perms.c:291 plugins/sudoers/set_perms.c:524
+#: plugins/sudoers/set_perms.c:764 plugins/sudoers/set_perms.c:906
 msgid "too many processes"
 msgstr "tro da procezoj"
 
-#: plugins/sudoers/set_perms.c:955
+#: plugins/sudoers/set_perms.c:970
 msgid "unable to set runas group vector"
 msgstr "ne eblas elekti vektoron de plenumigkiela grupo"
 
-#: plugins/sudoers/sudo_nss.c:238
+#: plugins/sudoers/sudo_nss.c:243
 #, c-format
 msgid "Matching Defaults entries for %s on this host:\n"
 msgstr "Kongruantaj eroj de Defaults: %s en ĉi tiu gastiganto:\n"
 
-#: plugins/sudoers/sudo_nss.c:251
+#: plugins/sudoers/sudo_nss.c:256
 #, c-format
 msgid "Runas and Command-specific defaults for %s:\n"
 msgstr "Plenumigkiela komando-specifaj aŭtomataĵoj por %s:\n"
 
-#: plugins/sudoers/sudo_nss.c:264
+#: plugins/sudoers/sudo_nss.c:269
 #, c-format
 msgid "User %s may run the following commands on this host:\n"
 msgstr "Uzanto %s rajtas plenumigi la jenajn komandojn en ĉi tiu gastiganto:\n"
 
-#: plugins/sudoers/sudo_nss.c:274
+#: plugins/sudoers/sudo_nss.c:279
 #, c-format
 msgid "User %s is not allowed to run sudo on %s.\n"
-msgstr "Uzanto %s ne rajton plenumigi sudo-on en %s.\n"
+msgstr "Uzanto %s ne rajtas plenumigi sudo-on en %s.\n"
 
-#: plugins/sudoers/sudoers.c:199 plugins/sudoers/sudoers.c:234
-#: plugins/sudoers/sudoers.c:911
+#: plugins/sudoers/sudoers.c:201 plugins/sudoers/sudoers.c:232
+#: plugins/sudoers/sudoers.c:931
 msgid "problem with defaults entries"
 msgstr "problemoj kun aŭtomataj eroj"
 
-#: plugins/sudoers/sudoers.c:203
+#: plugins/sudoers/sudoers.c:205
 #, c-format
 msgid "no valid sudoers sources found, quitting"
 msgstr "ne validaj fontotekstoj de sudoers trovita, ĉesiganta"
@@ -960,42 +963,42 @@ msgstr "ne validaj fontotekstoj de sudoers trovita, ĉesiganta"
 msgid "unable to execute %s: %s"
 msgstr "ne eblas plenumigi %s-on: %s"
 
-#: plugins/sudoers/sudoers.c:306
+#: plugins/sudoers/sudoers.c:311
 #, c-format
 msgid "sudoers specifies that root is not allowed to sudo"
-msgstr "sudoers specifas, ke ĉefradiko ne rajtas sudo-i"
+msgstr "sudoers specifas, ke ĉefuzanto ne rajtas sudo-i"
 
-#: plugins/sudoers/sudoers.c:313
+#: plugins/sudoers/sudoers.c:318
 #, c-format
 msgid "you are not permitted to use the -C option"
 msgstr "vi ne rajtas uzi la parametron -C"
 
-#: plugins/sudoers/sudoers.c:403
+#: plugins/sudoers/sudoers.c:408
 #, c-format
 msgid "timestamp owner (%s): No such user"
-msgstr "tempo-indikila estro (%s): Nenia uzanto"
+msgstr "posedanto de tempindiko estas %s -- sed tiu uzanto ne ekzistas"
 
-#: plugins/sudoers/sudoers.c:419
+#: plugins/sudoers/sudoers.c:424
 msgid "no tty"
 msgstr "neniu tty"
 
-#: plugins/sudoers/sudoers.c:420
+#: plugins/sudoers/sudoers.c:425
 #, c-format
 msgid "sorry, you must have a tty to run sudo"
 msgstr "bedaŭre vi devas havi tty-on por plenumigi sudo-on"
 
-#: plugins/sudoers/sudoers.c:463
+#: plugins/sudoers/sudoers.c:464
 msgid "No user or host"
 msgstr "Neniu uzanto aŭ gastiganto"
 
-#: plugins/sudoers/sudoers.c:477 plugins/sudoers/sudoers.c:498
-#: plugins/sudoers/sudoers.c:499 plugins/sudoers/sudoers.c:1465
-#: plugins/sudoers/sudoers.c:1466
+#: plugins/sudoers/sudoers.c:478 plugins/sudoers/sudoers.c:499
+#: plugins/sudoers/sudoers.c:500 plugins/sudoers/sudoers.c:1509
+#: plugins/sudoers/sudoers.c:1510
 #, c-format
 msgid "%s: command not found"
 msgstr "%s: komando ne trovita"
 
-#: plugins/sudoers/sudoers.c:479 plugins/sudoers/sudoers.c:495
+#: plugins/sudoers/sudoers.c:480 plugins/sudoers/sudoers.c:496
 #, c-format
 msgid ""
 "ignoring `%s' found in '.'\n"
@@ -1004,95 +1007,100 @@ msgstr ""
 "Ignoranta '%s'-on trovita en '.'\n"
 "Uzu 'sudo ./%s'-on se tio estas la '%s', kiun vi volas plenumigi."
 
-#: plugins/sudoers/sudoers.c:484
+#: plugins/sudoers/sudoers.c:485
 msgid "validation failure"
 msgstr "validiga malsukceso"
 
-#: plugins/sudoers/sudoers.c:494
+#: plugins/sudoers/sudoers.c:495
 msgid "command in current directory"
 msgstr "komando en nuna dosierujo"
 
-#: plugins/sudoers/sudoers.c:506
+#: plugins/sudoers/sudoers.c:507
 #, c-format
 msgid "sorry, you are not allowed to preserve the environment"
 msgstr "bedaŭre vi ne rajtas konservi la medion"
 
-#: plugins/sudoers/sudoers.c:894
+#: plugins/sudoers/sudoers.c:657 plugins/sudoers/sudoers.c:664
+#, c-format
+msgid "internal error, runas_groups overflow"
+msgstr "ena eraro, runas_groups superfluo"
+
+#: plugins/sudoers/sudoers.c:914
 #, c-format
 msgid "internal error, set_cmnd() overflow"
-msgstr "ena eraro, set_cmnd() superfluo"
+msgstr "ena eraro, superfluo en set_cmnd()"
 
-#: plugins/sudoers/sudoers.c:936
+#: plugins/sudoers/sudoers.c:957
 #, c-format
 msgid "fixed mode on %s"
 msgstr "fiksita reĝimo en %s"
 
-#: plugins/sudoers/sudoers.c:940
+#: plugins/sudoers/sudoers.c:961
 #, c-format
 msgid "set group on %s"
 msgstr "elekti grupon en %s"
 
-#: plugins/sudoers/sudoers.c:943
+#: plugins/sudoers/sudoers.c:964
 #, c-format
 msgid "unable to set group on %s"
 msgstr "ne eblas elekti grupon en %s"
 
-#: plugins/sudoers/sudoers.c:946
+#: plugins/sudoers/sudoers.c:967
 #, c-format
 msgid "unable to fix mode on %s"
 msgstr "ne eblas fiksi reĝimon en %s"
 
-#: plugins/sudoers/sudoers.c:959
+#: plugins/sudoers/sudoers.c:980
 #, c-format
 msgid "%s is not a regular file"
-msgstr "%s ne estas regula dosiero"
+msgstr "%s ne estas normala dosiero"
 
-#: plugins/sudoers/sudoers.c:961
+#: plugins/sudoers/sudoers.c:982
 #, c-format
 msgid "%s is mode 0%o, should be 0%o"
 msgstr "%s estas reĝimo 0%o, devas esti 0%o"
 
-#: plugins/sudoers/sudoers.c:965
+#: plugins/sudoers/sudoers.c:986
 #, c-format
 msgid "%s is owned by uid %u, should be %u"
 msgstr "%s estas estrita de uid %u, devas esti %u"
 
-#: plugins/sudoers/sudoers.c:968
+#: plugins/sudoers/sudoers.c:989
 #, c-format
 msgid "%s is owned by gid %u, should be %u"
 msgstr "%s estas estrita de gid %u, devas esti %u"
 
-#: plugins/sudoers/sudoers.c:1012
+#: plugins/sudoers/sudoers.c:1038
 #, c-format
 msgid "only root can use `-c %s'"
 msgstr "nur ĉefuzanto rajtas uzi '-c %s'"
 
-#: plugins/sudoers/sudoers.c:1022
+#: plugins/sudoers/sudoers.c:1049
 #, c-format
 msgid "unknown login class: %s"
 msgstr "nekonata ensaluta klaso: %s"
 
-#: plugins/sudoers/sudoers.c:1056
+#: plugins/sudoers/sudoers.c:1077
 #, c-format
 msgid "unable to resolve host %s"
-msgstr "ne eblas solvi gastiganton %s"
+msgstr "ne eblas trovi gastiganton %s"
 
-#: plugins/sudoers/sudoers.c:1106 plugins/sudoers/testsudoers.c:351
+#: plugins/sudoers/sudoers.c:1129 plugins/sudoers/testsudoers.c:380
 #, c-format
 msgid "unknown group: %s"
 msgstr "nekonata grupo: %s"
 
-#: plugins/sudoers/sudoers.c:1150
+#: plugins/sudoers/sudoers.c:1178
 #, c-format
 msgid "Sudoers policy plugin version %s\n"
 msgstr "Eldono %s de la konduta kromprogramo\n"
 
-#: plugins/sudoers/sudoers.c:1152
+#: plugins/sudoers/sudoers.c:1180
 #, c-format
 msgid "Sudoers file grammar version %d\n"
 msgstr "Eldono %d de la gramatikilo de sudoers\n"
 
-#: plugins/sudoers/sudoers.c:1156
+#: plugins/sudoers/sudoers.c:1184
 #, c-format
 msgid ""
 "\n"
@@ -1101,147 +1109,147 @@ msgstr ""
 "\n"
 "Pado de sudoers: %s\n"
 
-#: plugins/sudoers/sudoers.c:1159
+#: plugins/sudoers/sudoers.c:1187
 #, c-format
 msgid "nsswitch path: %s\n"
 msgstr "pado de nsswitch: %s\n"
 
-#: plugins/sudoers/sudoers.c:1161
+#: plugins/sudoers/sudoers.c:1189
 #, c-format
 msgid "ldap.conf path: %s\n"
 msgstr "pado de ldap.conf: %s\n"
 
-#: plugins/sudoers/sudoers.c:1162
+#: plugins/sudoers/sudoers.c:1190
 #, c-format
 msgid "ldap.secret path: %s\n"
 msgstr "pado de ldap.secret: %s\n"
 
-#: plugins/sudoers/sudoreplay.c:265
+#: plugins/sudoers/sudoreplay.c:286
 #, c-format
 msgid "invalid filter option: %s"
 msgstr "nevalida filtrila elekto: %s"
 
-#: plugins/sudoers/sudoreplay.c:278
+#: plugins/sudoers/sudoreplay.c:299
 #, c-format
 msgid "invalid max wait: %s"
 msgstr "nevalida maksimuma atendo: %s"
 
-#: plugins/sudoers/sudoreplay.c:284
+#: plugins/sudoers/sudoreplay.c:305
 #, c-format
 msgid "invalid speed factor: %s"
 msgstr "nevalida rapida faktoro: %s"
 
-#: plugins/sudoers/sudoreplay.c:287 plugins/sudoers/visudo.c:174
+#: plugins/sudoers/sudoreplay.c:308 plugins/sudoers/visudo.c:187
 #, c-format
 msgid "%s version %s\n"
 msgstr "%s eldono %s\n"
 
-#: plugins/sudoers/sudoreplay.c:310
+#: plugins/sudoers/sudoreplay.c:333
 #, c-format
 msgid "%s/%.2s/%.2s/%.2s/timing: %s"
 msgstr "%s/%.2s/%.2s/%.2s tempo-registrado: %s"
 
-#: plugins/sudoers/sudoreplay.c:316
+#: plugins/sudoers/sudoreplay.c:339
 #, c-format
 msgid "%s/%s/timing: %s"
 msgstr "%s/%s/tempo-registrado: %s"
 
-#: plugins/sudoers/sudoreplay.c:341
+#: plugins/sudoers/sudoreplay.c:364
 #, c-format
 msgid "invalid log file %s"
 msgstr "nevalida protokolo %s"
 
-#: plugins/sudoers/sudoreplay.c:343
+#: plugins/sudoers/sudoreplay.c:366
 #, c-format
 msgid "Replaying sudo session: %s"
 msgstr "Refaranta sudo-seancon: %s"
 
-#: plugins/sudoers/sudoreplay.c:369
+#: plugins/sudoers/sudoreplay.c:392
 #, c-format
 msgid "unable to set tty to raw mode"
 msgstr "ne eblas elekti tty-on en nudan reĝimon"
 
-#: plugins/sudoers/sudoreplay.c:383
+#: plugins/sudoers/sudoreplay.c:406
 #, c-format
 msgid "invalid timing file line: %s"
 msgstr "nevalida linio en la tempo-registran dosieron: %s"
 
-#: plugins/sudoers/sudoreplay.c:425
+#: plugins/sudoers/sudoreplay.c:448
 #, c-format
 msgid "writing to standard output"
 msgstr "skribanta al eligo"
 
-#: plugins/sudoers/sudoreplay.c:455
+#: plugins/sudoers/sudoreplay.c:480
 #, c-format
 msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
 msgstr "nanosleep: tv_sec %ld, tv_nsec %ld"
 
-#: plugins/sudoers/sudoreplay.c:503 plugins/sudoers/sudoreplay.c:528
+#: plugins/sudoers/sudoreplay.c:529 plugins/sudoers/sudoreplay.c:554
 #, c-format
 msgid "ambiguous expression \"%s\""
 msgstr "ambigua esprimo \"%s\""
 
-#: plugins/sudoers/sudoreplay.c:545
+#: plugins/sudoers/sudoreplay.c:571
 #, c-format
 msgid "too many parenthesized expressions, max %d"
-msgstr "tro da esprimoj en krampoj, maksimumo: %d"
+msgstr "tro da esprimoj en krampoj; maksimumo estas %d"
 
-#: plugins/sudoers/sudoreplay.c:556
+#: plugins/sudoers/sudoreplay.c:582
 #, c-format
 msgid "unmatched ')' in expression"
 msgstr "esprimo kun ')' sen samnivela '('"
 
-#: plugins/sudoers/sudoreplay.c:562
+#: plugins/sudoers/sudoreplay.c:588
 #, c-format
 msgid "unknown search term \"%s\""
 msgstr "nekonata serĉaĵo \"%s\""
 
-#: plugins/sudoers/sudoreplay.c:576
+#: plugins/sudoers/sudoreplay.c:602
 #, c-format
 msgid "%s requires an argument"
 msgstr "%s bezonas parametron"
 
-#: plugins/sudoers/sudoreplay.c:580
+#: plugins/sudoers/sudoreplay.c:606
 #, c-format
 msgid "invalid regular expression: %s"
 msgstr "nevalida regulesprimo: %s"
 
-#: plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:612
 #, c-format
 msgid "could not parse date \"%s\""
 msgstr "ne eblis analizi daton \"%s\""
 
-#: plugins/sudoers/sudoreplay.c:599
+#: plugins/sudoers/sudoreplay.c:625
 #, c-format
 msgid "unmatched '(' in expression"
 msgstr "esprimo kun '(' sen samnivela ')'"
 
-#: plugins/sudoers/sudoreplay.c:601
+#: plugins/sudoers/sudoreplay.c:627
 #, c-format
 msgid "illegal trailing \"or\""
 msgstr "nevalida posta \"or\""
 
-#: plugins/sudoers/sudoreplay.c:603
+#: plugins/sudoers/sudoreplay.c:629
 #, c-format
 msgid "illegal trailing \"!\""
 msgstr "nevalida posta \"!\""
 
-#: plugins/sudoers/sudoreplay.c:819
+#: plugins/sudoers/sudoreplay.c:851
 #, c-format
 msgid "invalid regex: %s"
 msgstr "nevalida regulesprimo: %s"
 
-#: plugins/sudoers/sudoreplay.c:941
+#: plugins/sudoers/sudoreplay.c:976
 #, c-format
 msgid "usage: %s [-h] [-d directory] [-m max_wait] [-s speed_factor] ID\n"
 msgstr "uzado: %s [-h] [-d dosierujo] [-m maksimuma_atendo] [-s rapida_faktoro] identigilo\n"
 
-#: plugins/sudoers/sudoreplay.c:944
+#: plugins/sudoers/sudoreplay.c:979
 #, c-format
 msgid "usage: %s [-h] [-d directory] -l [search expression]\n"
 msgstr "uzado: %s [-h] [-d dosierujo] -l [serĉaĵo]\n"
 
-#: plugins/sudoers/sudoreplay.c:953
+#: plugins/sudoers/sudoreplay.c:988
 #, c-format
 msgid ""
 "%s - replay sudo session logs\n"
@@ -1250,7 +1258,7 @@ msgstr ""
 "%s - refari sudo-seancajn protokolojn\n"
 "\n"
 
-#: plugins/sudoers/sudoreplay.c:955
+#: plugins/sudoers/sudoreplay.c:990
 msgid ""
 "\n"
 "Options:\n"
@@ -1271,16 +1279,16 @@ msgstr ""
 "  -s [rapido]  rapidigi aŭ malrapidigi eligon\n"
 "  -V           eligi eldonan informon kaj eliri"
 
-#: plugins/sudoers/testsudoers.c:230
+#: plugins/sudoers/testsudoers.c:246
 #, c-format
 msgid "internal error, init_vars() overflow"
-msgstr "ena eraro, init_vars() suprfluo"
+msgstr "ena eraro, superfluo en init_vars()"
 
-#: plugins/sudoers/testsudoers.c:309
+#: plugins/sudoers/testsudoers.c:331
 msgid "\thost  unmatched"
 msgstr "\thost  sen egalo"
 
-#: plugins/sudoers/testsudoers.c:312
+#: plugins/sudoers/testsudoers.c:334
 msgid ""
 "\n"
 "Command allowed"
@@ -1288,7 +1296,7 @@ msgstr ""
 "\n"
 "Komando permesata"
 
-#: plugins/sudoers/testsudoers.c:313
+#: plugins/sudoers/testsudoers.c:335
 msgid ""
 "\n"
 "Command denied"
@@ -1296,7 +1304,7 @@ msgstr ""
 "\n"
 "Komando rifuzata"
 
-#: plugins/sudoers/testsudoers.c:313
+#: plugins/sudoers/testsudoers.c:335
 msgid ""
 "\n"
 "Command unmatched"
@@ -1304,104 +1312,104 @@ msgstr ""
 "\n"
 "Komando sen egalo"
 
-#: toke.l:667 toke.l:793 toke.l:818 toke.l:904 plugins/sudoers/toke_util.c:111
-#: plugins/sudoers/toke_util.c:163 plugins/sudoers/toke_util.c:202
+#: toke.l:672 toke.l:802 toke.l:827 toke.l:923 plugins/sudoers/toke_util.c:113
+#: plugins/sudoers/toke_util.c:167 plugins/sudoers/toke_util.c:207
 msgid "unable to allocate memory"
 msgstr "ne eblas generi memoron"
 
-#: toke.l:786
+#: toke.l:795
 msgid "too many levels of includes"
-msgstr "tro da niveloj de inluzivaĵoj"
+msgstr "tro da niveloj de inkluzivaĵoj"
 
-#: plugins/sudoers/toke_util.c:213
+#: plugins/sudoers/toke_util.c:218
 msgid "fill_args: buffer overflow"
 msgstr "fill_args: bufra superfluo"
 
-#: plugins/sudoers/visudo.c:175
+#: plugins/sudoers/visudo.c:188
 #, c-format
 msgid "%s grammar version %d\n"
 msgstr "%s gramatika eldono %d\n"
 
-#: plugins/sudoers/visudo.c:208 plugins/sudoers/auth/rfc1938.c:103
+#: plugins/sudoers/visudo.c:221 plugins/sudoers/auth/rfc1938.c:104
 #, c-format
 msgid "you do not exist in the %s database"
 msgstr "vi ne ekzistas en la datumbazo %s"
 
-#: plugins/sudoers/visudo.c:238 plugins/sudoers/visudo.c:518
+#: plugins/sudoers/visudo.c:253 plugins/sudoers/visudo.c:539
 #, c-format
 msgid "press return to edit %s: "
 msgstr "premu enen-klavon por redakti %s-on: "
 
-#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:326
+#: plugins/sudoers/visudo.c:336 plugins/sudoers/visudo.c:342
 #, c-format
 msgid "write error"
 msgstr "skriba eraro"
 
-#: plugins/sudoers/visudo.c:408
+#: plugins/sudoers/visudo.c:424
 #, c-format
 msgid "unable to stat temporary file (%s), %s unchanged"
 msgstr "ne eblas stat-i provizoron dosieron (%s), %s neŝanĝita"
 
-#: plugins/sudoers/visudo.c:413
+#: plugins/sudoers/visudo.c:429
 #, c-format
 msgid "zero length temporary file (%s), %s unchanged"
 msgstr "nul-longa provizora dosiero (%s), %s neŝanĝita"
 
-#: plugins/sudoers/visudo.c:419
+#: plugins/sudoers/visudo.c:435
 #, c-format
 msgid "editor (%s) failed, %s unchanged"
 msgstr "redaktilo (%s) malsukcesis, %s neŝanĝita"
 
-#: plugins/sudoers/visudo.c:442
+#: plugins/sudoers/visudo.c:458
 #, c-format
 msgid "%s unchanged"
 msgstr "%s neŝanĝita"
 
-#: plugins/sudoers/visudo.c:466
+#: plugins/sudoers/visudo.c:484
 #, c-format
 msgid "unable to re-open temporary file (%s), %s unchanged."
 msgstr "ne eblas remalfermi provizoran dosieron (%s), %s neŝanĝita."
 
-#: plugins/sudoers/visudo.c:476
+#: plugins/sudoers/visudo.c:494
 #, c-format
 msgid "unabled to parse temporary file (%s), unknown error"
 msgstr "ne eblas analizi provizoran dosieron (%s), nekonata eraro"
 
-#: plugins/sudoers/visudo.c:511
+#: plugins/sudoers/visudo.c:532
 #, c-format
 msgid "internal error, unable to find %s in list!"
 msgstr "ena eraro, ne eblas trovi '%s'-on en listo!"
 
-#: plugins/sudoers/visudo.c:546 plugins/sudoers/visudo.c:555
+#: plugins/sudoers/visudo.c:584 plugins/sudoers/visudo.c:593
 #, c-format
 msgid "unable to set (uid, gid) of %s to (%u, %u)"
 msgstr "ne eblas ŝanĝi (uid, gid) de %s al (%u, %u)"
 
-#: plugins/sudoers/visudo.c:550 plugins/sudoers/visudo.c:560
+#: plugins/sudoers/visudo.c:588 plugins/sudoers/visudo.c:598
 #, c-format
 msgid "unable to change mode of %s to 0%o"
 msgstr "ne eblas ŝanĝi reĝimon de %s al 0%o"
 
-#: plugins/sudoers/visudo.c:577
+#: plugins/sudoers/visudo.c:615
 #, c-format
 msgid "%s and %s not on the same file system, using mv to rename"
 msgstr "%s kaj %s ne estas la sama dosiersistemo, uzanta mv-on por alinomi"
 
-#: plugins/sudoers/visudo.c:591
+#: plugins/sudoers/visudo.c:629
 #, c-format
 msgid "command failed: '%s %s %s', %s unchanged"
 msgstr "komando malsukcesis: '%s %s %s', %s neŝanĝita"
 
-#: plugins/sudoers/visudo.c:601
+#: plugins/sudoers/visudo.c:639
 #, c-format
 msgid "error renaming %s, %s unchanged"
-msgstr "eraro alinomanta %s-on, %s neŝanĝita"
+msgstr "eraro dum alinomi %s-on; %s neŝanĝita"
 
-#: plugins/sudoers/visudo.c:661
+#: plugins/sudoers/visudo.c:702
 msgid "What now? "
 msgstr "Kion nun? "
 
-#: plugins/sudoers/visudo.c:675
+#: plugins/sudoers/visudo.c:716
 msgid ""
 "Options are:\n"
 "  (e)dit sudoers file again\n"
@@ -1413,92 +1421,92 @@ msgstr ""
 "  x) eliri sen konservi ŝanĝojn al sudoers-dosiero\n"
 "  q) Eliri kaj konservi ŝanĝojn al sudoers-dosiero (DANĜERA!)\n"
 
-#: plugins/sudoers/visudo.c:712
+#: plugins/sudoers/visudo.c:757
 #, c-format
 msgid "unable to execute %s"
 msgstr "ne eblas plenumigi: %s"
 
-#: plugins/sudoers/visudo.c:719
+#: plugins/sudoers/visudo.c:764
 #, c-format
 msgid "unable to run %s"
 msgstr "ne eblas plenumigi: %s"
 
-#: plugins/sudoers/visudo.c:750
+#: plugins/sudoers/visudo.c:796
 #, c-format
 msgid "failed to parse %s file, unknown error"
 msgstr "malsukcesis analizi dosieron %s, nekonata eraro"
 
-#: plugins/sudoers/visudo.c:762
+#: plugins/sudoers/visudo.c:808
 #, c-format
 msgid "parse error in %s near line %d\n"
 msgstr "analiza eraro en %s proksime al linio %d\n"
 
-#: plugins/sudoers/visudo.c:765
+#: plugins/sudoers/visudo.c:811
 #, c-format
 msgid "parse error in %s\n"
 msgstr "analiza eraro en %s\n"
 
-#: plugins/sudoers/visudo.c:767
+#: plugins/sudoers/visudo.c:814 plugins/sudoers/visudo.c:816
 #, c-format
 msgid "%s: parsed OK\n"
 msgstr "%s: analizita senerare\n"
 
-#: plugins/sudoers/visudo.c:776
+#: plugins/sudoers/visudo.c:826
 #, c-format
 msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
 msgstr "%s: malĝusta estro (uid, gid) devas esti (%u, %u)\n"
 
-#: plugins/sudoers/visudo.c:783
+#: plugins/sudoers/visudo.c:833
 #, c-format
 msgid "%s: bad permissions, should be mode 0%o\n"
 msgstr "%s: misaj permesoj, devas esti reĝimo 0%o\n"
 
-#: plugins/sudoers/visudo.c:822
+#: plugins/sudoers/visudo.c:880
 #, c-format
 msgid "%s busy, try again later"
 msgstr "%s okupata, reprovu pli malfrue"
 
-#: plugins/sudoers/visudo.c:865
+#: plugins/sudoers/visudo.c:924
 #, c-format
 msgid "specified editor (%s) doesn't exist"
 msgstr "specifita tekstoredaktilo (%s) ne ekzistas"
 
-#: plugins/sudoers/visudo.c:888
+#: plugins/sudoers/visudo.c:947
 #, c-format
 msgid "unable to stat editor (%s)"
 msgstr "ne eblas stat-i tekstoredaktilon (%s)"
 
-#: plugins/sudoers/visudo.c:936
+#: plugins/sudoers/visudo.c:995
 #, c-format
 msgid "no editor found (editor path = %s)"
 msgstr "neniu tekstoredaktilo trovita (pado = %s)"
 
-#: plugins/sudoers/visudo.c:1025
+#: plugins/sudoers/visudo.c:1089
 #, c-format
 msgid "Error: cycle in %s_Alias `%s'"
 msgstr "Eraro: ciklo en %s_Alias '%s'"
 
-#: plugins/sudoers/visudo.c:1026
+#: plugins/sudoers/visudo.c:1090
 #, c-format
 msgid "Warning: cycle in %s_Alias `%s'"
 msgstr "Averto: ciklo en %s_Alias '%s'"
 
-#: plugins/sudoers/visudo.c:1029
+#: plugins/sudoers/visudo.c:1093
 #, c-format
 msgid "Error: %s_Alias `%s' referenced but not defined"
 msgstr "Eraro: %s_Alias '%s' referinta sed ne difinita"
 
-#: plugins/sudoers/visudo.c:1030
+#: plugins/sudoers/visudo.c:1094
 #, c-format
 msgid "Warning: %s_Alias `%s' referenced but not defined"
 msgstr "Averto: %s_Alias '%s' referinta sed ne difinita"
 
-#: plugins/sudoers/visudo.c:1167
+#: plugins/sudoers/visudo.c:1229
 #, c-format
 msgid "%s: unused %s_Alias %s"
 msgstr "%s neuzata %s_Alias %s"
 
-#: plugins/sudoers/visudo.c:1224
+#: plugins/sudoers/visudo.c:1286
 #, c-format
 msgid ""
 "%s - safely edit the sudoers file\n"
@@ -1507,7 +1515,7 @@ msgstr ""
 "%s - sekure redakti la dosieron sudoers\n"
 "\n"
 
-#: plugins/sudoers/visudo.c:1226
+#: plugins/sudoers/visudo.c:1288
 msgid ""
 "\n"
 "Options:\n"
@@ -1527,35 +1535,40 @@ msgstr ""
 "  -s          malsevera kontrolado de sintakso\n"
 "  -V          montri eldonon kaj eliri"
 
-#: plugins/sudoers/auth/bsdauth.c:64
+#: plugins/sudoers/auth/bsdauth.c:78
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "ne eblas akiri ensalutan klason por uzanto %s"
+
+#: plugins/sudoers/auth/bsdauth.c:84
 msgid "unable to begin bsd authentication"
-msgstr "ne eblas komenci bsd-konstatado"
+msgstr "ne eblas komenci bsd-konstatadn"
 
-#: plugins/sudoers/auth/bsdauth.c:71
+#: plugins/sudoers/auth/bsdauth.c:92
 msgid "invalid authentication type"
 msgstr "nevalida konstata tipo"
 
-#: plugins/sudoers/auth/bsdauth.c:79
+#: plugins/sudoers/auth/bsdauth.c:101
 msgid "unable to setup authentication"
 msgstr "ne eblas starigi konstatadon"
 
-#: plugins/sudoers/auth/fwtk.c:59
+#: plugins/sudoers/auth/fwtk.c:60
 #, c-format
 msgid "unable to read fwtk config"
 msgstr "ne eblas legi fwtk-agordon"
 
-#: plugins/sudoers/auth/fwtk.c:64
+#: plugins/sudoers/auth/fwtk.c:65
 #, c-format
 msgid "unable to connect to authentication server"
-msgstr "ne eblas konekti al konstatanta servilo"
+msgstr "ne eblas konektiĝi al konstatanta servilo"
 
-#: plugins/sudoers/auth/fwtk.c:70 plugins/sudoers/auth/fwtk.c:93
-#: plugins/sudoers/auth/fwtk.c:126
+#: plugins/sudoers/auth/fwtk.c:71 plugins/sudoers/auth/fwtk.c:95
+#: plugins/sudoers/auth/fwtk.c:128
 #, c-format
 msgid "lost connection to authentication server"
 msgstr "konekto al konstatanta servilo perdita"
 
-#: plugins/sudoers/auth/fwtk.c:74
+#: plugins/sudoers/auth/fwtk.c:75
 #, c-format
 msgid ""
 "authentication server error:\n"
@@ -1564,148 +1577,148 @@ msgstr ""
 "eraro de konstatanta servilo:\n"
 "%s"
 
-#: plugins/sudoers/auth/kerb5.c:114
-#, c-format
-msgid "%s: unable to parse '%s': %s"
-msgstr "%s: ne eblas analizi: '%s': %s"
-
-#: plugins/sudoers/auth/kerb5.c:127
+#: plugins/sudoers/auth/kerb5.c:117
 #, c-format
 msgid "%s: unable to unparse princ ('%s'): %s"
 msgstr "%s ne eblas analizi princ-on ('%s'): %s"
 
-#: plugins/sudoers/auth/kerb5.c:144
+#: plugins/sudoers/auth/kerb5.c:160
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: ne eblas analizi: '%s': %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
 #, c-format
 msgid "%s: unable to resolve ccache: %s"
 msgstr "%s: ne eblas trovi ccache-on: %s"
 
-#: plugins/sudoers/auth/kerb5.c:188
+#: plugins/sudoers/auth/kerb5.c:218
 #, c-format
 msgid "%s: unable to allocate options: %s"
 msgstr "%s: ne eblas generi elektojn: %s"
 
-#: plugins/sudoers/auth/kerb5.c:204
+#: plugins/sudoers/auth/kerb5.c:234
 #, c-format
 msgid "%s: unable to get credentials: %s"
 msgstr "%s: ne eblas akiri atestilojn: %s"
 
-#: plugins/sudoers/auth/kerb5.c:217
+#: plugins/sudoers/auth/kerb5.c:247
 #, c-format
 msgid "%s: unable to initialize ccache: %s"
 msgstr "%s: ne eblas iniciati ccache-on: %s"
 
-#: plugins/sudoers/auth/kerb5.c:221
+#: plugins/sudoers/auth/kerb5.c:251
 #, c-format
 msgid "%s: unable to store cred in ccache: %s"
 msgstr "%s: ne eblas konservi atestilon en ccache: %s"
 
-#: plugins/sudoers/auth/kerb5.c:284
+#: plugins/sudoers/auth/kerb5.c:316
 #, c-format
 msgid "%s: unable to get host principal: %s"
 msgstr "%s: ne eblas atingi ĉefgastiganto: %s"
 
-#: plugins/sudoers/auth/kerb5.c:299
+#: plugins/sudoers/auth/kerb5.c:331
 #, c-format
 msgid "%s: Cannot verify TGT! Possible attack!: %s"
 msgstr "%s: Ne eblas konstati TGT-on! Ebla atako!: %s"
 
-#: plugins/sudoers/auth/pam.c:99
+#: plugins/sudoers/auth/pam.c:100
 msgid "unable to initialize PAM"
 msgstr "ne eblas iniciati PAM-on"
 
-#: plugins/sudoers/auth/pam.c:142
+#: plugins/sudoers/auth/pam.c:144
 msgid "account validation failure, is your account locked?"
 msgstr "malsukceso ĉe konta validigo, ĉu via konto estas ŝlosita?"
 
-#: plugins/sudoers/auth/pam.c:146
+#: plugins/sudoers/auth/pam.c:148
 msgid "Account or password is expired, reset your password and try again"
 msgstr "Konto aŭ pasvorto eksvalidiĝis, restarigu vian pasvorton kaj reprovu"
 
-#: plugins/sudoers/auth/pam.c:153
+#: plugins/sudoers/auth/pam.c:155
 #, c-format
 msgid "pam_chauthtok: %s"
 msgstr "pam_chauthtok: %s"
 
-#: plugins/sudoers/auth/pam.c:157
+#: plugins/sudoers/auth/pam.c:159
 msgid "Password expired, contact your system administrator"
 msgstr "Pasvorto eksvalidiĝis, kontaktu vian sistemestron"
 
-#: plugins/sudoers/auth/pam.c:161
+#: plugins/sudoers/auth/pam.c:163
 msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
 msgstr "Konto eksvalidiĝis aŭ PAM-agordon malhavas sekcion \"account\" por sudo, kontaktu vian sistemestron"
 
-#: plugins/sudoers/auth/pam.c:176
+#: plugins/sudoers/auth/pam.c:178
 #, c-format
 msgid "pam_authenticate: %s"
 msgstr "pam_authenticate: %s"
 
-#: plugins/sudoers/auth/pam.c:296
+#: plugins/sudoers/auth/pam.c:306
 msgid "Password: "
 msgstr "Pasvorto: "
 
-#: plugins/sudoers/auth/pam.c:297
+#: plugins/sudoers/auth/pam.c:307
 msgid "Password:"
 msgstr "Pasvorto:"
 
-#: plugins/sudoers/auth/securid.c:82 plugins/sudoers/auth/securid5.c:106
-#, c-format
-msgid "unable to contact the SecurID server"
-msgstr "ne eblas kontakti la servilon de SecurID"
-
 #: plugins/sudoers/auth/securid5.c:81
 #, c-format
 msgid "failed to initialise the ACE API library"
 msgstr "malsukcesis iniciati la bibliotekon de la API ACE"
 
-#: plugins/sudoers/auth/securid5.c:115
+#: plugins/sudoers/auth/securid5.c:107
+#, c-format
+msgid "unable to contact the SecurID server"
+msgstr "ne eblas kontakti la servilon de SecurID"
+
+#: plugins/sudoers/auth/securid5.c:116
 #, c-format
 msgid "User ID locked for SecurID Authentication"
 msgstr "Uzanto identigilo ŝlosita pro konstatado en SecurID"
 
-#: plugins/sudoers/auth/securid5.c:119 plugins/sudoers/auth/securid5.c:169
+#: plugins/sudoers/auth/securid5.c:120 plugins/sudoers/auth/securid5.c:171
 #, c-format
 msgid "invalid username length for SecurID"
 msgstr "nevalida salutnoma longo por SecurID"
 
-#: plugins/sudoers/auth/securid5.c:123 plugins/sudoers/auth/securid5.c:174
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:176
 #, c-format
 msgid "invalid Authentication Handle for SecurID"
 msgstr "nevalida konstatilo por SecurID"
 
-#: plugins/sudoers/auth/securid5.c:127
+#: plugins/sudoers/auth/securid5.c:128
 #, c-format
 msgid "SecurID communication failed"
 msgstr "Komunikiĝo kun SecurID malsukcesis"
 
-#: plugins/sudoers/auth/securid5.c:131 plugins/sudoers/auth/securid5.c:213
+#: plugins/sudoers/auth/securid5.c:132 plugins/sudoers/auth/securid5.c:215
 #, c-format
 msgid "unknown SecurID error"
 msgstr "nekonata SecurID-eraro"
 
-#: plugins/sudoers/auth/securid5.c:164
+#: plugins/sudoers/auth/securid5.c:166
 #, c-format
 msgid "invalid passcode length for SecurID"
 msgstr "nevalida paskoda longo por SecurID"
 
-#: plugins/sudoers/auth/sia.c:106
+#: plugins/sudoers/auth/sia.c:109
 msgid "unable to initialize SIA session"
 msgstr "ne eblas iniciati SIA-seascon"
 
-#: plugins/sudoers/auth/sudo_auth.c:124
-msgid "There are no authentication methods compiled into sudo!  If you want to turn off authentication, use the --disable-authentication configure option."
-msgstr "Ekzistas neniaj konstatantaj metodoj muntitaj en sudo! Se vi volas malŝalti konstatadon, uzu la munta parametro --disable-authentication."
-
-#: plugins/sudoers/auth/sudo_auth.c:134
+#: plugins/sudoers/auth/sudo_auth.c:117
 msgid "Invalid authentication methods compiled into sudo!  You may mix standalone and non-standalone authentication."
 msgstr "Nevalidaj konstatantaj metodoj muntitaj en sudo! Vi rajtas miksi dependan kaj sendependan konstatadon."
 
-#: plugins/sudoers/auth/sudo_auth.c:243
+#: plugins/sudoers/auth/sudo_auth.c:199
+msgid "There are no authentication methods compiled into sudo!  If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Ekzistas neniaj konstatantaj metodoj muntitaj en sudo! Se vi volas malŝalti konstatadon, uzu la munta parametro --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:271
 #, c-format
 msgid "%d incorrect password attempt"
 msgid_plural "%d incorrect password attempts"
 msgstr[0] "%d malĝusta pasvorta provo"
 msgstr[1] "%d malĝustaj pasvortaj provoj"
 
-#: plugins/sudoers/auth/sudo_auth.c:335
+#: plugins/sudoers/auth/sudo_auth.c:374
 msgid "Authentication methods:"
 msgstr "Konstatantaj metodoj:"
index c4840e9a6e32fee6bcff2985ef090438e7e040ff..fc00079fe93187b2a9f85785ee390b34686ae345 100644 (file)
Binary files a/plugins/sudoers/po/fi.mo and b/plugins/sudoers/po/fi.mo differ
index 6815ff5437d839a18dc5a0958a59521d9cb20ebb..0cfdc01622e2e25661291b7ea3426ebdbc931af6 100644 (file)
@@ -1,15 +1,15 @@
 # Finnish messages for sudoers.
 # This file is put in the public domain.
-# Copyright © 2011 Free Software Foundation, Inc.
+# Copyright © 2011, 2012 Free Software Foundation, Inc.
 # This file is distributed under the same license as the sudo package.
-# Jorma Karvonen <karvonen.jorma@gmail.com>, 2011.
+# Jorma Karvonen <karvonen.jorma@gmail.com>, 2011-2012.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: sudoers 1.8.3rc1\n"
+"Project-Id-Version: sudoers 1.8.4rc1\n"
 "Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
-"POT-Creation-Date: 2011-09-16 16:52-0400\n"
-"PO-Revision-Date: 2011-09-18 15:17+0200\n"
+"POT-Creation-Date: 2012-02-06 15:48-0500\n"
+"PO-Revision-Date: 2012-02-08 10:09+0200\n"
 "Last-Translator: Jorma Karvonen <karvonen.jorma@gmail.com>\n"
 "Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"
 "Language: fi\n"
@@ -18,148 +18,148 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
 
-#: plugins/sudoers/alias.c:122
+#: plugins/sudoers/alias.c:125
 #, c-format
 msgid "Alias `%s' already defined"
 msgstr "Alias ”%s” on jo määritelty"
 
-#: plugins/sudoers/bsm_audit.c:58 plugins/sudoers/bsm_audit.c:61
-#: plugins/sudoers/bsm_audit.c:109 plugins/sudoers/bsm_audit.c:113
-#: plugins/sudoers/bsm_audit.c:163 plugins/sudoers/bsm_audit.c:167
+#: plugins/sudoers/bsm_audit.c:61 plugins/sudoers/bsm_audit.c:64
+#: plugins/sudoers/bsm_audit.c:113 plugins/sudoers/bsm_audit.c:117
+#: plugins/sudoers/bsm_audit.c:169 plugins/sudoers/bsm_audit.c:173
 msgid "getaudit: failed"
 msgstr "getaudit: epäonnistui"
 
-#: plugins/sudoers/bsm_audit.c:87 plugins/sudoers/bsm_audit.c:148
+#: plugins/sudoers/bsm_audit.c:91 plugins/sudoers/bsm_audit.c:154
 msgid "Could not determine audit condition"
 msgstr "Ei voitu määritellä audit-ehtoa"
 
-#: plugins/sudoers/bsm_audit.c:98
+#: plugins/sudoers/bsm_audit.c:102
 msgid "getauid failed"
 msgstr "getauid epäonnistui"
 
-#: plugins/sudoers/bsm_audit.c:100 plugins/sudoers/bsm_audit.c:157
+#: plugins/sudoers/bsm_audit.c:104 plugins/sudoers/bsm_audit.c:163
 msgid "au_open: failed"
 msgstr "au_open: epäonnistui"
 
-#: plugins/sudoers/bsm_audit.c:115 plugins/sudoers/bsm_audit.c:169
+#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:175
 msgid "au_to_subject: failed"
 msgstr "au_to_subject: epäonnistui"
 
-#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:173
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:179
 msgid "au_to_exec_args: failed"
 msgstr "au_to_exec_args: epäonnistui"
 
-#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:182
+#: plugins/sudoers/bsm_audit.c:127 plugins/sudoers/bsm_audit.c:188
 msgid "au_to_return32: failed"
 msgstr "au_to_return32: epäonnistui"
 
-#: plugins/sudoers/bsm_audit.c:126 plugins/sudoers/bsm_audit.c:185
+#: plugins/sudoers/bsm_audit.c:130 plugins/sudoers/bsm_audit.c:191
 msgid "unable to commit audit record"
 msgstr "ei kyetä suorittamaan commit-toimintoa audit-tietueelle"
 
-#: plugins/sudoers/bsm_audit.c:155
+#: plugins/sudoers/bsm_audit.c:161
 msgid "getauid: failed"
 msgstr "getauid: epäonnistui"
 
-#: plugins/sudoers/bsm_audit.c:178
+#: plugins/sudoers/bsm_audit.c:184
 msgid "au_to_text: failed"
 msgstr "au_to_text: epäonnistui"
 
-#: plugins/sudoers/check.c:141
+#: plugins/sudoers/check.c:158
 #, c-format
 msgid "sorry, a password is required to run %s"
 msgstr "kohteen %s suorittamiseen vaaditaan salasana"
 
 #  Avaamisen kohde voi olla timestamp file, sudoers file tai pathbuf
-#: plugins/sudoers/check.c:225 plugins/sudoers/iolog.c:169
-#: plugins/sudoers/sudoers.c:971 plugins/sudoers/sudoreplay.c:325
-#: plugins/sudoers/sudoreplay.c:334 plugins/sudoers/sudoreplay.c:675
-#: plugins/sudoers/sudoreplay.c:767 plugins/sudoers/visudo.c:744
+#: plugins/sudoers/check.c:249 plugins/sudoers/iolog.c:172
+#: plugins/sudoers/sudoers.c:992 plugins/sudoers/sudoreplay.c:348
+#: plugins/sudoers/sudoreplay.c:357 plugins/sudoers/sudoreplay.c:703
+#: plugins/sudoers/sudoreplay.c:797 plugins/sudoers/visudo.c:790
 #, c-format
 msgid "unable to open %s"
 msgstr "ei kyetä avaamaan kohdetta %s"
 
 #  Kirjoittamisen kohde voi olla timestamp file tai pathbuf
-#: plugins/sudoers/check.c:229 plugins/sudoers/iolog.c:199
+#: plugins/sudoers/check.c:253 plugins/sudoers/iolog.c:202
 #, c-format
 msgid "unable to write to %s"
 msgstr "ei kyetä kirjoittamaan kohteeseen %s"
 
-#: plugins/sudoers/check.c:237 plugins/sudoers/check.c:475
-#: plugins/sudoers/check.c:525 plugins/sudoers/iolog.c:122
-#: plugins/sudoers/iolog.c:153
+#: plugins/sudoers/check.c:261 plugins/sudoers/check.c:506
+#: plugins/sudoers/check.c:556 plugins/sudoers/iolog.c:123
+#: plugins/sudoers/iolog.c:156
 #, c-format
 msgid "unable to mkdir %s"
 msgstr "ei kyetä suorittamaan käskyä mkdir %s"
 
-#: plugins/sudoers/check.c:370
+#: plugins/sudoers/check.c:396
 #, c-format
 msgid "internal error, expand_prompt() overflow"
 msgstr "sisäinen virhe, expand_prompt()-ylivuoto"
 
-#: plugins/sudoers/check.c:426
+#: plugins/sudoers/check.c:456
 #, c-format
 msgid "timestamp path too long: %s"
 msgstr "aikaleimapolku on liian pitkä: %s"
 
-#: plugins/sudoers/check.c:454 plugins/sudoers/check.c:498
-#: plugins/sudoers/iolog.c:155
+#: plugins/sudoers/check.c:485 plugins/sudoers/check.c:529
+#: plugins/sudoers/iolog.c:158
 #, c-format
 msgid "%s exists but is not a directory (0%o)"
 msgstr "%s on olemassa, mutta ei ole hakemisto (0%o)"
 
-#: plugins/sudoers/check.c:457 plugins/sudoers/check.c:501
-#: plugins/sudoers/check.c:546
+#: plugins/sudoers/check.c:488 plugins/sudoers/check.c:532
+#: plugins/sudoers/check.c:577
 #, c-format
 msgid "%s owned by uid %u, should be uid %u"
 msgstr "%s on uid %u:n omistama, pitäisi olla uid %u:n omistama"
 
-#: plugins/sudoers/check.c:462 plugins/sudoers/check.c:506
+#: plugins/sudoers/check.c:493 plugins/sudoers/check.c:537
 #, c-format
 msgid "%s writable by non-owner (0%o), should be mode 0700"
 msgstr "%s on kirjoitettava ei-omistajalle (0%o), pitäisi olla tila 0700"
 
-#: plugins/sudoers/check.c:470 plugins/sudoers/check.c:514
-#: plugins/sudoers/check.c:582 plugins/sudoers/sudoers.c:957
-#: plugins/sudoers/visudo.c:304 plugins/sudoers/visudo.c:544
+#: plugins/sudoers/check.c:501 plugins/sudoers/check.c:545
+#: plugins/sudoers/check.c:613 plugins/sudoers/sudoers.c:978
+#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:582
 #, c-format
 msgid "unable to stat %s"
 msgstr "ei kyetä kutsumaan funktiota stat %s"
 
-#: plugins/sudoers/check.c:540
+#: plugins/sudoers/check.c:571
 #, c-format
 msgid "%s exists but is not a regular file (0%o)"
 msgstr "%s on olemassa, mutta ei ole tavallinen tiedosto (0%o)"
 
-#: plugins/sudoers/check.c:552
+#: plugins/sudoers/check.c:583
 #, c-format
 msgid "%s writable by non-owner (0%o), should be mode 0600"
 msgstr "%s on kirjoitettava ei-omistajalle (0%o), pitäisi olla tila 0600"
 
-#: plugins/sudoers/check.c:606
+#: plugins/sudoers/check.c:637
 #, c-format
 msgid "timestamp too far in the future: %20.20s"
 msgstr "aikaleima liian kaukana tulevaisuudessa: %20.20s"
 
-#: plugins/sudoers/check.c:652
+#: plugins/sudoers/check.c:684
 #, c-format
 msgid "unable to remove %s (%s), will reset to the epoch"
 msgstr "ei kyetä poistamaan %s (%s), nollataan aika"
 
-#: plugins/sudoers/check.c:660
+#: plugins/sudoers/check.c:692
 #, c-format
 msgid "unable to reset %s to the epoch"
 msgstr "ei kyetä nollaamaan %s ajaksi"
 
-#: plugins/sudoers/check.c:714 plugins/sudoers/check.c:720
+#: plugins/sudoers/check.c:752 plugins/sudoers/check.c:758
+#: plugins/sudoers/sudoers.c:829 plugins/sudoers/sudoers.c:833
 #, c-format
 msgid "unknown uid: %u"
 msgstr "tuntematon uid-käyttäjätunniste: %u"
 
-#: plugins/sudoers/check.c:717 plugins/sudoers/sudoers.c:748
-#: plugins/sudoers/sudoers.c:814 plugins/sudoers/sudoers.c:815
-#: plugins/sudoers/sudoers.c:1088 plugins/sudoers/testsudoers.c:202
-#: plugins/sudoers/testsudoers.c:337
+#: plugins/sudoers/check.c:755 plugins/sudoers/sudoers.c:770
+#: plugins/sudoers/sudoers.c:1108 plugins/sudoers/testsudoers.c:218
+#: plugins/sudoers/testsudoers.c:362
 #, c-format
 msgid "unknown user: %s"
 msgstr "tuntematon käyttäjä: %s"
@@ -406,305 +406,304 @@ msgstr "Kun vaaditaan salasana ’list’-näennäiskomennolle: %s"
 msgid "When to require a password for 'verify' pseudocommand: %s"
 msgstr "Kun vaaditaan salasana ’verify’-näennäiskomennolle: %s"
 
+#  Jostain syystä pariton lainausmerkki
 #: plugins/sudoers/def_data.c:243
-msgid "Preload the dummy exec functions contained in 'noexec_file'"
-msgstr "Esilataa vale-exec-funktiot, jotka sisältyvät kohteeseen â\80\99noexec_fileâ\80\99"
+msgid "Preload the dummy exec functions contained in \"_PATH_SUDO_NOEXEC"
+msgstr "Esilataa vale-exec-funktiot, jotka sisältyvät kohteeseen â\80\9d_PATH_SUDO_NOEXEC"
 
 #: plugins/sudoers/def_data.c:247
-#, c-format
-msgid "File containing dummy exec functions: %s"
-msgstr "Tiedosto, joka sisältää vale-exec-funktioita: %s"
-
-#: plugins/sudoers/def_data.c:251
 msgid "If LDAP directory is up, do we ignore local sudoers file"
 msgstr "Jos LDAP-hakemisto on ylhäällä, ohitammeko paikallisen sudoers-tiedoston"
 
-#: plugins/sudoers/def_data.c:255
+#: plugins/sudoers/def_data.c:251
 #, c-format
 msgid "File descriptors >= %d will be closed before executing a command"
 msgstr "Tiedostokuvaajat >= %d suljetaan ennen komennon suoritusta"
 
-#: plugins/sudoers/def_data.c:259
+#: plugins/sudoers/def_data.c:255
 msgid "If set, users may override the value of `closefrom' with the -C option"
 msgstr "Jos asetettu, käyttäjä voi korvata ’closefrom’-arvon valitsimella -C"
 
-#: plugins/sudoers/def_data.c:263
+#: plugins/sudoers/def_data.c:259
 msgid "Allow users to set arbitrary environment variables"
 msgstr "Salli käyttäjien asettaa mielivaltaisia ympäristömuuttujia"
 
-#: plugins/sudoers/def_data.c:267
+#: plugins/sudoers/def_data.c:263
 msgid "Reset the environment to a default set of variables"
 msgstr "Nollaa ympäristö muuttujien oletusjoukoksi"
 
-#: plugins/sudoers/def_data.c:271
+#: plugins/sudoers/def_data.c:267
 msgid "Environment variables to check for sanity:"
 msgstr "Ympäristömuuttujat, joille tehdään järkevyystarkistus:"
 
-#: plugins/sudoers/def_data.c:275
+#: plugins/sudoers/def_data.c:271
 msgid "Environment variables to remove:"
 msgstr "Poistettavat ympäristömuuttujat:"
 
-#: plugins/sudoers/def_data.c:279
+#: plugins/sudoers/def_data.c:275
 msgid "Environment variables to preserve:"
 msgstr "Säilytettävät ympäristömuuttujat:"
 
-#: plugins/sudoers/def_data.c:283
+#: plugins/sudoers/def_data.c:279
 #, c-format
 msgid "SELinux role to use in the new security context: %s"
 msgstr "Uudessa turva-asiayhteydessä käytettävä SELinux-rooli: %s"
 
-#: plugins/sudoers/def_data.c:287
+#: plugins/sudoers/def_data.c:283
 #, c-format
 msgid "SELinux type to use in the new security context: %s"
 msgstr "Uudessa turva-asiayhteydessä käytettävä SELinux-tyyppi: %s"
 
-#: plugins/sudoers/def_data.c:291
+#: plugins/sudoers/def_data.c:287
 #, c-format
 msgid "Path to the sudo-specific environment file: %s"
 msgstr "Polku sudo-kohtaiseen ympäristötiedostoon: %s"
 
-#: plugins/sudoers/def_data.c:295
+#: plugins/sudoers/def_data.c:291
 #, c-format
 msgid "Locale to use while parsing sudoers: %s"
 msgstr "Locale-asetus, jota käytetään sudoers-jäsentämisessä: %s"
 
-#: plugins/sudoers/def_data.c:299
-msgid "Allow sudo to prompt for a password even if it would be visisble"
+#: plugins/sudoers/def_data.c:295
+msgid "Allow sudo to prompt for a password even if it would be visible"
 msgstr "Salli sudo-ohjelman kysyä salasana vieläpä jos se olisi näkyvä"
 
-#: plugins/sudoers/def_data.c:303
+#: plugins/sudoers/def_data.c:299
 msgid "Provide visual feedback at the password prompt when there is user input"
 msgstr "Tarjoa visuaalista palautetta salasanakehotteelta silloin kun on käyttäjäsyöte"
 
-#: plugins/sudoers/def_data.c:307
+#: plugins/sudoers/def_data.c:303
 msgid "Use faster globbing that is less accurate but does not access the filesystem"
 msgstr "Käyttää nopeampaa jokerimerkkien korvausta, joka on epätarkempi, mutta ei lue tiedostojärjestelmää"
 
-#: plugins/sudoers/def_data.c:311
+#: plugins/sudoers/def_data.c:307
 msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
 msgstr "Sudoers umask korvaa käyttäjän umask-määrittelyn, vieläpä jos se on sallivampi"
 
-#: plugins/sudoers/def_data.c:315
+#: plugins/sudoers/def_data.c:311
 msgid "Log user's input for the command being run"
 msgstr "Kirjaa lokiin käyttäjän syöte suoritettavalle komennolle"
 
-#: plugins/sudoers/def_data.c:319
+#: plugins/sudoers/def_data.c:315
 msgid "Log the output of the command being run"
 msgstr "Kirjaa lokiin suoritettavan komennon tuloste"
 
-#: plugins/sudoers/def_data.c:323
+#: plugins/sudoers/def_data.c:319
 msgid "Compress I/O logs using zlib"
 msgstr "Tiivistä siirräntälokit käyttäen zlib-ohjelmaa"
 
-#: plugins/sudoers/def_data.c:327
+#: plugins/sudoers/def_data.c:323
 msgid "Always run commands in a pseudo-tty"
 msgstr "Suorita aina komennot näennäis-tty:ssä"
 
+#: plugins/sudoers/def_data.c:327
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Lisäosa ei-Unix-ryhmätuelle: %s"
+
 #: plugins/sudoers/def_data.c:331
-msgid "Plugin for non-Unix group support"
-msgstr "Lisäosa ei-Unix-ryhmätuelle"
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Hakemisto, johon tallennetaan syöte-/tulostelokit: %s"
 
 #: plugins/sudoers/def_data.c:335
-msgid "Directory in which to store input/output logs"
-msgstr "Hakemisto, johon tallennetaan syöte-/tulostelokit"
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Tiedosto, johon tallennetaan syöte-/tulosteloki: %s"
 
 #: plugins/sudoers/def_data.c:339
-msgid "File in which to store the input/output log"
-msgstr "Tiedosto, johon tallennetaan syöte-/tulosteloki"
-
-#: plugins/sudoers/def_data.c:343
 msgid "Add an entry to the utmp/utmpx file when allocating a pty"
 msgstr "Lisää rivi utmp-/utmpx-tiedostoon, kun varataan pty"
 
-#: plugins/sudoers/def_data.c:347
+#: plugins/sudoers/def_data.c:343
 msgid "Set the user in utmp to the runas user, not the invoking user"
 msgstr "Aseta käyttäjäksi utmp-tiedostoon suorittava käyttäjä, ei kutsuva käyttäjä"
 
-#: plugins/sudoers/defaults.c:205
+#: plugins/sudoers/defaults.c:208
 #, c-format
 msgid "unknown defaults entry `%s'"
 msgstr "tuntematon oletusrivi ”%s”"
 
-#: plugins/sudoers/defaults.c:213 plugins/sudoers/defaults.c:223
-#: plugins/sudoers/defaults.c:243 plugins/sudoers/defaults.c:256
-#: plugins/sudoers/defaults.c:269 plugins/sudoers/defaults.c:282
-#: plugins/sudoers/defaults.c:295 plugins/sudoers/defaults.c:315
-#: plugins/sudoers/defaults.c:325
+#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
+#: plugins/sudoers/defaults.c:246 plugins/sudoers/defaults.c:259
+#: plugins/sudoers/defaults.c:272 plugins/sudoers/defaults.c:285
+#: plugins/sudoers/defaults.c:298 plugins/sudoers/defaults.c:318
+#: plugins/sudoers/defaults.c:328
 #, c-format
 msgid "value `%s' is invalid for option `%s'"
 msgstr "arvo ”%s” on virheellinen valitsimelle ”%s”"
 
 #  parametrinä on variable
-#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
-#: plugins/sudoers/defaults.c:234 plugins/sudoers/defaults.c:251
-#: plugins/sudoers/defaults.c:264 plugins/sudoers/defaults.c:277
-#: plugins/sudoers/defaults.c:290 plugins/sudoers/defaults.c:310
-#: plugins/sudoers/defaults.c:321
+#: plugins/sudoers/defaults.c:219 plugins/sudoers/defaults.c:229
+#: plugins/sudoers/defaults.c:237 plugins/sudoers/defaults.c:254
+#: plugins/sudoers/defaults.c:267 plugins/sudoers/defaults.c:280
+#: plugins/sudoers/defaults.c:293 plugins/sudoers/defaults.c:313
+#: plugins/sudoers/defaults.c:324
 #, c-format
 msgid "no value specified for `%s'"
 msgstr "arvoa ei ole määritelty muuttujalle ”%s”"
 
 #  Parametri on muuttuja
-#: plugins/sudoers/defaults.c:239
+#: plugins/sudoers/defaults.c:242
 #, c-format
 msgid "values for `%s' must start with a '/'"
 msgstr "muuttujan ”%s” arvojen on alettava merkillä ’/’"
 
-#: plugins/sudoers/defaults.c:301
+#: plugins/sudoers/defaults.c:304
 #, c-format
 msgid "option `%s' does not take a value"
 msgstr "valitsin ”%s” ei ota arvoa"
 
-#: plugins/sudoers/env.c:259
+#: plugins/sudoers/env.c:258
 #, c-format
 msgid "internal error, sudo_setenv() overflow"
 msgstr "sisäinen virhe, sudo_setenv()-ylivuoto"
 
-#: plugins/sudoers/env.c:289
+#: plugins/sudoers/env.c:291
 #, c-format
 msgid "sudo_putenv: corrupted envp, length mismatch"
 msgstr "sudo_putenv: rikkoutunut envp, pituus ei täsmää"
 
-#: plugins/sudoers/env.c:698
+#: plugins/sudoers/env.c:710
 #, c-format
 msgid "sorry, you are not allowed to set the following environment variables: %s"
 msgstr "seuraavia ympäristömuuttujia ei ole lupa asettaa: %s"
 
-#: plugins/sudoers/find_path.c:68 plugins/sudoers/find_path.c:107
-#: plugins/sudoers/find_path.c:122 plugins/sudoers/iolog.c:124
-#: plugins/sudoers/sudoers.c:903 toke.l:663 toke.l:814
+#: plugins/sudoers/find_path.c:69 plugins/sudoers/find_path.c:108
+#: plugins/sudoers/find_path.c:123 plugins/sudoers/iolog.c:125
+#: plugins/sudoers/sudoers.c:923 toke.l:668 toke.l:823
 #, c-format
 msgid "%s: %s"
 msgstr "%s: %s"
 
-#: gram.y:103
+#: gram.y:110
 #, c-format
 msgid ">>> %s: %s near line %d <<<"
 msgstr ">>> %s: %s lähellä riviä %d <<<"
 
-#: plugins/sudoers/group_plugin.c:90
+#: plugins/sudoers/group_plugin.c:91
 #, c-format
 msgid "%s%s: %s"
 msgstr "%s%s: %s"
 
-#: plugins/sudoers/group_plugin.c:102
+#: plugins/sudoers/group_plugin.c:103
 #, c-format
 msgid "%s must be owned by uid %d"
 msgstr "%s-omistajan on oltava uid %d"
 
-#: plugins/sudoers/group_plugin.c:106
+#: plugins/sudoers/group_plugin.c:107
 #, c-format
 msgid "%s must only be writable by owner"
 msgstr "%s on vain omistajan kirjoitettava"
 
-#: plugins/sudoers/group_plugin.c:113
+#: plugins/sudoers/group_plugin.c:114
 #, c-format
 msgid "unable to dlopen %s: %s"
 msgstr "ei kyetä kutsumaan funktiota dlopen %s: %s"
 
 #  parametrina on path
-#: plugins/sudoers/group_plugin.c:118
+#: plugins/sudoers/group_plugin.c:119
 #, c-format
 msgid "unable to find symbol \"group_plugin\" in %s"
 msgstr "ei kyetä löytämään symbolia ”group_plugin” polusta %s"
 
-#: plugins/sudoers/group_plugin.c:123
+#: plugins/sudoers/group_plugin.c:124
 #, c-format
 msgid "%s: incompatible group plugin major version %d, expected %d"
 msgstr "%s: yhteensopimaton ryhmälisäosan major-versio %d, odotettiin %d"
 
-#: plugins/sudoers/interfaces.c:109
+#: plugins/sudoers/interfaces.c:112
 msgid "Local IP address and netmask pairs:\n"
 msgstr "Paikallinen ip-osoite ja verkkopeiteparit:\n"
 
 #  Parametrinä on sudoers-tiedosto tai pathbuf
-#: plugins/sudoers/iolog.c:176 plugins/sudoers/sudoers.c:978
+#: plugins/sudoers/iolog.c:179 plugins/sudoers/sudoers.c:999
 #, c-format
 msgid "unable to read %s"
 msgstr "ei kyetä lukemaan kohdetta %s"
 
-#: plugins/sudoers/iolog.c:179
+#: plugins/sudoers/iolog.c:182
 #, c-format
 msgid "invalid sequence number %s"
 msgstr "virheellinen sarjanumero %s"
 
 #  Parametrina on pathbuf
-#: plugins/sudoers/iolog.c:225 plugins/sudoers/iolog.c:228
-#: plugins/sudoers/iolog.c:478 plugins/sudoers/iolog.c:483
-#: plugins/sudoers/iolog.c:489 plugins/sudoers/iolog.c:497
-#: plugins/sudoers/iolog.c:505 plugins/sudoers/iolog.c:513
-#: plugins/sudoers/iolog.c:521
+#: plugins/sudoers/iolog.c:231 plugins/sudoers/iolog.c:234
+#: plugins/sudoers/iolog.c:499 plugins/sudoers/iolog.c:504
+#: plugins/sudoers/iolog.c:510 plugins/sudoers/iolog.c:518
+#: plugins/sudoers/iolog.c:526 plugins/sudoers/iolog.c:534
+#: plugins/sudoers/iolog.c:542
 #, c-format
 msgid "unable to create %s"
 msgstr "ei kyetä luomaan hakemistopolkua %s"
 
-#: plugins/sudoers/iolog_path.c:247 plugins/sudoers/sudoers.c:357
+#: plugins/sudoers/iolog_path.c:256 plugins/sudoers/sudoers.c:362
 #, c-format
 msgid "unable to set locale to \"%s\", using \"C\""
 msgstr "ei kyetä asettamaan locale-asetukseksi ”%s”, käytetään ”C”"
 
-#: plugins/sudoers/ldap.c:368
+#: plugins/sudoers/ldap.c:374
 #, c-format
 msgid "sudo_ldap_conf_add_ports: port too large"
 msgstr "sudo_ldap_conf_add_ports: portti on liian suuri"
 
-#: plugins/sudoers/ldap.c:391
+#: plugins/sudoers/ldap.c:397
 #, c-format
 msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
 msgstr "sudo_ldap_conf_add_ports: hostbuf-puskuritila loppui"
 
 #  URL on verkko-osoite, loogisesti URI on verkkoresurssi(osoite)
-#: plugins/sudoers/ldap.c:420
+#: plugins/sudoers/ldap.c:427
 #, c-format
 msgid "unsupported LDAP uri type: %s"
 msgstr "tukematon LDAP-verkkoresurssin tunnustyyppi: %s"
 
-#: plugins/sudoers/ldap.c:449
+#: plugins/sudoers/ldap.c:456
 #, c-format
 msgid "invalid uri: %s"
 msgstr "virheellinen verkkoresurssin tunnus: %s"
 
-#: plugins/sudoers/ldap.c:455
+#: plugins/sudoers/ldap.c:462
 #, c-format
 msgid "unable to mix ldap and ldaps URIs"
 msgstr "ei kyetä sekottamaan ldap:n ja ldap-kohteiden verkkoresurssitunnuksia"
 
-#: plugins/sudoers/ldap.c:459
+#: plugins/sudoers/ldap.c:466
 #, c-format
 msgid "unable to mix ldaps and starttls"
 msgstr "ei kyetä sekoittamaan ldap- ja starttl-kohteita"
 
-#: plugins/sudoers/ldap.c:478
+#: plugins/sudoers/ldap.c:485
 #, c-format
 msgid "sudo_ldap_parse_uri: out of space building hostbuf"
 msgstr "sudo_ldap_parse_uri: hostbuf-puskuritila loppui"
 
-#: plugins/sudoers/ldap.c:541
+#: plugins/sudoers/ldap.c:550
 #, c-format
 msgid "unable to initialize SSL cert and key db: %s"
 msgstr "ei kyetä alustamaan SSL-varmenne- ja -avaintietokantaa: %s"
 
-#: plugins/sudoers/ldap.c:937
+#: plugins/sudoers/ldap.c:958
 #, c-format
 msgid "unable to get GMT time"
 msgstr "ei kyetä saamaan GMT-aikaa"
 
-#: plugins/sudoers/ldap.c:943
+#: plugins/sudoers/ldap.c:964
 #, c-format
 msgid "unable to format timestamp"
 msgstr "ei kyetä muotoilemaan aikaleimaa"
 
-#: plugins/sudoers/ldap.c:951
+#: plugins/sudoers/ldap.c:972
 #, c-format
 msgid "unable to build time filter"
 msgstr "ei kyetä rakentamaan aikasuodatinta"
 
-#: plugins/sudoers/ldap.c:1052
+#: plugins/sudoers/ldap.c:1185
 #, c-format
 msgid "sudo_ldap_build_pass1 allocation mismatch"
 msgstr "sudo_ldap_build_pass1-varaustäsmäämättömyys"
 
-#: plugins/sudoers/ldap.c:1562
+#: plugins/sudoers/ldap.c:1705
 #, c-format
 msgid ""
 "\n"
@@ -713,7 +712,7 @@ msgstr ""
 "\n"
 "LDAP-rooli: %s\n"
 
-#: plugins/sudoers/ldap.c:1564
+#: plugins/sudoers/ldap.c:1707
 #, c-format
 msgid ""
 "\n"
@@ -722,124 +721,129 @@ msgstr ""
 "\n"
 "LDAP-rooli: TUNTEMATON\n"
 
-#: plugins/sudoers/ldap.c:1611
+#: plugins/sudoers/ldap.c:1754
 #, c-format
 msgid "    Order: %s\n"
 msgstr "    Järjestys: %s\n"
 
-#: plugins/sudoers/ldap.c:1619
+#: plugins/sudoers/ldap.c:1762
 #, c-format
 msgid "    Commands:\n"
 msgstr "    Komennot:\n"
 
-#: plugins/sudoers/ldap.c:2006
+#: plugins/sudoers/ldap.c:2161
 #, c-format
 msgid "unable to initialize LDAP: %s"
 msgstr "ei kyetä alustamaan kohdetta LDAP: %s"
 
-#: plugins/sudoers/ldap.c:2037
+#: plugins/sudoers/ldap.c:2192
 #, c-format
 msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
 msgstr "start_tls määritelty mutta LDAP-kirjastot ei tue funktiota ldap_start_tls_s() tai funktiota ldap_start_tls_s_np()"
 
-#: plugins/sudoers/ldap.c:2268
+#: plugins/sudoers/ldap.c:2428
 #, c-format
 msgid "invalid sudoOrder attribute: %s"
 msgstr "virheellinen sudoOrder-attribuutti: %s"
 
-#: plugins/sudoers/linux_audit.c:55
+#: plugins/sudoers/linux_audit.c:57
 #, c-format
 msgid "unable to open audit system"
 msgstr "ei kyetä avaamaan audit-järjestelmää"
 
-#: plugins/sudoers/linux_audit.c:79
+#: plugins/sudoers/linux_audit.c:82
 #, c-format
 msgid "internal error, linux_audit_command() overflow"
 msgstr "sisäinen virhe, linux_audit_command()-ylivuoto"
 
-#: plugins/sudoers/linux_audit.c:88
+#: plugins/sudoers/linux_audit.c:91
 #, c-format
 msgid "unable to send audit message"
 msgstr "ei kyetä lähettämään audit-viestiä"
 
-#: plugins/sudoers/logging.c:192
+#: plugins/sudoers/logging.c:198
 #, c-format
 msgid "unable to open log file: %s: %s"
 msgstr "ei kyetä avaamaan lokitiedostoa: %s: %s"
 
-#: plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:201
 #, c-format
 msgid "unable to lock log file: %s: %s"
 msgstr "ei kyetä lukitsemaan lokitiedostoa: %s: %s"
 
-#: plugins/sudoers/logging.c:249
+#: plugins/sudoers/logging.c:256
 msgid "user NOT in sudoers"
 msgstr "käyttäjä EI ole sudoers-tiedostossa"
 
-#: plugins/sudoers/logging.c:251
+#: plugins/sudoers/logging.c:258
 msgid "user NOT authorized on host"
 msgstr "käyttäjä ei ole varmennettu tietokoneella"
 
-#: plugins/sudoers/logging.c:253
+#: plugins/sudoers/logging.c:260
 msgid "command not allowed"
 msgstr "komento ei ole sallittu"
 
-#: plugins/sudoers/logging.c:263
+#: plugins/sudoers/logging.c:270
 #, c-format
 msgid "%s is not in the sudoers file.  This incident will be reported.\n"
 msgstr "käyttäjä %s ei ole sudoers-tiedostossa.  Tästä tapahtumasta ilmoitetaan.\n"
 
-#: plugins/sudoers/logging.c:266
+#: plugins/sudoers/logging.c:273
 #, c-format
 msgid "%s is not allowed to run sudo on %s.  This incident will be reported.\n"
 msgstr "käyttäjä %s ei saa suorittaa komentoa sudo tietokoneella %s.  Tästä tapahtumasta ilmoitetaan.\n"
 
-#: plugins/sudoers/logging.c:270
+#: plugins/sudoers/logging.c:277
 #, c-format
 msgid "Sorry, user %s may not run sudo on %s.\n"
 msgstr "Käyttäjä %s ei voi suorittaa komentoa sudo tietokoneella %s.\n"
 
-#: plugins/sudoers/logging.c:273
+#: plugins/sudoers/logging.c:280
 #, c-format
 msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
 msgstr "Käyttäjän %s ei sallita suorittaa ’%s%s%s’ käyttäjänä %s%s%s tietokoneella %s.\n"
 
-#: plugins/sudoers/logging.c:408
+#: plugins/sudoers/logging.c:420
 #, c-format
 msgid "unable to fork"
 msgstr "ei kyetä kutsumaan fork-funktiota"
 
-#: plugins/sudoers/logging.c:415 plugins/sudoers/logging.c:472
+#: plugins/sudoers/logging.c:427 plugins/sudoers/logging.c:489
 #, c-format
 msgid "unable to fork: %m"
 msgstr "ei kyetä kutsumaan fork-funktiota: %m"
 
-#: plugins/sudoers/logging.c:465
+#: plugins/sudoers/logging.c:479
 #, c-format
 msgid "unable to open pipe: %m"
 msgstr "ei kyetä avaamaan putkea: %m"
 
-#: plugins/sudoers/logging.c:484
+#: plugins/sudoers/logging.c:504
 #, c-format
 msgid "unable to dup stdin: %m"
 msgstr "ei kyetä kutsumaan funktiota dup vakiosyötteellä: %m"
 
-#: plugins/sudoers/logging.c:518
+#: plugins/sudoers/logging.c:540
 #, c-format
 msgid "unable to execute %s: %m"
 msgstr "ei kyetä suorittamaan %s: %m"
 
-#: plugins/sudoers/logging.c:728
+#: plugins/sudoers/logging.c:755
 #, c-format
 msgid "internal error: insufficient space for log line"
 msgstr "sisäinen virhe: riittämättömästi tilaa lokiriville"
 
-#: plugins/sudoers/parse.c:115
+#: plugins/sudoers/parse.c:123
 #, c-format
 msgid "parse error in %s near line %d"
 msgstr "jäsentämisvirhe tiedostossa %s lähellä riviä %d"
 
-#: plugins/sudoers/parse.c:371
+#: plugins/sudoers/parse.c:126
+#, c-format
+msgid "parse error in %s"
+msgstr "jäsentämisvirhe tiedostossa %s"
+
+#: plugins/sudoers/parse.c:389
 #, c-format
 msgid ""
 "\n"
@@ -848,17 +852,17 @@ msgstr ""
 "\n"
 "Sudoers-rivi:\n"
 
-#: plugins/sudoers/parse.c:373
+#: plugins/sudoers/parse.c:391
 #, c-format
 msgid "    RunAsUsers: "
 msgstr "    SuoritaKäyttäjänä: "
 
-#: plugins/sudoers/parse.c:388
+#: plugins/sudoers/parse.c:406
 #, c-format
 msgid "    RunAsGroups: "
 msgstr "    SuoritaRyhmänä: "
 
-#: plugins/sudoers/parse.c:397
+#: plugins/sudoers/parse.c:415
 #, c-format
 msgid ""
 "    Commands:\n"
@@ -871,97 +875,97 @@ msgstr ""
 msgid ": "
 msgstr ": "
 
-#: plugins/sudoers/pwutil.c:251
+#: plugins/sudoers/pwutil.c:260
 #, c-format
 msgid "unable to cache uid %u (%s), already exists"
 msgstr "ei kyetä laittamaan välimuistiin uid %u (%s) -käyttäjää, on jo siellä"
 
-#: plugins/sudoers/pwutil.c:259
+#: plugins/sudoers/pwutil.c:268
 #, c-format
 msgid "unable to cache uid %u, already exists"
 msgstr "ei kyetä laittamaan välimuistiin uid %u -käyttäjää, on jo siellä"
 
-#: plugins/sudoers/pwutil.c:295 plugins/sudoers/pwutil.c:304
+#: plugins/sudoers/pwutil.c:305 plugins/sudoers/pwutil.c:314
 #, c-format
 msgid "unable to cache user %s, already exists"
 msgstr "ei kyetä laittamaan välimuistiin käyttäjää %s, on jo siellä"
 
-#: plugins/sudoers/pwutil.c:607
+#: plugins/sudoers/pwutil.c:655
 #, c-format
 msgid "unable to cache gid %u (%s), already exists"
 msgstr "ei kyetä laittamaan välimuistiin gid %u (%s) -ryhmää, on jo siellä"
 
-#: plugins/sudoers/pwutil.c:615
+#: plugins/sudoers/pwutil.c:663
 #, c-format
 msgid "unable to cache gid %u, already exists"
 msgstr "ei kyetä laittamaan välimuistiin gid %u -ryhmää, on jo siellä"
 
-#: plugins/sudoers/pwutil.c:644 plugins/sudoers/pwutil.c:653
+#: plugins/sudoers/pwutil.c:693 plugins/sudoers/pwutil.c:702
 #, c-format
 msgid "unable to cache group %s, already exists"
 msgstr "ei kyetä laittamaan välimuistiin ryhmää %s, on jo siellä"
 
-#: plugins/sudoers/set_perms.c:109 plugins/sudoers/set_perms.c:358
-#: plugins/sudoers/set_perms.c:590 plugins/sudoers/set_perms.c:824
+#: plugins/sudoers/set_perms.c:114 plugins/sudoers/set_perms.c:365
+#: plugins/sudoers/set_perms.c:601 plugins/sudoers/set_perms.c:837
 msgid "perm stack overflow"
 msgstr "käyttöoikeuspinoylivuoto"
 
-#: plugins/sudoers/set_perms.c:117 plugins/sudoers/set_perms.c:366
-#: plugins/sudoers/set_perms.c:598 plugins/sudoers/set_perms.c:832
+#: plugins/sudoers/set_perms.c:122 plugins/sudoers/set_perms.c:373
+#: plugins/sudoers/set_perms.c:609 plugins/sudoers/set_perms.c:845
 msgid "perm stack underflow"
 msgstr "käyttöoikeuspinovajaus"
 
-#: plugins/sudoers/set_perms.c:223 plugins/sudoers/set_perms.c:458
-#: plugins/sudoers/set_perms.c:695
+#: plugins/sudoers/set_perms.c:228 plugins/sudoers/set_perms.c:466
+#: plugins/sudoers/set_perms.c:706
 msgid "unable to change to runas gid"
 msgstr "ei kyetä vaihtamaan runas gid -tunnisteeksi"
 
-#: plugins/sudoers/set_perms.c:231 plugins/sudoers/set_perms.c:465
-#: plugins/sudoers/set_perms.c:702
+#: plugins/sudoers/set_perms.c:236 plugins/sudoers/set_perms.c:473
+#: plugins/sudoers/set_perms.c:713
 msgid "unable to change to runas uid"
 msgstr "ei kyetä vaihtamaan runas gid -tunnisteeksi"
 
-#: plugins/sudoers/set_perms.c:245 plugins/sudoers/set_perms.c:478
-#: plugins/sudoers/set_perms.c:715
+#: plugins/sudoers/set_perms.c:250 plugins/sudoers/set_perms.c:486
+#: plugins/sudoers/set_perms.c:726
 #, c-format
 msgid "unable to change to sudoers gid"
 msgstr "ei kyetä vaihtamaan sudoers gid-tunnisteeksi"
 
-#: plugins/sudoers/set_perms.c:286 plugins/sudoers/set_perms.c:516
-#: plugins/sudoers/set_perms.c:753 plugins/sudoers/set_perms.c:893
+#: plugins/sudoers/set_perms.c:291 plugins/sudoers/set_perms.c:524
+#: plugins/sudoers/set_perms.c:764 plugins/sudoers/set_perms.c:906
 msgid "too many processes"
 msgstr "liian monta prosessia"
 
-#: plugins/sudoers/set_perms.c:955
+#: plugins/sudoers/set_perms.c:970
 msgid "unable to set runas group vector"
 msgstr "ei kyetä asettaan runas-ryhmävektoria"
 
-#: plugins/sudoers/sudo_nss.c:238
+#: plugins/sudoers/sudo_nss.c:243
 #, c-format
 msgid "Matching Defaults entries for %s on this host:\n"
 msgstr "Täsmäävät Defaults-rivit kohteelle %s tällä tietokoneella:\n"
 
-#: plugins/sudoers/sudo_nss.c:251
+#: plugins/sudoers/sudo_nss.c:256
 #, c-format
 msgid "Runas and Command-specific defaults for %s:\n"
 msgstr "Runas- ja Command-kohtaiset oletukset kohteelle %s:\n"
 
-#: plugins/sudoers/sudo_nss.c:264
+#: plugins/sudoers/sudo_nss.c:269
 #, c-format
 msgid "User %s may run the following commands on this host:\n"
 msgstr "Käyttäjä %s voi suorittaa seuraavat komennot tällä tietokoneella:\n"
 
-#: plugins/sudoers/sudo_nss.c:274
+#: plugins/sudoers/sudo_nss.c:279
 #, c-format
 msgid "User %s is not allowed to run sudo on %s.\n"
 msgstr "Käyttäjä %s ei saa suorittaa komentoa sudo tietokoneella %s.\n"
 
-#: plugins/sudoers/sudoers.c:199 plugins/sudoers/sudoers.c:234
-#: plugins/sudoers/sudoers.c:911
+#: plugins/sudoers/sudoers.c:201 plugins/sudoers/sudoers.c:232
+#: plugins/sudoers/sudoers.c:931
 msgid "problem with defaults entries"
 msgstr "oletusrivien pulma"
 
-#: plugins/sudoers/sudoers.c:203
+#: plugins/sudoers/sudoers.c:205
 #, c-format
 msgid "no valid sudoers sources found, quitting"
 msgstr "ei löytynyt kelvollisia sudoers-lähteitä, poistutaan"
@@ -971,42 +975,42 @@ msgstr "ei löytynyt kelvollisia sudoers-lähteitä, poistutaan"
 msgid "unable to execute %s: %s"
 msgstr "ei kyetä suorittamaan komentoa %s: %s"
 
-#: plugins/sudoers/sudoers.c:306
+#: plugins/sudoers/sudoers.c:311
 #, c-format
 msgid "sudoers specifies that root is not allowed to sudo"
 msgstr "sudoers määrittelee, että root ei saa suorittaa sudo-komentoa"
 
-#: plugins/sudoers/sudoers.c:313
+#: plugins/sudoers/sudoers.c:318
 #, c-format
 msgid "you are not permitted to use the -C option"
 msgstr "ei käyttöoikeuksia valitsimelle -C"
 
-#: plugins/sudoers/sudoers.c:403
+#: plugins/sudoers/sudoers.c:408
 #, c-format
 msgid "timestamp owner (%s): No such user"
 msgstr "aikaleimaomistaja (%s): Tuntematon käyttäjä"
 
-#: plugins/sudoers/sudoers.c:419
+#: plugins/sudoers/sudoers.c:424
 msgid "no tty"
 msgstr "ei tty:tä"
 
-#: plugins/sudoers/sudoers.c:420
+#: plugins/sudoers/sudoers.c:425
 #, c-format
 msgid "sorry, you must have a tty to run sudo"
 msgstr "sudo-komennon suorittamiseksi on oltava tty"
 
-#: plugins/sudoers/sudoers.c:463
+#: plugins/sudoers/sudoers.c:464
 msgid "No user or host"
 msgstr "Ei käyttäjä eikä tietokone"
 
-#: plugins/sudoers/sudoers.c:477 plugins/sudoers/sudoers.c:498
-#: plugins/sudoers/sudoers.c:499 plugins/sudoers/sudoers.c:1465
-#: plugins/sudoers/sudoers.c:1466
+#: plugins/sudoers/sudoers.c:478 plugins/sudoers/sudoers.c:499
+#: plugins/sudoers/sudoers.c:500 plugins/sudoers/sudoers.c:1509
+#: plugins/sudoers/sudoers.c:1510
 #, c-format
 msgid "%s: command not found"
 msgstr "%s: komentoa ei löytynyt"
 
-#: plugins/sudoers/sudoers.c:479 plugins/sudoers/sudoers.c:495
+#: plugins/sudoers/sudoers.c:480 plugins/sudoers/sudoers.c:496
 #, c-format
 msgid ""
 "ignoring `%s' found in '.'\n"
@@ -1015,98 +1019,103 @@ msgstr ""
 "ohitetaan komento ”%s”, joka löytyi kohteesta ’.’\n"
 "Käytä ”sudo ./%s”, jos tämä on ”%s”-komento, joka halutaan suorittaa."
 
-#: plugins/sudoers/sudoers.c:484
+#: plugins/sudoers/sudoers.c:485
 msgid "validation failure"
 msgstr "kelpuutushäiriö"
 
-#: plugins/sudoers/sudoers.c:494
+#: plugins/sudoers/sudoers.c:495
 msgid "command in current directory"
 msgstr "komento nykyisessä hakemistossa"
 
-#: plugins/sudoers/sudoers.c:506
+#: plugins/sudoers/sudoers.c:507
 #, c-format
 msgid "sorry, you are not allowed to preserve the environment"
 msgstr "ympäristöä ei ole lupa säilyttää"
 
-#: plugins/sudoers/sudoers.c:894
+#: plugins/sudoers/sudoers.c:657 plugins/sudoers/sudoers.c:664
+#, c-format
+msgid "internal error, runas_groups overflow"
+msgstr "sisäinen virhe, runas_groups-ylivuoto"
+
+#: plugins/sudoers/sudoers.c:914
 #, c-format
 msgid "internal error, set_cmnd() overflow"
 msgstr "sisäinen virhe, set_cmnd()-ylivuoto"
 
 #  Parametri on sudoers file
-#: plugins/sudoers/sudoers.c:936
+#: plugins/sudoers/sudoers.c:957
 #, c-format
 msgid "fixed mode on %s"
 msgstr "korjattu tila tiedostossa %s"
 
 #  Parametri on suoders file
-#: plugins/sudoers/sudoers.c:940
+#: plugins/sudoers/sudoers.c:961
 #, c-format
 msgid "set group on %s"
 msgstr "aseta ryhmä tiedostossa %s"
 
 #  Parametri on sudoers file
-#: plugins/sudoers/sudoers.c:943
+#: plugins/sudoers/sudoers.c:964
 #, c-format
 msgid "unable to set group on %s"
 msgstr "ei kyetä asettamaan ryhmää tiedostossa %s"
 
-#: plugins/sudoers/sudoers.c:946
+#: plugins/sudoers/sudoers.c:967
 #, c-format
 msgid "unable to fix mode on %s"
 msgstr "ei kyetä korjaamaan tilaa tiedostossa %s"
 
-#: plugins/sudoers/sudoers.c:959
+#: plugins/sudoers/sudoers.c:980
 #, c-format
 msgid "%s is not a regular file"
 msgstr "%s ei ole tavallinen tiedosto"
 
-#: plugins/sudoers/sudoers.c:961
+#: plugins/sudoers/sudoers.c:982
 #, c-format
 msgid "%s is mode 0%o, should be 0%o"
 msgstr "%s on tila 0%o, pitäisi olla 0%o"
 
-#: plugins/sudoers/sudoers.c:965
+#: plugins/sudoers/sudoers.c:986
 #, c-format
 msgid "%s is owned by uid %u, should be %u"
 msgstr "%s on uid %u -käyttäjän omistama, pitäisi olla %u"
 
-#: plugins/sudoers/sudoers.c:968
+#: plugins/sudoers/sudoers.c:989
 #, c-format
 msgid "%s is owned by gid %u, should be %u"
 msgstr "%s on gid %u -ryhmän omistama, pitäisi olla %u"
 
-#: plugins/sudoers/sudoers.c:1012
+#: plugins/sudoers/sudoers.c:1038
 #, c-format
 msgid "only root can use `-c %s'"
 msgstr "vain root-käyttäjä voi käyttää valitsinta ”-c %s”"
 
-#: plugins/sudoers/sudoers.c:1022
+#: plugins/sudoers/sudoers.c:1049
 #, c-format
 msgid "unknown login class: %s"
 msgstr "tuntematon kirjautumisluokka: %s"
 
-#: plugins/sudoers/sudoers.c:1056
+#: plugins/sudoers/sudoers.c:1077
 #, c-format
 msgid "unable to resolve host %s"
 msgstr "ei kyetä ratkaisemaan tietokonetta %s"
 
-#: plugins/sudoers/sudoers.c:1106 plugins/sudoers/testsudoers.c:351
+#: plugins/sudoers/sudoers.c:1129 plugins/sudoers/testsudoers.c:380
 #, c-format
 msgid "unknown group: %s"
 msgstr "tuntematon ryhmä: %s"
 
-#: plugins/sudoers/sudoers.c:1150
+#: plugins/sudoers/sudoers.c:1178
 #, c-format
 msgid "Sudoers policy plugin version %s\n"
 msgstr "Sudoers-menettelytapalisäosaversio %s\n"
 
-#: plugins/sudoers/sudoers.c:1152
+#: plugins/sudoers/sudoers.c:1180
 #, c-format
 msgid "Sudoers file grammar version %d\n"
 msgstr "Sudoers-tiedostokielioppiversio %d\n"
 
-#: plugins/sudoers/sudoers.c:1156
+#: plugins/sudoers/sudoers.c:1184
 #, c-format
 msgid ""
 "\n"
@@ -1115,147 +1124,147 @@ msgstr ""
 "\n"
 "Sudoers-polku: %s\n"
 
-#: plugins/sudoers/sudoers.c:1159
+#: plugins/sudoers/sudoers.c:1187
 #, c-format
 msgid "nsswitch path: %s\n"
 msgstr "nsswitch-polku: %s\n"
 
-#: plugins/sudoers/sudoers.c:1161
+#: plugins/sudoers/sudoers.c:1189
 #, c-format
 msgid "ldap.conf path: %s\n"
 msgstr "ldap.conf-polku: %s\n"
 
-#: plugins/sudoers/sudoers.c:1162
+#: plugins/sudoers/sudoers.c:1190
 #, c-format
 msgid "ldap.secret path: %s\n"
 msgstr "ldap.secret-polku: %s\n"
 
-#: plugins/sudoers/sudoreplay.c:265
+#: plugins/sudoers/sudoreplay.c:286
 #, c-format
 msgid "invalid filter option: %s"
 msgstr "virheellinen suodatinvalitsin: %s"
 
-#: plugins/sudoers/sudoreplay.c:278
+#: plugins/sudoers/sudoreplay.c:299
 #, c-format
 msgid "invalid max wait: %s"
 msgstr "virheellinen enimmäisodotusaika: %s"
 
-#: plugins/sudoers/sudoreplay.c:284
+#: plugins/sudoers/sudoreplay.c:305
 #, c-format
 msgid "invalid speed factor: %s"
 msgstr "virheellinen nopeustekijä: %s"
 
-#: plugins/sudoers/sudoreplay.c:287 plugins/sudoers/visudo.c:174
+#: plugins/sudoers/sudoreplay.c:308 plugins/sudoers/visudo.c:187
 #, c-format
 msgid "%s version %s\n"
 msgstr "%s versio %s\n"
 
-#: plugins/sudoers/sudoreplay.c:310
+#: plugins/sudoers/sudoreplay.c:333
 #, c-format
 msgid "%s/%.2s/%.2s/%.2s/timing: %s"
 msgstr "%s/%.2s/%.2s/%.2s/ajoitus: %s"
 
-#: plugins/sudoers/sudoreplay.c:316
+#: plugins/sudoers/sudoreplay.c:339
 #, c-format
 msgid "%s/%s/timing: %s"
 msgstr "%s/%s/ajoitus: %s"
 
-#: plugins/sudoers/sudoreplay.c:341
+#: plugins/sudoers/sudoreplay.c:364
 #, c-format
 msgid "invalid log file %s"
 msgstr "virheellinen lokitiedosto %s"
 
-#: plugins/sudoers/sudoreplay.c:343
+#: plugins/sudoers/sudoreplay.c:366
 #, c-format
 msgid "Replaying sudo session: %s"
 msgstr "Toistetaan sudo-istunto: %s"
 
-#: plugins/sudoers/sudoreplay.c:369
+#: plugins/sudoers/sudoreplay.c:392
 #, c-format
 msgid "unable to set tty to raw mode"
 msgstr "ei kyetä asettamaa tty:ta raakatilaan"
 
-#: plugins/sudoers/sudoreplay.c:383
+#: plugins/sudoers/sudoreplay.c:406
 #, c-format
 msgid "invalid timing file line: %s"
 msgstr "virheellinen ajoitustiedostorivi: %s"
 
-#: plugins/sudoers/sudoreplay.c:425
+#: plugins/sudoers/sudoreplay.c:448
 #, c-format
 msgid "writing to standard output"
 msgstr "kirjoitetaan vakiotulosteeseen"
 
-#: plugins/sudoers/sudoreplay.c:455
+#: plugins/sudoers/sudoreplay.c:480
 #, c-format
 msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
 msgstr "nanosleep: tv_sec %ld, tv_nsec %ld"
 
-#: plugins/sudoers/sudoreplay.c:503 plugins/sudoers/sudoreplay.c:528
+#: plugins/sudoers/sudoreplay.c:529 plugins/sudoers/sudoreplay.c:554
 #, c-format
 msgid "ambiguous expression \"%s\""
 msgstr "monimerkityksellinen lauseke ”%s”"
 
-#: plugins/sudoers/sudoreplay.c:545
+#: plugins/sudoers/sudoreplay.c:571
 #, c-format
 msgid "too many parenthesized expressions, max %d"
 msgstr "liian monta sulkumerkillistä lauseketta, enintään %d"
 
-#: plugins/sudoers/sudoreplay.c:556
+#: plugins/sudoers/sudoreplay.c:582
 #, c-format
 msgid "unmatched ')' in expression"
 msgstr "täsmäämätön ’)’ lausekkeessa"
 
-#: plugins/sudoers/sudoreplay.c:562
+#: plugins/sudoers/sudoreplay.c:588
 #, c-format
 msgid "unknown search term \"%s\""
 msgstr "tuntematon hakutermi ”%s”"
 
-#: plugins/sudoers/sudoreplay.c:576
+#: plugins/sudoers/sudoreplay.c:602
 #, c-format
 msgid "%s requires an argument"
 msgstr "%s vaatii argumentin"
 
-#: plugins/sudoers/sudoreplay.c:580
+#: plugins/sudoers/sudoreplay.c:606
 #, c-format
 msgid "invalid regular expression: %s"
 msgstr "virheellinen säännöllinen lauseke: %s"
 
-#: plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:612
 #, c-format
 msgid "could not parse date \"%s\""
 msgstr "ei voitu jäsentää päivämäärää ”%s”"
 
-#: plugins/sudoers/sudoreplay.c:599
+#: plugins/sudoers/sudoreplay.c:625
 #, c-format
 msgid "unmatched '(' in expression"
 msgstr "täsmäämätön ’(’ lausekkeessa"
 
-#: plugins/sudoers/sudoreplay.c:601
+#: plugins/sudoers/sudoreplay.c:627
 #, c-format
 msgid "illegal trailing \"or\""
 msgstr "virheellinen jäljessä oleva ”or”"
 
-#: plugins/sudoers/sudoreplay.c:603
+#: plugins/sudoers/sudoreplay.c:629
 #, c-format
 msgid "illegal trailing \"!\""
 msgstr "virheellinen jäljessä oleva ”!”"
 
-#: plugins/sudoers/sudoreplay.c:819
+#: plugins/sudoers/sudoreplay.c:851
 #, c-format
 msgid "invalid regex: %s"
 msgstr "virheellinen säännöllinen lauseke: %s"
 
-#: plugins/sudoers/sudoreplay.c:941
+#: plugins/sudoers/sudoreplay.c:976
 #, c-format
 msgid "usage: %s [-h] [-d directory] [-m max_wait] [-s speed_factor] ID\n"
 msgstr "käyttö: %s [-h] [-d hakemisto] [-m enimmäisodotusaika] [-s nopeustekijä] ID-tunniste\n"
 
-#: plugins/sudoers/sudoreplay.c:944
+#: plugins/sudoers/sudoreplay.c:979
 #, c-format
 msgid "usage: %s [-h] [-d directory] -l [search expression]\n"
 msgstr "käyttö: %s [-h] [-d hakemisto] -l [hakulauseke]\n"
 
-#: plugins/sudoers/sudoreplay.c:953
+#: plugins/sudoers/sudoreplay.c:988
 #, c-format
 msgid ""
 "%s - replay sudo session logs\n"
@@ -1264,7 +1273,7 @@ msgstr ""
 "%s - toista sudo-istuntolokit\n"
 "\n"
 
-#: plugins/sudoers/sudoreplay.c:955
+#: plugins/sudoers/sudoreplay.c:990
 msgid ""
 "\n"
 "Options:\n"
@@ -1286,16 +1295,16 @@ msgstr ""
 "  -s nopeustekijä  nopeuta tai hidasta tulostusta\n"
 "  -V               näytä versiotiedot ja poistu"
 
-#: plugins/sudoers/testsudoers.c:230
+#: plugins/sudoers/testsudoers.c:246
 #, c-format
 msgid "internal error, init_vars() overflow"
 msgstr "sisäinen virhe, init_vars()-ylivuoto"
 
-#: plugins/sudoers/testsudoers.c:309
+#: plugins/sudoers/testsudoers.c:331
 msgid "\thost  unmatched"
 msgstr "\ttietokone täsmäämätön"
 
-#: plugins/sudoers/testsudoers.c:312
+#: plugins/sudoers/testsudoers.c:334
 msgid ""
 "\n"
 "Command allowed"
@@ -1303,7 +1312,7 @@ msgstr ""
 "\n"
 "Komento sallittu"
 
-#: plugins/sudoers/testsudoers.c:313
+#: plugins/sudoers/testsudoers.c:335
 msgid ""
 "\n"
 "Command denied"
@@ -1311,7 +1320,7 @@ msgstr ""
 "\n"
 "Komento kielletty"
 
-#: plugins/sudoers/testsudoers.c:313
+#: plugins/sudoers/testsudoers.c:335
 msgid ""
 "\n"
 "Command unmatched"
@@ -1319,104 +1328,104 @@ msgstr ""
 "\n"
 "Täsmäämätön komento"
 
-#: toke.l:667 toke.l:793 toke.l:818 toke.l:904 plugins/sudoers/toke_util.c:111
-#: plugins/sudoers/toke_util.c:163 plugins/sudoers/toke_util.c:202
+#: toke.l:672 toke.l:802 toke.l:827 toke.l:923 plugins/sudoers/toke_util.c:113
+#: plugins/sudoers/toke_util.c:167 plugins/sudoers/toke_util.c:207
 msgid "unable to allocate memory"
 msgstr "ei kyetä varaamaan muistia"
 
-#: toke.l:786
+#: toke.l:795
 msgid "too many levels of includes"
 msgstr "liian monta include-tasoa"
 
-#: plugins/sudoers/toke_util.c:213
+#: plugins/sudoers/toke_util.c:218
 msgid "fill_args: buffer overflow"
 msgstr "fill_args: puskuriylivuoto"
 
-#: plugins/sudoers/visudo.c:175
+#: plugins/sudoers/visudo.c:188
 #, c-format
 msgid "%s grammar version %d\n"
 msgstr "%s kielioppiversio %d\n"
 
-#: plugins/sudoers/visudo.c:208 plugins/sudoers/auth/rfc1938.c:103
+#: plugins/sudoers/visudo.c:221 plugins/sudoers/auth/rfc1938.c:104
 #, c-format
 msgid "you do not exist in the %s database"
 msgstr "ei ole olemassa %s-tietokannassa"
 
-#: plugins/sudoers/visudo.c:238 plugins/sudoers/visudo.c:518
+#: plugins/sudoers/visudo.c:253 plugins/sudoers/visudo.c:539
 #, c-format
 msgid "press return to edit %s: "
 msgstr "muokkaa %s painamalla enter-painiketta: "
 
-#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:326
+#: plugins/sudoers/visudo.c:336 plugins/sudoers/visudo.c:342
 #, c-format
 msgid "write error"
 msgstr "kirjoitusvirhe"
 
-#: plugins/sudoers/visudo.c:408
+#: plugins/sudoers/visudo.c:424
 #, c-format
 msgid "unable to stat temporary file (%s), %s unchanged"
 msgstr "ei kyetä kutsumaan stat-funktiota tilapäiselle tiedostolle (%s), %s ennallaan"
 
-#: plugins/sudoers/visudo.c:413
+#: plugins/sudoers/visudo.c:429
 #, c-format
 msgid "zero length temporary file (%s), %s unchanged"
 msgstr "nollapituinen tilapäinen tiedosto (%s), %s ennallaan"
 
-#: plugins/sudoers/visudo.c:419
+#: plugins/sudoers/visudo.c:435
 #, c-format
 msgid "editor (%s) failed, %s unchanged"
 msgstr "editori (%s) epäonnistui, %s ennallaan"
 
-#: plugins/sudoers/visudo.c:442
+#: plugins/sudoers/visudo.c:458
 #, c-format
 msgid "%s unchanged"
 msgstr "%s ennallaan"
 
-#: plugins/sudoers/visudo.c:466
+#: plugins/sudoers/visudo.c:484
 #, c-format
 msgid "unable to re-open temporary file (%s), %s unchanged."
 msgstr "ei kyetä avaamaan uudelleen tilapäistä tiedostoa (%s), %s ennallaan."
 
-#: plugins/sudoers/visudo.c:476
+#: plugins/sudoers/visudo.c:494
 #, c-format
 msgid "unabled to parse temporary file (%s), unknown error"
 msgstr "ei kyetä jäsentämään tilapäistä tiedostoa (%s), tuntematon virhe"
 
-#: plugins/sudoers/visudo.c:511
+#: plugins/sudoers/visudo.c:532
 #, c-format
 msgid "internal error, unable to find %s in list!"
 msgstr "sisäinen virhe, ei kyetä löytämään %s luettelosta!"
 
-#: plugins/sudoers/visudo.c:546 plugins/sudoers/visudo.c:555
+#: plugins/sudoers/visudo.c:584 plugins/sudoers/visudo.c:593
 #, c-format
 msgid "unable to set (uid, gid) of %s to (%u, %u)"
 msgstr "ei kyetä asettamaan kohdetta %s (uid, gid) arvoihin (%u, %u)"
 
-#: plugins/sudoers/visudo.c:550 plugins/sudoers/visudo.c:560
+#: plugins/sudoers/visudo.c:588 plugins/sudoers/visudo.c:598
 #, c-format
 msgid "unable to change mode of %s to 0%o"
 msgstr "ei kyetä muuttamaan %s-tilaa arvoon 0%o"
 
-#: plugins/sudoers/visudo.c:577
+#: plugins/sudoers/visudo.c:615
 #, c-format
 msgid "%s and %s not on the same file system, using mv to rename"
 msgstr "%s ja %s eivät ole samassa tiedostojärjestelmässä, käytetään komentoa mv uudelleennimeämiseen"
 
-#: plugins/sudoers/visudo.c:591
+#: plugins/sudoers/visudo.c:629
 #, c-format
 msgid "command failed: '%s %s %s', %s unchanged"
 msgstr "komento epäonnistui: ’%s %s %s’, %s ennallaan"
 
-#: plugins/sudoers/visudo.c:601
+#: plugins/sudoers/visudo.c:639
 #, c-format
 msgid "error renaming %s, %s unchanged"
 msgstr "virhe nimettäessä %s uudelleen, %s ennallaan"
 
-#: plugins/sudoers/visudo.c:661
+#: plugins/sudoers/visudo.c:702
 msgid "What now? "
 msgstr "Mitä nyt?"
 
-#: plugins/sudoers/visudo.c:675
+#: plugins/sudoers/visudo.c:716
 msgid ""
 "Options are:\n"
 "  (e)dit sudoers file again\n"
@@ -1429,93 +1438,93 @@ msgstr ""
 "  (Q) poistu ja tallenna muutokset sudoers-tiedostoon (VAARA!)\n"
 
 #  Parametri on path, mutta saattaa sisältää suoritettavan ohjelman
-#: plugins/sudoers/visudo.c:712
+#: plugins/sudoers/visudo.c:757
 #, c-format
 msgid "unable to execute %s"
 msgstr "ei kyetä suorittamaan kohdetta %s"
 
 #  Parametri on path, mutta saattaa sisältää suoritettavan ohjelman
-#: plugins/sudoers/visudo.c:719
+#: plugins/sudoers/visudo.c:764
 #, c-format
 msgid "unable to run %s"
 msgstr "ei kyetä suorittamaan kohdetta %s"
 
-#: plugins/sudoers/visudo.c:750
+#: plugins/sudoers/visudo.c:796
 #, c-format
 msgid "failed to parse %s file, unknown error"
 msgstr "tiedoston %s jäsentäminen epäonnistui, tuntematon virhe"
 
-#: plugins/sudoers/visudo.c:762
+#: plugins/sudoers/visudo.c:808
 #, c-format
 msgid "parse error in %s near line %d\n"
 msgstr "jäsentämisvirhe tiedostossa %s lähellä riviä %d\n"
 
-#: plugins/sudoers/visudo.c:765
+#: plugins/sudoers/visudo.c:811
 #, c-format
 msgid "parse error in %s\n"
 msgstr "jäsentämisvirhe tiedostossa %s\n"
 
-#: plugins/sudoers/visudo.c:767
+#: plugins/sudoers/visudo.c:814 plugins/sudoers/visudo.c:816
 #, c-format
 msgid "%s: parsed OK\n"
 msgstr "%s: jäsentäminen valmis\n"
 
-#: plugins/sudoers/visudo.c:776
+#: plugins/sudoers/visudo.c:826
 #, c-format
 msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
 msgstr "%s: väärä omistaja (uid, gid), pitäisi olla (%u, %u)\n"
 
-#: plugins/sudoers/visudo.c:783
+#: plugins/sudoers/visudo.c:833
 #, c-format
 msgid "%s: bad permissions, should be mode 0%o\n"
 msgstr "%s: väärät käyttöoikeudet, pitäisi olla tila 0%o\n"
 
-#: plugins/sudoers/visudo.c:822
+#: plugins/sudoers/visudo.c:880
 #, c-format
 msgid "%s busy, try again later"
 msgstr "%s varattu, yritä myöhemmin uudelleen"
 
-#: plugins/sudoers/visudo.c:865
+#: plugins/sudoers/visudo.c:924
 #, c-format
 msgid "specified editor (%s) doesn't exist"
 msgstr "määritelty editori (%s) ei ole olemassa"
 
-#: plugins/sudoers/visudo.c:888
+#: plugins/sudoers/visudo.c:947
 #, c-format
 msgid "unable to stat editor (%s)"
 msgstr "ei kyetä kutsumaan funktiota stat editori (%s)"
 
-#: plugins/sudoers/visudo.c:936
+#: plugins/sudoers/visudo.c:995
 #, c-format
 msgid "no editor found (editor path = %s)"
 msgstr "editoria ei löytynyt (editoripolku = %s)"
 
-#: plugins/sudoers/visudo.c:1025
+#: plugins/sudoers/visudo.c:1089
 #, c-format
 msgid "Error: cycle in %s_Alias `%s'"
 msgstr "Virhe: jakso kohteessa %s_Alias ”%s”"
 
-#: plugins/sudoers/visudo.c:1026
+#: plugins/sudoers/visudo.c:1090
 #, c-format
 msgid "Warning: cycle in %s_Alias `%s'"
 msgstr "Varoitus: jakso kohteessa %s_Alias ”%s”"
 
-#: plugins/sudoers/visudo.c:1029
+#: plugins/sudoers/visudo.c:1093
 #, c-format
 msgid "Error: %s_Alias `%s' referenced but not defined"
 msgstr "Virhe: %s_Alias ”%s” uudelleenviitattu, mutta ei määritelty"
 
-#: plugins/sudoers/visudo.c:1030
+#: plugins/sudoers/visudo.c:1094
 #, c-format
 msgid "Warning: %s_Alias `%s' referenced but not defined"
 msgstr "Varoitus: %s_Alias ”%s” uudelleenviitattu, mutta ei määritelty"
 
-#: plugins/sudoers/visudo.c:1167
+#: plugins/sudoers/visudo.c:1229
 #, c-format
 msgid "%s: unused %s_Alias %s"
 msgstr "%s: käyttämätön %s_Alias %s"
 
-#: plugins/sudoers/visudo.c:1224
+#: plugins/sudoers/visudo.c:1286
 #, c-format
 msgid ""
 "%s - safely edit the sudoers file\n"
@@ -1524,7 +1533,7 @@ msgstr ""
 "%s - muokkaa sudoers-tiedostoa turvallisesti\n"
 "\n"
 
-#: plugins/sudoers/visudo.c:1226
+#: plugins/sudoers/visudo.c:1288
 msgid ""
 "\n"
 "Options:\n"
@@ -1544,35 +1553,40 @@ msgstr ""
 "  -s          tiukka syntaksitarkistus\n"
 "  -V          näytä versiotiedot ja poistu"
 
-#: plugins/sudoers/auth/bsdauth.c:64
+#: plugins/sudoers/auth/bsdauth.c:78
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "ei kyetä saamaan kirjautumisluokkaa käyttäjälle %s"
+
+#: plugins/sudoers/auth/bsdauth.c:84
 msgid "unable to begin bsd authentication"
 msgstr "ei kyetä aloittamaan bsd-todentamista"
 
-#: plugins/sudoers/auth/bsdauth.c:71
+#: plugins/sudoers/auth/bsdauth.c:92
 msgid "invalid authentication type"
 msgstr "virheellinen todennustyyppi"
 
-#: plugins/sudoers/auth/bsdauth.c:79
+#: plugins/sudoers/auth/bsdauth.c:101
 msgid "unable to setup authentication"
 msgstr "ei kyetä asettamaan todentamista"
 
-#: plugins/sudoers/auth/fwtk.c:59
+#: plugins/sudoers/auth/fwtk.c:60
 #, c-format
 msgid "unable to read fwtk config"
 msgstr "ei kyetä lukemaan fwtk config -asetusta"
 
-#: plugins/sudoers/auth/fwtk.c:64
+#: plugins/sudoers/auth/fwtk.c:65
 #, c-format
 msgid "unable to connect to authentication server"
 msgstr "ei kyetä yhdistämään todentamispalvelimelle"
 
-#: plugins/sudoers/auth/fwtk.c:70 plugins/sudoers/auth/fwtk.c:93
-#: plugins/sudoers/auth/fwtk.c:126
+#: plugins/sudoers/auth/fwtk.c:71 plugins/sudoers/auth/fwtk.c:95
+#: plugins/sudoers/auth/fwtk.c:128
 #, c-format
 msgid "lost connection to authentication server"
 msgstr "kadotettiin yhteys todentamispalvelimelle"
 
-#: plugins/sudoers/auth/fwtk.c:74
+#: plugins/sudoers/auth/fwtk.c:75
 #, c-format
 msgid ""
 "authentication server error:\n"
@@ -1581,154 +1595,157 @@ msgstr ""
 "todentamispalvelinvirhe:\n"
 "%s"
 
-#  Ensimmäinen parametri on auth name
-#: plugins/sudoers/auth/kerb5.c:114
-#, c-format
-msgid "%s: unable to parse '%s': %s"
-msgstr "%s: ei kyetä jäsentämään todentamisnimeä ’%s’: %s"
-
 #  Sana princ viittaa krb5_principal -määrittelyyn
-#: plugins/sudoers/auth/kerb5.c:127
+#: plugins/sudoers/auth/kerb5.c:117
 #, c-format
 msgid "%s: unable to unparse princ ('%s'): %s"
 msgstr "%s: ei kyetä poistamaan valtuutetun (’%s’) jäsentämistä: %s"
 
-#: plugins/sudoers/auth/kerb5.c:144
+#  Ensimmäinen parametri on auth name
+#: plugins/sudoers/auth/kerb5.c:160
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: ei kyetä jäsentämään todentamisnimeä ’%s’: %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
 #, c-format
 msgid "%s: unable to resolve ccache: %s"
 msgstr "%s:  ei kyetä ratkaisemaan ccache-välimuistia: %s"
 
-#: plugins/sudoers/auth/kerb5.c:188
+#: plugins/sudoers/auth/kerb5.c:218
 #, c-format
 msgid "%s: unable to allocate options: %s"
 msgstr "%s: ei kyetä varaamaan valitsimia: %s"
 
-#: plugins/sudoers/auth/kerb5.c:204
+#: plugins/sudoers/auth/kerb5.c:234
 #, c-format
 msgid "%s: unable to get credentials: %s"
 msgstr "%s: ei kyetä hakemaan valtuustietoja: %s"
 
-#: plugins/sudoers/auth/kerb5.c:217
+#: plugins/sudoers/auth/kerb5.c:247
 #, c-format
 msgid "%s: unable to initialize ccache: %s"
 msgstr "%s: ei kyetä alustamaan ccache-välimuistia: %s"
 
-#: plugins/sudoers/auth/kerb5.c:221
+#: plugins/sudoers/auth/kerb5.c:251
 #, c-format
 msgid "%s: unable to store cred in ccache: %s"
 msgstr "%s: ei kyetä tallentamaan valtuustietoja ccache-välimuistiin: %s"
 
-#: plugins/sudoers/auth/kerb5.c:284
+#: plugins/sudoers/auth/kerb5.c:316
 #, c-format
 msgid "%s: unable to get host principal: %s"
 msgstr "%s: ei kyetä hakemaan tietokoneen valtuutettua: %s"
 
-#: plugins/sudoers/auth/kerb5.c:299
+#: plugins/sudoers/auth/kerb5.c:331
 #, c-format
 msgid "%s: Cannot verify TGT! Possible attack!: %s"
 msgstr "%s: Ei voida todentaa TGT-lippua! Mahdollinen hyökkäys!: %s"
 
-#: plugins/sudoers/auth/pam.c:99
+#: plugins/sudoers/auth/pam.c:100
 msgid "unable to initialize PAM"
 msgstr "ei kyetä alustamaan PAM:ia"
 
-#: plugins/sudoers/auth/pam.c:142
+#: plugins/sudoers/auth/pam.c:144
 msgid "account validation failure, is your account locked?"
 msgstr "tilikelpuutushäiriö, onko tilisi lukittu?"
 
-#: plugins/sudoers/auth/pam.c:146
+#: plugins/sudoers/auth/pam.c:148
 msgid "Account or password is expired, reset your password and try again"
 msgstr "Tili tai salasana on vanhentunut, nollaa salasanasi tai yritä uudelleen"
 
-#: plugins/sudoers/auth/pam.c:153
+#: plugins/sudoers/auth/pam.c:155
 #, c-format
 msgid "pam_chauthtok: %s"
 msgstr "pam_chauthtok: %s"
 
-#: plugins/sudoers/auth/pam.c:157
+#: plugins/sudoers/auth/pam.c:159
 msgid "Password expired, contact your system administrator"
 msgstr "Salasana vanhentunut, ota yhteyttä järjestelmän ylläpitäjään"
 
-#: plugins/sudoers/auth/pam.c:161
+#: plugins/sudoers/auth/pam.c:163
 msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
 msgstr "Tili vanhentunut tai PAM-asetuksista puuttuu ”account”-lohko sudo-komennolle, ota yhteyttä järjestelmän ylläpitäjään"
 
-#: plugins/sudoers/auth/pam.c:176
+#: plugins/sudoers/auth/pam.c:178
 #, c-format
 msgid "pam_authenticate: %s"
 msgstr "pam_authenticate: %s"
 
-#: plugins/sudoers/auth/pam.c:296
+#: plugins/sudoers/auth/pam.c:306
 msgid "Password: "
 msgstr "Salasana: "
 
-#: plugins/sudoers/auth/pam.c:297
+#: plugins/sudoers/auth/pam.c:307
 msgid "Password:"
 msgstr "Salasana:"
 
-#: plugins/sudoers/auth/securid.c:82 plugins/sudoers/auth/securid5.c:106
-#, c-format
-msgid "unable to contact the SecurID server"
-msgstr "ei kyetä ottamaan yhteyttä SecurID-palvelimeen"
-
 #: plugins/sudoers/auth/securid5.c:81
 #, c-format
 msgid "failed to initialise the ACE API library"
 msgstr "epäonnistui ACE API -kirjaston alustamisessa"
 
-#: plugins/sudoers/auth/securid5.c:115
+#: plugins/sudoers/auth/securid5.c:107
+#, c-format
+msgid "unable to contact the SecurID server"
+msgstr "ei kyetä ottamaan yhteyttä SecurID-palvelimeen"
+
+#: plugins/sudoers/auth/securid5.c:116
 #, c-format
 msgid "User ID locked for SecurID Authentication"
 msgstr "Käyttäjätunniste lukittu SecurID-todennukselle"
 
-#: plugins/sudoers/auth/securid5.c:119 plugins/sudoers/auth/securid5.c:169
+#: plugins/sudoers/auth/securid5.c:120 plugins/sudoers/auth/securid5.c:171
 #, c-format
 msgid "invalid username length for SecurID"
 msgstr "virheellinen käyttäjänimipituus kohteelle SecurID"
 
-#: plugins/sudoers/auth/securid5.c:123 plugins/sudoers/auth/securid5.c:174
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:176
 #, c-format
 msgid "invalid Authentication Handle for SecurID"
 msgstr "virheellinen todentamiskäsittelijä kohteelle SecurID"
 
-#: plugins/sudoers/auth/securid5.c:127
+#: plugins/sudoers/auth/securid5.c:128
 #, c-format
 msgid "SecurID communication failed"
 msgstr "SecurID-viestintä epäonnistui"
 
-#: plugins/sudoers/auth/securid5.c:131 plugins/sudoers/auth/securid5.c:213
+#: plugins/sudoers/auth/securid5.c:132 plugins/sudoers/auth/securid5.c:215
 #, c-format
 msgid "unknown SecurID error"
 msgstr "tuntematon SecurID-virhe"
 
-#: plugins/sudoers/auth/securid5.c:164
+#: plugins/sudoers/auth/securid5.c:166
 #, c-format
 msgid "invalid passcode length for SecurID"
 msgstr "virheellinen salasanakoodipituus kohteelle SecurID"
 
-#: plugins/sudoers/auth/sia.c:106
+#: plugins/sudoers/auth/sia.c:109
 msgid "unable to initialize SIA session"
 msgstr "ei kyetä alustamaan SIA-istuntoa"
 
-#: plugins/sudoers/auth/sudo_auth.c:124
-msgid "There are no authentication methods compiled into sudo!  If you want to turn off authentication, use the --disable-authentication configure option."
-msgstr "Sudo-ohjelmaan ei ole käännetty todentamismenelmiä! Jos haluat kääntää pois todentamisen, käytä asetusvalitsinta --disable-authentication."
-
-#: plugins/sudoers/auth/sudo_auth.c:134
+#: plugins/sudoers/auth/sudo_auth.c:117
 msgid "Invalid authentication methods compiled into sudo!  You may mix standalone and non-standalone authentication."
 msgstr "Virheellisiä todennusmenetelmiä käännetty sudo-ohjelmaan! Yksittäisiä ja ei-yksittäisiä todennuksia on ehkä sekoitettu keskenään."
 
-#: plugins/sudoers/auth/sudo_auth.c:243
+#: plugins/sudoers/auth/sudo_auth.c:199
+msgid "There are no authentication methods compiled into sudo!  If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "Sudo-ohjelmaan ei ole käännetty todentamismenelmiä! Jos haluat kääntää pois todentamisen, käytä asetusvalitsinta --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:271
 #, c-format
 msgid "%d incorrect password attempt"
 msgid_plural "%d incorrect password attempts"
 msgstr[0] "%d väärä salasana yritetty"
 msgstr[1] "%d väärää salasanaa yritetty"
 
-#: plugins/sudoers/auth/sudo_auth.c:335
+#: plugins/sudoers/auth/sudo_auth.c:374
 msgid "Authentication methods:"
 msgstr "Todennusmenetelmät:"
 
+#~ msgid "File containing dummy exec functions: %s"
+#~ msgstr "Tiedosto, joka sisältää vale-exec-funktioita: %s"
+
 #~ msgid ""
 #~ "Available options in a sudoers ``Defaults'' line:\n"
 #~ "\n"
index af993f31286d389707e5f8c414316a73667f17cd..2f4ec149e5674e26bf34760219c0e28231ac3771 100644 (file)
Binary files a/plugins/sudoers/po/ja.mo and b/plugins/sudoers/po/ja.mo differ
index 40b7ef558c8e69e324d6e76796272773766e5e0f..5939bc8f7f0419b09e9b83caac986ccbbe3ee849 100644 (file)
@@ -7,7 +7,7 @@ msgstr ""
 "Project-Id-Version: sudoers 1.8.3rc1\n"
 "Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
 "POT-Creation-Date: 2011-09-16 16:52-0400\n"
-"PO-Revision-Date: 2011-10-20 05:47+0900\n"
+"PO-Revision-Date: 2011-11-23 09:39+0900\n"
 "Last-Translator: Yasuaki Taniguchi <yasuakit@gmail.com>\n"
 "Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
 "Language: ja\n"
@@ -777,7 +777,7 @@ msgstr "コマンドが許可されていません"
 #: plugins/sudoers/logging.c:263
 #, c-format
 msgid "%s is not in the sudoers file.  This incident will be reported.\n"
-msgstr "%s は sudoers ファイルではありません。この事象は記録・報告されます。\n"
+msgstr "%s は sudoers ファイル内にありません。この事象は記録・報告されます。\n"
 
 #: plugins/sudoers/logging.c:266
 #, c-format
index e2fa75839e72773e6f52de7eff2f02ea8b49df2e..4d558b47e71be710c7689ab3b675dfb7ca8930e6 100644 (file)
Binary files a/plugins/sudoers/po/pl.mo and b/plugins/sudoers/po/pl.mo differ
index 574b887ffa0c6555f9bf454c4c328c0785998220..21230fabc8ac9c401785360cebfc3cbf6103a136 100644 (file)
@@ -1,13 +1,13 @@
 # Polish translation for sudo/sudoers.
 # This file is put in the public domain.
-# Jakub Bogusz <qboosh@pld-linux.org>, 2011.
+# Jakub Bogusz <qboosh@pld-linux.org>, 2011-2012.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: sudoers 1.8.3rc1\n"
+"Project-Id-Version: sudoers 1.8.4rc1\n"
 "Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
-"POT-Creation-Date: 2011-09-16 16:52-0400\n"
-"PO-Revision-Date: 2011-09-17 14:02+0200\n"
+"POT-Creation-Date: 2012-02-06 15:48-0500\n"
+"PO-Revision-Date: 2012-02-08 18:07+0100\n"
 "Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n"
 "Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
 "Language: pl\n"
@@ -16,146 +16,146 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
 
-#: plugins/sudoers/alias.c:122
+#: plugins/sudoers/alias.c:125
 #, c-format
 msgid "Alias `%s' already defined"
 msgstr "Alias `%s' jest już zdefiniowany"
 
-#: plugins/sudoers/bsm_audit.c:58 plugins/sudoers/bsm_audit.c:61
-#: plugins/sudoers/bsm_audit.c:109 plugins/sudoers/bsm_audit.c:113
-#: plugins/sudoers/bsm_audit.c:163 plugins/sudoers/bsm_audit.c:167
+#: plugins/sudoers/bsm_audit.c:61 plugins/sudoers/bsm_audit.c:64
+#: plugins/sudoers/bsm_audit.c:113 plugins/sudoers/bsm_audit.c:117
+#: plugins/sudoers/bsm_audit.c:169 plugins/sudoers/bsm_audit.c:173
 msgid "getaudit: failed"
 msgstr "getaudit: niepowodzenie"
 
-#: plugins/sudoers/bsm_audit.c:87 plugins/sudoers/bsm_audit.c:148
+#: plugins/sudoers/bsm_audit.c:91 plugins/sudoers/bsm_audit.c:154
 msgid "Could not determine audit condition"
 msgstr "Nie udało się określić warunku audytowego"
 
-#: plugins/sudoers/bsm_audit.c:98
+#: plugins/sudoers/bsm_audit.c:102
 msgid "getauid failed"
 msgstr "getauid nie powiodło się"
 
-#: plugins/sudoers/bsm_audit.c:100 plugins/sudoers/bsm_audit.c:157
+#: plugins/sudoers/bsm_audit.c:104 plugins/sudoers/bsm_audit.c:163
 msgid "au_open: failed"
 msgstr "au_open: niepowodzenie"
 
-#: plugins/sudoers/bsm_audit.c:115 plugins/sudoers/bsm_audit.c:169
+#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:175
 msgid "au_to_subject: failed"
 msgstr "au_to_subject: niepowodzenie"
 
-#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:173
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:179
 msgid "au_to_exec_args: failed"
 msgstr "au_to_exec_args: niepowodzenie"
 
-#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:182
+#: plugins/sudoers/bsm_audit.c:127 plugins/sudoers/bsm_audit.c:188
 msgid "au_to_return32: failed"
 msgstr "au_to_return32: niepowodzenie"
 
-#: plugins/sudoers/bsm_audit.c:126 plugins/sudoers/bsm_audit.c:185
+#: plugins/sudoers/bsm_audit.c:130 plugins/sudoers/bsm_audit.c:191
 msgid "unable to commit audit record"
 msgstr "nie udało się zatwierdzić rekordu audytowego"
 
-#: plugins/sudoers/bsm_audit.c:155
+#: plugins/sudoers/bsm_audit.c:161
 msgid "getauid: failed"
 msgstr "getauid: niepowodzenie"
 
-#: plugins/sudoers/bsm_audit.c:178
+#: plugins/sudoers/bsm_audit.c:184
 msgid "au_to_text: failed"
 msgstr "au_to_text: niepowodzenie"
 
-#: plugins/sudoers/check.c:141
+#: plugins/sudoers/check.c:158
 #, c-format
 msgid "sorry, a password is required to run %s"
 msgstr "niestety do uruchomienia %s wymagane jest hasło"
 
-#: plugins/sudoers/check.c:225 plugins/sudoers/iolog.c:169
-#: plugins/sudoers/sudoers.c:971 plugins/sudoers/sudoreplay.c:325
-#: plugins/sudoers/sudoreplay.c:334 plugins/sudoers/sudoreplay.c:675
-#: plugins/sudoers/sudoreplay.c:767 plugins/sudoers/visudo.c:744
+#: plugins/sudoers/check.c:249 plugins/sudoers/iolog.c:172
+#: plugins/sudoers/sudoers.c:992 plugins/sudoers/sudoreplay.c:348
+#: plugins/sudoers/sudoreplay.c:357 plugins/sudoers/sudoreplay.c:703
+#: plugins/sudoers/sudoreplay.c:797 plugins/sudoers/visudo.c:790
 #, c-format
 msgid "unable to open %s"
 msgstr "nie udało się otworzyć %s"
 
-#: plugins/sudoers/check.c:229 plugins/sudoers/iolog.c:199
+#: plugins/sudoers/check.c:253 plugins/sudoers/iolog.c:202
 #, c-format
 msgid "unable to write to %s"
 msgstr "nie udało się zapisać do %s"
 
-#: plugins/sudoers/check.c:237 plugins/sudoers/check.c:475
-#: plugins/sudoers/check.c:525 plugins/sudoers/iolog.c:122
-#: plugins/sudoers/iolog.c:153
+#: plugins/sudoers/check.c:261 plugins/sudoers/check.c:506
+#: plugins/sudoers/check.c:556 plugins/sudoers/iolog.c:123
+#: plugins/sudoers/iolog.c:156
 #, c-format
 msgid "unable to mkdir %s"
 msgstr "nie udało się wykonać mkdir %s"
 
-#: plugins/sudoers/check.c:370
+#: plugins/sudoers/check.c:396
 #, c-format
 msgid "internal error, expand_prompt() overflow"
 msgstr "błąd wewnętrzny, przepełnienie expand_prompt()"
 
-#: plugins/sudoers/check.c:426
+#: plugins/sudoers/check.c:456
 #, c-format
 msgid "timestamp path too long: %s"
 msgstr "ścieżka znacznika czasu zbyt długa: %s"
 
-#: plugins/sudoers/check.c:454 plugins/sudoers/check.c:498
-#: plugins/sudoers/iolog.c:155
+#: plugins/sudoers/check.c:485 plugins/sudoers/check.c:529
+#: plugins/sudoers/iolog.c:158
 #, c-format
 msgid "%s exists but is not a directory (0%o)"
 msgstr "%s istnieje, ale nie jest katalogiem (0%o)"
 
-#: plugins/sudoers/check.c:457 plugins/sudoers/check.c:501
-#: plugins/sudoers/check.c:546
+#: plugins/sudoers/check.c:488 plugins/sudoers/check.c:532
+#: plugins/sudoers/check.c:577
 #, c-format
 msgid "%s owned by uid %u, should be uid %u"
 msgstr "właścicielem %s jest uid %u, powinien być uid %u"
 
-#: plugins/sudoers/check.c:462 plugins/sudoers/check.c:506
+#: plugins/sudoers/check.c:493 plugins/sudoers/check.c:537
 #, c-format
 msgid "%s writable by non-owner (0%o), should be mode 0700"
 msgstr "%s zapisywalny nie tylko dla właściciela (uprawnienia 0%o, powinny być 0700)"
 
-#: plugins/sudoers/check.c:470 plugins/sudoers/check.c:514
-#: plugins/sudoers/check.c:582 plugins/sudoers/sudoers.c:957
-#: plugins/sudoers/visudo.c:304 plugins/sudoers/visudo.c:544
+#: plugins/sudoers/check.c:501 plugins/sudoers/check.c:545
+#: plugins/sudoers/check.c:613 plugins/sudoers/sudoers.c:978
+#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:582
 #, c-format
 msgid "unable to stat %s"
 msgstr "nie udało się wykonać stat na %s"
 
-#: plugins/sudoers/check.c:540
+#: plugins/sudoers/check.c:571
 #, c-format
 msgid "%s exists but is not a regular file (0%o)"
 msgstr "%s istnieje, ale nie jest zwykłym plikiem (0%o)"
 
-#: plugins/sudoers/check.c:552
+#: plugins/sudoers/check.c:583
 #, c-format
 msgid "%s writable by non-owner (0%o), should be mode 0600"
 msgstr "%s zapisywalny nie tylko dla właściciela (uprawnienia 0%o, powinny być 0600)"
 
-#: plugins/sudoers/check.c:606
+#: plugins/sudoers/check.c:637
 #, c-format
 msgid "timestamp too far in the future: %20.20s"
 msgstr "znacznik czasu zbyt daleko w przyszłości: %20.20s"
 
-#: plugins/sudoers/check.c:652
+#: plugins/sudoers/check.c:684
 #, c-format
 msgid "unable to remove %s (%s), will reset to the epoch"
 msgstr "nie udało się usunąć %s (%s), zostanie zresetowany do epoch"
 
-#: plugins/sudoers/check.c:660
+#: plugins/sudoers/check.c:692
 #, c-format
 msgid "unable to reset %s to the epoch"
 msgstr "nie udało się zresetować %s do epoch"
 
-#: plugins/sudoers/check.c:714 plugins/sudoers/check.c:720
+#: plugins/sudoers/check.c:752 plugins/sudoers/check.c:758
+#: plugins/sudoers/sudoers.c:829 plugins/sudoers/sudoers.c:833
 #, c-format
 msgid "unknown uid: %u"
 msgstr "nieznany uid: %u"
 
-#: plugins/sudoers/check.c:717 plugins/sudoers/sudoers.c:748
-#: plugins/sudoers/sudoers.c:814 plugins/sudoers/sudoers.c:815
-#: plugins/sudoers/sudoers.c:1088 plugins/sudoers/testsudoers.c:202
-#: plugins/sudoers/testsudoers.c:337
+#: plugins/sudoers/check.c:755 plugins/sudoers/sudoers.c:770
+#: plugins/sudoers/sudoers.c:1108 plugins/sudoers/testsudoers.c:218
+#: plugins/sudoers/testsudoers.c:362
 #, c-format
 msgid "unknown user: %s"
 msgstr "nieznany użytkownik: %s"
@@ -402,298 +402,296 @@ msgid "When to require a password for 'verify' pseudocommand: %s"
 msgstr "Kiedy ma być wymagane hasło dla pseudopolecenia 'verify': %s"
 
 #: plugins/sudoers/def_data.c:243
-msgid "Preload the dummy exec functions contained in 'noexec_file'"
-msgstr "Wczytanie pustych funkcji exec zawartych w 'noexec_file'"
+msgid "Preload the dummy exec functions contained in \"_PATH_SUDO_NOEXEC"
+msgstr "Wczytanie pustych funkcji exec zawartych w \"_PATH_SUDO_NOEXEC"
 
 #: plugins/sudoers/def_data.c:247
-#, c-format
-msgid "File containing dummy exec functions: %s"
-msgstr "Plik zawierający puste funkcje exec: %s"
-
-#: plugins/sudoers/def_data.c:251
 msgid "If LDAP directory is up, do we ignore local sudoers file"
 msgstr "Jeśli istnieje katalog LDAP, czy ignorować lokalny plik sudoers"
 
-#: plugins/sudoers/def_data.c:255
+#: plugins/sudoers/def_data.c:251
 #, c-format
 msgid "File descriptors >= %d will be closed before executing a command"
 msgstr "Deskryptory plików >= %d będą zamykane przed uruchomieniem polecenia"
 
-#: plugins/sudoers/def_data.c:259
+#: plugins/sudoers/def_data.c:255
 msgid "If set, users may override the value of `closefrom' with the -C option"
 msgstr "Czy użytkownicy mogą zmieniać wartość `closefrom' opcją -C"
 
-#: plugins/sudoers/def_data.c:263
+#: plugins/sudoers/def_data.c:259
 msgid "Allow users to set arbitrary environment variables"
 msgstr "Zezwolenie użytkownikom na ustawianie dowolnych zmiennych środowiskowych"
 
-#: plugins/sudoers/def_data.c:267
+#: plugins/sudoers/def_data.c:263
 msgid "Reset the environment to a default set of variables"
 msgstr "Wyczyszczenie środowiska do domyślnego zbioru zmiennych"
 
-#: plugins/sudoers/def_data.c:271
+#: plugins/sudoers/def_data.c:267
 msgid "Environment variables to check for sanity:"
 msgstr "Zmienne środowiskowe do sprawdzania poprawności:"
 
-#: plugins/sudoers/def_data.c:275
+#: plugins/sudoers/def_data.c:271
 msgid "Environment variables to remove:"
 msgstr "Zmienne środowiskowe do usunięcia:"
 
-#: plugins/sudoers/def_data.c:279
+#: plugins/sudoers/def_data.c:275
 msgid "Environment variables to preserve:"
 msgstr "Zmienne środowiskowe do zachowania:"
 
-#: plugins/sudoers/def_data.c:283
+#: plugins/sudoers/def_data.c:279
 #, c-format
 msgid "SELinux role to use in the new security context: %s"
 msgstr "Rola SELinuksa do używania w nowym kontekście bezpieczeństwa: %s"
 
-#: plugins/sudoers/def_data.c:287
+#: plugins/sudoers/def_data.c:283
 #, c-format
 msgid "SELinux type to use in the new security context: %s"
 msgstr "Typ SELinuksa do używania w nowym kontekście bezpieczeństwa: %s"
 
-#: plugins/sudoers/def_data.c:291
+#: plugins/sudoers/def_data.c:287
 #, c-format
 msgid "Path to the sudo-specific environment file: %s"
 msgstr "Ścieżka do pliku środowiska specyficznego dla sudo: %s"
 
-#: plugins/sudoers/def_data.c:295
+#: plugins/sudoers/def_data.c:291
 #, c-format
 msgid "Locale to use while parsing sudoers: %s"
 msgstr "Lokalizacja, jak ma być używana przy analizie pliku sudoers: %s"
 
-#: plugins/sudoers/def_data.c:299
-msgid "Allow sudo to prompt for a password even if it would be visisble"
+#: plugins/sudoers/def_data.c:295
+msgid "Allow sudo to prompt for a password even if it would be visible"
 msgstr "Zezwolenie sudo na pytanie o hasło nawet gdyby miało być widoczne"
 
-#: plugins/sudoers/def_data.c:303
+#: plugins/sudoers/def_data.c:299
 msgid "Provide visual feedback at the password prompt when there is user input"
 msgstr "Uwidocznienie wprowadzania hasła przez użytkownika w miarę wpisywania"
 
-#: plugins/sudoers/def_data.c:307
+#: plugins/sudoers/def_data.c:303
 msgid "Use faster globbing that is less accurate but does not access the filesystem"
 msgstr "Użycie szybszych masek (glob) - mniej dokładnych, ale nie odwołujących się do systemu plików"
 
-#: plugins/sudoers/def_data.c:311
+#: plugins/sudoers/def_data.c:307
 msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
 msgstr "Wartość umask podana w sudoers ma zastąpić wartość użytkownika, nawet jeśli pozwala na więcej"
 
-#: plugins/sudoers/def_data.c:315
+#: plugins/sudoers/def_data.c:311
 msgid "Log user's input for the command being run"
 msgstr "Logowanie wejścia użytkownika dla uruchamianych poleceń"
 
-#: plugins/sudoers/def_data.c:319
+#: plugins/sudoers/def_data.c:315
 msgid "Log the output of the command being run"
 msgstr "Logowanie wyjścia z uruchamianych poleceń"
 
-#: plugins/sudoers/def_data.c:323
+#: plugins/sudoers/def_data.c:319
 msgid "Compress I/O logs using zlib"
 msgstr "Kompresja logów we/wy przy użyciu zliba"
 
-#: plugins/sudoers/def_data.c:327
+#: plugins/sudoers/def_data.c:323
 msgid "Always run commands in a pseudo-tty"
 msgstr "Uruchamianie poleceń zawsze na pseudoterminalu"
 
+#: plugins/sudoers/def_data.c:327
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Wtyczka do obsługi grup nieuniksowych: %s"
+
 #: plugins/sudoers/def_data.c:331
-msgid "Plugin for non-Unix group support"
-msgstr "Wtyczka do obsługi grup nieuniksowych"
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Katalog do zapisu logów wejścia/wyjścia: %s"
 
 #: plugins/sudoers/def_data.c:335
-msgid "Directory in which to store input/output logs"
-msgstr "Katalog do zapisu logów wejścia/wyjścia"
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Plik do zapisu logu wejścia/wyjścia: %s"
 
 #: plugins/sudoers/def_data.c:339
-msgid "File in which to store the input/output log"
-msgstr "Plik do zapisu logu wejścia/wyjścia"
-
-#: plugins/sudoers/def_data.c:343
 msgid "Add an entry to the utmp/utmpx file when allocating a pty"
 msgstr "Dodawanie wpisu do pliku utmp/utmpx przy przydzielaniu pty"
 
-#: plugins/sudoers/def_data.c:347
+#: plugins/sudoers/def_data.c:343
 msgid "Set the user in utmp to the runas user, not the invoking user"
 msgstr "Ustawianie użytkownika w utmp jako docelowego, nie wywołującego"
 
-#: plugins/sudoers/defaults.c:205
+#: plugins/sudoers/defaults.c:208
 #, c-format
 msgid "unknown defaults entry `%s'"
 msgstr "nieznany wpis domyślny `%s'"
 
-#: plugins/sudoers/defaults.c:213 plugins/sudoers/defaults.c:223
-#: plugins/sudoers/defaults.c:243 plugins/sudoers/defaults.c:256
-#: plugins/sudoers/defaults.c:269 plugins/sudoers/defaults.c:282
-#: plugins/sudoers/defaults.c:295 plugins/sudoers/defaults.c:315
-#: plugins/sudoers/defaults.c:325
+#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
+#: plugins/sudoers/defaults.c:246 plugins/sudoers/defaults.c:259
+#: plugins/sudoers/defaults.c:272 plugins/sudoers/defaults.c:285
+#: plugins/sudoers/defaults.c:298 plugins/sudoers/defaults.c:318
+#: plugins/sudoers/defaults.c:328
 #, c-format
 msgid "value `%s' is invalid for option `%s'"
 msgstr "błędna wartość `%s' dla opcji `%s'"
 
-#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
-#: plugins/sudoers/defaults.c:234 plugins/sudoers/defaults.c:251
-#: plugins/sudoers/defaults.c:264 plugins/sudoers/defaults.c:277
-#: plugins/sudoers/defaults.c:290 plugins/sudoers/defaults.c:310
-#: plugins/sudoers/defaults.c:321
+#: plugins/sudoers/defaults.c:219 plugins/sudoers/defaults.c:229
+#: plugins/sudoers/defaults.c:237 plugins/sudoers/defaults.c:254
+#: plugins/sudoers/defaults.c:267 plugins/sudoers/defaults.c:280
+#: plugins/sudoers/defaults.c:293 plugins/sudoers/defaults.c:313
+#: plugins/sudoers/defaults.c:324
 #, c-format
 msgid "no value specified for `%s'"
 msgstr "nie podano wartości dla `%s'"
 
-#: plugins/sudoers/defaults.c:239
+#: plugins/sudoers/defaults.c:242
 #, c-format
 msgid "values for `%s' must start with a '/'"
 msgstr "wartości `%s' muszą zaczynać się od '/'"
 
-#: plugins/sudoers/defaults.c:301
+#: plugins/sudoers/defaults.c:304
 #, c-format
 msgid "option `%s' does not take a value"
 msgstr "opcja `%s' nie przyjmuje wartości"
 
-#: plugins/sudoers/env.c:259
+#: plugins/sudoers/env.c:258
 #, c-format
 msgid "internal error, sudo_setenv() overflow"
 msgstr "błąd wewnętrzny, przepełnienie sudo_setenv()"
 
-#: plugins/sudoers/env.c:289
+#: plugins/sudoers/env.c:291
 #, c-format
 msgid "sudo_putenv: corrupted envp, length mismatch"
 msgstr "sudo_putenv: uszkodzone envp, niezgodność długości"
 
-#: plugins/sudoers/env.c:698
+#: plugins/sudoers/env.c:710
 #, c-format
 msgid "sorry, you are not allowed to set the following environment variables: %s"
 msgstr "niestety nie jest dozwolone ustawianie następujących zmiennych środowiskowych: %s"
 
-#: plugins/sudoers/find_path.c:68 plugins/sudoers/find_path.c:107
-#: plugins/sudoers/find_path.c:122 plugins/sudoers/iolog.c:124
-#: plugins/sudoers/sudoers.c:903 toke.l:663 toke.l:814
+#: plugins/sudoers/find_path.c:69 plugins/sudoers/find_path.c:108
+#: plugins/sudoers/find_path.c:123 plugins/sudoers/iolog.c:125
+#: plugins/sudoers/sudoers.c:923 toke.l:668 toke.l:823
 #, c-format
 msgid "%s: %s"
 msgstr "%s: %s"
 
-#: gram.y:103
+#: gram.y:110
 #, c-format
 msgid ">>> %s: %s near line %d <<<"
 msgstr ">>> %s: %s w okolicy linii %d <<<"
 
-#: plugins/sudoers/group_plugin.c:90
+#: plugins/sudoers/group_plugin.c:91
 #, c-format
 msgid "%s%s: %s"
 msgstr "%s%s: %s"
 
-#: plugins/sudoers/group_plugin.c:102
+#: plugins/sudoers/group_plugin.c:103
 #, c-format
 msgid "%s must be owned by uid %d"
 msgstr "właścicielem %s musi być uid %d"
 
-#: plugins/sudoers/group_plugin.c:106
+#: plugins/sudoers/group_plugin.c:107
 #, c-format
 msgid "%s must only be writable by owner"
 msgstr "prawo zapisu do %s może mieć tylko właściciel"
 
-#: plugins/sudoers/group_plugin.c:113
+#: plugins/sudoers/group_plugin.c:114
 #, c-format
 msgid "unable to dlopen %s: %s"
 msgstr "nie udało się wykonać dlopen %s: %s"
 
-#: plugins/sudoers/group_plugin.c:118
+#: plugins/sudoers/group_plugin.c:119
 #, c-format
 msgid "unable to find symbol \"group_plugin\" in %s"
 msgstr "nie udało się odnaleźć symbolu \"group_plugin\" w %s"
 
-#: plugins/sudoers/group_plugin.c:123
+#: plugins/sudoers/group_plugin.c:124
 #, c-format
 msgid "%s: incompatible group plugin major version %d, expected %d"
 msgstr "%s: niezgodna główna wersja wtyczki grup %d, oczekiwano %d"
 
-#: plugins/sudoers/interfaces.c:109
+#: plugins/sudoers/interfaces.c:112
 msgid "Local IP address and netmask pairs:\n"
 msgstr "Pary lokalnych adresów IP i masek:\n"
 
-#: plugins/sudoers/iolog.c:176 plugins/sudoers/sudoers.c:978
+#: plugins/sudoers/iolog.c:179 plugins/sudoers/sudoers.c:999
 #, c-format
 msgid "unable to read %s"
 msgstr "nie udało się odczytać %s"
 
-#: plugins/sudoers/iolog.c:179
+#: plugins/sudoers/iolog.c:182
 #, c-format
 msgid "invalid sequence number %s"
 msgstr "błędny numer sekwencyjny %s"
 
-#: plugins/sudoers/iolog.c:225 plugins/sudoers/iolog.c:228
-#: plugins/sudoers/iolog.c:478 plugins/sudoers/iolog.c:483
-#: plugins/sudoers/iolog.c:489 plugins/sudoers/iolog.c:497
-#: plugins/sudoers/iolog.c:505 plugins/sudoers/iolog.c:513
-#: plugins/sudoers/iolog.c:521
+#: plugins/sudoers/iolog.c:231 plugins/sudoers/iolog.c:234
+#: plugins/sudoers/iolog.c:499 plugins/sudoers/iolog.c:504
+#: plugins/sudoers/iolog.c:510 plugins/sudoers/iolog.c:518
+#: plugins/sudoers/iolog.c:526 plugins/sudoers/iolog.c:534
+#: plugins/sudoers/iolog.c:542
 #, c-format
 msgid "unable to create %s"
 msgstr "nie udało się utworzyć %s"
 
-#: plugins/sudoers/iolog_path.c:247 plugins/sudoers/sudoers.c:357
+#: plugins/sudoers/iolog_path.c:256 plugins/sudoers/sudoers.c:362
 #, c-format
 msgid "unable to set locale to \"%s\", using \"C\""
 msgstr "nie udało się ustawić lokalizacji na \"%s\", użyto \"C\""
 
-#: plugins/sudoers/ldap.c:368
+#: plugins/sudoers/ldap.c:374
 #, c-format
 msgid "sudo_ldap_conf_add_ports: port too large"
 msgstr "sudo_ldap_conf_add_ports: port zbyt duży"
 
-#: plugins/sudoers/ldap.c:391
+#: plugins/sudoers/ldap.c:397
 #, c-format
 msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
 msgstr "sudo_ldap_conf_add_ports: brak miejsca podczas rozszerzania hostbuf"
 
-#: plugins/sudoers/ldap.c:420
+#: plugins/sudoers/ldap.c:427
 #, c-format
 msgid "unsupported LDAP uri type: %s"
 msgstr "nieobsługiwany rodzaj URI LDAP: %s"
 
-#: plugins/sudoers/ldap.c:449
+#: plugins/sudoers/ldap.c:456
 #, c-format
 msgid "invalid uri: %s"
 msgstr "błędny URI: %s"
 
-#: plugins/sudoers/ldap.c:455
+#: plugins/sudoers/ldap.c:462
 #, c-format
 msgid "unable to mix ldap and ldaps URIs"
 msgstr "nie można mieszać URI ldap i ldaps"
 
-#: plugins/sudoers/ldap.c:459
+#: plugins/sudoers/ldap.c:466
 #, c-format
 msgid "unable to mix ldaps and starttls"
 msgstr "nie można mieszać ldaps i starttls"
 
-#: plugins/sudoers/ldap.c:478
+#: plugins/sudoers/ldap.c:485
 #, c-format
 msgid "sudo_ldap_parse_uri: out of space building hostbuf"
 msgstr "sudo_ldap_parse_uri: brak miejsca podczas konstruowania hostbuf"
 
-#: plugins/sudoers/ldap.c:541
+#: plugins/sudoers/ldap.c:550
 #, c-format
 msgid "unable to initialize SSL cert and key db: %s"
 msgstr "nie udało się zainicjować bazy certyfikatów i kluczy SSL: %s"
 
-#: plugins/sudoers/ldap.c:937
+#: plugins/sudoers/ldap.c:958
 #, c-format
 msgid "unable to get GMT time"
 msgstr "nie udało się pobrać czasu GMT"
 
-#: plugins/sudoers/ldap.c:943
+#: plugins/sudoers/ldap.c:964
 #, c-format
 msgid "unable to format timestamp"
 msgstr "nie udało się sformatować znacznika czasu"
 
-#: plugins/sudoers/ldap.c:951
+#: plugins/sudoers/ldap.c:972
 #, c-format
 msgid "unable to build time filter"
 msgstr "nie udało się stworzyć filtra czasu"
 
-#: plugins/sudoers/ldap.c:1052
+#: plugins/sudoers/ldap.c:1185
 #, c-format
 msgid "sudo_ldap_build_pass1 allocation mismatch"
 msgstr "niezgodność przydzielenia sudo_ldap_build_pass1"
 
-#: plugins/sudoers/ldap.c:1562
+#: plugins/sudoers/ldap.c:1705
 #, c-format
 msgid ""
 "\n"
@@ -702,7 +700,7 @@ msgstr ""
 "\n"
 "Rola LDAP: %s\n"
 
-#: plugins/sudoers/ldap.c:1564
+#: plugins/sudoers/ldap.c:1707
 #, c-format
 msgid ""
 "\n"
@@ -711,124 +709,129 @@ msgstr ""
 "\n"
 "Rola LDAP: NIEZNANA\n"
 
-#: plugins/sudoers/ldap.c:1611
+#: plugins/sudoers/ldap.c:1754
 #, c-format
 msgid "    Order: %s\n"
 msgstr "    Porządek: %s\n"
 
-#: plugins/sudoers/ldap.c:1619
+#: plugins/sudoers/ldap.c:1762
 #, c-format
 msgid "    Commands:\n"
 msgstr "    Polecenia:\n"
 
-#: plugins/sudoers/ldap.c:2006
+#: plugins/sudoers/ldap.c:2161
 #, c-format
 msgid "unable to initialize LDAP: %s"
 msgstr "nie udało się zainicjować LDAP: %s"
 
-#: plugins/sudoers/ldap.c:2037
+#: plugins/sudoers/ldap.c:2192
 #, c-format
 msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
 msgstr "wybrano start_tls, ale biblioteki LDAP nie obsługują ldap_start_tls_s() ani ldap_start_tls_s_np()"
 
-#: plugins/sudoers/ldap.c:2268
+#: plugins/sudoers/ldap.c:2428
 #, c-format
 msgid "invalid sudoOrder attribute: %s"
 msgstr "błędny atrybut sudoOrder: %s"
 
-#: plugins/sudoers/linux_audit.c:55
+#: plugins/sudoers/linux_audit.c:57
 #, c-format
 msgid "unable to open audit system"
 msgstr "nie udało się otworzyć systemu audytowego"
 
-#: plugins/sudoers/linux_audit.c:79
+#: plugins/sudoers/linux_audit.c:82
 #, c-format
 msgid "internal error, linux_audit_command() overflow"
 msgstr "błąd wewnętrzny, przepełnienie linux_audit_command()"
 
-#: plugins/sudoers/linux_audit.c:88
+#: plugins/sudoers/linux_audit.c:91
 #, c-format
 msgid "unable to send audit message"
 msgstr "nie udało się wysłać komunikatu audytowego"
 
-#: plugins/sudoers/logging.c:192
+#: plugins/sudoers/logging.c:198
 #, c-format
 msgid "unable to open log file: %s: %s"
 msgstr "nie udało się otworzyć pliku logu: %s: %s"
 
-#: plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:201
 #, c-format
 msgid "unable to lock log file: %s: %s"
 msgstr "nie udało się zablokować pliku logu: %s: %s"
 
-#: plugins/sudoers/logging.c:249
+#: plugins/sudoers/logging.c:256
 msgid "user NOT in sudoers"
 msgstr "użytkownik NIE występuje w sudoers"
 
-#: plugins/sudoers/logging.c:251
+#: plugins/sudoers/logging.c:258
 msgid "user NOT authorized on host"
 msgstr "użytkownik NIE jest autoryzowany na hoście"
 
-#: plugins/sudoers/logging.c:253
+#: plugins/sudoers/logging.c:260
 msgid "command not allowed"
 msgstr "polecenie niedozwolone"
 
-#: plugins/sudoers/logging.c:263
+#: plugins/sudoers/logging.c:270
 #, c-format
 msgid "%s is not in the sudoers file.  This incident will be reported.\n"
 msgstr "%s nie występuje w pliku sudoers. Ten incydent zostanie zgłoszony.\n"
 
-#: plugins/sudoers/logging.c:266
+#: plugins/sudoers/logging.c:273
 #, c-format
 msgid "%s is not allowed to run sudo on %s.  This incident will be reported.\n"
 msgstr "%s nie ma uprawnień do uruchamiania sudo na %s. Ten incydent zostanie zgłoszony.\n"
 
-#: plugins/sudoers/logging.c:270
+#: plugins/sudoers/logging.c:277
 #, c-format
 msgid "Sorry, user %s may not run sudo on %s.\n"
 msgstr "Niestety użytkownik %s nie może uruchamiać sudo na %s.\n"
 
-#: plugins/sudoers/logging.c:273
+#: plugins/sudoers/logging.c:280
 #, c-format
 msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
 msgstr "Niestety użytkownik %s nie ma uprawnień do uruchamiania '%s%s%s' jako %s%s%s na %s.\n"
 
-#: plugins/sudoers/logging.c:408
+#: plugins/sudoers/logging.c:420
 #, c-format
 msgid "unable to fork"
 msgstr "nie udało się wykonać fork"
 
-#: plugins/sudoers/logging.c:415 plugins/sudoers/logging.c:472
+#: plugins/sudoers/logging.c:427 plugins/sudoers/logging.c:489
 #, c-format
 msgid "unable to fork: %m"
 msgstr "nie udało się wykonać fork: %m"
 
-#: plugins/sudoers/logging.c:465
+#: plugins/sudoers/logging.c:479
 #, c-format
 msgid "unable to open pipe: %m"
 msgstr "nie udało się otworzyć potoku: %m"
 
-#: plugins/sudoers/logging.c:484
+#: plugins/sudoers/logging.c:504
 #, c-format
 msgid "unable to dup stdin: %m"
 msgstr "nie udało się wykonać dup na stdin: %m"
 
-#: plugins/sudoers/logging.c:518
+#: plugins/sudoers/logging.c:540
 #, c-format
 msgid "unable to execute %s: %m"
 msgstr "nie udało się wywołać %s: %m"
 
-#: plugins/sudoers/logging.c:728
+#: plugins/sudoers/logging.c:755
 #, c-format
 msgid "internal error: insufficient space for log line"
 msgstr "błąd wewnętrzny: za mało miejsca na linię logu"
 
-#: plugins/sudoers/parse.c:115
+#: plugins/sudoers/parse.c:123
 #, c-format
 msgid "parse error in %s near line %d"
 msgstr "błąd składni w %s w okolicy linii %d"
 
-#: plugins/sudoers/parse.c:371
+#: plugins/sudoers/parse.c:126
+#, c-format
+msgid "parse error in %s"
+msgstr "błąd składni w %s"
+
+#: plugins/sudoers/parse.c:389
 #, c-format
 msgid ""
 "\n"
@@ -837,17 +840,17 @@ msgstr ""
 "\n"
 "Wpis sudoers:\n"
 
-#: plugins/sudoers/parse.c:373
+#: plugins/sudoers/parse.c:391
 #, c-format
 msgid "    RunAsUsers: "
 msgstr "    Jako użytkownicy: "
 
-#: plugins/sudoers/parse.c:388
+#: plugins/sudoers/parse.c:406
 #, c-format
 msgid "    RunAsGroups: "
 msgstr "    Jako grupy: "
 
-#: plugins/sudoers/parse.c:397
+#: plugins/sudoers/parse.c:415
 #, c-format
 msgid ""
 "    Commands:\n"
@@ -860,97 +863,97 @@ msgstr ""
 msgid ": "
 msgstr ": "
 
-#: plugins/sudoers/pwutil.c:251
+#: plugins/sudoers/pwutil.c:260
 #, c-format
 msgid "unable to cache uid %u (%s), already exists"
 msgstr "nie udało się zapamiętać uid-a %u (%s), już istnieje"
 
-#: plugins/sudoers/pwutil.c:259
+#: plugins/sudoers/pwutil.c:268
 #, c-format
 msgid "unable to cache uid %u, already exists"
 msgstr "nie udało się zapamiętać uid-a %u, już istnieje"
 
-#: plugins/sudoers/pwutil.c:295 plugins/sudoers/pwutil.c:304
+#: plugins/sudoers/pwutil.c:305 plugins/sudoers/pwutil.c:314
 #, c-format
 msgid "unable to cache user %s, already exists"
 msgstr "nie udało się zapamiętać użytkownika %s, już istnieje"
 
-#: plugins/sudoers/pwutil.c:607
+#: plugins/sudoers/pwutil.c:655
 #, c-format
 msgid "unable to cache gid %u (%s), already exists"
 msgstr "nie udało się zapamiętać gid-a %u (%s), już istnieje"
 
-#: plugins/sudoers/pwutil.c:615
+#: plugins/sudoers/pwutil.c:663
 #, c-format
 msgid "unable to cache gid %u, already exists"
 msgstr "nie udało się zapamiętać gid-a %u, już istnieje"
 
-#: plugins/sudoers/pwutil.c:644 plugins/sudoers/pwutil.c:653
+#: plugins/sudoers/pwutil.c:693 plugins/sudoers/pwutil.c:702
 #, c-format
 msgid "unable to cache group %s, already exists"
 msgstr "nie udało się zapamiętać grupy %s, już istnieje"
 
-#: plugins/sudoers/set_perms.c:109 plugins/sudoers/set_perms.c:358
-#: plugins/sudoers/set_perms.c:590 plugins/sudoers/set_perms.c:824
+#: plugins/sudoers/set_perms.c:114 plugins/sudoers/set_perms.c:365
+#: plugins/sudoers/set_perms.c:601 plugins/sudoers/set_perms.c:837
 msgid "perm stack overflow"
 msgstr "przepełnienie stosu uprawnień"
 
-#: plugins/sudoers/set_perms.c:117 plugins/sudoers/set_perms.c:366
-#: plugins/sudoers/set_perms.c:598 plugins/sudoers/set_perms.c:832
+#: plugins/sudoers/set_perms.c:122 plugins/sudoers/set_perms.c:373
+#: plugins/sudoers/set_perms.c:609 plugins/sudoers/set_perms.c:845
 msgid "perm stack underflow"
 msgstr "niedopełnienie stosu uprawnień"
 
-#: plugins/sudoers/set_perms.c:223 plugins/sudoers/set_perms.c:458
-#: plugins/sudoers/set_perms.c:695
+#: plugins/sudoers/set_perms.c:228 plugins/sudoers/set_perms.c:466
+#: plugins/sudoers/set_perms.c:706
 msgid "unable to change to runas gid"
 msgstr "nie udało się zmienić na docelowy gid"
 
-#: plugins/sudoers/set_perms.c:231 plugins/sudoers/set_perms.c:465
-#: plugins/sudoers/set_perms.c:702
+#: plugins/sudoers/set_perms.c:236 plugins/sudoers/set_perms.c:473
+#: plugins/sudoers/set_perms.c:713
 msgid "unable to change to runas uid"
 msgstr "nie udało się zmienić na docelowy uid"
 
-#: plugins/sudoers/set_perms.c:245 plugins/sudoers/set_perms.c:478
-#: plugins/sudoers/set_perms.c:715
+#: plugins/sudoers/set_perms.c:250 plugins/sudoers/set_perms.c:486
+#: plugins/sudoers/set_perms.c:726
 #, c-format
 msgid "unable to change to sudoers gid"
 msgstr "nie udało się zmienić na gid sudoers"
 
-#: plugins/sudoers/set_perms.c:286 plugins/sudoers/set_perms.c:516
-#: plugins/sudoers/set_perms.c:753 plugins/sudoers/set_perms.c:893
+#: plugins/sudoers/set_perms.c:291 plugins/sudoers/set_perms.c:524
+#: plugins/sudoers/set_perms.c:764 plugins/sudoers/set_perms.c:906
 msgid "too many processes"
 msgstr "zbyt dużo procesów"
 
-#: plugins/sudoers/set_perms.c:955
+#: plugins/sudoers/set_perms.c:970
 msgid "unable to set runas group vector"
 msgstr "nie udało się ustawić wektora grup docelowych"
 
-#: plugins/sudoers/sudo_nss.c:238
+#: plugins/sudoers/sudo_nss.c:243
 #, c-format
 msgid "Matching Defaults entries for %s on this host:\n"
 msgstr "Pasujące wpisy Defaults dla %s na tym hoście:\n"
 
-#: plugins/sudoers/sudo_nss.c:251
+#: plugins/sudoers/sudo_nss.c:256
 #, c-format
 msgid "Runas and Command-specific defaults for %s:\n"
 msgstr "Wartości specyficzne dla Runas i Command dla %s:\n"
 
-#: plugins/sudoers/sudo_nss.c:264
+#: plugins/sudoers/sudo_nss.c:269
 #, c-format
 msgid "User %s may run the following commands on this host:\n"
 msgstr "Użytkownik %s może uruchamiać na tym hoście następujące polecenia:\n"
 
-#: plugins/sudoers/sudo_nss.c:274
+#: plugins/sudoers/sudo_nss.c:279
 #, c-format
 msgid "User %s is not allowed to run sudo on %s.\n"
 msgstr "Użytkownik %s nie ma uprawnień do uruchamiania sudo na %s.\n"
 
-#: plugins/sudoers/sudoers.c:199 plugins/sudoers/sudoers.c:234
-#: plugins/sudoers/sudoers.c:911
+#: plugins/sudoers/sudoers.c:201 plugins/sudoers/sudoers.c:232
+#: plugins/sudoers/sudoers.c:931
 msgid "problem with defaults entries"
 msgstr "problem z wpisami domyślnymi"
 
-#: plugins/sudoers/sudoers.c:203
+#: plugins/sudoers/sudoers.c:205
 #, c-format
 msgid "no valid sudoers sources found, quitting"
 msgstr "nie znaleziono poprawnych źródeł sudoers, zakończenie"
@@ -960,42 +963,42 @@ msgstr "nie znaleziono poprawnych źródeł sudoers, zakończenie"
 msgid "unable to execute %s: %s"
 msgstr "nie udało się wywołać %s: %s"
 
-#: plugins/sudoers/sudoers.c:306
+#: plugins/sudoers/sudoers.c:311
 #, c-format
 msgid "sudoers specifies that root is not allowed to sudo"
 msgstr "wg sudoers root nie ma prawa używać sudo"
 
-#: plugins/sudoers/sudoers.c:313
+#: plugins/sudoers/sudoers.c:318
 #, c-format
 msgid "you are not permitted to use the -C option"
 msgstr "brak uprawnień do używania opcji -C"
 
-#: plugins/sudoers/sudoers.c:403
+#: plugins/sudoers/sudoers.c:408
 #, c-format
 msgid "timestamp owner (%s): No such user"
 msgstr "właściciel znacznika czasu (%s): nie ma takiego użytkownika"
 
-#: plugins/sudoers/sudoers.c:419
+#: plugins/sudoers/sudoers.c:424
 msgid "no tty"
 msgstr "brak tty"
 
-#: plugins/sudoers/sudoers.c:420
+#: plugins/sudoers/sudoers.c:425
 #, c-format
 msgid "sorry, you must have a tty to run sudo"
 msgstr "niestety do uruchomienia sudo konieczny jest tty"
 
-#: plugins/sudoers/sudoers.c:463
+#: plugins/sudoers/sudoers.c:464
 msgid "No user or host"
 msgstr "Brak użytkownika lub hosta"
 
-#: plugins/sudoers/sudoers.c:477 plugins/sudoers/sudoers.c:498
-#: plugins/sudoers/sudoers.c:499 plugins/sudoers/sudoers.c:1465
-#: plugins/sudoers/sudoers.c:1466
+#: plugins/sudoers/sudoers.c:478 plugins/sudoers/sudoers.c:499
+#: plugins/sudoers/sudoers.c:500 plugins/sudoers/sudoers.c:1509
+#: plugins/sudoers/sudoers.c:1510
 #, c-format
 msgid "%s: command not found"
 msgstr "%s: nie znaleziono polecenia"
 
-#: plugins/sudoers/sudoers.c:479 plugins/sudoers/sudoers.c:495
+#: plugins/sudoers/sudoers.c:480 plugins/sudoers/sudoers.c:496
 #, c-format
 msgid ""
 "ignoring `%s' found in '.'\n"
@@ -1004,95 +1007,100 @@ msgstr ""
 "zignorowano plik `%s' znaleziony w '.'\n"
 "Proszę użyć `sudo ./%s', jeśli to `%s' ma być uruchomiony."
 
-#: plugins/sudoers/sudoers.c:484
+#: plugins/sudoers/sudoers.c:485
 msgid "validation failure"
 msgstr "błąd kontroli poprawności"
 
-#: plugins/sudoers/sudoers.c:494
+#: plugins/sudoers/sudoers.c:495
 msgid "command in current directory"
 msgstr "polecenie w bieżącym katalogu"
 
-#: plugins/sudoers/sudoers.c:506
+#: plugins/sudoers/sudoers.c:507
 #, c-format
 msgid "sorry, you are not allowed to preserve the environment"
 msgstr "niestety brak uprawnień do zachowania środowiska"
 
-#: plugins/sudoers/sudoers.c:894
+#: plugins/sudoers/sudoers.c:657 plugins/sudoers/sudoers.c:664
+#, c-format
+msgid "internal error, runas_groups overflow"
+msgstr "błąd wewnętrzny, przepełnienie runas_groups"
+
+#: plugins/sudoers/sudoers.c:914
 #, c-format
 msgid "internal error, set_cmnd() overflow"
 msgstr "błąd wewnętrzny, przepełnienie set_cmnd()"
 
-#: plugins/sudoers/sudoers.c:936
+#: plugins/sudoers/sudoers.c:957
 #, c-format
 msgid "fixed mode on %s"
 msgstr "poprawiono uprawnienia %s"
 
-#: plugins/sudoers/sudoers.c:940
+#: plugins/sudoers/sudoers.c:961
 #, c-format
 msgid "set group on %s"
 msgstr "ustawiono grupę %s"
 
-#: plugins/sudoers/sudoers.c:943
+#: plugins/sudoers/sudoers.c:964
 #, c-format
 msgid "unable to set group on %s"
 msgstr "nie udało się ustawić grupy %s"
 
-#: plugins/sudoers/sudoers.c:946
+#: plugins/sudoers/sudoers.c:967
 #, c-format
 msgid "unable to fix mode on %s"
 msgstr "nie udało się poprawić uprawnień %s"
 
-#: plugins/sudoers/sudoers.c:959
+#: plugins/sudoers/sudoers.c:980
 #, c-format
 msgid "%s is not a regular file"
 msgstr "%s nie jest zwykłym plikiem"
 
-#: plugins/sudoers/sudoers.c:961
+#: plugins/sudoers/sudoers.c:982
 #, c-format
 msgid "%s is mode 0%o, should be 0%o"
 msgstr "%s ma uprawnienia 0%o, powinny być 0%o"
 
-#: plugins/sudoers/sudoers.c:965
+#: plugins/sudoers/sudoers.c:986
 #, c-format
 msgid "%s is owned by uid %u, should be %u"
 msgstr "właścicielem %s jest uid %u, powinien być %u"
 
-#: plugins/sudoers/sudoers.c:968
+#: plugins/sudoers/sudoers.c:989
 #, c-format
 msgid "%s is owned by gid %u, should be %u"
 msgstr "właścicielem %s jest gid %u, powinien być %u"
 
-#: plugins/sudoers/sudoers.c:1012
+#: plugins/sudoers/sudoers.c:1038
 #, c-format
 msgid "only root can use `-c %s'"
 msgstr "tylko root może używać `-c %s'"
 
-#: plugins/sudoers/sudoers.c:1022
+#: plugins/sudoers/sudoers.c:1049
 #, c-format
 msgid "unknown login class: %s"
 msgstr "nieznana klasa logowania: %s"
 
-#: plugins/sudoers/sudoers.c:1056
+#: plugins/sudoers/sudoers.c:1077
 #, c-format
 msgid "unable to resolve host %s"
 msgstr "nie udało się rozwiązać nazwy hosta %s"
 
-#: plugins/sudoers/sudoers.c:1106 plugins/sudoers/testsudoers.c:351
+#: plugins/sudoers/sudoers.c:1129 plugins/sudoers/testsudoers.c:380
 #, c-format
 msgid "unknown group: %s"
 msgstr "nieznana grupa: %s"
 
-#: plugins/sudoers/sudoers.c:1150
+#: plugins/sudoers/sudoers.c:1178
 #, c-format
 msgid "Sudoers policy plugin version %s\n"
 msgstr "Wersja wtyczki polityki sudoers %s\n"
 
-#: plugins/sudoers/sudoers.c:1152
+#: plugins/sudoers/sudoers.c:1180
 #, c-format
 msgid "Sudoers file grammar version %d\n"
 msgstr "Wersja gramatyki pliku sudoers %d\n"
 
-#: plugins/sudoers/sudoers.c:1156
+#: plugins/sudoers/sudoers.c:1184
 #, c-format
 msgid ""
 "\n"
@@ -1101,147 +1109,147 @@ msgstr ""
 "\n"
 "Ścieżka do sudoers: %s\n"
 
-#: plugins/sudoers/sudoers.c:1159
+#: plugins/sudoers/sudoers.c:1187
 #, c-format
 msgid "nsswitch path: %s\n"
 msgstr "ścieżka do nsswitch: %s\n"
 
-#: plugins/sudoers/sudoers.c:1161
+#: plugins/sudoers/sudoers.c:1189
 #, c-format
 msgid "ldap.conf path: %s\n"
 msgstr "ścieżka do ldap.conf: %s\n"
 
-#: plugins/sudoers/sudoers.c:1162
+#: plugins/sudoers/sudoers.c:1190
 #, c-format
 msgid "ldap.secret path: %s\n"
 msgstr "ścieżka do ldap.secret: %s\n"
 
-#: plugins/sudoers/sudoreplay.c:265
+#: plugins/sudoers/sudoreplay.c:286
 #, c-format
 msgid "invalid filter option: %s"
 msgstr "błędna opcja filtra: %s"
 
-#: plugins/sudoers/sudoreplay.c:278
+#: plugins/sudoers/sudoreplay.c:299
 #, c-format
 msgid "invalid max wait: %s"
 msgstr "błędny maksymalny czas oczekiwania: %s"
 
-#: plugins/sudoers/sudoreplay.c:284
+#: plugins/sudoers/sudoreplay.c:305
 #, c-format
 msgid "invalid speed factor: %s"
 msgstr "błędny współczynnik szybkości: %s"
 
-#: plugins/sudoers/sudoreplay.c:287 plugins/sudoers/visudo.c:174
+#: plugins/sudoers/sudoreplay.c:308 plugins/sudoers/visudo.c:187
 #, c-format
 msgid "%s version %s\n"
 msgstr "%s wersja %s\n"
 
-#: plugins/sudoers/sudoreplay.c:310
+#: plugins/sudoers/sudoreplay.c:333
 #, c-format
 msgid "%s/%.2s/%.2s/%.2s/timing: %s"
 msgstr "%s/%.2s/%.2s/%.2s/czas: %s"
 
-#: plugins/sudoers/sudoreplay.c:316
+#: plugins/sudoers/sudoreplay.c:339
 #, c-format
 msgid "%s/%s/timing: %s"
 msgstr "%s/%s/czas: %s"
 
-#: plugins/sudoers/sudoreplay.c:341
+#: plugins/sudoers/sudoreplay.c:364
 #, c-format
 msgid "invalid log file %s"
 msgstr "błędny plik logu %s"
 
-#: plugins/sudoers/sudoreplay.c:343
+#: plugins/sudoers/sudoreplay.c:366
 #, c-format
 msgid "Replaying sudo session: %s"
 msgstr "Odtwarzanie sesji sudo: %s"
 
-#: plugins/sudoers/sudoreplay.c:369
+#: plugins/sudoers/sudoreplay.c:392
 #, c-format
 msgid "unable to set tty to raw mode"
 msgstr "nie udało się przestawić tty w tryb surowy"
 
-#: plugins/sudoers/sudoreplay.c:383
+#: plugins/sudoers/sudoreplay.c:406
 #, c-format
 msgid "invalid timing file line: %s"
 msgstr "błędna linia pliku czasu: %s"
 
-#: plugins/sudoers/sudoreplay.c:425
+#: plugins/sudoers/sudoreplay.c:448
 #, c-format
 msgid "writing to standard output"
 msgstr "zapis na standardowe wyjście"
 
-#: plugins/sudoers/sudoreplay.c:455
+#: plugins/sudoers/sudoreplay.c:480
 #, c-format
 msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
 msgstr "nanospeep: tv_sec %ld, tv_nsec %ld"
 
-#: plugins/sudoers/sudoreplay.c:503 plugins/sudoers/sudoreplay.c:528
+#: plugins/sudoers/sudoreplay.c:529 plugins/sudoers/sudoreplay.c:554
 #, c-format
 msgid "ambiguous expression \"%s\""
 msgstr "niejednoznaczne wyrażenie \"%s\""
 
-#: plugins/sudoers/sudoreplay.c:545
+#: plugins/sudoers/sudoreplay.c:571
 #, c-format
 msgid "too many parenthesized expressions, max %d"
 msgstr "zbyt dużo zagnieżdżonych wyrażeń w nawiasach, maksimum to %d"
 
-#: plugins/sudoers/sudoreplay.c:556
+#: plugins/sudoers/sudoreplay.c:582
 #, c-format
 msgid "unmatched ')' in expression"
 msgstr "niesparowany ')' w wyrażeniu"
 
-#: plugins/sudoers/sudoreplay.c:562
+#: plugins/sudoers/sudoreplay.c:588
 #, c-format
 msgid "unknown search term \"%s\""
 msgstr "nieznany warunek wyszukiwania \"%s\""
 
-#: plugins/sudoers/sudoreplay.c:576
+#: plugins/sudoers/sudoreplay.c:602
 #, c-format
 msgid "%s requires an argument"
 msgstr "%s wymaga argumentu"
 
-#: plugins/sudoers/sudoreplay.c:580
+#: plugins/sudoers/sudoreplay.c:606
 #, c-format
 msgid "invalid regular expression: %s"
 msgstr "błędne wyrażenie regularne: %s"
 
-#: plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:612
 #, c-format
 msgid "could not parse date \"%s\""
 msgstr "nie udało się przeanalizować daty \"%s\""
 
-#: plugins/sudoers/sudoreplay.c:599
+#: plugins/sudoers/sudoreplay.c:625
 #, c-format
 msgid "unmatched '(' in expression"
 msgstr "niesparowany '(' w wyrażeniu"
 
-#: plugins/sudoers/sudoreplay.c:601
+#: plugins/sudoers/sudoreplay.c:627
 #, c-format
 msgid "illegal trailing \"or\""
 msgstr "niedozwolone kończące \"or\""
 
-#: plugins/sudoers/sudoreplay.c:603
+#: plugins/sudoers/sudoreplay.c:629
 #, c-format
 msgid "illegal trailing \"!\""
 msgstr "niedozwolony kończący \"!\""
 
-#: plugins/sudoers/sudoreplay.c:819
+#: plugins/sudoers/sudoreplay.c:851
 #, c-format
 msgid "invalid regex: %s"
 msgstr "błędne wyrażenie regularne: %s"
 
-#: plugins/sudoers/sudoreplay.c:941
+#: plugins/sudoers/sudoreplay.c:976
 #, c-format
 msgid "usage: %s [-h] [-d directory] [-m max_wait] [-s speed_factor] ID\n"
 msgstr "Składnia: %s [-h] [-d katalog] [-m maks_oczek] [-s wsp_szybkości] ID\n"
 
-#: plugins/sudoers/sudoreplay.c:944
+#: plugins/sudoers/sudoreplay.c:979
 #, c-format
 msgid "usage: %s [-h] [-d directory] -l [search expression]\n"
 msgstr "Składnia: %s [-h] [-d katalog] -k [wyrażenie wyszukiwania]\n"
 
-#: plugins/sudoers/sudoreplay.c:953
+#: plugins/sudoers/sudoreplay.c:988
 #, c-format
 msgid ""
 "%s - replay sudo session logs\n"
@@ -1250,7 +1258,7 @@ msgstr ""
 "%s - odtwarzanie logów sesji sudo\n"
 "\n"
 
-#: plugins/sudoers/sudoreplay.c:955
+#: plugins/sudoers/sudoreplay.c:990
 msgid ""
 "\n"
 "Options:\n"
@@ -1272,16 +1280,16 @@ msgstr ""
 "  -s wsp_szybkości przyspieszenie lub spowolnienie wyjścia\n"
 "  -V               wyświetlenie informacji o wersji i zakończenie"
 
-#: plugins/sudoers/testsudoers.c:230
+#: plugins/sudoers/testsudoers.c:246
 #, c-format
 msgid "internal error, init_vars() overflow"
 msgstr "błąd wewnętrzny, przepełnienie init_vars()"
 
-#: plugins/sudoers/testsudoers.c:309
+#: plugins/sudoers/testsudoers.c:331
 msgid "\thost  unmatched"
 msgstr "\thost nie znaleziony"
 
-#: plugins/sudoers/testsudoers.c:312
+#: plugins/sudoers/testsudoers.c:334
 msgid ""
 "\n"
 "Command allowed"
@@ -1289,7 +1297,7 @@ msgstr ""
 "\n"
 "Polecenie dozwolone"
 
-#: plugins/sudoers/testsudoers.c:313
+#: plugins/sudoers/testsudoers.c:335
 msgid ""
 "\n"
 "Command denied"
@@ -1297,7 +1305,7 @@ msgstr ""
 "\n"
 "Polecenie niedozwolone"
 
-#: plugins/sudoers/testsudoers.c:313
+#: plugins/sudoers/testsudoers.c:335
 msgid ""
 "\n"
 "Command unmatched"
@@ -1305,104 +1313,104 @@ msgstr ""
 "\n"
 "Polecenie nie znalezione"
 
-#: toke.l:667 toke.l:793 toke.l:818 toke.l:904 plugins/sudoers/toke_util.c:111
-#: plugins/sudoers/toke_util.c:163 plugins/sudoers/toke_util.c:202
+#: toke.l:672 toke.l:802 toke.l:827 toke.l:923 plugins/sudoers/toke_util.c:113
+#: plugins/sudoers/toke_util.c:167 plugins/sudoers/toke_util.c:207
 msgid "unable to allocate memory"
 msgstr "nie udało się przydzielić pamięci"
 
-#: toke.l:786
+#: toke.l:795
 msgid "too many levels of includes"
 msgstr "za dużo poziomów include"
 
-#: plugins/sudoers/toke_util.c:213
+#: plugins/sudoers/toke_util.c:218
 msgid "fill_args: buffer overflow"
 msgstr "fill_args: przepełnienie bufora"
 
-#: plugins/sudoers/visudo.c:175
+#: plugins/sudoers/visudo.c:188
 #, c-format
 msgid "%s grammar version %d\n"
 msgstr "%s, wersja gramatyki %d\n"
 
-#: plugins/sudoers/visudo.c:208 plugins/sudoers/auth/rfc1938.c:103
+#: plugins/sudoers/visudo.c:221 plugins/sudoers/auth/rfc1938.c:104
 #, c-format
 msgid "you do not exist in the %s database"
 msgstr "nie istniejesz w bazie danych %s"
 
-#: plugins/sudoers/visudo.c:238 plugins/sudoers/visudo.c:518
+#: plugins/sudoers/visudo.c:253 plugins/sudoers/visudo.c:539
 #, c-format
 msgid "press return to edit %s: "
 msgstr "wciśnięcie return przejdzie do edycji %s: "
 
-#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:326
+#: plugins/sudoers/visudo.c:336 plugins/sudoers/visudo.c:342
 #, c-format
 msgid "write error"
 msgstr "błąd zapisu"
 
-#: plugins/sudoers/visudo.c:408
+#: plugins/sudoers/visudo.c:424
 #, c-format
 msgid "unable to stat temporary file (%s), %s unchanged"
 msgstr "nie udało się wykonać stat na pliku tymczasowym (%s), %s nie zmieniony"
 
-#: plugins/sudoers/visudo.c:413
+#: plugins/sudoers/visudo.c:429
 #, c-format
 msgid "zero length temporary file (%s), %s unchanged"
 msgstr "plik tymczasowy (%s) zerowej długości, %s nie zmieniony"
 
-#: plugins/sudoers/visudo.c:419
+#: plugins/sudoers/visudo.c:435
 #, c-format
 msgid "editor (%s) failed, %s unchanged"
 msgstr "błąd edytora (%s), %s nie zmieniony"
 
-#: plugins/sudoers/visudo.c:442
+#: plugins/sudoers/visudo.c:458
 #, c-format
 msgid "%s unchanged"
 msgstr "%s nie zmieniony"
 
-#: plugins/sudoers/visudo.c:466
+#: plugins/sudoers/visudo.c:484
 #, c-format
 msgid "unable to re-open temporary file (%s), %s unchanged."
 msgstr "nie udało się ponownie otworzyć pliku tymczasowego (%s), %s nie zmieniony."
 
-#: plugins/sudoers/visudo.c:476
+#: plugins/sudoers/visudo.c:494
 #, c-format
 msgid "unabled to parse temporary file (%s), unknown error"
 msgstr "nie udało się przeanalizować pliku tymczasowego (%s), nieznany błąd"
 
-#: plugins/sudoers/visudo.c:511
+#: plugins/sudoers/visudo.c:532
 #, c-format
 msgid "internal error, unable to find %s in list!"
 msgstr "błąd wewnętrzny, nie znaleziono %s na liście!"
 
-#: plugins/sudoers/visudo.c:546 plugins/sudoers/visudo.c:555
+#: plugins/sudoers/visudo.c:584 plugins/sudoers/visudo.c:593
 #, c-format
 msgid "unable to set (uid, gid) of %s to (%u, %u)"
 msgstr "nie udało się ustawić (uid, gid) %s na (%u, %u)"
 
-#: plugins/sudoers/visudo.c:550 plugins/sudoers/visudo.c:560
+#: plugins/sudoers/visudo.c:588 plugins/sudoers/visudo.c:598
 #, c-format
 msgid "unable to change mode of %s to 0%o"
 msgstr "nie udało się zmienić uprawnień %s na 0%o"
 
-#: plugins/sudoers/visudo.c:577
+#: plugins/sudoers/visudo.c:615
 #, c-format
 msgid "%s and %s not on the same file system, using mv to rename"
 msgstr "%s i %s nie są na tym samym systemie plików, użycie mv do zmiany nazwy"
 
-#: plugins/sudoers/visudo.c:591
+#: plugins/sudoers/visudo.c:629
 #, c-format
 msgid "command failed: '%s %s %s', %s unchanged"
 msgstr "polecenie nie powiodło się: '%s %s %s', %s nie zmieniony"
 
-#: plugins/sudoers/visudo.c:601
+#: plugins/sudoers/visudo.c:639
 #, c-format
 msgid "error renaming %s, %s unchanged"
 msgstr "błąd podczas zmiany nazwy %s, %s nie zmieniony"
 
-#: plugins/sudoers/visudo.c:661
+#: plugins/sudoers/visudo.c:702
 msgid "What now? "
 msgstr "Co teraz? "
 
-#: plugins/sudoers/visudo.c:675
+#: plugins/sudoers/visudo.c:716
 msgid ""
 "Options are:\n"
 "  (e)dit sudoers file again\n"
@@ -1414,92 +1422,92 @@ msgstr ""
 "  (x) wyjście bez zapisu zmian do pliku sudoers\n"
 "  (Q) wyjście i zapisanie zmian w pliku sudoers (NIEBEZPIECZNE!)\n"
 
-#: plugins/sudoers/visudo.c:712
+#: plugins/sudoers/visudo.c:757
 #, c-format
 msgid "unable to execute %s"
 msgstr "nie udało się wywołać %s"
 
-#: plugins/sudoers/visudo.c:719
+#: plugins/sudoers/visudo.c:764
 #, c-format
 msgid "unable to run %s"
 msgstr "nie udało się uruchomić %s"
 
-#: plugins/sudoers/visudo.c:750
+#: plugins/sudoers/visudo.c:796
 #, c-format
 msgid "failed to parse %s file, unknown error"
 msgstr "nie udało się przeanalizować pliku %s, nieznany błąd"
 
-#: plugins/sudoers/visudo.c:762
+#: plugins/sudoers/visudo.c:808
 #, c-format
 msgid "parse error in %s near line %d\n"
 msgstr "błąd składni w %s w okolicy linii %d\n"
 
-#: plugins/sudoers/visudo.c:765
+#: plugins/sudoers/visudo.c:811
 #, c-format
 msgid "parse error in %s\n"
 msgstr "błąd składni w %s\n"
 
-#: plugins/sudoers/visudo.c:767
+#: plugins/sudoers/visudo.c:814 plugins/sudoers/visudo.c:816
 #, c-format
 msgid "%s: parsed OK\n"
 msgstr "%s: składnia poprawna\n"
 
-#: plugins/sudoers/visudo.c:776
+#: plugins/sudoers/visudo.c:826
 #, c-format
 msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
 msgstr "%s: błędny właściciel, (uid, gid) powinny wynosić (%u, %u)\n"
 
-#: plugins/sudoers/visudo.c:783
+#: plugins/sudoers/visudo.c:833
 #, c-format
 msgid "%s: bad permissions, should be mode 0%o\n"
 msgstr "%s: błędne uprawnienia, powinny być 0%o\n"
 
-#: plugins/sudoers/visudo.c:822
+#: plugins/sudoers/visudo.c:880
 #, c-format
 msgid "%s busy, try again later"
 msgstr "%s zajęty, proszę spróbować później"
 
-#: plugins/sudoers/visudo.c:865
+#: plugins/sudoers/visudo.c:924
 #, c-format
 msgid "specified editor (%s) doesn't exist"
 msgstr "podany edytor (%s) nie istnieje"
 
-#: plugins/sudoers/visudo.c:888
+#: plugins/sudoers/visudo.c:947
 #, c-format
 msgid "unable to stat editor (%s)"
 msgstr "nie udało się wykonać stat na edytorze (%s)"
 
-#: plugins/sudoers/visudo.c:936
+#: plugins/sudoers/visudo.c:995
 #, c-format
 msgid "no editor found (editor path = %s)"
 msgstr "nie znaleziono edytora (ścieżka = %s)"
 
-#: plugins/sudoers/visudo.c:1025
+#: plugins/sudoers/visudo.c:1089
 #, c-format
 msgid "Error: cycle in %s_Alias `%s'"
 msgstr "Błąd: cykl w %s_Alias `%s'"
 
-#: plugins/sudoers/visudo.c:1026
+#: plugins/sudoers/visudo.c:1090
 #, c-format
 msgid "Warning: cycle in %s_Alias `%s'"
 msgstr "Uwaga: cykl w %s_Alias `%s'"
 
-#: plugins/sudoers/visudo.c:1029
+#: plugins/sudoers/visudo.c:1093
 #, c-format
 msgid "Error: %s_Alias `%s' referenced but not defined"
 msgstr "Błąd: %s_Alias `%s' użyty, ale nie zdefiniowany"
 
-#: plugins/sudoers/visudo.c:1030
+#: plugins/sudoers/visudo.c:1094
 #, c-format
 msgid "Warning: %s_Alias `%s' referenced but not defined"
 msgstr "Uwaga: %s_Alias `%s' użyty, ale nie zdefiniowany"
 
-#: plugins/sudoers/visudo.c:1167
+#: plugins/sudoers/visudo.c:1229
 #, c-format
 msgid "%s: unused %s_Alias %s"
 msgstr "%s: nie użyty %s_Alias %s"
 
-#: plugins/sudoers/visudo.c:1224
+#: plugins/sudoers/visudo.c:1286
 #, c-format
 msgid ""
 "%s - safely edit the sudoers file\n"
@@ -1508,7 +1516,7 @@ msgstr ""
 "%s - bezpieczna edycja pliku sudoers\n"
 "\n"
 
-#: plugins/sudoers/visudo.c:1226
+#: plugins/sudoers/visudo.c:1288
 msgid ""
 "\n"
 "Options:\n"
@@ -1528,35 +1536,40 @@ msgstr ""
 "  -s          ścisłe sprawdzanie składni\n"
 "  -V          wyświetlenie informacji o wersji i zakończenie"
 
-#: plugins/sudoers/auth/bsdauth.c:64
+#: plugins/sudoers/auth/bsdauth.c:78
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "nie udało się uzyskać klasy logowania dla użytkownika %s"
+
+#: plugins/sudoers/auth/bsdauth.c:84
 msgid "unable to begin bsd authentication"
 msgstr "nie udało się rozpocząć uwierzytelnienia BSD"
 
-#: plugins/sudoers/auth/bsdauth.c:71
+#: plugins/sudoers/auth/bsdauth.c:92
 msgid "invalid authentication type"
 msgstr "błędny rodzaj uwierzytelnienia"
 
-#: plugins/sudoers/auth/bsdauth.c:79
+#: plugins/sudoers/auth/bsdauth.c:101
 msgid "unable to setup authentication"
 msgstr "nie udało się ustawić parametrów uwierzytelnienia"
 
-#: plugins/sudoers/auth/fwtk.c:59
+#: plugins/sudoers/auth/fwtk.c:60
 #, c-format
 msgid "unable to read fwtk config"
 msgstr "nie udało się odczytać konfiguracji fwtk"
 
-#: plugins/sudoers/auth/fwtk.c:64
+#: plugins/sudoers/auth/fwtk.c:65
 #, c-format
 msgid "unable to connect to authentication server"
 msgstr "nie udało się połączyć z serwerem uwierzytelniającym"
 
-#: plugins/sudoers/auth/fwtk.c:70 plugins/sudoers/auth/fwtk.c:93
-#: plugins/sudoers/auth/fwtk.c:126
+#: plugins/sudoers/auth/fwtk.c:71 plugins/sudoers/auth/fwtk.c:95
+#: plugins/sudoers/auth/fwtk.c:128
 #, c-format
 msgid "lost connection to authentication server"
 msgstr "utracono połączenie z serwerem uwierzytelniającym"
 
-#: plugins/sudoers/auth/fwtk.c:74
+#: plugins/sudoers/auth/fwtk.c:75
 #, c-format
 msgid ""
 "authentication server error:\n"
@@ -1565,142 +1578,142 @@ msgstr ""
 "błąd serwera uwierzytelniającego:\n"
 "%s"
 
-#: plugins/sudoers/auth/kerb5.c:114
-#, c-format
-msgid "%s: unable to parse '%s': %s"
-msgstr "%s: nie udało się przeanalizować '%s': %s"
-
-#: plugins/sudoers/auth/kerb5.c:127
+#: plugins/sudoers/auth/kerb5.c:117
 #, c-format
 msgid "%s: unable to unparse princ ('%s'): %s"
 msgstr "%s: nie udało się złożyć princ ('%s'): %s"
 
-#: plugins/sudoers/auth/kerb5.c:144
+#: plugins/sudoers/auth/kerb5.c:160
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: nie udało się przeanalizować '%s': %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
 #, c-format
 msgid "%s: unable to resolve ccache: %s"
 msgstr "%s: nie udało się rozwiązać ccache: %s"
 
-#: plugins/sudoers/auth/kerb5.c:188
+#: plugins/sudoers/auth/kerb5.c:218
 #, c-format
 msgid "%s: unable to allocate options: %s"
 msgstr "%s: nie udało się przydzielić opcji: %s"
 
-#: plugins/sudoers/auth/kerb5.c:204
+#: plugins/sudoers/auth/kerb5.c:234
 #, c-format
 msgid "%s: unable to get credentials: %s"
 msgstr "%s: nie udało się pobrać danych uwierzytelniających: %s"
 
-#: plugins/sudoers/auth/kerb5.c:217
+#: plugins/sudoers/auth/kerb5.c:247
 #, c-format
 msgid "%s: unable to initialize ccache: %s"
 msgstr "%s: nie udało się zainicjować ccache: %s"
 
-#: plugins/sudoers/auth/kerb5.c:221
+#: plugins/sudoers/auth/kerb5.c:251
 #, c-format
 msgid "%s: unable to store cred in ccache: %s"
 msgstr "%s: nie udało się zapisać danych uwierzytelniających w ccache: %s"
 
-#: plugins/sudoers/auth/kerb5.c:284
+#: plugins/sudoers/auth/kerb5.c:316
 #, c-format
 msgid "%s: unable to get host principal: %s"
 msgstr "%s: nie udało się pobrać głównego hosta: %s"
 
-#: plugins/sudoers/auth/kerb5.c:299
+#: plugins/sudoers/auth/kerb5.c:331
 #, c-format
 msgid "%s: Cannot verify TGT! Possible attack!: %s"
 msgstr "%s: Nie można zweryfikować TGT! Możliwy atak!: %s"
 
-#: plugins/sudoers/auth/pam.c:99
+#: plugins/sudoers/auth/pam.c:100
 msgid "unable to initialize PAM"
 msgstr "nie udało się zainicjować PAM"
 
-#: plugins/sudoers/auth/pam.c:142
+#: plugins/sudoers/auth/pam.c:144
 msgid "account validation failure, is your account locked?"
 msgstr "błąd kontroli poprawności konta - konto zablokowane?"
 
-#: plugins/sudoers/auth/pam.c:146
+#: plugins/sudoers/auth/pam.c:148
 msgid "Account or password is expired, reset your password and try again"
 msgstr "Konto lub hasło wygasło, należy ustawić ponownie hasło i spróbować jeszcze raz"
 
-#: plugins/sudoers/auth/pam.c:153
+#: plugins/sudoers/auth/pam.c:155
 #, c-format
 msgid "pam_chauthtok: %s"
 msgstr "pam_chauthtok: %s"
 
-#: plugins/sudoers/auth/pam.c:157
+#: plugins/sudoers/auth/pam.c:159
 msgid "Password expired, contact your system administrator"
 msgstr "Hasło wygasło, proszę skontaktować się z administratorem systemu"
 
-#: plugins/sudoers/auth/pam.c:161
+#: plugins/sudoers/auth/pam.c:163
 msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
 msgstr "Konto wygasło lub w konfiguracji PAM brak sekcji \"account\" dla sudo, proszę skontaktować się z administratorem systemu"
 
-#: plugins/sudoers/auth/pam.c:176
+#: plugins/sudoers/auth/pam.c:178
 #, c-format
 msgid "pam_authenticate: %s"
 msgstr "pam_authenticate: %s"
 
-#: plugins/sudoers/auth/pam.c:296
+#: plugins/sudoers/auth/pam.c:306
 msgid "Password: "
 msgstr "Hasło: "
 
-#: plugins/sudoers/auth/pam.c:297
+#: plugins/sudoers/auth/pam.c:307
 msgid "Password:"
 msgstr "Hasło:"
 
-#: plugins/sudoers/auth/securid.c:82 plugins/sudoers/auth/securid5.c:106
-#, c-format
-msgid "unable to contact the SecurID server"
-msgstr "nie udało się połączyć z serwerem SecurID"
-
 #: plugins/sudoers/auth/securid5.c:81
 #, c-format
 msgid "failed to initialise the ACE API library"
 msgstr "nie udało się zainicjować biblioteki ACE API"
 
-#: plugins/sudoers/auth/securid5.c:115
+#: plugins/sudoers/auth/securid5.c:107
+#, c-format
+msgid "unable to contact the SecurID server"
+msgstr "nie udało się połączyć z serwerem SecurID"
+
+#: plugins/sudoers/auth/securid5.c:116
 #, c-format
 msgid "User ID locked for SecurID Authentication"
 msgstr "ID użytkownika zablokowany dla uwierzytelnienia SecurID"
 
-#: plugins/sudoers/auth/securid5.c:119 plugins/sudoers/auth/securid5.c:169
+#: plugins/sudoers/auth/securid5.c:120 plugins/sudoers/auth/securid5.c:171
 #, c-format
 msgid "invalid username length for SecurID"
 msgstr "błędna długość nazwy użytkownika dla SecurID"
 
-#: plugins/sudoers/auth/securid5.c:123 plugins/sudoers/auth/securid5.c:174
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:176
 #, c-format
 msgid "invalid Authentication Handle for SecurID"
 msgstr "błędny uchwyt uwierzytelnienia dla SecurID"
 
-#: plugins/sudoers/auth/securid5.c:127
+#: plugins/sudoers/auth/securid5.c:128
 #, c-format
 msgid "SecurID communication failed"
 msgstr "błąd komunikacji SecurID"
 
-#: plugins/sudoers/auth/securid5.c:131 plugins/sudoers/auth/securid5.c:213
+#: plugins/sudoers/auth/securid5.c:132 plugins/sudoers/auth/securid5.c:215
 #, c-format
 msgid "unknown SecurID error"
 msgstr "nieznany błąd SecurID"
 
-#: plugins/sudoers/auth/securid5.c:164
+#: plugins/sudoers/auth/securid5.c:166
 #, c-format
 msgid "invalid passcode length for SecurID"
 msgstr "błędna długość hasła dla SecurID"
 
-#: plugins/sudoers/auth/sia.c:106
+#: plugins/sudoers/auth/sia.c:109
 msgid "unable to initialize SIA session"
 msgstr "nie udało się zainicjować sesji SIA"
 
-#: plugins/sudoers/auth/sudo_auth.c:124
-msgid "There are no authentication methods compiled into sudo!  If you want to turn off authentication, use the --disable-authentication configure option."
-msgstr "W sudo nie wkompilowano żadnych metod uwierzytelniania! Aby wyłączyć uwierzytelnianie, proszę użyć opcji konfiguracyjnej --disable-authentication."
-
-#: plugins/sudoers/auth/sudo_auth.c:134
+#: plugins/sudoers/auth/sudo_auth.c:117
 msgid "Invalid authentication methods compiled into sudo!  You may mix standalone and non-standalone authentication."
 msgstr "W sudo wkompilowano błędne metody uwierzytelniania! Można mieszać samodzielne i niesamodzielne sposoby uwierzytelniania."
 
-#: plugins/sudoers/auth/sudo_auth.c:243
+#: plugins/sudoers/auth/sudo_auth.c:199
+msgid "There are no authentication methods compiled into sudo!  If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "W sudo nie wkompilowano żadnych metod uwierzytelniania! Aby wyłączyć uwierzytelnianie, proszę użyć opcji konfiguracyjnej --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:271
 #, c-format
 msgid "%d incorrect password attempt"
 msgid_plural "%d incorrect password attempts"
@@ -1708,6 +1721,6 @@ msgstr[0] "%d błędna próba wprowadzenia hasła"
 msgstr[1] "%d błędne próby wprowadzenia hasła"
 msgstr[2] "%d błędnych prób wprowadzenia hasła"
 
-#: plugins/sudoers/auth/sudo_auth.c:335
+#: plugins/sudoers/auth/sudo_auth.c:374
 msgid "Authentication methods:"
 msgstr "Metody uwierzytelniania:"
index b096194c7215aeed23f57300588ffca03770aafc..8c4af90ab0238af22a402f82ef753f45ce85570c 100644 (file)
@@ -5,9 +5,9 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: sudo 1.8.3p2\n"
+"Project-Id-Version: sudo 1.8.4\n"
 "Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
-"POT-Creation-Date: 2012-01-24 16:12-0500\n"
+"POT-Creation-Date: 2012-02-06 15:48-0500\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,146 +17,146 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
 
-#: plugins/sudoers/alias.c:122
+#: plugins/sudoers/alias.c:125
 #, c-format
 msgid "Alias `%s' already defined"
 msgstr ""
 
-#: plugins/sudoers/bsm_audit.c:58 plugins/sudoers/bsm_audit.c:61
-#: plugins/sudoers/bsm_audit.c:109 plugins/sudoers/bsm_audit.c:113
-#: plugins/sudoers/bsm_audit.c:163 plugins/sudoers/bsm_audit.c:167
+#: plugins/sudoers/bsm_audit.c:61 plugins/sudoers/bsm_audit.c:64
+#: plugins/sudoers/bsm_audit.c:113 plugins/sudoers/bsm_audit.c:117
+#: plugins/sudoers/bsm_audit.c:169 plugins/sudoers/bsm_audit.c:173
 msgid "getaudit: failed"
 msgstr ""
 
-#: plugins/sudoers/bsm_audit.c:87 plugins/sudoers/bsm_audit.c:148
+#: plugins/sudoers/bsm_audit.c:91 plugins/sudoers/bsm_audit.c:154
 msgid "Could not determine audit condition"
 msgstr ""
 
-#: plugins/sudoers/bsm_audit.c:98
+#: plugins/sudoers/bsm_audit.c:102
 msgid "getauid failed"
 msgstr ""
 
-#: plugins/sudoers/bsm_audit.c:100 plugins/sudoers/bsm_audit.c:157
+#: plugins/sudoers/bsm_audit.c:104 plugins/sudoers/bsm_audit.c:163
 msgid "au_open: failed"
 msgstr ""
 
-#: plugins/sudoers/bsm_audit.c:115 plugins/sudoers/bsm_audit.c:169
+#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:175
 msgid "au_to_subject: failed"
 msgstr ""
 
-#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:173
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:179
 msgid "au_to_exec_args: failed"
 msgstr ""
 
-#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:182
+#: plugins/sudoers/bsm_audit.c:127 plugins/sudoers/bsm_audit.c:188
 msgid "au_to_return32: failed"
 msgstr ""
 
-#: plugins/sudoers/bsm_audit.c:126 plugins/sudoers/bsm_audit.c:185
+#: plugins/sudoers/bsm_audit.c:130 plugins/sudoers/bsm_audit.c:191
 msgid "unable to commit audit record"
 msgstr ""
 
-#: plugins/sudoers/bsm_audit.c:155
+#: plugins/sudoers/bsm_audit.c:161
 msgid "getauid: failed"
 msgstr ""
 
-#: plugins/sudoers/bsm_audit.c:178
+#: plugins/sudoers/bsm_audit.c:184
 msgid "au_to_text: failed"
 msgstr ""
 
-#: plugins/sudoers/check.c:157
+#: plugins/sudoers/check.c:158
 #, c-format
 msgid "sorry, a password is required to run %s"
 msgstr ""
 
-#: plugins/sudoers/check.c:244 plugins/sudoers/iolog.c:169
-#: plugins/sudoers/sudoers.c:960 plugins/sudoers/sudoreplay.c:325
-#: plugins/sudoers/sudoreplay.c:334 plugins/sudoers/sudoreplay.c:675
-#: plugins/sudoers/sudoreplay.c:767 plugins/sudoers/visudo.c:744
+#: plugins/sudoers/check.c:249 plugins/sudoers/iolog.c:172
+#: plugins/sudoers/sudoers.c:992 plugins/sudoers/sudoreplay.c:348
+#: plugins/sudoers/sudoreplay.c:357 plugins/sudoers/sudoreplay.c:703
+#: plugins/sudoers/sudoreplay.c:797 plugins/sudoers/visudo.c:790
 #, c-format
 msgid "unable to open %s"
 msgstr ""
 
-#: plugins/sudoers/check.c:248 plugins/sudoers/iolog.c:199
+#: plugins/sudoers/check.c:253 plugins/sudoers/iolog.c:202
 #, c-format
 msgid "unable to write to %s"
 msgstr ""
 
-#: plugins/sudoers/check.c:256 plugins/sudoers/check.c:494
-#: plugins/sudoers/check.c:544 plugins/sudoers/iolog.c:122
-#: plugins/sudoers/iolog.c:153
+#: plugins/sudoers/check.c:261 plugins/sudoers/check.c:506
+#: plugins/sudoers/check.c:556 plugins/sudoers/iolog.c:123
+#: plugins/sudoers/iolog.c:156
 #, c-format
 msgid "unable to mkdir %s"
 msgstr ""
 
-#: plugins/sudoers/check.c:389
+#: plugins/sudoers/check.c:396
 #, c-format
 msgid "internal error, expand_prompt() overflow"
 msgstr ""
 
-#: plugins/sudoers/check.c:445
+#: plugins/sudoers/check.c:456
 #, c-format
 msgid "timestamp path too long: %s"
 msgstr ""
 
-#: plugins/sudoers/check.c:473 plugins/sudoers/check.c:517
-#: plugins/sudoers/iolog.c:155
+#: plugins/sudoers/check.c:485 plugins/sudoers/check.c:529
+#: plugins/sudoers/iolog.c:158
 #, c-format
 msgid "%s exists but is not a directory (0%o)"
 msgstr ""
 
-#: plugins/sudoers/check.c:476 plugins/sudoers/check.c:520
-#: plugins/sudoers/check.c:565
+#: plugins/sudoers/check.c:488 plugins/sudoers/check.c:532
+#: plugins/sudoers/check.c:577
 #, c-format
 msgid "%s owned by uid %u, should be uid %u"
 msgstr ""
 
-#: plugins/sudoers/check.c:481 plugins/sudoers/check.c:525
+#: plugins/sudoers/check.c:493 plugins/sudoers/check.c:537
 #, c-format
 msgid "%s writable by non-owner (0%o), should be mode 0700"
 msgstr ""
 
-#: plugins/sudoers/check.c:489 plugins/sudoers/check.c:533
-#: plugins/sudoers/check.c:601 plugins/sudoers/sudoers.c:946
-#: plugins/sudoers/visudo.c:304 plugins/sudoers/visudo.c:544
+#: plugins/sudoers/check.c:501 plugins/sudoers/check.c:545
+#: plugins/sudoers/check.c:613 plugins/sudoers/sudoers.c:978
+#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:582
 #, c-format
 msgid "unable to stat %s"
 msgstr ""
 
-#: plugins/sudoers/check.c:559
+#: plugins/sudoers/check.c:571
 #, c-format
 msgid "%s exists but is not a regular file (0%o)"
 msgstr ""
 
-#: plugins/sudoers/check.c:571
+#: plugins/sudoers/check.c:583
 #, c-format
 msgid "%s writable by non-owner (0%o), should be mode 0600"
 msgstr ""
 
-#: plugins/sudoers/check.c:625
+#: plugins/sudoers/check.c:637
 #, c-format
 msgid "timestamp too far in the future: %20.20s"
 msgstr ""
 
-#: plugins/sudoers/check.c:671
+#: plugins/sudoers/check.c:684
 #, c-format
 msgid "unable to remove %s (%s), will reset to the epoch"
 msgstr ""
 
-#: plugins/sudoers/check.c:679
+#: plugins/sudoers/check.c:692
 #, c-format
 msgid "unable to reset %s to the epoch"
 msgstr ""
 
-#: plugins/sudoers/check.c:733 plugins/sudoers/check.c:739
-#: plugins/sudoers/sudoers.c:800 plugins/sudoers/sudoers.c:804
+#: plugins/sudoers/check.c:752 plugins/sudoers/check.c:758
+#: plugins/sudoers/sudoers.c:829 plugins/sudoers/sudoers.c:833
 #, c-format
 msgid "unknown uid: %u"
 msgstr ""
 
-#: plugins/sudoers/check.c:736 plugins/sudoers/sudoers.c:742
-#: plugins/sudoers/sudoers.c:1077 plugins/sudoers/testsudoers.c:202
-#: plugins/sudoers/testsudoers.c:337
+#: plugins/sudoers/check.c:755 plugins/sudoers/sudoers.c:770
+#: plugins/sudoers/sudoers.c:1108 plugins/sudoers/testsudoers.c:218
+#: plugins/sudoers/testsudoers.c:362
 #, c-format
 msgid "unknown user: %s"
 msgstr ""
@@ -403,452 +403,455 @@ msgid "When to require a password for 'verify' pseudocommand: %s"
 msgstr ""
 
 #: plugins/sudoers/def_data.c:243
-msgid "Preload the dummy exec functions contained in 'noexec_file'"
+msgid "Preload the dummy exec functions contained in \"_PATH_SUDO_NOEXEC"
 msgstr ""
 
 #: plugins/sudoers/def_data.c:247
-#, c-format
-msgid "File containing dummy exec functions: %s"
-msgstr ""
-
-#: plugins/sudoers/def_data.c:251
 msgid "If LDAP directory is up, do we ignore local sudoers file"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:255
+#: plugins/sudoers/def_data.c:251
 #, c-format
 msgid "File descriptors >= %d will be closed before executing a command"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:259
+#: plugins/sudoers/def_data.c:255
 msgid "If set, users may override the value of `closefrom' with the -C option"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:263
+#: plugins/sudoers/def_data.c:259
 msgid "Allow users to set arbitrary environment variables"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:267
+#: plugins/sudoers/def_data.c:263
 msgid "Reset the environment to a default set of variables"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:271
+#: plugins/sudoers/def_data.c:267
 msgid "Environment variables to check for sanity:"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:275
+#: plugins/sudoers/def_data.c:271
 msgid "Environment variables to remove:"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:279
+#: plugins/sudoers/def_data.c:275
 msgid "Environment variables to preserve:"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:283
+#: plugins/sudoers/def_data.c:279
 #, c-format
 msgid "SELinux role to use in the new security context: %s"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:287
+#: plugins/sudoers/def_data.c:283
 #, c-format
 msgid "SELinux type to use in the new security context: %s"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:291
+#: plugins/sudoers/def_data.c:287
 #, c-format
 msgid "Path to the sudo-specific environment file: %s"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:295
+#: plugins/sudoers/def_data.c:291
 #, c-format
 msgid "Locale to use while parsing sudoers: %s"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:299
-msgid "Allow sudo to prompt for a password even if it would be visisble"
+#: plugins/sudoers/def_data.c:295
+msgid "Allow sudo to prompt for a password even if it would be visible"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:303
+#: plugins/sudoers/def_data.c:299
 msgid "Provide visual feedback at the password prompt when there is user input"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:307
+#: plugins/sudoers/def_data.c:303
 msgid ""
 "Use faster globbing that is less accurate but does not access the filesystem"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:311
+#: plugins/sudoers/def_data.c:307
 msgid ""
 "The umask specified in sudoers will override the user's, even if it is more "
 "permissive"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:315
+#: plugins/sudoers/def_data.c:311
 msgid "Log user's input for the command being run"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:319
+#: plugins/sudoers/def_data.c:315
 msgid "Log the output of the command being run"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:323
+#: plugins/sudoers/def_data.c:319
 msgid "Compress I/O logs using zlib"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:327
+#: plugins/sudoers/def_data.c:323
 msgid "Always run commands in a pseudo-tty"
 msgstr ""
 
+#: plugins/sudoers/def_data.c:327
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr ""
+
 #: plugins/sudoers/def_data.c:331
-msgid "Plugin for non-Unix group support"
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
 msgstr ""
 
 #: plugins/sudoers/def_data.c:335
-msgid "Directory in which to store input/output logs"
+#, c-format
+msgid "File in which to store the input/output log: %s"
 msgstr ""
 
 #: plugins/sudoers/def_data.c:339
-msgid "File in which to store the input/output log"
-msgstr ""
-
-#: plugins/sudoers/def_data.c:343
 msgid "Add an entry to the utmp/utmpx file when allocating a pty"
 msgstr ""
 
-#: plugins/sudoers/def_data.c:347
+#: plugins/sudoers/def_data.c:343
 msgid "Set the user in utmp to the runas user, not the invoking user"
 msgstr ""
 
-#: plugins/sudoers/defaults.c:205
+#: plugins/sudoers/defaults.c:208
 #, c-format
 msgid "unknown defaults entry `%s'"
 msgstr ""
 
-#: plugins/sudoers/defaults.c:213 plugins/sudoers/defaults.c:223
-#: plugins/sudoers/defaults.c:243 plugins/sudoers/defaults.c:256
-#: plugins/sudoers/defaults.c:269 plugins/sudoers/defaults.c:282
-#: plugins/sudoers/defaults.c:295 plugins/sudoers/defaults.c:315
-#: plugins/sudoers/defaults.c:325
+#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
+#: plugins/sudoers/defaults.c:246 plugins/sudoers/defaults.c:259
+#: plugins/sudoers/defaults.c:272 plugins/sudoers/defaults.c:285
+#: plugins/sudoers/defaults.c:298 plugins/sudoers/defaults.c:318
+#: plugins/sudoers/defaults.c:328
 #, c-format
 msgid "value `%s' is invalid for option `%s'"
 msgstr ""
 
-#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
-#: plugins/sudoers/defaults.c:234 plugins/sudoers/defaults.c:251
-#: plugins/sudoers/defaults.c:264 plugins/sudoers/defaults.c:277
-#: plugins/sudoers/defaults.c:290 plugins/sudoers/defaults.c:310
-#: plugins/sudoers/defaults.c:321
+#: plugins/sudoers/defaults.c:219 plugins/sudoers/defaults.c:229
+#: plugins/sudoers/defaults.c:237 plugins/sudoers/defaults.c:254
+#: plugins/sudoers/defaults.c:267 plugins/sudoers/defaults.c:280
+#: plugins/sudoers/defaults.c:293 plugins/sudoers/defaults.c:313
+#: plugins/sudoers/defaults.c:324
 #, c-format
 msgid "no value specified for `%s'"
 msgstr ""
 
-#: plugins/sudoers/defaults.c:239
+#: plugins/sudoers/defaults.c:242
 #, c-format
 msgid "values for `%s' must start with a '/'"
 msgstr ""
 
-#: plugins/sudoers/defaults.c:301
+#: plugins/sudoers/defaults.c:304
 #, c-format
 msgid "option `%s' does not take a value"
 msgstr ""
 
-#: plugins/sudoers/env.c:259
+#: plugins/sudoers/env.c:258
 #, c-format
 msgid "internal error, sudo_setenv() overflow"
 msgstr ""
 
-#: plugins/sudoers/env.c:289
+#: plugins/sudoers/env.c:291
 #, c-format
 msgid "sudo_putenv: corrupted envp, length mismatch"
 msgstr ""
 
-#: plugins/sudoers/env.c:703
+#: plugins/sudoers/env.c:710
 #, c-format
 msgid ""
 "sorry, you are not allowed to set the following environment variables: %s"
 msgstr ""
 
-#: plugins/sudoers/find_path.c:68 plugins/sudoers/find_path.c:107
-#: plugins/sudoers/find_path.c:122 plugins/sudoers/iolog.c:124
-#: plugins/sudoers/sudoers.c:892 toke.l:663 toke.l:814
+#: plugins/sudoers/find_path.c:69 plugins/sudoers/find_path.c:108
+#: plugins/sudoers/find_path.c:123 plugins/sudoers/iolog.c:125
+#: plugins/sudoers/sudoers.c:923 toke.l:668 toke.l:823
 #, c-format
 msgid "%s: %s"
 msgstr ""
 
-#: gram.y:103
+#: gram.y:110
 #, c-format
 msgid ">>> %s: %s near line %d <<<"
 msgstr ""
 
-#: plugins/sudoers/group_plugin.c:90
+#: plugins/sudoers/group_plugin.c:91
 #, c-format
 msgid "%s%s: %s"
 msgstr ""
 
-#: plugins/sudoers/group_plugin.c:102
+#: plugins/sudoers/group_plugin.c:103
 #, c-format
 msgid "%s must be owned by uid %d"
 msgstr ""
 
-#: plugins/sudoers/group_plugin.c:106
+#: plugins/sudoers/group_plugin.c:107
 #, c-format
 msgid "%s must only be writable by owner"
 msgstr ""
 
-#: plugins/sudoers/group_plugin.c:113
+#: plugins/sudoers/group_plugin.c:114
 #, c-format
 msgid "unable to dlopen %s: %s"
 msgstr ""
 
-#: plugins/sudoers/group_plugin.c:118
+#: plugins/sudoers/group_plugin.c:119
 #, c-format
 msgid "unable to find symbol \"group_plugin\" in %s"
 msgstr ""
 
-#: plugins/sudoers/group_plugin.c:123
+#: plugins/sudoers/group_plugin.c:124
 #, c-format
 msgid "%s: incompatible group plugin major version %d, expected %d"
 msgstr ""
 
-#: plugins/sudoers/interfaces.c:109
+#: plugins/sudoers/interfaces.c:112
 msgid "Local IP address and netmask pairs:\n"
 msgstr ""
 
-#: plugins/sudoers/iolog.c:176 plugins/sudoers/sudoers.c:967
+#: plugins/sudoers/iolog.c:179 plugins/sudoers/sudoers.c:999
 #, c-format
 msgid "unable to read %s"
 msgstr ""
 
-#: plugins/sudoers/iolog.c:179
+#: plugins/sudoers/iolog.c:182
 #, c-format
 msgid "invalid sequence number %s"
 msgstr ""
 
-#: plugins/sudoers/iolog.c:225 plugins/sudoers/iolog.c:228
-#: plugins/sudoers/iolog.c:478 plugins/sudoers/iolog.c:483
-#: plugins/sudoers/iolog.c:489 plugins/sudoers/iolog.c:497
-#: plugins/sudoers/iolog.c:505 plugins/sudoers/iolog.c:513
-#: plugins/sudoers/iolog.c:521
+#: plugins/sudoers/iolog.c:231 plugins/sudoers/iolog.c:234
+#: plugins/sudoers/iolog.c:499 plugins/sudoers/iolog.c:504
+#: plugins/sudoers/iolog.c:510 plugins/sudoers/iolog.c:518
+#: plugins/sudoers/iolog.c:526 plugins/sudoers/iolog.c:534
+#: plugins/sudoers/iolog.c:542
 #, c-format
 msgid "unable to create %s"
 msgstr ""
 
-#: plugins/sudoers/iolog_path.c:247 plugins/sudoers/sudoers.c:355
+#: plugins/sudoers/iolog_path.c:256 plugins/sudoers/sudoers.c:362
 #, c-format
 msgid "unable to set locale to \"%s\", using \"C\""
 msgstr ""
 
-#: plugins/sudoers/ldap.c:368
+#: plugins/sudoers/ldap.c:374
 #, c-format
 msgid "sudo_ldap_conf_add_ports: port too large"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:391
+#: plugins/sudoers/ldap.c:397
 #, c-format
 msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:420
+#: plugins/sudoers/ldap.c:427
 #, c-format
 msgid "unsupported LDAP uri type: %s"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:449
+#: plugins/sudoers/ldap.c:456
 #, c-format
 msgid "invalid uri: %s"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:455
+#: plugins/sudoers/ldap.c:462
 #, c-format
 msgid "unable to mix ldap and ldaps URIs"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:459
+#: plugins/sudoers/ldap.c:466
 #, c-format
 msgid "unable to mix ldaps and starttls"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:478
+#: plugins/sudoers/ldap.c:485
 #, c-format
 msgid "sudo_ldap_parse_uri: out of space building hostbuf"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:541
+#: plugins/sudoers/ldap.c:550
 #, c-format
 msgid "unable to initialize SSL cert and key db: %s"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:937
+#: plugins/sudoers/ldap.c:958
 #, c-format
 msgid "unable to get GMT time"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:943
+#: plugins/sudoers/ldap.c:964
 #, c-format
 msgid "unable to format timestamp"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:951
+#: plugins/sudoers/ldap.c:972
 #, c-format
 msgid "unable to build time filter"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:1052
+#: plugins/sudoers/ldap.c:1185
 #, c-format
 msgid "sudo_ldap_build_pass1 allocation mismatch"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:1562
+#: plugins/sudoers/ldap.c:1705
 #, c-format
 msgid ""
 "\n"
 "LDAP Role: %s\n"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:1564
+#: plugins/sudoers/ldap.c:1707
 #, c-format
 msgid ""
 "\n"
 "LDAP Role: UNKNOWN\n"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:1611
+#: plugins/sudoers/ldap.c:1754
 #, c-format
 msgid "    Order: %s\n"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:1619
+#: plugins/sudoers/ldap.c:1762
 #, c-format
 msgid "    Commands:\n"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:2006
+#: plugins/sudoers/ldap.c:2161
 #, c-format
 msgid "unable to initialize LDAP: %s"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:2037
+#: plugins/sudoers/ldap.c:2192
 #, c-format
 msgid ""
 "start_tls specified but LDAP libs do not support ldap_start_tls_s() or "
 "ldap_start_tls_s_np()"
 msgstr ""
 
-#: plugins/sudoers/ldap.c:2268
+#: plugins/sudoers/ldap.c:2428
 #, c-format
 msgid "invalid sudoOrder attribute: %s"
 msgstr ""
 
-#: plugins/sudoers/linux_audit.c:55
+#: plugins/sudoers/linux_audit.c:57
 #, c-format
 msgid "unable to open audit system"
 msgstr ""
 
-#: plugins/sudoers/linux_audit.c:79
+#: plugins/sudoers/linux_audit.c:82
 #, c-format
 msgid "internal error, linux_audit_command() overflow"
 msgstr ""
 
-#: plugins/sudoers/linux_audit.c:88
+#: plugins/sudoers/linux_audit.c:91
 #, c-format
 msgid "unable to send audit message"
 msgstr ""
 
-#: plugins/sudoers/logging.c:192
+#: plugins/sudoers/logging.c:198
 #, c-format
 msgid "unable to open log file: %s: %s"
 msgstr ""
 
-#: plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:201
 #, c-format
 msgid "unable to lock log file: %s: %s"
 msgstr ""
 
-#: plugins/sudoers/logging.c:249
+#: plugins/sudoers/logging.c:256
 msgid "user NOT in sudoers"
 msgstr ""
 
-#: plugins/sudoers/logging.c:251
+#: plugins/sudoers/logging.c:258
 msgid "user NOT authorized on host"
 msgstr ""
 
-#: plugins/sudoers/logging.c:253
+#: plugins/sudoers/logging.c:260
 msgid "command not allowed"
 msgstr ""
 
-#: plugins/sudoers/logging.c:263
+#: plugins/sudoers/logging.c:270
 #, c-format
 msgid "%s is not in the sudoers file.  This incident will be reported.\n"
 msgstr ""
 
-#: plugins/sudoers/logging.c:266
+#: plugins/sudoers/logging.c:273
 #, c-format
 msgid "%s is not allowed to run sudo on %s.  This incident will be reported.\n"
 msgstr ""
 
-#: plugins/sudoers/logging.c:270
+#: plugins/sudoers/logging.c:277
 #, c-format
 msgid "Sorry, user %s may not run sudo on %s.\n"
 msgstr ""
 
-#: plugins/sudoers/logging.c:273
+#: plugins/sudoers/logging.c:280
 #, c-format
 msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
 msgstr ""
 
-#: plugins/sudoers/logging.c:408
+#: plugins/sudoers/logging.c:420
 #, c-format
 msgid "unable to fork"
 msgstr ""
 
-#: plugins/sudoers/logging.c:415 plugins/sudoers/logging.c:472
+#: plugins/sudoers/logging.c:427 plugins/sudoers/logging.c:489
 #, c-format
 msgid "unable to fork: %m"
 msgstr ""
 
-#: plugins/sudoers/logging.c:465
+#: plugins/sudoers/logging.c:479
 #, c-format
 msgid "unable to open pipe: %m"
 msgstr ""
 
-#: plugins/sudoers/logging.c:484
+#: plugins/sudoers/logging.c:504
 #, c-format
 msgid "unable to dup stdin: %m"
 msgstr ""
 
-#: plugins/sudoers/logging.c:518
+#: plugins/sudoers/logging.c:540
 #, c-format
 msgid "unable to execute %s: %m"
 msgstr ""
 
-#: plugins/sudoers/logging.c:728
+#: plugins/sudoers/logging.c:755
 #, c-format
 msgid "internal error: insufficient space for log line"
 msgstr ""
 
-#: plugins/sudoers/parse.c:115
+#: plugins/sudoers/parse.c:123
 #, c-format
 msgid "parse error in %s near line %d"
 msgstr ""
 
-#: plugins/sudoers/parse.c:371
+#: plugins/sudoers/parse.c:126
+#, c-format
+msgid "parse error in %s"
+msgstr ""
+
+#: plugins/sudoers/parse.c:389
 #, c-format
 msgid ""
 "\n"
 "Sudoers entry:\n"
 msgstr ""
 
-#: plugins/sudoers/parse.c:373
+#: plugins/sudoers/parse.c:391
 #, c-format
 msgid "    RunAsUsers: "
 msgstr ""
 
-#: plugins/sudoers/parse.c:388
+#: plugins/sudoers/parse.c:406
 #, c-format
 msgid "    RunAsGroups: "
 msgstr ""
 
-#: plugins/sudoers/parse.c:397
+#: plugins/sudoers/parse.c:415
 #, c-format
 msgid ""
 "    Commands:\n"
@@ -859,93 +862,93 @@ msgstr ""
 msgid ": "
 msgstr ""
 
-#: plugins/sudoers/pwutil.c:251
+#: plugins/sudoers/pwutil.c:260
 #, c-format
 msgid "unable to cache uid %u (%s), already exists"
 msgstr ""
 
-#: plugins/sudoers/pwutil.c:259
+#: plugins/sudoers/pwutil.c:268
 #, c-format
 msgid "unable to cache uid %u, already exists"
 msgstr ""
 
-#: plugins/sudoers/pwutil.c:295 plugins/sudoers/pwutil.c:304
+#: plugins/sudoers/pwutil.c:305 plugins/sudoers/pwutil.c:314
 #, c-format
 msgid "unable to cache user %s, already exists"
 msgstr ""
 
-#: plugins/sudoers/pwutil.c:622
+#: plugins/sudoers/pwutil.c:655
 #, c-format
 msgid "unable to cache gid %u (%s), already exists"
 msgstr ""
 
-#: plugins/sudoers/pwutil.c:630
+#: plugins/sudoers/pwutil.c:663
 #, c-format
 msgid "unable to cache gid %u, already exists"
 msgstr ""
 
-#: plugins/sudoers/pwutil.c:659 plugins/sudoers/pwutil.c:668
+#: plugins/sudoers/pwutil.c:693 plugins/sudoers/pwutil.c:702
 #, c-format
 msgid "unable to cache group %s, already exists"
 msgstr ""
 
-#: plugins/sudoers/set_perms.c:109 plugins/sudoers/set_perms.c:358
-#: plugins/sudoers/set_perms.c:591 plugins/sudoers/set_perms.c:825
+#: plugins/sudoers/set_perms.c:114 plugins/sudoers/set_perms.c:365
+#: plugins/sudoers/set_perms.c:601 plugins/sudoers/set_perms.c:837
 msgid "perm stack overflow"
 msgstr ""
 
-#: plugins/sudoers/set_perms.c:117 plugins/sudoers/set_perms.c:366
-#: plugins/sudoers/set_perms.c:599 plugins/sudoers/set_perms.c:833
+#: plugins/sudoers/set_perms.c:122 plugins/sudoers/set_perms.c:373
+#: plugins/sudoers/set_perms.c:609 plugins/sudoers/set_perms.c:845
 msgid "perm stack underflow"
 msgstr ""
 
-#: plugins/sudoers/set_perms.c:223 plugins/sudoers/set_perms.c:458
-#: plugins/sudoers/set_perms.c:696
+#: plugins/sudoers/set_perms.c:228 plugins/sudoers/set_perms.c:466
+#: plugins/sudoers/set_perms.c:706
 msgid "unable to change to runas gid"
 msgstr ""
 
-#: plugins/sudoers/set_perms.c:231 plugins/sudoers/set_perms.c:465
-#: plugins/sudoers/set_perms.c:703
+#: plugins/sudoers/set_perms.c:236 plugins/sudoers/set_perms.c:473
+#: plugins/sudoers/set_perms.c:713
 msgid "unable to change to runas uid"
 msgstr ""
 
-#: plugins/sudoers/set_perms.c:245 plugins/sudoers/set_perms.c:478
-#: plugins/sudoers/set_perms.c:716
+#: plugins/sudoers/set_perms.c:250 plugins/sudoers/set_perms.c:486
+#: plugins/sudoers/set_perms.c:726
 #, c-format
 msgid "unable to change to sudoers gid"
 msgstr ""
 
-#: plugins/sudoers/set_perms.c:286 plugins/sudoers/set_perms.c:516
-#: plugins/sudoers/set_perms.c:754 plugins/sudoers/set_perms.c:894
+#: plugins/sudoers/set_perms.c:291 plugins/sudoers/set_perms.c:524
+#: plugins/sudoers/set_perms.c:764 plugins/sudoers/set_perms.c:906
 msgid "too many processes"
 msgstr ""
 
-#: plugins/sudoers/set_perms.c:956
+#: plugins/sudoers/set_perms.c:970
 msgid "unable to set runas group vector"
 msgstr ""
 
-#: plugins/sudoers/sudo_nss.c:238
+#: plugins/sudoers/sudo_nss.c:243
 #, c-format
 msgid "Matching Defaults entries for %s on this host:\n"
 msgstr ""
 
-#: plugins/sudoers/sudo_nss.c:251
+#: plugins/sudoers/sudo_nss.c:256
 #, c-format
 msgid "Runas and Command-specific defaults for %s:\n"
 msgstr ""
 
-#: plugins/sudoers/sudo_nss.c:264
+#: plugins/sudoers/sudo_nss.c:269
 #, c-format
 msgid "User %s may run the following commands on this host:\n"
 msgstr ""
 
-#: plugins/sudoers/sudo_nss.c:274
+#: plugins/sudoers/sudo_nss.c:279
 #, c-format
 msgid "User %s is not allowed to run sudo on %s.\n"
 msgstr ""
 
 #: plugins/sudoers/sudoers.c:201 plugins/sudoers/sudoers.c:232
-#: plugins/sudoers/sudoers.c:900
+#: plugins/sudoers/sudoers.c:931
 msgid "problem with defaults entries"
 msgstr ""
 
@@ -954,296 +957,301 @@ msgstr ""
 msgid "no valid sudoers sources found, quitting"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:255
+#: plugins/sudoers/sudoers.c:257
 #, c-format
 msgid "unable to execute %s: %s"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:304
+#: plugins/sudoers/sudoers.c:311
 #, c-format
 msgid "sudoers specifies that root is not allowed to sudo"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:311
+#: plugins/sudoers/sudoers.c:318
 #, c-format
 msgid "you are not permitted to use the -C option"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:401
+#: plugins/sudoers/sudoers.c:408
 #, c-format
 msgid "timestamp owner (%s): No such user"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:417
+#: plugins/sudoers/sudoers.c:424
 msgid "no tty"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:418
+#: plugins/sudoers/sudoers.c:425
 #, c-format
 msgid "sorry, you must have a tty to run sudo"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:457
+#: plugins/sudoers/sudoers.c:464
 msgid "No user or host"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:471 plugins/sudoers/sudoers.c:492
-#: plugins/sudoers/sudoers.c:493 plugins/sudoers/sudoers.c:1454
-#: plugins/sudoers/sudoers.c:1455
+#: plugins/sudoers/sudoers.c:478 plugins/sudoers/sudoers.c:499
+#: plugins/sudoers/sudoers.c:500 plugins/sudoers/sudoers.c:1509
+#: plugins/sudoers/sudoers.c:1510
 #, c-format
 msgid "%s: command not found"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:473 plugins/sudoers/sudoers.c:489
+#: plugins/sudoers/sudoers.c:480 plugins/sudoers/sudoers.c:496
 #, c-format
 msgid ""
 "ignoring `%s' found in '.'\n"
 "Use `sudo ./%s' if this is the `%s' you wish to run."
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:478
+#: plugins/sudoers/sudoers.c:485
 msgid "validation failure"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:488
+#: plugins/sudoers/sudoers.c:495
 msgid "command in current directory"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:500
+#: plugins/sudoers/sudoers.c:507
 #, c-format
 msgid "sorry, you are not allowed to preserve the environment"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:883
+#: plugins/sudoers/sudoers.c:657 plugins/sudoers/sudoers.c:664
+#, c-format
+msgid "internal error, runas_groups overflow"
+msgstr ""
+
+#: plugins/sudoers/sudoers.c:914
 #, c-format
 msgid "internal error, set_cmnd() overflow"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:925
+#: plugins/sudoers/sudoers.c:957
 #, c-format
 msgid "fixed mode on %s"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:929
+#: plugins/sudoers/sudoers.c:961
 #, c-format
 msgid "set group on %s"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:932
+#: plugins/sudoers/sudoers.c:964
 #, c-format
 msgid "unable to set group on %s"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:935
+#: plugins/sudoers/sudoers.c:967
 #, c-format
 msgid "unable to fix mode on %s"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:948
+#: plugins/sudoers/sudoers.c:980
 #, c-format
 msgid "%s is not a regular file"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:950
+#: plugins/sudoers/sudoers.c:982
 #, c-format
 msgid "%s is mode 0%o, should be 0%o"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:954
+#: plugins/sudoers/sudoers.c:986
 #, c-format
 msgid "%s is owned by uid %u, should be %u"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:957
+#: plugins/sudoers/sudoers.c:989
 #, c-format
 msgid "%s is owned by gid %u, should be %u"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:1001
+#: plugins/sudoers/sudoers.c:1038
 #, c-format
 msgid "only root can use `-c %s'"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:1011
+#: plugins/sudoers/sudoers.c:1049
 #, c-format
 msgid "unknown login class: %s"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:1045
+#: plugins/sudoers/sudoers.c:1077
 #, c-format
 msgid "unable to resolve host %s"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:1095 plugins/sudoers/testsudoers.c:351
+#: plugins/sudoers/sudoers.c:1129 plugins/sudoers/testsudoers.c:380
 #, c-format
 msgid "unknown group: %s"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:1139
+#: plugins/sudoers/sudoers.c:1178
 #, c-format
 msgid "Sudoers policy plugin version %s\n"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:1141
+#: plugins/sudoers/sudoers.c:1180
 #, c-format
 msgid "Sudoers file grammar version %d\n"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:1145
+#: plugins/sudoers/sudoers.c:1184
 #, c-format
 msgid ""
 "\n"
 "Sudoers path: %s\n"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:1148
+#: plugins/sudoers/sudoers.c:1187
 #, c-format
 msgid "nsswitch path: %s\n"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:1150
+#: plugins/sudoers/sudoers.c:1189
 #, c-format
 msgid "ldap.conf path: %s\n"
 msgstr ""
 
-#: plugins/sudoers/sudoers.c:1151
+#: plugins/sudoers/sudoers.c:1190
 #, c-format
 msgid "ldap.secret path: %s\n"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:265
+#: plugins/sudoers/sudoreplay.c:286
 #, c-format
 msgid "invalid filter option: %s"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:278
+#: plugins/sudoers/sudoreplay.c:299
 #, c-format
 msgid "invalid max wait: %s"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:284
+#: plugins/sudoers/sudoreplay.c:305
 #, c-format
 msgid "invalid speed factor: %s"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:287 plugins/sudoers/visudo.c:174
+#: plugins/sudoers/sudoreplay.c:308 plugins/sudoers/visudo.c:187
 #, c-format
 msgid "%s version %s\n"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:310
+#: plugins/sudoers/sudoreplay.c:333
 #, c-format
 msgid "%s/%.2s/%.2s/%.2s/timing: %s"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:316
+#: plugins/sudoers/sudoreplay.c:339
 #, c-format
 msgid "%s/%s/timing: %s"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:341
+#: plugins/sudoers/sudoreplay.c:364
 #, c-format
 msgid "invalid log file %s"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:343
+#: plugins/sudoers/sudoreplay.c:366
 #, c-format
 msgid "Replaying sudo session: %s"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:369
+#: plugins/sudoers/sudoreplay.c:392
 #, c-format
 msgid "unable to set tty to raw mode"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:383
+#: plugins/sudoers/sudoreplay.c:406
 #, c-format
 msgid "invalid timing file line: %s"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:425
+#: plugins/sudoers/sudoreplay.c:448
 #, c-format
 msgid "writing to standard output"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:455
+#: plugins/sudoers/sudoreplay.c:480
 #, c-format
 msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:503 plugins/sudoers/sudoreplay.c:528
+#: plugins/sudoers/sudoreplay.c:529 plugins/sudoers/sudoreplay.c:554
 #, c-format
 msgid "ambiguous expression \"%s\""
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:545
+#: plugins/sudoers/sudoreplay.c:571
 #, c-format
 msgid "too many parenthesized expressions, max %d"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:556
+#: plugins/sudoers/sudoreplay.c:582
 #, c-format
 msgid "unmatched ')' in expression"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:562
+#: plugins/sudoers/sudoreplay.c:588
 #, c-format
 msgid "unknown search term \"%s\""
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:576
+#: plugins/sudoers/sudoreplay.c:602
 #, c-format
 msgid "%s requires an argument"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:580
+#: plugins/sudoers/sudoreplay.c:606
 #, c-format
 msgid "invalid regular expression: %s"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:612
 #, c-format
 msgid "could not parse date \"%s\""
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:599
+#: plugins/sudoers/sudoreplay.c:625
 #, c-format
 msgid "unmatched '(' in expression"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:601
+#: plugins/sudoers/sudoreplay.c:627
 #, c-format
 msgid "illegal trailing \"or\""
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:603
+#: plugins/sudoers/sudoreplay.c:629
 #, c-format
 msgid "illegal trailing \"!\""
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:819
+#: plugins/sudoers/sudoreplay.c:851
 #, c-format
 msgid "invalid regex: %s"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:941
+#: plugins/sudoers/sudoreplay.c:976
 #, c-format
 msgid "usage: %s [-h] [-d directory] [-m max_wait] [-s speed_factor] ID\n"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:944
+#: plugins/sudoers/sudoreplay.c:979
 #, c-format
 msgid "usage: %s [-h] [-d directory] -l [search expression]\n"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:953
+#: plugins/sudoers/sudoreplay.c:988
 #, c-format
 msgid ""
 "%s - replay sudo session logs\n"
 "\n"
 msgstr ""
 
-#: plugins/sudoers/sudoreplay.c:955
+#: plugins/sudoers/sudoreplay.c:990
 msgid ""
 "\n"
 "Options:\n"
@@ -1256,131 +1264,131 @@ msgid ""
 "  -V               display version information and exit"
 msgstr ""
 
-#: plugins/sudoers/testsudoers.c:230
+#: plugins/sudoers/testsudoers.c:246
 #, c-format
 msgid "internal error, init_vars() overflow"
 msgstr ""
 
-#: plugins/sudoers/testsudoers.c:309
+#: plugins/sudoers/testsudoers.c:331
 msgid "\thost  unmatched"
 msgstr ""
 
-#: plugins/sudoers/testsudoers.c:312
+#: plugins/sudoers/testsudoers.c:334
 msgid ""
 "\n"
 "Command allowed"
 msgstr ""
 
-#: plugins/sudoers/testsudoers.c:313
+#: plugins/sudoers/testsudoers.c:335
 msgid ""
 "\n"
 "Command denied"
 msgstr ""
 
-#: plugins/sudoers/testsudoers.c:313
+#: plugins/sudoers/testsudoers.c:335
 msgid ""
 "\n"
 "Command unmatched"
 msgstr ""
 
-#: toke.l:667 toke.l:793 toke.l:818 toke.l:904 plugins/sudoers/toke_util.c:111
-#: plugins/sudoers/toke_util.c:163 plugins/sudoers/toke_util.c:202
+#: toke.l:672 toke.l:802 toke.l:827 toke.l:923 plugins/sudoers/toke_util.c:113
+#: plugins/sudoers/toke_util.c:167 plugins/sudoers/toke_util.c:207
 msgid "unable to allocate memory"
 msgstr ""
 
-#: toke.l:786
+#: toke.l:795
 msgid "too many levels of includes"
 msgstr ""
 
-#: plugins/sudoers/toke_util.c:213
+#: plugins/sudoers/toke_util.c:218
 msgid "fill_args: buffer overflow"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:175
+#: plugins/sudoers/visudo.c:188
 #, c-format
 msgid "%s grammar version %d\n"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:208 plugins/sudoers/auth/rfc1938.c:103
+#: plugins/sudoers/visudo.c:221 plugins/sudoers/auth/rfc1938.c:104
 #, c-format
 msgid "you do not exist in the %s database"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:238 plugins/sudoers/visudo.c:518
+#: plugins/sudoers/visudo.c:253 plugins/sudoers/visudo.c:539
 #, c-format
 msgid "press return to edit %s: "
 msgstr ""
 
-#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:326
+#: plugins/sudoers/visudo.c:336 plugins/sudoers/visudo.c:342
 #, c-format
 msgid "write error"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:408
+#: plugins/sudoers/visudo.c:424
 #, c-format
 msgid "unable to stat temporary file (%s), %s unchanged"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:413
+#: plugins/sudoers/visudo.c:429
 #, c-format
 msgid "zero length temporary file (%s), %s unchanged"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:419
+#: plugins/sudoers/visudo.c:435
 #, c-format
 msgid "editor (%s) failed, %s unchanged"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:442
+#: plugins/sudoers/visudo.c:458
 #, c-format
 msgid "%s unchanged"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:466
+#: plugins/sudoers/visudo.c:484
 #, c-format
 msgid "unable to re-open temporary file (%s), %s unchanged."
 msgstr ""
 
-#: plugins/sudoers/visudo.c:476
+#: plugins/sudoers/visudo.c:494
 #, c-format
 msgid "unabled to parse temporary file (%s), unknown error"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:511
+#: plugins/sudoers/visudo.c:532
 #, c-format
 msgid "internal error, unable to find %s in list!"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:546 plugins/sudoers/visudo.c:555
+#: plugins/sudoers/visudo.c:584 plugins/sudoers/visudo.c:593
 #, c-format
 msgid "unable to set (uid, gid) of %s to (%u, %u)"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:550 plugins/sudoers/visudo.c:560
+#: plugins/sudoers/visudo.c:588 plugins/sudoers/visudo.c:598
 #, c-format
 msgid "unable to change mode of %s to 0%o"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:577
+#: plugins/sudoers/visudo.c:615
 #, c-format
 msgid "%s and %s not on the same file system, using mv to rename"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:591
+#: plugins/sudoers/visudo.c:629
 #, c-format
 msgid "command failed: '%s %s %s', %s unchanged"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:601
+#: plugins/sudoers/visudo.c:639
 #, c-format
 msgid "error renaming %s, %s unchanged"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:661
+#: plugins/sudoers/visudo.c:702
 msgid "What now? "
 msgstr ""
 
-#: plugins/sudoers/visudo.c:675
+#: plugins/sudoers/visudo.c:716
 msgid ""
 "Options are:\n"
 "  (e)dit sudoers file again\n"
@@ -1388,99 +1396,99 @@ msgid ""
 "  (Q)uit and save changes to sudoers file (DANGER!)\n"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:712
+#: plugins/sudoers/visudo.c:757
 #, c-format
 msgid "unable to execute %s"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:719
+#: plugins/sudoers/visudo.c:764
 #, c-format
 msgid "unable to run %s"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:750
+#: plugins/sudoers/visudo.c:796
 #, c-format
 msgid "failed to parse %s file, unknown error"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:762
+#: plugins/sudoers/visudo.c:808
 #, c-format
 msgid "parse error in %s near line %d\n"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:765
+#: plugins/sudoers/visudo.c:811
 #, c-format
 msgid "parse error in %s\n"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:767
+#: plugins/sudoers/visudo.c:814 plugins/sudoers/visudo.c:816
 #, c-format
 msgid "%s: parsed OK\n"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:776
+#: plugins/sudoers/visudo.c:826
 #, c-format
 msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:783
+#: plugins/sudoers/visudo.c:833
 #, c-format
 msgid "%s: bad permissions, should be mode 0%o\n"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:822
+#: plugins/sudoers/visudo.c:880
 #, c-format
 msgid "%s busy, try again later"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:865
+#: plugins/sudoers/visudo.c:924
 #, c-format
 msgid "specified editor (%s) doesn't exist"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:888
+#: plugins/sudoers/visudo.c:947
 #, c-format
 msgid "unable to stat editor (%s)"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:936
+#: plugins/sudoers/visudo.c:995
 #, c-format
 msgid "no editor found (editor path = %s)"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:1025
+#: plugins/sudoers/visudo.c:1089
 #, c-format
 msgid "Error: cycle in %s_Alias `%s'"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:1026
+#: plugins/sudoers/visudo.c:1090
 #, c-format
 msgid "Warning: cycle in %s_Alias `%s'"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:1029
+#: plugins/sudoers/visudo.c:1093
 #, c-format
 msgid "Error: %s_Alias `%s' referenced but not defined"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:1030
+#: plugins/sudoers/visudo.c:1094
 #, c-format
 msgid "Warning: %s_Alias `%s' referenced but not defined"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:1167
+#: plugins/sudoers/visudo.c:1229
 #, c-format
 msgid "%s: unused %s_Alias %s"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:1224
+#: plugins/sudoers/visudo.c:1286
 #, c-format
 msgid ""
 "%s - safely edit the sudoers file\n"
 "\n"
 msgstr ""
 
-#: plugins/sudoers/visudo.c:1226
+#: plugins/sudoers/visudo.c:1288
 msgid ""
 "\n"
 "Options:\n"
@@ -1492,171 +1500,176 @@ msgid ""
 "  -V          display version information and exit"
 msgstr ""
 
-#: plugins/sudoers/auth/bsdauth.c:64
+#: plugins/sudoers/auth/bsdauth.c:78
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr ""
+
+#: plugins/sudoers/auth/bsdauth.c:84
 msgid "unable to begin bsd authentication"
 msgstr ""
 
-#: plugins/sudoers/auth/bsdauth.c:71
+#: plugins/sudoers/auth/bsdauth.c:92
 msgid "invalid authentication type"
 msgstr ""
 
-#: plugins/sudoers/auth/bsdauth.c:79
+#: plugins/sudoers/auth/bsdauth.c:101
 msgid "unable to setup authentication"
 msgstr ""
 
-#: plugins/sudoers/auth/fwtk.c:59
+#: plugins/sudoers/auth/fwtk.c:60
 #, c-format
 msgid "unable to read fwtk config"
 msgstr ""
 
-#: plugins/sudoers/auth/fwtk.c:64
+#: plugins/sudoers/auth/fwtk.c:65
 #, c-format
 msgid "unable to connect to authentication server"
 msgstr ""
 
-#: plugins/sudoers/auth/fwtk.c:70 plugins/sudoers/auth/fwtk.c:93
-#: plugins/sudoers/auth/fwtk.c:126
+#: plugins/sudoers/auth/fwtk.c:71 plugins/sudoers/auth/fwtk.c:95
+#: plugins/sudoers/auth/fwtk.c:128
 #, c-format
 msgid "lost connection to authentication server"
 msgstr ""
 
-#: plugins/sudoers/auth/fwtk.c:74
+#: plugins/sudoers/auth/fwtk.c:75
 #, c-format
 msgid ""
 "authentication server error:\n"
 "%s"
 msgstr ""
 
-#: plugins/sudoers/auth/kerb5.c:110
+#: plugins/sudoers/auth/kerb5.c:117
 #, c-format
 msgid "%s: unable to unparse princ ('%s'): %s"
 msgstr ""
 
-#: plugins/sudoers/auth/kerb5.c:149
+#: plugins/sudoers/auth/kerb5.c:160
 #, c-format
 msgid "%s: unable to parse '%s': %s"
 msgstr ""
 
-#: plugins/sudoers/auth/kerb5.c:160
+#: plugins/sudoers/auth/kerb5.c:170
 #, c-format
 msgid "%s: unable to resolve ccache: %s"
 msgstr ""
 
-#: plugins/sudoers/auth/kerb5.c:204
+#: plugins/sudoers/auth/kerb5.c:218
 #, c-format
 msgid "%s: unable to allocate options: %s"
 msgstr ""
 
-#: plugins/sudoers/auth/kerb5.c:220
+#: plugins/sudoers/auth/kerb5.c:234
 #, c-format
 msgid "%s: unable to get credentials: %s"
 msgstr ""
 
-#: plugins/sudoers/auth/kerb5.c:233
+#: plugins/sudoers/auth/kerb5.c:247
 #, c-format
 msgid "%s: unable to initialize ccache: %s"
 msgstr ""
 
-#: plugins/sudoers/auth/kerb5.c:237
+#: plugins/sudoers/auth/kerb5.c:251
 #, c-format
 msgid "%s: unable to store cred in ccache: %s"
 msgstr ""
 
-#: plugins/sudoers/auth/kerb5.c:300
+#: plugins/sudoers/auth/kerb5.c:316
 #, c-format
 msgid "%s: unable to get host principal: %s"
 msgstr ""
 
-#: plugins/sudoers/auth/kerb5.c:315
+#: plugins/sudoers/auth/kerb5.c:331
 #, c-format
 msgid "%s: Cannot verify TGT! Possible attack!: %s"
 msgstr ""
 
-#: plugins/sudoers/auth/pam.c:99
+#: plugins/sudoers/auth/pam.c:100
 msgid "unable to initialize PAM"
 msgstr ""
 
-#: plugins/sudoers/auth/pam.c:142
+#: plugins/sudoers/auth/pam.c:144
 msgid "account validation failure, is your account locked?"
 msgstr ""
 
-#: plugins/sudoers/auth/pam.c:146
+#: plugins/sudoers/auth/pam.c:148
 msgid "Account or password is expired, reset your password and try again"
 msgstr ""
 
-#: plugins/sudoers/auth/pam.c:153
+#: plugins/sudoers/auth/pam.c:155
 #, c-format
 msgid "pam_chauthtok: %s"
 msgstr ""
 
-#: plugins/sudoers/auth/pam.c:157
+#: plugins/sudoers/auth/pam.c:159
 msgid "Password expired, contact your system administrator"
 msgstr ""
 
-#: plugins/sudoers/auth/pam.c:161
+#: plugins/sudoers/auth/pam.c:163
 msgid ""
 "Account expired or PAM config lacks an \"account\" section for sudo, contact "
 "your system administrator"
 msgstr ""
 
-#: plugins/sudoers/auth/pam.c:176
+#: plugins/sudoers/auth/pam.c:178
 #, c-format
 msgid "pam_authenticate: %s"
 msgstr ""
 
-#: plugins/sudoers/auth/pam.c:300
+#: plugins/sudoers/auth/pam.c:306
 msgid "Password: "
 msgstr ""
 
-#: plugins/sudoers/auth/pam.c:301
+#: plugins/sudoers/auth/pam.c:307
 msgid "Password:"
 msgstr ""
 
-#: plugins/sudoers/auth/securid.c:82 plugins/sudoers/auth/securid5.c:105
+#: plugins/sudoers/auth/securid5.c:81
 #, c-format
-msgid "unable to contact the SecurID server"
+msgid "failed to initialise the ACE API library"
 msgstr ""
 
-#: plugins/sudoers/auth/securid5.c:80
+#: plugins/sudoers/auth/securid5.c:107
 #, c-format
-msgid "failed to initialise the ACE API library"
+msgid "unable to contact the SecurID server"
 msgstr ""
 
-#: plugins/sudoers/auth/securid5.c:114
+#: plugins/sudoers/auth/securid5.c:116
 #, c-format
 msgid "User ID locked for SecurID Authentication"
 msgstr ""
 
-#: plugins/sudoers/auth/securid5.c:118 plugins/sudoers/auth/securid5.c:168
+#: plugins/sudoers/auth/securid5.c:120 plugins/sudoers/auth/securid5.c:171
 #, c-format
 msgid "invalid username length for SecurID"
 msgstr ""
 
-#: plugins/sudoers/auth/securid5.c:122 plugins/sudoers/auth/securid5.c:173
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:176
 #, c-format
 msgid "invalid Authentication Handle for SecurID"
 msgstr ""
 
-#: plugins/sudoers/auth/securid5.c:126
+#: plugins/sudoers/auth/securid5.c:128
 #, c-format
 msgid "SecurID communication failed"
 msgstr ""
 
-#: plugins/sudoers/auth/securid5.c:130 plugins/sudoers/auth/securid5.c:212
+#: plugins/sudoers/auth/securid5.c:132 plugins/sudoers/auth/securid5.c:215
 #, c-format
 msgid "unknown SecurID error"
 msgstr ""
 
-#: plugins/sudoers/auth/securid5.c:163
+#: plugins/sudoers/auth/securid5.c:166
 #, c-format
 msgid "invalid passcode length for SecurID"
 msgstr ""
 
-#: plugins/sudoers/auth/sia.c:106
+#: plugins/sudoers/auth/sia.c:109
 msgid "unable to initialize SIA session"
 msgstr ""
 
-#: plugins/sudoers/auth/sudo_auth.c:119
+#: plugins/sudoers/auth/sudo_auth.c:117
 msgid ""
 "Invalid authentication methods compiled into sudo!  You may mix standalone "
 "and non-standalone authentication."
@@ -1675,6 +1688,6 @@ msgid_plural "%d incorrect password attempts"
 msgstr[0] ""
 msgstr[1] ""
 
-#: plugins/sudoers/auth/sudo_auth.c:367
+#: plugins/sudoers/auth/sudo_auth.c:374
 msgid "Authentication methods:"
 msgstr ""
index f27723501fd6ec5b8ef43d001b03c7fd5d432653..1f9519bc78c119d4b71ac8a1a3daaf288d9e4bf7 100644 (file)
Binary files a/plugins/sudoers/po/uk.mo and b/plugins/sudoers/po/uk.mo differ
index 4fe0c35057127a003702f8abcaebe2e562b29451..1de56b1a762f255d15d0cc91fd0fd4ad65e4711c 100644 (file)
@@ -1,13 +1,13 @@
 # Ukrainian translation for sudoers.
 # This file is put in the public domain.
 #
-# Yuri Chornoivan <yurchor@ukr.net>, 2011.
+# Yuri Chornoivan <yurchor@ukr.net>, 2011, 2012.
 msgid ""
 msgstr ""
-"Project-Id-Version: sudoers 1.8.3rc1\n"
+"Project-Id-Version: sudoers 1.8.4rc1\n"
 "Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
-"POT-Creation-Date: 2011-09-16 16:52-0400\n"
-"PO-Revision-Date: 2011-09-17 12:50+0300\n"
+"POT-Creation-Date: 2012-02-06 15:48-0500\n"
+"PO-Revision-Date: 2012-02-07 23:11+0200\n"
 "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
 "Language-Team: Ukrainian <translation-team-uk@lists.sourceforge.net>\n"
 "Language: \n"
@@ -17,146 +17,146 @@ msgstr ""
 "Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 "X-Generator: Lokalize 1.2\n"
 
-#: plugins/sudoers/alias.c:122
+#: plugins/sudoers/alias.c:125
 #, c-format
 msgid "Alias `%s' already defined"
 msgstr "Замінник «%s» вже визначено"
 
-#: plugins/sudoers/bsm_audit.c:58 plugins/sudoers/bsm_audit.c:61
-#: plugins/sudoers/bsm_audit.c:109 plugins/sudoers/bsm_audit.c:113
-#: plugins/sudoers/bsm_audit.c:163 plugins/sudoers/bsm_audit.c:167
+#: plugins/sudoers/bsm_audit.c:61 plugins/sudoers/bsm_audit.c:64
+#: plugins/sudoers/bsm_audit.c:113 plugins/sudoers/bsm_audit.c:117
+#: plugins/sudoers/bsm_audit.c:169 plugins/sudoers/bsm_audit.c:173
 msgid "getaudit: failed"
 msgstr "getaudit: помилка"
 
-#: plugins/sudoers/bsm_audit.c:87 plugins/sudoers/bsm_audit.c:148
+#: plugins/sudoers/bsm_audit.c:91 plugins/sudoers/bsm_audit.c:154
 msgid "Could not determine audit condition"
 msgstr "Не вдалося визначити умови аудита"
 
-#: plugins/sudoers/bsm_audit.c:98
+#: plugins/sudoers/bsm_audit.c:102
 msgid "getauid failed"
 msgstr "помилка getauid"
 
-#: plugins/sudoers/bsm_audit.c:100 plugins/sudoers/bsm_audit.c:157
+#: plugins/sudoers/bsm_audit.c:104 plugins/sudoers/bsm_audit.c:163
 msgid "au_open: failed"
 msgstr "au_open: помилка"
 
-#: plugins/sudoers/bsm_audit.c:115 plugins/sudoers/bsm_audit.c:169
+#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:175
 msgid "au_to_subject: failed"
 msgstr "au_to_subject: помилка"
 
-#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:173
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:179
 msgid "au_to_exec_args: failed"
 msgstr "au_to_exec_args: помилка"
 
-#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:182
+#: plugins/sudoers/bsm_audit.c:127 plugins/sudoers/bsm_audit.c:188
 msgid "au_to_return32: failed"
 msgstr "au_to_return32: помилка"
 
-#: plugins/sudoers/bsm_audit.c:126 plugins/sudoers/bsm_audit.c:185
+#: plugins/sudoers/bsm_audit.c:130 plugins/sudoers/bsm_audit.c:191
 msgid "unable to commit audit record"
 msgstr "не вдалося надіслати запис аудита"
 
-#: plugins/sudoers/bsm_audit.c:155
+#: plugins/sudoers/bsm_audit.c:161
 msgid "getauid: failed"
 msgstr "getauid: помилка"
 
-#: plugins/sudoers/bsm_audit.c:178
+#: plugins/sudoers/bsm_audit.c:184
 msgid "au_to_text: failed"
 msgstr "au_to_text: помилка"
 
-#: plugins/sudoers/check.c:141
+#: plugins/sudoers/check.c:158
 #, c-format
 msgid "sorry, a password is required to run %s"
 msgstr "вибачте, для виконання %s слід вказати пароль"
 
-#: plugins/sudoers/check.c:225 plugins/sudoers/iolog.c:169
-#: plugins/sudoers/sudoers.c:971 plugins/sudoers/sudoreplay.c:325
-#: plugins/sudoers/sudoreplay.c:334 plugins/sudoers/sudoreplay.c:675
-#: plugins/sudoers/sudoreplay.c:767 plugins/sudoers/visudo.c:744
+#: plugins/sudoers/check.c:249 plugins/sudoers/iolog.c:172
+#: plugins/sudoers/sudoers.c:992 plugins/sudoers/sudoreplay.c:348
+#: plugins/sudoers/sudoreplay.c:357 plugins/sudoers/sudoreplay.c:703
+#: plugins/sudoers/sudoreplay.c:797 plugins/sudoers/visudo.c:790
 #, c-format
 msgid "unable to open %s"
 msgstr "не вдалося відкрити %s"
 
-#: plugins/sudoers/check.c:229 plugins/sudoers/iolog.c:199
+#: plugins/sudoers/check.c:253 plugins/sudoers/iolog.c:202
 #, c-format
 msgid "unable to write to %s"
 msgstr "не вдалося виконати запис до %s"
 
-#: plugins/sudoers/check.c:237 plugins/sudoers/check.c:475
-#: plugins/sudoers/check.c:525 plugins/sudoers/iolog.c:122
-#: plugins/sudoers/iolog.c:153
+#: plugins/sudoers/check.c:261 plugins/sudoers/check.c:506
+#: plugins/sudoers/check.c:556 plugins/sudoers/iolog.c:123
+#: plugins/sudoers/iolog.c:156
 #, c-format
 msgid "unable to mkdir %s"
 msgstr "не вдалося створити каталог %s"
 
-#: plugins/sudoers/check.c:370
+#: plugins/sudoers/check.c:396
 #, c-format
 msgid "internal error, expand_prompt() overflow"
 msgstr "внутрішня помилка, переповнення expand_prompt()"
 
-#: plugins/sudoers/check.c:426
+#: plugins/sudoers/check.c:456
 #, c-format
 msgid "timestamp path too long: %s"
 msgstr "шлях часового штампа є занадто довгим: %s"
 
-#: plugins/sudoers/check.c:454 plugins/sudoers/check.c:498
-#: plugins/sudoers/iolog.c:155
+#: plugins/sudoers/check.c:485 plugins/sudoers/check.c:529
+#: plugins/sudoers/iolog.c:158
 #, c-format
 msgid "%s exists but is not a directory (0%o)"
 msgstr "%s існує, але не є каталогом (0%o)"
 
-#: plugins/sudoers/check.c:457 plugins/sudoers/check.c:501
-#: plugins/sudoers/check.c:546
+#: plugins/sudoers/check.c:488 plugins/sudoers/check.c:532
+#: plugins/sudoers/check.c:577
 #, c-format
 msgid "%s owned by uid %u, should be uid %u"
 msgstr "власником %s є uid %u, має бути uid %u"
 
-#: plugins/sudoers/check.c:462 plugins/sudoers/check.c:506
+#: plugins/sudoers/check.c:493 plugins/sudoers/check.c:537
 #, c-format
 msgid "%s writable by non-owner (0%o), should be mode 0700"
 msgstr "%s доступний до запису невласником (0%o), має бути встановлено режим 0700"
 
-#: plugins/sudoers/check.c:470 plugins/sudoers/check.c:514
-#: plugins/sudoers/check.c:582 plugins/sudoers/sudoers.c:957
-#: plugins/sudoers/visudo.c:304 plugins/sudoers/visudo.c:544
+#: plugins/sudoers/check.c:501 plugins/sudoers/check.c:545
+#: plugins/sudoers/check.c:613 plugins/sudoers/sudoers.c:978
+#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:582
 #, c-format
 msgid "unable to stat %s"
 msgstr "не вдалося виконати stat для %s"
 
-#: plugins/sudoers/check.c:540
+#: plugins/sudoers/check.c:571
 #, c-format
 msgid "%s exists but is not a regular file (0%o)"
 msgstr "%s існує, але не є звичайним файлом (0%o)"
 
-#: plugins/sudoers/check.c:552
+#: plugins/sudoers/check.c:583
 #, c-format
 msgid "%s writable by non-owner (0%o), should be mode 0600"
 msgstr "%s доступний до запису невласником (0%o), має бути встановлено режим 0600"
 
-#: plugins/sudoers/check.c:606
+#: plugins/sudoers/check.c:637
 #, c-format
 msgid "timestamp too far in the future: %20.20s"
 msgstr "занадто далекий часовий штамп у майбутньому: %20.20s"
 
-#: plugins/sudoers/check.c:652
+#: plugins/sudoers/check.c:684
 #, c-format
 msgid "unable to remove %s (%s), will reset to the epoch"
 msgstr "на вдалося вилучити %s (%s), час буде змінено відповідно до епохи"
 
-#: plugins/sudoers/check.c:660
+#: plugins/sudoers/check.c:692
 #, c-format
 msgid "unable to reset %s to the epoch"
 msgstr "не вдалося встановити для %s час епохи"
 
-#: plugins/sudoers/check.c:714 plugins/sudoers/check.c:720
+#: plugins/sudoers/check.c:752 plugins/sudoers/check.c:758
+#: plugins/sudoers/sudoers.c:829 plugins/sudoers/sudoers.c:833
 #, c-format
 msgid "unknown uid: %u"
 msgstr "невідоме значення uid: %u"
 
-#: plugins/sudoers/check.c:717 plugins/sudoers/sudoers.c:748
-#: plugins/sudoers/sudoers.c:814 plugins/sudoers/sudoers.c:815
-#: plugins/sudoers/sudoers.c:1088 plugins/sudoers/testsudoers.c:202
-#: plugins/sudoers/testsudoers.c:337
+#: plugins/sudoers/check.c:755 plugins/sudoers/sudoers.c:770
+#: plugins/sudoers/sudoers.c:1108 plugins/sudoers/testsudoers.c:218
+#: plugins/sudoers/testsudoers.c:362
 #, c-format
 msgid "unknown user: %s"
 msgstr "невідомий користувач: %s"
@@ -403,298 +403,296 @@ msgid "When to require a password for 'verify' pseudocommand: %s"
 msgstr "Умови запиту пароля для псевдокоманди «verify»: %s"
 
 #: plugins/sudoers/def_data.c:243
-msgid "Preload the dummy exec functions contained in 'noexec_file'"
-msgstr "Попередньо завантажувати фіктивні функції виконання з «noexec_file»"
+msgid "Preload the dummy exec functions contained in \"_PATH_SUDO_NOEXEC"
+msgstr "Попередньо завантажувати фіктивні функції виконання з «_PATH_SUDO_NOEXEC"
 
 #: plugins/sudoers/def_data.c:247
-#, c-format
-msgid "File containing dummy exec functions: %s"
-msgstr "Файл, що містить фіктивні функції виконання: %s"
-
-#: plugins/sudoers/def_data.c:251
 msgid "If LDAP directory is up, do we ignore local sudoers file"
 msgstr "Чи слід ігнорувати локальний файл sudoers, якщо є доступ до каталогу LDAP"
 
-#: plugins/sudoers/def_data.c:255
+#: plugins/sudoers/def_data.c:251
 #, c-format
 msgid "File descriptors >= %d will be closed before executing a command"
 msgstr "Дескриптори файлів >= %d буде закрито перед виконанням команди"
 
-#: plugins/sudoers/def_data.c:259
+#: plugins/sudoers/def_data.c:255
 msgid "If set, users may override the value of `closefrom' with the -C option"
 msgstr "Якщо встановлено, користувачі можуть перевизначати значення «closefrom» за допомогою параметра -C"
 
-#: plugins/sudoers/def_data.c:263
+#: plugins/sudoers/def_data.c:259
 msgid "Allow users to set arbitrary environment variables"
 msgstr "Дозволити користувачам встановлювати значення довільних змінних середовища"
 
-#: plugins/sudoers/def_data.c:267
+#: plugins/sudoers/def_data.c:263
 msgid "Reset the environment to a default set of variables"
 msgstr "Відновити типовий набір змінних середовища"
 
-#: plugins/sudoers/def_data.c:271
+#: plugins/sudoers/def_data.c:267
 msgid "Environment variables to check for sanity:"
 msgstr "Змінні середовища, коректність яких слід перевіряти:"
 
-#: plugins/sudoers/def_data.c:275
+#: plugins/sudoers/def_data.c:271
 msgid "Environment variables to remove:"
 msgstr "Змінні середовища, які слід вилучити:"
 
-#: plugins/sudoers/def_data.c:279
+#: plugins/sudoers/def_data.c:275
 msgid "Environment variables to preserve:"
 msgstr "Змінні середовища, які слід зберегти:"
 
-#: plugins/sudoers/def_data.c:283
+#: plugins/sudoers/def_data.c:279
 #, c-format
 msgid "SELinux role to use in the new security context: %s"
 msgstr "Роль SELinux, яку слід використати у новому контексті захисту: %s"
 
-#: plugins/sudoers/def_data.c:287
+#: plugins/sudoers/def_data.c:283
 #, c-format
 msgid "SELinux type to use in the new security context: %s"
 msgstr "Тип SELinux, який слід використати у новому контексті захисту: %s"
 
-#: plugins/sudoers/def_data.c:291
+#: plugins/sudoers/def_data.c:287
 #, c-format
 msgid "Path to the sudo-specific environment file: %s"
 msgstr "Шлях до специфічного для sudo файла середовища: %s"
 
-#: plugins/sudoers/def_data.c:295
+#: plugins/sudoers/def_data.c:291
 #, c-format
 msgid "Locale to use while parsing sudoers: %s"
 msgstr "Локаль, яку слід використати під час обробки sudoers: %s"
 
-#: plugins/sudoers/def_data.c:299
-msgid "Allow sudo to prompt for a password even if it would be visisble"
-msgstr "Ð\94озволиÑ\82и sudo Ð½Ð°Ð´Ñ\81илаÑ\82и Ð·Ð°Ð¿Ð¸Ñ\82 Ñ\89одо Ð¿Ð°Ñ\80олÑ\8f, Ð½Ð°Ð²Ñ\96Ñ\82Ñ\8c Ñ\8fкÑ\89о Ñ\86ей Ð·Ð°Ð¿Ð¸Ñ\82 Ð½Ðµ Ð¼Ð¾Ð¶Ð½Ð° Ð±Ñ\83де Ð¿Ð¾Ð±Ð°Ñ\87иÑ\82и"
+#: plugins/sudoers/def_data.c:295
+msgid "Allow sudo to prompt for a password even if it would be visible"
+msgstr "Ð\94озволиÑ\82и sudo Ð½Ð°Ð´Ñ\81илаÑ\82и Ð·Ð°Ð¿Ð¸Ñ\82 Ñ\89одо Ð¿Ð°Ñ\80олÑ\8f, Ð½Ð°Ð²Ñ\96Ñ\82Ñ\8c Ñ\8fкÑ\89о Ñ\86ей Ð¿Ð°Ñ\80олÑ\8c Ð±Ñ\83де Ð²Ð¸Ð´Ð¸Ð¼Ð¸Ð¼"
 
-#: plugins/sudoers/def_data.c:303
+#: plugins/sudoers/def_data.c:299
 msgid "Provide visual feedback at the password prompt when there is user input"
 msgstr "Супроводжувати введення користувачем пароля показом замінників символів пароля"
 
-#: plugins/sudoers/def_data.c:307
+#: plugins/sudoers/def_data.c:303
 msgid "Use faster globbing that is less accurate but does not access the filesystem"
 msgstr "Швидше встановлення відповідності, менш точне, але без доступу до файлової системи"
 
-#: plugins/sudoers/def_data.c:311
+#: plugins/sudoers/def_data.c:307
 msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
 msgstr "Значення umask, вказане у sudoers, перевизначатиме значення користувача, навіть якщо це значення відкриває ширший доступ"
 
-#: plugins/sudoers/def_data.c:315
+#: plugins/sudoers/def_data.c:311
 msgid "Log user's input for the command being run"
 msgstr "Записувати дані, вказані користувачем під час виконання команди"
 
-#: plugins/sudoers/def_data.c:319
+#: plugins/sudoers/def_data.c:315
 msgid "Log the output of the command being run"
 msgstr "Записувати дані, виведені командою під час виконання"
 
-#: plugins/sudoers/def_data.c:323
+#: plugins/sudoers/def_data.c:319
 msgid "Compress I/O logs using zlib"
 msgstr "Стискати журнали за допомогою zlib"
 
-#: plugins/sudoers/def_data.c:327
+#: plugins/sudoers/def_data.c:323
 msgid "Always run commands in a pseudo-tty"
 msgstr "Завжди запускати команди у псевдо-tty"
 
+#: plugins/sudoers/def_data.c:327
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "Додаток для підтримки не-Unix груп: %s"
+
 #: plugins/sudoers/def_data.c:331
-msgid "Plugin for non-Unix group support"
-msgstr "Додаток для підтримки не-Unix груп"
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "Каталог, у якому слід зберігати журнали введення/виведення: %s"
 
 #: plugins/sudoers/def_data.c:335
-msgid "Directory in which to store input/output logs"
-msgstr "Каталог, у якому слід зберігати журнали введення/виведення"
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "Файл, у якому слід зберігати журнал введення/виведення даних: %s"
 
 #: plugins/sudoers/def_data.c:339
-msgid "File in which to store the input/output log"
-msgstr "Файл, у якому слід зберігати журнал введення/виведення даних"
-
-#: plugins/sudoers/def_data.c:343
 msgid "Add an entry to the utmp/utmpx file when allocating a pty"
 msgstr "Додати запис до файла utmp/utmpx під час розміщення pty"
 
-#: plugins/sudoers/def_data.c:347
+#: plugins/sudoers/def_data.c:343
 msgid "Set the user in utmp to the runas user, not the invoking user"
 msgstr "Встановити користувача у utmp у значення користувача, від імені якого виконується команда"
 
-#: plugins/sudoers/defaults.c:205
+#: plugins/sudoers/defaults.c:208
 #, c-format
 msgid "unknown defaults entry `%s'"
 msgstr "невідомий запис типових параметрів «%s»"
 
-#: plugins/sudoers/defaults.c:213 plugins/sudoers/defaults.c:223
-#: plugins/sudoers/defaults.c:243 plugins/sudoers/defaults.c:256
-#: plugins/sudoers/defaults.c:269 plugins/sudoers/defaults.c:282
-#: plugins/sudoers/defaults.c:295 plugins/sudoers/defaults.c:315
-#: plugins/sudoers/defaults.c:325
+#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
+#: plugins/sudoers/defaults.c:246 plugins/sudoers/defaults.c:259
+#: plugins/sudoers/defaults.c:272 plugins/sudoers/defaults.c:285
+#: plugins/sudoers/defaults.c:298 plugins/sudoers/defaults.c:318
+#: plugins/sudoers/defaults.c:328
 #, c-format
 msgid "value `%s' is invalid for option `%s'"
 msgstr "значення «%s» є некоректним для параметра «%s»"
 
-#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
-#: plugins/sudoers/defaults.c:234 plugins/sudoers/defaults.c:251
-#: plugins/sudoers/defaults.c:264 plugins/sudoers/defaults.c:277
-#: plugins/sudoers/defaults.c:290 plugins/sudoers/defaults.c:310
-#: plugins/sudoers/defaults.c:321
+#: plugins/sudoers/defaults.c:219 plugins/sudoers/defaults.c:229
+#: plugins/sudoers/defaults.c:237 plugins/sudoers/defaults.c:254
+#: plugins/sudoers/defaults.c:267 plugins/sudoers/defaults.c:280
+#: plugins/sudoers/defaults.c:293 plugins/sudoers/defaults.c:313
+#: plugins/sudoers/defaults.c:324
 #, c-format
 msgid "no value specified for `%s'"
 msgstr "не вказано значення для «%s»"
 
-#: plugins/sudoers/defaults.c:239
+#: plugins/sudoers/defaults.c:242
 #, c-format
 msgid "values for `%s' must start with a '/'"
 msgstr "значення для «%s» має починатися з «/»"
 
-#: plugins/sudoers/defaults.c:301
+#: plugins/sudoers/defaults.c:304
 #, c-format
 msgid "option `%s' does not take a value"
 msgstr "параметру «%s» не потрібно передавати значення"
 
-#: plugins/sudoers/env.c:259
+#: plugins/sudoers/env.c:258
 #, c-format
 msgid "internal error, sudo_setenv() overflow"
 msgstr "внутрішня помилка, переповнення sudo_setenv()"
 
-#: plugins/sudoers/env.c:289
+#: plugins/sudoers/env.c:291
 #, c-format
 msgid "sudo_putenv: corrupted envp, length mismatch"
 msgstr "sudo_putenv: помилкове значення envp, невідповідність довжин"
 
-#: plugins/sudoers/env.c:698
+#: plugins/sudoers/env.c:710
 #, c-format
 msgid "sorry, you are not allowed to set the following environment variables: %s"
 msgstr "вибачте, вам не дозволено встановлювати такі змінні середовища: %s"
 
-#: plugins/sudoers/find_path.c:68 plugins/sudoers/find_path.c:107
-#: plugins/sudoers/find_path.c:122 plugins/sudoers/iolog.c:124
-#: plugins/sudoers/sudoers.c:903 toke.l:663 toke.l:814
+#: plugins/sudoers/find_path.c:69 plugins/sudoers/find_path.c:108
+#: plugins/sudoers/find_path.c:123 plugins/sudoers/iolog.c:125
+#: plugins/sudoers/sudoers.c:923 toke.l:668 toke.l:823
 #, c-format
 msgid "%s: %s"
 msgstr "%s: %s"
 
-#: gram.y:103
+#: gram.y:110
 #, c-format
 msgid ">>> %s: %s near line %d <<<"
 msgstr ">>> %s: %s поблизу рядка %d <<<"
 
-#: plugins/sudoers/group_plugin.c:90
+#: plugins/sudoers/group_plugin.c:91
 #, c-format
 msgid "%s%s: %s"
 msgstr "%s%s: %s"
 
-#: plugins/sudoers/group_plugin.c:102
+#: plugins/sudoers/group_plugin.c:103
 #, c-format
 msgid "%s must be owned by uid %d"
 msgstr "%s має належати користувачеві з uid %d"
 
-#: plugins/sudoers/group_plugin.c:106
+#: plugins/sudoers/group_plugin.c:107
 #, c-format
 msgid "%s must only be writable by owner"
 msgstr "%s має бути доступним до запису лише для власника"
 
-#: plugins/sudoers/group_plugin.c:113
+#: plugins/sudoers/group_plugin.c:114
 #, c-format
 msgid "unable to dlopen %s: %s"
 msgstr "не вдалося виконати dlopen для %s: %s"
 
-#: plugins/sudoers/group_plugin.c:118
+#: plugins/sudoers/group_plugin.c:119
 #, c-format
 msgid "unable to find symbol \"group_plugin\" in %s"
 msgstr "не вдалося знайти символ «group_plugin» у %s"
 
-#: plugins/sudoers/group_plugin.c:123
+#: plugins/sudoers/group_plugin.c:124
 #, c-format
 msgid "%s: incompatible group plugin major version %d, expected %d"
 msgstr "%s: несумісна основна версія додатка обробки груп %d, мало бути — %d"
 
-#: plugins/sudoers/interfaces.c:109
+#: plugins/sudoers/interfaces.c:112
 msgid "Local IP address and netmask pairs:\n"
 msgstr "Пари локальних IP-адрес і масок мережі:\n"
 
-#: plugins/sudoers/iolog.c:176 plugins/sudoers/sudoers.c:978
+#: plugins/sudoers/iolog.c:179 plugins/sudoers/sudoers.c:999
 #, c-format
 msgid "unable to read %s"
 msgstr "не вдалося прочитати %s"
 
-#: plugins/sudoers/iolog.c:179
+#: plugins/sudoers/iolog.c:182
 #, c-format
 msgid "invalid sequence number %s"
 msgstr "некоректний номер у послідовності %s"
 
-#: plugins/sudoers/iolog.c:225 plugins/sudoers/iolog.c:228
-#: plugins/sudoers/iolog.c:478 plugins/sudoers/iolog.c:483
-#: plugins/sudoers/iolog.c:489 plugins/sudoers/iolog.c:497
-#: plugins/sudoers/iolog.c:505 plugins/sudoers/iolog.c:513
-#: plugins/sudoers/iolog.c:521
+#: plugins/sudoers/iolog.c:231 plugins/sudoers/iolog.c:234
+#: plugins/sudoers/iolog.c:499 plugins/sudoers/iolog.c:504
+#: plugins/sudoers/iolog.c:510 plugins/sudoers/iolog.c:518
+#: plugins/sudoers/iolog.c:526 plugins/sudoers/iolog.c:534
+#: plugins/sudoers/iolog.c:542
 #, c-format
 msgid "unable to create %s"
 msgstr "не вдалося створити %s"
 
-#: plugins/sudoers/iolog_path.c:247 plugins/sudoers/sudoers.c:357
+#: plugins/sudoers/iolog_path.c:256 plugins/sudoers/sudoers.c:362
 #, c-format
 msgid "unable to set locale to \"%s\", using \"C\""
 msgstr "не вдалося встановити локаль у значення «%s», використовуємо локаль «C»"
 
-#: plugins/sudoers/ldap.c:368
+#: plugins/sudoers/ldap.c:374
 #, c-format
 msgid "sudo_ldap_conf_add_ports: port too large"
 msgstr "sudo_ldap_conf_add_ports: занадто великий номер порту"
 
-#: plugins/sudoers/ldap.c:391
+#: plugins/sudoers/ldap.c:397
 #, c-format
 msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
 msgstr "sudo_ldap_conf_add_ports: вихід за межі розширеного буфера вузла"
 
-#: plugins/sudoers/ldap.c:420
+#: plugins/sudoers/ldap.c:427
 #, c-format
 msgid "unsupported LDAP uri type: %s"
 msgstr "непідтримуваний тип адреси LDAP: %s"
 
-#: plugins/sudoers/ldap.c:449
+#: plugins/sudoers/ldap.c:456
 #, c-format
 msgid "invalid uri: %s"
 msgstr "некоректна адреса: %s"
 
-#: plugins/sudoers/ldap.c:455
+#: plugins/sudoers/ldap.c:462
 #, c-format
 msgid "unable to mix ldap and ldaps URIs"
 msgstr "не можна використовувати суміш з адрес ldap і ldaps"
 
-#: plugins/sudoers/ldap.c:459
+#: plugins/sudoers/ldap.c:466
 #, c-format
 msgid "unable to mix ldaps and starttls"
 msgstr "не можна використовувати суміш з ldaps і starttls"
 
-#: plugins/sudoers/ldap.c:478
+#: plugins/sudoers/ldap.c:485
 #, c-format
 msgid "sudo_ldap_parse_uri: out of space building hostbuf"
 msgstr "sudo_ldap_parse_uri: вихід за межі пам’яті під час побудови буфера вузла"
 
-#: plugins/sudoers/ldap.c:541
+#: plugins/sudoers/ldap.c:550
 #, c-format
 msgid "unable to initialize SSL cert and key db: %s"
 msgstr "не вдалося ініціалізувати базу даних сертифікатів і ключів SSL: %s"
 
-#: plugins/sudoers/ldap.c:937
+#: plugins/sudoers/ldap.c:958
 #, c-format
 msgid "unable to get GMT time"
 msgstr "не вдалося отримати гринвіцький час"
 
-#: plugins/sudoers/ldap.c:943
+#: plugins/sudoers/ldap.c:964
 #, c-format
 msgid "unable to format timestamp"
 msgstr "не вдалося виконати форматування часового штампа"
 
-#: plugins/sudoers/ldap.c:951
+#: plugins/sudoers/ldap.c:972
 #, c-format
 msgid "unable to build time filter"
 msgstr "не вдалося побудувати фільтр часу"
 
-#: plugins/sudoers/ldap.c:1052
+#: plugins/sudoers/ldap.c:1185
 #, c-format
 msgid "sudo_ldap_build_pass1 allocation mismatch"
 msgstr "sudo_ldap_build_pass1: невідповідність розміщення"
 
-#: plugins/sudoers/ldap.c:1562
+#: plugins/sudoers/ldap.c:1705
 #, c-format
 msgid ""
 "\n"
@@ -703,7 +701,7 @@ msgstr ""
 "\n"
 "Роль LDAP: %s\n"
 
-#: plugins/sudoers/ldap.c:1564
+#: plugins/sudoers/ldap.c:1707
 #, c-format
 msgid ""
 "\n"
@@ -712,124 +710,129 @@ msgstr ""
 "\n"
 "Роль у LDAP: НЕВІДОМА\n"
 
-#: plugins/sudoers/ldap.c:1611
+#: plugins/sudoers/ldap.c:1754
 #, c-format
 msgid "    Order: %s\n"
 msgstr "    Порядок: %s\n"
 
-#: plugins/sudoers/ldap.c:1619
+#: plugins/sudoers/ldap.c:1762
 #, c-format
 msgid "    Commands:\n"
 msgstr "    Команди:\n"
 
-#: plugins/sudoers/ldap.c:2006
+#: plugins/sudoers/ldap.c:2161
 #, c-format
 msgid "unable to initialize LDAP: %s"
 msgstr "не вдалося ініціалізувати LDAP: %s"
 
-#: plugins/sudoers/ldap.c:2037
+#: plugins/sudoers/ldap.c:2192
 #, c-format
 msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
 msgstr "start_tls вказано, але у бібліотеках LDAP не передбачено підтримки ldap_start_tls_s() або ldap_start_tls_s_np()"
 
-#: plugins/sudoers/ldap.c:2268
+#: plugins/sudoers/ldap.c:2428
 #, c-format
 msgid "invalid sudoOrder attribute: %s"
 msgstr "некоректний атрибут sudoOrder: %s"
 
-#: plugins/sudoers/linux_audit.c:55
+#: plugins/sudoers/linux_audit.c:57
 #, c-format
 msgid "unable to open audit system"
 msgstr "не вдалося відкрити систему аудита"
 
-#: plugins/sudoers/linux_audit.c:79
+#: plugins/sudoers/linux_audit.c:82
 #, c-format
 msgid "internal error, linux_audit_command() overflow"
 msgstr "внутрішня помилка, переповнення linux_audit_command()"
 
-#: plugins/sudoers/linux_audit.c:88
+#: plugins/sudoers/linux_audit.c:91
 #, c-format
 msgid "unable to send audit message"
 msgstr "не вдалося надіслати повідомлення аудита"
 
-#: plugins/sudoers/logging.c:192
+#: plugins/sudoers/logging.c:198
 #, c-format
 msgid "unable to open log file: %s: %s"
 msgstr "не вдалося відкрити файл журналу: %s: %s"
 
-#: plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:201
 #, c-format
 msgid "unable to lock log file: %s: %s"
 msgstr "не вдалося заблокувати файл журналу: %s: %s"
 
-#: plugins/sudoers/logging.c:249
+#: plugins/sudoers/logging.c:256
 msgid "user NOT in sudoers"
 msgstr "користувача немає у списку sudoers"
 
-#: plugins/sudoers/logging.c:251
+#: plugins/sudoers/logging.c:258
 msgid "user NOT authorized on host"
 msgstr "користувача не уповноважено на дії на вузлі"
 
-#: plugins/sudoers/logging.c:253
+#: plugins/sudoers/logging.c:260
 msgid "command not allowed"
 msgstr "виконання команди заборонено"
 
-#: plugins/sudoers/logging.c:263
+#: plugins/sudoers/logging.c:270
 #, c-format
 msgid "%s is not in the sudoers file.  This incident will be reported.\n"
 msgstr "%s немає у файлі sudoers. Запис про подію додано до звіту.\n"
 
-#: plugins/sudoers/logging.c:266
+#: plugins/sudoers/logging.c:273
 #, c-format
 msgid "%s is not allowed to run sudo on %s.  This incident will be reported.\n"
 msgstr "%s заборонено виконувати sudo на %s. Запис про подію додано до звіту.\n"
 
-#: plugins/sudoers/logging.c:270
+#: plugins/sudoers/logging.c:277
 #, c-format
 msgid "Sorry, user %s may not run sudo on %s.\n"
 msgstr "Вибачте, користувач %s не має права виконувати sudo на %s.\n"
 
-#: plugins/sudoers/logging.c:273
+#: plugins/sudoers/logging.c:280
 #, c-format
 msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
 msgstr "Вибачте, користувач %s не має права виконувати «%s%s%s» від імені %s%s%s на %s.\n"
 
-#: plugins/sudoers/logging.c:408
+#: plugins/sudoers/logging.c:420
 #, c-format
 msgid "unable to fork"
 msgstr "не вдалося створити відгалуження"
 
-#: plugins/sudoers/logging.c:415 plugins/sudoers/logging.c:472
+#: plugins/sudoers/logging.c:427 plugins/sudoers/logging.c:489
 #, c-format
 msgid "unable to fork: %m"
 msgstr "не вдалося створити відгалуження: %m"
 
-#: plugins/sudoers/logging.c:465
+#: plugins/sudoers/logging.c:479
 #, c-format
 msgid "unable to open pipe: %m"
 msgstr "не вдалося відкрити канал: %m"
 
-#: plugins/sudoers/logging.c:484
+#: plugins/sudoers/logging.c:504
 #, c-format
 msgid "unable to dup stdin: %m"
 msgstr "не вдалося здублювати stdin: %m"
 
-#: plugins/sudoers/logging.c:518
+#: plugins/sudoers/logging.c:540
 #, c-format
 msgid "unable to execute %s: %m"
 msgstr "не вдалося виконати %s: %m"
 
-#: plugins/sudoers/logging.c:728
+#: plugins/sudoers/logging.c:755
 #, c-format
 msgid "internal error: insufficient space for log line"
 msgstr "внутрішня помилка: недостатньо місця для рядка журналу"
 
-#: plugins/sudoers/parse.c:115
+#: plugins/sudoers/parse.c:123
 #, c-format
 msgid "parse error in %s near line %d"
 msgstr "помилка обробки у %s поблизу рядка %d"
 
-#: plugins/sudoers/parse.c:371
+#: plugins/sudoers/parse.c:126
+#, c-format
+msgid "parse error in %s"
+msgstr "помилка обробки у %s"
+
+#: plugins/sudoers/parse.c:389
 #, c-format
 msgid ""
 "\n"
@@ -838,17 +841,17 @@ msgstr ""
 "\n"
 "Запис sudoers:\n"
 
-#: plugins/sudoers/parse.c:373
+#: plugins/sudoers/parse.c:391
 #, c-format
 msgid "    RunAsUsers: "
 msgstr "    Користувачі для запуску: "
 
-#: plugins/sudoers/parse.c:388
+#: plugins/sudoers/parse.c:406
 #, c-format
 msgid "    RunAsGroups: "
 msgstr "    Групи для запуску: "
 
-#: plugins/sudoers/parse.c:397
+#: plugins/sudoers/parse.c:415
 #, c-format
 msgid ""
 "    Commands:\n"
@@ -861,97 +864,97 @@ msgstr ""
 msgid ": "
 msgstr ": "
 
-#: plugins/sudoers/pwutil.c:251
+#: plugins/sudoers/pwutil.c:260
 #, c-format
 msgid "unable to cache uid %u (%s), already exists"
 msgstr "не вдалося кешувати uid %u (%s), запис вже існує"
 
-#: plugins/sudoers/pwutil.c:259
+#: plugins/sudoers/pwutil.c:268
 #, c-format
 msgid "unable to cache uid %u, already exists"
 msgstr "не вдалося кешувати uid %u, запис вже існує"
 
-#: plugins/sudoers/pwutil.c:295 plugins/sudoers/pwutil.c:304
+#: plugins/sudoers/pwutil.c:305 plugins/sudoers/pwutil.c:314
 #, c-format
 msgid "unable to cache user %s, already exists"
 msgstr "не вдалося кешувати користувача %s, запис вже існує"
 
-#: plugins/sudoers/pwutil.c:607
+#: plugins/sudoers/pwutil.c:655
 #, c-format
 msgid "unable to cache gid %u (%s), already exists"
 msgstr "не вдалося кешувати gid %u (%s), запис вже існує"
 
-#: plugins/sudoers/pwutil.c:615
+#: plugins/sudoers/pwutil.c:663
 #, c-format
 msgid "unable to cache gid %u, already exists"
 msgstr "не вдалося кешувати gid %u, запис вже існує"
 
-#: plugins/sudoers/pwutil.c:644 plugins/sudoers/pwutil.c:653
+#: plugins/sudoers/pwutil.c:693 plugins/sudoers/pwutil.c:702
 #, c-format
 msgid "unable to cache group %s, already exists"
 msgstr "не вдалося кешувати групу %s, запис вже існує"
 
-#: plugins/sudoers/set_perms.c:109 plugins/sudoers/set_perms.c:358
-#: plugins/sudoers/set_perms.c:590 plugins/sudoers/set_perms.c:824
+#: plugins/sudoers/set_perms.c:114 plugins/sudoers/set_perms.c:365
+#: plugins/sudoers/set_perms.c:601 plugins/sudoers/set_perms.c:837
 msgid "perm stack overflow"
 msgstr "переповнення стека доступу"
 
-#: plugins/sudoers/set_perms.c:117 plugins/sudoers/set_perms.c:366
-#: plugins/sudoers/set_perms.c:598 plugins/sudoers/set_perms.c:832
+#: plugins/sudoers/set_perms.c:122 plugins/sudoers/set_perms.c:373
+#: plugins/sudoers/set_perms.c:609 plugins/sudoers/set_perms.c:845
 msgid "perm stack underflow"
 msgstr "вичерпання стека доступу"
 
-#: plugins/sudoers/set_perms.c:223 plugins/sudoers/set_perms.c:458
-#: plugins/sudoers/set_perms.c:695
+#: plugins/sudoers/set_perms.c:228 plugins/sudoers/set_perms.c:466
+#: plugins/sudoers/set_perms.c:706
 msgid "unable to change to runas gid"
 msgstr "не вдалося змінити gid на runas"
 
-#: plugins/sudoers/set_perms.c:231 plugins/sudoers/set_perms.c:465
-#: plugins/sudoers/set_perms.c:702
+#: plugins/sudoers/set_perms.c:236 plugins/sudoers/set_perms.c:473
+#: plugins/sudoers/set_perms.c:713
 msgid "unable to change to runas uid"
 msgstr "не вдалося змінити uid на runas"
 
-#: plugins/sudoers/set_perms.c:245 plugins/sudoers/set_perms.c:478
-#: plugins/sudoers/set_perms.c:715
+#: plugins/sudoers/set_perms.c:250 plugins/sudoers/set_perms.c:486
+#: plugins/sudoers/set_perms.c:726
 #, c-format
 msgid "unable to change to sudoers gid"
 msgstr "не вдалося змінити gid на sudoers"
 
-#: plugins/sudoers/set_perms.c:286 plugins/sudoers/set_perms.c:516
-#: plugins/sudoers/set_perms.c:753 plugins/sudoers/set_perms.c:893
+#: plugins/sudoers/set_perms.c:291 plugins/sudoers/set_perms.c:524
+#: plugins/sudoers/set_perms.c:764 plugins/sudoers/set_perms.c:906
 msgid "too many processes"
 msgstr "забагато процесів"
 
-#: plugins/sudoers/set_perms.c:955
+#: plugins/sudoers/set_perms.c:970
 msgid "unable to set runas group vector"
 msgstr "не вдалося встановити вектор групи виконання"
 
-#: plugins/sudoers/sudo_nss.c:238
+#: plugins/sudoers/sudo_nss.c:243
 #, c-format
 msgid "Matching Defaults entries for %s on this host:\n"
 msgstr "Відповідність записів Defaults для %s на цьому вузлі:\n"
 
-#: plugins/sudoers/sudo_nss.c:251
+#: plugins/sudoers/sudo_nss.c:256
 #, c-format
 msgid "Runas and Command-specific defaults for %s:\n"
 msgstr "Типові значення для запуску від імені і команд для %s:\n"
 
-#: plugins/sudoers/sudo_nss.c:264
+#: plugins/sudoers/sudo_nss.c:269
 #, c-format
 msgid "User %s may run the following commands on this host:\n"
 msgstr "Користувач %s має право виконувати на цьому вузлі такі команди:\n"
 
-#: plugins/sudoers/sudo_nss.c:274
+#: plugins/sudoers/sudo_nss.c:279
 #, c-format
 msgid "User %s is not allowed to run sudo on %s.\n"
 msgstr "Користувач %s не має права виконувати sudo на %s.\n"
 
-#: plugins/sudoers/sudoers.c:199 plugins/sudoers/sudoers.c:234
-#: plugins/sudoers/sudoers.c:911
+#: plugins/sudoers/sudoers.c:201 plugins/sudoers/sudoers.c:232
+#: plugins/sudoers/sudoers.c:931
 msgid "problem with defaults entries"
 msgstr "проблема з типовими записами"
 
-#: plugins/sudoers/sudoers.c:203
+#: plugins/sudoers/sudoers.c:205
 #, c-format
 msgid "no valid sudoers sources found, quitting"
 msgstr "не знайдено коректних джерел даних sudoers, завершення роботи"
@@ -961,42 +964,42 @@ msgstr "не знайдено коректних джерел даних sudoers
 msgid "unable to execute %s: %s"
 msgstr "не вдалося виконати %s: %s"
 
-#: plugins/sudoers/sudoers.c:306
+#: plugins/sudoers/sudoers.c:311
 #, c-format
 msgid "sudoers specifies that root is not allowed to sudo"
 msgstr "sudoers вказує, що sudo не можна користуватися для виконання команд від  root"
 
-#: plugins/sudoers/sudoers.c:313
+#: plugins/sudoers/sudoers.c:318
 #, c-format
 msgid "you are not permitted to use the -C option"
 msgstr "вам не дозволено використовувати параметр -C"
 
-#: plugins/sudoers/sudoers.c:403
+#: plugins/sudoers/sudoers.c:408
 #, c-format
 msgid "timestamp owner (%s): No such user"
 msgstr "власник часового штампа (%s): не знайдено користувача з таким іменем"
 
-#: plugins/sudoers/sudoers.c:419
+#: plugins/sudoers/sudoers.c:424
 msgid "no tty"
 msgstr "немає tty"
 
-#: plugins/sudoers/sudoers.c:420
+#: plugins/sudoers/sudoers.c:425
 #, c-format
 msgid "sorry, you must have a tty to run sudo"
 msgstr "вибачте, для виконання sudo вашому користувачеві потрібен tty"
 
-#: plugins/sudoers/sudoers.c:463
+#: plugins/sudoers/sudoers.c:464
 msgid "No user or host"
 msgstr "Немає користувача або вузла"
 
-#: plugins/sudoers/sudoers.c:477 plugins/sudoers/sudoers.c:498
-#: plugins/sudoers/sudoers.c:499 plugins/sudoers/sudoers.c:1465
-#: plugins/sudoers/sudoers.c:1466
+#: plugins/sudoers/sudoers.c:478 plugins/sudoers/sudoers.c:499
+#: plugins/sudoers/sudoers.c:500 plugins/sudoers/sudoers.c:1509
+#: plugins/sudoers/sudoers.c:1510
 #, c-format
 msgid "%s: command not found"
 msgstr "%s: команду не знайдено"
 
-#: plugins/sudoers/sudoers.c:479 plugins/sudoers/sudoers.c:495
+#: plugins/sudoers/sudoers.c:480 plugins/sudoers/sudoers.c:496
 #, c-format
 msgid ""
 "ignoring `%s' found in '.'\n"
@@ -1005,95 +1008,100 @@ msgstr ""
 "пропущено «%s» знайдений у «.»\n"
 "Скористайтеся командою «sudo ./%s», якщо вам потрібно виконати саме «%s»."
 
-#: plugins/sudoers/sudoers.c:484
+#: plugins/sudoers/sudoers.c:485
 msgid "validation failure"
 msgstr "помилка під час спроби перевірки"
 
-#: plugins/sudoers/sudoers.c:494
+#: plugins/sudoers/sudoers.c:495
 msgid "command in current directory"
 msgstr "команда у поточному каталозі"
 
-#: plugins/sudoers/sudoers.c:506
+#: plugins/sudoers/sudoers.c:507
 #, c-format
 msgid "sorry, you are not allowed to preserve the environment"
 msgstr "вибачте, вам не дозволено зберігати середовище"
 
-#: plugins/sudoers/sudoers.c:894
+#: plugins/sudoers/sudoers.c:657 plugins/sudoers/sudoers.c:664
+#, c-format
+msgid "internal error, runas_groups overflow"
+msgstr "внутрішня помилка, переповнення runas_groups"
+
+#: plugins/sudoers/sudoers.c:914
 #, c-format
 msgid "internal error, set_cmnd() overflow"
 msgstr "внутрішня помилка, переповнення set_cmnd()"
 
-#: plugins/sudoers/sudoers.c:936
+#: plugins/sudoers/sudoers.c:957
 #, c-format
 msgid "fixed mode on %s"
 msgstr "виправлено режим на %s"
 
-#: plugins/sudoers/sudoers.c:940
+#: plugins/sudoers/sudoers.c:961
 #, c-format
 msgid "set group on %s"
 msgstr "встановлено групу у %s"
 
-#: plugins/sudoers/sudoers.c:943
+#: plugins/sudoers/sudoers.c:964
 #, c-format
 msgid "unable to set group on %s"
 msgstr "не вдалося встановити групу на %s"
 
-#: plugins/sudoers/sudoers.c:946
+#: plugins/sudoers/sudoers.c:967
 #, c-format
 msgid "unable to fix mode on %s"
 msgstr "не вдалося виправити режим на %s"
 
-#: plugins/sudoers/sudoers.c:959
+#: plugins/sudoers/sudoers.c:980
 #, c-format
 msgid "%s is not a regular file"
 msgstr "%s не є звичайним файлом"
 
-#: plugins/sudoers/sudoers.c:961
+#: plugins/sudoers/sudoers.c:982
 #, c-format
 msgid "%s is mode 0%o, should be 0%o"
 msgstr "%s має режим доступу 0%o, має бути 0%o"
 
-#: plugins/sudoers/sudoers.c:965
+#: plugins/sudoers/sudoers.c:986
 #, c-format
 msgid "%s is owned by uid %u, should be %u"
 msgstr "%s належить uid %u, має належати %u"
 
-#: plugins/sudoers/sudoers.c:968
+#: plugins/sudoers/sudoers.c:989
 #, c-format
 msgid "%s is owned by gid %u, should be %u"
 msgstr "%s належить gid %u, має належати %u"
 
-#: plugins/sudoers/sudoers.c:1012
+#: plugins/sudoers/sudoers.c:1038
 #, c-format
 msgid "only root can use `-c %s'"
 msgstr "використовувати «-c %s» може лише root"
 
-#: plugins/sudoers/sudoers.c:1022
+#: plugins/sudoers/sudoers.c:1049
 #, c-format
 msgid "unknown login class: %s"
 msgstr "невідомий клас входу: %s"
 
-#: plugins/sudoers/sudoers.c:1056
+#: plugins/sudoers/sudoers.c:1077
 #, c-format
 msgid "unable to resolve host %s"
 msgstr "не вдалося визначити адресу вузла %s"
 
-#: plugins/sudoers/sudoers.c:1106 plugins/sudoers/testsudoers.c:351
+#: plugins/sudoers/sudoers.c:1129 plugins/sudoers/testsudoers.c:380
 #, c-format
 msgid "unknown group: %s"
 msgstr "невідома група: %s"
 
-#: plugins/sudoers/sudoers.c:1150
+#: plugins/sudoers/sudoers.c:1178
 #, c-format
 msgid "Sudoers policy plugin version %s\n"
 msgstr "Додаток правил sudoers версії %s\n"
 
-#: plugins/sudoers/sudoers.c:1152
+#: plugins/sudoers/sudoers.c:1180
 #, c-format
 msgid "Sudoers file grammar version %d\n"
 msgstr "Граматична перевірка файла sudoers версії %d\n"
 
-#: plugins/sudoers/sudoers.c:1156
+#: plugins/sudoers/sudoers.c:1184
 #, c-format
 msgid ""
 "\n"
@@ -1102,147 +1110,147 @@ msgstr ""
 "\n"
 "Шлях до sudoers: %s\n"
 
-#: plugins/sudoers/sudoers.c:1159
+#: plugins/sudoers/sudoers.c:1187
 #, c-format
 msgid "nsswitch path: %s\n"
 msgstr "Шлях до nsswitch: %s\n"
 
-#: plugins/sudoers/sudoers.c:1161
+#: plugins/sudoers/sudoers.c:1189
 #, c-format
 msgid "ldap.conf path: %s\n"
 msgstr "Шлях до ldap.conf: %s\n"
 
-#: plugins/sudoers/sudoers.c:1162
+#: plugins/sudoers/sudoers.c:1190
 #, c-format
 msgid "ldap.secret path: %s\n"
 msgstr "Шлях до ldap.secret: %s\n"
 
-#: plugins/sudoers/sudoreplay.c:265
+#: plugins/sudoers/sudoreplay.c:286
 #, c-format
 msgid "invalid filter option: %s"
 msgstr "некоректний параметр фільтрування: %s"
 
-#: plugins/sudoers/sudoreplay.c:278
+#: plugins/sudoers/sudoreplay.c:299
 #, c-format
 msgid "invalid max wait: %s"
 msgstr "некоректне значення макс. очікування: %s"
 
-#: plugins/sudoers/sudoreplay.c:284
+#: plugins/sudoers/sudoreplay.c:305
 #, c-format
 msgid "invalid speed factor: %s"
 msgstr "некоректний коефіцієнт швидкості: %s"
 
-#: plugins/sudoers/sudoreplay.c:287 plugins/sudoers/visudo.c:174
+#: plugins/sudoers/sudoreplay.c:308 plugins/sudoers/visudo.c:187
 #, c-format
 msgid "%s version %s\n"
 msgstr "%s, версія %s\n"
 
-#: plugins/sudoers/sudoreplay.c:310
+#: plugins/sudoers/sudoreplay.c:333
 #, c-format
 msgid "%s/%.2s/%.2s/%.2s/timing: %s"
 msgstr "%s/%.2s/%.2s/%.2s/timing: %s"
 
-#: plugins/sudoers/sudoreplay.c:316
+#: plugins/sudoers/sudoreplay.c:339
 #, c-format
 msgid "%s/%s/timing: %s"
 msgstr "%s/%s/timing: %s"
 
-#: plugins/sudoers/sudoreplay.c:341
+#: plugins/sudoers/sudoreplay.c:364
 #, c-format
 msgid "invalid log file %s"
 msgstr "некоректний файл журналу %s"
 
-#: plugins/sudoers/sudoreplay.c:343
+#: plugins/sudoers/sudoreplay.c:366
 #, c-format
 msgid "Replaying sudo session: %s"
 msgstr "Відтворення сеансу sudo: %s"
 
-#: plugins/sudoers/sudoreplay.c:369
+#: plugins/sudoers/sudoreplay.c:392
 #, c-format
 msgid "unable to set tty to raw mode"
 msgstr "не вдалося перевести tty у режим без обробки даних"
 
-#: plugins/sudoers/sudoreplay.c:383
+#: plugins/sudoers/sudoreplay.c:406
 #, c-format
 msgid "invalid timing file line: %s"
 msgstr "некоректний рядок у файлі timing: %s"
 
-#: plugins/sudoers/sudoreplay.c:425
+#: plugins/sudoers/sudoreplay.c:448
 #, c-format
 msgid "writing to standard output"
 msgstr "запис до стандартного виводу даних"
 
-#: plugins/sudoers/sudoreplay.c:455
+#: plugins/sudoers/sudoreplay.c:480
 #, c-format
 msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
 msgstr "nanosleep: tv_sec %ld, tv_nsec %ld"
 
-#: plugins/sudoers/sudoreplay.c:503 plugins/sudoers/sudoreplay.c:528
+#: plugins/sudoers/sudoreplay.c:529 plugins/sudoers/sudoreplay.c:554
 #, c-format
 msgid "ambiguous expression \"%s\""
 msgstr "неоднозначний вираз «%s»"
 
-#: plugins/sudoers/sudoreplay.c:545
+#: plugins/sudoers/sudoreplay.c:571
 #, c-format
 msgid "too many parenthesized expressions, max %d"
 msgstr "забагато виразів у дужках, максимальна можлива кількість — %d"
 
-#: plugins/sudoers/sudoreplay.c:556
+#: plugins/sudoers/sudoreplay.c:582
 #, c-format
 msgid "unmatched ')' in expression"
 msgstr "зайва дужка, «)», у виразі"
 
-#: plugins/sudoers/sudoreplay.c:562
+#: plugins/sudoers/sudoreplay.c:588
 #, c-format
 msgid "unknown search term \"%s\""
 msgstr "невідомий ключ пошуку «%s»"
 
-#: plugins/sudoers/sudoreplay.c:576
+#: plugins/sudoers/sudoreplay.c:602
 #, c-format
 msgid "%s requires an argument"
 msgstr "%s потребує визначення аргументу"
 
-#: plugins/sudoers/sudoreplay.c:580
+#: plugins/sudoers/sudoreplay.c:606
 #, c-format
 msgid "invalid regular expression: %s"
 msgstr "некоректний формальний вираз: %s"
 
-#: plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:612
 #, c-format
 msgid "could not parse date \"%s\""
 msgstr "не вдалося обробити дату «%s»"
 
-#: plugins/sudoers/sudoreplay.c:599
+#: plugins/sudoers/sudoreplay.c:625
 #, c-format
 msgid "unmatched '(' in expression"
 msgstr "зайва дужка, «(», у виразі"
 
-#: plugins/sudoers/sudoreplay.c:601
+#: plugins/sudoers/sudoreplay.c:627
 #, c-format
 msgid "illegal trailing \"or\""
 msgstr "помилкове завершальне «or»"
 
-#: plugins/sudoers/sudoreplay.c:603
+#: plugins/sudoers/sudoreplay.c:629
 #, c-format
 msgid "illegal trailing \"!\""
 msgstr "помилкове завершальне «!»"
 
-#: plugins/sudoers/sudoreplay.c:819
+#: plugins/sudoers/sudoreplay.c:851
 #, c-format
 msgid "invalid regex: %s"
 msgstr "некоректний формальний вираз: %s"
 
-#: plugins/sudoers/sudoreplay.c:941
+#: plugins/sudoers/sudoreplay.c:976
 #, c-format
 msgid "usage: %s [-h] [-d directory] [-m max_wait] [-s speed_factor] ID\n"
 msgstr "використання: %s [-h] [-d каталог] [-m макс_очік] [-s коеф_швидкості] ідентифікатор\n"
 
-#: plugins/sudoers/sudoreplay.c:944
+#: plugins/sudoers/sudoreplay.c:979
 #, c-format
 msgid "usage: %s [-h] [-d directory] -l [search expression]\n"
 msgstr "використання: %s [-h] [-d каталог] -l [вираз для пошуку]\n"
 
-#: plugins/sudoers/sudoreplay.c:953
+#: plugins/sudoers/sudoreplay.c:988
 #, c-format
 msgid ""
 "%s - replay sudo session logs\n"
@@ -1251,7 +1259,7 @@ msgstr ""
 "%s — відтворення журналів сеансів sudo\n"
 "\n"
 
-#: plugins/sudoers/sudoreplay.c:955
+#: plugins/sudoers/sudoreplay.c:990
 msgid ""
 "\n"
 "Options:\n"
@@ -1273,16 +1281,16 @@ msgstr ""
 "  -s коеф_швидк    коефіцієнт прискорення або сповільнення виводу даних\n"
 "  -V               показати дані щодо версії і завершити роботу"
 
-#: plugins/sudoers/testsudoers.c:230
+#: plugins/sudoers/testsudoers.c:246
 #, c-format
 msgid "internal error, init_vars() overflow"
 msgstr "внутрішня помилка, переповнення init_vars()"
 
-#: plugins/sudoers/testsudoers.c:309
+#: plugins/sudoers/testsudoers.c:331
 msgid "\thost  unmatched"
 msgstr "\tвідповідника вузла не знайдено"
 
-#: plugins/sudoers/testsudoers.c:312
+#: plugins/sudoers/testsudoers.c:334
 msgid ""
 "\n"
 "Command allowed"
@@ -1290,7 +1298,7 @@ msgstr ""
 "\n"
 "Команду дозволено"
 
-#: plugins/sudoers/testsudoers.c:313
+#: plugins/sudoers/testsudoers.c:335
 msgid ""
 "\n"
 "Command denied"
@@ -1298,7 +1306,7 @@ msgstr ""
 "\n"
 "Команду заборонено"
 
-#: plugins/sudoers/testsudoers.c:313
+#: plugins/sudoers/testsudoers.c:335
 msgid ""
 "\n"
 "Command unmatched"
@@ -1306,104 +1314,104 @@ msgstr ""
 "\n"
 "Не знайдено відповідника команди"
 
-#: toke.l:667 toke.l:793 toke.l:818 toke.l:904 plugins/sudoers/toke_util.c:111
-#: plugins/sudoers/toke_util.c:163 plugins/sudoers/toke_util.c:202
+#: toke.l:672 toke.l:802 toke.l:827 toke.l:923 plugins/sudoers/toke_util.c:113
+#: plugins/sudoers/toke_util.c:167 plugins/sudoers/toke_util.c:207
 msgid "unable to allocate memory"
 msgstr "не вдалося отримати потрібний об’єм пам’яті"
 
-#: toke.l:786
+#: toke.l:795
 msgid "too many levels of includes"
 msgstr "занадто високий рівень вкладеності"
 
-#: plugins/sudoers/toke_util.c:213
+#: plugins/sudoers/toke_util.c:218
 msgid "fill_args: buffer overflow"
 msgstr "fill_args: переповнення буфера"
 
-#: plugins/sudoers/visudo.c:175
+#: plugins/sudoers/visudo.c:188
 #, c-format
 msgid "%s grammar version %d\n"
 msgstr "Граматична перевірка %s, версія %d\n"
 
-#: plugins/sudoers/visudo.c:208 plugins/sudoers/auth/rfc1938.c:103
+#: plugins/sudoers/visudo.c:221 plugins/sudoers/auth/rfc1938.c:104
 #, c-format
 msgid "you do not exist in the %s database"
 msgstr "вас немає у базі даних %s"
 
-#: plugins/sudoers/visudo.c:238 plugins/sudoers/visudo.c:518
+#: plugins/sudoers/visudo.c:253 plugins/sudoers/visudo.c:539
 #, c-format
 msgid "press return to edit %s: "
 msgstr "натисніть Enter для редагування %s: "
 
-#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:326
+#: plugins/sudoers/visudo.c:336 plugins/sudoers/visudo.c:342
 #, c-format
 msgid "write error"
 msgstr "помилка запису"
 
-#: plugins/sudoers/visudo.c:408
+#: plugins/sudoers/visudo.c:424
 #, c-format
 msgid "unable to stat temporary file (%s), %s unchanged"
 msgstr "не вдалося обробити stat файл тимчасових даних (%s), %s не змінено"
 
-#: plugins/sudoers/visudo.c:413
+#: plugins/sudoers/visudo.c:429
 #, c-format
 msgid "zero length temporary file (%s), %s unchanged"
 msgstr "файл тимчасових даних має нульовий об’єм (%s), %s не змінено"
 
-#: plugins/sudoers/visudo.c:419
+#: plugins/sudoers/visudo.c:435
 #, c-format
 msgid "editor (%s) failed, %s unchanged"
 msgstr "помилка редактора (%s), %s не змінено"
 
-#: plugins/sudoers/visudo.c:442
+#: plugins/sudoers/visudo.c:458
 #, c-format
 msgid "%s unchanged"
 msgstr "%s не змінено"
 
-#: plugins/sudoers/visudo.c:466
+#: plugins/sudoers/visudo.c:484
 #, c-format
 msgid "unable to re-open temporary file (%s), %s unchanged."
 msgstr "не вдалося повторно відкрити файл тимчасових даних (%s), %s не змінено."
 
-#: plugins/sudoers/visudo.c:476
+#: plugins/sudoers/visudo.c:494
 #, c-format
 msgid "unabled to parse temporary file (%s), unknown error"
 msgstr "не вдалося обробити файл тимчасових даних (%s), невідома помилка"
 
-#: plugins/sudoers/visudo.c:511
+#: plugins/sudoers/visudo.c:532
 #, c-format
 msgid "internal error, unable to find %s in list!"
 msgstr "внутрішня помилка, не вдалося знайти %s у списку!"
 
-#: plugins/sudoers/visudo.c:546 plugins/sudoers/visudo.c:555
+#: plugins/sudoers/visudo.c:584 plugins/sudoers/visudo.c:593
 #, c-format
 msgid "unable to set (uid, gid) of %s to (%u, %u)"
 msgstr "не вдалося встановити (uid, gid) %s у значення (%u, %u)"
 
-#: plugins/sudoers/visudo.c:550 plugins/sudoers/visudo.c:560
+#: plugins/sudoers/visudo.c:588 plugins/sudoers/visudo.c:598
 #, c-format
 msgid "unable to change mode of %s to 0%o"
 msgstr "не вдалося змінити режим доступу до %s на значення 0%o"
 
-#: plugins/sudoers/visudo.c:577
+#: plugins/sudoers/visudo.c:615
 #, c-format
 msgid "%s and %s not on the same file system, using mv to rename"
 msgstr "%s і %s не перебувають у одній файловій системі, використовуємо mv для перейменування"
 
-#: plugins/sudoers/visudo.c:591
+#: plugins/sudoers/visudo.c:629
 #, c-format
 msgid "command failed: '%s %s %s', %s unchanged"
 msgstr "помилка команди: «%s %s %s», %s не змінено"
 
-#: plugins/sudoers/visudo.c:601
+#: plugins/sudoers/visudo.c:639
 #, c-format
 msgid "error renaming %s, %s unchanged"
 msgstr "помилка перейменування %s, %s не змінено"
 
-#: plugins/sudoers/visudo.c:661
+#: plugins/sudoers/visudo.c:702
 msgid "What now? "
 msgstr "А зараз що? "
 
-#: plugins/sudoers/visudo.c:675
+#: plugins/sudoers/visudo.c:716
 msgid ""
 "Options are:\n"
 "  (e)dit sudoers file again\n"
@@ -1415,92 +1423,92 @@ msgstr ""
 "  (x) — вийти без внесення змін до файла sudoers\n"
 "  (Q) — вийти зі збереженням файла sudoers (НЕБЕЗПЕЧНО!)\n"
 
-#: plugins/sudoers/visudo.c:712
+#: plugins/sudoers/visudo.c:757
 #, c-format
 msgid "unable to execute %s"
 msgstr "не вдалося виконати %s"
 
-#: plugins/sudoers/visudo.c:719
+#: plugins/sudoers/visudo.c:764
 #, c-format
 msgid "unable to run %s"
 msgstr "не вдалося виконати %s"
 
-#: plugins/sudoers/visudo.c:750
+#: plugins/sudoers/visudo.c:796
 #, c-format
 msgid "failed to parse %s file, unknown error"
 msgstr "не вдалося обробити файл %s, невідома помилка"
 
-#: plugins/sudoers/visudo.c:762
+#: plugins/sudoers/visudo.c:808
 #, c-format
 msgid "parse error in %s near line %d\n"
 msgstr "помилка обробки у %s поблизу рядка %d\n"
 
-#: plugins/sudoers/visudo.c:765
+#: plugins/sudoers/visudo.c:811
 #, c-format
 msgid "parse error in %s\n"
 msgstr "помилка обробки у %s\n"
 
-#: plugins/sudoers/visudo.c:767
+#: plugins/sudoers/visudo.c:814 plugins/sudoers/visudo.c:816
 #, c-format
 msgid "%s: parsed OK\n"
 msgstr "%s: вдала обробка\n"
 
-#: plugins/sudoers/visudo.c:776
+#: plugins/sudoers/visudo.c:826
 #, c-format
 msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
 msgstr "%s: помилковий власник (uid, gid), має бути (%u, %u)\n"
 
-#: plugins/sudoers/visudo.c:783
+#: plugins/sudoers/visudo.c:833
 #, c-format
 msgid "%s: bad permissions, should be mode 0%o\n"
 msgstr "%s: помилкові права доступу, режим доступу має бути 0%o\n"
 
-#: plugins/sudoers/visudo.c:822
+#: plugins/sudoers/visudo.c:880
 #, c-format
 msgid "%s busy, try again later"
 msgstr "%s зайнято, повторіть спробу пізніше"
 
-#: plugins/sudoers/visudo.c:865
+#: plugins/sudoers/visudo.c:924
 #, c-format
 msgid "specified editor (%s) doesn't exist"
 msgstr "вказаного редактора (%s) не існує"
 
-#: plugins/sudoers/visudo.c:888
+#: plugins/sudoers/visudo.c:947
 #, c-format
 msgid "unable to stat editor (%s)"
 msgstr "не вдалося виконати stat для редактора (%s)"
 
-#: plugins/sudoers/visudo.c:936
+#: plugins/sudoers/visudo.c:995
 #, c-format
 msgid "no editor found (editor path = %s)"
 msgstr "не знайдено жодного редактора (шлях до редактора = %s)"
 
-#: plugins/sudoers/visudo.c:1025
+#: plugins/sudoers/visudo.c:1089
 #, c-format
 msgid "Error: cycle in %s_Alias `%s'"
 msgstr "Помилка: цикл у %s_Alias «%s»"
 
-#: plugins/sudoers/visudo.c:1026
+#: plugins/sudoers/visudo.c:1090
 #, c-format
 msgid "Warning: cycle in %s_Alias `%s'"
 msgstr "Попередження: цикл у %s_Alias «%s»"
 
-#: plugins/sudoers/visudo.c:1029
+#: plugins/sudoers/visudo.c:1093
 #, c-format
 msgid "Error: %s_Alias `%s' referenced but not defined"
 msgstr "Помилка: виявлено посилання %s_Alias «%s», яке не визначено"
 
-#: plugins/sudoers/visudo.c:1030
+#: plugins/sudoers/visudo.c:1094
 #, c-format
 msgid "Warning: %s_Alias `%s' referenced but not defined"
 msgstr "Попередження: виявлено посилання %s_Alias «%s», яке не визначено"
 
-#: plugins/sudoers/visudo.c:1167
+#: plugins/sudoers/visudo.c:1229
 #, c-format
 msgid "%s: unused %s_Alias %s"
 msgstr "%s: невикористаний %s_Alias %s"
 
-#: plugins/sudoers/visudo.c:1224
+#: plugins/sudoers/visudo.c:1286
 #, c-format
 msgid ""
 "%s - safely edit the sudoers file\n"
@@ -1509,7 +1517,7 @@ msgstr ""
 "%s — безпечне редагування файла sudoers\n"
 "\n"
 
-#: plugins/sudoers/visudo.c:1226
+#: plugins/sudoers/visudo.c:1288
 msgid ""
 "\n"
 "Options:\n"
@@ -1529,35 +1537,40 @@ msgstr ""
 "  -s          строга перевірка синтаксису\n"
 "  -V          показати дані щодо версії і завершити роботу"
 
-#: plugins/sudoers/auth/bsdauth.c:64
+#: plugins/sudoers/auth/bsdauth.c:78
+#, c-format
+msgid "unable to get login class for user %s"
+msgstr "не вдалося отримати клас входу до системи для користувача %s"
+
+#: plugins/sudoers/auth/bsdauth.c:84
 msgid "unable to begin bsd authentication"
 msgstr "не вдалося розпочати розпізнавання за BSD"
 
-#: plugins/sudoers/auth/bsdauth.c:71
+#: plugins/sudoers/auth/bsdauth.c:92
 msgid "invalid authentication type"
 msgstr "некоректний тип розпізнавання"
 
-#: plugins/sudoers/auth/bsdauth.c:79
+#: plugins/sudoers/auth/bsdauth.c:101
 msgid "unable to setup authentication"
 msgstr "не вдалося налаштувати розпізнавання"
 
-#: plugins/sudoers/auth/fwtk.c:59
+#: plugins/sudoers/auth/fwtk.c:60
 #, c-format
 msgid "unable to read fwtk config"
 msgstr "не вдалося прочитати налаштування fwtk"
 
-#: plugins/sudoers/auth/fwtk.c:64
+#: plugins/sudoers/auth/fwtk.c:65
 #, c-format
 msgid "unable to connect to authentication server"
 msgstr "не вдалося встановити з’єднання з сервером розпізнавання"
 
-#: plugins/sudoers/auth/fwtk.c:70 plugins/sudoers/auth/fwtk.c:93
-#: plugins/sudoers/auth/fwtk.c:126
+#: plugins/sudoers/auth/fwtk.c:71 plugins/sudoers/auth/fwtk.c:95
+#: plugins/sudoers/auth/fwtk.c:128
 #, c-format
 msgid "lost connection to authentication server"
 msgstr "втрачено зв’язок з сервером розпізнавання"
 
-#: plugins/sudoers/auth/fwtk.c:74
+#: plugins/sudoers/auth/fwtk.c:75
 #, c-format
 msgid ""
 "authentication server error:\n"
@@ -1566,142 +1579,142 @@ msgstr ""
 "помилка сервера розпізнавання:\n"
 "%s"
 
-#: plugins/sudoers/auth/kerb5.c:114
-#, c-format
-msgid "%s: unable to parse '%s': %s"
-msgstr "%s: не вдалося обробити «%s»: %s"
-
-#: plugins/sudoers/auth/kerb5.c:127
+#: plugins/sudoers/auth/kerb5.c:117
 #, c-format
 msgid "%s: unable to unparse princ ('%s'): %s"
 msgstr "%s: не вдалося зібрати princ ('%s'): %s"
 
-#: plugins/sudoers/auth/kerb5.c:144
+#: plugins/sudoers/auth/kerb5.c:160
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s: не вдалося обробити «%s»: %s"
+
+#: plugins/sudoers/auth/kerb5.c:170
 #, c-format
 msgid "%s: unable to resolve ccache: %s"
 msgstr "%s: не вдалося визначити ccache: %s"
 
-#: plugins/sudoers/auth/kerb5.c:188
+#: plugins/sudoers/auth/kerb5.c:218
 #, c-format
 msgid "%s: unable to allocate options: %s"
 msgstr "%s: не вдалося розмістити параметри: %s"
 
-#: plugins/sudoers/auth/kerb5.c:204
+#: plugins/sudoers/auth/kerb5.c:234
 #, c-format
 msgid "%s: unable to get credentials: %s"
 msgstr "%s: не вдалося отримати реєстраційні дані: %s"
 
-#: plugins/sudoers/auth/kerb5.c:217
+#: plugins/sudoers/auth/kerb5.c:247
 #, c-format
 msgid "%s: unable to initialize ccache: %s"
 msgstr "%s: не вдалося ініціалізувати ccache: %s"
 
-#: plugins/sudoers/auth/kerb5.c:221
+#: plugins/sudoers/auth/kerb5.c:251
 #, c-format
 msgid "%s: unable to store cred in ccache: %s"
 msgstr "%s: не вдалося зберегти реєстраційні дані у ccache: %s"
 
-#: plugins/sudoers/auth/kerb5.c:284
+#: plugins/sudoers/auth/kerb5.c:316
 #, c-format
 msgid "%s: unable to get host principal: %s"
 msgstr "%s: не вдалося отримати реєстраційний запис вузла: %s"
 
-#: plugins/sudoers/auth/kerb5.c:299
+#: plugins/sudoers/auth/kerb5.c:331
 #, c-format
 msgid "%s: Cannot verify TGT! Possible attack!: %s"
 msgstr "%s: спроба перевірки TGT зазнала невдачі! Ймовірно, вас атаковано: %s"
 
-#: plugins/sudoers/auth/pam.c:99
+#: plugins/sudoers/auth/pam.c:100
 msgid "unable to initialize PAM"
 msgstr "не вдалося ініціалізувати PAM"
 
-#: plugins/sudoers/auth/pam.c:142
+#: plugins/sudoers/auth/pam.c:144
 msgid "account validation failure, is your account locked?"
 msgstr "помилка під час спроби перевірки облікового запису. Ваш обліковий запис заблоковано?"
 
-#: plugins/sudoers/auth/pam.c:146
+#: plugins/sudoers/auth/pam.c:148
 msgid "Account or password is expired, reset your password and try again"
 msgstr "Строк дії облікового запису або пароля збіг, визначте новий пароль і повторіть спробу"
 
-#: plugins/sudoers/auth/pam.c:153
+#: plugins/sudoers/auth/pam.c:155
 #, c-format
 msgid "pam_chauthtok: %s"
 msgstr "pam_chauthtok: %s"
 
-#: plugins/sudoers/auth/pam.c:157
+#: plugins/sudoers/auth/pam.c:159
 msgid "Password expired, contact your system administrator"
 msgstr "Строк дії пароля збіг, зверніться до адміністратора вашої системи щодо поновлення пароля"
 
-#: plugins/sudoers/auth/pam.c:161
+#: plugins/sudoers/auth/pam.c:163
 msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
 msgstr "Строк дії облікового запису збіг або у файлі налаштувань PAM немає розділу \"account\" для sudo. Повідомте про це адміністратора вашої системи."
 
-#: plugins/sudoers/auth/pam.c:176
+#: plugins/sudoers/auth/pam.c:178
 #, c-format
 msgid "pam_authenticate: %s"
 msgstr "pam_authenticate: %s"
 
-#: plugins/sudoers/auth/pam.c:296
+#: plugins/sudoers/auth/pam.c:306
 msgid "Password: "
 msgstr "Пароль: "
 
-#: plugins/sudoers/auth/pam.c:297
+#: plugins/sudoers/auth/pam.c:307
 msgid "Password:"
 msgstr "Пароль:"
 
-#: plugins/sudoers/auth/securid.c:82 plugins/sudoers/auth/securid5.c:106
-#, c-format
-msgid "unable to contact the SecurID server"
-msgstr "не вдалося встановити зв’язок з сервером SecurID"
-
 #: plugins/sudoers/auth/securid5.c:81
 #, c-format
 msgid "failed to initialise the ACE API library"
 msgstr "не вдалося ініціалізувати бібліотеку програмного інтерфейсу до ACE"
 
-#: plugins/sudoers/auth/securid5.c:115
+#: plugins/sudoers/auth/securid5.c:107
+#, c-format
+msgid "unable to contact the SecurID server"
+msgstr "не вдалося встановити зв’язок з сервером SecurID"
+
+#: plugins/sudoers/auth/securid5.c:116
 #, c-format
 msgid "User ID locked for SecurID Authentication"
 msgstr "Ідентифікатор користувача заблоковано для розпізнавання SecurID"
 
-#: plugins/sudoers/auth/securid5.c:119 plugins/sudoers/auth/securid5.c:169
+#: plugins/sudoers/auth/securid5.c:120 plugins/sudoers/auth/securid5.c:171
 #, c-format
 msgid "invalid username length for SecurID"
 msgstr "некоректна довжина імені користувача для SecurID"
 
-#: plugins/sudoers/auth/securid5.c:123 plugins/sudoers/auth/securid5.c:174
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:176
 #, c-format
 msgid "invalid Authentication Handle for SecurID"
 msgstr "некоректний дескриптор розпізнавання для SecurID"
 
-#: plugins/sudoers/auth/securid5.c:127
+#: plugins/sudoers/auth/securid5.c:128
 #, c-format
 msgid "SecurID communication failed"
 msgstr "спроба обміну даними з SecurID зазнала невдачі"
 
-#: plugins/sudoers/auth/securid5.c:131 plugins/sudoers/auth/securid5.c:213
+#: plugins/sudoers/auth/securid5.c:132 plugins/sudoers/auth/securid5.c:215
 #, c-format
 msgid "unknown SecurID error"
 msgstr "невідома помилка SecurID"
 
-#: plugins/sudoers/auth/securid5.c:164
+#: plugins/sudoers/auth/securid5.c:166
 #, c-format
 msgid "invalid passcode length for SecurID"
 msgstr "некоректна довжина коду пароля для SecurID"
 
-#: plugins/sudoers/auth/sia.c:106
+#: plugins/sudoers/auth/sia.c:109
 msgid "unable to initialize SIA session"
 msgstr "не вдалося ініціалізувати сеанс SIA"
 
-#: plugins/sudoers/auth/sudo_auth.c:124
-msgid "There are no authentication methods compiled into sudo!  If you want to turn off authentication, use the --disable-authentication configure option."
-msgstr "sudo зібрано без можливостей з взаємодії з інструментами розпізнавання! Якщо ви хочете вимкнути розпізнавання, скористайтеся параметром налаштування --disable-authentication."
-
-#: plugins/sudoers/auth/sudo_auth.c:134
+#: plugins/sudoers/auth/sudo_auth.c:117
 msgid "Invalid authentication methods compiled into sudo!  You may mix standalone and non-standalone authentication."
 msgstr "sudo зібрано з підтримкою некоректних способів розпізнавання! Можливе змішування власних і зовнішніх способів розпізнавання."
 
-#: plugins/sudoers/auth/sudo_auth.c:243
+#: plugins/sudoers/auth/sudo_auth.c:199
+msgid "There are no authentication methods compiled into sudo!  If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "sudo зібрано без можливостей з взаємодії з інструментами розпізнавання! Якщо ви хочете вимкнути розпізнавання, скористайтеся параметром налаштування --disable-authentication."
+
+#: plugins/sudoers/auth/sudo_auth.c:271
 #, c-format
 msgid "%d incorrect password attempt"
 msgid_plural "%d incorrect password attempts"
@@ -1710,10 +1723,13 @@ msgstr[1] "%d невдалих спроби введення пароля"
 msgstr[2] "%d невдалих спроб введення пароля"
 msgstr[3] "одна невдала спроба введення пароля"
 
-#: plugins/sudoers/auth/sudo_auth.c:335
+#: plugins/sudoers/auth/sudo_auth.c:374
 msgid "Authentication methods:"
 msgstr "Способи розпізнавання:"
 
+#~ msgid "File containing dummy exec functions: %s"
+#~ msgstr "Файл, що містить фіктивні функції виконання: %s"
+
 #~ msgid ""
 #~ "Available options in a sudoers ``Defaults'' line:\n"
 #~ "\n"
index daa4ad47205e19a9252cb3b0affe457ba95afc7f..045a3ccba16adb91beef1e96c7160ebf1545c09e 100644 (file)
Binary files a/plugins/sudoers/po/zh_CN.mo and b/plugins/sudoers/po/zh_CN.mo differ
index 69be1fed2f415bea1b43a97dac2c89fb9e7c615c..14437bd2e3dae42c9dba23be2c65c1d5eaabfb82 100644 (file)
@@ -4,10 +4,10 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: sudoers 1.8.3rc1\n"
+"Project-Id-Version: sudoers 1.8.4rc1\n"
 "Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
-"POT-Creation-Date: 2011-09-16 16:52-0400\n"
-"PO-Revision-Date: 2011-09-18 10:01+0800\n"
+"POT-Creation-Date: 2012-02-06 15:48-0500\n"
+"PO-Revision-Date: 2012-02-10 10:01+0800\n"
 "Last-Translator: Wylmer Wang <wantinghard@gmail.com>\n"
 "Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n"
 "Language: \n"
@@ -16,146 +16,146 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
 
-#: plugins/sudoers/alias.c:122
+#: plugins/sudoers/alias.c:125
 #, c-format
 msgid "Alias `%s' already defined"
 msgstr "别名“%s”已定义"
 
-#: plugins/sudoers/bsm_audit.c:58 plugins/sudoers/bsm_audit.c:61
-#: plugins/sudoers/bsm_audit.c:109 plugins/sudoers/bsm_audit.c:113
-#: plugins/sudoers/bsm_audit.c:163 plugins/sudoers/bsm_audit.c:167
+#: plugins/sudoers/bsm_audit.c:61 plugins/sudoers/bsm_audit.c:64
+#: plugins/sudoers/bsm_audit.c:113 plugins/sudoers/bsm_audit.c:117
+#: plugins/sudoers/bsm_audit.c:169 plugins/sudoers/bsm_audit.c:173
 msgid "getaudit: failed"
 msgstr "getaudit:失败"
 
-#: plugins/sudoers/bsm_audit.c:87 plugins/sudoers/bsm_audit.c:148
+#: plugins/sudoers/bsm_audit.c:91 plugins/sudoers/bsm_audit.c:154
 msgid "Could not determine audit condition"
 msgstr "无法确定审核条件"
 
-#: plugins/sudoers/bsm_audit.c:98
+#: plugins/sudoers/bsm_audit.c:102
 msgid "getauid failed"
 msgstr "getauid 失败"
 
-#: plugins/sudoers/bsm_audit.c:100 plugins/sudoers/bsm_audit.c:157
+#: plugins/sudoers/bsm_audit.c:104 plugins/sudoers/bsm_audit.c:163
 msgid "au_open: failed"
 msgstr "au_open:失败"
 
-#: plugins/sudoers/bsm_audit.c:115 plugins/sudoers/bsm_audit.c:169
+#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:175
 msgid "au_to_subject: failed"
 msgstr "au_to_subject:失败"
 
-#: plugins/sudoers/bsm_audit.c:119 plugins/sudoers/bsm_audit.c:173
+#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:179
 msgid "au_to_exec_args: failed"
 msgstr "au_to_exec_args:失败"
 
-#: plugins/sudoers/bsm_audit.c:123 plugins/sudoers/bsm_audit.c:182
+#: plugins/sudoers/bsm_audit.c:127 plugins/sudoers/bsm_audit.c:188
 msgid "au_to_return32: failed"
 msgstr "au_to_return32:失败"
 
-#: plugins/sudoers/bsm_audit.c:126 plugins/sudoers/bsm_audit.c:185
+#: plugins/sudoers/bsm_audit.c:130 plugins/sudoers/bsm_audit.c:191
 msgid "unable to commit audit record"
 msgstr "无法提交审核记录"
 
-#: plugins/sudoers/bsm_audit.c:155
+#: plugins/sudoers/bsm_audit.c:161
 msgid "getauid: failed"
 msgstr "getauid:失败"
 
-#: plugins/sudoers/bsm_audit.c:178
+#: plugins/sudoers/bsm_audit.c:184
 msgid "au_to_text: failed"
 msgstr "au_to_text:失败"
 
-#: plugins/sudoers/check.c:141
+#: plugins/sudoers/check.c:158
 #, c-format
 msgid "sorry, a password is required to run %s"
 msgstr "抱歉,执行 %s 需要密码"
 
-#: plugins/sudoers/check.c:225 plugins/sudoers/iolog.c:169
-#: plugins/sudoers/sudoers.c:971 plugins/sudoers/sudoreplay.c:325
-#: plugins/sudoers/sudoreplay.c:334 plugins/sudoers/sudoreplay.c:675
-#: plugins/sudoers/sudoreplay.c:767 plugins/sudoers/visudo.c:744
+#: plugins/sudoers/check.c:249 plugins/sudoers/iolog.c:172
+#: plugins/sudoers/sudoers.c:992 plugins/sudoers/sudoreplay.c:348
+#: plugins/sudoers/sudoreplay.c:357 plugins/sudoers/sudoreplay.c:703
+#: plugins/sudoers/sudoreplay.c:797 plugins/sudoers/visudo.c:790
 #, c-format
 msgid "unable to open %s"
 msgstr "无法打开 %s"
 
-#: plugins/sudoers/check.c:229 plugins/sudoers/iolog.c:199
+#: plugins/sudoers/check.c:253 plugins/sudoers/iolog.c:202
 #, c-format
 msgid "unable to write to %s"
 msgstr "无法写入 %s"
 
-#: plugins/sudoers/check.c:237 plugins/sudoers/check.c:475
-#: plugins/sudoers/check.c:525 plugins/sudoers/iolog.c:122
-#: plugins/sudoers/iolog.c:153
+#: plugins/sudoers/check.c:261 plugins/sudoers/check.c:506
+#: plugins/sudoers/check.c:556 plugins/sudoers/iolog.c:123
+#: plugins/sudoers/iolog.c:156
 #, c-format
 msgid "unable to mkdir %s"
 msgstr "无法创建目录 %s"
 
-#: plugins/sudoers/check.c:370
+#: plugins/sudoers/check.c:396
 #, c-format
 msgid "internal error, expand_prompt() overflow"
 msgstr "内部错误,expand_prompt() 溢出"
 
-#: plugins/sudoers/check.c:426
+#: plugins/sudoers/check.c:456
 #, c-format
 msgid "timestamp path too long: %s"
 msgstr "时间戳路径过长:%s"
 
-#: plugins/sudoers/check.c:454 plugins/sudoers/check.c:498
-#: plugins/sudoers/iolog.c:155
+#: plugins/sudoers/check.c:485 plugins/sudoers/check.c:529
+#: plugins/sudoers/iolog.c:158
 #, c-format
 msgid "%s exists but is not a directory (0%o)"
 msgstr "%s 存在,但不是目录(0%o)"
 
-#: plugins/sudoers/check.c:457 plugins/sudoers/check.c:501
-#: plugins/sudoers/check.c:546
+#: plugins/sudoers/check.c:488 plugins/sudoers/check.c:532
+#: plugins/sudoers/check.c:577
 #, c-format
 msgid "%s owned by uid %u, should be uid %u"
 msgstr "%s 属于用户 ID %u,应为用户 ID %u"
 
-#: plugins/sudoers/check.c:462 plugins/sudoers/check.c:506
+#: plugins/sudoers/check.c:493 plugins/sudoers/check.c:537
 #, c-format
 msgid "%s writable by non-owner (0%o), should be mode 0700"
 msgstr "%s 对非所有者可写(0%o),模式应该为 0700"
 
-#: plugins/sudoers/check.c:470 plugins/sudoers/check.c:514
-#: plugins/sudoers/check.c:582 plugins/sudoers/sudoers.c:957
-#: plugins/sudoers/visudo.c:304 plugins/sudoers/visudo.c:544
+#: plugins/sudoers/check.c:501 plugins/sudoers/check.c:545
+#: plugins/sudoers/check.c:613 plugins/sudoers/sudoers.c:978
+#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:582
 #, c-format
 msgid "unable to stat %s"
 msgstr "无法 stat %s"
 
-#: plugins/sudoers/check.c:540
+#: plugins/sudoers/check.c:571
 #, c-format
 msgid "%s exists but is not a regular file (0%o)"
 msgstr "%s 存在,但不是常规文件(0%o)"
 
-#: plugins/sudoers/check.c:552
+#: plugins/sudoers/check.c:583
 #, c-format
 msgid "%s writable by non-owner (0%o), should be mode 0600"
 msgstr "%s 对非所有者可写(0%o),模式应该为 0600"
 
-#: plugins/sudoers/check.c:606
+#: plugins/sudoers/check.c:637
 #, c-format
 msgid "timestamp too far in the future: %20.20s"
 msgstr "时间戳太超前:%20.20s"
 
-#: plugins/sudoers/check.c:652
+#: plugins/sudoers/check.c:684
 #, c-format
 msgid "unable to remove %s (%s), will reset to the epoch"
 msgstr "无法移除 %s (%s),将重设为戳记"
 
-#: plugins/sudoers/check.c:660
+#: plugins/sudoers/check.c:692
 #, c-format
 msgid "unable to reset %s to the epoch"
 msgstr "无法将 %s 重设为戳记"
 
-#: plugins/sudoers/check.c:714 plugins/sudoers/check.c:720
+#: plugins/sudoers/check.c:752 plugins/sudoers/check.c:758
+#: plugins/sudoers/sudoers.c:829 plugins/sudoers/sudoers.c:833
 #, c-format
 msgid "unknown uid: %u"
 msgstr "未知的用户 ID:%u"
 
-#: plugins/sudoers/check.c:717 plugins/sudoers/sudoers.c:748
-#: plugins/sudoers/sudoers.c:814 plugins/sudoers/sudoers.c:815
-#: plugins/sudoers/sudoers.c:1088 plugins/sudoers/testsudoers.c:202
-#: plugins/sudoers/testsudoers.c:337
+#: plugins/sudoers/check.c:755 plugins/sudoers/sudoers.c:770
+#: plugins/sudoers/sudoers.c:1108 plugins/sudoers/testsudoers.c:218
+#: plugins/sudoers/testsudoers.c:362
 #, c-format
 msgid "unknown user: %s"
 msgstr "未知用户:%s"
@@ -403,298 +403,296 @@ msgid "When to require a password for 'verify' pseudocommand: %s"
 msgstr "何时为“verify”伪命令请求密码:%s"
 
 #: plugins/sudoers/def_data.c:243
-msgid "Preload the dummy exec functions contained in 'noexec_file'"
-msgstr "预加载“noexec_file”中包含的哑 exec 函数"
+msgid "Preload the dummy exec functions contained in \"_PATH_SUDO_NOEXEC"
+msgstr "预加载“_PATH_SUDO_NOEXEC”中包含的哑 exec 函数"
 
 #: plugins/sudoers/def_data.c:247
-#, c-format
-msgid "File containing dummy exec functions: %s"
-msgstr "含有哑 exec 函数的文件:%s"
-
-#: plugins/sudoers/def_data.c:251
 msgid "If LDAP directory is up, do we ignore local sudoers file"
 msgstr "如果 LDAP 目录有效,是不是忽略本地的 sudoers 文件"
 
-#: plugins/sudoers/def_data.c:255
+#: plugins/sudoers/def_data.c:251
 #, c-format
 msgid "File descriptors >= %d will be closed before executing a command"
 msgstr ">= %d 的文件描述符将会在执行命令前关闭"
 
-#: plugins/sudoers/def_data.c:259
+#: plugins/sudoers/def_data.c:255
 msgid "If set, users may override the value of `closefrom' with the -C option"
 msgstr "如果设置,用户可以通过 -C 选项覆盖“closefrom”的值"
 
-#: plugins/sudoers/def_data.c:263
+#: plugins/sudoers/def_data.c:259
 msgid "Allow users to set arbitrary environment variables"
 msgstr "允许用户设置任意的环境变量"
 
-#: plugins/sudoers/def_data.c:267
+#: plugins/sudoers/def_data.c:263
 msgid "Reset the environment to a default set of variables"
 msgstr "将环境重设为默认的变量集"
 
-#: plugins/sudoers/def_data.c:271
+#: plugins/sudoers/def_data.c:267
 msgid "Environment variables to check for sanity:"
 msgstr "要检查完整性的环境变量:"
 
-#: plugins/sudoers/def_data.c:275
+#: plugins/sudoers/def_data.c:271
 msgid "Environment variables to remove:"
 msgstr "要移除的环境变量:"
 
-#: plugins/sudoers/def_data.c:279
+#: plugins/sudoers/def_data.c:275
 msgid "Environment variables to preserve:"
 msgstr "要保留的环境变量:"
 
-#: plugins/sudoers/def_data.c:283
+#: plugins/sudoers/def_data.c:279
 #, c-format
 msgid "SELinux role to use in the new security context: %s"
 msgstr "在新的安全环境中使用的 SELinux 角色:%s"
 
-#: plugins/sudoers/def_data.c:287
+#: plugins/sudoers/def_data.c:283
 #, c-format
 msgid "SELinux type to use in the new security context: %s"
 msgstr "在新的安全环境中使用的 SELinux 类型:%s"
 
-#: plugins/sudoers/def_data.c:291
+#: plugins/sudoers/def_data.c:287
 #, c-format
 msgid "Path to the sudo-specific environment file: %s"
 msgstr "sudo 特定环境文件的路径:%s"
 
-#: plugins/sudoers/def_data.c:295
+#: plugins/sudoers/def_data.c:291
 #, c-format
 msgid "Locale to use while parsing sudoers: %s"
 msgstr "解析 sudoers 时使用的区域设置:%s"
 
-#: plugins/sudoers/def_data.c:299
-msgid "Allow sudo to prompt for a password even if it would be visisble"
+#: plugins/sudoers/def_data.c:295
+msgid "Allow sudo to prompt for a password even if it would be visible"
 msgstr "允许 sudo 询问密码,即使它不可见"
 
-#: plugins/sudoers/def_data.c:303
+#: plugins/sudoers/def_data.c:299
 msgid "Provide visual feedback at the password prompt when there is user input"
 msgstr "用户在询问密码窗口输入时提供视觉反馈"
 
-#: plugins/sudoers/def_data.c:307
+#: plugins/sudoers/def_data.c:303
 msgid "Use faster globbing that is less accurate but does not access the filesystem"
 msgstr "使用不太精确但不访问文件系统的较快通配方法"
 
-#: plugins/sudoers/def_data.c:311
+#: plugins/sudoers/def_data.c:307
 msgid "The umask specified in sudoers will override the user's, even if it is more permissive"
 msgstr "sudoers 中指定的 umask 会覆盖用户的,即使它允许的权限更多"
 
-#: plugins/sudoers/def_data.c:315
+#: plugins/sudoers/def_data.c:311
 msgid "Log user's input for the command being run"
 msgstr "记录用户在所执行命令中的输入"
 
-#: plugins/sudoers/def_data.c:319
+#: plugins/sudoers/def_data.c:315
 msgid "Log the output of the command being run"
 msgstr "记录所执行命令的输出"
 
-#: plugins/sudoers/def_data.c:323
+#: plugins/sudoers/def_data.c:319
 msgid "Compress I/O logs using zlib"
 msgstr "使用 zlib 压缩 I/O 日志"
 
-#: plugins/sudoers/def_data.c:327
+#: plugins/sudoers/def_data.c:323
 msgid "Always run commands in a pseudo-tty"
 msgstr "总是在伪终端中运行命令"
 
+#: plugins/sudoers/def_data.c:327
+#, c-format
+msgid "Plugin for non-Unix group support: %s"
+msgstr "用于非 Unix 组支持的插件:%s"
+
 #: plugins/sudoers/def_data.c:331
-msgid "Plugin for non-Unix group support"
-msgstr "用于非 Unix 组支持的插件"
+#, c-format
+msgid "Directory in which to store input/output logs: %s"
+msgstr "用于保存输入/输出日志的目录:%s"
 
 #: plugins/sudoers/def_data.c:335
-msgid "Directory in which to store input/output logs"
-msgstr "用于保存输入/输出日志的目录"
+#, c-format
+msgid "File in which to store the input/output log: %s"
+msgstr "用于保存输入/输出日志的文件:%s"
 
 #: plugins/sudoers/def_data.c:339
-msgid "File in which to store the input/output log"
-msgstr "用于保存输入/输出日志的文件"
-
-#: plugins/sudoers/def_data.c:343
 msgid "Add an entry to the utmp/utmpx file when allocating a pty"
 msgstr "在分配伪终端时向 utmp/utmpx 文件中添加一条记录"
 
-#: plugins/sudoers/def_data.c:347
+#: plugins/sudoers/def_data.c:343
 msgid "Set the user in utmp to the runas user, not the invoking user"
 msgstr "将 utmp 中的用户设为 runas 用户,而不是调用用户"
 
-#: plugins/sudoers/defaults.c:205
+#: plugins/sudoers/defaults.c:208
 #, c-format
 msgid "unknown defaults entry `%s'"
 msgstr "未知的默认条目“%s”"
 
-#: plugins/sudoers/defaults.c:213 plugins/sudoers/defaults.c:223
-#: plugins/sudoers/defaults.c:243 plugins/sudoers/defaults.c:256
-#: plugins/sudoers/defaults.c:269 plugins/sudoers/defaults.c:282
-#: plugins/sudoers/defaults.c:295 plugins/sudoers/defaults.c:315
-#: plugins/sudoers/defaults.c:325
+#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
+#: plugins/sudoers/defaults.c:246 plugins/sudoers/defaults.c:259
+#: plugins/sudoers/defaults.c:272 plugins/sudoers/defaults.c:285
+#: plugins/sudoers/defaults.c:298 plugins/sudoers/defaults.c:318
+#: plugins/sudoers/defaults.c:328
 #, c-format
 msgid "value `%s' is invalid for option `%s'"
 msgstr "值“%s”对选项“%s”无效"
 
-#: plugins/sudoers/defaults.c:216 plugins/sudoers/defaults.c:226
-#: plugins/sudoers/defaults.c:234 plugins/sudoers/defaults.c:251
-#: plugins/sudoers/defaults.c:264 plugins/sudoers/defaults.c:277
-#: plugins/sudoers/defaults.c:290 plugins/sudoers/defaults.c:310
-#: plugins/sudoers/defaults.c:321
+#: plugins/sudoers/defaults.c:219 plugins/sudoers/defaults.c:229
+#: plugins/sudoers/defaults.c:237 plugins/sudoers/defaults.c:254
+#: plugins/sudoers/defaults.c:267 plugins/sudoers/defaults.c:280
+#: plugins/sudoers/defaults.c:293 plugins/sudoers/defaults.c:313
+#: plugins/sudoers/defaults.c:324
 #, c-format
 msgid "no value specified for `%s'"
 msgstr "没有给“%s”指定值"
 
-#: plugins/sudoers/defaults.c:239
+#: plugins/sudoers/defaults.c:242
 #, c-format
 msgid "values for `%s' must start with a '/'"
 msgstr "“%s”的值必须以“/”开头"
 
-#: plugins/sudoers/defaults.c:301
+#: plugins/sudoers/defaults.c:304
 #, c-format
 msgid "option `%s' does not take a value"
 msgstr "“%s”选项不带值"
 
-#: plugins/sudoers/env.c:259
+#: plugins/sudoers/env.c:258
 #, c-format
 msgid "internal error, sudo_setenv() overflow"
 msgstr "内部错误,sudo_setenv()溢出"
 
-#: plugins/sudoers/env.c:289
+#: plugins/sudoers/env.c:291
 #, c-format
 msgid "sudo_putenv: corrupted envp, length mismatch"
 msgstr "sudo_putenv:envp 损坏,长度不符"
 
-#: plugins/sudoers/env.c:698
+#: plugins/sudoers/env.c:710
 #, c-format
 msgid "sorry, you are not allowed to set the following environment variables: %s"
 msgstr "对不起,您无权设置以下环境变量:%s"
 
-#: plugins/sudoers/find_path.c:68 plugins/sudoers/find_path.c:107
-#: plugins/sudoers/find_path.c:122 plugins/sudoers/iolog.c:124
-#: plugins/sudoers/sudoers.c:903 toke.l:663 toke.l:814
+#: plugins/sudoers/find_path.c:69 plugins/sudoers/find_path.c:108
+#: plugins/sudoers/find_path.c:123 plugins/sudoers/iolog.c:125
+#: plugins/sudoers/sudoers.c:923 toke.l:668 toke.l:823
 #, c-format
 msgid "%s: %s"
 msgstr "%s:%s"
 
-#: gram.y:103
+#: gram.y:110
 #, c-format
 msgid ">>> %s: %s near line %d <<<"
 msgstr ">>> %s:%s 在行 %d 附近<<<"
 
-#: plugins/sudoers/group_plugin.c:90
+#: plugins/sudoers/group_plugin.c:91
 #, c-format
 msgid "%s%s: %s"
 msgstr "%s%s:%s"
 
-#: plugins/sudoers/group_plugin.c:102
+#: plugins/sudoers/group_plugin.c:103
 #, c-format
 msgid "%s must be owned by uid %d"
 msgstr "%s 必须属于用户 ID %d"
 
-#: plugins/sudoers/group_plugin.c:106
+#: plugins/sudoers/group_plugin.c:107
 #, c-format
 msgid "%s must only be writable by owner"
 msgstr "%s 必须只对所有者可写"
 
-#: plugins/sudoers/group_plugin.c:113
+#: plugins/sudoers/group_plugin.c:114
 #, c-format
 msgid "unable to dlopen %s: %s"
 msgstr "无法执行 dlopen %s:%s"
 
-#: plugins/sudoers/group_plugin.c:118
+#: plugins/sudoers/group_plugin.c:119
 #, c-format
 msgid "unable to find symbol \"group_plugin\" in %s"
 msgstr "无法在 %s 中找到符号“group_plugin”"
 
-#: plugins/sudoers/group_plugin.c:123
+#: plugins/sudoers/group_plugin.c:124
 #, c-format
 msgid "%s: incompatible group plugin major version %d, expected %d"
 msgstr "%s:不兼容的组插件主版本号 %d,应为 %d"
 
-#: plugins/sudoers/interfaces.c:109
+#: plugins/sudoers/interfaces.c:112
 msgid "Local IP address and netmask pairs:\n"
 msgstr "本地 IP 地址和网络掩码对:\n"
 
-#: plugins/sudoers/iolog.c:176 plugins/sudoers/sudoers.c:978
+#: plugins/sudoers/iolog.c:179 plugins/sudoers/sudoers.c:999
 #, c-format
 msgid "unable to read %s"
 msgstr "无法读取 %s"
 
-#: plugins/sudoers/iolog.c:179
+#: plugins/sudoers/iolog.c:182
 #, c-format
 msgid "invalid sequence number %s"
 msgstr "无效的序列号:%s"
 
-#: plugins/sudoers/iolog.c:225 plugins/sudoers/iolog.c:228
-#: plugins/sudoers/iolog.c:478 plugins/sudoers/iolog.c:483
-#: plugins/sudoers/iolog.c:489 plugins/sudoers/iolog.c:497
-#: plugins/sudoers/iolog.c:505 plugins/sudoers/iolog.c:513
-#: plugins/sudoers/iolog.c:521
+#: plugins/sudoers/iolog.c:231 plugins/sudoers/iolog.c:234
+#: plugins/sudoers/iolog.c:499 plugins/sudoers/iolog.c:504
+#: plugins/sudoers/iolog.c:510 plugins/sudoers/iolog.c:518
+#: plugins/sudoers/iolog.c:526 plugins/sudoers/iolog.c:534
+#: plugins/sudoers/iolog.c:542
 #, c-format
 msgid "unable to create %s"
 msgstr "无法创建 %s"
 
-#: plugins/sudoers/iolog_path.c:247 plugins/sudoers/sudoers.c:357
+#: plugins/sudoers/iolog_path.c:256 plugins/sudoers/sudoers.c:362
 #, c-format
 msgid "unable to set locale to \"%s\", using \"C\""
 msgstr "无法将区域设置为“%s”,将使用“C”"
 
-#: plugins/sudoers/ldap.c:368
+#: plugins/sudoers/ldap.c:374
 #, c-format
 msgid "sudo_ldap_conf_add_ports: port too large"
 msgstr "sudo_ldap_conf_add_ports:端口太大"
 
-#: plugins/sudoers/ldap.c:391
+#: plugins/sudoers/ldap.c:397
 #, c-format
 msgid "sudo_ldap_conf_add_ports: out of space expanding hostbuf"
 msgstr "sudo_ldap_conf_add_ports:扩展主机缓存时空间不足"
 
-#: plugins/sudoers/ldap.c:420
+#: plugins/sudoers/ldap.c:427
 #, c-format
 msgid "unsupported LDAP uri type: %s"
 msgstr "不支持的 LDAP URI 类型:%s"
 
-#: plugins/sudoers/ldap.c:449
+#: plugins/sudoers/ldap.c:456
 #, c-format
 msgid "invalid uri: %s"
 msgstr "无效的 URI:%s"
 
-#: plugins/sudoers/ldap.c:455
+#: plugins/sudoers/ldap.c:462
 #, c-format
 msgid "unable to mix ldap and ldaps URIs"
 msgstr "无法混合 ldap 和 ldaps URI"
 
-#: plugins/sudoers/ldap.c:459
+#: plugins/sudoers/ldap.c:466
 #, c-format
 msgid "unable to mix ldaps and starttls"
 msgstr "无法混合 ldaps 和 starttls"
 
-#: plugins/sudoers/ldap.c:478
+#: plugins/sudoers/ldap.c:485
 #, c-format
 msgid "sudo_ldap_parse_uri: out of space building hostbuf"
 msgstr "sudo_ldap_parse_uri:构建主机缓存时空间不足"
 
-#: plugins/sudoers/ldap.c:541
+#: plugins/sudoers/ldap.c:550
 #, c-format
 msgid "unable to initialize SSL cert and key db: %s"
 msgstr "无法初始化 SSL 证书和密钥数据库:%s"
 
-#: plugins/sudoers/ldap.c:937
+#: plugins/sudoers/ldap.c:958
 #, c-format
 msgid "unable to get GMT time"
 msgstr "无法获取 GMT 时间"
 
-#: plugins/sudoers/ldap.c:943
+#: plugins/sudoers/ldap.c:964
 #, c-format
 msgid "unable to format timestamp"
 msgstr "无法格式化时间戳"
 
-#: plugins/sudoers/ldap.c:951
+#: plugins/sudoers/ldap.c:972
 #, c-format
 msgid "unable to build time filter"
 msgstr "无法构建时间过滤器"
 
-#: plugins/sudoers/ldap.c:1052
+#: plugins/sudoers/ldap.c:1185
 #, c-format
 msgid "sudo_ldap_build_pass1 allocation mismatch"
 msgstr "sudo_ldap_build_pass1 分配不匹配"
 
-#: plugins/sudoers/ldap.c:1562
+#: plugins/sudoers/ldap.c:1705
 #, c-format
 msgid ""
 "\n"
@@ -703,7 +701,7 @@ msgstr ""
 "\n"
 "LDAP 角色:%s\n"
 
-#: plugins/sudoers/ldap.c:1564
+#: plugins/sudoers/ldap.c:1707
 #, c-format
 msgid ""
 "\n"
@@ -712,124 +710,129 @@ msgstr ""
 "\n"
 "LDAP 角色:未知\n"
 
-#: plugins/sudoers/ldap.c:1611
+#: plugins/sudoers/ldap.c:1754
 #, c-format
 msgid "    Order: %s\n"
 msgstr "    顺序:%s\n"
 
-#: plugins/sudoers/ldap.c:1619
+#: plugins/sudoers/ldap.c:1762
 #, c-format
 msgid "    Commands:\n"
 msgstr "    命令:\n"
 
-#: plugins/sudoers/ldap.c:2006
+#: plugins/sudoers/ldap.c:2161
 #, c-format
 msgid "unable to initialize LDAP: %s"
 msgstr "无法初始化 LDAP:%s"
 
-#: plugins/sudoers/ldap.c:2037
+#: plugins/sudoers/ldap.c:2192
 #, c-format
 msgid "start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()"
 msgstr "指定了 start_tls,但 LDAP 库不支持 ldap_start_tls_s() 或 ldap_start_tls_s_np()"
 
-#: plugins/sudoers/ldap.c:2268
+#: plugins/sudoers/ldap.c:2428
 #, c-format
 msgid "invalid sudoOrder attribute: %s"
 msgstr "无效的 sudoOrder 属性:%s"
 
-#: plugins/sudoers/linux_audit.c:55
+#: plugins/sudoers/linux_audit.c:57
 #, c-format
 msgid "unable to open audit system"
 msgstr "无法打开审核系统"
 
-#: plugins/sudoers/linux_audit.c:79
+#: plugins/sudoers/linux_audit.c:82
 #, c-format
 msgid "internal error, linux_audit_command() overflow"
 msgstr "内部错误,linux_audit_command() 溢出"
 
-#: plugins/sudoers/linux_audit.c:88
+#: plugins/sudoers/linux_audit.c:91
 #, c-format
 msgid "unable to send audit message"
 msgstr "无法发送审核消息"
 
-#: plugins/sudoers/logging.c:192
+#: plugins/sudoers/logging.c:198
 #, c-format
 msgid "unable to open log file: %s: %s"
 msgstr "无法打开日志文件:%s:%s"
 
-#: plugins/sudoers/logging.c:195
+#: plugins/sudoers/logging.c:201
 #, c-format
 msgid "unable to lock log file: %s: %s"
 msgstr "无法锁定日志文件:%s:%s"
 
-#: plugins/sudoers/logging.c:249
+#: plugins/sudoers/logging.c:256
 msgid "user NOT in sudoers"
 msgstr "用户不在 sudoers 中"
 
-#: plugins/sudoers/logging.c:251
+#: plugins/sudoers/logging.c:258
 msgid "user NOT authorized on host"
 msgstr "用户未获得此主机上的授权"
 
-#: plugins/sudoers/logging.c:253
+#: plugins/sudoers/logging.c:260
 msgid "command not allowed"
 msgstr "命令禁止使用"
 
-#: plugins/sudoers/logging.c:263
+#: plugins/sudoers/logging.c:270
 #, c-format
 msgid "%s is not in the sudoers file.  This incident will be reported.\n"
 msgstr "%s 不在 sudoers 文件中。此事将被报告。\n"
 
-#: plugins/sudoers/logging.c:266
+#: plugins/sudoers/logging.c:273
 #, c-format
 msgid "%s is not allowed to run sudo on %s.  This incident will be reported.\n"
 msgstr "%s 无权在 %s 上运行 sudo。此事将被报告。\n"
 
-#: plugins/sudoers/logging.c:270
+#: plugins/sudoers/logging.c:277
 #, c-format
 msgid "Sorry, user %s may not run sudo on %s.\n"
 msgstr "对不起,用户 %s 不能在 %s 上运行 sudo。\n"
 
-#: plugins/sudoers/logging.c:273
+#: plugins/sudoers/logging.c:280
 #, c-format
 msgid "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n"
 msgstr "对不起,用户 %1$s 无权以 %5$s%6$s%7$s 的身份在 %8$s 上执行 %2$s%3$s%4$s。\n"
 
-#: plugins/sudoers/logging.c:408
+#: plugins/sudoers/logging.c:420
 #, c-format
 msgid "unable to fork"
 msgstr "无法执行 fork"
 
-#: plugins/sudoers/logging.c:415 plugins/sudoers/logging.c:472
+#: plugins/sudoers/logging.c:427 plugins/sudoers/logging.c:489
 #, c-format
 msgid "unable to fork: %m"
 msgstr "无法执行 fork:%m"
 
-#: plugins/sudoers/logging.c:465
+#: plugins/sudoers/logging.c:479
 #, c-format
 msgid "unable to open pipe: %m"
 msgstr "无法打开管道:%m"
 
-#: plugins/sudoers/logging.c:484
+#: plugins/sudoers/logging.c:504
 #, c-format
 msgid "unable to dup stdin: %m"
 msgstr "无法 dup stdin:%m"
 
-#: plugins/sudoers/logging.c:518
+#: plugins/sudoers/logging.c:540
 #, c-format
 msgid "unable to execute %s: %m"
 msgstr "无法执行 %s:%m"
 
-#: plugins/sudoers/logging.c:728
+#: plugins/sudoers/logging.c:755
 #, c-format
 msgid "internal error: insufficient space for log line"
 msgstr "内部错误:没有足够的空间存放日志行"
 
-#: plugins/sudoers/parse.c:115
+#: plugins/sudoers/parse.c:123
 #, c-format
 msgid "parse error in %s near line %d"
 msgstr "%s 中第 %d 行附近有解析错误"
 
-#: plugins/sudoers/parse.c:371
+#: plugins/sudoers/parse.c:126
+#, c-format
+msgid "parse error in %s"
+msgstr "%s 中出现解析错误"
+
+#: plugins/sudoers/parse.c:389
 #, c-format
 msgid ""
 "\n"
@@ -838,17 +841,17 @@ msgstr ""
 "\n"
 "Sudoers 条目:\n"
 
-#: plugins/sudoers/parse.c:373
+#: plugins/sudoers/parse.c:391
 #, c-format
 msgid "    RunAsUsers: "
 msgstr "    RunAs 用户:"
 
-#: plugins/sudoers/parse.c:388
+#: plugins/sudoers/parse.c:406
 #, c-format
 msgid "    RunAsGroups: "
 msgstr "    RunAs 组:"
 
-#: plugins/sudoers/parse.c:397
+#: plugins/sudoers/parse.c:415
 #, c-format
 msgid ""
 "    Commands:\n"
@@ -861,99 +864,99 @@ msgstr ""
 msgid ": "
 msgstr ":"
 
-#: plugins/sudoers/pwutil.c:251
+#: plugins/sudoers/pwutil.c:260
 #, c-format
 msgid "unable to cache uid %u (%s), already exists"
 msgstr "无法缓存用户 ID %u(%s),已存在"
 
-#: plugins/sudoers/pwutil.c:259
+#: plugins/sudoers/pwutil.c:268
 #, c-format
 msgid "unable to cache uid %u, already exists"
 msgstr "无法缓存用户 ID %u,已存在"
 
-#: plugins/sudoers/pwutil.c:295 plugins/sudoers/pwutil.c:304
+#: plugins/sudoers/pwutil.c:305 plugins/sudoers/pwutil.c:314
 #, c-format
 msgid "unable to cache user %s, already exists"
 msgstr "无法缓存用户 %s,已存在"
 
-#: plugins/sudoers/pwutil.c:607
+#: plugins/sudoers/pwutil.c:655
 #, c-format
 msgid "unable to cache gid %u (%s), already exists"
 msgstr "无法缓存组 ID %u(%s),已存在"
 
-#: plugins/sudoers/pwutil.c:615
+#: plugins/sudoers/pwutil.c:663
 #, c-format
 msgid "unable to cache gid %u, already exists"
 msgstr "无法缓存组 ID %u,已存在"
 
-#: plugins/sudoers/pwutil.c:644 plugins/sudoers/pwutil.c:653
+#: plugins/sudoers/pwutil.c:693 plugins/sudoers/pwutil.c:702
 #, c-format
 msgid "unable to cache group %s, already exists"
 msgstr "无法缓存组 %s,已存在"
 
-#: plugins/sudoers/set_perms.c:109 plugins/sudoers/set_perms.c:358
-#: plugins/sudoers/set_perms.c:590 plugins/sudoers/set_perms.c:824
+#: plugins/sudoers/set_perms.c:114 plugins/sudoers/set_perms.c:365
+#: plugins/sudoers/set_perms.c:601 plugins/sudoers/set_perms.c:837
 #, fuzzy
 msgid "perm stack overflow"
 msgstr "perm 堆栈上溢"
 
-#: plugins/sudoers/set_perms.c:117 plugins/sudoers/set_perms.c:366
-#: plugins/sudoers/set_perms.c:598 plugins/sudoers/set_perms.c:832
+#: plugins/sudoers/set_perms.c:122 plugins/sudoers/set_perms.c:373
+#: plugins/sudoers/set_perms.c:609 plugins/sudoers/set_perms.c:845
 #, fuzzy
 msgid "perm stack underflow"
 msgstr "perm 堆栈下溢"
 
-#: plugins/sudoers/set_perms.c:223 plugins/sudoers/set_perms.c:458
-#: plugins/sudoers/set_perms.c:695
+#: plugins/sudoers/set_perms.c:228 plugins/sudoers/set_perms.c:466
+#: plugins/sudoers/set_perms.c:706
 msgid "unable to change to runas gid"
 msgstr "无法切换为 runas 组 ID"
 
-#: plugins/sudoers/set_perms.c:231 plugins/sudoers/set_perms.c:465
-#: plugins/sudoers/set_perms.c:702
+#: plugins/sudoers/set_perms.c:236 plugins/sudoers/set_perms.c:473
+#: plugins/sudoers/set_perms.c:713
 msgid "unable to change to runas uid"
 msgstr "无法切换为 runas 用户 ID"
 
-#: plugins/sudoers/set_perms.c:245 plugins/sudoers/set_perms.c:478
-#: plugins/sudoers/set_perms.c:715
+#: plugins/sudoers/set_perms.c:250 plugins/sudoers/set_perms.c:486
+#: plugins/sudoers/set_perms.c:726
 #, c-format
 msgid "unable to change to sudoers gid"
 msgstr "无法切换为 sudoers 组 ID"
 
-#: plugins/sudoers/set_perms.c:286 plugins/sudoers/set_perms.c:516
-#: plugins/sudoers/set_perms.c:753 plugins/sudoers/set_perms.c:893
+#: plugins/sudoers/set_perms.c:291 plugins/sudoers/set_perms.c:524
+#: plugins/sudoers/set_perms.c:764 plugins/sudoers/set_perms.c:906
 msgid "too many processes"
 msgstr "进程过多"
 
-#: plugins/sudoers/set_perms.c:955
+#: plugins/sudoers/set_perms.c:970
 msgid "unable to set runas group vector"
 msgstr "无法设置 runas 组向量"
 
-#: plugins/sudoers/sudo_nss.c:238
+#: plugins/sudoers/sudo_nss.c:243
 #, c-format
 msgid "Matching Defaults entries for %s on this host:\n"
 msgstr "匹配此主机上 %s 的默认条目:\n"
 
-#: plugins/sudoers/sudo_nss.c:251
+#: plugins/sudoers/sudo_nss.c:256
 #, c-format
 msgid "Runas and Command-specific defaults for %s:\n"
 msgstr "%s Runas 和命令特定的默认值:\n"
 
-#: plugins/sudoers/sudo_nss.c:264
+#: plugins/sudoers/sudo_nss.c:269
 #, c-format
 msgid "User %s may run the following commands on this host:\n"
 msgstr "用户 %s 可以在该主机上运行以下命令:\n"
 
-#: plugins/sudoers/sudo_nss.c:274
+#: plugins/sudoers/sudo_nss.c:279
 #, c-format
 msgid "User %s is not allowed to run sudo on %s.\n"
 msgstr "用户 %s 无权在 %s 上运行 sudo。\n"
 
-#: plugins/sudoers/sudoers.c:199 plugins/sudoers/sudoers.c:234
-#: plugins/sudoers/sudoers.c:911
+#: plugins/sudoers/sudoers.c:201 plugins/sudoers/sudoers.c:232
+#: plugins/sudoers/sudoers.c:931
 msgid "problem with defaults entries"
 msgstr "默认条目有问题"
 
-#: plugins/sudoers/sudoers.c:203
+#: plugins/sudoers/sudoers.c:205
 #, c-format
 msgid "no valid sudoers sources found, quitting"
 msgstr "没有找到有效的 sudoers 资源,退出"
@@ -963,42 +966,42 @@ msgstr "没有找到有效的 sudoers 资源,退出"
 msgid "unable to execute %s: %s"
 msgstr "无法执行 %s:%s"
 
-#: plugins/sudoers/sudoers.c:306
+#: plugins/sudoers/sudoers.c:311
 #, c-format
 msgid "sudoers specifies that root is not allowed to sudo"
 msgstr "sudoers 指定 root 不允许执行 sudo"
 
-#: plugins/sudoers/sudoers.c:313
+#: plugins/sudoers/sudoers.c:318
 #, c-format
 msgid "you are not permitted to use the -C option"
 msgstr "您无权使用 -C 选项"
 
-#: plugins/sudoers/sudoers.c:403
+#: plugins/sudoers/sudoers.c:408
 #, c-format
 msgid "timestamp owner (%s): No such user"
 msgstr "时间戳所有者(%s):无此用户"
 
-#: plugins/sudoers/sudoers.c:419
+#: plugins/sudoers/sudoers.c:424
 msgid "no tty"
 msgstr "无终端"
 
-#: plugins/sudoers/sudoers.c:420
+#: plugins/sudoers/sudoers.c:425
 #, c-format
 msgid "sorry, you must have a tty to run sudo"
 msgstr "抱歉,您必须拥有一个终端来执行 sudo"
 
-#: plugins/sudoers/sudoers.c:463
+#: plugins/sudoers/sudoers.c:464
 msgid "No user or host"
 msgstr "无用户或主机"
 
-#: plugins/sudoers/sudoers.c:477 plugins/sudoers/sudoers.c:498
-#: plugins/sudoers/sudoers.c:499 plugins/sudoers/sudoers.c:1465
-#: plugins/sudoers/sudoers.c:1466
+#: plugins/sudoers/sudoers.c:478 plugins/sudoers/sudoers.c:499
+#: plugins/sudoers/sudoers.c:500 plugins/sudoers/sudoers.c:1509
+#: plugins/sudoers/sudoers.c:1510
 #, c-format
 msgid "%s: command not found"
 msgstr "%s:找不到命令"
 
-#: plugins/sudoers/sudoers.c:479 plugins/sudoers/sudoers.c:495
+#: plugins/sudoers/sudoers.c:480 plugins/sudoers/sudoers.c:496
 #, c-format
 msgid ""
 "ignoring `%s' found in '.'\n"
@@ -1007,95 +1010,100 @@ msgstr ""
 "忽略在“.”中找到的“%s”\n"
 "请使用“sudo ./%s”,如果这是您想运行的“%s”。"
 
-#: plugins/sudoers/sudoers.c:484
+#: plugins/sudoers/sudoers.c:485
 msgid "validation failure"
 msgstr "校验失败"
 
-#: plugins/sudoers/sudoers.c:494
+#: plugins/sudoers/sudoers.c:495
 msgid "command in current directory"
 msgstr "当前目录中的命令"
 
-#: plugins/sudoers/sudoers.c:506
+#: plugins/sudoers/sudoers.c:507
 #, c-format
 msgid "sorry, you are not allowed to preserve the environment"
 msgstr "抱歉,您无权保留环境"
 
-#: plugins/sudoers/sudoers.c:894
+#: plugins/sudoers/sudoers.c:657 plugins/sudoers/sudoers.c:664
+#, c-format
+msgid "internal error, runas_groups overflow"
+msgstr "内部错误,runas_groups 溢出"
+
+#: plugins/sudoers/sudoers.c:914
 #, c-format
 msgid "internal error, set_cmnd() overflow"
 msgstr "内部错误:set_cmnd() 溢出"
 
-#: plugins/sudoers/sudoers.c:936
+#: plugins/sudoers/sudoers.c:957
 #, fuzzy, c-format
 msgid "fixed mode on %s"
 msgstr "对 %s 修正了模式"
 
-#: plugins/sudoers/sudoers.c:940
+#: plugins/sudoers/sudoers.c:961
 #, c-format
 msgid "set group on %s"
 msgstr "对 %s 设置组"
 
-#: plugins/sudoers/sudoers.c:943
+#: plugins/sudoers/sudoers.c:964
 #, c-format
 msgid "unable to set group on %s"
 msgstr "无法对 %s 设置组"
 
-#: plugins/sudoers/sudoers.c:946
+#: plugins/sudoers/sudoers.c:967
 #, c-format
 msgid "unable to fix mode on %s"
 msgstr "无法对 %s 修正模式"
 
-#: plugins/sudoers/sudoers.c:959
+#: plugins/sudoers/sudoers.c:980
 #, c-format
 msgid "%s is not a regular file"
 msgstr "%s 不是常规文件"
 
-#: plugins/sudoers/sudoers.c:961
+#: plugins/sudoers/sudoers.c:982
 #, c-format
 msgid "%s is mode 0%o, should be 0%o"
 msgstr "%s 的模式为 0%o,应为 0%o"
 
-#: plugins/sudoers/sudoers.c:965
+#: plugins/sudoers/sudoers.c:986
 #, c-format
 msgid "%s is owned by uid %u, should be %u"
 msgstr "%s 属于用户 ID %u,应为 %u"
 
-#: plugins/sudoers/sudoers.c:968
+#: plugins/sudoers/sudoers.c:989
 #, c-format
 msgid "%s is owned by gid %u, should be %u"
 msgstr "%s 属于组 ID %u,应为 %u"
 
-#: plugins/sudoers/sudoers.c:1012
+#: plugins/sudoers/sudoers.c:1038
 #, c-format
 msgid "only root can use `-c %s'"
 msgstr "只有 root 才能使用“-c %s”"
 
-#: plugins/sudoers/sudoers.c:1022
+#: plugins/sudoers/sudoers.c:1049
 #, c-format
 msgid "unknown login class: %s"
 msgstr "未知的登录类别:%s"
 
-#: plugins/sudoers/sudoers.c:1056
+#: plugins/sudoers/sudoers.c:1077
 #, c-format
 msgid "unable to resolve host %s"
 msgstr "无法解析主机:%s"
 
-#: plugins/sudoers/sudoers.c:1106 plugins/sudoers/testsudoers.c:351
+#: plugins/sudoers/sudoers.c:1129 plugins/sudoers/testsudoers.c:380
 #, c-format
 msgid "unknown group: %s"
 msgstr "未知组:%s"
 
-#: plugins/sudoers/sudoers.c:1150
+#: plugins/sudoers/sudoers.c:1178
 #, c-format
 msgid "Sudoers policy plugin version %s\n"
 msgstr "Sudoers 策略插件版本 %s\n"
 
-#: plugins/sudoers/sudoers.c:1152
+#: plugins/sudoers/sudoers.c:1180
 #, c-format
 msgid "Sudoers file grammar version %d\n"
 msgstr "Sudoers 文件语法版本 %d\n"
 
-#: plugins/sudoers/sudoers.c:1156
+#: plugins/sudoers/sudoers.c:1184
 #, c-format
 msgid ""
 "\n"
@@ -1104,147 +1112,147 @@ msgstr ""
 "\n"
 "Sudoers 路径:%s\n"
 
-#: plugins/sudoers/sudoers.c:1159
+#: plugins/sudoers/sudoers.c:1187
 #, c-format
 msgid "nsswitch path: %s\n"
 msgstr "nsswitch 路径:%s\n"
 
-#: plugins/sudoers/sudoers.c:1161
+#: plugins/sudoers/sudoers.c:1189
 #, c-format
 msgid "ldap.conf path: %s\n"
 msgstr "ldap.conf 路径:%s\n"
 
-#: plugins/sudoers/sudoers.c:1162
+#: plugins/sudoers/sudoers.c:1190
 #, c-format
 msgid "ldap.secret path: %s\n"
 msgstr "ldap.secret 路径:%s\n"
 
-#: plugins/sudoers/sudoreplay.c:265
+#: plugins/sudoers/sudoreplay.c:286
 #, c-format
 msgid "invalid filter option: %s"
 msgstr "无效的过滤器选项:%s"
 
-#: plugins/sudoers/sudoreplay.c:278
+#: plugins/sudoers/sudoreplay.c:299
 #, c-format
 msgid "invalid max wait: %s"
 msgstr "无效的最大等待:%s"
 
-#: plugins/sudoers/sudoreplay.c:284
+#: plugins/sudoers/sudoreplay.c:305
 #, c-format
 msgid "invalid speed factor: %s"
 msgstr "无法的速度系数:%s"
 
-#: plugins/sudoers/sudoreplay.c:287 plugins/sudoers/visudo.c:174
+#: plugins/sudoers/sudoreplay.c:308 plugins/sudoers/visudo.c:187
 #, c-format
 msgid "%s version %s\n"
 msgstr "%s 版本 %s\n"
 
-#: plugins/sudoers/sudoreplay.c:310
+#: plugins/sudoers/sudoreplay.c:333
 #, fuzzy, c-format
 msgid "%s/%.2s/%.2s/%.2s/timing: %s"
 msgstr "%s/%.2s/%.2s/%.2s/时序:%s"
 
-#: plugins/sudoers/sudoreplay.c:316
+#: plugins/sudoers/sudoreplay.c:339
 #, fuzzy, c-format
 msgid "%s/%s/timing: %s"
 msgstr "%s/%s/时序:%s"
 
-#: plugins/sudoers/sudoreplay.c:341
+#: plugins/sudoers/sudoreplay.c:364
 #, c-format
 msgid "invalid log file %s"
 msgstr "无效的日志文件 %s"
 
-#: plugins/sudoers/sudoreplay.c:343
+#: plugins/sudoers/sudoreplay.c:366
 #, c-format
 msgid "Replaying sudo session: %s"
 msgstr "回放 sudo 会话:%s"
 
-#: plugins/sudoers/sudoreplay.c:369
+#: plugins/sudoers/sudoreplay.c:392
 #, c-format
 msgid "unable to set tty to raw mode"
 msgstr "无法将终端设为原始模式"
 
-#: plugins/sudoers/sudoreplay.c:383
+#: plugins/sudoers/sudoreplay.c:406
 #, fuzzy, c-format
 msgid "invalid timing file line: %s"
 msgstr "无效的时序文件行:%s"
 
-#: plugins/sudoers/sudoreplay.c:425
+#: plugins/sudoers/sudoreplay.c:448
 #, c-format
 msgid "writing to standard output"
 msgstr "写入标准输出"
 
-#: plugins/sudoers/sudoreplay.c:455
+#: plugins/sudoers/sudoreplay.c:480
 #, c-format
 msgid "nanosleep: tv_sec %ld, tv_nsec %ld"
 msgstr "nanosleep:tv_sec %ld,tv_nsec %ld"
 
-#: plugins/sudoers/sudoreplay.c:503 plugins/sudoers/sudoreplay.c:528
+#: plugins/sudoers/sudoreplay.c:529 plugins/sudoers/sudoreplay.c:554
 #, c-format
 msgid "ambiguous expression \"%s\""
 msgstr "有歧义的表达式“%s”"
 
-#: plugins/sudoers/sudoreplay.c:545
+#: plugins/sudoers/sudoreplay.c:571
 #, c-format
 msgid "too many parenthesized expressions, max %d"
 msgstr "括号表达式过多,最多 %d"
 
-#: plugins/sudoers/sudoreplay.c:556
+#: plugins/sudoers/sudoreplay.c:582
 #, c-format
 msgid "unmatched ')' in expression"
 msgstr "表达式中的“)”不匹配"
 
-#: plugins/sudoers/sudoreplay.c:562
+#: plugins/sudoers/sudoreplay.c:588
 #, c-format
 msgid "unknown search term \"%s\""
 msgstr "未知的搜索词“%s”"
 
-#: plugins/sudoers/sudoreplay.c:576
+#: plugins/sudoers/sudoreplay.c:602
 #, c-format
 msgid "%s requires an argument"
 msgstr "%s 需要参数"
 
-#: plugins/sudoers/sudoreplay.c:580
+#: plugins/sudoers/sudoreplay.c:606
 #, c-format
 msgid "invalid regular expression: %s"
 msgstr "无效的正则表达式:%s"
 
-#: plugins/sudoers/sudoreplay.c:586
+#: plugins/sudoers/sudoreplay.c:612
 #, c-format
 msgid "could not parse date \"%s\""
 msgstr "无法解析日期“%s”"
 
-#: plugins/sudoers/sudoreplay.c:599
+#: plugins/sudoers/sudoreplay.c:625
 #, c-format
 msgid "unmatched '(' in expression"
 msgstr "表达式中的“(”不匹配"
 
-#: plugins/sudoers/sudoreplay.c:601
+#: plugins/sudoers/sudoreplay.c:627
 #, c-format
 msgid "illegal trailing \"or\""
 msgstr "非法的结尾字符“or”"
 
-#: plugins/sudoers/sudoreplay.c:603
+#: plugins/sudoers/sudoreplay.c:629
 #, c-format
 msgid "illegal trailing \"!\""
 msgstr "非法的结尾字符“!”"
 
-#: plugins/sudoers/sudoreplay.c:819
+#: plugins/sudoers/sudoreplay.c:851
 #, c-format
 msgid "invalid regex: %s"
 msgstr "无效的正则表达式:%s"
 
-#: plugins/sudoers/sudoreplay.c:941
+#: plugins/sudoers/sudoreplay.c:976
 #, c-format
 msgid "usage: %s [-h] [-d directory] [-m max_wait] [-s speed_factor] ID\n"
 msgstr "用法:%s [-h] [-d 目录] [-m 最长等待] [-s 速度系数] ID\n"
 
-#: plugins/sudoers/sudoreplay.c:944
+#: plugins/sudoers/sudoreplay.c:979
 #, c-format
 msgid "usage: %s [-h] [-d directory] -l [search expression]\n"
 msgstr "用法:%s [-h] [-d 目录] -l [搜索表达式]\n"
 
-#: plugins/sudoers/sudoreplay.c:953
+#: plugins/sudoers/sudoreplay.c:988
 #, c-format
 msgid ""
 "%s - replay sudo session logs\n"
@@ -1253,7 +1261,7 @@ msgstr ""
 "%s - 回放 sudo 会话记录\n"
 "\n"
 
-#: plugins/sudoers/sudoreplay.c:955
+#: plugins/sudoers/sudoreplay.c:990
 msgid ""
 "\n"
 "Options:\n"
@@ -1275,16 +1283,16 @@ msgstr ""
 "  -s 速度系数      加速或减慢输出\n"
 "  -V               显示版本信息并退出"
 
-#: plugins/sudoers/testsudoers.c:230
+#: plugins/sudoers/testsudoers.c:246
 #, c-format
 msgid "internal error, init_vars() overflow"
 msgstr "内部错误,init_vars() 溢出"
 
-#: plugins/sudoers/testsudoers.c:309
+#: plugins/sudoers/testsudoers.c:331
 msgid "\thost  unmatched"
 msgstr "\t主机不匹配"
 
-#: plugins/sudoers/testsudoers.c:312
+#: plugins/sudoers/testsudoers.c:334
 msgid ""
 "\n"
 "Command allowed"
@@ -1292,7 +1300,7 @@ msgstr ""
 "\n"
 "命令允许"
 
-#: plugins/sudoers/testsudoers.c:313
+#: plugins/sudoers/testsudoers.c:335
 msgid ""
 "\n"
 "Command denied"
@@ -1300,7 +1308,7 @@ msgstr ""
 "\n"
 "命令被拒"
 
-#: plugins/sudoers/testsudoers.c:313
+#: plugins/sudoers/testsudoers.c:335
 msgid ""
 "\n"
 "Command unmatched"
@@ -1308,104 +1316,104 @@ msgstr ""
 "\n"
 "命令不匹配"
 
-#: toke.l:667 toke.l:793 toke.l:818 toke.l:904 plugins/sudoers/toke_util.c:111
-#: plugins/sudoers/toke_util.c:163 plugins/sudoers/toke_util.c:202
+#: toke.l:672 toke.l:802 toke.l:827 toke.l:923 plugins/sudoers/toke_util.c:113
+#: plugins/sudoers/toke_util.c:167 plugins/sudoers/toke_util.c:207
 msgid "unable to allocate memory"
 msgstr "无法分配内存"
 
-#: toke.l:786
+#: toke.l:795
 msgid "too many levels of includes"
 msgstr "include 嵌套层数过多"
 
-#: plugins/sudoers/toke_util.c:213
+#: plugins/sudoers/toke_util.c:218
 msgid "fill_args: buffer overflow"
 msgstr "fill_args:缓存溢出"
 
-#: plugins/sudoers/visudo.c:175
+#: plugins/sudoers/visudo.c:188
 #, c-format
 msgid "%s grammar version %d\n"
 msgstr "%s 语法版本 %d\n"
 
-#: plugins/sudoers/visudo.c:208 plugins/sudoers/auth/rfc1938.c:103
+#: plugins/sudoers/visudo.c:221 plugins/sudoers/auth/rfc1938.c:104
 #, c-format
 msgid "you do not exist in the %s database"
 msgstr "%s 数据库中没有您"
 
-#: plugins/sudoers/visudo.c:238 plugins/sudoers/visudo.c:518
+#: plugins/sudoers/visudo.c:253 plugins/sudoers/visudo.c:539
 #, c-format
 msgid "press return to edit %s: "
 msgstr "按回车键编辑 %s:"
 
-#: plugins/sudoers/visudo.c:320 plugins/sudoers/visudo.c:326
+#: plugins/sudoers/visudo.c:336 plugins/sudoers/visudo.c:342
 #, c-format
 msgid "write error"
 msgstr "写错误"
 
-#: plugins/sudoers/visudo.c:408
+#: plugins/sudoers/visudo.c:424
 #, c-format
 msgid "unable to stat temporary file (%s), %s unchanged"
 msgstr "无法 stat 临时文件(%s),%s 未更改"
 
-#: plugins/sudoers/visudo.c:413
+#: plugins/sudoers/visudo.c:429
 #, c-format
 msgid "zero length temporary file (%s), %s unchanged"
 msgstr "零长度的临时文件(%s),%s 未更改"
 
-#: plugins/sudoers/visudo.c:419
+#: plugins/sudoers/visudo.c:435
 #, c-format
 msgid "editor (%s) failed, %s unchanged"
 msgstr "编辑器(%s)失败,%s 未更改"
 
-#: plugins/sudoers/visudo.c:442
+#: plugins/sudoers/visudo.c:458
 #, c-format
 msgid "%s unchanged"
 msgstr "%s 未更改"
 
-#: plugins/sudoers/visudo.c:466
+#: plugins/sudoers/visudo.c:484
 #, c-format
 msgid "unable to re-open temporary file (%s), %s unchanged."
 msgstr "无法重新打开临时文件(%s),%s 未更改"
 
-#: plugins/sudoers/visudo.c:476
+#: plugins/sudoers/visudo.c:494
 #, c-format
 msgid "unabled to parse temporary file (%s), unknown error"
 msgstr "无法解析临时文件(%s),未知错误"
 
-#: plugins/sudoers/visudo.c:511
+#: plugins/sudoers/visudo.c:532
 #, c-format
 msgid "internal error, unable to find %s in list!"
 msgstr "内部错误,在列表中找不到 %s!"
 
-#: plugins/sudoers/visudo.c:546 plugins/sudoers/visudo.c:555
+#: plugins/sudoers/visudo.c:584 plugins/sudoers/visudo.c:593
 #, c-format
 msgid "unable to set (uid, gid) of %s to (%u, %u)"
 msgstr "无法将 %s 的 (uid, gid) 设为 (%u, %u)"
 
-#: plugins/sudoers/visudo.c:550 plugins/sudoers/visudo.c:560
+#: plugins/sudoers/visudo.c:588 plugins/sudoers/visudo.c:598
 #, c-format
 msgid "unable to change mode of %s to 0%o"
 msgstr "无法将 %s 的模式更改为 0%o"
 
-#: plugins/sudoers/visudo.c:577
+#: plugins/sudoers/visudo.c:615
 #, c-format
 msgid "%s and %s not on the same file system, using mv to rename"
 msgstr "%s 和 %s 不在同一个文件系统,使用 mv 进行重命名"
 
-#: plugins/sudoers/visudo.c:591
+#: plugins/sudoers/visudo.c:629
 #, c-format
 msgid "command failed: '%s %s %s', %s unchanged"
 msgstr "命令失败:“%s %s %s”,%s 未更改"
 
-#: plugins/sudoers/visudo.c:601
+#: plugins/sudoers/visudo.c:639
 #, c-format
 msgid "error renaming %s, %s unchanged"
 msgstr "重命名 %s 出错,%s 未更改"
 
-#: plugins/sudoers/visudo.c:661
+#: plugins/sudoers/visudo.c:702
 msgid "What now? "
 msgstr "现在做什么?"
 
-#: plugins/sudoers/visudo.c:675
+#: plugins/sudoers/visudo.c:716
 msgid ""
 "Options are:\n"
 "  (e)dit sudoers file again\n"
@@ -1417,92 +1425,92 @@ msgstr ""
 "  退出,不保存对 sudoers 文件的更改(x)\n"
 "  退出并将更改保存到 sudoers 文件(危险!)(Q)\n"
 
-#: plugins/sudoers/visudo.c:712
+#: plugins/sudoers/visudo.c:757
 #, c-format
 msgid "unable to execute %s"
 msgstr "无法执行 %s"
 
-#: plugins/sudoers/visudo.c:719
+#: plugins/sudoers/visudo.c:764
 #, c-format
 msgid "unable to run %s"
 msgstr "无法运行 %s"
 
-#: plugins/sudoers/visudo.c:750
+#: plugins/sudoers/visudo.c:796
 #, c-format
 msgid "failed to parse %s file, unknown error"
 msgstr "解析 %s 文件失败,未知错误"
 
-#: plugins/sudoers/visudo.c:762
+#: plugins/sudoers/visudo.c:808
 #, c-format
 msgid "parse error in %s near line %d\n"
 msgstr "%s 中第 %d 行附近出现解析错误\n"
 
-#: plugins/sudoers/visudo.c:765
+#: plugins/sudoers/visudo.c:811
 #, c-format
 msgid "parse error in %s\n"
 msgstr "%s 中出现解析错误\n"
 
-#: plugins/sudoers/visudo.c:767
+#: plugins/sudoers/visudo.c:814 plugins/sudoers/visudo.c:816
 #, c-format
 msgid "%s: parsed OK\n"
 msgstr "%s:解析正确\n"
 
-#: plugins/sudoers/visudo.c:776
+#: plugins/sudoers/visudo.c:826
 #, c-format
 msgid "%s: wrong owner (uid, gid) should be (%u, %u)\n"
 msgstr "%s:错误的所有者(uid, gid),应为 (%u, %u)\n"
 
-#: plugins/sudoers/visudo.c:783
+#: plugins/sudoers/visudo.c:833
 #, c-format
 msgid "%s: bad permissions, should be mode 0%o\n"
 msgstr "%s:权限不正确,模式应该是 0%o\n"
 
-#: plugins/sudoers/visudo.c:822
+#: plugins/sudoers/visudo.c:880
 #, c-format
 msgid "%s busy, try again later"
 msgstr "%s 忙,请稍后重试"
 
-#: plugins/sudoers/visudo.c:865
+#: plugins/sudoers/visudo.c:924
 #, c-format
 msgid "specified editor (%s) doesn't exist"
 msgstr "指定的编辑器(%s)不存在"
 
-#: plugins/sudoers/visudo.c:888
+#: plugins/sudoers/visudo.c:947
 #, c-format
 msgid "unable to stat editor (%s)"
 msgstr "无法 stat 编辑器(%s)"
 
-#: plugins/sudoers/visudo.c:936
+#: plugins/sudoers/visudo.c:995
 #, c-format
 msgid "no editor found (editor path = %s)"
 msgstr "未找到编辑器(编辑器路径 = %s)"
 
-#: plugins/sudoers/visudo.c:1025
+#: plugins/sudoers/visudo.c:1089
 #, c-format
 msgid "Error: cycle in %s_Alias `%s'"
 msgstr "错误:在 %s_Alias “%s”中循环"
 
-#: plugins/sudoers/visudo.c:1026
+#: plugins/sudoers/visudo.c:1090
 #, c-format
 msgid "Warning: cycle in %s_Alias `%s'"
 msgstr "警告:在 %s_Alias “%s”中循环"
 
-#: plugins/sudoers/visudo.c:1029
+#: plugins/sudoers/visudo.c:1093
 #, fuzzy, c-format
 msgid "Error: %s_Alias `%s' referenced but not defined"
 msgstr "错误:引用了 %s_Alias “%s”但尚未定义"
 
-#: plugins/sudoers/visudo.c:1030
+#: plugins/sudoers/visudo.c:1094
 #, fuzzy, c-format
 msgid "Warning: %s_Alias `%s' referenced but not defined"
 msgstr "警告:引用了 %s_Alias “%s”但尚未定义"
 
-#: plugins/sudoers/visudo.c:1167
+#: plugins/sudoers/visudo.c:1229
 #, c-format
 msgid "%s: unused %s_Alias %s"
 msgstr "%s:未使用的 %s_Alias %s"
 
-#: plugins/sudoers/visudo.c:1224
+#: plugins/sudoers/visudo.c:1286
 #, c-format
 msgid ""
 "%s - safely edit the sudoers file\n"
@@ -1511,7 +1519,7 @@ msgstr ""
 "%s - 安全地编辑 sudoers 文件\n"
 "\n"
 
-#: plugins/sudoers/visudo.c:1226
+#: plugins/sudoers/visudo.c:1288
 msgid ""
 "\n"
 "Options:\n"
@@ -1531,35 +1539,40 @@ msgstr ""
 "  -s          严格语法检查\n"
 "  -V          显示版本信息并退出"
 
-#: plugins/sudoers/auth/bsdauth.c:64
+#: plugins/sudoers/auth/bsdauth.c:78
+#, fuzzy, c-format
+msgid "unable to get login class for user %s"
+msgstr "无法打开日志文件:%s:%s"
+
+#: plugins/sudoers/auth/bsdauth.c:84
 msgid "unable to begin bsd authentication"
 msgstr "无法开始 bsd 认证"
 
-#: plugins/sudoers/auth/bsdauth.c:71
+#: plugins/sudoers/auth/bsdauth.c:92
 msgid "invalid authentication type"
 msgstr "无效的认证类型"
 
-#: plugins/sudoers/auth/bsdauth.c:79
+#: plugins/sudoers/auth/bsdauth.c:101
 msgid "unable to setup authentication"
 msgstr "无法设置认证"
 
-#: plugins/sudoers/auth/fwtk.c:59
+#: plugins/sudoers/auth/fwtk.c:60
 #, c-format
 msgid "unable to read fwtk config"
 msgstr "无法读取 fwtk 配置"
 
-#: plugins/sudoers/auth/fwtk.c:64
+#: plugins/sudoers/auth/fwtk.c:65
 #, c-format
 msgid "unable to connect to authentication server"
 msgstr "无法连接到认证服务器"
 
-#: plugins/sudoers/auth/fwtk.c:70 plugins/sudoers/auth/fwtk.c:93
-#: plugins/sudoers/auth/fwtk.c:126
+#: plugins/sudoers/auth/fwtk.c:71 plugins/sudoers/auth/fwtk.c:95
+#: plugins/sudoers/auth/fwtk.c:128
 #, c-format
 msgid "lost connection to authentication server"
 msgstr "丢失了到认证服务器的连接"
 
-#: plugins/sudoers/auth/fwtk.c:74
+#: plugins/sudoers/auth/fwtk.c:75
 #, c-format
 msgid ""
 "authentication server error:\n"
@@ -1568,152 +1581,155 @@ msgstr ""
 "认证服务器错误:\n"
 "%s"
 
-#: plugins/sudoers/auth/kerb5.c:114
-#, c-format
-msgid "%s: unable to parse '%s': %s"
-msgstr "%s:无法解析“%s”:%s"
-
-#: plugins/sudoers/auth/kerb5.c:127
+#: plugins/sudoers/auth/kerb5.c:117
 #, c-format
 msgid "%s: unable to unparse princ ('%s'): %s"
 msgstr "%s:无法解析 princ(“%s”):%s"
 
-#: plugins/sudoers/auth/kerb5.c:144
+#: plugins/sudoers/auth/kerb5.c:160
+#, c-format
+msgid "%s: unable to parse '%s': %s"
+msgstr "%s:无法解析“%s”:%s"
+
+#: plugins/sudoers/auth/kerb5.c:170
 #, c-format
 msgid "%s: unable to resolve ccache: %s"
 msgstr "%s:无法解析 ccache:%s"
 
-#: plugins/sudoers/auth/kerb5.c:188
+#: plugins/sudoers/auth/kerb5.c:218
 #, c-format
 msgid "%s: unable to allocate options: %s"
 msgstr "%s:无法分配选项:%s"
 
-#: plugins/sudoers/auth/kerb5.c:204
+#: plugins/sudoers/auth/kerb5.c:234
 #, c-format
 msgid "%s: unable to get credentials: %s"
 msgstr "%s:无法获取凭据:%s"
 
-#: plugins/sudoers/auth/kerb5.c:217
+#: plugins/sudoers/auth/kerb5.c:247
 #, c-format
 msgid "%s: unable to initialize ccache: %s"
 msgstr "%s:无法初始化 ccache:%s"
 
-#: plugins/sudoers/auth/kerb5.c:221
+#: plugins/sudoers/auth/kerb5.c:251
 #, fuzzy, c-format
 msgid "%s: unable to store cred in ccache: %s"
 msgstr "%s:无法储存 ccache 中的凭据"
 
-#: plugins/sudoers/auth/kerb5.c:284
+#: plugins/sudoers/auth/kerb5.c:316
 #, c-format
 msgid "%s: unable to get host principal: %s"
 msgstr ""
 
-#: plugins/sudoers/auth/kerb5.c:299
+#: plugins/sudoers/auth/kerb5.c:331
 #, c-format
 msgid "%s: Cannot verify TGT! Possible attack!: %s"
 msgstr "%s:无法验证目标!可能遭到了攻击!:%s"
 
-#: plugins/sudoers/auth/pam.c:99
+#: plugins/sudoers/auth/pam.c:100
 msgid "unable to initialize PAM"
 msgstr "无法初始化 PAM"
 
-#: plugins/sudoers/auth/pam.c:142
+#: plugins/sudoers/auth/pam.c:144
 msgid "account validation failure, is your account locked?"
 msgstr "账户验证失败,您的账户是不是上锁了?"
 
-#: plugins/sudoers/auth/pam.c:146
+#: plugins/sudoers/auth/pam.c:148
 msgid "Account or password is expired, reset your password and try again"
 msgstr "账户或密码过期,重置您的密码并重试"
 
-#: plugins/sudoers/auth/pam.c:153
+#: plugins/sudoers/auth/pam.c:155
 #, c-format
 msgid "pam_chauthtok: %s"
 msgstr "pam_chauthtok:%s"
 
-#: plugins/sudoers/auth/pam.c:157
+#: plugins/sudoers/auth/pam.c:159
 msgid "Password expired, contact your system administrator"
 msgstr "密码过期,联系您的系统管理员"
 
-#: plugins/sudoers/auth/pam.c:161
+#: plugins/sudoers/auth/pam.c:163
 msgid "Account expired or PAM config lacks an \"account\" section for sudo, contact your system administrator"
 msgstr "账户过期,或 PAM 配置缺少 sudo 使用的“account”节,联系您的系统管理员"
 
-#: plugins/sudoers/auth/pam.c:176
+#: plugins/sudoers/auth/pam.c:178
 #, c-format
 msgid "pam_authenticate: %s"
 msgstr "pam_authenticate:%s"
 
-#: plugins/sudoers/auth/pam.c:296
+#: plugins/sudoers/auth/pam.c:306
 msgid "Password: "
 msgstr "密码:"
 
-#: plugins/sudoers/auth/pam.c:297
+#: plugins/sudoers/auth/pam.c:307
 msgid "Password:"
 msgstr "密码:"
 
-#: plugins/sudoers/auth/securid.c:82 plugins/sudoers/auth/securid5.c:106
-#, c-format
-msgid "unable to contact the SecurID server"
-msgstr "无法联络 SecurID 服务器"
-
 #: plugins/sudoers/auth/securid5.c:81
 #, c-format
 msgid "failed to initialise the ACE API library"
 msgstr "初始化 ACE API 库失败"
 
-#: plugins/sudoers/auth/securid5.c:115
+#: plugins/sudoers/auth/securid5.c:107
+#, c-format
+msgid "unable to contact the SecurID server"
+msgstr "无法联络 SecurID 服务器"
+
+#: plugins/sudoers/auth/securid5.c:116
 #, c-format
 msgid "User ID locked for SecurID Authentication"
 msgstr "为进行 SecurID 认证,已锁定用户 ID"
 
-#: plugins/sudoers/auth/securid5.c:119 plugins/sudoers/auth/securid5.c:169
+#: plugins/sudoers/auth/securid5.c:120 plugins/sudoers/auth/securid5.c:171
 #, c-format
 msgid "invalid username length for SecurID"
 msgstr "SecurID 的用户名长度无效"
 
-#: plugins/sudoers/auth/securid5.c:123 plugins/sudoers/auth/securid5.c:174
+#: plugins/sudoers/auth/securid5.c:124 plugins/sudoers/auth/securid5.c:176
 #, fuzzy, c-format
 msgid "invalid Authentication Handle for SecurID"
 msgstr "SecurID 的认证句柄无效"
 
-#: plugins/sudoers/auth/securid5.c:127
+#: plugins/sudoers/auth/securid5.c:128
 #, c-format
 msgid "SecurID communication failed"
 msgstr "SecurID 通讯失败"
 
-#: plugins/sudoers/auth/securid5.c:131 plugins/sudoers/auth/securid5.c:213
+#: plugins/sudoers/auth/securid5.c:132 plugins/sudoers/auth/securid5.c:215
 #, c-format
 msgid "unknown SecurID error"
 msgstr "未知的 SecurID 错误"
 
-#: plugins/sudoers/auth/securid5.c:164
+#: plugins/sudoers/auth/securid5.c:166
 #, c-format
 msgid "invalid passcode length for SecurID"
 msgstr "无效的 SecurID 密码长度"
 
-#: plugins/sudoers/auth/sia.c:106
+#: plugins/sudoers/auth/sia.c:109
 msgid "unable to initialize SIA session"
 msgstr "无法初始化 SIA 会话"
 
-#: plugins/sudoers/auth/sudo_auth.c:124
-msgid "There are no authentication methods compiled into sudo!  If you want to turn off authentication, use the --disable-authentication configure option."
-msgstr "sudo 编译时没有加入任何认证方法!如果您想关闭认证,使用 --disable-authentication 配置选项。"
-
-#: plugins/sudoers/auth/sudo_auth.c:134
+#: plugins/sudoers/auth/sudo_auth.c:117
 #, fuzzy
 msgid "Invalid authentication methods compiled into sudo!  You may mix standalone and non-standalone authentication."
 msgstr "编译进 sudo 的认证方法无效!您可能混用了独立和非独立认证。"
 
-#: plugins/sudoers/auth/sudo_auth.c:243
+#: plugins/sudoers/auth/sudo_auth.c:199
+msgid "There are no authentication methods compiled into sudo!  If you want to turn off authentication, use the --disable-authentication configure option."
+msgstr "sudo 编译时没有加入任何认证方法!如果您想关闭认证,使用 --disable-authentication 配置选项。"
+
+#: plugins/sudoers/auth/sudo_auth.c:271
 #, c-format
 msgid "%d incorrect password attempt"
 msgid_plural "%d incorrect password attempts"
 msgstr[0] "%d 次错误密码尝试"
 
-#: plugins/sudoers/auth/sudo_auth.c:335
+#: plugins/sudoers/auth/sudo_auth.c:374
 msgid "Authentication methods:"
 msgstr "认证方法:"
 
+#~ msgid "File containing dummy exec functions: %s"
+#~ msgstr "含有哑 exec 函数的文件:%s"
+
 #~ msgid ""
 #~ "Available options in a sudoers ``Defaults'' line:\n"
 #~ "\n"
index aac32325ac42b7ad0d59e0dd0c3a68ac565be115..c1a80dc344f864ab3255592e808363cf7306ff4a 100644 (file)
@@ -146,6 +146,7 @@ make_pwitem(const struct passwd *pw, const char *name)
     size_t nsize, psize, csize, gsize, dsize, ssize, total;
     struct cache_item *item;
     struct passwd *newpw;
+    debug_decl(make_pwitem, SUDO_DEBUG_NSS)
 
     /* If shell field is empty, expand to _PATH_BSHELL. */
     pw_shell = (pw->pw_shell == NULL || pw->pw_shell[0] == '\0')
@@ -200,28 +201,35 @@ make_pwitem(const struct passwd *pw, const char *name)
     item->d.pw = newpw;
     item->refcnt = 1;
 
-    return item;
+    debug_return_ptr(item);
 }
 
 void
 pw_addref(struct passwd *pw)
 {
+    debug_decl(pw_addref, SUDO_DEBUG_NSS)
     ptr_to_item(pw)->refcnt++;
+    debug_return;
 }
 
 static void
 pw_delref_item(void *v)
 {
     struct cache_item *item = v;
+    debug_decl(pw_delref_item, SUDO_DEBUG_NSS)
 
     if (--item->refcnt == 0)
        efree(item);
+
+    debug_return;
 }
 
 void
 pw_delref(struct passwd *pw)
 {
+    debug_decl(pw_delref, SUDO_DEBUG_NSS)
     pw_delref_item(ptr_to_item(pw));
+    debug_return;
 }
 
 /*
@@ -233,6 +241,7 @@ sudo_getpwuid(uid_t uid)
 {
     struct cache_item key, *item;
     struct rbnode *node;
+    debug_decl(sudo_getpwuid, SUDO_DEBUG_NSS)
 
     key.k.uid = uid;
     if ((node = rbfind(pwcache_byuid, &key)) != NULL) {
@@ -264,7 +273,7 @@ sudo_getpwuid(uid_t uid)
 #endif
 done:
     item->refcnt++;
-    return item->d.pw;
+    debug_return_ptr(item->d.pw);
 }
 
 /*
@@ -277,6 +286,7 @@ sudo_getpwnam(const char *name)
     struct cache_item key, *item;
     struct rbnode *node;
     size_t len;
+    debug_decl(sudo_getpwnam, SUDO_DEBUG_NSS)
 
     key.k.name = (char *) name;
     if ((node = rbfind(pwcache_byname, &key)) != NULL) {
@@ -308,7 +318,7 @@ sudo_getpwnam(const char *name)
 #endif
 done:
     item->refcnt++;
-    return item->d.pw;
+    debug_return_ptr(item->d.pw);
 }
 
 /*
@@ -322,6 +332,7 @@ sudo_fakepwnamid(const char *user, uid_t uid, gid_t gid)
     struct rbnode *node;
     size_t len, namelen;
     int i;
+    debug_decl(sudo_fakepwnam, SUDO_DEBUG_NSS)
 
     namelen = strlen(user);
     len = sizeof(*item) + sizeof(*pw) + namelen + 1 /* pw_name */ +
@@ -364,7 +375,7 @@ sudo_fakepwnamid(const char *user, uid_t uid, gid_t gid)
        }
     }
     item->refcnt++;
-    return pw;
+    debug_return_ptr(pw);
 }
 
 /*
@@ -382,16 +393,22 @@ sudo_fakepwnam(const char *user, gid_t gid)
 void
 sudo_setpwent(void)
 {
+    debug_decl(sudo_setpwent, SUDO_DEBUG_NSS)
+
     setpwent();
     if (pwcache_byuid == NULL)
        pwcache_byuid = rbcreate(cmp_pwuid);
     if (pwcache_byname == NULL)
        pwcache_byname = rbcreate(cmp_pwnam);
+
+    debug_return;
 }
 
 void
 sudo_freepwcache(void)
 {
+    debug_decl(sudo_freepwcache, SUDO_DEBUG_NSS)
+
     if (pwcache_byuid != NULL) {
        rbdestroy(pwcache_byuid, pw_delref_item);
        pwcache_byuid = NULL;
@@ -400,13 +417,19 @@ sudo_freepwcache(void)
        rbdestroy(pwcache_byname, pw_delref_item);
        pwcache_byname = NULL;
     }
+
+    debug_return;
 }
 
 void
 sudo_endpwent(void)
 {
+    debug_decl(sudo_endpwent, SUDO_DEBUG_NSS)
+
     endpwent();
     sudo_freepwcache();
+
+    debug_return;
 }
 
 /*
@@ -432,6 +455,7 @@ make_gritem(const struct group *gr, const char *name)
     size_t nsize, psize, nmem, total, len;
     struct cache_item *item;
     struct group *newgr;
+    debug_decl(make_gritem, SUDO_DEBUG_NSS)
 
     /* Allocate in one big chunk for easy freeing. */
     nsize = psize = nmem = 0;
@@ -482,7 +506,7 @@ make_gritem(const struct group *gr, const char *name)
     item->d.gr = newgr;
     item->refcnt = 1;
 
-    return item;
+    debug_return_ptr(item);
 }
 
 #ifdef HAVE_UTMPX_H
@@ -507,6 +531,7 @@ make_grlist_item(const char *user, GETGROUPS_T *gids, int ngids)
     struct cache_item *item;
     struct group_list *grlist;
     struct group *grp;
+    debug_decl(make_grlist_item, SUDO_DEBUG_NSS)
 
 #ifdef HAVE_SETAUTHDB
     aix_setauthdb((char *) user);
@@ -575,28 +600,35 @@ again:
     aix_restoreauthdb();
 #endif
 
-    return item;
+    debug_return_ptr(item);
 }
 
 void
 gr_addref(struct group *gr)
 {
+    debug_decl(gr_addref, SUDO_DEBUG_NSS)
     ptr_to_item(gr)->refcnt++;
+    debug_return;
 }
 
 static void
 gr_delref_item(void *v)
 {
     struct cache_item *item = v;
+    debug_decl(gr_delref_item, SUDO_DEBUG_NSS)
 
     if (--item->refcnt == 0)
        efree(item);
+
+    debug_return;
 }
 
 void
 gr_delref(struct group *gr)
 {
+    debug_decl(gr_delref, SUDO_DEBUG_NSS)
     gr_delref_item(ptr_to_item(gr));
+    debug_return;
 }
 
 /*
@@ -607,6 +639,7 @@ sudo_getgrgid(gid_t gid)
 {
     struct cache_item key, *item;
     struct rbnode *node;
+    debug_decl(sudo_getgrgid, SUDO_DEBUG_NSS)
 
     key.k.gid = gid;
     if ((node = rbfind(grcache_bygid, &key)) != NULL) {
@@ -632,7 +665,7 @@ sudo_getgrgid(gid_t gid)
     }
 done:
     item->refcnt++;
-    return item->d.gr;
+    debug_return_ptr(item->d.gr);
 }
 
 /*
@@ -644,6 +677,7 @@ sudo_getgrnam(const char *name)
     struct cache_item key, *item;
     struct rbnode *node;
     size_t len;
+    debug_decl(sudo_getgrnam, SUDO_DEBUG_NSS)
 
     key.k.name = (char *) name;
     if ((node = rbfind(grcache_byname, &key)) != NULL) {
@@ -669,7 +703,7 @@ sudo_getgrnam(const char *name)
     }
 done:
     item->refcnt++;
-    return item->d.gr;
+    debug_return_ptr(item->d.gr);
 }
 
 /*
@@ -683,6 +717,7 @@ sudo_fakegrnam(const char *group)
     struct rbnode *node;
     size_t len, namelen;
     int i;
+    debug_decl(sudo_fakegrnam, SUDO_DEBUG_NSS)
 
     namelen = strlen(group);
     len = sizeof(*item) + sizeof(*gr) + namelen + 1;
@@ -714,33 +749,42 @@ sudo_fakegrnam(const char *group)
        }
     }
     item->refcnt++;
-    return gr;
+    debug_return_ptr(gr);
 }
 
 void
 grlist_addref(struct group_list *grlist)
 {
+    debug_decl(gr_addref, SUDO_DEBUG_NSS)
     ptr_to_item(grlist)->refcnt++;
+    debug_return;
 }
 
 static void
 grlist_delref_item(void *v)
 {
     struct cache_item *item = v;
+    debug_decl(gr_delref_item, SUDO_DEBUG_NSS)
 
     if (--item->refcnt == 0)
        efree(item);
+
+    debug_return;
 }
 
 void
 grlist_delref(struct group_list *grlist)
 {
+    debug_decl(gr_delref, SUDO_DEBUG_NSS)
     grlist_delref_item(ptr_to_item(grlist));
+    debug_return;
 }
 
 void
 sudo_setgrent(void)
 {
+    debug_decl(sudo_setgrent, SUDO_DEBUG_NSS)
+
     setgrent();
     if (grcache_bygid == NULL)
        grcache_bygid = rbcreate(cmp_grgid);
@@ -748,11 +792,15 @@ sudo_setgrent(void)
        grcache_byname = rbcreate(cmp_grnam);
     if (grlist_cache == NULL)
        grlist_cache = rbcreate(cmp_grnam);
+
+    debug_return;
 }
 
 void
 sudo_freegrcache(void)
 {
+    debug_decl(sudo_freegrcache, SUDO_DEBUG_NSS)
+
     if (grcache_bygid != NULL) {
        rbdestroy(grcache_bygid, gr_delref_item);
        grcache_bygid = NULL;
@@ -765,13 +813,19 @@ sudo_freegrcache(void)
        rbdestroy(grlist_cache, grlist_delref_item);
        grlist_cache = NULL;
     }
+
+    debug_return;
 }
 
 void
 sudo_endgrent(void)
 {
+    debug_decl(sudo_endgrent, SUDO_DEBUG_NSS)
+
     endgrent();
     sudo_freegrcache();
+
+    debug_return;
 }
 
 struct group_list *
@@ -782,6 +836,7 @@ get_group_list(struct passwd *pw)
     size_t len;
     GETGROUPS_T *gids;
     int ngids;
+    debug_decl(get_group_list, SUDO_DEBUG_NSS)
 
     key.k.name = pw->pw_name;
     if ((node = rbfind(grlist_cache, &key)) != NULL) {
@@ -802,7 +857,7 @@ get_group_list(struct passwd *pw)
        gids = emalloc2(ngids, sizeof(GETGROUPS_T));
        if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1) {
            efree(gids);
-           return NULL;
+           debug_return_ptr(NULL);
        }
     }
     if (ngids > 0) {
@@ -826,7 +881,7 @@ get_group_list(struct passwd *pw)
     }
 done:
     item->refcnt++;
-    return item->d.grlist;
+    debug_return_ptr(item->d.grlist);
 }
 
 void
@@ -834,6 +889,7 @@ set_group_list(const char *user, GETGROUPS_T *gids, int ngids)
 {
     struct cache_item key, *item;
     struct rbnode *node;
+    debug_decl(set_group_list, SUDO_DEBUG_NSS)
 
     /*
      * Cache group db entry if it doesn't already exist
@@ -846,14 +902,17 @@ set_group_list(const char *user, GETGROUPS_T *gids, int ngids)
            errorx(1, "unable to cache group list for %s, already exists",
                user);
     }
+    debug_return;
 }
 
-int
+bool
 user_in_group(struct passwd *pw, const char *group)
 {
     struct group_list *grlist;
     struct group *grp = NULL;
-    int i, matched = FALSE;
+    int i;
+    bool matched = false;
+    debug_decl(user_in_group, SUDO_DEBUG_NSS)
 
     if ((grlist = get_group_list(pw)) != NULL) {
        /*
@@ -862,12 +921,12 @@ user_in_group(struct passwd *pw, const char *group)
        if (group[0] == '#') {
            gid_t gid = atoi(group + 1);
            if (gid == pw->pw_gid) {
-               matched = TRUE;
+               matched = true;
                goto done;
            }
            for (i = 0; i < grlist->ngids; i++) {
                if (gid == grlist->gids[i]) {
-                   matched = TRUE;
+                   matched = true;
                    goto done;
                }
            }
@@ -879,7 +938,7 @@ user_in_group(struct passwd *pw, const char *group)
         */
        for (i = 0; i < grlist->ngroups; i++) {
            if (strcasecmp(group, grlist->groups[i]) == 0) {
-               matched = TRUE;
+               matched = true;
                goto done;
            }
        }
@@ -887,7 +946,7 @@ user_in_group(struct passwd *pw, const char *group)
        /* Finally check against user's primary (passwd file) group. */
        if ((grp = sudo_getgrgid(pw->pw_gid)) != NULL) {
            if (strcasecmp(group, grp->gr_name) == 0) {
-               matched = TRUE;
+               matched = true;
                goto done;
            }
        }
@@ -896,5 +955,5 @@ done:
            gr_delref(grp);
        grlist_delref(grlist);
     }
-    return matched;
+    debug_return_bool(matched);
 }
index 23c74d3f1f3b2a1a6603a78643ab03d3ef15425b..584f2c0aa14b6b07d5499b441ac67df1a06e957a 100644 (file)
@@ -57,6 +57,7 @@
 
 #include "missing.h"
 #include "alloc.h"
+#include "sudo_debug.h"
 #include "redblack.h"
 
 static void rbrepair(struct rbtree *, struct rbnode *);
@@ -90,6 +91,7 @@ struct rbtree *
 rbcreate(int (*compar)(const void *, const void*))
 {
     struct rbtree *tree;
+    debug_decl(rbcreate, SUDO_DEBUG_RBTREE)
 
     tree = (struct rbtree *) emalloc(sizeof(*tree));
     tree->compar = compar;
@@ -110,7 +112,7 @@ rbcreate(int (*compar)(const void *, const void*))
     tree->root.color = black;
     tree->root.data = NULL;
 
-    return tree;
+    debug_return_ptr(tree);
 }
 
 /*
@@ -120,6 +122,7 @@ static void
 rotate_left(struct rbtree *tree, struct rbnode *node)
 {
     struct rbnode *child;
+    debug_decl(rotate_left, SUDO_DEBUG_RBTREE)
 
     child = node->right;
     node->right = child->left;
@@ -134,6 +137,8 @@ rotate_left(struct rbtree *tree, struct rbnode *node)
        node->parent->right = child;
     child->left = node;
     node->parent = child;
+
+    debug_return;
 }
 
 /*
@@ -143,6 +148,7 @@ static void
 rotate_right(struct rbtree *tree, struct rbnode *node)
 {
     struct rbnode *child;
+    debug_decl(rotate_right, SUDO_DEBUG_RBTREE)
 
     child = node->left;
     node->left = child->right;
@@ -157,6 +163,8 @@ rotate_right(struct rbtree *tree, struct rbnode *node)
        node->parent->right = child;
     child->right = node;
     node->parent = child;
+
+    debug_return;
 }
 
 /*
@@ -170,12 +178,13 @@ rbinsert(struct rbtree *tree, void *data)
     struct rbnode *node = rbfirst(tree);
     struct rbnode *parent = rbroot(tree);
     int res;
+    debug_decl(rbinsert, SUDO_DEBUG_RBTREE)
 
     /* Find correct insertion point. */
     while (node != rbnil(tree)) {
        parent = node;
        if ((res = tree->compar(data, node->data)) == 0)
-           return node;
+           debug_return_ptr(node);
        node = res < 0 ? node->left : node->right;
     }
 
@@ -249,7 +258,7 @@ rbinsert(struct rbtree *tree, void *data)
        }
     }
     rbfirst(tree)->color = black;      /* first node is always black */
-    return NULL;
+    debug_return_ptr(NULL);
 }
 
 /*
@@ -261,13 +270,14 @@ rbfind(struct rbtree *tree, void *key)
 {
     struct rbnode *node = rbfirst(tree);
     int res;
+    debug_decl(rbfind, SUDO_DEBUG_RBTREE)
 
     while (node != rbnil(tree)) {
        if ((res = tree->compar(key, node->data)) == 0)
-           return node;
+           debug_return_ptr(node);
        node = res < 0 ? node->left : node->right;
     }
-    return NULL;
+    debug_return_ptr(NULL);
 }
 
 /*
@@ -280,23 +290,24 @@ rbapply_node(struct rbtree *tree, struct rbnode *node,
     int (*func)(void *, void *), void *cookie, enum rbtraversal order)
 {
     int error;
+    debug_decl(rbapply_node, SUDO_DEBUG_RBTREE)
 
     if (node != rbnil(tree)) {
        if (order == preorder)
            if ((error = func(node->data, cookie)) != 0)
-               return error;
+               debug_return_int(error);
        if ((error = rbapply_node(tree, node->left, func, cookie, order)) != 0)
-           return error;
+           debug_return_int(error);
        if (order == inorder)
            if ((error = func(node->data, cookie)) != 0)
-               return error;
+               debug_return_int(error);
        if ((error = rbapply_node(tree, node->right, func, cookie, order)) != 0)
-           return error;
+           debug_return_int(error);
        if (order == postorder)
            if ((error = func(node->data, cookie)) != 0)
-               return error;
+               debug_return_int(error);
     }
-    return 0;
+    debug_return_int(0);
 }
 
 /*
@@ -306,6 +317,7 @@ static struct rbnode *
 rbsuccessor(struct rbtree *tree, struct rbnode *node)
 {
     struct rbnode *succ;
+    debug_decl(rbsuccessor, SUDO_DEBUG_RBTREE)
 
     if ((succ = node->right) != rbnil(tree)) {
        while (succ->left != rbnil(tree))
@@ -317,7 +329,7 @@ rbsuccessor(struct rbtree *tree, struct rbnode *node)
        if (succ == rbroot(tree))
            succ = rbnil(tree);
     }
-    return succ;
+    debug_return_ptr(succ);
 }
 
 /*
@@ -326,6 +338,7 @@ rbsuccessor(struct rbtree *tree, struct rbnode *node)
 static void
 _rbdestroy(struct rbtree *tree, struct rbnode *node, void (*destroy)(void *))
 {
+    debug_decl(_rbdestroy, SUDO_DEBUG_RBTREE)
     if (node != rbnil(tree)) {
        _rbdestroy(tree, node->left, destroy);
        _rbdestroy(tree, node->right, destroy);
@@ -333,6 +346,7 @@ _rbdestroy(struct rbtree *tree, struct rbnode *node, void (*destroy)(void *))
            destroy(node->data);
        efree(node);
     }
+    debug_return;
 }
 
 /*
@@ -342,8 +356,10 @@ _rbdestroy(struct rbtree *tree, struct rbnode *node, void (*destroy)(void *))
 void
 rbdestroy(struct rbtree *tree, void (*destroy)(void *))
 {
+    debug_decl(rbdestroy, SUDO_DEBUG_RBTREE)
     _rbdestroy(tree, rbfirst(tree), destroy);
     efree(tree);
+    debug_return;
 }
 
 /*
@@ -353,6 +369,7 @@ void *rbdelete(struct rbtree *tree, struct rbnode *z)
 {
     struct rbnode *x, *y;
     void *data = z->data;
+    debug_decl(rbdelete, SUDO_DEBUG_RBTREE)
 
     if (z->left == rbnil(tree) || z->right == rbnil(tree))
        y = z;
@@ -383,7 +400,7 @@ void *rbdelete(struct rbtree *tree, struct rbnode *z)
     }
     free(z); 
     
-    return data;
+    debug_return_ptr(data);
 }
 
 /*
@@ -394,6 +411,7 @@ static void
 rbrepair(struct rbtree *tree, struct rbnode *node)
 {
     struct rbnode *sibling;
+    debug_decl(rbrepair, SUDO_DEBUG_RBTREE)
 
     while (node->color == black && node != rbroot(tree)) {
        if (node == node->parent->left) {
@@ -447,4 +465,6 @@ rbrepair(struct rbtree *tree, struct rbnode *node)
        }
     }
     node->color = black;
+
+    debug_return;
 }
index 036d86a71a94346ca8438dbff53a69cc94bfbbe3..f8079adb11337fe2dd218ef1909a6470ac45d8bd 100644 (file)
 #include <grp.h>
 #include <time.h>
 
+#define SUDO_ERROR_WRAP 0
+
 #define _SUDO_MAIN
 #include "sudoers.h"
 #include "def_data.c"
 
 struct sudo_user sudo_user;
 struct passwd *list_pw;
+sudo_conv_t sudo_conv;         /* NULL in non-plugin */
 
 static char sessid[7];
 
index 33d7b9ddd7ef75d7d6de3f48baaf3e79fc9ea85f..2b9b8a22c96aefa6a7c2442eda7646659a0ebd80 100644 (file)
 # include <strings.h>
 #endif /* HAVE_STRINGS_H */
 
+#define SUDO_ERROR_WRAP 0
+
 #include "missing.h"
 #include "error.h"
+#include "sudo_plugin.h"
+
+sudo_conv_t sudo_conv;         /* NULL in non-plugin */
 
 extern void writeln_wrap(FILE *fp, char *line, size_t len, size_t maxlen);
 
index 184b99fe0b96a63276f8384d8962a4fa5efc30ff..a73de59c7d5965c7f906d9942fc681448f27d17b 100644 (file)
@@ -43,6 +43,8 @@
 #include <arpa/inet.h>
 #include <netdb.h>
 
+#define SUDO_ERROR_WRAP 0
+
 #include "sudoers.h"
 #include "parse.h"
 #include "interfaces.h"
@@ -53,6 +55,8 @@ static int check_addr_printf(int msg_type, const char *fmt, ...);
 struct interface *interfaces;
 sudo_printf_t sudo_printf = check_addr_printf;
 
+sudo_conv_t sudo_conv;         /* NULL in non-plugin */
+
 static int
 check_addr(char *input)
 {
index 599a202e21c1070d4f9a980e5b7437e09d08ffab..e0f39214f869687d4ffc935cb7c751d7856a8e81 100644 (file)
 #  include <stdlib.h>
 # endif
 #endif /* STDC_HEADERS */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
 #ifdef HAVE_STRING_H
 # include <string.h>
 #endif /* HAVE_STRING_H */
 #include <grp.h>
 #include <pwd.h>
 
+#define SUDO_ERROR_WRAP 0
+
 #include "list.h"
 #include "parse.h"
 #include "toke.h"
-#include "gram.h"
+#include "sudo_plugin.h"
+#include <gram.h>
 
 /*
  * TODO: test realloc
  */
 
+sudo_conv_t sudo_conv;         /* NULL in non-plugin */
+
 YYSTYPE yylval;
 
 struct fill_test {
index 851e64426a4f617c17aabc4264eb34153e0b11c2..1c0bc4b436124ae2fbcb15b317f051f3992484a0 100644 (file)
@@ -1,4 +1,4 @@
-Does not parse.
+Parse error in sudoers near line 7.
 
 
 User_Alias     BAR = bar
index 6b6f2619b7182a67877d5c0aea91d972d172ff6a..3f6e2f215e2b21429c6d6a64143bfc55bdce4c6c 100644 (file)
@@ -1,4 +1,4 @@
-Does not parse.
+Parse error in sudoers near line 2.
 
 
 
index 6b6f2619b7182a67877d5c0aea91d972d172ff6a..3f6e2f215e2b21429c6d6a64143bfc55bdce4c6c 100644 (file)
@@ -1,4 +1,4 @@
-Does not parse.
+Parse error in sudoers near line 2.
 
 
 
index ccea9044c3ddd6e7075b6cc291545392d5a581e6..2f07300776701f056bc3e7c4d79050f694d62a44 100644 (file)
@@ -1,4 +1,4 @@
-Does not parse.
+Parse error in sudoers near line 8.
 
 
 User_Alias     UA1 = xy
index 655ed298354899748ba82a87ddb3fe522bcaed92..0cadc88f01245c5d2a0f735207c45526ab476d34 100644 (file)
@@ -82,9 +82,13 @@ static int perm_stack_depth = 0;
 void
 rewind_perms(void)
 {
+    debug_decl(rewind_perms, SUDO_DEBUG_PERMS)
+
     while (perm_stack_depth > 1)
        restore_perms();
     grlist_delref(perm_stack[0].grlist);
+
+    debug_return;
 }
 
 #ifdef HAVE_SETRESUID
@@ -101,6 +105,7 @@ set_perms(int perm)
     struct perm_state *state, *ostate = NULL;
     const char *errstr;
     int noexit;
+    debug_decl(set_perms, SUDO_DEBUG_PERMS)
 
     noexit = ISSET(perm, PERM_NOEXIT);
     CLR(perm, PERM_MASK);
@@ -279,13 +284,13 @@ set_perms(int perm)
 
 done:
     perm_stack_depth++;
-    return 1;
+    debug_return_bool(1);
 bad:
     /* XXX - better warnings inline */
     warningx("%s: %s", errstr,
        errno == EAGAIN ? _("too many processes") : strerror(errno));
     if (noexit)
-       return 0;
+       debug_return_bool(0);
     exit(1);
 }
 
@@ -293,9 +298,10 @@ void
 restore_perms(void)
 {
     struct perm_state *state, *ostate;
+    debug_decl(restore_perms, SUDO_DEBUG_PERMS)
 
     if (perm_stack_depth < 2)
-       return;
+       debug_return;
 
     state = &perm_stack[perm_stack_depth - 1];
     ostate = &perm_stack[perm_stack_depth - 2];
@@ -329,7 +335,7 @@ restore_perms(void)
        }
     }
     grlist_delref(state->grlist);
-    return;
+    debug_return;
 
 bad:
     exit(1);
@@ -350,6 +356,7 @@ set_perms(int perm)
     struct perm_state *state, *ostate = NULL;
     const char *errstr;
     int noexit;
+    debug_decl(set_perms, SUDO_DEBUG_PERMS)
 
     noexit = ISSET(perm, PERM_NOEXIT);
     CLR(perm, PERM_MASK);
@@ -385,19 +392,20 @@ set_perms(int perm)
 
     case PERM_ROOT:
        /*
-        * setreuid(0, 0) may fail on some systems
-        * when the euid is not already 0.
+        * setreuid(0, 0) may fail on some systems if euid is not already 0.
         */
-       if (setreuid(-1, ROOT_UID)) {
-           errstr = "setreuid(-1, ROOT_UID)";
-           goto bad;
+       if (ostate->euid != ROOT_UID) {
+           if (setreuid(-1, ROOT_UID)) {
+               errstr = "setreuid(-1, ROOT_UID)";
+               goto bad;
+           }
        }
-       if (setuid(ROOT_UID)) {
-           errstr = "setuid(ROOT_UID)";
+       state->euid = ROOT_UID;
+       if (setreuid(ID(ruid), -1)) {
+           errstr = "setreuid(ROOT_UID, -1)";
            goto bad;
        }
        state->ruid = ROOT_UID;
-       state->euid = ROOT_UID;
        state->rgid = -1;
        state->egid = -1;
        state->grlist = ostate->grlist;
@@ -509,13 +517,13 @@ set_perms(int perm)
 
 done:
     perm_stack_depth++;
-    return 1;
+    debug_return_bool(1);
 bad:
     /* XXX - better warnings inline */
     warningx("%s: %s", errstr,
        errno == EAGAIN ? _("too many processes") : strerror(errno));
     if (noexit)
-       return 0;
+       debug_return_bool(0);
     exit(1);
 }
 
@@ -523,9 +531,10 @@ void
 restore_perms(void)
 {
     struct perm_state *state, *ostate;
+    debug_decl(restore_perms, SUDO_DEBUG_PERMS)
 
     if (perm_stack_depth < 2)
-       return;
+       debug_return;
 
     state = &perm_stack[perm_stack_depth - 1];
     ostate = &perm_stack[perm_stack_depth - 2];
@@ -562,7 +571,7 @@ restore_perms(void)
        }
     }
     grlist_delref(state->grlist);
-    return;
+    debug_return;
 
 bad:
     exit(1);
@@ -583,6 +592,7 @@ set_perms(int perm)
     struct perm_state *state, *ostate = NULL;
     const char *errstr;
     int noexit;
+    debug_decl(set_perms, SUDO_DEBUG_PERMS)
 
     noexit = ISSET(perm, PERM_NOEXIT);
     CLR(perm, PERM_MASK);
@@ -747,13 +757,13 @@ set_perms(int perm)
 
 done:
     perm_stack_depth++;
-    return 1;
+    debug_return_bool(1);
 bad:
     /* XXX - better warnings inline */
     warningx("%s: %s", errstr,
        errno == EAGAIN ? _("too many processes") : strerror(errno));
     if (noexit)
-       return 0;
+       debug_return_bool(0);
     exit(1);
 }
 
@@ -761,9 +771,10 @@ void
 restore_perms(void)
 {
     struct perm_state *state, *ostate;
+    debug_decl(restore_perms, SUDO_DEBUG_PERMS)
 
     if (perm_stack_depth < 2)
-       return;
+       debug_return;
 
     state = &perm_stack[perm_stack_depth - 1];
     ostate = &perm_stack[perm_stack_depth - 2];
@@ -798,7 +809,7 @@ restore_perms(void)
        goto bad;
     }
     grlist_delref(state->grlist);
-    return;
+    debug_return;
 
 bad:
     exit(1);
@@ -817,6 +828,7 @@ set_perms(int perm)
     struct perm_state *state, *ostate = NULL;
     const char *errstr;
     int noexit;
+    debug_decl(set_perms, SUDO_DEBUG_PERMS)
 
     noexit = ISSET(perm, PERM_NOEXIT);
     CLR(perm, PERM_MASK);
@@ -887,13 +899,13 @@ set_perms(int perm)
 
 done:
     perm_stack_depth++;
-    return 1;
+    debug_return_bool(1);
 bad:
     /* XXX - better warnings inline */
     warningx("%s: %s", errstr,
        errno == EAGAIN ? _("too many processes") : strerror(errno));
     if (noexit)
-       return 0;
+       debug_return_bool(0);
     exit(1);
 }
 
@@ -901,9 +913,10 @@ void
 restore_perms(void)
 {
     struct perm_state *state, *ostate;
+    debug_decl(restore_perms, SUDO_DEBUG_PERMS)
 
     if (perm_stack_depth < 2)
-       return;
+       debug_return;
 
     state = &perm_stack[perm_stack_depth - 1];
     ostate = &perm_stack[perm_stack_depth - 2];
@@ -924,7 +937,7 @@ restore_perms(void)
        warning("setuid(%d)", (int)ostate->ruid);
        goto bad;
     }
-    return;
+    debug_return;
 
 bad:
     exit(1);
@@ -938,10 +951,11 @@ runas_setgroups(void)
 {
     struct passwd *pw;
     struct group_list *grlist;
+    debug_decl(runas_setgroups, SUDO_DEBUG_PERMS)
 
     if (def_preserve_groups) {
        grlist_addref(user_group_list);
-       return user_group_list;
+       debug_return_ptr(user_group_list);
     }
 
     pw = runas_pw ? runas_pw : sudo_user.pw;
@@ -954,5 +968,5 @@ runas_setgroups(void)
 #endif
     if (sudo_setgroups(grlist->ngids, grlist->gids) < 0)
        log_error(USE_ERRNO|MSG_ONLY, _("unable to set runas group vector"));
-    return grlist;
+    debug_return_ptr(grlist);
 }
index de0d5a6bb4ce59673cbbc76abbf694dcf4797369..d8ed0f5de19f3855554d0f249fc5764c96fd417c 100644 (file)
@@ -58,10 +58,11 @@ sudo_read_nss(void)
 {
     FILE *fp;
     char *cp;
-    int saw_files = FALSE;
-    int saw_ldap = FALSE;
-    int got_match = FALSE;
+    bool saw_files = false;
+    bool saw_ldap = false;
+    bool got_match = false;
     static struct sudo_nss_list snl;
+    debug_decl(sudo_read_nss, SUDO_DEBUG_NSS)
 
     if ((fp = fopen(_PATH_NSSWITCH_CONF, "r")) == NULL)
        goto nomatch;
@@ -79,16 +80,16 @@ sudo_read_nss(void)
        for ((cp = strtok(cp + 8, " \t")); cp != NULL; (cp = strtok(NULL, " \t"))) {
            if (strcasecmp(cp, "files") == 0 && !saw_files) {
                tq_append(&snl, &sudo_nss_file);
-               got_match = TRUE;
+               got_match = true;
            } else if (strcasecmp(cp, "ldap") == 0 && !saw_ldap) {
                tq_append(&snl, &sudo_nss_ldap);
-               got_match = TRUE;
+               got_match = true;
            } else if (strcasecmp(cp, "[NOTFOUND=return]") == 0 && got_match) {
                /* NOTFOUND affects the most recent entry */
-               tq_last(&snl)->ret_if_notfound = TRUE;
-               got_match = FALSE;
+               tq_last(&snl)->ret_if_notfound = true;
+               got_match = false;
            } else
-               got_match = FALSE;
+               got_match = false;
        }
        /* Only parse the first "sudoers:" line */
        break;
@@ -100,7 +101,7 @@ nomatch:
     if (tq_empty(&snl))
        tq_append(&snl, &sudo_nss_file);
 
-    return &snl;
+    debug_return_ptr(&snl);
 }
 
 #else /* HAVE_LDAP && _PATH_NSSWITCH_CONF */
@@ -116,10 +117,11 @@ sudo_read_nss(void)
 {
     FILE *fp;
     char *cp, *ep;
-    int saw_files = FALSE;
-    int saw_ldap = FALSE;
-    int got_match = FALSE;
+    bool saw_files = false;
+    bool saw_ldap = false;
+    bool got_match = false;
     static struct sudo_nss_list snl;
+    debug_decl(sudo_read_nss, SUDO_DEBUG_NSS)
 
     if ((fp = fopen(_PATH_NETSVC_CONF, "r")) == NULL)
        goto nomatch;
@@ -147,15 +149,15 @@ sudo_read_nss(void)
            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;
+               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;
+               got_match = true;
                ep = &cp[4];
            } else {
-               got_match = FALSE;
+               got_match = false;
            }
 
            /* check for = auth qualifier */
@@ -165,7 +167,7 @@ sudo_read_nss(void)
                    cp++;
                if (strncasecmp(cp, "auth", 4) == 0 &&
                    (isspace((unsigned char)cp[4]) || cp[4] == '\0')) {
-                   tq_last(&snl)->ret_if_found = TRUE;
+                   tq_last(&snl)->ret_if_found = true;
                }
            }
        }
@@ -179,7 +181,7 @@ nomatch:
     if (tq_empty(&snl))
        tq_append(&snl, &sudo_nss_file);
 
-    return &snl;
+    debug_return_ptr(&snl);
 }
 
 # else /* !_PATH_NETSVC_CONF && !_PATH_NSSWITCH_CONF */
@@ -191,13 +193,14 @@ struct sudo_nss_list *
 sudo_read_nss(void)
 {
     static struct sudo_nss_list snl;
+    debug_decl(sudo_read_nss, SUDO_DEBUG_NSS)
 
 #  ifdef HAVE_LDAP
     tq_append(&snl, &sudo_nss_ldap);
 #  endif
     tq_append(&snl, &sudo_nss_file);
 
-    return &snl;
+    debug_return_ptr(&snl);
 }
 
 # endif /* !HAVE_LDAP || !_PATH_NETSVC_CONF */
@@ -209,6 +212,7 @@ output(const char *buf)
 {
     struct sudo_conv_message msg;
     struct sudo_conv_reply repl;
+    debug_decl(output, SUDO_DEBUG_NSS)
 
     /* Call conversation function */
     memset(&msg, 0, sizeof(msg));
@@ -216,8 +220,8 @@ output(const char *buf)
     msg.msg = buf;
     memset(&repl, 0, sizeof(repl));
     if (sudo_conv(1, &msg, &repl) == -1)
-       return 0;
-    return (int)strlen(buf);
+       debug_return_int(0);
+    debug_return_int(strlen(buf));
 }
 
 /*
@@ -230,6 +234,7 @@ display_privs(struct sudo_nss_list *snl, struct passwd *pw)
     struct sudo_nss *nss;
     struct lbuf defs, privs;
     int count, olen;
+    debug_decl(display_privs, SUDO_DEBUG_NSS)
 
     lbuf_init(&defs, output, 4, NULL, sudo_user.cols);
     lbuf_init(&privs, output, 4, NULL, sudo_user.cols);
@@ -277,21 +282,24 @@ display_privs(struct sudo_nss_list *snl, struct passwd *pw)
 
     lbuf_destroy(&defs);
     lbuf_destroy(&privs);
+
+    debug_return;
 }
 
 /*
  * Check user_cmnd against sudoers and print the matching entry if the
  * command is allowed.
- * Returns TRUE if the command is allowed, else FALSE.
+ * Returns true if the command is allowed, else false.
  */
-int
+bool
 display_cmnd(struct sudo_nss_list *snl, struct passwd *pw)
 {
     struct sudo_nss *nss;
+    debug_decl(display_cmnd, SUDO_DEBUG_NSS)
 
     tq_foreach_fwd(snl, nss) {
        if (nss->display_cmnd(nss, pw) == 0)
-           return TRUE;
+           debug_return_bool(true);
     }
-    return FALSE;
+    debug_return_bool(false);
 }
index 0e25866d4d3396734a336231b845c103573b518e..168b23307994acac2ac0cd8f8cff37563932201d 100644 (file)
@@ -76,6 +76,9 @@
 #endif
 #include <ctype.h>
 #include <setjmp.h>
+#ifndef HAVE_GETADDRINFO
+# include "compat/getaddrinfo.h"
+#endif
 
 #include "sudoers.h"
 #include "interfaces.h"
@@ -107,14 +110,10 @@ struct sudo_user sudo_user;
 struct passwd *list_pw;
 struct interface *interfaces;
 int long_list;
-int debug_level;
 uid_t timestamp_uid;
 extern int errorlineno;
-extern int parse_error;
+extern bool parse_error;
 extern char *errorfile;
-#ifdef HAVE_LOGIN_CAP_H
-login_cap_t *lc;
-#endif /* HAVE_LOGIN_CAP_H */
 #ifdef HAVE_BSD_AUTH_H
 char *login_style;
 #endif /* HAVE_BSD_AUTH_H */
@@ -133,8 +132,8 @@ static sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp;
 int NewArgc;
 char **NewArgv;
 
-/* plugin_error.c */
-extern sigjmp_buf error_jmp;
+/* Declared here instead of plugin_error.c for static sudo builds. */
+sigjmp_buf error_jmp;
 
 static int
 sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
@@ -144,6 +143,7 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
     volatile int sources = 0;
     sigaction_t sa;
     struct sudo_nss *nss;
+    debug_decl(sudoers_policy_open, SUDO_DEBUG_PLUGIN)
 
     if (!sudo_conv)
        sudo_conv = conversation;
@@ -153,7 +153,7 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
     if (sigsetjmp(error_jmp, 1)) {
        /* called via error(), errorx() or log_error() */
        rewind_perms();
-       return -1;
+       debug_return_bool(-1);
     }
 
     bindtextdomain("sudoers", LOCALEDIR);
@@ -203,7 +203,7 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
     }
     if (sources == 0) {
        warningx(_("no valid sudoers sources found, quitting"));
-       return -1;
+       debug_return_bool(-1);
     }
 
     /* XXX - collect post-sudoers parse settings into a function */
@@ -212,7 +212,7 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
      * Initialize external group plugin, if any.
      */
     if (def_group_plugin) {
-       if (group_plugin_load(def_group_plugin) != TRUE)
+       if (group_plugin_load(def_group_plugin) != true)
            def_group_plugin = NULL;
     }
 
@@ -235,19 +235,21 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
        set_fqdn();     /* deferred until after sudoers is parsed */
 
     /* Set login class if applicable. */
-    set_loginclass(sudo_user.pw);
+    set_loginclass(runas_pw ? runas_pw : sudo_user.pw);
 
     restore_perms();
 
-    return TRUE;
+    debug_return_bool(true);
 }
 
 static void
 sudoers_policy_close(int exit_status, int error_code)
 {
+    debug_decl(sudoers_policy_close, SUDO_DEBUG_PLUGIN)
+
     if (sigsetjmp(error_jmp, 1)) {
        /* called via error(), errorx() or log_error() */
-       return;
+       debug_return;
     }
 
     /* We do not currently log the exit status. */
@@ -265,6 +267,8 @@ sudoers_policy_close(int exit_status, int error_code)
        gr_delref(runas_gr);
     if (user_group_list != NULL)
        grlist_delref(user_group_list);
+
+    debug_return;
 }
 
 /*
@@ -274,12 +278,14 @@ sudoers_policy_close(int exit_status, int error_code)
 static int
 sudoers_policy_init_session(struct passwd *pwd)
 {
+    debug_decl(sudoers_policy_init, SUDO_DEBUG_PLUGIN)
+
     if (sigsetjmp(error_jmp, 1)) {
        /* called via error(), errorx() or log_error() */
        return -1;
     }
 
-    return sudo_auth_begin_session(pwd);
+    debug_return_bool(sudo_auth_begin_session(pwd));
 }
 
 static int
@@ -291,7 +297,8 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
     struct sudo_nss *nss;
     int cmnd_status = -1, validated;
     volatile int info_len = 0;
-    volatile int rval = TRUE;
+    volatile int rval = true;
+    debug_decl(sudoers_policy_main, SUDO_DEBUG_PLUGIN)
 
     if (sigsetjmp(error_jmp, 1)) {
        /* error recovery via error(), errorx() or log_error() */
@@ -335,13 +342,13 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
        NewArgv = emalloc2(NewArgc + 2, sizeof(char *));
        memcpy(++NewArgv, argv, argc * sizeof(char *));
        NewArgv[NewArgc] = NULL;
-       if (ISSET(sudo_mode, MODE_LOGIN_SHELL))
+       if (ISSET(sudo_mode, MODE_LOGIN_SHELL) && runas_pw != NULL)
            NewArgv[0] = estrdup(runas_pw->pw_shell);
     }
 
     /* If given the -P option, set the "preserve_groups" flag. */
     if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS))
-       def_preserve_groups = TRUE;
+       def_preserve_groups = true;
 
     /* Find command in path */
     cmnd_status = set_cmnd();
@@ -427,14 +434,14 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
      */
     if (ISSET(sudo_mode, MODE_EDIT) ||
        (ISSET(sudo_mode, MODE_PRESERVE_ENV) && def_setenv))
-       def_env_reset = FALSE;
+       def_env_reset = false;
 
     /* Build a new environment that avoids any nasty bits. */
     rebuild_env();
 
     /* Require a password if sudoers says so.  */
     rval = check_user(validated, sudo_mode);
-    if (rval != TRUE)
+    if (rval != true)
        goto done;
 
     /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */
@@ -584,13 +591,13 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
 
 #if defined(__linux__) || defined(_AIX)
        /* Insert system-wide environment variables. */
-       read_env_file(_PATH_ENVIRONMENT, TRUE);
+       read_env_file(_PATH_ENVIRONMENT, true);
 #endif
     }
 
     /* Insert system-wide environment variables. */
     if (def_env_file)
-       read_env_file(def_env_file, FALSE);
+       read_env_file(def_env_file, false);
 
     /* Insert user-specified environment variables. */
     insert_env_vars(sudo_user.env_vars);
@@ -630,19 +637,33 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
        command_info[info_len++] = "preserve_groups=true";
     } else {
        int i, len;
+       gid_t egid;
        size_t glsize;
        char *cp, *gid_list;
        struct group_list *grlist = get_group_list(runas_pw);
 
-       glsize = sizeof("runas_groups=") - 1 + (grlist->ngids * (MAX_UID_T_LEN + 1));
+       /* We reserve an extra spot in the list for the effective gid. */
+       glsize = sizeof("runas_groups=") - 1 +
+           ((grlist->ngids + 1) * (MAX_UID_T_LEN + 1));
        gid_list = emalloc(glsize);
        memcpy(gid_list, "runas_groups=", sizeof("runas_groups=") - 1);
        cp = gid_list + sizeof("runas_groups=") - 1;
+
+       /* On BSD systems the effective gid is the first group in the list. */
+       egid = runas_gr ? (unsigned int)runas_gr->gr_gid :
+           (unsigned int)runas_pw->pw_gid;
+       len = snprintf(cp, glsize - (cp - gid_list), "%u", egid);
+       if (len < 0 || len >= glsize - (cp - gid_list))
+           errorx(1, _("internal error, runas_groups overflow"));
+       cp += len;
        for (i = 0; i < grlist->ngids; i++) {
-           /* XXX - check rval */
-           len = snprintf(cp, glsize - (cp - gid_list), "%s%u",
-                i ? "," : "", (unsigned int) grlist->gids[i]);
-           cp += len;
+           if (grlist->gids[i] != egid) {
+               len = snprintf(cp, glsize - (cp - gid_list), ",%u",
+                    (unsigned int) grlist->gids[i]);
+               if (len < 0 || len >= glsize - (cp - gid_list))
+                   errorx(1, _("internal error, runas_groups overflow"));
+               cp += len;
+           }
        }
        command_info[info_len++] = gid_list;
        grlist_delref(grlist);
@@ -651,8 +672,6 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
        easprintf(&command_info[info_len++], "closefrom=%d", def_closefrom);
     if (def_noexec)
        command_info[info_len++] = estrdup("noexec=true");
-    if (def_noexec_file)
-       command_info[info_len++] = fmt_string("noexec_file", def_noexec_file);
     if (def_set_utmp)
        command_info[info_len++] = estrdup("set_utmp=true");
     if (def_use_pty)
@@ -660,8 +679,8 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
     if (def_utmp_runas)
        command_info[info_len++] = fmt_string("utmp_user", runas_pw->pw_name);
 #ifdef HAVE_LOGIN_CAP_H
-    if (lc != NULL)
-       command_info[info_len++] = fmt_string("login_class", lc->lc_class);
+    if (def_use_loginclass)
+       command_info[info_len++] = fmt_string("login_class", login_class);
 #endif /* HAVE_LOGIN_CAP_H */
 #ifdef HAVE_SELINUX
     if (user_role != NULL)
@@ -681,7 +700,7 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
     goto done;
 
 bad:
-    rval = FALSE;
+    rval = false;
 
 done:
     rewind_perms();
@@ -690,37 +709,45 @@ done:
     sudo_endpwent();
     sudo_endgrent();
 
-    return rval;
+    debug_return_bool(rval);
 }
 
 static int
 sudoers_policy_check(int argc, char * const argv[], char *env_add[],
     char **command_infop[], char **argv_out[], char **user_env_out[])
 {
+    debug_decl(sudoers_policy_check, SUDO_DEBUG_PLUGIN)
+
     if (!ISSET(sudo_mode, MODE_EDIT))
        SET(sudo_mode, MODE_RUN);
 
-    return sudoers_policy_main(argc, argv, 0, env_add, command_infop,
-       argv_out, user_env_out);
+    debug_return_bool(sudoers_policy_main(argc, argv, 0, env_add, command_infop,
+       argv_out, user_env_out));
 }
 
 static int
 sudoers_policy_validate(void)
 {
+    debug_decl(sudoers_policy_validate, SUDO_DEBUG_PLUGIN)
+
     user_cmnd = "validate";
     SET(sudo_mode, MODE_VALIDATE);
 
-    return sudoers_policy_main(0, NULL, I_VERIFYPW, NULL, NULL, NULL, NULL);
+    debug_return_bool(sudoers_policy_main(0, NULL, I_VERIFYPW, NULL, NULL, NULL, NULL));
 }
 
 static void
 sudoers_policy_invalidate(int remove)
 {
+    debug_decl(sudoers_policy_invalidate, SUDO_DEBUG_PLUGIN)
+
     user_cmnd = "kill";
     if (sigsetjmp(error_jmp, 1) == 0) {
        remove_timestamp(remove);
        plugin_cleanup(0);
     }
+
+    debug_return;
 }
 
 static int
@@ -728,6 +755,7 @@ sudoers_policy_list(int argc, char * const argv[], int verbose,
     const char *list_user)
 {
     int rval;
+    debug_decl(sudoers_policy_list, SUDO_DEBUG_PLUGIN)
 
     user_cmnd = "list";
     if (argc)
@@ -740,7 +768,7 @@ sudoers_policy_list(int argc, char * const argv[], int verbose,
        list_pw = sudo_getpwnam(list_user);
        if (list_pw == NULL) {
            warningx(_("unknown user: %s"), list_user);
-           return -1;
+           debug_return_bool(-1);
        }
     }
     rval = sudoers_policy_main(argc, argv, I_LISTPW, NULL, NULL, NULL, NULL);
@@ -749,7 +777,7 @@ sudoers_policy_list(int argc, char * const argv[], int verbose,
        list_pw = NULL;
     }
 
-    return rval;
+    debug_return_bool(rval);
 }
 
 /*
@@ -760,6 +788,7 @@ static void
 init_vars(char * const envp[])
 {
     char * const * ep;
+    debug_decl(init_vars, SUDO_DEBUG_PLUGIN)
 
 #ifdef HAVE_TZSET
     (void) tzset();            /* set the timezone if applicable */
@@ -815,6 +844,7 @@ init_vars(char * const envp[])
     sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default;
 
     /* It is now safe to use log_error() and set_perms() */
+    debug_return;
 }
 
 /*
@@ -826,6 +856,7 @@ set_cmnd(void)
 {
     int rval;
     char *path = user_path;
+    debug_decl(set_cmnd, SUDO_DEBUG_PLUGIN)
 
     /* Resolve the path and return. */
     rval = FOUND;
@@ -899,7 +930,7 @@ set_cmnd(void)
     if (!update_defaults(SETDEF_CMND))
        log_error(NO_STDERR|NO_EXIT, _("problem with defaults entries"));
 
-    return rval;
+    debug_return_int(rval);
 }
 
 /*
@@ -907,11 +938,12 @@ set_cmnd(void)
  * Returns a handle to the sudoers file or NULL on error.
  */
 FILE *
-open_sudoers(const char *sudoers, int doedit, int *keepopen)
+open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
 {
     struct stat statbuf;
     FILE *fp = NULL;
     int rootstat;
+    debug_decl(open_sudoers, SUDO_DEBUG_PLUGIN)
 
     /*
      * Fix the mode and group on sudoers file from old default.
@@ -946,7 +978,7 @@ open_sudoers(const char *sudoers, int doedit, int *keepopen)
        log_error(USE_ERRNO|NO_EXIT, _("unable to stat %s"), sudoers);
     else if (!S_ISREG(statbuf.st_mode))
        log_error(NO_EXIT, _("%s is not a regular file"), sudoers);
-    else if ((statbuf.st_mode & 07577) != sudoers_mode)
+    else if ((statbuf.st_mode & 07577) != (sudoers_mode & 07577))
        log_error(NO_EXIT, _("%s is mode 0%o, should be 0%o"), sudoers,
            (unsigned int) (statbuf.st_mode & 07777),
            (unsigned int) sudoers_mode);
@@ -976,7 +1008,7 @@ open_sudoers(const char *sudoers, int doedit, int *keepopen)
     }
 
     restore_perms();           /* change back to root */
-    return fp;
+    debug_return_ptr(fp);
 }
 
 #ifdef HAVE_LOGIN_CAP_H
@@ -984,6 +1016,11 @@ static void
 set_loginclass(struct passwd *pw)
 {
     int errflags;
+    login_cap_t *lc;
+    debug_decl(set_loginclass, SUDO_DEBUG_PLUGIN)
+
+    if (!def_use_loginclass)
+       debug_return;
 
     /*
      * Don't make it a fatal error if the user didn't specify the login
@@ -1006,12 +1043,14 @@ set_loginclass(struct passwd *pw)
                (pw->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS;
     }
 
+    /* Make sure specified login class is valid. */
     lc = login_getclass(login_class);
     if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0) {
        log_error(errflags, _("unknown login class: %s"), login_class);
-       if (!lc)
-           lc = login_getclass(NULL);  /* needed for login_getstyle() later */
+       def_use_loginclass = false;
     }
+    login_close(lc);
+    debug_return;
 }
 #else
 static void
@@ -1026,47 +1065,39 @@ set_loginclass(struct passwd *pw)
 void
 set_fqdn(void)
 {
-#ifdef HAVE_GETADDRINFO
     struct addrinfo *res0, hint;
-#else
-    struct hostent *hp;
-#endif
     char *p;
+    debug_decl(set_fqdn, SUDO_DEBUG_PLUGIN)
 
-#ifdef HAVE_GETADDRINFO
     zero_bytes(&hint, sizeof(hint));
     hint.ai_family = PF_UNSPEC;
     hint.ai_flags = AI_CANONNAME;
     if (getaddrinfo(user_host, NULL, &hint, &res0) != 0) {
-#else
-    if (!(hp = gethostbyname(user_host))) {
-#endif
        log_error(MSG_ONLY|NO_EXIT,
            _("unable to resolve host %s"), user_host);
     } else {
        if (user_shost != user_host)
            efree(user_shost);
        efree(user_host);
-#ifdef HAVE_GETADDRINFO
        user_host = estrdup(res0->ai_canonname);
        freeaddrinfo(res0);
-#else
-       user_host = estrdup(hp->h_name);
-#endif
     }
     if ((p = strchr(user_host, '.')) != NULL)
        user_shost = estrndup(user_host, (size_t)(p - user_host));
     else
        user_shost = user_host;
+    debug_return;
 }
 
 /*
  * Get passwd entry for the user we are going to run commands as
  * and store it in runas_pw.  By default, commands run as "root".
  */
-void
+static void
 set_runaspw(const char *user)
 {
+    debug_decl(set_runaspw, SUDO_DEBUG_PLUGIN)
+
     if (runas_pw != NULL)
        pw_delref(runas_pw);
     if (*user == '#') {
@@ -1076,6 +1107,7 @@ set_runaspw(const char *user)
        if ((runas_pw = sudo_getpwnam(user)) == NULL)
            log_error(NO_MAIL|MSG_ONLY, _("unknown user: %s"), user);
     }
+    debug_return;
 }
 
 /*
@@ -1085,6 +1117,8 @@ set_runaspw(const char *user)
 static void
 set_runasgr(const char *group)
 {
+    debug_decl(set_runasgr, SUDO_DEBUG_PLUGIN)
+
     if (runas_gr != NULL)
        gr_delref(runas_gr);
     if (*group == '#') {
@@ -1094,6 +1128,7 @@ set_runasgr(const char *group)
        if ((runas_gr = sudo_getgrnam(group)) == NULL)
            log_error(NO_MAIL|MSG_ONLY, _("unknown group: %s"), group);
     }
+    debug_return;
 }
 
 /*
@@ -1105,7 +1140,7 @@ cb_runas_default(const char *user)
     /* Only reset runaspw if user didn't specify one. */
     if (!runas_user && !runas_group)
        set_runaspw(user);
-    return TRUE;
+    return true;
 }
 
 /*
@@ -1117,6 +1152,7 @@ plugin_cleanup(int gotsignal)
     struct sudo_nss *nss;
 
     if (!gotsignal) {
+       debug_decl(plugin_cleanup, SUDO_DEBUG_PLUGIN)
        if (snl != NULL) {
            tq_foreach_fwd(snl, nss)
                nss->close(nss);
@@ -1125,15 +1161,18 @@ plugin_cleanup(int gotsignal)
            group_plugin_unload();
        sudo_endpwent();
        sudo_endgrent();
+       debug_return;
     }
 }
 
 static int
 sudoers_policy_version(int verbose)
 {
+    debug_decl(sudoers_policy_version, SUDO_DEBUG_PLUGIN)
+
     if (sigsetjmp(error_jmp, 1)) {
        /* error recovery via error(), errorx() or log_error() */
-       return -1;
+       debug_return_bool(-1);
     }
 
     sudo_printf(SUDO_CONV_INFO_MSG, _("Sudoers policy plugin version %s\n"),
@@ -1153,10 +1192,12 @@ sudoers_policy_version(int verbose)
        dump_auth_methods();
        dump_defaults();
        sudo_printf(SUDO_CONV_INFO_MSG, "\n");
-       dump_interfaces(interfaces_string);
-       sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+       if (interfaces_string != NULL) {
+           dump_interfaces(interfaces_string);
+           sudo_printf(SUDO_CONV_INFO_MSG, "\n");
+       }
     }
-    return TRUE;
+    debug_return_bool(true);
 }
 
 static int
@@ -1164,7 +1205,9 @@ deserialize_info(char * const settings[], char * const user_info[])
 {
     char * const *cur;
     const char *p, *groups = NULL;
+    const char *debug_flags = NULL;
     int flags = 0;
+    debug_decl(deserialize_info, SUDO_DEBUG_PLUGIN)
 
 #define MATCHES(s, v) (strncmp(s, v, sizeof(v) - 1) == 0)
 
@@ -1175,8 +1218,8 @@ deserialize_info(char * const settings[], char * const user_info[])
            user_closefrom = atoi(*cur + sizeof("closefrom=") - 1);
            continue;
        }
-       if (MATCHES(*cur, "debug_level=")) {
-           debug_level = atoi(*cur + sizeof("debug_level=") - 1);
+       if (MATCHES(*cur, "debug_flags=")) {
+           debug_flags = *cur + sizeof("debug_flags=") - 1;
            continue;
        }
        if (MATCHES(*cur, "runas_user=")) {
@@ -1189,59 +1232,59 @@ deserialize_info(char * const settings[], char * const user_info[])
        }
        if (MATCHES(*cur, "prompt=")) {
            user_prompt = *cur + sizeof("prompt=") - 1;
-           def_passprompt_override = TRUE;
+           def_passprompt_override = true;
            continue;
        }
        if (MATCHES(*cur, "set_home=")) {
-           if (atobool(*cur + sizeof("set_home=") - 1) == TRUE)
+           if (atobool(*cur + sizeof("set_home=") - 1) == true)
                SET(flags, MODE_RESET_HOME);
            continue;
        }
        if (MATCHES(*cur, "preserve_environment=")) {
-           if (atobool(*cur + sizeof("preserve_environment=") - 1) == TRUE)
+           if (atobool(*cur + sizeof("preserve_environment=") - 1) == true)
                SET(flags, MODE_PRESERVE_ENV);
            continue;
        }
        if (MATCHES(*cur, "run_shell=")) {
-           if (atobool(*cur + sizeof("run_shell=") - 1) == TRUE)
+           if (atobool(*cur + sizeof("run_shell=") - 1) == true)
                SET(flags, MODE_SHELL);
            continue;
        }
        if (MATCHES(*cur, "login_shell=")) {
-           if (atobool(*cur + sizeof("login_shell=") - 1) == TRUE) {
+           if (atobool(*cur + sizeof("login_shell=") - 1) == true) {
                SET(flags, MODE_LOGIN_SHELL);
-               def_env_reset = TRUE;
+               def_env_reset = true;
            }
            continue;
        }
        if (MATCHES(*cur, "implied_shell=")) {
-           if (atobool(*cur + sizeof("implied_shell=") - 1) == TRUE)
+           if (atobool(*cur + sizeof("implied_shell=") - 1) == true)
                SET(flags, MODE_IMPLIED_SHELL);
            continue;
        }
        if (MATCHES(*cur, "preserve_groups=")) {
-           if (atobool(*cur + sizeof("preserve_groups=") - 1) == TRUE)
+           if (atobool(*cur + sizeof("preserve_groups=") - 1) == true)
                SET(flags, MODE_PRESERVE_GROUPS);
            continue;
        }
        if (MATCHES(*cur, "ignore_ticket=")) {
-           if (atobool(*cur + sizeof("ignore_ticket=") - 1) == TRUE)
+           if (atobool(*cur + sizeof("ignore_ticket=") - 1) == true)
                SET(flags, MODE_IGNORE_TICKET);
            continue;
        }
        if (MATCHES(*cur, "noninteractive=")) {
-           if (atobool(*cur + sizeof("noninteractive=") - 1) == TRUE)
+           if (atobool(*cur + sizeof("noninteractive=") - 1) == true)
                SET(flags, MODE_NONINTERACTIVE);
            continue;
        }
        if (MATCHES(*cur, "sudoedit=")) {
-           if (atobool(*cur + sizeof("sudoedit=") - 1) == TRUE)
+           if (atobool(*cur + sizeof("sudoedit=") - 1) == true)
                SET(flags, MODE_EDIT);
            continue;
        }
        if (MATCHES(*cur, "login_class=")) {
            login_class = *cur + sizeof("login_class=") - 1;
-           def_use_loginclass = TRUE;
+           def_use_loginclass = true;
            continue;
        }
 #ifdef HAVE_SELINUX
@@ -1368,15 +1411,26 @@ deserialize_info(char * const settings[], char * const user_info[])
        efree(gids);
     }
 
+    /* Setup debugging if indicated. */
+    if (debug_flags != NULL) {
+       sudo_debug_init(NULL, debug_flags);
+       for (cur = settings; *cur != NULL; cur++)
+           sudo_debug_printf(SUDO_DEBUG_INFO, "settings: %s", *cur);
+       for (cur = user_info; *cur != NULL; cur++)
+           sudo_debug_printf(SUDO_DEBUG_INFO, "user_info: %s", *cur);
+    }
+
 #undef MATCHES
-    return flags;
+    debug_return_int(flags);
 }
 
 static char *
 resolve_editor(char *editor, int nfiles, char **files, char ***argv_out)
 {
     char *cp, **nargv, *editor_path = NULL;
-    int ac, i, nargc, wasblank;
+    int ac, i, nargc;
+    bool wasblank;
+    debug_decl(resolve_editor, SUDO_DEBUG_PLUGIN)
 
     editor = estrdup(editor); /* becomes part of argv_out */
 
@@ -1386,11 +1440,11 @@ resolve_editor(char *editor, int nfiles, char **files, char ***argv_out)
      * line args so look for those and alloc space for them too.
      */
     nargc = 1;
-    for (wasblank = FALSE, cp = editor; *cp != '\0'; cp++) {
+    for (wasblank = false, cp = editor; *cp != '\0'; cp++) {
        if (isblank((unsigned char) *cp))
-           wasblank = TRUE;
+           wasblank = true;
        else if (wasblank) {
-           wasblank = FALSE;
+           wasblank = false;
            nargc++;
        }
     }
@@ -1399,7 +1453,7 @@ resolve_editor(char *editor, int nfiles, char **files, char ***argv_out)
     if (cp == NULL ||
        find_path(cp, &editor_path, NULL, getenv("PATH"), 0) != FOUND) {
        efree(editor);
-       return NULL;
+       debug_return_str(NULL);
     }
     nargv = (char **) emalloc2(nargc + 1 + nfiles + 1, sizeof(char *));
     for (ac = 0; cp != NULL && ac < nargc; ac++) {
@@ -1412,7 +1466,7 @@ resolve_editor(char *editor, int nfiles, char **files, char ***argv_out)
     nargv[ac] = NULL;
 
     *argv_out = nargv;
-    return editor_path;
+    debug_return_str(editor_path);
 }
 
 /*
@@ -1424,6 +1478,7 @@ static char *
 find_editor(int nfiles, char **files, char ***argv_out)
 {
     char *cp, *editor, *editor_path = NULL, **ev, *ev0[4];
+    debug_decl(find_editor, SUDO_DEBUG_PLUGIN)
 
     /*
      * If any of SUDO_EDITOR, VISUAL or EDITOR are set, choose the first one.
@@ -1454,7 +1509,7 @@ find_editor(int nfiles, char **files, char ***argv_out)
        audit_failure(NewArgv, _("%s: command not found"), editor);
        warningx(_("%s: command not found"), editor);
     }
-    return editor_path;
+    debug_return_str(editor_path);
 }
 
 #ifdef USE_ADMIN_FLAG
@@ -1464,16 +1519,17 @@ create_admin_success_flag(void)
     struct stat statbuf;
     char flagfile[PATH_MAX];
     int fd, n;
+    debug_decl(create_admin_success_flag, SUDO_DEBUG_PLUGIN)
 
     /* Check whether the user is in the admin group. */
     if (!user_in_group(sudo_user.pw, "admin"))
-       return;
+       debug_return;
 
     /* Build path to flag file. */
     n = snprintf(flagfile, sizeof(flagfile), "%s/.sudo_as_admin_successful",
        user_dir);
     if (n <= 0 || n >= sizeof(flagfile))
-       return;
+       debug_return;
 
     /* Create admin flag file if it doesn't already exist. */
     set_perms(PERM_USER);
@@ -1482,6 +1538,7 @@ create_admin_success_flag(void)
        close(fd);
     }
     restore_perms();
+    debug_return;
 }
 #else /* !USE_ADMIN_FLAG */
 static void
index 8b51e1d334f73c370ba0c3a0d02aa9c99a016187..1d4f3e9d410a14c775263fc8d1446aafbd9194be 100644 (file)
 #define _SUDO_SUDOERS_H
 
 #include <limits.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
 
 #include <pathnames.h>
 #include "missing.h"
@@ -34,6 +39,7 @@
 #include "logging.h"
 #include "sudo_nss.h"
 #include "sudo_plugin.h"
+#include "sudo_debug.h"
 
 #define DEFAULT_TEXT_DOMAIN    "sudoers"
 #include "gettext.h"
@@ -97,14 +103,6 @@ struct sudo_user {
 #define FLAG_NO_HOST           0x040
 #define FLAG_NO_CHECK          0x080
 
-/*
- * Pseudo-boolean values
- */
-#undef TRUE
-#define TRUE                     1
-#undef FALSE
-#define FALSE                    0
-
 /*
  * find_path()/load_cmnd() return values
  */
@@ -206,15 +204,15 @@ struct timeval;
 #define YY_DECL int yylex(void)
 
 /* goodpath.c */
-char *sudo_goodpath(const char *, struct stat *);
+bool sudo_goodpath(const char *, struct stat *);
 
 /* findpath.c */
 int find_path(char *, char **, struct stat *, char *, int);
 
 /* check.c */
 int check_user(int, int);
-void remove_timestamp(int);
-int user_is_exempt(void);
+void remove_timestamp(bool);
+bool user_is_exempt(void);
 
 /* sudo_auth.c */
 int verify_user(struct passwd *, char *);
@@ -258,7 +256,7 @@ void zero_bytes(volatile void *, size_t);
 
 /* sudo_nss.c */
 void display_privs(struct sudo_nss_list *, struct passwd *);
-int display_cmnd(struct sudo_nss_list *, struct passwd *);
+bool display_cmnd(struct sudo_nss_list *, struct passwd *);
 
 /* pwutil.c */
 void sudo_setgrent(void);
@@ -282,7 +280,7 @@ void gr_addref(struct group *);
 void gr_delref(struct group *);
 void pw_addref(struct passwd *);
 void pw_delref(struct passwd *);
-int user_in_group(struct passwd *, const char *);
+bool user_in_group(struct passwd *, const char *);
 
 /* timestr.c */
 char *get_timestr(time_t, int);
@@ -315,7 +313,7 @@ char *fmt_string(const char *, const char *);
 /* sudoers.c */
 void plugin_cleanup(int);
 void set_fqdn(void);
-FILE *open_sudoers(const char *, int, int *);
+FILE *open_sudoers(const char *, bool, bool *);
 
 /* aix.c */
 void aix_restoreauthdb(void);
index 3593d291eec0523f544789124a15aa7dcad18a3d..346ace6462c664d6f213f425b0e1277af1e2835f 100644 (file)
  * 38  sudo 1.7.4, added LOG_INPUT/LOG_OUTPUT and NOLOG_INPUT/NOLOG_OUTPUT tags
  * 39  sudo 1.7.6/1.8.1, White space is now permitted within a User_List in a per-user Defaults definition.
  * 40  sudo 1.7.6/1.8.1, A group ID is now allowed in a User_List or Runas_List.
+ * 41  sudo 1.7.6/1.8.4, Support for relative paths in #include and #includedir
 */
 
 #ifndef _SUDOERS_VERSION_H
 #define        _SUDOERS_VERSION_H
 
-#define SUDOERS_GRAMMAR_VERSION        40
+#define SUDOERS_GRAMMAR_VERSION        41
 
 #endif /* _SUDOERS_VERSION_H */
index 4e91566283123efa1580f5c9d2db25f34849e19e..df83a50e03155572ede6bf26631e35986b6ed6b8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2011 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2009-2012 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 @@
 #if TIME_WITH_SYS_TIME
 # include <time.h>
 #endif
-#ifndef HAVE_TIMESPEC
+#ifndef HAVE_STRUCT_TIMESPEC
 # include "compat/timespec.h"
 #endif
 #include <ctype.h>
 # include <locale.h>
 #endif
 #include <signal.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
 
 #include <pathnames.h>
 
@@ -92,6 +97,9 @@
 #include "alloc.h"
 #include "error.h"
 #include "gettext.h"
+#include "sudo_plugin.h"
+#include "sudo_conf.h"
+#include "sudo_debug.h"
 
 #ifndef LINE_MAX
 # define LINE_MAX 2048
@@ -170,6 +178,8 @@ struct search_node {
     } u;
 } *search_expr;
 
+sudo_conv_t sudo_conv; /* NULL in non-plugin */
+
 #define STACK_NODE_SIZE        32
 static struct search_node *node_stack[32];
 static int stack_top;
@@ -225,7 +235,7 @@ static int parse_timing(const char *buf, const char *decimal, int *idx, double *
 int
 main(int argc, char *argv[])
 {
-    int ch, idx, plen, nready, interactive = 0, listonly = 0;
+    int ch, idx, plen, nready, exitcode = 0, interactive = 0, listonly = 0;
     const char *id, *user = NULL, *pattern = NULL, *tty = NULL, *decimal = ".";
     char path[PATH_MAX], buf[LINE_MAX], *cp, *ep;
     double seconds, to_wait, speed = 1.0, max_wait = 0;
@@ -234,6 +244,14 @@ main(int argc, char *argv[])
     sigaction_t sa;
     size_t len, nbytes, nread, off;
     ssize_t nwritten;
+    debug_decl(main, SUDO_DEBUG_MAIN)
+
+#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
+    {
+       extern char *malloc_options;
+       malloc_options = "AFGJPR";
+    }  
+#endif
 
 #if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
     setprogname(argc > 0 ? argv[0] : "sudoreplay");
@@ -246,6 +264,9 @@ main(int argc, char *argv[])
     bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have sudoreplay domain */
     textdomain("sudoers");
 
+    /* Read sudo.conf. */
+    sudo_conf_read();
+
     while ((ch = getopt(argc, argv, "d:f:hlm:s:V")) != -1) {
        switch(ch) {
        case 'd':
@@ -285,7 +306,7 @@ main(int argc, char *argv[])
            break;
        case 'V':
            (void) printf(_("%s version %s\n"), getprogname(), PACKAGE_VERSION);
-           exit(0);
+           goto done;
        default:
            usage(1);
            /* NOTREACHED */
@@ -295,8 +316,10 @@ main(int argc, char *argv[])
     argc -= optind;
     argv += optind;
 
-    if (listonly)
-       exit(list_sessions(argc, argv, pattern, user, tty));
+    if (listonly) {
+       exitcode = list_sessions(argc, argv, pattern, user, tty);
+       goto done;
+    }
 
     if (argc != 1)
        usage(1);
@@ -429,7 +452,9 @@ main(int argc, char *argv[])
        }
     }
     term_restore(STDIN_FILENO, 1);
-    exit(0);
+done:
+    sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);
+    exit(exitcode);
 }
 
 static void
@@ -452,7 +477,7 @@ delay(double secs)
       rval = nanosleep(&ts, &rts);
     } while (rval == -1 && errno == EINTR);
     if (rval == -1) {
-       error(1, _("nanosleep: tv_sec %ld, tv_nsec %ld"),
+       error2(1, _("nanosleep: tv_sec %ld, tv_nsec %ld"),
            (long)ts.tv_sec, (long)ts.tv_nsec);
     }
 }
@@ -462,14 +487,14 @@ open_io_fd(char *path, int len, const char *suffix, union io_fd *fdp)
 {
     path[len] = '\0';
     strlcat(path, suffix, PATH_MAX);
+    debug_decl(open_io_fd, SUDO_DEBUG_UTIL)
 
 #ifdef HAVE_ZLIB_H
     fdp->g = gzopen(path, "r");
-    return fdp->g ? 0 : -1;
 #else
     fdp->f = fopen(path, "r");
-    return fdp->f ? 0 : -1;
 #endif
+    debug_return_int(fdp->v ? 0 : -1);
 }
 
 /*
@@ -480,6 +505,7 @@ parse_expr(struct search_node **headp, char *argv[])
 {
     struct search_node *sn, *newsn;
     char or = 0, not = 0, type, **av;
+    debug_decl(parse_expr, SUDO_DEBUG_UTIL)
 
     sn = *headp;
     for (av = argv; *av; av++) {
@@ -556,7 +582,7 @@ parse_expr(struct search_node **headp, char *argv[])
                errorx(1, _("unmatched ')' in expression"));
            if (node_stack[stack_top])
                sn->next = node_stack[stack_top]->next;
-           return av - argv + 1;
+           debug_return_int(av - argv + 1);
        bad:
        default:
            errorx(1, _("unknown search term \"%s\""), *av);
@@ -602,14 +628,15 @@ parse_expr(struct search_node **headp, char *argv[])
     if (not)
        errorx(1, _("illegal trailing \"!\""));
 
-    return av - argv;
+    debug_return_int(av - argv);
 }
 
-static int
+static bool
 match_expr(struct search_node *head, struct log_info *log)
 {
     struct search_node *sn;
-    int matched = 1, rc;
+    bool matched = true, rc;
+    debug_decl(match_expr, SUDO_DEBUG_UTIL)
 
     for (sn = head; sn; sn = sn->next) {
        /* If we have no match, skip ahead to the next OR entry. */
@@ -658,7 +685,7 @@ match_expr(struct search_node *head, struct log_info *log)
        if (sn->negated)
            matched = !matched;
     }
-    return matched;
+    debug_return_bool(matched);
 }
 
 static int
@@ -669,6 +696,7 @@ list_session(char *logfile, REGEX_T *re, const char *user, const char *tty)
     struct log_info li;
     size_t bufsize = 0, cwdsize = 0, cmdsize = 0;
     int rval = -1;
+    debug_decl(list_session, SUDO_DEBUG_UTIL)
 
     fp = fopen(logfile, "r");
     if (fp == NULL) {
@@ -749,9 +777,10 @@ list_session(char *logfile, REGEX_T *re, const char *user, const char *tty)
 
 done:
     fclose(fp);
-    return rval;
+    debug_return_int(rval);
 }
 
+/* XXX - always returns 0, calls error() on failure */
 static int
 find_sessions(const char *dir, REGEX_T *re, const char *user, const char *tty)
 {
@@ -761,6 +790,7 @@ find_sessions(const char *dir, REGEX_T *re, const char *user, const char *tty)
     size_t sdlen;
     int len;
     char pathbuf[PATH_MAX];
+    debug_decl(find_sessions, SUDO_DEBUG_UTIL)
 
     d = opendir(dir);
     if (d == NULL)
@@ -799,14 +829,16 @@ find_sessions(const char *dir, REGEX_T *re, const char *user, const char *tty)
     }
     closedir(d);
 
-    return 0;
+    debug_return_int(0);
 }
 
+/* XXX - always returns 0, calls error() on failure */
 static int
 list_sessions(int argc, char **argv, const char *pattern, const char *user,
     const char *tty)
 {
     REGEX_T rebuf, *re = NULL;
+    debug_decl(list_sessions, SUDO_DEBUG_UTIL)
 
     /* Parse search expression if present */
     parse_expr(&search_expr, argv);
@@ -822,7 +854,7 @@ list_sessions(int argc, char **argv, const char *pattern, const char *user,
     re = (char *) pattern;
 #endif /* HAVE_REGCOMP */
 
-    return find_sessions(session_dir, re, user, tty);
+    debug_return_int(find_sessions(session_dir, re, user, tty));
 }
 
 /*
@@ -837,6 +869,7 @@ check_input(int ttyfd, double *speed)
     struct timeval tv;
     char ch;
     ssize_t n;
+    debug_decl(check_input, SUDO_DEBUG_UTIL)
 
     fdsr = (fd_set *)emalloc2(howmany(ttyfd + 1, NFDBITS), sizeof(fd_mask));
 
@@ -868,6 +901,7 @@ check_input(int ttyfd, double *speed)
        }
     }
     free(fdsr);
+    debug_return;
 }
 
 /*
@@ -889,6 +923,7 @@ parse_timing(buf, decimal, idx, seconds, nbytes)
     long l;
     double d, fract = 0;
     char *cp, *ep;
+    debug_decl(parse_timing, SUDO_DEBUG_UTIL)
 
     /* Parse index */
     ul = strtoul(buf, &ep, 10);
@@ -929,9 +964,9 @@ parse_timing(buf, decimal, idx, seconds, nbytes)
        goto bad;
     *nbytes = (size_t)ul;
 
-    return 1;
+    debug_return_int(1);
 bad:
-    return 0;
+    debug_return_int(0);
 }
 
 static void
index 5eda9d02cb494331998cff16af630552a38d18df..d63ca9230600e94b888aa2f2ed8cf75a8032957c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1998-2005, 2007-2011
+ * Copyright (c) 1996, 1998-2005, 2007-2012
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -49,6 +49,8 @@
 #endif /* HAVE_UNISTD_H */
 #ifdef HAVE_FNMATCH
 # include <fnmatch.h>
+#else
+# include "compat/fnmatch.h"
 #endif /* HAVE_FNMATCH */
 #ifdef HAVE_NETGROUP_H
 # include <netgroup.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
+#ifdef HAVE_SETLOCALE
+# include <locale.h>
+#endif
 
 #include "tsgetgrpw.h"
 #include "sudoers.h"
 #include "interfaces.h"
 #include "parse.h"
+#include "sudo_conf.h"
 #include <gram.h>
 
-#ifndef HAVE_FNMATCH
-# include "compat/fnmatch.h"
-#endif /* HAVE_FNMATCH */
-
 /*
  * Function Prototypes
  */
@@ -107,8 +109,11 @@ struct interface *interfaces;
 struct sudo_user sudo_user;
 struct passwd *list_pw;
 static char *runas_group, *runas_user;
-extern int parse_error;
+extern int errorlineno;
+extern bool parse_error;
+extern char *errorfile;
 sudo_printf_t sudo_printf = testsudoers_printf;
+sudo_conv_t sudo_conv; /* NULL in non-plugin */
 
 /* For getopt(3) */
 extern char *optarg;
@@ -130,7 +135,8 @@ main(int argc, char *argv[])
     char *p, *grfile, *pwfile;
     char hbuf[MAXHOSTNAMELEN + 1];
     int match, host_match, runas_match, cmnd_match;
-    int ch, dflag;
+    int ch, dflag, exitcode = 0;
+    debug_decl(main, SUDO_DEBUG_MAIN)
 
 #if defined(SUDO_DEVEL) && defined(__OpenBSD__)
     malloc_options = "AFGJPR";
@@ -143,6 +149,15 @@ main(int argc, char *argv[])
     setprogname(argc > 0 ? argv[0] : "testsudoers");
 #endif
 
+#ifdef HAVE_SETLOCALE 
+    setlocale(LC_ALL, "");
+#endif
+    bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have own domain */
+    textdomain("sudoers");
+
+    /* Read sudo.conf. */
+    sudo_conf_read();
+
     dflag = 0;
     grfile = pwfile = NULL;
     while ((ch = getopt(argc, argv, "dg:G:h:p:tu:")) != -1) {
@@ -187,11 +202,12 @@ main(int argc, char *argv[])
     if (argc < 2) {
        if (!dflag)
            usage();
-       user_name = "root";
+       user_name = argc ? *argv++ : "root";
        user_cmnd = user_base = "true";
+       argc = 0;
     } else {
-       user_name = *argv;
-       user_cmnd = *++argv;
+       user_name = *argv++;
+       user_cmnd = *argv++;
        if ((p = strrchr(user_cmnd, '/')) != NULL)
            user_base = p + 1;
        else
@@ -220,11 +236,11 @@ main(int argc, char *argv[])
        char *to, **from;
        size_t size, n;
 
-       for (size = 0, from = argv + 1; *from; from++)
+       for (size = 0, from = argv; *from; from++)
            size += strlen(*from) + 1;
 
        user_args = (char *) emalloc(size);
-       for (to = user_args, from = argv + 1; *from; from++) {
+       for (to = user_args, from = argv; *from; from++) {
            n = strlcpy(to, *from, size - (to - user_args));
            if (n >= size - (to - user_args))
                    errorx(1, _("internal error, init_vars() overflow"));
@@ -248,8 +264,12 @@ main(int argc, char *argv[])
     init_parser("sudoers", 0);
 
     if (yyparse() != 0 || parse_error) {
-       parse_error = TRUE;
-       (void) fputs("Does not parse", stdout);
+       parse_error = true;
+       if (errorlineno != -1)
+           (void) printf("Parse error in %s near line %d",
+               errorfile, errorlineno);
+       else
+           (void) printf("Parse error in %s", errorfile);
     } else {
        (void) fputs("Parses OK", stdout);
     }
@@ -258,7 +278,7 @@ main(int argc, char *argv[])
        (void) fputs(" (problem with defaults entries)", stdout);
     puts(".");
 
-    if (def_group_plugin && group_plugin_load(def_group_plugin) != TRUE)
+    if (def_group_plugin && group_plugin_load(def_group_plugin) != true)
        def_group_plugin = NULL;
 
     /*
@@ -276,8 +296,10 @@ main(int argc, char *argv[])
     if (dflag) {
        (void) putchar('\n');
        dump_sudoers();
-       if (argc < 2)
-           exit(parse_error ? 1 : 0);
+       if (argc < 2) {
+           exitcode = parse_error ? 1 : 0;
+           goto done;
+       }
     }
 
     /* This loop must match the one in sudo_file_lookup() */
@@ -319,14 +341,17 @@ main(int argc, char *argv[])
      * 2 - command not matched
      * 3 - command denied
      */
-    if (parse_error)
-       exit(1);
-    exit(match == ALLOW ? 0 : match + 3);
+    exitcode = parse_error ? 1 : (match == ALLOW ? 0 : match + 3);
+done:
+    sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);
+    exit(exitcode);
 }
 
 static void
 set_runaspw(const char *user)
 {
+    debug_decl(main, SUDO_DEBUG_UTIL)
+
     if (runas_pw != NULL)
        pw_delref(runas_pw);
     if (*user == '#') {
@@ -336,11 +361,15 @@ set_runaspw(const char *user)
        if ((runas_pw = sudo_getpwnam(user)) == NULL)
            errorx(1, _("unknown user: %s"), user);
     }
+
+    debug_return;
 }
 
 static void
 set_runasgr(const char *group)
 {
+    debug_decl(main, SUDO_DEBUG_UTIL)
+
     if (runas_gr != NULL)
        gr_delref(runas_gr);
     if (*group == '#') {
@@ -350,6 +379,8 @@ set_runasgr(const char *group)
        if ((runas_gr = sudo_getgrnam(group)) == NULL)
            errorx(1, _("unknown group: %s"), group);
     }
+
+    debug_return;
 }
 
 /* 
@@ -361,7 +392,7 @@ cb_runas_default(const char *user)
     /* Only reset runaspw if user didn't specify one. */
     if (!runas_user && !runas_group)
         set_runaspw(user);
-    return TRUE;
+    return true;
 }
 
 void
@@ -383,9 +414,11 @@ set_fqdn(void)
 }
 
 FILE *
-open_sudoers(const char *path, int isdir, int *keepopen)
+open_sudoers(const char *path, bool doedit, bool *keepopen)
 {
-    return fopen(path, "r");
+    debug_decl(open_sudoers, SUDO_DEBUG_UTIL)
+
+    debug_return_ptr(fopen(path, "r"));
 }
 
 void
@@ -418,6 +451,7 @@ void
 print_member(struct member *m)
 {
     struct sudo_command *c;
+    debug_decl(print_member, SUDO_DEBUG_UTIL)
 
     if (m->negated)
        putchar('!');
@@ -430,6 +464,8 @@ print_member(struct member *m)
        printf("%s%s%s", c->cmnd, c->args ? " " : "",
            c->args ? c->args : "");
     }
+
+    debug_return;
 }
 
 void
@@ -437,6 +473,7 @@ print_defaults(void)
 {
     struct defaults *d;
     struct member *m;
+    debug_decl(print_member, SUDO_DEBUG_UTIL)
 
     tq_foreach_fwd(&defaults, d) {
        (void) fputs("Defaults", stdout);
@@ -459,12 +496,14 @@ print_defaults(void)
                putchar(',');
            print_member(m);
        }
-       printf("\t%s%s", d->op == FALSE ? "!" : "", d->var);
+       printf("\t%s%s", d->op == false ? "!" : "", d->var);
        if (d->val != NULL) {
-           printf("%c%s", d->op == TRUE ? '=' : d->op, d->val);
+           printf("%c%s", d->op == true ? '=' : d->op, d->val);
        }
        putchar('\n');
     }
+
+    debug_return;
 }
 
 int
@@ -473,6 +512,7 @@ print_alias(void *v1, void *v2)
     struct alias *a = (struct alias *)v1;
     struct member *m;
     struct sudo_command *c;
+    debug_decl(print_alias, SUDO_DEBUG_UTIL)
 
     switch (a->type) {
        case HOSTALIAS:
@@ -502,7 +542,7 @@ print_alias(void *v1, void *v2)
        }
     }
     putchar('\n');
-    return 0;
+    debug_return_int(0);
 }
 
 void
@@ -512,6 +552,7 @@ print_privilege(struct privilege *priv)
     struct member *m;
     struct privilege *p;
     struct cmndtag tags;
+    debug_decl(print_privilege, SUDO_DEBUG_UTIL)
 
     for (p = priv; p != NULL; p = p->next) {
        if (p != priv)
@@ -563,6 +604,7 @@ print_privilege(struct privilege *priv)
            memcpy(&tags, &cs->tags, sizeof(tags));
        }
     }
+    debug_return;
 }
 
 void
@@ -570,6 +612,7 @@ print_userspecs(void)
 {
     struct member *m;
     struct userspec *us;
+    debug_decl(print_userspecs, SUDO_DEBUG_UTIL)
 
     tq_foreach_fwd(&userspecs, us) {
        tq_foreach_fwd(&us->users, m) {
@@ -581,6 +624,7 @@ print_userspecs(void)
        print_privilege(us->privileges.first); /* XXX */
        putchar('\n');
     }
+    debug_return;
 }
 
 static int
@@ -588,6 +632,7 @@ testsudoers_printf(int msg_type, const char *fmt, ...)
 {
     va_list ap;
     FILE *fp;
+    debug_decl(testsudoers_printf, SUDO_DEBUG_UTIL)
             
     switch (msg_type) {
     case SUDO_CONV_INFO_MSG:
@@ -598,19 +643,21 @@ testsudoers_printf(int msg_type, const char *fmt, ...)
        break;
     default:
        errno = EINVAL;
-       return -1;
+       debug_return_int(-1);
     }
    
     va_start(ap, fmt);
     vfprintf(fp, fmt, ap);
     va_end(ap);
    
-    return 0;
+    debug_return_int(0);
 }
 
 void
 dump_sudoers(void)
 {
+    debug_decl(dump_sudoers, SUDO_DEBUG_UTIL)
+
     print_defaults();
 
     putchar('\n');
@@ -618,6 +665,8 @@ dump_sudoers(void)
 
     putchar('\n');
     print_userspecs();
+
+    debug_return;
 }
 
 static int testsudoers_print(const char *msg)
index 7bb8eb310a771e69d81fd884ea1c2ed9b2dd9d64..c007c8d13232735c159810e082fdc1e60aa63bb1 100644 (file)
@@ -4,7 +4,7 @@
 /* A lexical scanner generated by flex */
 
 /* Scanner skeleton version:
- * $Header: /cvs/src/usr.bin/lex/flex.skl,v 1.11 2010/08/04 18:24:50 millert Exp $
+ * $Header: /home/cvs/openbsd/src/usr.bin/lex/flex.skl,v 1.11 2010/08/04 18:24:50 millert Exp $
  */
 
 #define FLEX_SCANNER
@@ -349,15 +349,15 @@ static yyconst short int yy_accept[607] =
        37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
 
        37,   37,    0,   30,   42,   42,   42,    0,    0,    0,
-       21,   20,    0,    0,    0,    0,    0,   20,    0,   47,
-       47,   47,    0,    0,    0,   37,   37,   37,   37,   37,
+       18,    0,   21,   20,    0,    0,    0,    0,    0,   20,
+        0,   47,   47,   47,    0,    0,    0,   37,   37,   37,
        37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
-       37,   37,   37,    0,   28,   42,   42,   21,    0,   18,
+       37,   37,   37,   37,   37,    0,   28,   42,   42,   21,
         0,    0,   20,   47,   47,   47,   47,   47,    0,    0,
         0,    0,    0,   37,   37,   37,   37,   37,   37,   37,
        37,    0,   31,   42,    0,   47,   47,   47,   37,   37,
-       37,   37,   37,   37,    0,   29,    0,   47,   47,   47,
-       47,   47,   37,   37,   37,   37,   37,    0,   19,   35,
+       37,   37,   37,   37,    0,   29,    0,    0,   19,   47,
+       47,   47,   47,   47,   37,   37,   37,   37,   37,   35,
 
        35,   35,   35,   35,   35,    0
     } ;
@@ -435,51 +435,51 @@ static yyconst short int yy_base[671] =
       489, 2223, 2213, 2198, 2211, 2198,  420,  407,  529,  490,
       491, 1263, 1299, 1335, 2235, 2234,  839, 2234, 2232, 2228,
      2226,  528,  848,  657,  856,  665, 1371,    0,  877, 1382,
-      886,  894, 1424,  913,  570, 3665, 2208, 2197, 2198, 2177,
-     2184, 2193, 2190, 2169,  558, 2145, 2098, 2099,  648,  626,
-      530,  559,  923,  336, 1467, 1503,  964, 2138, 2137, 2108,
-     2086, 1537,  551, 1000, 1041, 1082,  653,  694,  797, 1049,
-
-      923, 1580,    0, 1116, 1591, 1090, 1008, 1633, 1125, 2069,
-     2065,  747,  686, 2046, 2005,  786,  926,  905, 2014, 1982,
-      679,  634,  544,  915, 1675, 1710, 1745, 2015, 1978, 1962,
-     1150, 1781, 1158, 1133, 1822, 1197, 1166, 1954, 1239, 1273,
+      886,  894, 1424,  913,  570, 3665, 2208, 2197, 2201, 2178,
+     2185, 2194, 2194, 2176,  558, 2169, 2152, 2150,  648,  626,
+      530,  559,  923,  336, 1467, 1503,  964, 2171, 2140, 2139,
+     2138, 1537,  551, 1000, 1041, 1082,  653,  694,  797, 1049,
+
+      923, 1580,    0, 1116, 1591, 1090, 1008, 1633, 1125, 2121,
+     2082,  747,  686, 2064, 2071,  786,  926,  905, 2080, 2033,
+      679,  634,  544,  915, 1675, 1710, 1745, 2052, 2043, 2033,
+     1150, 1781, 1158, 1133, 1822, 1197, 1166, 2028, 1239, 1273,
      1207,  950,  951,  962,  991, 1247, 1073, 1865,    0, 1283,
-     1876, 1307, 1315, 1918, 1323, 1923, 1923, 1188, 3665, 1924,
-     1898, 1893, 1873, 1286, 3665, 1336, 3665,  707, 1790, 1783,
-      786,  930,  764, 1298, 1358, 1041, 1960, 1995, 1400, 1823,
-     1799, 1348,  708, 1406, 1348, 2031,    0,  559, 2042, 1441,
+     1876, 1307, 1315, 1918, 1323, 1987, 1968, 1188, 3665, 1967,
+     1951, 1929, 1913, 1286, 3665, 1336, 3665,  707, 1897, 1889,
+      786,  930,  764, 1298, 1358, 1041, 1960, 1995, 1400, 1927,
+     1879, 1348,  708, 1406, 1348, 2031,    0,  559, 2042, 1441,
      1449, 2083, 1477, 1487, 1513, 1523, 1230, 1290, 1458, 1548,
 
-     1557, 1602, 2126,    0, 1613, 2137, 1650, 1565, 1660, 1765,
-     1763, 1680, 1675, 1359, 1406, 1626, 1601, 1577,  897,  938,
+     1557, 1602, 2126,    0, 1613, 2137, 1650, 1565, 1660, 1806,
+     1779, 1680, 1675, 1359, 1406, 1626, 1601, 1577,  897,  938,
      1695, 1589, 2180, 2216, 2252, 2288, 1611, 1686, 1720, 1731,
      1563, 1478, 1504, 1694, 1524, 2324,    0,  617, 2335, 1753,
      1761, 2376, 1769, 1798, 1550, 1808, 1841, 1851, 1335, 1358,
-     1887,  714,  825, 2419,    0,  926, 1407, 1508, 1506, 1471,
-     1547, 3665, 1616, 3665, 1423, 1731, 1907, 1512, 1575, 1910,
-     1915, 1935, 1498, 2429, 2465, 1971, 1611, 1977, 1457, 2005,
-     2015, 1987, 1408, 1254, 1732, 1782, 2059, 1842, 2501,    0,
-     1025, 2512, 2067, 2100, 2553, 2108, 2155, 2164, 2189, 1769,
-
-     1207, 1189, 1634, 3665, 1699, 1162, 1113, 1074, 1118,  384,
-     1040, 2211, 2218, 2238, 2243, 2263, 2288, 2249, 2307, 2596,
-     2632, 2668, 2304, 2354, 2395, 1025, 1006, 1889, 2016, 2362,
-     2043, 2704,    0, 1224, 2715, 2403, 2437, 2445,  992, 2454,
-     2474, 2483,  903, 1921, 3665, 1941,  839, 3665,  843, 3665,
-     1306, 2489, 2529, 2537, 1911, 2758, 2794, 2573, 2579,  811,
-     2607, 2617, 2642,  640,  629, 2109,  535,  447, 2650,    0,
-     1428, 1942, 3665, 2044, 2216, 2830, 2866, 2902, 2676, 2684,
-     2692,  337,    0,  333, 2067, 3665,  327, 2733, 1912, 2938,
-     2974, 2743, 3665, 2767, 2777, 2658, 3665,  166, 3665, 2805,
+     1887,  714,  825, 2419,    0,  926, 1407, 1468, 1430, 1431,
+     1547, 3665, 1616, 3665, 1381, 1731, 1045, 1512, 1575, 1908,
+     1913, 1970, 1498, 2429, 2465, 1947, 1611, 1981, 1264, 2006,
+     2016, 2061, 1198, 1181, 1732, 1782, 2067, 1842, 2501,    0,
+     1181, 2512, 2100, 1904, 2553, 2110, 2155, 2164, 2189, 1769,
+
+     1142, 1232, 1634, 3665, 1699, 1095, 1077, 1025, 1046, 1306,
+     3665,  384,  981, 2211, 2218, 2238, 2243, 2263, 2288, 2249,
+     2307, 2596, 2632, 2668, 2304, 2354, 2395,  983,  894, 1902,
+     1928, 2362, 1929, 2704,    0, 1428, 2715, 2403, 2437, 2445,
+      867, 2454, 2474, 2483,  831, 1982, 3665, 1983,  782, 3665,
+     1511, 2489, 2529, 2537, 1895, 2758, 2794, 2573, 2579,  650,
+     2607, 2617, 2642,  629,  525, 1931,  447,  347, 2650,    0,
+     1528, 2019, 3665, 2044, 1805, 2830, 2866, 2902, 2676, 2684,
+     2692,  323,    0,  316, 2067, 3665,  166, 1845, 3665, 2733,
+     1945, 2938, 2974, 2743, 3665, 2767, 2777, 2658, 3665, 2805,
 
      2813, 2847,   63, 2855, 2881, 3665, 3023, 3039, 3055, 3071,
-     3087, 3103, 3119, 3135, 3151, 3157, 3173, 3189, 1498, 3205,
+     3087, 3103, 3119, 3135, 3151, 3157, 3173, 3189, 2025, 3205,
      3221, 3237, 3253, 3269, 3285, 3301, 3307, 3314, 3330, 3346,
      3352, 3359, 3365, 3371, 3377, 3384, 3390, 3396, 3402, 3409,
      3417, 3423, 3429, 3435, 3442, 3450, 3456, 3462, 3469, 3477,
      3483, 3491, 3498, 3506, 3512, 3520, 3527, 3535, 3551, 3567,
-     3573, 3581, 3588, 3604, 3610, 3618, 3624, 3632, 1295, 3648
+     3583, 3589, 3597, 3604, 3610, 3618, 3624, 3632, 3648, 1295
     } ;
 
 static yyconst short int yy_def[671] =
@@ -534,21 +534,21 @@ static yyconst short int yy_def[671] =
       655,  655,  656,  392,  656,  656,  436,  436,  606,  439,
       439,  606,  439,  606,  606,  606,  606,  606,  606,  657,
       657,  658,  658,  658,  454,  454,   35,   35,   35,   35,
-      606,  606,  606,  606,  606,  606,  623,  623,  611,  659,
-      660,  611,  611,  611,  611,  611,  611,  606,  606,  606,
-      606,  606,  606,  661,  661,  662,  442,  662,  662,  489,
+      606,  606,  606,  606,  606,  606,  659,  623,  611,  660,
+      661,  611,  611,  611,  611,  611,  611,  606,  606,  606,
+      606,  606,  606,  662,  662,  663,  442,  663,  663,  489,
       489,  606,  492,  492,  606,  492,  606,  606,  606,  606,
 
-      663,  663,  606,  606,   35,   35,   35,  606,  664,  623,
-      611,  659,  659,  659,  659,  606,  659,  660,  660,  611,
-      611,  611,  606,  606,  606,  606,  665,  665,  666,  495,
-      666,  666,  532,  532,  606,  535,  535,  535,  606,  606,
-      606,  606,  606,  606,  606,   35,   35,  606,  664,  606,
+      664,  664,  606,  606,   35,   35,   35,  606,  659,  659,
+      606,  623,  611,  660,  660,  660,  660,  606,  660,  661,
+      661,  611,  611,  611,  606,  606,  606,  606,  665,  665,
+      666,  495,  666,  666,  534,  534,  606,  537,  537,  537,
+      606,  606,  606,  606,  606,  606,  606,   35,   35,  606,
       623,  606,  606,  611,  611,  611,  611,  611,  606,  606,
       606,  606,  606,  606,  667,  667,  668,  668,  668,  569,
-      569,  606,  606,   35,  623,  611,  611,  611,  606,  606,
-      606,  606,  669,  669,  606,  606,  670,  611,  611,  611,
-      611,  611,  606,  606,  606,  606,  606,  670,  606,  611,
+      569,  606,  606,   35,  669,  611,  611,  611,  606,  606,
+      606,  606,  670,  670,  606,  606,  669,  669,  606,  611,
+      611,  611,  611,  611,  606,  606,  606,  606,  606,  611,
 
       611,  611,  611,  611,  611,    0,  606,  606,  606,  606,
       606,  606,  606,  606,  606,  606,  606,  606,  606,  606,
@@ -578,7 +578,7 @@ static yyconst short int yy_nxt[3732] =
        56,   79,  147,  127,   77,   56,  148,   60,   61,   93,
        93,  150,  115,   93,   93,  238,  152,   62,   99,   99,
        99,   99,   99,   99,   99,   99,  146,   87,   79,   79,
-      146,   93,   62,   15,   16,   17,  117,   63,  599,  152,
+      146,   93,   62,   15,   16,   17,  117,   63,  589,  152,
       192,  195,  129,   77,  100,  100,  100,  100,  100,  101,
       143,  115,  130,   78,   94,   98,   98,   98,   98,   98,
        98,   98,   98,   79,  118,  119,  155,  156,  120,  151,
@@ -596,11 +596,11 @@ static yyconst short int yy_nxt[3732] =
 
        79,  152,   68,   69,   70,  606,  196,   79,  134,  134,
        79,  606,  134,  134,   79,  198,   71,  168,  168,  168,
-      168,  168,  168,  606,  155,  156,   79,  231,  159,  599,
+      168,  168,  168,  606,  155,  156,   79,  231,  159,  382,
       134,  160,  160,  160,  160,  160,  160,  160,  160,  241,
-       72,   15,   16,   17,   67,   63,  382,  170,   89,  283,
+       72,   15,   16,   17,   67,   63,  532,  170,   89,  283,
        68,   69,   70,  135,  162,   86,  214,   86,   86,  267,
-      530,   86,   86,  268,   71,   86,  170,  164,  165,  166,
+      606,   86,   86,  268,   71,   86,  170,  164,  165,  166,
       164,  164,  164,  164,  164,  214,   93,   93,   86,   86,
        93,   93,   79,   79,   79,  240,   83,  238,   72,   83,
       168,  168,  168,  168,  168,  168,  168,  168,   93,   84,
@@ -611,7 +611,7 @@ static yyconst short int yy_nxt[3732] =
       168,  168,  168,  168,  168,  168,  168,   85,   85,   85,
        85,   85,   85,   85,   85,   79,  551,   98,   98,   98,
        98,   98,   98,   78,  145,   79,  280,  145,  145,   78,
-      606,  237,   78,   78,  145,   78,   78,   78,  104,  104,
+      382,  237,   78,   78,  145,   78,   78,   78,  104,  104,
       104,  104,  104,  104,  104,  104,   97,  145,  279,   78,
       104,  104,  104,  104,  104,  105,  105,  105,  105,  106,
       105,  105,  105,  105,  105,  105,  105,  105,  105,  105,
@@ -620,7 +620,7 @@ static yyconst short int yy_nxt[3732] =
        78,   78,   78,   78,   78,   78,   78,   78,   78,  105,
       105,  105,  105,  105,  105,  105,  105,  606,  249,  249,
       249,  105,  105,  105,  105,  105,  177,   79,   79,   79,
-      105,  178,  170,  275,  179,  282,  180,  117,  382,  143,
+      105,  178,  170,  275,  179,  282,  180,  117,  532,  143,
       115,  214,   97,  238,   78,   78,   78,   78,   78,   78,
       114,  115,   78,   78,   78,  170,   78,   78,  134,  134,
        78,  265,  134,  134,  214,  118,  119,   79,   79,  120,
@@ -632,8 +632,8 @@ static yyconst short int yy_nxt[3732] =
       606,  606,  160,  160,  160,  160,  160,  160,  160,  160,
       160,  160,  160,  160,  160,  160,  160,  160,  484,  484,
       123,   83,  242,  243,  244,  242,  242,  242,  242,  242,
-       83,  142,  530,  322,  606,  606,  606,  606,  606,  606,
-      606,  606,   78,  487,   78,   78,   78,  170,   78,   78,
+       83,  142,  487,  322,  606,  606,  606,  606,  606,  606,
+      606,  606,   78,  559,   78,   78,   78,  170,   78,   78,
       253,  170,   78,  134,   79,   79,  255,  134,  606,  170,
       255,   83,   79,  134,   78,   78,   78,   90,  255,   90,
        90,   90,  372,   90,   90,  134,  134,   90,  247,  247,
@@ -651,17 +651,17 @@ static yyconst short int yy_nxt[3732] =
 
       257,  257,  257,  258,  258,  258,  258,  258,  259,  365,
       253,  170,   79,  167,  167,  167,  167,  167,  167,  133,
-      300,   78,   78,  133,  559,   78,   78,  421,  606,  133,
+      300,   78,   78,  133,  574,   78,   78,  421,  606,  133,
       256,  256,  256,  256,  256,  256,  256,  256,  606,  170,
-      419,  133,  133,   78,  201,  550,  202,  202,  202,  202,
+      419,  133,  133,   78,  201,  170,  202,  202,  202,  202,
       202,  202,  202,  202,  289,  289,  289,  289,  289,  289,
       289,  289,  211,  294,  295,  296,  294,  294,  294,  294,
       294,  264,  264,  264,  264,  264,  264,  264,  264,   79,
-      201,  574,  203,  203,  203,  203,  203,  203,  203,  203,
+      201,  170,  203,  203,  203,  203,  203,  203,  203,  203,
       253,  170,  298,  298,  298,  298,  298,  298,  467,   83,
 
       255,  302,  302,  302,  302,  302,  302,  302,  302,  303,
-      303,  303,  303,  303,  304,   79,  201,  170,  204,  204,
+      303,  303,  303,  303,  304,   79,  201,  487,  204,  204,
       204,  204,  204,  205,  202,  202,  606,  366,  301,  301,
       301,  301,  301,  301,  301,  301,  606,  170,  325,  326,
       327,  325,  325,  325,  325,  325,  300,  501,  501,  367,
@@ -671,41 +671,41 @@ static yyconst short int yy_nxt[3732] =
       284,  284,  284,  284,  284,  300,   79,  420,  469,  206,
       206,  206,  206,  206,  206,  208,  209,  210,  210,  210,
 
-      210,  210,  210,  211,  253,  170,  170,  212,  212,  212,
+      210,  210,  210,  211,  253,  170,  434,  212,  212,  212,
       212,  212,   79,  337,  346,  338,  338,  338,  338,  338,
-      338,  338,  338,  349,  349,  349,  349,  349,  350,  487,
+      338,  338,  338,  349,  349,  349,  349,  349,  350,   79,
       212,  212,  212,  212,  212,  212,  170,  215,  216,  217,
-      215,  215,  215,  215,  215,  218,  527,  527,  434,  219,
+      215,  215,  215,  215,  215,  218,  510,  511,  511,  219,
       219,  219,  219,  219,  337,  375,  339,  339,  339,  339,
       339,  339,  339,  339,  309,  309,  309,  309,  309,  309,
       309,  309,  219,  219,  219,  219,  219,  219,  220,  220,
-      220,  220,  220,  220,  220,  220,  606,  170,   79,   79,
+      220,  220,  220,  220,  220,  220,  606,  170,  550,   79,
       220,  220,  220,  220,  220,  337,  346,  340,  340,  340,
 
       340,  340,  341,  338,  338,  348,  348,  348,  348,  348,
       348,  348,  348,  206,  206,  206,  206,  206,  206,  201,
-      550,  202,  202,  202,  202,  202,  202,  202,  202,  253,
+      549,  202,  202,  202,  202,  202,  202,  202,  202,  253,
       170,  344,  344,  344,  344,  344,  344,  548,  606,  300,
       347,  347,  347,  347,  347,  347,  347,  347,  387,  387,
-      387,  387,  387,  388,   79,  201,  547,  202,  202,  202,
+      387,  387,  387,  388,   79,  201,  170,  202,  202,  202,
       202,  202,  202,  202,  202,  336,  336,  336,  336,  336,
       336,  336,  336,  386,  386,  386,  386,  386,  386,  386,
       386,  394,  395,  396,  394,  394,  394,  394,  394,  358,
        79,  253,  170,  254,  254,  254,  254,  254,  254,  254,
 
-      254,  255,  253,  170,  546,  256,  256,  256,  256,  256,
+      254,  255,  529,  529,  434,  256,  256,  256,  256,  256,
       606,  359,  385,  385,  385,  385,  385,  385,  385,  385,
-      337,  170,  338,  338,  338,  338,  338,  338,  256,  256,
+      337,  384,  338,  338,  338,  338,  338,  338,  256,  256,
       256,  256,  256,  256,  170,  260,  261,  262,  260,  260,
-      260,  260,  260,  263,  170,  565,  565,  264,  264,  264,
+      260,  260,  260,  263,  170,  253,  170,  264,  264,  264,
       264,  264,  337,  300,  338,  338,  338,  338,  338,  338,
       338,  338,  355,  355,  355,  355,  355,  355,  355,  355,
-      264,  264,  264,  264,  264,  264,  283,  434,  284,  284,
+      264,  264,  264,  264,  264,  264,  283,  478,  284,  284,
       284,  284,  284,  284,  284,  284,  337,  364,  338,  338,
       338,  338,  338,  338,  338,  338,  253,  170,  399,  399,
 
-      399,  399,  399,  399,  170,  597,  346,  575,   83,  365,
-      597,   79,  283,  346,  285,  285,  285,  285,  285,  285,
+      399,  399,  399,  399,  170,  599,  346,  510,  511,  365,
+      599,   79,  283,  346,  285,  285,  285,  285,  285,  285,
       285,  285,  403,  403,  403,  403,  403,  403,  403,  403,
       404,  404,  404,  404,  404,  405,  606,  366,  402,  402,
       402,  402,  402,  402,  402,  402,   79,   79,  283,  170,
@@ -718,21 +718,21 @@ static yyconst short int yy_nxt[3732] =
       299,  299,  299,  299,  299,  300,   79,  463,  503,  301,
       301,  301,  301,  301,  375,  376,  376,  376,  376,  376,
       376,  393,  393,  393,  393,  393,  393,  393,  393,  464,
-      504,  384,  301,  301,  301,  301,  301,  301,  170,  305,
-      306,  307,  305,  305,  305,  305,  305,  308,   79,  583,
-      583,  309,  309,  309,  309,  309,  436,  436,  436,  436,
+      504,  508,  301,  301,  301,  301,  301,  301,  170,  305,
+      306,  307,  305,  305,  305,  305,  305,  308,   79,  565,
+      565,  309,  309,  309,  309,  309,  436,  436,  436,  436,
       436,  436,  436,  436,  437,  437,  437,  437,  437,  438,
-      478,  253,  170,  508,  309,  309,  309,  309,  309,  309,
+      507,  253,  170,  506,  309,  309,  309,  309,  309,  309,
       283,  346,  284,  284,  284,  284,  284,  284,  284,  284,
       606,  382,  435,  435,  435,  435,  435,  435,  435,  435,
 
       444,  384,  445,  445,  445,  445,  445,  445,  445,  445,
-      507,  472,  144,  144,   83,   79,  283,  382,  284,  284,
+      505,  472,  575,   83,   83,   79,  283,  382,  284,  284,
       284,  284,  284,  284,  284,  284,  444,  434,  446,  446,
       446,  446,  446,  446,  446,  446,  444,  606,  447,  447,
-      447,  447,  447,  448,  445,  445,   79,  434,  461,  506,
-      505,   79,  332,  333,  334,  332,  332,  332,  332,  332,
-      335,  253,  170,  444,  336,  336,  336,  336,  336,  510,
+      447,  447,  447,  448,  445,  445,   79,  434,  461,  583,
+      583,   79,  332,  333,  334,  332,  332,  332,  332,  332,
+      335,  253,  170,  444,  336,  336,  336,  336,  336,  512,
       462,  401,  409,  409,  409,  409,  409,  409,  409,  409,
       455,  455,  455,  455,  455,  456,  384,  336,  336,  336,
       336,  336,  336,  253,  170,  344,  344,  344,  344,  344,
@@ -740,7 +740,7 @@ static yyconst short int yy_nxt[3732] =
       344,  344,  344,  300,  253,  170,  345,  345,  345,  345,
       345,  345,  345,  345,  346,  606,  170,  463,  347,  347,
       347,  347,  347,   79,  472,  401,  253,  170,  451,  451,
-      451,  451,  451,  451,  331,  503,  401,   79,  511,  464,
+      451,  451,  451,  451,  331,  503,  401,   79,  513,  464,
       466,  347,  347,  347,  347,  347,  347,  170,  351,  352,
       353,  351,  351,  351,  351,  351,  354,  504,  465,   79,
       355,  355,  355,  355,  355,  454,  454,  454,  454,  454,
@@ -748,9 +748,9 @@ static yyconst short int yy_nxt[3732] =
       453,  453,  453,  355,  355,  355,  355,  355,  355,  375,
       376,  376,  376,  376,  376,  376,  376,  376,  470,  478,
 
-      544,  479,  479,  479,  479,  479,  479,  479,  479,  443,
+      546,  479,  479,  479,  479,  479,  479,  479,  479,  443,
       443,  443,  443,  443,  443,  443,  443,  460,  470,  459,
-      470,  471,  545,   79,  375,  377,  377,  377,  377,  377,
+      470,  471,  547,   79,  375,  377,  377,  377,  377,  377,
       377,  377,  377,  478,  470,  480,  480,  480,  480,  480,
       480,  480,  480,   79,  478,  382,  481,  481,  481,  481,
       481,  482,  479,  479,  470,  434,  470,  470,   79,  375,
@@ -759,70 +759,70 @@ static yyconst short int yy_nxt[3732] =
       490,  491,  606,  170,  488,  488,  488,  488,  488,  488,
       488,  488,  401,   79,  382,  382,  383,  383,  383,  383,
 
-      383,  383,  383,  383,  384,  487,  458,  457,  385,  385,
+      383,  383,  383,  383,  384,  487,  588,  589,  385,  385,
       385,  385,  385,  497,  498,  499,  497,  497,  497,  497,
-      497,  444,  331,  445,  445,  445,  445,  445,  445,  445,
+      497,  444,  458,  445,  445,  445,  445,  445,  445,  445,
       445,  385,  385,  385,  385,  385,  385,  389,  390,  391,
-      389,  389,  389,  389,  389,  392,  251,  418,  417,  393,
+      389,  389,  389,  389,  389,  392,  588,  589,  457,  393,
       393,  393,  393,  393,  444,  606,  445,  445,  445,  445,
       445,  445,  445,  445,  444,  487,  445,  445,  445,  445,
       445,  445,  393,  393,  393,  393,  393,  393,  253,  170,
       399,  399,  399,  399,  399,  399,  399,  399,  346,  253,
       170,  400,  400,  400,  400,  400,  400,  400,  400,  401,
 
-      253,  170,  382,  402,  402,  402,  402,  402,  467,   83,
-      401,  513,  487,  514,  515,  516,  513,  415,  514,  515,
-      516,  509,  544,  414,  554,  588,  402,  402,  402,  402,
+      253,  170,  331,  402,  402,  402,  402,  402,  554,  515,
+      401,  516,  517,  518,  515,  382,  516,  517,  518,  535,
+      535,  535,  535,  535,  536,  487,  402,  402,  402,  402,
       402,  402,  170,  406,  407,  408,  406,  406,  406,  406,
-      406,  413,  572,  572,  545,  409,  409,  409,  409,  409,
-      520,  521,  522,  520,  520,  520,  520,  520,  517,   79,
-       79,  412,  411,  519,  573,  573,  410,  337,  409,  409,
+      406,  382,  606,   79,  382,  409,  409,  409,  409,  409,
+      251,  532,  532,  418,  532,  417,  519,  415,  590,  414,
+      472,  521,  473,  473,  473,  473,  473,  473,  409,  409,
       409,  409,  409,  409,  375,  376,  376,  376,  376,  376,
-      376,  376,  376,   79,  472,  331,  473,  473,  473,  473,
-      473,  473,  523,  524,  525,  523,  523,  523,  523,  523,
-
-      478,  251,  479,  479,  479,  479,  479,  479,   79,  375,
-      376,  376,  376,  376,  376,  376,  376,  376,  478,   79,
-      479,  479,  479,  479,  479,  479,  479,  479,  478,  382,
-      479,  479,  479,  479,  479,  479,  479,  479,  211,  530,
-      370,  369,  363,   79,  382,  585,  432,  432,  432,  432,
-      432,  432,  432,  432,  384,  382,  606,  433,  433,  433,
-      433,  433,  433,  433,  433,  434,  530,  586,  585,  435,
-      435,  435,  435,  435,  496,  496,  496,  496,  496,  496,
-      496,  496,  532,  532,  532,  532,  532,  532,  532,  532,
-      586,  362,  435,  435,  435,  435,  435,  435,  439,  440,
-
-      441,  439,  439,  439,  439,  439,  442,  357,  356,  331,
-      443,  443,  443,  443,  443,  533,  533,  533,  533,  533,
-      534,  606,  382,  531,  531,  531,  531,  531,  531,  531,
-      531,  251,  530,  443,  443,  443,  443,  443,  443,  253,
+      376,  376,  376,  546,  572,  522,  523,  524,  522,  522,
+      522,  522,  522,   79,  413,   79,  525,  526,  527,  525,
+
+      525,  525,  525,  525,  412,  547,  573,  411,   79,  375,
+      376,  376,  376,  376,  376,  376,  376,  376,   79,  478,
+      572,  479,  479,  479,  479,  479,  479,  479,  479,  478,
+      410,  479,  479,  479,  479,  479,  479,  479,  479,  144,
+      144,  337,  573,   79,  382,  585,  432,  432,  432,  432,
+      432,  432,  432,  432,  384,  382,  331,  433,  433,  433,
+      433,  433,  433,  433,  433,  434,  251,  586,  585,  435,
+      435,  435,  435,  435,  478,  211,  479,  479,  479,  479,
+      479,  479,  496,  496,  496,  496,  496,  496,  496,  496,
+      586,  370,  435,  435,  435,  435,  435,  435,  439,  440,
+
+      441,  439,  439,  439,  439,  439,  442,  369,  363,  362,
+      443,  443,  443,  443,  443,  534,  534,  534,  534,  534,
+      534,  534,  534,  606,  357,  533,  533,  533,  533,  533,
+      533,  533,  533,  443,  443,  443,  443,  443,  443,  253,
       170,  451,  451,  451,  451,  451,  451,  451,  451,  401,
       253,  170,  452,  452,  452,  452,  452,  452,  452,  452,
-      211,  211,  276,  320,  453,  453,  453,  453,  453,  170,
-      539,  539,  539,  539,  539,  539,  539,  539,  170,  540,
-      540,  540,  540,  540,  540,  540,  540,  453,  453,  453,
-      453,  453,  453,  472,  319,  473,  473,  473,  473,  473,
-
-      473,  473,  473,  170,  541,  541,  541,  541,  541,  542,
-      539,  539,  606,  317,  606,  606,  606,  575,   83,  513,
-      316,  514,  515,  516,  315,  314,  313,  312,   79,  472,
-      587,  474,  474,  474,  474,  474,  474,  474,  474,  606,
-      311,  514,  515,  516,  606,  310,  606,  606,  516,  292,
-      606,  251,  606,  606,  606,  211,  288,  211,  103,  517,
-      276,  278,  276,  277,   79,  472,  517,  475,  475,  475,
+      356,  331,  251,  211,  453,  453,  453,  453,  453,  170,
+      541,  541,  541,  541,  541,  541,  541,  541,  170,  542,
+      542,  542,  542,  542,  542,  542,  542,  453,  453,  453,
+      453,  453,  453,  472,  211,  473,  473,  473,  473,  473,
+
+      473,  473,  473,  170,  543,  543,  543,  543,  543,  544,
+      541,  541,  606,  276,  606,  606,  606,  320,  319,  515,
+      317,  516,  517,  518,  316,  315,  314,  313,   79,  472,
+      312,  474,  474,  474,  474,  474,  474,  474,  474,  606,
+      311,  516,  517,  518,  606,  310,  606,  606,  518,  292,
+      606,  251,  606,  606,  606,  211,  288,  211,  103,  519,
+      276,  278,  276,  277,   79,  472,  519,  475,  475,  475,
       475,  475,  476,  477,  477,  552,  276,  274,  553,  553,
-      553,  553,  553,  553,  553,  553,  517,  273,  272,  271,
-      270,  517,  269,   97,  211,  512,  512,  519,  251,  512,
+      553,  553,  553,  553,  553,  553,  519,  273,  272,  271,
+      270,  519,  269,   97,  211,  514,  514,  521,  251,  514,
 
        79,  472,  211,  477,  477,  477,  473,  473,  473,  473,
-      473,  512,  512,  512,  518,  518,  103,  559,  518,  560,
+      473,  514,  514,  514,  520,  520,  103,  559,  520,  560,
       560,  560,  560,  560,  560,  560,  560,   83,  199,  239,
-      518,  518,  518,  236,  235,  234,   79,  382,  233,  485,
+      520,  520,  520,  236,  235,  234,   79,  382,  233,  485,
       485,  485,  485,  485,  485,  485,  485,  434,  382,  232,
       486,  486,  486,  486,  486,  486,  486,  486,  487,  230,
       229,  228,  488,  488,  488,  488,  488,  559,  227,  561,
-      561,  561,  561,  561,  561,  561,  561,  538,  538,  538,
-      538,  538,  538,  538,  538,  488,  488,  488,  488,  488,
+      561,  561,  561,  561,  561,  561,  561,  540,  540,  540,
+      540,  540,  540,  540,  540,  488,  488,  488,  488,  488,
       488,  492,  493,  494,  492,  492,  492,  492,  492,  495,
 
       226,  225,  224,  496,  496,  496,  496,  496,  559,  223,
@@ -831,65 +831,65 @@ static yyconst short int yy_nxt[3732] =
       496,  496,  253,  170,  502,  502,  502,  502,  502,  502,
       502,  502,  472,  222,  473,  473,  473,  473,  473,  473,
       473,  473,  570,  570,  570,  570,  570,  571,  606,  221,
-      568,  568,  568,  568,  568,  568,  568,  568,  170,  539,
-      539,  539,  539,  539,  539,  539,  539,   79,  472,  103,
-      473,  473,  473,  473,  473,  473,  473,  473,  170,  539,
-      539,  539,  539,  539,  539,  539,  539,  170,  539,  539,
-
-      539,  539,  539,  539,  553,  553,  553,  553,  553,  553,
-      553,  553,   95,   79,  382,   83,  528,  528,  528,  528,
-      528,  528,  528,  528,  487,  382,   83,  529,  529,  529,
-      529,  529,  529,  529,  529,  530,  199,  151,  152,  531,
-      531,  531,  531,  531,  553,  553,  553,  553,  553,  553,
+      568,  568,  568,  568,  568,  568,  568,  568,  170,  541,
+      541,  541,  541,  541,  541,  541,  541,   79,  472,  103,
+      473,  473,  473,  473,  473,  473,  473,  473,  170,  541,
+      541,  541,  541,  541,  541,  541,  541,  170,  541,  541,
+
+      541,  541,  541,  541,  553,  553,  553,  553,  553,  553,
+      553,  553,   95,   79,  382,   83,  530,  530,  530,  530,
+      530,  530,  530,  530,  487,  382,   83,  531,  531,  531,
+      531,  531,  531,  531,  531,  532,  199,  151,  152,  533,
+      533,  533,  533,  533,  553,  553,  553,  553,  553,  553,
       553,  553,  576,  577,  578,  576,  576,  576,  576,  576,
-      146,  146,  531,  531,  531,  531,  531,  531,  535,  536,
-      537,  535,  535,  535,  535,  535,  138,  197,  132,  132,
-      538,  538,  538,  538,  538,   79,  554,  190,  555,  555,
+      146,  146,  533,  533,  533,  533,  533,  533,  537,  538,
+      539,  537,  537,  537,  537,  537,  138,  197,  132,  132,
+      540,  540,  540,  540,  540,   79,  554,  190,  555,  555,
       555,  555,  555,  555,  579,  580,  581,  579,  579,  579,
 
-      579,  579,  189,  538,  538,  538,  538,  538,  538,  554,
+      579,  579,  189,  540,  540,  540,  540,  540,  540,  554,
       188,  555,  555,  555,  555,  555,  555,  555,  555,  187,
       559,   79,  560,  560,  560,  560,  560,  560,  560,  560,
       559,  186,  560,  560,  560,  560,  560,  560,  560,  560,
       184,  183,  182,  181,   79,  554,  176,  556,  556,  556,
       556,  556,  556,  556,  556,  559,  175,  560,  560,  560,
       560,  560,  560,  382,  174,  584,  584,  584,  584,  584,
-      584,  584,  584,  593,  593,  593,  593,  593,  593,  103,
+      584,  584,  584,  595,  595,  595,  595,  595,  595,  103,
        79,  554,   78,  557,  557,  557,  557,  557,  558,  555,
-      555,  593,  593,  593,  593,  593,  593,  593,  593,  594,
+      555,  595,  595,  595,  595,  595,  595,  595,  595,  596,
 
-      594,  594,  594,  594,  594,  594,  594,  595,  595,  595,
-      595,  595,  596,  593,  593,  103,   79,  382,  163,  566,
-      566,  566,  566,  566,  566,  566,  566,  530,  382,   91,
+      596,  596,  596,  596,  596,  596,  596,  597,  597,  597,
+      597,  597,  598,  595,  595,  103,   79,  382,  163,  566,
+      566,  566,  566,  566,  566,  566,  566,  532,  382,   91,
       567,  567,  567,  567,  567,  567,  567,  567,   83,   81,
        80,   79,  568,  568,  568,  568,  568,  152,  600,  601,
-      602,  600,  600,  600,  600,  600,  588,  146,  589,  589,
-      589,  589,  589,  589,  138,  568,  568,  568,  568,  568,
+      602,  600,  600,  600,  600,  600,  590,  146,  591,  591,
+      591,  591,  591,  591,  138,  568,  568,  568,  568,  568,
       568,  554,  132,  555,  555,  555,  555,  555,  555,  555,
-      555,   79,  593,  593,  593,  593,  593,  593,  593,  593,
-      128,   79,  593,  593,  593,  593,  593,  593,  593,  593,
+      555,   79,  595,  595,  595,  595,  595,  595,  595,  595,
+      128,   79,  595,  595,  595,  595,  595,  595,  595,  595,
 
       126,  113,  112,  111,  110,  109,   79,  554,  108,  555,
       555,  555,  555,  555,  555,  555,  555,  105,  103,   91,
       603,  603,  603,  603,  603,  603,  603,  603,  600,  600,
       600,  600,  600,  600,  600,  600,   81,   80,   79,  606,
-      606,  606,   79,  588,  606,  589,  589,  589,  589,  589,
-      589,  589,  589,   79,  606,  606,  606,  606,  606,  606,
+      606,  606,   79,  590,  606,  591,  591,  591,  591,  591,
+      591,  591,  591,   79,  606,  606,  606,  606,  606,  606,
       606,   79,  604,  604,  604,  604,  604,  605,  603,  603,
-      603,  603,  603,  603,  603,  603,  603,  603,   79,  588,
-      606,  590,  590,  590,  590,  590,  590,  590,  590,  606,
+      603,  603,  603,  603,  603,  603,  603,  603,   79,  590,
+      606,  592,  592,  592,  592,  592,  592,  592,  592,  606,
       606,  606,  606,  606,  606,   79,  603,  603,  603,  603,
 
       603,  603,  606,   79,  606,  606,  606,  606,  606,  606,
-      606,  606,  606,  606,   79,  588,  606,  591,  591,  591,
-      591,  591,  592,  589,  589,  606,  606,  606,  606,   79,
+      606,  606,  606,  606,   79,  590,  606,  593,  593,  593,
+      593,  593,  594,  591,  591,  606,  606,  606,  606,   79,
       606,  606,  606,  606,  606,  606,  606,  606,  606,  606,
       606,  606,  606,  606,  606,  606,  606,  606,  606,  606,
-       79,  588,  606,  589,  589,  589,  589,  589,  589,  589,
-      589,  606,  606,  606,  606,  606,  606,  606,  606,  606,
+       79,  590,  606,  591,  591,  591,  591,  591,  591,  591,
+      591,  606,  606,  606,  606,  606,  606,  606,  606,  606,
       606,  606,  606,  606,  606,  606,  606,  606,  606,  606,
-      606,  606,  606,  606,  606,  606,   79,  588,  606,  589,
-      589,  589,  589,  589,  589,  589,  589,  606,  606,  606,
+      606,  606,  606,  606,  606,  606,   79,  590,  606,  591,
+      591,  591,  591,  591,  591,  591,  591,  606,  606,  606,
 
       606,  606,  606,  606,  606,  606,  606,  606,  606,  606,
       606,  606,  606,  606,  606,  606,  606,  606,  606,  606,
@@ -951,19 +951,19 @@ static yyconst short int yy_nxt[3732] =
       606,  450,  483,  483,  606,  606,  606,  483,  484,  606,
       484,  484,  606,  606,  606,  484,  500,  500,  500,  606,
       606,  606,  500,  501,  501,  501,  606,  606,  606,  606,
-      501,  512,  512,  606,  512,  512,  512,  606,  606,  512,
-      512,  512,  606,  606,  512,  512,  512,  518,  518,  606,
-      518,  518,  518,  606,  606,  518,  518,  518,  606,  606,
-      518,  518,  518,  526,  526,  606,  606,  606,  526,  527,
-      606,  527,  527,  606,  606,  606,  527,  543,  543,  606,
-
-      606,  606,  606,  543,  549,  549,  549,  549,  549,  549,
-      549,  549,  549,  549,  549,  549,  549,  549,  549,  549,
+      501,  509,  509,  509,  509,  509,  509,  509,  509,  509,
+      509,  509,  509,  509,  509,  509,  509,  514,  514,  606,
+      514,  514,  514,  606,  606,  514,  514,  514,  606,  606,
+      514,  514,  514,  520,  520,  606,  520,  520,  520,  606,
+      606,  520,  520,  520,  606,  606,  520,  520,  520,  528,
+
+      528,  606,  606,  606,  528,  529,  606,  529,  529,  606,
+      606,  606,  529,  545,  545,  606,  606,  606,  606,  545,
       564,  564,  606,  606,  606,  564,  565,  606,  565,  565,
       606,  606,  606,  565,  582,  582,  606,  606,  606,  582,
-      583,  606,  583,  606,  606,  606,  606,  583,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,   13,  606,  606,  606,  606,  606,
+      583,  606,  583,  606,  606,  606,  606,  583,  587,  587,
+      587,  587,  587,  587,  587,  587,  587,  587,  587,  587,
+      587,  587,  587,  587,   13,  606,  606,  606,  606,  606,
       606,  606,  606,  606,  606,  606,  606,  606,  606,  606,
       606,  606,  606,  606,  606,  606,  606,  606,  606,  606,
       606,  606,  606,  606,  606,  606,  606,  606,  606,  606,
@@ -993,7 +993,7 @@ static yyconst short int yy_chk[3732] =
         3,  196,   68,   50,   11,    4,   70,    6,    6,   25,
        25,   72,   72,   25,   25,  196,   74,    5,   27,   27,
        27,   27,   27,   27,   27,   27,   68,   88,  124,  127,
-       70,   25,    6,    7,    7,    7,   45,    7,  598,   75,
+       70,   25,    6,    7,    7,    7,   45,    7,  587,   75,
       124,  127,  129,   12,   28,   28,   28,   28,   28,   28,
       139,  139,  129,   43,   25,   43,   43,   43,   43,   43,
        43,   43,   43,  194,   45,   45,   77,   77,   45,   77,
@@ -1011,22 +1011,22 @@ static yyconst short int yy_chk[3732] =
 
       128,  154,    9,    9,    9,   86,  128,  202,   55,   55,
       136,  161,   55,   55,  185,  136,    9,  101,  101,  101,
-      101,  101,  101,   86,  155,  155,  198,  185,   87,  587,
+      101,  101,  101,   86,  155,  155,  198,  185,   87,  584,
        55,   87,   87,   87,   87,   87,   87,   87,   87,  198,
-        9,   10,   10,   10,   10,   10,  584,  171,   86,  284,
+        9,   10,   10,   10,   10,   10,  582,  171,   86,  284,
        10,   10,   10,   55,  161,   89,  171,   89,   89,  222,
-      582,   89,   89,  222,   10,   89,  213,   95,   95,   95,
+      568,   89,   89,  222,   10,   89,  213,   95,   95,   95,
        95,   95,   95,   95,   95,  213,   92,   92,   89,   89,
-       92,   92,  192,  195,  284,  195,  510,  192,   10,   19,
+       92,   92,  192,  195,  284,  195,  512,  192,   10,   19,
        99,   99,   99,   99,   99,   99,   99,   99,   92,   19,
 
        95,  221,   19,   19,   19,   19,   19,   19,   19,   19,
        26,  191,   26,   26,   26,   26,   26,   26,   26,   26,
        26,   92,  237,  221,   26,   26,   26,   26,   26,  100,
       100,  100,  100,  100,  100,  100,  100,  131,  131,  131,
-      131,  131,  131,  131,  131,   26,  510,   26,   26,   26,
+      131,  131,  131,  131,  131,   26,  512,   26,   26,   26,
        26,   26,   26,   32,  146,  238,  238,  146,  146,   32,
-      568,  191,   32,   32,  146,   32,   32,   32,   32,   32,
+      567,  191,   32,   32,  146,   32,   32,   32,   32,   32,
        32,   32,   32,   32,   32,   32,   32,  146,  237,   32,
        32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
        32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
@@ -1035,7 +1035,7 @@ static yyconst short int yy_chk[3732] =
        32,   32,   32,   32,   32,   32,   32,   32,   32,   35,
        35,   35,   35,   35,   35,   35,   35,   35,  210,  210,
       210,   35,   35,   35,   35,   35,  109,  231,  240,  241,
-       35,  109,  252,  231,  109,  241,  109,  117,  567,  150,
+       35,  109,  252,  231,  109,  241,  109,  117,  565,  150,
       150,  252,  239,  240,   35,   35,   35,   35,   35,   35,
        42,   42,   42,   42,   42,  293,   42,   42,  133,  133,
        42,  265,  133,  133,  293,  117,  117,  239,  281,  117,
@@ -1047,8 +1047,8 @@ static yyconst short int yy_chk[3732] =
       142,  142,  159,  159,  159,  159,  159,  159,  159,  159,
       160,  160,  160,  160,  160,  160,  160,  160,  438,  438,
        46,   63,  201,  201,  201,  201,  201,  201,  201,  201,
-      279,   63,  565,  280,   63,   63,   63,   63,   63,   63,
-       63,   63,   79,  564,   79,   79,   79,  297,   79,   79,
+      279,   63,  564,  280,   63,   63,   63,   63,   63,   63,
+       63,   63,   79,  560,   79,   79,   79,  297,   79,   79,
       254,  254,   79,  197,  280,  201,  297,  197,  256,  256,
       254,  321,  322,  197,   79,   79,   79,   91,  256,   91,
        91,   91,  322,   91,   91,  197,  197,   91,  209,  209,
@@ -1066,17 +1066,17 @@ static yyconst short int yy_chk[3732] =
 
       216,  216,  216,  217,  217,  217,  217,  217,  217,  316,
       299,  299,  373,  104,  104,  104,  104,  104,  104,  135,
-      299,  135,  135,  135,  560,  135,  135,  373,  219,  135,
+      299,  135,  135,  135,  549,  135,  135,  373,  219,  135,
       219,  219,  219,  219,  219,  219,  219,  219,  453,  453,
-      371,  135,  135,  135,  164,  549,  164,  164,  164,  164,
+      371,  135,  135,  135,  164,  545,  164,  164,  164,  164,
       164,  164,  164,  164,  247,  247,  247,  247,  247,  247,
       247,  247,  247,  253,  253,  253,  253,  253,  253,  253,
       253,  255,  255,  255,  255,  255,  255,  255,  255,  164,
-      165,  547,  165,  165,  165,  165,  165,  165,  165,  165,
+      165,  541,  165,  165,  165,  165,  165,  165,  165,  165,
       259,  259,  259,  259,  259,  259,  259,  259,  419,  419,
 
       259,  261,  261,  261,  261,  261,  261,  261,  261,  262,
-      262,  262,  262,  262,  262,  165,  166,  543,  166,  166,
+      262,  262,  262,  262,  262,  165,  166,  529,  166,  166,
       166,  166,  166,  166,  166,  166,  264,  317,  264,  264,
       264,  264,  264,  264,  264,  264,  301,  301,  283,  283,
       283,  283,  283,  283,  283,  283,  301,  456,  456,  317,
@@ -1086,41 +1086,41 @@ static yyconst short int yy_chk[3732] =
       287,  287,  287,  287,  287,  344,  420,  372,  420,  167,
       167,  167,  167,  167,  167,  170,  170,  170,  170,  170,
 
-      170,  170,  170,  170,  345,  345,  539,  170,  170,  170,
+      170,  170,  170,  170,  345,  345,  528,  170,  170,  170,
       170,  170,  287,  294,  345,  294,  294,  294,  294,  294,
-      294,  294,  294,  307,  307,  307,  307,  307,  307,  527,
+      294,  294,  294,  307,  307,  307,  307,  307,  307,  513,
       170,  170,  170,  170,  170,  170,  172,  172,  172,  172,
-      172,  172,  172,  172,  172,  172,  491,  491,  526,  172,
+      172,  172,  172,  172,  172,  172,  467,  467,  509,  172,
       172,  172,  172,  172,  295,  376,  295,  295,  295,  295,
       295,  295,  295,  295,  300,  300,  300,  300,  300,  300,
       300,  300,  172,  172,  172,  172,  172,  172,  173,  173,
-      173,  173,  173,  173,  173,  173,  347,  347,  511,  376,
+      173,  173,  173,  173,  173,  173,  347,  347,  508,  376,
       173,  173,  173,  173,  173,  296,  347,  296,  296,  296,
 
       296,  296,  296,  296,  296,  306,  306,  306,  306,  306,
       306,  306,  306,  173,  173,  173,  173,  173,  173,  203,
-      509,  203,  203,  203,  203,  203,  203,  203,  203,  304,
-      304,  304,  304,  304,  304,  304,  304,  508,  309,  304,
+      507,  203,  203,  203,  203,  203,  203,  203,  203,  304,
+      304,  304,  304,  304,  304,  304,  304,  506,  309,  304,
       309,  309,  309,  309,  309,  309,  309,  309,  334,  334,
-      334,  334,  334,  334,  203,  204,  507,  204,  204,  204,
+      334,  334,  334,  334,  203,  204,  501,  204,  204,  204,
       204,  204,  204,  204,  204,  331,  331,  331,  331,  331,
       331,  331,  331,  333,  333,  333,  333,  333,  333,  333,
       333,  337,  337,  337,  337,  337,  337,  337,  337,  358,
       204,  215,  215,  215,  215,  215,  215,  215,  215,  215,
 
-      215,  215,  502,  502,  506,  215,  215,  215,  215,  215,
+      215,  215,  491,  491,  484,  215,  215,  215,  215,  215,
       336,  358,  336,  336,  336,  336,  336,  336,  336,  336,
-      341,  501,  341,  341,  341,  341,  341,  341,  215,  215,
+      341,  483,  341,  341,  341,  341,  341,  341,  215,  215,
       215,  215,  215,  215,  218,  218,  218,  218,  218,  218,
-      218,  218,  218,  218,  397,  534,  534,  218,  218,  218,
+      218,  218,  218,  218,  397,  502,  502,  218,  218,  218,
       218,  218,  339,  397,  339,  339,  339,  339,  339,  339,
       339,  339,  346,  346,  346,  346,  346,  346,  346,  346,
-      218,  218,  218,  218,  218,  218,  242,  484,  242,  242,
+      218,  218,  218,  218,  218,  218,  242,  479,  242,  242,
       242,  242,  242,  242,  242,  242,  340,  364,  340,  340,
       340,  340,  340,  340,  340,  340,  350,  350,  350,  350,
 
-      350,  350,  350,  350,  398,  669,  350,  551,  551,  364,
-      669,  242,  243,  398,  243,  243,  243,  243,  243,  243,
+      350,  350,  350,  350,  398,  670,  350,  510,  510,  364,
+      670,  242,  243,  398,  243,  243,  243,  243,  243,  243,
       243,  243,  352,  352,  352,  352,  352,  352,  352,  352,
       353,  353,  353,  353,  353,  353,  355,  366,  355,  355,
       355,  355,  355,  355,  355,  355,  374,  243,  244,  449,
@@ -1133,20 +1133,20 @@ static yyconst short int yy_chk[3732] =
       260,  260,  260,  260,  260,  260,  375,  415,  457,  260,
       260,  260,  260,  260,  379,  379,  379,  379,  379,  379,
       379,  384,  384,  384,  384,  384,  384,  384,  384,  415,
-      457,  483,  260,  260,  260,  260,  260,  260,  263,  263,
-      263,  263,  263,  263,  263,  263,  263,  263,  379,  571,
-      571,  263,  263,  263,  263,  263,  390,  390,  390,  390,
+      457,  465,  260,  260,  260,  260,  260,  260,  263,  263,
+      263,  263,  263,  263,  263,  263,  263,  263,  379,  536,
+      536,  263,  263,  263,  263,  263,  390,  390,  390,  390,
       390,  390,  390,  390,  391,  391,  391,  391,  391,  391,
-      479,  399,  399,  465,  263,  263,  263,  263,  263,  263,
+      460,  399,  399,  459,  263,  263,  263,  263,  263,  263,
       285,  399,  285,  285,  285,  285,  285,  285,  285,  285,
       393,  432,  393,  393,  393,  393,  393,  393,  393,  393,
 
       394,  432,  394,  394,  394,  394,  394,  394,  394,  394,
-      460,  473,  619,  619,  468,  285,  286,  433,  286,  286,
+      458,  473,  551,  551,  468,  285,  286,  433,  286,  286,
       286,  286,  286,  286,  286,  286,  395,  433,  395,  395,
       395,  395,  395,  395,  395,  395,  396,  435,  396,  396,
-      396,  396,  396,  396,  396,  396,  473,  435,  461,  459,
-      458,  286,  292,  292,  292,  292,  292,  292,  292,  292,
+      396,  396,  396,  396,  396,  396,  473,  435,  461,  571,
+      571,  286,  292,  292,  292,  292,  292,  292,  292,  292,
       292,  400,  400,  445,  292,  292,  292,  292,  292,  468,
       461,  400,  401,  401,  401,  401,  401,  401,  401,  401,
       408,  408,  408,  408,  408,  408,  431,  292,  292,  292,
@@ -1174,84 +1174,84 @@ static yyconst short int yy_chk[3732] =
       441,  441,  443,  500,  443,  443,  443,  443,  443,  443,
       443,  443,  500,  327,  332,  486,  332,  332,  332,  332,
 
-      332,  332,  332,  332,  332,  486,  411,  410,  332,  332,
+      332,  332,  332,  332,  332,  486,  575,  575,  332,  332,
       332,  332,  332,  444,  444,  444,  444,  444,  444,  444,
-      444,  446,  381,  446,  446,  446,  446,  446,  446,  446,
+      444,  446,  411,  446,  446,  446,  446,  446,  446,  446,
       446,  332,  332,  332,  332,  332,  332,  335,  335,  335,
-      335,  335,  335,  335,  335,  335,  380,  370,  369,  335,
+      335,  335,  335,  335,  335,  335,  588,  588,  410,  335,
       335,  335,  335,  335,  447,  488,  447,  447,  447,  447,
       447,  447,  447,  447,  448,  488,  448,  448,  448,  448,
       448,  448,  335,  335,  335,  335,  335,  335,  348,  348,
       348,  348,  348,  348,  348,  348,  348,  348,  348,  351,
       351,  351,  351,  351,  351,  351,  351,  351,  351,  351,
 
-      451,  451,  528,  351,  351,  351,  351,  351,  467,  467,
-      451,  470,  528,  470,  470,  470,  471,  363,  471,  471,
-      471,  467,  544,  362,  555,  589,  351,  351,  351,  351,
+      451,  451,  381,  351,  351,  351,  351,  351,  555,  470,
+      451,  470,  470,  470,  471,  530,  471,  471,  471,  494,
+      494,  494,  494,  494,  494,  530,  351,  351,  351,  351,
       351,  351,  354,  354,  354,  354,  354,  354,  354,  354,
-      354,  361,  546,  572,  544,  354,  354,  354,  354,  354,
-      472,  472,  472,  472,  472,  472,  472,  472,  470,  555,
-      589,  360,  357,  471,  546,  572,  356,  338,  354,  354,
+      354,  531,  533,  555,  566,  354,  354,  354,  354,  354,
+      380,  531,  533,  370,  566,  369,  470,  363,  591,  362,
+      476,  471,  476,  476,  476,  476,  476,  476,  354,  354,
       354,  354,  354,  354,  377,  377,  377,  377,  377,  377,
-      377,  377,  377,  472,  476,  330,  476,  476,  476,  476,
-      476,  476,  478,  478,  478,  478,  478,  478,  478,  478,
-
-      482,  329,  482,  482,  482,  482,  482,  482,  377,  378,
-      378,  378,  378,  378,  378,  378,  378,  378,  480,  476,
-      480,  480,  480,  480,  480,  480,  480,  480,  481,  529,
-      481,  481,  481,  481,  481,  481,  481,  481,  328,  529,
-      320,  319,  315,  378,  386,  574,  386,  386,  386,  386,
-      386,  386,  386,  386,  386,  389,  531,  389,  389,  389,
-      389,  389,  389,  389,  389,  389,  531,  574,  585,  389,
-      389,  389,  389,  389,  487,  487,  487,  487,  487,  487,
-      487,  487,  493,  493,  493,  493,  493,  493,  493,  493,
-      585,  314,  389,  389,  389,  389,  389,  389,  392,  392,
-
-      392,  392,  392,  392,  392,  392,  392,  311,  310,  291,
-      392,  392,  392,  392,  392,  494,  494,  494,  494,  494,
-      494,  496,  566,  496,  496,  496,  496,  496,  496,  496,
-      496,  290,  566,  392,  392,  392,  392,  392,  392,  403,
+      377,  377,  377,  546,  548,  472,  472,  472,  472,  472,
+      472,  472,  472,  591,  361,  476,  478,  478,  478,  478,
+
+      478,  478,  478,  478,  360,  546,  548,  357,  377,  378,
+      378,  378,  378,  378,  378,  378,  378,  378,  472,  480,
+      572,  480,  480,  480,  480,  480,  480,  480,  480,  481,
+      356,  481,  481,  481,  481,  481,  481,  481,  481,  619,
+      619,  338,  572,  378,  386,  574,  386,  386,  386,  386,
+      386,  386,  386,  386,  386,  389,  330,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  329,  574,  585,  389,
+      389,  389,  389,  389,  482,  328,  482,  482,  482,  482,
+      482,  482,  487,  487,  487,  487,  487,  487,  487,  487,
+      585,  320,  389,  389,  389,  389,  389,  389,  392,  392,
+
+      392,  392,  392,  392,  392,  392,  392,  319,  315,  314,
+      392,  392,  392,  392,  392,  493,  493,  493,  493,  493,
+      493,  493,  493,  496,  311,  496,  496,  496,  496,  496,
+      496,  496,  496,  392,  392,  392,  392,  392,  392,  403,
       403,  403,  403,  403,  403,  403,  403,  403,  403,  403,
       406,  406,  406,  406,  406,  406,  406,  406,  406,  406,
-      289,  288,  278,  277,  406,  406,  406,  406,  406,  497,
+      310,  291,  290,  289,  406,  406,  406,  406,  406,  497,
       497,  497,  497,  497,  497,  497,  497,  497,  498,  498,
       498,  498,  498,  498,  498,  498,  498,  406,  406,  406,
-      406,  406,  406,  423,  276,  423,  423,  423,  423,  423,
+      406,  406,  406,  423,  288,  423,  423,  423,  423,  423,
 
       423,  423,  423,  499,  499,  499,  499,  499,  499,  499,
-      499,  499,  512,  274,  512,  512,  512,  575,  575,  513,
-      273,  513,  513,  513,  272,  271,  270,  269,  423,  424,
-      575,  424,  424,  424,  424,  424,  424,  424,  424,  514,
-      268,  514,  514,  514,  515,  267,  515,  515,  515,  251,
-      518,  250,  518,  518,  518,  249,  248,  246,  245,  512,
-      236,  235,  234,  233,  424,  425,  513,  425,  425,  425,
-      425,  425,  425,  425,  425,  516,  232,  229,  516,  516,
-      516,  516,  516,  516,  516,  516,  514,  227,  226,  225,
-      224,  515,  223,  220,  212,  517,  517,  518,  211,  517,
+      499,  499,  514,  278,  514,  514,  514,  277,  276,  515,
+      274,  515,  515,  515,  273,  272,  271,  270,  423,  424,
+      269,  424,  424,  424,  424,  424,  424,  424,  424,  516,
+      268,  516,  516,  516,  517,  267,  517,  517,  517,  251,
+      520,  250,  520,  520,  520,  249,  248,  246,  245,  514,
+      236,  235,  234,  233,  424,  425,  515,  425,  425,  425,
+      425,  425,  425,  425,  425,  518,  232,  229,  518,  518,
+      518,  518,  518,  518,  518,  518,  516,  227,  226,  225,
+      224,  517,  223,  220,  212,  519,  519,  520,  211,  519,
 
       425,  426,  208,  426,  426,  426,  426,  426,  426,  426,
-      426,  517,  517,  517,  519,  519,  207,  523,  519,  523,
-      523,  523,  523,  523,  523,  523,  523,  200,  199,  193,
-      519,  519,  519,  190,  189,  188,  426,  436,  187,  436,
+      426,  519,  519,  519,  521,  521,  207,  525,  521,  525,
+      525,  525,  525,  525,  525,  525,  525,  200,  199,  193,
+      521,  521,  521,  190,  189,  188,  426,  436,  187,  436,
       436,  436,  436,  436,  436,  436,  436,  436,  439,  186,
       439,  439,  439,  439,  439,  439,  439,  439,  439,  184,
-      183,  182,  439,  439,  439,  439,  439,  524,  181,  524,
-      524,  524,  524,  524,  524,  524,  524,  530,  530,  530,
-      530,  530,  530,  530,  530,  439,  439,  439,  439,  439,
+      183,  182,  439,  439,  439,  439,  439,  526,  181,  526,
+      526,  526,  526,  526,  526,  526,  526,  532,  532,  532,
+      532,  532,  532,  532,  532,  439,  439,  439,  439,  439,
       439,  442,  442,  442,  442,  442,  442,  442,  442,  442,
 
-      180,  179,  178,  442,  442,  442,  442,  442,  525,  177,
-      525,  525,  525,  525,  525,  525,  525,  525,  536,  536,
-      536,  536,  536,  536,  536,  536,  442,  442,  442,  442,
+      180,  179,  178,  442,  442,  442,  442,  442,  527,  177,
+      527,  527,  527,  527,  527,  527,  527,  527,  538,  538,
+      538,  538,  538,  538,  538,  538,  442,  442,  442,  442,
       442,  442,  454,  454,  454,  454,  454,  454,  454,  454,
       454,  454,  474,  176,  474,  474,  474,  474,  474,  474,
-      474,  474,  537,  537,  537,  537,  537,  537,  538,  175,
-      538,  538,  538,  538,  538,  538,  538,  538,  540,  540,
-      540,  540,  540,  540,  540,  540,  540,  474,  475,  169,
-      475,  475,  475,  475,  475,  475,  475,  475,  541,  541,
-      541,  541,  541,  541,  541,  541,  541,  542,  542,  542,
+      474,  474,  539,  539,  539,  539,  539,  539,  540,  175,
+      540,  540,  540,  540,  540,  540,  540,  540,  542,  542,
+      542,  542,  542,  542,  542,  542,  542,  474,  475,  169,
+      475,  475,  475,  475,  475,  475,  475,  475,  543,  543,
+      543,  543,  543,  543,  543,  543,  543,  544,  544,  544,
 
-      542,  542,  542,  542,  552,  552,  552,  552,  552,  552,
+      544,  544,  544,  544,  552,  552,  552,  552,  552,  552,
       552,  552,  168,  475,  489,  158,  489,  489,  489,  489,
       489,  489,  489,  489,  489,  492,  157,  492,  492,  492,
       492,  492,  492,  492,  492,  492,  156,  152,  151,  492,
@@ -1262,27 +1262,27 @@ static yyconst short int yy_chk[3732] =
       495,  495,  495,  495,  495,  554,  558,  122,  558,  558,
       558,  558,  558,  558,  559,  559,  559,  559,  559,  559,
 
-      559,  559,  121,  495,  495,  495,  495,  495,  495,  520,
-      120,  520,  520,  520,  520,  520,  520,  520,  520,  119,
+      559,  559,  121,  495,  495,  495,  495,  495,  495,  522,
+      120,  522,  522,  522,  522,  522,  522,  522,  522,  119,
       561,  558,  561,  561,  561,  561,  561,  561,  561,  561,
       562,  118,  562,  562,  562,  562,  562,  562,  562,  562,
-      113,  112,  111,  110,  520,  521,  108,  521,  521,  521,
-      521,  521,  521,  521,  521,  563,  107,  563,  563,  563,
+      113,  112,  111,  110,  522,  523,  108,  523,  523,  523,
+      523,  523,  523,  523,  523,  563,  107,  563,  563,  563,
       563,  563,  563,  569,  106,  569,  569,  569,  569,  569,
-      569,  569,  569,  596,  596,  596,  596,  596,  596,  102,
-      521,  522,   98,  522,  522,  522,  522,  522,  522,  522,
-      522,  579,  579,  579,  579,  579,  579,  579,  579,  580,
+      569,  569,  569,  598,  598,  598,  598,  598,  598,  102,
+      523,  524,   98,  524,  524,  524,  524,  524,  524,  524,
+      524,  579,  579,  579,  579,  579,  579,  579,  579,  580,
 
       580,  580,  580,  580,  580,  580,  580,  581,  581,  581,
-      581,  581,  581,  581,  581,   97,  522,  532,   93,  532,
-      532,  532,  532,  532,  532,  532,  532,  532,  535,   90,
-      535,  535,  535,  535,  535,  535,  535,  535,   82,   81,
-       80,   78,  535,  535,  535,  535,  535,   73,  588,  588,
-      588,  588,  588,  588,  588,  588,  592,   66,  592,  592,
-      592,  592,  592,  592,   59,  535,  535,  535,  535,  535,
-      535,  556,   54,  556,  556,  556,  556,  556,  556,  556,
-      556,  588,  594,  594,  594,  594,  594,  594,  594,  594,
-       51,  592,  595,  595,  595,  595,  595,  595,  595,  595,
+      581,  581,  581,  581,  581,   97,  524,  534,   93,  534,
+      534,  534,  534,  534,  534,  534,  534,  534,  537,   90,
+      537,  537,  537,  537,  537,  537,  537,  537,   82,   81,
+       80,   78,  537,  537,  537,  537,  537,   73,  590,  590,
+      590,  590,  590,  590,  590,  590,  594,   66,  594,  594,
+      594,  594,  594,  594,   59,  537,  537,  537,  537,  537,
+      537,  556,   54,  556,  556,  556,  556,  556,  556,  556,
+      556,  590,  596,  596,  596,  596,  596,  596,  596,  596,
+       51,  594,  597,  597,  597,  597,  597,  597,  597,  597,
 
        49,   41,   40,   39,   38,   37,  556,  557,   36,  557,
       557,  557,  557,  557,  557,  557,  557,   33,   29,   23,
@@ -1300,15 +1300,15 @@ static yyconst short int yy_chk[3732] =
       578,  578,  578,  578,  578,    0,    0,    0,    0,  605,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-      578,  590,    0,  590,  590,  590,  590,  590,  590,  590,
-      590,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      578,  592,    0,  592,  592,  592,  592,  592,  592,  592,
+      592,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,  590,  591,    0,  591,
-      591,  591,  591,  591,  591,  591,  591,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,  592,  593,    0,  593,
+      593,  593,  593,  593,  593,  593,  593,    0,    0,    0,
 
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,  591,  607,  607,  607,  607,  607,  607,  607,
+        0,    0,  593,  607,  607,  607,  607,  607,  607,  607,
       607,  607,  607,  607,  607,  607,  607,  607,  607,  608,
       608,  608,  608,  608,  608,  608,  608,  608,  608,  608,
       608,  608,  608,  608,  608,  609,  609,  609,  609,  609,
@@ -1366,19 +1366,19 @@ static yyconst short int yy_chk[3732] =
         0,  654,  655,  655,    0,    0,    0,  655,  656,    0,
       656,  656,    0,    0,    0,  656,  657,  657,  657,    0,
         0,    0,  657,  658,  658,  658,    0,    0,    0,    0,
-      658,  659,  659,    0,  659,  659,  659,    0,    0,  659,
-      659,  659,    0,    0,  659,  659,  659,  660,  660,    0,
+      658,  659,  659,  659,  659,  659,  659,  659,  659,  659,
+      659,  659,  659,  659,  659,  659,  659,  660,  660,    0,
       660,  660,  660,    0,    0,  660,  660,  660,    0,    0,
-      660,  660,  660,  661,  661,    0,    0,    0,  661,  662,
-        0,  662,  662,    0,    0,    0,  662,  663,  663,    0,
+      660,  660,  660,  661,  661,    0,  661,  661,  661,    0,
+        0,  661,  661,  661,    0,    0,  661,  661,  661,  662,
 
-        0,    0,    0,  663,  664,  664,  664,  664,  664,  664,
-      664,  664,  664,  664,  664,  664,  664,  664,  664,  664,
+      662,    0,    0,    0,  662,  663,    0,  663,  663,    0,
+        0,    0,  663,  664,  664,    0,    0,    0,    0,  664,
       665,  665,    0,    0,    0,  665,  666,    0,  666,  666,
         0,    0,    0,  666,  667,  667,    0,    0,    0,  667,
-      668,    0,  668,    0,    0,    0,    0,  668,  670,  670,
-      670,  670,  670,  670,  670,  670,  670,  670,  670,  670,
-      670,  670,  670,  670,  606,  606,  606,  606,  606,  606,
+      668,    0,  668,    0,    0,    0,    0,  668,  669,  669,
+      669,  669,  669,  669,  669,  669,  669,  669,  669,  669,
+      669,  669,  669,  669,  606,  606,  606,  606,  606,  606,
       606,  606,  606,  606,  606,  606,  606,  606,  606,  606,
       606,  606,  606,  606,  606,  606,  606,  606,  606,  606,
       606,  606,  606,  606,  606,  606,  606,  606,  606,  606,
@@ -1475,27 +1475,31 @@ char *yytext;
 #include "parse.h"
 #include "toke.h"
 #include <gram.h>
+#include "lbuf.h"
 
 extern YYSTYPE yylval;
-extern int parse_error;
+extern bool parse_error;
 int sudolineno;
+int last_token;
 char *sudoers;
 
-static int continued, prev_state, sawspace;
+static bool continued, sawspace;
+static int prev_state;
 
-static int _push_include(char *, int);
-static int pop_include(void);
+static bool _push_include(char *, bool);
+static bool pop_include(void);
 static char *parse_include(char *);
 
-#ifdef TRACELEXER
 static int sudoers_trace_print(const char *msg);
-#else
-# define sudoers_trace_print NULL
-#endif
 int (*trace_print)(const char *msg) = sudoers_trace_print;
 
-#define        push_include(_p)        (_push_include((_p), FALSE))
-#define        push_includedir(_p)     (_push_include((_p), TRUE))
+#define LEXRETURN(n)   do {    \
+       last_token = (n);       \
+       return (n);             \
+} while (0)
+
+#define        push_include(_p)        (_push_include((_p), false))
+#define        push_includedir(_p)     (_push_include((_p), true))
 #define YY_NO_INPUT 1
 #define YY_NO_UNPUT 1
 #define GOTDEFS 1
@@ -1508,7 +1512,7 @@ int (*trace_print)(const char *msg) = sudoers_trace_print;
 
 #define INSTR 5
 
-#line 1511 "lex.yy.c"
+#line 1515 "lex.yy.c"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -1662,9 +1666,9 @@ YY_DECL
        register char *yy_cp, *yy_bp;
        register int yy_act;
 
-#line 119 "toke.l"
+#line 123 "toke.l"
 
-#line 1667 "lex.yy.c"
+#line 1671 "lex.yy.c"
 
        if ( yy_init )
                {
@@ -1750,65 +1754,65 @@ do_action:      /* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 120 "toke.l"
+#line 124 "toke.l"
 {
                            LEXTRACE(", ");
-                           return ',';
+                           LEXRETURN(',');
                        }                       /* return ',' */
        YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 125 "toke.l"
+#line 129 "toke.l"
 BEGIN STARTDEFS;
        YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 127 "toke.l"
+#line 131 "toke.l"
 {
                            BEGIN INDEFS;
                            LEXTRACE("DEFVAR ");
                            if (!fill(yytext, yyleng))
                                yyterminate();
-                           return DEFVAR;
+                           LEXRETURN(DEFVAR);
                        }
        YY_BREAK
 
 case 4:
 YY_RULE_SETUP
-#line 136 "toke.l"
+#line 140 "toke.l"
 {
                            BEGIN STARTDEFS;
                            LEXTRACE(", ");
-                           return ',';
+                           LEXRETURN(',');
                        }                       /* return ',' */
        YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 142 "toke.l"
+#line 146 "toke.l"
 {
                            LEXTRACE("= ");
-                           return '=';
+                           LEXRETURN('=');
                        }                       /* return '=' */
        YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 147 "toke.l"
+#line 151 "toke.l"
 {
                            LEXTRACE("+= ");
-                           return '+';
+                           LEXRETURN('+');
                        }                       /* return '+' */
        YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 152 "toke.l"
+#line 156 "toke.l"
 {
                            LEXTRACE("-= ");
-                           return '-';
+                           LEXRETURN('-');
                        }                       /* return '-' */
        YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 157 "toke.l"
+#line 161 "toke.l"
 {
                            LEXTRACE("BEGINSTR ");
                            yylval.string = NULL;
@@ -1818,35 +1822,35 @@ YY_RULE_SETUP
        YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 164 "toke.l"
+#line 168 "toke.l"
 {
                            LEXTRACE("WORD(2) ");
                            if (!fill(yytext, yyleng))
                                yyterminate();
-                           return WORD;
+                           LEXRETURN(WORD);
                        }
        YY_BREAK
 
 
 case 10:
 YY_RULE_SETUP
-#line 173 "toke.l"
+#line 177 "toke.l"
 {
                            /* Line continuation char followed by newline. */
-                           ++sudolineno;
-                           continued = TRUE;
+                           sudolineno++;
+                           continued = true;
                        }
        YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 179 "toke.l"
+#line 183 "toke.l"
 {
                            LEXTRACE("ENDSTR ");
                            BEGIN prev_state;
 
                            if (yylval.string == NULL) {
                                LEXTRACE("ERROR "); /* empty string */
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
                            if (prev_state == INITIAL) {
                                switch (yylval.string[0]) {
@@ -1855,26 +1859,26 @@ YY_RULE_SETUP
                                        (yylval.string[1] == ':' &&
                                        yylval.string[2] == '\0')) {
                                        LEXTRACE("ERROR "); /* empty group */
-                                       return ERROR;
+                                       LEXRETURN(ERROR);
                                    }
                                    LEXTRACE("USERGROUP ");
-                                   return USERGROUP;
+                                   LEXRETURN(USERGROUP);
                                case '+':
                                    if (yylval.string[1] == '\0') {
                                        LEXTRACE("ERROR "); /* empty netgroup */
-                                       return ERROR;
+                                       LEXRETURN(ERROR);
                                    }
                                    LEXTRACE("NETGROUP ");
-                                   return NETGROUP;
+                                   LEXRETURN(NETGROUP);
                                }
                            }
                            LEXTRACE("WORD(4) ");
-                           return WORD;
+                           LEXRETURN(WORD);
                        }
        YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 211 "toke.l"
+#line 215 "toke.l"
 {
                            LEXTRACE("BACKSLASH ");
                            if (!append(yytext, yyleng))
@@ -1883,7 +1887,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 217 "toke.l"
+#line 221 "toke.l"
 {
                            LEXTRACE("STRBODY ");
                            if (!append(yytext, yyleng))
@@ -1894,55 +1898,55 @@ YY_RULE_SETUP
 
 case 14:
 YY_RULE_SETUP
-#line 225 "toke.l"
+#line 229 "toke.l"
 {
                            /* quoted fnmatch glob char, pass verbatim */
                            LEXTRACE("QUOTEDCHAR ");
                            if (!fill_args(yytext, 2, sawspace))
                                yyterminate();
-                           sawspace = FALSE;
+                           sawspace = false;
                        }
        YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 233 "toke.l"
+#line 237 "toke.l"
 {
                            /* quoted sudoers special char, strip backslash */
                            LEXTRACE("QUOTEDCHAR ");
                            if (!fill_args(yytext + 1, 1, sawspace))
                                yyterminate();
-                           sawspace = FALSE;
+                           sawspace = false;
                        }
        YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 241 "toke.l"
+#line 245 "toke.l"
 {
                            BEGIN INITIAL;
                            yyless(0);
-                           return COMMAND;
+                           LEXRETURN(COMMAND);
                        }                       /* end of command line args */
        YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 247 "toke.l"
+#line 251 "toke.l"
 {
                            LEXTRACE("ARG ");
                            if (!fill_args(yytext, yyleng, sawspace))
                                yyterminate();
-                           sawspace = FALSE;
+                           sawspace = false;
                        }                       /* a command line arg */
        YY_BREAK
 
 case 18:
 YY_RULE_SETUP
-#line 255 "toke.l"
+#line 259 "toke.l"
 {
                            char *path;
 
                            if (continued) {
                                LEXTRACE("ERROR ");
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
 
                            if ((path = parse_include(yytext)) == NULL)
@@ -1957,13 +1961,13 @@ YY_RULE_SETUP
        YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 273 "toke.l"
+#line 277 "toke.l"
 {
                            char *path;
 
                            if (continued) {
                                LEXTRACE("ERROR ");
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
 
                            if ((path = parse_include(yytext)) == NULL)
@@ -1981,14 +1985,14 @@ YY_RULE_SETUP
        YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 294 "toke.l"
+#line 298 "toke.l"
 {
                            char deftype;
                            int n;
 
                            if (continued) {
                                LEXTRACE("ERROR ");
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
 
                            for (n = 0; isblank((unsigned char)yytext[n]); n++)
@@ -2003,34 +2007,34 @@ YY_RULE_SETUP
                                case ':':
                                    yyless(n);
                                    LEXTRACE("DEFAULTS_USER ");
-                                   return DEFAULTS_USER;
+                                   LEXRETURN(DEFAULTS_USER);
                                case '>':
                                    yyless(n);
                                    LEXTRACE("DEFAULTS_RUNAS ");
-                                   return DEFAULTS_RUNAS;
+                                   LEXRETURN(DEFAULTS_RUNAS);
                                case '@':
                                    yyless(n);
                                    LEXTRACE("DEFAULTS_HOST ");
-                                   return DEFAULTS_HOST;
+                                   LEXRETURN(DEFAULTS_HOST);
                                case '!':
                                    yyless(n);
                                    LEXTRACE("DEFAULTS_CMND ");
-                                   return DEFAULTS_CMND;
+                                   LEXRETURN(DEFAULTS_CMND);
                                default:
                                    LEXTRACE("DEFAULTS ");
-                                   return DEFAULTS;
+                                   LEXRETURN(DEFAULTS);
                            }
                        }
        YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 334 "toke.l"
+#line 338 "toke.l"
 {
                            int n;
 
                            if (continued) {
                                LEXTRACE("ERROR ");
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
 
                            for (n = 0; isblank((unsigned char)yytext[n]); n++)
@@ -2038,196 +2042,196 @@ YY_RULE_SETUP
                            switch (yytext[n]) {
                                case 'H':
                                    LEXTRACE("HOSTALIAS ");
-                                   return HOSTALIAS;
+                                   LEXRETURN(HOSTALIAS);
                                case 'C':
                                    LEXTRACE("CMNDALIAS ");
-                                   return CMNDALIAS;
+                                   LEXRETURN(CMNDALIAS);
                                case 'U':
                                    LEXTRACE("USERALIAS ");
-                                   return USERALIAS;
+                                   LEXRETURN(USERALIAS);
                                case 'R':
                                    LEXTRACE("RUNASALIAS ");
-                                   return RUNASALIAS;
+                                   LEXRETURN(RUNASALIAS);
                            }
                        }
        YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 360 "toke.l"
+#line 364 "toke.l"
 {
                                /* cmnd does not require passwd for this user */
                                LEXTRACE("NOPASSWD ");
-                               return NOPASSWD;
+                               LEXRETURN(NOPASSWD);
                        }
        YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 366 "toke.l"
+#line 370 "toke.l"
 {
                                /* cmnd requires passwd for this user */
                                LEXTRACE("PASSWD ");
-                               return PASSWD;
+                               LEXRETURN(PASSWD);
                        }
        YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 372 "toke.l"
+#line 376 "toke.l"
 {
                                LEXTRACE("NOEXEC ");
-                               return NOEXEC;
+                               LEXRETURN(NOEXEC);
                        }
        YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 377 "toke.l"
+#line 381 "toke.l"
 {
                                LEXTRACE("EXEC ");
-                               return EXEC;
+                               LEXRETURN(EXEC);
                        }
        YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 382 "toke.l"
+#line 386 "toke.l"
 {
                                LEXTRACE("SETENV ");
-                               return SETENV;
+                               LEXRETURN(SETENV);
                        }
        YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 387 "toke.l"
+#line 391 "toke.l"
 {
                                LEXTRACE("NOSETENV ");
-                               return NOSETENV;
+                               LEXRETURN(NOSETENV);
                        }
        YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 392 "toke.l"
+#line 396 "toke.l"
 {
                                LEXTRACE("LOG_OUTPUT ");
-                               return LOG_OUTPUT;
+                               LEXRETURN(LOG_OUTPUT);
                        }
        YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 397 "toke.l"
+#line 401 "toke.l"
 {
                                LEXTRACE("NOLOG_OUTPUT ");
-                               return NOLOG_OUTPUT;
+                               LEXRETURN(NOLOG_OUTPUT);
                        }
        YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 402 "toke.l"
+#line 406 "toke.l"
 {
                                LEXTRACE("LOG_INPUT ");
-                               return LOG_INPUT;
+                               LEXRETURN(LOG_INPUT);
                        }
        YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 407 "toke.l"
+#line 411 "toke.l"
 {
                                LEXTRACE("NOLOG_INPUT ");
-                               return NOLOG_INPUT;
+                               LEXRETURN(NOLOG_INPUT);
                        }
        YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 412 "toke.l"
+#line 416 "toke.l"
 {
                            /* empty group or netgroup */
                            LEXTRACE("ERROR ");
-                           return ERROR;
+                           LEXRETURN(ERROR);
                        }
        YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 418 "toke.l"
+#line 422 "toke.l"
 {
                            /* netgroup */
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("NETGROUP ");
-                           return NETGROUP;
+                           LEXRETURN(NETGROUP);
                        }
        YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 426 "toke.l"
+#line 430 "toke.l"
 {
                            /* group */
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("USERGROUP ");
-                           return USERGROUP;
+                           LEXRETURN(USERGROUP);
                        }
        YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 434 "toke.l"
+#line 438 "toke.l"
 {
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("NTWKADDR ");
-                           return NTWKADDR;
+                           LEXRETURN(NTWKADDR);
                        }
        YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 441 "toke.l"
+#line 445 "toke.l"
 {
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("NTWKADDR ");
-                           return NTWKADDR;
+                           LEXRETURN(NTWKADDR);
                        }
        YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 448 "toke.l"
+#line 452 "toke.l"
 {
                            if (!ipv6_valid(yytext)) {
                                LEXTRACE("ERROR ");
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("NTWKADDR ");
-                           return NTWKADDR;
+                           LEXRETURN(NTWKADDR);
                        }
        YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 459 "toke.l"
+#line 463 "toke.l"
 {
                            if (!ipv6_valid(yytext)) {
                                LEXTRACE("ERROR ");
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("NTWKADDR ");
-                           return NTWKADDR;
+                           LEXRETURN(NTWKADDR);
                        }
        YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 470 "toke.l"
+#line 474 "toke.l"
 {
                            LEXTRACE("ALL ");
-                           return ALL;
+                           LEXRETURN(ALL);
 
                        }
        YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 476 "toke.l"
+#line 480 "toke.l"
 {
 #ifdef HAVE_SELINUX
                            LEXTRACE("ROLE ");
-                           return ROLE;
+                           LEXRETURN(ROLE);
 #else
                            goto got_alias;
 #endif
@@ -2235,11 +2239,11 @@ YY_RULE_SETUP
        YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 485 "toke.l"
+#line 489 "toke.l"
 {
 #ifdef HAVE_SELINUX
                            LEXTRACE("TYPE ");
-                           return TYPE;
+                           LEXRETURN(TYPE);
 #else
                            goto got_alias;
 #endif
@@ -2247,7 +2251,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 494 "toke.l"
+#line 498 "toke.l"
 {
 #ifndef HAVE_SELINUX
                        got_alias:
@@ -2255,23 +2259,23 @@ YY_RULE_SETUP
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("ALIAS ");
-                           return ALIAS;
+                           LEXRETURN(ALIAS);
                        }
        YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 504 "toke.l"
+#line 508 "toke.l"
 {
                            /* no command args allowed for Defaults!/path */
                            if (!fill_cmnd(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("COMMAND ");
-                           return COMMAND;
+                           LEXRETURN(COMMAND);
                        }
        YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 512 "toke.l"
+#line 516 "toke.l"
 {
                            BEGIN GOTCMND;
                            LEXTRACE("COMMAND ");
@@ -2281,14 +2285,14 @@ YY_RULE_SETUP
        YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 519 "toke.l"
+#line 523 "toke.l"
 {
                            /* directories can't have args... */
                            if (yytext[yyleng - 1] == '/') {
                                LEXTRACE("COMMAND ");
                                if (!fill_cmnd(yytext, yyleng))
                                    yyterminate();
-                               return COMMAND;
+                               LEXRETURN(COMMAND);
                            } else {
                                BEGIN GOTCMND;
                                LEXTRACE("COMMAND ");
@@ -2299,7 +2303,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 534 "toke.l"
+#line 538 "toke.l"
 {
                            LEXTRACE("BEGINSTR ");
                            yylval.string = NULL;
@@ -2309,113 +2313,113 @@ YY_RULE_SETUP
        YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 541 "toke.l"
+#line 545 "toke.l"
 {
                            /* a word */
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("WORD(5) ");
-                           return WORD;
+                           LEXRETURN(WORD);
                        }
        YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 549 "toke.l"
+#line 553 "toke.l"
 {
                            LEXTRACE("( ");
-                           return '(';
+                           LEXRETURN('(');
                        }
        YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 554 "toke.l"
+#line 558 "toke.l"
 {
                            LEXTRACE(") ");
-                           return ')';
+                           LEXRETURN(')');
                        }
        YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 559 "toke.l"
+#line 563 "toke.l"
 {
                            LEXTRACE(", ");
-                           return ',';
+                           LEXRETURN(',');
                        }                       /* return ',' */
        YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 564 "toke.l"
+#line 568 "toke.l"
 {
                            LEXTRACE("= ");
-                           return '=';
+                           LEXRETURN('=');
                        }                       /* return '=' */
        YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 569 "toke.l"
+#line 573 "toke.l"
 {
                            LEXTRACE(": ");
-                           return ':';
+                           LEXRETURN(':');
                        }                       /* return ':' */
        YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 574 "toke.l"
+#line 578 "toke.l"
 {
                            if (yyleng & 1) {
                                LEXTRACE("!");
-                               return '!';     /* return '!' */
+                               LEXRETURN('!'); /* return '!' */
                            }
                        }
        YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 581 "toke.l"
+#line 585 "toke.l"
 {
                            if (YY_START == INSTR) {
                                LEXTRACE("ERROR ");
-                               return ERROR;   /* line break in string */
+                               LEXRETURN(ERROR);       /* line break in string */
                            }
                            BEGIN INITIAL;
-                           ++sudolineno;
-                           continued = FALSE;
+                           sudolineno++;
+                           continued = false;
                            LEXTRACE("\n");
-                           return COMMENT;
+                           LEXRETURN(COMMENT);
                        }                       /* return newline */
        YY_BREAK
 case 55:
 YY_RULE_SETUP
-#line 593 "toke.l"
+#line 597 "toke.l"
 {                      /* throw away space/tabs */
-                           sawspace = TRUE;    /* but remember for fill_args */
+                           sawspace = true;    /* but remember for fill_args */
                        }
        YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 597 "toke.l"
+#line 601 "toke.l"
 {
-                           sawspace = TRUE;    /* remember for fill_args */
-                           ++sudolineno;
-                           continued = TRUE;
+                           sawspace = true;    /* remember for fill_args */
+                           sudolineno++;
+                           continued = true;
                        }                       /* throw away EOL after \ */
        YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 603 "toke.l"
+#line 607 "toke.l"
 {
                            BEGIN INITIAL;
-                           ++sudolineno;
-                           continued = FALSE;
+                           sudolineno++;
+                           continued = false;
                            LEXTRACE("#\n");
-                           return COMMENT;
+                           LEXRETURN(COMMENT);
                        }                       /* comment, not uid/gid */
        YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 611 "toke.l"
+#line 615 "toke.l"
 {
                            LEXTRACE("ERROR ");
-                           return ERROR;
+                           LEXRETURN(ERROR);
                        }       /* parse error */
        YY_BREAK
 case YY_STATE_EOF(INITIAL):
@@ -2424,12 +2428,12 @@ case YY_STATE_EOF(GOTCMND):
 case YY_STATE_EOF(STARTDEFS):
 case YY_STATE_EOF(INDEFS):
 case YY_STATE_EOF(INSTR):
-#line 616 "toke.l"
+#line 620 "toke.l"
 {
                            if (YY_START != INITIAL) {
                                BEGIN INITIAL;
                                LEXTRACE("ERROR ");
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
                            if (!pop_include())
                                yyterminate();
@@ -2437,10 +2441,10 @@ case YY_STATE_EOF(INSTR):
        YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 626 "toke.l"
+#line 630 "toke.l"
 ECHO;
        YY_BREAK
-#line 2443 "lex.yy.c"
+#line 2447 "lex.yy.c"
 
        case YY_END_OF_BUFFER:
                {
@@ -3331,7 +3335,7 @@ int main()
        return 0;
        }
 #endif
-#line 626 "toke.l"
+#line 630 "toke.l"
 
 struct path_list {
     char *path;
@@ -3343,7 +3347,7 @@ struct include_stack {
     char *path;
     struct path_list *more; /* more files in case of includedir */
     int lineno;
-    int keepopen;
+    bool keepopen;
 };
 
 static int
@@ -3365,6 +3369,7 @@ switch_dir(struct include_stack *stack, char *dirpath)
     struct stat sb;
     struct path_list *pl, *first = NULL;
     struct path_list **sorted = NULL;
+    debug_decl(switch_dir, SUDO_DEBUG_PARSER)
 
     if (!(dir = opendir(dirpath))) {
        if (errno != ENOENT) {
@@ -3435,7 +3440,7 @@ switch_dir(struct include_stack *stack, char *dirpath)
     }
 done:
     efree(dirpath);
-    return path;
+    debug_return_str(path);
 bad:
     while (first != NULL) {
        pl = first;
@@ -3446,7 +3451,7 @@ bad:
     efree(sorted);
     efree(dirpath);
     efree(path);
-    return NULL;
+    debug_return_str(NULL);
 }
 
 #define MAX_SUDOERS_DEPTH      128
@@ -3454,12 +3459,13 @@ bad:
 
 static size_t istacksize, idepth;
 static struct include_stack *istack;
-static int keepopen;
+static bool keepopen;
 
 void
 init_lexer(void)
 {
     struct path_list *pl;
+    debug_decl(init_lexer, SUDO_DEBUG_PARSER)
 
     while (idepth) {
        idepth--;
@@ -3477,48 +3483,51 @@ init_lexer(void)
     istack = NULL;
     istacksize = idepth = 0;
     sudolineno = 1;
-    keepopen = FALSE;
-    sawspace = FALSE;
-    continued = FALSE;
+    keepopen = false;
+    sawspace = false;
+    continued = false;
     prev_state = INITIAL;
+
+    debug_return;
 }
 
-static int
-_push_include(char *path, int isdir)
+static bool
+_push_include(char *path, bool isdir)
 {
     struct path_list *pl;
     FILE *fp;
+    debug_decl(_push_include, SUDO_DEBUG_PARSER)
 
     /* push current state onto stack */
     if (idepth >= istacksize) {
        if (idepth > MAX_SUDOERS_DEPTH) {
            yyerror(_("too many levels of includes"));
-           return FALSE;
+           debug_return_bool(false);
        }
        istacksize += SUDOERS_STACK_INCREMENT;
        istack = (struct include_stack *) realloc(istack,
            sizeof(*istack) * istacksize);
        if (istack == NULL) {
            yyerror(_("unable to allocate memory"));
-           return FALSE;
+           debug_return_bool(false);
        }
     }
     if (isdir) {
        if (!(path = switch_dir(&istack[idepth], path))) {
            /* switch_dir() called yyerror() for us */
-           return FALSE;
+           debug_return_bool(false);
        }
-       while ((fp = open_sudoers(path, FALSE, &keepopen)) == NULL) {
+       while ((fp = open_sudoers(path, false, &keepopen)) == NULL) {
            /* Unable to open path in includedir, go to next one, if any. */
            efree(path);
            if ((pl = istack[idepth].more) == NULL)
-               return FALSE;
+               debug_return_bool(false);
            path = pl->path;
            istack[idepth].more = pl->next;
            efree(pl);
        }
     } else {
-       if ((fp = open_sudoers(path, TRUE, &keepopen)) == NULL) {
+       if ((fp = open_sudoers(path, true, &keepopen)) == NULL) {
            char *errbuf;
            if (asprintf(&errbuf, _("%s: %s"), path, strerror(errno)) != -1) {
                yyerror(errbuf);
@@ -3526,7 +3535,7 @@ _push_include(char *path, int isdir)
            } else {
                yyerror(_("unable to allocate memory"));
            }
-           return FALSE;
+           debug_return_bool(false);
        }
        istack[idepth].more = NULL;
     }
@@ -3540,24 +3549,25 @@ _push_include(char *path, int isdir)
     sudoers = path;
     yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
 
-    return TRUE;
+    debug_return_bool(true);
 }
 
-static int
+static bool
 pop_include(void)
 {
     struct path_list *pl;
     FILE *fp;
+    debug_decl(pop_include, SUDO_DEBUG_PARSER)
 
     if (idepth == 0)
-       return FALSE;
+       debug_return_bool(false);
 
     if (!keepopen)
        fclose(YY_CURRENT_BUFFER->yy_input_file);
     yy_delete_buffer(YY_CURRENT_BUFFER);
     /* If we are in an include dir, move to the next file. */
     while ((pl = istack[idepth - 1].more) != NULL) {
-       fp = open_sudoers(pl->path, FALSE, &keepopen);
+       fp = open_sudoers(pl->path, false, &keepopen);
        if (fp != NULL) {
            istack[idepth - 1].more = pl->next;
            efree(sudoers);
@@ -3581,15 +3591,16 @@ pop_include(void)
        sudolineno = istack[idepth].lineno;
        keepopen = istack[idepth].keepopen;
     }
-    return TRUE;
+    debug_return_bool(true);
 }
 
 static char *
 parse_include(char *base)
 {
-    char *cp, *ep, *path;
-    int len = 0, subst = 0;
+    char *cp, *ep, *path, *pp;
+    int dirlen = 0, len = 0, subst = 0;
     size_t shost_len = 0;
+    debug_decl(parse_include, SUDO_DEBUG_PARSER)
 
     /* Pull out path from #include line. */
     cp = base + sizeof("#include");
@@ -3607,15 +3618,26 @@ parse_include(char *base)
        ep++;
     }
 
-    /* Make a copy of path and return it. */
+    /* Relative paths are located in the same dir as the sudoers file. */
+    if (*cp != '/') {
+       char *dirend = strrchr(sudoers, '/');
+       if (dirend != NULL)
+           dirlen = (int)(dirend - sudoers) + 1;
+    }
+
+    /* Make a copy of the fully-qualified path and return it. */
     len += (int)(ep - cp);
-    if ((path = malloc(len + 1)) == NULL) {
+    path = pp = malloc(len + dirlen + 1);
+    if (path == NULL) {
        yyerror(_("unable to allocate memory"));
-       return NULL;
+       debug_return_str(NULL);
+    }
+    if (dirlen) {
+       memcpy(path, sudoers, dirlen);
+       pp += dirlen;
     }
     if (subst) {
        /* substitute for %h */
-       char *pp = path;
        while (cp < ep) {
            if (cp[0] == '%' && cp[1] == 'h') {
                memcpy(pp, user_shost, shost_len);
@@ -3627,15 +3649,15 @@ parse_include(char *base)
        }
        *pp = '\0';
     } else {
-       memcpy(path, cp, len);
-       path[len] = '\0';
+       memcpy(pp, cp, len);
+       pp[len] = '\0';
     }
 
     /* Push any excess characters (e.g. comment, newline) back to the lexer */
     if (*ep != '\0')
        yyless((int)(ep - base));
 
-    return path;
+    debug_return_str(path);
 }
 
 #ifdef TRACELEXER
@@ -3644,4 +3666,26 @@ sudoers_trace_print(const char *msg)
 {
     return fputs(msg, stderr);
 }
+#else
+static int
+sudoers_trace_print(const char *msg)
+{
+    static bool initialized;
+    static struct lbuf lbuf;
+
+    if (!initialized) {
+       initialized = true;
+       lbuf_init(&lbuf, NULL, 0, NULL, 0);
+    }
+
+    lbuf_append(&lbuf, "%s", msg);
+    /* XXX - assumes a final newline */
+    if (strchr(msg, '\n') != NULL)
+    {
+       sudo_debug_printf2(SUDO_DEBUG_PARSER|SUDO_DEBUG_DEBUG, "%s:%d %s",
+           sudoers, sudolineno, lbuf.buf);
+       lbuf.len = 0;
+    }
+    return 0;
+}
 #endif /* TRACELEXER */
index 5e2a24a9033e6ab0c83c1c36f7a57d3470c3a9b4..aed6dc379ef247ed5785b15f030e9ae1c8db38fa 100644 (file)
 #ifndef _SUDO_TOKE_H
 #define _SUDO_TOKE_H
 
-int append(const char *, int);
-int fill_args(const char *, int, int);
-int fill_cmnd(const char *, int);
-int fill_txt(const char *, int, int);
-int ipv6_valid(const char *s);
+bool append(const char *, int);
+bool fill_args(const char *, int, int);
+bool fill_cmnd(const char *, int);
+bool fill_txt(const char *, int, int);
+bool ipv6_valid(const char *s);
 void yyerror(const char *);
 
 #ifndef FLEX_SCANNER
@@ -33,9 +33,14 @@ extern int (*trace_print)(const char *msg);
 /* realloc() to size + COMMANDARGINC to make room for command args */
 #define COMMANDARGINC   64
 
-#define LEXTRACE(msg)   do { \
-    if (trace_print != NULL) \
-        (*trace_print)(msg); \
+/*
+ * XXX - want to use debug file for lexer tracing, e.g.
+ *       sudo_debug_printf2(SUDO_DEBUG_PARSER|SUDO_DEBUG_DEBUG, "%s", msg);
+ *       but need to add buffering so that it is line oriented.
+ */
+#define LEXTRACE(msg)   do {                                           \
+    if (trace_print != NULL)                                           \
+       (*trace_print)(msg);                                            \
 } while (0);
 
 #endif /* _SUDO_TOKE_H */
index 398e1d1359431a1b801ff888ccfd0153f519d0f3..ced224876baccdc036a7e89f6d3aaa3a039f4500 100644 (file)
 #include "parse.h"
 #include "toke.h"
 #include <gram.h>
+#include "lbuf.h"
 
 extern YYSTYPE yylval;
-extern int parse_error;
+extern bool parse_error;
 int sudolineno;
+int last_token;
 char *sudoers;
 
-static int continued, prev_state, sawspace;
+static bool continued, sawspace;
+static int prev_state;
 
-static int _push_include(char *, int);
-static int pop_include(void);
+static bool _push_include(char *, bool);
+static bool pop_include(void);
 static char *parse_include(char *);
 
-#ifdef TRACELEXER
 static int sudoers_trace_print(const char *msg);
-#else
-# define sudoers_trace_print NULL
-#endif
 int (*trace_print)(const char *msg) = sudoers_trace_print;
 
-#define        push_include(_p)        (_push_include((_p), FALSE))
-#define        push_includedir(_p)     (_push_include((_p), TRUE))
+#define LEXRETURN(n)   do {    \
+       last_token = (n);       \
+       return (n);             \
+} while (0)
+
+#define        push_include(_p)        (_push_include((_p), false))
+#define        push_includedir(_p)     (_push_include((_p), true))
 %}
 
 HEX16                  [0-9A-Fa-f]{1,4}
@@ -119,7 +123,7 @@ DEFVAR                      [a-z_]+
 %%
 <GOTDEFS>[[:blank:]]*,[[:blank:]]* {
                            LEXTRACE(", ");
-                           return ',';
+                           LEXRETURN(',');
                        }                       /* return ',' */
 
 <GOTDEFS>[[:blank:]]+  BEGIN STARTDEFS;
@@ -129,29 +133,29 @@ DEFVAR                    [a-z_]+
                            LEXTRACE("DEFVAR ");
                            if (!fill(yytext, yyleng))
                                yyterminate();
-                           return DEFVAR;
+                           LEXRETURN(DEFVAR);
                        }
 
 <INDEFS>{
     ,                  {
                            BEGIN STARTDEFS;
                            LEXTRACE(", ");
-                           return ',';
+                           LEXRETURN(',');
                        }                       /* return ',' */
 
     =                  {
                            LEXTRACE("= ");
-                           return '=';
+                           LEXRETURN('=');
                        }                       /* return '=' */
 
     \+=                        {
                            LEXTRACE("+= ");
-                           return '+';
+                           LEXRETURN('+');
                        }                       /* return '+' */
 
     -=                 {
                            LEXTRACE("-= ");
-                           return '-';
+                           LEXRETURN('-');
                        }                       /* return '-' */
 
     \"                 {
@@ -165,15 +169,15 @@ DEFVAR                    [a-z_]+
                            LEXTRACE("WORD(2) ");
                            if (!fill(yytext, yyleng))
                                yyterminate();
-                           return WORD;
+                           LEXRETURN(WORD);
                        }
 }
 
 <INSTR>{
     \\[[:blank:]]*\n[[:blank:]]*       {
                            /* Line continuation char followed by newline. */
-                           ++sudolineno;
-                           continued = TRUE;
+                           sudolineno++;
+                           continued = true;
                        }
 
     \"                 {
@@ -182,7 +186,7 @@ DEFVAR                      [a-z_]+
 
                            if (yylval.string == NULL) {
                                LEXTRACE("ERROR "); /* empty string */
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
                            if (prev_state == INITIAL) {
                                switch (yylval.string[0]) {
@@ -191,21 +195,21 @@ DEFVAR                    [a-z_]+
                                        (yylval.string[1] == ':' &&
                                        yylval.string[2] == '\0')) {
                                        LEXTRACE("ERROR "); /* empty group */
-                                       return ERROR;
+                                       LEXRETURN(ERROR);
                                    }
                                    LEXTRACE("USERGROUP ");
-                                   return USERGROUP;
+                                   LEXRETURN(USERGROUP);
                                case '+':
                                    if (yylval.string[1] == '\0') {
                                        LEXTRACE("ERROR "); /* empty netgroup */
-                                       return ERROR;
+                                       LEXRETURN(ERROR);
                                    }
                                    LEXTRACE("NETGROUP ");
-                                   return NETGROUP;
+                                   LEXRETURN(NETGROUP);
                                }
                            }
                            LEXTRACE("WORD(4) ");
-                           return WORD;
+                           LEXRETURN(WORD);
                        }
 
     \\                 {
@@ -227,7 +231,7 @@ DEFVAR                      [a-z_]+
                            LEXTRACE("QUOTEDCHAR ");
                            if (!fill_args(yytext, 2, sawspace))
                                yyterminate();
-                           sawspace = FALSE;
+                           sawspace = false;
                        }
 
     \\[:\\,= \t#]      {
@@ -235,29 +239,29 @@ DEFVAR                    [a-z_]+
                            LEXTRACE("QUOTEDCHAR ");
                            if (!fill_args(yytext + 1, 1, sawspace))
                                yyterminate();
-                           sawspace = FALSE;
+                           sawspace = false;
                        }
 
     [#:\,=\n]          {
                            BEGIN INITIAL;
                            yyless(0);
-                           return COMMAND;
+                           LEXRETURN(COMMAND);
                        }                       /* end of command line args */
 
     [^#\\:, \t\n]+     {
                            LEXTRACE("ARG ");
                            if (!fill_args(yytext, yyleng, sawspace))
                                yyterminate();
-                           sawspace = FALSE;
+                           sawspace = false;
                        }                       /* a command line arg */
 }
 
-<INITIAL>^#include[[:blank:]]+\/.*\n {
+<INITIAL>^#include[[:blank:]]+.*\n {
                            char *path;
 
                            if (continued) {
                                LEXTRACE("ERROR ");
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
 
                            if ((path = parse_include(yytext)) == NULL)
@@ -270,12 +274,12 @@ DEFVAR                    [a-z_]+
                                yyterminate();
                        }
 
-<INITIAL>^#includedir[[:blank:]]+\/.*\n {
+<INITIAL>^#includedir[[:blank:]]+.*\n {
                            char *path;
 
                            if (continued) {
                                LEXTRACE("ERROR ");
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
 
                            if ((path = parse_include(yytext)) == NULL)
@@ -297,7 +301,7 @@ DEFVAR                      [a-z_]+
 
                            if (continued) {
                                LEXTRACE("ERROR ");
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
 
                            for (n = 0; isblank((unsigned char)yytext[n]); n++)
@@ -312,22 +316,22 @@ DEFVAR                    [a-z_]+
                                case ':':
                                    yyless(n);
                                    LEXTRACE("DEFAULTS_USER ");
-                                   return DEFAULTS_USER;
+                                   LEXRETURN(DEFAULTS_USER);
                                case '>':
                                    yyless(n);
                                    LEXTRACE("DEFAULTS_RUNAS ");
-                                   return DEFAULTS_RUNAS;
+                                   LEXRETURN(DEFAULTS_RUNAS);
                                case '@':
                                    yyless(n);
                                    LEXTRACE("DEFAULTS_HOST ");
-                                   return DEFAULTS_HOST;
+                                   LEXRETURN(DEFAULTS_HOST);
                                case '!':
                                    yyless(n);
                                    LEXTRACE("DEFAULTS_CMND ");
-                                   return DEFAULTS_CMND;
+                                   LEXRETURN(DEFAULTS_CMND);
                                default:
                                    LEXTRACE("DEFAULTS ");
-                                   return DEFAULTS;
+                                   LEXRETURN(DEFAULTS);
                            }
                        }
 
@@ -336,7 +340,7 @@ DEFVAR                      [a-z_]+
 
                            if (continued) {
                                LEXTRACE("ERROR ");
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
 
                            for (n = 0; isblank((unsigned char)yytext[n]); n++)
@@ -344,75 +348,75 @@ DEFVAR                    [a-z_]+
                            switch (yytext[n]) {
                                case 'H':
                                    LEXTRACE("HOSTALIAS ");
-                                   return HOSTALIAS;
+                                   LEXRETURN(HOSTALIAS);
                                case 'C':
                                    LEXTRACE("CMNDALIAS ");
-                                   return CMNDALIAS;
+                                   LEXRETURN(CMNDALIAS);
                                case 'U':
                                    LEXTRACE("USERALIAS ");
-                                   return USERALIAS;
+                                   LEXRETURN(USERALIAS);
                                case 'R':
                                    LEXTRACE("RUNASALIAS ");
-                                   return RUNASALIAS;
+                                   LEXRETURN(RUNASALIAS);
                            }
                        }
 
 NOPASSWD[[:blank:]]*:  {
                                /* cmnd does not require passwd for this user */
                                LEXTRACE("NOPASSWD ");
-                               return NOPASSWD;
+                               LEXRETURN(NOPASSWD);
                        }
 
 PASSWD[[:blank:]]*:    {
                                /* cmnd requires passwd for this user */
                                LEXTRACE("PASSWD ");
-                               return PASSWD;
+                               LEXRETURN(PASSWD);
                        }
 
 NOEXEC[[:blank:]]*:    {
                                LEXTRACE("NOEXEC ");
-                               return NOEXEC;
+                               LEXRETURN(NOEXEC);
                        }
 
 EXEC[[:blank:]]*:      {
                                LEXTRACE("EXEC ");
-                               return EXEC;
+                               LEXRETURN(EXEC);
                        }
 
 SETENV[[:blank:]]*:    {
                                LEXTRACE("SETENV ");
-                               return SETENV;
+                               LEXRETURN(SETENV);
                        }
 
 NOSETENV[[:blank:]]*:  {
                                LEXTRACE("NOSETENV ");
-                               return NOSETENV;
+                               LEXRETURN(NOSETENV);
                        }
 
 LOG_OUTPUT[[:blank:]]*:        {
                                LEXTRACE("LOG_OUTPUT ");
-                               return LOG_OUTPUT;
+                               LEXRETURN(LOG_OUTPUT);
                        }
 
 NOLOG_OUTPUT[[:blank:]]*:      {
                                LEXTRACE("NOLOG_OUTPUT ");
-                               return NOLOG_OUTPUT;
+                               LEXRETURN(NOLOG_OUTPUT);
                        }
 
 LOG_INPUT[[:blank:]]*: {
                                LEXTRACE("LOG_INPUT ");
-                               return LOG_INPUT;
+                               LEXRETURN(LOG_INPUT);
                        }
 
 NOLOG_INPUT[[:blank:]]*:       {
                                LEXTRACE("NOLOG_INPUT ");
-                               return NOLOG_INPUT;
+                               LEXRETURN(NOLOG_INPUT);
                        }
 
 <INITIAL,GOTDEFS>(\+|\%|\%:) {
                            /* empty group or netgroup */
                            LEXTRACE("ERROR ");
-                           return ERROR;
+                           LEXRETURN(ERROR);
                        }
 
 \+{WORD}               {
@@ -420,7 +424,7 @@ NOLOG_INPUT[[:blank:]]*:    {
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("NETGROUP ");
-                           return NETGROUP;
+                           LEXRETURN(NETGROUP);
                        }
 
 \%:?({WORD}|{ID})      {
@@ -428,55 +432,55 @@ NOLOG_INPUT[[:blank:]]*:  {
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("USERGROUP ");
-                           return USERGROUP;
+                           LEXRETURN(USERGROUP);
                        }
 
 {IPV4ADDR}(\/{IPV4ADDR})? {
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("NTWKADDR ");
-                           return NTWKADDR;
+                           LEXRETURN(NTWKADDR);
                        }
 
 {IPV4ADDR}\/([12]?[0-9]|3[0-2]) {
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("NTWKADDR ");
-                           return NTWKADDR;
+                           LEXRETURN(NTWKADDR);
                        }
 
 {IPV6ADDR}(\/{IPV6ADDR})? {
                            if (!ipv6_valid(yytext)) {
                                LEXTRACE("ERROR ");
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("NTWKADDR ");
-                           return NTWKADDR;
+                           LEXRETURN(NTWKADDR);
                        }
 
 {IPV6ADDR}\/([0-9]|[1-9][0-9]|1[01][0-9]|12[0-8]) {
                            if (!ipv6_valid(yytext)) {
                                LEXTRACE("ERROR ");
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("NTWKADDR ");
-                           return NTWKADDR;
+                           LEXRETURN(NTWKADDR);
                        }
 
 ALL {
                            LEXTRACE("ALL ");
-                           return ALL;
+                           LEXRETURN(ALL);
 
                        }
 
 <INITIAL>ROLE {
 #ifdef HAVE_SELINUX
                            LEXTRACE("ROLE ");
-                           return ROLE;
+                           LEXRETURN(ROLE);
 #else
                            goto got_alias;
 #endif
@@ -485,7 +489,7 @@ ALL {
 <INITIAL>TYPE {
 #ifdef HAVE_SELINUX
                            LEXTRACE("TYPE ");
-                           return TYPE;
+                           LEXRETURN(TYPE);
 #else
                            goto got_alias;
 #endif
@@ -498,7 +502,7 @@ ALL {
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("ALIAS ");
-                           return ALIAS;
+                           LEXRETURN(ALIAS);
                        }
 
 <GOTDEFS>({PATH}|sudoedit) {
@@ -506,7 +510,7 @@ ALL {
                            if (!fill_cmnd(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("COMMAND ");
-                           return COMMAND;
+                           LEXRETURN(COMMAND);
                        }
 
 sudoedit               {
@@ -522,7 +526,7 @@ sudoedit            {
                                LEXTRACE("COMMAND ");
                                if (!fill_cmnd(yytext, yyleng))
                                    yyterminate();
-                               return COMMAND;
+                               LEXRETURN(COMMAND);
                            } else {
                                BEGIN GOTCMND;
                                LEXTRACE("COMMAND ");
@@ -543,81 +547,81 @@ sudoedit          {
                            if (!fill(yytext, yyleng))
                                yyterminate();
                            LEXTRACE("WORD(5) ");
-                           return WORD;
+                           LEXRETURN(WORD);
                        }
 
 \(                     {
                            LEXTRACE("( ");
-                           return '(';
+                           LEXRETURN('(');
                        }
 
 \)                     {
                            LEXTRACE(") ");
-                           return ')';
+                           LEXRETURN(')');
                        }
 
 ,                      {
                            LEXTRACE(", ");
-                           return ',';
+                           LEXRETURN(',');
                        }                       /* return ',' */
 
 =                      {
                            LEXTRACE("= ");
-                           return '=';
+                           LEXRETURN('=');
                        }                       /* return '=' */
 
 :                      {
                            LEXTRACE(": ");
-                           return ':';
+                           LEXRETURN(':');
                        }                       /* return ':' */
 
 <*>!+                  {
                            if (yyleng & 1) {
                                LEXTRACE("!");
-                               return '!';     /* return '!' */
+                               LEXRETURN('!'); /* return '!' */
                            }
                        }
 
 <*>\n                  {
                            if (YY_START == INSTR) {
                                LEXTRACE("ERROR ");
-                               return ERROR;   /* line break in string */
+                               LEXRETURN(ERROR);       /* line break in string */
                            }
                            BEGIN INITIAL;
-                           ++sudolineno;
-                           continued = FALSE;
+                           sudolineno++;
+                           continued = false;
                            LEXTRACE("\n");
-                           return COMMENT;
+                           LEXRETURN(COMMENT);
                        }                       /* return newline */
 
 <*>[[:blank:]]+                {                       /* throw away space/tabs */
-                           sawspace = TRUE;    /* but remember for fill_args */
+                           sawspace = true;    /* but remember for fill_args */
                        }
 
 <*>\\[[:blank:]]*\n    {
-                           sawspace = TRUE;    /* remember for fill_args */
-                           ++sudolineno;
-                           continued = TRUE;
+                           sawspace = true;    /* remember for fill_args */
+                           sudolineno++;
+                           continued = true;
                        }                       /* throw away EOL after \ */
 
 <INITIAL,STARTDEFS,INDEFS>#(-[^\n0-9].*|[^\n0-9-].*)?\n        {
                            BEGIN INITIAL;
-                           ++sudolineno;
-                           continued = FALSE;
+                           sudolineno++;
+                           continued = false;
                            LEXTRACE("#\n");
-                           return COMMENT;
+                           LEXRETURN(COMMENT);
                        }                       /* comment, not uid/gid */
 
 <*>.                   {
                            LEXTRACE("ERROR ");
-                           return ERROR;
+                           LEXRETURN(ERROR);
                        }       /* parse error */
 
 <*><<EOF>>             {
                            if (YY_START != INITIAL) {
                                BEGIN INITIAL;
                                LEXTRACE("ERROR ");
-                               return ERROR;
+                               LEXRETURN(ERROR);
                            }
                            if (!pop_include())
                                yyterminate();
@@ -634,7 +638,7 @@ struct include_stack {
     char *path;
     struct path_list *more; /* more files in case of includedir */
     int lineno;
-    int keepopen;
+    bool keepopen;
 };
 
 static int
@@ -656,6 +660,7 @@ switch_dir(struct include_stack *stack, char *dirpath)
     struct stat sb;
     struct path_list *pl, *first = NULL;
     struct path_list **sorted = NULL;
+    debug_decl(switch_dir, SUDO_DEBUG_PARSER)
 
     if (!(dir = opendir(dirpath))) {
        if (errno != ENOENT) {
@@ -726,7 +731,7 @@ switch_dir(struct include_stack *stack, char *dirpath)
     }
 done:
     efree(dirpath);
-    return path;
+    debug_return_str(path);
 bad:
     while (first != NULL) {
        pl = first;
@@ -737,7 +742,7 @@ bad:
     efree(sorted);
     efree(dirpath);
     efree(path);
-    return NULL;
+    debug_return_str(NULL);
 }
 
 #define MAX_SUDOERS_DEPTH      128
@@ -745,12 +750,13 @@ bad:
 
 static size_t istacksize, idepth;
 static struct include_stack *istack;
-static int keepopen;
+static bool keepopen;
 
 void
 init_lexer(void)
 {
     struct path_list *pl;
+    debug_decl(init_lexer, SUDO_DEBUG_PARSER)
 
     while (idepth) {
        idepth--;
@@ -768,48 +774,51 @@ init_lexer(void)
     istack = NULL;
     istacksize = idepth = 0;
     sudolineno = 1;
-    keepopen = FALSE;
-    sawspace = FALSE;
-    continued = FALSE;
+    keepopen = false;
+    sawspace = false;
+    continued = false;
     prev_state = INITIAL;
+
+    debug_return;
 }
 
-static int
-_push_include(char *path, int isdir)
+static bool
+_push_include(char *path, bool isdir)
 {
     struct path_list *pl;
     FILE *fp;
+    debug_decl(_push_include, SUDO_DEBUG_PARSER)
 
     /* push current state onto stack */
     if (idepth >= istacksize) {
        if (idepth > MAX_SUDOERS_DEPTH) {
            yyerror(_("too many levels of includes"));
-           return FALSE;
+           debug_return_bool(false);
        }
        istacksize += SUDOERS_STACK_INCREMENT;
        istack = (struct include_stack *) realloc(istack,
            sizeof(*istack) * istacksize);
        if (istack == NULL) {
            yyerror(_("unable to allocate memory"));
-           return FALSE;
+           debug_return_bool(false);
        }
     }
     if (isdir) {
        if (!(path = switch_dir(&istack[idepth], path))) {
            /* switch_dir() called yyerror() for us */
-           return FALSE;
+           debug_return_bool(false);
        }
-       while ((fp = open_sudoers(path, FALSE, &keepopen)) == NULL) {
+       while ((fp = open_sudoers(path, false, &keepopen)) == NULL) {
            /* Unable to open path in includedir, go to next one, if any. */
            efree(path);
            if ((pl = istack[idepth].more) == NULL)
-               return FALSE;
+               debug_return_bool(false);
            path = pl->path;
            istack[idepth].more = pl->next;
            efree(pl);
        }
     } else {
-       if ((fp = open_sudoers(path, TRUE, &keepopen)) == NULL) {
+       if ((fp = open_sudoers(path, true, &keepopen)) == NULL) {
            char *errbuf;
            if (asprintf(&errbuf, _("%s: %s"), path, strerror(errno)) != -1) {
                yyerror(errbuf);
@@ -817,7 +826,7 @@ _push_include(char *path, int isdir)
            } else {
                yyerror(_("unable to allocate memory"));
            }
-           return FALSE;
+           debug_return_bool(false);
        }
        istack[idepth].more = NULL;
     }
@@ -831,24 +840,25 @@ _push_include(char *path, int isdir)
     sudoers = path;
     yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
 
-    return TRUE;
+    debug_return_bool(true);
 }
 
-static int
+static bool
 pop_include(void)
 {
     struct path_list *pl;
     FILE *fp;
+    debug_decl(pop_include, SUDO_DEBUG_PARSER)
 
     if (idepth == 0)
-       return FALSE;
+       debug_return_bool(false);
 
     if (!keepopen)
        fclose(YY_CURRENT_BUFFER->yy_input_file);
     yy_delete_buffer(YY_CURRENT_BUFFER);
     /* If we are in an include dir, move to the next file. */
     while ((pl = istack[idepth - 1].more) != NULL) {
-       fp = open_sudoers(pl->path, FALSE, &keepopen);
+       fp = open_sudoers(pl->path, false, &keepopen);
        if (fp != NULL) {
            istack[idepth - 1].more = pl->next;
            efree(sudoers);
@@ -872,15 +882,16 @@ pop_include(void)
        sudolineno = istack[idepth].lineno;
        keepopen = istack[idepth].keepopen;
     }
-    return TRUE;
+    debug_return_bool(true);
 }
 
 static char *
 parse_include(char *base)
 {
-    char *cp, *ep, *path;
-    int len = 0, subst = 0;
+    char *cp, *ep, *path, *pp;
+    int dirlen = 0, len = 0, subst = 0;
     size_t shost_len = 0;
+    debug_decl(parse_include, SUDO_DEBUG_PARSER)
 
     /* Pull out path from #include line. */
     cp = base + sizeof("#include");
@@ -898,15 +909,26 @@ parse_include(char *base)
        ep++;
     }
 
-    /* Make a copy of path and return it. */
+    /* Relative paths are located in the same dir as the sudoers file. */
+    if (*cp != '/') {
+       char *dirend = strrchr(sudoers, '/');
+       if (dirend != NULL)
+           dirlen = (int)(dirend - sudoers) + 1;
+    }
+
+    /* Make a copy of the fully-qualified path and return it. */
     len += (int)(ep - cp);
-    if ((path = malloc(len + 1)) == NULL) {
+    path = pp = malloc(len + dirlen + 1);
+    if (path == NULL) {
        yyerror(_("unable to allocate memory"));
-       return NULL;
+       debug_return_str(NULL);
+    }
+    if (dirlen) {
+       memcpy(path, sudoers, dirlen);
+       pp += dirlen;
     }
     if (subst) {
        /* substitute for %h */
-       char *pp = path;
        while (cp < ep) {
            if (cp[0] == '%' && cp[1] == 'h') {
                memcpy(pp, user_shost, shost_len);
@@ -918,15 +940,15 @@ parse_include(char *base)
        }
        *pp = '\0';
     } else {
-       memcpy(path, cp, len);
-       path[len] = '\0';
+       memcpy(pp, cp, len);
+       pp[len] = '\0';
     }
 
     /* Push any excess characters (e.g. comment, newline) back to the lexer */
     if (*ep != '\0')
        yyless((int)(ep - base));
 
-    return path;
+    debug_return_str(path);
 }
 
 #ifdef TRACELEXER
@@ -935,4 +957,26 @@ sudoers_trace_print(const char *msg)
 {
     return fputs(msg, stderr);
 }
+#else
+static int
+sudoers_trace_print(const char *msg)
+{
+    static bool initialized;
+    static struct lbuf lbuf;
+
+    if (!initialized) {
+       initialized = true;
+       lbuf_init(&lbuf, NULL, 0, NULL, 0);
+    }
+
+    lbuf_append(&lbuf, "%s", msg);
+    /* XXX - assumes a final newline */
+    if (strchr(msg, '\n') != NULL)
+    {
+       sudo_debug_printf2(SUDO_DEBUG_PARSER|SUDO_DEBUG_DEBUG, "%s:%d %s",
+           sudoers, sudolineno, lbuf.buf);
+       lbuf.len = 0;
+    }
+    return 0;
+}
 #endif /* TRACELEXER */
index 9254c4571f4ded96b50183e6438d843bc72d6b64..330279452ed003ca463e1bdca4c70a5ff00d2f10 100644 (file)
@@ -48,6 +48,7 @@
 # include <malloc.h>
 #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
 #include <ctype.h>
+
 #include "sudoers.h"
 #include "parse.h"
 #include "toke.h"
 static int arg_len = 0;
 static int arg_size = 0;
 
-static unsigned char
+static int
 hexchar(const char *s)
 {
-    int i;
-    int result = 0;
+    int i, result = 0;
+    debug_decl(hexchar, SUDO_DEBUG_PARSER)
 
     s += 2; /* skip \\x */
     for (i = 0; i < 2; i++) {
@@ -98,18 +99,19 @@ hexchar(const char *s)
            s++;
        }
     }
-    return (unsigned char)result;
+    debug_return_int(result);
 }
 
-int
+bool
 fill_txt(const char *src, int len, int olen)
 {
     char *dst;
+    debug_decl(fill_txt, SUDO_DEBUG_PARSER)
 
     dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1);
     if (dst == NULL) {
        yyerror(_("unable to allocate memory"));
-       return FALSE;
+       debug_return_bool(false);
     }
     yylval.string = dst;
 
@@ -133,35 +135,37 @@ fill_txt(const char *src, int len, int olen)
        }
     }
     *dst = '\0';
-    return TRUE;
+    debug_return_bool(true);
 }
 
-int
+bool
 append(const char *src, int len)
 {
     int olen = 0;
+    debug_decl(append, SUDO_DEBUG_PARSER)
 
     if (yylval.string != NULL)
        olen = strlen(yylval.string);
 
-    return fill_txt(src, len, olen);
+    debug_return_bool(fill_txt(src, len, olen));
 }
 
 #define SPECIAL(c) \
     ((c) == ',' || (c) == ':' || (c) == '=' || (c) == ' ' || (c) == '\t' || (c) == '#')
 
-int
+bool
 fill_cmnd(const char *src, int len)
 {
     char *dst;
     int i;
+    debug_decl(fill_cmnd, SUDO_DEBUG_PARSER)
 
     arg_len = arg_size = 0;
 
     dst = yylval.command.cmnd = (char *) malloc(len + 1);
     if (yylval.command.cmnd == NULL) {
        yyerror(_("unable to allocate memory"));
-       return FALSE;
+       debug_return_bool(false);
     }
 
     /* Copy the string and collapse any escaped sudo-specific characters. */
@@ -174,14 +178,15 @@ fill_cmnd(const char *src, int len)
     *dst = '\0';
 
     yylval.command.args = NULL;
-    return TRUE;
+    debug_return_bool(true);
 }
 
-int
+bool
 fill_args(const char *s, int len, int addspace)
 {
     int new_len;
     char *p;
+    debug_decl(fill_args, SUDO_DEBUG_PARSER)
 
     if (yylval.command.args == NULL) {
        addspace = 0;
@@ -200,7 +205,7 @@ fill_args(const char *s, int len, int addspace)
        if (p == NULL) {
            efree(yylval.command.args);
            yyerror(_("unable to allocate memory"));
-           return FALSE;
+           debug_return_bool(false);
        } else
            yylval.command.args = p;
     }
@@ -211,21 +216,22 @@ fill_args(const char *s, int len, int addspace)
        *p++ = ' ';
     if (strlcpy(p, s, arg_size - (p - yylval.command.args)) != len) {
        yyerror(_("fill_args: buffer overflow"));       /* paranoia */
-       return FALSE;
+       debug_return_bool(false);
     }
     arg_len = new_len;
-    return TRUE;
+    debug_return_bool(true);
 }
 
 /*
  * Check to make sure an IPv6 address does not contain multiple instances
  * of the string "::".  Assumes strlen(s) >= 1.
- * Returns TRUE if address is valid else FALSE.
+ * Returns true if address is valid else false.
  */
-int
+bool
 ipv6_valid(const char *s)
 {
     int nmatch = 0;
+    debug_decl(ipv6_valid, SUDO_DEBUG_PARSER)
 
     for (; *s != '\0'; s++) {
        if (s[0] == ':' && s[1] == ':') {
@@ -236,5 +242,5 @@ ipv6_valid(const char *s)
            nmatch = 0;                 /* reset if we hit netmask */
     }
 
-    return nmatch <= 1;
+    debug_return_bool(nmatch <= 1);
 }
index e37f6d50fc14cdaf82bd2909bc84eba7e5f9a333..72cd5bfd921035043e96918475d041ef59cabac4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1998-2005, 2007-2011
+ * Copyright (c) 1996, 1998-2005, 2007-2012
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -81,6 +81,7 @@
 #include "redblack.h"
 #include "gettext.h"
 #include "sudoers_version.h"
+#include "sudo_conf.h"
 #include <gram.h>
 
 struct sudoersfile {
@@ -93,6 +94,8 @@ struct sudoersfile {
 };
 TQ_DECLARE(sudoersfile)
 
+sudo_conv_t sudo_conv; /* NULL in non-plugin */
+
 /*
  * Function prototypes
  */
@@ -100,13 +103,13 @@ static void quit(int);
 static char *get_args(char *);
 static char *get_editor(char **);
 static void get_hostname(void);
-static char whatnow(void);
-static int check_aliases(int, int);
-static int check_syntax(char *, int, int);
-static int edit_sudoers(struct sudoersfile *, char *, char *, int);
-static int install_sudoers(struct sudoersfile *, int);
+static int whatnow(void);
+static int check_aliases(bool, bool);
+static bool check_syntax(char *, bool, bool, bool);
+static bool edit_sudoers(struct sudoersfile *, char *, char *, int);
+static bool install_sudoers(struct sudoersfile *, bool);
 static int print_unused(void *, void *);
-static int reparse_sudoers(char *, char *, int, int);
+static void reparse_sudoers(char *, char *, bool, bool);
 static int run_command(char *, char **);
 static int visudo_printf(int msg_type, const char *fmt, ...);
 static void setup_signals(void);
@@ -124,7 +127,8 @@ extern void yyrestart(FILE *);
 extern struct rbtree *aliases;
 extern FILE *yyin;
 extern char *sudoers, *errorfile;
-extern int errorlineno, parse_error;
+extern int errorlineno;
+extern bool parse_error;
 /* For getopt(3) */
 extern char *optarg;
 extern int optind;
@@ -138,16 +142,22 @@ struct passwd *list_pw;
 sudo_printf_t sudo_printf = visudo_printf;
 static struct sudoersfile_list sudoerslist;
 static struct rbtree *alias_freelist;
+static bool checkonly;
 
 int
 main(int argc, char *argv[])
 {
     struct sudoersfile *sp;
     char *args, *editor, *sudoers_path;
-    int ch, checkonly, quiet, strict, oldperms;
+    int ch, exitcode = 0;
+    bool quiet, strict, oldperms;
+    debug_decl(main, SUDO_DEBUG_MAIN)
+
 #if defined(SUDO_DEVEL) && defined(__OpenBSD__)
-    extern char *malloc_options;
-    malloc_options = "AFGJPR";
+    {
+       extern char *malloc_options;
+       malloc_options = "AFGJPR";
+    }
 #endif
 
 #if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
@@ -163,23 +173,26 @@ main(int argc, char *argv[])
     if (argc < 1)
        usage(1);
 
+    /* Read sudo.conf. */
+    sudo_conf_read();
+
     /*
      * Arg handling.
      */
-    checkonly = oldperms = quiet = strict = FALSE;
+    checkonly = oldperms = quiet = strict = false;
     sudoers_path = _PATH_SUDOERS;
     while ((ch = getopt(argc, argv, "Vcf:sq")) != -1) {
        switch (ch) {
            case 'V':
                (void) printf(_("%s version %s\n"), getprogname(), PACKAGE_VERSION);
                (void) printf(_("%s grammar version %d\n"), getprogname(), SUDOERS_GRAMMAR_VERSION);
-               exit(0);
+               goto done;
            case 'c':
                checkonly++;            /* check mode */
                break;
            case 'f':
                sudoers_path = optarg;  /* sudoers file path */
-               oldperms = TRUE;
+               oldperms = true;
                break;
            case 'h':
                help();
@@ -211,14 +224,16 @@ main(int argc, char *argv[])
     /* Setup defaults data structures. */
     init_defaults();
 
-    if (checkonly)
-       exit(check_syntax(sudoers_path, quiet, strict));
+    if (checkonly) {
+       exitcode = check_syntax(sudoers_path, quiet, strict, oldperms) ? 0 : 1;
+       goto done;
+    }
 
     /*
      * 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, TRUE, NULL)) == NULL) {
+    if ((yyin = open_sudoers(sudoers_path, true, NULL)) == NULL) {
        error(1, "%s", sudoers_path);
     }
     init_parser(sudoers_path, 0);
@@ -245,15 +260,14 @@ main(int argc, char *argv[])
     /* Check edited files for a parse error and re-edit any that fail. */
     reparse_sudoers(editor, args, strict, quiet);
 
-    /* Install the sudoers temp files. */
+    /* Install the sudoers temp files as needed. */
     tq_foreach_fwd(&sudoerslist, sp) {
-       if (!sp->modified)
-           (void) unlink(sp->tpath);
-       else
-           (void) install_sudoers(sp, oldperms);
+       (void) install_sudoers(sp, oldperms);
     }
 
-    exit(0);
+done:
+    sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);                
+    exit(exitcode);
 }
 
 /*
@@ -282,13 +296,13 @@ static char *lineno_editors[] = {
 
 /*
  * Edit each sudoers file.
- * Returns TRUE on success, else FALSE.
+ * Returns true on success, else false.
  */
-static int
+static bool
 edit_sudoers(struct sudoersfile *sp, char *editor, char *args, int lineno)
 {
     int tfd;                           /* sudoers temp file descriptor */
-    int modified;                      /* was the file modified? */
+    bool modified;                     /* was the file modified? */
     int ac;                            /* argument count */
     char **av;                         /* argument vector for run_command */
     char *cp;                          /* scratch char pointer */
@@ -299,6 +313,8 @@ edit_sudoers(struct sudoersfile *sp, char *editor, char *args, int lineno)
     off_t orig_size;                   /* starting size of sudoers file */
     ssize_t nread;                     /* number of bytes read */
     struct stat sb;                    /* stat buffer */
+    bool rval = false;                 /* return value */
+    debug_decl(edit_sudoers, SUDO_DEBUG_UTIL)
 
     if (fstat(sp->fd, &sb) == -1)
        error(1, _("unable to stat %s"), sp->path);
@@ -361,14 +377,14 @@ edit_sudoers(struct sudoersfile *sp, char *editor, char *args, int lineno)
     /* Find the length of the argument vector */
     ac = 3 + (lineno > 0);
     if (args) {
-        int wasblank;
+        bool wasblank;
 
         ac++;
-        for (wasblank = FALSE, cp = args; *cp; cp++) {
+        for (wasblank = false, cp = args; *cp; cp++) {
             if (isblank((unsigned char) *cp))
-                wasblank = TRUE;
+                wasblank = true;
             else if (wasblank) {
-                wasblank = FALSE;
+                wasblank = false;
                 ac++;
             }
         }
@@ -407,21 +423,21 @@ edit_sudoers(struct sudoersfile *sp, char *editor, char *args, int lineno)
        if (stat(sp->tpath, &sb) < 0) {
            warningx(_("unable to stat temporary file (%s), %s unchanged"),
                sp->tpath, sp->path);
-           return FALSE;
+           goto done;
        }
        if (sb.st_size == 0 && orig_size != 0) {
            warningx(_("zero length temporary file (%s), %s unchanged"),
                sp->tpath, sp->path);
-           sp->modified = TRUE;
-           return FALSE;
+           sp->modified = true;
+           goto done;
        }
     } else {
        warningx(_("editor (%s) failed, %s unchanged"), editor, sp->path);
-       return FALSE;
+       goto done;
     }
 
     /* Set modified bit if use changed the file. */
-    modified = TRUE;
+    modified = true;
     mtim_get(&sb, &tv);
     if (orig_size == sb.st_size && timevalcmp(&orig_mtim, &tv, ==)) {
        /*
@@ -430,7 +446,7 @@ edit_sudoers(struct sudoersfile *sp, char *editor, char *args, int lineno)
         */
        timevalsub(&tv1, &tv2);
        if (timevalisset(&tv2))
-           modified = FALSE;
+           modified = false;
     }
 
     /*
@@ -441,19 +457,21 @@ edit_sudoers(struct sudoersfile *sp, char *editor, char *args, int lineno)
     else
        warningx(_("%s unchanged"), sp->tpath);
 
-    return TRUE;
+    rval = true;
+done:
+    debug_return_bool(rval);
 }
 
 /*
  * Parse sudoers after editing and re-edit any ones that caused a parse error.
- * Returns TRUE on success, else FALSE.
  */
-static int
-reparse_sudoers(char *editor, char *args, int strict, int quiet)
+static void
+reparse_sudoers(char *editor, char *args, bool strict, bool quiet)
 {
     struct sudoersfile *sp, *last;
     FILE *fp;
     int ch;
+    debug_decl(reparse_sudoers, SUDO_DEBUG_UTIL)
 
     /*
      * Parse the edited sudoers files and do sanity checking
@@ -475,14 +493,14 @@ reparse_sudoers(char *editor, char *args, int strict, int quiet)
        if (yyparse() && !parse_error) {
            warningx(_("unabled to parse temporary file (%s), unknown error"),
                sp->tpath);
-           parse_error = TRUE;
+           parse_error = true;
            errorfile = sp->path;
        }
        fclose(yyin);
        if (!parse_error) {
            if (!update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER) ||
                check_aliases(strict, quiet) != 0) {
-               parse_error = TRUE;
+               parse_error = true;
                errorfile = sp->path;
            }
        }
@@ -492,9 +510,12 @@ reparse_sudoers(char *editor, char *args, int strict, int quiet)
         */
        if (parse_error) {
            switch (whatnow()) {
-               case 'Q' :      parse_error = FALSE;    /* ignore parse error */
+               case 'Q' :      parse_error = false;    /* ignore parse error */
                                break;
-               case 'x' :      cleanup(0);
+               case 'x' :      /* XXX - should return instead of exiting */
+                               cleanup(0);
+                               sudo_debug_exit_int(__func__, __FILE__,
+                                   __LINE__, sudo_debug_subsys, 0);
                                exit(0);
                                break;
            }
@@ -522,17 +543,34 @@ reparse_sudoers(char *editor, char *args, int strict, int quiet)
        }
     } while (parse_error);
 
-    return TRUE;
+    debug_return;
 }
 
 /*
  * Set the owner and mode on a sudoers temp file and
- * move it into place.  Returns TRUE on success, else FALSE.
+ * move it into place.  Returns true on success, else false.
  */
-static int
-install_sudoers(struct sudoersfile *sp, int oldperms)
+static bool
+install_sudoers(struct sudoersfile *sp, bool oldperms)
 {
     struct stat sb;
+    bool rval = false;
+    debug_decl(install_sudoers, SUDO_DEBUG_UTIL)
+
+    if (!sp->modified) {
+       /*
+        * No changes but fix owner/mode if needed.
+        */
+       (void) unlink(sp->tpath);
+       if (!oldperms && fstat(sp->fd, &sb) != -1) {
+           if (sb.st_uid != SUDOERS_UID || sb.st_gid != SUDOERS_GID)
+               (void) chown(sp->path, SUDOERS_UID, SUDOERS_GID);
+           if ((sb.st_mode & 0777) != SUDOERS_MODE)
+               (void) chmod(sp->path, SUDOERS_MODE);
+       }
+       rval = true;
+       goto done;
+    }
 
     /*
      * Change mode and ownership of temp file so when
@@ -554,12 +592,12 @@ install_sudoers(struct sudoersfile *sp, int oldperms)
        if (chown(sp->tpath, SUDOERS_UID, SUDOERS_GID) != 0) {
            warning(_("unable to set (uid, gid) of %s to (%u, %u)"),
                sp->tpath, SUDOERS_UID, SUDOERS_GID);
-           return FALSE;
+           goto done;
        }
        if (chmod(sp->tpath, SUDOERS_MODE) != 0) {
            warning(_("unable to change mode of %s to 0%o"), sp->tpath,
                SUDOERS_MODE);
-           return FALSE;
+           goto done;
        }
     }
 
@@ -593,17 +631,19 @@ install_sudoers(struct sudoersfile *sp, int oldperms)
                (void) unlink(sp->tpath);
                efree(sp->tpath);
                sp->tpath = NULL;
-               return FALSE;
+               goto done;
            }
            efree(sp->tpath);
            sp->tpath = NULL;
        } else {
            warning(_("error renaming %s, %s unchanged"), sp->tpath, sp->path);
            (void) unlink(sp->tpath);
-           return FALSE;
+           goto done;
        }
     }
-    return TRUE;
+    rval = true;
+done:
+    debug_return_bool(rval);
 }
 
 /* STUB */
@@ -621,10 +661,10 @@ init_envtables(void)
 }
 
 /* STUB */
-int
+bool
 user_is_exempt(void)
 {
-    return FALSE;
+    return false;
 }
 
 /* STUB */
@@ -645,17 +685,18 @@ sudo_endspent(void)
 int
 group_plugin_query(const char *user, const char *group, const struct passwd *pw)
 {
-    return FALSE;
+    return false;
 }
 
 /*
  * Assuming a parse error occurred, prompt the user for what they want
  * to do now.  Returns the first letter of their choice.
  */
-static char
+static int
 whatnow(void)
 {
     int choice, c;
+    debug_decl(whatnow, SUDO_DEBUG_UTIL)
 
     for (;;) {
        (void) fputs(_("What now? "), stdout);
@@ -670,7 +711,7 @@ whatnow(void)
            case 'e':
            case 'x':
            case 'Q':
-               return choice;
+               debug_return_int(choice);
            default:
                (void) puts(_("Options are:\n"
                    "  (e)dit sudoers file again\n"
@@ -686,19 +727,22 @@ whatnow(void)
 static void
 setup_signals(void)
 {
-       sigaction_t sa;
+    sigaction_t sa;
+    debug_decl(setup_signals, SUDO_DEBUG_UTIL)
 
-       /*
-        * Setup signal handlers to cleanup nicely.
-        */
-       zero_bytes(&sa, sizeof(sa));
-       sigemptyset(&sa.sa_mask);
-       sa.sa_flags = SA_RESTART;
-       sa.sa_handler = quit;
-       (void) sigaction(SIGTERM, &sa, NULL);
-       (void) sigaction(SIGHUP, &sa, NULL);
-       (void) sigaction(SIGINT, &sa, NULL);
-       (void) sigaction(SIGQUIT, &sa, NULL);
+    /*
+     * Setup signal handlers to cleanup nicely.
+     */
+    zero_bytes(&sa, sizeof(sa));
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_RESTART;
+    sa.sa_handler = quit;
+    (void) sigaction(SIGTERM, &sa, NULL);
+    (void) sigaction(SIGHUP, &sa, NULL);
+    (void) sigaction(SIGINT, &sa, NULL);
+    (void) sigaction(SIGQUIT, &sa, NULL);
+
+    debug_return;
 }
 
 static int
@@ -706,6 +750,7 @@ run_command(char *path, char **argv)
 {
     int status;
     pid_t pid, rv;
+    debug_decl(run_command, SUDO_DEBUG_UTIL)
 
     switch (pid = fork()) {
        case -1:
@@ -725,16 +770,43 @@ run_command(char *path, char **argv)
        rv = waitpid(pid, &status, 0);
     } while (rv == -1 && errno == EINTR);
 
-    if (rv == -1 || !WIFEXITED(status))
-       return -1;
-    return WEXITSTATUS(status);
+    if (rv != -1)
+       rv = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
+    debug_return_int(rv);
 }
 
-static int
-check_syntax(char *sudoers_path, int quiet, int strict)
+static bool
+check_owner(const char *path, bool quiet)
 {
     struct stat sb;
-    int error;
+    bool ok = true;
+    debug_decl(check_owner, SUDO_DEBUG_UTIL)
+
+    if (stat(path, &sb) == 0) {
+       if (sb.st_uid != SUDOERS_UID || sb.st_gid != SUDOERS_GID) {
+           ok = false;
+           if (!quiet) {
+               fprintf(stderr,
+                   _("%s: wrong owner (uid, gid) should be (%u, %u)\n"),
+                   path, SUDOERS_UID, SUDOERS_GID);
+               }
+       }
+       if ((sb.st_mode & 07777) != SUDOERS_MODE) {
+           ok = false;
+           if (!quiet) {
+               fprintf(stderr, _("%s: bad permissions, should be mode 0%o\n"),
+                   path, SUDOERS_MODE);
+           }
+       }
+    }
+    debug_return_bool(ok);
+}
+
+static bool
+check_syntax(char *sudoers_path, bool quiet, bool strict, bool oldperms)
+{
+    bool ok = false;
+    debug_decl(check_syntax, SUDO_DEBUG_UTIL)
 
     if (strcmp(sudoers_path, "-") == 0) {
        yyin = stdin;
@@ -742,51 +814,47 @@ check_syntax(char *sudoers_path, int quiet, int strict)
     } else if ((yyin = fopen(sudoers_path, "r")) == NULL) {
        if (!quiet)
            warning(_("unable to open %s"), sudoers_path);
-       exit(1);
+       goto done;
     }
     init_parser(sudoers_path, quiet);
     if (yyparse() && !parse_error) {
        if (!quiet)
            warningx(_("failed to parse %s file, unknown error"), sudoers_path);
-       parse_error = TRUE;
+       parse_error = true;
        errorfile = sudoers_path;
     }
     if (!parse_error && check_aliases(strict, quiet) != 0) {
-       parse_error = TRUE;
+       parse_error = true;
        errorfile = sudoers_path;
     }
-    error = parse_error;
-    if (!quiet) {
-       if (parse_error) {
+    ok = !parse_error;
+
+    if (parse_error) {
+       if (!quiet) {
            if (errorlineno != -1)
                (void) printf(_("parse error in %s near line %d\n"),
                    errorfile, errorlineno);
            else
                (void) printf(_("parse error in %s\n"), errorfile);
-       } else {
-           (void) printf(_("%s: parsed OK\n"), sudoers_path);
-       }
-    }
-    /* Check mode and owner in strict mode. */
-    if (strict && yyin != stdin && fstat(fileno(yyin), &sb) == 0) {
-       if (sb.st_uid != SUDOERS_UID || sb.st_gid != SUDOERS_GID) {
-           error = TRUE;
-           if (!quiet) {
-               fprintf(stderr,
-                   _("%s: wrong owner (uid, gid) should be (%u, %u)\n"),
-                   sudoers_path, SUDOERS_UID, SUDOERS_GID);
-               }
        }
-       if ((sb.st_mode & 07777) != SUDOERS_MODE) {
-           error = TRUE;
-           if (!quiet) {
-               fprintf(stderr, _("%s: bad permissions, should be mode 0%o\n"),
-                   sudoers_path, SUDOERS_MODE);
-           }
+    } else {
+       struct sudoersfile *sp;
+
+       /* Parsed OK, check mode and owner. */
+       if (oldperms || check_owner(sudoers_path, quiet))
+           (void) printf(_("%s: parsed OK\n"), sudoers_path);
+       else
+           ok = false;
+       tq_foreach_fwd(&sudoerslist, sp) {
+           if (oldperms || check_owner(sp->path, quiet))
+               (void) printf(_("%s: parsed OK\n"), sp->path);
+           else
+               ok = false;
        }
     }
 
-    return error;
+done:
+    debug_return_bool(ok);
 }
 
 /*
@@ -794,10 +862,17 @@ check_syntax(char *sudoers_path, int quiet, int strict)
  * any subsequent files #included via a callback from the parser.
  */
 FILE *
-open_sudoers(const char *path, int doedit, int *keepopen)
+open_sudoers(const char *path, bool doedit, bool *keepopen)
 {
     struct sudoersfile *entry;
     FILE *fp;
+    int open_flags;
+    debug_decl(open_sudoers, SUDO_DEBUG_UTIL)
+
+    if (checkonly)
+       open_flags = O_RDONLY;
+    else
+       open_flags = O_RDWR | O_CREAT;
 
     /* Check for existing entry */
     tq_foreach_fwd(&sudoerslist, entry) {
@@ -810,15 +885,15 @@ open_sudoers(const char *path, int doedit, int *keepopen)
        entry->modified = 0;
        entry->prev = entry;
        entry->next = NULL;
-       entry->fd = open(entry->path, O_RDWR | O_CREAT, SUDOERS_MODE);
+       entry->fd = open(entry->path, open_flags, SUDOERS_MODE);
        entry->tpath = NULL;
        entry->doedit = doedit;
        if (entry->fd == -1) {
            warning("%s", entry->path);
            efree(entry);
-           return NULL;
+           debug_return_ptr(NULL);
        }
-       if (!lock_file(entry->fd, SUDO_TLOCK))
+       if (!checkonly && !lock_file(entry->fd, SUDO_TLOCK))
            errorx(1, _("%s busy, try again later"), entry->path);
        if ((fp = fdopen(entry->fd, "r")) == NULL)
            error(1, "%s", entry->path);
@@ -835,14 +910,15 @@ open_sudoers(const char *path, int doedit, int *keepopen)
        }
     }
     if (keepopen != NULL)
-       *keepopen = TRUE;
-    return fp;
+       *keepopen = true;
+    debug_return_ptr(fp);
 }
 
 static char *
 get_editor(char **args)
 {
     char *Editor, *EditorArgs, *EditorPath, *UserEditor, *UserEditorArgs;
+    debug_decl(get_editor, SUDO_DEBUG_UTIL)
 
     /*
      * Check VISUAL and EDITOR environment variables to see which editor
@@ -936,7 +1012,7 @@ get_editor(char **args)
            errorx(1, _("no editor found (editor path = %s)"), def_editor);
     }
     *args = EditorArgs;
-    return Editor;
+    debug_return_str(Editor);
 }
 
 /*
@@ -946,6 +1022,7 @@ static char *
 get_args(char *cmnd)
 {
     char *args;
+    debug_decl(get_args, SUDO_DEBUG_UTIL)
 
     args = cmnd;
     while (*args && !isblank((unsigned char) *args))
@@ -955,7 +1032,7 @@ get_args(char *cmnd)
        while (*args && isblank((unsigned char) *args))
            args++;
     }
-    return *args ? args : NULL;
+    debug_return_str(*args ? args : NULL);
 }
 
 /*
@@ -965,35 +1042,38 @@ static void
 get_hostname(void)
 {
     char *p, thost[MAXHOSTNAMELEN + 1];
+    debug_decl(get_hostname, SUDO_DEBUG_UTIL)
 
-    if (gethostname(thost, sizeof(thost)) != 0) {
-       user_host = user_shost = "localhost";
-       return;
-    }
-    thost[sizeof(thost) - 1] = '\0';
-    user_host = estrdup(thost);
+    if (gethostname(thost, sizeof(thost)) != -1) {
+       thost[sizeof(thost) - 1] = '\0';
+       user_host = estrdup(thost);
 
-    if ((p = strchr(user_host, '.'))) {
-       *p = '\0';
-       user_shost = estrdup(user_host);
-       *p = '.';
+       if ((p = strchr(user_host, '.'))) {
+           *p = '\0';
+           user_shost = estrdup(user_host);
+           *p = '.';
+       } else {
+           user_shost = user_host;
+       }
     } else {
-       user_shost = user_host;
+       user_host = user_shost = "localhost";
     }
+    debug_return;
 }
 
-static int
-alias_remove_recursive(char *name, int type, int strict, int quiet)
+static bool
+alias_remove_recursive(char *name, int type)
 {
     struct member *m;
     struct alias *a;
-    int error = 0;
+    bool rval = true;
+    debug_decl(alias_remove_recursive, SUDO_DEBUG_ALIAS)
 
     if ((a = alias_find(name, type)) != NULL) {
        tq_foreach_fwd(&a->members, m) {
            if (m->type == ALIAS) {
-               if (!alias_remove_recursive(m->name, type, strict, quiet))
-                   error = 1;
+               if (!alias_remove_recursive(m->name, type))
+                   rval = false;
            }
        }
     }
@@ -1001,7 +1081,7 @@ alias_remove_recursive(char *name, int type, int strict, int quiet)
     a = alias_remove(name, type);
     if (a)
        rbinsert(alias_freelist, a);
-    return error;
+    debug_return_bool(rval);
 }
 
 static int
@@ -1009,13 +1089,14 @@ check_alias(char *name, int type, int strict, int quiet)
 {
     struct member *m;
     struct alias *a;
-    int error = 0;
+    int errors = 0;
+    debug_decl(check_alias, SUDO_DEBUG_ALIAS)
 
     if ((a = alias_find(name, type)) != NULL) {
        /* check alias contents */
        tq_foreach_fwd(&a->members, m) {
            if (m->type == ALIAS)
-               error += check_alias(m->name, type, strict, quiet);
+               errors += check_alias(m->name, type, strict, quiet);
        }
     } else {
        if (!quiet) {
@@ -1034,10 +1115,10 @@ check_alias(char *name, int type, int strict, int quiet)
                type == USERALIAS ? "User" : type == RUNASALIAS ? "Runas" :
                "Unknown", name);
        }
-       error++;
+       errors++;
     }
 
-    return error;
+    debug_return_int(errors);
 }
 
 /*
@@ -1045,14 +1126,15 @@ check_alias(char *name, int type, int strict, int quiet)
  * aliases or unused aliases.
  */
 static int
-check_aliases(int strict, int quiet)
+check_aliases(bool strict, bool quiet)
 {
     struct cmndspec *cs;
     struct member *m, *binding;
     struct privilege *priv;
     struct userspec *us;
     struct defaults *d;
-    int atype, error = 0;
+    int atype, errors = 0;
+    debug_decl(check_aliases, SUDO_DEBUG_ALIAS)
 
     alias_freelist = rbcreate(alias_compare);
 
@@ -1061,26 +1143,26 @@ check_aliases(int strict, int quiet)
        tq_foreach_fwd(&us->users, m) {
            if (m->type == ALIAS) {
                alias_seqno++;
-               error += check_alias(m->name, USERALIAS, strict, quiet);
+               errors += check_alias(m->name, USERALIAS, strict, quiet);
            }
        }
        tq_foreach_fwd(&us->privileges, priv) {
            tq_foreach_fwd(&priv->hostlist, m) {
                if (m->type == ALIAS) {
                    alias_seqno++;
-                   error += check_alias(m->name, HOSTALIAS, strict, quiet);
+                   errors += check_alias(m->name, HOSTALIAS, strict, quiet);
                }
            }
            tq_foreach_fwd(&priv->cmndlist, cs) {
                tq_foreach_fwd(&cs->runasuserlist, m) {
                    if (m->type == ALIAS) {
                        alias_seqno++;
-                       error += check_alias(m->name, RUNASALIAS, strict, quiet);
+                       errors += check_alias(m->name, RUNASALIAS, strict, quiet);
                    }
                }
                if ((m = cs->cmnd)->type == ALIAS) {
                    alias_seqno++;
-                   error += check_alias(m->name, CMNDALIAS, strict, quiet);
+                   errors += check_alias(m->name, CMNDALIAS, strict, quiet);
                }
            }
        }
@@ -1091,33 +1173,30 @@ check_aliases(int strict, int quiet)
        tq_foreach_fwd(&us->users, m) {
            if (m->type == ALIAS) {
                alias_seqno++;
-               if (!alias_remove_recursive(m->name, USERALIAS, strict, quiet))
-                   error++;
+               if (!alias_remove_recursive(m->name, USERALIAS))
+                   errors++;
            }
        }
        tq_foreach_fwd(&us->privileges, priv) {
            tq_foreach_fwd(&priv->hostlist, m) {
                if (m->type == ALIAS) {
                    alias_seqno++;
-                   if (!alias_remove_recursive(m->name, HOSTALIAS, strict,
-                       quiet))
-                       error++;
+                   if (!alias_remove_recursive(m->name, HOSTALIAS))
+                       errors++;
                }
            }
            tq_foreach_fwd(&priv->cmndlist, cs) {
                tq_foreach_fwd(&cs->runasuserlist, m) {
                    if (m->type == ALIAS) {
                        alias_seqno++;
-                       if (!alias_remove_recursive(m->name, RUNASALIAS,
-                           strict, quiet))
-                           error++;
+                       if (!alias_remove_recursive(m->name, RUNASALIAS))
+                           errors++;
                    }
                }
                if ((m = cs->cmnd)->type == ALIAS) {
                    alias_seqno++;
-                   if (!alias_remove_recursive(m->name, CMNDALIAS, strict,
-                       quiet))
-                       error++;
+                   if (!alias_remove_recursive(m->name, CMNDALIAS))
+                       errors++;
                }
            }
        }
@@ -1143,8 +1222,8 @@ check_aliases(int strict, int quiet)
            for (m = binding; m != NULL; m = m->next) {
                if (m->type == ALIAS) {
                    alias_seqno++;
-                   if (!alias_remove_recursive(m->name, atype, strict, quiet))
-                       error++;
+                   if (!alias_remove_recursive(m->name, atype))
+                       errors++;
                }
            }
        }
@@ -1155,7 +1234,7 @@ check_aliases(int strict, int quiet)
     if (!no_aliases() && !quiet)
        alias_apply(print_unused, strict ? "Error" : "Warning");
 
-    return strict ? error : 0;
+    debug_return_int(strict ? errors : 0);
 }
 
 static int
@@ -1164,7 +1243,7 @@ print_unused(void *v1, void *v2)
     struct alias *a = (struct alias *)v1;
     char *prefix = (char *)v2;
 
-    warningx(_("%s: unused %s_Alias %s"), prefix,
+    warningx2(_("%s: unused %s_Alias %s"), prefix,
        a->type == HOSTALIAS ? "Host" : a->type == CMNDALIAS ? "Cmnd" :
        a->type == USERALIAS ? "User" : a->type == RUNASALIAS ? "Runas" :
        "Unknown", a->name);
diff --git a/pp b/pp
index a7267c9193623cf4d572de8b619de7080957a114..3cf690cc451ed4c9b6f37d52c5c7b5b661ac1405 100755 (executable)
--- a/pp
+++ b/pp
@@ -1,7 +1,7 @@
 #!/bin/sh
-# (c) 2011 Quest Software, Inc. All rights reserved
-pp_revision="305"
- # Copyright 2010 Quest Software, Inc.  All rights reserved.
+# Copyright 2012 Quest Software, Inc. ALL RIGHTS RESERVED
+pp_revision="341"
+ # Copyright 2012 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
@@ -31,7 +31,7 @@ pp_revision="305"
  # Please see <http://rc.quest.com/topics/polypkg/> for more information
 
 pp_version="1.0.0.$pp_revision"
-pp_copyright="Copyright 2010, Quest Software, Inc. All rights reserved."
+pp_copyright="Copyright 2012, Quest Software, Inc. ALL RIGHTS RESERVED."
 
 pp_opt_debug=false
 pp_opt_destdir="$DESTDIR"
@@ -802,7 +802,7 @@ pp_frontend_init () {
     version=
     summary="no summary"
     description="No description"
-    copyright="Copyright 2010 Quest Software, Inc. All rights reserved."
+    copyright="Copyright 2012 Quest Software, Inc. ALL RIGHTS RESERVED."
 
     #-- if the user supplied extra arguments on the command line
     #   then load them now.
@@ -961,7 +961,7 @@ pp_frontend () {
              fi
             test $# -eq 0 || pp_warn "ignoring extra arguments: $line"
             continue;;
-         %pre|%post|%preun|%postup|%postun|%files|%depend|%check)
+         %pre|%post|%preun|%postup|%postun|%files|%depend|%check|%conflict)
              pp_debug "processing new component section $*"
              s="$1"; shift
              if test $# -eq 0 || pp_is_qualifier "$1"; then
@@ -1056,7 +1056,7 @@ pp_frontend () {
                . $pp_wrkdir/tmp
                : > $pp_wrkdir/tmp
                ;;
-       %pre.*|%preun.*|%post.*|%postup.*|%postun.*|%depend.*|%check.*|%service.*|%fixup)
+       %pre.*|%preun.*|%post.*|%postup.*|%postun.*|%depend.*|%check.*|%conflict.*|%service.*|%fixup)
                 pp_debug "leaving $section: substituting $pp_wrkdir/tmp"
                 # cat $pp_wrkdir/tmp >&2    # debugging
                 $pp_opt_debug && pp_substitute < $pp_wrkdir/tmp >&2
@@ -1092,6 +1092,10 @@ pp_frontend () {
                pp_debug "Adding explicit dependency $@ to $cpt"
                echo "$@" >> $pp_wrkdir/%depend.$cpt
                ;;
+       %conflict.*)
+               pp_debug "Adding explicit conflict $@ to $cpt"
+               echo "$@" >> $pp_wrkdir/%conflict.$cpt
+               ;;
      esac
   done
   exec <&-
@@ -1757,7 +1761,7 @@ pp_aix_add_service () {
 
        set -- $cmd
        cmd_cmd="$1"; shift
-       cmd_arg="$pp_aix_mkssys_cmd_args";
+       cmd_arg="$*";
 
        case "$stop_signal" in
                HUP) stop_signal=1;;
@@ -1787,7 +1791,7 @@ pp_aix_add_service () {
        cat <<-. >> $pp_wrkdir/%post.$svc
 svc=$svc
 uid=0
-cmd_cmd=$daemon
+cmd_cmd="$cmd_cmd"
 cmd_arg="$cmd_arg"
 stop_signal=$stop_signal
 force_signal=9
@@ -1808,7 +1812,8 @@ mkssys -s \$svc -u \$uid -p "\$cmd_cmd" \${cmd_arg:+-a "\$cmd_arg"} -S -n \$stop
         #-- add code to start the service on reboot
         ${pp_aix_init_services_after_install} &&
           cat <<-. >> $pp_wrkdir/%post.$svc
-mkitab "\$svc:2:once:/usr/bin/startsrc -s \$svc" > /dev/null 2>&1
+id=\`echo "\$svc" | cut -c1-14\`
+mkitab "\$id:2:once:/usr/bin/startsrc -s \$svc" > /dev/null 2>&1
 .
 
        ${pp_aix_start_services_after_install} &&
@@ -1824,7 +1829,7 @@ mv $pp_wrkdir/%post.$svc $pp_wrkdir/%post.run
 
         ${pp_aix_init_services_after_install} &&
            pp_prepend $pp_wrkdir/%preun.$svc <<-.
-rmitab $svc
+rmitab `echo "$svc" | cut -c1-14` > /dev/null 2>&1
 .
        pp_prepend $pp_wrkdir/%preun.$svc <<-.
 stopsrc -s $svc >/dev/null 2>&1
@@ -1891,6 +1896,7 @@ pp_backend_aix () {
                     -o -s $pp_wrkdir/%pre.$cmp \
                     -o -s $pp_wrkdir/%post.$cmp \
                     -o -s $pp_wrkdir/%preun.$cmp \
+                    -o -s $pp_wrkdir/%postun.$cmp \
                     -o -s $pp_wrkdir/%check.$cmp
             then
                 content=B
@@ -1965,6 +1971,11 @@ pp_backend_aix () {
                        < $pp_wrkdir/%preun.$cmp
            fi
 
+           if test -r $pp_wrkdir/%postun.$cmp; then
+               pp_aix_make_script $root_wrkdir/$pp_aix_bff_name.$ex.unpre_i \
+                       < $pp_wrkdir/%postun.$cmp
+           fi
+
            # remove empty files
            for f in $user_wrkdir/$pp_aix_bff_name.$ex.* $root_wrkdir/$pp_aix_bff_name.$ex.*; do
              if test ! -s "$f"; then
@@ -2271,8 +2282,18 @@ pp_sd_write_files () {
         test x"$m" = x"-" && m=$dm
 
         case $t in
-            s) echo "$line $st $p";;
-            *) echo "$line -o $o -g $g -m $m $pp_destdir$p $p";;
+            s)
+               # swpackage will make unqualified links relative to the
+               # current working (source) directory, not the destination;
+               # we need to qualify them to prevent this.
+               case "$st" in
+                   /*) echo "$line $st $p";;
+                   *) echo "$line `dirname $p`/$st $p";;
+               esac
+               ;;
+            *)
+               echo "$line -o $o -g $g -m $m $pp_destdir$p $p"
+               ;;
         esac
 
     done
@@ -2294,49 +2315,49 @@ pp_sd_service_group_script () {
 .
 
     cat <<-'.' >> $out
-        #-- starts services in order.. stops them all if any break
-        pp_start () {
-            undo=
-            for svc in $svcs; do
-                /sbin/init.d/$svc start
-               case $? in
-                 0|4)
-                   undo="$svc $undo"
-                   ;;
-                 *)
-                    if test -n "$undo"; then
-                        for svc in $undo; do
-                           /sbin/init.d/$svc stop
-                        done
-                        return 1
-                    fi
-                   ;;
-                esac
-            done
-            return 0
-        }
+       #-- starts services in order.. stops them all if any break
+       pp_start () {
+           undo=
+           for svc in \$svcs; do
+               /sbin/init.d/\$svc start
+               case \$? in
+                 0|4)
+                   undo="\$svc \$undo"
+                   ;;
+                 *)
+                   if test -n "\$undo"; then
+                       for svc in \$undo; do
+                           /sbin/init.d/\$svc stop
+                       done
+                       return 1
+                   fi
+                   ;;
+               esac
+           done
+           return 0
+       }
 
-        #-- stops services in reverse
-        pp_stop () {
-            reverse=
-            for svc in $svcs; do
-                reverse="$svc $reverse"
-            done
-            rc=0
-            for svc in $reverse; do
-                /sbin/init.d/$svc stop || rc=$?
-            done
-            return $rc
+       #-- stops services in reverse
+       pp_stop () {
+           reverse=
+           for svc in \$svcs; do
+               reverse="\$svc \$reverse"
+           done
+           rc=0
+           for svc in \$reverse; do
+               /sbin/init.d/\$svc stop || rc=\$?
+           done
+           return \$rc
         }
 
-        case $1 in
-            start_msg) echo "Starting $svcs";;
-            stop_msg)  echo "Stopping $svcs";;
+       case \$1 in
+           start_msg) echo "Starting \$svcs";;
+           stop_msg)  echo "Stopping \$svcs";;
            start)     pp_start;;
            stop)      pp_stop;;
-            *)        echo "usage: $0 {start|stop|start_msg|stop_msg}"
-                       exit 1;;
-        esac
+           *)         echo "usage: \$0 {start|stop|start_msg|stop_msg}"
+                      exit 1;;
+       esac
 .
 }
 
@@ -2387,61 +2408,61 @@ pp_sd_service_script () {
        }
 
        pp_stop () {
-           if test ! -s "$pidfile"; then
-               echo "Unable to stop $svc (no pid file)"
-               return 1
+           if test ! -s "\$pidfile"; then
+               echo "Unable to stop \$svc (no pid file)"
+               return 1
            else
-               read pid < "$pidfile"
-               if kill -0 "$pid" 2>/dev/null; then
-                   if kill -${stop_signal:-TERM} "$pid"; then
-                       rm -f "$pidfile"
-                       return 0
-                   else
-                       echo "Unable to stop $svc"
-                       return 1
-                   fi
-               else
-                   rm -f "$pidfile"
-                   return 0
-               fi
+               read pid < "\$pidfile"
+               if kill -0 "\$pid" 2>/dev/null; then
+                   if kill -${stop_signal:-TERM} "\$pid"; then
+                       rm -f "\$pidfile"
+                       return 0
+                   else
+                       echo "Unable to stop \$svc"
+                       return 1
+                   fi
+               else
+                   rm -f "\$pidfile"
+                   return 0
+               fi
            fi
        }
 
        pp_running () {
-           if test ! -s "$pidfile"; then
-               return 1
+           if test ! -s "\$pidfile"; then
+               return 1
            else
-               read pid < "$pidfile"
-               kill -0 "$pid" 2>/dev/null
+               read pid < "\$pidfile"
+               kill -0 "\$pid" 2>/dev/null
            fi
        }
 
-       case $1 in
-           start_msg) echo "Starting the $svc service";;
-           stop_msg)  echo "Stopping the $svc service";;
+       case \$1 in
+           start_msg) echo "Starting the \$svc service";;
+           stop_msg)  echo "Stopping the \$svc service";;
            start)
-                   if test -f "$config_file"; then
-                       . $config_file
-                   fi
-                   if pp_disabled; then
-                       exit 2
-                   elif pp_running; then
-                       echo "$svc already running";
-                       exit 0
-                   elif pp_start; then
-                       echo "$svc started";
-                       # rc(1M) says we should exit 4, but nobody expects it!
-                       exit 0
-                   else
-                       exit 1
-                   fi;;
+                   if test -f "\$config_file"; then
+                       . \$config_file
+                   fi
+                   if pp_disabled; then
+                       exit 2
+                   elif pp_running; then
+                       echo "\$svc already running";
+                       exit 0
+                   elif pp_start; then
+                       echo "\$svc started";
+                       # rc(1M) says we should exit 4, but nobody expects it!
+                       exit 0
+                   else
+                       exit 1
+                   fi;;
            stop)   if pp_stop; then
-                       echo "$svc stopped";
-                       exit 0
-                   else
-                       exit 1
-                   fi;;
-           *) echo "usage: $0 {start|stop|start_msg|stop_msg}"
+                       echo "\$svc stopped";
+                       exit 0
+                   else
+                       exit 1
+                   fi;;
+           *) echo "usage: \$0 {start|stop|start_msg|stop_msg}"
               exit 1;;
        esac
 .
@@ -2529,6 +2550,22 @@ pp_sd_control () {
     echo "                $ctrl $script"
 }
 
+pp_sd_depend () {
+    typeset _name _vers
+    while read _name _vers; do
+       case "$_name" in ""| "#"*) continue ;; esac
+       echo "                prerequisites $_name ${_vers:+r>= $_vers}"
+    done
+}
+
+pp_sd_conflict () {
+    typeset _name _vers
+    while read _name _vers; do
+       case "$_name" in ""| "#"*) continue ;; esac
+       echo "                exrequisites $_name ${_vers:+r>= $_vers}"
+    done
+}
+
 pp_backend_sd () {
     typeset psf cpt svc outfile release swp_flags
 
@@ -2580,6 +2617,10 @@ pp_backend_sd () {
                 title           "${summary:-cpt}"
                 revision        $version
 .
+        test -s $pp_wrkdir/%depend.$cpt &&
+              pp_sd_depend < $pp_wrkdir/%depend.$cpt >> $psf
+        test -s $pp_wrkdir/%conflict.$cpt &&
+              pp_sd_conflict < $pp_wrkdir/%conflict.$cpt >> $psf
 
        #-- make sure services are shut down during uninstall
         if test $cpt = run -a -n "$pp_services"; then
@@ -2911,6 +2952,16 @@ pp_solaris_depend () {
     done
 }
 
+pp_solaris_conflict () {
+    typeset _name _vers
+    while read _name _vers; do
+       if test -n "$_name"; then
+           echo "I $_name $_name"
+           test -n "$_vers" && echo " $_vers"
+       fi
+    done
+}
+
 pp_solaris_space() {
     echo "$2:$3:$1" >> $pp_wrkdir/space.cumulative
 }
@@ -2927,14 +2978,14 @@ pp_solaris_proto () {
        typeset abi
 
        while read t m o g f p st; do
-         if test x"$o" = x"-"; then
-            o="root"
-          fi
-         if test x"$g" = x"-"; then
-            g="bin"
-          fi
+         # Use Solaris default mode, owner and group if all unspecified
+         if test x"$m$o$g" = x"---"; then
+           m="?"; o="?"; g="?"
+         fi
+         test x"$o" = x"-" && o="root"
          case "$t" in
-           f) test x"$m" = x"-" && m=444
+           f) test x"$g" = x"-" && g="bin"
+              test x"$m" = x"-" && m=444
               case "$f" in
                *v*) echo "v $1 $p=$pp_destdir$p $m $o $g";;
                *)   echo "f $1 $p=$pp_destdir$p $m $o $g";;
@@ -2953,12 +3004,15 @@ pp_solaris_proto () {
                  fi
               fi
                ;;
-           d) test x"$m" = x"-" && m=555
+           d) test x"$g" = x"-" && g="sys"
+              test x"$m" = x"-" && m=555
               echo "d $1 $p $m $o $g"
                ;;
-           s) test x"$m" = x"-" && m=777
-               test x"$m" = x"777" ||
+           s) test x"$g" = x"-" && g="bin"
+              test x"$m" = x"-" && m=777
+               if test x"$m" != x"777" -a x"$m" != x"?"; then
                   pp_warn "$p: invalid mode $m for symlink, should be 777 or -"
+              fi
               echo "s $1 $p=$st $m $o $g"
                ;;
          esac
@@ -3021,6 +3075,7 @@ pp_backend_solaris () {
         #-- scripts to run before and after install
         : > $pp_wrkdir/postinstall
         : > $pp_wrkdir/preremove
+        : > $pp_wrkdir/postremove
        for _cmp in $pp_components; do
         #-- add the preinstall scripts in definition order
         if test -s $pp_wrkdir/%pre.$_cmp; then
@@ -3037,15 +3092,22 @@ pp_backend_solaris () {
             pp_solaris_procedure $_cmp preremove < $pp_wrkdir/%preun.$_cmp |
                     pp_prepend $pp_wrkdir/preremove
         fi
+        #-- add the postremove scripts in definition order
+        if test -s $pp_wrkdir/%postun.$_cmp; then
+            pp_solaris_procedure $_cmp postremove < $pp_wrkdir/%postun.$_cmp \
+                >> $pp_wrkdir/postremove
+        fi
         #-- Add the check script in definition order
         if test -s $pp_wrkdir/%check.$_cmp; then
             pp_solaris_procedure $_cmp checkinstall \
                         < $pp_wrkdir/%check.$_cmp \
                        >> $pp_wrkdir/checkinstall
         fi
-        #-- All dependencies are merged together for Solaris pkgs
+        #-- All dependencies and conflicts are merged together for Solaris pkgs
         test -s $pp_wrkdir/%depend.$_cmp &&
-              pp_solaris_depend < $pp_wrkdir/%depend.$_cmp > $pp_wrkdir/depend
+              pp_solaris_depend < $pp_wrkdir/%depend.$_cmp >> $pp_wrkdir/depend
+        test -s $pp_wrkdir/%conflict.$_cmp &&
+              pp_solaris_conflict < $pp_wrkdir/%conflict.$_cmp >> $pp_wrkdir/depend
        done
 
 
@@ -3060,6 +3122,7 @@ pp_backend_solaris () {
                 pp_solaris_make_service $_svc
                 pp_solaris_install_service $_svc | pp_prepend $pp_wrkdir/postinstall
                 pp_solaris_remove_service $_svc | pp_prepend $pp_wrkdir/preremove
+                pp_solaris_remove_service $_svc | pp_prepend $pp_wrkdir/postremove
                 unset pp_svc_xml_file
             done
 
@@ -3140,7 +3203,7 @@ fi >&2
 
        pkgmk -d $pp_wrkdir/pkg -f $prototype \
                || { error "pkgmk failed"; return; }
-       pkgtrans -s $pp_wrkdir/pkg \
+        pkgtrans -s $pp_wrkdir/pkg \
                $pp_wrkdir/`pp_backend_solaris_names` \
                 ${pp_solaris_name:-$name} \
                || { error "pkgtrans failed"; return; }
@@ -3339,13 +3402,14 @@ pp_solaris_smf () {
 
     pp_solaris_name=${pp_solaris_name:-$name}
     pp_solaris_manpath=${pp_solaris_manpath:-"/usr/share/man"}
+    pp_solaris_mansect=${pp_solaris_mansect:-1}
     smf_start_timeout=${smf_start_timeout:-60}
     smf_stop_timeout=${smf_stop_timeout:-60}
     smf_restart_timeout=${smf_restart_timeout:-60}
 
     svc=${pp_solaris_smf_service_name:-$1}
     _pp_solaris_service_script=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
-    _pp_solaris_manpage=${pp_solaris_manpage:-$pp_solaris_smf_service_name}
+    _pp_solaris_manpage=${pp_solaris_manpage:-$svc}
 
     if [ -z $pp_svc_xml_file ]; then
         pp_svc_xml_file="/var/svc/manifest/$_smf_category/$svc.xml"
@@ -3377,6 +3441,7 @@ pp_solaris_smf () {
     f=$pp_svc_xml_file
     pp_add_file_if_missing $f ||
         return 0
+    pp_solaris_add_parent_dirs "$f"
 
     _pp_solaris_smf_dependencies="
           <dependency name='pp_local_filesystems'
@@ -3440,7 +3505,7 @@ pp_solaris_smf () {
                   <loctext xml:lang='C'>$description</loctext>
               </common_name>
               <documentation>
-                  <manpage title='$pp_solaris_manpage' section='1' manpath='$pp_solaris_manpath'/>
+                  <manpage title='$pp_solaris_manpage' section='$pp_solaris_mansect' manpath='$pp_solaris_manpath'/>
               </documentation>
           </template>
         </service>
@@ -3456,8 +3521,9 @@ pp_solaris_make_service_group () {
     file="/etc/init.d/$group"
     out="$pp_destdir$file"
 
-    #-- return if the script is supplued already
+    #-- return if the script is supplied already
     pp_add_file_if_missing "$file" run 755 || return 0
+    pp_solaris_add_parent_dirs "$file"
 
     echo "#! /sbin/sh" > $out
     echo "# polypkg service group script for these services:" >> $out
@@ -3525,6 +3591,7 @@ pp_solaris_make_service () {
     #-- return if we don't need to create the init script
     pp_add_file_if_missing "$file" run 755 ||
         return 0
+    pp_solaris_add_parent_dirs "$file"
 
     echo "#! /sbin/sh" >$out
     echo "#-- This service init file generated by polypkg" >>$out
@@ -3540,12 +3607,13 @@ if [ -x /usr/sbin/svcadm ] && [ "x\$1" != "xstatus" ] && [ "t\$$_smf_method_envv
             /usr/sbin/svcadm enable -s $_smf_category/$svc
             RESULT=\$?
             if [ "\$RESULT" -ne 0 ] ; then
-                echo "Error \$RESULT starting $svc"
-                fi
+                echo "Error \$RESULT starting $svc" >&2
+            fi
             ;;
         stop)
             echo "stopping $svc"
             /usr/sbin/svcadm disable -ts $_smf_category/$svc
+           RESULT=0
             ;;
         restart)
             echo "restarting $svc"
@@ -3554,14 +3622,14 @@ if [ -x /usr/sbin/svcadm ] && [ "x\$1" != "xstatus" ] && [ "t\$$_smf_method_envv
             /usr/sbin/svcadm enable -s $_smf_category/$svc
             RESULT=\$?
             if [ "\$RESULT" -ne 0 ] ; then
-                echo "Error \$RESULT starting $svc"
-                    fi
-                    ;;
+                echo "Error \$RESULT starting $svc" >&2
+            fi
+            ;;
         *)
-            echo "Usage: $file {start|stop|restart|status}"
-            exit 1
+            echo "Usage: $file {start|stop|restart|status}" >&2
+            RESULT=1
     esac
-    exit 0
+    exit $RESULT
 fi
 _EOF
     fi
@@ -3604,8 +3672,8 @@ _EOF
 
         # returns true if $svc is running
         pp_running () {
-            test -r "$pidfile" &&
-            read pid junk < "$pidfile" &&
+            test -s "$pidfile" || return 1
+            read pid junk < "$pidfile" 2>/dev/null
             test ${pid:-0} -gt 1 &&
             kill -0 "$pid" 2>/dev/null
         }
@@ -3741,6 +3809,18 @@ else
 fi'
 }
 
+pp_solaris_add_parent_dirs () {
+    typeset dir
+
+    dir=${1%/*}
+    while test -n "$dir"; do
+       if awk "\$6 == \"$dir/\" {exit 1}" < $pp_wrkdir/%files.run; then
+           echo "d - - - - $dir/" >> $pp_wrkdir/%files.run
+       fi
+       dir=${dir%/*}
+    done
+}
+
 pp_platforms="$pp_platforms deb"
 
 pp_backend_deb_detect () {
@@ -3839,6 +3919,19 @@ pp_deb_version_final() {
     fi
 }
 
+pp_deb_conflict () {
+    local _name _vers _conflicts
+
+    _conflicts="Conflicts:"
+    while read _name _vers; do
+       case "$_name" in ""| "#"*) continue ;; esac
+       _conflicts="$_conflicts $_name"
+       test -n "$_vers" && _conflicts="$_conflicts $_name (>= $vers)"
+       _conflicts="${_conflicts},"
+    done
+    echo "${_conflicts%,}"
+}
+
 pp_deb_make_control() {
     package_name=`pp_deb_cmp_full_name "$1"`
     cat <<-.
@@ -3855,6 +3948,9 @@ pp_deb_make_control() {
        sed -ne '/^[    ]*$/!s/^[       ]*/Depends: /p' \
            < $pp_wrkdir/%depend."$1"
     fi
+    if test -s $pp_wrkdir/%conflict."$1"; then
+       pp_deb_conflict < $pp_wrkdir/%conflict."$1"
+    fi
 }
 
 pp_deb_make_md5sums() {
@@ -3964,6 +4060,11 @@ pp_deb_make_DEBIAN() {
         "$pp_wrkdir/%preun.$cmp" "Pre-uninstall script for $cmp_full_name"\
         || exit $?
 
+    # Create postrm
+    pp_deb_make_package_maintainer_script "$data/DEBIAN/postrm" \
+        "$pp_wrkdir/%postun.$cmp" "Post-uninstall script for $cmp_full_name"\
+        || exit $?
+
     umask $old_umask
 }
 
@@ -3973,6 +4074,12 @@ pp_deb_make_data() {
     cmp=$1
     data=$pp_wrkdir/`pp_deb_cmp_full_name $cmp`
     cat $pp_wrkdir/%files.${cmp} | while read t m o g f p st; do
+       if test x"$m" = x"-"; then
+           case "$t" in
+               d) m=755;;
+               f) m=644;;
+           esac
+       fi
        test x"$o" = x"-" && o=root
        test x"$g" = x"-" && g=root
         case "$t" in
@@ -4245,17 +4352,11 @@ pp_backend_deb_vas_platforms () {
        *)      pp_die "unknown architecture ${pp_deb_arch_std}";;
     esac
 }
-pp_backend_deb_init_svc_vars () {
-    # Default multi-user runlevel on Debian is 2; 3-5 are also multi-user
-    pp_deb_default_start_runlevels="2 3 4 5"
-    pp_deb_default_svc_description="No description"
-}
-
 pp_backend_deb_init_svc_vars () {
 
     reload_signal=
-    start_runlevels=${pp_deb_default_start_runlevels}   # == lsb default-start
-    stop_runlevels="0 1 6"                              # == lsb default-stop
+    start_runlevels=${pp_deb_default_start_runlevels-"2 3 4 5"} # == lsb default-start
+    stop_runlevels=${pp_deb_default_stop_runlevels-"0 1 6"}     # == lsb default-stop
     svc_description="${pp_deb_default_svc_description}" # == lsb short descr
     svc_process=
 
@@ -4286,9 +4387,10 @@ pp_deb_service_make_init_script () {
     #_process=${svc_process:-"$1"} --? WTF
 
     #-- construct a start command that builds a pid file if needed
+    #-- the command name in /proc/[pid]/stat is limited to 15 characters 
     _cmd="$cmd";
     _cmd_path=`echo $cmd | cut -d" " -f1`
-    _cmd_name=`basename $_cmd_path`
+    _cmd_name=`basename $_cmd_path | cut -c1-15`
     _cmd_args=`echo $cmd | cut -d" " -f2-`
     test x"$_cmd_path" != x"$_cmd_args" || _cmd_args=
 
@@ -4301,7 +4403,7 @@ pp_deb_service_make_init_script () {
        # Required-Stop: ${lsb_required_stop}
        # Default-Start: ${start_runlevels}
        # Default-Stop: ${stop_runlevels}
-       # Short-Description: ${svc_description}
+       # Short-Description: ${svc_description:-no description}
        ### END INIT INFO
        # Generated by PolyPackage ${pp_version}
        # ${copyright}
@@ -5399,6 +5501,8 @@ pp_rpm_writefiles () {
                    farch=x86_64;;
                *": ELF 32-bit MSB "*", PowerPC"*)
                    farch=ppc;;
+               *": ELF 64-bit MSB "*", 64-bit PowerPC"*)
+                   farch=ppc64;;
                *": ELF 64-bit LSB "*", IA-64"*)
                    farch=ia64;;
                *": ELF 32-bit MSB "*", IBM S/390"*)
@@ -5424,7 +5528,7 @@ pp_rpm_writefiles () {
                        farch=x86_64;;
                    "ELF32 PowerPC")
                        farch=ppc;;
-                   "ELF64 PowerPC")
+                   "ELF64 PowerPC"*)
                        farch=ppc64;;
                    "ELF64 IA-64")
                        farch=ia64;;
@@ -5457,12 +5561,21 @@ pp_rpm_subname () {
 }
 
 pp_rpm_depend () {
+    local _name _vers
     while read _name _vers; do
         case "$_name" in ""| "#"*) continue ;; esac
         echo "Requires: $_name ${_vers:+>= $_vers}"
     done
 }
 
+pp_rpm_conflict () {
+    local _name _vers
+    while read _name _vers; do
+        case "$_name" in ""| "#"*) continue ;; esac
+        echo "Conflicts: $_name ${_vers:+>= $_vers}"
+    done
+}
+
 pp_rpm_override_requires () {
     local orig_find_requires
 
@@ -5528,6 +5641,9 @@ pp_backend_rpm () {
         elif test -s $pp_wrkdir/%depend.run; then
             pp_rpm_depend < $pp_wrkdir/%depend.run >> $specfile
         fi
+        if test -s $pp_wrkdir/%conflict.run; then
+            pp_rpm_conflict < $pp_wrkdir/%conflict.run >> $specfile
+        fi
 
        pp_rpm_override_requires >> $specfile
 
@@ -5567,6 +5683,9 @@ pp_backend_rpm () {
                 elif test -s $pp_wrkdir/%depend.$cmp; then
                     pp_rpm_depend < $pp_wrkdir/%depend.$cmp >> $specfile
                 fi
+                if test -s $pp_wrkdir/%conflict.$cmp; then
+                    pp_rpm_conflict < $pp_wrkdir/%conflict.$cmp >> $specfile
+                fi
 
                 eval '_pkg="$pp_rpm_'$cmp'_provides"'
                eval pp_rpm_label Provides $_pkg
@@ -5653,6 +5772,13 @@ pp_backend_rpm () {
                 cat $pp_wrkdir/%preun.$cmp
                 echo :   # causes script to exit true
             fi
+
+            if test -s $pp_wrkdir/%postun.$cmp; then
+                echo ""
+                echo "%postun $_subname"
+                cat $pp_wrkdir/%postun.$cmp
+                echo :   # causes script to exit true
+            fi
        done >>$specfile
 
         #-- create a suitable work area for rpmbuild
@@ -5886,11 +6012,6 @@ pp_backend_rpm_vas_platforms () {
     esac
 }
 
-pp_backend_rpm_init_svc_vars () {
-    pp_rpm_default_start_runlevels="2 3 4 5"
-    pp_rpm_default_svc_description="No description"
-}
-
 pp_rpm_service_install_common () {
     cat <<-'.'
 
@@ -5997,8 +6118,8 @@ pp_rpm_service_remove () {
 pp_backend_rpm_init_svc_vars () {
 
     reload_signal=
-    start_runlevels=${pp_rpm_default_start_runlevels}   # == lsb default-start
-    stop_runlevels="0 1 6"                              # == lsb default-stop
+    start_runlevels=${pp_rpm_default_start_runlevels-"2 3 4 5"} # == lsb default-start
+    stop_runlevels=${pp_rpm_default_stop_runlevels-"0 1 6"} # == lsb default-stop
     svc_description="${pp_rpm_default_svc_description}" # == lsb short descr
     svc_process=
 
@@ -6452,10 +6573,11 @@ pp_backend_macos_init () {
     pp_macos_bundle_vendor=
     pp_macos_bundle_version=
     pp_macos_bundle_info_string=
-    pp_macos_prog_packagemaker=/Developer/usr/bin/packagemaker
-    pp_macos_pkg_domain=anywhere
-    pp_macos_pkg_extra_flags=
-    pp_macos_sudo=
+    pp_macos_pkg_type=bundle
+    pp_macos_pkg_license=
+    pp_macos_pkg_readme=
+    pp_macos_pkg_welcome=
+    pp_macos_sudo=sudo
     # OS X puts the library version *before* the .dylib extension
     pp_shlib_suffix='*.dylib'
 }
@@ -6496,63 +6618,87 @@ pp_macos_plist () {
 pp_macos_rewrite_cpio () {
     typeset script
     script=$pp_wrkdir/cpio-rewrite.pl
-    # rely on the fact that OS X comes with perl. It is a little easier to
-    # re-write a binary stream with perl than it is with posix :)
-    #
-    # A CPIO header block has octal fields at the following offset/lengths:
-    #   0  6 magic
-    #   6  6 dev
-    #  12  6 ino
-    #  18  6 mode
-    #  24  6 uid
-    #  30  6 gid
-    #  36  6 nlink
-    #  42  6 rdev
-    #  48 11 mtime
-    #  59  6 namesize
-    #  65 11 filesize
-    #  76    --
     cat <<-'.' >$script
+       #!/usr/bin/perl
+       #
+       # Filter a cpio file, applying the user/group/mode specified in %files
+       #
+       # A CPIO header block has octal fields at the following offset/lengths:
+       #   0  6 magic
+       #   6  6 dev
+       #  12  6 ino
+       #  18  6 mode
+       #  24  6 uid
+       #  30  6 gid
+       #  36  6 nlink
+       #  42  6 rdev
+       #  48 11 mtime
+       #  59  6 namesize (including NUL terminator)
+       #  65 11 filesize
+       #  76    --
+       #
+       use strict;
+       use warnings;
+       no strict 'subs';
+
+       # set %uid, %gid, %mode based on %files
+       my (%uid, %gid, %mode, %users, %groups);
+       my %type_map = ( d => 0040000, f => 0100000, s => 0120000 );
        while (<DATA>) {
-               my ($type,$mode,$uid,$gid,$flags,$name) =
-                   m/^(.) (\d+) (\S+) (\S+) (\S+) (.*)/;
-               $uid = 0 if $uid eq "-";
-               $gid = 0 if $gid eq "-";
-               if ($uid ne "=" and $uid =~ m/\D/) {
-                       my @pw = getpwnam($uid) or die "bad username '$uid'";
-                       $uid = $pw[2];
-               }
-               if ($gid ne "=" and $gid =~ m/\D/) {
-                       my @gr = getgrnam($gid) or die "bad group '$gid'";
-                       $gid = $gr[2];
-               }
-               $name = ".".$name."\0";
-               $ok{$name} = 1;
-               $uid{$name} = sprintf("%06o",int($uid)) unless $uid eq "=";
-               $gid{$name} = sprintf("%06o",int($gid)) unless $gid eq "=";
-               $mode{$name} = sprintf("%06o",oct($mode)) unless $mode eq "=";
+           my ($type,$mode,$uid,$gid,$flags,$name) =
+               m/^(.) (\S+) (\S+) (\S+) (\S+) (\S+)/;
+           $mode = $type eq "f" ? "0644" : "0755" if $mode eq "-";
+           $uid = 0 if $uid eq "-";
+           $gid = 0 if $gid eq "-";
+           if ($uid ne "=" and $uid =~ m/\D/) {
+               unless (exists $users{$uid}) {
+                   my @pw = getpwnam($uid) or die "bad username '$uid'";
+                   $users{$uid} = $pw[2];
+               }
+               $uid = $users{$uid};
+           }
+           if ($gid ne "=" and $gid =~ m/\D/) {
+               unless (exists $groups{$gid}) {
+                   my @gr = getgrnam($gid) or die "bad group'$gid'";
+                   $groups{$gid} = $gr[2];
+               }
+               $gid = $groups{$gid};
+           }
+           $name =~ s:/$:: if $type eq "d";
+           $name = ".".$name."\0";
+           $uid{$name} = sprintf("%06o",int($uid)) unless $uid eq "=";
+           $gid{$name} = sprintf("%06o",int($gid)) unless $gid eq "=";
+           $mode{$name} = sprintf("%06o",oct($mode)|$type_map{$type}) unless $mode eq "=";
        }
-       $ok{"TRAILER!!!\0"} = 1;
-       while (!eof STDIN) {
-               read STDIN, $header, 76;
-               die "bad magic" unless $header =~ m/^070707/;
-               $namesize = oct(substr($header,59,6));
-               $filesize = oct(substr($header,65,11));
-               read STDIN, $name, $namesize;
-               # convert uid and gid to 0
-               substr($header, 24, 6) = $uid{$name} if defined($uid{$name});
-               substr($header, 30, 6) = $gid{$name} if defined($gid{$name});
-               substr($header, 18, 6) = $mode{$name} if defined($mode{$name});
-               print ($header, $name) if $ok{$name};
-               # copy-through the file data
-               while ($filesize > 0) {
-                       my $seg = 8192;
-                       $seg = $filesize if $filesize < $seg;
-                       undef $data;
-                       read STDIN, $data, $seg;
-                       print $data if $ok{$name};
-                       $filesize -= $seg;
-               }
+       undef %users;
+       undef %groups;
+       # parse the cpio file
+       while (read(STDIN, my $header, 76)) {
+           die "bad magic" unless $header =~ m/^070707/;
+           my $namesize = oct(substr($header, 59, 6));
+           my $filesize = oct(substr($header, 65, 11));
+           read(STDIN, my $name, $namesize);
+           # update uid, gid and mode
+           substr($header, 24, 6) = $uid{$name} if exists $uid{$name};
+           substr($header, 30, 6) = $gid{$name} if exists $gid{$name};
+           substr($header, 18, 6) = $mode{$name} if exists $mode{$name};
+           print($header, $name);
+           # check for trailer at EOF
+           last if $filesize == 0 && $name eq "TRAILER!!!\0";
+           # copy-through the file data
+           while ($filesize > 0) {
+               my $seg = 8192;
+               $seg = $filesize if $filesize < $seg;
+               read(STDIN, my $data, $seg);
+               print $data;
+               $filesize -= $seg;
+           }
+       }
+       # pass through any padding at the end (blocksize-dependent)
+       for (;;) {
+           my $numread = read(STDIN, my $data, 8192);
+           last unless $numread;
+           print $data;
        }
        exit(0);
        __DATA__
@@ -6570,7 +6716,7 @@ pp_macos_files_bom () {
            ?) m="000$m";;
            ??) m="00$m";;
            ???) m="0$m";;
-           ?????*) pp_fatal "pp_macos_writebom: mode '$m' too long";;
+           ?????*) pp_error "pp_macos_writebom: mode '$m' too long";;
        esac
 
        # convert owner,group into owner/group in octal
@@ -6580,19 +6726,25 @@ pp_macos_files_bom () {
 
        case $t in
            f)
+               test x"$m" = x"000-" && m=0644
                echo ".$p       10$m    $owner  `
                    /usr/bin/cksum < "${pp_destdir}$p" |
-                   awk '{print $2 "    " $1}'`";;
+                   awk '{print $2 "    " $1}'`"
+               ;;
            d)
-               echo ".${p%/}   4$m     $owner";;
+               test x"$m" = x"000-" && m=0755
+               echo ".${p%/}   4$m     $owner"
+               ;;
            s)
+               test x"$m" = x"000-" && m=0755
                rl=`/usr/bin/readlink "${pp_destdir}$p"`
                #test x"$rl" = x"$st" ||
                #    pp_error "symlink mismatch $rl != $st"
                echo ".$p       12$m    $owner  `
                    /usr/bin/readlink -n "${pp_destdir}$p" |
                    /usr/bin/cksum |
-                   awk '{print $2 "    " $1}'` $st";;
+                   awk '{print $2 "    " $1}'` $st"
+               ;;
        esac
     done
 }
@@ -6606,8 +6758,11 @@ pp_macos_bom_fix_parents () {
                      print "$d\t40755\t0/0\n";
                  }
                }
-       m/^\S+/;
-       &chk(&dirname($&));'
+       m/^(\S+)\s+(\d+)/;
+       if (oct($2) & 040000) {
+           $seen{$1}++; # directory
+       }
+       &chk(&dirname($1));'
 }
 
 pp_macos_files_size () {
@@ -6648,6 +6803,7 @@ pp_macos_mkbom () {
     pp_warn "mkbom workaround: copying source files to staging area"
 
     bomstage=$pp_wrkdir/bom_stage
+    $pp_macos_sudo /bin/mkdir "$bomstage"
     while IFS='        ' read path mode ugid size cksumi linkpath; do
        if test -h "$pp_destdir/$path"; then
            $pp_macos_sudo /bin/ln -s "$linkpath" "$bomstage/$path"
@@ -6667,9 +6823,18 @@ pp_macos_mkbom () {
 }
 
 pp_backend_macos () {
+    : ${pp_macos_bundle_id:=$pp_macos_default_bundle_id_prefix$name}
+    case "$pp_macos_pkg_type" in
+       bundle) pp_backend_macos_bundle;;
+       flat) pp_backend_macos_flat;;
+       *) pp_error "unsupported package type $pp_macos_pkg_type";;
+    esac
+}
+
+pp_backend_macos_bundle () {
     typeset pkgdir Contents Resources lprojdir
     typeset Info_plist Description_plist
-    typeset bundle_vendor bundle_version size
+    typeset bundle_vendor bundle_version size cmp filelists
 
     mac_version=`sw_vers -productVersion`
     bundle_vendor=${pp_macos_bundle_vendor:-$vendor}
@@ -6677,9 +6842,6 @@ pp_backend_macos () {
     if test -z "$pp_macos_bundle_version"; then
         bundle_version=`echo "$version.0.0.0" | sed -n -e 's/[^0-9.]//g' \
             -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/p'`
-        #if test x"$bundle_version" != x"$version"; then
-        #    pp_warn "converted version from '$version' to '$bundle_version'"
-        #fi
     else
         bundle_version="$pp_macos_bundle_version"
     fi
@@ -6691,7 +6853,7 @@ pp_backend_macos () {
     Resources=$Contents/Resources
     lprojdir=$Resources/en.lproj
     mkdir $pkgdir $Contents $Resources $lprojdir ||
-       pp_fatal "Can't make package temporary directories"
+       pp_error "Can't make package temporary directories"
 
     echo "major: 1" > $Resources/package_version
     echo "minor: 0" >> $Resources/package_version
@@ -6699,12 +6861,50 @@ pp_backend_macos () {
     case $mac_version in
         "10.6"*)
             xattr -w "com.apple.TextEncoding" "macintosh;0" "$Resources/package_version"
-            xattr -w "com.apple.TextEncoding" "macintosh;0" "$Resources/PkgInfo"
+            xattr -w "com.apple.TextEncoding" "macintosh;0" "$Contents/PkgInfo"
             ;;
     esac
 
+    # Copy welcome file/dir for display at package install time.
+    if test -n "$pp_macos_pkg_welcome"; then
+       typeset sfx
+       sfx=`echo "$pp_macos_pkg_welcome"|sed 's/^.*\.\([^\.]*\)$/\1/'`
+       case "$sfx" in
+           rtf|html|rtfd|txt) ;;
+           *) sfx=txt;;
+       esac
+       cp -R ${pp_macos_pkg_welcome} $Resources/Welcome.$sfx
+    fi
+
+    # Copy readme file/dir for display at package install time.
+    if test -n "$pp_macos_pkg_readme"; then
+       typeset sfx
+       sfx=`echo "$pp_macos_pkg_readme"|sed 's/^.*\.\([^\.]*\)$/\1/'`
+       case "$sfx" in
+           rtf|html|rtfd|txt) ;;
+           *) sfx=txt;;
+       esac
+       cp -R ${pp_macos_pkg_readme} $Resources/ReadMe.$sfx
+    fi
+
+    # Copy license file/dir for display at package install time.
+    if test -n "$pp_macos_pkg_license"; then
+       typeset sfx
+       sfx=`echo "$pp_macos_pkg_license"|sed 's/^.*\.\([^\.]*\)$/\1/'`
+       case "$sfx" in
+           rtf|html|rtfd|txt) ;;
+           *) sfx=txt;;
+       esac
+       cp -R ${pp_macos_pkg_license} $Resources/License.$sfx
+    fi
+
+    # Find file lists (%files.* includes ignore files)
+    for cmp in $pp_components; do
+       test -f $pp_wrkdir/%files.$cmp && filelists="$filelists${filelists:+ }$pp_wrkdir/%files.$cmp"
+    done
+
     # compute the installed size
-    size=`cat $pp_wrkdir/%files.* | pp_macos_files_size`
+    size=`cat $filelists | pp_macos_files_size`
 
     #-- Create Info.plist
     Info_plist=$Contents/Info.plist
@@ -6713,7 +6913,7 @@ pp_backend_macos () {
        key CFBundleGetInfoString string \
            "${pp_macos_bundle_info_string:-$version $bundle_vendor}" \
        key CFBundleIdentifier string \
-           "${pp_macos_bundle_id:-$pp_macos_default_bundle_id_prefix$name}" \
+           "${pp_macos_bundle_id}" \
     key CFBundleName string "$name" \
        key CFBundleShortVersionString string "$bundle_version" \
        key IFMajorVersion integer 1 \
@@ -6745,8 +6945,8 @@ pp_backend_macos () {
            key IFPkgDescriptionVersion string "$version" \
        \} end-plist > $Description_plist
 
-       # write Resources/files
-    cat $pp_wrkdir/%files.* | awk '{print $6}' > $Resources/files
+    # write Resources/files
+    awk '{print $6}' $filelists > $Resources/files
 
     # write package size file
     printf \
@@ -6755,7 +6955,7 @@ InstalledSize $size
 CompressedSize 0
 " > $Resources/$name.sizes
 
-    # write Resources/postinstall
+    # write Resources/preinstall
     for cmp in $pp_components; do
        if test -s $pp_wrkdir/%pre.$cmp; then
            if test ! -s $Resources/preinstall; then
@@ -6779,7 +6979,7 @@ CompressedSize 0
        fi
     done
 
-    # write Resources/postupgrade)
+    # write Resources/postupgrade
     for cmp in $pp_components; do
        if test -s $pp_wrkdir/%postup.$cmp; then
            if test ! -s $Resources/postupgrade; then
@@ -6791,7 +6991,7 @@ CompressedSize 0
        fi
     done
 
-    # write Resources/preremove)
+    # write Resources/preremove
     for cmp in $pp_components; do
        if test -s $pp_wrkdir/%preun.$cmp; then
            if test ! -s $Resources/preremove; then
@@ -6803,7 +7003,7 @@ CompressedSize 0
        fi
     done
 
-    # write Resources/postremove)
+    # write Resources/postremove
     for cmp in $pp_components; do
        if test -s $pp_wrkdir/%postun.$cmp; then
            if test ! -s $Resources/postremove; then
@@ -6822,29 +7022,194 @@ CompressedSize 0
     fi
 
     # Create the bill-of-materials (Archive.bom)
-    cat $pp_wrkdir/%files.* | pp_macos_files_bom | sort |
+    cat $filelists | pp_macos_files_bom | sort |
        pp_macos_bom_fix_parents > $pp_wrkdir/tmp.bomls
 
     pp_macos_mkbom $pp_wrkdir/tmp.bomls $Contents/Archive.bom
 
     # Create the cpio archive (Archive.pax.gz)
-    # On 10.5, we used "-f -" to write explicitly to stdout
     (
     cd $pp_destdir &&
-    cat $pp_wrkdir/%files.* | awk '{ print "." $6 }' | sed '/\/$/d' | sort | /bin/pax -w -f - | gzip -9 -c > $Contents/Archive.pax.gz
+    awk '{ print "." $6 }' $filelists | sed 's:/$::' | sort | /usr/bin/cpio -o | pp_macos_rewrite_cpio $filelists | gzip -9f -c > $Contents/Archive.pax.gz
     )
 
-       $pp_macos_sudo rm -rf $pp_wrkdir/bom_stage
+    test -d $pp_wrkdir/bom_stage && $pp_macos_sudo rm -rf $pp_wrkdir/bom_stage
 
+    rm -f ${name}-${version}.dmg
     hdiutil create -fs HFS+ -srcfolder $pkgdir -volname $name ${name}-${version}.dmg
 }
 
+pp_backend_macos_flat () {
+    typeset pkgdir bundledir Resources lprojdir
+    typeset Info_plist Description_plist
+    typeset bundle_vendor bundle_version size numfiles cmp filelists
+
+    mac_version=`sw_vers -productVersion`
+    bundle_vendor=${pp_macos_bundle_vendor:-$vendor}
+
+    if test -z "$pp_macos_bundle_version"; then
+        bundle_version=`echo "$version.0.0.0" | sed -n -e 's/[^0-9.]//g' \
+            -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/p'`
+    else
+        bundle_version="$pp_macos_bundle_version"
+    fi
+    source_version=`echo $version | sed 's/.*\.//'`
+
+    # build the flat package layout
+    pkgdir=$pp_wrkdir/pkg
+    bundledir=$pp_wrkdir/pkg/$name.pkg
+    Resources=$pkgdir/Resources
+    lprojdir=$Resources/en.lproj
+    mkdir $pkgdir $bundledir $Resources $lprojdir ||
+       pp_error "Can't make package temporary directories"
+
+    # Find file lists (%files.* includes ignore files)
+    for cmp in $pp_components; do
+       test -f $pp_wrkdir/%files.$cmp && filelists="$filelists${filelists:+ }$pp_wrkdir/%files.$cmp"
+    done
+
+    # compute the installed size and number of files/dirs
+    size=`cat $filelists | pp_macos_files_size`
+    numfiles=`cat $filelists | wc -l`
+    numfiles="${numfiles##* }"
+
+    # Write Distribution file
+    cat <<-. >$pkgdir/Distribution
+       <?xml version="1.0" encoding="UTF-8"?>
+       <installer-script minSpecVersion="1.000000" authoringTool="com.quest.rc.PolyPkg" authoringToolVersion="$pp_version" authoringToolBuild="$pp_revision">
+           <title>$name $version</title>
+           <options customize="never" allow-external-scripts="no"/>
+           <domains enable_localSystem="true"/>
+.
+    if test -n "$pp_macos_pkg_welcome"; then
+       cp -R "${pp_macos_pkg_welcome}" $Resources
+       echo "    <welcome file=\"${pp_macos_pkg_welcome##*/}\"/>" >>$pkgdir/Distribution
+    fi
+    if test -n "$pp_macos_pkg_readme"; then
+       cp -R "${pp_macos_pkg_readme}" $Resources
+       echo "    <readme file=\"${pp_macos_pkg_readme##*/}\"/>" >>$pkgdir/Distribution
+    fi
+    if test -n "$pp_macos_pkg_license"; then
+       cp -R "${pp_macos_pkg_license}" $Resources
+       echo "    <license file=\"${pp_macos_pkg_license##*/}\"/>" >>$pkgdir/Distribution
+    fi
+    cat <<-. >>$pkgdir/Distribution
+           <choices-outline>
+               <line choice="choice0"/>
+           </choices-outline>
+           <choice id="choice0" title="$name $version">
+               <pkg-ref id="${pp_macos_bundle_id}"/>
+           </choice>
+           <pkg-ref id="${pp_macos_bundle_id}" installKBytes="$size" version="$version" auth="Root">#$name.pkg</pkg-ref>
+       </installer-script>
+.
+
+    # write scripts archive
+    # XXX - missing preupgrade, preflight, postflight
+    mkdir $pp_wrkdir/scripts
+    for cmp in $pp_components; do
+       if test -s $pp_wrkdir/%pre.$cmp; then
+           if test ! -s $pp_wrkdir/scripts/preinstall; then
+               echo "#!/bin/sh" > $pp_wrkdir/scripts/preinstall
+               chmod +x $pp_wrkdir/scripts/preinstall
+           fi
+           cat $pp_wrkdir/%pre.$cmp >> $pp_wrkdir/scripts/preinstall
+           echo : >> $pp_wrkdir/scripts/preinstall
+       fi
+       if test -s $pp_wrkdir/%post.$cmp; then
+           if test ! -s $pp_wrkdir/scripts/postinstall; then
+               echo "#!/bin/sh" > $pp_wrkdir/scripts/postinstall
+               chmod +x $pp_wrkdir/scripts/postinstall
+           fi
+           cat $pp_wrkdir/%post.$cmp >> $pp_wrkdir/scripts/postinstall
+           echo : >> $pp_wrkdir/scripts/postinstall
+       fi
+       if test -s $pp_wrkdir/%postup.$cmp; then
+           if test ! -s $pp_wrkdir/scripts/postupgrade; then
+               echo "#!/bin/sh" > $pp_wrkdir/scripts/postupgrade
+               chmod +x $pp_wrkdir/scripts/postupgrade
+           fi
+           cat $pp_wrkdir/%postup.$cmp >> $pp_wrkdir/scripts/postupgrade
+           echo : >> $pp_wrkdir/scripts/postupgrade
+       fi
+       # XXX - not supported
+       if test -s $pp_wrkdir/%preun.$cmp; then
+           if test ! -s $pp_wrkdir/scripts/preremove; then
+               echo "#!/bin/sh" > $pp_wrkdir/scripts/preremove
+               chmod +x $pp_wrkdir/scripts/preremove
+           fi
+           cat $pp_wrkdir/%preun.$cmp >> $pp_wrkdir/scripts/preremove
+           echo : >> $pp_wrkdir/scripts/preremove
+       fi
+       # XXX - not supported
+       if test -s $pp_wrkdir/%postun.$cmp; then
+           if test ! -s $pp_wrkdir/scripts/postremove; then
+               echo "#!/bin/sh" > $pp_wrkdir/scripts/postremove
+               chmod +x $pp_wrkdir/scripts/postremove
+           fi
+           cat $pp_wrkdir/%postun.$cmp >> $pp_wrkdir/scripts/postremove
+           echo : >> $pp_wrkdir/scripts/postremove
+       fi
+    done
+    if test "`echo $pp_wrkdir/scripts/*`" != "$pp_wrkdir/scripts/*"; then
+       # write scripts archive, scripts are mode 0755 uid/gid 0/0
+       # resetting the owner and mode is not strictly required
+       (
+       cd $pp_wrkdir/scripts || pp_error "Can't cd to $pp_wrkdir/scripts"
+       rm -f $pp_wrkdir/tmp.files.scripts
+       for s in *; do
+           echo "f 0755 0 0 - ./$s" >>$pp_wrkdir/tmp.files.scripts
+       done
+       find . -type f | /usr/bin/cpio -o | pp_macos_rewrite_cpio $pp_wrkdir/tmp.files.scripts | gzip -9f -c > $bundledir/Scripts
+       )
+    fi
+
+    # Write PackageInfo file
+    cat <<-. >$bundledir/PackageInfo
+       <?xml version="1.0" encoding="UTF-8"?>
+       <pkg-info format-version="2" identifier="${pp_macos_bundle_id}" version="$version" install-location="/" relocatable="false" overwrite-permissions="true" followSymLinks="true" auth="root">
+           <payload installKBytes="$size" numberOfFiles="$numfiles"/>
+.
+    if test -s $bundledir/Scripts; then
+       echo "    <scripts>" >>$bundledir/PackageInfo
+       for s in preflight postflight preinstall postinstall preupgrade postupgrade; do
+           if test -s "$pp_wrkdir/scripts/$s"; then
+               echo "  <$s file=\"$s\"/>" >>$bundledir/PackageInfo
+           fi
+       done
+       echo "    </scripts>" >>$bundledir/PackageInfo
+    fi
+    cat <<-. >>$bundledir/PackageInfo
+       </pkg-info>
+.
+
+    # Create the bill-of-materials (Bom)
+    cat $filelists | pp_macos_files_bom | sort |
+       pp_macos_bom_fix_parents > $pp_wrkdir/tmp.bomls
+    pp_macos_mkbom $pp_wrkdir/tmp.bomls $bundledir/Bom
+
+    # Create the cpio payload
+    (
+    cd $pp_destdir || pp_error "Can't cd to $pp_destdir"
+    awk '{ print "." $6 }' $filelists | sed 's:/$::' | sort | /usr/bin/cpio -o | pp_macos_rewrite_cpio $filelists | gzip -9f -c > $bundledir/Payload
+    )
+
+    test -d $pp_wrkdir/bom_stage && $pp_macos_sudo rm -rf $pp_wrkdir/bom_stage
+
+    # Create the flat package with xar (like pkgutil --flatten does)
+    (cd $pkgdir && /usr/bin/xar --distribution --no-compress Scripts --no-compress Payload -jcf "../$name-$version.pkg" *)
+}
+
 pp_backend_macos_cleanup () {
     :
 }
 
 pp_backend_macos_names () {
-    echo ${name}.pkg
+    case "$pp_macos_pkg_type" in
+       bundle) echo ${name}.pkg;;
+       flat) echo ${name}-${version}.pkg;;
+       *) pp_error "unsupported package type $pp_macos_pkg_type";;
+    esac
 }
 
 pp_backend_macos_install_script () {
index 49ed68e874030c46bf92f0ac595d2e061820f9e1..5e6e6ab64625e24c4dd70672911aba96d39e53dc 100644 (file)
@@ -64,8 +64,7 @@ install_uid = 0
 install_gid = 0
 
 # OS dependent defines
-DEFS = @OSDEFS@ -D_PATH_SUDO_CONF=\"$(sysconfdir)/sudo.conf\" \
-       -DLOCALEDIR=\"$(localedir)\" 
+DEFS = @OSDEFS@ -DLOCALEDIR=\"$(localedir)\" 
 
 #### End of system configuration section. ####
 
@@ -73,9 +72,9 @@ SHELL = @SHELL@
 
 PROGS = @PROGS@
 
-OBJS = conversation.o error.o exec.o exec_pty.o get_pty.o net_ifs.o \
-       load_plugins.o parse_args.o sudo.o sudo_edit.o tgetpass.o \
-       ttysize.o utmp.o @SUDO_OBJS@
+OBJS = conversation.o error.o exec.o exec_common.o exec_pty.o get_pty.o \
+       net_ifs.o load_plugins.o parse_args.o sudo.o sudo_edit.o tgetpass.o \
+       ttyname.o ttysize.o utmp.o @SUDO_OBJS@
 
 LIBOBJDIR = $(top_builddir)/@ac_config_libobj_dir@/
 
@@ -100,12 +99,12 @@ sudo: $(OBJS) $(LT_LIBS)
 libsudo_noexec.la: sudo_noexec.lo
        $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LTLDFLAGS) -o $@ sudo_noexec.lo -avoid-version -rpath $(noexecdir)
 
-sesh: sesh.o
-       $(CC) -o $@ sesh.o
+sesh: sesh.o error.o exec_common.o @LIBINTL@ $(LT_LIBS)
+       $(LIBTOOL) --mode=link $(CC) -o $@ sesh.o error.o exec_common.o $(LDFLAGS) @LIBINTL@ $(LIBS) -static-libtool-libs
 
 pre-install:
 
-install: install-dirs install-binaries @INSTALL_NOEXEC@
+install: install-binaries @INSTALL_NOEXEC@
 
 install-dirs:
        $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(bindir) \
@@ -124,7 +123,7 @@ install-includes:
 # We install sudo_noexec by hand so we can avoid a "lib" prefix
 # and a version number.  Since we use LD_PRELOAD, neither is needed.
 install-noexec: install-dirs libsudo_noexec.la
-       if [ -f .libs/lib$(noexecfile) ]; then $(INSTALL) -b~ -O $(install_uid) -G $(install_gid) -M 0755 .libs/lib$(noexecfile) $(DESTDIR)$(noexecdir)/$(noexecfile); fi
+       if [ -f .libs/lib$(noexecfile) ]; then $(INSTALL) -b~ -O $(install_uid) -G $(install_gid) -m 0755 .libs/lib$(noexecfile) $(DESTDIR)$(noexecdir)/$(noexecfile); fi
 
 install-plugin:
 
@@ -153,78 +152,112 @@ cleandir: realclean
 # Autogenerated dependencies, do not modify
 conversation.o: $(srcdir)/conversation.c $(top_builddir)/config.h \
                 $(srcdir)/sudo.h $(top_builddir)/pathnames.h \
-                $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
-                $(incdir)/fileops.h $(incdir)/list.h $(incdir)/gettext.h \
-                $(incdir)/sudo_plugin.h
+                $(top_srcdir)/compat/stdbool.h $(incdir)/missing.h \
+                $(incdir)/alloc.h $(incdir)/error.h $(incdir)/fileops.h \
+                $(incdir)/list.h $(incdir)/sudo_conf.h $(incdir)/list.h \
+                $(incdir)/sudo_debug.h $(incdir)/gettext.h \
+                $(incdir)/sudo_plugin.h $(srcdir)/sudo_plugin_int.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/conversation.c
 error.o: $(srcdir)/error.c $(top_builddir)/config.h $(incdir)/missing.h \
          $(incdir)/error.h $(incdir)/gettext.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/error.c
 exec.o: $(srcdir)/exec.c $(top_builddir)/config.h $(srcdir)/sudo.h \
-        $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/alloc.h \
-        $(incdir)/error.h $(incdir)/fileops.h $(incdir)/list.h \
-        $(incdir)/gettext.h $(srcdir)/sudo_exec.h $(incdir)/sudo_plugin.h \
+        $(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
+        $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
+        $(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_conf.h \
+        $(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
+        $(srcdir)/sudo_exec.h $(incdir)/sudo_plugin.h \
         $(srcdir)/sudo_plugin_int.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/exec.c
+exec_common.o: $(srcdir)/exec_common.c $(top_builddir)/config.h \
+               $(srcdir)/sudo.h $(top_builddir)/pathnames.h \
+               $(top_srcdir)/compat/stdbool.h $(incdir)/missing.h \
+               $(incdir)/alloc.h $(incdir)/error.h $(incdir)/fileops.h \
+               $(incdir)/list.h $(incdir)/sudo_conf.h $(incdir)/list.h \
+               $(incdir)/sudo_debug.h $(incdir)/gettext.h $(srcdir)/sudo_exec.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/exec_common.c
 exec_pty.o: $(srcdir)/exec_pty.c $(top_builddir)/config.h $(srcdir)/sudo.h \
-            $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/alloc.h \
-            $(incdir)/error.h $(incdir)/fileops.h $(incdir)/list.h \
-            $(incdir)/gettext.h $(srcdir)/sudo_exec.h $(incdir)/sudo_plugin.h \
+            $(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
+            $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
+            $(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_conf.h \
+            $(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
+            $(srcdir)/sudo_exec.h $(incdir)/sudo_plugin.h \
             $(srcdir)/sudo_plugin_int.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/exec_pty.c
 get_pty.o: $(srcdir)/get_pty.c $(top_builddir)/config.h $(srcdir)/sudo.h \
-           $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/alloc.h \
-           $(incdir)/error.h $(incdir)/fileops.h $(incdir)/list.h \
-           $(incdir)/gettext.h
+           $(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
+           $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
+           $(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_conf.h \
+           $(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/get_pty.c
 load_plugins.o: $(srcdir)/load_plugins.c $(top_builddir)/config.h \
                 $(top_srcdir)/compat/dlfcn.h $(srcdir)/sudo.h \
-                $(top_builddir)/pathnames.h $(incdir)/missing.h \
-                $(incdir)/alloc.h $(incdir)/error.h $(incdir)/fileops.h \
-                $(incdir)/list.h $(incdir)/gettext.h $(incdir)/sudo_plugin.h \
-                $(srcdir)/sudo_plugin_int.h
+                $(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
+                $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
+                $(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_conf.h \
+                $(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
+                $(incdir)/sudo_plugin.h $(srcdir)/sudo_plugin_int.h \
+                $(incdir)/sudo_conf.h $(incdir)/list.h $(incdir)/sudo_debug.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/load_plugins.c
 net_ifs.o: $(srcdir)/net_ifs.c $(top_builddir)/config.h $(incdir)/missing.h \
-           $(incdir)/alloc.h $(incdir)/error.h $(incdir)/gettext.h
+           $(incdir)/alloc.h $(incdir)/error.h $(incdir)/sudo_debug.h \
+           $(incdir)/gettext.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/net_ifs.c
 parse_args.o: $(srcdir)/parse_args.c $(top_builddir)/config.h ./sudo_usage.h \
-              $(srcdir)/sudo.h $(top_builddir)/pathnames.h $(incdir)/missing.h \
+              $(srcdir)/sudo.h $(top_builddir)/pathnames.h \
+              $(top_srcdir)/compat/stdbool.h $(incdir)/missing.h \
               $(incdir)/alloc.h $(incdir)/error.h $(incdir)/fileops.h \
-              $(incdir)/list.h $(incdir)/gettext.h $(incdir)/lbuf.h
+              $(incdir)/list.h $(incdir)/sudo_conf.h $(incdir)/list.h \
+              $(incdir)/sudo_debug.h $(incdir)/gettext.h $(incdir)/lbuf.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/parse_args.c
 preload.o: $(srcdir)/preload.c $(top_builddir)/config.h $(incdir)/sudo_plugin.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/preload.c
 selinux.o: $(srcdir)/selinux.c $(top_builddir)/config.h $(srcdir)/sudo.h \
-           $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/alloc.h \
-           $(incdir)/error.h $(incdir)/fileops.h $(incdir)/list.h \
-           $(incdir)/gettext.h
+           $(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
+           $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
+           $(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_conf.h \
+           $(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/selinux.c
-sesh.o: $(srcdir)/sesh.c $(top_builddir)/config.h $(incdir)/missing.h \
-        $(incdir)/gettext.h
+sesh.o: $(srcdir)/sesh.c $(top_builddir)/config.h \
+        $(top_srcdir)/compat/stdbool.h $(incdir)/missing.h $(incdir)/gettext.h \
+        $(incdir)/error.h $(incdir)/sudo_conf.h $(incdir)/list.h \
+        $(incdir)/sudo_debug.h $(srcdir)/sudo_exec.h $(incdir)/sudo_plugin.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/sesh.c
 sudo.o: $(srcdir)/sudo.c $(top_builddir)/config.h $(srcdir)/sudo.h \
-        $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/alloc.h \
-        $(incdir)/error.h $(incdir)/fileops.h $(incdir)/list.h \
-        $(incdir)/gettext.h $(incdir)/sudo_plugin.h \
-        $(srcdir)/sudo_plugin_int.h ./sudo_usage.h
+        $(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
+        $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
+        $(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_conf.h \
+        $(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
+        $(incdir)/sudo_plugin.h $(srcdir)/sudo_plugin_int.h ./sudo_usage.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/sudo.c
 sudo_edit.o: $(srcdir)/sudo_edit.c $(top_builddir)/config.h $(srcdir)/sudo.h \
-             $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/alloc.h \
-             $(incdir)/error.h $(incdir)/fileops.h $(incdir)/list.h \
-             $(incdir)/gettext.h
+             $(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
+             $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
+             $(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_conf.h \
+             $(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/sudo_edit.c
 sudo_noexec.lo: $(srcdir)/sudo_noexec.c $(top_builddir)/config.h \
                 $(incdir)/missing.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/sudo_noexec.c
 tgetpass.o: $(srcdir)/tgetpass.c $(top_builddir)/config.h $(srcdir)/sudo.h \
-            $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/alloc.h \
-            $(incdir)/error.h $(incdir)/fileops.h $(incdir)/list.h \
-            $(incdir)/gettext.h
+            $(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
+            $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
+            $(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_conf.h \
+            $(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/tgetpass.c
-ttysize.o: $(srcdir)/ttysize.c $(top_builddir)/config.h $(incdir)/missing.h
+ttyname.o: $(srcdir)/ttyname.c $(top_builddir)/config.h $(srcdir)/sudo.h \
+           $(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
+           $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
+           $(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_conf.h \
+           $(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/ttyname.c
+ttysize.o: $(srcdir)/ttysize.c $(top_builddir)/config.h $(incdir)/missing.h \
+           $(incdir)/sudo_debug.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/ttysize.c
 utmp.o: $(srcdir)/utmp.c $(top_builddir)/config.h $(srcdir)/sudo.h \
-        $(top_builddir)/pathnames.h $(incdir)/missing.h $(incdir)/alloc.h \
-        $(incdir)/error.h $(incdir)/fileops.h $(incdir)/list.h \
-        $(incdir)/gettext.h $(srcdir)/sudo_exec.h
+        $(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
+        $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
+        $(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_conf.h \
+        $(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
+        $(srcdir)/sudo_exec.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/utmp.c
index fa40f791a0434174c477a8c18fb417c5ac038c1c..a2dab5a7c385b142a81ee69fe8f6af65583c4241 100644 (file)
 
 #include "sudo.h"
 #include "sudo_plugin.h"
+#include "sudo_plugin_int.h"
 
 extern int tgetpass_flags; /* XXX */
 
+#if defined(HAVE_DLOPEN) || defined(HAVE_SHL_LOAD)
+sudo_conv_t sudo_conv; /* NULL in sudo front-end */
+#endif
+
 /*
  * Sudo conversation function.
  */
@@ -91,6 +96,10 @@ sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[],
                if (msg->msg)
                    (void) fputs(msg->msg, stderr);
                break;
+           case SUDO_CONV_DEBUG_MSG:
+               if (msg->msg)
+                   sudo_debug_write(msg->msg, strlen(msg->msg));
+               break;
            default:
                goto err;
        }
index ed3ccabd199db818458dd89f6a3f0f5814527796..56108c1f6e68f21b3f66317de559a3e36b54be3c 100644 (file)
@@ -33,7 +33,7 @@ static void _warning(int, const char *, va_list);
        void cleanup(int);
 
 void
-error(int eval, const char *fmt, ...)
+error2(int eval, const char *fmt, ...)
 {
        va_list ap;
        va_start(ap, fmt);
@@ -44,7 +44,7 @@ error(int eval, const char *fmt, ...)
 }
 
 void
-errorx(int eval, const char *fmt, ...)
+errorx2(int eval, const char *fmt, ...)
 {
        va_list ap;
        va_start(ap, fmt);
@@ -55,7 +55,7 @@ errorx(int eval, const char *fmt, ...)
 }
 
 void
-warning(const char *fmt, ...)
+warning2(const char *fmt, ...)
 {
        va_list ap;
        va_start(ap, fmt);
@@ -64,7 +64,7 @@ warning(const char *fmt, ...)
 }
 
 void
-warningx(const char *fmt, ...)
+warningx2(const char *fmt, ...)
 {
        va_list ap;
        va_start(ap, fmt);
index fab19803e829d5b8723dfc1100c51639935c1e16..80e87177ac5b9a20addeadcbe6cdb6a1b8ba35c5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2011 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2009-2012 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
@@ -74,34 +74,13 @@ struct sigforward {
 TQ_DECLARE(sigforward)
 static struct sigforward_list sigfwd_list;
 
-static int handle_signals(int fd, pid_t child, int log_io,
+static int handle_signals(int sv[2], pid_t child, int log_io,
     struct command_status *cstat);
 static void forward_signals(int fd);
 static void schedule_signal(int signo);
-
-/*
- * Like execve(2) but falls back to running through /bin/sh
- * ala execvp(3) if we get ENOEXEC.
- */
-int
-my_execve(const char *path, char *const argv[], char *const envp[])
-{
-    execve(path, argv, envp);
-    if (errno == ENOEXEC) {
-       int argc;
-       char **nargv;
-
-       for (argc = 0; argv[argc] != NULL; argc++)
-           continue;
-       nargv = emalloc2(argc + 2, sizeof(char *));
-       nargv[0] = "sh";
-       nargv[1] = (char *)path;
-       memcpy(nargv + 2, argv + 1, argc * sizeof(char *));
-       execve(_PATH_BSHELL, nargv, envp);
-       efree(nargv);
-    }
-    return -1;
-}
+#ifdef SA_SIGINFO
+static void handler_nofwd(int s, siginfo_t *info, void *context);
+#endif
 
 /*
  * Fork and execute a command, returns the child's pid.
@@ -112,6 +91,7 @@ static int fork_cmnd(struct command_details *details, int sv[2])
     struct command_status cstat;
     sigaction_t sa;
     pid_t child;
+    debug_decl(fork_cmnd, SUDO_DEBUG_EXEC)
 
     zero_bytes(&sa, sizeof(sa));
     sigemptyset(&sa.sa_mask);
@@ -131,23 +111,39 @@ static int fork_cmnd(struct command_details *details, int sv[2])
        close(signal_pipe[1]);
        fcntl(sv[1], F_SETFD, FD_CLOEXEC);
        restore_signals();
-       if (exec_setup(details, NULL, -1) == TRUE) {
+       if (exec_setup(details, NULL, -1) == true) {
            /* headed for execve() */
-           if (details->closefrom >= 0)
-               closefrom(details->closefrom);
+           sudo_debug_execve(SUDO_DEBUG_INFO, details->command,
+               details->argv, details->envp);
+           if (details->closefrom >= 0) {
+               int maxfd = details->closefrom;
+               dup2(sv[1], maxfd);
+               (void)fcntl(maxfd, F_SETFD, FD_CLOEXEC);
+               sv[1] = maxfd++;
+               if (sudo_debug_fd_set(maxfd) != -1)
+                   maxfd++;
+               closefrom(maxfd);
+           }
 #ifdef HAVE_SELINUX
-           if (ISSET(details->flags, CD_RBAC_ENABLED))
-               selinux_execve(details->command, details->argv, details->envp);
-           else
+           if (ISSET(details->flags, CD_RBAC_ENABLED)) {
+               selinux_execve(details->command, details->argv, details->envp,
+                   ISSET(details->flags, CD_NOEXEC));
+           } else
 #endif
-               my_execve(details->command, details->argv, details->envp);
+           {
+               sudo_execve(details->command, details->argv, details->envp,
+                   ISSET(details->flags, CD_NOEXEC));
+           }
+           sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to exec %s: %s",
+               details->command, strerror(errno));
        }
        cstat.type = CMD_ERRNO;
        cstat.val = errno;
        send(sv[1], &cstat, sizeof(cstat), 0);
+       sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, 1);
        _exit(1);
     }
-    return child;
+    debug_return_int(child);
 }
 
 static struct signal_state {
@@ -177,9 +173,12 @@ void
 save_signals(void)
 {
     struct signal_state *ss;
+    debug_decl(save_signals, SUDO_DEBUG_EXEC)
 
     for (ss = saved_signals; ss->signo != -1; ss++)
        sigaction(ss->signo, NULL, &ss->sa);
+
+    debug_return;
 }
 
 /*
@@ -189,9 +188,12 @@ void
 restore_signals(void)
 {
     struct signal_state *ss;
+    debug_decl(restore_signals, SUDO_DEBUG_EXEC)
 
     for (ss = saved_signals; ss->signo != -1; ss++)
        sigaction(ss->signo, &ss->sa, NULL);
+
+    debug_return;
 }
 
 /*
@@ -200,13 +202,15 @@ restore_signals(void)
  * we fact that we have two different controlling terminals to deal with.
  */
 int
-sudo_execve(struct command_details *details, struct command_status *cstat)
+sudo_execute(struct command_details *details, struct command_status *cstat)
 {
-    int maxfd, n, nready, sv[2], log_io = FALSE;
+    int maxfd, n, nready, sv[2];
     const char *utmp_user = NULL;
+    bool log_io = false;
     fd_set *fdsr, *fdsw;
     sigaction_t sa;
     pid_t child;
+    debug_decl(sudo_execute, SUDO_DEBUG_EXEC)
 
     /* If running in background mode, fork and exit. */
     if (ISSET(details->flags, CD_BACKGROUND)) {
@@ -214,13 +218,15 @@ sudo_execve(struct command_details *details, struct command_status *cstat)
            case -1:
                cstat->type = CMD_ERRNO;
                cstat->val = errno;
-               return -1;
+               debug_return_int(-1);
            case 0:
                /* child continues without controlling terminal */
                (void)setpgid(0, 0);
                break;
            default:
                /* parent exits (but does not flush buffers) */
+               sudo_debug_exit_int(__func__, __FILE__, __LINE__,
+                   sudo_debug_subsys, 0);
                _exit(0);
        }
     }
@@ -231,10 +237,10 @@ sudo_execve(struct command_details *details, struct command_status *cstat)
      * as the io plugin tailqueue will be empty and no I/O logging will occur.
      */
     if (!tq_empty(&io_plugins) || ISSET(details->flags, CD_USE_PTY)) {
-       log_io = TRUE;
+       log_io = true;
        if (ISSET(details->flags, CD_SET_UTMP))
            utmp_user = details->utmp_user ? details->utmp_user : user_details.username;
-       sudo_debug(8, "allocate pty for I/O logging");
+       sudo_debug_printf(SUDO_DEBUG_INFO, "allocate pty for I/O logging");
        pty_setup(details->euid, user_details.tty, utmp_user);
     }
 
@@ -256,21 +262,35 @@ sudo_execve(struct command_details *details, struct command_status *cstat)
     sigemptyset(&sa.sa_mask);
 
     /*
-     * Signals for forward to the child process (excluding SIGALRM and SIGCHLD).
+     * Signals to forward to the child process (excluding SIGALRM and SIGCHLD).
      * Note: HP-UX select() will not be interrupted if SA_RESTART set.
      */
     sa.sa_flags = SA_INTERRUPT; /* do not restart syscalls */
     sa.sa_handler = handler;
     sigaction(SIGALRM, &sa, NULL);
     sigaction(SIGCHLD, &sa, NULL);
-    sigaction(SIGHUP, &sa, NULL);
-    sigaction(SIGINT, &sa, NULL);
     sigaction(SIGPIPE, &sa, NULL);
-    sigaction(SIGQUIT, &sa, NULL);
     sigaction(SIGTERM, &sa, NULL);
     sigaction(SIGUSR1, &sa, NULL);
     sigaction(SIGUSR2, &sa, NULL);
 
+    /*
+     * When not running the command in a pty, we do not want to
+     * forward signals generated by the kernel that the child will
+     * already have received either by virtue of being in the
+     * controlling tty's process group (SIGINT, SIGQUIT) or because
+     * the session is terminating (SIGHUP).
+     */
+#ifdef SA_SIGINFO
+    if (!log_io) {
+       sa.sa_flags |= SA_SIGINFO;
+       sa.sa_sigaction = handler_nofwd;
+    }
+#endif
+    sigaction(SIGHUP, &sa, NULL);
+    sigaction(SIGINT, &sa, NULL);
+    sigaction(SIGQUIT, &sa, NULL);
+
     /* Max fd we will be selecting on. */
     maxfd = MAX(sv[0], signal_pipe[0]);
 
@@ -313,6 +333,7 @@ sudo_execve(struct command_details *details, struct command_status *cstat)
        if (log_io)
            fd_set_iobs(fdsr, fdsw); /* XXX - better name */
        nready = select(maxfd + 1, fdsr, fdsw, NULL, NULL);
+       sudo_debug_printf(SUDO_DEBUG_DEBUG, "select returns %d", nready);
        if (nready == -1) {
            if (errno == EINTR)
                continue;
@@ -322,10 +343,10 @@ sudo_execve(struct command_details *details, struct command_status *cstat)
            forward_signals(sv[0]);
        }
        if (FD_ISSET(signal_pipe[0], fdsr)) {
-           n = handle_signals(signal_pipe[0], child, log_io, cstat);
+           n = handle_signals(sv, child, log_io, cstat);
            if (n == 0) {
                /* Child has exited, cstat is set, we are done. */
-               goto done;
+               break;
            }
            if (n == -1) {
                /* Error reading signal_pipe[0], should not happen. */
@@ -337,38 +358,55 @@ sudo_execve(struct command_details *details, struct command_status *cstat)
        if (FD_ISSET(sv[0], fdsr)) {
            /* read child status */
            n = recv(sv[0], cstat, sizeof(*cstat), 0);
-           if (n == -1) {
-               if (errno == EINTR)
-                   continue;
-               /*
-                * If not logging I/O we will receive ECONNRESET when
-                * the command is executed.  It is safe to ignore this.
-                */
-               if (log_io && errno != EAGAIN) {
-                   cstat->type = CMD_ERRNO;
-                   cstat->val = errno;
+           if (n != sizeof(*cstat)) {
+               if (n == -1) {
+                   if (errno == EINTR)
+                       continue;
+                   /*
+                    * If not logging I/O we may receive ECONNRESET when
+                    * the command is executed and sv is closed.
+                    * It is safe to ignore this.
+                    */
+                   if (log_io && errno != EAGAIN) {
+                       cstat->type = CMD_ERRNO;
+                       cstat->val = errno;
+                       break;
+                   }
+                   sudo_debug_printf(SUDO_DEBUG_ERROR,
+                       "failed to read child status: %s", strerror(errno));
+               } else {
+                   /* Short read or EOF. */
+                   sudo_debug_printf(SUDO_DEBUG_ERROR,
+                       "failed to read child status: %s",
+                       n ? "short read" : "EOF");
+                   /* XXX - should set cstat */
                    break;
                }
            }
            if (cstat->type == CMD_WSTATUS) {
                if (WIFSTOPPED(cstat->val)) {
                    /* Suspend parent and tell child how to resume on return. */
-                   sudo_debug(8, "child stopped, suspending parent");
+                   sudo_debug_printf(SUDO_DEBUG_INFO,
+                       "child stopped, suspending parent");
                    n = suspend_parent(WSTOPSIG(cstat->val));
                    schedule_signal(n);
                    continue;
                } else {
                    /* Child exited or was killed, either way we are done. */
+                   sudo_debug_printf(SUDO_DEBUG_INFO, "child exited or was killed");
                    break;
                }
            } else if (cstat->type == CMD_ERRNO) {
                /* Child was unable to execute command or broken pipe. */
+               sudo_debug_printf(SUDO_DEBUG_INFO, "errno from child: %s",
+                   strerror(cstat->val));
                break;
            }
        }
 
        if (perform_io(fdsr, fdsw, cstat) != 0) {
            /* I/O error, kill child if still alive and finish. */
+           sudo_debug_printf(SUDO_DEBUG_ERROR, "I/O error, terminating child");
            schedule_signal(SIGKILL);
            forward_signals(sv[0]);
            break;
@@ -388,7 +426,6 @@ sudo_execve(struct command_details *details, struct command_status *cstat)
     }
 #endif
 
-done:
     efree(fdsr);
     efree(fdsw);
     while (!tq_empty(&sigfwd_list)) {
@@ -397,7 +434,7 @@ done:
        efree(sigfwd);
     }
 
-    return cstat->type == CMD_ERRNO ? -1 : 0;
+    debug_return_int(cstat->type == CMD_ERRNO ? -1 : 0);
 }
 
 /*
@@ -405,12 +442,13 @@ done:
  * Returns -1 on error, 0 on child exit, else 1.
  */
 static int
-handle_signals(int fd, pid_t child, int log_io, struct command_status *cstat)
+handle_signals(int sv[2], pid_t child, int log_io, struct command_status *cstat)
 {
     unsigned char signo;
     ssize_t nread;
     int status;
     pid_t pid;
+    debug_decl(handle_signals, SUDO_DEBUG_EXEC)
 
     for (;;) {
        /* read signal pipe */
@@ -425,12 +463,13 @@ handle_signals(int fd, pid_t child, int log_io, struct command_status *cstat)
            /* If pipe is empty, we are done. */
            if (errno == EAGAIN)
                break;
-           sudo_debug(9, "error reading signal pipe %s", strerror(errno));
+           sudo_debug_printf(SUDO_DEBUG_ERROR, "error reading signal pipe %s",
+               strerror(errno));
            cstat->type = CMD_ERRNO;
            cstat->val = errno;
-           return -1;
+           debug_return_int(-1);
        }
-       sudo_debug(9, "received signal %d", signo);
+       sudo_debug_printf(SUDO_DEBUG_DIAG, "received signal %d", signo);
        if (signo == SIGCHLD) {
            /*
             * If logging I/O, child is the intermediate process,
@@ -440,8 +479,16 @@ handle_signals(int fd, pid_t child, int log_io, struct command_status *cstat)
                pid = waitpid(child, &status, WUNTRACED|WNOHANG);
            } while (pid == -1 && errno == EINTR);
            if (pid == child) {
-               /* If not logging I/O and child has exited we are done. */
-               if (!log_io) {
+               if (log_io) {
+                   /*
+                    * On BSD we get ECONNRESET on sv[0] if monitor dies
+                    * and select() will return with sv[0] readable.
+                    * On Linux that doesn't appear to happen so if the
+                    * monitor dies, shut down the socketpair to force a
+                    * select() notification.
+                    */
+                   (void) shutdown(sv[0], SHUT_WR);
+               } else {
                    if (WIFSTOPPED(status)) {
                        /*
                         * Save the controlling terminal's process group
@@ -464,10 +511,9 @@ handle_signals(int fd, pid_t child, int log_io, struct command_status *cstat)
                        /* Child has exited, we are done. */
                        cstat->type = CMD_WSTATUS;
                        cstat->val = status;
-                       return 0;
+                       debug_return_int(0);
                    }
                }
-               /* Else we get ECONNRESET on sv[0] if child dies. */
            }
        } else {
            if (log_io) {
@@ -476,13 +522,13 @@ handle_signals(int fd, pid_t child, int log_io, struct command_status *cstat)
            } else {
                /* Nothing listening on sv[0], send directly. */
                if (signo == SIGALRM)
-                   terminate_child(child, FALSE);
+                   terminate_child(child, false);
                else if (kill(child, signo) != 0)
                    warning("kill(%d, %d)", (int)child, signo);
            }
        }
     }
-    return 1;
+    debug_return_int(1);
 }
 
 /*
@@ -494,11 +540,12 @@ forward_signals(int sock)
     struct sigforward *sigfwd;
     struct command_status cstat;
     ssize_t nsent;
+    debug_decl(forward_signals, SUDO_DEBUG_EXEC)
 
     while (!tq_empty(&sigfwd_list)) {
        sigfwd = tq_first(&sigfwd_list);
-       sudo_debug(9, "sending signal %d to child over backchannel",
-           sigfwd->signo);
+       sudo_debug_printf(SUDO_DEBUG_INFO,
+           "sending signal %d to child over backchannel", sigfwd->signo);
        cstat.type = CMD_SIGNO;
        cstat.val = sigfwd->signo;
        do {
@@ -508,16 +555,20 @@ forward_signals(int sock)
        efree(sigfwd);
        if (nsent != sizeof(cstat)) {
            if (errno == EPIPE) {
+               sudo_debug_printf(SUDO_DEBUG_ERROR,
+                   "broken pipe writing to child over backchannel");
                /* Other end of socket gone, empty out sigfwd_list. */
                while (!tq_empty(&sigfwd_list)) {
                    sigfwd = tq_first(&sigfwd_list);
                    tq_remove(&sigfwd_list, sigfwd);
                    efree(sigfwd);
                }
+               /* XXX - child (monitor) is dead, we should exit too? */
            }
            break;
        }
     }
+    debug_return;
 }
 
 /*
@@ -527,12 +578,17 @@ static void
 schedule_signal(int signo)
 {
     struct sigforward *sigfwd;
+    debug_decl(schedule_signal, SUDO_DEBUG_EXEC)
+
+    sudo_debug_printf(SUDO_DEBUG_DIAG, "forwarding signal %d to child", signo);
 
     sigfwd = emalloc(sizeof(*sigfwd));
     sigfwd->prev = sigfwd;
     sigfwd->next = NULL;
     sigfwd->signo = signo;
     tq_append(&sigfwd_list, sigfwd);
+
+    debug_return;
 }
 
 /*
@@ -552,6 +608,30 @@ handler(int s)
        /* shut up glibc */;
 }
 
+#ifdef SA_SIGINFO
+/*
+ * Generic handler for signals passed from parent -> child.
+ * The other end of signal_pipe is checked in the main event loop.
+ * This version is for the non-pty case and does not forward
+ * signals that are generated by the kernel.
+ */
+static void
+handler_nofwd(int s, siginfo_t *info, void *context)
+{
+    unsigned char signo = (unsigned char)s;
+
+    /* Only forward user-generated signals. */
+    if (info->si_code <= 0) {
+       /*
+        * The pipe is non-blocking, if we overflow the kernel's pipe
+        * buffer we drop the signal.  This is not a problem in practice.
+        */
+       if (write(signal_pipe[1], &signo, sizeof(signo)) == -1)
+           /* shut up glibc */;
+    }
+}
+#endif /* SA_SIGINFO */
+
 /*
  * Open a pipe and make both ends non-blocking.
  * Returns 0 on success and -1 on error.
@@ -560,6 +640,7 @@ int
 pipe_nonblock(int fds[2])
 {
     int flags, rval;
+    debug_decl(pipe_nonblock, SUDO_DEBUG_EXEC)
 
     rval = pipe(fds);
     if (rval != -1) {
@@ -577,5 +658,5 @@ pipe_nonblock(int fds[2])
        }
     }
 
-    return rval;
+    debug_return_int(rval);
 }
diff --git a/src/exec_common.c b/src/exec_common.c
new file mode 100644 (file)
index 0000000..389aa5c
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2009-2012 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
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_PRIV_SET
+# include <priv.h>
+#endif
+#include <errno.h>
+
+#include "sudo.h"
+#include "sudo_exec.h"
+
+/*
+ * Disable execution of child processes in the command we are about
+ * to run.  On systems with privilege sets, we can remove the exec
+ * privilege.  On other systems we use LD_PRELOAD and the like.
+ */
+static char * const *
+disable_execute(char *const envp[])
+{
+#ifdef _PATH_SUDO_NOEXEC
+    char * const *ev;
+    char *preload, **nenvp;
+    int env_len = 0, env_size = 128;
+#endif /* _PATH_SUDO_NOEXEC */
+    debug_decl(disable_execute, SUDO_DEBUG_UTIL)
+
+#ifdef HAVE_PRIV_SET
+    /* Solaris privileges, remove PRIV_PROC_EXEC post-execve. */
+    if (priv_set(PRIV_OFF, PRIV_LIMIT, "PRIV_PROC_EXEC", NULL) == 0)
+       debug_return_ptr(envp);
+    warning(_("unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"));
+#endif /* HAVE_PRIV_SET */
+
+#ifdef _PATH_SUDO_NOEXEC
+    nenvp = emalloc2(env_size, sizeof(char *));
+
+    /*
+     * Preload a noexec file.  For a list of LD_PRELOAD-alikes, see
+     * http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
+     * XXX - need to support 32-bit and 64-bit variants
+     */
+# if defined(__darwin__) || defined(__APPLE__)
+    nenvp[env_len++] = "DYLD_FORCE_FLAT_NAMESPACE=";
+    preload = fmt_string("DYLD_INSERT_LIBRARIES", sudo_conf_noexec_path());
+# elif defined(__osf__) || defined(__sgi)
+    easprintf(&preload, "_RLD_LIST=%s:DEFAULT", sudo_conf_noexec_path());
+# elif defined(_AIX)
+    preload = fmt_string("LDR_PRELOAD", sudo_conf_noexec_path());
+# else
+    preload = fmt_string("LD_PRELOAD", sudo_conf_noexec_path());
+# endif
+    if (preload == NULL)
+       errorx(1, _("unable to allocate memory"));
+    nenvp[env_len++] = preload;
+
+    for (ev = envp; *ev != NULL; ev++) {
+       /*
+        * Prune out existing preloaded libraries.
+        * XXX - should append to new value instead.
+        */
+# if defined(__darwin__) || defined(__APPLE__)
+       if (strncmp(*ev, "DYLD_INSERT_LIBRARIES=", sizeof("DYLD_INSERT_LIBRARIES=") - 1) == 0)
+           continue;
+       if (strncmp(*ev, "DYLD_FORCE_FLAT_NAMESPACE=", sizeof("DYLD_INSERT_LIBRARIES=") - 1) == 0)
+           continue;
+# elif defined(__osf__) || defined(__sgi)
+       if (strncmp(*ev, "_RLD_LIST=", sizeof("_RLD_LIST=") - 1) == 0)
+           continue;
+# elif defined(_AIX)
+       if (strncmp(*ev, "LDR_PRELOAD=", sizeof("LDR_PRELOAD=") - 1) == 0)
+           continue;
+# else
+       if (strncmp(*ev, "LD_PRELOAD=", sizeof("LD_PRELOAD=") - 1) == 0)
+           continue;
+# endif
+       /* Need at least 2 slots for current element and a NULL. */
+       if (env_len + 2 > env_size) {
+           env_size += 128;
+           nenvp = erealloc3(nenvp, env_size, sizeof(char *));
+       }
+       nenvp[env_len++] = *ev;
+    }
+    nenvp[env_len] = NULL;
+    envp = nenvp;
+#endif /* _PATH_SUDO_NOEXEC */
+
+    debug_return_ptr(envp);
+}
+
+/*
+ * Like execve(2) but falls back to running through /bin/sh
+ * ala execvp(3) if we get ENOEXEC.
+ */
+int
+sudo_execve(const char *path, char *const argv[], char *const envp[], int noexec)
+{
+    /* Modify the environment as needed to disable further execve(). */
+    if (noexec)
+       envp = disable_execute(envp);
+
+    execve(path, argv, envp);
+    if (errno == ENOEXEC) {
+       int argc;
+       char **nargv;
+
+       for (argc = 0; argv[argc] != NULL; argc++)
+           continue;
+       nargv = emalloc2(argc + 2, sizeof(char *));
+       nargv[0] = "sh";
+       nargv[1] = (char *)path;
+       memcpy(nargv + 2, argv + 1, argc * sizeof(char *));
+       execve(_PATH_BSHELL, nargv, envp);
+       efree(nargv);
+    }
+    return -1;
+}
index 60ed7efc969e1184dd1524e39faacfc777b19a83..01fb6796cb2bbd06aa7b71294018e0667a61efff 100644 (file)
@@ -85,15 +85,13 @@ struct io_buffer {
     int off; /* write position (how much already consumed) */
     int rfd;  /* reader (producer) */
     int wfd; /* writer (consumer) */
-    int (*action)(const char *buf, unsigned int len);
+    bool (*action)(const char *buf, unsigned int len);
     char buf[16 * 1024];
 };
 
 static char slavename[PATH_MAX];
-static int foreground;
+static bool foreground, pipeline, tty_initialized;
 static int io_fds[6] = { -1, -1, -1, -1, -1, -1};
-static int pipeline = FALSE;
-static int tty_initialized;
 static int ttymode = TERM_COOKED;
 static pid_t ppgrp, child, child_pgrp;
 static sigset_t ttyblock;
@@ -101,7 +99,7 @@ static struct io_buffer *iobufs;
 
 static void flush_output(void);
 static int exec_monitor(struct command_details *details, int backchannel);
-static void exec_pty(struct command_details *detail);
+static void exec_pty(struct command_details *detail, int *errfd);
 static void sigwinch(int s);
 static void sync_ttysize(int src, int dst);
 static void deliver_signal(pid_t pid, int signo);
@@ -113,12 +111,16 @@ static int safe_close(int fd);
 void
 cleanup(int gotsignal)
 {
+    debug_decl(cleanup, SUDO_DEBUG_EXEC);
+
     if (!tq_empty(&io_plugins))
        term_restore(io_fds[SFD_USERTTY], 0);
 #ifdef HAVE_SELINUX
     selinux_restore_tty();
 #endif
     utmp_logout(slavename, 0); /* XXX - only if CD_SET_UTMP */
+
+    debug_return;
 }
 
 /*
@@ -129,6 +131,8 @@ cleanup(int gotsignal)
 void
 pty_setup(uid_t uid, const char *tty, const char *utmp_user)
 {
+    debug_decl(pty_setup, SUDO_DEBUG_EXEC);
+
     io_fds[SFD_USERTTY] = open(_PATH_TTY, O_RDWR|O_NOCTTY, 0);
     if (io_fds[SFD_USERTTY] != -1) {
        if (!get_pty(&io_fds[SFD_MASTER], &io_fds[SFD_SLAVE],
@@ -138,121 +142,123 @@ pty_setup(uid_t uid, const char *tty, const char *utmp_user)
        if (utmp_user != NULL)
            utmp_login(tty, slavename, io_fds[SFD_SLAVE], utmp_user);
     }
+
+    debug_return;
 }
 
 /* Call I/O plugin tty input log method. */
-static int
+static bool
 log_ttyin(const char *buf, unsigned int n)
 {
     struct plugin_container *plugin;
     sigset_t omask;
-    int rval = TRUE;
+    bool rval = true;
+    debug_decl(log_ttyin, SUDO_DEBUG_EXEC);
 
     sigprocmask(SIG_BLOCK, &ttyblock, &omask);
-
     tq_foreach_fwd(&io_plugins, plugin) {
        if (plugin->u.io->log_ttyin) {
            if (!plugin->u.io->log_ttyin(buf, n)) {
-               rval = FALSE;
+               rval = false;
                break;
            }
        }
     }
-
     sigprocmask(SIG_SETMASK, &omask, NULL);
-    return rval;
+
+    debug_return_bool(rval);
 }
 
 /* Call I/O plugin stdin log method. */
-static int
+static bool
 log_stdin(const char *buf, unsigned int n)
 {
     struct plugin_container *plugin;
     sigset_t omask;
-    int rval = TRUE;
+    bool rval = true;
+    debug_decl(log_stdin, SUDO_DEBUG_EXEC);
 
     sigprocmask(SIG_BLOCK, &ttyblock, &omask);
-
     tq_foreach_fwd(&io_plugins, plugin) {
        if (plugin->u.io->log_stdin) {
            if (!plugin->u.io->log_stdin(buf, n)) {
-               rval = FALSE;
+               rval = false;
                break;
            }
        }
     }
-
     sigprocmask(SIG_SETMASK, &omask, NULL);
-    return rval;
+
+    debug_return_bool(rval);
 }
 
 /* Call I/O plugin tty output log method. */
-static int
+static bool
 log_ttyout(const char *buf, unsigned int n)
 {
     struct plugin_container *plugin;
     sigset_t omask;
-    int rval = TRUE;
+    bool rval = true;
+    debug_decl(log_ttyout, SUDO_DEBUG_EXEC);
 
     sigprocmask(SIG_BLOCK, &ttyblock, &omask);
-
     tq_foreach_fwd(&io_plugins, plugin) {
        if (plugin->u.io->log_ttyout) {
            if (!plugin->u.io->log_ttyout(buf, n)) {
-               rval = FALSE;
+               rval = false;
                break;
            }
        }
     }
-
     sigprocmask(SIG_SETMASK, &omask, NULL);
-    return rval;
+
+    debug_return_bool(rval);
 }
 
 /* Call I/O plugin stdout log method. */
-static int
+static bool
 log_stdout(const char *buf, unsigned int n)
 {
     struct plugin_container *plugin;
     sigset_t omask;
-    int rval = TRUE;
+    bool rval = true;
+    debug_decl(log_stdout, SUDO_DEBUG_EXEC);
 
     sigprocmask(SIG_BLOCK, &ttyblock, &omask);
-
     tq_foreach_fwd(&io_plugins, plugin) {
        if (plugin->u.io->log_stdout) {
            if (!plugin->u.io->log_stdout(buf, n)) {
-               rval = FALSE;
+               rval = false;
                break;
            }
        }
     }
-
     sigprocmask(SIG_SETMASK, &omask, NULL);
-    return rval;
+
+    debug_return_bool(rval);
 }
 
 /* Call I/O plugin stderr log method. */
-static int
+static bool
 log_stderr(const char *buf, unsigned int n)
 {
     struct plugin_container *plugin;
     sigset_t omask;
-    int rval = TRUE;
+    bool rval = true;
+    debug_decl(log_stderr, SUDO_DEBUG_EXEC);
 
     sigprocmask(SIG_BLOCK, &ttyblock, &omask);
-
     tq_foreach_fwd(&io_plugins, plugin) {
        if (plugin->u.io->log_stderr) {
            if (!plugin->u.io->log_stderr(buf, n)) {
-               rval = FALSE;
+               rval = false;
                break;
            }
        }
     }
-
     sigprocmask(SIG_SETMASK, &omask, NULL);
-    return rval;
+
+    debug_return_bool(rval);
 }
 
 /*
@@ -263,15 +269,19 @@ log_stderr(const char *buf, unsigned int n)
 static void
 check_foreground(void)
 {
+    debug_decl(check_foreground, SUDO_DEBUG_EXEC);
+
     if (io_fds[SFD_USERTTY] != -1) {
        foreground = tcgetpgrp(io_fds[SFD_USERTTY]) == ppgrp;
        if (foreground && !tty_initialized) {
            if (term_copy(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE])) {
-               tty_initialized = 1;
+               tty_initialized = true;
                sync_ttysize(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE]);
            }
        }
     }
+
+    debug_return;
 }
 
 /*
@@ -284,6 +294,7 @@ suspend_parent(int signo)
 {
     sigaction_t sa, osa;
     int n, oldmode = ttymode, rval = 0;
+    debug_decl(suspend_parent, SUDO_DEBUG_EXEC);
 
     switch (signo) {
     case SIGTTOU:
@@ -321,7 +332,7 @@ suspend_parent(int signo)
        /* Suspend self and continue child when we resume. */
        sa.sa_handler = SIG_DFL;
        sigaction(signo, &sa, &osa);
-       sudo_debug(8, "kill parent %d", signo);
+       sudo_debug_printf(SUDO_DEBUG_INFO, "kill parent %d", signo);
        if (killpg(ppgrp, signo) != 0)
            warning("killpg(%d, %d)", (int)ppgrp, signo);
 
@@ -332,7 +343,7 @@ suspend_parent(int signo)
         * Only modify term if we are foreground process and either
         * the old tty mode was not cooked or child got SIGTT{IN,OU}
         */
-       sudo_debug(8, "parent is in %s, ttymode %d -> %d",
+       sudo_debug_printf(SUDO_DEBUG_INFO, "parent is in %s, ttymode %d -> %d",
            foreground ? "foreground" : "background", oldmode, ttymode);
 
        if (ttymode != TERM_COOKED) {
@@ -352,36 +363,47 @@ suspend_parent(int signo)
        break;
     }
 
-    return rval;
+    debug_return_int(rval);
 }
 
 /*
  * Kill child with increasing urgency.
  */
 void
-terminate_child(pid_t pid, int use_pgrp)
+terminate_child(pid_t pid, bool use_pgrp)
 {
+    debug_decl(terminate_child, SUDO_DEBUG_EXEC);
+
     /*
      * Note that SIGCHLD will interrupt the sleep()
      */
     if (use_pgrp) {
+       sudo_debug_printf(SUDO_DEBUG_INFO, "killpg %d SIGHUP", (int)pid);
        killpg(pid, SIGHUP);
+       sudo_debug_printf(SUDO_DEBUG_INFO, "killpg %d SIGTERM", (int)pid);
        killpg(pid, SIGTERM);
        sleep(2);
+       sudo_debug_printf(SUDO_DEBUG_INFO, "killpg %d SIGKILL", (int)pid);
        killpg(pid, SIGKILL);
     } else {
+       sudo_debug_printf(SUDO_DEBUG_INFO, "kill %d SIGHUP", (int)pid);
        kill(pid, SIGHUP);
+       sudo_debug_printf(SUDO_DEBUG_INFO, "kill %d SIGTERM", (int)pid);
        kill(pid, SIGTERM);
        sleep(2);
+       sudo_debug_printf(SUDO_DEBUG_INFO, "kill %d SIGKILL", (int)pid);
        kill(pid, SIGKILL);
     }
+
+    debug_return;
 }
 
 static struct io_buffer *
-io_buf_new(int rfd, int wfd, int (*action)(const char *, unsigned int),
+io_buf_new(int rfd, int wfd, bool (*action)(const char *, unsigned int),
     struct io_buffer *head)
 {
     struct io_buffer *iob;
+    debug_decl(io_buf_new, SUDO_DEBUG_EXEC);
 
     iob = emalloc(sizeof(*iob));
     zero_bytes(iob, sizeof(*iob));
@@ -389,7 +411,8 @@ io_buf_new(int rfd, int wfd, int (*action)(const char *, unsigned int),
     iob->wfd = wfd;
     iob->action = action;
     iob->next = head;
-    return iob;
+
+    debug_return_ptr(iob);
 }
 
 /*
@@ -401,6 +424,7 @@ perform_io(fd_set *fdsr, fd_set *fdsw, struct command_status *cstat)
 {
     struct io_buffer *iob;
     int n, errors = 0;
+    debug_decl(perform_io, SUDO_DEBUG_EXEC);
 
     for (iob = iobufs; iob; iob = iob->next) {
        if (iob->rfd != -1 && FD_ISSET(iob->rfd, fdsr)) {
@@ -413,6 +437,9 @@ perform_io(fd_set *fdsr, fd_set *fdsw, struct command_status *cstat)
                    if (errno == EAGAIN)
                        break;
                    if (errno != ENXIO && errno != EBADF) {
+                       sudo_debug_printf(SUDO_DEBUG_ERROR,
+                           "error reading fd %d: %s", iob->rfd,
+                           strerror(errno));
                        errors++;
                        break;
                    }
@@ -424,7 +451,7 @@ perform_io(fd_set *fdsr, fd_set *fdsw, struct command_status *cstat)
                    break;
                default:
                    if (!iob->action(iob->buf + iob->len, n))
-                       terminate_child(child, TRUE);
+                       terminate_child(child, true);
                    iob->len += n;
                    break;
            }
@@ -445,8 +472,11 @@ perform_io(fd_set *fdsr, fd_set *fdsw, struct command_status *cstat)
                    iob->wfd = -1;
                    continue;
                }
-               if (errno != EAGAIN)
+               if (errno != EAGAIN) {
                    errors++;
+                   sudo_debug_printf(SUDO_DEBUG_ERROR,
+                       "error writing fd %d: %s", iob->wfd, strerror(errno));
+               }
            } else {
                iob->off += n;
            }
@@ -456,7 +486,7 @@ perform_io(fd_set *fdsr, fd_set *fdsw, struct command_status *cstat)
        cstat->type = CMD_ERRNO;
        cstat->val = errno;
     }
-    return errors;
+    debug_return_int(errors);
 }
 
 /*
@@ -471,6 +501,7 @@ fork_pty(struct command_details *details, int sv[], int *maxfd)
     struct io_buffer *iob;
     int io_pipe[3][2], n;
     sigaction_t sa;
+    debug_decl(fork_pty, SUDO_DEBUG_EXEC);
         
     ppgrp = getpgrp(); /* parent's pgrp, so child can signal us */
      
@@ -521,7 +552,7 @@ fork_pty(struct command_details *details, int sv[], int *maxfd)
      */
     memset(io_pipe, 0, sizeof(io_pipe));
     if (io_fds[SFD_STDIN] == -1 || !isatty(STDIN_FILENO)) {
-       pipeline = TRUE;
+       pipeline = true;
        if (pipe(io_pipe[STDIN_FILENO]) != 0)
            error(1, _("unable to create pipe"));
        iobufs = io_buf_new(STDIN_FILENO, io_pipe[STDIN_FILENO][1],
@@ -529,7 +560,7 @@ fork_pty(struct command_details *details, int sv[], int *maxfd)
        io_fds[SFD_STDIN] = io_pipe[STDIN_FILENO][0];
     }
     if (io_fds[SFD_STDOUT] == -1 || !isatty(STDOUT_FILENO)) {
-       pipeline = TRUE;
+       pipeline = true;
        if (pipe(io_pipe[STDOUT_FILENO]) != 0)
            error(1, _("unable to create pipe"));
        iobufs = io_buf_new(io_pipe[STDOUT_FILENO][0], STDOUT_FILENO,
@@ -552,7 +583,7 @@ fork_pty(struct command_details *details, int sv[], int *maxfd)
     if (foreground) {
        /* Copy terminal attrs from user tty -> pty slave. */
        if (term_copy(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE])) {
-           tty_initialized = 1;
+           tty_initialized = true;
            sync_ttysize(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE]);
        }
 
@@ -578,7 +609,7 @@ fork_pty(struct command_details *details, int sv[], int *maxfd)
        close(signal_pipe[0]);
        close(signal_pipe[1]);
        fcntl(sv[1], F_SETFD, FD_CLOEXEC);
-       if (exec_setup(details, slavename, io_fds[SFD_SLAVE]) == TRUE) {
+       if (exec_setup(details, slavename, io_fds[SFD_SLAVE]) == true) {
            /* Close the other end of the stdin/stdout/stderr pipes and exec. */
            if (io_pipe[STDIN_FILENO][1])
                close(io_pipe[STDIN_FILENO][1]);
@@ -618,13 +649,14 @@ fork_pty(struct command_details *details, int sv[], int *maxfd)
            (void) fcntl(iob->wfd, F_SETFL, n | O_NONBLOCK);
     }
 
-    return child;
+    debug_return_int(child);
 }
 
 void
 pty_close(struct command_status *cstat)
 {
     int n;
+    debug_decl(pty_close, SUDO_DEBUG_EXEC);
 
     /* Flush any remaining output (the plugin already got it) */
     if (io_fds[SFD_USERTTY] != -1) {
@@ -660,6 +692,7 @@ pty_close(struct command_status *cstat)
        }
     }
     utmp_logout(slavename, cstat->type == CMD_WSTATUS ? cstat->val : 0); /* XXX - only if CD_SET_UTMP */
+    debug_return;
 }
 
 /*
@@ -670,6 +703,7 @@ void
 fd_set_iobs(fd_set *fdsr, fd_set *fdsw)
 {
     struct io_buffer *iob;
+    debug_decl(fd_set_iobs, SUDO_DEBUG_EXEC);
 
     for (iob = iobufs; iob; iob = iob->next) {
        if (iob->rfd == -1 && iob->wfd == -1)
@@ -694,18 +728,20 @@ fd_set_iobs(fd_set *fdsr, fd_set *fdsw)
                FD_SET(iob->wfd, fdsw);
        }
     }
+    debug_return;
 }
 
 static void
 deliver_signal(pid_t pid, int signo)
 {
     int status;
+    debug_decl(deliver_signal, SUDO_DEBUG_EXEC);
 
     /* Handle signal from parent. */
-    sudo_debug(8, "signal %d from parent", signo);
+    sudo_debug_printf(SUDO_DEBUG_INFO, "received signal %d from parent", signo);
     switch (signo) {
     case SIGALRM:
-       terminate_child(pid, TRUE);
+       terminate_child(pid, true);
        break;
     case SIGCONT_FG:
        /* Continue in foreground, grant it controlling tty. */
@@ -729,6 +765,7 @@ deliver_signal(pid_t pid, int signo)
        killpg(pid, signo);
        break;
     }
+    debug_return;
 }
 
 /*
@@ -739,33 +776,37 @@ static int
 send_status(int fd, struct command_status *cstat)
 {
     int n = -1;
+    debug_decl(send_status, SUDO_DEBUG_EXEC);
 
     if (cstat->type != CMD_INVALID) {
+       sudo_debug_printf(SUDO_DEBUG_INFO,
+           "sending status message to parent: [%d, %d]",
+           cstat->type, cstat->val);
        do {
            n = send(fd, cstat, sizeof(*cstat), 0);
        } while (n == -1 && errno == EINTR);
        if (n != sizeof(*cstat)) {
-           sudo_debug(8, "unable to send status to parent: %s",
-               strerror(errno));
-       } else {
-           sudo_debug(8, "sent status to parent");
+           sudo_debug_printf(SUDO_DEBUG_ERROR,
+               "unable to send status to parent: %s", strerror(errno));
        }
        cstat->type = CMD_INVALID; /* prevent re-sending */
     }
-    return n;
+    debug_return_int(n);
 }
 
 /*
  * Wait for child status after receiving SIGCHLD.
  * If the child was stopped, the status is send back to the parent.
  * Otherwise, cstat is filled in but not sent.
- * Returns TRUE if child is still alive, else FALSE.
+ * Returns true if child is still alive, else false.
  */
-static int
+static bool
 handle_sigchld(int backchannel, struct command_status *cstat)
 {
-    int status, alive = TRUE;
+    bool alive = true;
+    int status;
     pid_t pid;
+    debug_decl(handle_sigchld, SUDO_DEBUG_EXEC);
 
     /* read child status */
     do {
@@ -776,22 +817,25 @@ handle_sigchld(int backchannel, struct command_status *cstat)
            cstat->type = CMD_WSTATUS;
            cstat->val = status;
            if (WIFSTOPPED(status)) {
-               sudo_debug(8, "command stopped, signal %d", WSTOPSIG(status));
+               sudo_debug_printf(SUDO_DEBUG_INFO, "command stopped, signal %d",
+                   WSTOPSIG(status));
                do {
                    child_pgrp = tcgetpgrp(io_fds[SFD_SLAVE]);
                } while (child_pgrp == -1 && errno == EINTR);
                if (send_status(backchannel, cstat) == -1)
                    return alive; /* XXX */
            } else if (WIFSIGNALED(status)) {
-               sudo_debug(8, "command killed, signal %d", WTERMSIG(status));
+               sudo_debug_printf(SUDO_DEBUG_INFO, "command killed, signal %d",
+                   WTERMSIG(status));
            } else {
-               sudo_debug(8, "command exited: %d", WEXITSTATUS(status));
+               sudo_debug_printf(SUDO_DEBUG_INFO, "command exited: %d",
+                   WEXITSTATUS(status));
            }
        }
        if (!WIFSTOPPED(status))
-           alive = FALSE;
+           alive = false;
     }
-    return alive;
+    debug_return_bool(alive);
 }
 
 /*
@@ -809,8 +853,9 @@ exec_monitor(struct command_details *details, int backchannel)
     fd_set *fdsr;
     sigaction_t sa;
     int errpipe[2], maxfd, n, status;
-    int alive = TRUE;
+    bool alive = true;
     unsigned char signo;
+    debug_decl(exec_monitor, SUDO_DEBUG_EXEC);
 
     /* Close unused fds. */
     if (io_fds[SFD_MASTER] != -1)
@@ -843,6 +888,17 @@ exec_monitor(struct command_details *details, int backchannel)
     sa.sa_handler = handler;
     sigaction(SIGCHLD, &sa, NULL);
 
+    /* Catch common signals so we can cleanup properly. */
+    sa.sa_flags = SA_RESTART;
+    sa.sa_handler = handler;
+    sigaction(SIGHUP, &sa, NULL);
+    sigaction(SIGINT, &sa, NULL);
+    sigaction(SIGQUIT, &sa, NULL);
+    sigaction(SIGTERM, &sa, NULL);
+    sigaction(SIGTSTP, &sa, NULL);
+    sigaction(SIGUSR1, &sa, NULL);
+    sigaction(SIGUSR2, &sa, NULL);
+
     /*
      * Start a new session with the parent as the session leader
      * and the slave pty as the controlling terminal.
@@ -870,7 +926,7 @@ exec_monitor(struct command_details *details, int backchannel)
      * when it needs access to the controlling tty.
      */
     if (pipeline)
-       foreground = 0;
+       foreground = false;
 
     /* Start command and wait for it to stop or exit */
     if (pipe(errpipe) == -1)
@@ -890,7 +946,7 @@ exec_monitor(struct command_details *details, int backchannel)
        restore_signals();
 
        /* setup tty and exec command */
-       exec_pty(details);
+       exec_pty(details, &errpipe[1]);
        cstat.type = CMD_ERRNO;
        cstat.val = errno;
        if (write(errpipe[1], &cstat, sizeof(cstat)) == -1)
@@ -1004,10 +1060,11 @@ done:
        /* Send parent status. */
        send_status(backchannel, &cstat);
     }
+    sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, 1);
     _exit(1);
 
 bad:
-    return errno;
+    debug_return_int(errno);
 }
 
 /*
@@ -1021,6 +1078,7 @@ flush_output(void)
     struct timeval tv;
     fd_set *fdsr, *fdsw;
     int nready, nwriters, maxfd = -1;
+    debug_decl(flush_output, SUDO_DEBUG_EXEC);
 
     /* Determine maxfd */
     for (iob = iobufs; iob; iob = iob->next) {
@@ -1030,7 +1088,7 @@ flush_output(void)
            maxfd = iob->wfd;
     }
     if (maxfd == -1)
-       return;
+       debug_return;
 
     fdsr = (fd_set *)emalloc2(howmany(maxfd + 1, NFDBITS), sizeof(fd_mask));
     fdsw = (fd_set *)emalloc2(howmany(maxfd + 1, NFDBITS), sizeof(fd_mask));
@@ -1081,6 +1139,7 @@ flush_output(void)
     }
     efree(fdsr);
     efree(fdsw);
+    debug_return;
 }
 
 /*
@@ -1088,9 +1147,10 @@ flush_output(void)
  * Returns only if execve() fails.
  */
 static void
-exec_pty(struct command_details *details)
+exec_pty(struct command_details *details, int *errfd)
 {
     pid_t self = getpid();
+    debug_decl(exec_pty, SUDO_DEBUG_EXEC);
 
     /* Set child process group here too to avoid a race. */
     setpgid(0, self);
@@ -1117,14 +1177,31 @@ exec_pty(struct command_details *details)
     if (io_fds[SFD_STDERR] != io_fds[SFD_SLAVE])
        close(io_fds[SFD_STDERR]);
 
-    if (details->closefrom >= 0)
-       closefrom(details->closefrom);
+    sudo_debug_execve(SUDO_DEBUG_INFO, details->command,
+       details->argv, details->envp);
+
+    if (details->closefrom >= 0) {
+       int maxfd = details->closefrom;
+       dup2(*errfd, maxfd);
+       (void)fcntl(maxfd, F_SETFD, FD_CLOEXEC);
+       *errfd = maxfd++;
+       if (sudo_debug_fd_set(maxfd) != -1)
+           maxfd++;
+       closefrom(maxfd);
+    }
 #ifdef HAVE_SELINUX
-    if (ISSET(details->flags, CD_RBAC_ENABLED))
-       selinux_execve(details->command, details->argv, details->envp);
-    else
+    if (ISSET(details->flags, CD_RBAC_ENABLED)) {
+       selinux_execve(details->command, details->argv, details->envp,
+           ISSET(details->flags, CD_NOEXEC));
+    } else
 #endif
-       my_execve(details->command, details->argv, details->envp);
+    {
+       sudo_execve(details->command, details->argv, details->envp,
+           ISSET(details->flags, CD_NOEXEC));
+    }
+    sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to exec %s: %s",
+       details->command, strerror(errno));
+    debug_return;
 }
 
 /*
@@ -1136,12 +1213,15 @@ sync_ttysize(int src, int dst)
 #ifdef TIOCGWINSZ
     struct winsize wsize;
     pid_t pgrp;
+    debug_decl(sync_ttysize, SUDO_DEBUG_EXEC);
 
     if (ioctl(src, TIOCGWINSZ, &wsize) == 0) {
            ioctl(dst, TIOCSWINSZ, &wsize);
            if ((pgrp = tcgetpgrp(dst)) != -1)
                killpg(pgrp, SIGWINCH);
     }
+
+    debug_return;
 #endif
 }
 
@@ -1164,10 +1244,12 @@ sigwinch(int s)
 static int
 safe_close(int fd)
 {
+    debug_decl(safe_close, SUDO_DEBUG_EXEC);
+
     /* Avoid closing /dev/tty or std{in,out,err}. */
     if (fd < 3 || fd == io_fds[SFD_USERTTY]) {
        errno = EINVAL;
        return -1;
     }
-    return close(fd);
+    debug_return_int(close(fd));
 }
index f303721d2d391599e89989d1eb97517f0e6156dc..21449cb919485b308c6fd66c187727e0ea40ea6b 100644 (file)
@@ -63,15 +63,18 @@ get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
 {
     struct group *gr;
     gid_t ttygid = -1;
+    int rval = 0;
+    debug_decl(get_pty, SUDO_DEBUG_PTY)
 
     if ((gr = getgrnam("tty")) != NULL)
        ttygid = gr->gr_gid;
 
-    if (openpty(master, slave, name, NULL, NULL) != 0)
-       return 0;
-    if (chown(name, ttyuid, ttygid) != 0)
-       return 0;
-    return 1;
+    if (openpty(master, slave, name, NULL, NULL) == 0) {
+       if (chown(name, ttyuid, ttygid) == 0)
+           rval = 1;
+    }
+
+    debug_return_bool(rval);
 }
 
 #elif defined(HAVE__GETPTY)
@@ -79,19 +82,23 @@ int
 get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
 {
     char *line;
+    int rval = 0;
+    debug_decl(get_pty, SUDO_DEBUG_PTY)
 
     /* IRIX-style dynamic ptys (may fork) */
     line = _getpty(master, O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP, 0);
-    if (line == NULL)
-       return 0;
-    *slave = open(line, O_RDWR|O_NOCTTY, 0);
-    if (*slave == -1) {
-       close(*master);
-       return 0;
+    if (line != NULL) {
+       *slave = open(line, O_RDWR|O_NOCTTY, 0);
+       if (*slave != -1) {
+           (void) chown(line, ttyuid, -1);
+           strlcpy(name, line, namesz);
+           rval = 1;
+       } else {
+           close(*master);
+           *master = -1;
+       }
     }
-    (void) chown(line, ttyuid, -1);
-    strlcpy(name, line, namesz);
-    return 1;
+    debug_return_bool(rval);
 }
 #elif defined(HAVE_GRANTPT)
 # ifndef HAVE_POSIX_OPENPT
@@ -113,33 +120,36 @@ int
 get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
 {
     char *line;
+    int rval = 0;
+    debug_decl(get_pty, SUDO_DEBUG_PTY)
 
     *master = posix_openpt(O_RDWR|O_NOCTTY);
-    if (*master == -1)
-       return 0;
-
-    (void) grantpt(*master); /* may fork */
-    if (unlockpt(*master) != 0) {
-       close(*master);
-       return 0;
-    }
-    line = ptsname(*master);
-    if (line == NULL) {
-       close(*master);
-       return 0;
-    }
-    *slave = open(line, O_RDWR|O_NOCTTY, 0);
-    if (*slave == -1) {
-       close(*master);
-       return 0;
-    }
+    if (*master != -1) {
+       (void) grantpt(*master); /* may fork */
+       if (unlockpt(*master) != 0) {
+           close(*master);
+           goto done;
+       }
+       line = ptsname(*master);
+       if (line == NULL) {
+           close(*master);
+           goto done;
+       }
+       *slave = open(line, O_RDWR|O_NOCTTY, 0);
+       if (*slave == -1) {
+           close(*master);
+           goto done;
+       }
 # if defined(I_PUSH) && !defined(_AIX)
-    ioctl(*slave, I_PUSH, "ptem");     /* pseudo tty emulation module */
-    ioctl(*slave, I_PUSH, "ldterm");   /* line discipline module */
+       ioctl(*slave, I_PUSH, "ptem");  /* pseudo tty emulation module */
+       ioctl(*slave, I_PUSH, "ldterm");        /* line discipline module */
 # endif
-    (void) chown(line, ttyuid, -1);
-    strlcpy(name, line, namesz);
-    return 1;
+       (void) chown(line, ttyuid, -1);
+       strlcpy(name, line, namesz);
+       rval = 1;
+    }
+done:
+    debug_return_bool(rval);
 }
 
 #else /* Old-style BSD ptys */
@@ -152,6 +162,8 @@ get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
     char *bank, *cp;
     struct group *gr;
     gid_t ttygid = -1;
+    int rval = 0;
+    debug_decl(get_pty, SUDO_DEBUG_PTY)
 
     if ((gr = getgrnam("tty")) != NULL)
        ttygid = gr->gr_gid;
@@ -163,7 +175,7 @@ get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
            *master = open(line, O_RDWR|O_NOCTTY, 0);
            if (*master == -1) {
                if (errno == ENOENT)
-                   return 0; /* out of ptys */
+                   goto done; /* out of ptys */
                continue; /* already in use */
            }
            line[sizeof("/dev/p") - 2] = 't';
@@ -175,11 +187,13 @@ get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
            *slave = open(line, O_RDWR|O_NOCTTY, 0);
            if (*slave != -1) {
                    strlcpy(name, line, namesz);
-                   return 1; /* success */
+                   rval = 1; /* success */
+                   goto done;
            }
            (void) close(*master);
        }
     }
-    return 0;
+done:
+    debug_return(rval);
 }
 #endif /* HAVE_OPENPTY */
index 6bee3f8471dd7f46b6e48e5c24fcc9e3ea07fef3..e86c1432c391521b55169647f100302ef56dea47 100644 (file)
 #include "sudo.h"
 #include "sudo_plugin.h"
 #include "sudo_plugin_int.h"
+#include "sudo_conf.h"
+#include "sudo_debug.h"
 
 #ifndef RTLD_GLOBAL
 # define RTLD_GLOBAL   0
 #endif
 
-#ifdef _PATH_SUDO_NOEXEC
-const char *noexec_path = _PATH_SUDO_NOEXEC;
-#endif
-
 /*
- * Read in /etc/sudo.conf
- * Returns a list of plugins.
+ * Load the plugins listed in sudo.conf.
  */
-static struct plugin_info_list *
-sudo_read_conf(const char *conf_file)
-{
-    FILE *fp;
-    char *cp, *name, *path;
-    struct plugin_info *info;
-    static struct plugin_info_list pil; /* XXX */
-
-    if ((fp = fopen(conf_file, "r")) == NULL)
-       goto done;
-
-    while ((cp = sudo_parseln(fp)) != NULL) {
-       /* Skip blank or comment lines */
-       if (*cp == '\0')
-           continue;
-
-       /* Look for a line starting with "Path" */
-       if (strncasecmp(cp, "Path", 4) == 0) {
-           /* Parse line */
-           if ((name = strtok(cp + 4, " \t")) == NULL ||
-               (path = strtok(NULL, " \t")) == NULL) {
-               continue;
-           }
-           if (strcasecmp(name, "askpass") == 0)
-               askpass_path = estrdup(path);
-#ifdef _PATH_SUDO_NOEXEC
-           else if (strcasecmp(name, "noexec") == 0)
-               noexec_path = estrdup(path);
-#endif
-           continue;
-       }
-
-       /* Look for a line starting with "Plugin" */
-       if (strncasecmp(cp, "Plugin", 6) == 0) {
-           /* Parse line */
-           if ((name = strtok(cp + 6, " \t")) == NULL ||
-               (path = strtok(NULL, " \t")) == NULL) {
-               continue;
-           }
-           info = emalloc(sizeof(*info));
-           info->symbol_name = estrdup(name);
-           info->path = estrdup(path);
-           info->prev = info;
-           info->next = NULL;
-           tq_append(&pil, info);
-           continue;
-       }
-    }
-    fclose(fp);
-
-done:
-    if (tq_empty(&pil)) {
-       /* Default policy plugin */
-       info = emalloc(sizeof(*info));
-       info->symbol_name = "sudoers_policy";
-       info->path = SUDOERS_PLUGIN;
-       info->prev = info;
-       info->next = NULL;
-       tq_append(&pil, info);
-
-       /* Default I/O plugin */
-       info = emalloc(sizeof(*info));
-       info->symbol_name = "sudoers_io";
-       info->path = SUDOERS_PLUGIN;
-       info->prev = info;
-       info->next = NULL;
-       tq_append(&pil, info);
-    }
-
-    return &pil;
-}
-
-/*
- * Load the plugins listed in conf_file.
- */
-int
-sudo_load_plugins(const char *conf_file,
-    struct plugin_container *policy_plugin,
+bool
+sudo_load_plugins(struct plugin_container *policy_plugin,
     struct plugin_container_list *io_plugins)
 {
+    struct plugin_info_list *plugins;
     struct generic_plugin *plugin;
     struct plugin_container *container;
     struct plugin_info *info;
-    struct plugin_info_list *plugin_list;
     struct stat sb;
     void *handle;
     char path[PATH_MAX];
-    int rval = FALSE;
-
-    /* Parse sudo.conf */
-    plugin_list = sudo_read_conf(conf_file);
+    bool rval = false;
+    debug_decl(sudo_load_plugins, SUDO_DEBUG_PLUGIN)
 
-    tq_foreach_fwd(plugin_list, info) {
+    /* Walk plugin list. */
+    plugins = sudo_conf_plugins();
+    tq_foreach_fwd(plugins, info) {
        if (info->path[0] == '/') {
            if (strlcpy(path, info->path, sizeof(path)) >= sizeof(path)) {
                warningx(_("%s: %s"), info->path, strerror(ENAMETOOLONG));
@@ -205,7 +126,7 @@ sudo_load_plugins(const char *conf_file,
        if (plugin->type == SUDO_POLICY_PLUGIN) {
            if (policy_plugin->handle) {
                warningx(_("%s: only a single policy plugin may be loaded"),
-                   conf_file);
+                   _PATH_SUDO_CONF);
                goto done;
            }
            policy_plugin->handle = handle;
@@ -223,7 +144,7 @@ sudo_load_plugins(const char *conf_file,
     }
     if (policy_plugin->handle == NULL) {
        warningx(_("%s: at least one policy plugin must be specified"),
-           conf_file);
+           _PATH_SUDO_CONF);
        goto done;
     }
     if (policy_plugin->u.policy->check_policy == NULL) {
@@ -232,8 +153,8 @@ sudo_load_plugins(const char *conf_file,
        goto done;
     }
 
-    rval = TRUE;
+    rval = true;
 
 done:
-    return rval;
+    debug_return_bool(rval);
 }
index 3dc1f4dfdde89bbe11ede577aeecd4d71282f818..fa8b6760415b327a42018dfb4644e682e8bda9c9 100644 (file)
@@ -83,6 +83,7 @@ struct rtentry;
 #include "missing.h"
 #include "alloc.h"
 #include "error.h"
+#include "sudo_debug.h"
 
 #define DEFAULT_TEXT_DOMAIN    "sudo"
 #include "gettext.h"
@@ -107,15 +108,16 @@ get_net_ifs(char **addrinfo)
 {
     struct ifaddrs *ifa, *ifaddrs;
     struct sockaddr_in *sin;
-#ifdef HAVE_IN6_ADDR
+#ifdef HAVE_STRUCT_IN6_ADDR
     struct sockaddr_in6 *sin6;
     char addrbuf[INET6_ADDRSTRLEN];
 #endif
     int ailen, i, len, num_interfaces = 0;
     char *cp;
+    debug_decl(get_net_ifs, SUDO_DEBUG_NETIF)
 
     if (getifaddrs(&ifaddrs))
-       return 0;
+       debug_return_int(0);
 
     /* Allocate space for the interfaces info string. */
     for (ifa = ifaddrs; ifa != NULL; ifa = ifa -> ifa_next) {
@@ -126,7 +128,7 @@ get_net_ifs(char **addrinfo)
 
        switch (ifa->ifa_addr->sa_family) {
            case AF_INET:
-#ifdef HAVE_IN6_ADDR
+#ifdef HAVE_STRUCT_IN6_ADDR
            case AF_INET6:
 #endif
                num_interfaces++;
@@ -134,7 +136,7 @@ get_net_ifs(char **addrinfo)
        }
     }
     if (num_interfaces == 0)
-       return 0;
+       debug_return_int(0);
     ailen = num_interfaces * 2 * INET6_ADDRSTRLEN;
     *addrinfo = cp = emalloc(ailen);
 
@@ -166,7 +168,7 @@ get_net_ifs(char **addrinfo)
                }
                cp += len;
                break;
-#ifdef HAVE_IN6_ADDR
+#ifdef HAVE_STRUCT_IN6_ADDR
            case AF_INET6:
                sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
                inet_ntop(AF_INET6, &sin6->sin6_addr, addrbuf, sizeof(addrbuf));
@@ -187,7 +189,7 @@ get_net_ifs(char **addrinfo)
                }
                cp += len;
                break;
-#endif /* HAVE_IN6_ADDR */
+#endif /* HAVE_STRUCT_IN6_ADDR */
        }
     }
 
@@ -197,7 +199,7 @@ done:
 #else
     efree(ifaddrs);
 #endif
-    return num_interfaces;
+    debug_return_int(num_interfaces);
 }
 
 #elif defined(SIOCGIFCONF) && !defined(STUB_LOAD_INTERFACES)
@@ -218,6 +220,7 @@ get_net_ifs(char **addrinfo)
 #ifdef _ISC
     struct strioctl strioctl;
 #endif /* _ISC */
+    debug_decl(get_net_ifs, SUDO_DEBUG_NETIF)
 
     sock = socket(AF_INET, SOCK_DGRAM, 0);
     if (sock < 0)
@@ -250,7 +253,7 @@ get_net_ifs(char **addrinfo)
 
     /* Allocate space for the maximum number of interfaces that could exist. */
     if ((n = ifconf->ifc_len / sizeof(struct ifreq)) == 0)
-       return 0;
+       debug_return_int(0);
     ailen = n * 2 * INET6_ADDRSTRLEN;
     *addrinfo = cp = emalloc(ailen);
 
@@ -261,10 +264,10 @@ get_net_ifs(char **addrinfo)
 
        /* Set i to the subscript of the next interface. */
        i += sizeof(struct ifreq);
-#ifdef HAVE_SA_LEN
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
        if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr))
            i += ifr->ifr_addr.sa_len - sizeof(struct sockaddr);
-#endif /* HAVE_SA_LEN */
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
 
        /* Skip duplicates and interfaces with NULL addresses. */
        sin = (struct sockaddr_in *) &ifr->ifr_addr;
@@ -327,7 +330,7 @@ done:
     efree(ifconf_buf);
     (void) close(sock);
 
-    return num_interfaces;
+    debug_return_int(num_interfaces);
 }
 
 #else /* !SIOCGIFCONF || STUB_LOAD_INTERFACES */
@@ -338,7 +341,8 @@ done:
 int
 get_net_ifs(char **addrinfo)
 {
-    return 0;
+    debug_decl(get_net_ifs, SUDO_DEBUG_NETIF)
+    debug_return_int(0);
 }
 
 #endif /* SIOCGIFCONF && !STUB_LOAD_INTERFACES */
index f8aac4b62b9f4b07c6042eec0e0338cb24fdbb0d..22a4d20a6f5c87b06e8f8428cacb9824ead40b35 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1993-1996, 1998-2011 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1993-1996, 1998-2012 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
@@ -72,8 +72,8 @@ static struct sudo_settings {
     { "bsdauth_type" },
 #define ARG_LOGIN_CLASS 1
     { "login_class" },
-#define ARG_DEBUG_LEVEL 2
-    { "debug_level" },
+#define ARG_DEBUG_FLAGS 2
+    { "debug_flags" },
 #define ARG_PRESERVE_ENVIRONMENT 3
     { "preserve_environment" },
 #define ARG_RUNAS_GROUP 4
@@ -126,8 +126,10 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
     int valid_flags, ch;
     int i, j;
     char *cp, **env_add, **settings;
+    const char *debug_flags;
     int nenv = 0;
     int env_size = 32;
+    debug_decl(parse_args, SUDO_DEBUG_ARGS)
 
     env_add = emalloc2(env_size, sizeof(char *));
 
@@ -144,6 +146,11 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
     if (get_net_ifs(&cp) > 0)
        sudo_settings[ARG_NET_ADDRS].value = cp;
 
+    /* Set debug file and flags from sudo.conf. */
+    debug_flags = sudo_conf_debug_flags();
+    if (debug_flags != NULL)
+       sudo_settings[ARG_DEBUG_FLAGS].value = debug_flags;
+
     /* Returns true if the last option string was "--" */
 #define got_end_of_args        (optind > 1 && argv[optind - 1][0] == '-' && \
            argv[optind - 1][1] == '-' && argv[optind - 1][2] == '\0')
@@ -188,11 +195,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
                    break;
 #endif
                case 'D':
-                   if ((debug_level = atoi(optarg)) < 1 || debug_level > 9) {
-                       warningx(_("the argument to -D must be between 1 and 9 inclusive"));
-                       usage(1);
-                   }
-                   sudo_settings[ARG_DEBUG_LEVEL].value = optarg;
+                   /* Ignored for backwards compatibility. */
                    break;
                case 'E':
                    sudo_settings[ARG_PRESERVE_ENVIRONMENT].value = "true";
@@ -421,8 +424,8 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
     settings = emalloc2(NUM_SETTINGS + 1, sizeof(char *));
     for (i = 0, j = 0; i < NUM_SETTINGS; i++) {
        if (sudo_settings[i].value) {
-           sudo_debug(9, "settings: %s=%s", sudo_settings[i].name,
-               sudo_settings[i].value);
+           sudo_debug_printf(SUDO_DEBUG_INFO, "settings: %s=%s",
+               sudo_settings[i].name, sudo_settings[i].value);
            settings[j] = fmt_string(sudo_settings[i].name,
                sudo_settings[i].value);
            if (settings[j] == NULL)
@@ -447,7 +450,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
     *env_addp = env_add;
     *nargc = argc;
     *nargv = argv;
-    return mode | flags;
+    debug_return_int(mode | flags);
 }
 
 static int
@@ -510,6 +513,8 @@ usage(int fatal)
 static void
 usage_excl(int fatal)
 {
+    debug_decl(usage_excl, SUDO_DEBUG_ARGS)
+
     warningx(_("Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"));
     usage(fatal);
 }
@@ -520,6 +525,7 @@ help(void)
     struct lbuf lbuf;
     int indent = 16;
     const char *pname = getprogname();
+    debug_decl(help, SUDO_DEBUG_ARGS)
 
     lbuf_init(&lbuf, usage_out, indent, NULL, user_details.ts_cols);
     if (strcmp(pname, "sudoedit") == 0)
@@ -593,5 +599,6 @@ help(void)
        _("stop processing command line arguments\n"));
     lbuf_print(&lbuf);
     lbuf_destroy(&lbuf);
+    sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, 0);
     exit(0);
 }
diff --git a/src/po/es.mo b/src/po/es.mo
new file mode 100644 (file)
index 0000000..b3ae6a2
Binary files /dev/null and b/src/po/es.mo differ
diff --git a/src/po/es.po b/src/po/es.po
new file mode 100644 (file)
index 0000000..53277c5
--- /dev/null
@@ -0,0 +1,735 @@
+# traducción al español de sudo.
+# This file is distributed under the same license as the sudo package.
+#
+# Abel Sendón <abelnicolas1976@gmail.com>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.4b1\n"
+"Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
+"POT-Creation-Date: 2012-01-06 15:10-0500\n"
+"PO-Revision-Date: 2012-02-03 00:09-0300\n"
+"Last-Translator: Abel Sendón <abelnicolas1976@gmail.com>\n"
+"Language-Team: Spanish <es@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Lokalize 1.2\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Poedit-Language: Spanish\n"
+"X-Poedit-Country: ARGENTINA\n"
+
+#: src/error.c:82 src/error.c:86
+msgid ": "
+msgstr ": "
+
+#: src/exec.c:133 src/exec_pty.c:604 src/exec_pty.c:936 src/tgetpass.c:227
+#, c-format
+msgid "unable to fork"
+msgstr "no se puede bifurcar"
+
+#: src/exec.c:299
+#, c-format
+msgid "unable to create sockets"
+msgstr "no se puede crear sockets"
+
+#: src/exec.c:306 src/exec_pty.c:557 src/exec_pty.c:565 src/exec_pty.c:572
+#: src/exec_pty.c:871 src/exec_pty.c:933 src/tgetpass.c:224
+#, c-format
+msgid "unable to create pipe"
+msgstr "no se puede crear tubería"
+
+#: src/exec.c:373 src/exec_pty.c:1000 src/exec_pty.c:1135
+#, c-format
+msgid "select failed"
+msgstr "selección fallida"
+
+#: src/exec.c:458
+#, c-format
+msgid "unable to restore tty label"
+msgstr "no se puede restaurar la etiqueta tty"
+
+#: src/exec_pty.c:140
+#, c-format
+msgid "unable to allocate pty"
+msgstr "no se puede asignar pty"
+
+#: src/exec_pty.c:597
+#, c-format
+msgid "unable to set terminal to raw mode"
+msgstr "no se puede establecer la terminal en modo directo"
+
+#: src/exec_pty.c:914
+#, c-format
+msgid "unable to set controlling tty"
+msgstr "no se puede establecer el controlador tty"
+
+#: src/exec_pty.c:1008
+#, c-format
+msgid "error reading from signal pipe"
+msgstr "error al leer desde la tubería de la señal"
+
+#: src/exec_pty.c:1027
+#, c-format
+msgid "error reading from pipe"
+msgstr "error al leer de la tubería"
+
+#: src/exec_pty.c:1043
+#, c-format
+msgid "error reading from socketpair"
+msgstr "error leyendo de socketpair"
+
+#: src/exec_pty.c:1047
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "tipo de respuesta inesperada en canales alternos %d"
+
+#: src/load_plugins.c:79
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: src/load_plugins.c:85
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:95
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s debe ser propiedad del uid %d"
+
+#: src/load_plugins.c:99
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s sólo tener permisos de escritura por el propietario"
+
+#: src/load_plugins.c:106
+#, c-format
+msgid "unable to dlopen %s: %s"
+msgstr "no se puede dlopen %s: %s"
+
+#: src/load_plugins.c:111
+#, c-format
+msgid "%s: unable to find symbol %s"
+msgstr "%s: no se puede de encontrar el símbolo %s"
+
+#: src/load_plugins.c:117
+#, c-format
+msgid "%s: unknown policy type %d"
+msgstr "%s: tipo de política desconocida %d"
+
+#: src/load_plugins.c:121
+#, c-format
+msgid "%s: incompatible policy major version %d, expected %d"
+msgstr "%s: incompatible la versión principal de la política %d, se esperaba %d"
+
+#: src/load_plugins.c:128
+#, c-format
+msgid "%s: only a single policy plugin may be loaded"
+msgstr "%s: se puede cargar sólo una política de plugin"
+
+#: src/load_plugins.c:146
+#, c-format
+msgid "%s: at least one policy plugin must be specified"
+msgstr "%s: debe ser especificada al menos una política de plugin"
+
+#: src/load_plugins.c:151
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "la política del plugin %s no incluye un método check_policy"
+
+#: src/net_ifs.c:157 src/net_ifs.c:166 src/net_ifs.c:178 src/net_ifs.c:187
+#: src/net_ifs.c:298 src/net_ifs.c:322
+#, c-format
+msgid "load_interfaces: overflow detected"
+msgstr "load_interfaces: desbordamiento detectado"
+
+#: src/net_ifs.c:227
+#, c-format
+msgid "unable to open socket"
+msgstr "no se puede de abrir socket"
+
+#: src/parse_args.c:187
+#, c-format
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "el argumento -C debe ser un número mayor o igual a 3"
+
+#: src/parse_args.c:276
+#, c-format
+msgid "unknown user: %s"
+msgstr "usuario desconocido: %s"
+
+#: src/parse_args.c:335
+#, c-format
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "no se deben especificar las opciones '-i' y '-s' simultáneamente"
+
+#: src/parse_args.c:339
+#, c-format
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "no se deben especificar las opciones '-i' y '-E' simultáneamente"
+
+#: src/parse_args.c:349
+#, c-format
+msgid "the `-E' option is not valid in edit mode"
+msgstr "la opción '-E' no es válida en el modo edición"
+
+#: src/parse_args.c:351
+#, c-format
+msgid "you may not specify environment variables in edit mode"
+msgstr "no se debe especificar variables de entorno en el modo edición"
+
+#: src/parse_args.c:359
+#, c-format
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "la opción '-U' sólo se puede usar con la opcion '-l'"
+
+#: src/parse_args.c:363
+#, c-format
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "las opciones '-A' y '-S' no se pueden utilizar conjuntamente"
+
+#: src/parse_args.c:432 src/sudo.c:482 src/sudo.c:502 src/sudo.c:509
+#: src/sudo.c:519 common/alloc.c:85 common/alloc.c:105 common/alloc.c:123
+#: common/alloc.c:145 common/alloc.c:203 common/alloc.c:217
+#, c-format
+msgid "unable to allocate memory"
+msgstr "no se puede de asignar memoria"
+
+#: src/parse_args.c:445
+#, c-format
+msgid "sudoedit is not supported on this platform"
+msgstr "sudoedit no está soportada en ésta plataforma"
+
+#: src/parse_args.c:518
+#, c-format
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "puede ser especificada sólo una de las opciones -e, -h, -i, -K, -l, -s, -v o -V"
+
+#: src/parse_args.c:532
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s - edita archivos como otro usuario\n"
+"\n"
+
+#: src/parse_args.c:534
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s - ejecuta un comando como otro usuario\n"
+"\n"
+
+#: src/parse_args.c:539
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Opciones:\n"
+
+#: src/parse_args.c:542
+msgid "use helper program for password prompting\n"
+msgstr "utilizar el programa de ayuda para la solicitud de contraseña\n"
+
+#: src/parse_args.c:545
+msgid "use specified BSD authentication type\n"
+msgstr "utiliza tipo de autentificación especificado en BSD\n"
+
+#: src/parse_args.c:547
+msgid "run command in the background\n"
+msgstr "ejecuta un comando en segundo plano\n"
+
+#: src/parse_args.c:549
+msgid "close all file descriptors >= fd\n"
+msgstr "cierra todos los descriptores de archivo >= fd\n"
+
+#: src/parse_args.c:552
+msgid "run command with specified login class\n"
+msgstr "ejecuta un comando con la clase especificada de inicio de sesión\n"
+
+#: src/parse_args.c:555
+msgid "preserve user environment when executing command\n"
+msgstr "preserva entorno del usuario cuando está ejecutando un comando\n"
+
+#: src/parse_args.c:557
+msgid "edit files instead of running a command\n"
+msgstr "edita archivos en vez de ejecutar un comando\n"
+
+#: src/parse_args.c:559
+msgid "execute command as the specified group\n"
+msgstr "ejecuta un comando como el grupo especificado\n"
+
+#: src/parse_args.c:561
+msgid "set HOME variable to target user's home dir.\n"
+msgstr "asigna la variable HOME al directorio de inicio del usuario\n"
+
+#: src/parse_args.c:563
+msgid "display help message and exit\n"
+msgstr "muestra este mensaje de ayuda y sale\n"
+
+#: src/parse_args.c:565
+msgid "run a login shell as target user\n"
+msgstr "ejecuta un intérprete de comandos como un determinado usuario\n"
+
+#: src/parse_args.c:567
+msgid "remove timestamp file completely\n"
+msgstr "remueve un archivo de marca completamente\n"
+
+#: src/parse_args.c:569
+msgid "invalidate timestamp file\n"
+msgstr "archivo de marca inválido\n"
+
+#: src/parse_args.c:571
+msgid "list user's available commands\n"
+msgstr "lista los comandos del usuario disponibles\n"
+
+#: src/parse_args.c:573
+msgid "non-interactive mode, will not prompt user\n"
+msgstr "modo no-interactivo, no se pedirá usuario\n"
+
+#: src/parse_args.c:575
+msgid "preserve group vector instead of setting to target's\n"
+msgstr "preserva el vector de grupos en vez de establecer de objetivo\n"
+
+#: src/parse_args.c:577
+msgid "use specified password prompt\n"
+msgstr "usa la contraseña especificada\n"
+
+#: src/parse_args.c:580 src/parse_args.c:588
+msgid "create SELinux security context with specified role\n"
+msgstr "crea el contexto de seguridad SELinux con la regla especificada\n"
+
+#: src/parse_args.c:583
+msgid "read password from standard input\n"
+msgstr "lee la contraseña desde la entrada estandar\n"
+
+#: src/parse_args.c:585
+msgid "run a shell as target user\n"
+msgstr "ejecuta un intérprete de comandos como un determinado usuario\n"
+
+#: src/parse_args.c:591
+msgid "when listing, list specified user's privileges\n"
+msgstr "cuando está listando, lista los privilegios del usuario especificado\n"
+
+#: src/parse_args.c:593
+msgid "run command (or edit file) as specified user\n"
+msgstr "ejecuta un comando (o edita un archivo) como un usuario específico\n"
+
+#: src/parse_args.c:595
+msgid "display version information and exit\n"
+msgstr "muestra la información de la versión y sale\n"
+
+#: src/parse_args.c:597
+msgid "update user's timestamp without running a command\n"
+msgstr "actualiza la marca del usuario sin ejecutar un comando\n"
+
+#: src/parse_args.c:599
+msgid "stop processing command line arguments\n"
+msgstr "detiene el proceso de argumentos de la línea de comandos\n"
+
+#: src/selinux.c:76
+#, c-format
+msgid "unable to open audit system"
+msgstr "no se puede de abrir el sistema de auditoría"
+
+#: src/selinux.c:84
+#, c-format
+msgid "unable to send audit message"
+msgstr "no se puede enviar mensaje de auditoría"
+
+#: src/selinux.c:112
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "no se puede fgetfilecon %s"
+
+#: src/selinux.c:117
+#, c-format
+msgid "%s changed labels"
+msgstr "%s etiquetas cambiadas"
+
+#: src/selinux.c:122
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "no se puede restaurar el contexto para %s"
+
+#: src/selinux.c:162
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "no se puede abrir %s, no volver a etiquetar tty"
+
+#: src/selinux.c:171
+#, c-format
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "no se puede obtener el actual contexto tty, no volver a etiquetar tty"
+
+#: src/selinux.c:178
+#, c-format
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "no se puede obtener el nuevo contexto tty, no volver a etiquetar tty"
+
+#: src/selinux.c:185
+#, c-format
+msgid "unable to set new tty context"
+msgstr "no se puede establecer nuevo contexto tty"
+
+#: src/selinux.c:195 src/selinux.c:208 src/sudo.c:335
+#, c-format
+msgid "unable to open %s"
+msgstr "no se pudo abrir %s"
+
+#: src/selinux.c:251
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "se debe especificar una regla por tipo %s"
+
+#: src/selinux.c:257
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "no se puede obtener el tipo de regla predeterminada %s"
+
+#: src/selinux.c:275
+#, c-format
+msgid "failed to set new role %s"
+msgstr "falló al establecer nueva regla %s"
+
+#: src/selinux.c:279
+#, c-format
+msgid "failed to set new type %s"
+msgstr "falló al establecer nuevo tipo %s"
+
+#: src/selinux.c:288
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s no es un contexto válido"
+
+#: src/selinux.c:323
+#, c-format
+msgid "failed to get old_context"
+msgstr "falló al obtener old_context"
+
+#: src/selinux.c:329
+#, c-format
+msgid "unable to determine enforcing mode."
+msgstr "no se puede determinar el método de forzado"
+
+#: src/selinux.c:341
+#, c-format
+msgid "unable to setup tty context for %s"
+msgstr "no se puede establecer el contexto tty para %s"
+
+#: src/selinux.c:371
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "no se puede establecer el contexto de ejecución a %s"
+
+#: src/selinux.c:378
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "no se puede establecer la clave de creación de contexto a %s"
+
+#: src/sesh.c:48
+msgid "requires at least one argument"
+msgstr "requiere al menos un argumento"
+
+#: src/sesh.c:64
+#, c-format
+msgid "unable to execute %s"
+msgstr "no se puede ejecutar %s"
+
+#: src/sudo.c:198
+#, c-format
+msgid "must be setuid root"
+msgstr "debe ser setuid root"
+
+#: src/sudo.c:219
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Sudo versión %s\n"
+
+#: src/sudo.c:221
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Opciones de configuración: %s\n"
+
+#: src/sudo.c:226
+#, c-format
+msgid "fatal error, unable to load plugins"
+msgstr "error fatal, no se puede cargar los plugins"
+
+#: src/sudo.c:234
+#, c-format
+msgid "unable to initialize policy plugin"
+msgstr "no se puede inicializar la política de plugin"
+
+#: src/sudo.c:289
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "error al inicializar los plugins de E/S %s"
+
+#: src/sudo.c:310
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "inesperado modo sudo 0x%x"
+
+#: src/sudo.c:404
+#, c-format
+msgid "unable to get group vector"
+msgstr "no se puede obtener el vector de grupo"
+
+#: src/sudo.c:478
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "uid desconocido %u: quién es usted?"
+
+#: src/sudo.c:818
+#, c-format
+msgid "resource control limit has been reached"
+msgstr "el límite de control de recursos ha sido alcanzado"
+
+#: src/sudo.c:821
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "el usuario \"%s\" no es miembro del proyecto \"%s\""
+
+#: src/sudo.c:825
+#, c-format
+msgid "the invoking task is final"
+msgstr "la tarea que invoca es definitiva"
+
+#: src/sudo.c:828
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "no podría unirse al proyecto \"%s\""
+
+#: src/sudo.c:833
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "no hay fondo de recursos aceptando las asignaciones existentes para el proyecto \"%s\""
+
+#: src/sudo.c:837
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "el fondo de recursos especificado no existe para el proyecto \"%s\""
+
+#: src/sudo.c:841
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "no se podría enlazar al fondo de recursos predeterminado para el proyecto \"%s\" "
+
+#: src/sudo.c:847
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "configuración del proyecto fallida \"%s\" "
+
+#: src/sudo.c:849
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "aviso, el control de asignación de recursos falló para el proyecto \"%s\""
+
+#: src/sudo.c:879
+#, c-format
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "no se puede remover PRIV_PROC_EXEC desde PRIV_LIMIT"
+
+#: src/sudo.c:988
+#, c-format
+msgid "unknown login class %s"
+msgstr "clase de inicio de sesión desconocida %s"
+
+#: src/sudo.c:1004 src/sudo.c:1007
+#, c-format
+msgid "unable to set user context"
+msgstr "no se puede establecer el contexto del usuario"
+
+#: src/sudo.c:1022
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "no se puede establecer el gid efectivo para ejecutar como gid %u"
+
+#: src/sudo.c:1028
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "no se puede establecer el gid para ejecutar como gid %u"
+
+#: src/sudo.c:1036
+#, c-format
+msgid "unable to set supplementary group IDs"
+msgstr "no se puede establecer el grupo suplementario de IDs"
+
+#: src/sudo.c:1044
+#, c-format
+msgid "unable to set process priority"
+msgstr "no se puede establecer la prioridad de proceso"
+
+#: src/sudo.c:1052
+#, c-format
+msgid "unable to change root to %s"
+msgstr "no se puede cambiar de root a %s"
+
+#: src/sudo.c:1062 src/sudo.c:1068 src/sudo.c:1074
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "no se puede cambiar a runas uid (%u, %u)"
+
+#: src/sudo.c:1088
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "no se puede cambiar al directorio %s"
+
+#: src/sudo.c:1158
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "inesperada terminación de condición hija: %d"
+
+#: src/sudo.c:1204
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "la política del plugin %s no soporta listado de privilegios"
+
+#: src/sudo.c:1216
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "la política del plugin %s no soporta la opción -v"
+
+#: src/sudo.c:1228
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "la política del plugin %s no soporta las opciones -k/-K"
+
+#: src/sudo_edit.c:111
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "no se puede cambiar uid a root (%u)"
+
+#: src/sudo_edit.c:143
+#, c-format
+msgid "plugin error: missing file list for sudoedit"
+msgstr "error de plugin: falta la lista de archivos para sudoedit"
+
+#: src/sudo_edit.c:171 src/sudo_edit.c:271
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: no es un archivo regular"
+
+#: src/sudo_edit.c:205 src/sudo_edit.c:307
+#, c-format
+msgid "%s: short write"
+msgstr "%s: escritura corta"
+
+#: src/sudo_edit.c:272
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s sin modificar"
+
+#: src/sudo_edit.c:285
+#, c-format
+msgid "%s unchanged"
+msgstr "%s sin cambios"
+
+#: src/sudo_edit.c:297 src/sudo_edit.c:318
+#, c-format
+msgid "unable to write to %s"
+msgstr "no se puede escribir en %s"
+
+#: src/sudo_edit.c:298 src/sudo_edit.c:316 src/sudo_edit.c:319
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "los contenidos de edición de sesión se dejan en %s"
+
+#: src/sudo_edit.c:315
+#, c-format
+msgid "unable to read temporary file"
+msgstr "no se puede leer el archivo temporal"
+
+#: src/tgetpass.c:96
+#, c-format
+msgid "no tty present and no askpass program specified"
+msgstr "sin tty presente y no hay programa askpass especificado"
+
+#: src/tgetpass.c:105
+#, c-format
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "no hay programa askpass especificado, intente establecer SUDO_ASKPASS"
+
+#: src/tgetpass.c:237
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "no se puede establecer el gid a %u"
+
+#: src/tgetpass.c:241
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "no se puede establecer el uid a %u"
+
+#: src/tgetpass.c:246
+#, c-format
+msgid "unable to run %s"
+msgstr "no se puede ejecutar %s"
+
+#: src/utmp.c:278
+#, c-format
+msgid "unable to save stdin"
+msgstr "no se puede guardar stdin"
+
+#: src/utmp.c:280
+#, c-format
+msgid "unable to dup2 stdin"
+msgstr "no se puede hacer dup2 stdin"
+
+#: src/utmp.c:283
+#, c-format
+msgid "unable to restore stdin"
+msgstr "no se puede restaurar stdin"
+
+#: common/aix.c:144
+#, c-format
+msgid "unable to open userdb"
+msgstr "no se puede abrir userdb"
+
+#: common/aix.c:147
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "no se puede cambiar al registro \"%s\" para %s"
+
+#: common/aix.c:161
+#, c-format
+msgid "unable to restore registry"
+msgstr "no se puede restaurar el registro"
+
+#: common/alloc.c:82
+msgid "internal error, tried to emalloc(0)"
+msgstr "error interno: trató emalloc(0)"
+
+#: common/alloc.c:99
+msgid "internal error, tried to emalloc2(0)"
+msgstr "error interno: trató emalloc2(0)"
+
+#: common/alloc.c:101
+msgid "internal error, emalloc2() overflow"
+msgstr "error interno: desbordamiento en emalloc2()"
+
+#: common/alloc.c:119
+msgid "internal error, tried to erealloc(0)"
+msgstr "error interno: trató erealloc(0)"
+
+#: common/alloc.c:138
+msgid "internal error, tried to erealloc3(0)"
+msgstr "error interno: trató erealloc3(0)"
+
+#: common/alloc.c:140
+msgid "internal error, erealloc3() overflow"
+msgstr "error interno: desbordamiento de erealloc3()"
+
+#: compat/strsignal.c:47
+msgid "Unknown signal"
+msgstr "Señal desconocida"
+
+#~ msgid "the argument to -D must be between 1 and 9 inclusive"
+#~ msgstr "el argumento -D debe estar entre 1 y 9 inclusive"
diff --git a/src/po/sr.mo b/src/po/sr.mo
new file mode 100644 (file)
index 0000000..8bc781e
Binary files /dev/null and b/src/po/sr.mo differ
diff --git a/src/po/sr.po b/src/po/sr.po
new file mode 100644 (file)
index 0000000..37552c4
--- /dev/null
@@ -0,0 +1,740 @@
+# Language sudo-1 translations for sudo package.
+# This file is put in the public domain.
+# Мирослав Николић <miroslavnikolic@rocketmail.com>, 2011.
+msgid ""
+msgstr ""
+"Project-Id-Version: sudo 1.8.3rc1\n"
+"Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
+"POT-Creation-Date: 2011-09-16 13:37-0400\n"
+"PO-Revision-Date: 2011-11-30 12:17+0200\n"
+"Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
+"Language-Team: Serbian <gnu@prevod.org>\n"
+"Language: sr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Generator: Virtaal 0.6.1\n"
+
+#: src/error.c:82 src/error.c:86
+msgid ": "
+msgstr ": "
+
+#: src/exec.c:125 src/exec_pty.c:573 src/exec_pty.c:880 src/tgetpass.c:224
+#, c-format
+msgid "unable to fork"
+msgstr "не могу да поделим"
+
+#: src/exec.c:246
+#, c-format
+msgid "unable to create sockets"
+msgstr "не могу да направим утичнице"
+
+#: src/exec.c:253 src/exec_pty.c:526 src/exec_pty.c:534 src/exec_pty.c:541
+#: src/exec_pty.c:826 src/exec_pty.c:877 src/tgetpass.c:221
+#, c-format
+msgid "unable to create pipe"
+msgstr "не могу да направим спојку"
+
+#: src/exec.c:319 src/exec_pty.c:944 src/exec_pty.c:1077
+#, c-format
+msgid "select failed"
+msgstr "избор није успео"
+
+#: src/exec.c:387
+#, c-format
+msgid "unable to restore tty label"
+msgstr "не могу да повратим tty натпис"
+
+#: src/exec_pty.c:136
+#, c-format
+msgid "unable to allocate pty"
+msgstr "не могу да доделим pty"
+
+#: src/exec_pty.c:566
+#, c-format
+msgid "unable to set terminal to raw mode"
+msgstr "не могу да подесим терминал у сирови режим"
+
+#: src/exec_pty.c:858
+#, c-format
+msgid "unable to set controlling tty"
+msgstr "не могу да подесим контролисање tty"
+
+#: src/exec_pty.c:952
+#, c-format
+msgid "error reading from signal pipe"
+msgstr "грешка у читању из спојке сигнала"
+
+#: src/exec_pty.c:971
+#, c-format
+msgid "error reading from pipe"
+msgstr "грешка у читању из спојке"
+
+#: src/exec_pty.c:987
+#, c-format
+msgid "error reading from socketpair"
+msgstr "грешка у читању из пара прикључка"
+
+#: src/exec_pty.c:991
+#, c-format
+msgid "unexpected reply type on backchannel: %d"
+msgstr "неочекивана врста одговора на повратном каналу: %d"
+
+#: src/load_plugins.c:158
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: src/load_plugins.c:164
+#, c-format
+msgid "%s%s: %s"
+msgstr "%s%s: %s"
+
+#: src/load_plugins.c:174
+#, c-format
+msgid "%s must be owned by uid %d"
+msgstr "%s мора бити у власништву уида %d"
+
+#: src/load_plugins.c:178
+#, c-format
+msgid "%s must be only be writable by owner"
+msgstr "%s мора бити уписив само од стране власника"
+
+#: src/load_plugins.c:185
+#, c-format
+msgid "unable to dlopen %s: %s"
+msgstr "не могу да дл-отворим %s: %s"
+
+#: src/load_plugins.c:190
+#, c-format
+msgid "%s: unable to find symbol %s"
+msgstr "%s: не могу да пронађем симбол %s"
+
+#: src/load_plugins.c:196
+#, c-format
+msgid "%s: unknown policy type %d"
+msgstr "%s: непозната врста сигурности %d"
+
+#: src/load_plugins.c:200
+#, c-format
+msgid "%s: incompatible policy major version %d, expected %d"
+msgstr "%s: несагласно главно издање сигурности %d, очекивано је %d"
+
+#: src/load_plugins.c:207
+#, c-format
+msgid "%s: only a single policy plugin may be loaded"
+msgstr "%s: само прикључак самосталне сигурности може бити учитан"
+
+#: src/load_plugins.c:225
+#, c-format
+msgid "%s: at least one policy plugin must be specified"
+msgstr "%s: барем један прикључак сигурности мора бити наведен"
+
+#: src/load_plugins.c:230
+#, c-format
+msgid "policy plugin %s does not include a check_policy method"
+msgstr "прикључак сигурности %s не садржи метод провере_сигурности"
+
+#: src/net_ifs.c:155 src/net_ifs.c:164 src/net_ifs.c:176 src/net_ifs.c:185
+#: src/net_ifs.c:295 src/net_ifs.c:319
+#, c-format
+msgid "load_interfaces: overflow detected"
+msgstr "учитај_сучеља: откривено је прекорачење"
+
+#: src/net_ifs.c:224
+#, c-format
+msgid "unable to open socket"
+msgstr "не могу да отворим утичницу"
+
+#: src/parse_args.c:180
+#, c-format
+msgid "the argument to -C must be a number greater than or equal to 3"
+msgstr "аргумент уз -C мора бити број већи или једнак 3"
+
+#: src/parse_args.c:192
+#, c-format
+msgid "the argument to -D must be between 1 and 9 inclusive"
+msgstr "аргумент уз -D мора бити између 1 и 9 укључујући"
+
+#: src/parse_args.c:273
+#, c-format
+msgid "unknown user: %s"
+msgstr "непознат корисник: %s"
+
+#: src/parse_args.c:332
+#, c-format
+msgid "you may not specify both the `-i' and `-s' options"
+msgstr "не можете да наведете обе опције „-i“ и „-s“"
+
+#: src/parse_args.c:336
+#, c-format
+msgid "you may not specify both the `-i' and `-E' options"
+msgstr "не можете да наведете обе опције „-i“ и „-E“"
+
+#: src/parse_args.c:346
+#, c-format
+msgid "the `-E' option is not valid in edit mode"
+msgstr "опција „-E“ није исправна у режиму уређивања"
+
+#: src/parse_args.c:348
+#, c-format
+msgid "you may not specify environment variables in edit mode"
+msgstr "не можете да одредите променљиве окружења у режиму уређивања"
+
+#: src/parse_args.c:356
+#, c-format
+msgid "the `-U' option may only be used with the `-l' option"
+msgstr "опција „-U“ може бити коришћена само са опцијом „-l“"
+
+#: src/parse_args.c:360
+#, c-format
+msgid "the `-A' and `-S' options may not be used together"
+msgstr "опције „-A“ и „-S“ не могу бити коришћене заједно"
+
+#: src/parse_args.c:429 src/sudo.c:435 src/sudo.c:455 src/sudo.c:463
+#: src/sudo.c:473 common/alloc.c:85 common/alloc.c:105 common/alloc.c:123
+#: common/alloc.c:145 common/alloc.c:203 common/alloc.c:217
+#, c-format
+msgid "unable to allocate memory"
+msgstr "не могу да доделим меморију"
+
+#: src/parse_args.c:442
+#, c-format
+msgid "sudoedit is not supported on this platform"
+msgstr "„sudoedit“ није подржано на овој платформи"
+
+#: src/parse_args.c:513
+#, c-format
+msgid "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
+msgstr "Само једна од опција -e, -h, -i, -K, -l, -s, -v или -V може бити наведена "
+
+#: src/parse_args.c:526
+#, c-format
+msgid ""
+"%s - edit files as another user\n"
+"\n"
+msgstr ""
+"%s — уредите датотеке као други корисник\n"
+"\n"
+
+#: src/parse_args.c:528
+#, c-format
+msgid ""
+"%s - execute a command as another user\n"
+"\n"
+msgstr ""
+"%s — извршите наредбу као други корисник\n"
+"\n"
+
+#: src/parse_args.c:533
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Опције:\n"
+
+#: src/parse_args.c:536
+msgid "use helper program for password prompting\n"
+msgstr "користите програм испомоћи за упит лозинке\n"
+
+#: src/parse_args.c:539
+msgid "use specified BSD authentication type\n"
+msgstr "користи наведену врсту БСД потврде идентитета\n"
+
+#: src/parse_args.c:541
+msgid "run command in the background\n"
+msgstr "покреће наредбу у позадини\n"
+
+#: src/parse_args.c:543
+msgid "close all file descriptors >= fd\n"
+msgstr "затвара све описнике датотеке >= fd\n"
+
+#: src/parse_args.c:546
+msgid "run command with specified login class\n"
+msgstr "покреће наредбу са наведеном класом пријаве\n"
+
+#: src/parse_args.c:549
+msgid "preserve user environment when executing command\n"
+msgstr "чува корисничко окружење приликом извршавања наредбе\n"
+
+#: src/parse_args.c:551
+msgid "edit files instead of running a command\n"
+msgstr "уређује датотеке уместо да изврши наредбу\n"
+
+#: src/parse_args.c:553
+msgid "execute command as the specified group\n"
+msgstr "извршава наредбу као наведену групу\n"
+
+#: src/parse_args.c:555
+msgid "set HOME variable to target user's home dir.\n"
+msgstr "подешава променљиву ЛИЧНО у циљну корисничку личну фасциклу.\n"
+
+#: src/parse_args.c:557
+msgid "display help message and exit\n"
+msgstr "приказује поруку помоћи и излази\n"
+
+#: src/parse_args.c:559
+msgid "run a login shell as target user\n"
+msgstr "покреће љуску пријаве као крајњи корисник\n"
+
+#: src/parse_args.c:561
+msgid "remove timestamp file completely\n"
+msgstr "потпуно уклања датотеку записа датума и времена\n"
+
+#: src/parse_args.c:563
+msgid "invalidate timestamp file\n"
+msgstr "чини неисправном датотеку датума и времена\n"
+
+#: src/parse_args.c:565
+msgid "list user's available commands\n"
+msgstr "наводи наредбе доступне кориснику\n"
+
+#: src/parse_args.c:567
+msgid "non-interactive mode, will not prompt user\n"
+msgstr "немеђудејствени режим, неће питати корисника\n"
+
+#: src/parse_args.c:569
+msgid "preserve group vector instead of setting to target's\n"
+msgstr "чува вектор групе уместо да подеси на циљеве\n"
+
+#: src/parse_args.c:571
+msgid "use specified password prompt\n"
+msgstr "користи наведени упит лозинке\n"
+
+#: src/parse_args.c:574 src/parse_args.c:582
+msgid "create SELinux security context with specified role\n"
+msgstr "ствара СЕЛинукс сигурносни контекст са наведеном улогом\n"
+
+#: src/parse_args.c:577
+msgid "read password from standard input\n"
+msgstr "чита лозинку са стандардног улаза\n"
+
+#: src/parse_args.c:579
+msgid "run a shell as target user\n"
+msgstr "покреће љуску као крајњи корисник\n"
+
+#: src/parse_args.c:585
+msgid "when listing, list specified user's privileges\n"
+msgstr "када прави списак, исписује наведене привилегије корисника\n"
+
+#: src/parse_args.c:587
+msgid "run command (or edit file) as specified user\n"
+msgstr "покреће наредбу (или уређује датотеку) као наведени корисник\n"
+
+#: src/parse_args.c:589
+msgid "display version information and exit\n"
+msgstr "приказује податке о издању и излази\n"
+
+#: src/parse_args.c:591
+msgid "update user's timestamp without running a command\n"
+msgstr "освежава кориснички запис датума и времена без покретања наредбе\n"
+
+#: src/parse_args.c:593
+msgid "stop processing command line arguments\n"
+msgstr "зауставља обрађивање аргумената линије наредби\n"
+
+#: src/selinux.c:75
+#, c-format
+msgid "unable to open audit system"
+msgstr "не могу да отворим аудит систем"
+
+#: src/selinux.c:85
+#, c-format
+msgid "unable to send audit message"
+msgstr "не могу да пошаљем аудит поруку"
+
+#: src/selinux.c:112
+#, c-format
+msgid "unable to fgetfilecon %s"
+msgstr "не могу да добавим контекст отворене датотеке %s"
+
+#: src/selinux.c:117
+#, c-format
+msgid "%s changed labels"
+msgstr "%s измењена натписа"
+
+#: src/selinux.c:122
+#, c-format
+msgid "unable to restore context for %s"
+msgstr "не могу да повратим контекст за %s"
+
+#: src/selinux.c:161
+#, c-format
+msgid "unable to open %s, not relabeling tty"
+msgstr "не могу да отворим %s, није тту за поновно натписивање"
+
+#: src/selinux.c:170
+#, c-format
+msgid "unable to get current tty context, not relabeling tty"
+msgstr "не могу да добавим текући тту контекст, није тту за поновно натписивање"
+
+#: src/selinux.c:177
+#, c-format
+msgid "unable to get new tty context, not relabeling tty"
+msgstr "не могу да добавим нови тту контекст, није тту за поновно натписивање"
+
+#: src/selinux.c:184
+#, c-format
+msgid "unable to set new tty context"
+msgstr "не могу да подесим нови тту контекст"
+
+#: src/selinux.c:194 src/selinux.c:207 src/sudo.c:323
+#, c-format
+msgid "unable to open %s"
+msgstr "не могу да отворим %s"
+
+#: src/selinux.c:249
+#, c-format
+msgid "you must specify a role for type %s"
+msgstr "морате да наведете улогу за врсту %s"
+
+#: src/selinux.c:255
+#, c-format
+msgid "unable to get default type for role %s"
+msgstr "не могу да добавим основну врсту за улогу %s"
+
+#: src/selinux.c:273
+#, c-format
+msgid "failed to set new role %s"
+msgstr "нисам успео да подесим нову улогу %s"
+
+#: src/selinux.c:277
+#, c-format
+msgid "failed to set new type %s"
+msgstr "нисам успео да подесим нову врсту %s"
+
+#: src/selinux.c:286
+#, c-format
+msgid "%s is not a valid context"
+msgstr "%s није исправан контекст"
+
+#: src/selinux.c:320
+#, c-format
+msgid "failed to get old_context"
+msgstr "нисам успео да добавим стари_контекст"
+
+#: src/selinux.c:326
+#, c-format
+msgid "unable to determine enforcing mode."
+msgstr "не могу да одредим режим присиљавања."
+
+#: src/selinux.c:338
+#, c-format
+msgid "unable to setup tty context for %s"
+msgstr "не могу да подесим тту контекст за %s"
+
+#: src/selinux.c:367
+#, c-format
+msgid "unable to set exec context to %s"
+msgstr "не могу да подесим извршни контекст за %s"
+
+#: src/selinux.c:374
+#, c-format
+msgid "unable to set key creation context to %s"
+msgstr "не могу да подесим контекст стварања кључа за %s"
+
+#: src/sesh.c:48
+msgid "requires at least one argument"
+msgstr "захтева барем један аргумент"
+
+#: src/sesh.c:64
+#, c-format
+msgid "unable to execute %s"
+msgstr "не могу да извршим %s"
+
+#: src/sudo.c:191
+#, c-format
+msgid "must be setuid root"
+msgstr "морате бити сетуид администратор"
+
+#: src/sudo.c:209
+#, c-format
+msgid "Sudo version %s\n"
+msgstr "Судо издање %s\n"
+
+#: src/sudo.c:211
+#, c-format
+msgid "Configure options: %s\n"
+msgstr "Опције подешавања: %s\n"
+
+#: src/sudo.c:216
+#, c-format
+msgid "fatal error, unable to load plugins"
+msgstr "кобна грешка, не могу да учитам прикључке"
+
+#: src/sudo.c:224
+#, c-format
+msgid "unable to initialize policy plugin"
+msgstr "не могу да започнем прикључак сигурности"
+
+#: src/sudo.c:279
+#, c-format
+msgid "error initializing I/O plugin %s"
+msgstr "грешка приликом покретања У/И прикључка %s"
+
+#: src/sudo.c:300
+#, c-format
+msgid "unexpected sudo mode 0x%x"
+msgstr "неочекивани судо режим 0x%x"
+
+#: src/sudo.c:389
+#, c-format
+msgid "unable to get group vector"
+msgstr "не могу да добавим вектор групе"
+
+#: src/sudo.c:431
+#, c-format
+msgid "unknown uid %u: who are you?"
+msgstr "непознати уид %u: ко сте ви?"
+
+#: src/sudo.c:773
+#, c-format
+msgid "resource control limit has been reached"
+msgstr "ограничење контроле ресурса је достигнуто"
+
+#: src/sudo.c:776
+#, c-format
+msgid "user \"%s\" is not a member of project \"%s\""
+msgstr "корисник „%s“ није члан пројекта „%s“"
+
+#: src/sudo.c:780
+#, c-format
+msgid "the invoking task is final"
+msgstr "задатак призивања је завршни"
+
+#: src/sudo.c:783
+#, c-format
+msgid "could not join project \"%s\""
+msgstr "не могу да приступим пројекту „%s“"
+
+#: src/sudo.c:788
+#, c-format
+msgid "no resource pool accepting default bindings exists for project \"%s\""
+msgstr "не постоји депо извора који прихвата основне пречице за пројекат „%s“"
+
+#: src/sudo.c:792
+#, c-format
+msgid "specified resource pool does not exist for project \"%s\""
+msgstr "наведени депо извора не постоји за пројекат „%s“"
+
+#: src/sudo.c:796
+#, c-format
+msgid "could not bind to default resource pool for project \"%s\""
+msgstr "не могу да се повежем са основним депоом извора за пројекат „%s“"
+
+#: src/sudo.c:802
+#, c-format
+msgid "setproject failed for project \"%s\""
+msgstr "подешавање пројекта није успело за пројекат „%s“"
+
+#: src/sudo.c:804
+#, c-format
+msgid "warning, resource control assignment failed for project \"%s\""
+msgstr "упозорење, није успело додељивање контроле ресурса за пројекат „%s“"
+
+#: src/sudo.c:832
+#, c-format
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr "не могу да уклоним PRIV_PROC_EXEC из PRIV_LIMIT"
+
+#: src/sudo.c:938
+#, c-format
+msgid "unknown login class %s"
+msgstr "непозната класа пријаве %s"
+
+#: src/sudo.c:945 src/sudo.c:948
+#, c-format
+msgid "unable to set user context"
+msgstr "не могу да подесим кориснички контекст"
+
+#: src/sudo.c:959
+#, c-format
+msgid "unable to set effective gid to runas gid %u"
+msgstr "не могу да подесим ефективан гид да се покрене_као гид %u"
+
+#: src/sudo.c:965
+#, c-format
+msgid "unable to set gid to runas gid %u"
+msgstr "не могу да подесим гид да се покрене као гид %u"
+
+#: src/sudo.c:973
+#, c-format
+msgid "unable to set supplementary group IDs"
+msgstr "не могу да подесим додатне ИБ-ове групе"
+
+#: src/sudo.c:981
+#, c-format
+msgid "unable to set process priority"
+msgstr "не могу да подесим приоритет процеса"
+
+#: src/sudo.c:989
+#, c-format
+msgid "unable to change root to %s"
+msgstr "не могу да променим администратора на %s"
+
+#: src/sudo.c:999 src/sudo.c:1005 src/sudo.c:1011
+#, c-format
+msgid "unable to change to runas uid (%u, %u)"
+msgstr "не могу да се пребацим у покрени_као уид (%u, %u)"
+
+#: src/sudo.c:1025
+#, c-format
+msgid "unable to change directory to %s"
+msgstr "не могу да променим директоријум у %s"
+
+#: src/sudo.c:1092
+#, c-format
+msgid "unexpected child termination condition: %d"
+msgstr "неочекивани услов завршетка потпроцеса: %d"
+
+#: src/sudo.c:1132
+#, c-format
+msgid "policy plugin %s does not support listing privileges"
+msgstr "прикључак сигурности %s не подржава привилегије исписивања"
+
+#: src/sudo.c:1143
+#, c-format
+msgid "policy plugin %s does not support the -v option"
+msgstr "прикључак сигурности %s не подржава опцију -v"
+
+#: src/sudo.c:1154
+#, c-format
+msgid "policy plugin %s does not support the -k/-K options"
+msgstr "прикључак сигурности %s не подржава опције -k/-K"
+
+#: src/sudo_edit.c:108
+#, c-format
+msgid "unable to change uid to root (%u)"
+msgstr "не могу да променим уид у администратора (%u)"
+
+#: src/sudo_edit.c:140
+#, c-format
+msgid "plugin error: missing file list for sudoedit"
+msgstr "грешка прикључка: недостаје датотеа списка за уређивање судоа"
+
+#: src/sudo_edit.c:168 src/sudo_edit.c:268
+#, c-format
+msgid "%s: not a regular file"
+msgstr "%s: није обична датотека"
+
+#: src/sudo_edit.c:202 src/sudo_edit.c:304
+#, c-format
+msgid "%s: short write"
+msgstr "%s: кратак упис"
+
+#: src/sudo_edit.c:269
+#, c-format
+msgid "%s left unmodified"
+msgstr "%s је остао неизмењен"
+
+#: src/sudo_edit.c:282
+#, c-format
+msgid "%s unchanged"
+msgstr "%s је непромењен"
+
+#: src/sudo_edit.c:294 src/sudo_edit.c:315
+#, c-format
+msgid "unable to write to %s"
+msgstr "не могу да упишем у %s"
+
+#: src/sudo_edit.c:295 src/sudo_edit.c:313 src/sudo_edit.c:316
+#, c-format
+msgid "contents of edit session left in %s"
+msgstr "садржај сесије уређивања је остао у %s"
+
+#: src/sudo_edit.c:312
+#, c-format
+msgid "unable to read temporary file"
+msgstr "не могу да прочитам привремену датотеку"
+
+#: src/tgetpass.c:95
+#, c-format
+msgid "no tty present and no askpass program specified"
+msgstr "тту не постоји и није наведен програм за пропуштање"
+
+#: src/tgetpass.c:104
+#, c-format
+msgid "no askpass program specified, try setting SUDO_ASKPASS"
+msgstr "није наведен програм за пропуштање, покушајте да подесите SUDO_ASKPASS"
+
+#: src/tgetpass.c:234
+#, c-format
+msgid "unable to set gid to %u"
+msgstr "не могу да подесим гид у %u"
+
+#: src/tgetpass.c:238
+#, c-format
+msgid "unable to set uid to %u"
+msgstr "не могу да подесим уид у %u"
+
+#: src/tgetpass.c:243
+#, c-format
+msgid "unable to run %s"
+msgstr "не могу да покренем %s"
+
+#: src/utmp.c:263
+#, c-format
+msgid "unable to save stdin"
+msgstr "не могу да сачувам стандардни улаз"
+
+#: src/utmp.c:265
+#, c-format
+msgid "unable to dup2 stdin"
+msgstr "не могу да дуп2 стандардни улаз"
+
+#: src/utmp.c:268
+#, c-format
+msgid "unable to restore stdin"
+msgstr "не могу да повратим стандардни улаз"
+
+#: common/aix.c:144
+#, c-format
+msgid "unable to open userdb"
+msgstr "не могу да отворим корисничку базу података"
+
+#: common/aix.c:147
+#, c-format
+msgid "unable to switch to registry \"%s\" for %s"
+msgstr "не могу да се пребацим на регистар „%s“ за %s"
+
+#: common/aix.c:161
+#, c-format
+msgid "unable to restore registry"
+msgstr "не могу да повратим регистар"
+
+#: common/alloc.c:82
+#, c-format
+msgid "internal error, tried to emalloc(0)"
+msgstr "унутрашња грешка, покушах да обавим „emalloc(0)“"
+
+#: common/alloc.c:99
+#, c-format
+msgid "internal error, tried to emalloc2(0)"
+msgstr "унутрашња грешка, покушах да обавим „emalloc2(0)“"
+
+#: common/alloc.c:101
+#, c-format
+msgid "internal error, emalloc2() overflow"
+msgstr "унутрашња грешка, прекорачење функције „emalloc2()“"
+
+#: common/alloc.c:119
+#, c-format
+msgid "internal error, tried to erealloc(0)"
+msgstr "унутрашња грешка, покушах да обавим „erealloc(0)“"
+
+#: common/alloc.c:138
+#, c-format
+msgid "internal error, tried to erealloc3(0)"
+msgstr "унутрашња грешка, покушах да обавим „erealloc3(0)“"
+
+#: common/alloc.c:140
+#, c-format
+msgid "internal error, erealloc3() overflow"
+msgstr "унутрашња грешка, прекорачење функције „erealloc3()“"
+
+#: compat/strsignal.c:47
+msgid "Unknown signal"
+msgstr "Непознати сигнал"
index dc79e5d57c8a748c9fc9dfe3b18f9b0c86a97d61..1858bf07fb35b9f507b63ef18d44176f30dfc2bc 100644 (file)
@@ -5,9 +5,9 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: sudo 1.8.3p2\n"
+"Project-Id-Version: sudo 1.8.4\n"
 "Report-Msgid-Bugs-To: http://www.sudo.ws/bugs\n"
-"POT-Creation-Date: 2012-01-24 16:12-0500\n"
+"POT-Creation-Date: 2012-02-16 17:06-0500\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -20,323 +20,324 @@ msgstr ""
 msgid ": "
 msgstr ""
 
-#: src/exec.c:125 src/exec_pty.c:573 src/exec_pty.c:880 src/tgetpass.c:224
+#: src/exec.c:105 src/exec_pty.c:604 src/exec_pty.c:936 src/tgetpass.c:227
 #, c-format
 msgid "unable to fork"
 msgstr ""
 
-#: src/exec.c:246
+#: src/exec.c:252
 #, c-format
 msgid "unable to create sockets"
 msgstr ""
 
-#: src/exec.c:253 src/exec_pty.c:526 src/exec_pty.c:534 src/exec_pty.c:541
-#: src/exec_pty.c:826 src/exec_pty.c:877 src/tgetpass.c:221
+#: src/exec.c:259 src/exec_pty.c:557 src/exec_pty.c:565 src/exec_pty.c:572
+#: src/exec_pty.c:871 src/exec_pty.c:933 src/tgetpass.c:224
 #, c-format
 msgid "unable to create pipe"
 msgstr ""
 
-#: src/exec.c:319 src/exec_pty.c:944 src/exec_pty.c:1077
+#: src/exec.c:340 src/exec_pty.c:1000 src/exec_pty.c:1135
 #, c-format
 msgid "select failed"
 msgstr ""
 
-#: src/exec.c:387
+#: src/exec.c:425
 #, c-format
 msgid "unable to restore tty label"
 msgstr ""
 
-#: src/exec_pty.c:136
+#: src/exec_common.c:66
+#, c-format
+msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
+msgstr ""
+
+#: src/exec_common.c:88 src/parse_args.c:432 src/sudo.c:445 src/sudo.c:465
+#: src/sudo.c:472 src/sudo.c:483 src/sudo.c:842 common/alloc.c:85
+#: common/alloc.c:105 common/alloc.c:123 common/alloc.c:145 common/alloc.c:203
+#: common/alloc.c:217
+#, c-format
+msgid "unable to allocate memory"
+msgstr ""
+
+#: src/exec_pty.c:140
 #, c-format
 msgid "unable to allocate pty"
 msgstr ""
 
-#: src/exec_pty.c:566
+#: src/exec_pty.c:597
 #, c-format
 msgid "unable to set terminal to raw mode"
 msgstr ""
 
-#: src/exec_pty.c:858
+#: src/exec_pty.c:914
 #, c-format
 msgid "unable to set controlling tty"
 msgstr ""
 
-#: src/exec_pty.c:952
+#: src/exec_pty.c:1008
 #, c-format
 msgid "error reading from signal pipe"
 msgstr ""
 
-#: src/exec_pty.c:971
+#: src/exec_pty.c:1027
 #, c-format
 msgid "error reading from pipe"
 msgstr ""
 
-#: src/exec_pty.c:987
+#: src/exec_pty.c:1043
 #, c-format
 msgid "error reading from socketpair"
 msgstr ""
 
-#: src/exec_pty.c:991
+#: src/exec_pty.c:1047
 #, c-format
 msgid "unexpected reply type on backchannel: %d"
 msgstr ""
 
-#: src/load_plugins.c:158
+#: src/load_plugins.c:79
 #, c-format
 msgid "%s: %s"
 msgstr ""
 
-#: src/load_plugins.c:164
+#: src/load_plugins.c:85
 #, c-format
 msgid "%s%s: %s"
 msgstr ""
 
-#: src/load_plugins.c:174
+#: src/load_plugins.c:95
 #, c-format
 msgid "%s must be owned by uid %d"
 msgstr ""
 
-#: src/load_plugins.c:178
+#: src/load_plugins.c:99
 #, c-format
 msgid "%s must be only be writable by owner"
 msgstr ""
 
-#: src/load_plugins.c:185
+#: src/load_plugins.c:106
 #, c-format
 msgid "unable to dlopen %s: %s"
 msgstr ""
 
-#: src/load_plugins.c:190
+#: src/load_plugins.c:111
 #, c-format
 msgid "%s: unable to find symbol %s"
 msgstr ""
 
-#: src/load_plugins.c:196
+#: src/load_plugins.c:117
 #, c-format
 msgid "%s: unknown policy type %d"
 msgstr ""
 
-#: src/load_plugins.c:200
+#: src/load_plugins.c:121
 #, c-format
 msgid "%s: incompatible policy major version %d, expected %d"
 msgstr ""
 
-#: src/load_plugins.c:207
+#: src/load_plugins.c:128
 #, c-format
 msgid "%s: only a single policy plugin may be loaded"
 msgstr ""
 
-#: src/load_plugins.c:225
+#: src/load_plugins.c:146
 #, c-format
 msgid "%s: at least one policy plugin must be specified"
 msgstr ""
 
-#: src/load_plugins.c:230
+#: src/load_plugins.c:151
 #, c-format
 msgid "policy plugin %s does not include a check_policy method"
 msgstr ""
 
-#: src/net_ifs.c:155 src/net_ifs.c:164 src/net_ifs.c:176 src/net_ifs.c:185
-#: src/net_ifs.c:295 src/net_ifs.c:319
+#: src/net_ifs.c:157 src/net_ifs.c:166 src/net_ifs.c:178 src/net_ifs.c:187
+#: src/net_ifs.c:298 src/net_ifs.c:322
 #, c-format
 msgid "load_interfaces: overflow detected"
 msgstr ""
 
-#: src/net_ifs.c:224
+#: src/net_ifs.c:227
 #, c-format
 msgid "unable to open socket"
 msgstr ""
 
-#: src/parse_args.c:180
+#: src/parse_args.c:187
 #, c-format
 msgid "the argument to -C must be a number greater than or equal to 3"
 msgstr ""
 
-#: src/parse_args.c:192
-#, c-format
-msgid "the argument to -D must be between 1 and 9 inclusive"
-msgstr ""
-
-#: src/parse_args.c:273
+#: src/parse_args.c:276
 #, c-format
 msgid "unknown user: %s"
 msgstr ""
 
-#: src/parse_args.c:332
+#: src/parse_args.c:335
 #, c-format
 msgid "you may not specify both the `-i' and `-s' options"
 msgstr ""
 
-#: src/parse_args.c:336
+#: src/parse_args.c:339
 #, c-format
 msgid "you may not specify both the `-i' and `-E' options"
 msgstr ""
 
-#: src/parse_args.c:346
+#: src/parse_args.c:349
 #, c-format
 msgid "the `-E' option is not valid in edit mode"
 msgstr ""
 
-#: src/parse_args.c:348
+#: src/parse_args.c:351
 #, c-format
 msgid "you may not specify environment variables in edit mode"
 msgstr ""
 
-#: src/parse_args.c:356
+#: src/parse_args.c:359
 #, c-format
 msgid "the `-U' option may only be used with the `-l' option"
 msgstr ""
 
-#: src/parse_args.c:360
+#: src/parse_args.c:363
 #, c-format
 msgid "the `-A' and `-S' options may not be used together"
 msgstr ""
 
-#: src/parse_args.c:429 src/sudo.c:435 src/sudo.c:455 src/sudo.c:463
-#: src/sudo.c:473 common/alloc.c:85 common/alloc.c:105 common/alloc.c:123
-#: common/alloc.c:145 common/alloc.c:203 common/alloc.c:217
-#, c-format
-msgid "unable to allocate memory"
-msgstr ""
-
-#: src/parse_args.c:442
+#: src/parse_args.c:445
 #, c-format
 msgid "sudoedit is not supported on this platform"
 msgstr ""
 
-#: src/parse_args.c:513
+#: src/parse_args.c:518
 #, c-format
 msgid ""
 "Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"
 msgstr ""
 
-#: src/parse_args.c:526
+#: src/parse_args.c:532
 #, c-format
 msgid ""
 "%s - edit files as another user\n"
 "\n"
 msgstr ""
 
-#: src/parse_args.c:528
+#: src/parse_args.c:534
 #, c-format
 msgid ""
 "%s - execute a command as another user\n"
 "\n"
 msgstr ""
 
-#: src/parse_args.c:533
+#: src/parse_args.c:539
 #, c-format
 msgid ""
 "\n"
 "Options:\n"
 msgstr ""
 
-#: src/parse_args.c:536
+#: src/parse_args.c:542
 msgid "use helper program for password prompting\n"
 msgstr ""
 
-#: src/parse_args.c:539
+#: src/parse_args.c:545
 msgid "use specified BSD authentication type\n"
 msgstr ""
 
-#: src/parse_args.c:541
+#: src/parse_args.c:547
 msgid "run command in the background\n"
 msgstr ""
 
-#: src/parse_args.c:543
+#: src/parse_args.c:549
 msgid "close all file descriptors >= fd\n"
 msgstr ""
 
-#: src/parse_args.c:546
+#: src/parse_args.c:552
 msgid "run command with specified login class\n"
 msgstr ""
 
-#: src/parse_args.c:549
+#: src/parse_args.c:555
 msgid "preserve user environment when executing command\n"
 msgstr ""
 
-#: src/parse_args.c:551
+#: src/parse_args.c:557
 msgid "edit files instead of running a command\n"
 msgstr ""
 
-#: src/parse_args.c:553
+#: src/parse_args.c:559
 msgid "execute command as the specified group\n"
 msgstr ""
 
-#: src/parse_args.c:555
+#: src/parse_args.c:561
 msgid "set HOME variable to target user's home dir.\n"
 msgstr ""
 
-#: src/parse_args.c:557
+#: src/parse_args.c:563
 msgid "display help message and exit\n"
 msgstr ""
 
-#: src/parse_args.c:559
+#: src/parse_args.c:565
 msgid "run a login shell as target user\n"
 msgstr ""
 
-#: src/parse_args.c:561
+#: src/parse_args.c:567
 msgid "remove timestamp file completely\n"
 msgstr ""
 
-#: src/parse_args.c:563
+#: src/parse_args.c:569
 msgid "invalidate timestamp file\n"
 msgstr ""
 
-#: src/parse_args.c:565
+#: src/parse_args.c:571
 msgid "list user's available commands\n"
 msgstr ""
 
-#: src/parse_args.c:567
+#: src/parse_args.c:573
 msgid "non-interactive mode, will not prompt user\n"
 msgstr ""
 
-#: src/parse_args.c:569
+#: src/parse_args.c:575
 msgid "preserve group vector instead of setting to target's\n"
 msgstr ""
 
-#: src/parse_args.c:571
+#: src/parse_args.c:577
 msgid "use specified password prompt\n"
 msgstr ""
 
-#: src/parse_args.c:574 src/parse_args.c:582
+#: src/parse_args.c:580 src/parse_args.c:588
 msgid "create SELinux security context with specified role\n"
 msgstr ""
 
-#: src/parse_args.c:577
+#: src/parse_args.c:583
 msgid "read password from standard input\n"
 msgstr ""
 
-#: src/parse_args.c:579
+#: src/parse_args.c:585
 msgid "run a shell as target user\n"
 msgstr ""
 
-#: src/parse_args.c:585
+#: src/parse_args.c:591
 msgid "when listing, list specified user's privileges\n"
 msgstr ""
 
-#: src/parse_args.c:587
+#: src/parse_args.c:593
 msgid "run command (or edit file) as specified user\n"
 msgstr ""
 
-#: src/parse_args.c:589
+#: src/parse_args.c:595
 msgid "display version information and exit\n"
 msgstr ""
 
-#: src/parse_args.c:591
+#: src/parse_args.c:597
 msgid "update user's timestamp without running a command\n"
 msgstr ""
 
-#: src/parse_args.c:593
+#: src/parse_args.c:599
 msgid "stop processing command line arguments\n"
 msgstr ""
 
-#: src/selinux.c:75
+#: src/selinux.c:76
 #, c-format
 msgid "unable to open audit system"
 msgstr ""
 
-#: src/selinux.c:85
+#: src/selinux.c:84
 #, c-format
 msgid "unable to send audit message"
 msgstr ""
@@ -356,377 +357,367 @@ msgstr ""
 msgid "unable to restore context for %s"
 msgstr ""
 
-#: src/selinux.c:161
+#: src/selinux.c:162
 #, c-format
 msgid "unable to open %s, not relabeling tty"
 msgstr ""
 
-#: src/selinux.c:170
+#: src/selinux.c:171
 #, c-format
 msgid "unable to get current tty context, not relabeling tty"
 msgstr ""
 
-#: src/selinux.c:177
+#: src/selinux.c:178
 #, c-format
 msgid "unable to get new tty context, not relabeling tty"
 msgstr ""
 
-#: src/selinux.c:184
+#: src/selinux.c:185
 #, c-format
 msgid "unable to set new tty context"
 msgstr ""
 
-#: src/selinux.c:194 src/selinux.c:207 src/sudo.c:323
+#: src/selinux.c:195 src/selinux.c:208 src/sudo.c:331
 #, c-format
 msgid "unable to open %s"
 msgstr ""
 
-#: src/selinux.c:249
+#: src/selinux.c:251
 #, c-format
 msgid "you must specify a role for type %s"
 msgstr ""
 
-#: src/selinux.c:255
+#: src/selinux.c:257
 #, c-format
 msgid "unable to get default type for role %s"
 msgstr ""
 
-#: src/selinux.c:273
+#: src/selinux.c:275
 #, c-format
 msgid "failed to set new role %s"
 msgstr ""
 
-#: src/selinux.c:277
+#: src/selinux.c:279
 #, c-format
 msgid "failed to set new type %s"
 msgstr ""
 
-#: src/selinux.c:286
+#: src/selinux.c:288
 #, c-format
 msgid "%s is not a valid context"
 msgstr ""
 
-#: src/selinux.c:320
+#: src/selinux.c:323
 #, c-format
 msgid "failed to get old_context"
 msgstr ""
 
-#: src/selinux.c:326
+#: src/selinux.c:329
 #, c-format
 msgid "unable to determine enforcing mode."
 msgstr ""
 
-#: src/selinux.c:338
+#: src/selinux.c:341
 #, c-format
 msgid "unable to setup tty context for %s"
 msgstr ""
 
-#: src/selinux.c:367
+#: src/selinux.c:372
 #, c-format
 msgid "unable to set exec context to %s"
 msgstr ""
 
-#: src/selinux.c:374
+#: src/selinux.c:379
 #, c-format
 msgid "unable to set key creation context to %s"
 msgstr ""
 
-#: src/sesh.c:48
+#: src/sesh.c:69
+#, c-format
 msgid "requires at least one argument"
 msgstr ""
 
-#: src/sesh.c:64
+#: src/sesh.c:90
 #, c-format
 msgid "unable to execute %s"
 msgstr ""
 
-#: src/sudo.c:191
+#: src/sudo.c:189
 #, c-format
 msgid "must be setuid root"
 msgstr ""
 
-#: src/sudo.c:209
+#: src/sudo.c:212
 #, c-format
 msgid "Sudo version %s\n"
 msgstr ""
 
-#: src/sudo.c:211
+#: src/sudo.c:214
 #, c-format
 msgid "Configure options: %s\n"
 msgstr ""
 
-#: src/sudo.c:216
+#: src/sudo.c:219
 #, c-format
 msgid "fatal error, unable to load plugins"
 msgstr ""
 
-#: src/sudo.c:224
+#: src/sudo.c:227
 #, c-format
 msgid "unable to initialize policy plugin"
 msgstr ""
 
-#: src/sudo.c:279
+#: src/sudo.c:282
 #, c-format
 msgid "error initializing I/O plugin %s"
 msgstr ""
 
-#: src/sudo.c:300
+#: src/sudo.c:306
 #, c-format
 msgid "unexpected sudo mode 0x%x"
 msgstr ""
 
-#: src/sudo.c:389
+#: src/sudo.c:400
 #, c-format
 msgid "unable to get group vector"
 msgstr ""
 
-#: src/sudo.c:431
+#: src/sudo.c:441
 #, c-format
 msgid "unknown uid %u: who are you?"
 msgstr ""
 
-#: src/sudo.c:773
+#: src/sudo.c:784
 #, c-format
 msgid "resource control limit has been reached"
 msgstr ""
 
-#: src/sudo.c:776
+#: src/sudo.c:787
 #, c-format
 msgid "user \"%s\" is not a member of project \"%s\""
 msgstr ""
 
-#: src/sudo.c:780
+#: src/sudo.c:791
 #, c-format
 msgid "the invoking task is final"
 msgstr ""
 
-#: src/sudo.c:783
+#: src/sudo.c:794
 #, c-format
 msgid "could not join project \"%s\""
 msgstr ""
 
-#: src/sudo.c:788
+#: src/sudo.c:799
 #, c-format
 msgid "no resource pool accepting default bindings exists for project \"%s\""
 msgstr ""
 
-#: src/sudo.c:792
+#: src/sudo.c:803
 #, c-format
 msgid "specified resource pool does not exist for project \"%s\""
 msgstr ""
 
-#: src/sudo.c:796
+#: src/sudo.c:807
 #, c-format
 msgid "could not bind to default resource pool for project \"%s\""
 msgstr ""
 
-#: src/sudo.c:802
+#: src/sudo.c:813
 #, c-format
 msgid "setproject failed for project \"%s\""
 msgstr ""
 
-#: src/sudo.c:804
+#: src/sudo.c:815
 #, c-format
 msgid "warning, resource control assignment failed for project \"%s\""
 msgstr ""
 
-#: src/sudo.c:832
-#, c-format
-msgid "unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"
-msgstr ""
-
-#: src/sudo.c:938
+#: src/sudo.c:880
 #, c-format
 msgid "unknown login class %s"
 msgstr ""
 
-#: src/sudo.c:945 src/sudo.c:948
+#: src/sudo.c:896 src/sudo.c:899
 #, c-format
 msgid "unable to set user context"
 msgstr ""
 
-#: src/sudo.c:959
+#: src/sudo.c:915
 #, c-format
-msgid "unable to set effective gid to runas gid %u"
+msgid "unable to set supplementary group IDs"
 msgstr ""
 
-#: src/sudo.c:965
+#: src/sudo.c:922
 #, c-format
-msgid "unable to set gid to runas gid %u"
+msgid "unable to set effective gid to runas gid %u"
 msgstr ""
 
-#: src/sudo.c:973
+#: src/sudo.c:928
 #, c-format
-msgid "unable to set supplementary group IDs"
+msgid "unable to set gid to runas gid %u"
 msgstr ""
 
-#: src/sudo.c:981
+#: src/sudo.c:935
 #, c-format
 msgid "unable to set process priority"
 msgstr ""
 
-#: src/sudo.c:989
+#: src/sudo.c:943
 #, c-format
 msgid "unable to change root to %s"
 msgstr ""
 
-#: src/sudo.c:999 src/sudo.c:1005 src/sudo.c:1011
+#: src/sudo.c:950 src/sudo.c:956 src/sudo.c:962
 #, c-format
 msgid "unable to change to runas uid (%u, %u)"
 msgstr ""
 
-#: src/sudo.c:1025
+#: src/sudo.c:976
 #, c-format
 msgid "unable to change directory to %s"
 msgstr ""
 
-#: src/sudo.c:1092
+#: src/sudo.c:1049
 #, c-format
 msgid "unexpected child termination condition: %d"
 msgstr ""
 
-#: src/sudo.c:1132
+#: src/sudo.c:1095
 #, c-format
 msgid "policy plugin %s does not support listing privileges"
 msgstr ""
 
-#: src/sudo.c:1143
+#: src/sudo.c:1107
 #, c-format
 msgid "policy plugin %s does not support the -v option"
 msgstr ""
 
-#: src/sudo.c:1154
+#: src/sudo.c:1119
 #, c-format
 msgid "policy plugin %s does not support the -k/-K options"
 msgstr ""
 
-#: src/sudo_edit.c:108
+#: src/sudo_edit.c:111
 #, c-format
 msgid "unable to change uid to root (%u)"
 msgstr ""
 
-#: src/sudo_edit.c:140
+#: src/sudo_edit.c:143
 #, c-format
 msgid "plugin error: missing file list for sudoedit"
 msgstr ""
 
-#: src/sudo_edit.c:168 src/sudo_edit.c:268
+#: src/sudo_edit.c:171 src/sudo_edit.c:271
 #, c-format
 msgid "%s: not a regular file"
 msgstr ""
 
-#: src/sudo_edit.c:202 src/sudo_edit.c:304
+#: src/sudo_edit.c:205 src/sudo_edit.c:307
 #, c-format
 msgid "%s: short write"
 msgstr ""
 
-#: src/sudo_edit.c:269
+#: src/sudo_edit.c:272
 #, c-format
 msgid "%s left unmodified"
 msgstr ""
 
-#: src/sudo_edit.c:282
+#: src/sudo_edit.c:285
 #, c-format
 msgid "%s unchanged"
 msgstr ""
 
-#: src/sudo_edit.c:294 src/sudo_edit.c:315
+#: src/sudo_edit.c:297 src/sudo_edit.c:318
 #, c-format
 msgid "unable to write to %s"
 msgstr ""
 
-#: src/sudo_edit.c:295 src/sudo_edit.c:313 src/sudo_edit.c:316
+#: src/sudo_edit.c:298 src/sudo_edit.c:316 src/sudo_edit.c:319
 #, c-format
 msgid "contents of edit session left in %s"
 msgstr ""
 
-#: src/sudo_edit.c:312
+#: src/sudo_edit.c:315
 #, c-format
 msgid "unable to read temporary file"
 msgstr ""
 
-#: src/tgetpass.c:95
+#: src/tgetpass.c:96
 #, c-format
 msgid "no tty present and no askpass program specified"
 msgstr ""
 
-#: src/tgetpass.c:104
+#: src/tgetpass.c:105
 #, c-format
 msgid "no askpass program specified, try setting SUDO_ASKPASS"
 msgstr ""
 
-#: src/tgetpass.c:234
+#: src/tgetpass.c:237
 #, c-format
 msgid "unable to set gid to %u"
 msgstr ""
 
-#: src/tgetpass.c:238
+#: src/tgetpass.c:241
 #, c-format
 msgid "unable to set uid to %u"
 msgstr ""
 
-#: src/tgetpass.c:243
+#: src/tgetpass.c:246
 #, c-format
 msgid "unable to run %s"
 msgstr ""
 
-#: src/utmp.c:265
+#: src/utmp.c:278
 #, c-format
 msgid "unable to save stdin"
 msgstr ""
 
-#: src/utmp.c:267
+#: src/utmp.c:280
 #, c-format
 msgid "unable to dup2 stdin"
 msgstr ""
 
-#: src/utmp.c:270
+#: src/utmp.c:283
 #, c-format
 msgid "unable to restore stdin"
 msgstr ""
 
-#: common/aix.c:144
+#: common/aix.c:149
 #, c-format
 msgid "unable to open userdb"
 msgstr ""
 
-#: common/aix.c:147
+#: common/aix.c:152
 #, c-format
 msgid "unable to switch to registry \"%s\" for %s"
 msgstr ""
 
-#: common/aix.c:161
+#: common/aix.c:169
 #, c-format
 msgid "unable to restore registry"
 msgstr ""
 
 #: common/alloc.c:82
-#, c-format
 msgid "internal error, tried to emalloc(0)"
 msgstr ""
 
 #: common/alloc.c:99
-#, c-format
 msgid "internal error, tried to emalloc2(0)"
 msgstr ""
 
 #: common/alloc.c:101
-#, c-format
 msgid "internal error, emalloc2() overflow"
 msgstr ""
 
 #: common/alloc.c:119
-#, c-format
 msgid "internal error, tried to erealloc(0)"
 msgstr ""
 
 #: common/alloc.c:138
-#, c-format
 msgid "internal error, tried to erealloc3(0)"
 msgstr ""
 
 #: common/alloc.c:140
-#, c-format
 msgid "internal error, erealloc3() overflow"
 msgstr ""
 
index dc519731a48c91a33437d1cfb8c1ae32cfb5f958..23ffbd0f7e63fc85af396fd0ae0924e8476966e5 100644 (file)
@@ -64,8 +64,9 @@ static int
 audit_role_change(const security_context_t old_context,
     const security_context_t new_context, const char *ttyn)
 {
-    int au_fd, rc;
+    int au_fd, rc = -1;
     char *message;
+    debug_decl(audit_role_change, SUDO_DEBUG_SELINUX)
 
     au_fd = audit_open();
     if (au_fd == -1) {
@@ -73,21 +74,19 @@ audit_role_change(const security_context_t old_context,
         if (errno != EINVAL && errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT
 )
             error(1, _("unable to open audit system"));
-       return -1;
+    } else {
+       /* audit role change using the same format as newrole(1) */
+       easprintf(&message, "newrole: old-context=%s new-context=%s",
+           old_context, new_context);
+       rc = audit_log_user_message(au_fd, AUDIT_USER_ROLE_CHANGE,
+           message, NULL, NULL, ttyn, 1);
+       if (rc <= 0)
+           warning(_("unable to send audit message"));
+       efree(message);
+       close(au_fd);
     }
 
-    /* audit role change using the same format as newrole(1) */
-    easprintf(&message, "newrole: old-context=%s new-context=%s",
-       old_context, new_context);
-    rc = audit_log_user_message(au_fd, AUDIT_USER_ROLE_CHANGE,
-       message, NULL, NULL, ttyn, 1);
-    if (rc <= 0)
-       warning(_("unable to send audit message"));
-
-    efree(message);
-    close(au_fd);
-
-    return rc;
+    debug_return_int(rc);
 }
 #endif
 
@@ -103,6 +102,7 @@ selinux_restore_tty(void)
 {
     int retval = 0;
     security_context_t chk_tty_context = NULL;
+    debug_decl(selinux_restore_tty, SUDO_DEBUG_SELINUX)
 
     if (se_state.ttyfd == -1 || se_state.new_tty_context == NULL)
        goto skip_relabel;
@@ -130,7 +130,7 @@ skip_relabel:
        freecon(chk_tty_context);
        chk_tty_context = NULL;
     }
-    return retval;
+    debug_return_int(retval);
 }
 
 /*
@@ -147,12 +147,13 @@ relabel_tty(const char *ttyn, int ptyfd)
     security_context_t tty_con = NULL;
     security_context_t new_tty_con = NULL;
     int fd;
+    debug_decl(relabel_tty, SUDO_DEBUG_SELINUX)
 
     se_state.ttyfd = ptyfd;
 
     /* It is perfectly legal to have no tty. */
     if (ptyfd == -1 && ttyn == NULL)
-       return 0;
+       debug_return_int(0);
 
     /* If sudo is not allocating a pty for the command, open current tty. */
     if (ptyfd == -1) {
@@ -222,7 +223,7 @@ relabel_tty(const char *ttyn, int ptyfd)
     se_state.ttyn = ttyn;
     se_state.tty_context = tty_con;
     se_state.new_tty_context = new_tty_con;
-    return 0;
+    debug_return_int(0);
 
 bad:
     if (se_state.ttyfd != -1 && se_state.ttyfd != ptyfd) {
@@ -230,7 +231,7 @@ bad:
        se_state.ttyfd = -1;
     }
     freecon(tty_con);
-    return -1;
+    debug_return_int(-1);
 }
 
 /*
@@ -243,18 +244,19 @@ get_exec_context(security_context_t old_context, const char *role, const char *t
     security_context_t new_context = NULL;
     context_t context = NULL;
     char *typebuf = NULL;
+    debug_decl(get_exec_context, SUDO_DEBUG_SELINUX)
     
     /* We must have a role, the type is optional (we can use the default). */
     if (!role) {
        warningx(_("you must specify a role for type %s"), type);
        errno = EINVAL;
-       return NULL;
+       goto bad;
     }
     if (!type) {
        if (get_default_type(role, &typebuf)) {
            warningx(_("unable to get default type for role %s"), role);
            errno = EINVAL;
-           return NULL;
+           goto bad;
        }
        type = typebuf;
     }
@@ -293,13 +295,13 @@ get_exec_context(security_context_t old_context, const char *role, const char *t
 #endif
 
     context_free(context);
-    return new_context;
+    debug_return_ptr(new_context);
 
 bad:
-    free(typebuf);
+    efree(typebuf);
     context_free(context);
     freecon(new_context);
-    return NULL;
+    debug_return_ptr(NULL);
 }
 
 /* 
@@ -314,6 +316,7 @@ selinux_setup(const char *role, const char *type, const char *ttyn,
     int ptyfd)
 {
     int rval = -1;
+    debug_decl(selinux_setup, SUDO_DEBUG_SELINUX)
 
     /* Store the caller's SID in old_context. */
     if (getprevcon(&se_state.old_context)) {
@@ -354,40 +357,50 @@ selinux_setup(const char *role, const char *type, const char *ttyn,
     rval = 0;
 
 done:
-    return rval;
+    debug_return_int(rval);
 }
 
 void
-selinux_execve(const char *path, char *argv[], char *envp[])
+selinux_execve(const char *path, char *const argv[], char *const envp[],
+    int noexec)
 {
     char **nargv;
     int argc, serrno;
+    debug_decl(selinux_execve, SUDO_DEBUG_SELINUX)
 
     if (setexeccon(se_state.new_context)) {
        warning(_("unable to set exec context to %s"), se_state.new_context);
        if (se_state.enforcing)
-           return;
+           debug_return;
     }
 
 #ifdef HAVE_SETKEYCREATECON
     if (setkeycreatecon(se_state.new_context)) {
        warning(_("unable to set key creation context to %s"), se_state.new_context);
        if (se_state.enforcing)
-           return;
+           debug_return;
     }
 #endif /* HAVE_SETKEYCREATECON */
 
+    /*
+     * Build new argv with sesh as argv[0].
+     * If argv[0] ends in -noexec, sesh will disable execute
+     * for the command it runs.
+     */
     for (argc = 0; argv[argc] != NULL; argc++)
        continue;
-
-    /* Build new argv with sesh as argv[0]. */
     nargv = emalloc2(argc + 2, sizeof(char *));
-    nargv[0] = *argv[0] == '-' ? "-sesh" : "sesh";
+    if (noexec)
+       nargv[0] = *argv[0] == '-' ? "-sesh-noexec" : "sesh-noexec";
+    else
+       nargv[0] = *argv[0] == '-' ? "-sesh" : "sesh";
     nargv[1] = (char *)path;
     memcpy(&nargv[2], &argv[1], argc * sizeof(char *)); /* copies NULL */
 
-    execve(_PATH_SUDO_SESH, nargv, envp);
+    /* sesh will handle noexec for us. */
+    sudo_execve(_PATH_SUDO_SESH, nargv, envp, 0);
     serrno = errno;
     free(nargv);
     errno = serrno;
+    debug_return;
 }
index f6818ce60181e2762c6d84ee216ee46508424678..d6b56c3c515aa0a4b18d174c37164b704307e3f9 100644 (file)
@@ -19,8 +19,6 @@
 #include <config.h>
 
 #include <sys/types.h>
-#include <err.h>
-#include <errno.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #ifdef HAVE_SETLOCALE
 # include <locale.h>
 #endif
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
 
 #include "missing.h"
+#include "alloc.h"
+#include "error.h"
 #include "gettext.h"
+#include "sudo_conf.h"
+#include "sudo_debug.h"
+#include "sudo_exec.h"
+#include "sudo_plugin.h"
+
+sudo_conv_t sudo_conv;  /* NULL in non-plugin */
+
+/*
+ * Cleanup hook for error()/errorx()
+ */
+void
+cleanup(int gotsignal)
+{
+    return;
+}
 
 int
-main (int argc, char *argv[])
+main(int argc, char *argv[], char *envp[])
 {
     char *cp, *cmnd;
+    int noexec = 0;
+    debug_decl(main, SUDO_DEBUG_MAIN)
 
 #ifdef HAVE_SETLOCALE 
     setlocale(LC_ALL, "");
@@ -45,22 +67,28 @@ main (int argc, char *argv[])
     textdomain(PACKAGE_NAME);
 
     if (argc < 2)
-       errx(EXIT_FAILURE, _("requires at least one argument"));
+       errorx(EXIT_FAILURE, _("requires at least one argument"));
+
+    /* Read sudo.conf. */
+    sudo_conf_read();
+
+    /* If argv[0] ends in -noexec, pass the flag to sudo_execve() */
+    if ((cp = strrchr(argv[0], '-')) != NULL && cp != argv[0])
+       noexec = strcmp(cp, "-noexec") == 0;
 
     /* Shift argv and make a copy of the command to execute. */
     argv++;
     argc--;
-    cmnd = strdup(argv[0]);
-    if (cmnd == NULL)
-       err(EXIT_FAILURE, NULL);
+    cmnd = estrdup(argv[0]);
 
     /* If invoked as a login shell, modify argv[0] accordingly. */
-    if (argv[0][0] == '-') {
+    if (argv[-1][0] == '-') {
        if ((cp = strrchr(argv[0], '/')) == NULL)
            cp = argv[0];
        *cp = '-';
     }
-    execv(cmnd, argv);
-    warn(_("unable to execute %s"), argv[0]);
+    sudo_execve(cmnd, argv, envp, noexec);
+    warning(_("unable to execute %s"), argv[0]);
+    sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, EXIT_FAILURE);                
     _exit(EXIT_FAILURE);
 }
index 9e52cd5130ca66bea6d874e60d27d5e9e76fa0da..eb006a088f720b049c41932a0cf67edba932fe78 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2011 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2009-2012 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
@@ -25,9 +25,6 @@
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include <sys/socket.h>
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif /* HAVE_SYS_SELECT_H */
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <stdio.h>
 # endif /* __hpux */
 # include <prot.h>
 #endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */
-#ifdef HAVE_PRIV_SET
-# include <priv.h>
+#if defined(HAVE_STRUCT_KINFO_PROC_P_TDEV) || defined (HAVE_STRUCT_KINFO_PROC_KP_EPROC_E_TDEV)
+# include <sys/sysctl.h>
+#elif defined(HAVE_STRUCT_KINFO_PROC_KI_TDEV)
+# include <sys/sysctl.h>
+# include <sys/user.h>
 #endif
 
 #include "sudo.h"
@@ -102,7 +102,7 @@ struct plugin_container policy_plugin;
 struct plugin_container_list io_plugins;
 struct user_details user_details;
 const char *list_user, *runas_user, *runas_group; /* extern for parse_args.c */
-int debug_level;
+static int sudo_mode;
 
 /*
  * Local functions
@@ -112,15 +112,6 @@ static void disable_coredumps(void);
 static char **get_user_info(struct user_details *);
 static void command_info_to_details(char * const info[],
     struct command_details *details);
-static int policy_open(struct plugin_container *plugin, char * const settings[],
-    char * const user_info[], char * const user_env[]);
-static void policy_close(struct plugin_container *plugin, int exit_status,
-    int error);
-static int iolog_open(struct plugin_container *plugin, char * const settings[],
-    char * const user_info[], char * const command_details[],
-    int argc, char * const argv[], char * const user_env[]);
-static void iolog_close(struct plugin_container *plugin, int exit_status,
-    int error);
 
 /* Policy plugin convenience functions. */
 static int policy_open(struct plugin_container *plugin, char * const settings[],
@@ -146,26 +137,33 @@ static void iolog_close(struct plugin_container *plugin, int exit_status,
     int error);
 static int iolog_show_version(struct plugin_container *plugin, int verbose);
 
-#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
+#ifdef RLIMIT_CORE
 static struct rlimit corelimit;
-#endif /* RLIMIT_CORE && !SUDO_DEVEL */
+#endif /* RLIMIT_CORE */
 #if defined(__linux__)
 static struct rlimit nproclimit;
 #endif
 
+#ifdef HAVE_LOGIN_CAP_H
+extern char **environ;
+#endif
+
 int
 main(int argc, char *argv[], char *envp[])
 {
-    int nargc, sudo_mode, exitcode = 0;
+    int nargc, ok, exitcode = 0;
     char **nargv, **settings, **env_add;
     char **user_info, **command_info, **argv_out, **user_env_out;
     struct plugin_container *plugin, *next;
     struct command_details command_details;
     sigset_t mask;
-    int ok;
+    debug_decl(main, SUDO_DEBUG_MAIN)
+
 #if defined(SUDO_DEVEL) && defined(__OpenBSD__)
-    extern char *malloc_options;
-    malloc_options = "AFGJPR";
+    {
+       extern char *malloc_options;
+       malloc_options = "AFGJPR";
+    }
 #endif
 
 #if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
@@ -190,19 +188,24 @@ main(int argc, char *argv[], char *envp[])
     if (geteuid() != 0)
        errorx(1, _("must be setuid root"));
 
-    /* Reset signal mask, disable core dumps and make sure fds 0-2 are open. */
+    /* Reset signal mask and make sure fds 0-2 are open. */
     (void) sigemptyset(&mask);
     (void) sigprocmask(SIG_SETMASK, &mask, NULL);
-    disable_coredumps();
     fix_fds();
 
     /* Fill in user_info with user name, uid, cwd, etc. */
     memset(&user_details, 0, sizeof(user_details));
     user_info = get_user_info(&user_details);
 
+    /* Read sudo.conf. */
+    sudo_conf_read();
+
+    /* Disable core dumps if not enabled in sudo.conf. */
+    disable_coredumps();
+
     /* Parse command line arguments. */
     sudo_mode = parse_args(argc, argv, &nargc, &nargv, &settings, &env_add);
-    sudo_debug(9, "sudo_mode %d", sudo_mode);
+    sudo_debug_printf(SUDO_DEBUG_DEBUG, "sudo_mode %d", sudo_mode);
 
     /* Print sudo version early, in case of plugin init failure. */
     if (ISSET(sudo_mode, MODE_VERSION)) {
@@ -211,13 +214,13 @@ main(int argc, char *argv[], char *envp[])
            (void) printf(_("Configure options: %s\n"), CONFIGURE_ARGS);
     }
 
-    /* Read sudo.conf and load plugins. */
-    if (!sudo_load_plugins(_PATH_SUDO_CONF, &policy_plugin, &io_plugins))
+    /* Load plugins. */
+    if (!sudo_load_plugins(&policy_plugin, &io_plugins))
        errorx(1, _("fatal error, unable to load plugins"));
 
     /* Open policy plugin. */
     ok = policy_open(&policy_plugin, settings, user_info, envp);
-    if (ok != TRUE) {
+    if (ok != 1) {
        if (ok == -2)
            usage(1);
        else
@@ -230,14 +233,14 @@ main(int argc, char *argv[], char *envp[])
            tq_foreach_fwd(&io_plugins, plugin) {
                ok = iolog_open(plugin, settings, user_info, NULL,
                    nargc, nargv, envp);
-               if (ok == TRUE)
+               if (ok == 1)
                    iolog_show_version(plugin, !user_details.uid);
            }
            break;
        case MODE_VALIDATE:
        case MODE_VALIDATE|MODE_INVALIDATE:
            ok = policy_validate(&policy_plugin);
-           exit(ok != TRUE);
+           exit(ok != 1);
        case MODE_KILL:
        case MODE_INVALIDATE:
            policy_invalidate(&policy_plugin, sudo_mode == MODE_KILL);
@@ -249,13 +252,13 @@ main(int argc, char *argv[], char *envp[])
        case MODE_LIST|MODE_INVALIDATE:
            ok = policy_list(&policy_plugin, nargc, nargv,
                ISSET(sudo_mode, MODE_LONG_LIST), list_user);
-           exit(ok != TRUE);
+           exit(ok != 1);
        case MODE_EDIT:
        case MODE_RUN:
            ok = policy_check(&policy_plugin, nargc, nargv, env_add,
                &command_info, &argv_out, &user_env_out);
-           sudo_debug(8, "policy plugin returns %d", ok);
-           if (ok != TRUE) {
+           sudo_debug_printf(SUDO_DEBUG_INFO, "policy plugin returns %d", ok);
+           if (ok != 1) {
                if (ok == -2)
                    usage(1);
                exit(1); /* plugin printed error message */
@@ -266,9 +269,9 @@ main(int argc, char *argv[], char *envp[])
                ok = iolog_open(plugin, settings, user_info,
                    command_info, nargc, nargv, envp);
                switch (ok) {
-               case TRUE:
+               case 1:
                    break;
-               case FALSE:
+               case 0:
                    /* I/O plugin asked to be disabled, remove from list. */
                    tq_remove(&io_plugins, plugin);
                    break;
@@ -285,10 +288,13 @@ main(int argc, char *argv[], char *envp[])
            command_details.envp = user_env_out;
            if (ISSET(sudo_mode, MODE_BACKGROUND))
                SET(command_details.flags, CD_BACKGROUND);
+           /* Become full root (not just setuid) so user cannot kill us. */
+           (void) setuid(ROOT_UID);
            /* Restore coredumpsize resource limit before running. */
-#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
-           (void) setrlimit(RLIMIT_CORE, &corelimit);
-#endif /* RLIMIT_CORE && !SUDO_DEVEL */
+#ifdef RLIMIT_CORE
+           if (sudo_conf_disable_coredump())
+               (void) setrlimit(RLIMIT_CORE, &corelimit);
+#endif /* RLIMIT_CORE */
            if (ISSET(command_details.flags, CD_SUDOEDIT)) {
                exitcode = sudo_edit(&command_details);
            } else {
@@ -299,6 +305,7 @@ main(int argc, char *argv[], char *envp[])
        default:
            errorx(1, _("unexpected sudo mode 0x%x"), sudo_mode);
     }
+    sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);                
     exit(exitcode);
 }
 
@@ -310,6 +317,7 @@ static void
 fix_fds(void)
 {
     int miss[3], devnull = -1;
+    debug_decl(fix_fds, SUDO_DEBUG_UTIL)
 
     /*
      * stdin, stdout and stderr must be open; set them to /dev/null
@@ -330,6 +338,7 @@ fix_fds(void)
        if (devnull > STDERR_FILENO)
            close(devnull);
     }
+    debug_return;
 }
 
 /*
@@ -340,6 +349,7 @@ static int
 fill_group_list(struct user_details *ud)
 {
     int maxgroups, tries, rval = -1;
+    debug_decl(fill_group_list, SUDO_DEBUG_UTIL)
 
 #if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX)
     maxgroups = (int)sysconf(_SC_NGROUPS_MAX);
@@ -360,7 +370,7 @@ fill_group_list(struct user_details *ud)
        ud->groups = emalloc2(ud->ngroups, sizeof(GETGROUPS_T));
        rval = getgrouplist(ud->username, ud->gid, ud->groups, &ud->ngroups);
     }
-    return rval;
+    debug_return_int(rval);
 }
 
 static char *
@@ -369,6 +379,7 @@ get_user_groups(struct user_details *ud)
     char *cp, *gid_list = NULL;
     size_t glsize;
     int i, len;
+    debug_decl(get_user_groups, SUDO_DEBUG_UTIL)
 
     /*
      * Systems with mbr_check_membership() support more than NGROUPS_MAX
@@ -402,7 +413,7 @@ get_user_groups(struct user_details *ud)
            i ? "," : "", (unsigned int)ud->groups[i]);
        cp += len;
     }
-    return gid_list;
+    debug_return_str(gid_list);
 }
 
 /*
@@ -412,11 +423,10 @@ get_user_groups(struct user_details *ud)
 static char **
 get_user_info(struct user_details *ud)
 {
-    char cwd[PATH_MAX];
-    char host[MAXHOSTNAMELEN];
-    char **user_info, *cp;
+    char *cp, **user_info, cwd[PATH_MAX], host[MAXHOSTNAMELEN];
     struct passwd *pw;
     int i = 0;
+    debug_decl(get_user_info, SUDO_DEBUG_UTIL)
 
     /* XXX - bound check number of entries */
     user_info = emalloc2(32, sizeof(char *));
@@ -456,12 +466,12 @@ get_user_info(struct user_details *ud)
        ud->cwd = user_info[i] + sizeof("cwd=") - 1;
     }
 
-    if ((cp = ttyname(STDIN_FILENO)) || (cp = ttyname(STDOUT_FILENO)) ||
-       (cp = ttyname(STDERR_FILENO))) {
+    if ((cp = get_process_ttyname()) != NULL) {
        user_info[++i] = fmt_string("tty", cp);
        if (user_info[i] == NULL)
            errorx(1, _("unable to allocate memory"));
        ud->tty = user_info[i] + sizeof("tty=") - 1;
+       efree(cp);
     }
 
     if (gethostname(host, sizeof(host)) == 0)
@@ -479,7 +489,7 @@ get_user_info(struct user_details *ud)
 
     user_info[++i] = NULL;
 
-    return user_info;
+    debug_return_ptr(user_info);
 }
 
 /*
@@ -492,6 +502,7 @@ command_info_to_details(char * const info[], struct command_details *details)
     long lval;
     unsigned long ulval;
     char *cp, *ep;
+    debug_decl(command_info_to_details, SUDO_DEBUG_PCOMM)
 
     memset(details, 0, sizeof(*details));
     details->closefrom = -1;
@@ -502,8 +513,9 @@ command_info_to_details(char * const info[], struct command_details *details)
        break; \
     }
 
+    sudo_debug_printf(SUDO_DEBUG_INFO, "command info from plugin:");
     for (i = 0; info[i] != NULL; i++) {
-       sudo_debug(9, "command info: %s", info[i]);
+       sudo_debug_printf(SUDO_DEBUG_INFO, "    %d: %s", i, info[i]);
        switch (info[i][0]) {
            case 'c':
                SET_STRING("chroot=", chroot)
@@ -545,21 +557,14 @@ command_info_to_details(char * const info[], struct command_details *details)
                    break;
                }
                if (strncmp("noexec=", info[i], sizeof("noexec=") - 1) == 0) {
-                   if (atobool(info[i] + sizeof("noexec=") - 1) == TRUE)
+                   if (atobool(info[i] + sizeof("noexec=") - 1) == true)
                        SET(details->flags, CD_NOEXEC);
                    break;
                }
-#ifdef _PATH_SUDO_NOEXEC
-               /* XXX - deprecated */
-               if (strncmp("noexec_file=", info[i], sizeof("noexec_file=") - 1) == 0) {
-                   noexec_path = info[i] + sizeof("noexec_file=") - 1;
-                   break;
-               }
-#endif /* _PATH_SUDO_NOEXEC */
                break;
            case 'p':
                if (strncmp("preserve_groups=", info[i], sizeof("preserve_groups=") - 1) == 0) {
-                   if (atobool(info[i] + sizeof("preserve_groups=") - 1) == TRUE)
+                   if (atobool(info[i] + sizeof("preserve_groups=") - 1) == true)
                        SET(details->flags, CD_PRESERVE_GROUPS);
                    break;
                }
@@ -653,12 +658,12 @@ command_info_to_details(char * const info[], struct command_details *details)
                SET_STRING("selinux_role=", selinux_role)
                SET_STRING("selinux_type=", selinux_type)
                if (strncmp("set_utmp=", info[i], sizeof("set_utmp=") - 1) == 0) {
-                   if (atobool(info[i] + sizeof("set_utmp=") - 1) == TRUE)
+                   if (atobool(info[i] + sizeof("set_utmp=") - 1) == true)
                        SET(details->flags, CD_SET_UTMP);
                    break;
                }
                if (strncmp("sudoedit=", info[i], sizeof("sudoedit=") - 1) == 0) {
-                   if (atobool(info[i] + sizeof("sudoedit=") - 1) == TRUE)
+                   if (atobool(info[i] + sizeof("sudoedit=") - 1) == true)
                        SET(details->flags, CD_SUDOEDIT);
                    break;
                }
@@ -695,7 +700,7 @@ command_info_to_details(char * const info[], struct command_details *details)
                    break;
                }
                if (strncmp("use_pty=", info[i], sizeof("use_pty=") - 1) == 0) {
-                   if (atobool(info[i] + sizeof("use_pty=") - 1) == TRUE)
+                   if (atobool(info[i] + sizeof("use_pty=") - 1) == true)
                        SET(details->flags, CD_USE_PTY);
                    break;
                }
@@ -711,6 +716,7 @@ command_info_to_details(char * const info[], struct command_details *details)
     if (details->selinux_role != NULL && is_selinux_enabled() > 0)
        SET(details->flags, CD_RBAC_ENABLED);
 #endif
+    debug_return;
 }
 
 /*
@@ -721,9 +727,10 @@ command_info_to_details(char * const info[], struct command_details *details)
 static void
 disable_coredumps(void)
 {
-#if defined(__linux__) || (defined(RLIMIT_CORE) && !defined(SUDO_DEVEL))
+#if defined(__linux__) || defined(RLIMIT_CORE)
     struct rlimit rl;
 #endif
+    debug_decl(disable_coredumps, SUDO_DEBUG_UTIL)
 
 #if defined(__linux__)
     /*
@@ -739,15 +746,18 @@ disable_coredumps(void)
        (void)setrlimit(RLIMIT_NPROC, &rl);
     }
 #endif /* __linux__ */
-#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
+#ifdef RLIMIT_CORE
     /*
-     * Turn off core dumps.
+     * Turn off core dumps?
      */
-    (void) getrlimit(RLIMIT_CORE, &corelimit);
-    memcpy(&rl, &corelimit, sizeof(struct rlimit));
-    rl.rlim_cur = 0;
-    (void) setrlimit(RLIMIT_CORE, &rl);
-#endif /* RLIMIT_CORE && !SUDO_DEVEL */
+    if (sudo_conf_disable_coredump()) {
+       (void) getrlimit(RLIMIT_CORE, &corelimit);
+       memcpy(&rl, &corelimit, sizeof(struct rlimit));
+       rl.rlim_cur = 0;
+       (void) setrlimit(RLIMIT_CORE, &rl);
+    }
+#endif /* RLIMIT_CORE */
+    debug_return;
 }
 
 #ifdef HAVE_PROJECT_H
@@ -757,6 +767,7 @@ set_project(struct passwd *pw)
     struct project proj;
     char buf[PROJECT_BUFSZ];
     int errval;
+    debug_decl(set_project, SUDO_DEBUG_UTIL)
 
     /*
      * Collect the default project for the user and settaskid
@@ -809,96 +820,26 @@ set_project(struct passwd *pw)
        warning("getdefaultproj");
     }
     endprojent();
+    debug_return;
 }
 #endif /* HAVE_PROJECT_H */
 
-/*
- * Disable execution of child processes in the command we are about
- * to run.  On systems with privilege sets, we can remove the exec
- * privilege.  On other systems we use LD_PRELOAD and the like.
- */
-static void
-disable_execute(struct command_details *details)
-{
-#ifdef _PATH_SUDO_NOEXEC
-    char *cp, **ev, **nenvp;
-    int env_len = 0, env_size = 128;
-#endif /* _PATH_SUDO_NOEXEC */
-
-#ifdef HAVE_PRIV_SET
-    /* Solaris privileges, remove PRIV_PROC_EXEC post-execve. */
-    if (priv_set(PRIV_OFF, PRIV_LIMIT, "PRIV_PROC_EXEC", NULL) == 0)
-       return;
-    warning(_("unable to remove PRIV_PROC_EXEC from PRIV_LIMIT"));
-#endif /* HAVE_PRIV_SET */
-
-#ifdef _PATH_SUDO_NOEXEC
-    nenvp = emalloc2(env_size, sizeof(char *));
-    for (ev = details->envp; *ev != NULL; ev++) {
-       if (env_len + 2 > env_size) {
-           env_size += 128;
-           nenvp = erealloc3(nenvp, env_size, sizeof(char *));
-       }
-       /*
-        * Prune out existing preloaded libraries.
-        * XXX - should save and append instead of replacing.
-        */
-# if defined(__darwin__) || defined(__APPLE__)
-       if (strncmp(*ev, "DYLD_INSERT_LIBRARIES=", sizeof("DYLD_INSERT_LIBRARIES=") - 1) == 0)
-           continue;
-       if (strncmp(*ev, "DYLD_FORCE_FLAT_NAMESPACE=", sizeof("DYLD_INSERT_LIBRARIES=") - 1) == 0)
-           continue;
-# elif defined(__osf__) || defined(__sgi)
-       if (strncmp(*ev, "_RLD_LIST=", sizeof("_RLD_LIST=") - 1) == 0)
-           continue;
-# elif defined(_AIX)
-       if (strncmp(*ev, "LDR_PRELOAD=", sizeof("LDR_PRELOAD=") - 1) == 0)
-           continue;
-# else
-       if (strncmp(*ev, "LD_PRELOAD=", sizeof("LD_PRELOAD=") - 1) == 0)
-           continue;
-# endif
-       nenvp[env_len++] = *ev;
-    }
-
-    /*
-     * Preload a noexec file?  For a list of LD_PRELOAD-alikes, see
-     * http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
-     * XXX - need to support 32-bit and 64-bit variants
-     */
-# if defined(__darwin__) || defined(__APPLE__)
-    nenvp[env_len++] = "DYLD_FORCE_FLAT_NAMESPACE=";
-    cp = fmt_string("DYLD_INSERT_LIBRARIES", noexec_path);
-# elif defined(__osf__) || defined(__sgi)
-    easprintf(&cp, "_RLD_LIST=%s:DEFAULT", noexec_path);
-# elif defined(_AIX)
-    cp = fmt_string("LDR_PRELOAD", noexec_path);
-# else
-    cp = fmt_string("LD_PRELOAD", noexec_path);
-# endif
-    if (cp == NULL)
-       error(1, NULL);
-    nenvp[env_len++] = cp;
-    nenvp[env_len] = NULL;
-
-    details->envp = nenvp;
-#endif /* _PATH_SUDO_NOEXEC */
-}
-
 /*
  * Setup the execution environment immediately prior to the call to execve()
- * Returns TRUE on success and FALSE on failure.
+ * Returns true on success and false on failure.
  */
-int
+bool
 exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
 {
-    int rval = FALSE;
+    bool rval = false;
     struct passwd *pw;
+    debug_decl(exec_setup, SUDO_DEBUG_EXEC)
 
 #ifdef HAVE_SETAUTHDB
     aix_setauthdb(IDtouser(details->euid));
 #endif
-    pw = getpwuid(details->euid);
+    if ((pw = getpwuid(details->euid)) != NULL && (pw = pw_dup(pw)) == NULL)
+       errorx(1, _("unable to allocate memory"));
 #ifdef HAVE_SETAUTHDB
     aix_restoreauthdb();
 #endif
@@ -907,7 +848,7 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
      * Call policy plugin's session init before other setup occurs.
      * The session init code is expected to print an error as needed.
      */
-    if (policy_init_session(&policy_plugin, pw) != TRUE)
+    if (policy_init_session(&policy_plugin, pw) != true)
        goto done;
 
 #ifdef HAVE_SELINUX
@@ -931,7 +872,8 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
            login_cap_t *lc;
 
            /*
-            * We only use setusercontext() to set the nice value and rlimits.
+            * We only use setusercontext() to set the nice value and rlimits
+            * unless this is a login shell (sudo -i).
             */
            lc = login_getclass((char *)details->login_class);
            if (!lc) {
@@ -939,7 +881,16 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
                errno = ENOENT;
                goto done;
            }
-           flags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY;
+           if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
+               /* Set everything except user, group and login name. */
+               flags = LOGIN_SETALL;
+               CLR(flags, LOGIN_SETGROUP|LOGIN_SETLOGIN|LOGIN_SETUSER);
+               CLR(details->flags, CD_SET_UMASK); /* LOGIN_UMASK instead */
+               /* Swap in the plugin-supplied environment for LOGIN_SETENV */
+               environ = details->envp;
+           } else {
+               flags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY;
+           }
            if (setusercontext(lc, pw, pw->pw_uid, flags)) {
                if (pw->pw_uid != ROOT_UID) {
                    warning(_("unable to set user context"));
@@ -947,6 +898,10 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
                } else
                    warning(_("unable to set user context"));
            }
+           if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
+               /* Stash the updated environment pointer in command details */
+               details->envp = environ;
+           }
        }
 #endif /* HAVE_LOGIN_CAP_H */
     }
@@ -954,6 +909,14 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
     /*
      * Set groups, including supplementary group vector.
      */
+    if (!ISSET(details->flags, CD_PRESERVE_GROUPS)) {
+       if (details->ngroups >= 0) {
+           if (sudo_setgroups(details->ngroups, details->groups) < 0) {
+               warning(_("unable to set supplementary group IDs"));
+               goto done;
+           }
+       }
+    }
 #ifdef HAVE_SETEUID
     if (ISSET(details->flags, CD_SET_EGID) && setegid(details->egid)) {
        warning(_("unable to set effective gid to runas gid %u"),
@@ -967,15 +930,6 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
        goto done;
     }
 
-    if (!ISSET(details->flags, CD_PRESERVE_GROUPS)) {
-       if (details->ngroups >= 0) {
-           if (sudo_setgroups(details->ngroups, details->groups) < 0) {
-               warning(_("unable to set supplementary group IDs"));
-               goto done;
-           }
-       }
-    }
-
     if (ISSET(details->flags, CD_SET_PRIORITY)) {
        if (setpriority(PRIO_PROCESS, 0, details->priority) != 0) {
            warning(_("unable to set process priority"));
@@ -991,9 +945,6 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
        }
     }
 
-    if (ISSET(details->flags, CD_NOEXEC))
-       disable_execute(details);
-
 #ifdef HAVE_SETRESUID
     if (setresuid(details->uid, details->euid, details->euid) != 0) {
        warning(_("unable to change to runas uid (%u, %u)"), details->uid,
@@ -1043,10 +994,11 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
     }
 #endif
 
-    rval = TRUE;
+    rval = true;
 
 done:
-    return rval;
+    efree(pw);
+    debug_return_bool(rval);
 }
 
 /*
@@ -1058,29 +1010,34 @@ run_command(struct command_details *details)
     struct plugin_container *plugin;
     struct command_status cstat;
     int exitcode = 1;
+    debug_decl(run_command, SUDO_DEBUG_EXEC)
 
     cstat.type = CMD_INVALID;
     cstat.val = 0;
 
-    sudo_execve(details, &cstat);
+    sudo_execute(details, &cstat);
 
     switch (cstat.type) {
     case CMD_ERRNO:
        /* exec_setup() or execve() returned an error. */
-       sudo_debug(9, "calling policy close with errno");
+       sudo_debug_printf(SUDO_DEBUG_DEBUG,
+           "calling policy close with errno %d", cstat.val);
        policy_close(&policy_plugin, 0, cstat.val);
        tq_foreach_fwd(&io_plugins, plugin) {
-           sudo_debug(9, "calling I/O close with errno");
+           sudo_debug_printf(SUDO_DEBUG_DEBUG,
+               "calling I/O close with errno %d", cstat.val);
            iolog_close(plugin, 0, cstat.val);
        }
        exitcode = 1;
        break;
     case CMD_WSTATUS:
        /* Command ran, exited or was killed. */
-       sudo_debug(9, "calling policy close with wait status");
+       sudo_debug_printf(SUDO_DEBUG_DEBUG,
+           "calling policy close with wait status %d", cstat.val);
        policy_close(&policy_plugin, cstat.val, 0);
        tq_foreach_fwd(&io_plugins, plugin) {
-           sudo_debug(9, "calling I/O close with wait status");
+           sudo_debug_printf(SUDO_DEBUG_DEBUG,
+               "calling I/O close with wait status %d", cstat.val);
            iolog_close(plugin, cstat.val, 0);
        }
        if (WIFEXITED(cstat.val))
@@ -1092,27 +1049,31 @@ run_command(struct command_details *details)
        warningx(_("unexpected child termination condition: %d"), cstat.type);
        break;
     }
-    return exitcode;
+    debug_return_int(exitcode);
 }
 
 static int
 policy_open(struct plugin_container *plugin, char * const settings[],
     char * const user_info[], char * const user_env[])
 {
-    return plugin->u.policy->open(SUDO_API_VERSION, sudo_conversation,
-       _sudo_printf, settings, user_info, user_env);
+    debug_decl(policy_open, SUDO_DEBUG_PCOMM)
+    debug_return_bool(plugin->u.policy->open(SUDO_API_VERSION,
+       sudo_conversation, _sudo_printf, settings, user_info, user_env));
 }
 
 static void
 policy_close(struct plugin_container *plugin, int exit_status, int error)
 {
+    debug_decl(policy_close, SUDO_DEBUG_PCOMM)
     plugin->u.policy->close(exit_status, error);
+    debug_return;
 }
 
 static int
 policy_show_version(struct plugin_container *plugin, int verbose)
 {
-    return plugin->u.policy->show_version(verbose);
+    debug_decl(policy_show_version, SUDO_DEBUG_PCOMM)
+    debug_return_bool(plugin->u.policy->show_version(verbose));
 }
 
 static int
@@ -1120,49 +1081,55 @@ policy_check(struct plugin_container *plugin, int argc, char * const argv[],
     char *env_add[], char **command_info[], char **argv_out[],
     char **user_env_out[])
 {
-    return plugin->u.policy->check_policy(argc, argv, env_add, command_info,
-       argv_out, user_env_out);
+    debug_decl(policy_check, SUDO_DEBUG_PCOMM)
+    debug_return_bool(plugin->u.policy->check_policy(argc, argv, env_add,
+       command_info, argv_out, user_env_out));
 }
 
 static int
 policy_list(struct plugin_container *plugin, int argc, char * const argv[],
     int verbose, const char *list_user)
 {
+    debug_decl(policy_list, SUDO_DEBUG_PCOMM)
     if (plugin->u.policy->list == NULL) {
        warningx(_("policy plugin %s does not support listing privileges"),
            plugin->name);
-       return FALSE;
+       debug_return_bool(false);
     }
-    return plugin->u.policy->list(argc, argv, verbose, list_user);
+    debug_return_bool(plugin->u.policy->list(argc, argv, verbose, list_user));
 }
 
 static int
 policy_validate(struct plugin_container *plugin)
 {
+    debug_decl(policy_validate, SUDO_DEBUG_PCOMM)
     if (plugin->u.policy->validate == NULL) {
        warningx(_("policy plugin %s does not support the -v option"),
            plugin->name);
-       return FALSE;
+       debug_return_bool(false);
     }
-    return plugin->u.policy->validate();
+    debug_return_bool(plugin->u.policy->validate());
 }
 
 static void
 policy_invalidate(struct plugin_container *plugin, int remove)
 {
+    debug_decl(policy_invalidate, SUDO_DEBUG_PCOMM)
     if (plugin->u.policy->invalidate == NULL) {
        errorx(1, _("policy plugin %s does not support the -k/-K options"),
            plugin->name);
     }
     plugin->u.policy->invalidate(remove);
+    debug_return;
 }
 
 static int
 policy_init_session(struct plugin_container *plugin, struct passwd *pwd)
 {
+    debug_decl(policy_init_session, SUDO_DEBUG_PCOMM)
     if (plugin->u.policy->init_session)
-       return plugin->u.policy->init_session(pwd);
-    return TRUE;
+       debug_return_bool(plugin->u.policy->init_session(pwd));
+    debug_return_bool(true);
 }
 
 static int
@@ -1171,6 +1138,7 @@ iolog_open(struct plugin_container *plugin, char * const settings[],
     int argc, char * const argv[], char * const user_env[])
 {
     int rval;
+    debug_decl(iolog_open, SUDO_DEBUG_PCOMM)
 
     /*
      * Backwards compatibility for API major 1, minor 0
@@ -1186,37 +1154,20 @@ iolog_open(struct plugin_container *plugin, char * const settings[],
            _sudo_printf, settings, user_info, command_info, argc, argv,
            user_env);
     }
-    return rval;
+    debug_return_bool(rval);
 }
 
 static void
 iolog_close(struct plugin_container *plugin, int exit_status, int error)
 {
+    debug_decl(iolog_close, SUDO_DEBUG_PCOMM)
     plugin->u.io->close(exit_status, error);
+    debug_return;
 }
 
 static int
 iolog_show_version(struct plugin_container *plugin, int verbose)
 {
-    return plugin->u.io->show_version(verbose);
-}
-
-/*
- * Simple debugging/logging.
- */
-void
-sudo_debug(int level, const char *fmt, ...)
-{
-    va_list ap;
-    char *buf;
-
-    if (level > debug_level)
-       return;
-
-    /* Bracket fmt with program name and a newline to make it a single write */
-    va_start(ap, fmt);
-    evasprintf(&buf, fmt, ap);
-    va_end(ap);
-    fprintf(stderr, "%s: %s\n", getprogname(), buf);
-    efree(buf);
+    debug_decl(iolog_show_version, SUDO_DEBUG_PCOMM)
+    debug_return_bool(plugin->u.io->show_version(verbose));
 }
index f3155059fdec9346c726770d3f9698ab4a3f4212..a5e29bcd816ab766a3c6914c47da83e154939d51 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1993-1996, 1998-2005, 2007-2011
+ * Copyright (c) 1993-1996, 1998-2005, 2007-2012
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
 
 #include <limits.h>
 #include <pathnames.h>
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# include "compat/stdbool.h"
+#endif /* HAVE_STDBOOL_H */
 
 #include "missing.h"
 #include "alloc.h"
 #include "error.h"
 #include "fileops.h"
 #include "list.h"
+#include "sudo_conf.h"
+#include "sudo_debug.h"
 #include "gettext.h"
 
 #ifdef __TANDEM
 # define ROOT_UID       0
 #endif
 
-/*
- * Pseudo-boolean values
- */
-#undef TRUE
-#define TRUE                     1
-#undef FALSE
-#define FALSE                    0
-
 /*
  * Various modes sudo can be in (based on arguments) in hex
  */
@@ -171,7 +170,7 @@ extern const char *noexec_path;
 void zero_bytes(volatile void *, size_t);
 
 /* exec.c */
-int sudo_execve(struct command_details *details, struct command_status *cstat);
+int sudo_execute(struct command_details *details, struct command_status *cstat);
 void save_signals(void);
 void restore_signals(void);
 
@@ -186,7 +185,7 @@ int term_restore(int, int);
 char *fmt_string(const char *var, const char *value);
 
 /* atobool.c */
-int atobool(const char *str);
+bool atobool(const char *str);
 
 /* parse_args.c */
 int parse_args(int argc, char **argv, int *nargc, char ***nargv,
@@ -200,10 +199,8 @@ int get_pty(int *master, int *slave, char *name, size_t namesz, uid_t uid);
 void get_ttysize(int *rowp, int *colp);
 
 /* sudo.c */
-int exec_setup(struct command_details *details, const char *ptyname, int ptyfd);
+bool exec_setup(struct command_details *details, const char *ptyname, int ptyfd);
 int run_command(struct command_details *details);
-void sudo_debug(int level, const char *format, ...) __printflike(2, 3);
-extern int debug_level;
 extern const char *list_user, *runas_user, *runas_group;
 extern struct user_details user_details;
 
@@ -217,7 +214,8 @@ void usage(int);
 int selinux_restore_tty(void);
 int selinux_setup(const char *role, const char *type, const char *ttyn,
     int ttyfd);
-void selinux_execve(const char *path, char *argv[], char *envp[]);
+void selinux_execve(const char *path, char *const argv[], char *const envp[],
+    int noexec);
 
 /* aix.c */
 void aix_prep_user(char *user, const char *tty);
@@ -230,4 +228,7 @@ int get_net_ifs(char **addrinfo);
 /* setgroups.c */
 int sudo_setgroups(int ngids, const GETGROUPS_T *gids);
 
+/* ttyname.c */
+char *get_process_ttyname(void);
+
 #endif /* _SUDO_SUDO_H */
index af7f07192e423969b8bc7d42ee0613c0a608038c..16c705790b849b44927b2c6ecb3792a9429acc85 100644 (file)
@@ -58,6 +58,7 @@ static void
 switch_user(uid_t euid, gid_t egid, int ngroups, GETGROUPS_T *groups)
 {
     int serrno = errno;
+    debug_decl(switch_user, SUDO_DEBUG_EDIT)
 
     /* When restoring root, change euid first; otherwise change it last. */
     if (euid == ROOT_UID) {
@@ -74,8 +75,9 @@ switch_user(uid_t euid, gid_t egid, int ngroups, GETGROUPS_T *groups)
        if (seteuid(euid) != 0)
            error(1, "seteuid(%d)", (int)euid);
     }
-
     errno = serrno;
+
+    debug_return;
 }
 
 /*
@@ -98,7 +100,8 @@ sudo_edit(struct command_details *command_details)
        char *ofile;
        struct timeval omtim;
        off_t osize;
-    } *tf;
+    } *tf = NULL;
+    debug_decl(sudo_edit, SUDO_DEBUG_EDIT)
 
     /*
      * Set real, effective and saved uids to root.
@@ -106,7 +109,7 @@ sudo_edit(struct command_details *command_details)
      */
     if (setuid(ROOT_UID) != 0) {
        warning(_("unable to change uid to root (%u)"), ROOT_UID);
-       return 1;
+       goto cleanup;
     }
 
     /*
@@ -138,7 +141,7 @@ sudo_edit(struct command_details *command_details)
     }
     if (nfiles == 0) {
        warningx(_("plugin error: missing file list for sudoedit"));
-       return 1;
+       goto cleanup;
     }
 
     /*
@@ -220,7 +223,7 @@ sudo_edit(struct command_details *command_details)
        j++;
     }
     if ((nfiles = j) == 0)
-       return 1;                       /* no files readable, you lose */
+       goto cleanup;           /* no files readable, you lose */
 
     /*
      * Allocate space for the new argument vector and fill it in.
@@ -317,15 +320,17 @@ sudo_edit(struct command_details *command_details)
        }
        close(ofd);
     }
+    debug_return_int(rval);
 
-    return rval;
 cleanup:
     /* Clean up temp files and return. */
-    for (i = 0; i < nfiles; i++) {
-       if (tf[i].tfile != NULL)
-           unlink(tf[i].tfile);
+    if (tf != NULL) {
+       for (i = 0; i < nfiles; i++) {
+           if (tf[i].tfile != NULL)
+               unlink(tf[i].tfile);
+       }
     }
-    return 1;
+    debug_return_int(1);
 }
 
 #else /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
@@ -336,7 +341,8 @@ cleanup:
 int
 sudo_edit(struct command_details *command_details)
 {
-    return 1;
+    debug_decl(sudo_edit, SUDO_DEBUG_EDIT)
+    debug_return_int(1);
 }
 
 #endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
index 744dd6a3d21cfd5deafc0341b4b9166d2867f45f..d9ce2e85d4f62dfaff223eb1e349903512c8a2d8 100644 (file)
  */
 
 /* exec.c */
-int my_execve(const char *path, char *const argv[], char *const envp[]);
+int sudo_execve(const char *path, char *const argv[], char *const envp[], int noexec);
 int pipe_nonblock(int fds[2]);
 
 /* exec_pty.c */
+struct command_details;
+struct command_status;
 int fork_pty(struct command_details *details, int sv[], int *maxfd);
 int perform_io(fd_set *fdsr, fd_set *fdsw, struct command_status *cstat);
 int suspend_parent(int signo);
@@ -39,12 +41,12 @@ void fd_set_iobs(fd_set *fdsr, fd_set *fdsw);
 void handler(int s);
 void pty_close(struct command_status *cstat);
 void pty_setup(uid_t uid, const char *tty, const char *utmp_user);
-void terminate_child(pid_t pid, int use_pgrp);
+void terminate_child(pid_t pid, bool use_pgrp);
 extern int signal_pipe[2];
 
 /* utmp.c */
-int utmp_login(const char *from_line, const char *to_line, int ttyfd,
+bool utmp_login(const char *from_line, const char *to_line, int ttyfd,
     const char *user);
-int utmp_logout(const char *line, int status);
+bool utmp_logout(const char *line, int status);
 
 #endif /* _SUDO_EXEC_H */
index 7f050aa3ffa194d3648f5259fe84ca70bd6d3596..4e05720deea47ac15e5931092b641eef27247512 100644 (file)
@@ -19,9 +19,6 @@
 #include <sys/types.h>
 
 #include <errno.h>
-#ifndef HAVE_TIMESPEC
-# include <time.h>
-#endif
 #include <stdarg.h>
 
 #include "missing.h"
index 772cde9c6af3169d0277c0a46ea6484a5972d956..135c1234467acef69102fb7e18e9f43af41a0dfa 100644 (file)
@@ -48,15 +48,6 @@ struct io_plugin_1_0 {
 /*
  * Sudo plugin internals.
  */
-
-struct plugin_info {
-    struct plugin_info *prev; /* required */
-    struct plugin_info *next; /* required */
-    const char *path;
-    const char *symbol_name;
-};
-TQ_DECLARE(plugin_info)
-
 struct plugin_container {
     struct plugin_container *prev; /* required */
     struct plugin_container *next; /* required */
@@ -78,8 +69,7 @@ int sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[],
     struct sudo_conv_reply replies[]);
 int _sudo_printf(int msg_type, const char *fmt, ...);
 
-int sudo_load_plugins(const char *conf_file,
-    struct plugin_container *policy_plugin,
+bool sudo_load_plugins(struct plugin_container *policy_plugin,
     struct plugin_container_list *io_plugins);
 
 #endif /* _SUDO_PLUGIN_INT_H */
index f1e9dac34443d170c04012f3242cc66283646d12..f8a9d3e323b284612629f77ad81a3cdb3f8ec87a 100644 (file)
@@ -79,6 +79,7 @@ tgetpass(const char *prompt, int timeout, int flags)
     static const char *askpass;
     static char buf[SUDO_PASS_MAX + 1];
     int i, input, output, save_errno, neednl = 0, need_restart;
+    debug_decl(tgetpass, SUDO_DEBUG_CONV)
 
     (void) fflush(stdout);
 
@@ -93,7 +94,7 @@ tgetpass(const char *prompt, int timeout, int flags)
        !tty_present()) {
        if (askpass == NULL || getenv("DISPLAY") == NULL) {
            warningx(_("no tty present and no askpass program specified"));
-           return NULL;
+           debug_return_str(NULL);
        }
        SET(flags, TGP_ASKPASS);
     }
@@ -102,7 +103,7 @@ tgetpass(const char *prompt, int timeout, int flags)
     if (ISSET(flags, TGP_ASKPASS)) {
        if (askpass == NULL || *askpass == '\0')
            errorx(1, _("no askpass program specified, try setting SUDO_ASKPASS"));
-       return sudo_askpass(askpass, prompt);
+       debug_return_str_masked(sudo_askpass(askpass, prompt));
     }
 
 restart:
@@ -203,7 +204,8 @@ restore:
 
     if (save_errno)
        errno = save_errno;
-    return pass;
+
+    debug_return_str_masked(pass);
 }
 
 /*
@@ -216,6 +218,7 @@ sudo_askpass(const char *askpass, const char *prompt)
     sigaction_t sa, saved_sa_pipe;
     int pfd[2];
     pid_t pid;
+    debug_decl(sudo_askpass, SUDO_DEBUG_CONV)
 
     if (pipe(pfd) == -1)
        error(1, _("unable to create pipe"));
@@ -257,7 +260,7 @@ sudo_askpass(const char *askpass, const char *prompt)
     (void) close(pfd[0]);
     (void) sigaction(SIGPIPE, &saved_sa_pipe, NULL);
 
-    return pass;
+    debug_return_str_masked(pass);
 }
 
 extern int term_erase, term_kill;
@@ -269,10 +272,11 @@ getln(int fd, char *buf, size_t bufsiz, int feedback)
     ssize_t nr = -1;
     char *cp = buf;
     char c = '\0';
+    debug_decl(getln, SUDO_DEBUG_CONV)
 
     if (left == 0) {
        errno = EINVAL;
-       return NULL;                    /* sanity */
+       debug_return_str(NULL);         /* sanity */
     }
 
     while (--left) {
@@ -312,7 +316,7 @@ getln(int fd, char *buf, size_t bufsiz, int feedback)
        }
     }
 
-    return nr == 1 ? buf : NULL;
+    debug_return_str_masked(nr == 1 ? buf : NULL);
 }
 
 static void
@@ -326,8 +330,9 @@ int
 tty_present(void)
 {
     int fd;
+    debug_decl(tty_present, SUDO_DEBUG_UTIL)
 
     if ((fd = open(_PATH_TTY, O_RDWR|O_NOCTTY)) != -1)
        close(fd);
-    return fd != -1;
+    debug_return_bool(fd != -1);
 }
diff --git a/src/ttyname.c b/src/ttyname.c
new file mode 100644 (file)
index 0000000..b73325a
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2012 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 <sys/stat.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <errno.h>
+#include <fcntl.h>
+#if defined(HAVE_STRUCT_KINFO_PROC_P_TDEV) || defined (HAVE_STRUCT_KINFO_PROC_KP_EPROC_E_TDEV) || defined(HAVE_STRUCT_KINFO_PROC2_P_TDEV)
+# include <sys/sysctl.h>
+#elif defined(HAVE_STRUCT_KINFO_PROC_KI_TDEV)
+# include <sys/sysctl.h>
+# include <sys/user.h>
+#endif
+
+#include "sudo.h"
+
+/*
+ * How to access the tty device number in struct kinfo_proc.
+ */
+#if defined(HAVE_STRUCT_KINFO_PROC2_P_TDEV)
+# define SUDO_KERN_PROC                KERN_PROC2
+# define sudo_kinfo_proc       kinfo_proc2
+# define sudo_kp_tdev          p_tdev
+# define sudo_kp_namelen       6
+#elif defined(HAVE_STRUCT_KINFO_PROC_P_TDEV)
+# define SUDO_KERN_PROC                KERN_PROC
+# define sudo_kinfo_proc       kinfo_proc
+# define sudo_kp_tdev          p_tdev
+# define sudo_kp_namelen       6
+#elif defined(HAVE_STRUCT_KINFO_PROC_KI_TDEV)
+# define SUDO_KERN_PROC                KERN_PROC
+# define sudo_kinfo_proc       kinfo_proc
+# define sudo_kp_tdev          ki_tdev
+# define sudo_kp_namelen       4
+#elif defined(HAVE_STRUCT_KINFO_PROC_KP_EPROC_E_TDEV)
+# define SUDO_KERN_PROC                KERN_PROC
+# define sudo_kinfo_proc       kinfo_proc
+# define sudo_kp_tdev          kp_eproc.e_tdev
+# define sudo_kp_namelen       4
+#endif
+
+#ifdef sudo_kp_tdev
+/*
+ * Return a string from ttyname() containing the tty to which the process is
+ * attached or NULL if there is no tty associated with the process (or its
+ * parent).  First tries sysctl using the current pid, then the parent's pid.
+ * Falls back on ttyname of std{in,out,err} if that fails.
+ */
+char *
+get_process_ttyname(void)
+{
+    char *tty = NULL;
+    struct sudo_kinfo_proc *ki_proc = NULL;
+    size_t size = sizeof(*ki_proc);
+    int i, mib[6], rc;
+    debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL)
+
+    /*
+     * Lookup tty for this process and, failing that, our parent.
+     * Even if we redirect std{in,out,err} the kernel should still know.
+     */
+    for (i = 0; tty == NULL && i < 2; i++) {
+       mib[0] = CTL_KERN;
+       mib[1] = SUDO_KERN_PROC;
+       mib[2] = KERN_PROC_PID;
+       mib[3] = i ? (int)getppid() : (int)getpid();
+       mib[4] = sizeof(*ki_proc);
+       mib[5] = 1;
+       do {
+           size += size / 10;
+           ki_proc = erealloc(ki_proc, size);
+           rc = sysctl(mib, sudo_kp_namelen, ki_proc, &size, NULL, 0);
+       } while (rc == -1 && errno == ENOMEM);
+       if (rc != -1) {
+           char *dev = devname(ki_proc->sudo_kp_tdev, S_IFCHR);
+           /* Some versions of devname() return NULL, others do not. */
+           if (dev == NULL || *dev == '?' || *dev == '#') {
+               sudo_debug_printf(SUDO_DEBUG_WARN,
+                   "unable to map device number %u to name",
+                   ki_proc->sudo_kp_tdev);
+           } else if (*dev != '/') {
+               /* devname() doesn't use the /dev/ prefix, add one... */
+               size_t len = sizeof(_PATH_DEV) + strlen(dev);
+               tty = emalloc(len);
+               strlcpy(tty, _PATH_DEV, len);
+               strlcat(tty, dev, len);
+           } else {
+               /* Should not happen but just in case... */
+               tty = estrdup(dev);
+           }
+       } else {
+           sudo_debug_printf(SUDO_DEBUG_WARN,
+               "unable to resolve tty via KERN_PROC: %s", strerror(errno));
+       }
+    }
+    efree(ki_proc);
+
+    /* If all else fails, fall back on ttyname(). */
+    if (tty == NULL) {
+       if ((tty = ttyname(STDIN_FILENO)) != NULL ||
+           (tty = ttyname(STDOUT_FILENO)) != NULL ||
+           (tty = ttyname(STDERR_FILENO)) != NULL)
+           tty = estrdup(tty);
+    }
+
+    debug_return_str(tty);
+}
+#else
+/*
+ * Return a string from ttyname() containing the tty to which the process is
+ * attached or NULL if there is no tty associated with the process (or its
+ * parent).  First tries std{in,out,err} then falls back to the parent's /proc
+ * entry.  We could try following the parent all the way to pid 1 but
+ * /proc/%d/status is system-specific (text on Linux, a struct on Solaris).
+ */
+char *
+get_process_ttyname(void)
+{
+    char path[PATH_MAX], *tty = NULL;
+    pid_t ppid;
+    int i, fd;
+    debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL)
+
+    if ((tty = ttyname(STDIN_FILENO)) == NULL &&
+       (tty = ttyname(STDOUT_FILENO)) == NULL &&
+       (tty = ttyname(STDERR_FILENO)) == NULL) {
+       /* No tty for child, check the parent via /proc. */
+       ppid = getppid();
+       for (i = STDIN_FILENO; i < STDERR_FILENO && tty == NULL; i++) {
+           snprintf(path, sizeof(path), "/proc/%d/fd/%d", (int)ppid, i);
+           fd = open(path, O_RDONLY|O_NOCTTY, 0);
+           if (fd != -1) {
+               tty = ttyname(fd);
+               close(fd);
+           }
+       }
+    }
+
+    debug_return_str(estrdup(tty));
+}
+#endif /* sudo_kp_tdev */
index 81972d1ff4b49a167640a58e900f0557e6fba2e2..d3ac78ba0f17ae6bfa03fbd51f1054fd4289f720 100644 (file)
@@ -35,6 +35,7 @@
 #include <termios.h>
 
 #include "missing.h"
+#include "sudo_debug.h"
 
 /* Compatibility with older tty systems. */
 #if !defined(TIOCGWINSZ) && defined(TIOCGSIZE)
 # define ws_row                ts_lines
 #endif
 
-void
-get_ttysize(int *rowp, int *colp)
-{
-    char *p;
 #ifdef TIOCGWINSZ
+static int
+get_ttysize_ioctl(int *rowp, int *colp)
+{
     struct winsize wsize;
+    debug_decl(get_ttysize_ioctl, SUDO_DEBUG_EXEC)
 
     if (ioctl(STDERR_FILENO, TIOCGWINSZ, &wsize) == 0 &&
        wsize.ws_row != 0 && wsize.ws_col  != 0) {
        *rowp = wsize.ws_row;
        *colp = wsize.ws_col;
-       return;
+       debug_return_int(0);
+    }
+    debug_return_int(-1);
+}
+#else
+static int
+get_ttysize_ioctl(int *rowp, int *colp)
+{
+    return -1;
+}
+#endif /* TIOCGWINSZ */
+
+void
+get_ttysize(int *rowp, int *colp)
+{
+    debug_decl(fork_cmnd, SUDO_DEBUG_EXEC)
+
+    if (get_ttysize_ioctl(rowp, colp) == -1) {
+       char *p;
+
+       /* Fall back on $LINES and $COLUMNS. */
+       if ((p = getenv("LINES")) == NULL || (*rowp = atoi(p)) <= 0)
+           *rowp = 24;
+       if ((p = getenv("COLUMNS")) == NULL || (*colp = atoi(p)) <= 0)
+           *colp = 80;
     }
-#endif
 
-    /* Fall back on $LINES and $COLUMNS. */
-    if ((p = getenv("LINES")) == NULL || (*rowp = atoi(p)) <= 0)
-       *rowp = 24;
-    if ((p = getenv("COLUMNS")) == NULL || (*colp = atoi(p)) <= 0)
-       *colp = 80;
+    debug_return;
 }
index e3d711bee1cdc41b53ec05a2f6cb65bbeeaedc18..7f8113bd5a2f567aa123e03bde4cc13d769bb69e 100644 (file)
@@ -94,6 +94,7 @@ utmp_setid(sudo_utmp_t *old, sudo_utmp_t *new)
 {
     const char *line = new->ut_line;
     size_t idlen;
+    debug_decl(utmp_setid, SUDO_DEBUG_UTMP)
 
     /* Skip over "tty" in the id if old entry did too. */
     if (old != NULL) {
@@ -111,6 +112,8 @@ utmp_setid(sudo_utmp_t *old, sudo_utmp_t *new)
        idlen = sizeof(new->ut_id);
     }
     strncpy(new->ut_id, line, idlen);
+
+    debug_return;
 }
 #endif /* HAVE_GETUTXID || HAVE_GETUTID */
 
@@ -121,6 +124,7 @@ static void
 utmp_settime(sudo_utmp_t *ut)
 {
     struct timeval tv;
+    debug_decl(utmp_settime, SUDO_DEBUG_UTMP)
 
     gettimeofday(&tv, NULL);
 
@@ -130,6 +134,8 @@ utmp_settime(sudo_utmp_t *ut)
 #else
     ut->ut_time = tv.tv_sec;
 #endif
+
+    debug_return;
 }
 
 /*
@@ -139,6 +145,8 @@ static void
 utmp_fill(const char *line, const char *user, sudo_utmp_t *ut_old,
     sudo_utmp_t *ut_new)
 {
+    debug_decl(utmp_file, SUDO_DEBUG_UTMP)
+
     if (ut_old == NULL) {
        memset(ut_new, 0, sizeof(*ut_new));
        if (user == NULL) {
@@ -161,6 +169,7 @@ utmp_fill(const char *line, const char *user, sudo_utmp_t *ut_old,
 #if defined(HAVE_STRUCT_UTMPX_UT_TYPE) || defined(HAVE_STRUCT_UTMP_UT_TYPE)
     ut_new->ut_type = USER_PROCESS;
 #endif
+    debug_return;
 }
 
 /*
@@ -172,12 +181,13 @@ utmp_fill(const char *line, const char *user, sudo_utmp_t *ut_old,
  *  Legacy: sparse file indexed by ttyslot() * sizeof(struct utmp)
  */
 #if defined(HAVE_GETUTXID) || defined(HAVE_GETUTID)
-int
+bool
 utmp_login(const char *from_line, const char *to_line, int ttyfd,
     const char *user)
 {
     sudo_utmp_t utbuf, *ut_old = NULL;
-    int rval = FALSE;
+    bool rval = false;
+    debug_decl(utmp_login, SUDO_DEBUG_UTMP)
 
     /* Strip off /dev/ prefix from line as needed. */
     if (strncmp(to_line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
@@ -194,17 +204,18 @@ utmp_login(const char *from_line, const char *to_line, int ttyfd,
     }
     utmp_fill(to_line, user, ut_old, &utbuf);
     if (pututxline(&utbuf) != NULL)
-       rval = TRUE;
+       rval = true;
     endutxent();
 
-    return rval;
+    debug_return_bool(rval);
 }
 
-int
+bool
 utmp_logout(const char *line, int status)
 {
-    int rval = FALSE;
+    bool rval = false;
     sudo_utmp_t *ut, utbuf;
+    debug_decl(utmp_logout, SUDO_DEBUG_UTMP)
 
     /* Strip off /dev/ prefix from line as needed. */
     if (strncmp(line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
@@ -223,9 +234,9 @@ utmp_logout(const char *line, int status)
 # endif
        utmp_settime(ut);
        if (pututxline(ut) != NULL)
-           rval = TRUE;
+           rval = true;
     }
-    return rval;
+    debug_return_bool(rval);
 }
 
 #else /* !HAVE_GETUTXID && !HAVE_GETUTID */
@@ -241,6 +252,7 @@ utmp_slot(const char *line, int ttyfd)
 {
     int slot = 1;
     struct ttyent *tty;
+    debug_decl(utmp_slot, SUDO_DEBUG_UTMP)
 
     setttyent();
     while ((tty = getttyent()) != NULL) {
@@ -249,13 +261,14 @@ utmp_slot(const char *line, int ttyfd)
        slot++;
     }
     endttyent();
-    return tty ? slot : 0;
+    debug_return_int(tty ? slot : 0);
 }
 # else
 static int
 utmp_slot(const char *line, int ttyfd)
 {
     int sfd, slot;
+    debug_decl(utmp_slot, SUDO_DEBUG_UTMP)
 
     /*
      * Temporarily point stdin to the tty since ttyslot()
@@ -270,17 +283,19 @@ utmp_slot(const char *line, int ttyfd)
        error(1, _("unable to restore stdin"));
     close(sfd);
 
-    return slot;
+    debug_return_int(slot);
 }
 # endif /* HAVE_GETTTYENT */
 
-int
+bool
 utmp_login(const char *from_line, const char *to_line, int ttyfd,
     const char *user)
 {
     sudo_utmp_t utbuf, *ut_old = NULL;
-    int slot, rval = FALSE;
+    bool rval = false;
+    int slot;
     FILE *fp;
+    debug_decl(utmp_login, SUDO_DEBUG_UTMP)
 
     /* Strip off /dev/ prefix from line as needed. */
     if (strncmp(to_line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
@@ -314,23 +329,24 @@ utmp_login(const char *from_line, const char *to_line, int ttyfd,
     utmp_fill(to_line, user, ut_old, &utbuf);
     if (fseek(fp, slot * (long)sizeof(utbuf), SEEK_SET) == 0) {
        if (fwrite(&utbuf, sizeof(utbuf), 1, fp) == 1)
-           rval = TRUE;
+           rval = true;
     }
     fclose(fp);
 
 done:
-    return rval;
+    debug_return_bool(rval);
 }
 
-int
+bool
 utmp_logout(const char *line, int status)
 {
     sudo_utmp_t utbuf;
-    int rval = FALSE;
+    bool rval = false;
     FILE *fp;
+    debug_decl(utmp_logout, SUDO_DEBUG_UTMP)
 
     if ((fp = fopen(_PATH_UTMP, "r+")) == NULL)
-       return rval;
+       debug_return_int(rval);
 
     /* Strip off /dev/ prefix from line as needed. */
     if (strncmp(line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
@@ -346,13 +362,13 @@ utmp_logout(const char *line, int status)
            /* Back up and overwrite record. */
            if (fseek(fp, 0L - (long)sizeof(utbuf), SEEK_CUR) == 0) {
                if (fwrite(&utbuf, sizeof(utbuf), 1, fp) == 1)
-                   rval = TRUE;
+                   rval = true;
            }
            break;
        }
     }
     fclose(fp);
 
-    return rval;
+    debug_return_bool(rval);
 }
 #endif /* HAVE_GETUTXID || HAVE_GETUTID */
diff --git a/sudo.pp b/sudo.pp
index a6e808cff27eed96bee8572c3cbb5c83cdc01f48..f846a8be5c96d44fbe5f92dff0960b6f7fa50729 100644 (file)
--- a/sudo.pp
+++ b/sudo.pp
@@ -12,7 +12,7 @@ limited root privileges to users and log root activity.  \
 The basic philosophy is to give as few privileges as possible but \
 still allow people to get their work done."
        vendor="Todd C. Miller"
-       copyright="(c) 1993-1996,1998-2011 Todd C. Miller"
+       copyright="(c) 1993-1996,1998-2012 Todd C. Miller"
 
 %if [aix]
        # AIX package summary is limited to 40 characters
@@ -74,14 +74,17 @@ still allow people to get their work done."
        # Note that the order must match that of sudoers.
        case "$pp_rpm_distro" in
        centos*|rhel*)
+               chmod u+w ${pp_destdir}${sudoersdir}/sudoers
                /bin/ed - ${pp_destdir}${sudoersdir}/sudoers <<-'EOF'
                /Locale settings/+1,s/^# //
                /Desktop path settings/+1,s/^# //
                w
                q
                EOF
+               chmod u-w ${pp_destdir}${sudoersdir}/sudoers
                ;;
        sles*)
+               chmod u+w ${pp_destdir}${sudoersdir}/sudoers
                /bin/ed - ${pp_destdir}${sudoersdir}/sudoers <<-'EOF'
                /Locale settings/+1,s/^# //
                /ConsoleKit session/+1,s/^# //
@@ -90,6 +93,7 @@ still allow people to get their work done."
                w
                q
                EOF
+               chmod u-w ${pp_destdir}${sudoersdir}/sudoers
                ;;
        esac
 
@@ -157,6 +161,7 @@ still allow people to get their work done."
 %if [deb]
        # Uncomment some Defaults and the %sudo rule in sudoers
        # Note that the order must match that of sudoers and be tab-indented.
+       chmod u+w ${pp_destdir}${sudoersdir}/sudoers
        /bin/ed - ${pp_destdir}${sudoersdir}/sudoers <<-'EOF'
        /Locale settings/+1,s/^# //
        /X11 resource/+1,s/^# //
@@ -164,6 +169,7 @@ still allow people to get their work done."
        w
        q
        EOF
+       chmod u-w ${pp_destdir}${sudoersdir}/sudoers
        mkdir -p ${pp_destdir}/etc/pam.d
        cat > ${pp_destdir}/etc/pam.d/sudo <<-EOF
        #%PAM-1.0
@@ -176,6 +182,14 @@ still allow people to get their work done."
        EOF
 %endif
 
+%if [macos]
+       pp_macos_pkg_type=flat
+       pp_macos_bundle_id=ws.sudo.pkg.sudo
+       pp_macos_pkg_license=doc/LICENSE
+       pp_macos_pkg_readme=${pp_wrkdir}/ReadMe.txt
+       perl -pe 'last if (/^What/i && $seen++)' NEWS > ${pp_wrkdir}/ReadMe.txt
+%endif
+
        # OS-level directories that should generally exist but might not.
        extradirs=`echo ${pp_destdir}/${mandir}/[mc]* | sed "s#${pp_destdir}/##g"`
        extradirs="$extradirs `dirname $docdir` `dirname $timedir`"
@@ -189,20 +203,21 @@ still allow people to get their work done."
        osdirs=`echo $osdirs | tr " " "\n" | sort -u`
 
 %files
-       $osdirs                -
-       $bindir/sudo        4111 root:
-       $bindir/sudoedit    4111 root:
-       $sbindir/visudo     0111
-       $bindir/sudoreplay  0111
-       $includedir/sudo_plugin.h
-       $libexecdir/*           optional
+       $osdirs                 -
+       $bindir/sudo            4111 root:
+       $bindir/sudoedit        4111 root:
+       $sbindir/visudo         0111
+       $bindir/sudoreplay      0111
+       $includedir/sudo_plugin.h 0444
+       $libexecdir/*           0755 optional
        $sudoersdir/sudoers.d/  0750 $sudoers_uid:$sudoers_gid
        $timedir/               0700 root:
        $docdir/
-       $docdir/*
+       $docdir/sudoers2ldif    0555 optional,ignore-others
+       $docdir/*               0444
        $localedir/             optional
-       $localedir/**           optional
-       /etc/pam.d/*            volatile,optional
+       $localedir/**           0444 optional
+       /etc/pam.d/*            0444 volatile,optional
 %if [rpm,deb]
        $sudoersdir/sudoers $sudoers_mode $sudoers_uid:$sudoers_gid volatile
 %else