summaryrefslogtreecommitdiff
path: root/libpam
diff options
context:
space:
mode:
authorTomas Mraz <tm@t8m.info>2006-01-12 10:06:49 +0000
committerTomas Mraz <tm@t8m.info>2006-01-12 10:06:49 +0000
commit94483545da687d9dba81175575d07ba9f77a3eb5 (patch)
treef401c4f560af05cf6bf492eb8a36183b80b80d8d /libpam
parent52fa7eff1bc0d56ad8ba8df0764d2c93383e17ef (diff)
Relevant BUGIDs:
Purpose of commit: new feature Commit summary: --------------- 2006-01-12 Steve Grubb <sgrubb@redhat.com> * 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.
Diffstat (limited to 'libpam')
-rw-r--r--libpam/Makefile.am4
-rw-r--r--libpam/pam_account.c4
-rw-r--r--libpam/pam_audit.c128
-rw-r--r--libpam/pam_auth.c8
-rw-r--r--libpam/pam_end.c4
-rw-r--r--libpam/pam_password.c4
-rw-r--r--libpam/pam_private.h10
-rw-r--r--libpam/pam_session.c19
-rw-r--r--libpam/pam_start.c3
9 files changed, 180 insertions, 4 deletions
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 <sgrubb@redhat.com> */
+
+#include "pam_private.h"
+#include <stdio.h>
+#include <syslog.h>
+
+#if HAVE_LIBAUDIT
+#include <libaudit.h>
+#include <pwd.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <errno.h>
+
+#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 <morgan@kernel.org>
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) {