Add Linux audit support.

This commit is contained in:
Todd C. Miller
2010-06-16 11:17:02 -04:00
parent fdd4805438
commit 2cd108304d
13 changed files with 237 additions and 32 deletions

View File

@@ -144,6 +144,10 @@ Special features/options:
--with-csops --with-csops
Add CSOps standard options. You probably aren't interested in this. Add CSOps standard options. You probably aren't interested in this.
--with-linux-audit
Enable audit support for Linux systems. Audits attempts
to run a command as well as SELinux role changes.
--with-skey[=DIR] --with-skey[=DIR]
Enable S/Key OTP (One Time Password) support. If specified, Enable S/Key OTP (One Time Password) support. If specified,
DIR should contain include and lib directories with skey.h DIR should contain include and lib directories with skey.h

View File

@@ -149,6 +149,8 @@ plugins/sudoers/interfaces.c
plugins/sudoers/interfaces.h plugins/sudoers/interfaces.h
plugins/sudoers/iolog.c plugins/sudoers/iolog.c
plugins/sudoers/ldap.c plugins/sudoers/ldap.c
plugins/sudoers/linux_audit.c
plugins/sudoers/linux_audit.h
plugins/sudoers/logging.c plugins/sudoers/logging.c
plugins/sudoers/logging.h plugins/sudoers/logging.h
plugins/sudoers/match.c plugins/sudoers/match.c

View File

@@ -30,6 +30,9 @@ What's new in Sudo 1.7.3?
commands as a non-root user and when one of stdin, stdout or stderr commands as a non-root user and when one of stdin, stdout or stderr
is not a terminal. is not a terminal.
* Sudo will now use the Linux audit system with configure with
the --with-linux-audit flag.
* Sudo now uses mbr_check_membership() on systems that support it * Sudo now uses mbr_check_membership() on systems that support it
to determine group membership. Currently, only Darwin (Mac OS X) to determine group membership. Currently, only Darwin (Mac OS X)
supports this. supports this.

View File

@@ -64,7 +64,7 @@
/* Define to 1 if you use BSD authentication. */ /* Define to 1 if you use BSD authentication. */
#undef HAVE_BSD_AUTH_H #undef HAVE_BSD_AUTH_H
/* Define to 1 to enable BSM auditing. */ /* Define to 1 to enable BSM audit support. */
#undef HAVE_BSM_AUDIT #undef HAVE_BSM_AUDIT
/* Define to 1 if you have the `closefrom' function. */ /* Define to 1 if you have the `closefrom' function. */
@@ -301,6 +301,9 @@
/* Define to 1 if you have the `ldap_unbind_ext_s' function. */ /* Define to 1 if you have the `ldap_unbind_ext_s' function. */
#undef HAVE_LDAP_UNBIND_EXT_S #undef HAVE_LDAP_UNBIND_EXT_S
/* Define to 1 to enable Linux audit support. */
#undef HAVE_LINUX_AUDIT
/* Define to 1 if you have the `lockf' function. */ /* Define to 1 if you have the `lockf' function. */
#undef HAVE_LOCKF #undef HAVE_LOCKF

49
configure vendored
View File

@@ -908,6 +908,7 @@ with_CC
with_rpath with_rpath
with_blibpath with_blibpath
with_bsm_audit with_bsm_audit
with_linux_audit
with_incpath with_incpath
with_libpath with_libpath
with_libraries with_libraries
@@ -1663,6 +1664,7 @@ Optional Packages:
--with-rpath pass -R flag in addition to -L for lib paths --with-rpath pass -R flag in addition to -L for lib paths
--with-blibpath=PATH pass -blibpath flag to ld for additional lib paths --with-blibpath=PATH pass -blibpath flag to ld for additional lib paths
--with-bsm-audit enable BSM audit support --with-bsm-audit enable BSM audit support
--with-linux-audit enable Linux audit support
--with-incpath additional places to look for include files --with-incpath additional places to look for include files
--with-libpath additional places to look for libraries --with-libpath additional places to look for libraries
--with-libraries additional libraries to link with --with-libraries additional libraries to link with
@@ -2925,7 +2927,7 @@ if test "${with_bsm_audit+set}" = set; then :
yes) $as_echo "#define HAVE_BSM_AUDIT 1" >>confdefs.h yes) $as_echo "#define HAVE_BSM_AUDIT 1" >>confdefs.h
SUDOERS_LIBS="${SUDOERS_LIBS} -lbsm" SUDOERS_LIBS="${SUDOERS_LIBS} -lbsm"
SUDOERS_OBJS="${SUDOERS_OBJS} bsm_audit.o" SUDOERS_OBJS="${SUDOERS_OBJS} bsm_audit.lo"
;; ;;
no) ;; no) ;;
*) as_fn_error "\"--with-bsm-audit does not take an argument.\"" "$LINENO" 5 *) as_fn_error "\"--with-bsm-audit does not take an argument.\"" "$LINENO" 5
@@ -2935,6 +2937,22 @@ fi
# Check whether --with-linux-audit was given.
if test "${with_linux_audit+set}" = set; then :
withval=$with_linux_audit; case $with_linux_audit in
yes) $as_echo "#define HAVE_LINUX_AUDIT 1" >>confdefs.h
SUDO_LIBS="${SUDOERS_LIBS} -laudit"
SUDOERS_OBJS="${SUDOERS_OBJS} linux_audit.lo"
;;
no) ;;
*) as_fn_error "\"--with-linux-audit does not take an argument.\"" "$LINENO" 5
;;
esac
fi
# Check whether --with-incpath was given. # Check whether --with-incpath was given.
if test "${with_incpath+set}" = set; then : if test "${with_incpath+set}" = set; then :
withval=$with_incpath; case $with_incpath in withval=$with_incpath; case $with_incpath in
@@ -6608,13 +6626,13 @@ if test "${lt_cv_nm_interface+set}" = set; then :
else else
lt_cv_nm_interface="BSD nm" lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext echo "int some_variable = 0;" > conftest.$ac_ext
(eval echo "\"\$as_me:6611: $ac_compile\"" >&5) (eval echo "\"\$as_me:6629: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err) (eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5 cat conftest.err >&5
(eval echo "\"\$as_me:6614: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval echo "\"\$as_me:6632: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5 cat conftest.err >&5
(eval echo "\"\$as_me:6617: output\"" >&5) (eval echo "\"\$as_me:6635: output\"" >&5)
cat conftest.out >&5 cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin" lt_cv_nm_interface="MS dumpbin"
@@ -7819,7 +7837,7 @@ ia64-*-hpux*)
;; ;;
*-*-irix6*) *-*-irix6*)
# Find out which ABI we are using. # Find out which ABI we are using.
echo '#line 7822 "configure"' > conftest.$ac_ext echo '#line 7840 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5 (eval $ac_compile) 2>&5
ac_status=$? ac_status=$?
@@ -9211,11 +9229,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:9214: $lt_compile\"" >&5) (eval echo "\"\$as_me:9232: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:9218: \$? = $ac_status" >&5 echo "$as_me:9236: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@@ -9550,11 +9568,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:9553: $lt_compile\"" >&5) (eval echo "\"\$as_me:9571: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:9557: \$? = $ac_status" >&5 echo "$as_me:9575: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@@ -9655,11 +9673,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:9658: $lt_compile\"" >&5) (eval echo "\"\$as_me:9676: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 cat out/conftest.err >&5
echo "$as_me:9662: \$? = $ac_status" >&5 echo "$as_me:9680: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
@@ -9710,11 +9728,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:9713: $lt_compile\"" >&5) (eval echo "\"\$as_me:9731: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 cat out/conftest.err >&5
echo "$as_me:9717: \$? = $ac_status" >&5 echo "$as_me:9735: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
@@ -12077,7 +12095,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 12080 "configure" #line 12098 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@@ -12173,7 +12191,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 12176 "configure" #line 12194 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@@ -20343,5 +20361,6 @@ fi

View File

@@ -235,13 +235,27 @@ AC_ARG_WITH(bsm-audit, [AS_HELP_STRING([--with-bsm-audit], [enable BSM audit sup
[case $with_bsm_audit in [case $with_bsm_audit in
yes) AC_DEFINE(HAVE_BSM_AUDIT) yes) AC_DEFINE(HAVE_BSM_AUDIT)
SUDOERS_LIBS="${SUDOERS_LIBS} -lbsm" SUDOERS_LIBS="${SUDOERS_LIBS} -lbsm"
SUDOERS_OBJS="${SUDOERS_OBJS} bsm_audit.o" SUDOERS_OBJS="${SUDOERS_OBJS} bsm_audit.lo"
;; ;;
no) ;; no) ;;
*) AC_MSG_ERROR(["--with-bsm-audit does not take an argument."]) *) AC_MSG_ERROR(["--with-bsm-audit does not take an argument."])
;; ;;
esac]) esac])
dnl
dnl Handle Linux auditing support.
dnl
AC_ARG_WITH(linux-audit, [AS_HELP_STRING([--with-linux-audit], [enable Linux audit support])],
[case $with_linux_audit in
yes) AC_DEFINE(HAVE_LINUX_AUDIT)
SUDO_LIBS="${SUDOERS_LIBS} -laudit"
SUDOERS_OBJS="${SUDOERS_OBJS} linux_audit.lo"
;;
no) ;;
*) AC_MSG_ERROR(["--with-linux-audit does not take an argument."])
;;
esac])
AC_ARG_WITH(incpath, [AS_HELP_STRING([--with-incpath], [additional places to look for include files])], AC_ARG_WITH(incpath, [AS_HELP_STRING([--with-incpath], [additional places to look for include files])],
[case $with_incpath in [case $with_incpath in
yes) AC_MSG_ERROR(["must give --with-incpath an argument."]) yes) AC_MSG_ERROR(["must give --with-incpath an argument."])
@@ -2786,7 +2800,7 @@ AH_TEMPLATE(HAL_INSULTS, [Define to 1 if you want 2001-like insults.])
AH_TEMPLATE(HAVE_AFS, [Define to 1 if you use AFS.]) AH_TEMPLATE(HAVE_AFS, [Define to 1 if you use AFS.])
AH_TEMPLATE(HAVE_AIXAUTH, [Define to 1 if you use AIX general authentication.]) AH_TEMPLATE(HAVE_AIXAUTH, [Define to 1 if you use AIX general authentication.])
AH_TEMPLATE(HAVE_BSD_AUTH_H, [Define to 1 if you use BSD authentication.]) AH_TEMPLATE(HAVE_BSD_AUTH_H, [Define to 1 if you use BSD authentication.])
AH_TEMPLATE(HAVE_BSM_AUDIT, [Define to 1 to enable BSM auditing.]) AH_TEMPLATE(HAVE_BSM_AUDIT, [Define to 1 to enable BSM audit support.])
AH_TEMPLATE(HAVE_DCE, [Define to 1 if you use OSF DCE.]) AH_TEMPLATE(HAVE_DCE, [Define to 1 if you use OSF DCE.])
AH_TEMPLATE(HAVE_DD_FD, [Define to 1 if your `DIR' contains dd_fd.]) AH_TEMPLATE(HAVE_DD_FD, [Define to 1 if your `DIR' contains dd_fd.])
AH_TEMPLATE(HAVE_DIRFD, [Define to 1 if you have the `dirfd' function or macro.]) AH_TEMPLATE(HAVE_DIRFD, [Define to 1 if you have the `dirfd' function or macro.])
@@ -2814,6 +2828,7 @@ AH_TEMPLATE(HAVE_KRB5_INIT_SECURE_CONTEXT, [Define to 1 if you have the `krb5_in
AH_TEMPLATE(HAVE_KRB5_VERIFY_USER, [Define to 1 if you have the `krb5_verify_user' function.]) AH_TEMPLATE(HAVE_KRB5_VERIFY_USER, [Define to 1 if you have the `krb5_verify_user' function.])
AH_TEMPLATE(HAVE_LBER_H, [Define to 1 if your LDAP needs <lber.h>. (OpenLDAP does not)]) AH_TEMPLATE(HAVE_LBER_H, [Define to 1 if your LDAP needs <lber.h>. (OpenLDAP does not)])
AH_TEMPLATE(HAVE_LDAP, [Define to 1 if you use LDAP for sudoers.]) AH_TEMPLATE(HAVE_LDAP, [Define to 1 if you use LDAP for sudoers.])
AH_TEMPLATE(HAVE_LINUX_AUDIT, [Define to 1 to enable Linux audit support.])
AH_TEMPLATE(HAVE_OPIE, [Define to 1 if you use NRL OPIE.]) AH_TEMPLATE(HAVE_OPIE, [Define to 1 if you use NRL OPIE.])
AH_TEMPLATE(HAVE_PAM, [Define to 1 if you use PAM authentication.]) AH_TEMPLATE(HAVE_PAM, [Define to 1 if you use PAM authentication.])
AH_TEMPLATE(HAVE_PROJECT_H, [Define to 1 if you have the <project.h> header file.]) AH_TEMPLATE(HAVE_PROJECT_H, [Define to 1 if you have the <project.h> header file.])

View File

@@ -186,8 +186,8 @@ $(devdir)/getdate.c: $(srcdir)/getdate.y
# Sudoers dependencies # Sudoers dependencies
alias.lo: $(srcdir)/alias.c $(SUDODEP) $(srcdir)/parse.h $(incdir)/list.h $(srcdir)/redblack.h alias.lo: $(srcdir)/alias.c $(SUDODEP) $(srcdir)/parse.h $(incdir)/list.h $(srcdir)/redblack.h
audit.lo: audit.c $(SUDODEP) audit.lo: $(srcdir)/audit.c $(SUDODEP)
bsm_audit.lo: bsm_audit.c $(SUDODEP) $(srcdir)/bsm_audit.h bsm_audit.lo: $(srcdir)/bsm_audit.c $(SUDODEP) $(srcdir)/bsm_audit.h
boottime.lo: $(srcdir)/boottime.c $(top_builddir)/config.h boottime.lo: $(srcdir)/boottime.c $(top_builddir)/config.h
check.lo: $(srcdir)/check.c $(SUDODEP) check.lo: $(srcdir)/check.c $(SUDODEP)
defaults.lo: $(srcdir)/defaults.c $(SUDODEP) $(devdir)/def_data.c $(authdir)/sudo_auth.h $(devdir)/gram.h defaults.lo: $(srcdir)/defaults.c $(SUDODEP) $(devdir)/def_data.c $(authdir)/sudo_auth.h $(devdir)/gram.h
@@ -200,6 +200,7 @@ gram.lo: $(devdir)/gram.c $(SUDODEP) $(srcdir)/parse.h $(incdir)/list.h $(devdir
interfaces.lo: $(srcdir)/interfaces.c $(SUDODEP) $(srcdir)/interfaces.h interfaces.lo: $(srcdir)/interfaces.c $(SUDODEP) $(srcdir)/interfaces.h
iolog.lo: $(srcdir)/iolog.c $(SUDODEP) iolog.lo: $(srcdir)/iolog.c $(SUDODEP)
ldap.lo: $(srcdir)/ldap.c $(SUDODEP) $(srcdir)/parse.h $(incdir)/list.h ldap.lo: $(srcdir)/ldap.c $(SUDODEP) $(srcdir)/parse.h $(incdir)/list.h
linux_audit.lo: $(srcdir)/linux_audit.c $(SUDODEP) $(srcdir)/linux_audit.h
logging.lo: $(srcdir)/logging.c $(SUDODEP) logging.lo: $(srcdir)/logging.c $(SUDODEP)
match.lo: $(srcdir)/match.c $(SUDODEP) $(srcdir)/parse.h $(incdir)/list.h $(srcdir)/interfaces.h $(devdir)/gram.h match.lo: $(srcdir)/match.c $(SUDODEP) $(srcdir)/parse.h $(incdir)/list.h $(srcdir)/interfaces.h $(devdir)/gram.h
parse.lo: $(srcdir)/parse.c $(SUDODEP) $(srcdir)/parse.h $(incdir)/list.h $(devdir)/gram.h parse.lo: $(srcdir)/parse.c $(SUDODEP) $(srcdir)/parse.h $(incdir)/list.h $(devdir)/gram.h

View File

@@ -34,13 +34,19 @@
#ifdef HAVE_BSM_AUDIT #ifdef HAVE_BSM_AUDIT
# include "bsm_audit.h" # include "bsm_audit.h"
#endif #endif
#ifdef HAVE_LINUX_AUDIT
# include "linux_audit.h"
#endif
void void
audit_success(char **exec_args) audit_success(char *exec_args[])
{ {
#ifdef HAVE_BSM_AUDIT #ifdef HAVE_BSM_AUDIT
bsm_audit_success(exec_args); bsm_audit_success(exec_args);
#endif #endif
#ifdef HAVE_LINUX_AUDIT
linux_audit_command(exec_args, 1);
#endif
} }
void void
@@ -51,6 +57,9 @@ audit_failure(char **exec_args, char const *const fmt, ...)
va_start(ap, fmt); va_start(ap, fmt);
#ifdef HAVE_BSM_AUDIT #ifdef HAVE_BSM_AUDIT
bsm_audit_failure(exec_args, fmt, ap); bsm_audit_failure(exec_args, fmt, ap);
#endif
#ifdef HAVE_LINUX_AUDIT
linux_audit_command(exec_args, 0);
#endif #endif
va_end(ap); va_end(ap);
} }

View File

@@ -30,6 +30,8 @@
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include "bsm_audit.h"
void log_error(int flags, const char *fmt, ...) __attribute__((__noreturn__)); void log_error(int flags, const char *fmt, ...) __attribute__((__noreturn__));
static int static int

View File

@@ -0,0 +1,93 @@
/*
* 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.
*/
#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 */
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <libaudit.h>
#include <compat.h>
#include <error.h>
#include <alloc.h>
#include <missing.h>
#include <linux_audit.h>
/*
* Open audit connection if possible.
* Returns audit fd on success and -1 on failure.
*/
static int
linux_audit_open(void)
{
static int au_fd = -1;
if (au_fd != -1)
return au_fd;
au_fd = audit_open();
if (au_fd == -1) {
/* Kernel may not have audit support. */
if (errno != EINVAL && errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT)
error(1, "unable to open audit system");
} else {
(void)fcntl(au_fd, F_SETFD, FD_CLOEXEC);
}
return au_fd;
}
int
linux_audit_command(char *argv[], int result)
{
int au_fd, rc;
char *command, *cp, **av;
size_t size, n;
if ((au_fd = linux_audit_open()) == -1)
return -1;
/* Convert argv to a flat string. */
for (size = 0, av = argv; *av != NULL; av++)
size += strlen(*av) + 1;
command = cp = emalloc(size);
for (av = argv; *av != NULL; av++) {
n = strlcpy(cp, *av, size - (cp - command));
if (n >= size - (cp - command))
errorx(1, "internal error, linux_audit_command() overflow");
cp += n;
*cp++ = ' ';
}
*--cp = '\0';
/* Log command, ignoring EPERM on error. */
rc = audit_log_user_command(au_fd, AUDIT_USER_CMD, command, NULL, result);
if (rc <= 0)
warning("unable to send audit message");
efree(command);
return rc;
}

View File

@@ -0,0 +1,22 @@
/*
* 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 _SUDO_LINUX_AUDIT_H
#define _SUDO_LINUX_AUDIT_H
int linux_audit_command(char *argv[], int result);
#endif /* _SUDO_LINUX_AUDIT_H */

View File

@@ -47,8 +47,8 @@
# define MAXSYSLOGLEN 960 # define MAXSYSLOGLEN 960
#endif #endif
void audit_success(char **); void audit_success(char *[]);
void audit_failure(char **, char const * const, ...); void audit_failure(char *[], char const * const, ...);
void log_allowed(int); void log_allowed(int);
void log_denial(int, int); void log_denial(int, int);
void log_error(int flags, const char *fmt, ...) __printflike(2, 3); void log_error(int flags, const char *fmt, ...) __printflike(2, 3);

View File

@@ -36,9 +36,6 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <signal.h> #include <signal.h>
#ifdef WITH_AUDIT
#include <libaudit.h>
#endif
#include <selinux/flask.h> /* for SECCLASS_CHR_FILE */ #include <selinux/flask.h> /* for SECCLASS_CHR_FILE */
#include <selinux/selinux.h> /* for is_selinux_enabled() */ #include <selinux/selinux.h> /* for is_selinux_enabled() */
@@ -46,8 +43,11 @@
#include <selinux/get_default_type.h> #include <selinux/get_default_type.h>
#include <selinux/get_context_list.h> #include <selinux/get_context_list.h>
#ifdef HAVE_LINUX_AUDIT
# include <libaudit.h>
#endif
#include "sudo.h" #include "sudo.h"
#include "pathnames.h"
static struct selinux_state { static struct selinux_state {
security_context_t old_context; security_context_t old_context;
@@ -59,6 +59,38 @@ static struct selinux_state {
int enforcing; int enforcing;
} se_state; } se_state;
#ifdef HAVE_LINUX_AUDIT
static int
audit_role_change(const security_context_t old_context,
const security_context_t new_context, const char *ttyn)
{
int au_fd, rc;
char *message;
au_fd = audit_open();
if (au_fd == -1) {
/* Kernel may not have audit support. */
if (errno != EINVAL && errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT
)
error(1, "unable to open audit system");
return -1;
}
/* audit role change using the same format as newrole(1) */
easprintf(&message, "newrole: old-context=%s new-context=%s",
old_context, new_context);
rc = audit_log_user_message(au_fd, AUDIT_USER_ROLE_CHANGE,
message, NULL, NULL, ttyn, 1);
if (rc <= 0)
warning("unable to send audit message");
efree(message);
close(au_fd);
return rc;
}
#endif
/* /*
* This function attempts to revert the relabeling done to the tty. * This function attempts to revert the relabeling done to the tty.
* fd - referencing the opened ttyn * fd - referencing the opened ttyn
@@ -314,6 +346,11 @@ selinux_setup(const char *role, const char *type, const char *ttyn,
} }
#endif #endif
#ifdef HAVE_LINUX_AUDIT
audit_role_change(se_state.old_context, se_state.new_context,
se_state.ttyn);
#endif
rval = 0; rval = 0;
done: done:
@@ -338,11 +375,6 @@ selinux_execve(const char *path, char *argv[], char *envp[])
return; return;
} }
#ifdef WITH_AUDIT
if (send_audit_message(1, se_state.old_context, se_state.new_context, se_state.ttyn))
return;
#endif
for (argc = 0; argv[argc] != NULL; argc++) for (argc = 0; argv[argc] != NULL; argc++)
continue; continue;