xserver: Branch 'XACE-SELINUX' - 2 commits

Eamon Walsh ewalsh at kemper.freedesktop.org
Wed Oct 17 11:13:26 PDT 2007


 Xext/Makefile.am                    |    3 
 Xext/XSELinuxConfig                 |  133 --
 Xext/xselinux.c                     | 1675 ++++++++++--------------------------
 Xext/xselinux.h                     |  105 --
 configure.ac                        |    2 
 hw/xfree86/dixmods/extmod/modinit.h |    1 
 mi/miinitext.c                      |    6 
 7 files changed, 527 insertions(+), 1398 deletions(-)

New commits:
commit af4dde0ac19ecec1d0ad988eb25b15401e7c6b36
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Wed Oct 17 14:13:02 2007 -0400

    xselinux: Remove config file, this has been moved to the policy.

diff --git a/Xext/Makefile.am b/Xext/Makefile.am
index 2423c83..6fe1c34 100644
--- a/Xext/Makefile.am
+++ b/Xext/Makefile.am
@@ -80,9 +80,6 @@ endif
 XSELINUX_SRCS = xselinux.c xselinux.h
 if XSELINUX
 BUILTIN_SRCS += $(XSELINUX_SRCS)
-
-SERVERCONFIG_DATA += XSELinuxConfig
-AM_CFLAGS += -DXSELINUXCONFIGFILE=\"$(SERVERCONFIGdir)/XSELinuxConfig\"
 endif
 
 # Security extension: multi-level security to protect clients from each other
diff --git a/Xext/XSELinuxConfig b/Xext/XSELinuxConfig
deleted file mode 100644
index 66f93c5..0000000
--- a/Xext/XSELinuxConfig
+++ /dev/null
@@ -1,133 +0,0 @@
-#
-# Config file for XSELinux extension
-#
-
-#
-# The default client rule defines a context to be used for all clients
-# connecting to the server from a remote host.
-#
-client	*				system_u:object_r:remote_xclient_t:s0
-
-#
-# Property rules map a property name to a context.  A default property
-# rule indicated by an asterisk should follow all other property rules.
-#
-# Properties set by typical clients: WM, _NET_WM, etc.
-property WM_NAME			system_u:object_r:client_xproperty_t:s0
-property WM_CLASS			system_u:object_r:client_xproperty_t:s0
-property WM_ICON_NAME			system_u:object_r:client_xproperty_t:s0
-property WM_HINTS			system_u:object_r:client_xproperty_t:s0
-property WM_NORMAL_HINTS		system_u:object_r:client_xproperty_t:s0
-property WM_COMMAND			system_u:object_r:client_xproperty_t:s0
-property WM_CLIENT_MACHINE		system_u:object_r:client_xproperty_t:s0
-property WM_LOCALE_NAME			system_u:object_r:client_xproperty_t:s0
-property WM_CLIENT_LEADER		system_u:object_r:client_xproperty_t:s0
-property WM_STATE			system_u:object_r:client_xproperty_t:s0
-property WM_PROTOCOLS			system_u:object_r:client_xproperty_t:s0
-property WM_WINDOW_ROLE			system_u:object_r:client_xproperty_t:s0
-property WM_TRANSIENT_FOR		system_u:object_r:client_xproperty_t:s0
-property _NET_WM_NAME			system_u:object_r:client_xproperty_t:s0
-property _NET_WM_ICON			system_u:object_r:client_xproperty_t:s0
-property _NET_WM_ICON_NAME		system_u:object_r:client_xproperty_t:s0
-property _NET_WM_PID			system_u:object_r:client_xproperty_t:s0
-property _NET_WM_STATE			system_u:object_r:client_xproperty_t:s0
-property _NET_WM_DESKTOP		system_u:object_r:client_xproperty_t:s0
-property _NET_WM_SYNC_REQUEST_COUNTER	system_u:object_r:client_xproperty_t:s0
-property _NET_WM_WINDOW_TYPE		system_u:object_r:client_xproperty_t:s0
-property _NET_WM_USER_TIME		system_u:object_r:client_xproperty_t:s0
-property _MOTIF_DRAG_RECEIVER_INFO	system_u:object_r:client_xproperty_t:s0
-property XdndAware			system_u:object_r:client_xproperty_t:s0
-
-# Properties written by xrdb
-property RESOURCE_MANAGER		system_u:object_r:rm_xproperty_t:s0
-property SCREEN_RESOURCES		system_u:object_r:rm_xproperty_t:s0
-
-# Properties written by window managers
-property _MIT_PRIORITY_COLORS		system_u:object_r:wm_xproperty_t:s0
-
-# Properties used for security labeling
-property _SELINUX_CLIENT_CONTEXT	system_u:object_r:seclabel_xproperty_t:s0
-
-# Properties used to communicate screen information
-property XFree86_VT			system_u:object_r:info_xproperty_t:s0
-property XFree86_DDC_EDID1_RAWDATA	system_u:object_r:info_xproperty_t:s0
-
-# Clipboard and selection properties
-property CUT_BUFFER0			system_u:object_r:clipboard_xproperty_t:s0
-property CUT_BUFFER1			system_u:object_r:clipboard_xproperty_t:s0
-property CUT_BUFFER2			system_u:object_r:clipboard_xproperty_t:s0
-property CUT_BUFFER3			system_u:object_r:clipboard_xproperty_t:s0
-property CUT_BUFFER4			system_u:object_r:clipboard_xproperty_t:s0
-property CUT_BUFFER5			system_u:object_r:clipboard_xproperty_t:s0
-property CUT_BUFFER6			system_u:object_r:clipboard_xproperty_t:s0
-property CUT_BUFFER7			system_u:object_r:clipboard_xproperty_t:s0
-property _XT_SELECTION_0		system_u:object_r:clipboard_xproperty_t:s0
-
-# Default fallback type
-property *	   			system_u:object_r:unknown_xproperty_t:s0
-
-#
-# Extension rules map an extension name to a context.  A default extension
-# rule indicated by an asterisk should follow all other extension rules.
-#
-# Standard extensions
-extension BIG-REQUESTS			system_u:object_r:std_xext_t:s0
-extension DOUBLE-BUFFER			system_u:object_r:std_xext_t:s0
-extension Extended-Visual-Information	system_u:object_r:std_xext_t:s0
-extension MIT-SUNDRY-NONSTANDARD	system_u:object_r:std_xext_t:s0
-extension SHAPE				system_u:object_r:std_xext_t:s0
-extension SYNC				system_u:object_r:std_xext_t:s0
-extension XC-MISC			system_u:object_r:std_xext_t:s0
-extension XFIXES			system_u:object_r:std_xext_t:s0
-extension XFree86-Misc			system_u:object_r:std_xext_t:s0
-extension XpExtension                   system_u:object_r:std_xext_t:s0
-
-# Screen management and multihead extensions
-extension RANDR				system_u:object_r:output_xext_t:s0
-extension XINERAMA			system_u:object_r:std_xext_t:s0
-
-# Input extensions
-extension XInputExtension		system_u:object_r:input_xext_t:s0
-extension XKEYBOARD			system_u:object_r:input_xext_t:s0
-
-# Screensaver, power management extensions
-extension DPMS				system_u:object_r:screensaver_xext_t:s0
-extension MIT-SCREEN-SAVER		system_u:object_r:screensaver_xext_t:s0
-
-# Fonting extensions
-extension FontCache			system_u:object_r:font_xext_t:s0
-extension XFree86-Bigfont		system_u:object_r:font_xext_t:s0
-
-# Shared memory extensions
-extension MIT-SHM			system_u:object_r:shmem_xext_t:s0
-
-# Accelerated graphics, OpenGL, direct rendering extensions
-extension DAMAGE			system_u:object_r:accelgraphics_xext_t:s0
-extension GLX				system_u:object_r:accelgraphics_xext_t:s0
-extension NV-CONTROL			system_u:object_r:accelgraphics_xext_t:s0
-extension NV-GLX			system_u:object_r:accelgraphics_xext_t:s0
-extension NVIDIA-GLX			system_u:object_r:accelgraphics_xext_t:s0
-extension RENDER			system_u:object_r:std_xext_t:s0
-extension XFree86-DGA			system_u:object_r:accelgraphics_xext_t:s0
-
-# Debugging, testing, and recording extensions
-extension RECORD			system_u:object_r:debug_xext_t:s0
-extension X-Resource			system_u:object_r:debug_xext_t:s0
-extension XTEST				system_u:object_r:debug_xext_t:s0
-
-# Extensions just for window managers
-extension TOG-CUP			system_u:object_r:windowmgr_xext_t:s0
-
-# Security-related extensions
-extension SECURITY			system_u:object_r:security_xext_t:s0
-extension SELinux			system_u:object_r:security_xext_t:s0
-extension XAccessControlExtension	system_u:object_r:security_xext_t:s0
-extension XC-APPGROUP			system_u:object_r:security_xext_t:s0
-
-# Video extensions
-extension XFree86-VidModeExtension	system_u:object_r:video_xext_t:s0
-extension XVideo			system_u:object_r:video_xext_t:s0
-extension XVideo-MotionCompensation	system_u:object_r:video_xext_t:s0
-
-# Default fallback type
-extension *	   			system_u:object_r:unknown_xext_t:s0
commit baabae623b3658196b67a710dc72663c2105bf31
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Wed Oct 17 13:54:56 2007 -0400

    xselinux: Started reworking extension using new XACE hooks.

diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index bc86a32..9ff0554 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -32,13 +32,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <dix-config.h>
 #endif
 
-#include <X11/X.h>
 #include <X11/Xatom.h>
-#include <X11/Xproto.h>
-#include <X11/Xfuncproto.h>
+#include "resource.h"
+#include "privates.h"
+#include "registry.h"
 #include "dixstruct.h"
 #include "extnsionst.h"
-#include "resource.h"
+#include "scrnintstr.h"
 #include "selection.h"
 #include "xacestr.h"
 #include "xselinux.h"
@@ -50,14 +50,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <stdarg.h>
 #include "modinit.h"
 
-#ifndef XSELINUXCONFIGFILE
-#warning "XSELinux Policy file is not defined"
-#define XSELINUXCONFIGFILE  NULL
-#endif
+/* private state record */
+static DevPrivateKey stateKey = &stateKey;
 
-/* devPrivates in client and extension */
-static int clientPrivateIndex;
-static int extnsnPrivateIndex;
+/* This is what we store for security state */
+typedef struct {
+    security_id_t sid;
+    struct avc_entry_ref aeref;
+    char *client_path;
+} SELinuxStateRec;
 
 /* audit file descriptor */
 static int audit_fd;
@@ -65,1337 +66,681 @@ static int audit_fd;
 /* structure passed to auditing callback */
 typedef struct {
     ClientPtr client;	/* client */
-    char *property;	/* property name, if any */
+    char *client_path;	/* client's executable path */
+    unsigned id;	/* resource id, if any */
+    int restype;	/* resource type, if any */
+    Atom property;	/* property name, if any */
     char *extension;	/* extension name, if any */
-} XSELinuxAuditRec;
+} SELinuxAuditRec;
 
 /* labeling handle */
 static struct selabel_handle *label_hnd;
 
-/* Atoms for SELinux window labeling properties */
-Atom atom_ctx;
-Atom atom_client_ctx;
+/* whether AVC is active */
+static int avc_active;
+
+/* atoms for window label properties */
+static Atom atom_ctx;
+static Atom atom_client_ctx;
 
-/* Selection stuff from dix */
-extern Selection *CurrentSelections;
-extern int NumCurrentSelections;
+/* The unlabeled SID */
+static security_id_t unlabeled_sid;
 
-/* Dynamically allocated security classes and permissions */
+/* Array of object classes indexed by resource type */
+static security_class_t *knownTypes;
+static unsigned numKnownTypes;
+
+/* dynamically allocated security classes and permissions */
 static struct security_class_mapping map[] = {
-    { "drawable",
-      { "create", "destroy", "draw", "copy", "getattr", NULL }},
-    { "window",
-      { "addchild", "create", "destroy", "map", "unmap", "chstack",
-	"chproplist", "chprop", "listprop", "getattr", "setattr", "setfocus",
-	"move", "chselection", "chparent", "ctrllife", "enumerate",
-	"transparent", "mousemotion", "clientcomevent", "inputevent",
-	"drawevent", "windowchangeevent", "windowchangerequest",
-	"serverchangeevent", "extensionevent", NULL }},
-    { "gc",
-      { "create", "free", "getattr", "setattr", NULL }},
-    { "font",
-      { "load", "free", "getattr", "use", NULL }},
-    { "colormap",
-      { "create", "free", "install", "uninstall", "list", "read", "store",
-	"getattr", "setattr", NULL }},
-    { "property",
-      { "create", "free", "read", "write", NULL }},
-    { "cursor",
-      { "create", "createglyph", "free", "assign", "setattr", NULL }},
-    { "xclient",
-      { "kill", NULL }},
-    { "xinput",
-      { "lookup", "getattr", "setattr", "setfocus", "warppointer",
-	"activegrab", "passivegrab", "ungrab", "bell", "mousemotion",
-	"relabelinput", NULL }},
-    { "xserver",
-      { "screensaver", "gethostlist", "sethostlist", "getfontpath",
-	"setfontpath", "getattr", "grab", "ungrab", NULL }},
-    { "xextension",
-      { "query", "use", NULL }},
+    { "x_drawable", { "read", "write", "destroy", "create", "getattr", "setattr", "list_property", "get_property", "set_property", "", "", "list_child", "add_child", "remove_child", "hide", "show", "blend", "override", "", "", "", "", "send", "receive", "", "manage", NULL }},
+    { "x_screen", { "", "", "", "", "getattr", "setattr", "saver_getattr", "saver_setattr", "", "", "", "", "", "", "hide_cursor", "show_cursor", "saver_hide", "saver_show", NULL }},
+    { "x_gc", { "", "", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }},
+    { "x_font", { "", "", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_glyph", "remove_glyph", "", "", "", "", "", "", "", "", "", "", "use", NULL }},
+    { "x_colormap", { "read", "write", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_color", "remove_color", "", "", "", "", "", "", "install", "uninstall", "", "", "use", NULL }},
+    { "x_property", { "read", "write", "destroy", "create", NULL }},
+    { "x_selection", { "read", "", "", "", "getattr", "setattr", NULL }},
+    { "x_cursor", { "read", "write", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }},
+    { "x_client", { "", "", "destroy", "", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "manage", NULL }},
+    { "x_device", { "read", "write", "", "", "getattr", "setattr", "", "", "", "getfocus", "setfocus", "", "", "", "", "", "", "grab", "freeze", "force_cursor", "", "", "", "", "", "manage", "", "bell", NULL }},
+    { "x_server", { "record", "", "", "", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "grab", "", "", "", "", "", "", "", "manage", "debug", NULL }},
+    { "x_extension", { "", "", "", "", "query", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }},
+    { "x_resource", { "read", "write", "write", "write", "read", "write", "read", "read", "write", "read", "write", "read", "write", "write", "write", "read", "read", "write", "write", "write", "write", "write", "write", "read", "read", "write", "read", "write", NULL }},
     { NULL }
 };
 
 /*
- * list of classes corresponding to SIDs in the
- * rsid array of the security state structure (below).
- *
- * XXX SIDs should be stored in their native objects, not all
- * bunched together in the client structure.  However, this will
- * require modification to the resource manager.
+ * Returns the object class corresponding to the given resource type.
  */
-static security_class_t sClasses[] = {
-    SECCLASS_WINDOW,
-    SECCLASS_DRAWABLE,
-    SECCLASS_GC,
-    SECCLASS_CURSOR,
-    SECCLASS_FONT,
-    SECCLASS_COLORMAP,
-    SECCLASS_PROPERTY,
-    SECCLASS_XCLIENT,
-    SECCLASS_XINPUT,
-    SECCLASS_XSERVER
-};
-#define NRES (sizeof(sClasses)/sizeof(sClasses[0]))
-
-/* This is what we store for client security state */
-typedef struct {
-    int haveState;
-    security_id_t sid;
-    security_id_t rsid[NRES];
-    struct avc_entry_ref aeref;
-} XSELinuxClientStateRec;
-
-/* Convenience macros for accessing security state fields */
-#define STATEPTR(client) \
-    ((client)->devPrivates[clientPrivateIndex].ptr)
-#define HAVESTATE(client) \
-    (((XSELinuxClientStateRec*)STATEPTR(client))->haveState)
-#define SID(client) \
-    (((XSELinuxClientStateRec*)STATEPTR(client))->sid)
-#define RSID(client,n) \
-    (((XSELinuxClientStateRec*)STATEPTR(client))->rsid[n])
-#define AEREF(client) \
-    (((XSELinuxClientStateRec*)STATEPTR(client))->aeref)
-#define EXTENSIONSID(ext) \
-    ((ext)->devPrivates[extnsnPrivateIndex].ptr)
-
-/*
- * Returns the index into the rsid array where the SID for the
- * given class is stored.
- */
-static int
-IndexByClass(security_class_t class)
+static security_class_t
+SELinuxTypeToClass(RESTYPE type)
 {
-    int i;
-    for (i=0; i<NRES; i++)
-	if (class == sClasses[i])
-	    return i;
-    return 0;
-}
-
-/*
- * Does sanity checking on a resource ID.  This can be removed after
- * testing.
- */
-static void
-CheckXID(XID id)
-{
-    /*
-    XID c = CLIENT_ID(id);
-
-    if (c > 10)
-	ErrorF("Warning: possibly mangled ID %x\n", id);
-
-    c = id & RESOURCE_ID_MASK;
-    if (c > 100)
-	ErrorF("Warning: possibly mangled ID %x\n", id);
-        */
-}
-
-/*
- * Byte-swap a CARD32 id if necessary.
- */
-static XID
-SwapXID(ClientPtr client, XID id)
-{
-    register char n;
-    if (client->swapped)
-	swapl(&id, n);
-    return id;
-}
-
-/*
- * ServerPerm - check access permissions on a server-owned object.
- *
- * Arguments:
- * client: Client doing the request.
- * class: Security class of the server object being accessed.
- * perm: Permissions required on the object.
- *
- * Returns: X status code.
- */
-static int
-ServerPerm(ClientPtr client,
-	   security_class_t class,
-	   access_vector_t perm)
-{
-    int idx = IndexByClass(class);
-    if (HAVESTATE(client))
-    {
-	XSELinuxAuditRec auditdata;
-	auditdata.client = client;
-	auditdata.property = NULL;
-	auditdata.extension = NULL;
-	errno = 0;
-        if (avc_has_perm(SID(client), RSID(serverClient,idx), class,
-                         perm, &AEREF(client), &auditdata) < 0)
-        {
-            if (errno == EACCES)
-		return BadAccess;
-	    ErrorF("ServerPerm: unexpected error %d\n", errno);
-	    return BadValue;
-        }
+    RESTYPE fulltype = type;
+    type &= TypeMask;
+
+    if (type >= numKnownTypes) {
+	/* Need to increase size of classes array */
+	unsigned size = sizeof(security_class_t);
+	knownTypes = xrealloc(knownTypes, (type + 1) * size);
+	if (!knownTypes)
+	    return 0;
+	memset(knownTypes + numKnownTypes, 0,
+	       (type - numKnownTypes + 1) * size);
     }
-    else
-    {
-	ErrorF("No client state in server-perm check!\n");
-        return Success;
+
+    if (!knownTypes[type]) {
+	const char *str;
+	knownTypes[type] = SECCLASS_X_RESOURCE;
+
+	if (fulltype & RC_DRAWABLE)
+	    knownTypes[type] = SECCLASS_X_DRAWABLE;
+	if (fulltype == RT_GC)
+	    knownTypes[type] = SECCLASS_X_GC;
+	if (fulltype == RT_FONT)
+	    knownTypes[type] = SECCLASS_X_FONT;
+	if (fulltype == RT_CURSOR)
+	    knownTypes[type] = SECCLASS_X_CURSOR;
+	if (fulltype == RT_COLORMAP)
+	    knownTypes[type] = SECCLASS_X_COLORMAP;
+	
+	/* Need to do a string lookup */
+	str = LookupResourceName(fulltype);
+	if (!strcmp(str, "PICTURE"))
+	    knownTypes[type] = SECCLASS_X_DRAWABLE;
+	if (!strcmp(str, "GLYPHSET"))
+	    knownTypes[type] = SECCLASS_X_FONT;
     }
 
-    return Success;
+//    ErrorF("Returning a class of %d for a type of %d\n", knownTypes[type], type);
+    return knownTypes[type];
 }
 
 /*
- * IDPerm - check access permissions on a resource.
- *
- * Arguments:
- * client: Client doing the request.
- * id: resource id of the resource being accessed.
- * class: Security class of the resource being accessed.
- * perm: Permissions required on the resource.
- *
- * Returns: X status code.
+ * Performs an SELinux permission check.
  */
 static int
-IDPerm(ClientPtr sclient,
-	 XID id,
-	 security_class_t class,
-	 access_vector_t perm)
+SELinuxDoCheck(ClientPtr client, SELinuxStateRec *obj, security_class_t class,
+	       Mask access_mode, SELinuxAuditRec *auditdata)
 {
-    ClientPtr tclient;
-    int idx = IndexByClass(class);
-    XSELinuxAuditRec auditdata;
+    SELinuxStateRec *subj;
 
-    if (id == None)
-	return Success;
-
-    CheckXID(id);
-    tclient = clients[CLIENT_ID(id)];
+//    ErrorF("SuperCheck: client=%d, class=%d, access_mode=%x\n", client->index, class, access_mode);
 
-    /*
-     * This happens in the case where a client has
-     * disconnected.  XXX might want to make the server
-     * own orphaned resources...
-     */
-    if (!tclient || !HAVESTATE(tclient) || !HAVESTATE(sclient))
-    {
+    /* serverClient requests OK */
+    if (client->index == 0)
 	return Success;
-    }
 
-    auditdata.client = sclient;
-    auditdata.property = NULL;
-    auditdata.extension = NULL;
+    subj = dixLookupPrivate(&client->devPrivates, stateKey);
+    auditdata->client = client;
+    auditdata->client_path = subj->client_path;
     errno = 0;
-    if (avc_has_perm(SID(sclient), RSID(tclient,idx), class,
-		     perm, &AEREF(sclient), &auditdata) < 0)
-    {
+
+    if (avc_has_perm(subj->sid, obj->sid, class, access_mode, &subj->aeref,
+		     auditdata) < 0) {
 	if (errno == EACCES)
 	    return BadAccess;
-	ErrorF("IDPerm: unexpected error %d\n", errno);
+	ErrorF("ServerPerm: unexpected error %d\n", errno);
 	return BadValue;
     }
 
     return Success;
 }
 
-/*
- * GetPropertySID - compute SID for a property object.
- *
- * Arguments:
- * basecontext: context of client owning the property.
- * name: name of the property.
- *
- * Returns: proper SID for the object or NULL on error.
- */
-static security_id_t
-GetPropertySID(security_context_t base, const char *name)
-{
-    security_context_t con, result;
-    security_id_t sid = NULL;
-
-    /* look in the mappings of names to types */
-    if (selabel_lookup(label_hnd, &con, name, SELABEL_X_PROP) < 0)
-	goto out;
-
-    /* perform a transition to obtain the final context */
-    if (security_compute_create(base, con, SECCLASS_PROPERTY, &result) < 0)
-	goto out2;
-
-    /* get a SID for the context */
-    avc_context_to_sid(result, &sid);
-    freecon(result);
-  out2:
-    freecon(con);
-  out:
-    return sid;
-}
-
-/*
- * GetExtensionSID - compute SID for an extension object.
- *
- * Arguments:
- * name: name of the extension.
- *
- * Returns: proper SID for the object or NULL on error.
- */
-static security_id_t
-GetExtensionSID(const char *name)
-{
-    security_context_t base, con, result;
-    security_id_t sid = NULL;
-
-    /* get server context */
-    if (getcon(&base) < 0)
-	goto out;
-
-    /* look in the mappings of names to types */
-    if (selabel_lookup(label_hnd, &con, name, SELABEL_X_EXT) < 0)
-	goto out2;
-
-    /* perform a transition to obtain the final context */
-    if (security_compute_create(base, con, SECCLASS_XEXTENSION, &result) < 0)
-	goto out3;
-
-    /* get a SID for the context */
-    avc_context_to_sid(result, &sid);
-    freecon(result);
-  out3:
-    freecon(con);
-  out2:
-    freecon(base);
-  out:
-    return sid;
-}
+//static void
+//SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+//{
+//    XaceSelectionAccessRec *rec = calldata;
+//}
 
-/*
- * AssignServerState - set up server security state.
- *
- * Arguments:
- */
 static void
-AssignServerState(void)
+SELinuxExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 {
-    int i;
-    security_context_t basectx, objctx;
-    XSELinuxClientStateRec *state;
+    XaceExtAccessRec *rec = calldata;
+    SELinuxStateRec *subj, *obj, *serv;
+    SELinuxAuditRec auditdata = { NULL, NULL, 0, 0, 0, NULL };
+    int rc;
 
-    state = (XSELinuxClientStateRec*)STATEPTR(serverClient);
-    avc_entry_ref_init(&state->aeref);
+    subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
+    obj = dixLookupPrivate(&rec->ext->devPrivates, stateKey);
 
-    /* use the context of the X server process for the serverClient */
-    if (getcon(&basectx) < 0)
-	FatalError("Couldn't get context of X server process\n");
+    /* If this is a new object that needs labeling, do it now */
+    /* XXX there should be a separate callback for this */
+    if (obj->sid == unlabeled_sid) {
+	const char *name = rec->ext->name;
+	security_context_t con;
+	security_id_t sid;
 
-    /* get a SID from the context */
-    if (avc_context_to_sid(basectx, &state->sid) < 0)
-	FatalError("Client %d: context_to_sid(%s) failed\n", 0, basectx);
+	serv = dixLookupPrivate(&serverClient->devPrivates, stateKey);
 
-    /* get contexts and then SIDs for each resource type */
-    for (i=0; i<NRES; i++) {
-	if (security_compute_create(basectx, basectx, sClasses[i],
-				    &objctx) < 0)
-	    FatalError("Client %d: compute_create(base=%s, cls=%d) failed\n",
-		       0, basectx, sClasses[i]);
+	/* Look in the mappings of property names to contexts */
+	if (selabel_lookup(label_hnd, &con, name, SELABEL_X_EXT) < 0) {
+	    ErrorF("XSELinux: a property label lookup failed!\n");
+	    rec->status = BadValue;
+	    return;
+	}
+	/* Get a SID for context */
+	if (avc_context_to_sid(con, &sid) < 0) {
+	    ErrorF("XSELinux: a context_to_SID call failed!\n");
+	    rec->status = BadAlloc;
+	    return;
+	}
 
-	if (avc_context_to_sid(objctx, &state->rsid[i]) < 0)
-	    FatalError("Client %d: context_to_sid(%s) failed\n",
-		       0, objctx);
+	sidput(obj->sid);
 
-	freecon(objctx);
+	/* Perform a transition to obtain the final SID */
+	if (avc_compute_create(serv->sid, sid, SECCLASS_X_EXTENSION,
+			       &obj->sid) < 0) {
+	    ErrorF("XSELinux: a SID transition call failed!\n");
+	    freecon(con);
+	    rec->status = BadValue;
+	    return;
+	}
+	freecon(con);
     }
 
-    /* mark as set up, free base context, and return */
-    state->haveState = TRUE;
-    freecon(basectx);
+    /* Perform the security check */
+    auditdata.extension = rec->ext->name;
+    rc = SELinuxDoCheck(rec->client, obj, SECCLASS_X_EXTENSION,
+			rec->access_mode, &auditdata);
+    if (rc != Success)
+	rec->status = rc;
 }
 
-/*
- * AssignClientState - set up client security state.
- *
- * Arguments:
- * client: client to set up (can be serverClient).
- */
 static void
-AssignClientState(ClientPtr client)
+SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 {
-    int i;
-    security_context_t basectx, objctx;
-    XSELinuxClientStateRec *state;
-
-    state = (XSELinuxClientStateRec*)STATEPTR(client);
-    avc_entry_ref_init(&state->aeref);
+    XacePropertyAccessRec *rec = calldata;
+    SELinuxStateRec *subj, *obj;
+    SELinuxAuditRec auditdata = { NULL, NULL, 0, 0, 0, NULL };
+    int rc;
 
-    XtransConnInfo ci = ((OsCommPtr)client->osPrivate)->trans_conn;
-    if (_XSERVTransIsLocal(ci)) {
-	/* for local clients, can get context from the socket */
-	int fd = _XSERVTransGetConnectionNumber(ci);
-	if (getpeercon(fd, &basectx) < 0)
-	    FatalError("Client %d: couldn't get context from socket\n",
-		       client->index);
-    }
-    else
-	/* for remote clients, need to use a default context */
-	if (selabel_lookup(label_hnd, &basectx, NULL, SELABEL_X_CLIENT) < 0)
-	    FatalError("Client %d: couldn't get default remote connection context\n",
-		       client->index);
+    subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
+    obj = dixLookupPrivate(&rec->pProp->devPrivates, stateKey);
 
-    /* get a SID from the context */
-    if (avc_context_to_sid(basectx, &state->sid) < 0)
-	FatalError("Client %d: context_to_sid(%s) failed\n",
-		   client->index, basectx);
+    /* If this is a new object that needs labeling, do it now */
+    if (rec->access_mode & DixCreateAccess) {
+	const char *name = NameForAtom(rec->pProp->propertyName);
+	security_context_t con;
+	security_id_t sid;
 
-    /* get contexts and then SIDs for each resource type */
-    for (i=0; i<NRES; i++) {
-	if (security_compute_create(basectx, basectx, sClasses[i],
-				    &objctx) < 0)
-	    FatalError("Client %d: compute_create(base=%s, cls=%d) failed\n",
-		       client->index, basectx, sClasses[i]);
+	/* Look in the mappings of property names to contexts */
+	if (selabel_lookup(label_hnd, &con, name, SELABEL_X_PROP) < 0) {
+	    ErrorF("XSELinux: a property label lookup failed!\n");
+	    rec->status = BadValue;
+	    return;
+	}
+	/* Get a SID for context */
+	if (avc_context_to_sid(con, &sid) < 0) {
+	    ErrorF("XSELinux: a context_to_SID call failed!\n");
+	    rec->status = BadAlloc;
+	    return;
+	}
 
-	if (avc_context_to_sid(objctx, &state->rsid[i]) < 0)
-	    FatalError("Client %d: context_to_sid(%s) failed\n",
-		       client->index, objctx);
+	sidput(obj->sid);
 
-	freecon(objctx);
+	/* Perform a transition to obtain the final SID */
+	if (avc_compute_create(subj->sid, sid, SECCLASS_X_PROPERTY,
+			       &obj->sid) < 0) {
+	    ErrorF("XSELinux: a SID transition call failed!\n");
+	    freecon(con);
+	    rec->status = BadValue;
+	    return;
+	}
+	freecon(con);
+	avc_entry_ref_init(&obj->aeref);
     }
 
-    /* mark as set up, free base context, and return */
-    state->haveState = TRUE;
-    freecon(basectx);
+    /* Perform the security check */
+    auditdata.property = rec->pProp->propertyName;
+    rc = SELinuxDoCheck(rec->client, obj, SECCLASS_X_PROPERTY,
+			rec->access_mode, &auditdata);
+    if (rc != Success)
+	rec->status = rc;
 }
 
-/*
- * FreeClientState - tear down client security state.
- *
- * Arguments:
- * client: client to release (can be serverClient).
- */
 static void
-FreeClientState(ClientPtr client)
+SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 {
-    int i;
-    XSELinuxClientStateRec *state = (XSELinuxClientStateRec*)STATEPTR(client);
-
-    /* client state may not be set up if its auth was rejected */
-    if (state->haveState) {
-	state = (XSELinuxClientStateRec*)STATEPTR(client);
-	sidput(state->sid);
-	for (i=0; i<NRES; i++)
-	    sidput(state->rsid[i]);
-	state->haveState = FALSE;
+    XaceResourceAccessRec *rec = calldata;
+    SELinuxStateRec *subj, *obj, *pobj;
+    SELinuxAuditRec auditdata = { NULL, NULL, 0, 0, 0, NULL };
+    PrivateRec **privatePtr;
+    security_class_t class;
+    int rc, offset;
+
+    subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
+
+    /* Determine if the resource object has a devPrivates field */
+    offset = dixLookupPrivateOffset(rec->rtype);
+    if (offset < 0) {
+	/* No: use the SID of the owning client */
+	class = SECCLASS_X_RESOURCE;
+	privatePtr = &clients[CLIENT_ID(rec->id)]->devPrivates;
+	obj = dixLookupPrivate(privatePtr, stateKey);
+    } else {
+	/* Yes: use the SID from the resource object itself */
+	class = SELinuxTypeToClass(rec->rtype);
+	privatePtr = DEVPRIV_AT(rec->res, offset);
+	obj = dixLookupPrivate(privatePtr, stateKey);
     }
-}
 
-#define REQUEST_SIZE_CHECK(client, req) \
-    (client->req_len >= (sizeof(req) >> 2))
-#define IDPERM(client, req, field, class, perm) \
-    (REQUEST_SIZE_CHECK(client,req) ? \
-     IDPerm(client, SwapXID(client,((req*)stuff)->field), class, perm) : \
-     BadLength)
-
-static int
-CheckSendEventPerms(ClientPtr client)
-{
-    register char n;
-    access_vector_t perm = 0;
-    REQUEST(xSendEventReq);
-
-    /* might need type bounds checking here */
-    if (!REQUEST_SIZE_CHECK(client, xSendEventReq))
-	return BadLength;
-
-    switch (stuff->event.u.u.type) {
-	case SelectionClear:
-	case SelectionNotify:
-	case SelectionRequest:
-	case ClientMessage:
-	case PropertyNotify:
-	    perm = WINDOW__CLIENTCOMEVENT;
-	    break;
-	case ButtonPress:
-	case ButtonRelease:
-	case KeyPress:
-	case KeyRelease:
-	case KeymapNotify:
-	case MotionNotify:
-	case EnterNotify:
-	case LeaveNotify:
-	case FocusIn:
-	case FocusOut:
-	    perm = WINDOW__INPUTEVENT;
-	    break;
-	case Expose:
-	case GraphicsExpose:
-	case NoExpose:
-	case VisibilityNotify:
-	    perm = WINDOW__DRAWEVENT;
-	    break;
-	case CirculateNotify:
-	case ConfigureNotify:
-	case CreateNotify:
-	case DestroyNotify:
-	case MapNotify:
-	case UnmapNotify:
-	case GravityNotify:
-	case ReparentNotify:
-	    perm = WINDOW__WINDOWCHANGEEVENT;
-	    break;
-	case CirculateRequest:
-	case ConfigureRequest:
-	case MapRequest:
-	case ResizeRequest:
-	    perm = WINDOW__WINDOWCHANGEREQUEST;
-	    break;
-	case ColormapNotify:
-	case MappingNotify:
-	    perm = WINDOW__SERVERCHANGEEVENT;
-	    break;
-	default:
-	    perm = WINDOW__EXTENSIONEVENT;
-	    break;
+    /* If this is a new object that needs labeling, do it now */
+    if (rec->access_mode & DixCreateAccess && offset >= 0) {
+	if (rec->parent)
+	    offset = dixLookupPrivateOffset(rec->ptype);
+	if (rec->parent && offset >= 0)
+	    /* Use the SID of the parent object in the labeling operation */
+	    pobj = dixLookupPrivate(DEVPRIV_AT(rec->parent, offset), stateKey);
+	else
+	    /* Use the SID of the subject */
+	    pobj = subj;
+
+	sidput(obj->sid);
+
+	/* Perform a transition to obtain the final SID */
+	if (avc_compute_create(subj->sid, pobj->sid, class, &obj->sid) < 0) {
+	    ErrorF("XSELinux: a compute_create call failed!\n");
+	    rec->status = BadValue;
+	    return;
+	}
     }
-    if (client->swapped)
-	swapl(&stuff->destination, n);
-    return IDPerm(client, stuff->destination, SECCLASS_WINDOW, perm);
+
+    /* Perform the security check */
+    auditdata.restype = rec->rtype;
+    auditdata.id = rec->id;
+    rc = SELinuxDoCheck(rec->client, obj, class, rec->access_mode, &auditdata);
+    if (rc != Success)
+	rec->status = rc;
 }
 
-static int
-CheckConvertSelectionPerms(ClientPtr client)
+static void
+SELinuxScreen(CallbackListPtr *pcbl, pointer is_saver, pointer calldata)
 {
-    register char n;
-    int rval = Success;
-    REQUEST(xConvertSelectionReq);
+    XaceScreenAccessRec *rec = calldata;
+    SELinuxStateRec *subj, *obj;
+    SELinuxAuditRec auditdata = { NULL, NULL, 0, 0, 0, NULL };
+    Mask access_mode = rec->access_mode;
+    int rc;
 
-    if (!REQUEST_SIZE_CHECK(client, xConvertSelectionReq))
-	return BadLength;
+    subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
+    obj = dixLookupPrivate(&rec->screen->devPrivates, stateKey);
 
-    if (client->swapped)
-    {
-	swapl(&stuff->selection, n);
-	swapl(&stuff->requestor, n);
-    }
+    /* If this is a new object that needs labeling, do it now */
+    if (access_mode & DixCreateAccess) {
+	sidput(obj->sid);
 
-    if (ValidAtom(stuff->selection))
-    {
-	int i = 0;
-	while ((i < NumCurrentSelections) &&
-	       CurrentSelections[i].selection != stuff->selection) i++;
-	if (i < NumCurrentSelections) {
-	    rval = IDPerm(client, CurrentSelections[i].window,
-			  SECCLASS_WINDOW, WINDOW__CLIENTCOMEVENT);
-	    if (rval != Success)
-		return rval;
+	/* Perform a transition to obtain the final SID */
+	if (avc_compute_create(subj->sid, subj->sid, SECCLASS_X_SCREEN,
+			       &obj->sid) < 0) {
+	    ErrorF("XSELinux: a compute_create call failed!\n");
+	    rec->status = BadValue;
+	    return;
 	}
     }
-    return IDPerm(client, stuff->requestor,
-		  SECCLASS_WINDOW, WINDOW__CLIENTCOMEVENT);
+
+    if (is_saver)
+	access_mode <<= 2;
+
+    rc = SELinuxDoCheck(rec->client, obj, SECCLASS_X_SCREEN,
+			access_mode, &auditdata);
+    if (rc != Success)
+	rec->status = rc;
 }
 
-static int
-CheckSetSelectionOwnerPerms(ClientPtr client)
+static void
+SELinuxClient(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 {
-    register char n;
-    int rval = Success;
-    REQUEST(xSetSelectionOwnerReq);
-
-    if (!REQUEST_SIZE_CHECK(client, xSetSelectionOwnerReq))
-	return BadLength;
+    XaceClientAccessRec *rec = calldata;
+    SELinuxStateRec *obj;
+    SELinuxAuditRec auditdata = { NULL, NULL, 0, 0, 0, NULL };
+    int rc;
 
-    if (client->swapped)
-    {
-	swapl(&stuff->selection, n);
-	swapl(&stuff->window, n);
-    }
+    obj = dixLookupPrivate(&rec->target->devPrivates, stateKey);
 
-    if (ValidAtom(stuff->selection))
-    {
-	int i = 0;
-	while ((i < NumCurrentSelections) &&
-	       CurrentSelections[i].selection != stuff->selection) i++;
-	if (i < NumCurrentSelections) {
-	    rval = IDPerm(client, CurrentSelections[i].window,
-			  SECCLASS_WINDOW, WINDOW__CHSELECTION);
-	    if (rval != Success)
-		return rval;
-	}
-    }
-    return IDPerm(client, stuff->window,
-			  SECCLASS_WINDOW, WINDOW__CHSELECTION);
+    rc = SELinuxDoCheck(rec->client, obj, SECCLASS_X_CLIENT,
+			rec->access_mode, &auditdata);
+    if (rc != Success)
+	rec->status = rc;
 }
 
 static void
-XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxServer(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 {
-    XaceCoreDispatchRec *rec = (XaceCoreDispatchRec*)calldata;
-    ClientPtr client = rec->client;
-    REQUEST(xReq);
-    int rval = Success, rval2 = Success, rval3 = Success;
-
-    switch(stuff->reqType) {
-    /* Drawable class control requirements */
-    case X_ClearArea:
-	rval = IDPERM(client, xClearAreaReq, window,
-		      SECCLASS_DRAWABLE, DRAWABLE__DRAW);
-	break;
-    case X_PolySegment:
-    case X_PolyRectangle:
-    case X_PolyArc:
-    case X_PolyFillRectangle:
-    case X_PolyFillArc:
-	rval = IDPERM(client, xPolySegmentReq, drawable,
-		      SECCLASS_DRAWABLE, DRAWABLE__DRAW);
-	break;
-    case X_PolyPoint:
-    case X_PolyLine:
-	rval = IDPERM(client, xPolyPointReq, drawable,
-		      SECCLASS_DRAWABLE, DRAWABLE__DRAW);
-	break;
-    case X_FillPoly:
-	rval = IDPERM(client, xFillPolyReq, drawable,
-		      SECCLASS_DRAWABLE, DRAWABLE__DRAW);
-	break;
-    case X_PutImage:
-	rval = IDPERM(client, xPutImageReq, drawable,
-		      SECCLASS_DRAWABLE, DRAWABLE__DRAW);
-	break;
-    case X_CopyArea:
-    case X_CopyPlane:
-	rval = IDPERM(client, xCopyAreaReq, srcDrawable,
-		      SECCLASS_DRAWABLE, DRAWABLE__COPY);
-	rval2 = IDPERM(client, xCopyAreaReq, dstDrawable,
-		       SECCLASS_DRAWABLE, DRAWABLE__DRAW);
-	break;
-    case X_GetImage:
-	rval = IDPERM(client, xGetImageReq, drawable,
-		      SECCLASS_DRAWABLE, DRAWABLE__COPY);
-	break;
-    case X_GetGeometry:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_DRAWABLE, DRAWABLE__GETATTR);
-	break;
-
-    /* Window class control requirements */
-    case X_ChangeProperty:
-	rval = IDPERM(client, xChangePropertyReq, window,
-		      SECCLASS_WINDOW,
-		      WINDOW__CHPROPLIST | WINDOW__CHPROP |
-		      WINDOW__LISTPROP);
-	break;
-    case X_ChangeSaveSet:
-	rval = IDPERM(client, xChangeSaveSetReq, window,
-		      SECCLASS_WINDOW,
-		      WINDOW__CTRLLIFE | WINDOW__CHPARENT);
-	break;
-    case X_ChangeWindowAttributes:
-	rval = IDPERM(client, xChangeWindowAttributesReq, window,
-		      SECCLASS_WINDOW, WINDOW__SETATTR);
-	break;
-    case X_CirculateWindow:
-	rval = IDPERM(client, xCirculateWindowReq, window,
-		      SECCLASS_WINDOW, WINDOW__CHSTACK);
-	break;
-    case X_ConfigureWindow:
-	rval = IDPERM(client, xConfigureWindowReq, window,
-		      SECCLASS_WINDOW,
-		      WINDOW__SETATTR | WINDOW__MOVE | WINDOW__CHSTACK);
-	break;
-    case X_ConvertSelection:
-	rval = CheckConvertSelectionPerms(client);
-	break;
-    case X_CreateWindow:
-	rval = IDPERM(client, xCreateWindowReq, wid,
-		      SECCLASS_WINDOW,
-		      WINDOW__CREATE | WINDOW__SETATTR | WINDOW__MOVE);
-	rval2 = IDPERM(client, xCreateWindowReq, parent,
-		       SECCLASS_WINDOW,
-		       WINDOW__CHSTACK | WINDOW__ADDCHILD);
-	rval3 = IDPERM(client, xCreateWindowReq, wid,
-		       SECCLASS_DRAWABLE, DRAWABLE__CREATE);
-	break;
-    case X_DeleteProperty:
-	rval = IDPERM(client, xDeletePropertyReq, window,
-		      SECCLASS_WINDOW,
-		      WINDOW__CHPROP | WINDOW__CHPROPLIST);
-	break;
-    case X_DestroyWindow:
-    case X_DestroySubwindows:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_WINDOW,
-		      WINDOW__ENUMERATE | WINDOW__UNMAP | WINDOW__DESTROY);
-	rval2 = IDPERM(client, xResourceReq, id,
-		       SECCLASS_DRAWABLE, DRAWABLE__DESTROY);
-	break;
-    case X_GetMotionEvents:
-	rval = IDPERM(client, xGetMotionEventsReq, window,
-		      SECCLASS_WINDOW, WINDOW__MOUSEMOTION);
-	break;
-    case X_GetProperty:
-	rval = IDPERM(client, xGetPropertyReq, window,
-		      SECCLASS_WINDOW, WINDOW__LISTPROP);
-	break;
-    case X_GetWindowAttributes:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_WINDOW, WINDOW__GETATTR);
-	break;
-    case X_KillClient:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_XCLIENT, XCLIENT__KILL);
-	break;
-    case X_ListProperties:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_WINDOW, WINDOW__LISTPROP);
-	break;
-    case X_MapWindow:
-    case X_MapSubwindows:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_WINDOW,
-		      WINDOW__ENUMERATE | WINDOW__GETATTR | WINDOW__MAP);
-	break;
-    case X_QueryTree:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_WINDOW, WINDOW__ENUMERATE | WINDOW__GETATTR);
-	break;
-    case X_RotateProperties:
-	rval = IDPERM(client, xRotatePropertiesReq, window,
-		      SECCLASS_WINDOW, WINDOW__CHPROP | WINDOW__CHPROPLIST);
-	break;
-    case X_ReparentWindow:
-	rval = IDPERM(client, xReparentWindowReq, window,
-		      SECCLASS_WINDOW, WINDOW__CHPARENT | WINDOW__MOVE);
-	rval2 = IDPERM(client, xReparentWindowReq, parent,
-		       SECCLASS_WINDOW, WINDOW__CHSTACK | WINDOW__ADDCHILD);
-	break;
-    case X_SendEvent:
-	rval = CheckSendEventPerms(client);
-	break;
-    case X_SetInputFocus:
-	rval = IDPERM(client, xSetInputFocusReq, focus,
-		      SECCLASS_WINDOW, WINDOW__SETFOCUS);
-	rval2 = ServerPerm(client, SECCLASS_XINPUT, XINPUT__SETFOCUS);
-	break;
-    case X_SetSelectionOwner:
-	rval = CheckSetSelectionOwnerPerms(client);
-	break;
-    case X_TranslateCoords:
-	rval = IDPERM(client, xTranslateCoordsReq, srcWid,
-		      SECCLASS_WINDOW, WINDOW__GETATTR);
-	rval2 = IDPERM(client, xTranslateCoordsReq, dstWid,
-		       SECCLASS_WINDOW, WINDOW__GETATTR);
-	break;
-    case X_UnmapWindow:
-    case X_UnmapSubwindows:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_WINDOW,
-		      WINDOW__ENUMERATE | WINDOW__GETATTR |
-		      WINDOW__UNMAP);
-	break;
-    case X_WarpPointer:
-	rval = IDPERM(client, xWarpPointerReq, srcWid,
-		      SECCLASS_WINDOW, WINDOW__GETATTR);
-	rval2 = IDPERM(client, xWarpPointerReq, dstWid,
-		       SECCLASS_WINDOW, WINDOW__GETATTR);
-	rval3 = ServerPerm(client, SECCLASS_XINPUT, XINPUT__WARPPOINTER);
-	break;
-
-    /* Input class control requirements */
-    case X_GrabButton:
-    case X_GrabKey:
-	rval = ServerPerm(client, SECCLASS_XINPUT, XINPUT__PASSIVEGRAB);
-	break;
-    case X_GrabKeyboard:
-    case X_GrabPointer:
-    case X_ChangeActivePointerGrab:
-	rval = ServerPerm(client, SECCLASS_XINPUT, XINPUT__ACTIVEGRAB);
-	break;
-    case X_AllowEvents:
-    case X_UngrabButton:
-    case X_UngrabKey:
-    case X_UngrabKeyboard:
-    case X_UngrabPointer:
-	rval = ServerPerm(client, SECCLASS_XINPUT, XINPUT__UNGRAB);
-	break;
-    case X_GetKeyboardControl:
-    case X_GetKeyboardMapping:
-    case X_GetPointerControl:
-    case X_GetPointerMapping:
-    case X_GetModifierMapping:
-    case X_QueryKeymap:
-    case X_QueryPointer:
-	rval = ServerPerm(client, SECCLASS_XINPUT, XINPUT__GETATTR);
-	break;
-    case X_ChangeKeyboardControl:
-    case X_ChangePointerControl:
-    case X_ChangeKeyboardMapping:
-    case X_SetModifierMapping:
-    case X_SetPointerMapping:
-	rval = ServerPerm(client, SECCLASS_XINPUT, XINPUT__SETATTR);
-	break;
-    case X_Bell:
-	rval = ServerPerm(client, SECCLASS_XINPUT, XINPUT__BELL);
-	break;
-
-    /* Colormap class control requirements */
-    case X_AllocColor:
-    case X_AllocColorCells:
-    case X_AllocColorPlanes:
-    case X_AllocNamedColor:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_COLORMAP,
-		      COLORMAP__READ | COLORMAP__STORE);
-	break;
-    case X_CopyColormapAndFree:
-	rval = IDPERM(client, xCopyColormapAndFreeReq, mid,
-		      SECCLASS_COLORMAP, COLORMAP__CREATE);
-	rval2 = IDPERM(client, xCopyColormapAndFreeReq, srcCmap,
-		       SECCLASS_COLORMAP,
-		       COLORMAP__READ | COLORMAP__FREE);
-	break;
-    case X_CreateColormap:
-	rval = IDPERM(client, xCreateColormapReq, mid,
-		      SECCLASS_COLORMAP, COLORMAP__CREATE);
-	rval2 = IDPERM(client, xCreateColormapReq, window,
-		       SECCLASS_DRAWABLE, DRAWABLE__DRAW);
-	break;
-    case X_FreeColormap:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_COLORMAP, COLORMAP__FREE);
-	break;
-    case X_FreeColors:
-	rval = IDPERM(client, xFreeColorsReq, cmap,
-		      SECCLASS_COLORMAP, COLORMAP__STORE);
-	break;
-    case X_InstallColormap:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_COLORMAP, COLORMAP__INSTALL);
-	rval2 = ServerPerm(client, SECCLASS_COLORMAP, COLORMAP__INSTALL);
-	break;
-    case X_ListInstalledColormaps:
-	rval = ServerPerm(client, SECCLASS_COLORMAP, COLORMAP__LIST);
-	break;
-    case X_LookupColor:
-    case X_QueryColors:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_COLORMAP, COLORMAP__READ);
-	break;
-    case X_StoreColors:
-    case X_StoreNamedColor:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_COLORMAP, COLORMAP__STORE);
-	break;
-    case X_UninstallColormap:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_COLORMAP, COLORMAP__UNINSTALL);
-	rval2 = ServerPerm(client, SECCLASS_COLORMAP, COLORMAP__UNINSTALL);
-	break;
-
-    /* Font class control requirements */
-    case X_CloseFont:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_FONT, FONT__FREE);
-	break;
-    case X_ImageText8:
-    case X_ImageText16:
-	/* Font accesses checked through the resource manager */
-	rval = IDPERM(client, xImageTextReq, drawable,
-		      SECCLASS_DRAWABLE, DRAWABLE__DRAW);
-	break;
-    case X_OpenFont:
-	rval = ServerPerm(client, SECCLASS_FONT, FONT__LOAD);
-	rval2 = IDPERM(client, xOpenFontReq, fid,
-		       SECCLASS_FONT, FONT__USE);
-	break;
-    case X_PolyText8:
-    case X_PolyText16:
-	/* Font accesses checked through the resource manager */
-	rval = ServerPerm(client, SECCLASS_FONT, FONT__LOAD);
-	rval2 = IDPERM(client, xPolyTextReq, gc,
-		       SECCLASS_GC, GC__SETATTR);
-	rval3 = IDPERM(client, xPolyTextReq, drawable,
-		       SECCLASS_DRAWABLE, DRAWABLE__DRAW);
-	break;
-
-    /* Pixmap class control requirements */
-    case X_CreatePixmap:
-	rval = IDPERM(client, xCreatePixmapReq, pid,
-		      SECCLASS_DRAWABLE, DRAWABLE__CREATE);
-	break;
-    case X_FreePixmap:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_DRAWABLE, DRAWABLE__DESTROY);
-	break;
-
-    /* Cursor class control requirements */
-    case X_CreateCursor:
-	rval = IDPERM(client, xCreateCursorReq, cid,
-		      SECCLASS_CURSOR, CURSOR__CREATE);
-	rval2 = IDPERM(client, xCreateCursorReq, source,
-		       SECCLASS_DRAWABLE, DRAWABLE__DRAW);
-	rval3 = IDPERM(client, xCreateCursorReq, mask,
-		       SECCLASS_DRAWABLE, DRAWABLE__COPY);
-	break;
-    case X_CreateGlyphCursor:
-	rval = IDPERM(client, xCreateGlyphCursorReq, cid,
-		      SECCLASS_CURSOR, CURSOR__CREATEGLYPH);
-	rval2 = IDPERM(client, xCreateGlyphCursorReq, source,
-		       SECCLASS_FONT, FONT__USE);
-	rval3 = IDPERM(client, xCreateGlyphCursorReq, mask,
-		       SECCLASS_FONT, FONT__USE);
-	break;
-    case X_RecolorCursor:
-	rval = IDPERM(client, xRecolorCursorReq, cursor,
-		      SECCLASS_CURSOR, CURSOR__SETATTR);
-	break;
-    case X_FreeCursor:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_CURSOR, CURSOR__FREE);
-	break;
-
-    /* GC class control requirements */
-    case X_CreateGC:
-	rval = IDPERM(client, xCreateGCReq, gc,
-		      SECCLASS_GC, GC__CREATE | GC__SETATTR);
-	break;
-    case X_ChangeGC:
-    case X_SetDashes:
-    case X_SetClipRectangles:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_GC, GC__SETATTR);
-	break;
-    case X_CopyGC:
-	rval = IDPERM(client, xCopyGCReq, srcGC,
-		      SECCLASS_GC, GC__GETATTR);
-	rval2 = IDPERM(client, xCopyGCReq, dstGC,
-		       SECCLASS_GC, GC__SETATTR);
-	break;
-    case X_FreeGC:
-	rval = IDPERM(client, xResourceReq, id,
-		      SECCLASS_GC, GC__FREE);
-	break;
-
-    /* Server class control requirements */
-    case X_GrabServer:
-	rval = ServerPerm(client, SECCLASS_XSERVER, XSERVER__GRAB);
-	break;
-    case X_UngrabServer:
-	rval = ServerPerm(client, SECCLASS_XSERVER, XSERVER__UNGRAB);
-	break;
-    case X_ForceScreenSaver:
-    case X_GetScreenSaver:
-    case X_SetScreenSaver:
-	rval = ServerPerm(client, SECCLASS_XSERVER, XSERVER__SCREENSAVER);
-	break;
-    case X_ListHosts:
-	rval = ServerPerm(client, SECCLASS_XSERVER, XSERVER__GETHOSTLIST);
-	break;
-    case X_ChangeHosts:
-    case X_SetAccessControl:
-	rval = ServerPerm(client, SECCLASS_XSERVER, XSERVER__SETHOSTLIST);
-	break;
-    case X_GetFontPath:
-	rval = ServerPerm(client, SECCLASS_XSERVER, XSERVER__GETFONTPATH);
-	break;
-    case X_SetFontPath:
-	rval = ServerPerm(client, SECCLASS_XSERVER, XSERVER__SETFONTPATH);
-	break;
-    case X_QueryBestSize:
-	rval = ServerPerm(client, SECCLASS_XSERVER, XSERVER__GETATTR);
-	break;
-
-    default:
-	break;
-    }
-    if (rval != Success)
-	rec->status = rval;
-    if (rval2 != Success)
-	rec->status = rval2;
-    if (rval != Success)
-	rec->status = rval3;
+    XaceServerAccessRec *rec = calldata;
+    SELinuxStateRec *obj;
+    SELinuxAuditRec auditdata = { NULL, NULL, 0, 0, 0, NULL };
+    int rc;
+
+    obj = dixLookupPrivate(&serverClient->devPrivates, stateKey);
+
+    rc = SELinuxDoCheck(rec->client, obj, SECCLASS_X_SERVER,
+			rec->access_mode, &auditdata);
+    if (rc != Success)
+	rec->status = rc;
 }
 
+/* Extension callbacks */
 static void
-XSELinuxExtDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxStateInit(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 {
-    XaceExtAccessRec *rec = (XaceExtAccessRec*)calldata;
-    ClientPtr client = rec->client;
-    ExtensionEntry *ext = rec->ext;
-    security_id_t extsid;
-    access_vector_t perm;
-    REQUEST(xReq);
+    PrivateCallbackRec *rec = calldata;
+    SELinuxStateRec *state = *rec->value;
 
-    /* XXX there should be a separate callback for this */
-    if (!EXTENSIONSID(ext))
-    {
-	extsid = GetExtensionSID(ext->name);
-	if (!extsid)
-	    return;
-	EXTENSIONSID(ext) = extsid;
-    }
+    sidget(unlabeled_sid);
+    state->sid = unlabeled_sid;
 
-    extsid = (security_id_t)EXTENSIONSID(ext);
-    perm = ((stuff->reqType == X_QueryExtension) ||
-	    (stuff->reqType == X_ListExtensions)) ?
-	XEXTENSION__QUERY : XEXTENSION__USE;
-
-    if (HAVESTATE(client))
-    {
-	XSELinuxAuditRec auditdata;
-	auditdata.client = client;
-	auditdata.property = NULL;
-	auditdata.extension = ext->name;
-	errno = 0;
-	if (avc_has_perm(SID(client), extsid, SECCLASS_XEXTENSION,
-			 perm, &AEREF(client), &auditdata) < 0)
-	{
-	    if (errno == EACCES)
-		rec->status = BadAccess;
-	    ErrorF("ExtDispatch: unexpected error %d\n", errno);
-	    rec->status = BadValue;
-	}
-    } else
-	ErrorF("No client state in extension dispatcher!\n");
-} /* XSELinuxExtDispatch */
+    avc_entry_ref_init(&state->aeref);
+}
 
 static void
-XSELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxStateFree(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 {
-    XacePropertyAccessRec *rec = (XacePropertyAccessRec*)calldata;
-    WindowPtr pWin = rec->pWin;
-    ClientPtr client = rec->client;
-    ClientPtr tclient;
-    access_vector_t perm = 0;
-    security_id_t propsid;
-    char *propname = NameForAtom(rec->pProp->propertyName);
-
-    tclient = wClient(pWin);
-    if (!tclient || !HAVESTATE(tclient))
-        return;
+    PrivateCallbackRec *rec = calldata;
+    SELinuxStateRec *state = *rec->value;
 
-    propsid = GetPropertySID(SID(tclient)->ctx, propname);
-    if (!propsid)
-	return;
-
-    if (rec->access_mode & DixReadAccess)
-	perm |= PROPERTY__READ;
-    if (rec->access_mode & DixWriteAccess)
-	perm |= PROPERTY__WRITE;
-    if (rec->access_mode & DixDestroyAccess)
-	perm |= PROPERTY__FREE;
-    if (!rec->access_mode)
-	perm = PROPERTY__READ | PROPERTY__WRITE | PROPERTY__FREE;
-
-    if (HAVESTATE(client))
-    {
-	XSELinuxAuditRec auditdata;
-	auditdata.client = client;
-	auditdata.property = propname;
-	auditdata.extension = NULL;
-	errno = 0;
-	if (avc_has_perm(SID(client), propsid, SECCLASS_PROPERTY,
-			 perm, &AEREF(client), &auditdata) < 0)
-	{
-	    if (errno == EACCES)
-		rec->status = BadAccess;
-	    ErrorF("Property: unexpected error %d\n", errno);
-	    rec->status = BadValue;
-	}
-    } else
-	ErrorF("No client state in property callback!\n");
+    xfree(state->client_path);
 
-    /* XXX this should be saved in the property structure */
-    sidput(propsid);
-} /* XSELinuxProperty */
+    if (avc_active)
+	sidput(state->sid);
+}
 
 static void
-XSELinuxResLookup(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 {
-    XaceResourceAccessRec *rec = (XaceResourceAccessRec*)calldata;
-    ClientPtr client = rec->client;
-    REQUEST(xReq);
-    access_vector_t perm = 0;
-    int rval = Success;
+    NewClientInfoRec *pci = calldata;
+    ClientPtr client = pci->client;
+    XtransConnInfo ci = ((OsCommPtr)client->osPrivate)->trans_conn;
+    SELinuxStateRec *state;
+    security_context_t ctx;
 
-    /* serverClient requests OK */
-    if (client->index == 0)
+    if (client->clientState != ClientStateInitial)
 	return;
 
-    switch(rec->rtype) {
-	case RT_FONT: {
-	    switch(stuff->reqType) {
-		case X_ImageText8:
-		case X_ImageText16:
-		case X_PolyText8:
-		case X_PolyText16:
-		    perm = FONT__USE;
-		    break;
-		case X_ListFonts:
-		case X_ListFontsWithInfo:
-		case X_QueryFont:
-		case X_QueryTextExtents:
-		    perm = FONT__GETATTR;
-		    break;
-		default:
-		    break;
-	    }
-	    if (perm)
-		rval = IDPerm(client, rec->id, SECCLASS_FONT, perm);
-	    break;
-	}
-	default:
-	    break;
-    }
-    if (rval != Success)
-	rec->status = rval;
-} /* XSELinuxResLookup */
+    state = dixLookupPrivate(&client->devPrivates, stateKey);
+    sidput(state->sid);
 
-static void
-XSELinuxMap(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
-    XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata;
-    if (IDPerm(rec->client, rec->pWin->drawable.id,
-               SECCLASS_WINDOW, WINDOW__MAP) != Success)
-	rec->status = BadAccess;
-} /* XSELinuxMap */
+    if (_XSERVTransIsLocal(ci)) {
+	int fd = _XSERVTransGetConnectionNumber(ci);
+	struct ucred creds;
+	socklen_t len = sizeof(creds);
+	char path[PATH_MAX + 1];
+	size_t bytes;
 
-static void
-XSELinuxDrawable(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
-    XaceDrawableAccessRec *rec = (XaceDrawableAccessRec*)calldata;
-    if (IDPerm(rec->client, rec->pDraw->id,
-               SECCLASS_DRAWABLE, DRAWABLE__COPY) != Success)
-	rec->status = BadAccess;
-} /* XSELinuxDrawable */
+	/* For local clients, can get context from the socket */
+	if (getpeercon(fd, &ctx) < 0)
+	    FatalError("Client %d: couldn't get context from socket\n",
+		       client->index);
 
-static void
-XSELinuxServer(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
-    XaceServerAccessRec *rec = (XaceServerAccessRec*)calldata;
-    access_vector_t perm = (rec->access_mode == DixReadAccess) ?
-	XSERVER__GETHOSTLIST : XSERVER__SETHOSTLIST;
+	/* Try and determine the client's executable name */
+	memset(&creds, 0, sizeof(creds));
+	if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &creds, &len) < 0)
+	    goto finish;
 
-    if (ServerPerm(rec->client, SECCLASS_XSERVER, perm) != Success)
-	rec->status = BadAccess;
-} /* XSELinuxServer */
+	snprintf(path, PATH_MAX + 1, "/proc/%d/cmdline", creds.pid);
+	fd = open(path, O_RDONLY);
+	if (fd < 0)
+	    goto finish;
 
-/* Extension callbacks */
-static void
-XSELinuxClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
-    NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
-    ClientPtr client = pci->client;
+	bytes = read(fd, path, PATH_MAX + 1);
+	close(fd);
+	if (bytes <= 0)
+	    goto finish;
 
-    switch(client->clientState)
-    {
-    case ClientStateInitial:
-	AssignServerState();
-	break;
+	state->client_path = xalloc(bytes);
+	if (!state->client_path)
+	    goto finish;
 
-	case ClientStateRunning:
-	{
-	    AssignClientState(client);
-	    break;
-	}
-	case ClientStateGone:
-	case ClientStateRetained:
-	{
-	    FreeClientState(client);
-	    break;
-	}
-	default: break;
-    }
-} /* XSELinuxClientState */
+	memcpy(state->client_path, path, bytes);
+	state->client_path[bytes - 1] = 0;
+    } else
+	/* For remote clients, need to use a default context */
+	if (selabel_lookup(label_hnd, &ctx, NULL, SELABEL_X_CLIENT) < 0)
+	    FatalError("Client %d: couldn't get default remote context\n",
+		       client->index);
+
+finish:
+    /* Get a SID from the context */
+    if (avc_context_to_sid(ctx, &state->sid) < 0)
+	FatalError("Client %d: context_to_sid(%s) failed\n",
+		   client->index, ctx);
+
+    freecon(ctx);
+}
 
 /* Labeling callbacks */
 static void
-XSELinuxResourceState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxResourceState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 {
-    ResourceStateInfoRec *rec = (ResourceStateInfoRec *)calldata;
+    ResourceStateInfoRec *rec = calldata;
+    SELinuxStateRec *state;
     WindowPtr pWin;
-    ClientPtr client;
-    security_context_t ctx;
-    int rc;
 
     if (rec->type != RT_WINDOW)
 	return;
 
     pWin = (WindowPtr)rec->value;
-    client = wClient(pWin);
+    state = dixLookupPrivate(&wClient(pWin)->devPrivates, stateKey);
 
-    if (HAVESTATE(client)) {
-	rc = avc_sid_to_context(SID(client), &ctx);
+    if (state->sid) {
+	security_context_t ctx;
+	int rc = avc_sid_to_context(state->sid, &ctx);
 	if (rc < 0)
 	    FatalError("XSELinux: Failed to get security context!\n");
 	rc = dixChangeWindowProperty(serverClient,
 				     pWin, atom_client_ctx, XA_STRING, 8,
 				     PropModeReplace, strlen(ctx), ctx, FALSE);
+	if (rc != Success)
+	    FatalError("XSELinux: Failed to set label property on window!\n");
 	freecon(ctx);
     }
     else
-	rc = dixChangeWindowProperty(serverClient,
-				     pWin, atom_client_ctx, XA_STRING, 8,
-				     PropModeReplace, 10, "UNLABELED!", FALSE);
-    if (rc != Success)
-	FatalError("XSELinux: Failed to set context property on window!\n");
-} /* XSELinuxResourceState */
-
-static Bool
-XSELinuxLoadConfigFile(void)
-{
-    struct selinux_opt options[] = {
-	{ SELABEL_OPT_PATH, XSELINUXCONFIGFILE },
-	{ SELABEL_OPT_VALIDATE, (char *)1 },
-    };
-
-    if (!XSELINUXCONFIGFILE)
-        return FALSE;
+	FatalError("XSELinux: Unexpected unlabeled client found\n");
 
-    label_hnd = selabel_open(SELABEL_CTX_X, options, 2);
-    return !!label_hnd;
-} /* XSELinuxLoadConfigFile */
+    state = dixLookupPrivate(&pWin->devPrivates, stateKey);
 
-static void
-XSELinuxFreeConfigData(void)
-{
-    selabel_close(label_hnd);
-    label_hnd = NULL;
-} /* XSELinuxFreeConfigData */
+    if (state->sid) {
+	security_context_t ctx;
+	int rc = avc_sid_to_context(state->sid, &ctx);
+	if (rc < 0)
+	    FatalError("XSELinux: Failed to get security context!\n");
+	rc = dixChangeWindowProperty(serverClient,
+				     pWin, atom_ctx, XA_STRING, 8,
+				     PropModeReplace, strlen(ctx), ctx, FALSE);
+	if (rc != Success)
+	    FatalError("XSELinux: Failed to set label property on window!\n");
+	freecon(ctx);
+    }
+    else
+	FatalError("XSELinux: Unexpected unlabeled window found\n");
+}
 
 /* Extension dispatch functions */
 static int
-ProcXSELinuxDispatch(ClientPtr client)
+ProcSELinuxDispatch(ClientPtr client)
 {
     return BadRequest;
-} /* ProcXSELinuxDispatch */
+}
 
 static void
-XSELinuxResetProc(ExtensionEntry *extEntry)
+SELinuxResetProc(ExtensionEntry *extEntry)
 {
-    FreeClientState(serverClient);
+    /* XXX unregister all callbacks here */
 
-    XSELinuxFreeConfigData();
+    selabel_close(label_hnd);
+    label_hnd = NULL;
 
     audit_close(audit_fd);
 
     avc_destroy();
-} /* XSELinuxResetProc */
+    avc_active = 0;
 
-static void
-XSELinuxAVCAudit(void *auditdata,
-		 security_class_t class,
-		 char *msgbuf,
-		 size_t msgbufsize)
+    xfree(knownTypes);
+    knownTypes = NULL;
+    numKnownTypes = 0;
+}
+
+static int
+SELinuxAudit(void *auditdata,
+	     security_class_t class,
+	     char *msgbuf,
+	     size_t msgbufsize)
 {
-    XSELinuxAuditRec *audit = (XSELinuxAuditRec*)auditdata;
+    SELinuxAuditRec *audit = auditdata;
     ClientPtr client = audit->client;
-    char requestNum[8];
+    char idNum[16], *propertyName;
+    int major = 0, minor = 0;
     REQUEST(xReq);
 
-    if (stuff)
-	snprintf(requestNum, 8, "%d", stuff->reqType);
+    if (audit->id)
+	snprintf(idNum, 16, "%x", audit->id);
+    if (stuff) {
+	major = stuff->reqType;
+	minor = (major < 128) ? 0 : MinorOpcodeOfRequest(client);
+    }
 
-    snprintf(msgbuf, msgbufsize, "%s%s%s%s%s%s",
-	     stuff ? "request=" : "",
-	     stuff ? requestNum : "",
-	     audit->property ? " property=" : "",
-	     audit->property ? audit->property : "",
-	     audit->extension ? " extension=" : "",
-	     audit->extension ? audit->extension : "");
+    propertyName = audit->property ? NameForAtom(audit->property) : NULL;
+
+    return snprintf(msgbuf, msgbufsize, "%s%s%s%s%s%s%s%s%s%s%s%s",
+		    stuff ? "request=" : "",
+		    stuff ? LookupRequestName(major, minor) : "",
+		    audit->client_path ? " client=" : "",
+		    audit->client_path ? audit->client_path : "",
+		    audit->id ? " resid=" : "",
+		    audit->id ? idNum : "",
+		    audit->restype ? " restype=" : "",
+		    audit->restype ? LookupResourceName(audit->restype) : "",
+		    audit->property ? " property=" : "",
+		    audit->property ? propertyName : "",
+		    audit->extension ? " extension=" : "",
+		    audit->extension ? audit->extension : "");
 }
 
-static void
-XSELinuxAVCLog(const char *fmt, ...)
+static int
+SELinuxLog(int type, const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
     VErrorF(fmt, ap);
     va_end(ap);
+    return 0;
 }
 
-/* XSELinuxExtensionSetup
- *
- * Set up the XSELinux Extension (pre-init)
- */
-void
-XSELinuxExtensionSetup(INITARGS)
+static void
+SELinuxFixupLabels(void)
 {
-    /* Allocate the client private index */
-    clientPrivateIndex = AllocateClientPrivateIndex();
-    if (!AllocateClientPrivate(clientPrivateIndex,
-			       sizeof (XSELinuxClientStateRec)))
-	FatalError("XSELinux: Failed to allocate client private.\n");
-
-    /* Allocate the extension private index */
-    extnsnPrivateIndex = AllocateExtensionPrivateIndex();
-    if (!AllocateExtensionPrivate(extnsnPrivateIndex, 0))
-	FatalError("XSELinux: Failed to allocate extension private.\n");
+    int i;
+    XaceScreenAccessRec srec;
+    SELinuxStateRec *state;
+    security_context_t ctx;
+    pointer unused;
+
+    /* Do the serverClient */
+    state = dixLookupPrivate(&serverClient->devPrivates, stateKey);
+    sidput(state->sid);
+
+    /* Use the context of the X server process for the serverClient */
+    if (getcon(&ctx) < 0)
+	FatalError("Couldn't get context of X server process\n");
+
+    /* Get a SID from the context */
+    if (avc_context_to_sid(ctx, &state->sid) < 0)
+	FatalError("serverClient: context_to_sid(%s) failed\n", ctx);
+
+    freecon(ctx);
+
+    srec.client = serverClient;
+    srec.access_mode = DixCreateAccess;
+    srec.status = Success;
+
+    for (i = 0; i < screenInfo.numScreens; i++) {
+	/* Do the screen object */
+	srec.screen = screenInfo.screens[i];
+	SELinuxScreen(NULL, NULL, &srec);
+
+	/* Do the default colormap */
+	dixLookupResource(&unused, screenInfo.screens[i]->defColormap,
+			  RT_COLORMAP, serverClient, DixCreateAccess);
+    }
 }
 
-/* XSELinuxExtensionInit
- *
- * Initialize the XSELinux Extension
- */
 void
 XSELinuxExtensionInit(INITARGS)
 {
-    ExtensionEntry	*extEntry;
-    struct avc_log_callback alc = {XSELinuxAVCLog, XSELinuxAVCAudit};
+    ExtensionEntry *extEntry;
+    struct selinux_opt options[] = { { SELABEL_OPT_VALIDATE, (char *)1 } };
+    security_context_t con;
+    int ret = TRUE;
 
-    if (!is_selinux_enabled())
-    {
+    /* Setup SELinux stuff */
+    if (!is_selinux_enabled()) {
         ErrorF("XSELinux: Extension failed to load: SELinux not enabled\n");
         return;
     }
 
-    if (selinux_set_mapping(map) < 0) {
+    selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback)SELinuxLog);
+    selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback)SELinuxAudit);
+
+    if (selinux_set_mapping(map) < 0)
 	FatalError("XSELinux: Failed to set up security class mapping\n");
-    }
 
-    if (avc_init("xserver", NULL, &alc, NULL, NULL) < 0)
-    {
+    if (avc_open(NULL, 0) < 0)
 	FatalError("XSELinux: Couldn't initialize SELinux userspace AVC\n");
-    }
+    avc_active = 1;
 
-    if (!AddCallback(&ClientStateCallback, XSELinuxClientState, NULL))
-	return;
-    if (!AddCallback(&ResourceStateCallback, XSELinuxResourceState, NULL))
-	return;
+    label_hnd = selabel_open(SELABEL_CTX_X, options, 1);
+    if (!label_hnd)
+	FatalError("XSELinux: Failed to open x_contexts mapping in policy\n");
+
+    if (security_get_initial_context("unlabeled", &con) < 0)
+	FatalError("XSELinux: Failed to look up unlabeled context\n");
+    if (avc_context_to_sid(con, &unlabeled_sid) < 0)
+	FatalError("XSELinux: a context_to_SID call failed!\n");
+    freecon(con);
+
+    /* Prepare for auditing */
+    audit_fd = audit_open();
+    if (audit_fd < 0)
+        FatalError("XSELinux: Failed to open the system audit log\n");
+
+    /* Allocate private storage */
+    if (!dixRequestPrivate(stateKey, sizeof(SELinuxStateRec)))
+	FatalError("XSELinux: Failed to allocate private storage.\n");
 
     /* Create atoms for doing window labeling */
-    atom_ctx = MakeAtom("_SELINUX_CONTEXT", 16, 1);
+    atom_ctx = MakeAtom("_SELINUX_CONTEXT", 16, TRUE);
     if (atom_ctx == BAD_RESOURCE)
 	FatalError("XSELinux: Failed to create atom\n");
-    atom_client_ctx = MakeAtom("_SELINUX_CLIENT_CONTEXT", 23, 1);
+    atom_client_ctx = MakeAtom("_SELINUX_CLIENT_CONTEXT", 23, TRUE);
     if (atom_client_ctx == BAD_RESOURCE)
 	FatalError("XSELinux: Failed to create atom\n");
 
-    /* Load the config file.  If this fails, shut down the server,
-     * since an unknown security status is worse than no security.
-     */
-    if (XSELinuxLoadConfigFile() != TRUE)
-    {
-	FatalError("XSELinux: Failed to load security policy\n");
-    }
-
-    /* prepare for auditing */
-    audit_fd = audit_open();
-    if (audit_fd < 0)
-    {
-        FatalError("XSELinux: Failed to open the system audit log\n");
-    }
-
-    /* register security callbacks */
-    XaceRegisterCallback(XACE_CORE_DISPATCH, XSELinuxCoreDispatch, NULL);
-    XaceRegisterCallback(XACE_EXT_ACCESS, XSELinuxExtDispatch, NULL);
-    XaceRegisterCallback(XACE_EXT_DISPATCH, XSELinuxExtDispatch, NULL);
-    XaceRegisterCallback(XACE_RESOURCE_ACCESS, XSELinuxResLookup, NULL);
-    XaceRegisterCallback(XACE_MAP_ACCESS, XSELinuxMap, NULL);
-    XaceRegisterCallback(XACE_SERVER_ACCESS, XSELinuxServer, NULL);
-    XaceRegisterCallback(XACE_PROPERTY_ACCESS, XSELinuxProperty, NULL);
-    /* XaceRegisterCallback(XACE_DECLARE_EXT_SECURE, XSELinuxDeclare, NULL);
-    XaceRegisterCallback(XACE_DEVICE_ACCESS, XSELinuxDevice, NULL); */
-
-    /* register extension with server */
+    /* Register callbacks */
+    ret &= dixRegisterPrivateInitFunc(stateKey, SELinuxStateInit, NULL);
+    ret &= dixRegisterPrivateDeleteFunc(stateKey, SELinuxStateFree, NULL);
+
+    ret &= AddCallback(&ClientStateCallback, SELinuxClientState, 0);
+    ret &= AddCallback(&ResourceStateCallback, SELinuxResourceState, 0);
+
+    ret &= XaceRegisterCallback(XACE_EXT_DISPATCH, SELinuxExtension, 0);
+    ret &= XaceRegisterCallback(XACE_RESOURCE_ACCESS, SELinuxResource, 0);
+//    ret &= XaceRegisterCallback(XACE_DEVICE_ACCESS, SELinuxDevice, 0);
+    ret &= XaceRegisterCallback(XACE_PROPERTY_ACCESS, SELinuxProperty, 0);
+//    ret &= XaceRegisterCallback(XACE_SEND_ACCESS, SELinuxSend, 0);
+//    ret &= XaceRegisterCallback(XACE_RECEIVE_ACCESS, SELinuxReceive, 0);
+    ret &= XaceRegisterCallback(XACE_CLIENT_ACCESS, SELinuxClient, 0);
+    ret &= XaceRegisterCallback(XACE_EXT_ACCESS, SELinuxExtension, 0);
+    ret &= XaceRegisterCallback(XACE_SERVER_ACCESS, SELinuxServer, 0);
+//    ret &= XaceRegisterCallback(XACE_SELECTION_ACCESS, SELinuxSelection, 0);
+    ret &= XaceRegisterCallback(XACE_SCREEN_ACCESS, SELinuxScreen, 0);
+    ret &= XaceRegisterCallback(XACE_SCREENSAVER_ACCESS, SELinuxScreen, &ret);
+    if (!ret)
+	FatalError("XSELinux: Failed to register one or more callbacks\n");
+
+    /* Add extension to server */
     extEntry = AddExtension(XSELINUX_EXTENSION_NAME,
 			    XSELinuxNumberEvents, XSELinuxNumberErrors,
-			    ProcXSELinuxDispatch, ProcXSELinuxDispatch,
-			    XSELinuxResetProc, StandardMinorOpcode);
+			    ProcSELinuxDispatch, ProcSELinuxDispatch,
+			    SELinuxResetProc, StandardMinorOpcode);
+
+    /* Label objects that were created before we could register ourself */
+    SELinuxFixupLabels();
 }
diff --git a/Xext/xselinux.h b/Xext/xselinux.h
index 57fcbb2..02ec86b 100644
--- a/Xext/xselinux.h
+++ b/Xext/xselinux.h
@@ -20,6 +20,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #ifndef _XSELINUX_H
 #define _XSELINUX_H
 
+#include "dixaccess.h"
+
 /* Extension info */
 #define XSELINUX_EXTENSION_NAME		"SELinux"
 #define XSELINUX_MAJOR_VERSION		1
@@ -28,95 +30,18 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define XSELinuxNumberErrors		0
 
 /* Private Flask definitions */
-#define SECCLASS_DRAWABLE		1
-#define DRAWABLE__CREATE		0x00000001UL
-#define DRAWABLE__DESTROY		0x00000002UL
-#define DRAWABLE__DRAW			0x00000004UL
-#define DRAWABLE__COPY			0x00000008UL
-#define DRAWABLE__GETATTR		0x00000010UL
-#define SECCLASS_WINDOW			2
-#define WINDOW__ADDCHILD		0x00000001UL
-#define WINDOW__CREATE			0x00000002UL
-#define WINDOW__DESTROY			0x00000004UL
-#define WINDOW__MAP			0x00000008UL
-#define WINDOW__UNMAP			0x00000010UL
-#define WINDOW__CHSTACK			0x00000020UL
-#define WINDOW__CHPROPLIST		0x00000040UL
-#define WINDOW__CHPROP			0x00000080UL
-#define WINDOW__LISTPROP		0x00000100UL
-#define WINDOW__GETATTR			0x00000200UL
-#define WINDOW__SETATTR			0x00000400UL
-#define WINDOW__SETFOCUS		0x00000800UL
-#define WINDOW__MOVE			0x00001000UL
-#define WINDOW__CHSELECTION		0x00002000UL
-#define WINDOW__CHPARENT		0x00004000UL
-#define WINDOW__CTRLLIFE		0x00008000UL
-#define WINDOW__ENUMERATE		0x00010000UL
-#define WINDOW__TRANSPARENT		0x00020000UL
-#define WINDOW__MOUSEMOTION		0x00040000UL
-#define WINDOW__CLIENTCOMEVENT		0x00080000UL
-#define WINDOW__INPUTEVENT		0x00100000UL
-#define WINDOW__DRAWEVENT		0x00200000UL
-#define WINDOW__WINDOWCHANGEEVENT	0x00400000UL
-#define WINDOW__WINDOWCHANGEREQUEST	0x00800000UL
-#define WINDOW__SERVERCHANGEEVENT	0x01000000UL
-#define WINDOW__EXTENSIONEVENT		0x02000000UL
-#define SECCLASS_GC			3
-#define GC__CREATE			0x00000001UL
-#define GC__FREE			0x00000002UL
-#define GC__GETATTR			0x00000004UL
-#define GC__SETATTR			0x00000008UL
-#define SECCLASS_FONT			4
-#define FONT__LOAD			0x00000001UL
-#define FONT__FREE			0x00000002UL
-#define FONT__GETATTR			0x00000004UL
-#define FONT__USE			0x00000008UL
-#define SECCLASS_COLORMAP		5
-#define COLORMAP__CREATE		0x00000001UL
-#define COLORMAP__FREE			0x00000002UL
-#define COLORMAP__INSTALL		0x00000004UL
-#define COLORMAP__UNINSTALL		0x00000008UL
-#define COLORMAP__LIST			0x00000010UL
-#define COLORMAP__READ			0x00000020UL
-#define COLORMAP__STORE			0x00000040UL
-#define COLORMAP__GETATTR		0x00000080UL
-#define COLORMAP__SETATTR		0x00000100UL
-#define SECCLASS_PROPERTY		6
-#define PROPERTY__CREATE		0x00000001UL
-#define PROPERTY__FREE			0x00000002UL
-#define PROPERTY__READ			0x00000004UL
-#define PROPERTY__WRITE			0x00000008UL
-#define SECCLASS_CURSOR			7
-#define CURSOR__CREATE			0x00000001UL
-#define CURSOR__CREATEGLYPH		0x00000002UL
-#define CURSOR__FREE			0x00000004UL
-#define CURSOR__ASSIGN			0x00000008UL
-#define CURSOR__SETATTR			0x00000010UL
-#define SECCLASS_XCLIENT		8
-#define XCLIENT__KILL			0x00000001UL
-#define SECCLASS_XINPUT			9
-#define XINPUT__LOOKUP			0x00000001UL
-#define XINPUT__GETATTR			0x00000002UL
-#define XINPUT__SETATTR			0x00000004UL
-#define XINPUT__SETFOCUS		0x00000008UL
-#define XINPUT__WARPPOINTER		0x00000010UL
-#define XINPUT__ACTIVEGRAB		0x00000020UL
-#define XINPUT__PASSIVEGRAB		0x00000040UL
-#define XINPUT__UNGRAB			0x00000080UL
-#define XINPUT__BELL			0x00000100UL
-#define XINPUT__MOUSEMOTION		0x00000200UL
-#define XINPUT__RELABELINPUT		0x00000400UL
-#define SECCLASS_XSERVER		10
-#define XSERVER__SCREENSAVER		0x00000001UL
-#define XSERVER__GETHOSTLIST		0x00000002UL
-#define XSERVER__SETHOSTLIST		0x00000004UL
-#define XSERVER__GETFONTPATH		0x00000008UL
-#define XSERVER__SETFONTPATH		0x00000010UL
-#define XSERVER__GETATTR		0x00000020UL
-#define XSERVER__GRAB			0x00000040UL
-#define XSERVER__UNGRAB			0x00000080UL
-#define SECCLASS_XEXTENSION		11
-#define XEXTENSION__QUERY		0x00000001UL
-#define XEXTENSION__USE			0x00000002UL
+#define SECCLASS_X_DRAWABLE		1
+#define SECCLASS_X_SCREEN		2
+#define SECCLASS_X_GC			3
+#define SECCLASS_X_FONT			4
+#define SECCLASS_X_COLORMAP		5
+#define SECCLASS_X_PROPERTY		6
+#define SECCLASS_X_SELECTION		7
+#define SECCLASS_X_CURSOR		8
+#define SECCLASS_X_CLIENT		9
+#define SECCLASS_X_DEVICE		10
+#define SECCLASS_X_SERVER		11
+#define SECCLASS_X_EXTENSION		12
+#define SECCLASS_X_RESOURCE		13
 
 #endif /* _XSELINUX_H */
diff --git a/configure.ac b/configure.ac
index e73e250..8901fae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -511,7 +511,7 @@ AC_ARG_ENABLE(xinerama,	      AS_HELP_STRING([--disable-xinerama], [Build Xinera
 AC_ARG_ENABLE(xf86vidmode,    AS_HELP_STRING([--disable-xf86vidmode], [Build XF86VidMode extension (default: auto)]), [XF86VIDMODE=$enableval], [XF86VIDMODE=auto])
 AC_ARG_ENABLE(xf86misc,       AS_HELP_STRING([--disable-xf86misc], [Build XF86Misc extension (default: auto)]), [XF86MISC=$enableval], [XF86MISC=auto])
 AC_ARG_ENABLE(xace,           AS_HELP_STRING([--disable-xace], [Build X-ACE extension (default: enabled)]), [XACE=$enableval], [XACE=yes])
-AC_ARG_ENABLE(xselinux,       AS_HELP_STRING([--disable-xselinux], [Build SELinux extension (TEMPORARILY DISABLED)]), [XSELINUX=no], [XSELINUX=no])
+AC_ARG_ENABLE(xselinux,       AS_HELP_STRING([--disable-xselinux], [Build SELinux extension (default: disabled)]), [XSELINUX=$enableval], [XSELINUX=no])
 AC_ARG_ENABLE(xcsecurity,     AS_HELP_STRING([--disable-xcsecurity], [Build Security extension (TEMPORARILY DISABLED)]), [XCSECURITY=no], [XCSECURITY=no])
 AC_ARG_ENABLE(appgroup,       AS_HELP_STRING([--disable-appgroup], [Build XC-APPGROUP extension (default: enabled)]), [APPGROUP=$enableval], [APPGROUP=$XCSECURITY])
 AC_ARG_ENABLE(xcalibrate,     AS_HELP_STRING([--enable-xcalibrate], [Build XCalibrate extension (default: disabled)]), [XCALIBRATE=$enableval], [XCALIBRATE=no])
diff --git a/hw/xfree86/dixmods/extmod/modinit.h b/hw/xfree86/dixmods/extmod/modinit.h
index fb75092..191b3ef 100644
--- a/hw/xfree86/dixmods/extmod/modinit.h
+++ b/hw/xfree86/dixmods/extmod/modinit.h
@@ -130,7 +130,6 @@ extern void XaceExtensionInit(INITARGS);
 #endif
 
 #ifdef XSELINUX
-extern void XSELinuxExtensionSetup(INITARGS);
 extern void XSELinuxExtensionInit(INITARGS);
 #endif
 
diff --git a/mi/miinitext.c b/mi/miinitext.c
index 964ef3e..2540975 100644
--- a/mi/miinitext.c
+++ b/mi/miinitext.c
@@ -324,7 +324,6 @@ extern void XaceExtensionInit(INITARGS);
 extern void SecurityExtensionInit(INITARGS);
 #endif
 #ifdef XSELINUX
-extern void XSELinuxExtensionSetup(INITARGS);
 extern void XSELinuxExtensionInit(INITARGS);
 #endif
 #ifdef XPRINT
@@ -537,9 +536,6 @@ InitExtensions(argc, argv)
     int		argc;
     char	*argv[];
 {
-#ifdef XSELINUX
-    XSELinuxExtensionSetup();
-#endif
 #ifdef PANORAMIX
 # if !defined(PRINT_ONLY_SERVER) && !defined(NO_PANORAMIX)
   if (!noPanoramiXExtension) PanoramiXExtensionInit();
@@ -718,7 +714,7 @@ static ExtensionModule staticExtensions[] = {
     { SecurityExtensionInit, SECURITY_EXTENSION_NAME, &noSecurityExtension, NULL, NULL },
 #endif
 #ifdef XSELINUX
-    { XSELinuxExtensionInit, XSELINUX_EXTENSION_NAME, NULL, XSELinuxExtensionSetup, NULL },
+    { XSELinuxExtensionInit, XSELINUX_EXTENSION_NAME, NULL, NULL, NULL },
 #endif
 #ifdef XPRINT
     { XpExtensionInit, XP_PRINTNAME, NULL, NULL, NULL },


More information about the xorg-commit mailing list