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],