From 94483545da687d9dba81175575d07ba9f77a3eb5 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 12 Jan 2006 10:06:49 +0000 Subject: Relevant BUGIDs: Purpose of commit: new feature Commit summary: --------------- 2006-01-12 Steve Grubb * configure.in: Add check for audit library. * libpam/Makefile.am (libpam_la_LDFLAGS): Add LIBAUDIT. (libpam_la_SOURCES): Add pam_audit.c. * libpam/pam_account.c (pam_acct_mgmt): Add _pam_auditlog() call. * libpam/pam_auth.c (pam_authenticate), (pam_setcred): Likewise. * libpam/pam_password.c (pam_chauthtok): Likewise. * libpam/pam_session.c (pam_open_session), (pam_close_session): Likewise. * libpam/pam_private.h: Add audit_state member to pam_handle, declare _pam_auditlog and _pam_audit_end. * libpam/pam_start.c (pam_start): Initialize audit_state. * libpam/pam_audit.c: New file with _pam_auditlog and _pam_audit_end implementation. * libpam/pam_end.c (pam_end): Add _pam_audit_end() call. * NEWS: Note about added auditing. --- ChangeLog | 18 +++++++ NEWS | 1 + configure.in | 10 ++++ libpam/Makefile.am | 4 +- libpam/pam_account.c | 4 ++ libpam/pam_audit.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++ libpam/pam_auth.c | 8 ++++ libpam/pam_end.c | 4 ++ libpam/pam_password.c | 4 ++ libpam/pam_private.h | 10 ++++ libpam/pam_session.c | 19 +++++++- libpam/pam_start.c | 3 ++ 12 files changed, 209 insertions(+), 4 deletions(-) create mode 100644 libpam/pam_audit.c diff --git a/ChangeLog b/ChangeLog index c80ebc9a..05adc4fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2006-01-12 Steve Grubb + + * configure.in: Add check for audit library. + * libpam/Makefile.am (libpam_la_LDFLAGS): Add LIBAUDIT. + (libpam_la_SOURCES): Add pam_audit.c. + * libpam/pam_account.c (pam_acct_mgmt): Add _pam_auditlog() call. + * libpam/pam_auth.c (pam_authenticate), (pam_setcred): Likewise. + * libpam/pam_password.c (pam_chauthtok): Likewise. + * libpam/pam_session.c (pam_open_session), + (pam_close_session): Likewise. + * libpam/pam_private.h: Add audit_state member to pam_handle, + declare _pam_auditlog and _pam_audit_end. + * libpam/pam_start.c (pam_start): Initialize audit_state. + * libpam/pam_audit.c: New file with _pam_auditlog and _pam_audit_end + implementation. + * libpam/pam_end.c (pam_end): Add _pam_audit_end() call. + * NEWS: Note about added auditing. + 2006-01-11 Thorsten Kukuk * libpam/Makefile.am (AM_CFLAGS): Define LIBPAM_COMPILE. diff --git a/NEWS b/NEWS index ac65caba..12404325 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ Linux-PAM NEWS -- history of user-visible changes. * Fix NULL pointer checks in libpam.so * pam_succeed_if, pam_group, pam_time: Support netgroup matching. * New translations for: nb, hu +* Audit PAM calls if Linux Audit is available Release 0.99.2.1 diff --git a/configure.in b/configure.in index 02ca8880..de800a62 100644 --- a/configure.in +++ b/configure.in @@ -271,6 +271,16 @@ LIBS=$BACKUP_LIBS AC_SUBST(LIBCRACK) AM_CONDITIONAL([HAVE_LIBCRACK], [test ! -z "$LIBCRACK"]) +dnl Look for Linux Auditing library - see documentation +AC_CHECK_HEADER([libaudit.h]) +BACKUP_LIBS=$LIBS +AC_CHECK_LIB(audit, audit_log_user_message, LIBAUDIT=-laudit, LIBAUDIT="") +LIBS=$BACKUP_LIBS +AC_SUBST(LIBAUDIT) +if test ! -z "$LIBAUDIT" ; then + AC_DEFINE([HAVE_LIBAUDIT], 1, [Defined if audit support should be compiled in]) +fi + BACKUP_LIBS=$LIBS AC_SEARCH_LIBS([crypt],[xcrypt crypt], LIBCRYPT="-l$ac_lib", LIBCRYPT="") LIBS=$BACKUP_LIBS diff --git a/libpam/Makefile.am b/libpam/Makefile.am index 5a5b94eb..81329a3f 100644 --- a/libpam/Makefile.am +++ b/libpam/Makefile.am @@ -16,7 +16,7 @@ include_HEADERS = $(addprefix include/security/, _pam_compat.h _pam_macros.h _pa noinst_HEADERS = pam_dynamic.h pam_prelude.h pam_private.h pam_tokens.h \ pam_modutil_private.h -libpam_la_LDFLAGS = -no-undefined -version-info 81:2:81 +libpam_la_LDFLAGS = -no-undefined -version-info 81:2:81 @LIBAUDIT@ if HAVE_VERSIONING libpam_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libpam.map endif @@ -27,7 +27,7 @@ libpam_la_SOURCES = pam_account.c pam_auth.c pam_data.c pam_delay.c \ pam_dispatch.c pam_end.c pam_env.c pam_handlers.c pam_item.c \ pam_malloc.c pam_misc.c pam_password.c pam_prelude.c \ pam_session.c pam_start.c pam_static.c pam_strerror.c \ - pam_vprompt.c pam_syslog.c pam_dynamic.c \ + pam_vprompt.c pam_syslog.c pam_dynamic.c pam_audit.c \ pam_modutil_cleanup.c pam_modutil_getpwnam.c pam_modutil_ioloop.c \ pam_modutil_getgrgid.c pam_modutil_getpwuid.c pam_modutil_getgrnam.c \ pam_modutil_getspnam.c pam_modutil_getlogin.c pam_modutil_ingroup.c diff --git a/libpam/pam_account.c b/libpam/pam_account.c index 3a4fb1fc..3e579f11 100644 --- a/libpam/pam_account.c +++ b/libpam/pam_account.c @@ -19,5 +19,9 @@ int pam_acct_mgmt(pam_handle_t *pamh, int flags) retval = _pam_dispatch(pamh, flags, PAM_ACCOUNT); +#if HAVE_LIBAUDIT + retval = _pam_auditlog(pamh, PAM_ACCOUNT, retval, flags); +#endif + return retval; } diff --git a/libpam/pam_audit.c b/libpam/pam_audit.c new file mode 100644 index 00000000..7c067d9b --- /dev/null +++ b/libpam/pam_audit.c @@ -0,0 +1,128 @@ +/* pam_audit.c -- Instrumentation code for Linux Auditing System */ + +/* (C) 2005-2006 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying the Linux-PAM source distribution. + + Authors: + Steve Grubb */ + +#include "pam_private.h" +#include +#include + +#if HAVE_LIBAUDIT +#include +#include +#include +#include +#include +#include +#include + +#define PAMAUDIT_LOGGED 1 + +static int +_pam_audit_writelog(pam_handle_t *pamh, int audit_fd, int type, + const char *message, int retval) +{ + int rc; + char buf[256]; + + snprintf(buf, sizeof(buf), "PAM: %s acct=%s ", message, + (retval != PAM_USER_UNKNOWN && pamh->user) ? pamh->user : "?"); + + rc = audit_log_user_message( audit_fd, type, buf, + pamh->rhost, NULL, pamh->tty, retval == PAM_SUCCESS ); + + pamh->audit_state |= PAMAUDIT_LOGGED; + return rc; +} + +int +_pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags) +{ + const char *message; + int type; + int audit_fd; + + audit_fd = audit_open(); + if (audit_fd < 0) { + /* You get these error codes only when the kernel doesn't have + * audit compiled in. */ + if (errno == EINVAL || errno == EPROTONOSUPPORT || + errno == EAFNOSUPPORT) + return retval; + + /* this should only fail in case of extreme resource shortage, + * need to prevent login in that case for CAPP compliance. + */ + pam_syslog(pamh, LOG_CRIT, "audit_open() failed: %s", + strerror(errno)); + return PAM_SYSTEM_ERR; + } + + switch (action) { + case PAM_AUTHENTICATE: + message = "authentication"; + type = AUDIT_USER_AUTH; + break; + case PAM_OPEN_SESSION: + message = "session open"; + type = AUDIT_USER_START; + break; + case PAM_CLOSE_SESSION: + message = "session close"; + type = AUDIT_USER_END; + break; + case PAM_ACCOUNT: + message = "accounting"; + type = AUDIT_USER_ACCT; + break; + case PAM_CHAUTHTOK: + message = "chauthtok"; + type = AUDIT_USER_CHAUTHTOK; + break; + case PAM_SETCRED: + message = "setcred"; + if (flags & PAM_ESTABLISH_CRED) + type = AUDIT_CRED_ACQ; + else if ((flags & PAM_REINITIALIZE_CRED) || (flags & PAM_REFRESH_CRED)) + type = AUDIT_CRED_REFR; + else if (flags & PAM_DELETE_CRED) + type = AUDIT_CRED_DISP; + else + type = AUDIT_USER_ERR; + break; + case _PAM_ACTION_DONE: + message = "bad_ident"; + type = AUDIT_USER_ERR; + break; + default: + message = "UNKNOWN"; + type = AUDIT_USER_ERR; + pam_syslog(pamh, LOG_CRIT, "_pam_auditlog() should never get here"); + retval = PAM_SYSTEM_ERR; + } + + if (_pam_audit_writelog(pamh, audit_fd, type, message, retval) < 0) + retval = PAM_SYSTEM_ERR; + + audit_close(audit_fd); + return retval; +} + +int +_pam_audit_end(pam_handle_t *pamh, int status UNUSED) +{ + if (! (pamh->audit_state & PAMAUDIT_LOGGED)) { + /* PAM library is being shut down without any of the auditted + * stacks having been run. Assume that this is sshd faking + * things for an unknown user. + */ + _pam_auditlog(pamh, _PAM_ACTION_DONE, PAM_USER_UNKNOWN, 0); + } + + return 0; +} + +#endif /* HAVE_LIBAUDIT */ diff --git a/libpam/pam_auth.c b/libpam/pam_auth.c index 1e7bc6e7..772e5edf 100644 --- a/libpam/pam_auth.c +++ b/libpam/pam_auth.c @@ -45,6 +45,10 @@ int pam_authenticate(pam_handle_t *pamh, int flags) prelude_send_alert(pamh, retval); #endif +#if HAVE_LIBAUDIT + retval = _pam_auditlog(pamh, PAM_AUTHENTICATE, retval, flags); +#endif + return retval; } @@ -67,6 +71,10 @@ int pam_setcred(pam_handle_t *pamh, int flags) retval = _pam_dispatch(pamh, flags, PAM_SETCRED); +#if HAVE_LIBAUDIT + retval = _pam_auditlog(pamh, PAM_SETCRED, retval, flags); +#endif + D(("pam_setcred exit")); return retval; diff --git a/libpam/pam_end.c b/libpam/pam_end.c index 2226eaae..e46dd0c4 100644 --- a/libpam/pam_end.c +++ b/libpam/pam_end.c @@ -21,6 +21,10 @@ int pam_end(pam_handle_t *pamh, int pam_status) return PAM_SYSTEM_ERR; } +#ifdef HAVE_LIBAUDIT + _pam_audit_end(pamh, pam_status); +#endif + /* first liberate the modules (it is not inconcevible that the modules may need to use the service_name etc. to clean up) */ diff --git a/libpam/pam_password.c b/libpam/pam_password.c index bfe41029..6d566061 100644 --- a/libpam/pam_password.c +++ b/libpam/pam_password.c @@ -52,6 +52,10 @@ int pam_chauthtok(pam_handle_t *pamh, int flags) D(("will resume when ready", retval)); } +#if HAVE_LIBAUDIT + retval = _pam_auditlog(pamh, PAM_CHAUTHTOK, retval, flags); +#endif + return retval; } diff --git a/libpam/pam_private.h b/libpam/pam_private.h index 2929a2f6..ce255452 100644 --- a/libpam/pam_private.h +++ b/libpam/pam_private.h @@ -150,6 +150,10 @@ struct pam_handle { event driven applications */ const char *mod_name; /* Name of the module currently executed */ int choice; /* Which function we call from the module */ + +#if HAVE_LIBAUDIT + int audit_state; /* keep track of reported audit messages */ +#endif }; /* Values for select arg to _pam_dispatch() */ @@ -286,6 +290,12 @@ if ((pamh) == NULL) { \ #define __PAM_TO_APP(pamh) \ do { (pamh)->caller_is = _PAM_CALLED_FROM_APP; } while (0) + +#if HAVE_LIBAUDIT +extern int _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags); +extern int _pam_audit_end(pam_handle_t *pamh, int pam_status); +#endif + /* * Copyright (C) 1995 by Red Hat Software, Marc Ewing * Copyright (c) 1996-8,2001 by Andrew G. Morgan diff --git a/libpam/pam_session.c b/libpam/pam_session.c index 98125ba6..a0f2d8d7 100644 --- a/libpam/pam_session.c +++ b/libpam/pam_session.c @@ -10,6 +10,8 @@ int pam_open_session(pam_handle_t *pamh, int flags) { + int retval; + D(("called")); IF_NO_PAMH("pam_open_session", pamh, PAM_SYSTEM_ERR); @@ -18,12 +20,18 @@ int pam_open_session(pam_handle_t *pamh, int flags) D(("called from module!?")); return PAM_SYSTEM_ERR; } + retval = _pam_dispatch(pamh, flags, PAM_OPEN_SESSION); - return _pam_dispatch(pamh, flags, PAM_OPEN_SESSION); +#if HAVE_LIBAUDIT + retval = _pam_auditlog(pamh, PAM_OPEN_SESSION, retval, flags); +#endif + return retval; } int pam_close_session(pam_handle_t *pamh, int flags) { + int retval; + D(("called")); IF_NO_PAMH("pam_close_session", pamh, PAM_SYSTEM_ERR); @@ -33,5 +41,12 @@ int pam_close_session(pam_handle_t *pamh, int flags) return PAM_SYSTEM_ERR; } - return _pam_dispatch(pamh, flags, PAM_CLOSE_SESSION); + retval = _pam_dispatch(pamh, flags, PAM_CLOSE_SESSION); + +#if HAVE_LIBAUDIT + retval = _pam_auditlog(pamh, PAM_CLOSE_SESSION, retval, flags); +#endif + + return retval; + } diff --git a/libpam/pam_start.c b/libpam/pam_start.c index 63f58f5b..e1d30034 100644 --- a/libpam/pam_start.c +++ b/libpam/pam_start.c @@ -88,6 +88,9 @@ int pam_start ( (*pamh)->oldauthtok = NULL; (*pamh)->fail_delay.delay_fn_ptr = NULL; (*pamh)->former.choice = PAM_NOT_STACKED; +#if HAVE_LIBAUDIT + (*pamh)->audit_state = 0; +#endif if (((*pamh)->pam_conversation = (struct pam_conv *) malloc(sizeof(struct pam_conv))) == NULL) { -- cgit v1.2.3