Add os-specific initialization functions for solaris (workaround

setuid locale problem in Solaris 11) and openbsd (set malloc_options
if SUDO_DEVEL).  Also move set_project() to solaris.c.
This commit is contained in:
Todd C. Miller
2012-11-11 07:11:22 -05:00
parent 56de023de8
commit 83dde2fbb6
11 changed files with 267 additions and 101 deletions

View File

@@ -303,6 +303,7 @@ src/get_pty.c
src/hooks.c
src/load_plugins.c
src/net_ifs.c
src/openbsd.c
src/parse_args.c
src/po/README
src/po/da.mo
@@ -345,6 +346,7 @@ src/po/zh_CN.po
src/preload.c
src/selinux.c
src/sesh.c
src/solaris.c
src/sudo.c
src/sudo.h
src/sudo_edit.c

View File

@@ -927,6 +927,9 @@
/* Define to `int' if <sys/types.h> does not define. */
#undef mode_t
/* Define to an OS-specific initialization function or `os_init_common'. */
#undef os_init
/* Define to `int' if <signal.h> does not define. */
#undef sig_atomic_t

15
configure vendored
View File

@@ -2990,6 +2990,7 @@ LOCALEDIR_SUFFIX=
LT_LDEXPORTS="-export-symbols \$(shlib_exp)"
LT_LDDEP="\$(shlib_exp)"
NO_VIZ=
OS_INIT=os_init_common
CHECKSHADOW=true
shadow_defs=
@@ -13918,6 +13919,10 @@ case "$host" in
# LD_PRELOAD is space-delimited
RTLD_PRELOAD_DELIM=" "
# Solaris-specific initialization
OS_INIT=os_init_solaris
SUDO_OBJS="${SUDO_OBJS} solaris.o"
# To get the crypt(3) prototype (so we pass -Wall)
OSDEFS="${OSDEFS} -D__EXTENSIONS__"
# AFS support needs -lucb
@@ -14465,6 +14470,10 @@ done
: ${with_logincap='maybe'}
;;
*-*-*openbsd*)
# OpenBSD-specific initialization
OS_INIT=os_init_openbsd
SUDO_OBJS="${SUDO_OBJS} openbsd.o"
# OpenBSD has a real setreuid(2) starting with 3.3 but
# we will use setresuid(2) instead.
SKIP_SETREUID=yes
@@ -20918,6 +20927,12 @@ if test -n "$LIBS"; then
done
fi
cat >>confdefs.h <<_ACEOF
#define os_init $OS_INIT
_ACEOF
if test -n "$GCC"; then
if test X"$enable_warnings" = X"yes" -o X"$with_devel" = X"yes"; then
CFLAGS="${CFLAGS} -Wall"

View File

@@ -193,6 +193,7 @@ LOCALEDIR_SUFFIX=
LT_LDEXPORTS="-export-symbols \$(shlib_exp)"
LT_LDDEP="\$(shlib_exp)"
NO_VIZ=
OS_INIT=os_init_common
dnl
dnl Other vaiables
@@ -1566,6 +1567,10 @@ case "$host" in
# LD_PRELOAD is space-delimited
RTLD_PRELOAD_DELIM=" "
# Solaris-specific initialization
OS_INIT=os_init_solaris
SUDO_OBJS="${SUDO_OBJS} solaris.o"
# To get the crypt(3) prototype (so we pass -Wall)
OSDEFS="${OSDEFS} -D__EXTENSIONS__"
# AFS support needs -lucb
@@ -1903,6 +1908,10 @@ case "$host" in
: ${with_logincap='maybe'}
;;
*-*-*openbsd*)
# OpenBSD-specific initialization
OS_INIT=os_init_openbsd
SUDO_OBJS="${SUDO_OBJS} openbsd.o"
# OpenBSD has a real setreuid(2) starting with 3.3 but
# we will use setresuid(2) instead.
SKIP_SETREUID=yes
@@ -3459,6 +3468,11 @@ if test -n "$LIBS"; then
done
fi
dnl
dnl OS-specific initialization
dnl
AC_DEFINE_UNQUOTED(os_init, $OS_INIT, [Define to an OS-specific initialization function or `os_init_common'.])
dnl
dnl We add -Wall and -Werror after all tests so they don't cause failures
dnl

View File

@@ -51,7 +51,7 @@ sub mkdep {
# Expand some configure bits
$makefile =~ s:\@DEV\@::g;
$makefile =~ s:\@COMMON_OBJS\@:aix.lo:;
$makefile =~ s:\@SUDO_OBJS\@:preload.o selinux.o sesh.o sudo_noexec.lo:;
$makefile =~ s:\@SUDO_OBJS\@:openbsd.o preload.o selinux.o sesh.o solaris.o sudo_noexec.lo:;
$makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo plugin_error.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:;

View File

@@ -430,7 +430,8 @@ alias.lo: $(srcdir)/alias.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
$(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
$(srcdir)/parse.h $(srcdir)/redblack.h $(devdir)/gram.h
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(srcdir)/alias.c
audit.lo: $(srcdir)/audit.c $(top_builddir)/config.h $(incdir)/missing.h \
audit.lo: $(srcdir)/audit.c $(top_builddir)/config.h \
$(top_srcdir)/compat/stdbool.h $(incdir)/missing.h \
$(srcdir)/logging.h $(incdir)/sudo_debug.h $(srcdir)/bsm_audit.h \
$(srcdir)/linux_audit.h
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(srcdir)/audit.c
@@ -511,7 +512,8 @@ env.lo: $(srcdir)/env.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
$(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(srcdir)/env.c
error.o: $(top_srcdir)/src/error.c $(top_builddir)/config.h \
$(incdir)/missing.h $(incdir)/error.h $(incdir)/gettext.h
$(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
$(incdir)/gettext.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(top_srcdir)/src/error.c
find_path.lo: $(srcdir)/find_path.c $(top_builddir)/config.h \
$(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
@@ -681,7 +683,8 @@ passwd.lo: $(authdir)/passwd.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
$(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(authdir)/passwd.c
plugin_error.lo: $(srcdir)/plugin_error.c $(top_builddir)/config.h \
$(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
$(top_srcdir)/compat/stdbool.h $(incdir)/missing.h \
$(incdir)/alloc.h $(incdir)/error.h $(srcdir)/logging.h \
$(incdir)/sudo_plugin.h $(incdir)/gettext.h
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(srcdir)/plugin_error.c
policy.lo: $(srcdir)/policy.c $(top_builddir)/config.h $(srcdir)/sudoers.h \

View File

@@ -175,7 +175,7 @@ env_hooks.o: $(srcdir)/env_hooks.c $(top_builddir)/config.h \
$(incdir)/sudo_plugin.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(srcdir)/env_hooks.c
error.o: $(srcdir)/error.c $(top_builddir)/config.h $(incdir)/missing.h \
$(incdir)/error.h $(incdir)/gettext.h
$(incdir)/alloc.h $(incdir)/error.h $(incdir)/gettext.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(srcdir)/error.c
exec.o: $(srcdir)/exec.c $(top_builddir)/config.h $(srcdir)/sudo.h \
$(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
@@ -227,6 +227,12 @@ net_ifs.o: $(srcdir)/net_ifs.c $(top_builddir)/config.h $(incdir)/missing.h \
$(incdir)/alloc.h $(incdir)/error.h $(incdir)/sudo_debug.h \
$(incdir)/gettext.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(srcdir)/net_ifs.c
openbsd.o: $(srcdir)/openbsd.c $(top_builddir)/config.h $(srcdir)/sudo.h \
$(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
$(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
$(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_conf.h \
$(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(srcdir)/openbsd.c
parse_args.o: $(srcdir)/parse_args.c $(top_builddir)/config.h ./sudo_usage.h \
$(srcdir)/sudo.h $(top_builddir)/pathnames.h \
$(top_srcdir)/compat/stdbool.h $(incdir)/missing.h \
@@ -249,6 +255,12 @@ sesh.o: $(srcdir)/sesh.c $(top_builddir)/config.h \
$(incdir)/list.h $(incdir)/sudo_debug.h $(srcdir)/sudo_exec.h \
$(incdir)/sudo_plugin.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(srcdir)/sesh.c
solaris.o: $(srcdir)/solaris.c $(top_builddir)/config.h $(srcdir)/sudo.h \
$(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
$(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
$(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_conf.h \
$(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(srcdir)/solaris.c
sudo.o: $(srcdir)/sudo.c $(top_builddir)/config.h $(srcdir)/sudo.h \
$(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
$(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \

52
src/openbsd.c Normal file
View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2012 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
# 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 "sudo.h"
int
os_init(int argc, char *argv[], char *envp[])
{
#ifdef SUDO_DEVEL
extern char *malloc_options;
malloc_options = "AFGJPR";
#endif
return os_init_common(argc, argv, envp);
}

127
src/solaris.c Normal file
View File

@@ -0,0 +1,127 @@
/*
* Copyright (c) 2009-2012 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/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 */
#ifdef HAVE_PROJECT_H
# include <project.h>
# include <sys/task.h>
#endif
#include <dlfcn.h>
#include <errno.h>
#include <pwd.h>
#include "sudo.h"
int
os_init(int argc, char *argv[], char *envp[])
{
/*
* Solaris 11 is unable to load the per-locale shared objects
* without this. This bug was fixed in Solaris 11 Update 1.
*/
void *handle = dlopen("/usr/lib/locale/common/methods_unicode.so.3",
RTLD_LAZY|RTLD_GLOBAL);
return os_init_common(argc, argv, envp);
}
#ifdef HAVE_PROJECT_H
void
set_project(struct passwd *pw)
{
struct project proj;
char buf[PROJECT_BUFSZ];
int errval;
debug_decl(set_project, SUDO_DEBUG_UTIL)
/*
* Collect the default project for the user and settaskid
*/
setprojent();
if (getdefaultproj(pw->pw_name, &proj, buf, sizeof(buf)) != NULL) {
errval = setproject(proj.pj_name, pw->pw_name, TASK_NORMAL);
switch(errval) {
case 0:
break;
case SETPROJ_ERR_TASK:
switch (errno) {
case EAGAIN:
warningx(N_("resource control limit has been reached"));
break;
case ESRCH:
warningx(N_("user \"%s\" is not a member of project \"%s\""),
pw->pw_name, proj.pj_name);
break;
case EACCES:
warningx(N_("the invoking task is final"));
break;
default:
warningx(N_("could not join project \"%s\""), proj.pj_name);
}
case SETPROJ_ERR_POOL:
switch (errno) {
case EACCES:
warningx(N_("no resource pool accepting default bindings "
"exists for project \"%s\""), proj.pj_name);
break;
case ESRCH:
warningx(N_("specified resource pool does not exist for "
"project \"%s\""), proj.pj_name);
break;
default:
warningx(N_("could not bind to default resource pool for "
"project \"%s\""), proj.pj_name);
}
break;
default:
if (errval <= 0) {
warningx(N_("setproject failed for project \"%s\""), proj.pj_name);
} else {
warningx(N_("warning, resource control assignment failed for "
"project \"%s\""), proj.pj_name);
}
}
} else {
warning("getdefaultproj");
}
endprojent();
debug_return;
}
#endif /* HAVE_PROJECT_H */

View File

@@ -86,12 +86,6 @@
# endif /* __hpux */
# include <prot.h>
#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */
#if defined(HAVE_STRUCT_KINFO_PROC_P_TDEV) || defined (HAVE_STRUCT_KINFO_PROC_KP_EPROC_E_TDEV)
# include <sys/sysctl.h>
#elif defined(HAVE_STRUCT_KINFO_PROC_KI_TDEV)
# include <sys/sysctl.h>
# include <sys/user.h>
#endif
#include "sudo.h"
#include "sudo_plugin.h"
@@ -160,17 +154,7 @@ main(int argc, char *argv[], char *envp[])
sigset_t mask;
debug_decl(main, SUDO_DEBUG_MAIN)
#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
{
extern char *malloc_options;
malloc_options = "AFGJPR";
}
#endif
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
if (argc > 0)
setprogname(argv[0]);
#endif
os_init(argc, argv, envp);
#ifdef HAVE_SETLOCALE
setlocale(LC_ALL, "");
@@ -311,6 +295,16 @@ main(int argc, char *argv[], char *envp[])
exit(exitcode);
}
int
os_init_common(int argc, char *argv[], char *envp[])
{
#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
if (argc > 0)
setprogname(argv[0]);
#endif
return 0;
}
/*
* Ensure that stdin, stdout and stderr are open; set to /dev/null if not.
* Some operating systems do this automatically in the kernel or libc.
@@ -838,70 +832,6 @@ disable_coredumps(void)
debug_return;
}
#ifdef HAVE_PROJECT_H
static void
set_project(struct passwd *pw)
{
struct project proj;
char buf[PROJECT_BUFSZ];
int errval;
debug_decl(set_project, SUDO_DEBUG_UTIL)
/*
* Collect the default project for the user and settaskid
*/
setprojent();
if (getdefaultproj(pw->pw_name, &proj, buf, sizeof(buf)) != NULL) {
errval = setproject(proj.pj_name, pw->pw_name, TASK_NORMAL);
switch(errval) {
case 0:
break;
case SETPROJ_ERR_TASK:
switch (errno) {
case EAGAIN:
warningx(N_("resource control limit has been reached"));
break;
case ESRCH:
warningx(N_("user \"%s\" is not a member of project \"%s\""),
pw->pw_name, proj.pj_name);
break;
case EACCES:
warningx(N_("the invoking task is final"));
break;
default:
warningx(N_("could not join project \"%s\""), proj.pj_name);
}
case SETPROJ_ERR_POOL:
switch (errno) {
case EACCES:
warningx(N_("no resource pool accepting default bindings "
"exists for project \"%s\""), proj.pj_name);
break;
case ESRCH:
warningx(N_("specified resource pool does not exist for "
"project \"%s\""), proj.pj_name);
break;
default:
warningx(N_("could not bind to default resource pool for "
"project \"%s\""), proj.pj_name);
}
break;
default:
if (errval <= 0) {
warningx(N_("setproject failed for project \"%s\""), proj.pj_name);
} else {
warningx(N_("warning, resource control assignment failed for "
"project \"%s\""), proj.pj_name);
}
}
} else {
warning("getdefaultproj");
}
endprojent();
debug_return;
}
#endif /* HAVE_PROJECT_H */
/*
* Setup the execution environment immediately prior to the call to execve()
* Returns true on success and false on failure.

View File

@@ -215,6 +215,7 @@ void get_ttysize(int *rowp, int *colp);
bool exec_setup(struct command_details *details, const char *ptyname, int ptyfd);
int policy_init_session(struct command_details *details);
int run_command(struct command_details *details);
int os_init_common(int argc, char *argv[], char *envp[]);
extern const char *list_user, *runas_user, *runas_group;
extern struct user_details user_details;
@@ -224,6 +225,9 @@ int sudo_edit(struct command_details *details);
/* parse_args.c */
void usage(int);
/* openbsd.c */
int os_init_openbsd(int argc, char *argv[], char *envp[]);
/* selinux.c */
int selinux_restore_tty(void);
int selinux_setup(const char *role, const char *type, const char *ttyn,
@@ -231,6 +235,10 @@ int selinux_setup(const char *role, const char *type, const char *ttyn,
void selinux_execve(const char *path, char *const argv[], char *const envp[],
int noexec);
/* solaris.c */
void set_project(struct passwd *);
int os_init_solaris(int argc, char *argv[], char *envp[]);
/* aix.c */
void aix_prep_user(char *user, const char *tty);
void aix_restoreauthdb(void);