Add wrapper functions for dlopen() et al so that we can support

statically compiling in the sudoers plugin but still allow other
plugins to be loaded.  The new --enable-static-sudoers configure
option will cause the sudoers plugin to be compiled statically into
the sudo binary.  This does not prevent other plugins from being
loaded as per sudo.conf.
This commit is contained in:
Todd C. Miller
2013-11-22 16:35:15 -07:00
parent 0fb17059a6
commit 12f3bdf60e
26 changed files with 579 additions and 369 deletions

View File

@@ -171,6 +171,14 @@ Compilation options:
binary itself. This will also disable the noexec option
as it too relies on dynamic shared object support.
--enable-static-sudoers
By default, the sudoers plugin is built and installed as a
dynamic shared object. When the --enable-static-sudoers
option is specified, the sudoers plugin is compiled directly
into the sudo binary. Unlike --disable-shared, this does
not prevent other plugins from being used and the noexec
option will continue to function.
--enable-zlib[=location]
Enable the use of the zlib compress library when storing
I/O log files. If specified, location is the base directory

View File

@@ -52,14 +52,13 @@ common/secure_path.c
common/setgroups.c
common/sudo_conf.c
common/sudo_debug.c
common/sudo_dso.c
common/sudo_printf.c
common/term.c
common/ttysize.c
compat/Makefile.in
compat/charclass.h
compat/closefrom.c
compat/dlfcn.h
compat/dlopen.c
compat/endian.h
compat/fnmatch.c
compat/fnmatch.h
@@ -150,6 +149,7 @@ include/queue.h
include/secure_path.h
include/sudo_conf.h
include/sudo_debug.h
include/sudo_dso.h
include/sudo_event.h
include/sudo_plugin.h
indent.pro

4
NEWS
View File

@@ -3,6 +3,10 @@ What's new in Sudo 1.8.9?
* Reworked sudo's main event loop to use a simple event subsystem
using poll(2) or select(2) as the back end.
* It is now possible to statically compile the sudoers plugin into
the sudo binary without disabling shared library support. The
sudo.conf file may still be used to configure other plugins.
What's new in Sudo 1.8.8?
* Removed a warning on PAM systems with stacked auth modules

View File

@@ -67,8 +67,8 @@ DEFS = @OSDEFS@ -D_PATH_SUDO_CONF=\"$(sysconfdir)/sudo.conf\"
SHELL = @SHELL@
LTOBJS = alloc.lo atobool.lo atoid.lo event.lo fatal.lo fileops.lo \
fmt_string.lo gidlist.lo lbuf.lo secure_path.lo \
setgroups.lo sudo_conf.lo sudo_debug.lo sudo_printf.lo term.lo \
fmt_string.lo gidlist.lo lbuf.lo secure_path.lo setgroups.lo \
sudo_conf.lo sudo_debug.lo sudo_dso.lo sudo_printf.lo term.lo \
ttysize.lo @COMMON_OBJS@
PARSELN_TEST_OBJS = parseln_test.lo locale_stub.lo
@@ -247,6 +247,9 @@ sudo_debug.lo: $(srcdir)/sudo_debug.c $(incdir)/alloc.h $(incdir)/fatal.h \
$(incdir)/sudo_plugin.h $(top_builddir)/config.h \
$(top_srcdir)/compat/stdbool.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sudo_debug.c
sudo_dso.lo: $(srcdir)/sudo_dso.c $(incdir)/missing.h $(incdir)/sudo_dso.h \
$(top_builddir)/config.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sudo_dso.c
sudo_printf.lo: $(srcdir)/sudo_printf.c $(incdir)/missing.h \
$(incdir)/sudo_debug.h $(incdir)/sudo_plugin.h \
$(top_builddir)/config.h

320
common/sudo_dso.c Normal file
View File

@@ -0,0 +1,320 @@
/*
* Copyright (c) 2010, 2012-2013 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 <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif /* STDC_HEADERS */
#ifdef HAVE_STRING_H
# include <string.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif /* HAVE_STRINGS_H */
#if defined(HAVE_SHL_LOAD)
# include <dl.h>
#elif defined(HAVE_DLOPEN)
# include <dlfcn.h>
#endif
#include <errno.h>
#include "sudo_dso.h"
#include "missing.h"
/*
* Pointer for statically compiled symbols.
*/
static struct sudo_preload_table *preload_table;
void
sudo_dso_preload_table(struct sudo_preload_table *table)
{
preload_table = table;
}
#if defined(HAVE_SHL_LOAD)
# ifndef DYNAMIC_PATH
# define DYNAMIC_PATH 0
# endif
void *
sudo_dso_load(const char *path, int mode)
{
struct sudo_preload_table *pt;
int flags = DYNAMIC_PATH | BIND_VERBOSE;
if (mode == 0)
mode = SUDO_DSO_LAZY; /* default behavior */
/* Check prelinked symbols first. */
if (preload_table != NULL) {
for (pt = preload_table; pt->handle != NULL; pt++) {
if (pt->path != NULL && strcmp(path, pt->path) == 0)
return pt->handle;
}
}
/* We don't support SUDO_DSO_GLOBAL or SUDO_DSO_LOCAL yet. */
if (ISSET(mode, SUDO_DSO_LAZY))
flags |= BIND_DEFERRED;
if (ISSET(mode, SUDO_DSO_NOW))
flags |= BIND_IMMEDIATE;
return (void *)shl_load(path, flags, 0L);
}
int
sudo_dso_unload(void *handle)
{
struct sudo_preload_table *pt;
/* Check prelinked symbols first. */
if (preload_table != NULL) {
for (pt = preload_table; pt->handle != NULL; pt++) {
if (pt->handle == handle)
return 0;
}
}
return shl_unload((shl_t)handle);
}
void *
sudo_dso_findsym(void *vhandle, const char *symbol)
{
struct sudo_preload_table *pt;
shl_t handle = vhandle;
void *value = NULL;
/* Check prelinked symbols first. */
if (preload_table != NULL) {
for (pt = preload_table; pt->handle != NULL; pt++) {
if (pt->handle == handle) {
struct sudo_preload_symbol *sym;
for (sym = pt->symbols; sym->name != NULL; sym++) {
if (strcmp(sym->name, symbol) == 0)
return sym->addr;
}
errno = ENOENT;
return NULL;
}
}
}
/*
* Note that the behavior of of SUDO_DSO_NEXT and SUDO_DSO_SELF
* differs from most implementations when called from
* a shared library.
*/
if (vhandle == SUDO_DSO_NEXT) {
/* Iterate over all shared libs looking for symbol. */
struct shl_descriptor *desc;
int idx = 0;
while (shl_get(idx++, &desc) == 0) {
if (shl_findsym(&desc->handle, symbol, TYPE_UNDEFINED, &value) == 0)
break;
}
} else {
if (vhandle == SUDO_DSO_DEFAULT)
handle = NULL;
else if (vhandle == SUDO_DSO_SELF)
handle = PROG_HANDLE;
(void)shl_findsym(&handle, symbol, TYPE_UNDEFINED, &value);
}
return value;
}
char *
sudo_dso_strerror(void)
{
return strerror(errno);
}
#elif defined(HAVE_DLOPEN)
# ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
# endif
void *
sudo_dso_load(const char *path, int mode)
{
struct sudo_preload_table *pt;
int flags = 0;
/* Check prelinked symbols first. */
if (preload_table != NULL) {
for (pt = preload_table; pt->handle != NULL; pt++) {
if (pt->path != NULL && strcmp(path, pt->path) == 0)
return pt->handle;
}
}
/* Map SUDO_DSO_* -> RTLD_* */
if (ISSET(mode, SUDO_DSO_LAZY))
flags |= RTLD_LAZY;
if (ISSET(mode, SUDO_DSO_NOW))
flags |= RTLD_NOW;
if (ISSET(mode, SUDO_DSO_GLOBAL))
flags |= RTLD_GLOBAL;
if (ISSET(mode, SUDO_DSO_LOCAL))
flags |= RTLD_LOCAL;
return dlopen(path, flags);
}
int
sudo_dso_unload(void *handle)
{
struct sudo_preload_table *pt;
/* Check prelinked symbols first. */
if (preload_table != NULL) {
for (pt = preload_table; pt->handle != NULL; pt++) {
if (pt->handle == handle)
return 0;
}
}
return dlclose(handle);
}
void *
sudo_dso_findsym(void *handle, const char *symbol)
{
struct sudo_preload_table *pt;
/* Check prelinked symbols first. */
if (preload_table != NULL) {
for (pt = preload_table; pt->handle != NULL; pt++) {
if (pt->handle == handle) {
struct sudo_preload_symbol *sym;
for (sym = pt->symbols; sym->name != NULL; sym++) {
if (strcmp(sym->name, symbol) == 0)
return sym->addr;
}
errno = ENOENT;
return NULL;
}
}
}
/*
* Not all implementations support the special handles.
*/
if (handle == SUDO_DSO_NEXT) {
# ifdef RTLD_NEXT
handle = RTLD_NEXT;
# else
errno = ENOENT;
return NULL;
# endif
} else if (handle == SUDO_DSO_DEFAULT) {
# ifdef RTLD_DEFAULT
handle = RTLD_DEFAULT;
# else
errno = ENOENT;
return NULL;
# endif
} else if (handle == SUDO_DSO_SELF) {
# ifdef RTLD_SELF
handle = RTLD_SELF;
# else
errno = ENOENT;
return NULL;
# endif
}
return dlsym(handle, symbol);
}
char *
sudo_dso_strerror(void)
{
return dlerror();
}
#else /* !HAVE_SHL_LOAD && !HAVE_DLOPEN */
/*
* Emulate dlopen() using a static list of symbols compiled into sudo.
*/
void *
sudo_dso_load(const char *path, int mode)
{
struct sudo_preload_table *pt;
/* Check prelinked symbols first. */
if (preload_table != NULL) {
for (pt = preload_table; pt->handle != NULL; pt++) {
if (pt->path != NULL && strcmp(path, pt->path) == 0)
return pt->handle;
}
}
return NULL;
}
int
sudo_dso_unload(void *handle)
{
struct sudo_preload_table *pt;
if (preload_table != NULL) {
for (pt = preload_table; pt->handle != NULL; pt++) {
if (pt->handle == handle)
return 0;
}
}
return -1;
}
void *
sudo_dso_findsym(void *handle, const char *symbol)
{
struct sudo_preload_table *pt;
if (preload_table != NULL) {
for (pt = preload_table; pt->handle != NULL; pt++) {
if (pt->handle == handle) {
struct sudo_preload_symbol *sym;
for (sym = pt->symbols; sym->name != NULL; sym++) {
if (strcmp(sym->name, symbol) == 0)
return sym->addr;
}
}
}
}
errno = ENOENT;
return NULL;
}
char *
sudo_dso_strerror(void)
{
return strerror(errno);
}
#endif /* !HAVE_SHL_LOAD && !HAVE_DLOPEN */

View File

@@ -166,9 +166,6 @@ cleandir: realclean
# Autogenerated dependencies, do not modify
closefrom.lo: $(srcdir)/closefrom.c $(incdir)/missing.h $(top_builddir)/config.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/closefrom.c
dlopen.lo: $(srcdir)/dlopen.c $(incdir)/missing.h $(top_builddir)/config.h \
$(top_srcdir)/compat/dlfcn.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/dlopen.c
fnm_test.o: $(srcdir)/regress/fnmatch/fnm_test.c $(incdir)/missing.h \
$(top_builddir)/config.h $(top_srcdir)/compat/fnmatch.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/regress/fnmatch/fnm_test.c

View File

@@ -1,43 +0,0 @@
/*
* 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.
*/
#ifndef _DLFCN_H_
#define _DLFCN_H_
/* Emulated functions. */
void *sudo_dlopen(const char *path, int mode);
int sudo_dlclose(void *handle);
void *sudo_dlsym(void *handle, const char *symbol);
char *sudo_dlerror(void);
/* Map emulated functions to standard names. */
#define dlopen(p, m) sudo_dlopen(p, m)
#define dlclose(h) sudo_dlclose(h)
#define dlsym(h, s) sudo_dlsym(h, s)
#define dlerror() sudo_dlerror()
/* Values for dlopen() mode. */
#define RTLD_LAZY 0x1
#define RTLD_NOW 0x2
#define RTLD_GLOBAL 0x4
#define RTLD_LOCAL 0x8
/* Special handle arguments for dlsym(). */
#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */
#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */
#define RTLD_SELF ((void *) -3) /* Search the caller itself. */
#endif /* !_DLFCN_H_ */

View File

@@ -1,156 +0,0 @@
/*
* Copyright (c) 2010, 2012-2013 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>
#ifndef HAVE_DLOPEN
#include <sys/types.h>
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif /* STDC_HEADERS */
#ifdef HAVE_STRING_H
# include <string.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif /* HAVE_STRINGS_H */
#include <errno.h>
#include "compat/dlfcn.h"
#include "missing.h"
#ifdef HAVE_SHL_LOAD
/*
* Emulate dlopen() using shl_load().
*/
#include <dl.h>
#ifndef DYNAMIC_PATH
# define DYNAMIC_PATH 0
#endif
void *
sudo_dlopen(const char *path, int mode)
{
int flags = DYNAMIC_PATH | BIND_VERBOSE;
if (mode == 0)
mode = RTLD_LAZY; /* default behavior */
/* We don't support RTLD_GLOBAL or RTLD_LOCAL yet. */
if (ISSET(mode, RTLD_LAZY))
flags |= BIND_DEFERRED;
if (ISSET(mode, RTLD_NOW))
flags |= BIND_IMMEDIATE;
return (void *)shl_load(path, flags, 0L);
}
int
sudo_dlclose(void *handle)
{
return shl_unload((shl_t)handle);
}
void *
sudo_dlsym(void *vhandle, const char *symbol)
{
shl_t handle = vhandle;
void *value = NULL;
/*
* Note that the behavior of of RTLD_NEXT and RTLD_SELF
* differs from most implementations when called from
* a shared library.
*/
if (vhandle == RTLD_NEXT) {
/* Iterate over all shared libs looking for symbol. */
struct shl_descriptor *desc;
int idx = 0;
while (shl_get(idx++, &desc) == 0) {
if (shl_findsym(&desc->handle, symbol, TYPE_UNDEFINED, &value) == 0)
break;
}
} else {
if (vhandle == RTLD_DEFAULT)
handle = NULL;
else if (vhandle == RTLD_SELF)
handle = PROG_HANDLE;
(void)shl_findsym(&handle, symbol, TYPE_UNDEFINED, &value);
}
return value;
}
char *
sudo_dlerror(void)
{
return strerror(errno);
}
#else /* !HAVE_SHL_LOAD */
/*
* Emulate dlopen() using a static list of symbols compiled into sudo.
*/
struct sudo_preload_table {
const char *name;
void *address;
};
extern struct sudo_preload_table sudo_preload_table[];
void *
sudo_dlopen(const char *path, int mode)
{
return (void *)path;
}
int
sudo_dlclose(void *handle)
{
return 0;
}
void *
sudo_dlsym(void *handle, const char *symbol)
{
struct sudo_preload_table *sym;
if (symbol != RTLD_NEXT && symbol != RTLD_DEFAULT && symbol != RTLD_SELF) {
for (sym = sudo_preload_table; sym->name != NULL; sym++) {
if (strcmp(symbol, sym->name) == 0)
return sym->address;
}
}
return NULL;
}
char *
sudo_dlerror(void)
{
return strerror(errno);
}
#endif /* HAVE_SHL_LOAD */
#endif /* HAVE_DLOPEN */

View File

@@ -987,15 +987,16 @@
/* The size of `long int', as computed by sizeof. */
#undef SIZEOF_LONG_INT
/* Define to 1 to compile the sudoers plugin statically into the sudo binary.
*/
#undef STATIC_SUDOERS_PLUGIN
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if the code in interfaces.c does not compile for you. */
#undef STUB_LOAD_INTERFACES
/* The name of the sudoers plugin, including extension. */
#undef SUDOERS_PLUGIN
/* An instance string to append to the username (separated by a slash) for
Kerberos V authentication. */
#undef SUDO_KRB5_INSTANCE

51
configure vendored
View File

@@ -928,6 +928,7 @@ enable_poll
enable_admin_flag
enable_nls
enable_rpath
enable_static_sudoers
with_selinux
enable_gss_krb5_ccache_name
enable_shared
@@ -1594,6 +1595,8 @@ Optional Features:
--enable-admin-flag Whether to create a Ubuntu-style admin flag file
--disable-nls Disable natural language support using gettext
--disable-rpath Disable passing of -Rpath to the linker
--enable-static-sudoers Build the sudoers policy module as part of the sudo
binary instead as a plugin
--enable-gss-krb5-ccache-name
Use GSS-API to set the Kerberos V cred cache name
--enable-shared[=PKGS] build shared libraries [default=yes]
@@ -5725,6 +5728,14 @@ else
fi
# Check whether --enable-static-sudoers was given.
if test "${enable_static_sudoers+set}" = set; then :
enableval=$enable_static_sudoers;
else
enable_static_sudoers=no
fi
# Check whether --with-selinux was given.
if test "${with_selinux+set}" = set; then :
@@ -20991,20 +21002,32 @@ case "$lt_cv_dlopen" in
dlopen)
$as_echo "#define HAVE_DLOPEN 1" >>confdefs.h
SUDO_OBJS="$SUDO_OBJS locale_stub.o"
LT_STATIC="--tag=disable-static"
if test "$enable_static_sudoers" = "yes"; then
$as_echo "#define STATIC_SUDOERS_PLUGIN 1" >>confdefs.h
SUDO_OBJS="${SUDO_OBJS} preload.o"
SUDO_LIBS="${SUDO_LIBS} \$(top_builddir)/plugins/sudoers/sudoers.la"
SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} --tag=disable-shared -static"
LT_STATIC=""
else
SUDO_OBJS="$SUDO_OBJS locale_stub.o"
LT_STATIC="--tag=disable-static"
fi
;;
shl_load)
$as_echo "#define HAVE_SHL_LOAD 1" >>confdefs.h
SUDO_OBJS="$SUDO_OBJS locale_stub.o"
LT_STATIC="--tag=disable-static"
case " $LIBOBJS " in
*" dlopen.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS dlopen.$ac_objext"
;;
esac
if test "$enable_static_sudoers" = "yes"; then
$as_echo "#define STATIC_SUDOERS_PLUGIN 1" >>confdefs.h
SUDO_OBJS="${SUDO_OBJS} preload.o"
SUDO_LIBS="${SUDO_LIBS} \$(top_builddir)/plugins/sudoers/sudoers.la"
SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} --tag=disable-shared -static"
LT_STATIC=""
else
SUDO_OBJS="$SUDO_OBJS locale_stub.o"
LT_STATIC="--tag=disable-static"
fi
;;
*)
if test X"${ac_cv_func_dlopen}" = X"yes"; then
@@ -21014,12 +21037,6 @@ esac
SUDO_OBJS="${SUDO_OBJS} preload.o"
SUDO_LIBS="${SUDO_LIBS} \$(top_builddir)/plugins/sudoers/sudoers.la"
LT_STATIC=""
case " $LIBOBJS " in
*" dlopen.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS dlopen.$ac_objext"
;;
esac
;;
esac
@@ -22026,10 +22043,6 @@ EOF
done
cat >>confdefs.h <<EOF
#define _PATH_SUDO_PLUGIN_DIR "$PLUGINDIR/"
EOF
cat >>confdefs.h <<EOF
#define SUDOERS_PLUGIN "sudoers.so"
EOF
fi

View File

@@ -1412,6 +1412,10 @@ AC_ARG_ENABLE(rpath,
[AS_HELP_STRING([--disable-rpath], [Disable passing of -Rpath to the linker])],
[], [enable_rpath=yes])
AC_ARG_ENABLE(static-sudoers,
[AS_HELP_STRING([--enable-static-sudoers], [Build the sudoers policy module as part of the sudo binary instead as a plugin])],
[], [enable_static_sudoers=no])
AC_ARG_WITH(selinux, [AS_HELP_STRING([--with-selinux], [enable SELinux support])],
[case $with_selinux in
yes) SELINUX_USAGE="[[-r role]] [[-t type]] "
@@ -3320,14 +3324,29 @@ fi
case "$lt_cv_dlopen" in
dlopen)
AC_DEFINE(HAVE_DLOPEN)
SUDO_OBJS="$SUDO_OBJS locale_stub.o"
LT_STATIC="--tag=disable-static"
if test "$enable_static_sudoers" = "yes"; then
AC_DEFINE(STATIC_SUDOERS_PLUGIN)
SUDO_OBJS="${SUDO_OBJS} preload.o"
SUDO_LIBS="${SUDO_LIBS} \$(top_builddir)/plugins/sudoers/sudoers.la"
SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} --tag=disable-shared -static"
LT_STATIC=""
else
SUDO_OBJS="$SUDO_OBJS locale_stub.o"
LT_STATIC="--tag=disable-static"
fi
;;
shl_load)
AC_DEFINE(HAVE_SHL_LOAD)
SUDO_OBJS="$SUDO_OBJS locale_stub.o"
LT_STATIC="--tag=disable-static"
AC_LIBOBJ(dlopen)
if test "$enable_static_sudoers" = "yes"; then
AC_DEFINE(STATIC_SUDOERS_PLUGIN)
SUDO_OBJS="${SUDO_OBJS} preload.o"
SUDO_LIBS="${SUDO_LIBS} \$(top_builddir)/plugins/sudoers/sudoers.la"
SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} --tag=disable-shared -static"
LT_STATIC=""
else
SUDO_OBJS="$SUDO_OBJS locale_stub.o"
LT_STATIC="--tag=disable-static"
fi
;;
*)
if test X"${ac_cv_func_dlopen}" = X"yes"; then
@@ -3337,7 +3356,6 @@ case "$lt_cv_dlopen" in
SUDO_OBJS="${SUDO_OBJS} preload.o"
SUDO_LIBS="${SUDO_LIBS} \$(top_builddir)/plugins/sudoers/sudoers.la"
LT_STATIC=""
AC_LIBOBJ(dlopen)
;;
esac
@@ -3684,7 +3702,6 @@ if test X"$with_noexec" != X"no" -o X"$with_selinux" != X"no" -o "$enabled_share
eval PLUGINDIR="$_PLUGINDIR"
done
SUDO_DEFINE_UNQUOTED(_PATH_SUDO_PLUGIN_DIR, "$PLUGINDIR/")
SUDO_DEFINE_UNQUOTED(SUDOERS_PLUGIN, "sudoers.so")
fi
exec_prefix="$oexec_prefix"
fi
@@ -3752,7 +3769,6 @@ dnl
AH_TEMPLATE(BROKEN_SYSLOG, [Define to 1 if the `syslog' function returns a non-zero int to denote failure.])
AH_TEMPLATE(CLASSIC_INSULTS, [Define to 1 if you want the insults from the "classic" version sudo.])
AH_TEMPLATE(CSOPS_INSULTS, [Define to 1 if you want insults culled from the twisted minds of CSOps.])
AH_TEMPLATE(SUDOERS_PLUGIN, [The name of the sudoers plugin, including extension.])
AH_TEMPLATE(DONT_LEAK_PATH_INFO, [Define to 1 if you want sudo to display "command not allowed" instead of "command not found" when a command cannot be found.])
AH_TEMPLATE(ENV_DEBUG, [Define to 1 to enable environment function debugging.])
AH_TEMPLATE(ENV_EDITOR, [Define to 1 if you want visudo to honor the EDITOR and VISUAL env variables.])
@@ -3824,6 +3840,7 @@ AH_TEMPLATE(SEND_MAIL_WHEN_NO_HOST, [Define to 1 to send mail when the user is n
AH_TEMPLATE(SEND_MAIL_WHEN_NO_USER, [Define to 1 to send mail when the user is not in the sudoers file.])
AH_TEMPLATE(SHELL_IF_NO_ARGS, [Define to 1 if you want sudo to start a shell if given no arguments.])
AH_TEMPLATE(SHELL_SETS_HOME, [Define to 1 if you want sudo to set $HOME in shell mode.])
AH_TEMPLATE(STATIC_SUDOERS_PLUGIN, [Define to 1 to compile the sudoers plugin statically into the sudo binary.])
AH_TEMPLATE(STUB_LOAD_INTERFACES, [Define to 1 if the code in interfaces.c does not compile for you.])
AH_TEMPLATE(UMASK_OVERRIDE, [Define to 1 to use the umask specified in sudoers even when it is less restrictive than the invoking user's.])
AH_TEMPLATE(USE_ADMIN_FLAG, [Define to 1 if you want to create ~/.sudo_as_admin_successful if the user is in the admin group the first time they run sudo.])

49
include/sudo_dso.h Normal file
View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2010, 2013 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SUDO_DSO_H
#define _SUDO_DSO_H
/* Values for sudo_dso_load() mode. */
#define SUDO_DSO_LAZY 0x1
#define SUDO_DSO_NOW 0x2
#define SUDO_DSO_GLOBAL 0x4
#define SUDO_DSO_LOCAL 0x8
/* Special handle arguments for sudo_dso_findsym(). */
#define SUDO_DSO_NEXT ((void *)-1) /* Search subsequent objects. */
#define SUDO_DSO_DEFAULT ((void *)-2) /* Use default search algorithm. */
#define SUDO_DSO_SELF ((void *)-3) /* Search the caller itself. */
/* Internal structs for static linking of plugins. */
struct sudo_preload_symbol {
const char *name;
void *addr;
};
struct sudo_preload_table {
const char *path;
void *handle;
struct sudo_preload_symbol *symbols;
};
/* Public functions. */
char *sudo_dso_strerror(void);
int sudo_dso_unload(void *handle);
void *sudo_dso_findsym(void *handle, const char *symbol);
void *sudo_dso_load(const char *path, int mode);
void sudo_dso_preload_table(struct sudo_preload_table *table);
#endif /* _SUDO_DSO_H */

View File

@@ -70,7 +70,7 @@ sub mkdep {
$makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo sssd.lo:;
# XXX - fill in AUTH_OBJS from contents of the auth dir instead
$makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
$makefile =~ s:\@LTLIBOBJS\@:closefrom.lo dlopen.lo fnmatch.lo getaddrinfo.lo getcwd.lo getgrouplist.lo getline.lo getprogname.lo getopt_long.lo glob.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo pw_dup.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo utimes.lo globtest.o fnm_test.o:;
$makefile =~ s:\@LTLIBOBJS\@:closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getgrouplist.lo getline.lo getprogname.lo getopt_long.lo glob.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo pw_dup.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo utimes.lo globtest.o fnm_test.o:;
# Parse OBJS lines
my %objs;

View File

@@ -328,7 +328,7 @@ check: $(TEST_PROGS) visudo testsudoers
diff regress/parser/check_digest.out $(srcdir)/regress/parser/check_digest.out.ok || rval=`expr $$rval + $$?`; \
./check_fill || rval=`expr $$rval + $$?`; \
./check_iolog_path $(srcdir)/regress/iolog_path/data || rval=`expr $$rval + $$?`; \
if [ X"$(soext)" != X"" ]; then \
if [ X"$(soext)" != X"" -a -e .libs/sudoers$(soext) ]; then \
./check_symbols .libs/sudoers$(soext) $(shlib_exp) || rval=`expr $$rval + $$?`; \
fi; \
mkdir -p regress/logging; \
@@ -513,8 +513,8 @@ check_iolog_path.o: $(srcdir)/regress/iolog_path/check_iolog_path.c \
$(top_srcdir)/compat/stdbool.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/regress/iolog_path/check_iolog_path.c
check_symbols.o: $(srcdir)/regress/check_symbols/check_symbols.c \
$(incdir)/fatal.h $(incdir)/missing.h \
$(top_builddir)/config.h $(top_srcdir)/compat/dlfcn.h
$(incdir)/fatal.h $(incdir)/missing.h $(incdir)/sudo_dso.h \
$(top_builddir)/config.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/regress/check_symbols/check_symbols.c
check_wrap.o: $(srcdir)/regress/logging/check_wrap.c $(incdir)/fatal.h \
$(incdir)/missing.h $(incdir)/sudo_plugin.h \
@@ -587,10 +587,10 @@ gram.lo: $(devdir)/gram.c $(devdir)/def_data.h $(incdir)/alloc.h \
group_plugin.lo: $(srcdir)/group_plugin.c $(devdir)/def_data.h \
$(incdir)/alloc.h $(incdir)/fatal.h $(incdir)/fileops.h \
$(incdir)/gettext.h $(incdir)/missing.h $(incdir)/queue.h \
$(incdir)/sudo_debug.h $(incdir)/sudo_plugin.h \
$(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
$(srcdir)/sudoers.h $(top_builddir)/config.h \
$(top_builddir)/pathnames.h $(top_srcdir)/compat/dlfcn.h \
$(incdir)/sudo_debug.h $(incdir)/sudo_dso.h \
$(incdir)/sudo_plugin.h $(srcdir)/defaults.h \
$(srcdir)/logging.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
$(top_builddir)/config.h $(top_builddir)/pathnames.h \
$(top_srcdir)/compat/stdbool.h
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/group_plugin.c
group_plugin.o: group_plugin.lo
@@ -634,11 +634,10 @@ kerb5.lo: $(authdir)/kerb5.c $(devdir)/def_data.h $(incdir)/alloc.h \
ldap.lo: $(srcdir)/ldap.c $(devdir)/def_data.h $(incdir)/alloc.h \
$(incdir)/fatal.h $(incdir)/fileops.h $(incdir)/gettext.h \
$(incdir)/lbuf.h $(incdir)/missing.h $(incdir)/queue.h \
$(incdir)/sudo_debug.h $(incdir)/sudo_plugin.h $(srcdir)/defaults.h \
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
$(srcdir)/sudoers.h $(top_builddir)/config.h \
$(top_builddir)/pathnames.h $(top_srcdir)/compat/dlfcn.h \
$(top_srcdir)/compat/stdbool.h
$(incdir)/sudo_debug.h $(incdir)/sudo_dso.h $(incdir)/sudo_plugin.h \
$(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(top_builddir)/config.h \
$(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/ldap.c
linux_audit.lo: $(srcdir)/linux_audit.c $(incdir)/alloc.h $(incdir)/fatal.h \
$(incdir)/gettext.h $(incdir)/missing.h $(incdir)/sudo_debug.h \
@@ -790,11 +789,10 @@ sia.lo: $(authdir)/sia.c $(devdir)/def_data.h $(incdir)/alloc.h \
sssd.lo: $(srcdir)/sssd.c $(devdir)/def_data.h $(incdir)/alloc.h \
$(incdir)/fatal.h $(incdir)/fileops.h $(incdir)/gettext.h \
$(incdir)/lbuf.h $(incdir)/missing.h $(incdir)/queue.h \
$(incdir)/sudo_debug.h $(incdir)/sudo_plugin.h $(srcdir)/defaults.h \
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
$(srcdir)/sudoers.h $(top_builddir)/config.h \
$(top_builddir)/pathnames.h $(top_srcdir)/compat/dlfcn.h \
$(top_srcdir)/compat/stdbool.h
$(incdir)/sudo_debug.h $(incdir)/sudo_dso.h $(incdir)/sudo_plugin.h \
$(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(top_builddir)/config.h \
$(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sssd.c
sudo_auth.lo: $(authdir)/sudo_auth.c $(devdir)/def_data.h $(incdir)/alloc.h \
$(incdir)/fatal.h $(incdir)/fileops.h $(incdir)/gettext.h \

View File

@@ -40,20 +40,12 @@
#ifdef TIME_WITH_SYS_TIME
# include <time.h>
#endif
#ifdef HAVE_DLOPEN
# include <dlfcn.h>
#else
# include "compat/dlfcn.h"
#endif
#include <ctype.h>
#include <errno.h>
#include <pwd.h>
#include "sudoers.h"
#ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
#endif
#include "sudo_dso.h"
#if defined(HAVE_DLOPEN) || defined(HAVE_SHL_LOAD)
@@ -108,12 +100,12 @@ group_plugin_load(char *plugin_info)
}
/* Open plugin and map in symbol. */
group_handle = dlopen(path, RTLD_LAZY|RTLD_GLOBAL);
group_handle = sudo_dso_load(path, SUDO_DSO_LAZY|SUDO_DSO_GLOBAL);
if (!group_handle) {
warningx(U_("unable to dlopen %s: %s"), path, dlerror());
warningx(U_("unable to load %s: %s"), path, sudo_dso_strerror());
goto done;
}
group_plugin = dlsym(group_handle, "group_plugin");
group_plugin = sudo_dso_findsym(group_handle, "group_plugin");
if (group_plugin == NULL) {
warningx(U_("unable to find symbol \"group_plugin\" in %s"), path);
goto done;
@@ -157,7 +149,7 @@ done:
if (rc != true) {
if (group_handle != NULL) {
dlclose(group_handle);
sudo_dso_unload(group_handle);
group_handle = NULL;
group_plugin = NULL;
}
@@ -176,7 +168,7 @@ group_plugin_unload(void)
group_plugin = NULL;
}
if (group_handle != NULL) {
dlclose(group_handle);
sudo_dso_unload(group_handle);
group_handle = NULL;
}
debug_return;

View File

@@ -64,16 +64,12 @@
# else
# include <sasl.h>
# endif
# ifdef HAVE_DLOPEN
# include <dlfcn.h>
# else
# include "compat/dlfcn.h"
# endif
#endif /* HAVE_LDAP_SASL_INTERACTIVE_BIND_S */
#include "sudoers.h"
#include "parse.h"
#include "lbuf.h"
#include "sudo_dso.h"
/* Older Netscape LDAP SDKs don't prototype ldapssl_set_strength() */
#if defined(HAVE_LDAPSSL_SET_STRENGTH) && !defined(HAVE_LDAP_SSL_H) && !defined(HAVE_MPS_LDAP_SSL_H)
@@ -2046,7 +2042,8 @@ sudo_set_krb5_ccache_name(const char *name, const char **old_name)
debug_decl(sudo_set_krb5_ccache_name, SUDO_DEBUG_LDAP)
if (!initialized) {
sudo_gss_krb5_ccache_name = dlsym(RTLD_DEFAULT, "gss_krb5_ccache_name");
sudo_gss_krb5_ccache_name =
sudo_dso_findsym(SUDO_DSO_DEFAULT, "gss_krb5_ccache_name");
initialized = true;
}

View File

@@ -35,21 +35,13 @@
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif /* HAVE_STRINGS_H */
#ifdef HAVE_DLOPEN
# include <dlfcn.h>
#else
# include "compat/dlfcn.h"
#endif
#include <errno.h>
#include <limits.h>
#include "missing.h"
#include "sudo_dso.h"
#include "fatal.h"
#ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
#endif
#ifndef LINE_MAX
# define LINE_MAX 2048
#endif
@@ -82,9 +74,9 @@ main(int argc, char *argv[])
plugin_path = argv[1];
symbols_file = argv[2];
handle = dlopen(plugin_path, RTLD_LAZY|RTLD_GLOBAL);
handle = sudo_dso_load(plugin_path, SUDO_DSO_LAZY|SUDO_DSO_GLOBAL);
if (handle == NULL)
fatalx_nodebug("unable to dlopen %s: %s", plugin_path, dlerror());
fatalx_nodebug("unable to load %s: %s", plugin_path, sudo_dso_strerror());
fp = fopen(symbols_file, "r");
if (fp == NULL)
@@ -94,10 +86,10 @@ main(int argc, char *argv[])
ntests++;
if ((cp = strchr(line, '\n')) != NULL)
*cp = '\0';
sym = dlsym(handle, line);
sym = sudo_dso_findsym(handle, line);
if (sym == NULL) {
printf("%s: test %d: unable to resolve symbol %s: %s\n",
getprogname(), ntests, line, dlerror());
getprogname(), ntests, line, sudo_dso_strerror());
errors++;
}
}
@@ -106,14 +98,14 @@ main(int argc, char *argv[])
* Make sure unexported symbols are not available.
*/
ntests++;
sym = dlsym(handle, "user_in_group");
sym = sudo_dso_findsym(handle, "user_in_group");
if (sym != NULL) {
printf("%s: test %d: able to resolve local symbol user_in_group\n",
getprogname(), ntests);
errors++;
}
dlclose(handle);
sudo_dso_unload(handle);
printf("%s: %d tests run, %d errors, %d%% success rate\n", getprogname(),
ntests, errors, (ntests - errors) * 100 / ntests);

View File

@@ -43,11 +43,6 @@
#ifdef TIME_WITH_SYS_TIME
# include <time.h>
#endif
#ifdef HAVE_DLOPEN
# include <dlfcn.h>
#else
# include "compat/dlfcn.h"
#endif
#include <ctype.h>
#include <pwd.h>
#include <grp.h>
@@ -58,6 +53,7 @@
#include "sudoers.h"
#include "parse.h"
#include "lbuf.h"
#include "sudo_dso.h"
#include "sudo_debug.h"
/* SSSD <--> SUDO interface - do not change */
@@ -250,14 +246,15 @@ static int sudo_sss_open(struct sudo_nss *nss)
handle = emalloc(sizeof(struct sudo_sss_handle));
/* Load symbols */
handle->ssslib = dlopen(path, RTLD_LAZY);
handle->ssslib = sudo_dso_load(path, SUDO_DSO_LAZY);
if (handle->ssslib == NULL) {
warningx(U_("unable to dlopen %s: %s"), path, dlerror());
warningx(U_("unable to load %s: %s"), path, sudo_dso_strerror());
warningx(U_("unable to initialize SSS source. Is SSSD installed on your machine?"));
debug_return_int(EFAULT);
}
handle->fn_send_recv = dlsym(handle->ssslib, "sss_sudo_send_recv");
handle->fn_send_recv =
sudo_dso_findsym(handle->ssslib, "sss_sudo_send_recv");
if (handle->fn_send_recv == NULL) {
warningx(U_("unable to find symbol \"%s\" in %s"), path,
"sss_sudo_send_recv");
@@ -265,28 +262,31 @@ static int sudo_sss_open(struct sudo_nss *nss)
}
handle->fn_send_recv_defaults =
dlsym(handle->ssslib, "sss_sudo_send_recv_defaults");
sudo_dso_findsym(handle->ssslib, "sss_sudo_send_recv_defaults");
if (handle->fn_send_recv_defaults == NULL) {
warningx(U_("unable to find symbol \"%s\" in %s"), path,
"sss_sudo_send_recv_defaults");
debug_return_int(EFAULT);
}
handle->fn_free_result = dlsym(handle->ssslib, "sss_sudo_free_result");
handle->fn_free_result =
sudo_dso_findsym(handle->ssslib, "sss_sudo_free_result");
if (handle->fn_free_result == NULL) {
warningx(U_("unable to find symbol \"%s\" in %s"), path,
"sss_sudo_free_result");
debug_return_int(EFAULT);
}
handle->fn_get_values = dlsym(handle->ssslib, "sss_sudo_get_values");
handle->fn_get_values =
sudo_dso_findsym(handle->ssslib, "sss_sudo_get_values");
if (handle->fn_get_values == NULL) {
warningx(U_("unable to find symbol \"%s\" in %s"), path,
"sss_sudo_get_values");
debug_return_int(EFAULT);
}
handle->fn_free_values = dlsym(handle->ssslib, "sss_sudo_free_values");
handle->fn_free_values =
sudo_dso_findsym(handle->ssslib, "sss_sudo_free_values");
if (handle->fn_free_values == NULL) {
warningx(U_("unable to find symbol \"%s\" in %s"), path,
"sss_sudo_free_values");
@@ -310,7 +310,7 @@ static int sudo_sss_close(struct sudo_nss *nss)
if (nss && nss->handle) {
handle = nss->handle;
dlclose(handle->ssslib);
sudo_dso_unload(handle->ssslib);
}
efree(nss->handle);

View File

@@ -145,6 +145,6 @@ cleandir: realclean
# Autogenerated dependencies, do not modify
system_group.lo: $(srcdir)/system_group.c $(incdir)/missing.h \
$(incdir)/sudo_plugin.h $(top_builddir)/config.h \
$(top_srcdir)/compat/dlfcn.h $(top_srcdir)/compat/stdbool.h
$(incdir)/sudo_dso.h $(incdir)/sudo_plugin.h \
$(top_builddir)/config.h $(top_srcdir)/compat/stdbool.h
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/system_group.c

View File

@@ -45,11 +45,6 @@
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_DLOPEN
# include <dlfcn.h>
#else
# include "compat/dlfcn.h"
#endif
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@@ -59,10 +54,7 @@
#include "sudo_plugin.h"
#include "missing.h"
#ifndef RTLD_DEFAULT
# define RTLD_DEFAULT NULL
#endif
#include "sudo_dso.h"
/*
* Sudoers group plugin that does group name-based lookups using the system
@@ -97,7 +89,7 @@ sysgroup_init(int version, sudo_printf_t sudo_printf, char *const argv[])
}
/* Share group cache with sudo if possible. */
handle = dlsym(RTLD_DEFAULT, "sudo_getgrnam");
handle = sudo_dso_findsym(SUDO_DSO_DEFAULT, "sudo_getgrnam");
if (handle != NULL) {
sysgroup_getgrnam = (sysgroup_getgrnam_t)handle;
} else {
@@ -105,7 +97,7 @@ sysgroup_init(int version, sudo_printf_t sudo_printf, char *const argv[])
need_setent = true;
}
handle = dlsym(RTLD_DEFAULT, "sudo_getgrgid");
handle = sudo_dso_findsym(SUDO_DSO_DEFAULT, "sudo_getgrgid");
if (handle != NULL) {
sysgroup_getgrgid = (sysgroup_getgrgid_t)handle;
} else {
@@ -113,7 +105,7 @@ sysgroup_init(int version, sudo_printf_t sudo_printf, char *const argv[])
need_setent = true;
}
handle = dlsym(RTLD_DEFAULT, "sudo_gr_delref");
handle = sudo_dso_findsym(SUDO_DSO_DEFAULT, "sudo_gr_delref");
if (handle != NULL)
sysgroup_gr_delref = (sysgroup_gr_delref_t)handle;

View File

@@ -191,8 +191,8 @@ conversation.o: $(srcdir)/conversation.c $(incdir)/alloc.h $(incdir)/fatal.h \
env_hooks.o: $(srcdir)/env_hooks.c $(incdir)/alloc.h $(incdir)/fatal.h \
$(incdir)/fileops.h $(incdir)/gettext.h $(incdir)/missing.h \
$(incdir)/queue.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
$(incdir)/sudo_plugin.h $(srcdir)/sudo.h $(top_builddir)/config.h \
$(top_builddir)/pathnames.h $(top_srcdir)/compat/dlfcn.h \
$(incdir)/sudo_dso.h $(incdir)/sudo_plugin.h $(srcdir)/sudo.h \
$(top_builddir)/config.h $(top_builddir)/pathnames.h \
$(top_srcdir)/compat/stdbool.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/env_hooks.c
exec.o: $(srcdir)/exec.c $(incdir)/alloc.h $(incdir)/fatal.h \
@@ -233,10 +233,9 @@ hooks.o: $(srcdir)/hooks.c $(incdir)/alloc.h $(incdir)/fatal.h \
load_plugins.o: $(srcdir)/load_plugins.c $(incdir)/alloc.h $(incdir)/fatal.h \
$(incdir)/fileops.h $(incdir)/gettext.h $(incdir)/missing.h \
$(incdir)/queue.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
$(incdir)/sudo_plugin.h $(srcdir)/sudo.h \
$(incdir)/sudo_dso.h $(incdir)/sudo_plugin.h $(srcdir)/sudo.h \
$(srcdir)/sudo_plugin_int.h $(top_builddir)/config.h \
$(top_builddir)/pathnames.h $(top_srcdir)/compat/dlfcn.h \
$(top_srcdir)/compat/stdbool.h
$(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/load_plugins.c
locale_stub.o: $(srcdir)/locale_stub.c $(incdir)/fatal.h $(incdir)/gettext.h \
$(incdir)/missing.h $(top_builddir)/config.h
@@ -258,7 +257,8 @@ parse_args.o: $(srcdir)/parse_args.c $(incdir)/alloc.h $(incdir)/fatal.h \
$(top_builddir)/pathnames.h $(top_srcdir)/compat/getopt.h \
$(top_srcdir)/compat/stdbool.h ./sudo_usage.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/parse_args.c
preload.o: $(srcdir)/preload.c $(incdir)/sudo_plugin.h $(top_builddir)/config.h
preload.o: $(srcdir)/preload.c $(incdir)/sudo_dso.h $(incdir)/sudo_plugin.h \
$(top_builddir)/config.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/preload.c
selinux.o: $(srcdir)/selinux.c $(incdir)/alloc.h $(incdir)/fatal.h \
$(incdir)/fileops.h $(incdir)/gettext.h $(incdir)/missing.h \

View File

@@ -37,14 +37,10 @@
# include <malloc.h>
#endif /* HAVE_MALLOC_H && !STDC_HEADERS */
#include <errno.h>
#ifdef HAVE_DLOPEN
# include <dlfcn.h>
#else
# include "compat/dlfcn.h"
#endif
#include "sudo.h"
#include "sudo_plugin.h"
#include "sudo_dso.h"
extern char **environ; /* global environment pointer */
static char **priv_environ; /* private environment pointer */
@@ -72,13 +68,11 @@ typedef char * (*sudo_fn_getenv_t)(const char *);
char *
getenv_unhooked(const char *name)
{
#if defined(HAVE_DLOPEN) && defined(RTLD_NEXT)
sudo_fn_getenv_t fn;
fn = (sudo_fn_getenv_t)dlsym(RTLD_NEXT, "getenv");
fn = (sudo_fn_getenv_t)sudo_dso_findsym(SUDO_DSO_NEXT, "getenv");
if (fn != NULL)
return fn(name);
#endif /* HAVE_DLOPEN && RTLD_NEXT */
return rpl_getenv(name);
}
@@ -144,13 +138,11 @@ typedef int (*sudo_fn_putenv_t)(PUTENV_CONST char *);
static int
putenv_unhooked(PUTENV_CONST char *string)
{
#if defined(HAVE_DLOPEN) && defined(RTLD_NEXT)
sudo_fn_putenv_t fn;
fn = (sudo_fn_putenv_t)dlsym(RTLD_NEXT, "putenv");
fn = (sudo_fn_putenv_t)sudo_dso_findsym(SUDO_DSO_NEXT, "putenv");
if (fn != NULL)
return fn(string);
#endif /* HAVE_DLOPEN && RTLD_NEXT */
return rpl_putenv(string);
}
@@ -214,13 +206,11 @@ typedef int (*sudo_fn_setenv_t)(const char *, const char *, int);
static int
setenv_unhooked(const char *var, const char *val, int overwrite)
{
#if defined(HAVE_SETENV) && defined(HAVE_DLOPEN) && defined(RTLD_NEXT)
sudo_fn_setenv_t fn;
fn = (sudo_fn_setenv_t)dlsym(RTLD_NEXT, "setenv");
fn = (sudo_fn_setenv_t)sudo_dso_findsym(SUDO_DSO_NEXT, "setenv");
if (fn != NULL)
return fn(var, val, overwrite);
#endif /* HAVE_SETENV && HAVE_DLOPEN && RTLD_NEXT */
return rpl_setenv(var, val, overwrite);
}
@@ -273,19 +263,16 @@ static int
unsetenv_unhooked(const char *var)
{
int rval = 0;
#if defined(HAVE_UNSETENV) && defined(HAVE_DLOPEN) && defined(RTLD_NEXT)
sudo_fn_unsetenv_t fn;
fn = (sudo_fn_unsetenv_t)dlsym(RTLD_NEXT, "unsetenv");
fn = (sudo_fn_unsetenv_t)sudo_dso_findsym(SUDO_DSO_NEXT, "unsetenv");
if (fn != NULL) {
# ifdef UNSETENV_VOID
fn(var);
# else
rval = fn(var);
# endif
} else
#endif /* HAVE_UNSETENV && HAVE_DLOPEN && RTLD_NEXT */
{
} else {
rval = rpl_unsetenv(var);
}
return rval;

View File

@@ -36,26 +36,17 @@
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_DLOPEN
# include <dlfcn.h>
#else
# include "compat/dlfcn.h"
#endif
#include <errno.h>
#include "sudo.h"
#include "sudo_plugin.h"
#include "sudo_plugin_int.h"
#include "sudo_conf.h"
#include "sudo_dso.h"
#include "sudo_debug.h"
#ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
#endif
#ifndef SUDOERS_PLUGIN
# define SUDOERS_PLUGIN "sudoers.la"
#endif
/* We always use the same name for the sudoers plugin, regardless of the OS */
#define SUDOERS_PLUGIN "sudoers.so"
#ifdef _PATH_SUDO_PLUGIN_DIR
static int
@@ -74,7 +65,27 @@ sudo_stat_plugin(struct plugin_info *info, char *fullpath,
}
status = stat(fullpath, sb);
} else {
int len = snprintf(fullpath, pathsize, "%s%s", _PATH_SUDO_PLUGIN_DIR,
int len;
#ifdef STATIC_SUDOERS_PLUGIN
/* Check static symbols. */
if (strcmp(info->path, SUDOERS_PLUGIN) == 0) {
if (strlcpy(fullpath, info->path, pathsize) >= pathsize) {
warningx(U_("error in %s, line %d while loading plugin `%s'"),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
warningx(U_("%s: %s"), info->path, strerror(ENAMETOOLONG));
goto done;
}
/* Plugin is static, fake up struct stat. */
memset(sb, 0, sizeof(*sb));
sb->st_uid = ROOT_UID;
sb->st_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
status = 0;
goto done;
}
#endif /* STATIC_SUDOERS_PLUGIN */
len = snprintf(fullpath, pathsize, "%s%s", _PATH_SUDO_PLUGIN_DIR,
info->path);
if (len <= 0 || (size_t)len >= pathsize) {
warningx(U_("error in %s, line %d while loading plugin `%s'"),
@@ -181,14 +192,14 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
goto done;
/* Open plugin and map in symbol */
handle = dlopen(path, RTLD_LAZY|RTLD_GLOBAL);
handle = sudo_dso_load(path, SUDO_DSO_LAZY|SUDO_DSO_GLOBAL);
if (!handle) {
warningx(U_("error in %s, line %d while loading plugin `%s'"),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
warningx(U_("unable to dlopen %s: %s"), path, dlerror());
warningx(U_("unable to load %s: %s"), path, sudo_dso_strerror());
goto done;
}
plugin = dlsym(handle, info->symbol_name);
plugin = sudo_dso_findsym(handle, info->symbol_name);
if (!plugin) {
warningx(U_("error in %s, line %d while loading plugin `%s'"),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
@@ -221,7 +232,7 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
}
warningx(U_("ignoring duplicate policy plugin `%s' in %s, line %d"),
info->symbol_name, _PATH_SUDO_CONF, info->lineno);
dlclose(handle);
sudo_dso_unload(handle);
handle = NULL;
}
if (handle != NULL) {
@@ -236,7 +247,7 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
if (strcmp(container->name, info->symbol_name) == 0) {
warningx(U_("ignoring duplicate I/O plugin `%s' in %s, line %d"),
info->symbol_name, _PATH_SUDO_CONF, info->lineno);
dlclose(handle);
sudo_dso_unload(handle);
handle = NULL;
break;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2011 Todd C. Miller <Todd.Miller@courtesan.com>
* Copyright (c) 2010, 2011, 2013 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
@@ -28,18 +28,40 @@
#endif
#include "sudo_plugin.h"
#include "sudo_dso.h"
#ifdef STATIC_SUDOERS_PLUGIN
extern struct policy_plugin sudoers_policy;
extern struct io_plugin sudoers_io;
struct sudo_preload_table {
const char *name;
void *address;
} sudo_preload_table[] = {
{ "sudoers_policy", (void *) &sudoers_policy},
{ "sudoers_io", (void *) &sudoers_io},
#ifdef HAVE_GSS_KRB5_CCACHE_NAME
{ "gss_krb5_ccache_name", (void *) &gss_krb5_ccache_name},
#endif
static struct sudo_preload_symbol sudo_rtld_default_symbols[] = {
# ifdef HAVE_GSS_KRB5_CCACHE_NAME
{ "gss_krb5_ccache_name", (void *)&gss_krb5_ccache_name},
# endif
{ (const char *)0, (void *)0 }
};
/* XXX - can we autogenerate these? */
static struct sudo_preload_symbol sudo_sudoers_plugin_symbols[] = {
{ "sudoers_policy", (void *)&sudoers_policy},
{ "sudoers_io", (void *)&sudoers_io},
{ (const char *)0, (void *)0 }
};
/*
* Statically compiled symbols indexed by handle.
*/
static struct sudo_preload_table sudo_preload_table[] = {
{ (char *)0, SUDO_DSO_DEFAULT, sudo_rtld_default_symbols },
{ "sudoers.so", &sudo_sudoers_plugin_symbols, sudo_sudoers_plugin_symbols },
{ (char *)0, (void *)0, (struct sudo_preload_symbol *)0 }
};
void
preload_static_symbols(void)
{
sudo_dso_preload_table(sudo_preload_table);
}
#endif /* STATIC_SUDOERS_PLUGIN */

View File

@@ -302,6 +302,9 @@ os_init_common(int argc, char *argv[], char *envp[])
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
if (argc > 0)
setprogname(argv[0]);
#endif
#ifdef STATIC_SUDOERS_PLUGIN
preload_static_symbols();
#endif
return 0;
}

View File

@@ -266,4 +266,7 @@ void save_signals(void);
/* gidlist.c */
int parse_gid_list(const char *gidstr, const gid_t *basegid, GETGROUPS_T **gidsp);
/* preload.c */
void preload_static_symbols(void);
#endif /* _SUDO_SUDO_H */