Re: Adding a second sysconfdir
"Todd C. Miller via sudo-workers" <[email protected]> Thu, 09 Feb 2023 13:46:46 -0700
| Newsgroups | gmane.comp.tools.sudo.devel |
|---|---|
| Message-ID | <[email protected]> |
------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <[email protected]> On Wed, 01 Feb 2023 14:11:43 -0700, "Todd C. Miller via sudo-workers" wrote: > Another option would be to make _PATH_SUDOERS, _PATH_SUDO_CONF, and > _PATH_SUDO_LOGSRVD_CONF a colon-separated list of path. For example, > if distconfdir is set this could be "/etc/sudoers:/usr/etc/sudoers". > Then the functions that open the configuration file would simply > choose the first file in the list that exists. > > This seems like a more general solution to me. Here is a (large) patch that implements configuration paths in sudo and adds support for distconfdir, as I understand it. For visudo, if there is no sysconfdir sudoers file but the distconfdir version exists, the distconfdir version is edited and installed in sysconfdir. There is a minor issue in visudo where syntax errors in the distconfdir file will be reported with the file name of the sysconfdir version but that is fairly minor and the distconfdir sudoers file should not contain errors in the first place. This feature will not make sudo 1.9.13 but it should be possible to include it in 1.9.14. - todd ------- =_aaaaaaaaaa0 Content-Type: text/x-patch; name="sudo-config-path-distconfdir.patch"; charset="us-ascii" Content-Disposition: attachment; filename="sudo-config-path-distconfdir.patch" Content-Transfer-Encoding: quoted-printable diff -r c3be19c34043 INSTALL.md --- a/INSTALL.md Fri Feb 03 10:26:24 2023 -0700 +++ b/INSTALL.md Thu Feb 09 13:38:41 2023 -0700 @@ -110,7 +110,8 @@ Defaults are listed in brackets after th Install plugins and helper programs in DIR/sudo [PREFIX/libexec/s= udo] = --sysconfdir=3DDIR - Look for `sudo.conf` and `sudoers` files in DIR. [/etc] + Look for configuration files such as `sudo.conf` and `sudoers` + files in DIR. [/etc] = --includedir=3DDIR Install sudo_plugin.h include file in DIR [PREFIX/include] @@ -347,6 +348,12 @@ Defaults are listed in brackets after th = ### Optional features: = + --enable-distconf + Search for configuration files in distconfdir (PREFIX/etc) + if they are not found in sysconfdir (/etc). This can be + used to provide a default set of configuration files that + are read when the files in sysconfdir are not present. + --disable-root-mailer By default sudo will run the mailer as root when tattling on a user so as to prevent that user from killing the mailer. diff -r c3be19c34043 Makefile.in --- a/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 2010-2015, 2017-2022 Todd C. Miller <[email protected]> +# Copyright (c) 2010-2015, 2017-2023 Todd C. Miller <[email protected]> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -31,6 +31,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ includedir =3D @includedir@ datarootdir =3D @datarootdir@ diff -r c3be19c34043 configure --- a/configure Fri Feb 03 10:26:24 2023 -0700 +++ b/configure Thu Feb 09 13:38:41 2023 -0700 @@ -723,6 +723,10 @@ OBJEXT EXEEXT ac_ct_CC CC +sudoers_path +sudo_logsrvd_conf +sudo_conf +cvtsudoers_conf python_plugin sudoers_plugin plugindir @@ -782,6 +786,7 @@ PYTHON_PLUGIN SIGNAME devsearch DIGEST +distconfdir exampledir TMPFILES_D COMPAT_EXP @@ -1049,6 +1054,7 @@ enable_openssl_pkgconfig_template enable_wolfssl enable_gcrypt enable_python +enable_distconf enable_shared enable_static with_pic @@ -1769,6 +1775,7 @@ Optional Features: --enable-wolfssl Use wolfSSL's TLS and sha2 functions --enable-gcrypt Use GNU crypt's sha2 functions --enable-python Compile python plugin support + --enable-distconf Use distconfdir in addition to sysconfdir --enable-shared[=3DPKGS] build shared libraries [default=3Dyes] --enable-static[=3DPKGS] build static libraries [default=3Dyes] --enable-fast-install[=3DPKGS] @@ -3598,6 +3605,7 @@ ac_config_headers=3D"$ac_config_headers co = = = + # # Begin initial values for man page substitution # @@ -3658,6 +3666,7 @@ INSTALL_INTERCEPT=3D INSTALL_NOEXEC=3D PRELOAD_MODULE=3D-module exampledir=3D'$(docdir)/examples' +distconfdir=3D'$(prefix)/etc' devdir=3D'$(srcdir)' PROGS=3D"sudo" : ${MANDIRTYPE=3D'man'} @@ -3706,10 +3715,19 @@ PYTHON_PLUGIN=3D# LOGSRVD=3D LOGSRVD_SRC=3Dlogsrvd LOGSRV_SRC=3Dlib/logsrv -LOGSRVD_CONF=3D'sudo_logsrvd.conf' +LOGSRVD_CONF=3Dsudo_logsrvd.conf LIBLOGSRV=3D'$(top_builddir)/lib/logsrv/liblogsrv.la $(top_builddir)/lib/= protobuf-c/libprotobuf-c.la' PPFILES=3D'$(srcdir)/etc/sudo.pp' = + + + + +cvtsudoers_conf=3D'$(sysconfdir)/cvtsudoers.conf' +sudo_conf=3D'$(sysconfdir)/sudo.conf' +sudo_logsrvd_conf=3D'$(sysconfdir)/sudo_logsrvd.conf' +sudoers_path=3D'$(sysconfdir)/sudoers' + RTLD_PRELOAD_VAR=3D"LD_PRELOAD" RTLD_PRELOAD_ENABLE_VAR=3D RTLD_PRELOAD_DELIM=3D":" @@ -7173,6 +7191,22 @@ printf "%s\n" "$as_me: WARNING: ignoring fi = = +# Check whether --enable-distconf was given. +if test ${enable_distconf+y} +then : + enableval=3D$enable_distconf; case "$enableval" in + yes|no) + ;; + *) as_fn_error $? "--enable-distconf does not take an argument." "$LI= NENO" 5 + ;; + esac + +else case e in #( + e) enable_distconf=3Dno ;; +esac +fi + + ac_ext=3Dc ac_cpp=3D'$CPP $CPPFLAGS' ac_compile=3D'$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -35367,26 +35401,6 @@ while test X"$plugindir" !=3D X"$_plugindi done exec_prefix=3D"$oexec_prefix" = -# Convert exampledir to something that can be used in the man pages -# I wish there was a better way to expand this. -EXAMPLES=3D"$exampledir" -while :; do - EXAMPLES=3D"`echo \"$EXAMPLES\" | sed -e 's/(/{/g' -e 's/)/}/g'`" - case "$EXAMPLES" in - *\${[A-Za-z]*}*) - eval EXAMPLES=3D"$EXAMPLES" - ;; - *) - break - ;; - esac -done -case "$EXAMPLES" in - NONE/*) - EXAMPLES=3D"${ac_default_prefix}${EXAMPLES#NONE}" - ;; -esac - if test X"$enable_intercept" !=3D X"no" then : = @@ -35491,6 +35505,228 @@ test "$localstatedir" =3D '${prefix}/var' = test "$runstatedir" =3D '${localstatedir}/run' && runstatedir=3D'$(locals= tatedir)/run' test "$sysconfdir" =3D '${prefix}/etc' && sysconfdir=3D'/etc' = +# Append distconfdir versions of the config files if enabled +# and distconfdir is different from sysconfdir. +if test $enable_distconf =3D yes +then : + + + _sysconfdir=3D"$sysconfdir" + while :; do + _sysconfdir=3D"`echo \"$_sysconfdir\" | sed -e 's/(/{/g' -e 's/)/}/g'`" + case "$_sysconfdir" in + *\${[A-Za-z]*}*) + eval _sysconfdir=3D"$_sysconfdir" + ;; + *) + break + ;; + esac +done +case "$_sysconfdir" in + NONE/*) + _sysconfdir=3D"${ac_default_prefix}${_sysconfdir#NONE}" + ;; +esac + + + _distconfdir=3D"$distconfdir" + while :; do + _distconfdir=3D"`echo \"$_distconfdir\" | sed -e 's/(/{/g' -e 's/)/}/g'`= " + case "$_distconfdir" in + *\${[A-Za-z]*}*) + eval _distconfdir=3D"$_distconfdir" + ;; + *) + break + ;; + esac +done +case "$_distconfdir" in + NONE/*) + _distconfdir=3D"${ac_default_prefix}${_distconfdir#NONE}" + ;; +esac + + if test "$_sysconfdir" !=3D "$_distconfdir" +then : + + as_fn_append cvtsudoers_conf ':$(distconfdir)/cvtsudoers.conf' + as_fn_append sudo_conf ':$(distconfdir)/sudo.conf' + as_fn_append sudo_logsrvd_conf ':$(distconfdir)/sudo_logsrvd.conf' + as_fn_append sudoers_path ':$(distconfdir)/sudoers' + +fi + +fi + +# Expand config file paths for use in pathnames.h (after config dir overr= ide) + + as_save_IFS=3D$IFS + IFS=3D: + _sudo_define_path_res=3D + for as_dir in $cvtsudoers_conf; do + + _sudo_define_path_exp=3D"$as_dir" + while :; do + _sudo_define_path_exp=3D"`echo \"$_sudo_define_path_exp\" | sed -e 's/(/= {/g' -e 's/)/}/g'`" + case "$_sudo_define_path_exp" in + *\${[A-Za-z]*}*) + eval _sudo_define_path_exp=3D"$_sudo_define_path_exp" + ;; + *) + break + ;; + esac +done +case "$_sudo_define_path_exp" in + NONE/*) + _sudo_define_path_exp=3D"${ac_default_prefix}${_sudo_define_path_= exp#NONE}" + ;; +esac + + if test -z "${_sudo_define_path_res}"; then + _sudo_define_path_res=3D"${_sudo_define_path_exp}" + else + _sudo_define_path_res=3D"${_sudo_define_path_res}:${_sudo_define_pat= h_exp}" + fi + done + IFS=3D$as_save_IFS + cat >>confdefs.h <<EOF +#define _PATH_CVTSUDOERS_CONF "${_sudo_define_path_res}" +EOF + + + + as_save_IFS=3D$IFS + IFS=3D: + _sudo_define_path_res=3D + for as_dir in $sudo_conf; do + + _sudo_define_path_exp=3D"$as_dir" + while :; do + _sudo_define_path_exp=3D"`echo \"$_sudo_define_path_exp\" | sed -e 's/(/= {/g' -e 's/)/}/g'`" + case "$_sudo_define_path_exp" in + *\${[A-Za-z]*}*) + eval _sudo_define_path_exp=3D"$_sudo_define_path_exp" + ;; + *) + break + ;; + esac +done +case "$_sudo_define_path_exp" in + NONE/*) + _sudo_define_path_exp=3D"${ac_default_prefix}${_sudo_define_path_= exp#NONE}" + ;; +esac + + if test -z "${_sudo_define_path_res}"; then + _sudo_define_path_res=3D"${_sudo_define_path_exp}" + else + _sudo_define_path_res=3D"${_sudo_define_path_res}:${_sudo_define_pat= h_exp}" + fi + done + IFS=3D$as_save_IFS + cat >>confdefs.h <<EOF +#define _PATH_SUDO_CONF "${_sudo_define_path_res}" +EOF + + + + as_save_IFS=3D$IFS + IFS=3D: + _sudo_define_path_res=3D + for as_dir in $sudo_logsrvd_conf; do + + _sudo_define_path_exp=3D"$as_dir" + while :; do + _sudo_define_path_exp=3D"`echo \"$_sudo_define_path_exp\" | sed -e 's/(/= {/g' -e 's/)/}/g'`" + case "$_sudo_define_path_exp" in + *\${[A-Za-z]*}*) + eval _sudo_define_path_exp=3D"$_sudo_define_path_exp" + ;; + *) + break + ;; + esac +done +case "$_sudo_define_path_exp" in + NONE/*) + _sudo_define_path_exp=3D"${ac_default_prefix}${_sudo_define_path_= exp#NONE}" + ;; +esac + + if test -z "${_sudo_define_path_res}"; then + _sudo_define_path_res=3D"${_sudo_define_path_exp}" + else + _sudo_define_path_res=3D"${_sudo_define_path_res}:${_sudo_define_pat= h_exp}" + fi + done + IFS=3D$as_save_IFS + cat >>confdefs.h <<EOF +#define _PATH_SUDO_LOGSRVD_CONF "${_sudo_define_path_res}" +EOF + + + + as_save_IFS=3D$IFS + IFS=3D: + _sudo_define_path_res=3D + for as_dir in $sudoers_path; do + + _sudo_define_path_exp=3D"$as_dir" + while :; do + _sudo_define_path_exp=3D"`echo \"$_sudo_define_path_exp\" | sed -e 's/(/= {/g' -e 's/)/}/g'`" + case "$_sudo_define_path_exp" in + *\${[A-Za-z]*}*) + eval _sudo_define_path_exp=3D"$_sudo_define_path_exp" + ;; + *) + break + ;; + esac +done +case "$_sudo_define_path_exp" in + NONE/*) + _sudo_define_path_exp=3D"${ac_default_prefix}${_sudo_define_path_= exp#NONE}" + ;; +esac + + if test -z "${_sudo_define_path_res}"; then + _sudo_define_path_res=3D"${_sudo_define_path_exp}" + else + _sudo_define_path_res=3D"${_sudo_define_path_res}:${_sudo_define_pat= h_exp}" + fi + done + IFS=3D$as_save_IFS + cat >>confdefs.h <<EOF +#define _PATH_SUDOERS "${_sudo_define_path_res}" +EOF + + + +# Convert exampledir to something that can be used in the man pages + + EXAMPLES=3D"$exampledir" + while :; do + EXAMPLES=3D"`echo \"$EXAMPLES\" | sed -e 's/(/{/g' -e 's/)/}/g'`" + case "$EXAMPLES" in + *\${[A-Za-z]*}*) + eval EXAMPLES=3D"$EXAMPLES" + ;; + *) + break + ;; + esac +done +case "$EXAMPLES" in + NONE/*) + EXAMPLES=3D"${ac_default_prefix}${EXAMPLES#NONE}" + ;; +esac + + if test X"$INIT_SCRIPT" !=3D X"" then : = diff -r c3be19c34043 configure.ac --- a/configure.ac Fri Feb 03 10:26:24 2023 -0700 +++ b/configure.ac Thu Feb 09 13:38:41 2023 -0700 @@ -117,6 +117,7 @@ AC_SUBST([RC_LINK]) AC_SUBST([COMPAT_EXP]) AC_SUBST([TMPFILES_D]) AC_SUBST([exampledir]) +AC_SUBST([distconfdir]) AC_SUBST([DIGEST]) AC_SUBST([devsearch]) AC_SUBST([SIGNAME]) @@ -244,6 +245,7 @@ INSTALL_INTERCEPT=3D INSTALL_NOEXEC=3D PRELOAD_MODULE=3D-module exampledir=3D'$(docdir)/examples' +distconfdir=3D'$(prefix)/etc' devdir=3D'$(srcdir)' PROGS=3D"sudo" : ${MANDIRTYPE=3D'man'} @@ -295,11 +297,24 @@ PYTHON_PLUGIN=3D# LOGSRVD=3D LOGSRVD_SRC=3Dlogsrvd LOGSRV_SRC=3Dlib/logsrv -LOGSRVD_CONF=3D'sudo_logsrvd.conf' +LOGSRVD_CONF=3Dsudo_logsrvd.conf LIBLOGSRV=3D'$(top_builddir)/lib/logsrv/liblogsrv.la $(top_builddir)/lib/= protobuf-c/libprotobuf-c.la' PPFILES=3D'$(srcdir)/etc/sudo.pp' = dnl +dnl Config file paths +dnl Either a single file or a colon-separated list of paths. +dnl +AC_SUBST([cvtsudoers_conf]) +AC_SUBST([sudo_conf]) +AC_SUBST([sudo_logsrvd_conf]) +AC_SUBST([sudoers_path]) +cvtsudoers_conf=3D'$(sysconfdir)/cvtsudoers.conf' +sudo_conf=3D'$(sysconfdir)/sudo.conf' +sudo_logsrvd_conf=3D'$(sysconfdir)/sudo_logsrvd.conf' +sudoers_path=3D'$(sysconfdir)/sudoers' + +dnl dnl LD_PRELOAD equivalents dnl RTLD_PRELOAD_VAR=3D"LD_PRELOAD" @@ -1613,6 +1628,16 @@ AC_ARG_ENABLE(python, esac ]) = +AC_ARG_ENABLE(distconf, +[AS_HELP_STRING([--enable-distconf], [Use distconfdir in addition to sysc= onfdir])], +[ case "$enableval" in + yes|no) + ;; + *) AC_MSG_ERROR([--enable-distconf does not take an argument.]) + ;; + esac +], [enable_distconf=3Dno]) + dnl dnl C compiler checks dnl @@ -4257,26 +4282,6 @@ while test X"$plugindir" !=3D X"$_plugindi done exec_prefix=3D"$oexec_prefix" = -# Convert exampledir to something that can be used in the man pages -# I wish there was a better way to expand this. -EXAMPLES=3D"$exampledir" -while :; do - EXAMPLES=3D"`echo \"$EXAMPLES\" | sed -e 's/(/{/g' -e 's/)/}/g'`" - case "$EXAMPLES" in - *\${[[A-Za-z]]*}*) - eval EXAMPLES=3D"$EXAMPLES" - ;; - *) - break - ;; - esac -done -case "$EXAMPLES" in - NONE/*) - EXAMPLES=3D"${ac_default_prefix}${EXAMPLES#NONE}" - ;; -esac - dnl dnl Defer setting _PATH_SUDO_NOEXEC, etc until after exec_prefix is set dnl @@ -4355,6 +4360,28 @@ test "$localstatedir" =3D '${prefix}/var' = test "$runstatedir" =3D '${localstatedir}/run' && runstatedir=3D'$(locals= tatedir)/run' test "$sysconfdir" =3D '${prefix}/etc' && sysconfdir=3D'/etc' = +# Append distconfdir versions of the config files if enabled +# and distconfdir is different from sysconfdir. +AS_IF([test $enable_distconf =3D yes], [ + SUDO_EXPAND_PATH([$sysconfdir], [_sysconfdir]) + SUDO_EXPAND_PATH([$distconfdir], [_distconfdir]) + AS_IF([test "$_sysconfdir" !=3D "$_distconfdir"], [ + AS_VAR_APPEND([cvtsudoers_conf], [':$(distconfdir)/cvtsudoers.conf']) + AS_VAR_APPEND([sudo_conf], [':$(distconfdir)/sudo.conf']) + AS_VAR_APPEND([sudo_logsrvd_conf], [':$(distconfdir)/sudo_logsrvd.conf']= ) + AS_VAR_APPEND([sudoers_path], [':$(distconfdir)/sudoers']) + ]) +]) + +# Expand config file paths for use in pathnames.h (after config dir overr= ide) +SUDO_DEFINE_PATH([$cvtsudoers_conf], [_PATH_CVTSUDOERS_CONF]) +SUDO_DEFINE_PATH([$sudo_conf], [_PATH_SUDO_CONF]) +SUDO_DEFINE_PATH([$sudo_logsrvd_conf], [_PATH_SUDO_LOGSRVD_CONF]) +SUDO_DEFINE_PATH([$sudoers_path], [_PATH_SUDOERS]) + +# Convert exampledir to something that can be used in the man pages +SUDO_EXPAND_PATH([$exampledir], [EXAMPLES]) + dnl dnl Substitute into the Makefile and man pages dnl diff -r c3be19c34043 docs/Makefile.in --- a/docs/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/docs/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 2010-2015, 2017-2022 Todd C. Miller <[email protected]> +# Copyright (c) 2010-2015, 2017-2023 Todd C. Miller <[email protected]> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -47,6 +47,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ datarootdir =3D @datarootdir@ localstatedir =3D @localstatedir@ diff -r c3be19c34043 examples/Makefile.in --- a/examples/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/examples/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 2014, 2017-2022 Todd C. Miller <[email protected]> +# Copyright (c) 2014, 2017-2023 Todd C. Miller <[email protected]> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -40,6 +40,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ datarootdir =3D @datarootdir@ localstatedir =3D @localstatedir@ diff -r c3be19c34043 include/Makefile.in --- a/include/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/include/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 2011-2015, 2017-2018 Todd C. Miller <[email protected]> +# Copyright (c) 2011-2015, 2017-2023 Todd C. Miller <[email protected]> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -40,6 +40,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ datarootdir =3D @datarootdir@ localstatedir =3D @localstatedir@ diff -r c3be19c34043 include/sudo_util.h --- a/include/sudo_util.h Fri Feb 03 10:26:24 2023 -0700 +++ b/include/sudo_util.h Thu Feb 09 13:38:41 2023 -0700 @@ -305,12 +305,16 @@ sudo_dso_public unsigned int sudo_pow2_r #define SUDO_PATH_GROUP_WRITABLE -5 sudo_dso_public int sudo_secure_dir_v1(const char *path, uid_t uid, gid_t= gid, struct stat *sb); #define sudo_secure_dir(_a, _b, _c, _d) sudo_secure_dir_v1((_a), (_b), (_= c), (_d)) +sudo_dso_public int sudo_secure_fd_v1(int fd, unsigned int type, uid_t ui= d, gid_t gid, struct stat *sb); +#define sudo_secure_fd(_a, _b, _c, _d, _e) sudo_secure_fd_v1((_a), (_b), = (_c), (_d), (_e)) sudo_dso_public int sudo_secure_file_v1(const char *path, uid_t uid, gid_= t gid, struct stat *sb); #define sudo_secure_file(_a, _b, _c, _d) sudo_secure_file_v1((_a), (_b), = (_c), (_d)) sudo_dso_public int sudo_secure_open_file_v1(const char *path, uid_t uid,= gid_t gid, struct stat *sb, int *error); #define sudo_secure_open_file(_a, _b, _c, _d, _e) sudo_secure_open_file_v= 1((_a), (_b), (_c), (_d), (_e)) sudo_dso_public int sudo_secure_open_dir_v1(const char *path, uid_t uid, = gid_t gid, struct stat *sb, int *error); #define sudo_secure_open_dir(_a, _b, _c, _d, _e) sudo_secure_open_dir_v1(= (_a), (_b), (_c), (_d), (_e)) +sudo_dso_public int sudo_open_conf_path_v1(const char *path, char *name, = size_t namesize, int (*fn)(const char *, int)); +#define sudo_open_conf_path(_a, _b, _c, _d) sudo_open_conf_path_v1((_a), = (_b), (_c), (_d)) = /* setgroups.c */ sudo_dso_public int sudo_setgroups_v1(int ngids, const GETGROUPS_T *gids)= ; diff -r c3be19c34043 lib/util/Makefile.in --- a/lib/util/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/lib/util/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -37,6 +37,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ datarootdir =3D @datarootdir@ localstatedir =3D @localstatedir@ @@ -65,7 +66,7 @@ INSTALL_OWNER =3D -o $(install_uid) -g $(i INSTALL_BACKUP =3D @INSTALL_BACKUP@ = # C preprocessor defines -CPPDEFS =3D -D_PATH_SUDO_CONF=3D\"$(sysconfdir)/sudo.conf\" +CPPDEFS =3D -D_PATH_SUDO_CONF=3D\"@sudo_conf@\" = # C preprocessor flags CPPFLAGS =3D -I$(incdir) -I$(top_builddir) -I. -I$(srcdir) $(CPPDEFS) \ diff -r c3be19c34043 lib/util/secure_path.c --- a/lib/util/secure_path.c Fri Feb 03 10:26:24 2023 -0700 +++ b/lib/util/secure_path.c Thu Feb 09 13:38:41 2023 -0700 @@ -24,6 +24,7 @@ #include <config.h> = #include <sys/stat.h> +#include <errno.h> #include <fcntl.h> #include <string.h> #include <unistd.h> @@ -95,6 +96,21 @@ sudo_secure_dir_v1(const char *path, uid } = /* + * Verify that fd matches type and not writable by other users. + */ +int +sudo_secure_fd_v1(int fd, unsigned int type, uid_t uid, gid_t gid, + struct stat *sb) +{ + int ret =3D SUDO_PATH_MISSING; + debug_decl(sudo_secure_fd, SUDO_DEBUG_UTIL); + + if (fd !=3D -1 && fstat(fd, sb) =3D=3D 0) + ret =3D sudo_check_secure(sb, type, uid, gid); + debug_return_int(ret); +} + +/* * Open path read-only as long as it is not writable by other users. * Returns an open file descriptor on success, else -1. * Sets error to SUDO_PATH_SECURE on success, and a value < 0 on failure. @@ -143,3 +159,45 @@ sudo_secure_open_dir_v1(const char *path { return sudo_secure_open(path, S_IFDIR, uid, gid, sb, error); } + +/* + * Open the first file found in a colon-separated list of paths. + * Subsequent files in the path are only attempted if the + * previous file does not exist. Errors other than ENOENT are + * considered fatal and will stop processing the path. + * Sets name based on the last file it tried to open, even on error. + */ +int +sudo_open_conf_path_v1(const char *path, char *name, size_t namesize, + int (*fn)(const char *, int)) +{ + const char *cp, *ep, *path_end; + int fd =3D -1; + debug_decl(sudo_open_conf_path, SUDO_DEBUG_UTIL); + + path_end =3D path + strlen(path); + for (cp =3D sudo_strsplit(path, path_end, ":", &ep); + cp !=3D NULL; cp =3D sudo_strsplit(NULL, path_end, ":", &ep)) { + + const size_t len =3D ep - cp; + if (len >=3D namesize) { + /* We always set name, even on error. */ + memcpy(name, cp, namesize - 1); + name[namesize - 1] =3D '\0'; + errno =3D ENAMETOOLONG; + break; + } + memcpy(name, cp, len); + name[len] =3D '\0'; + + fd =3D fn ? + fn(name, O_RDONLY|O_NONBLOCK) : open(name, O_RDONLY|O_NONBLOCK); + if (fd !=3D -1) { + (void)fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); + break; + } + if (errno !=3D ENOENT) + break; + } + debug_return_int(fd); +} diff -r c3be19c34043 lib/util/sudo_conf.c --- a/lib/util/sudo_conf.c Fri Feb 03 10:26:24 2023 -0700 +++ b/lib/util/sudo_conf.c Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: ISC * - * Copyright (c) 2009-2021 Todd C. Miller <[email protected]> + * Copyright (c) 2009-2023 Todd C. Miller <[email protected]> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -629,12 +629,13 @@ sudo_conf_init(int conf_types) * Read in /etc/sudo.conf and populates sudo_conf_data. */ int -sudo_conf_read_v1(const char *conf_file, int conf_types) +sudo_conf_read_v1(const char *path, int conf_types) { FILE *fp =3D NULL; - int fd, ret =3D false; + int fd =3D -1, ret =3D false; char *prev_locale, *line =3D NULL; unsigned int conf_lineno =3D 0; + char conf_file[PATH_MAX]; size_t linesize =3D 0; debug_decl(sudo_conf_read, SUDO_DEBUG_UTIL); = @@ -651,57 +652,62 @@ sudo_conf_read_v1(const char *conf_file, if (prev_locale[0] !=3D 'C' || prev_locale[1] !=3D '\0') setlocale(LC_ALL, "C"); = -#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - if (conf_file =3D=3D NULL) { - struct stat sb; - int error; - - conf_file =3D _PATH_SUDO_CONF; - fd =3D sudo_secure_open_file(conf_file, ROOT_UID, -1, &sb, &error); - if (fd =3D=3D -1) { - switch (error) { - case SUDO_PATH_MISSING: - /* Root should always be able to read sudo.conf. */ - if (errno !=3D ENOENT && geteuid() =3D=3D ROOT_UID) - sudo_warn(U_("unable to open %s"), conf_file); - break; - case SUDO_PATH_BAD_TYPE: - sudo_warnx(U_("%s is not a regular file"), conf_file); - break; - case SUDO_PATH_WRONG_OWNER: - sudo_warnx(U_("%s is owned by uid %u, should be %u"), - conf_file, (unsigned int) sb.st_uid, ROOT_UID); - break; - case SUDO_PATH_WORLD_WRITABLE: - sudo_warnx(U_("%s is world writable"), conf_file); - break; - case SUDO_PATH_GROUP_WRITABLE: - sudo_warnx(U_("%s is group writable"), conf_file); - break; - default: - sudo_warnx("%s: internal error, unexpected error %d", - __func__, error); - break; - } + if (path !=3D NULL) { + /* Caller specified a single file, which must exist. */ + if (strlcpy(conf_file, path, sizeof(conf_file)) >=3D sizeof(conf_file)) = { + errno =3D ENAMETOOLONG; + sudo_warn("%s", path); goto done; } - } else -#else - if (conf_file =3D=3D NULL) - conf_file =3D _PATH_SUDO_CONF; -#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ - { fd =3D open(conf_file, O_RDONLY); if (fd =3D=3D -1) { sudo_warn(U_("unable to open %s"), conf_file); goto done; } + } else { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + struct stat sb; + int error; + + /* _PATH_SUDO_CONF is a colon-separated list of path. */ + fd =3D sudo_open_conf_path(_PATH_SUDO_CONF, conf_file, + sizeof(conf_file), NULL); + error =3D sudo_secure_fd(fd, S_IFREG, ROOT_UID, -1, &sb); + switch (error) { + case SUDO_PATH_SECURE: + /* OK! */ + break; + case SUDO_PATH_MISSING: + /* Root should always be able to read sudo.conf. */ + if (errno !=3D ENOENT && geteuid() =3D=3D ROOT_UID) + sudo_warn(U_("unable to open %s"), conf_file); + goto done; + case SUDO_PATH_BAD_TYPE: + sudo_warnx(U_("%s is not a regular file"), conf_file); + goto done; + case SUDO_PATH_WRONG_OWNER: + sudo_warnx(U_("%s is owned by uid %u, should be %u"), + conf_file, (unsigned int) sb.st_uid, ROOT_UID); + goto done; + case SUDO_PATH_WORLD_WRITABLE: + sudo_warnx(U_("%s is world writable"), conf_file); + goto done; + case SUDO_PATH_GROUP_WRITABLE: + sudo_warnx(U_("%s is group writable"), conf_file); + goto done; + default: + sudo_warnx("%s: internal error, unexpected error %d", + __func__, error); + goto done; + } +#else + /* No default sudo.conf when fuzzing. */ + goto done; +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } = if ((fp =3D fdopen(fd, "r")) =3D=3D NULL) { - if (errno !=3D ENOENT && geteuid() =3D=3D ROOT_UID) - sudo_warn(U_("unable to open %s"), conf_file); - close(fd); + sudo_warn(U_("unable to open %s"), conf_file); goto done; } = @@ -749,6 +755,8 @@ sudo_conf_read_v1(const char *conf_file, done: if (fp !=3D NULL) fclose(fp); + else if (fd !=3D -1) + close(fd); free(line); = /* Restore locale if needed. */ diff -r c3be19c34043 lib/util/util.exp.in --- a/lib/util/util.exp.in Fri Feb 03 10:26:24 2023 -0700 +++ b/lib/util/util.exp.in Thu Feb 09 13:38:41 2023 -0700 @@ -119,6 +119,7 @@ sudo_mmap_free_v1 sudo_mmap_protect_v1 sudo_mmap_strdup_v1 sudo_new_key_val_v1 +sudo_open_conf_path_v1 sudo_open_parent_dir_v1 sudo_parse_gids_v1 sudo_parseln_v1 @@ -130,6 +131,7 @@ sudo_rcstr_delref sudo_rcstr_dup sudo_regex_compile_v1 sudo_secure_dir_v1 +sudo_secure_fd_v1 sudo_secure_file_v1 sudo_secure_open_dir_v1 sudo_secure_open_file_v1 diff -r c3be19c34043 lib/zlib/Makefile.in --- a/lib/zlib/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/lib/zlib/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 2011-2018 Todd C. Miller <[email protected]> +# Copyright (c) 2011-2023 Todd C. Miller <[email protected]> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -35,6 +35,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ datarootdir =3D @datarootdir@ localstatedir =3D @localstatedir@ diff -r c3be19c34043 logsrvd/Makefile.in --- a/logsrvd/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/logsrvd/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 2019-2021 Todd C. Miller <[email protected]> +# Copyright (c) 2019-2023 Todd C. Miller <[email protected]> # # 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 @@ LT_LIBS =3D $(top_builddir)/lib/iolog/libs LIBS =3D $(LT_LIBS) @LIBTLS@ = # C preprocessor defines -CPPDEFS =3D -D_PATH_SUDO_LOGSRVD_CONF=3D\"$(sysconfdir)/sudo_logsrvd.conf= \" \ +CPPDEFS =3D -D_PATH_SUDO_LOGSRVD_CONF=3D\"@sudo_logsrvd_conf@\" \ -DLOCALEDIR=3D\"$(localedir)\" = # C preprocessor flags @@ -98,6 +98,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ datarootdir =3D @datarootdir@ localedir =3D @localedir@ diff -r c3be19c34043 logsrvd/logsrvd.c --- a/logsrvd/logsrvd.c Fri Feb 03 10:26:24 2023 -0700 +++ b/logsrvd/logsrvd.c Thu Feb 09 13:38:41 2023 -0700 @@ -85,7 +85,7 @@ TAILQ_HEAD(connection_list, connection_c static struct connection_list connections =3D TAILQ_HEAD_INITIALIZER(conn= ections); static struct listener_list listeners =3D TAILQ_HEAD_INITIALIZER(listener= s); static const char server_id[] =3D "Sudo Audit Server " PACKAGE_VERSION; -static const char *conf_file =3D _PATH_SUDO_LOGSRVD_CONF; +static const char *conf_file =3D NULL; = /* Event loop callbacks. */ static void client_msg_cb(int fd, int what, void *v); @@ -1663,7 +1663,8 @@ server_dump_stats(void) debug_decl(server_dump_stats, SUDO_DEBUG_UTIL); = sudo_debug_printf(SUDO_DEBUG_INFO, "%s", server_id); - sudo_debug_printf(SUDO_DEBUG_INFO, "configuration file: %s", conf_fil= e); + sudo_debug_printf(SUDO_DEBUG_INFO, "configuration file: %s", + conf_file ? conf_file : _PATH_SUDO_LOGSRVD_CONF); = sudo_debug_printf(SUDO_DEBUG_INFO, "listen addresses:"); n =3D 0; diff -r c3be19c34043 logsrvd/logsrvd_conf.c --- a/logsrvd/logsrvd_conf.c Fri Feb 03 10:26:24 2023 -0700 +++ b/logsrvd/logsrvd_conf.c Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: ISC * - * Copyright (c) 2019-2022 Todd C. Miller <[email protected]> + * Copyright (c) 2019-2023 Todd C. Miller <[email protected]> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -1854,25 +1854,39 @@ logsrvd_conf_apply(struct logsrvd_config = /* * Read .ini style logsrvd.conf file. + * If path is NULL, use _PATH_SUDO_LOGSRVD_CONF. * Note that we use '#' not ';' for the comment character. */ bool logsrvd_conf_read(const char *path) { struct logsrvd_config *config; + char conf_file[PATH_MAX]; bool ret =3D false; FILE *fp =3D NULL; + int fd =3D -1; debug_decl(logsrvd_conf_read, SUDO_DEBUG_UTIL); = config =3D logsrvd_conf_alloc(); = - if ((fp =3D fopen(path, "r")) =3D=3D NULL) { - if (errno !=3D ENOENT) { - sudo_warn("%s", path); + if (path !=3D NULL) { + if (strlcpy(conf_file, path, sizeof(conf_file)) >=3D sizeof(conf_f= ile)) + errno =3D ENAMETOOLONG; + else + fd =3D open(conf_file, O_RDONLY); + } else { + fd =3D sudo_open_conf_path(_PATH_SUDO_LOGSRVD_CONF, conf_file, + sizeof(conf_file), NULL); + } + if (fd !=3D -1) + fp =3D fdopen(fd, "r"); + if (fp =3D=3D NULL) { + if (path !=3D NULL || errno !=3D ENOENT) { + sudo_warn("%s", conf_file); goto done; } } else { - if (!logsrvd_conf_parse(config, fp, path)) + if (!logsrvd_conf_parse(config, fp, conf_file)) goto done; } = diff -r c3be19c34043 m4/sudo.m4 --- a/m4/sudo.m4 Fri Feb 03 10:26:24 2023 -0700 +++ b/m4/sudo.m4 Thu Feb 09 13:38:41 2023 -0700 @@ -556,7 +556,6 @@ AC_DEFUN([SUDO_APPEND_COMPAT_EXP], [ ]) = dnl -dnl dnl Append one or more symbols to INTERCEPT_EXP dnl AC_DEFUN([SUDO_APPEND_INTERCEPT_EXP], [ @@ -680,3 +679,47 @@ m4_define([SUDO_DEFINE_UNQUOTED], [@%:@define] $1 m4_if($#, 2, [$2], $#, 3, [$2], 1) EOF ]) + +dnl +dnl Expand Makefile-style variables in $1 and store the result in $2. +dnl Used to expand file paths for use in man pages and pathnames.h. +dnl +AC_DEFUN([SUDO_EXPAND_PATH], [ + $2=3D"$1" + while :; do + $2=3D"`echo \"$$2\" | sed -e 's/(/{/g' -e 's/)/}/g'`" + case "$$2" in + *\${[[A-Za-z]]*}*) + eval $2=3D"$$2" + ;; + *) + break + ;; + esac +done +case "$$2" in + NONE/*) + $2=3D"${ac_default_prefix}${$2#NONE}" + ;; +esac +]) + +dnl +dnl Expand Makefile-style variables in $1, a colon-separated list of path= s, +dnl and define the result as a string using the name $2. +dnl +AC_DEFUN([SUDO_DEFINE_PATH], [ + as_save_IFS=3D$IFS + IFS=3D: + _sudo_define_path_res=3D + for as_dir in $1; do + SUDO_EXPAND_PATH([$as_dir], [_sudo_define_path_exp]) + if test -z "${_sudo_define_path_res}"; then + _sudo_define_path_res=3D"${_sudo_define_path_exp}" + else + _sudo_define_path_res=3D"${_sudo_define_path_res}:${_sudo_define_pat= h_exp}" + fi + done + IFS=3D$as_save_IFS + SUDO_DEFINE_UNQUOTED($2, "${_sudo_define_path_res}") +]) diff -r c3be19c34043 pathnames.h.in --- a/pathnames.h.in Fri Feb 03 10:26:24 2023 -0700 +++ b/pathnames.h.in Thu Feb 09 13:38:41 2023 -0700 @@ -58,38 +58,38 @@ #endif /* _PATH_ENVIRONMENT */ = /* + * The following paths are controlled via the configure script. + */ + +/* * NOTE: _PATH_SUDO_CONF is usually overridden by the Makefile. */ #ifndef _PATH_SUDO_CONF -# define _PATH_SUDO_CONF "/etc/sudo.conf" +# undef _PATH_SUDO_CONF #endif /* _PATH_SUDO_CONF */ = /* * NOTE: _PATH_SUDOERS is usually overridden by the Makefile. */ #ifndef _PATH_SUDOERS -# define _PATH_SUDOERS "/etc/sudoers" +# undef _PATH_SUDOERS #endif /* _PATH_SUDOERS */ = /* * NOTE: _PATH_CVTSUDOERS_CONF is usually overridden by the Makefile. */ #ifndef _PATH_CVTSUDOERS_CONF -# define _PATH_CVTSUDOERS_CONF "/etc/cvtsudoers.conf" +# undef _PATH_CVTSUDOERS_CONF #endif /* _PATH_CVTSUDOERS_CONF */ = /* * NOTE: _PATH_SUDO_LOGSRVD_CONF is usually overridden by the Makefile. */ #ifndef _PATH_SUDO_LOGSRVD_CONF -# define _PATH_SUDO_LOGSRVD_CONF "/etc/sudo_logsrvd.conf" +# undef _PATH_SUDO_LOGSRVD_CONF #endif /* _PATH_SUDO_LOGSRVD_CONF */ = /* - * The following paths are controlled via the configure script. - */ - -/* * Where sudo_logsrvd stores its pid file files. Defaults to * /var/run/sudo/sudo_logsrvd.pid, /var/db/sudo/sudo_logsrvd.pid, * /var/lib/sudo/sudo_logsrvd.pid, /var/adm/sudo/sudo_logsrvd.pid or diff -r c3be19c34043 plugins/audit_json/Makefile.in --- a/plugins/audit_json/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/audit_json/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 2020 Todd C. Miller <[email protected]> +# Copyright (c) 2020-2023 Todd C. Miller <[email protected]> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -86,6 +86,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ datarootdir =3D @datarootdir@ localstatedir =3D @localstatedir@ diff -r c3be19c34043 plugins/group_file/Makefile.in --- a/plugins/group_file/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/group_file/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 2010-2018 Todd C. Miller <[email protected]> +# Copyright (c) 2010-2023 Todd C. Miller <[email protected]> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -88,6 +88,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ datarootdir =3D @datarootdir@ localstatedir =3D @localstatedir@ diff -r c3be19c34043 plugins/python/Makefile.in --- a/plugins/python/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/python/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 2019-2020 Todd C. Miller <[email protected]> +# Copyright (c) 2019-2023 Todd C. Miller <[email protected]> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -93,6 +93,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ datarootdir =3D @datarootdir@ localstatedir =3D @localstatedir@ diff -r c3be19c34043 plugins/sample/Makefile.in --- a/plugins/sample/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/sample/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 2011-2022 Todd C. Miller <[email protected]> +# Copyright (c) 2011-2023 Todd C. Miller <[email protected]> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -87,6 +87,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ datarootdir =3D @datarootdir@ localstatedir =3D @localstatedir@ diff -r c3be19c34043 plugins/sample_approval/Makefile.in --- a/plugins/sample_approval/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/sample_approval/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 2020 Todd C. Miller <[email protected]> +# Copyright (c) 2020-2023 Todd C. Miller <[email protected]> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -86,6 +86,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ datarootdir =3D @datarootdir@ localstatedir =3D @localstatedir@ diff -r c3be19c34043 plugins/sudoers/Makefile.in --- a/plugins/sudoers/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/sudoers/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 1996, 1998-2005, 2007-2022 +# Copyright (c) 1996, 1998-2005, 2007-2023 # Todd C. Miller <[email protected]> # # Permission to use, copy, modify, and distribute this software for any @@ -72,8 +72,8 @@ TESTSUDOERS_LIBS =3D $(NET_LIBS) = # C preprocessor defines CPPDEFS =3D -DLIBDIR=3D\"$(libdir)\" -DLOCALEDIR=3D\"$(localedir)\" \ - -D_PATH_SUDOERS=3D\"$(sysconfdir)/sudoers\" \ - -D_PATH_CVTSUDOERS_CONF=3D\"$(sysconfdir)/cvtsudoers.conf\" \ + -D_PATH_SUDOERS=3D\"@sudoers_path@\" \ + -D_PATH_CVTSUDOERS_CONF=3D\"@cvtsudoers_conf@\" \ -DSUDOERS_UID=3D$(sudoers_uid) -DSUDOERS_GID=3D$(sudoers_gid) \ -DSUDOERS_MODE=3D$(sudoers_mode) = @@ -120,6 +120,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ datarootdir =3D @datarootdir@ localedir =3D @localedir@ diff -r c3be19c34043 plugins/sudoers/cvtsudoers.c --- a/plugins/sudoers/cvtsudoers.c Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/sudoers/cvtsudoers.c Thu Feb 09 13:38:41 2023 -0700 @@ -35,6 +35,7 @@ #endif /* HAVE_STRINGS_H */ #include <ctype.h> #include <errno.h> +#include <fcntl.h> #include <pwd.h> #include <unistd.h> #ifdef HAVE_GETOPT_LONG @@ -112,7 +113,7 @@ main(int argc, char *argv[]) enum sudoers_formats input_format =3D format_sudoers; const char *input_file =3D "-"; const char *output_file =3D "-"; - const char *conf_file =3D _PATH_CVTSUDOERS_CONF; + const char *conf_file =3D NULL; const char *grfile =3D NULL, *pwfile =3D NULL; const char *cp, *errstr; int ch, exitcode =3D EXIT_FAILURE; @@ -548,36 +549,56 @@ cvtsudoers_parse_keyword(const char *con } = static struct cvtsudoers_config * -cvtsudoers_conf_read(const char *conf_file) +cvtsudoers_conf_read(const char *path) { - char *line =3D NULL; + char conf_file[PATH_MAX], *line =3D NULL; size_t linesize =3D 0; - FILE *fp; + FILE *fp =3D NULL; + int fd =3D -1; debug_decl(cvtsudoers_conf_read, SUDOERS_DEBUG_UTIL); = - if ((fp =3D fopen(conf_file, "r")) =3D=3D NULL) + if (path !=3D NULL) { + /* Empty string means use the defaults. */ + if (*path =3D=3D '\0') + debug_return_ptr(&cvtsudoers_config); + if (strlcpy(conf_file, path, sizeof(conf_file)) >=3D sizeof(conf_file)) + errno =3D ENAMETOOLONG; + else = + fd =3D open(conf_file, O_RDONLY); + } else { + fd =3D sudo_open_conf_path(_PATH_CVTSUDOERS_CONF, conf_file, + sizeof(conf_file), NULL); + } + if (fd !=3D -1) + fp =3D fdopen(fd, "r"); + if (fp =3D=3D NULL) { + if (path !=3D NULL || errno !=3D ENOENT) + sudo_warn("%s", conf_file); debug_return_ptr(&cvtsudoers_config); + } = while (sudo_parseln(&line, &linesize, NULL, fp, 0) !=3D -1) { - char *cp, *keyword, *value; + char *keyword, *value; + size_t len; = if (*line =3D=3D '\0') continue; /* skip empty line */ = /* Parse keyword =3D value */ keyword =3D line; - if ((cp =3D strchr(line, '=3D')) =3D=3D NULL) + if ((value =3D strchr(line, '=3D')) =3D=3D NULL || value =3D=3D line) continue; - value =3D cp-- + 1; + len =3D value - line; = - /* Trim whitespace after keyword. */ - while (cp !=3D line && isblank((unsigned char)cp[-1])) - cp--; - *cp =3D '\0'; + /* Trim whitespace after keyword and NUL-terminate. */ + while (len > 0 && isblank((unsigned char)line[len - 1])) + len--; + line[len] =3D '\0'; = /* Trim whitespace before value. */ - while (isblank((unsigned char)*value)) + do { value++; + } while (isblank((unsigned char)*value)); = /* Look up keyword in config tables */ if (!cvtsudoers_parse_keyword(conf_file, keyword, value, cvtsudoers_conf= _vars)) @@ -758,7 +779,7 @@ parse_sudoers(const char *input_file, st } = FILE * -open_sudoers(const char *file, bool doedit, bool *keepopen) +open_sudoers(const char *file, char **outfile, bool doedit, bool *keepope= n) { return fopen(file, "r"); } diff -r c3be19c34043 plugins/sudoers/file.c --- a/plugins/sudoers/file.c Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/sudoers/file.c Thu Feb 09 13:38:41 2023 -0700 @@ -59,6 +59,7 @@ sudo_file_open(struct sudo_nss *nss) { debug_decl(sudo_file_open, SUDOERS_DEBUG_NSS); struct sudo_file_handle *handle; + char *outfile; = /* Note: relies on defaults being initialized early. */ if (def_ignore_local_sudoers) @@ -72,9 +73,11 @@ sudo_file_open(struct sudo_nss *nss) = handle =3D malloc(sizeof(*handle)); if (handle !=3D NULL) { - handle->fp =3D open_sudoers(sudoers_file, false, NULL); + handle->fp =3D open_sudoers(sudoers_file, &outfile, false, NULL); if (handle->fp !=3D NULL) { init_parse_tree(&handle->parse_tree, NULL, NULL); + sudo_rcstr_delref(sudoers); + sudoers =3D outfile; } else { free(handle); handle =3D NULL; diff -r c3be19c34043 plugins/sudoers/regress/fuzz/fuzz_sudoers.c --- a/plugins/sudoers/regress/fuzz/fuzz_sudoers.c Fri Feb 03 10:26:24 2023= -0700 +++ b/plugins/sudoers/regress/fuzz/fuzz_sudoers.c Thu Feb 09 13:38:41 2023= -0700 @@ -54,7 +54,7 @@ bool sudoers_recovery =3D true; int sudo_mode; = FILE * -open_sudoers(const char *file, bool doedit, bool *keepopen) +open_sudoers(const char *file, char **outfile, bool doedit, bool *keepope= n) { /* * If we allow the fuzzer to choose include paths it will diff -r c3be19c34043 plugins/sudoers/regress/fuzz/fuzz_sudoers_ldif.c --- a/plugins/sudoers/regress/fuzz/fuzz_sudoers_ldif.c Fri Feb 03 10:26:24= 2023 -0700 +++ b/plugins/sudoers/regress/fuzz/fuzz_sudoers_ldif.c Thu Feb 09 13:38:41= 2023 -0700 @@ -37,7 +37,7 @@ struct passwd *list_pw; sudo_printf_t sudo_printf =3D fuzz_printf; = FILE * -open_sudoers(const char *file, bool doedit, bool *keepopen) +open_sudoers(const char *file, char **outfile, bool doedit, bool *keepope= n) { /* * If we allow the fuzzer to choose include paths it will diff -r c3be19c34043 plugins/sudoers/sudoers.c --- a/plugins/sudoers/sudoers.c Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/sudoers/sudoers.c Thu Feb 09 13:38:41 2023 -0700 @@ -249,7 +249,7 @@ sudoers_init(void *info, sudoers_logger_ } = /* Open and parse sudoers, set global defaults. */ - init_parser(sudoers_file, false, false); + init_parser(NULL, false, false); TAILQ_FOREACH_SAFE(nss, snl, entries, nss_next) { if (nss->open(nss) =3D=3D -1 || (nss->parse_tree =3D nss->parse(nss)) =3D= =3D NULL) { TAILQ_REMOVE(snl, nss, entries); @@ -1126,91 +1126,109 @@ set_cmnd(void) debug_return_int(ret); } = +static int +open_file(const char *path, int flags) +{ + int fd; + debug_decl(open_file, SUDOERS_DEBUG_PLUGIN); + + if (!set_perms(PERM_SUDOERS)) + debug_return_int(-1); + + fd =3D open(path, flags); + if (fd =3D=3D -1 && errno =3D=3D EACCES && geteuid() !=3D ROOT_UID) { + /* + * If we tried to open sudoers as non-root but got EACCES, + * try again as root. + */ + int serrno =3D errno; + if (restore_perms() && set_perms(PERM_ROOT)) + fd =3D open(path, flags); + errno =3D serrno; + } + if (!restore_perms()) { + /* unable to change back to root */ + if (fd !=3D -1) { + close(fd); + fd =3D -1; + } + } + + debug_return_int(fd); +} + /* * Open sudoers file and check mode/owner/type. * Returns a handle to the sudoers file or NULL on error. */ FILE * -open_sudoers(const char *file, bool doedit, bool *keepopen) +open_sudoers(const char *path, char **outfile, bool doedit, bool *keepope= n) { + char fname[PATH_MAX]; FILE *fp =3D NULL; struct stat sb; int error, fd; debug_decl(open_sudoers, SUDOERS_DEBUG_PLUGIN); = - if (!set_perms(PERM_SUDOERS)) - debug_return_ptr(NULL); - -again: - fd =3D sudo_secure_open_file(file, sudoers_uid, sudoers_gid, &sb, &er= ror); - if (fd !=3D -1) { + fd =3D sudo_open_conf_path(path, fname, sizeof(fname), open_file); + error =3D sudo_secure_fd(fd, S_IFREG, sudoers_uid, sudoers_gid, &sb); + switch (error) { + case SUDO_PATH_SECURE: /* * Make sure we can read the file so we can present the * user with a reasonable error message (unlike the lexer). */ if ((fp =3D fdopen(fd, "r")) =3D=3D NULL) { - log_warning(SLOG_SEND_MAIL, N_("unable to open %s"), file); + log_warning(SLOG_SEND_MAIL, N_("unable to open %s"), fname); close(fd); } else { if (sb.st_size !=3D 0 && fgetc(fp) =3D=3D EOF) { log_warning(SLOG_SEND_MAIL, - N_("unable to read %s"), file); + N_("unable to read %s"), fname); fclose(fp); fp =3D NULL; } else { /* Rewind fp and set close on exec flag. */ rewind(fp); (void) fcntl(fileno(fp), F_SETFD, 1); + if (outfile !=3D NULL) { + *outfile =3D sudo_rcstr_dup(fname); + if (*outfile =3D=3D NULL) { + sudo_warnx(U_("%s: %s"), __func__, + U_("unable to allocate memory")); + fclose(fp); + fp =3D NULL; + } + } } } - } else { - switch (error) { - case SUDO_PATH_MISSING: - /* - * If we tried to open sudoers as non-root but got EACCES, - * try again as root. - */ - if (errno =3D=3D EACCES && geteuid() !=3D ROOT_UID) { - int serrno =3D errno; - if (restore_perms()) { - if (!set_perms(PERM_ROOT)) - debug_return_ptr(NULL); - goto again; - } - errno =3D serrno; - } - log_warning(SLOG_SEND_MAIL, N_("unable to open %s"), file); - break; - case SUDO_PATH_BAD_TYPE: - log_warningx(SLOG_SEND_MAIL, - N_("%s is not a regular file"), file); - break; - case SUDO_PATH_WRONG_OWNER: - log_warningx(SLOG_SEND_MAIL, - N_("%s is owned by uid %u, should be %u"), file, - (unsigned int) sb.st_uid, (unsigned int) sudoers_uid); - break; - case SUDO_PATH_WORLD_WRITABLE: - log_warningx(SLOG_SEND_MAIL, N_("%s is world writable"), file); - break; - case SUDO_PATH_GROUP_WRITABLE: - log_warningx(SLOG_SEND_MAIL, - N_("%s is owned by gid %u, should be %u"), file, - (unsigned int) sb.st_gid, (unsigned int) sudoers_gid); - break; - default: - sudo_warnx("%s: internal error, unexpected error %d", - __func__, error); - break; - } - } - - if (!restore_perms()) { - /* unable to change back to root */ - if (fp !=3D NULL) { - fclose(fp); - fp =3D NULL; - } + break; + case SUDO_PATH_MISSING: + log_warning(SLOG_SEND_MAIL, N_("unable to open %s"), path); + if (fd !=3D -1) + close(fd); + break; + case SUDO_PATH_BAD_TYPE: + log_warningx(SLOG_SEND_MAIL, + N_("%s is not a regular file"), fname); + break; + case SUDO_PATH_WRONG_OWNER: + log_warningx(SLOG_SEND_MAIL, + N_("%s is owned by uid %u, should be %u"), fname, + (unsigned int) sb.st_uid, (unsigned int) sudoers_uid); + break; + case SUDO_PATH_WORLD_WRITABLE: + log_warningx(SLOG_SEND_MAIL, N_("%s is world writable"), fname); + break; + case SUDO_PATH_GROUP_WRITABLE: + log_warningx(SLOG_SEND_MAIL, + N_("%s is owned by gid %u, should be %u"), fname, + (unsigned int) sb.st_gid, (unsigned int) sudoers_gid); + break; + default: + sudo_warnx("%s: internal error, unexpected error %d", + __func__, error); + break; } = debug_return_ptr(fp); diff -r c3be19c34043 plugins/sudoers/sudoers.h --- a/plugins/sudoers/sudoers.h Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/sudoers/sudoers.h Thu Feb 09 13:38:41 2023 -0700 @@ -421,7 +421,7 @@ void register_env_file(void * (*ef_open) bool matches_env_pattern(const char *pattern, const char *var, bool *full= _match); = /* sudoers.c */ -FILE *open_sudoers(const char *, bool, bool *); +FILE *open_sudoers(const char *, char **, bool, bool *); bool cb_log_input(const char *file, int line, int column, const union sud= o_defs_val *sd_un, int op); bool cb_log_output(const char *file, int line, int column, const union su= do_defs_val *sd_un, int op); int set_cmnd_path(const char *runchroot); diff -r c3be19c34043 plugins/sudoers/testsudoers.c --- a/plugins/sudoers/testsudoers.c Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/sudoers/testsudoers.c Thu Feb 09 13:38:41 2023 -0700 @@ -437,7 +437,7 @@ sudo_endspent(void) } = FILE * -open_sudoers(const char *file, bool doedit, bool *keepopen) +open_sudoers(const char *file, char **outfile, bool doedit, bool *keepope= n) { struct stat sb; FILE *fp =3D NULL; diff -r c3be19c34043 plugins/sudoers/toke.c --- a/plugins/sudoers/toke.c Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/sudoers/toke.c Thu Feb 09 13:38:41 2023 -0700 @@ -5841,9 +5841,9 @@ push_include(const char *opath, bool isd SLIST_REMOVE_HEAD(&istack[idepth].more, entries); path =3D pl->path; free(pl); - } while ((fp =3D open_sudoers(path, false, &keepopen)) =3D=3D NULL); + } while ((fp =3D open_sudoers(path, NULL, false, &keepopen)) =3D=3D NULL= ); } else { - if ((fp =3D open_sudoers(path, true, &keepopen)) =3D=3D NULL) { + if ((fp =3D open_sudoers(path, NULL, true, &keepopen)) =3D=3D NULL) { /* The error was already printed by open_sudoers() */ sudoerserror(NULL); sudo_rcstr_delref(path); @@ -5886,7 +5886,7 @@ pop_include(void) /* If we are in an include dir, move to the next file. */ while ((pl =3D SLIST_FIRST(&istack[idepth - 1].more)) !=3D NULL) { SLIST_REMOVE_HEAD(&istack[idepth - 1].more, entries); - fp =3D open_sudoers(pl->path, false, &keepopen); + fp =3D open_sudoers(pl->path, NULL, false, &keepopen); if (fp !=3D NULL) { sudolinebuf.len =3D sudolinebuf.off =3D 0; sudolinebuf.toke_start =3D sudolinebuf.toke_end =3D 0; diff -r c3be19c34043 plugins/sudoers/toke.l --- a/plugins/sudoers/toke.l Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/sudoers/toke.l Thu Feb 09 13:38:41 2023 -0700 @@ -1288,9 +1288,9 @@ push_include(const char *opath, bool isd SLIST_REMOVE_HEAD(&istack[idepth].more, entries); path =3D pl->path; free(pl); - } while ((fp =3D open_sudoers(path, false, &keepopen)) =3D=3D NULL); + } while ((fp =3D open_sudoers(path, NULL, false, &keepopen)) =3D=3D NULL= ); } else { - if ((fp =3D open_sudoers(path, true, &keepopen)) =3D=3D NULL) { + if ((fp =3D open_sudoers(path, NULL, true, &keepopen)) =3D=3D NULL) { /* The error was already printed by open_sudoers() */ sudoerserror(NULL); sudo_rcstr_delref(path); @@ -1333,7 +1333,7 @@ pop_include(void) /* If we are in an include dir, move to the next file. */ while ((pl =3D SLIST_FIRST(&istack[idepth - 1].more)) !=3D NULL) { SLIST_REMOVE_HEAD(&istack[idepth - 1].more, entries); - fp =3D open_sudoers(pl->path, false, &keepopen); + fp =3D open_sudoers(pl->path, NULL, false, &keepopen); if (fp !=3D NULL) { sudolinebuf.len =3D sudolinebuf.off =3D 0; sudolinebuf.toke_start =3D sudolinebuf.toke_end =3D 0; diff -r c3be19c34043 plugins/sudoers/visudo.c --- a/plugins/sudoers/visudo.c Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/sudoers/visudo.c Thu Feb 09 13:38:41 2023 -0700 @@ -250,10 +250,18 @@ main(int argc, char *argv[]) = if (export_path !=3D NULL) { /* Backward compatibility for the time being. */ + char pathbuf[PATH_MAX]; + int fd; sudo_warnx("%s", U_("the -x option will be removed in a future release")); sudo_warnx("%s", U_("please consider using the cvtsudoers utility instead")); + /* Export the first sudoers file that exists in the path. */ + fd =3D sudo_open_conf_path(sudoers_file, pathbuf, sizeof(pathbuf), NULL)= ; + if (fd !=3D -1) { + close(fd); + sudoers_file =3D pathbuf; + } execlp("cvtsudoers", "cvtsudoers", "-f", "json", "-o", export_path, sudoers_file, (char *)0); sudo_fatal(U_("unable to execute %s"), "cvtsudoers"); @@ -289,9 +297,9 @@ main(int argc, char *argv[]) * Parse the existing sudoers file(s) to highlight any existing * errors and to pull in editor and env_editor conf values. */ - if ((sudoersin =3D open_sudoers(sudoers_file, true, NULL)) =3D=3D NUL= L) + init_parser(NULL, quiet, true); + if ((sudoersin =3D open_sudoers(sudoers_file, &sudoers, true, NULL)) = =3D=3D NULL) exit(EXIT_FAILURE); - init_parser(sudoers_file, quiet, true); sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale); (void) sudoersparse(); (void) update_defaults(&parsed_policy, NULL, @@ -960,26 +968,30 @@ check_file(const char *path, bool quiet, } = static bool -check_syntax(const char *file, bool quiet, bool strict, bool check_owner, +check_syntax(const char *path, bool quiet, bool strict, bool check_owner, bool check_mode) { bool ok =3D false; - int oldlocale; + int fd, oldlocale; + char fname[PATH_MAX]; debug_decl(check_syntax, SUDOERS_DEBUG_UTIL); = - if (strcmp(file, "-") =3D=3D 0) { + if (strcmp(path, "-") =3D=3D 0) { sudoersin =3D stdin; - file =3D "stdin"; - } else if ((sudoersin =3D fopen(file, "r")) =3D=3D NULL) { - if (!quiet) - sudo_warn(U_("unable to open %s"), file); - goto done; + (void)strlcpy(fname, "stdin", sizeof(fname)); + } else { + fd =3D sudo_open_conf_path(path, fname, sizeof(fname), NULL); + if (fd =3D=3D -1 || (sudoersin =3D fdopen(fd, "r")) =3D=3D NULL) { + if (!quiet) + sudo_warn(U_("unable to open %s"), fname); + goto done; + } } - init_parser(file, quiet, true); + init_parser(fname, quiet, true); sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale); if (sudoersparse() && !parse_error) { if (!quiet) - sudo_warnx(U_("failed to parse %s file, unknown error"), file); + sudo_warnx(U_("failed to parse %s file, unknown error"), fname); parse_error =3D true; } if (!parse_error) { @@ -994,9 +1006,9 @@ check_syntax(const char *file, bool quie struct sudoersfile *sp; = /* Parsed OK, check mode and owner. */ - if (check_file(file, quiet, check_owner, check_mode)) { + if (check_file(fname, quiet, check_owner, check_mode)) { if (!quiet) - (void) printf(_("%s: parsed OK\n"), file); + (void) printf(_("%s: parsed OK\n"), fname); } else { ok =3D false; } @@ -1041,24 +1053,45 @@ lock_sudoers(struct sudoersfile *entry) static struct sudoersfile * new_sudoers(const char *path, bool doedit) { + const char *cp, *ep, *path_end; struct sudoersfile *entry; struct stat sb; - int open_flags; + size_t len; + int fd =3D -1; debug_decl(new_sudoersfile, SUDOERS_DEBUG_UTIL); = - if (checkonly) - open_flags =3D O_RDONLY; - else - open_flags =3D O_RDWR | O_CREAT; + /* Open the first file found in the colon-separated path. */ + path_end =3D path + strlen(path); + for (cp =3D sudo_strsplit(path, path_end, ":", &ep); + cp !=3D NULL; cp =3D sudo_strsplit(NULL, path_end, ":", &ep)) { = + char fname[PATH_MAX]; + len =3D ep - cp; + if (len >=3D sizeof(fname)) { + errno =3D ENAMETOOLONG; + break; + } + memcpy(fname, cp, len); + fname[len] =3D '\0'; + + /* Open in write mode for file locking. */ + fd =3D open(fname, checkonly ? O_RDONLY : O_RDWR); + if (fd !=3D -1 || errno !=3D ENOENT) + break; + } + + /* If more than one file is specified, we always write to the first o= ne. */ + len =3D strcspn(path, ":"); entry =3D calloc(1, sizeof(*entry)); - if (entry =3D=3D NULL || (entry->path =3D strdup(path)) =3D=3D NULL) + if (entry =3D=3D NULL || (entry->path =3D strndup(path, len)) =3D=3D = NULL) sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - /* entry->tpath =3D NULL; */ - /* entry->modified =3D false; */ - entry->doedit =3D doedit; - entry->fd =3D open(entry->path, open_flags, sudoers_mode); - if (entry->fd =3D=3D -1 || fstat(entry->fd, &sb) =3D=3D -1) { + if (fd =3D=3D -1 && errno =3D=3D ENOENT) { + if (!checkonly) { + /* Create the first file in the path. */ + fd =3D open(entry->path, O_RDWR|O_CREAT, sudoers_mode); + } + } + if (fd =3D=3D -1 || fstat(fd, &sb) =3D=3D -1) { sudo_warn("%s", entry->path); goto bad; } @@ -1066,14 +1099,20 @@ new_sudoers(const char *path, bool doedi sudo_warnx(U_("%s is not a regular file"), entry->path); goto bad; } + entry->fd =3D fd; + /* entry->tpath =3D NULL; */ + /* entry->modified =3D false; */ + entry->doedit =3D doedit; if (!checkonly && !lock_sudoers(entry)) goto bad; debug_return_ptr(entry); bad: - if (entry->fd !=3D -1) - close(entry->fd); - free(entry->path); - free(entry); + if (fd !=3D -1) + close(fd); + if (entry !=3D NULL) { + free(entry->path); + free(entry); + } debug_return_ptr(NULL); } = @@ -1082,21 +1121,24 @@ bad: * any subsequent files #included via a callback from the parser. */ FILE * -open_sudoers(const char *path, bool doedit, bool *keepopen) +open_sudoers(const char *path, char **outfile, bool doedit, bool *keepope= n) { struct sudoersfile *entry; + size_t len; FILE *fp; debug_decl(open_sudoers, SUDOERS_DEBUG_UTIL); = - /* Check for existing entry */ + /* Check for existing entry using the first file in path. */ + len =3D strcspn(path, ":"); TAILQ_FOREACH(entry, &sudoerslist, entries) { - if (strcmp(path, entry->path) =3D=3D 0) + if (strncmp(path, entry->path, len) =3D=3D 0 && entry->path[len] =3D=3D = '\0') break; } if (entry =3D=3D NULL) { if (doedit && !edit_includes) { /* Only edit the main sudoers file. */ - if (strcmp(path, sudoers_file) !=3D 0) + if (strncmp(path, sudoers_file, len) !=3D 0 || + (sudoers_file[len] !=3D '\0' && sudoers_file[len] !=3D ':')) doedit =3D false; } if ((entry =3D new_sudoers(path, doedit)) =3D=3D NULL) @@ -1117,6 +1159,12 @@ open_sudoers(const char *path, bool doed } if (keepopen !=3D NULL) *keepopen =3D true; + if (outfile !=3D NULL) { + /* XXX - if path is a list, entry->path may not exist yet. */ + *outfile =3D sudo_rcstr_dup(entry->path); + if (*outfile =3D=3D NULL) + sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"))= ; + } debug_return_ptr(fp); } = diff -r c3be19c34043 plugins/system_group/Makefile.in --- a/plugins/system_group/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/plugins/system_group/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 2011-2018 Todd C. Miller <[email protected]> +# Copyright (c) 2011-2023 Todd C. Miller <[email protected]> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -88,6 +88,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ datarootdir =3D @datarootdir@ localstatedir =3D @localstatedir@ diff -r c3be19c34043 src/Makefile.in --- a/src/Makefile.in Fri Feb 03 10:26:24 2023 -0700 +++ b/src/Makefile.in Thu Feb 09 13:38:41 2023 -0700 @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 2010-2022 Todd C. Miller <[email protected]> +# Copyright (c) 2010-2023 Todd C. Miller <[email protected]> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -50,7 +50,7 @@ LT_LIBS =3D $(top_builddir)/lib/util/libsu LIBS =3D @LIBS@ @SUDO_LIBS@ @GETGROUPS_LIB@ @NET_LIBS@ $(LT_LIBS) = # C preprocessor defines -CPPDEFS =3D -D_PATH_SUDO_CONF=3D\"$(sysconfdir)/sudo.conf\" \ +CPPDEFS =3D -D_PATH_SUDO_CONF=3D\"@sudo_conf@\" \ -DLOCALEDIR=3D\"$(localedir)\" = # C preprocessor flags @@ -101,6 +101,7 @@ exec_prefix =3D @exec_prefix@ bindir =3D @bindir@ sbindir =3D @sbindir@ sysconfdir =3D @sysconfdir@ +distconfdir =3D @distconfdir@ libexecdir =3D @libexecdir@ datarootdir =3D @datarootdir@ localedir =3D @localedir@ ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ____________________________________________________________ sudo-workers mailing list <[email protected]> For list information, options, or to unsubscribe, visit: https://www.sudo.ws/mailman/listinfo/sudo-workers ------- =_aaaaaaaaaa0--