Include a sample plugin that can read Unix-format group files.
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
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
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
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
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
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@
/* The message given when a bad password is entered. */
#undef INCORRECT_PASSWORD
-/* The name of libvas.so */
-#undef LIBVAS_SO
-
/* The syslog facility sudo will use. */
#undef LOGFAC
/* Define to 1 if 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
with_interfaces
with_stow
with_askpass
-with_libvas
-with_libvas_rpath
with_plugin_dir
enable_authentication
enable_root_mailer
--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
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.
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"
;;
*-*-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=$?
-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.
-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.
-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
-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
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
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
;;
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}"
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
"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;;
-
;;
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
;;
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.
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
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
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.
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.
/* 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 */
--- /dev/null
+#
+# 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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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
+};
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@
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@
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
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
"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
}
#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,
use_pty
T_FLAG
"Always run commands in a pseudo-tty"
+group_plugin
+ T_STR
+ "Plugin for non-Unix group support"
--- /dev/null
+/*
+ * 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);
+}
#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;
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)
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);
}
+++ /dev/null
-/*
- * (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 */
#include "sudoers.h"
-#ifdef __TANDEM
-# define ROOT_UID 65535
-#else
-# define ROOT_UID 0
-#endif
-
/*
* Prototypes
*/
#include "interfaces.h"
#include "auth/sudo_auth.h"
-#ifdef USING_NONUNIX_GROUPS
-# include "nonunix.h"
-#endif
-
/*
* Prototypes
*/
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();
/* 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
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) {
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;
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();
}
#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
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;
(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
+++ /dev/null
-/*
- * (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;
-}
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)
{
#include "sudo_plugin_int.h"
#include <sudo_usage.h>
-#ifdef USING_NONUNIX_GROUPS
-# include "nonunix.h"
-#endif
-
/*
* Local variables
*/