Replace built-in non-unix group support with a sudoers group plugin.
Include a sample plugin that can read Unix-format group files.
This commit is contained in:
10
INSTALL
10
INSTALL
@@ -340,16 +340,6 @@ Special features/options:
|
||||
Enable support for role based access control (RBAC) on
|
||||
systems that support SELinux.
|
||||
|
||||
--with-libvas=[NAME]
|
||||
Enable non-Unix group support using Quest Authentication
|
||||
Services. If NAME is specified, it should be the name of
|
||||
the shared library providing QAS support (libvas.so by default).
|
||||
|
||||
--with-libvas-rpath=[PATH]
|
||||
The path to search when loading libvas.so (or an alternate
|
||||
name as specified by --with-libvas). This option only has
|
||||
an effect when --with-libvas is specified.
|
||||
|
||||
The following options are also configurable at runtime:
|
||||
|
||||
--with-long-otp-prompt
|
||||
|
6
MANIFEST
6
MANIFEST
@@ -101,6 +101,9 @@ mkinstalldirs
|
||||
pathnames.h.in
|
||||
plugins/sample/Makefile.in
|
||||
plugins/sample/sample_plugin.c
|
||||
plugins/sample_group/Makefile.in
|
||||
plugins/sample_group/getgrent.c
|
||||
plugins/sample_group/sample_group.c
|
||||
plugins/sudoers/Makefile.in
|
||||
plugins/sudoers/aixcrypt.exp
|
||||
plugins/sudoers/alias.c
|
||||
@@ -140,6 +143,7 @@ plugins/sudoers/goodpath.c
|
||||
plugins/sudoers/gram.c
|
||||
plugins/sudoers/gram.h
|
||||
plugins/sudoers/gram.y
|
||||
plugins/sudoers/group_plugin.c
|
||||
plugins/sudoers/ins_2001.h
|
||||
plugins/sudoers/ins_classic.h
|
||||
plugins/sudoers/ins_csops.h
|
||||
@@ -155,7 +159,6 @@ plugins/sudoers/logging.c
|
||||
plugins/sudoers/logging.h
|
||||
plugins/sudoers/match.c
|
||||
plugins/sudoers/mkdefaults
|
||||
plugins/sudoers/nonunix.h
|
||||
plugins/sudoers/parse.c
|
||||
plugins/sudoers/parse.h
|
||||
plugins/sudoers/plugin_error.c
|
||||
@@ -175,7 +178,6 @@ plugins/sudoers/timestr.c
|
||||
plugins/sudoers/toke.c
|
||||
plugins/sudoers/toke.l
|
||||
plugins/sudoers/tsgetgrpw.c
|
||||
plugins/sudoers/vasgroups.c
|
||||
plugins/sudoers/visudo.c
|
||||
src/Makefile.in
|
||||
src/conversation.c
|
||||
|
@@ -20,7 +20,8 @@ devdir = @devdir@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
SUBDIRS = compat common src plugins/sample plugins/sudoers include doc
|
||||
SUBDIRS = compat common src plugins/sample plugins/sample_group \
|
||||
plugins/sudoers include doc
|
||||
|
||||
VERSION = @PACKAGE_VERSION@
|
||||
|
||||
|
@@ -585,9 +585,6 @@
|
||||
/* The message given when a bad password is entered. */
|
||||
#undef INCORRECT_PASSWORD
|
||||
|
||||
/* The name of libvas.so */
|
||||
#undef LIBVAS_SO
|
||||
|
||||
/* The syslog facility sudo will use. */
|
||||
#undef LOGFAC
|
||||
|
||||
@@ -719,9 +716,6 @@
|
||||
/* Define to 1 if you want a different ticket file for each tty. */
|
||||
#undef USE_TTY_TICKETS
|
||||
|
||||
/* Define to 1 if using a non-Unix group lookup implementation. */
|
||||
#undef USING_NONUNIX_GROUPS
|
||||
|
||||
/* Define to avoid using the passwd/shadow file for authentication. */
|
||||
#undef WITHOUT_PASSWD
|
||||
|
||||
|
87
configure
vendored
87
configure
vendored
@@ -978,8 +978,6 @@ with_secure_path
|
||||
with_interfaces
|
||||
with_stow
|
||||
with_askpass
|
||||
with_libvas
|
||||
with_libvas_rpath
|
||||
with_plugin_dir
|
||||
enable_authentication
|
||||
enable_root_mailer
|
||||
@@ -1741,10 +1739,6 @@ Optional Packages:
|
||||
--without-interfaces don't try to read the ip addr of ether interfaces
|
||||
--with-stow properly handle GNU stow packaging
|
||||
--with-askpass=PATH Fully qualified pathname of askpass helper
|
||||
--with-libvas=NAME Name of the libvas shared library
|
||||
(default=libvas.so)
|
||||
--with-libvas-rpath=PATH
|
||||
Path to look for libvas in [default=/opt/quest/lib]
|
||||
--with-plugin_dir set directory to load plugins from
|
||||
--with-selinux enable SELinux support
|
||||
--with-pic try to use only PIC/non-PIC objects [default=use
|
||||
@@ -5093,42 +5087,6 @@ $as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Check whether --with-libvas was given.
|
||||
if test "${with_libvas+set}" = set; then :
|
||||
withval=$with_libvas; case $with_libvas in
|
||||
yes) with_libvas=libvas.so
|
||||
;;
|
||||
no) ;;
|
||||
*)
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define LIBVAS_SO "$with_libvas"
|
||||
_ACEOF
|
||||
|
||||
;;
|
||||
esac
|
||||
if test X"$with_libvas" != X"no"; then
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define LIBVAS_SO "$with_libvas"
|
||||
_ACEOF
|
||||
|
||||
$as_echo "#define USING_NONUNIX_GROUPS 1" >>confdefs.h
|
||||
|
||||
NONUNIX_GROUPS_IMPL="vasgroups.o"
|
||||
|
||||
# Check whether --with-libvas-rpath was given.
|
||||
if test "${with_libvas_rpath+set}" = set; then :
|
||||
withval=$with_libvas_rpath; LIBVAS_RPATH=$withval
|
||||
else
|
||||
LIBVAS_RPATH=/opt/quest/lib
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
|
||||
with_plugindir="$libexecdir"
|
||||
|
||||
# Check whether --with-plugin_dir was given.
|
||||
@@ -6968,13 +6926,13 @@ if test "${lt_cv_nm_interface+set}" = set; then :
|
||||
else
|
||||
lt_cv_nm_interface="BSD nm"
|
||||
echo "int some_variable = 0;" > conftest.$ac_ext
|
||||
(eval echo "\"\$as_me:6971: $ac_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:6929: $ac_compile\"" >&5)
|
||||
(eval "$ac_compile" 2>conftest.err)
|
||||
cat conftest.err >&5
|
||||
(eval echo "\"\$as_me:6974: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
|
||||
(eval echo "\"\$as_me:6932: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
|
||||
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
|
||||
cat conftest.err >&5
|
||||
(eval echo "\"\$as_me:6977: output\"" >&5)
|
||||
(eval echo "\"\$as_me:6935: output\"" >&5)
|
||||
cat conftest.out >&5
|
||||
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
|
||||
lt_cv_nm_interface="MS dumpbin"
|
||||
@@ -8179,7 +8137,7 @@ ia64-*-hpux*)
|
||||
;;
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 8182 "configure"' > conftest.$ac_ext
|
||||
echo '#line 8140 "configure"' > conftest.$ac_ext
|
||||
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
@@ -9440,11 +9398,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:9443: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:9401: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:9447: \$? = $ac_status" >&5
|
||||
echo "$as_me:9405: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@@ -9779,11 +9737,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:9782: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:9740: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:9786: \$? = $ac_status" >&5
|
||||
echo "$as_me:9744: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@@ -9884,11 +9842,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:9887: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:9845: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:9891: \$? = $ac_status" >&5
|
||||
echo "$as_me:9849: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@@ -9939,11 +9897,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:9942: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:9900: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:9946: \$? = $ac_status" >&5
|
||||
echo "$as_me:9904: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@@ -12306,7 +12264,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 12309 "configure"
|
||||
#line 12267 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -12402,7 +12360,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 12405 "configure"
|
||||
#line 12363 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -18129,19 +18087,6 @@ fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if test X"$LIBVAS_RPATH" != X""; then
|
||||
if test -n "$blibpath"; then
|
||||
blibpath_add="${blibpath_add}:$LIBVAS_RPATH"
|
||||
else
|
||||
case "$host" in
|
||||
*-*-hpux*) LDFLAGS="$LDFLAGS -Wl,+b,$LIBVAS_RPATH"
|
||||
;;
|
||||
*) LDFLAGS="$LDFLAGS -Wl,-R$LIBVAS_RPATH"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$blibpath"; then
|
||||
if test -n "$blibpath_add"; then
|
||||
SUDOERS_LDFLAGS="$SUDOERS_LDFLAGS -Wl,-blibpath:${blibpath}${blibpath_add}"
|
||||
@@ -18312,7 +18257,7 @@ EOF
|
||||
exec_prefix="$oexec_prefix"
|
||||
fi
|
||||
|
||||
ac_config_files="$ac_config_files Makefile common/Makefile compat/Makefile doc/Makefile include/Makefile src/sudo_usage.h src/Makefile plugins/sample/Makefile plugins/sudoers/Makefile"
|
||||
ac_config_files="$ac_config_files Makefile common/Makefile compat/Makefile doc/Makefile include/Makefile src/sudo_usage.h src/Makefile plugins/sample/Makefile plugins/sample_group/Makefile plugins/sudoers/Makefile"
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
# This file is a shell script that caches the results of configure
|
||||
@@ -19270,6 +19215,7 @@ do
|
||||
"src/sudo_usage.h") CONFIG_FILES="$CONFIG_FILES src/sudo_usage.h" ;;
|
||||
"src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
|
||||
"plugins/sample/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/sample/Makefile" ;;
|
||||
"plugins/sample_group/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/sample_group/Makefile" ;;
|
||||
"plugins/sudoers/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/sudoers/Makefile" ;;
|
||||
|
||||
*) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
|
||||
@@ -20574,6 +20520,5 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
43
configure.in
43
configure.in
@@ -1087,29 +1087,6 @@ AC_ARG_WITH(askpass, [AS_HELP_STRING([--with-askpass=PATH], [Fully qualified pat
|
||||
;;
|
||||
esac], AC_MSG_RESULT(no))
|
||||
|
||||
dnl
|
||||
dnl If enabled, set LIBVAS_SO, LIBVAS_RPATH and USING_NONUNIX_GROUPS
|
||||
dnl
|
||||
AC_ARG_WITH(libvas, [AS_HELP_STRING([--with-libvas=NAME], [Name of the libvas shared library (default=libvas.so)])],
|
||||
[case $with_libvas in
|
||||
yes) with_libvas=libvas.so
|
||||
;;
|
||||
no) ;;
|
||||
*) AC_DEFINE_UNQUOTED([LIBVAS_SO], ["$with_libvas"], [The name of libvas.so])
|
||||
;;
|
||||
esac
|
||||
if test X"$with_libvas" != X"no"; then
|
||||
AC_DEFINE_UNQUOTED([LIBVAS_SO], ["$with_libvas"], [The name of libvas.so])
|
||||
AC_DEFINE(USING_NONUNIX_GROUPS)
|
||||
NONUNIX_GROUPS_IMPL="vasgroups.o"
|
||||
AC_ARG_WITH([libvas-rpath],
|
||||
[AS_HELP_STRING([--with-libvas-rpath=PATH],
|
||||
[Path to look for libvas in [default=/opt/quest/lib]])],
|
||||
[LIBVAS_RPATH=$withval],
|
||||
[LIBVAS_RPATH=/opt/quest/lib])
|
||||
fi
|
||||
])
|
||||
|
||||
with_plugindir="$libexecdir"
|
||||
AC_ARG_WITH(plugin_dir, [AS_HELP_STRING([--with-plugin_dir], [set directory to load plugins from])],
|
||||
[case $with_plugin_dir in
|
||||
@@ -2671,23 +2648,6 @@ case "$host" in
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl
|
||||
dnl Add LIBVAS_RPATH to LDFLAGS
|
||||
dnl GNU ld accepts -R/path/ as an alias for -rpath /path/
|
||||
dnl
|
||||
if test X"$LIBVAS_RPATH" != X""; then
|
||||
if test -n "$blibpath"; then
|
||||
blibpath_add="${blibpath_add}:$LIBVAS_RPATH"
|
||||
else
|
||||
case "$host" in
|
||||
*-*-hpux*) LDFLAGS="$LDFLAGS -Wl,+b,$LIBVAS_RPATH"
|
||||
;;
|
||||
*) LDFLAGS="$LDFLAGS -Wl,-R$LIBVAS_RPATH"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Add $blibpath to SUDOERS_LDFLAGS if specified by the user or if we
|
||||
dnl added -L dirpaths to SUDOERS_LDFLAGS.
|
||||
@@ -2779,7 +2739,7 @@ dnl
|
||||
dnl Substitute into the Makefile and man pages
|
||||
dnl
|
||||
dnl AC_CONFIG_FILES([doc/sudo.man doc/visudo.man doc/sudoers.man doc/sudoers.ldap.man doc/sudoreplay.man src/Makefile src/sudo_usage.h])
|
||||
AC_CONFIG_FILES([Makefile common/Makefile compat/Makefile doc/Makefile include/Makefile src/sudo_usage.h src/Makefile plugins/sample/Makefile plugins/sudoers/Makefile])
|
||||
AC_CONFIG_FILES([Makefile common/Makefile compat/Makefile doc/Makefile include/Makefile src/sudo_usage.h src/Makefile plugins/sample/Makefile plugins/sample_group/Makefile plugins/sudoers/Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
dnl
|
||||
@@ -2875,7 +2835,6 @@ AH_TEMPLATE(USE_TTY_TICKETS, [Define to 1 if you want a different ticket file fo
|
||||
AH_TEMPLATE(WITHOUT_PASSWD, [Define to avoid using the passwd/shadow file for authentication.])
|
||||
AH_TEMPLATE(sig_atomic_t, [Define to `int' if <signal.h> does not define.])
|
||||
AH_TEMPLATE(__signed, [Define to `signed' or nothing if compiler does not support a signed type qualifier.])
|
||||
AH_TEMPLATE(USING_NONUNIX_GROUPS, [Define to 1 if using a non-Unix group lookup implementation.])
|
||||
|
||||
dnl
|
||||
dnl Bits to copy verbatim into config.h.in
|
||||
|
28
doc/LICENSE
28
doc/LICENSE
@@ -48,31 +48,3 @@ bear the following UCB license:
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
nonunix.h and vasgroups.c bear the following license:
|
||||
|
||||
Copyright (c) 2006 Quest Software, Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of Quest Software, Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
@@ -52,32 +52,3 @@ bear the following UCB license:
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
=head3
|
||||
nonunix.h and vasgroups.c bear the following license:
|
||||
|
||||
Copyright (c) 2006 Quest Software, Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of Quest Software, Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
@@ -104,4 +104,33 @@ struct generic_plugin {
|
||||
/* the rest depends on the type... */
|
||||
};
|
||||
|
||||
/* Sudoers group plugin version major/minor */
|
||||
#define GROUP_API_VERSION_MAJOR 1
|
||||
#define GROUP_API_VERSION_MINOR 0
|
||||
#define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | GROUP_API_VERSION_MINOR)
|
||||
|
||||
/* Getters and setters for group version */
|
||||
#define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16)
|
||||
#define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
|
||||
#define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \
|
||||
*(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
|
||||
} while(0)
|
||||
#define GROUP_API_VERSION_SET_MINOR(vp, n) do { \
|
||||
*(vp) = (*(vp) & 0xffff0000) | (n); \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
* version: for compatibility checking
|
||||
* group_init: return 1 on success, 0 if unconfigured, -1 on error.
|
||||
* group_cleanup: called to clean up resources used by provider
|
||||
* user_in_group: returns 1 if user is in group, 0 if not.
|
||||
* note that pwd may be NULL if the user is not in passwd.
|
||||
*/
|
||||
struct sudoers_group_plugin {
|
||||
unsigned int version;
|
||||
int (*init)(int version, sudo_printf_t sudo_printf, char *const argv[]);
|
||||
void (*cleanup)(void);
|
||||
int (*query)(const char *user, const char *group, const struct passwd *pwd);
|
||||
};
|
||||
|
||||
#endif /* _SUDO_PLUGIN_H */
|
||||
|
120
plugins/sample_group/Makefile.in
Normal file
120
plugins/sample_group/Makefile.in
Normal file
@@ -0,0 +1,120 @@
|
||||
#
|
||||
# Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# @configure_input@
|
||||
#
|
||||
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
srcdir = @srcdir@
|
||||
devdir = @devdir@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
incdir = $(top_srcdir)/include
|
||||
|
||||
# For out of tree builds
|
||||
VPATH = $(srcdir)
|
||||
|
||||
# Compiler & tools to use
|
||||
CC = @CC@
|
||||
LIBTOOL = @LIBTOOL@ --tag=disable-static
|
||||
|
||||
# Our install program supports extra flags...
|
||||
INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
|
||||
|
||||
# Libraries
|
||||
LIBS = $(LIBOBJDIR)/libreplace.la
|
||||
|
||||
# C preprocessor flags
|
||||
CPPFLAGS = -I$(incdir) -I$(top_builddir) @CPPFLAGS@
|
||||
|
||||
# Usually -O and/or -g
|
||||
CFLAGS = @CFLAGS@
|
||||
|
||||
# Flags to pass to the link stage
|
||||
LDFLAGS =
|
||||
|
||||
# Where to install things...
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
sysconfdir = @sysconfdir@
|
||||
libexecdir = @libexecdir@
|
||||
datarootdir = @datarootdir@
|
||||
plugindir = @PLUGINDIR@
|
||||
|
||||
# OS dependent defines
|
||||
DEFS = @OSDEFS@
|
||||
|
||||
#### End of system configuration section. ####
|
||||
|
||||
SHELL = @SHELL@
|
||||
|
||||
OBJS = sample_group.lo getgrent.lo
|
||||
|
||||
LIBOBJDIR = $(top_builddir)/@ac_config_libobj_dir@/
|
||||
|
||||
VERSION = @PACKAGE_VERSION@
|
||||
|
||||
all: sample_group.la
|
||||
|
||||
.SUFFIXES: .o .c .h .lo
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $<
|
||||
|
||||
.c.lo:
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $<
|
||||
|
||||
getgrent.lo: $(srcdir)/getgrent.c
|
||||
|
||||
sample_group.lo: $(srcdir)/sample_group.c
|
||||
|
||||
sample_group.la: $(OBJS)
|
||||
$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) -module -avoid-version -rpath $(plugindir)
|
||||
|
||||
install: install-dirs install-plugin
|
||||
|
||||
install-dirs:
|
||||
$(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(plugindir)
|
||||
|
||||
install-binaries:
|
||||
|
||||
install-includes:
|
||||
|
||||
install-man:
|
||||
|
||||
install-plugin: install-dirs sample_group.la
|
||||
$(LIBTOOL) --mode=install --quiet $(INSTALL) sample_group.la $(plugindir)
|
||||
|
||||
check:
|
||||
@echo nothing to check
|
||||
|
||||
clean:
|
||||
-$(LIBTOOL) --mode=clean rm -f *.lo *.o *.la *.a stamp-* core *.core core.*
|
||||
|
||||
mostlyclean: clean
|
||||
|
||||
distclean: clean
|
||||
-rm -rf Makefile .libs
|
||||
|
||||
clobber: distclean
|
||||
|
||||
realclean: distclean
|
||||
rm -f TAGS tags
|
||||
|
||||
cleandir: realclean
|
185
plugins/sample_group/getgrent.c
Normal file
185
plugins/sample_group/getgrent.c
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2008, 2010 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Trivial replacements for the libc getgr{uid,nam}() routines.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
# include <stddef.h>
|
||||
#else
|
||||
# ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
# endif
|
||||
#endif /* STDC_HEADERS */
|
||||
#ifdef HAVE_STRING_H
|
||||
# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
|
||||
# include <memory.h>
|
||||
# endif
|
||||
# include <string.h>
|
||||
#endif /* HAVE_STRING_H */
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif /* HAVE_STRINGS_H */
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include <compat.h>
|
||||
#include <missing.h>
|
||||
|
||||
#ifndef LINE_MAX
|
||||
# define LINE_MAX 2048
|
||||
#endif
|
||||
|
||||
#undef GRMEM_MAX
|
||||
#define GRMEM_MAX 200
|
||||
|
||||
static FILE *grf;
|
||||
static const char *grfile = "/etc/group";
|
||||
static int gr_stayopen;
|
||||
|
||||
void mysetgrfile(const char *);
|
||||
void mysetgrent(void);
|
||||
void myendgrent(void);
|
||||
struct group *mygetgrent(void);
|
||||
struct group *mygetgrnam(const char *);
|
||||
struct group *mygetgrgid(gid_t);
|
||||
|
||||
void
|
||||
mysetgrfile(const char *file)
|
||||
{
|
||||
grfile = file;
|
||||
if (grf != NULL)
|
||||
myendgrent();
|
||||
}
|
||||
|
||||
void
|
||||
mysetgrent(void)
|
||||
{
|
||||
if (grf == NULL) {
|
||||
grf = fopen(grfile, "r");
|
||||
if (grf != NULL)
|
||||
fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
|
||||
} else {
|
||||
rewind(grf);
|
||||
}
|
||||
gr_stayopen = 1;
|
||||
}
|
||||
|
||||
void
|
||||
myendgrent(void)
|
||||
{
|
||||
if (grf != NULL) {
|
||||
fclose(grf);
|
||||
grf = NULL;
|
||||
}
|
||||
gr_stayopen = 0;
|
||||
}
|
||||
|
||||
struct group *
|
||||
mygetgrent(void)
|
||||
{
|
||||
static struct group gr;
|
||||
static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
|
||||
size_t len;
|
||||
char *cp, *colon;
|
||||
int n;
|
||||
|
||||
if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
|
||||
return(NULL);
|
||||
|
||||
memset(&gr, 0, sizeof(gr));
|
||||
if ((colon = strchr(cp = colon, ':')) == NULL)
|
||||
return(NULL);
|
||||
*colon++ = '\0';
|
||||
gr.gr_name = cp;
|
||||
if ((colon = strchr(cp = colon, ':')) == NULL)
|
||||
return(NULL);
|
||||
*colon++ = '\0';
|
||||
gr.gr_passwd = cp;
|
||||
if ((colon = strchr(cp = colon, ':')) == NULL)
|
||||
return(NULL);
|
||||
*colon++ = '\0';
|
||||
gr.gr_gid = atoi(cp);
|
||||
len = strlen(colon);
|
||||
if (len > 0 && colon[len - 1] == '\n')
|
||||
colon[len - 1] = '\0';
|
||||
if (*colon != '\0') {
|
||||
gr.gr_mem = gr_mem;
|
||||
cp = strtok(colon, ",");
|
||||
for (n = 0; cp != NULL && n < GRMEM_MAX; n++) {
|
||||
gr.gr_mem[n] = cp;
|
||||
cp = strtok(NULL, ",");
|
||||
}
|
||||
gr.gr_mem[n++] = NULL;
|
||||
} else
|
||||
gr.gr_mem = NULL;
|
||||
return(&gr);
|
||||
}
|
||||
|
||||
struct group *
|
||||
mygetgrnam(const char *name)
|
||||
{
|
||||
struct group *gr;
|
||||
|
||||
if (grf == NULL) {
|
||||
if ((grf = fopen(grfile, "r")) == NULL)
|
||||
return(NULL);
|
||||
fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
|
||||
} else {
|
||||
rewind(grf);
|
||||
}
|
||||
while ((gr = mygetgrent()) != NULL) {
|
||||
if (strcmp(gr->gr_name, name) == 0)
|
||||
break;
|
||||
}
|
||||
if (!gr_stayopen) {
|
||||
fclose(grf);
|
||||
grf = NULL;
|
||||
}
|
||||
return(gr);
|
||||
}
|
||||
|
||||
struct group *
|
||||
mygetgrgid(gid_t gid)
|
||||
{
|
||||
struct group *gr;
|
||||
|
||||
if (grf == NULL) {
|
||||
if ((grf = fopen(grfile, "r")) == NULL)
|
||||
return(NULL);
|
||||
fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
|
||||
} else {
|
||||
rewind(grf);
|
||||
}
|
||||
while ((gr = mygetgrent()) != NULL) {
|
||||
if (gr->gr_gid == gid)
|
||||
break;
|
||||
}
|
||||
if (!gr_stayopen) {
|
||||
fclose(grf);
|
||||
grf = NULL;
|
||||
}
|
||||
return(gr);
|
||||
}
|
140
plugins/sample_group/sample_group.c
Normal file
140
plugins/sample_group/sample_group.c
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
# include <stddef.h>
|
||||
#else
|
||||
# ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
# endif
|
||||
#endif /* STDC_HEADERS */
|
||||
#ifdef HAVE_STRING_H
|
||||
# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
|
||||
# include <memory.h>
|
||||
# endif
|
||||
# include <string.h>
|
||||
#endif /* HAVE_STRING_H */
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif /* HAVE_STRINGS_H */
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include <sudo_plugin.h>
|
||||
#include <compat.h>
|
||||
#include <missing.h>
|
||||
|
||||
/*
|
||||
* Sample sudoers group plugin that uses an extra group file with the
|
||||
* same format as /etc/group.
|
||||
*/
|
||||
|
||||
#undef TRUE
|
||||
#define TRUE 1
|
||||
#undef FALSE
|
||||
#define FALSE 0
|
||||
#undef ERROR
|
||||
#define ERROR -1
|
||||
|
||||
static sudo_printf_t sudo_log;
|
||||
|
||||
extern void mysetgrfile(const char *);
|
||||
extern void mysetgrent(void);
|
||||
extern void myendgrent(void);
|
||||
extern struct group *mygetgrnam(const char *);
|
||||
|
||||
static int sample_init(int version, sudo_printf_t sudo_printf, char *const argv[])
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
sudo_log = sudo_printf;
|
||||
|
||||
if (GROUP_API_VERSION_GET_MAJOR(version) != GROUP_API_VERSION_MAJOR) {
|
||||
sudo_log(SUDO_CONV_ERROR_MSG,
|
||||
"sample_group: incompatible major version %d, expected %d\n",
|
||||
GROUP_API_VERSION_GET_MAJOR(version),
|
||||
GROUP_API_VERSION_MAJOR);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Sanity check the specified group file. */
|
||||
if (argv == NULL || argv[0] == NULL) {
|
||||
sudo_log(SUDO_CONV_ERROR_MSG,
|
||||
"sample_group: path to group file not specified\n");
|
||||
return ERROR;
|
||||
}
|
||||
if (stat(argv[0], &sb) != 0) {
|
||||
sudo_log(SUDO_CONV_ERROR_MSG,
|
||||
"sample_group: %s: %s\n", argv[0], strerror(errno));
|
||||
return ERROR;
|
||||
}
|
||||
if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
|
||||
sudo_log(SUDO_CONV_ERROR_MSG,
|
||||
"%s must be only be writable by owner\n", argv[0]);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
mysetgrfile(argv[0]);
|
||||
mysetgrent();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void sample_cleanup(void)
|
||||
{
|
||||
myendgrent();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns TRUE if "user" is a member of "group", else FALSE.
|
||||
*/
|
||||
static int sample_query(const char *user, const char *group, const struct passwd *pwd)
|
||||
{
|
||||
struct group *grp;
|
||||
char **member;
|
||||
|
||||
grp = mygetgrnam(group);
|
||||
if (grp != NULL) {
|
||||
for (member = grp->gr_mem; *member != NULL; member++) {
|
||||
if (strcasecmp(user, *member) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
struct sudoers_group_plugin group_plugin = {
|
||||
GROUP_API_VERSION,
|
||||
sample_init,
|
||||
sample_cleanup,
|
||||
sample_query
|
||||
};
|
@@ -105,7 +105,7 @@ LIBSUDOERS_OBJS = alias.lo audit.lo defaults.lo gram.lo match.lo pwutil.lo \
|
||||
|
||||
SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo \
|
||||
plugin_error.lo env.lo getspwuid.lo \
|
||||
goodpath.lo find_path.lo interfaces.lo \
|
||||
goodpath.lo group_plugin.lo find_path.lo interfaces.lo \
|
||||
logging.lo parse.lo set_perms.lo sudoers.lo sudo_nss.lo \
|
||||
iolog.lo @SUDOERS_OBJS@
|
||||
|
||||
@@ -113,7 +113,7 @@ VISUDO_OBJS = visudo.o goodpath.o find_path.o error.o
|
||||
|
||||
REPLAY_OBJS = getdate.o sudoreplay.o error.o
|
||||
|
||||
TEST_OBJS = interfaces.o testsudoers.o tsgetgrpw.o error.o
|
||||
TEST_OBJS = interfaces.o testsudoers.o tsgetgrpw.o error.o group_plugin.o
|
||||
|
||||
VERSION = @PACKAGE_VERSION@
|
||||
|
||||
@@ -197,6 +197,7 @@ getspwuid.lo: $(srcdir)/getspwuid.c $(SUDODEP)
|
||||
goodpath.lo: $(srcdir)/goodpath.c $(SUDODEP)
|
||||
gram.lo: $(devdir)/gram.c $(SUDODEP) $(srcdir)/parse.h $(incdir)/list.h $(devdir)/gram.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(devdir)/gram.c
|
||||
group_plugin.lo: $(srcdir)/group_plugin.c $(SUDODEP)
|
||||
interfaces.lo: $(srcdir)/interfaces.c $(SUDODEP) $(srcdir)/interfaces.h
|
||||
iolog.lo: $(srcdir)/iolog.c $(SUDODEP)
|
||||
ldap.lo: $(srcdir)/ldap.c $(SUDODEP) $(srcdir)/parse.h $(incdir)/list.h
|
||||
@@ -213,7 +214,6 @@ timestr.lo: $(srcdir)/timestr.c $(incdir)/compat.h $(top_builddir)/config.h
|
||||
toke.lo: $(devdir)/toke.c $(SUDODEP) $(srcdir)/parse.h $(incdir)/list.h $(devdir)/gram.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(devdir)/toke.c
|
||||
tsgetgrpw.lo: $(srcdir)/tsgetgrpw.c $(SUDODEP)
|
||||
vasgroups.lo: $(srcdir)/vasgroups.c $(srcdir)/nonunix.h $(SUDODEP)
|
||||
plugin_error.lo: $(srcdir)/plugin_error.c $(incdir)/error.h $(incdir)/compat.h $(top_builddir)/config.h
|
||||
|
||||
# Auth dependencies
|
||||
|
@@ -326,6 +326,10 @@ struct sudo_defs_types sudo_defs_table[] = {
|
||||
"use_pty", T_FLAG,
|
||||
"Always run commands in a pseudo-tty",
|
||||
NULL,
|
||||
}, {
|
||||
"group_plugin", T_STR,
|
||||
"Plugin for non-Unix group support",
|
||||
NULL,
|
||||
}, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
|
@@ -150,6 +150,8 @@
|
||||
#define I_COMPRESS_IO 74
|
||||
#define def_use_pty (sudo_defs_table[75].sd_un.flag)
|
||||
#define I_USE_PTY 75
|
||||
#define def_group_plugin (sudo_defs_table[76].sd_un.str)
|
||||
#define I_GROUP_PLUGIN 76
|
||||
|
||||
enum def_tupple {
|
||||
never,
|
||||
|
@@ -241,3 +241,6 @@ compress_io
|
||||
use_pty
|
||||
T_FLAG
|
||||
"Always run commands in a pseudo-tty"
|
||||
group_plugin
|
||||
T_STR
|
||||
"Plugin for non-Unix group support"
|
||||
|
163
plugins/sudoers/group_plugin.c
Normal file
163
plugins/sudoers/group_plugin.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
# include <stddef.h>
|
||||
#else
|
||||
# ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
# endif
|
||||
#endif /* STDC_HEADERS */
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif /* HAVE_STRING_H */
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif /* HAVE_STRINGS_H */
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
#if TIME_WITH_SYS_TIME
|
||||
# include <time.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "sudoers.h"
|
||||
|
||||
static void *group_handle;
|
||||
static struct sudoers_group_plugin *group_plugin;
|
||||
|
||||
/*
|
||||
* Load the specified plugin and run its init function.
|
||||
* Returns -1 if unable to open the plugin, else it returns
|
||||
* the value from the plugin's init function.
|
||||
*/
|
||||
int
|
||||
group_plugin_load(char *plugin_info)
|
||||
{
|
||||
struct stat sb;
|
||||
char *args, path[PATH_MAX], savedch;
|
||||
char **argv = NULL;
|
||||
size_t len;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Fill in .so path and split out args (if any).
|
||||
*/
|
||||
path[0] = '\0';
|
||||
if (plugin_info[0] != '/')
|
||||
strlcpy(path, _PATH_SUDO_PLUGIN_DIR, sizeof(path));
|
||||
if ((args = strpbrk(plugin_info, " \t")) != NULL) {
|
||||
savedch = *args;
|
||||
*args = '\0';
|
||||
}
|
||||
len = strlcat(path, plugin_info, sizeof(path));
|
||||
if (args != NULL)
|
||||
*args++ = savedch;
|
||||
if (len >= sizeof(path)) {
|
||||
warningx("%s%s: %s", _PATH_SUDO_PLUGIN_DIR, plugin_info,
|
||||
strerror(ENAMETOOLONG));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Sanity check plugin path. */
|
||||
if (stat(path, &sb) != 0) {
|
||||
warning("%s", path);
|
||||
return -1;
|
||||
}
|
||||
if (sb.st_uid != ROOT_UID) {
|
||||
warningx("%s must be owned by uid %d", path, ROOT_UID);
|
||||
return -1;
|
||||
}
|
||||
if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
|
||||
warningx("%s must be only be writable by owner", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Open plugin and map in symbol. */
|
||||
group_handle = dlopen(path, RTLD_NOW);
|
||||
if (!group_handle) {
|
||||
warningx("unable to dlopen %s: %s", path, dlerror());
|
||||
return -1;
|
||||
}
|
||||
group_plugin = dlsym(group_handle, "group_plugin");
|
||||
if (group_plugin == NULL) {
|
||||
warningx("unable to find symbol \"group_plugin\" in %s", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (GROUP_API_VERSION_GET_MAJOR(group_plugin->version) != GROUP_API_VERSION_MAJOR) {
|
||||
warningx("%s: incompatible group plugin major version %d, expected %d",
|
||||
path, GROUP_API_VERSION_GET_MAJOR(group_plugin->version),
|
||||
GROUP_API_VERSION_MAJOR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Split args into a vector if specified.
|
||||
*/
|
||||
if (args != NULL) {
|
||||
int ac = 0, wasblank = TRUE;
|
||||
char *cp;
|
||||
|
||||
for (cp = args; *cp != '\0'; cp++) {
|
||||
if (isblank((unsigned char)*cp)) {
|
||||
wasblank = TRUE;
|
||||
} else if (wasblank) {
|
||||
wasblank = FALSE;
|
||||
ac++;
|
||||
}
|
||||
}
|
||||
if (ac != 0) {
|
||||
argv = emalloc2(ac, sizeof(char *));
|
||||
ac = 0;
|
||||
for ((cp = strtok(args, " \t")); cp; (cp = strtok(NULL, " \t")))
|
||||
argv[ac++] = cp;
|
||||
}
|
||||
}
|
||||
|
||||
rc = (group_plugin->init)(GROUP_API_VERSION, sudo_printf, argv);
|
||||
|
||||
efree(argv);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
group_plugin_unload(void)
|
||||
{
|
||||
(group_plugin->cleanup)();
|
||||
dlclose(group_handle);
|
||||
group_handle = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
group_plugin_query(const char *user, const char *group,
|
||||
const struct passwd *pwd)
|
||||
{
|
||||
return (group_plugin->query)(user, group, pwd);
|
||||
}
|
@@ -88,9 +88,6 @@
|
||||
#ifndef HAVE_EXTENDED_GLOB
|
||||
# include <compat/glob.h>
|
||||
#endif /* HAVE_EXTENDED_GLOB */
|
||||
#ifdef USING_NONUNIX_GROUPS
|
||||
# include "nonunix.h"
|
||||
#endif /* USING_NONUNIX_GROUPS */
|
||||
|
||||
static struct member_list empty;
|
||||
|
||||
@@ -778,10 +775,8 @@ usergr_matches(char *group, char *user, struct passwd *pw)
|
||||
if (*group++ != '%')
|
||||
return(FALSE);
|
||||
|
||||
#ifdef USING_NONUNIX_GROUPS
|
||||
if (*group == ':')
|
||||
return(sudo_nonunix_groupcheck(++group, user, pw));
|
||||
#endif /* USING_NONUNIX_GROUPS */
|
||||
if (*group == ':' && def_group_plugin)
|
||||
return(group_plugin_query(user, group + 1, pw));
|
||||
|
||||
/* look up user's primary gid in the passwd file */
|
||||
if (pw == NULL && (pw = sudo_getpwnam(user)) == NULL)
|
||||
@@ -790,12 +785,9 @@ usergr_matches(char *group, char *user, struct passwd *pw)
|
||||
if (user_in_group(pw, group))
|
||||
return(TRUE);
|
||||
|
||||
#ifdef USING_NONUNIX_GROUPS
|
||||
/* not a Unix group, could be an AD group */
|
||||
if (sudo_nonunix_groupcheck_available() &&
|
||||
sudo_nonunix_groupcheck(group, user, pw))
|
||||
/* not a Unix group, could be an external group */
|
||||
if (def_group_plugin && group_plugin_query(user, group, pw))
|
||||
return(TRUE);
|
||||
#endif /* USING_NONUNIX_GROUPS */
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* (c) 2006 Quest Software, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Quest Software, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _NONUNIX_H
|
||||
#define _NONUNIX_H
|
||||
|
||||
void sudo_nonunix_groupcheck_init(void);
|
||||
void sudo_nonunix_groupcheck_cleanup(void);
|
||||
int sudo_nonunix_groupcheck(const char *group, const char *user,
|
||||
const struct passwd *pwd);
|
||||
int sudo_nonunix_groupcheck_available(void);
|
||||
|
||||
#endif /* _NONUNIX_H */
|
@@ -50,12 +50,6 @@
|
||||
|
||||
#include "sudoers.h"
|
||||
|
||||
#ifdef __TANDEM
|
||||
# define ROOT_UID 65535
|
||||
#else
|
||||
# define ROOT_UID 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
|
@@ -105,10 +105,6 @@
|
||||
#include "interfaces.h"
|
||||
#include "auth/sudo_auth.h"
|
||||
|
||||
#ifdef USING_NONUNIX_GROUPS
|
||||
# include "nonunix.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
@@ -223,10 +219,6 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
|
||||
|
||||
init_vars(envp); /* XXX - move this later? */
|
||||
|
||||
#ifdef USING_NONUNIX_GROUPS
|
||||
sudo_nonunix_groupcheck_init(); /* initialise nonunix groups impl */
|
||||
#endif /* USING_NONUNIX_GROUPS */
|
||||
|
||||
/* Parse nsswitch.conf for sudoers order. */
|
||||
snl = sudo_read_nss();
|
||||
|
||||
@@ -246,6 +238,18 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
|
||||
|
||||
/* XXX - collect post-sudoers parse settings into a function */
|
||||
|
||||
/*
|
||||
* Initialize external group plugin.
|
||||
*/
|
||||
if (def_group_plugin) {
|
||||
switch (group_plugin_load(def_group_plugin)) {
|
||||
case -1:
|
||||
return -1;
|
||||
case FALSE:
|
||||
def_group_plugin = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set runas passwd/group entries based on command line or sudoers.
|
||||
* Note that if runas_group was specified without runas_user we
|
||||
@@ -343,10 +347,6 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
||||
if (ISSET(sudo_mode, MODE_LOGIN_SHELL))
|
||||
NewArgv[0] = runas_pw->pw_shell;
|
||||
|
||||
#ifdef USING_NONUNIX_GROUPS
|
||||
sudo_nonunix_groupcheck_init(); /* initialise nonunix groups impl */
|
||||
#endif /* USING_NONUNIX_GROUPS */
|
||||
|
||||
/* Find command in path */
|
||||
cmnd_status = set_cmnd(sudo_mode);
|
||||
if (cmnd_status == -1) {
|
||||
@@ -527,11 +527,8 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
||||
tq_foreach_fwd(snl, nss) {
|
||||
nss->close(nss);
|
||||
}
|
||||
|
||||
#ifdef USING_NONUNIX_GROUPS
|
||||
/* Finished with the groupcheck code */
|
||||
sudo_nonunix_groupcheck_cleanup();
|
||||
#endif
|
||||
if (def_group_plugin)
|
||||
group_plugin_unload();
|
||||
|
||||
if (ISSET(sudo_mode, (MODE_VALIDATE|MODE_CHECK|MODE_LIST)))
|
||||
goto done;
|
||||
@@ -1138,9 +1135,8 @@ cleanup(int gotsignal)
|
||||
tq_foreach_fwd(snl, nss)
|
||||
nss->close(nss);
|
||||
}
|
||||
#ifdef USING_NONUNIX_GROUPS
|
||||
sudo_nonunix_groupcheck_cleanup();
|
||||
#endif
|
||||
if (def_group_plugin)
|
||||
group_plugin_unload();
|
||||
sudo_endpwent();
|
||||
sudo_endgrent();
|
||||
}
|
||||
|
@@ -177,6 +177,12 @@ struct sudo_user {
|
||||
#define user_type (sudo_user.type)
|
||||
#define user_closefrom (sudo_user.closefrom)
|
||||
|
||||
#ifdef __TANDEM
|
||||
# define ROOT_UID 65535
|
||||
#else
|
||||
# define ROOT_UID 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We used to use the system definition of PASS_MAX or _PASSWD_LEN,
|
||||
* but that caused problems with various alternate authentication
|
||||
@@ -299,6 +305,12 @@ FILE *open_sudoers(const char *, int, int *);
|
||||
void aix_restoreauthdb(void);
|
||||
void aix_setauthdb(char *user);
|
||||
|
||||
/* group_plugin.c */
|
||||
int group_plugin_load(char *plugin_info);
|
||||
void group_plugin_unload(void);
|
||||
int group_plugin_query(const char *user, const char *group,
|
||||
const struct passwd *pwd);
|
||||
|
||||
#ifndef _SUDO_MAIN
|
||||
extern struct sudo_user sudo_user;
|
||||
extern struct passwd *auth_pw, *list_pw;
|
||||
|
@@ -248,6 +248,9 @@ main(int argc, char *argv[])
|
||||
(void) fputs(" (problem with defaults entries)", stdout);
|
||||
puts(".");
|
||||
|
||||
if (def_group_plugin && group_plugin_load(def_group_plugin) != TRUE)
|
||||
def_group_plugin = NULL;
|
||||
|
||||
/*
|
||||
* Set runas passwd/group entries based on command line or sudoers.
|
||||
* Note that if runas_group was specified without runas_user we
|
||||
|
@@ -1,319 +0,0 @@
|
||||
/*
|
||||
* (c) 2006 Quest Software, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Quest Software, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <vas.h>
|
||||
|
||||
#include "nonunix.h"
|
||||
#include "sudoers.h"
|
||||
#include "parse.h"
|
||||
|
||||
|
||||
/* Pseudo-boolean types */
|
||||
#undef TRUE
|
||||
#undef FALSE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
|
||||
static vas_ctx_t *sudo_vas_ctx;
|
||||
static vas_id_t *sudo_vas_id;
|
||||
/* Don't use VAS_NAME_FLAG_NO_CACHE or lookups just won't work.
|
||||
* -tedp, 2006-08-29 */
|
||||
static const int update_flags = 0;
|
||||
static int sudo_vas_available = 0;
|
||||
static char *err_msg = NULL;
|
||||
static void *libvas_handle = NULL;
|
||||
|
||||
/* libvas functions */
|
||||
static vas_err_t (*v_ctx_alloc) (vas_ctx_t **ctx);
|
||||
static void (*v_ctx_free) (vas_ctx_t *ctx);
|
||||
static vas_err_t (*v_id_alloc) (vas_ctx_t *ctx, const char *name, vas_id_t **id);
|
||||
static void (*v_id_free) (vas_ctx_t *ctx, vas_id_t *id);
|
||||
static vas_err_t (*v_id_establish_cred_keytab) (vas_ctx_t *ctx, vas_id_t *id, int credflags, const char *keytab);
|
||||
static vas_err_t (*v_user_init) (vas_ctx_t *ctx, vas_id_t *id, const char *name, int flags, vas_user_t **user);
|
||||
static void (*v_user_free) (vas_ctx_t *ctx, vas_user_t *user);
|
||||
static vas_err_t (*v_group_init) (vas_ctx_t *ctx, vas_id_t *id, const char *name, int flags, vas_group_t **group);
|
||||
static void (*v_group_free) (vas_ctx_t *ctx, vas_group_t *group);
|
||||
static vas_err_t (*v_user_is_member) (vas_ctx_t *ctx, vas_id_t *id, vas_user_t *user, vas_group_t *group);
|
||||
static const char* (*v_err_get_string) (vas_ctx_t *ctx, int with_cause);
|
||||
|
||||
|
||||
static int resolve_vas_funcs(void);
|
||||
|
||||
|
||||
/**
|
||||
* Whether nonunix group lookups are available.
|
||||
* @return 1 if available, 0 if not.
|
||||
*/
|
||||
int
|
||||
sudo_nonunix_groupcheck_available(void)
|
||||
{
|
||||
return sudo_vas_available;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the user is in the group
|
||||
* @param group group name which can be in DOMAIN\sam format or just the group
|
||||
* name
|
||||
* @param user user name
|
||||
* @param pwd (unused)
|
||||
* @return 1 if user is a member of the group, 0 if not (or error occurred)
|
||||
*/
|
||||
int
|
||||
sudo_nonunix_groupcheck( const char* group, const char* user, const struct passwd* pwd )
|
||||
{
|
||||
static int error_cause_shown = FALSE;
|
||||
int rval = FALSE;
|
||||
vas_err_t vaserr;
|
||||
vas_user_t* vas_user = NULL;
|
||||
vas_group_t* vas_group = NULL;
|
||||
|
||||
if (!sudo_vas_available) {
|
||||
if (error_cause_shown == FALSE) {
|
||||
/* Produce the saved error reason */
|
||||
warningx("Non-unix group checking unavailable: %s",
|
||||
err_msg ? err_msg
|
||||
: "(unknown cause)");
|
||||
error_cause_shown = TRUE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* resolve the user and group. The user will be a real Unix account name,
|
||||
* while the group may be a unix name, or any group name accepted by
|
||||
* vas_name_to_dn, which means any of:
|
||||
* - Group Name
|
||||
* - Group Name@FULLY.QUALIFIED.DOMAIN
|
||||
* - CN=sudoers,CN=Users,DC=rcdev,DC=vintela,DC=com
|
||||
* - S-1-2-34-5678901234-5678901234-5678901234-567
|
||||
*
|
||||
* XXX - we may get non-VAS user accounts here. You can add local users to an
|
||||
* Active Directory group through override files. Should we handle that case?
|
||||
* */
|
||||
if( (vaserr = v_user_init( sudo_vas_ctx, sudo_vas_id, user, update_flags, &vas_user )) != VAS_ERR_SUCCESS ) {
|
||||
if (vaserr == VAS_ERR_NOT_FOUND) {
|
||||
/* No such user in AD. Probably a local user. */
|
||||
vaserr = VAS_ERR_SUCCESS;
|
||||
}
|
||||
goto FINISHED;
|
||||
}
|
||||
|
||||
if( (vaserr = v_group_init( sudo_vas_ctx, sudo_vas_id, group, update_flags, &vas_group )) != VAS_ERR_SUCCESS ) {
|
||||
goto FINISHED;
|
||||
}
|
||||
|
||||
/* do the membership check */
|
||||
if( (vaserr = v_user_is_member( sudo_vas_ctx, sudo_vas_id, vas_user, vas_group )) == VAS_ERR_SUCCESS ) {
|
||||
rval = TRUE;
|
||||
}
|
||||
else if (vaserr == VAS_ERR_NOT_FOUND) {
|
||||
/* fake the vaserr code so no error is triggered */
|
||||
vaserr = VAS_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
FINISHED: /* cleanups */
|
||||
if (vaserr != VAS_ERR_SUCCESS && vaserr != VAS_ERR_NOT_FOUND ) {
|
||||
warningx("Error while checking group membership "
|
||||
"for user \"%s\", group \"%s\", error: %s%s.", user, group,
|
||||
v_err_get_string(sudo_vas_ctx, 1),
|
||||
/* A helpful hint if there seems to be a non-FQDN as the domain */
|
||||
(strchr(group, '@') && !strchr(group, '.'))
|
||||
? "\nMake sure the fully qualified domain name is specified"
|
||||
: "");
|
||||
}
|
||||
if( vas_group ) v_group_free( sudo_vas_ctx, vas_group );
|
||||
if( vas_user ) v_user_free( sudo_vas_ctx, vas_user );
|
||||
|
||||
return(rval);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_err_msg(const char *msg, ...) {
|
||||
va_list ap;
|
||||
|
||||
if (!msg) /* assert */
|
||||
return;
|
||||
|
||||
if (err_msg)
|
||||
free(err_msg);
|
||||
|
||||
va_start(ap, msg);
|
||||
|
||||
if (vasprintf(&err_msg, msg, ap) == -1)
|
||||
err_msg = NULL;
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise nonunix_groupcheck state.
|
||||
*/
|
||||
void
|
||||
sudo_nonunix_groupcheck_init(void)
|
||||
{
|
||||
vas_err_t vaserr;
|
||||
void *libvas;
|
||||
|
||||
if (err_msg) {
|
||||
free(err_msg);
|
||||
err_msg = NULL;
|
||||
}
|
||||
|
||||
libvas = dlopen(LIBVAS_SO, RTLD_LAZY);
|
||||
if (!libvas) {
|
||||
set_err_msg("dlopen() failed: %s", dlerror());
|
||||
return;
|
||||
}
|
||||
|
||||
libvas_handle = libvas;
|
||||
|
||||
if (resolve_vas_funcs() != 0)
|
||||
return;
|
||||
|
||||
if (VAS_ERR_SUCCESS == (vaserr = v_ctx_alloc(&sudo_vas_ctx))) {
|
||||
|
||||
if (VAS_ERR_SUCCESS == (vaserr = v_id_alloc(sudo_vas_ctx, "host/", &sudo_vas_id))) {
|
||||
|
||||
if (update_flags & VAS_NAME_FLAG_NO_LDAP) {
|
||||
sudo_vas_available = 1;
|
||||
return; /* OK */
|
||||
} else { /* Get a keytab */
|
||||
if ((vaserr = v_id_establish_cred_keytab( sudo_vas_ctx,
|
||||
sudo_vas_id,
|
||||
VAS_ID_FLAG_USE_MEMORY_CCACHE
|
||||
| VAS_ID_FLAG_KEEP_COPY_OF_CRED
|
||||
| VAS_ID_FLAG_NO_INITIAL_TGT,
|
||||
NULL )) == VAS_ERR_SUCCESS) {
|
||||
sudo_vas_available = 1;
|
||||
return; /* OK */
|
||||
}
|
||||
|
||||
if (!err_msg)
|
||||
set_err_msg("unable to establish creds: %s",
|
||||
v_err_get_string(sudo_vas_ctx, 1));
|
||||
}
|
||||
|
||||
v_id_free(sudo_vas_ctx, sudo_vas_id);
|
||||
sudo_vas_id = NULL;
|
||||
}
|
||||
|
||||
/* This is the last opportunity to get an error message from libvas */
|
||||
if (!err_msg)
|
||||
set_err_msg("Error initializing non-unix group checking: %s",
|
||||
v_err_get_string(sudo_vas_ctx, 1));
|
||||
|
||||
v_ctx_free(sudo_vas_ctx);
|
||||
sudo_vas_ctx = NULL;
|
||||
}
|
||||
|
||||
if (!err_msg)
|
||||
set_err_msg("Failed to get a libvas handle for non-unix group checking (unknown cause)");
|
||||
|
||||
sudo_vas_available = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clean up nonunix_groupcheck state.
|
||||
*/
|
||||
void
|
||||
sudo_nonunix_groupcheck_cleanup(void)
|
||||
{
|
||||
if (err_msg) {
|
||||
free(err_msg);
|
||||
err_msg = NULL;
|
||||
}
|
||||
|
||||
if (sudo_vas_available) {
|
||||
v_id_free(sudo_vas_ctx, sudo_vas_id);
|
||||
sudo_vas_id = NULL;
|
||||
|
||||
v_ctx_free(sudo_vas_ctx);
|
||||
sudo_vas_ctx = NULL;
|
||||
|
||||
sudo_vas_available = FALSE;
|
||||
}
|
||||
|
||||
if (libvas_handle) {
|
||||
if (dlclose(libvas_handle) != 0)
|
||||
warningx("dlclose() failed: %s", dlerror());
|
||||
libvas_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define RESOLVE_OR_ERR(fptr, sym) \
|
||||
do { \
|
||||
void *_fptr = dlsym(libvas_handle, (sym)); \
|
||||
if (!_fptr) { \
|
||||
set_err_msg("dlsym() failed: %s", dlerror()); \
|
||||
return -1; \
|
||||
} \
|
||||
fptr = _fptr; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* Resolve all the libvas functions.
|
||||
* Returns -1 and sets err_msg if something went wrong, or 0 on success.
|
||||
*/
|
||||
int
|
||||
resolve_vas_funcs(void)
|
||||
{
|
||||
if (!libvas_handle) /* assert */
|
||||
return -1;
|
||||
|
||||
RESOLVE_OR_ERR(v_ctx_alloc, "vas_ctx_alloc");
|
||||
RESOLVE_OR_ERR(v_ctx_free, "vas_ctx_free");
|
||||
RESOLVE_OR_ERR(v_id_alloc, "vas_id_alloc");
|
||||
RESOLVE_OR_ERR(v_id_free, "vas_id_free");
|
||||
RESOLVE_OR_ERR(v_id_establish_cred_keytab, "vas_id_establish_cred_keytab");
|
||||
RESOLVE_OR_ERR(v_user_init, "vas_user_init");
|
||||
RESOLVE_OR_ERR(v_user_free, "vas_user_free");
|
||||
RESOLVE_OR_ERR(v_group_init, "vas_group_init");
|
||||
RESOLVE_OR_ERR(v_group_free, "vas_group_free");
|
||||
RESOLVE_OR_ERR(v_user_is_member, "vas_user_is_member");
|
||||
RESOLVE_OR_ERR(v_err_get_string, "vas_err_get_string");
|
||||
|
||||
return 0;
|
||||
}
|
@@ -573,6 +573,13 @@ sudo_endspent(void)
|
||||
return;
|
||||
}
|
||||
|
||||
/* STUB */
|
||||
int
|
||||
group_plugin_query(const char *user, const char *group, const struct passwd *pw)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char *
|
||||
sudo_getepw(const struct passwd *pw)
|
||||
{
|
||||
|
@@ -80,10 +80,6 @@
|
||||
#include "sudo_plugin_int.h"
|
||||
#include <sudo_usage.h>
|
||||
|
||||
#ifdef USING_NONUNIX_GROUPS
|
||||
# include "nonunix.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables
|
||||
*/
|
||||
|
Reference in New Issue
Block a user