diff --git a/.cvsignore b/.cvsignore index b062bed..c1b4a48 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,2 +1,2 @@ sudo-1.6.8p12-sudoers -sudo-1.6.9p12.tar.gz +sudo-1.6.9p13.tar.gz diff --git a/sources b/sources index 033787a..da4c36a 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -3dad7cdd28925f9bdf387510961f8e9f sudo-1.6.8p12-sudoers -a5795c292e5c64dd9f7bcba8c1c712c9 sudo-1.6.9p12.tar.gz +573c851f2a204f1cdbbdb657015fc6ef sudo-1.6.8p12-sudoers +7e9d3e7780c632469ffe88fcc4a6b1ca sudo-1.6.9p13.tar.gz diff --git a/sudo-1.6.8p12-sudoers b/sudo-1.6.8p12-sudoers index bd2d94b..2e7ef76 100644 --- a/sudo-1.6.8p12-sudoers +++ b/sudo-1.6.8p12-sudoers @@ -56,12 +56,11 @@ Cmnd_Alias DRIVERS = /sbin/modprobe Defaults requiretty Defaults env_reset -Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR \ - LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \ - LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC \ - LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS \ - _XKB_CHARSET XAUTHORITY" +Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS" +Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE" +Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES" +Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE" +Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY" ## Next comes the main part: which users can run what software on ## which machines (the sudoers file can be shared between multiple diff --git a/sudo-1.6.9p12-selinux.patch b/sudo-1.6.9p12-selinux.patch deleted file mode 100644 index aecd865..0000000 --- a/sudo-1.6.9p12-selinux.patch +++ /dev/null @@ -1,672 +0,0 @@ -diff -up /dev/null sudo-1.6.9p12/sesh.c ---- /dev/null 2008-02-05 17:16:01.642928004 +0100 -+++ sudo-1.6.9p12/sesh.c 2008-02-06 13:06:50.000000000 +0100 -@@ -0,0 +1,46 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+main (int argc, char **argv) { -+ char buf[PATH_MAX]; -+ pid_t pid; -+ if ( argc < 2 ) { -+ fprintf(stderr,"%s: Requires at least one argument\n", argv[0]); -+ exit(-1); -+ } -+ -+ if ((pid = fork()) < 0) { -+ snprintf(buf, sizeof(buf), "%s: Couldn't fork",argv[0]); -+ perror(buf); -+ exit(-1); -+ } else if (pid > 0) { -+ /* Parent */ -+ int status; -+ int ret; -+ -+ do { -+ if ((ret = waitpid(pid, &status, 0)) < 0 && errno == EINTR) -+ continue; -+ else if (ret < 0) { -+ perror("waitpid failed"); -+ exit(1); -+ } -+ } while (0); -+ -+ if (WIFEXITED(status)) -+ exit(WEXITSTATUS(status)); -+ else -+ exit(1); -+ } else { -+ /* Child */ -+ execv(argv[1], &argv[1]); -+ -+ snprintf(buf, sizeof(buf), "%s: Error execing %s", argv[0], argv[1]); -+ perror(buf); -+ exit(-1); -+ } -+} -diff -up sudo-1.6.9p12/configure.in.selinux sudo-1.6.9p12/configure.in ---- sudo-1.6.9p12/configure.in.selinux 2008-02-06 12:45:07.000000000 +0100 -+++ sudo-1.6.9p12/configure.in 2008-02-06 13:06:50.000000000 +0100 -@@ -102,7 +102,7 @@ dnl - dnl Initial values for Makefile variables listed above - dnl May be overridden by environment variables.. - dnl --PROGS="sudo visudo" -+PROGS="sudo visudo sesh" - : ${MANTYPE='man'} - : ${mansrcdir='.'} - : ${SUDOERS_MODE='0440'} -diff -up /dev/null sudo-1.6.9p12/selinux.c ---- /dev/null 2008-02-05 17:16:01.642928004 +0100 -+++ sudo-1.6.9p12/selinux.c 2008-02-06 13:06:50.000000000 +0100 -@@ -0,0 +1,425 @@ -+/* -+ * Copyright (c) 2008 Dan Walsh -+ * -+ * Borrowed heavily from newrole source code -+ * Authors: -+ * Anthony Colatrella -+ * Tim Fraser -+ * Steve Grubb -+ * Darrel Goeddel -+ * Michael Thompson -+ * Dan Walsh -+ * -+ * 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. -+ * -+ */ -+#ifdef WITH_SELINUX -+#include -+#include -+#include -+#ifdef STDC_HEADERS -+# include -+# include -+#else -+# ifdef HAVE_STDLIB_H -+# include -+# endif -+#endif /* STDC_HEADERS */ -+#ifdef HAVE_STRING_H -+# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) -+# include -+# endif -+# include -+#else -+# ifdef HAVE_STRINGS_H -+# include -+# endif -+#endif /* HAVE_STRING_H */ -+#ifdef HAVE_UNISTD_H -+# include -+#endif /* HAVE_UNISTD_H */ -+#include -+#include -+#include -+ -+#ifdef WITH_AUDIT -+#include -+#endif -+ -+#include "sudo.h" -+ -+#include -+ -+#ifdef USE_AUDIT -+#include -+#endif -+ -+#include /* for SECCLASS_CHR_FILE */ -+#include /* for is_selinux_enabled() */ -+#include /* for context-mangling functions */ -+#include -+#include -+ -+/** -+ * This function attempts to revert the relabeling done to the tty. -+ * fd - referencing the opened ttyn -+ * ttyn - name of tty to restore -+ * tty_context - original context of the tty -+ * new_tty_context - context tty was relabeled to -+ * -+ * Returns zero on success, non-zero otherwise -+ */ -+static int restore_tty_label(int fd, const char *ttyn, -+ security_context_t tty_context, -+ security_context_t new_tty_context) -+{ -+ int rc = 0; -+ security_context_t chk_tty_context = NULL; -+ -+ if (!ttyn) -+ goto skip_relabel; -+ -+ if (!new_tty_context) -+ goto skip_relabel; -+ -+ /* Verify that the tty still has the context set by newrole. */ -+ if ((rc = fgetfilecon(fd, &chk_tty_context)) < 0) { -+ fprintf(stderr, "Could not fgetfilecon %s.\n", ttyn); -+ goto skip_relabel; -+ } -+ -+ if ((rc = strcmp(chk_tty_context, new_tty_context))) { -+ fprintf(stderr, "%s changed labels.\n", ttyn); -+ goto skip_relabel; -+ } -+ -+ if ((rc = fsetfilecon(fd, tty_context)) < 0) -+ fprintf(stderr, -+ "Warning! Could not restore context for %s\n", ttyn); -+ skip_relabel: -+ freecon(chk_tty_context); -+ return rc; -+} -+ -+/** -+ * This function attempts to relabel the tty. If this function fails, then -+ * the fd is closed, the contexts are free'd and -1 is returned. On success, -+ * a valid fd is returned and tty_context and new_tty_context are set. -+ * -+ * This function will not fail if it can not relabel the tty when selinux is -+ * in permissive mode. -+ */ -+static int relabel_tty(const char *ttyn, security_context_t new_context, -+ security_context_t * tty_context, -+ security_context_t * new_tty_context) -+{ -+ int fd; -+ int enforcing = security_getenforce(); -+ security_context_t tty_con = NULL; -+ security_context_t new_tty_con = NULL; -+ -+ if (!ttyn) -+ return 0; -+ -+ if (enforcing < 0) { -+ fprintf(stderr, "Could not determine enforcing mode.\n"); -+ return -1; -+ } -+ -+ /* Re-open TTY descriptor */ -+ fd = open(ttyn, O_RDWR | O_NONBLOCK); -+ if (fd < 0) { -+ fprintf(stderr, "Error! Could not open %s.\n", ttyn); -+ return fd; -+ } -+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); -+ -+ if (fgetfilecon(fd, &tty_con) < 0) { -+ fprintf(stderr, "%s! Could not get current context " -+ "for %s, not relabeling tty.\n", -+ enforcing ? "Error" : "Warning", ttyn); -+ if (enforcing) -+ goto close_fd; -+ } -+ -+ if (tty_con && -+ (security_compute_relabel(new_context, tty_con, -+ SECCLASS_CHR_FILE, &new_tty_con) < 0)) { -+ fprintf(stderr, "%s! Could not get new context for %s, " -+ "not relabeling tty.\n", -+ enforcing ? "Error" : "Warning", ttyn); -+ if (enforcing) -+ goto close_fd; -+ } -+ -+ if (new_tty_con) -+ if (fsetfilecon(fd, new_tty_con) < 0) { -+ fprintf(stderr, -+ "%s! Could not set new context for %s\n", -+ enforcing ? "Error" : "Warning", ttyn); -+ freecon(new_tty_con); -+ new_tty_con = NULL; -+ if (enforcing) -+ goto close_fd; -+ } -+ -+ *tty_context = tty_con; -+ *new_tty_context = new_tty_con; -+ return fd; -+ -+ close_fd: -+ freecon(tty_con); -+ close(fd); -+ return -1; -+} -+ -+security_context_t get_exec_context(security_context_t old_context, char *role_s, char *type_s) { -+ -+ /* our target security ID ("sid") */ -+ security_context_t new_context=NULL; -+ -+ /* manipulatable form of context_s */ -+ context_t context; -+ -+ if( !role_s ) { -+ fprintf(stderr,"You must specify a role.\n"); -+ return NULL; -+ } -+ -+ -+ /* -+ * Get the SID and context of the caller, and extract -+ * the username from the context. Don't rely on the Linux -+ * uid information - it isn't trustworthy. -+ */ -+ -+ /* -+ * Create a context structure so that we extract and modify -+ * components easily. -+ */ -+ context=context_new(old_context); -+ -+ /* -+ * -+ * Step 3: Construct a new SID based on our old SID and the -+ * arguments specified on the command line. -+ * -+ */ -+ -+ /* The first step in constructing a new SID for the new shell we * -+ * plan to exec is to take our old context in `context' as a * -+ * starting point, and modify it according to the options the user * -+ * specified on the command line. */ -+ -+ /* If the user specified a new role on the command line (if `role_s' * -+ * is set), then replace the old role in `context' with this new role. */ -+ if( !type_s ) { -+ if( get_default_type(role_s,&type_s) ) -+ { -+ fprintf(stderr,"Couldn't get default type.\n"); -+ goto err; -+ } -+ } -+ -+ if( context_role_set(context,role_s)) { -+ fprintf(stderr,"failed to set new role %s\n",role_s); -+ goto err; -+ } -+ -+ /* If the user specified a new type on the command line (if `type_s' * -+ * is set), then replace the old type in `context' with this new type. */ -+ if( type_s ) { -+ if( context_type_set(context,type_s)) { -+ fprintf(stderr,"failed to set new type %s\n",type_s); -+ goto err; -+ } -+ } /* if user specified new type */ -+ -+ /* The second step in creating the new SID is to convert our modified * -+ * `context' structure back to a context string and then to a SID. */ -+ -+ /* Make `context_s' point to a string version of the new `context'. */ -+ if( !(new_context=strdup(context_str(context)))) { -+ fprintf(stderr,"failed to convert new context to string\n" ); -+ goto err; -+ } -+ -+ if (security_check_context(new_context) < 0) { -+ fprintf(stderr, "%s is not a valid context\n", new_context); -+ goto err; -+ } -+ -+#ifdef DEBUG -+ printf("Your new context is %s\n",new_context); -+#endif -+ -+ context_free(context); -+ return new_context; -+ -+ err: -+ context_free(context); -+ freecon(new_context); -+ return NULL; -+ -+} -+ -+void selinux_exec(char *role_s, char *type_s, char *safe_cmd, int NewArgc, char **NewArgv, char **environ){ -+ pid_t childPid = 0; -+ int ttyfd = -1; -+ /* our original securiy ID ("old_context") */ -+ security_context_t old_context=NULL; -+ -+ /* security context to change to while running command*/ -+ security_context_t new_tty_context=NULL; -+ /* current security context of tty */ -+ security_context_t tty_context=NULL; -+ -+ char *ttyn = NULL; /* tty path */ -+ -+ /* our target security ID ("sid") */ -+ security_context_t new_context=NULL; -+ /* Put the caller's SID into `old_context'. */ -+ if (getprevcon(&old_context)) { -+ fprintf(stderr,"failed to get old_context.\n"); -+ exit(-1); -+ } -+ -+#ifdef DEBUG -+ printf( "Your old context was %s\n", old_context ); -+#endif -+ new_context=get_exec_context(old_context, role_s,type_s); -+ if (! new_context) { -+ fprintf(stderr, "Could not set exec context to %s.\n", new_context); -+ exit(-1); -+ } -+ -+ ttyn = ttyname(STDIN_FILENO); -+ if (!ttyn || *ttyn == '\0') { -+ fprintf(stderr, -+ "Warning! Could not retrieve tty information.\n"); -+ } -+ -+ ttyfd = relabel_tty(ttyn, new_context, &tty_context, &new_tty_context); -+ if (ttyfd < 0) { -+ fprintf(stderr, "Could not setup tty context for %s.\n", new_context); -+ exit(-1); -+ } -+ -+#ifdef DEBUG -+ printf("Your old tty context is %s\n",tty_context); -+ printf("Your new tty context is %s\n",new_tty_context); -+#endif -+ -+ -+ childPid = fork(); -+ if (childPid < 0) { -+ /* fork failed, no child to worry about */ -+ int errsv = errno; -+ fprintf(stderr, "newrole: failure forking: %s", -+ strerror(errsv)); -+ if (restore_tty_label(ttyfd, ttyn, tty_context, new_tty_context)) -+ fprintf(stderr, "Unable to restore tty label...\n"); -+ if (close(ttyfd)) -+ fprintf(stderr, "Failed to close tty properly\n"); -+ goto err; -+ } else if (childPid) { -+ /* PARENT -+ * It doesn't make senes to exit early on errors at this point, -+ * since we are doing cleanup which needs to be done. -+ * We can exit with a bad rc though -+ */ -+ pid_t pid; -+ int exit_code = 0; -+ int status; -+ -+ do { -+ pid = wait(&status); -+ } while (pid < 0 && errno == EINTR); -+ -+ /* Preserve child exit status, unless there is another error. */ -+ if (WIFEXITED(status)) -+ exit_code = WEXITSTATUS(status); -+ -+ if (restore_tty_label(ttyfd, ttyn, tty_context, new_tty_context)) { -+ fprintf(stderr, "Unable to restore tty label...\n"); -+ exit_code = -1; -+ } -+ freecon(tty_context); -+ freecon(new_tty_context); -+ if (close(ttyfd)) { -+ fprintf(stderr, "Failed to close tty properly\n"); -+ exit_code = -1; -+ } -+ exit(exit_code); -+ } -+ /* CHILD */ -+ /* Close the tty and reopen descriptors 0 through 2 */ -+ if (ttyn) { -+ if (close(ttyfd) || close(0) || close(1) || close(2)) { -+ fprintf(stderr, "Could not close descriptors.\n"); -+ goto err; -+ } -+ ttyfd = open(ttyn, O_RDONLY | O_NONBLOCK); -+ if (ttyfd != 0) -+ goto err; -+ fcntl(ttyfd, F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NONBLOCK); -+ ttyfd = open(ttyn, O_RDWR | O_NONBLOCK); -+ if (ttyfd != 1) -+ goto err; -+ fcntl(ttyfd, F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NONBLOCK); -+ ttyfd = open(ttyn, O_RDWR | O_NONBLOCK); -+ if (ttyfd != 2) -+ goto err; -+ fcntl(ttyfd, F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NONBLOCK); -+ } -+ if (setexeccon(new_context)) { -+ fprintf(stderr, "Could not set exec context to %s.\n", -+ new_context); -+ goto err; -+ } -+ -+#ifdef USE_AUDIT -+ if (send_audit_message(1, old_context, new_context, ttyn)) -+ goto err; -+#endif -+ -+ { -+ /* -+ SELinux will only not transition properly with the following -+ code. Basically if the user chooses to use a different security -+ context. We need to start the selinux shell, before executing -+ the command. This way the process transition will happen -+ correctly. For example if they user wants to run rpm from -+ sysadm_r. Sudo will exec the /usr/sbin/sesh followed by the -+ specified command.*/ -+ char **dst, **src = NewArgv+1; -+ NewArgv = (char **) emalloc2((++NewArgc + 1), sizeof(char *)); -+ NewArgv[0] = estrdup("/usr/sbin/sesh"); -+ NewArgv[1] = safe_cmd; -+ safe_cmd = estrdup("/usr/sbin/sesh"); -+ /* copy the args from Argv */ -+ for (dst = NewArgv + 2; (*dst = *src) != NULL; ++src, ++dst) -+ ; -+ } -+ freecon(old_context); -+ freecon(new_context); -+ -+ execve(safe_cmd, NewArgv, environ); /* run the command */ -+ -+ perror("failed to exec shell\n"); -+ err: -+ freecon(old_context); -+ freecon(new_context); -+ exit(-1); -+} -+#endif /* WITH_SELINUX */ -diff -up sudo-1.6.9p12/Makefile.in.selinux sudo-1.6.9p12/Makefile.in ---- sudo-1.6.9p12/Makefile.in.selinux 2008-02-06 12:45:07.000000000 +0100 -+++ sudo-1.6.9p12/Makefile.in 2008-02-06 13:08:50.000000000 +0100 -@@ -43,7 +43,8 @@ INSTALL = $(SHELL) $(srcdir)/install-sh - # Libraries - LIBS = @LIBS@ - NET_LIBS = @NET_LIBS@ --SUDO_LIBS = @SUDO_LIBS@ @AFS_LIBS@ @GETGROUPS_LIB@ $(LIBS) $(NET_LIBS) -+SELINUX_LIBS = -lselinux -+SUDO_LIBS = @SUDO_LIBS@ @AFS_LIBS@ @GETGROUPS_LIB@ $(LIBS) $(NET_LIBS) $(SELINUX_LIBS) - - # C preprocessor flags - CPPFLAGS = -I. -I$(srcdir) @CPPFLAGS@ -@@ -91,7 +92,7 @@ sudoers_gid = @SUDOERS_GID@ - sudoers_mode = @SUDOERS_MODE@ - - # Pass in paths and uid/gid + OS dependent defined --DEFS = @OSDEFS@ -D_PATH_SUDOERS=\"$(sudoersdir)/sudoers\" -D_PATH_SUDOERS_TMP=\"$(sudoersdir)/sudoers.tmp\" -DSUDOERS_UID=$(sudoers_uid) -DSUDOERS_GID=$(sudoers_gid) -DSUDOERS_MODE=$(sudoers_mode) -+DEFS = @OSDEFS@ -D_PATH_SUDOERS=\"$(sudoersdir)/sudoers\" -D_PATH_SUDOERS_TMP=\"$(sudoersdir)/sudoers.tmp\" -DSUDOERS_UID=$(sudoers_uid) -DSUDOERS_GID=$(sudoers_gid) -DSUDOERS_MODE=$(sudoers_mode) -DWITH_SELINUX - - #### End of system configuration section. #### - -@@ -105,7 +106,7 @@ SRCS = alloc.c alloca.c check.c closefro - logging.c memrchr.c mkstemp.c parse.c parse.lex parse.yacc set_perms.c \ - sigaction.c snprintf.c strcasecmp.c strerror.c strlcat.c strlcpy.c \ - sudo.c sudo_noexec.c sudo.tab.c sudo_edit.c testsudoers.c tgetpass.c \ -- utimes.c visudo.c zero_bytes.c $(AUTH_SRCS) -+ utimes.c visudo.c zero_bytes.c $(AUTH_SRCS) selinux.c sesh.c - - AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \ - auth/kerb4.c auth/kerb5.c auth/pam.c auth/passwd.c auth/rfc1938.c \ -@@ -124,11 +125,13 @@ AUDIT_OBJS = audit_help.o - PARSEOBJS = sudo.tab.o lex.yy.o alloc.o defaults.o - - SUDOBJS = check.o env.o getspwuid.o gettime.o goodpath.o fileops.o find_path.o \ -- interfaces.o logging.o parse.o set_perms.o sudo.o sudo_edit.o \ -+ interfaces.o logging.o parse.o set_perms.o sudo.o selinux.o sudo_edit.o \ - tgetpass.o zero_bytes.o @SUDO_OBJS@ $(AUTH_OBJS) $(PARSEOBJS) $(AUDIT_OBJS) - - VISUDOBJS = visudo.o fileops.o gettime.o goodpath.o find_path.o $(PARSEOBJS) - -+SESH_OBJS = sesh.o -+ - TESTOBJS = interfaces.o testsudoers.o $(PARSEOBJS) - - LIBOBJS = @LIBOBJS@ @ALLOCA@ -@@ -149,7 +152,7 @@ DISTFILES = $(SRCS) $(HDRS) BUGS CHANGES - BINFILES= BUGS CHANGES HISTORY LICENSE README TROUBLESHOOTING \ - UPGRADE install-sh mkinstalldirs sample.syslog.conf sample.sudoers \ - sudo sudo.cat sudo.man sudo.pod sudoers sudoers.cat sudoers.man \ -- sudoers.pod visudo visudo.cat visudo.man visudo.pod -+ sudoers.pod visudo visudo.cat visudo.man visudo.pod sesh - - BINSPECIAL= INSTALL.binary Makefile.binary libtool - -@@ -181,6 +184,9 @@ sudo: $(SUDOBJS) $(LIBOBJS) - visudo: $(VISUDOBJS) $(LIBOBJS) - $(CC) -o $@ $(VISUDOBJS) $(LIBOBJS) $(LDFLAGS) $(LIBS) $(NET_LIBS) - -+sesh: $(SESH_OBJS) -+ $(CC) -o $@ $(SESH_OBJS) $(LDFLAGS) $(LIBS) -+ - testsudoers: $(TESTOBJS) $(LIBOBJS) - $(CC) -o $@ $(TESTOBJS) $(LIBOBJS) $(LDFLAGS) $(LIBS) $(NET_LIBS) - -@@ -222,6 +228,7 @@ logging.o: logging.c $(SUDODEP) - set_perms.o: set_perms.c $(SUDODEP) - tgetpass.o: tgetpass.c $(SUDODEP) - visudo.o: visudo.c $(SUDODEP) version.h -+sesh.o: sesh.c - sudo.o: sudo.c $(SUDODEP) interfaces.h version.h - interfaces.o: interfaces.c $(SUDODEP) interfaces.h - testsudoers.o: testsudoers.c $(SUDODEP) parse.h interfaces.h -@@ -320,6 +327,7 @@ install-binaries: $(PROGS) - ln $(DESTDIR)$(sudodir)/sudo $(DESTDIR)$(sudodir)/sudoedit - - $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0111 -s visudo $(DESTDIR)$(visudodir)/visudo -+ $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0111 -s sesh $(DESTDIR)$(visudodir)/sesh - - install-noexec: sudo_noexec.la - $(LIBTOOL) --mode=install $(INSTALL) sudo_noexec.la $(DESTDIR)$(noexecdir) -diff -up sudo-1.6.9p12/sudo.c.selinux sudo-1.6.9p12/sudo.c ---- sudo-1.6.9p12/sudo.c.selinux 2008-02-06 12:45:07.000000000 +0100 -+++ sudo-1.6.9p12/sudo.c 2008-02-06 13:06:50.000000000 +0100 -@@ -101,6 +101,14 @@ - #include - #endif - -+#ifdef WITH_SELINUX -+#include -+static char *role_s = NULL; /* role spec'd by user in argv[] */ -+static char *type_s = NULL; /* type spec'd by user in argv[] */ -+extern void selinux_exec(char *role_s, char *type_s, char *safe_cmnd, int NewArgc, char **NewArgv, char **environ); -+ -+#endif -+ - #include "sudo.h" - #include "interfaces.h" - #include "version.h" -@@ -487,6 +495,12 @@ main(argc, argv, envp) - if (ISSET(sudo_mode, MODE_BACKGROUND) && fork() > 0) - exit(0); - else { -+#ifdef WITH_SELINUX -+ if( is_selinux_enabled() >0 && role_s) { -+ selinux_exec(role_s, type_s, safe_cmnd, NewArgc, NewArgv, environ); /* run the command */ -+ exit(-1); -+ } -+#endif - execve(safe_cmnd, NewArgv, environ); - } - #else -@@ -817,6 +831,30 @@ parse_args(argc, argv) - NewArgv++; - break; - #endif -+#ifdef WITH_SELINUX -+ case 'r': -+ /* Must have an associated SELinux role. */ -+ if (NewArgv[1] == NULL) -+ usage(1); -+ -+ role_s = NewArgv[1]; -+ -+ /* Shift Argv over and adjust Argc. */ -+ NewArgc--; -+ NewArgv++; -+ break; -+ case 't': -+ /* Must have an associated SELinux type. */ -+ if (NewArgv[1] == NULL) -+ usage(1); -+ -+ type_s = NewArgv[1]; -+ -+ /* Shift Argv over and adjust Argc. */ -+ NewArgc--; -+ NewArgv++; -+ break; -+#endif - #ifdef HAVE_LOGIN_CAP_H - case 'c': - /* Must have an associated login class. */ -@@ -1318,6 +1356,9 @@ usage(exit_val) - #ifdef HAVE_BSD_AUTH_H - " [-a auth_type]", - #endif -+#ifdef WITH_SELINUX -+ " [-r role] [-t type] ", -+#endif - #ifdef HAVE_LOGIN_CAP_H - " [-c class|-]", - #endif -diff -up sudo-1.6.9p12/sudo.man.in.selinux sudo-1.6.9p12/sudo.man.in ---- sudo-1.6.9p12/sudo.man.in.selinux 2008-01-14 13:22:57.000000000 +0100 -+++ sudo-1.6.9p12/sudo.man.in 2008-02-06 13:06:50.000000000 +0100 -@@ -159,6 +159,7 @@ sudo, sudoedit \- execute a command as a - .PP - \&\fBsudo\fR [\fB\-bEHPS\fR] [\fB\-a\fR\ \fIauth_type\fR] - [\fB\-c\fR\ \fIclass\fR|\fI\-\fR] [\fB\-p\fR\ \fIprompt\fR] [\fB\-u\fR\ \fIusername\fR|\fI#uid\fR] -+[\fB\-r\fR \fIrole\fR ] [\fB\-t\fR \fItype\fR ] - [\fB\s-1VAR\s0\fR=\fIvalue\fR] {\fB\-i\fR\ |\ \fB\-s\fR\ |\ \fIcommand\fR} - .PP - \&\fBsudoedit\fR [\fB\-S\fR] [\fB\-a\fR\ \fIauth_type\fR] [\fB\-c\fR\ \fIclass\fR|\fI\-\fR] -@@ -323,6 +324,16 @@ preserve the invoking user's group vecto - \&\fBsudo\fR will initialize the group vector to the list of groups the - target user is in. The real and effective group IDs, however, are - still set to match the target user. -+.IP "\-r" 4 -+.IX Item "-r" -+The \fB\-r\fR (\fRrole\fR) option causes the new (SELinux) security context to have the role specified by -+\fIROLE\fR. -+.IP "\-t" 4 -+.IX Item "-t" -+The \fB\-t\fR (\fRtype\fR) option causes the new (SELinux) security context to have the have the type (domain) -+specified by -+\fITYPE\fR. -+If no type is specified, the default type is derived from the specified role. - .IP "\-p" 4 - .IX Item "-p" - The \fB\-p\fR (\fIprompt\fR) option allows you to override the default diff --git a/sudo-1.6.9p13-audit.patch b/sudo-1.6.9p13-audit.patch new file mode 100644 index 0000000..eef7ac3 --- /dev/null +++ b/sudo-1.6.9p13-audit.patch @@ -0,0 +1,422 @@ +diff -up sudo-1.6.9p13/set_perms.c.audit sudo-1.6.9p13/set_perms.c +--- sudo-1.6.9p13/set_perms.c.audit 2007-11-28 00:41:23.000000000 +0100 ++++ sudo-1.6.9p13/set_perms.c 2008-02-21 14:03:02.000000000 +0100 +@@ -53,6 +53,10 @@ + #ifdef HAVE_LOGIN_CAP_H + # include + #endif ++#if defined(WITH_AUDIT) && defined(HAVE_LIBCAP) ++# include ++# include ++#endif + + #include "sudo.h" + +@@ -119,13 +123,46 @@ set_perms(perm) + break; + + case PERM_FULL_RUNAS: +- /* headed for exec(), assume euid == ROOT_UID */ +- runas_setup(); +- if (setresuid(def_stay_setuid ? +- user_uid : runas_pw->pw_uid, +- runas_pw->pw_uid, runas_pw->pw_uid)) +- err(1, "unable to change to runas uid"); +- break; ++#if defined(WITH_AUDIT) && defined(HAVE_LIBCAP) ++ { /* BEGIN CAP BLOCK */ ++ cap_t new_caps; ++ cap_value_t cap_list[] = { CAP_AUDIT_WRITE }; ++ ++ if (runas_pw->pw_uid != ROOT_UID) { ++ new_caps = cap_init (); ++ if (!new_caps) ++ err(1, "Error initing capabilities, aborting.\n"); ++ ++ if(cap_set_flag(new_caps, CAP_PERMITTED, 1, cap_list, CAP_SET) || ++ cap_set_flag(new_caps, CAP_EFFECTIVE, 1, cap_list, CAP_SET)) { ++ err(1, "Error setting capabilities, aborting\n"); ++ } ++ ++ if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) ++ err(1, "Error setting KEEPCAPS, aborting\n"); ++ } ++#endif ++ /* headed for exec(), assume euid == ROOT_UID */ ++ runas_setup (); ++ if (setresuid(def_stay_setuid ? ++ user_uid : runas_pw->pw_uid, ++ runas_pw->pw_uid, runas_pw->pw_uid)) ++ err(1, "unable to change to runas uid"); ++ ++#if defined(WITH_AUDIT) && defined(HAVE_LIBCAP) ++ if (runas_pw->pw_uid != ROOT_UID) { ++ if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) < 0) ++ err(1, "Error resetting KEEPCAPS, aborting\n"); ++ ++ if (cap_set_proc(new_caps)) ++ err(1, "Error dropping capabilities, aborting\n"); ++ ++ if (cap_free (new_caps)) ++ err(1, "Error freeing caps\n"); ++ } ++ } /* END CAP BLOCK */ ++#endif ++ break; + + case PERM_SUDOERS: + /* assume euid == ROOT_UID, ruid == user */ +diff -up sudo-1.6.9p13/sudo.c.audit sudo-1.6.9p13/sudo.c +--- sudo-1.6.9p13/sudo.c.audit 2008-02-21 14:03:02.000000000 +0100 ++++ sudo-1.6.9p13/sudo.c 2008-02-21 14:03:02.000000000 +0100 +@@ -100,6 +100,10 @@ + # include + #endif + ++#ifdef WITH_AUDIT ++#include ++#endif ++ + #include "sudo.h" + #include "interfaces.h" + #include "version.h" +@@ -295,6 +299,10 @@ main(argc, argv, envp) + if (safe_cmnd == NULL) + safe_cmnd = estrdup(user_cmnd); + ++#if defined(WITH_AUDIT) ++ audit_help_open (); ++#endif ++ + /* + * Look up the timestamp dir owner if one is specified. + */ +@@ -305,9 +313,13 @@ main(argc, argv, envp) + pw = getpwuid(atoi(def_timestampowner + 1)); + else + pw = getpwnam(def_timestampowner); +- if (!pw) ++ if (!pw) { ++#if defined(WITH_AUDIT) ++ audit_logger(AUDIT_USER_CMD, user_cmnd, 0); ++#endif + log_error(0, "timestamp owner (%s): No such user", + def_timestampowner); ++ } + timestamp_uid = pw->pw_uid; + } + +@@ -317,15 +329,22 @@ main(argc, argv, envp) + exit(0); + } + +- if (ISSET(validated, VALIDATE_ERROR)) ++ if (ISSET(validated, VALIDATE_ERROR)) { ++#if defined(WITH_AUDIT) ++ audit_logger(AUDIT_USER_CMD, user_cmnd, 0); ++#endif + log_error(0, "parse error in %s near line %d", _PATH_SUDOERS, + errorlineno); ++ } + + /* Is root even allowed to run sudo? */ + if (user_uid == 0 && !def_root_sudo) { + (void) fprintf(stderr, + "Sorry, %s has been configured to not allow root to run it.\n", + getprogname()); ++#if defined(WITH_AUDIT) ++ audit_logger(AUDIT_USER_CMD, user_cmnd, 0); ++#endif + exit(1); + } + +@@ -339,8 +358,12 @@ main(argc, argv, envp) + + /* Bail if a tty is required and we don't have one. */ + if (def_requiretty) { +- if ((fd = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1) ++ if ((fd = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1) { ++#if defined(WITH_AUDIT) ++ audit_logger(AUDIT_USER_CMD, user_cmnd, 0); ++#endif + log_error(NO_MAIL, "sorry, you must have a tty to run sudo"); ++ } + else + (void) close(fd); + } +@@ -373,17 +396,27 @@ main(argc, argv, envp) + /* Finally tell the user if the command did not exist. */ + if (cmnd_status == NOT_FOUND_DOT) { + warnx("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.", user_cmnd, user_cmnd, user_cmnd); ++#if defined(WITH_AUDIT) ++ audit_logger(AUDIT_USER_CMD, user_cmnd, 0); ++#endif + exit(1); + } else if (cmnd_status == NOT_FOUND) { + warnx("%s: command not found", user_cmnd); ++#if defined(WITH_AUDIT) ++ audit_logger(AUDIT_USER_CMD, user_cmnd, 0); ++#endif + exit(1); + } + + /* If user specified env vars make sure sudoers allows it. */ + if (ISSET(sudo_mode, MODE_RUN) && !ISSET(validated, FLAG_SETENV)) { +- if (ISSET(sudo_mode, MODE_PRESERVE_ENV)) ++ if (ISSET(sudo_mode, MODE_PRESERVE_ENV)) { ++#if defined(WITH_AUDIT) ++ audit_logger(AUDIT_USER_CMD, user_cmnd, 0); ++#endif + log_error(NO_MAIL, + "sorry, you are not allowed to preserve the environment"); ++ } + else + validate_env_vars(sudo_user.env_vars); + } +@@ -442,6 +475,17 @@ main(argc, argv, envp) + (void) sigaction(SIGTSTP, &saved_sa_tstp, NULL); + (void) sigaction(SIGCHLD, &saved_sa_chld, NULL); + ++ if (access(safe_cmnd, X_OK) != 0) { ++ warn ("unable to execute %s", safe_cmnd); ++#ifdef WITH_AUDIT ++ audit_logger(AUDIT_USER_CMD, safe_cmnd, 0); ++#endif ++ exit(127); ++ } ++#ifdef WITH_AUDIT ++ audit_logger(AUDIT_USER_CMD, safe_cmnd, 1); ++#endif ++ + #ifndef PROFILING + if (ISSET(sudo_mode, MODE_BACKGROUND) && fork() > 0) + exit(0); +@@ -465,6 +509,9 @@ main(argc, argv, envp) + NewArgv[1] = safe_cmnd; + execve(_PATH_BSHELL, NewArgv, environ); + } ++#ifdef WITH_AUDIT ++ audit_logger(AUDIT_USER_CMD, safe_cmnd, 0); ++#endif + warn("unable to execute %s", safe_cmnd); + exit(127); + } else if (ISSET(validated, FLAG_NO_USER) || (validated & FLAG_NO_HOST)) { +diff -up sudo-1.6.9p13/configure.in.audit sudo-1.6.9p13/configure.in +--- sudo-1.6.9p13/configure.in.audit 2008-02-21 14:03:02.000000000 +0100 ++++ sudo-1.6.9p13/configure.in 2008-02-21 14:03:02.000000000 +0100 +@@ -166,6 +166,10 @@ dnl + dnl Options for --with + dnl + ++AC_ARG_WITH(audit, ++ [AC_HELP_STRING([--with-audit], [use auditing support @<:@default=yes if found@:>@])], ++ [with_audit=$withval], [with_audit=yes]) ++ + AC_ARG_WITH(CC, [ --with-CC C compiler to use], + [case $with_CC in + yes) AC_MSG_ERROR(["must give --with-CC an argument."]) +@@ -1614,6 +1618,25 @@ dnl + : ${mansectsu='8'} + : ${mansectform='5'} + ++ ++AC_SUBST(LIBAUDIT) ++if test "$with_audit" = "yes"; then ++ # See if we have the audit library ++ AC_CHECK_HEADER(libaudit.h, [audit_header="yes"], [audit_header="no"]) ++ if test "$audit_header" = "yes"; then ++ AC_CHECK_LIB(audit, audit_log_user_command, ++ [AC_DEFINE(WITH_AUDIT, 1, [Define if you want to enable Audit messages]) ++ LIBAUDIT="-laudit"]) ++ fi ++ # See if we have the libcap library ++ AC_CHECK_HEADERS(sys/capability.h sys/prctl.h, [cap_header="yes"], [cap_header="no"]) ++ if test "$cap_header" = "yes"; then ++ AC_CHECK_LIB(cap, cap_init, ++ [AC_DEFINE(HAVE_LIBCAP, 1, [SELinux libcap support]) ++ SUDO_LIBS="${SUDO_LIBS} -lcap"]) ++ fi ++fi ++ + dnl + dnl Add in any libpaths or libraries specified via configure + dnl +diff -up /dev/null sudo-1.6.9p13/audit_help.c +--- /dev/null 2008-02-05 17:16:01.642928004 +0100 ++++ sudo-1.6.9p13/audit_help.c 2008-02-21 14:20:56.000000000 +0100 +@@ -0,0 +1,124 @@ ++/* ++ * Audit helper functions used throughout sudo ++ * ++ * Copyright (C) 2007, Red Hat, Inc. ++ * ++ * 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 Julianne F. Haugh 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 JULIE HAUGH 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 JULIE HAUGH 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 ++ ++#ifdef WITH_AUDIT ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef HAVE_SELINUX ++#include ++#endif ++ ++int audit_fd; ++ ++void audit_help_open (void) ++{ ++ audit_fd = audit_open (); ++ if (audit_fd < 0) { ++ /* You get these only when the kernel doesn't have ++ * audit compiled in. */ ++ if (errno == EINVAL || errno == EPROTONOSUPPORT || ++ errno == EAFNOSUPPORT) ++ return; ++ fprintf (stderr, "Cannot open audit interface - aborting.\n"); ++ exit (1); ++ } ++} ++ ++/* ++ * This function will log a message to the audit system using a predefined ++ * message format. Parameter usage is as follows: ++ * ++ * type - type of message: AUDIT_USER_CMD ++ * command - the command being logged ++ * result - 1 is "success" and 0 is "failed" ++ * ++ */ ++void audit_logger (int type, const char *command, int result) ++{ ++ int err; ++ ++ if (audit_fd < 0) ++ return; ++ else { ++ err = audit_log_user_command (audit_fd, type, command, NULL, result); ++ /* The kernel supports auditing and we had ++ enough privilege to write to the socket. */ ++ if( err <= 0 && !(errno == EPERM && getuid() != 0) ) { ++ perror("audit_log_user_command()"); ++ } ++ } ++} ++ ++#ifdef HAVE_SELINUX ++int send_audit_message(int success, security_context_t old_context, ++ security_context_t new_context, const char *ttyn) ++{ ++ char *msg = NULL; ++ int rc; ++ ++ if (audit_fd < 0) ++ return -1; ++ ++ if (asprintf(&msg, "newrole: old-context=%s new-context=%s", ++ old_context ? old_context : "?", ++ new_context ? new_context : "?") < 0) { ++ fprintf(stderr, "Error allocating memory.\n"); ++ rc = -1; ++ goto out; ++ } ++ ++ rc = audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE, ++ msg, NULL, NULL, ttyn, success); ++ if (rc <= 0) { ++ fprintf(stderr, "Error sending audit message.\n"); ++ rc = -1; ++ goto out; ++ } ++ rc = 0; ++ ++ out: ++ free(msg); ++ return rc; ++} ++#endif ++ ++#endif /* WITH_AUDIT */ ++ ++ +diff -up sudo-1.6.9p13/Makefile.in.audit sudo-1.6.9p13/Makefile.in +--- sudo-1.6.9p13/Makefile.in.audit 2008-02-19 19:13:10.000000000 +0100 ++++ sudo-1.6.9p13/Makefile.in 2008-02-21 14:03:02.000000000 +0100 +@@ -120,11 +120,13 @@ HDRS = compat.h def_data.h defaults.h in + + AUTH_OBJS = sudo_auth.o @AUTH_OBJS@ + ++AUDIT_OBJS = audit_help.o ++ + PARSEOBJS = sudo.tab.o lex.yy.o alloc.o defaults.o + + SUDOBJS = check.o env.o getspwuid.o gettime.o goodpath.o fileops.o find_path.o \ + interfaces.o logging.o parse.o set_perms.o sudo.o sudo_edit.o \ +- tgetpass.o zero_bytes.o @SUDO_OBJS@ $(AUTH_OBJS) $(PARSEOBJS) ++ tgetpass.o zero_bytes.o @SUDO_OBJS@ $(AUTH_OBJS) $(PARSEOBJS) $(AUDIT_OBJS) + + VISUDOBJS = visudo.o fileops.o gettime.o goodpath.o find_path.o $(PARSEOBJS) + +@@ -276,6 +278,9 @@ securid5.o: $(authdir)/securid5.c $(AUTH + sia.o: $(authdir)/sia.c $(AUTHDEP) + $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/sia.c + ++audit_help.o: audit_help.c sudo.h ++ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(LIBADUIT) $(srcdir)/audit_help.c ++ + sudo.man.in: $(srcdir)/sudo.pod + @rm -f $(srcdir)/$@ + ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' sudo.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudo.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" | perl -p sudo.man.pl >> $@ ) +diff -up sudo-1.6.9p13/sudo.h.audit sudo-1.6.9p13/sudo.h +--- sudo-1.6.9p13/sudo.h.audit 2008-02-21 14:03:02.000000000 +0100 ++++ sudo-1.6.9p13/sudo.h 2008-02-21 14:03:02.000000000 +0100 +@@ -23,6 +23,8 @@ + #ifndef _SUDO_SUDO_H + #define _SUDO_SUDO_H + ++#include ++ + #include + #include + #include "compat.h" +@@ -287,4 +289,10 @@ extern int sudo_mode; + extern int errno; + #endif + ++#ifdef WITH_AUDIT ++extern int audit_fd; ++extern void audit_help_open (void); ++extern void audit_logger (int, const char *, int); ++#endif ++ + #endif /* _SUDO_SUDO_H */ diff --git a/sudo-1.6.9p4-audit.patch b/sudo-1.6.9p4-audit.patch deleted file mode 100644 index 158dee0..0000000 --- a/sudo-1.6.9p4-audit.patch +++ /dev/null @@ -1,393 +0,0 @@ -diff -up sudo-1.6.9p12/set_perms.c.audit sudo-1.6.9p12/set_perms.c ---- sudo-1.6.9p12/set_perms.c.audit 2007-11-28 00:41:23.000000000 +0100 -+++ sudo-1.6.9p12/set_perms.c 2008-02-05 14:09:29.000000000 +0100 -@@ -53,6 +53,10 @@ - #ifdef HAVE_LOGIN_CAP_H - # include - #endif -+#if defined(WITH_AUDIT) && defined(HAVE_LIBCAP) -+# include -+# include -+#endif - - #include "sudo.h" - -@@ -119,13 +123,46 @@ set_perms(perm) - break; - - case PERM_FULL_RUNAS: -- /* headed for exec(), assume euid == ROOT_UID */ -- runas_setup(); -- if (setresuid(def_stay_setuid ? -- user_uid : runas_pw->pw_uid, -- runas_pw->pw_uid, runas_pw->pw_uid)) -- err(1, "unable to change to runas uid"); -- break; -+#if defined(WITH_AUDIT) && defined(HAVE_LIBCAP) -+ { /* BEGIN CAP BLOCK */ -+ cap_t new_caps; -+ cap_value_t cap_list[] = { CAP_AUDIT_WRITE }; -+ -+ if (runas_pw->pw_uid != ROOT_UID) { -+ new_caps = cap_init (); -+ if (!new_caps) -+ err(1, "Error initing capabilities, aborting.\n"); -+ -+ if(cap_set_flag(new_caps, CAP_PERMITTED, 1, cap_list, CAP_SET) || -+ cap_set_flag(new_caps, CAP_EFFECTIVE, 1, cap_list, CAP_SET)) { -+ err(1, "Error setting capabilities, aborting\n"); -+ } -+ -+ if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) -+ err(1, "Error setting KEEPCAPS, aborting\n"); -+ } -+#endif -+ /* headed for exec(), assume euid == ROOT_UID */ -+ runas_setup (); -+ if (setresuid(def_stay_setuid ? -+ user_uid : runas_pw->pw_uid, -+ runas_pw->pw_uid, runas_pw->pw_uid)) -+ err(1, "unable to change to runas uid"); -+ -+#if defined(WITH_AUDIT) && defined(HAVE_LIBCAP) -+ if (runas_pw->pw_uid != ROOT_UID) { -+ if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) < 0) -+ err(1, "Error resetting KEEPCAPS, aborting\n"); -+ -+ if (cap_set_proc(new_caps)) -+ err(1, "Error dropping capabilities, aborting\n"); -+ -+ if (cap_free (new_caps)) -+ err(1, "Error freeing caps\n"); -+ } -+ } /* END CAP BLOCK */ -+#endif -+ break; - - case PERM_SUDOERS: - /* assume euid == ROOT_UID, ruid == user */ -diff -up sudo-1.6.9p12/sudo.c.audit sudo-1.6.9p12/sudo.c ---- sudo-1.6.9p12/sudo.c.audit 2008-02-05 13:57:21.000000000 +0100 -+++ sudo-1.6.9p12/sudo.c 2008-02-05 13:57:21.000000000 +0100 -@@ -97,6 +97,10 @@ - # include - #endif - -+#ifdef WITH_AUDIT -+#include -+#endif -+ - #include "sudo.h" - #include "interfaces.h" - #include "version.h" -@@ -292,6 +296,10 @@ main(argc, argv, envp) - if (safe_cmnd == NULL) - safe_cmnd = estrdup(user_cmnd); - -+#if defined(WITH_AUDIT) -+ audit_help_open (); -+#endif -+ - /* - * Look up the timestamp dir owner if one is specified. - */ -@@ -302,9 +310,13 @@ main(argc, argv, envp) - pw = getpwuid(atoi(def_timestampowner + 1)); - else - pw = getpwnam(def_timestampowner); -- if (!pw) -+ if (!pw) { -+#if defined(WITH_AUDIT) -+ audit_logger(AUDIT_USER_CMD, user_cmnd, 0); -+#endif - log_error(0, "timestamp owner (%s): No such user", - def_timestampowner); -+ } - timestamp_uid = pw->pw_uid; - } - -@@ -314,15 +326,22 @@ main(argc, argv, envp) - exit(0); - } - -- if (ISSET(validated, VALIDATE_ERROR)) -+ if (ISSET(validated, VALIDATE_ERROR)) { -+#if defined(WITH_AUDIT) -+ audit_logger(AUDIT_USER_CMD, user_cmnd, 0); -+#endif - log_error(0, "parse error in %s near line %d", _PATH_SUDOERS, - errorlineno); -+ } - - /* Is root even allowed to run sudo? */ - if (user_uid == 0 && !def_root_sudo) { - (void) fprintf(stderr, - "Sorry, %s has been configured to not allow root to run it.\n", - getprogname()); -+#if defined(WITH_AUDIT) -+ audit_logger(AUDIT_USER_CMD, user_cmnd, 0); -+#endif - exit(1); - } - -@@ -336,8 +355,12 @@ main(argc, argv, envp) - - /* Bail if a tty is required and we don't have one. */ - if (def_requiretty) { -- if ((fd = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1) -+ if ((fd = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1) { -+#if defined(WITH_AUDIT) -+ audit_logger(AUDIT_USER_CMD, user_cmnd, 0); -+#endif - log_error(NO_MAIL, "sorry, you must have a tty to run sudo"); -+ } - else - (void) close(fd); - } -@@ -370,17 +393,27 @@ main(argc, argv, envp) - /* Finally tell the user if the command did not exist. */ - if (cmnd_status == NOT_FOUND_DOT) { - warnx("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.", user_cmnd, user_cmnd, user_cmnd); -+#if defined(WITH_AUDIT) -+ audit_logger(AUDIT_USER_CMD, user_cmnd, 0); -+#endif - exit(1); - } else if (cmnd_status == NOT_FOUND) { - warnx("%s: command not found", user_cmnd); -+#if defined(WITH_AUDIT) -+ audit_logger(AUDIT_USER_CMD, user_cmnd, 0); -+#endif - exit(1); - } - - /* If user specified env vars make sure sudoers allows it. */ - if (ISSET(sudo_mode, MODE_RUN) && !ISSET(validated, FLAG_SETENV)) { -- if (ISSET(sudo_mode, MODE_PRESERVE_ENV)) -+ if (ISSET(sudo_mode, MODE_PRESERVE_ENV)) { -+#if defined(WITH_AUDIT) -+ audit_logger(AUDIT_USER_CMD, user_cmnd, 0); -+#endif - log_error(NO_MAIL, - "sorry, you are not allowed to preserve the environment"); -+ } - else - validate_env_vars(sudo_user.env_vars); - } -@@ -439,11 +472,23 @@ main(argc, argv, envp) - (void) sigaction(SIGTSTP, &saved_sa_tstp, NULL); - (void) sigaction(SIGCHLD, &saved_sa_chld, NULL); - -+ if (access(safe_cmnd, X_OK) != 0) { -+ warn ("unable to execute %s", safe_cmnd); -+#ifdef WITH_AUDIT -+ audit_logger(AUDIT_USER_CMD, safe_cmnd, 0); -+#endif -+ exit(127); -+ } -+#ifdef WITH_AUDIT -+ audit_logger(AUDIT_USER_CMD, safe_cmnd, 1); -+#endif -+ - #ifndef PROFILING - if (ISSET(sudo_mode, MODE_BACKGROUND) && fork() > 0) - exit(0); -- else -+ else { - execve(safe_cmnd, NewArgv, environ); -+ } - #else - exit(0); - #endif /* PROFILING */ -@@ -456,6 +501,9 @@ main(argc, argv, envp) - NewArgv[1] = safe_cmnd; - execve(_PATH_BSHELL, NewArgv, environ); - } -+#ifdef WITH_AUDIT -+ audit_logger(AUDIT_USER_CMD, safe_cmnd, 0); -+#endif - warn("unable to execute %s", safe_cmnd); - exit(127); - } else if (ISSET(validated, FLAG_NO_USER) || (validated & FLAG_NO_HOST)) { -diff -up sudo-1.6.9p12/configure.in.audit sudo-1.6.9p12/configure.in ---- sudo-1.6.9p12/configure.in.audit 2008-02-05 13:57:21.000000000 +0100 -+++ sudo-1.6.9p12/configure.in 2008-02-05 13:57:21.000000000 +0100 -@@ -154,6 +154,10 @@ dnl - dnl Options for --with - dnl - -+AC_ARG_WITH(audit, -+ [AC_HELP_STRING([--with-audit], [use auditing support @<:@default=yes if found@:>@])], -+ [with_audit=$withval], [with_audit=yes]) -+ - AC_ARG_WITH(CC, [ --with-CC C compiler to use], - [case $with_CC in - yes) AC_MSG_ERROR(["must give --with-CC an argument."]) -@@ -1588,6 +1592,25 @@ dnl - : ${mansectsu='8'} - : ${mansectform='5'} - -+ -+AC_SUBST(LIBAUDIT) -+if test "$with_audit" = "yes"; then -+ # See if we have the audit library -+ AC_CHECK_HEADER(libaudit.h, [audit_header="yes"], [audit_header="no"]) -+ if test "$audit_header" = "yes"; then -+ AC_CHECK_LIB(audit, audit_log_user_command, -+ [AC_DEFINE(WITH_AUDIT, 1, [Define if you want to enable Audit messages]) -+ LIBAUDIT="-laudit"]) -+ fi -+ # See if we have the libcap library -+ AC_CHECK_HEADERS(sys/capability.h sys/prctl.h, [cap_header="yes"], [cap_header="no"]) -+ if test "$cap_header" = "yes"; then -+ AC_CHECK_LIB(cap, cap_init, -+ [AC_DEFINE(HAVE_LIBCAP, 1, [SELinux libcap support]) -+ SUDO_LIBS="${SUDO_LIBS} -lcap"]) -+ fi -+fi -+ - dnl - dnl Add in any libpaths or libraries specified via configure - dnl -diff -up /dev/null sudo-1.6.9p12/audit_help.c ---- /dev/null 2008-02-05 11:01:55.583821645 +0100 -+++ sudo-1.6.9p12/audit_help.c 2008-02-05 13:57:21.000000000 +0100 -@@ -0,0 +1,88 @@ -+/* -+ * Audit helper functions used throughout sudo -+ * -+ * Copyright (C) 2007, Red Hat, Inc. -+ * -+ * 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 Julianne F. Haugh 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 JULIE HAUGH 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 JULIE HAUGH 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 -+ -+#ifdef WITH_AUDIT -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+int audit_fd; -+ -+void audit_help_open (void) -+{ -+ audit_fd = audit_open (); -+ if (audit_fd < 0) { -+ /* You get these only when the kernel doesn't have -+ * audit compiled in. */ -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || -+ errno == EAFNOSUPPORT) -+ return; -+ fprintf (stderr, "Cannot open audit interface - aborting.\n"); -+ exit (1); -+ } -+} -+ -+/* -+ * This function will log a message to the audit system using a predefined -+ * message format. Parameter usage is as follows: -+ * -+ * type - type of message: AUDIT_USER_CMD -+ * command - the command being logged -+ * result - 1 is "success" and 0 is "failed" -+ * -+ */ -+void audit_logger (int type, const char *command, int result) -+{ -+ int err; -+ -+ if (audit_fd < 0) -+ return; -+ else { -+ err = audit_log_user_command (audit_fd, type, command, NULL, result); -+ /* The kernel supports auditing and we had -+ enough privilege to write to the socket. */ -+ if( err <= 0 && !(errno == EPERM && getuid() != 0) ) { -+ perror("audit_log_user_command()"); -+ } -+ } -+} -+ -+ -+#endif /* WITH_AUDIT */ -+ -+ -diff -up sudo-1.6.9p12/Makefile.in.audit sudo-1.6.9p12/Makefile.in ---- sudo-1.6.9p12/Makefile.in.audit 2008-01-14 13:22:57.000000000 +0100 -+++ sudo-1.6.9p12/Makefile.in 2008-02-05 13:57:21.000000000 +0100 -@@ -119,11 +119,13 @@ HDRS = compat.h def_data.h defaults.h in - - AUTH_OBJS = sudo_auth.o @AUTH_OBJS@ - -+AUDIT_OBJS = audit_help.o -+ - PARSEOBJS = sudo.tab.o lex.yy.o alloc.o defaults.o - - SUDOBJS = check.o env.o getspwuid.o gettime.o goodpath.o fileops.o find_path.o \ - interfaces.o logging.o parse.o set_perms.o sudo.o sudo_edit.o \ -- tgetpass.o zero_bytes.o @SUDO_OBJS@ $(AUTH_OBJS) $(PARSEOBJS) -+ tgetpass.o zero_bytes.o @SUDO_OBJS@ $(AUTH_OBJS) $(PARSEOBJS) $(AUDIT_OBJS) - - VISUDOBJS = visudo.o fileops.o gettime.o goodpath.o find_path.o $(PARSEOBJS) - -@@ -274,6 +276,9 @@ securid5.o: $(authdir)/securid5.c $(AUTH - sia.o: $(authdir)/sia.c $(AUTHDEP) - $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/sia.c - -+audit_help.o: audit_help.c sudo.h -+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(LIBADUIT) $(srcdir)/audit_help.c -+ - sudo.man.in: $(srcdir)/sudo.pod - @rm -f $(srcdir)/$@ - ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e 1d -e '/^=pod/q' -e 's/^/.\\" /p' sudo.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudo.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" >> $@ ) -diff -up sudo-1.6.9p12/sudo.h.audit sudo-1.6.9p12/sudo.h ---- sudo-1.6.9p12/sudo.h.audit 2008-02-05 13:57:21.000000000 +0100 -+++ sudo-1.6.9p12/sudo.h 2008-02-05 13:57:21.000000000 +0100 -@@ -23,6 +23,8 @@ - #ifndef _SUDO_SUDO_H - #define _SUDO_SUDO_H - -+#include -+ - #include - #include - #include "compat.h" -@@ -278,4 +280,10 @@ extern int sudo_mode; - extern int errno; - #endif - -+#ifdef WITH_AUDIT -+extern int audit_fd; -+extern void audit_help_open (void); -+extern void audit_logger (int, const char *, int); -+#endif -+ - #endif /* _SUDO_SUDO_H */ diff --git a/sudo.spec b/sudo.spec index b460ec2..d45b69b 100644 --- a/sudo.spec +++ b/sudo.spec @@ -1,6 +1,6 @@ Summary: Allows restricted root access for specified users Name: sudo -Version: 1.6.9p12 +Version: 1.6.9p13 Release: 1%{?dist} License: BSD Group: Applications/System @@ -26,8 +26,7 @@ Patch2: sudo-1.6.9p4-login.patch # the rest, see changelog Patch3: sudo-1.6.9p4-getgrouplist.patch Patch4: sudo-1.6.9p12-noPam.patch -Patch5: sudo-1.6.9p4-audit.patch -Patch6: sudo-1.6.9p12-selinux.patch +Patch5: sudo-1.6.9p13-audit.patch %description Sudo (superuser do) allows a system administrator to give certain @@ -47,7 +46,6 @@ on many different machines. %patch3 -p1 -b .getgrouplist %patch4 -p1 -b .noPam %patch5 -p1 -b .audit -%patch6 -p1 -b .selinux autoreconf @@ -72,7 +70,8 @@ export CFLAGS="$RPM_OPT_FLAGS $F_PIE" LDFLAGS="-pie" --with-env-editor \ --with-ignore-dot \ --with-tty-tickets \ - --with-ldap + --with-ldap \ + --with-selinux # --without-kerb5 \ # --without-kerb4 make @@ -118,7 +117,7 @@ rm -rf $RPM_BUILD_ROOT %attr(4111,root,root) %{_bindir}/sudo %attr(4111,root,root) %{_bindir}/sudoedit %attr(0755,root,root) %{_sbindir}/visudo -%attr(0755,root,root) %{_sbindir}/sesh +%attr(0755,root,root) %{_libexecdir}/sesh %{_libexecdir}/sudo_noexec.* %{_mandir}/man5/sudoers.5* %{_mandir}/man8/sudo.8* @@ -130,6 +129,9 @@ rm -rf $RPM_BUILD_ROOT /bin/chmod 0440 /etc/sudoers || : %changelog +* Thu Feb 21 2008 Peter Vrabec 1.6.9p13-1 +- upgrade to the latest upstream release + * Wed Feb 06 2008 Peter Vrabec 1.6.9p12-1 - upgrade to the latest upstream release - add selinux support