diff -urN /usr/src/packages/BUILD/Linux-PAM-0.76/Make.Rules.in Linux-PAM-0.76/Make.Rules.in --- /usr/src/packages/BUILD/Linux-PAM-0.76/Make.Rules.in 2003-07-08 12:38:11.000000000 -0500 +++ Linux-PAM-0.76/Make.Rules.in 2003-07-07 06:52:18.000000000 -0500 @@ -109,4 +109,5 @@ STRIP=@STRIP@ CC_STATIC=@CC_STATIC@ -LINKLIBS = $(NEED_LINK_LIB_C) $(LIBDL) +LIBLAUS=@LIBLAUS@ +LINKLIBS = $(NEED_LINK_LIB_C) $(LIBDL) $(LIBLAUS) diff -urN /usr/src/packages/BUILD/Linux-PAM-0.76/_pam_aconf.h.in Linux-PAM-0.76/_pam_aconf.h.in --- /usr/src/packages/BUILD/Linux-PAM-0.76/_pam_aconf.h.in 2001-11-25 21:04:46.000000000 -0600 +++ Linux-PAM-0.76/_pam_aconf.h.in 2003-07-07 06:00:35.000000000 -0500 @@ -96,4 +96,7 @@ # include #endif /* MEMORY_DEBUG */ +/* use LAuS (Linux Auditing System) library? */ +#undef HAVE_LIBLAUS + #endif /* PAM_ACONF_H */ diff -urN /usr/src/packages/BUILD/Linux-PAM-0.76/configure.in Linux-PAM-0.76/configure.in --- /usr/src/packages/BUILD/Linux-PAM-0.76/configure.in 2003-07-08 12:38:11.000000000 -0500 +++ Linux-PAM-0.76/configure.in 2003-07-07 06:50:38.000000000 -0500 @@ -275,6 +275,11 @@ fi AC_SUBST(CRACKLIB_DICTPATH) +dnl Look for LAuS (Linux Auditing System) library - see documentation +AC_CHECK_HEADER([laus.h]) +AC_CHECK_LIB(laus, laus_open, AC_DEFINE(HAVE_LIBLAUS) LIBLAUS=-llaus) +AC_SUBST(LIBLAUS) + dnl Set FLAGS, linker options etc. depending on C compiler. dnl gcc is tested and much preferred; others less so, if at all dnl diff -urN /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_account.c Linux-PAM-0.76/libpam/pam_account.c --- /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_account.c 2001-01-22 00:07:28.000000000 -0600 +++ Linux-PAM-0.76/libpam/pam_account.c 2003-07-22 00:20:05.000000000 -0500 @@ -19,5 +19,9 @@ retval = _pam_dispatch(pamh, flags, PAM_ACCOUNT); +#if HAVE_LIBLAUS + retval = _pam_auditlog(pamh, PAM_ACCOUNT, retval); +#endif + return retval; } diff -urN /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_auth.c Linux-PAM-0.76/libpam/pam_auth.c --- /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_auth.c 2001-01-22 00:07:28.000000000 -0600 +++ Linux-PAM-0.76/libpam/pam_auth.c 2003-07-22 00:34:54.000000000 -0500 @@ -40,6 +40,10 @@ D(("will resume when ready")); } +#if HAVE_LIBLAUS + retval = _pam_auditlog(pamh, PAM_AUTHENTICATE, retval); +#endif + return retval; } diff -urN /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_dispatch.c Linux-PAM-0.76/libpam/pam_dispatch.c --- /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_dispatch.c 2001-10-10 23:52:26.000000000 -0500 +++ Linux-PAM-0.76/libpam/pam_dispatch.c 2003-05-14 12:40:30.000000000 -0500 @@ -148,6 +148,22 @@ cached_retval = h->cached_retval = retval; } + if (cached_retval == PAM_SUCCESS + && retval > PAM_SUCCESS && retval < _PAM_RETURN_VALUES + ) { + /* the inscrutable logic above has decided to + * overwrite the current module's valid failure code with + * a cached success value, which is wrong if the current + * module is marked as requisite, since it won't fail. + */ + + if (h->actions[retval] == _PAM_ACTION_DIE) { + D(("not using cached value, preserving failure retval=%d", + retval)); + cached_retval = retval; + } + } + /* verify that the return value is a valid one */ if ((cached_retval < PAM_SUCCESS) || (cached_retval >= _PAM_RETURN_VALUES)) { diff -urN /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_end.c Linux-PAM-0.76/libpam/pam_end.c --- /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_end.c 2001-01-22 00:07:28.000000000 -0600 +++ Linux-PAM-0.76/libpam/pam_end.c 2003-09-24 20:01:12.000000000 -0500 @@ -21,6 +21,10 @@ return PAM_SYSTEM_ERR; } +#if HAVE_LIBLAUS + _pam_laus_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 -urN /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_log.c Linux-PAM-0.76/libpam/pam_log.c --- /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_log.c 2000-11-19 17:54:02.000000000 -0600 +++ Linux-PAM-0.76/libpam/pam_log.c 2003-09-24 20:46:54.000000000 -0500 @@ -373,3 +373,128 @@ D(("done.")); } +#if HAVE_LIBLAUS +/* instrumentation code for LAuS (Linux Auditing System) */ + +#include +#include +#include +#include +#include +#include + +#define PAMLAUS_LOGGED 1 + +/* resolve hostname - caller must pass a INET6_ADDRSTRLEN byte buffer + * Returns string w/ numerical address, or "?" on failure + */ +static void +_resolve_addr(char buf[], char *host) +{ + struct hostent *hent; + + buf[0] = '?'; + buf[1] = 0; + + if (!host) return; + + hent = gethostbyname(host); + if (!hent || !hent->h_addr) { + D(("pam_audit resolve_addr: cannot resolve hostname %s", host)); + return; + } + + inet_ntop(hent->h_addrtype, hent->h_addr, buf, INET6_ADDRSTRLEN); +} + +static void +_pam_audit_writelog(pam_handle_t *pamh, const char *message, int retval) +{ + char addrbuf[INET6_ADDRSTRLEN]; + char *tag; + + tag = (retval == PAM_SUCCESS) ? AUTH_success : AUTH_failure; + + _resolve_addr(addrbuf, pamh->rhost); + + laus_log(tag, "PAM %s: user=%s (hostname=%s, addr=%s, terminal=%s)", + message, + (retval != PAM_USER_UNKNOWN && pamh->user) ? pamh->user : "?", + pamh->rhost ? pamh->rhost : "?", + addrbuf, + pamh->tty ? pamh->tty : "?" + ); + + pamh->laus_state |= PAMLAUS_LOGGED; +} + +int +_pam_auditlog(pam_handle_t *pamh, int action, int retval) +{ + int err; + const char *message; + + err = laus_init(); + if (err<0) { + /* this should only fail in case of extreme resource shortage, + * need to prevent login in that case for CAPP compliance. + */ + _pam_system_log(LOG_CRIT, "laus_init() failed: %s", + laus_strerror(err)); + return PAM_SYSTEM_ERR; + } + + err = laus_open(NULL); + if (err<0) { + /* audit subsystem is disabled, continue without auditing + laus_close();*/ + return retval; + } + + switch (action) { + case PAM_AUTHENTICATE: + message = "authentication"; + break; + case PAM_OPEN_SESSION: + message = "session open"; + break; + case PAM_CLOSE_SESSION: + message = "session close"; + break; + case PAM_ACCOUNT: + message = "accounting"; + break; + case PAM_CHAUTHTOK: + message = "chauthtok"; + break; + case _PAM_ACTION_DONE: + message = "bad_ident"; + break; + default: + message = "UNKNOWN"; + _pam_system_log(LOG_CRIT, "_pam_auditlog() should never get here"); + retval = PAM_SYSTEM_ERR; + } + + _pam_audit_writelog(pamh, message, retval); + + laus_close(); + + return retval; +} + +int +_pam_laus_end(pam_handle_t *pamh, int status) +{ + if (! (pamh->laus_state & PAMLAUS_LOGGED)) { + /* PAM library is being shut down without any of the audited + * stacks having been run. Assume that this is sshd faking + * things for an unknown user. + */ + _pam_auditlog(pamh, _PAM_ACTION_DONE, PAM_USER_UNKNOWN); + } + + return 0; +} + +#endif /* HAVE_LIBLAUS */ diff -urN /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_password.c Linux-PAM-0.76/libpam/pam_password.c --- /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_password.c 2001-01-22 00:07:29.000000000 -0600 +++ Linux-PAM-0.76/libpam/pam_password.c 2003-09-24 20:45:07.000000000 -0500 @@ -52,6 +52,10 @@ D(("will resume when ready", retval)); } +#if HAVE_LIBLAUS + _pam_auditlog(pamh, PAM_CHAUTHTOK, retval); +#endif + return retval; } diff -urN /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_private.h Linux-PAM-0.76/libpam/pam_private.h --- /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_private.h 2003-07-08 12:38:11.000000000 -0500 +++ Linux-PAM-0.76/libpam/pam_private.h 2003-09-18 10:03:51.000000000 -0500 @@ -147,6 +147,9 @@ struct service handlers; struct _pam_former_state former; /* library state - support for event driven applications */ +#if HAVE_LIBLAUS + int laus_state; /* keep track of reported audit messages */ +#endif }; /* Values for select arg to _pam_dispatch() */ @@ -288,6 +291,11 @@ #define __PAM_TO_APP(pamh) \ do { (pamh)->caller_is = _PAM_CALLED_FROM_APP; } while (0) +#if HAVE_LIBLAUS +extern int _pam_auditlog(pam_handle_t *pamh, int action, int retval); +extern int _pam_laus_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 -urN /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_session.c Linux-PAM-0.76/libpam/pam_session.c --- /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_session.c 2001-01-22 00:07:29.000000000 -0600 +++ Linux-PAM-0.76/libpam/pam_session.c 2003-07-22 00:20:25.000000000 -0500 @@ -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); @@ -19,11 +21,19 @@ return PAM_SYSTEM_ERR; } - return _pam_dispatch(pamh, flags, PAM_OPEN_SESSION); + retval = _pam_dispatch(pamh, flags, PAM_OPEN_SESSION); + +#if HAVE_LIBLAUS + retval = _pam_auditlog(pamh, PAM_OPEN_SESSION, retval); +#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 +43,11 @@ return PAM_SYSTEM_ERR; } - return _pam_dispatch(pamh, flags, PAM_CLOSE_SESSION); + retval = _pam_dispatch(pamh, PAM_SUCCESS, PAM_CLOSE_SESSION); + +#if HAVE_LIBLAUS + retval = _pam_auditlog(pamh, PAM_CLOSE_SESSION, retval); +#endif + + return retval; } diff -urN /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_start.c Linux-PAM-0.76/libpam/pam_start.c --- /usr/src/packages/BUILD/Linux-PAM-0.76/libpam/pam_start.c 2003-07-08 12:38:11.000000000 -0500 +++ Linux-PAM-0.76/libpam/pam_start.c 2003-09-24 20:27:02.000000000 -0500 @@ -70,6 +70,9 @@ (*pamh)->oldauthtok = NULL; (*pamh)->fail_delay.delay_fn_ptr = NULL; (*pamh)->former.choice = PAM_NOT_STACKED; +#if HAVE_LIBLAUS + (*pamh)->laus_state = 0; +#endif if (pam_conversation == NULL || ((*pamh)->pam_conversation = (struct pam_conv *)