2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-23 02:17:35 +00:00

Merge sudo 1.9.16p1 from tip.

--HG--
branch : 1.9
This commit is contained in:
Todd C. Miller 2024-11-12 09:04:24 -07:00
commit 7b41190db6
25 changed files with 432 additions and 300 deletions

View File

@ -16,25 +16,36 @@ on:
paths: paths:
- '**.c' - '**.c'
- '**.h' - '**.h'
permissions: {}
jobs: jobs:
Fuzzing: Fuzzing:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
security-events: write
steps: steps:
- name: Build Fuzzers - name: Build Fuzzers
id: build id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with: with:
oss-fuzz-project-name: 'sudoers' oss-fuzz-project-name: 'sudoers'
dry-run: false language: c
- name: Run Fuzzers - name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with: with:
oss-fuzz-project-name: 'sudoers' oss-fuzz-project-name: 'sudoers'
language: c
fuzz-seconds: 600 fuzz-seconds: 600
dry-run: false output-sarif: true
- name: Upload Crash - name: Upload Crash
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v3
if: failure() && steps.build.outcome == 'success' if: failure() && steps.build.outcome == 'success'
with: with:
name: artifacts name: artifacts
path: ./out/artifacts path: ./out/artifacts
- name: Upload Sarif
if: always() && steps.build.outcome == 'success'
uses: github/codeql-action/upload-sarif@v2
with:
# Path to SARIF file relative to the root of the repository
sarif_file: cifuzz-sarif/results.sarif
checkout_path: cifuzz-sarif

View File

@ -1005,10 +1005,12 @@ Defaults are listed in brackets after the description.
--with-secure-path-value[=PATH] --with-secure-path-value[=PATH]
Sets the value of "secure_path" that is substituted into Sets the value of "secure_path" that is substituted into
the default sudoers file. This option is intended to be the default sudoers file. A value of "no" will cause the
used by package maintainers who wish to set "secure_path" "secure_path" line in the default sudoers file to be commented
to a system-specific value in the default sudoers file. out. This option is intended to be used by package maintainers
It does not actually enable "secure-path". who wish to set "secure_path" to a system-specific value
in the default sudoers file. It does not actually enable
"secure-path" in the sudoers plugin itself.
--with-sendmail=PATH --with-sendmail=PATH
Override configure's guess as to the location of sendmail. Override configure's guess as to the location of sendmail.

59
NEWS
View File

@ -1,3 +1,30 @@
What's new in Sudo 1.9.16p1
* Fixed the test for cross-compiling when checking for C99 snprintf().
The changes made to the test in sudo 1.9.16 resulted in a different
problem. GitHub issue #386.
* Fixed the date used by the exit record in sudo-format log files.
This was a regression introduced in sudo 1.9.16 and only affected
file-based logs, not syslog. GitHub issue #405.
* Fixed the root cause of the "unable to find terminal name for
device" message when running sudo on AIX when no terminal is
present. In sudo 1.9.16 this was turned from a debug message
into a warning. GitHub issue #408
* When a duplicate alias is found in the sudoers file, the warning
message now includes the file and line number of the previous
definition.
* Added support for the --with-secure-path-value=no configure
option to allow packagers to ship the default sudoers file with
the secure path line commented out.
* Sudo no longer sends mail when a user runs "sudo -nv" or "sudo -nl",
even if "mail_badpass" or "mail_always" are set. Sudo already
avoids logging to a file or syslog in this case. Bug #1072.
What's new in Sudo 1.9.16 What's new in Sudo 1.9.16
* Added the "cmddenial_message" sudoers option to provide additional * Added the "cmddenial_message" sudoers option to provide additional
@ -442,7 +469,7 @@ What's new in Sudo 1.9.13
* Sudo no longer checks the ownership and mode of the plugins that * Sudo no longer checks the ownership and mode of the plugins that
it loads. Plugins are configured via either the sudo.conf or it loads. Plugins are configured via either the sudo.conf or
sudoers file which are trusted configuration files. These checks sudoers file which are trusted configuration files. These checks
suffered from time-of-check vs. time-of-use race conditions and suffered from time-of-check versus time-of-use race conditions and
complicate loading plugins that are not simple paths. Ownership complicate loading plugins that are not simple paths. Ownership
and mode checks are still performed when loading the sudo.conf and mode checks are still performed when loading the sudo.conf
and sudoers files, which do not suffer from race conditions. and sudoers files, which do not suffer from race conditions.
@ -531,7 +558,7 @@ What's new in Sudo 1.9.12
security policy. The new "intercept_verify" sudoers setting can security policy. The new "intercept_verify" sudoers setting can
be used to control this behavior. be used to control this behavior.
* Fixed running commands with a relative path (e.g. ./foo) in * Fixed running commands with a relative path (e.g., ./foo) in
intercept mode. Previously, this would fail if sudo's current intercept mode. Previously, this would fail if sudo's current
working directory was different from that of the command. working directory was different from that of the command.
@ -596,7 +623,7 @@ What's new in Sudo 1.9.12
from the EDITOR environment variable. GitHub issue #179. from the EDITOR environment variable. GitHub issue #179.
* The sudo Python plugin now implements the "find_spec" method instead * The sudo Python plugin now implements the "find_spec" method instead
of the the deprecated "find_module". This fixes a test failure when of the deprecated "find_module". This fixes a test failure when
a newer version of setuptools that doesn't include "find_module" is a newer version of setuptools that doesn't include "find_module" is
found on the system. found on the system.
@ -1042,7 +1069,7 @@ What's new in Sudo 1.9.7p2
to load a plugin with a name that conflicts with a Python module to load a plugin with a name that conflicts with a Python module
installed in the system location. installed in the system location.
* Sudo no longer sets the the open files resource limit to "unlimited" * Sudo no longer sets the open files resource limit to "unlimited"
while it runs. This avoids a problem where sudo's closefrom() while it runs. This avoids a problem where sudo's closefrom()
emulation would need to close a very large number of descriptors emulation would need to close a very large number of descriptors
on systems without a way to determine which ones are actually open. on systems without a way to determine which ones are actually open.
@ -1089,7 +1116,7 @@ What's new in Sudo 1.9.7
* The "fuzz" Makefile target now runs all the fuzzers for 8192 * The "fuzz" Makefile target now runs all the fuzzers for 8192
passes (can be overridden via the FUZZ_RUNS variable). This makes passes (can be overridden via the FUZZ_RUNS variable). This makes
it easier to run the fuzzers in-tree. To run a fuzzer indefinitely, it easier to run the fuzzers in-tree. To run a fuzzer indefinitely,
set FUZZ_RUNS=-1, e.g. "make FUZZ_RUNS=-1 fuzz". set FUZZ_RUNS=-1, e.g., "make FUZZ_RUNS=-1 fuzz".
* Fixed fuzzing on FreeBSD where the ld.lld linker returns an * Fixed fuzzing on FreeBSD where the ld.lld linker returns an
error by default when a symbol is multiply-defined. error by default when a symbol is multiply-defined.
@ -1719,7 +1746,7 @@ What's new in Sudo 1.9.0
* Fixed an issue where PAM session modules could be called with * Fixed an issue where PAM session modules could be called with
the wrong user name when multiple users in the passwd database the wrong user name when multiple users in the passwd database
share the the same user-ID. Debian bug #734752. share the same user-ID. Debian bug #734752.
* Sudo command line options that take a value may only be specified * Sudo command line options that take a value may only be specified
once. This is to help guard against problems caused by poorly once. This is to help guard against problems caused by poorly
@ -1766,7 +1793,7 @@ What's new in Sudo 1.8.30
* Sudo now treats an attempt to run "sudo sudoedit" as simply * Sudo now treats an attempt to run "sudo sudoedit" as simply
"sudoedit". If the sudoers file contains a fully-qualified path "sudoedit". If the sudoers file contains a fully-qualified path
to sudoedit, sudo will now treat it simply as "sudoedit" (with to sudoedit, sudo will now treat it simply as "sudoedit" (with
no path). Visudo will will now treat a fully-qualified path no path). Visudo will now treat a fully-qualified path
to sudoedit as an error. Bug #871. to sudoedit as an error. Bug #871.
* Fixed a bug introduced in sudo 1.8.28 where sudo would warn about * Fixed a bug introduced in sudo 1.8.28 where sudo would warn about
@ -2826,7 +2853,7 @@ What's new in Sudo 1.8.15
* When the command sudo is running dies due to a signal, sudo will * When the command sudo is running dies due to a signal, sudo will
now send itself that same signal with the default signal handler now send itself that same signal with the default signal handler
installed instead of exiting. The bash shell appears to ignore installed instead of exiting. The bash shell appears to ignore
some signals, e.g. SIGINT, unless the command being run is killed some signals, e.g., SIGINT, unless the command being run is killed
by that signal. This makes the behavior of commands run under by that signal. This makes the behavior of commands run under
sudo the same as without sudo when bash is the shell. Bug #722 sudo the same as without sudo when bash is the shell. Bug #722
@ -3620,7 +3647,7 @@ What's new in Sudo 1.8.6p1?
What's new in Sudo 1.8.6? What's new in Sudo 1.8.6?
* Sudo is now built with the -fstack-protector flag if the the * Sudo is now built with the -fstack-protector flag if the
compiler supports it. Also, the -zrelro linker flag is used if compiler supports it. Also, the -zrelro linker flag is used if
supported. The --disable-hardening configure option can be used supported. The --disable-hardening configure option can be used
to build sudo without stack smashing protection. to build sudo without stack smashing protection.
@ -3758,7 +3785,7 @@ What's new in Sudo 1.8.5?
* On systems with an SVR4-style /proc file system, the /proc/pid/psinfo * On systems with an SVR4-style /proc file system, the /proc/pid/psinfo
file is now uses to determine the controlling terminal, if possible. file is now uses to determine the controlling terminal, if possible.
This allows tty-based tickets to work properly even when, e.g. This allows tty-based tickets to work properly even when, e.g.,
standard input, output and error are redirected to /dev/null. standard input, output and error are redirected to /dev/null.
* The output of "sudoreplay -l" is now sorted by file name (or * The output of "sudoreplay -l" is now sorted by file name (or
@ -3766,7 +3793,7 @@ What's new in Sudo 1.8.5?
order in which they were found on the file system. order in which they were found on the file system.
* Sudo now behaves properly when I/O logging is enabled and the * Sudo now behaves properly when I/O logging is enabled and the
controlling terminal is revoked (e.g. the running sshd is killed). controlling terminal is revoked (e.g., the running sshd is killed).
Previously, sudo may have exited without calling the I/O plugin's Previously, sudo may have exited without calling the I/O plugin's
close function which can lead to an incomplete I/O log. close function which can lead to an incomplete I/O log.
@ -3877,19 +3904,19 @@ What's new in Sudo 1.8.4?
* The deprecated "noexec_file" sudoers option is no longer supported. * The deprecated "noexec_file" sudoers option is no longer supported.
* Fixed a race condition when I/O logging is not enabled that could * Fixed a race condition when I/O logging is not enabled that could
result in tty-generated signals (e.g. control-C) being received result in tty-generated signals (e.g., control-C) being received
by the command twice. by the command twice.
* If none of the standard input, output or error are connected to * If none of the standard input, output or error are connected to
a tty device, sudo will now check its parent's standard input, 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 output or error for the tty name on systems with /proc and BSD
systems that support the KERN_PROC_PID sysctl. This allows systems that support the KERN_PROC_PID sysctl. This allows
tty-based tickets to work properly even when, e.g. standard tty-based tickets to work properly even when, e.g., standard
input, output and error are redirected to /dev/null. input, output and error are redirected to /dev/null.
* Added the --enable-kerb5-instance configure option to allow * Added the --enable-kerb5-instance configure option to allow
people using Kerberos V authentication to specify a custom people using Kerberos V authentication to specify a custom
instance so the principal name can be, e.g. "username/sudo" instance so the principal name can be, e.g., "username/sudo"
similar to how ksu uses "username/root". similar to how ksu uses "username/root".
* Fixed a bug where a pattern like "/usr/*" included /usr/bin/ in * Fixed a bug where a pattern like "/usr/*" included /usr/bin/ in
@ -4076,7 +4103,7 @@ What's new in Sudo 1.8.1?
fixed. fixed.
* Sudo will now create an entry in the utmp (or utmpx) file when * Sudo will now create an entry in the utmp (or utmpx) file when
allocating a pseudo-tty (e.g. when logging I/O). The "set_utmp" allocating a pseudo-tty (e.g., when logging I/O). The "set_utmp"
and "utmp_runas" sudoers file options can be used to control this. and "utmp_runas" sudoers file options can be used to control this.
Other policy plugins may use the "set_utmp" and "utmp_user" Other policy plugins may use the "set_utmp" and "utmp_user"
entries in the command_info list. entries in the command_info list.
@ -4377,7 +4404,7 @@ What's new in Sudo 1.7.3?
now taken into account when looking up users and groups. Sudo now taken into account when looking up users and groups. Sudo
now applies the correct the user and group ids when running a now applies the correct the user and group ids when running a
command as a user whose account details come from a different command as a user whose account details come from a different
source (e.g. LDAP or DCE vs. local files). source (e.g., LDAP or DCE versus local files).
* Support for multiple 'sudoers_base' and 'uri' entries in ldap.conf. * Support for multiple 'sudoers_base' and 'uri' entries in ldap.conf.
When multiple entries are listed, sudo will try each one in the When multiple entries are listed, sudo will try each one in the

View File

@ -60,7 +60,7 @@ can store sudoers content.
For OpenLDAP, there are two options, depending on how slapd is configured. For OpenLDAP, there are two options, depending on how slapd is configured.
The first option is to copy the file schema.OpenLDAP to the schema The first option is to copy the file schema.OpenLDAP to the schema
directory (e.g. /etc/openldap/schema). You must then edit your directory (e.g., /etc/openldap/schema). You must then edit your
slapd.conf and add an include line the new schema, for example: slapd.conf and add an include line the new schema, for example:
# Sudo LDAP schema # Sudo LDAP schema

69
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.72 for sudo 1.9.16. # Generated by GNU Autoconf 2.72 for sudo 1.9.16p1.
# #
# Report bugs to <https://bugzilla.sudo.ws/>. # Report bugs to <https://bugzilla.sudo.ws/>.
# #
@ -614,8 +614,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='sudo' PACKAGE_NAME='sudo'
PACKAGE_TARNAME='sudo' PACKAGE_TARNAME='sudo'
PACKAGE_VERSION='1.9.16' PACKAGE_VERSION='1.9.16p1'
PACKAGE_STRING='sudo 1.9.16' PACKAGE_STRING='sudo 1.9.16p1'
PACKAGE_BUGREPORT='https://bugzilla.sudo.ws/' PACKAGE_BUGREPORT='https://bugzilla.sudo.ws/'
PACKAGE_URL='' PACKAGE_URL=''
@ -734,6 +734,7 @@ pam_login_service
pam_session pam_session
editor editor
secure_path_status secure_path_status
secure_path_config
secure_path secure_path
netsvc_conf netsvc_conf
nsswitch_conf nsswitch_conf
@ -1644,7 +1645,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # 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. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
'configure' configures sudo 1.9.16 to adapt to many kinds of systems. 'configure' configures sudo 1.9.16p1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1710,7 +1711,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of sudo 1.9.16:";; short | recursive ) echo "Configuration of sudo 1.9.16p1:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1885,7 +1886,8 @@ Optional Packages:
--with-ldap-conf-file path to LDAP configuration file --with-ldap-conf-file path to LDAP configuration file
--with-ldap-secret-file path to LDAP secret password file --with-ldap-secret-file path to LDAP secret password file
--with-secure-path-value --with-secure-path-value
value of secure_path in the default sudoers file value of secure_path in the default sudoers file, or
"no" to comment out by default
--with-secure-path override the user's path with a built-in one --with-secure-path override the user's path with a built-in one
--without-interfaces don't try to read the ip addr of network interfaces --without-interfaces don't try to read the ip addr of network interfaces
--with-askpass=PATH Fully qualified pathname of askpass helper --with-askpass=PATH Fully qualified pathname of askpass helper
@ -2004,7 +2006,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
sudo configure 1.9.16 sudo configure 1.9.16p1
generated by GNU Autoconf 2.72 generated by GNU Autoconf 2.72
Copyright (C) 2023 Free Software Foundation, Inc. Copyright (C) 2023 Free Software Foundation, Inc.
@ -2824,7 +2826,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by sudo $as_me 1.9.16, which was It was created by sudo $as_me 1.9.16p1, which was
generated by GNU Autoconf 2.72. Invocation command line was generated by GNU Autoconf 2.72. Invocation command line was
$ $0$ac_configure_args_raw $ $0$ac_configure_args_raw
@ -3685,6 +3687,7 @@ sudoers_path='$(sysconfdir)/sudoers'
# #
@ -3733,6 +3736,7 @@ sesh_file="$libexecdir/sudo/sesh"
visudo="$sbindir/visudo" visudo="$sbindir/visudo"
nsswitch_conf=/etc/nsswitch.conf nsswitch_conf=/etc/nsswitch.conf
secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
secure_path_config=
secure_path_status="disabled" secure_path_status="disabled"
pam_session=on pam_session=on
pam_login_service=sudo pam_login_service=sudo
@ -6314,7 +6318,9 @@ EOF
if test ${with_secure_path_value+y} if test ${with_secure_path_value+y}
then : then :
withval=$with_secure_path_value; case $with_secure_path_value in withval=$with_secure_path_value; case $with_secure_path_value in
yes|no) as_fn_error $? "must give --secure-path-value an argument." "$LINENO" 5 yes) as_fn_error $? "must give --with-secure-path-value an argument." "$LINENO" 5
;;
no) secure_path_config="# "
;; ;;
*) secure_path="$with_secure_path_value" *) secure_path="$with_secure_path_value"
;; ;;
@ -24790,7 +24796,31 @@ esac
COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }mktemp_test" COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }mktemp_test"
fi fi
ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" if test X"$ac_cv_build_prog_cc_c99" != X"no" -a X"$cross_compiling" = X"yes"
then :
# If we have a C99 compiler and are cross-compiling, assume
# C99-compliant v?snprintf().
ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf"
if test "x$ac_cv_func_snprintf" = xyes
then :
printf "%s\n" "#define HAVE_SNPRINTF 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf"
if test "x$ac_cv_func_vsnprintf" = xyes
then :
printf "%s\n" "#define HAVE_VSNPRINTF 1" >>confdefs.h
fi
ac_cv_have_working_snprintf="$ac_cv_func_snprintf"
ac_cv_have_working_vsnprintf="$ac_cv_func_vsnprintf"
else case e in #(
e)
# Check for C99-compliant v?snprintf().
ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf"
if test "x$ac_cv_func_snprintf" = xyes if test "x$ac_cv_func_snprintf" = xyes
then : then :
printf "%s\n" "#define HAVE_SNPRINTF 1" >>confdefs.h printf "%s\n" "#define HAVE_SNPRINTF 1" >>confdefs.h
@ -24919,19 +24949,8 @@ printf "%s\n" "$as_me: WARNING: Replacing missing/broken (v)snprintf() with sudo
printf "%s\n" "#define PREFER_PORTABLE_SNPRINTF 1" >>confdefs.h printf "%s\n" "#define PREFER_PORTABLE_SNPRINTF 1" >>confdefs.h
fi fi
if test X"$ac_cv_build_prog_cc_c99" != X"no" ;;
then : esac
# If we have a C99 compiler and are cross-compiling, assume
# C99-compliant v?snprintf().
if test X"$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf" = X"crosscross"
then :
ac_cv_have_working_snprintf=yes
ac_cv_have_working_vsnprintf=yes
fi
fi fi
if test X"$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf" = X"yesyes" if test X"$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf" = X"yesyes"
then : then :
@ -36755,7 +36774,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by sudo $as_me 1.9.16, which was This file was extended by sudo $as_me 1.9.16p1, which was
generated by GNU Autoconf 2.72. Invocation command line was generated by GNU Autoconf 2.72. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -36823,7 +36842,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped' ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\ ac_cs_version="\\
sudo config.status 1.9.16 sudo config.status 1.9.16p1
configured by $0, generated by GNU Autoconf 2.72, configured by $0, generated by GNU Autoconf 2.72,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@ -18,7 +18,7 @@ dnl ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
dnl OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. dnl OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
dnl dnl
AC_PREREQ([2.69]) AC_PREREQ([2.69])
AC_INIT([sudo], [1.9.16], [https://bugzilla.sudo.ws/], [sudo]) AC_INIT([sudo], [1.9.16p1], [https://bugzilla.sudo.ws/], [sudo])
AC_CONFIG_HEADERS([config.h pathnames.h]) AC_CONFIG_HEADERS([config.h pathnames.h])
AC_CONFIG_SRCDIR([src/sudo.c]) AC_CONFIG_SRCDIR([src/sudo.c])
AC_CONFIG_AUX_DIR([scripts]) AC_CONFIG_AUX_DIR([scripts])
@ -177,6 +177,7 @@ AC_SUBST([sssd_lib])
AC_SUBST([nsswitch_conf]) AC_SUBST([nsswitch_conf])
AC_SUBST([netsvc_conf]) AC_SUBST([netsvc_conf])
AC_SUBST([secure_path]) AC_SUBST([secure_path])
AC_SUBST([secure_path_config])
AC_SUBST([secure_path_status]) AC_SUBST([secure_path_status])
AC_SUBST([editor]) AC_SUBST([editor])
AC_SUBST([pam_session]) AC_SUBST([pam_session])
@ -230,6 +231,7 @@ sesh_file="$libexecdir/sudo/sesh"
visudo="$sbindir/visudo" visudo="$sbindir/visudo"
nsswitch_conf=/etc/nsswitch.conf nsswitch_conf=/etc/nsswitch.conf
secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
secure_path_config=
secure_path_status="disabled" secure_path_status="disabled"
pam_session=on pam_session=on
pam_login_service=sudo pam_login_service=sudo
@ -1068,9 +1070,11 @@ AC_ARG_WITH(ldap-secret-file, [AS_HELP_STRING([--with-ldap-secret-file], [path t
test -n "$with_ldap_secret_file" && ldap_secret="$with_ldap_secret_file" test -n "$with_ldap_secret_file" && ldap_secret="$with_ldap_secret_file"
SUDO_DEFINE_UNQUOTED(_PATH_LDAP_SECRET, "$ldap_secret", [Path to the ldap.secret file]) SUDO_DEFINE_UNQUOTED(_PATH_LDAP_SECRET, "$ldap_secret", [Path to the ldap.secret file])
AC_ARG_WITH(secure-path-value, [AS_HELP_STRING([--with-secure-path-value], [value of secure_path in the default sudoers file])], AC_ARG_WITH(secure-path-value, [AS_HELP_STRING([--with-secure-path-value], [value of secure_path in the default sudoers file, or "no" to comment out by default])],
[case $with_secure_path_value in [case $with_secure_path_value in
yes|no) AC_MSG_ERROR([must give --secure-path-value an argument.]) yes) AC_MSG_ERROR([must give --with-secure-path-value an argument.])
;;
no) secure_path_config="# "
;; ;;
*) secure_path="$with_secure_path_value" *) secure_path="$with_secure_path_value"
;; ;;
@ -3060,14 +3064,15 @@ AS_IF([test X"$sudo_mktemp" = X"yes"], [
SUDO_APPEND_COMPAT_EXP(sudo_mkdtemp sudo_mkdtempat sudo_mkostempsat sudo_mkstemp sudo_mkstemps) SUDO_APPEND_COMPAT_EXP(sudo_mkdtemp sudo_mkdtempat sudo_mkostempsat sudo_mkstemp sudo_mkstemps)
COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }mktemp_test" COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }mktemp_test"
]) ])
AX_FUNC_SNPRINTF AS_IF([test X"$ac_cv_prog_cc_c99" != X"no" -a X"$cross_compiling" = X"yes"], [
AS_IF([test X"$ac_cv_prog_cc_c99" != X"no"], [
# If we have a C99 compiler and are cross-compiling, assume # If we have a C99 compiler and are cross-compiling, assume
# C99-compliant v?snprintf(). # C99-compliant v?snprintf().
AS_IF([test X"$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf" = X"crosscross"], [ AC_CHECK_FUNCS(snprintf vsnprintf)
ac_cv_have_working_snprintf=yes ac_cv_have_working_snprintf="$ac_cv_func_snprintf"
ac_cv_have_working_vsnprintf=yes ac_cv_have_working_vsnprintf="$ac_cv_func_vsnprintf"
]) ], [
# Check for C99-compliant v?snprintf().
AX_FUNC_SNPRINTF
]) ])
AS_IF([test X"$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf" = X"yesyes"], [ AS_IF([test X"$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf" = X"yesyes"], [
# System has a C99-compliant v?snprintf(), check for v?asprintf() # System has a C99-compliant v?snprintf(), check for v?asprintf()

View File

@ -102,18 +102,20 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
all: $(DEVDOCS) $(DOCS) all: $(DEVDOCS) $(DOCS)
igor: all igor:
@if [ "$(mantype)" != "mdoc" ]; then \ @rval=0; \
echo "make igor only supported for mdoc manuals" 1>&2; \ for f in *.mdoc.in; do \
exit 1; \ echo $(IGOR) -D $$f; \
else \ $(IGOR) -D $$f || rval=`expr $$rval + $$?`; \
rval=0; \ done; \
for m in $(DOCS); do \ for f in $(OTHER_DOCS) $(OTHER_DOCS_LDAP); do \
echo $(IGOR) -D $$m; \ case `basename $$f` in \
$(IGOR) -D $$m || rval=`expr $$rval + $$?`; \ [A-Z][A-Z]*) \
done; \ echo $(IGOR) -abrw $$f; \
exit $$rval; \ $(IGOR) -abrw $$f || rval=`expr $$rval + $$?`;; \
fi esac; \
done; \
exit $$rval
lint: all lint: all
@if [ "$(mantype)" != "mdoc" ]; then \ @if [ "$(mantype)" != "mdoc" ]; then \

View File

@ -13,7 +13,7 @@ We try to respond to security issues in a timely manner but understand that Sudo
Include as much of the following information as possible to help us better understand the nature and scope of the potential issue: Include as much of the following information as possible to help us better understand the nature and scope of the potential issue:
* Type of issue (e.g. buffer overflow, privilege escalation, etc.) * Type of issue (e.g., buffer overflow, privilege escalation, etc.)
* Full paths of source file(s) related to the issue * Full paths of source file(s) related to the issue
* The location of the affected source code (tag/branch/commit or direct URL) * The location of the affected source code (tag/branch/commit or direct URL)
* Any special configuration required to reproduce the issue * Any special configuration required to reproduce the issue

View File

@ -95,10 +95,10 @@ It just says "Sorry, try again." three times and exits.
> Don't forget to send a SIGHUP to your syslogd so that it re-reads > Don't forget to send a SIGHUP to your syslogd so that it re-reads
> its conf file. Also, remember that syslogd does *not* create > its conf file. Also, remember that syslogd does *not* create
> log files, you need to create the file before syslogd will log > log files, you need to create the file before syslogd will log
> to it (e.g.: touch /var/log/sudo). > to it (e.g., `touch /var/log/sudo`).
> The facility (e.g. 'auth.debug') must be separated from > The facility (e.g., 'auth.debug') must be separated from
> the destination (e.g. '/var/log/auth' or '@loghost') by tabs, > the destination (e.g., '/var/log/auth' or '@loghost') by tabs,
> *not* spaces. This is a common error. > *not* spaces. This is a common error.
#### Sudo won't accept my password, even when entered correctly #### Sudo won't accept my password, even when entered correctly
@ -137,9 +137,9 @@ It just says "Sorry, try again." three times and exits.
> site you may be interested in sudo's LDAP sudoers support, see > site you may be interested in sudo's LDAP sudoers support, see
> [README.LDAP.md](../README.LDAP.md) and the sudoers.ldap manual. > [README.LDAP.md](../README.LDAP.md) and the sudoers.ldap manual.
#### I don't run sendmail, does this mean that I cannot use sudo? #### I don't run sendmail, can I still use sudo?
> No, you just need to disable mailing with a line like: > Yes, you just need to disable mailing with a line like:
Defaults !mailerpath Defaults !mailerpath

View File

@ -294,8 +294,8 @@ Notes on upgrading from an older release
important that the time stamp files not persist when the system important that the time stamp files not persist when the system
reboots. For this reason, the default location for the time reboots. For this reason, the default location for the time
stamp files has changed back to a directory located in `/var/run`. stamp files has changed back to a directory located in `/var/run`.
Systems that do not have `/var/run` (e.g. AIX) or that do not clear Systems that do not have `/var/run` (e.g., AIX) or that do not clear
it on boot (e.g. HP-UX) will need to clear the time stamp it on boot (e.g., HP-UX) will need to clear the time stamp
directory via a start up script. Such a script is installed by directory via a start up script. Such a script is installed by
default on AIX and HP-UX systems. default on AIX and HP-UX systems.
@ -504,7 +504,7 @@ Notes on upgrading from an older release
When sudo is build with LDAP support the `/etc/nsswitch.conf` file is When sudo is build with LDAP support the `/etc/nsswitch.conf` file is
now used to determine the sudoers sea ch order. sudo will default to now used to determine the sudoers sea ch order. sudo will default to
only using `/etc/sudoers` unless `/etc/nsswitch.conf` says otherwise. only using `/etc/sudoers` unless `/etc/nsswitch.conf` says otherwise.
This can be changed with an nsswitch.conf line, e.g.: This can be changed with an nsswitch.conf line, for example:
sudoers: ldap files sudoers: ldap files
@ -548,7 +548,7 @@ Notes on upgrading from an older release
Prior to sudo 1.6.9, the TERM and PATH environment variables Prior to sudo 1.6.9, the TERM and PATH environment variables
would always be preserved even if the env_keep option was would always be preserved even if the env_keep option was
redefined. That is no longer the case. Consequently, if redefined. That is no longer the case. Consequently, if
env_keep is set with "=" and not simply appended to (i.e. using env_keep is set with "=" and not simply appended to (i.e., using
"+="), PATH and TERM must be explicitly included in the list "+="), PATH and TERM must be explicitly included in the list
of environment variables to keep. The LOGNAME, SHELL, USER, of environment variables to keep. The LOGNAME, SHELL, USER,
and USERNAME environment variables are still always set. and USERNAME environment variables are still always set.

View File

@ -25,7 +25,7 @@
.nr BA @BAMAN@ .nr BA @BAMAN@
.nr LC @LCMAN@ .nr LC @LCMAN@
.nr PS @PSMAN@ .nr PS @PSMAN@
.TH "SUDOERS" "@mansectform@" "July 14, 2024" "Sudo @PACKAGE_VERSION@" "File Formats Manual" .TH "SUDOERS" "@mansectform@" "November 11, 2024" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
.nh .nh
.if n .ad l .if n .ad l
.SH "NAME" .SH "NAME"
@ -3838,7 +3838,7 @@ This flag is
\fIon\fR \fIon\fR
by default. by default.
.sp .sp
This setting is only supported by version 1.8.16 or higher. This setting is only supported by version 1.9.16 or higher.
.TP 18n .TP 18n
passprompt_override passprompt_override
If set, the prompt specified by If set, the prompt specified by
@ -5570,11 +5570,16 @@ The
\fIrestricted_env_file\fR \fIrestricted_env_file\fR
option specifies the fully qualified path to a file containing variables option specifies the fully qualified path to a file containing variables
to be set in the environment of the program being run. to be set in the environment of the program being run.
Entries in this file should either be of the form Entries in this file should be assignments in the form
\(oqVARIABLE=value\(cq \(oqVARIABLE=value\(cq
or or
\(oqexport VARIABLE=value\(cq. \(oqexport VARIABLE=value\(cq,
separated by newline characters.
The value may optionally be enclosed in single or double quotes. The value may optionally be enclosed in single or double quotes.
Shell-style variable substitution is not supported.
Empty lines and comments starting with a pound sign
(\(oq#\(cq)
are ignored.
Variables in this file are only added if the variable does not already Variables in this file are only added if the variable does not already
exist in the environment. exist in the environment.
Unlike Unlike

View File

@ -25,7 +25,7 @@
.nr BA @BAMAN@ .nr BA @BAMAN@
.nr LC @LCMAN@ .nr LC @LCMAN@
.nr PS @PSMAN@ .nr PS @PSMAN@
.Dd July 14, 2024 .Dd November 11, 2024
.Dt SUDOERS @mansectform@ .Dt SUDOERS @mansectform@
.Os Sudo @PACKAGE_VERSION@ .Os Sudo @PACKAGE_VERSION@
.Sh NAME .Sh NAME
@ -3637,7 +3637,7 @@ This flag is
.Em on .Em on
by default. by default.
.Pp .Pp
This setting is only supported by version 1.8.16 or higher. This setting is only supported by version 1.9.16 or higher.
.It passprompt_override .It passprompt_override
If set, the prompt specified by If set, the prompt specified by
.Em passprompt .Em passprompt
@ -5220,11 +5220,16 @@ The
.Em restricted_env_file .Em restricted_env_file
option specifies the fully qualified path to a file containing variables option specifies the fully qualified path to a file containing variables
to be set in the environment of the program being run. to be set in the environment of the program being run.
Entries in this file should either be of the form Entries in this file should be assignments in the form
.Ql VARIABLE=value .Ql VARIABLE=value
or or
.Ql export VARIABLE=value . .Ql export VARIABLE=value ,
separated by newline characters.
The value may optionally be enclosed in single or double quotes. The value may optionally be enclosed in single or double quotes.
Shell-style variable substitution is not supported.
Empty lines and comments starting with a pound sign
.Pq Ql #
are ignored.
Variables in this file are only added if the variable does not already Variables in this file are only added if the variable does not already
exist in the environment. exist in the environment.
Unlike Unlike

View File

@ -1453,6 +1453,7 @@ eventlog_exit(const struct eventlog *evlog, int flags)
bool ret = true; bool ret = true;
debug_decl(eventlog_exit, SUDO_DEBUG_UTIL); debug_decl(eventlog_exit, SUDO_DEBUG_UTIL);
/* We expect evlog->event_time to be the command start time. */
if (sudo_timespecisset(&evlog->run_time)) { if (sudo_timespecisset(&evlog->run_time)) {
sudo_timespecadd(&evlog->event_time, &evlog->run_time, &exit_time); sudo_timespecadd(&evlog->event_time, &evlog->run_time, &exit_time);
args.event_time = &exit_time; args.event_time = &exit_time;

View File

@ -423,7 +423,7 @@ store_exit_local(ExitMessage *msg, uint8_t *buf, size_t len,
"command exited with %d", msg->exit_value); "command exited with %d", msg->exit_value);
} }
if (logsrvd_conf_log_exit()) { if (logsrvd_conf_log_exit()) {
if (!eventlog_exit(closure->evlog, flags)) { if (!eventlog_exit(evlog, flags)) {
closure->errstr = _("error logging exit event"); closure->errstr = _("error logging exit event");
debug_return_bool(false); debug_return_bool(false);
} }

View File

@ -297,25 +297,26 @@ int
sudo_pam_verify(const struct sudoers_context *ctx, struct passwd *pw, sudo_pam_verify(const struct sudoers_context *ctx, struct passwd *pw,
const char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback) const char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback)
{ {
const char *envccname; const char *envccname, *pam_user;
const char *s; int rc, *pam_status = (int *)auth->data;
int *pam_status = (int *)auth->data;
debug_decl(sudo_pam_verify, SUDOERS_DEBUG_AUTH); debug_decl(sudo_pam_verify, SUDOERS_DEBUG_AUTH);
def_prompt = prompt; /* for converse */ def_prompt = prompt; /* for converse */
getpass_error = false; /* set by converse if user presses ^C */ getpass_error = false; /* set by converse if user presses ^C */
pam_closure.callback = callback; /* passed to conversation function */ pam_closure.callback = callback; /* passed to conversation function */
/* Set KRB5CCNAME from the user environment if not set to propagate this /*
* information to PAM modules that may use it to authentication. */ * Set KRB5CCNAME from the user environment if not set to propagate this
envccname = sudo_getenv("KRB5CCNAME"); * information to PAM modules that may use it to authentication.
if (envccname == NULL && ctx->user.ccname != NULL) { */
if (sudo_setenv("KRB5CCNAME", ctx->user.ccname, true) != 0) { envccname = sudo_getenv("KRB5CCNAME");
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO, if (envccname == NULL && ctx->user.ccname != NULL) {
"unable to set KRB5CCNAME"); if (sudo_setenv("KRB5CCNAME", ctx->user.ccname, true) != 0) {
debug_return_int(AUTH_FAILURE); sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
} "unable to set KRB5CCNAME");
debug_return_int(AUTH_FAILURE);
} }
}
/* PAM_SILENT prevents the authentication service from generating output. */ /* PAM_SILENT prevents the authentication service from generating output. */
*pam_status = pam_authenticate(pamh, def_pam_silent ? PAM_SILENT : 0); *pam_status = pam_authenticate(pamh, def_pam_silent ? PAM_SILENT : 0);
@ -323,31 +324,41 @@ sudo_pam_verify(const struct sudoers_context *ctx, struct passwd *pw,
/* Restore def_prompt, the passed-in prompt may be freed later. */ /* Restore def_prompt, the passed-in prompt may be freed later. */
def_prompt = PASSPROMPT; def_prompt = PASSPROMPT;
/* Restore KRB5CCNAME to its original value. */ /* Restore KRB5CCNAME to its original value. */
if (envccname == NULL && sudo_unsetenv("KRB5CCNAME") != 0) { if (envccname == NULL && sudo_unsetenv("KRB5CCNAME") != 0) {
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
"unable to restore KRB5CCNAME"); "unable to restore KRB5CCNAME");
debug_return_int(AUTH_FAILURE); debug_return_int(AUTH_FAILURE);
} }
if (getpass_error) { if (getpass_error) {
/* error or ^C from tgetpass() or running non-interactive */ /* error or ^C from tgetpass() or running non-interactive */
debug_return_int(noninteractive ? AUTH_NONINTERACTIVE : AUTH_INTR); debug_return_int(noninteractive ? AUTH_NONINTERACTIVE : AUTH_INTR);
} }
switch (*pam_status) { switch (*pam_status) {
case PAM_SUCCESS: case PAM_SUCCESS:
debug_return_int(AUTH_SUCCESS); /* Verify user did not change during PAM transaction. */
case PAM_AUTH_ERR: rc = pam_get_item(pamh, PAM_USER, (PAM_CONST void **)&pam_user);
case PAM_AUTHINFO_UNAVAIL: if (rc == PAM_SUCCESS &&
case PAM_MAXTRIES: (pam_user == NULL || strcmp(pam_user, pw->pw_name) != 0)) {
case PAM_PERM_DENIED:
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
"pam_authenticate: %d", *pam_status); "unable to authenticate '%s' as user '%s'",
pw->pw_name, pam_user);
debug_return_int(AUTH_FAILURE); debug_return_int(AUTH_FAILURE);
default: }
s = sudo_pam_strerror(pamh, *pam_status); debug_return_int(AUTH_SUCCESS);
log_warningx(ctx, 0, N_("PAM authentication error: %s"), s); case PAM_AUTH_ERR:
debug_return_int(AUTH_ERROR); case PAM_AUTHINFO_UNAVAIL:
case PAM_MAXTRIES:
case PAM_PERM_DENIED:
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
"pam_authenticate: %d", *pam_status);
debug_return_int(AUTH_FAILURE);
default:
log_warningx(ctx, 0, N_("PAM authentication error: %s"),
sudo_pam_strerror(pamh, *pam_status));
debug_return_int(AUTH_ERROR);
} }
} }
@ -363,59 +374,59 @@ sudo_pam_approval(const struct sudoers_context *ctx, struct passwd *pw,
if (def_pam_acct_mgmt) { if (def_pam_acct_mgmt) {
rc = pam_acct_mgmt(pamh, PAM_SILENT); rc = pam_acct_mgmt(pamh, PAM_SILENT);
switch (rc) { switch (rc) {
case PAM_SUCCESS: case PAM_SUCCESS:
break;
case PAM_AUTH_ERR:
log_warningx(ctx, 0, N_("account validation failure, "
"is your account locked?"));
status = AUTH_ERROR;
break;
case PAM_NEW_AUTHTOK_REQD:
/* Ignore if user is exempt from password restrictions. */
if (exempt) {
rc = *pam_status;
break; break;
case PAM_AUTH_ERR: }
log_warningx(ctx, 0, N_("account validation failure, " /* New password required, try to change it. */
"is your account locked?")); log_warningx(ctx, 0, N_("Account or password is "
status = AUTH_ERROR; "expired, reset your password and try again"));
rc = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
if (rc == PAM_SUCCESS)
break; break;
case PAM_NEW_AUTHTOK_REQD: s = pam_strerror(pamh, rc);
/* Ignore if user is exempt from password restrictions. */ log_warningx(ctx, 0,
if (exempt) { N_("unable to change expired password: %s"), s);
rc = *pam_status; status = AUTH_FAILURE;
break; break;
} case PAM_AUTHTOK_EXPIRED:
/* New password required, try to change it. */ /* Ignore if user is exempt from password restrictions. */
log_warningx(ctx, 0, N_("Account or password is " if (exempt) {
"expired, reset your password and try again")); rc = *pam_status;
rc = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
if (rc == PAM_SUCCESS)
break;
s = pam_strerror(pamh, rc);
log_warningx(ctx, 0,
N_("unable to change expired password: %s"), s);
status = AUTH_FAILURE;
break;
case PAM_AUTHTOK_EXPIRED:
/* Ignore if user is exempt from password restrictions. */
if (exempt) {
rc = *pam_status;
break;
}
/* Password expired, cannot be updated by user. */
log_warningx(ctx, 0,
N_("Password expired, contact your system administrator"));
status = AUTH_ERROR;
break;
case PAM_ACCT_EXPIRED:
log_warningx(ctx, 0,
N_("Account expired or PAM config lacks an \"account\" "
"section for sudo, contact your system administrator"));
status = AUTH_ERROR;
break;
case PAM_AUTHINFO_UNAVAIL:
case PAM_MAXTRIES:
case PAM_PERM_DENIED:
s = sudo_pam_strerror(pamh, rc);
log_warningx(ctx, 0, N_("PAM account management error: %s"), s);
status = AUTH_FAILURE;
break;
default:
s = sudo_pam_strerror(pamh, rc);
log_warningx(ctx, 0, N_("PAM account management error: %s"), s);
status = AUTH_ERROR;
break; break;
}
/* Password expired, cannot be updated by user. */
log_warningx(ctx, 0,
N_("Password expired, contact your system administrator"));
status = AUTH_ERROR;
break;
case PAM_ACCT_EXPIRED:
log_warningx(ctx, 0,
N_("Account expired or PAM config lacks an \"account\" "
"section for sudo, contact your system administrator"));
status = AUTH_ERROR;
break;
case PAM_AUTHINFO_UNAVAIL:
case PAM_MAXTRIES:
case PAM_PERM_DENIED:
s = sudo_pam_strerror(pamh, rc);
log_warningx(ctx, 0, N_("PAM account management error: %s"), s);
status = AUTH_FAILURE;
break;
default:
s = sudo_pam_strerror(pamh, rc);
log_warningx(ctx, 0, N_("PAM account management error: %s"), s);
status = AUTH_ERROR;
break;
} }
*pam_status = rc; *pam_status = rc;
} }
@ -706,53 +717,53 @@ converse(int num_msg, PAM_CONST struct pam_message **msg,
type = SUDO_CONV_PROMPT_ECHO_OFF; type = SUDO_CONV_PROMPT_ECHO_OFF;
switch (pm->msg_style) { switch (pm->msg_style) {
case PAM_PROMPT_ECHO_ON: case PAM_PROMPT_ECHO_ON:
type = SUDO_CONV_PROMPT_ECHO_ON; type = SUDO_CONV_PROMPT_ECHO_ON;
FALLTHROUGH; FALLTHROUGH;
case PAM_PROMPT_ECHO_OFF: case PAM_PROMPT_ECHO_OFF:
/* Error out if the last password read was interrupted. */ /* Error out if the last password read was interrupted. */
if (getpass_error) if (getpass_error)
goto bad;
/* Treat non-interactive mode as a getpass error. */
if (noninteractive) {
getpass_error = true;
goto bad;
}
/* Choose either the sudo prompt or the PAM one. */
prompt = use_pam_prompt(pm->msg) ? pm->msg : def_prompt;
/* Read the password unless interrupted. */
pass = auth_getpass(prompt, type, callback);
if (pass == NULL) {
/* Error (or ^C) reading password, don't try again. */
getpass_error = true;
goto bad;
}
if (strlen(pass) >= PAM_MAX_RESP_SIZE) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"password longer than %d", PAM_MAX_RESP_SIZE);
freezero(pass, strlen(pass));
pass = NULL;
goto bad;
}
reply[n].resp = pass; /* auth_getpass() malloc's a copy */
break;
case PAM_TEXT_INFO:
if (pm->msg != NULL && !is_filtered(pm->msg))
sudo_printf(SUDO_CONV_INFO_MSG|SUDO_CONV_PREFER_TTY,
"%s\n", pm->msg);
break;
case PAM_ERROR_MSG:
if (pm->msg != NULL)
sudo_printf(SUDO_CONV_ERROR_MSG|SUDO_CONV_PREFER_TTY,
"%s\n", pm->msg);
break;
default:
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unsupported message style: %d", pm->msg_style);
goto bad; goto bad;
/* Treat non-interactive mode as a getpass error. */
if (noninteractive) {
getpass_error = true;
goto bad;
}
/* Choose either the sudo prompt or the PAM one. */
prompt = use_pam_prompt(pm->msg) ? pm->msg : def_prompt;
/* Read the password unless interrupted. */
pass = auth_getpass(prompt, type, callback);
if (pass == NULL) {
/* Error (or ^C) reading password, don't try again. */
getpass_error = true;
goto bad;
}
if (strlen(pass) >= PAM_MAX_RESP_SIZE) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"password longer than %d", PAM_MAX_RESP_SIZE);
freezero(pass, strlen(pass));
pass = NULL;
goto bad;
}
reply[n].resp = pass; /* auth_getpass() malloc's a copy */
break;
case PAM_TEXT_INFO:
if (pm->msg != NULL && !is_filtered(pm->msg))
sudo_printf(SUDO_CONV_INFO_MSG|SUDO_CONV_PREFER_TTY,
"%s\n", pm->msg);
break;
case PAM_ERROR_MSG:
if (pm->msg != NULL)
sudo_printf(SUDO_CONV_ERROR_MSG|SUDO_CONV_PREFER_TTY,
"%s\n", pm->msg);
break;
default:
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unsupported message style: %d", pm->msg_style);
goto bad;
} }
} }

View File

@ -167,7 +167,7 @@ static struct defaults *new_default(char *, char *, short);
static struct member *new_member(char *, short); static struct member *new_member(char *, short);
static struct sudo_command *new_command(char *, char *); static struct sudo_command *new_command(char *, char *);
static struct command_digest *new_digest(unsigned int, char *); static struct command_digest *new_digest(unsigned int, char *);
static void alias_error(const char *name, int errnum); static void alias_error(const char *name, short type, int errnum);
#line 167 "gram.c" #line 167 "gram.c"
@ -2927,7 +2927,7 @@ yyreduce:
{ {
if (!alias_add(&parsed_policy, (yyvsp[-3].string), HOSTALIAS, if (!alias_add(&parsed_policy, (yyvsp[-3].string), HOSTALIAS,
sudoers, alias_line, alias_column, (yyvsp[0].member))) { sudoers, alias_line, alias_column, (yyvsp[0].member))) {
alias_error((yyvsp[-3].string), errno); alias_error((yyvsp[-3].string), HOSTALIAS, errno);
YYERROR; YYERROR;
} }
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string)); parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
@ -2960,7 +2960,7 @@ yyreduce:
{ {
if (!alias_add(&parsed_policy, (yyvsp[-3].string), CMNDALIAS, if (!alias_add(&parsed_policy, (yyvsp[-3].string), CMNDALIAS,
sudoers, alias_line, alias_column, (yyvsp[0].member))) { sudoers, alias_line, alias_column, (yyvsp[0].member))) {
alias_error((yyvsp[-3].string), errno); alias_error((yyvsp[-3].string), CMNDALIAS, errno);
YYERROR; YYERROR;
} }
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string)); parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
@ -2993,7 +2993,7 @@ yyreduce:
{ {
if (!alias_add(&parsed_policy, (yyvsp[-3].string), RUNASALIAS, if (!alias_add(&parsed_policy, (yyvsp[-3].string), RUNASALIAS,
sudoers, alias_line, alias_column, (yyvsp[0].member))) { sudoers, alias_line, alias_column, (yyvsp[0].member))) {
alias_error((yyvsp[-3].string), errno); alias_error((yyvsp[-3].string), RUNASALIAS, errno);
YYERROR; YYERROR;
} }
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string)); parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
@ -3016,7 +3016,7 @@ yyreduce:
{ {
if (!alias_add(&parsed_policy, (yyvsp[-3].string), USERALIAS, if (!alias_add(&parsed_policy, (yyvsp[-3].string), USERALIAS,
sudoers, alias_line, alias_column, (yyvsp[0].member))) { sudoers, alias_line, alias_column, (yyvsp[0].member))) {
alias_error((yyvsp[-3].string), errno); alias_error((yyvsp[-3].string), USERALIAS, errno);
YYERROR; YYERROR;
} }
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string)); parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
@ -3475,12 +3475,27 @@ sudoerserror(const char *s)
} }
static void static void
alias_error(const char *name, int errnum) alias_error(const char *name, short type, int errnum)
{ {
if (errnum == EEXIST) if (errnum == EEXIST) {
sudoerserrorf(U_("Alias \"%s\" already defined"), name); struct alias *a = alias_get(&parsed_policy, name, type);
else if (a != NULL) {
sudoerserrorf(
U_("duplicate %s \"%s\", previously defined at %s:%d:%d"),
alias_type_to_string(type), name, a->file, a->line, a->column);
alias_put(a);
} else {
if (errno == ELOOP) {
sudoerserrorf(U_("cycle in %s \"%s\""),
alias_type_to_string(type), name);
} else {
sudoerserrorf(U_("duplicate %s \"%s\""),
alias_type_to_string(type), name);
}
}
} else {
sudoerserror(N_("unable to allocate memory")); sudoerserror(N_("unable to allocate memory"));
}
} }
static struct defaults * static struct defaults *

View File

@ -84,7 +84,7 @@ static struct defaults *new_default(char *, char *, short);
static struct member *new_member(char *, short); static struct member *new_member(char *, short);
static struct sudo_command *new_command(char *, char *); static struct sudo_command *new_command(char *, char *);
static struct command_digest *new_digest(unsigned int, char *); static struct command_digest *new_digest(unsigned int, char *);
static void alias_error(const char *name, int errnum); static void alias_error(const char *name, short type, int errnum);
%} %}
%union { %union {
@ -1012,7 +1012,7 @@ hostalias : ALIAS {
} '=' hostlist { } '=' hostlist {
if (!alias_add(&parsed_policy, $1, HOSTALIAS, if (!alias_add(&parsed_policy, $1, HOSTALIAS,
sudoers, alias_line, alias_column, $4)) { sudoers, alias_line, alias_column, $4)) {
alias_error($1, errno); alias_error($1, HOSTALIAS, errno);
YYERROR; YYERROR;
} }
parser_leak_remove(LEAK_PTR, $1); parser_leak_remove(LEAK_PTR, $1);
@ -1039,7 +1039,7 @@ cmndalias : ALIAS {
} '=' cmndlist { } '=' cmndlist {
if (!alias_add(&parsed_policy, $1, CMNDALIAS, if (!alias_add(&parsed_policy, $1, CMNDALIAS,
sudoers, alias_line, alias_column, $4)) { sudoers, alias_line, alias_column, $4)) {
alias_error($1, errno); alias_error($1, CMNDALIAS, errno);
YYERROR; YYERROR;
} }
parser_leak_remove(LEAK_PTR, $1); parser_leak_remove(LEAK_PTR, $1);
@ -1066,7 +1066,7 @@ runasalias : ALIAS {
} '=' userlist { } '=' userlist {
if (!alias_add(&parsed_policy, $1, RUNASALIAS, if (!alias_add(&parsed_policy, $1, RUNASALIAS,
sudoers, alias_line, alias_column, $4)) { sudoers, alias_line, alias_column, $4)) {
alias_error($1, errno); alias_error($1, RUNASALIAS, errno);
YYERROR; YYERROR;
} }
parser_leak_remove(LEAK_PTR, $1); parser_leak_remove(LEAK_PTR, $1);
@ -1085,7 +1085,7 @@ useralias : ALIAS {
} '=' userlist { } '=' userlist {
if (!alias_add(&parsed_policy, $1, USERALIAS, if (!alias_add(&parsed_policy, $1, USERALIAS,
sudoers, alias_line, alias_column, $4)) { sudoers, alias_line, alias_column, $4)) {
alias_error($1, errno); alias_error($1, USERALIAS, errno);
YYERROR; YYERROR;
} }
parser_leak_remove(LEAK_PTR, $1); parser_leak_remove(LEAK_PTR, $1);
@ -1292,12 +1292,27 @@ sudoerserror(const char *s)
} }
static void static void
alias_error(const char *name, int errnum) alias_error(const char *name, short type, int errnum)
{ {
if (errnum == EEXIST) if (errnum == EEXIST) {
sudoerserrorf(U_("Alias \"%s\" already defined"), name); struct alias *a = alias_get(&parsed_policy, name, type);
else if (a != NULL) {
sudoerserrorf(
U_("duplicate %s \"%s\", previously defined at %s:%d:%d"),
alias_type_to_string(type), name, a->file, a->line, a->column);
alias_put(a);
} else {
if (errno == ELOOP) {
sudoerserrorf(U_("cycle in %s \"%s\""),
alias_type_to_string(type), name);
} else {
sudoerserrorf(U_("duplicate %s \"%s\""),
alias_type_to_string(type), name);
}
}
} else {
sudoerserror(N_("unable to allocate memory")); sudoerserror(N_("unable to allocate memory"));
}
} }
static struct defaults * static struct defaults *

View File

@ -507,15 +507,6 @@ log_auth_failure(const struct sudoers_context *ctx, unsigned int status,
/* Do auditing first (audit_failure() handles the locale itself). */ /* Do auditing first (audit_failure() handles the locale itself). */
audit_failure(ctx, ctx->runas.argv, "%s", N_("authentication failure")); audit_failure(ctx, ctx->runas.argv, "%s", N_("authentication failure"));
if (ISSET(status, FLAG_NO_USER_INPUT)) {
/* For "sudo -n", only log the entry if an actual command was run. */
if (ISSET(ctx->mode, MODE_LIST|MODE_VALIDATE))
logit = false;
} else if (!ISSET(status, FLAG_BAD_PASSWORD)) {
/* Authenticated OK, sudoers denials are logged separately. */
logit = false;
}
/* /*
* Do we need to send mail? * Do we need to send mail?
* We want to avoid sending multiple messages for the same command * We want to avoid sending multiple messages for the same command
@ -536,6 +527,18 @@ log_auth_failure(const struct sudoers_context *ctx, unsigned int status,
logit = false; logit = false;
} }
/* Special case overrides for logging and mailing. */
if (ISSET(status, FLAG_NO_USER_INPUT)) {
/* For "sudo -n", only log the entry if an actual command was run. */
if (ISSET(ctx->mode, MODE_LIST|MODE_VALIDATE)) {
logit = false;
mailit = false;
}
} else if (!ISSET(status, FLAG_BAD_PASSWORD)) {
/* Authenticated OK, sudoers denials are logged separately. */
logit = false;
}
if (logit || mailit) { if (logit || mailit) {
/* Log and mail messages should be in the sudoers locale. */ /* Log and mail messages should be in the sudoers locale. */
sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale); sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
@ -655,6 +658,11 @@ log_exit_status(const struct sudoers_context *ctx, int status)
if (!def_log_exit_status) if (!def_log_exit_status)
SET(evl_flags, EVLOG_MAIL_ONLY); SET(evl_flags, EVLOG_MAIL_ONLY);
} }
/*
* eventlog_exit() expects event_time to be the command start time,
* not the current time as set by sudoers_to_eventlog().
*/
sudo_timespecsub(&evlog.event_time, &run_time, &evlog.event_time);
evlog.run_time = run_time; evlog.run_time = run_time;
evlog.exit_value = exit_value; evlog.exit_value = exit_value;
evlog.signal_name = signal_name; evlog.signal_name = signal_name;

View File

@ -40,7 +40,7 @@
* char. If non-NULL, the copy function must have strlcpy-like semantics. * char. If non-NULL, the copy function must have strlcpy-like semantics.
*/ */
char * char *
strvec_join(char *const argv[], char sep, size_t (*cpy)(char *, const char *, size_t)) strvec_join(char *const argv[], char sep, size_t (*cpy)(char * restrict, const char * restrict, size_t))
{ {
char *dst, *result = NULL; char *dst, *result = NULL;
char *const *av; char *const *av;

View File

@ -496,10 +496,10 @@ void canon_path_free(char *resolved);
void canon_path_free_cache(void); void canon_path_free_cache(void);
/* strlcpy_unesc.c */ /* strlcpy_unesc.c */
size_t strlcpy_unescape(char *restrict dst, const char *restrict src, size_t size); size_t strlcpy_unescape(char * restrict dst, const char * restrict src, size_t size);
/* strvec_join.c */ /* strvec_join.c */
char *strvec_join(char *const argv[], char sep, size_t (*cpy)(char *, const char *, size_t)); char *strvec_join(char *const argv[], char sep, size_t (*cpy)(char * restrict, const char * restrict, size_t));
/* unesc_str.c */ /* unesc_str.c */
void unescape_string(char *str); void unescape_string(char *str);

View File

@ -47,8 +47,8 @@ Defaults!@visudo@ env_keep += "SUDO_EDITOR EDITOR VISUAL"
## ##
## Use a hard-coded PATH instead of the user's to find commands. ## Use a hard-coded PATH instead of the user's to find commands.
## This also helps prevent poorly written scripts from running ## This also helps prevent poorly written scripts from running
## artbitrary commands under sudo. ## arbitrary commands under sudo.
Defaults secure_path="@secure_path@" @secure_path_config@Defaults secure_path="@secure_path@"
## ##
## You may wish to keep some of the following environment variables ## You may wish to keep some of the following environment variables
## when running commands via sudo. ## when running commands via sudo.
@ -107,6 +107,10 @@ Defaults secure_path="@secure_path@"
## Some package scripts run a huge number of commands, which is made ## Some package scripts run a huge number of commands, which is made
## slower by these options and also can clutter up the logs. ## slower by these options and also can clutter up the logs.
# Defaults!PKGMAN !intercept, !log_subcmds # Defaults!PKGMAN !intercept, !log_subcmds
##
## Uncomment to disable PAM silent mode. Otherwise messages by PAM
## modules such as pam_faillock will not be printed.
# Defaults !pam_silent
## ##
## Runas alias specification ## Runas alias specification

View File

@ -1386,7 +1386,7 @@ script_matches(const char *script, const char *execpath, int argc,
/* Match interpreter. */ /* Match interpreter. */
if (!pathname_matches(execpath, interp, true)) { if (!pathname_matches(execpath, interp, true)) {
/* It is possible for the interpreter to be a script too. */ /* It is possible for the interpreter to be a script too. */
if (argv > 0 && strcmp(interp, argv[1]) == 0) { if (argc > 0 && strcmp(interp, argv[1]) == 0) {
/* Interpreter args must match for *this* interpreter. */ /* Interpreter args must match for *this* interpreter. */
if (interp_args == NULL || if (interp_args == NULL ||
(argc > 1 && strcmp(interp_args, argv[2]) == 0)) { (argc > 1 && strcmp(interp_args, argv[2]) == 0)) {

View File

@ -1,7 +1,7 @@
/* /*
* SPDX-License-Identifier: ISC * SPDX-License-Identifier: ISC
* *
* Copyright (c) 2012-2023 Todd C. Miller <Todd.Miller@sudo.ws> * Copyright (c) 2012-2024 Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -23,7 +23,7 @@
#include <config.h> #include <config.h>
/* Large files not supported by procfs.h on Solaris. */ /* Large files may not be supported by procfs.h on Solaris. */
#if defined(HAVE_STRUCT_PSINFO_PR_TTYDEV) #if defined(HAVE_STRUCT_PSINFO_PR_TTYDEV)
# undef _FILE_OFFSET_BITS # undef _FILE_OFFSET_BITS
# undef _LARGE_FILES # undef _LARGE_FILES
@ -175,7 +175,8 @@ get_process_ttyname(char *name, size_t namelen)
if ((psinfo.pr_ttydev & DEVNO64) && sizeof(dev_t) == 4) if ((psinfo.pr_ttydev & DEVNO64) && sizeof(dev_t) == 4)
ttydev = makedev(major64(psinfo.pr_ttydev), minor64(psinfo.pr_ttydev)); ttydev = makedev(major64(psinfo.pr_ttydev), minor64(psinfo.pr_ttydev));
#endif #endif
if (ttydev != (dev_t)-1) { /* On AIX, pr_ttydev is 0 (not -1) when no terminal is present. */
if (ttydev != 0 && ttydev != (dev_t)-1) {
errno = serrno; errno = serrno;
if (sudo_ttyname_dev(ttydev, name, namelen) == NULL) { if (sudo_ttyname_dev(ttydev, name, namelen) == NULL) {
sudo_warnx( sudo_warnx(
@ -185,6 +186,7 @@ get_process_ttyname(char *name, size_t namelen)
} }
goto done; goto done;
} }
ttydev = (dev_t)-1;
} }
} else { } else {
struct stat sb; struct stat sb;