X Access Control Extension Specification

   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 AUTHOR 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 OF OR OTHER DEALINGS IN
   THE SOFTWARE.

                              Abstract

      The X Access Control Extension (XACE) is a set of generic
      "hooks" that can be used by other X extensions to perform
    access checks. The goal of XACE is to prevent clutter in the
     core dix/os code by providing a common mechanism for doing
    these sorts of checks. The concept is identical to the Linux
             Security Module (LSM) in the Linux Kernel.

     XACE is a generalization of the "Security" extension, which
    provides a simple on/off trust model, with untrusted windows
   being restricted in certain areas. Most of XACE consists simply
    of replacing the Security-specific checks in the dix/os layer
   with generic callback lists. However, the framework is flexible
     enough to allow for hooks to be added or deprecated in the
                               future.

   This paper describes the implementation of XACE, changes to the
   core server DIX and OS layers that have been made or are being
   considered, and each of the security hooks that XACE offers at
      the current time and their function. It is expected that
    changes to XACE be documented here. Please notify the authors
     of this document of any changes to XACE so that they may be
                        properly documented.
           _______________________________________________

   Table of Contents
   Introduction
   Usage
   Protocol

Introduction

Prerequisites

   This document is targeted to programmers who are writing
   security extensions for X. It is assumed that the reader is
   familiar with the C programming language. It is assumed that
   the reader understands the general workings of the X protocol
   and X server. It is highly recommended that the reader review
   the specifications for the SECURITY and APPGROUP extensions.
   The relevant documents are all available in the X.Org
   documentation package.
     __________________________________________________________

Purpose

   XACE makes it easier to implement new security models for X by
   providing a set of pluggable hooks that extension writers can
   use. The idea is to provide an abstraction layer between
   security extensions and the core DIX/OS code of the X server.
   This prevents security extensions writers from having to
   understand the inner workings of the X server and it prevents X
   server maintainers from having to deal with multiple security
   subsystems, each with its own intrusive code.

   For example, consider the X.Org X server's resource subsystem,
   which is used to track different types of server objects using
   ID numbers. The act of looking up an object by its ID number is
   a security-relevant operation which security extension writers
   would likely wish to control. For one or two security
   extensions it may be acceptable to simply insert the
   extension's code directly into the resource manager code,
   bracketed by ifdef's. However for more extensions this approach
   leads to a tangle of code, particularly when results need to be
   logically combined, as in if statement conditions.
   Additionally, different extension writers might place their
   resource checking code in different places in the server,
   leading to difficulty in tracking down where exactly a
   particular lookup operation is being blocked. Finally, this
   approach may lead to unexpected interactions between the code
   of different extensions, since there is no collaboration
   between extension writers.

   The solution employed by the X Access Control Extension is to
   place hooks (calls into XACE) at security-relevant places, such
   as the resource subsystem mentioned above. Other extensions,
   typically in their initialization routines, can register
   callback functions on these hooks. When the hook is called from
   the server code, each callback function registered on it is
   called in turn. The callback function is provided with
   necessary arguments needed to make a security decision,
   including a return value argument which can be set to indicate
   the result. XACE itself does not make security decisions, or
   even know or care how such decisions are made. XACE merely
   enforces the result of the decision, such as by returning a
   BadAccess error to the requesting client.

   This separation between the decision-making logic and the
   enforcement logic is advantageous because it allows a great
   variety of security models to be developed without resorting to
   intrusive modifications to the core systems being secured. The
   challenge is to ensure that the hook framework itself provides
   hooks everywhere they need to be provided. Once created,
   however, a hook can be used by everyone, leading to less
   duplication of effort.
     __________________________________________________________

Prior Work

Security Extension

   XACE is primarily based on the SECURITY extension. This
   extension introduced the concept of "trusted" and "untrusted"
   client connections, with the trust level established by the
   authorization token used in the initial client connection.
   Untrusted clients are restricted in several areas, notably in
   the use of background "None" windows, access to server
   resources owned by trusted clients, and certain keyboard input
   operations. Server extensions are also declared "trusted" or
   "untrusted," with only untrusted extensions being visible to
   untrusted client connections.

   The primary limitation of the SECURITY extension is a lack of
   granularity. The trust level of client connections is set at
   connection time and is not changed. Creating untrusted clients
   is cumbersome since untrusted authorizations must be generated
   dynamically (they cannot be specified in the authorization file
   used by the server at startup time), and the default trusted
   behavior is not restricted in any way. The author of the
   SECURITY extension did anticipate the need for flexibility in
   some areas, but the XACE modifications introduce a much broader
   level of generalization.

   The benefit of the SECURITY extension is that its authors
   already had identified the proper places in the core X server
   code to place their trust level checks. Thus, the only thing
   that needed to be done for XACE was to swap out these checks
   for more generic XACE hooks. The SECURITY authors also
   introduced several features into the core server code, such as
   the "Security" versions of the resource lookup functions, and
   the custom ProcVectors used to dispatch client requests.

   With the introduction of XACE, the SECURITY extension has been
   rewritten to sit on top of XACE, thus maintaining backwards
   compatibility.
     __________________________________________________________

Solaris Trusted Extensions

   Trusted Extensions for Solaris has an X extension (Xtsol) which
   adds security functionality. Some of the XACE hooks in the
   current set were derived from security checks made by the Xtsol
   code. In other places, where the Xtsol and SECURITY extensions
   both have checks, a single XACE hook replaces both.
     __________________________________________________________

Linux Security Modules

   XACE is influenced by the Linux Security Modules project, which
   provides a similar framework of security hooks for the Linux
   kernel.
     __________________________________________________________

Future Work

Security Hooks

   It is anticipated that the set of security hooks provided by
   XACE will change with time. Some of the current hooks provide
   legacy functionality for the SECURITY extension and may become
   deprecated. More hooks will likely be added as well, as more
   portions of the X server are subjected to security analysis.
   Existing hooks may be added in more places in the code,
   particularly protocol extensions. Currently, the only method
   XACE provides for restricting access to protocol extensions is
   to deny access to them entirely.

   It should be noted that XACE includes hooks in the protocol
   dispatch table, which allow a security extension to examine any
   incoming protocol request (core or extension) and block the
   request before it is handled by the server (resulting in a
   BadAccess error). This functionality can be used as a stopgap
   measure for security checks that are not supported by the other
   XACE hooks. The end goal, however, is to have hooks integrated
   into the server proper, as the SECURITY extension has done.

   In the future, it may be worthwhile to integrate XACE directly
   into the X server code, removing its status as an "extension"
   (XACE defines no new protocol). This would eliminate the ifdef
   directives that bracket the XACE hooks, and would allow for
   further integration with the surrounding code. It would also
   avoid the need to use the extension loader to initialize XACE.
   The use of modern coding techniques such as static inlining
   could also be used to improve performance in the hook
   mechanism.
     __________________________________________________________

X Authentication

   The X server supports several authentication methods.
   Currently, they are implemented directly in the OS layer of the
   X server. However, with new improvements to the Pluggable
   Authentication Modules (PAM) library, it may be possible to
   move these authentication methods out of the server,
   implementing each one as a PAM module. This would separate
   security-specific code from the X server, as well allow the
   authentication code in the OS layer to be cleaned up
   significantly. However, the author has not studied the problem
   in great detail, so it's too early to tell whether this idea is
   workable.

   Another area where the X authentication code could use some
   cleanup is the SECURITY extension's "Query Security"
   authentication pseudo-method. This method is used to determine
   whether or not an X server supports certain "site policies,"
   identified via strings. This method can also be used to assert
   requirements about extension security. This part of the
   SECURITY extension was not refactored along with the rest of
   the extension as part of the XACE work. As part of the PAM
   project described above, it would be beneficial if this
   authentication method could be moved out to a PAM module or
   simply dropped. Doing this would allow the SECURITY extension
   to be loaded as a module instead of being built-in, since the
   auth code is the only remaining part of that extension that
   needs to be compiled in.
     __________________________________________________________

Core X Server

   There are some minor improvements that could be made to the
   core X server itself outside of XACE. As will be discussed,
   security extension writers are expected to use the devPrivates
   mechanism to store security state with various server object.
   This mechanism is currently duplicated for each structure type
   that supports it; it may be possible to use macros to generate
   the functions for each supported structure type, at least
   reducing the code size. This would also make it easier to
   support more structures; only a new structure field would be
   required along with slight changes to the code that allocates
   the structure. Extending devPrivates support to other
   structures, or even generic resources, would be beneficial for
   security extension writers. The feasibility of doing this
   generalization is currently being investigated by the author.
   In addition, initialization and teardown callbacks are needed
   as described in the Section called Device Privates; support for
   them is currently spotty.

   The module loader should be looked at to see if the extension
   loading sequence could be improved. There are comments to that
   effect in the module loading code, which read (paraphrasing):
   "Please make extension loading not suck." Right now, there are
   two intialization functions that extensions can use: a "setup"
   function which is called first, before any ExtensionEntry
   structures are created, and an "init" function which is called
   when the structure is created. This is OK, but the order in
   which the setup functions are called is odd: loadable
   extensions are called first, before built-in extensions. The
   calls also happen from totally different places in the code,
   with loadables being set up from the InitOutput function which
   is nonintuitive. Finally, the extension support code has large,
   cumbersome lists of extensions bracketed by ifdef's, along with
   boolean variables meant to be used for dynamic configuration of
   extensions which are in practice unused. Perhaps autotools
   could be used to build the list of extensions to load, instead
   of having a hard-coded list. The author is investigating
   possibilities for work in this area.
     __________________________________________________________

Usage

Storing Security State

   The first thing you, the security extension writer, should
   decide on is the state information that your extension will be
   storing and how it will be stored. XACE itself does not provide
   any mechanism for storing state. Two methods of storing
   security state are discussed here.
     __________________________________________________________

Global Variables

   One method of storing state is simply to use global variables
   in the extension code. Tables can be kept corresponding to
   internal server structures, updated to stay synchronized with
   the structures themselves.
     __________________________________________________________

Device Privates

   Another method of storing state is to attach your extension's
   security data directly to the server structures. This method is
   possible via the devPrivates mechanism provide by the DIX
   layer. However, only the server structures listed in Table 1
   currently support this mechanism; work is in progress to add
   other structure types (see the Section called Core X Server).

   Table 1. Current devPrivates support in DIX.
   Structure Supports Pre-Allocation Cleared to Zero Callbacks
   Available
   ClientRec Yes Yes Init/Free
   ExtensionEntry Yes Yes No
   ScreenRec No Yes No
   WindowRec Yes No Init
   GCRec Yes No No
   PixmapRec Yes No No
   ColormapRec No Yes Init
   DeviceIntRec No Yes No

   For an example of how to use devPrivates, refer to the SECURITY
   extension source code in Xext/security.c which makes use of
   them for storing state in the ClientRec and ExtensionEntry
   structures. Basically, your extension must register for space
   in each structure type. This is done slightly differently
   depending on the structure; see the SECURITY example as well as
   dix/privates.c, which contains the implementation. All
   structures provide an instance of DevUnion, indexed by a number
   that is returned to you in the devPrivates array member of the
   structure. This union can be used as a long value or a pointer.
   Some structures allow a byte count to be provided at
   registration time, which will be automatically allocated and
   returned through the pointer member of the union.

   The registration must be done in the extension setup routine
   for the ExtensionEntry structure only; for all other structures
   it can be performed in the extension init routine. See the
   SECURITY code for registration examples.

   When a structure having devPrivates support is allocated, the
   space requested by all registrants is allocated along with it.
   In some cases, the newly allocated memory is cleared to zero.
   Work is underway to make sure that all supported structures
   have the memory cleared; the ones that currently do are listed
   in Table 1. However, your security extension may need to take
   further action to initialize the newly created data. How
   exactly this is done depends on the structure. Again, some
   structures don't currently provide a way for your extension to
   be called immediately when a structure instance is created. The
   ClientRec and WindowRec structures do have support for this, as
   indicated in Table 1. Examine the SECURITY source for more
   information. The eventual goal is to have a callback, XACE or
   otherwise, notifying when each supported structure is
   initialized.

   The same applies to freeing memory or otherwise tearing down
   your security state when an object is being destroyed. Some
   structures don't currently have callbacks associated with this
   event which would allow a security extension to gain control.
   The ClientRec structure does have support. The eventual goal is
   to provide a mechanism for this purpose.

   Note

   Memory allocated through the devPrivates mechanism itself will
   be freed automatically.
     __________________________________________________________

Using Hooks

Overview

   XACE has two header files that security extension code may need
   to include. Include Xext/xacestr.h if you need the structure
   definitions for the XACE hooks. Otherwise, include Xext/xace.h,
   which contains everything else including constants and function
   declarations.

   XACE hooks use the standard X server callback mechanism. Your
   security extension's callback functions should all use the
   following prototype:

   void MyCallback( CallbackListPtr *pcbl pointer userdata pointer
   calldata );

   When the callback is called, pcbl points to the callback list
   itself. The X callback mechanism allows the list to be
   manipulated in various ways, but XACE callbacks should not do
   this. Remember that other security extensions may be registered
   on the same hook. userdata is set to the data argument that was
   passed to XaceRegisterCallback at registration time; this can
   be used by your extension to pass data into the callback.
   calldata points to a value or structure which is specific to
   each XACE hook. These are discussed in the documentation for
   each specific hook, below. Your extension must cast this
   argument to the appropriate pointer type.

   To register a callback on a given hook, use
   XaceRegisterCallback:

   Bool XaceRegisterCallback( int hook CallbackProcPtr callback
   pointer userdata );

   Where hook is the XACE hook you wish to register on, callback
   is the callback function you wish to register, and userdata
   will be passed through to the callback as its second argument,
   as described above. See Table 2 in the Section called Hooks for
   the list of XACE hook codes. XaceRegisterCallback is typically
   called from the extension initialization code; see the SECURITY
   source for examples. The return value is TRUE for success,
   FALSE otherwise.

   To unregister a callback, use XaceDeleteCallback:

   Bool XaceDeleteCallback( int hook CallbackProcPtr callback
   pointer userdata );

   where the three arguments are identical to those used in the
   call to XaceRegisterCallback. The return value is TRUE for
   success, FALSE otherwise.
     __________________________________________________________

Hooks

   The currently defined set of XACE hooks is shown in Table 2. As
   discussed in the Section called Security Hooks, the set of
   hooks is likely to change in the future as XACE is adopted and
   further security analysis of the X server is performed.

   Table 2. XACE security hooks.
   Hook Identifier Callback Argument Type Refer to
   XACE_CORE_DISPATCH XaceCoreDispatchRec the Section called Core
   Dispatch
   XACE_EXT_DISPATCH XaceExtAccessRec the Section called Extension
   Dispatch
   XACE_RESOURCE_ACCESS XaceResourceAccessRec the Section called
   Resource Access
   XACE_PROPERTY_ACCESS XacePropertyAccessRec the Section called
   Property Access
   XACE_MAP_ACCESS XaceMapAccessRec the Section called Map Access
   XACE_DRAWABLE_ACCESS XaceDrawableAccessRec the Section called
   Drawable Access
   XACE_BACKGRND_ACCESS XaceMapAccessRec the Section called
   Background Access
   XACE_DEVICE_ACCESS XaceDeviceAccessRec the Section called
   Device Access
   XACE_HOSTLIST_ACCESS XaceHostlistAccessRec the Section called
   Host List Access
   XACE_EXT_ACCESS XaceExtAccessRec the Section called Extension
   Access
   XACE_WINDOW_INIT XaceWindowRec the Section called Window
   Initialization
   XACE_AUTH_AVAIL XaceAuthAvailRec the Section called
   Authorization Availability Hook
   XACE_KEY_AVAIL XaceKeyAvailRec the Section called Keypress
   Availability Hook
   XACE_AUDIT_BEGIN XaceAuditRec the Section called Auditing Hooks
   XACE_AUDIT_END XaceAuditRec the Section called Auditing Hooks

   In the descriptions that follow, it is helpful to have a
   listing of Xext/xacestr.h available for reference.
     __________________________________________________________

Core Dispatch

   This hook allows security extensions to examine all incoming
   core protocol requests before they are dispatched. The hook
   argument is a pointer to a structure of type
   XaceCoreDispatchRec. This structure contains a client field of
   type ClientPtr and a rval field of type int.

   The client field refers to the client making the incoming
   request. Note that the complete request is accessible via the
   requestBuffer member of the client structure. The REQUEST
   family of macros, located in include/dix.h, are useful in
   verifying and reading from this member.

   The rval field should be set to FALSE if the request is to be
   denied. The result of a denied request is a BadAccess error,
   which is delivered to the client.
     __________________________________________________________

Extension Dispatch

   This hook allows security extensions to examine all incoming
   extension protocol requests before they are dispatched. The
   hook argument is a pointer to a structure of type
   XaceExtAccessRec. This structure contains a client field of
   type ClientPtr, a ext field of type ExtensionEntry*, and a rval
   field of type int.

   The client field refers to the client making the incoming
   request. Note that the complete request is accessible via the
   requestBuffer member of the client structure. The REQUEST
   family of macros, located in include/dix.h, are useful in
   verifying and reading from this member.

   The ext field refers to the extension being accessed. This is
   required information since extensions are not associated with
   any particular major number.

   The rval field should be set to FALSE if the request is to be
   denied. The result of a denied request is a BadAccess error,
   which is delivered to the client.
     __________________________________________________________

Resource Access

   This hook allows security extensions to monitor all resource
   lookups. The hook argument is a pointer to a structure of type
   XaceResourceAccessRec. This structure contains a client field
   of type ClientPtr, a id field of type XID, a rtype field of
   type RESTYPE, a access_mode field of type Mask, a res field of
   type pointer, and a rval field of type int.

   The client field refers to the client on whose behalf the
   lookup is being performed. Note that this may be serverClient
   for server lookups.

   The id field is the resource ID being looked up.

   The rtype field is the resource type being looked up.

   The access_mode field encodes the type of action being
   performed. The valid values are defined in include/resource.h
   (look for SecurityReadAccess). This field is a legacy of the
   SECURITY extension.

   Warning

   The access_mode field is not widely used by the core server and
   is often the default "unknown" value. The semantics of this
   field may be changed in the future.

   The res field is the resource itself: the result of the lookup.

   The rval field should be set to FALSE if the lookup is to be
   denied. The result of a denied request is a lookup failure,
   which will have varying effects on the client (or server)
   depending on the type of resource.
     __________________________________________________________

Property Access

   This hook allows security extensions to monitor all property
   accesses. The hook argument is a pointer to a structure of type
   XacePropertyAccessRec. This structure contains a client field
   of type ClientPtr, a pWin field of type WindowPtr, a
   propertyName field of type Atom, a access_mode field of type
   Mask, and a rval field of type int.

   The client field refers to the client which is accessing the
   property. Note that this may be serverClient for server
   lookups.

   The pWin field is the window on which the property is being
   accessed.

   The propertyName field is the name of the property being
   accessed.

   The access_mode field encodes the type of action being
   performed. The valid values are defined in include/resource.h
   (look for SecurityReadAccess). This field is a legacy of the
   SECURITY extension.

   The rval field should be set to one of the Operation constants
   defined in Xext/xace.h. The options are to allow, deny, or
   ignore the request. The difference between denying and ignoring
   is that an ignored request returns successfully but either does
   nothing (for a write) or returns an empty string (for a read).

   Warning

   The semantics of the access_mode field and the rval field may
   be changed in the future. See the warning in the Section called
   Resource Access.
     __________________________________________________________

Map Access

   This hook allows security extensions to approve or deny
   requests to map windows. The hook argument is a pointer to a
   structure of type XaceMapAccessRec. This structure contains a
   client field of type ClientPtr, a pWin field of type WindowPtr,
   and a rval field of type int.

   The client field refers to the client making the request.

   The pWin field refers to the window being mapped.

   The rval field should be set to FALSE if the request is to be
   denied. Currently, the result of a denied request is a
   successful return leaving the window unmapped. In the future,
   this may be changed to return a BadAccess error to the client.
     __________________________________________________________

Drawable Access

   This hook allows security extensions to force censoring of
   overlapping windows when a GetImage request is made. Refer to
   the "Image Security" section of the SECURITY extension
   specification for more information. The hook argument is a
   pointer to a structure of type XaceDrawableAccessRec. This
   structure contains a client field of type ClientPtr, a pDraw
   field of type DrawablePtr, and a rval field of type int.

   The client field refers to the client making the request.

   The pDrawable field refers to the subject of the GetImage
   request.

   The rval field should be set to FALSE if the drawable is to be
   checked for overlapping windows and censored appropriately.
     __________________________________________________________

Background Access

   This hook allows security extensions to force censoring of
   background "None" windows, preventing contents of other windows
   from showing through. The hook argument is a pointer to a
   structure of type XaceMapAccessRec. This structure contains a
   client field of type ClientPtr, a pWin field of type WindowPtr,
   and a rval field of type int.

   The client field refers to the client making the request,
   typically a CreateWindow request.

   The pWin field refers to the window being created.

   The rval field should be set to FALSE if the background is to
   be censored.

   Warning

   This hook may be merged with the drawable access hook at some
   point in the future.
     __________________________________________________________

Device Access

   This hook allows security extensions to restrict certain
   actions by clients related to keyboard input. For the
   specifics, refer to the "Input Security" section of the
   SECURITY extension specification. The hook argument is a
   pointer to a structure of type XaceDeviceAccessRec. This
   structure contains a client field of type ClientPtr, a dev
   field of type DeviceIntPtr, a fromRequest field of type Bool,
   and a rval field of type int.

   The client field refers to the client attempting to access the
   device (keyboard). Note that this may be serverClient.

   The dev field refers to the input device being accessed.

   The fromRequest field is TRUE if the access is the result of a
   client request; FALSE otherwise.

   The rval field should be set to FALSE if the client is to be
   restricted. The result of the return value varies depending on
   the context of the call.

   Warning

   This hook is a legacy of the SECURITY extension and covers only
   the core server. Extensions do exist, such as XEVIE, that allow
   clients to intercept and modify input events.

   The input subsystem in X.Org is in a state of change and it is
   expected that input event security will not be fully addressed
   until later versions of XACE.
     __________________________________________________________

Host List Access

   This hook allows security extensions to approve or deny
   requests to read or change the host access list. The hook
   argument is a pointer to a structure of type
   XaceHostlistAccessRec. This structure contains a client field
   of type ClientPtr, a access_mode field of type Mask, and a rval
   field of type int.

   The client field refers to the client making the request.

   The access_mode field encodes the type of action being
   performed. The valid values are defined in include/resource.h
   (look for SecurityReadAccess). Currently this field is set to
   read access for ProcListHosts and write access otherwise.

   The rval field should be set to FALSE if the request is to be
   denied. The result of a denied request is a BadAccess error,
   which is delivered to the client.
     __________________________________________________________

Extension Access

   This hook allows security extensions to approve or deny
   requests involving supported server extensions. The hook
   argument is a pointer to a structure of type XaceExtAccessRec.
   This structure contains a client field of type ClientPtr, a ext
   field of type ExtensionEntry*, and a rval field of type int.

   The client field refers to the client making the request.

   The ext field refers to the extension being queried.

   The rval field should be set to FALSE if the client is not to
   be made aware of the extension. For a QueryExtension request, a
   denial results in a response indicating the extension is not
   present. For a ListExtensions request, a denial results in the
   exclusion of the extension from the returned list.
     __________________________________________________________

Window Initialization

   This hook allows security extensions to set up security state
   for newly created windows. The hook argument is a pointer to a
   structure of type XaceWindowRec. This structure contains a
   client field of type ClientPtr, and a pWin field of type
   WindowPtr.

   The client field refers to the client owning the window. Note
   that this may be serverClient.

   The pWin field refers to the newly created window.

   This hook has no return value.
     __________________________________________________________

Authorization Availability Hook

   This hook allows security extensions to examine the
   authorization associated with a newly connected client. This
   can be used to set up client security state depending on the
   authorization method that was used. The hook argument is a
   pointer to a structure of type XaceAuthAvailRec. This structure
   contains a client field of type ClientPtr, and a authId field
   of type XID.

   The client field refers to the newly connected client.

   The authId field is the resource ID of the client's
   authorization.

   This hook has no return value.

   Note

   This hook is called after the client enters the initial state
   and before the client enters the running state. Keep this in
   mind if your security extension uses the ClientStateCallback
   list to keep track of clients.

   This hook is a legacy of the APPGROUP Extension. In the future,
   this hook may be phased out in favor of a new client state,
   ClientStateAuthenticated.
     __________________________________________________________

Keypress Availability Hook

   This hook allows security extensions to examine keypresses
   outside of the normal event mechanism. This could be used to
   implement server-side hotkey support. The hook argument is a
   pointer to a structure of type XaceKeyAvailRec. This structure
   contains a event field of type xEventPtr, a keybd field of type
   DeviceIntPtr, and a count field of type int.

   The event field refers to the keyboard event, typically a
   KeyPress or KeyRelease.

   The keybd field refers to the input device that generated the
   event.

   The count field is the number of repetitions of the event (not
   100\% sure of this at present, however).

   This hook has no return value.

   Warning

   The warning in the Section called Device Access applies to this
   hook. This hook is provided mainly for support of the Trusted
   Solaris extension.
     __________________________________________________________

Auditing Hooks

   Two hooks provide basic auditing support. The begin hook is
   called immediately before an incoming client request is
   dispatched and before the dispatch hook is called (refer to the
   Section called Core Dispatch). The end hook is called
   immedately after the processing of the request has finished.
   The hook argument is a pointer to a structure of type
   XaceKeyAvailRec. This structure contains a client field of type
   ClientPtr, and a requestResult field of type int.

   The client field refers to client making the request.

   The requestResult field contains the result of the request,
   either Success or one of the protocol error codes. Note that
   this field is significant only in the end hook.

   These hooks have no return value.
     __________________________________________________________

Protocol

Requests

   XACE does not define any X protocol.
     __________________________________________________________

Events

   XACE does not define any X protocol.
     __________________________________________________________

Errors

   XACE does not define any X protocol.
