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