1272N/Adiff --git a/common/rfb/Makefile.am b/common/rfb/Makefile.am
1272N/Aindex ad4956e..5ec455a 100644
1272N/A--- a/common/rfb/Makefile.am
1272N/A+++ b/common/rfb/Makefile.am
1272N/A@@ -56,6 +56,7 @@ endif
1272N/A
1272N/A librfb_la_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/win
1272N/A librfb_la_LIBADD = @GNUTLS_LIBS@ $(LIBS)
1272N/A+librfb_la_LIBADD += $(BSM_LIB)
1272N/A
1272N/A if HAVE_PAM
1272N/A librfb_la_SOURCES += UnixPasswordValidator.cxx UnixPasswordValidator.h pam.c pam.h
1272N/Adiff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
1272N/Aindex e1c8cf8..d3601f7 100644
1272N/A--- a/common/rfb/VNCSConnectionST.cxx
1272N/A+++ b/common/rfb/VNCSConnectionST.cxx
1272N/A@@ -28,6 +28,10 @@
1272N/A #define XK_XKB_KEYS
1272N/A #include <rfb/keysymdef.h>
1272N/A
1272N/A+#ifdef HAVE_LIBBSM
1272N/A+#include <ucred.h>
1272N/A+#endif
1272N/A+
1272N/A using namespace rfb;
1272N/A
1272N/A static LogWriter vlog("VNCSConnST");
1272N/A@@ -49,6 +53,26 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
1272N/A lastEventTime = time(0);
1272N/A
1272N/A server->clients.push_front(this);
1272N/A+
1272N/A+#ifdef HAVE_LIBBSM
1272N/A+ if (adt_start_session(&audit_handle, NULL, 0) != 0) {
1272N/A+ vlog.error("adt_start_session failed: %s", strerror(errno));
1272N/A+ } else {
1272N/A+ ucred_t *uc = NULL;
1272N/A+
1272N/A+ if (getpeerucred(sock->getFd(), &uc) == 0) {
1272N/A+ if (adt_set_from_ucred(audit_handle, uc, ADT_NEW) != 0) {
1272N/A+ vlog.error("adt_set_from_ucred failed: %s", strerror(errno));
1272N/A+ }
1272N/A+ ucred_free(uc);
1272N/A+ } else {
1272N/A+ if (adt_set_user(audit_handle, ADT_NO_ATTRIB, ADT_NO_ATTRIB,
1272N/A+ ADT_NO_ATTRIB, ADT_NO_ATTRIB, NULL, ADT_NEW) != 0) {
1272N/A+ vlog.error("adt_set_user failed: %s", strerror(errno));
1272N/A+ }
1272N/A+ }
1272N/A+ }
1272N/A+#endif
1272N/A }
1272N/A
1272N/A
1272N/A@@ -69,6 +93,9 @@ VNCSConnectionST::~VNCSConnectionST()
1272N/A // Remove this client from the server
1272N/A server->clients.remove(this);
1272N/A
1272N/A+#ifdef HAVE_LIBBSM
1272N/A+ adt_end_session(audit_handle);
1272N/A+#endif
1272N/A }
1272N/A
1272N/A
1272N/A@@ -95,6 +122,32 @@ void VNCSConnectionST::close(const char* reason)
1272N/A
1272N/A if (authenticated()) {
1272N/A server->lastDisconnectTime = time(0);
1272N/A+
1272N/A+#ifdef HAVE_LIBBSM
1272N/A+ adt_event_data_t *event;
1272N/A+
1272N/A+ if ((event = adt_alloc_event(audit_handle, ADT_vnc_disconnect)) == NULL) {
1272N/A+ vlog.error("adt_alloc_event failed: %s", strerror(errno));
1272N/A+ } else {
1272N/A+ event->adt_vnc_disconnect.peer = sock->getFd();
1272N/A+ if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
1272N/A+ vlog.error("adt_put_event failed: %s", strerror(errno));
1272N/A+ }
1272N/A+ adt_free_event(event);
1272N/A+ }
1272N/A+ } else { // authentication failed
1272N/A+ adt_event_data_t *event;
1272N/A+
1272N/A+ if ((event = adt_alloc_event(audit_handle, ADT_vnc_connect)) == NULL) {
1272N/A+ vlog.error("adt_alloc_event failed: %s", strerror(errno));
1272N/A+ } else {
1272N/A+ event->adt_vnc_connect.peer = sock->getFd();
1272N/A+ if (adt_put_event(event, ADT_FAILURE, EACCES) != 0) {
1272N/A+ vlog.error("adt_put_event failed: %s", strerror(errno));
1272N/A+ }
1272N/A+ adt_free_event(event);
1272N/A+ }
1272N/A+#endif
1272N/A }
1272N/A
1272N/A // Just shutdown the socket and mark our state as closing. Eventually the
1272N/A@@ -343,6 +396,20 @@ void VNCSConnectionST::approveConnectionOrClose(bool accept,
1272N/A
1272N/A void VNCSConnectionST::authSuccess()
1272N/A {
1272N/A+#ifdef HAVE_LIBBSM
1272N/A+ adt_event_data_t *event;
1272N/A+
1272N/A+ if ((event = adt_alloc_event(audit_handle, ADT_vnc_connect)) == NULL) {
1272N/A+ vlog.error("adt_alloc_event failed: %s", strerror(errno));
1272N/A+ } else {
1272N/A+ event->adt_vnc_connect.peer = sock->getFd();
1272N/A+ if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
1272N/A+ vlog.error("adt_put_event failed: %s", strerror(errno));
1272N/A+ }
1272N/A+ adt_free_event(event);
1272N/A+ }
1272N/A+#endif
1272N/A+
1272N/A lastEventTime = time(0);
1272N/A
1272N/A server->startDesktop();
1272N/Adiff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h
1272N/Aindex c9e4ac8..ecdd0dc 100644
1272N/A--- a/common/rfb/VNCSConnectionST.h
1272N/A+++ b/common/rfb/VNCSConnectionST.h
1272N/A@@ -33,6 +33,15 @@
1272N/A #include <rfb/TransImageGetter.h>
1272N/A #include <rfb/VNCServerST.h>
1272N/A
1272N/A+#ifdef HAVE_CONFIG_H
1272N/A+#include <config.h>
1272N/A+#endif
1272N/A+
1272N/A+#ifdef HAVE_LIBBSM
1272N/A+#include <bsm/adt.h>
1272N/A+#include <bsm/adt_event.h>
1272N/A+#endif
1272N/A+
1272N/A namespace rfb {
1272N/A class VNCSConnectionST : public SConnection,
1272N/A public WriteSetCursorCallback {
1272N/A@@ -171,6 +180,11 @@ namespace rfb {
1272N/A
1272N/A CharArray closeReason;
1272N/A time_t startTime;
1272N/A+
1272N/A+#ifdef HAVE_LIBBSM
1272N/A+ adt_session_data_t *audit_handle;
1272N/A+#endif
1272N/A+
1272N/A };
1272N/A }
1272N/A #endif
1272N/Adiff --git a/configure.ac b/configure.ac
1272N/Aindex ca3e025..5879f42 100644
1272N/A--- a/configure.ac
1272N/A+++ b/configure.ac
1272N/A@@ -134,6 +134,12 @@ fi
1272N/A AC_SUBST([PAM_LIBS])
1272N/A AM_CONDITIONAL([HAVE_PAM], [ ! test "x$PAM_LIBS" = x ])
1272N/A
1272N/A+# Solaris auditing
1272N/A+AC_CHECK_LIB([bsm], [adt_start_session], [HAVE_LIBBSM=yes ; BSM_LIB=-lbsm ;
1272N/A+ AC_DEFINE([HAVE_LIBBSM], [],
1272N/A+ [Define to 1 if you have the Solaris auditing library (-lbsm)])])
1272N/A+AC_SUBST([BSM_LIB])
1272N/A+
1272N/A VNCCONFIG_DIR='vncconfig'
1272N/A AC_ARG_ENABLE([vncconfig],
1272N/A AS_HELP_STRING([--enable-vncconfig],