7010804 Xorg should audit connections and disconnections. nv_169
authorAlan Coopersmith <Alan.Coopersmith@Oracle.COM>
Thu, 16 Jun 2011 22:03:49 -0700
changeset 1149 e852f51b09cd
parent 1148 bf06d87c78ae
child 1150 6ca683bb9e8d
7010804 Xorg should audit connections and disconnections.
open-src/xserver/xorg/osaudit.patch
open-src/xserver/xorg/patch-list
open-src/xserver/xorg/sun-src/os/osaudit.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/xserver/xorg/osaudit.patch	Thu Jun 16 22:03:49 2011 -0700
@@ -0,0 +1,95 @@
+#
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+
+7010804 Xorg should audit connections and disconnections.
+
+diff --git a/configure.ac b/configure.ac
+index 756733e..1f1ba8e 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -312,6 +312,12 @@ AC_CHECK_HEADER([execinfo.h],[
+     ])]
+ )
+ 
++# Solaris auditing
++AC_CHECK_LIB([bsm], [adt_start_session], [HAVE_LIBBSM=yes ; SYS_LIBS=-lbsm ;
++    AC_DEFINE([HAVE_LIBBSM], [],
++        [Define to 1 if you have the Solaris auditing library (-lbsm)])])
++AM_CONDITIONAL([HAVE_LIBBSM], [test "x$HAVE_LIBBSM" = xyes])
++
+ dnl ARM needs additional compiler flags for proper backtraces if GCC is
+ dnl used. Compile a dummy program with the -mapcs-frame option. If it
+ dnl succeeds, we know that we are building for ARM with GCC.
+diff --git a/dix/main.c b/dix/main.c
+index 692bec1..dcc38b3 100644
+--- a/dix/main.c
++++ b/dix/main.c
+@@ -202,6 +202,7 @@ int main(int argc, char *argv[], char *envp[])
+ 	dixResetRegistry();
+ 	ResetFontPrivateIndex();
+ 	InitCallbackManager();
++	OSAuditInit(); /* Must be after InitCallbackManager() */
+ 	InitOutput(&screenInfo, argc, argv);
+ 
+ 	if (screenInfo.numScreens < 1)
+diff --git a/include/dix-config.h.in b/include/dix-config.h.in
+index d81264d..25bedef 100644
+--- a/include/dix-config.h.in
++++ b/include/dix-config.h.in
+@@ -133,6 +133,9 @@
+ /* Build a standalone xpbproxy */
+ #undef STANDALONE_XPBPROXY
+ 
++/* Define to 1 if you have the Solaris BSM auditing library (-lbsm) */
++#undef HAVE_LIBBSM
++
+ /* Define to 1 if you have the `m' library (-lm). */
+ #undef HAVE_LIBM
+ 
+diff --git a/os/Makefile.am b/os/Makefile.am
+index 3e4f2c5..40c732f 100644
+--- a/os/Makefile.am
++++ b/os/Makefile.am
+@@ -23,6 +23,7 @@ libos_la_SOURCES = 	\
+ 	connection.c	\
+ 	io.c		\
+ 	mitauth.c	\
++	osaudit.c	\
+ 	oscolor.c	\
+ 	osdep.h		\
+ 	osinit.c	\
+diff --git a/os/osdep.h b/os/osdep.h
+index 087e36d..9095aab 100644
+--- a/os/osdep.h
++++ b/os/osdep.h
+@@ -285,4 +285,7 @@ extern void XdmcpRegisterBroadcastAddress (const struct sockaddr_in *addr);
+ extern void XdmAuthenticationInit (const char *cookie, int cookie_length);
+ #endif
+ 
++/* in osaudit.c */
++extern void OSAuditInit (void);
++
+ #endif /* _OSDEP_H_ */
+-- 
+1.7.3.2
+
--- a/open-src/xserver/xorg/patch-list	Thu Jun 16 21:43:44 2011 -0700
+++ b/open-src/xserver/xorg/patch-list	Thu Jun 16 22:03:49 2011 -0700
@@ -1,5 +1,6 @@
 randr-check-rotate.patch,-p1
 7050250.patch,-p1
+osaudit.patch,-p1
 oslog-race.patch,-p1
 sun-paths.patch,-p1
 sun-extramodes.patch,-p1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/xserver/xorg/sun-src/os/osaudit.c	Thu Jun 16 22:03:49 2011 -0700
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#define XSERV_t
+#define TRANS_SERVER
+#include <X11/Xtrans/Xtrans.h>
+#include <X11/Xtrans/Xtransint.h>
+
+#include "misc.h"
+#include "osdep.h"
+#include "dixstruct.h"
+
+static DevPrivateKeyRec OSAuditPrivKeyRec;
+#define OSAuditPrivKey (&OSAuditPrivKeyRec)
+
+#define GetOSAuditClient(pClient)    \
+  ((OSAuditClientPrivatePtr) dixLookupPrivate(&(pClient)->devPrivates, OSAuditPrivKey))
+
+#ifdef HAVE_LIBBSM	/* Solaris auditing implementation */
+#include <ucred.h>
+#include <bsm/adt.h>
+#include <bsm/adt_event.h>
+
+#ifdef ADT_xconnect
+# define OS_AUDIT_IMPLEMENTED
+
+typedef struct {
+    adt_session_data_t	*ah;		/* audit handle */
+    ClientState		 prevState;
+} OSAuditClientPrivateRec, *OSAuditClientPrivatePtr;
+
+static void
+OSAuditClientInit (ClientPtr pClient)
+{
+    adt_session_data_t	*ah;		/* audit handle */
+    ucred_t		*uc = NULL;	/* peer's ucred */
+    XtransConnInfo	 ci;		/* peer's connection info */
+    int			 peer;		/* peer's file descriptor */
+    int			 saveid;
+
+    OSAuditClientPrivatePtr	 priv = GetOSAuditClient(pClient);
+
+    saveid = geteuid();
+    if (saveid != 0) {
+	/* reset privs back to root */
+        if (seteuid(0) < 0) {
+	    Error("OSAuditClientInit: seteuid(0)");
+	    saveid = 0;
+	}
+    }
+    
+    if (adt_start_session(&ah, NULL, 0) != 0) {
+	Error("OSAuditClientInit: adt_start_session");
+	goto end;
+    }
+
+    if (pClient->osPrivate == NULL) {
+	Error("OSAuditClientInit: NULL osPrivate");
+	goto end;
+    }
+    ci = ((OsCommPtr)pClient->osPrivate)->trans_conn;
+    peer = _XSERVTransGetConnectionNumber(ci);
+    if (getpeerucred(peer, &uc) == 0) {
+	if (adt_set_from_ucred(ah, uc, ADT_NEW) != 0) {
+	    Error("OSAuditClientInit: adt_set_from_ucred");
+	}
+	ucred_free(uc);
+    } else {
+	if (adt_set_user(ah, ADT_NO_ATTRIB, ADT_NO_ATTRIB, ADT_NO_ATTRIB,
+			 ADT_NO_ATTRIB, NULL, ADT_NEW) != 0) {
+	    Error("OSAuditClientInit: adt_set_user");
+	}
+    }
+
+    priv->ah = ah;
+
+  end:
+    if (saveid != 0) {
+	/* set privs back to user */
+        if (seteuid(saveid) < 0) {
+	    Error("OSAuditClientInit: seteuid(saveid)");
+	}
+    }
+
+}
+
+static void
+OSAudit (ClientPtr pClient, int event_id, int status, int reason)
+{
+    adt_event_data_t	*event;		/* event handle */
+    XtransConnInfo	 ci;		/* peer's connection info */
+    int			 peer;		/* peer's file descriptor */
+    int			 saveid;
+
+    OSAuditClientPrivatePtr	 priv = GetOSAuditClient(pClient);
+
+    if (priv->ah == NULL) {
+	Error("OSAudit: NULL adt_session_data");
+	return;
+    }
+
+    if ((event = adt_alloc_event(priv->ah, event_id)) == NULL) {
+	Error("OSAudit: adt_set_from_ucred");
+	return;
+    }
+
+    /* fill in event */
+    switch (event_id) {
+    case ADT_xconnect:
+	if (pClient->osPrivate != NULL) {
+	    ci = ((OsCommPtr)pClient->osPrivate)->trans_conn;
+	    peer = _XSERVTransGetConnectionNumber(ci);
+	} else {
+	    peer = -1;
+	}
+	event->adt_xconnect.client = pClient->index;
+	event->adt_xconnect.peer = peer;
+	break;
+    case ADT_xdisconnect:
+	event->adt_xdisconnect.client = pClient->index;
+	break;
+    default:
+	Error("OSAudit: unknown event_id");
+    }
+
+    saveid = geteuid();
+    if (saveid != 0) {
+	/* reset privs back to root */
+        if (seteuid(0) < 0) {
+	    Error("OSAuditClientInit: seteuid(0)");
+	    saveid = 0;
+	}
+    }
+    
+    if (adt_put_event(event, status, reason) != 0) {
+	Error("OSAudit: adt_put_event");
+    }
+
+    if (saveid != 0) {
+	/* set privs back to user */
+        if (seteuid(saveid) < 0) {
+	    Error("OSAuditClientInit: seteuid(saveid)");
+	}
+    }    
+    
+    adt_free_event(event);
+}
+
+/* Called when new client connects or existing client disconnects */
+static void
+OSAuditClientStateChange(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
+{
+    NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
+    ClientPtr pClient = pci->client;
+    OSAuditClientPrivatePtr	 priv = GetOSAuditClient(pClient);
+
+    switch (pClient->clientState) {
+
+    case ClientStateInitial:  /* client attempting to connect */
+	OSAuditClientInit(pClient);
+	break;
+
+    case ClientStateRunning:  /* connection accepted */
+	OSAudit (pClient, ADT_xconnect, ADT_SUCCESS, ADT_SUCCESS);
+	break;
+
+    case ClientStateGone:     /* connection terminating */
+	if (priv->prevState == ClientStateInitial) /* was never accepted */
+	    OSAudit (pClient, ADT_xconnect, ADT_FAILURE, EACCES);
+	else	/* successful connection that ran for a while */
+	    OSAudit (pClient, ADT_xdisconnect, ADT_SUCCESS, ADT_SUCCESS);
+	adt_end_session(priv->ah);
+	priv->ah = NULL;
+	break;
+
+    default:
+	return; /* skip over setting prevState to an unknown state */
+    }
+
+    priv->prevState = pClient->clientState;
+}
+#endif /* ADT_xconnect */
+#endif /* HAVE_LIBBSM -- Solaris auditing implementation */
+
+/* Generic code to initialize all OS auditing implementations */
+void
+OSAuditInit(void)
+{
+#ifdef OS_AUDIT_IMPLEMENTED
+    /* Reserve room in the client privates for the audit data */
+    if (!dixRegisterPrivateKey(&OSAuditPrivKeyRec, PRIVATE_CLIENT,
+			       sizeof(OSAuditClientPrivateRec)))
+	FatalError("could not allocate OSAuditPrivKey\n");
+
+    /* Register callback to be called on every client connect & disconnect */
+    if (!AddCallback(&ClientStateCallback, OSAuditClientStateChange, NULL))
+	FatalError("could not register OSAuditClientStateChange callback\n");
+#else
+/* nothing implemented for this OS */
+    return;
+#endif
+}