sudo/sudo-1.6.9p13-audit.patch

374 lines
13 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diff -up /dev/null sudo-1.6.9p17/audit_help.c
--- /dev/null 2008-08-23 21:55:45.734000982 +0200
+++ sudo-1.6.9p17/audit_help.c 2008-09-02 15:49:38.000000000 +0200
@@ -0,0 +1,140 @@
+/*
+ * 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 <config.h>
+
+#ifdef WITH_AUDIT
+
+#include <stdlib.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <libaudit.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#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
+ * params - parames of the command
+ * result - 1 is "success" and 0 is "failed"
+ *
+ */
+void audit_logger (int type, const char *command, const char *params, int result)
+{
+ int err;
+ char *msg;
+
+ if( audit_fd < 0 )
+ return;
+ else {
+
+ if( params )
+ err = asprintf(&msg, "%s %s", command, params);
+ else
+ err = asprintf(&msg, "%s", command);
+ if (err < 0) {
+ fprintf (stderr, "Memory allocation for audit message wasnt possible.\n");
+ return;
+ }
+
+ err = audit_log_user_command (audit_fd, type, msg, NULL, result);
+ /* The kernel supports auditing and we had
+ enough privilege to write to the socket. */
+ if( err <= 0 && !((errno == EPERM && getuid() > 0) || errno == ECONNREFUSED ) ) {
+ perror("audit_log_user_command()");
+ }
+
+ free(msg);
+ }
+}
+
+#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.9p17/configure.in.audit sudo-1.6.9p17/configure.in
--- sudo-1.6.9p17/configure.in.audit 2008-09-02 15:48:46.000000000 +0200
+++ sudo-1.6.9p17/configure.in 2008-09-02 15:48:46.000000000 +0200
@@ -167,6 +167,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."])
@@ -1616,6 +1620,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 sudo-1.6.9p17/Makefile.in.audit sudo-1.6.9p17/Makefile.in
--- sudo-1.6.9p17/Makefile.in.audit 2008-06-22 22:29:03.000000000 +0200
+++ sudo-1.6.9p17/Makefile.in 2008-09-02 15:48:46.000000000 +0200
@@ -121,11 +121,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)
@@ -277,6 +279,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.9p17/set_perms.c.audit sudo-1.6.9p17/set_perms.c
--- sudo-1.6.9p17/set_perms.c.audit 2007-11-28 00:41:23.000000000 +0100
+++ sudo-1.6.9p17/set_perms.c 2008-09-02 15:48:46.000000000 +0200
@@ -53,6 +53,10 @@
#ifdef HAVE_LOGIN_CAP_H
# include <login_cap.h>
#endif
+#if defined(WITH_AUDIT) && defined(HAVE_LIBCAP)
+# include <sys/prctl.h>
+# include <sys/capability.h>
+#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.9p17/sudo.c.audit sudo-1.6.9p17/sudo.c
--- sudo-1.6.9p17/sudo.c.audit 2008-09-02 15:48:46.000000000 +0200
+++ sudo-1.6.9p17/sudo.c 2008-09-02 15:48:46.000000000 +0200
@@ -100,6 +100,10 @@
# include <selinux/selinux.h>
#endif
+#ifdef WITH_AUDIT
+#include <libaudit.h>
+#endif
+
#include "sudo.h"
#include "interfaces.h"
#include "version.h"
@@ -289,6 +293,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.
*/
@@ -435,6 +443,17 @@ main(argc, argv, envp)
(void) sigaction(SIGQUIT, &saved_sa_quit, NULL);
(void) sigaction(SIGTSTP, &saved_sa_tstp, 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, user_args, 0);
+#endif
+ exit(127);
+ }
+#ifdef WITH_AUDIT
+ audit_logger(AUDIT_USER_CMD, safe_cmnd, user_args, 1);
+#endif
+
#ifndef PROFILING
if (ISSET(sudo_mode, MODE_BACKGROUND) && fork() > 0)
exit(0);
@@ -458,10 +477,16 @@ main(argc, argv, envp)
NewArgv[1] = safe_cmnd;
execve(_PATH_BSHELL, NewArgv, environ);
}
+#ifdef WITH_AUDIT
+ audit_logger(AUDIT_USER_CMD, safe_cmnd, user_args, 0);
+#endif
warn("unable to execute %s", safe_cmnd);
exit(127);
} else if (ISSET(validated, FLAG_NO_USER) || (validated & FLAG_NO_HOST)) {
log_auth(validated, 1);
+#ifdef WITH_AUDIT
+ audit_logger(AUDIT_USER_CMD, safe_cmnd, user_args, 0);
+#endif
exit(1);
} else if (ISSET(validated, VALIDATE_NOT_OK)) {
if (def_path_info) {
@@ -482,6 +507,9 @@ main(argc, argv, envp)
/* Just tell the user they are not allowed to run foo. */
log_auth(validated, 1);
}
+#ifdef WITH_AUDIT
+ audit_logger(AUDIT_USER_CMD, safe_cmnd, user_args, 0);
+#endif
exit(1);
} else {
/* should never get here */
diff -up sudo-1.6.9p17/sudo.h.audit sudo-1.6.9p17/sudo.h
--- sudo-1.6.9p17/sudo.h.audit 2008-09-02 15:48:46.000000000 +0200
+++ sudo-1.6.9p17/sudo.h 2008-09-02 15:48:46.000000000 +0200
@@ -23,6 +23,8 @@
#ifndef _SUDO_SUDO_H
#define _SUDO_SUDO_H
+#include <config.h>
+
#include <pathnames.h>
#include <limits.h>
#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 *, const char *, int);
+#endif
+
#endif /* _SUDO_SUDO_H */