From: Todd C. Miller Date: Tue, 8 May 2012 17:35:52 +0000 (-0400) Subject: Add group plugin that does lookups by name using the system group X-Git-Tag: SUDO_1_8_5~1^2~15 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=994d2ff69a0122d4815bedb1724fd2e2a8ac3670;p=sudo Add group plugin that does lookups by name using the system group database. --- diff --git a/Makefile.in b/Makefile.in index ef474f596..a6a76ad02 100644 --- a/Makefile.in +++ b/Makefile.in @@ -47,7 +47,7 @@ sudoers_mode = @SUDOERS_MODE@ SUBDIRS = compat common @ZLIB_SRC@ plugins/sudoers src include doc -SAMPLES = plugins/sample plugins/sample_group +SAMPLES = plugins/sample plugins/sample_group plugins/system_group VERSION = @PACKAGE_VERSION@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ diff --git a/configure b/configure index 9e17f4769..9c2fcba8d 100755 --- a/configure +++ b/configure @@ -20162,7 +20162,7 @@ test "$datarootdir" = '${prefix}/share' && datarootdir='$(prefix)/share' test "$docdir" = '${datarootdir}/doc/${PACKAGE_TARNAME}' && docdir='$(datarootdir)/doc/$(PACKAGE_TARNAME)' test "$sysconfdir" = '${prefix}/etc' -a X"$with_stow" != X"yes" && sysconfdir='/etc' -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 plugins/sudoers/sudoers" +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/system_group/Makefile plugins/sudoers/Makefile plugins/sudoers/sudoers" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -21165,6 +21165,7 @@ do "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/system_group/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/system_group/Makefile" ;; "plugins/sudoers/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/sudoers/Makefile" ;; "plugins/sudoers/sudoers") CONFIG_FILES="$CONFIG_FILES plugins/sudoers/sudoers" ;; diff --git a/configure.in b/configure.in index 050c3846b..3ab4fa2d7 100644 --- a/configure.in +++ b/configure.in @@ -3267,7 +3267,7 @@ dnl dnl Substitute into the Makefile and man pages dnl dnl AC_CONFIG_FILES([doc/sudo.man doc/visudo.man doc/sudoers.man doc/sudoers.ldap.man doc/sudoreplay.man src/Makefile src/sudo_usage.h]) -AC_CONFIG_FILES([Makefile common/Makefile compat/Makefile doc/Makefile include/Makefile src/sudo_usage.h src/Makefile plugins/sample/Makefile plugins/sample_group/Makefile plugins/sudoers/Makefile plugins/sudoers/sudoers]) +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/system_group/Makefile plugins/sudoers/Makefile plugins/sudoers/sudoers]) AC_OUTPUT dnl diff --git a/plugins/system_group/Makefile.in b/plugins/system_group/Makefile.in new file mode 100644 index 000000000..991998f8c --- /dev/null +++ b/plugins/system_group/Makefile.in @@ -0,0 +1,126 @@ +# +# Copyright (c) 2011-2012 Todd C. Miller +# +# 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 + +# Compiler & tools to use +CC = @CC@ +LIBTOOL = @LIBTOOL@ @LT_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) -I$(top_srcdir) @CPPFLAGS@ + +# Usually -O and/or -g +CFLAGS = @CFLAGS@ + +# Flags to pass to the link stage +LDFLAGS = @LDFLAGS@ +LTLDFLAGS = @LTLDFLAGS@ + +# Where to install things... +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +sbindir = @sbindir@ +sysconfdir = @sysconfdir@ +libexecdir = @libexecdir@ +datarootdir = @datarootdir@ +localstatedir = @localstatedir@ +plugindir = @PLUGINDIR@ +soext = @SOEXT@ + +# OS dependent defines +DEFS = @OSDEFS@ + +#### End of system configuration section. #### + +SHELL = @SHELL@ + +OBJS = system_group.lo + +LIBOBJDIR = $(top_builddir)/@ac_config_libobj_dir@/ + +VERSION = @PACKAGE_VERSION@ + +all: system_group.la + +Makefile: $(srcdir)/Makefile.in + (cd $(top_builddir) && ./config.status --file plugins/system_group/Makefile) + +.SUFFIXES: .o .c .h .lo + +.c.lo: + $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $< + +system_group.la: $(OBJS) + $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LTLDFLAGS) -o $@ $(OBJS) $(LIBS) -module -export-symbols $(srcdir)/system_group.sym -avoid-version -rpath $(plugindir) + +pre-install: + +install: install-plugin + +install-dirs: + $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(plugindir) + +install-binaries: + +install-includes: + +install-doc: + +install-plugin: install-dirs system_group.la + $(INSTALL) -b~ -m 0755 .libs/system_group$(soext) $(DESTDIR)$(plugindir) + +uninstall: + -rm -f $(DESTDIR)$(plugindir)/system_group$(soext) + +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 + +# Autogenerated dependencies, do not modify +system_group.lo: $(srcdir)/system_group.c $(top_builddir)/config.h \ + $(top_srcdir)/compat/stdbool.h $(incdir)/sudo_plugin.h \ + $(incdir)/missing.h + $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/system_group.c diff --git a/plugins/system_group/system_group.c b/plugins/system_group/system_group.c new file mode 100644 index 000000000..5d725f8ec --- /dev/null +++ b/plugins/system_group/system_group.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2010, 2012 Todd C. Miller + * + * 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 + +#include +#include +#include + +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STDBOOL_H +# include +#else +# include "compat/stdbool.h" +#endif /* HAVE_STDBOOL_H */ +#ifdef HAVE_STRING_H +# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) +# include +# endif +# include +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include +#endif /* HAVE_STRINGS_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_DLOPEN +# include +#else +# include "compat/dlfcn.h" +#endif +#include +#include +#include +#include +#include +#include + +#include "sudo_plugin.h" +#include "missing.h" + +#ifndef RTLD_DEFAULT +# define RTLD_DEFAULT NULL +#endif + +/* + * Sudoers group plugin that does group name-based lookups using the system + * group database functions, similar to how sudo behaved prior to 1.7.3. + * This can be used on systems where lookups by group ID are problematic. + */ + +static sudo_printf_t sudo_log; + +typedef struct group * (*sysgroup_getgrnam_t)(const char *); +typedef struct group * (*sysgroup_getgrgid_t)(gid_t); + +static sysgroup_getgrnam_t sysgroup_getgrnam; +static sysgroup_getgrgid_t sysgroup_getgrgid; +static bool need_setent; + +static int +sysgroup_init(int version, sudo_printf_t sudo_printf, char *const argv[]) +{ + struct stat sb; + void *handle; + + sudo_log = sudo_printf; + + if (GROUP_API_VERSION_GET_MAJOR(version) != GROUP_API_VERSION_MAJOR) { + sudo_log(SUDO_CONV_ERROR_MSG, + "sysgroup_group: incompatible major version %d, expected %d\n", + GROUP_API_VERSION_GET_MAJOR(version), + GROUP_API_VERSION_MAJOR); + return -1; + } + + /* Share group cache with sudo if possible. */ + handle = dlsym(RTLD_DEFAULT, "sudo_getgrnam"); + if (handle != NULL) { + sysgroup_getgrnam = (sysgroup_getgrnam_t)handle; + } else { + sysgroup_getgrnam = (sysgroup_getgrnam_t)getgrnam; + need_setent = true; + } + + handle = dlsym(RTLD_DEFAULT, "sudo_getgrgid"); + if (handle != NULL) { + sysgroup_getgrgid = (sysgroup_getgrgid_t)handle; + } else { + sysgroup_getgrgid = (sysgroup_getgrgid_t)getgrgid; + need_setent = true; + } + + if (need_setent) + setgrent(); + + return true; +} + +static void +sysgroup_cleanup(void) +{ + if (need_setent) + endgrent(); +} + +/* + * Returns true if "user" is a member of "group", else false. + */ +static int +sysgroup_query(const char *user, const char *group, const struct passwd *pwd) +{ + char **member, *ep = '\0'; + struct group *grp; + gid_t gid; + + grp = sysgroup_getgrnam(group); + if (grp == NULL && group[0] == '#' && group[1] != '\0') { + long lval = strtol(group + 1, &ep, 10); + if (*ep == '\0') { + if ((lval != LONG_MAX && lval != LONG_MIN) || errno != ERANGE) + grp = sysgroup_getgrgid((gid_t)lval); + } + } + if (grp != NULL) { + for (member = grp->gr_mem; *member != NULL; member++) { + if (strcasecmp(user, *member) == 0) { + gr_delref(grp); + return true; + } + } + gr_delref(grp); + } + + return false; +} + +struct sudoers_group_plugin group_plugin = { + GROUP_API_VERSION, + sysgroup_init, + sysgroup_cleanup, + sysgroup_query +}; diff --git a/plugins/system_group/system_group.sym b/plugins/system_group/system_group.sym new file mode 100644 index 000000000..a859d6ca6 --- /dev/null +++ b/plugins/system_group/system_group.sym @@ -0,0 +1 @@ +group_plugin