diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2008-11-02 15:26:35 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2008-11-02 15:26:35 +0000 |
commit | dbca69c8a4f3e2d1ccb4f89152213b2861b33af6 (patch) | |
tree | f8963ef73903a7b4374adc2354dffbaa905112ac /xserver/Xext/security.c | |
parent | 33b2029f322f3c238b7ba528083195ad8dde33e1 (diff) |
xserver 1.5.2. tested by ckuethe@, oga@, and others.
Diffstat (limited to 'xserver/Xext/security.c')
-rw-r--r-- | xserver/Xext/security.c | 1496 |
1 files changed, 351 insertions, 1145 deletions
diff --git a/xserver/Xext/security.c b/xserver/Xext/security.c index a8a75ea6c..ad30e06b8 100644 --- a/xserver/Xext/security.c +++ b/xserver/Xext/security.c @@ -28,63 +28,62 @@ in this Software without prior written authorization from The Open Group. #include <dix-config.h> #endif -#include "dixstruct.h" -#include "extnsionst.h" -#include "windowstr.h" -#include "inputstr.h" #include "scrnintstr.h" -#include "gcstruct.h" -#include "colormapst.h" +#include "inputstr.h" +#include "windowstr.h" #include "propertyst.h" +#include "colormapst.h" +#include "privates.h" +#include "registry.h" #include "xacestr.h" #include "securitysrv.h" #include <X11/extensions/securstr.h> -#include <assert.h> -#include <stdarg.h> #ifdef XAPPGROUP #include "appgroup.h" #endif -#include <stdio.h> /* for file reading operations */ -#include <X11/Xatom.h> /* for XA_STRING */ - -#ifndef DEFAULTPOLICYFILE -# define DEFAULTPOLICYFILE NULL -#endif -#if defined(WIN32) || defined(__CYGWIN__) -#include <X11/Xos.h> -#undef index -#endif - #include "modinit.h" +/* Extension stuff */ static int SecurityErrorBase; /* first Security error number */ static int SecurityEventBase; /* first Security event number */ -static int securityClientPrivateIndex; -static int securityExtnsnPrivateIndex; -/* this is what we store as client security state */ -typedef struct { - unsigned int trustLevel; - XID authId; -} SecurityClientStateRec; - -#define STATEVAL(extnsn) \ - ((extnsn)->devPrivates[securityExtnsnPrivateIndex].val) -#define STATEPTR(client) \ - ((client)->devPrivates[securityClientPrivateIndex].ptr) -#define TRUSTLEVEL(client) \ - (((SecurityClientStateRec*)STATEPTR(client))->trustLevel) -#define AUTHID(client) \ - (((SecurityClientStateRec*)STATEPTR(client))->authId) +RESTYPE SecurityAuthorizationResType; /* resource type for authorizations */ +static RESTYPE RTEventClient; static CallbackListPtr SecurityValidateGroupCallback = NULL; -RESTYPE SecurityAuthorizationResType; /* resource type for authorizations */ +/* Private state record */ +static DevPrivateKey stateKey = &stateKey; -static RESTYPE RTEventClient; +/* This is what we store as client security state */ +typedef struct { + int haveState; + unsigned int trustLevel; + XID authId; +} SecurityStateRec; + +/* Extensions that untrusted clients shouldn't have access to */ +static char *SecurityUntrustedExtensions[] = { + "RandR", + "SECURITY", + "XFree86-DGA", + NULL +}; + +/* + * Access modes that untrusted clients are allowed on trusted objects. + */ +static const Mask SecurityResourceMask = + DixGetAttrAccess | DixReceiveAccess | DixListPropAccess | + DixGetPropAccess | DixListAccess; +static const Mask SecurityRootWindowExtraMask = + DixReceiveAccess | DixSendAccess | DixAddAccess | DixRemoveAccess; +static const Mask SecurityDeviceMask = + DixGetAttrAccess | DixReceiveAccess | DixGetFocusAccess | + DixGrabAccess | DixSetAttrAccess | DixUseAccess; +static const Mask SecurityServerMask = DixGetAttrAccess | DixGrabAccess; +static const Mask SecurityClientMask = DixGetAttrAccess; -#define CALLBACK(name) static void \ -name(CallbackListPtr *pcbl, pointer nulldata, pointer calldata) /* SecurityAudit * @@ -110,6 +109,51 @@ SecurityAudit(char *format, ...) va_end(args); } /* SecurityAudit */ +/* + * Performs a Security permission check. + */ +static int +SecurityDoCheck(SecurityStateRec *subj, SecurityStateRec *obj, + Mask requested, Mask allowed) +{ + if (!subj->haveState || !obj->haveState) + return Success; + if (subj->trustLevel == XSecurityClientTrusted) + return Success; + if (obj->trustLevel != XSecurityClientTrusted) + return Success; + if ((requested | allowed) == allowed) + return Success; + + return BadAccess; +} + +/* + * Labels initial server objects. + */ +static void +SecurityLabelInitial(void) +{ + SecurityStateRec *state; + + /* Do the serverClient */ + state = dixLookupPrivate(&serverClient->devPrivates, stateKey); + state->trustLevel = XSecurityClientTrusted; + state->haveState = TRUE; +} + +/* + * Looks up a request name + */ +static _X_INLINE const char * +SecurityLookupRequestName(ClientPtr client) +{ + int major = ((xReq *)client->requestBuffer)->reqType; + int minor = MinorOpcodeOfRequest(client); + return LookupRequestName(major, minor); +} + + #define rClient(obj) (clients[CLIENT_ID((obj)->resource)]) /* SecurityDeleteAuthorization @@ -170,10 +214,12 @@ SecurityDeleteAuthorization( /* kill all clients using this auth */ for (i = 1; i<currentMaxClients; i++) - { - if (clients[i] && (AUTHID(clients[i]) == pAuth->id)) - CloseDownClient(clients[i]); - } + if (clients[i]) { + SecurityStateRec *state; + state = dixLookupPrivate(&clients[i]->devPrivates, stateKey); + if (state->haveState && state->authId == pAuth->id) + CloseDownClient(clients[i]); + } SecurityAudit("revoked authorization ID %d\n", pAuth->id); xfree(pAuth); @@ -322,12 +368,6 @@ ProcSecurityQueryVersion( /* REQUEST(xSecurityQueryVersionReq); */ xSecurityQueryVersionReply rep; - /* paranoia: this "can't happen" because this extension is hidden - * from untrusted clients, but just in case... - */ - if (TRUSTLEVEL(client) != XSecurityClientTrusted) - return BadRequest; - REQUEST_SIZE_MATCH(xSecurityQueryVersionReq); rep.type = X_Reply; rep.sequenceNumber = client->sequence; @@ -408,12 +448,6 @@ ProcSecurityGenerateAuthorization( char *pAuthdata; /* generated auth data */ Mask eventMask; /* what events on this auth does client want */ - /* paranoia: this "can't happen" because this extension is hidden - * from untrusted clients, but just in case... - */ - if (TRUSTLEVEL(client) != XSecurityClientTrusted) - return BadRequest; - /* check request length */ REQUEST_AT_LEAST_SIZE(xSecurityGenerateAuthorizationReq); @@ -591,12 +625,6 @@ ProcSecurityRevokeAuthorization( REQUEST(xSecurityRevokeAuthorizationReq); SecurityAuthorizationPtr pAuth; - /* paranoia: this "can't happen" because this extension is hidden - * from untrusted clients, but just in case... - */ - if (TRUSTLEVEL(client) != XSecurityClientTrusted) - return BadRequest; - REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq); pAuth = (SecurityAuthorizationPtr)SecurityLookupIDByType(client, @@ -714,59 +742,6 @@ SwapSecurityAuthorizationRevokedEvent( cpswapl(from->authId, to->authId); } -/* SecurityDetermineEventPropogationLimits - * - * This is a helper function for SecurityCheckDeviceAccess. - * - * Arguments: - * dev is the device for which the starting and stopping windows for - * event propogation should be determined. - * The values pointed to by ppWin and ppStopWin are not used. - * - * Returns: - * ppWin is filled in with a pointer to the window at which event - * propogation for the given device should start given the current - * state of the server (pointer position, window layout, etc.) - * ppStopWin is filled in with the window at which event propogation - * should stop; events should not go to ppStopWin. - * - * Side Effects: none. - */ - -static void -SecurityDetermineEventPropogationLimits( - DeviceIntPtr dev, - WindowPtr *ppWin, - WindowPtr *ppStopWin) -{ - WindowPtr pFocusWin = dev->focus ? dev->focus->win : NoneWin; - - if (pFocusWin == NoneWin) - { /* no focus -- events don't go anywhere */ - *ppWin = *ppStopWin = NULL; - return; - } - - if (pFocusWin == PointerRootWin) - { /* focus follows the pointer */ - *ppWin = GetSpriteWindow(); - *ppStopWin = NULL; /* propogate all the way to the root */ - } - else - { /* a real window is set for the focus */ - WindowPtr pSpriteWin = GetSpriteWindow(); - *ppStopWin = pFocusWin->parent; /* don't go past the focus window */ - - /* if the pointer is in a subwindow of the focus window, start - * at that subwindow, else start at the focus window itself - */ - if (IsParent(pFocusWin, pSpriteWin)) - *ppWin = pSpriteWin; - else *ppWin = pFocusWin; - } -} /* SecurityDetermineEventPropogationLimits */ - - /* SecurityCheckDeviceAccess * * Arguments: @@ -783,162 +758,30 @@ SecurityDetermineEventPropogationLimits( * An audit message is generated if access is denied. */ -CALLBACK(SecurityCheckDeviceAccess) -{ - XaceDeviceAccessRec *rec = (XaceDeviceAccessRec*)calldata; - ClientPtr client = rec->client; - DeviceIntPtr dev = rec->dev; - Bool fromRequest = rec->fromRequest; - WindowPtr pWin, pStopWin; - Bool untrusted_got_event; - Bool found_event_window; - Mask eventmask; - int reqtype = 0; - - /* trusted clients always allowed to do anything */ - if (TRUSTLEVEL(client) == XSecurityClientTrusted) - return; - - /* device security other than keyboard is not implemented yet */ - if (dev != inputInfo.keyboard) - return; - - /* some untrusted client wants access */ - - if (fromRequest) - { - reqtype = ((xReq *)client->requestBuffer)->reqType; - switch (reqtype) - { - /* never allow these */ - case X_ChangeKeyboardMapping: - case X_ChangeKeyboardControl: - case X_SetModifierMapping: - SecurityAudit("client %d attempted request %d\n", - client->index, reqtype); - rec->rval = FALSE; - return; - default: - break; - } - } - - untrusted_got_event = FALSE; - found_event_window = FALSE; - - if (dev->grab) - { - untrusted_got_event = - (TRUSTLEVEL(rClient(dev->grab)) != XSecurityClientTrusted); - } - else - { - SecurityDetermineEventPropogationLimits(dev, &pWin, &pStopWin); - - eventmask = KeyPressMask | KeyReleaseMask; - while ( (pWin != pStopWin) && !found_event_window) - { - OtherClients *other; - - if (pWin->eventMask & eventmask) - { - found_event_window = TRUE; - client = wClient(pWin); - if (TRUSTLEVEL(client) != XSecurityClientTrusted) - { - untrusted_got_event = TRUE; - } - } - if (wOtherEventMasks(pWin) & eventmask) - { - found_event_window = TRUE; - for (other = wOtherClients(pWin); other; other = other->next) - { - if (other->mask & eventmask) - { - client = rClient(other); - if (TRUSTLEVEL(client) != XSecurityClientTrusted) - { - untrusted_got_event = TRUE; - break; - } - } - } - } - if (wDontPropagateMask(pWin) & eventmask) - break; - pWin = pWin->parent; - } /* while propogating the event */ - } - - /* allow access by untrusted clients only if an event would have gone - * to an untrusted client - */ - - if (!untrusted_got_event) - { - char *devname = dev->name; - if (!devname) devname = "unnamed"; - if (fromRequest) - SecurityAudit("client %d attempted request %d device %d (%s)\n", - client->index, reqtype, dev->id, devname); - else - SecurityAudit("client %d attempted to access device %d (%s)\n", - client->index, dev->id, devname); - rec->rval = FALSE; - } - return; -} /* SecurityCheckDeviceAccess */ - - - -/* SecurityAuditResourceIDAccess - * - * Arguments: - * client is the client doing the resource access. - * id is the resource id. - * - * Returns: NULL - * - * Side Effects: - * An audit message is generated with details of the denied - * resource access. - */ - -static pointer -SecurityAuditResourceIDAccess( - ClientPtr client, - XID id) +static void +SecurityDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata) { - int cid = CLIENT_ID(id); - int reqtype = ((xReq *)client->requestBuffer)->reqType; - switch (reqtype) - { - case X_ChangeProperty: - case X_DeleteProperty: - case X_GetProperty: - { - xChangePropertyReq *req = - (xChangePropertyReq *)client->requestBuffer; - int propertyatom = req->property; - char *propertyname = NameForAtom(propertyatom); - - SecurityAudit("client %d attempted request %d with window 0x%x property %s of client %d\n", - client->index, reqtype, id, propertyname, cid); - break; - } - default: - { - SecurityAudit("client %d attempted request %d with resource 0x%x of client %d\n", - client->index, reqtype, id, cid); - break; - } + XaceDeviceAccessRec *rec = calldata; + SecurityStateRec *subj, *obj; + Mask requested = rec->access_mode; + Mask allowed = SecurityDeviceMask; + + subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); + obj = dixLookupPrivate(&serverClient->devPrivates, stateKey); + + if (rec->dev != inputInfo.keyboard) + /* this extension only supports the core keyboard */ + allowed = requested; + + if (SecurityDoCheck(subj, obj, requested, allowed) != Success) { + SecurityAudit("Security denied client %d keyboard access on request " + "%s\n", rec->client->index, + SecurityLookupRequestName(rec->client)); + rec->status = BadAccess; } - return NULL; -} /* SecurityAuditResourceIDAccess */ - +} -/* SecurityCheckResourceIDAccess +/* SecurityResource * * This function gets plugged into client->CheckAccess and is called from * SecurityLookupIDByType/Class to determine if the client can access the @@ -959,867 +802,256 @@ SecurityAuditResourceIDAccess( * Disallowed resource accesses are audited. */ -CALLBACK(SecurityCheckResourceIDAccess) +static void +SecurityResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) { - XaceResourceAccessRec *rec = (XaceResourceAccessRec*)calldata; - ClientPtr client = rec->client; - XID id = rec->id; - RESTYPE rtype = rec->rtype; - Mask access_mode = rec->access_mode; - pointer rval = rec->res; - int cid, reqtype; - - if (TRUSTLEVEL(client) == XSecurityClientTrusted || - DixUnknownAccess == access_mode) - return; /* for compatibility, we have to allow access */ - - cid = CLIENT_ID(id); - reqtype = ((xReq *)client->requestBuffer)->reqType; - switch (reqtype) - { /* these are always allowed */ - case X_QueryTree: - case X_TranslateCoords: - case X_GetGeometry: - /* property access is controlled in SecurityCheckPropertyAccess */ - case X_GetProperty: - case X_ChangeProperty: - case X_DeleteProperty: - case X_RotateProperties: - case X_ListProperties: - return; - default: - break; - } + XaceResourceAccessRec *rec = calldata; + SecurityStateRec *subj, *obj; + int cid = CLIENT_ID(rec->id); + Mask requested = rec->access_mode; + Mask allowed = SecurityResourceMask; + + subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); + obj = dixLookupPrivate(&clients[cid]->devPrivates, stateKey); + + /* disable background None for untrusted windows */ + if ((requested & DixCreateAccess) && (rec->rtype == RT_WINDOW)) + if (subj->haveState && subj->trustLevel != XSecurityClientTrusted) + ((WindowPtr)rec->res)->forcedBG = TRUE; + + /* special checks for server-owned resources */ + if (cid == 0) { + if (rec->rtype & RC_DRAWABLE) + /* additional operations allowed on root windows */ + allowed |= SecurityRootWindowExtraMask; + + else if (rec->rtype == RT_COLORMAP) + /* allow access to default colormaps */ + allowed = requested; - if (cid != 0) - { /* not a server-owned resource */ - /* - * The following 'if' restricts clients to only access resources at - * the same trustLevel. Since there are currently only two trust levels, - * and trusted clients never call this function, this degenerates into - * saying that untrusted clients can only access resources of other - * untrusted clients. One way to add the notion of groups would be to - * allow values other than Trusted (0) and Untrusted (1) for this field. - * Clients at the same trust level would be able to use each other's - * resources, but not those of clients at other trust levels. I haven't - * tried it, but this probably mostly works already. The obvious - * competing alternative for grouping clients for security purposes is to - * use app groups. dpw - */ - if (TRUSTLEVEL(client) == TRUSTLEVEL(clients[cid]) -#ifdef XAPPGROUP - || (RT_COLORMAP == rtype && - XagDefaultColormap (client) == (Colormap) id) -#endif - ) - return; else - goto deny; + /* allow read access to other server-owned resources */ + allowed |= DixReadAccess; } - else /* server-owned resource - probably a default colormap or root window */ - { - if (RC_DRAWABLE & rtype) - { - switch (reqtype) - { /* the following operations are allowed on root windows */ - case X_CreatePixmap: - case X_CreateGC: - case X_CreateWindow: - case X_CreateColormap: - case X_ListProperties: - case X_GrabPointer: - case X_UngrabButton: - case X_QueryBestSize: - case X_GetWindowAttributes: - break; - case X_SendEvent: - { /* see if it is an event specified by the ICCCM */ - xSendEventReq *req = (xSendEventReq *) - (client->requestBuffer); - if (req->propagate == xTrue - || - (req->eventMask != ColormapChangeMask && - req->eventMask != StructureNotifyMask && - req->eventMask != - (SubstructureRedirectMask|SubstructureNotifyMask) - ) - || - (req->event.u.u.type != UnmapNotify && - req->event.u.u.type != ConfigureRequest && - req->event.u.u.type != ClientMessage - ) - ) - { /* not an ICCCM event */ - goto deny; - } - break; - } /* case X_SendEvent on root */ - - case X_ChangeWindowAttributes: - { /* Allow selection of PropertyNotify and StructureNotify - * events on the root. - */ - xChangeWindowAttributesReq *req = - (xChangeWindowAttributesReq *)(client->requestBuffer); - if (req->valueMask == CWEventMask) - { - CARD32 value = *((CARD32 *)(req + 1)); - if ( (value & - ~(PropertyChangeMask|StructureNotifyMask)) == 0) - break; - } - goto deny; - } /* case X_ChangeWindowAttributes on root */ - - default: - { - /* others not allowed */ - goto deny; - } - } - } /* end server-owned window or drawable */ - else if (SecurityAuthorizationResType == rtype) - { - SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)rval; - if (pAuth->trustLevel != TRUSTLEVEL(client)) - goto deny; - } - else if (RT_COLORMAP != rtype) - { /* don't allow anything else besides colormaps */ - goto deny; - } - } - return; - deny: - SecurityAuditResourceIDAccess(client, id); - rec->rval = FALSE; /* deny access */ -} /* SecurityCheckResourceIDAccess */ - - -/* SecurityClientStateCallback - * - * Arguments: - * pcbl is &ClientStateCallback. - * nullata is NULL. - * calldata is a pointer to a NewClientInfoRec (include/dixstruct.h) - * which contains information about client state changes. - * - * Returns: nothing. - * - * Side Effects: - * - * If a new client is connecting, its authorization ID is copied to - * client->authID. If this is a generated authorization, its reference - * count is bumped, its timer is cancelled if it was running, and its - * trustlevel is copied to TRUSTLEVEL(client). - * - * If a client is disconnecting and the client was using a generated - * authorization, the authorization's reference count is decremented, and - * if it is now zero, the timer for this authorization is started. - */ -CALLBACK(SecurityClientStateCallback) -{ - NewClientInfoRec *pci = (NewClientInfoRec *)calldata; - ClientPtr client = pci->client; - - switch (client->clientState) - { - case ClientStateInitial: - TRUSTLEVEL(client) = XSecurityClientTrusted; - AUTHID(client) = None; - break; - - case ClientStateRunning: - { - XID authId = AuthorizationIDOfClient(client); - SecurityAuthorizationPtr pAuth; - - TRUSTLEVEL(client) = XSecurityClientTrusted; - AUTHID(client) = authId; - pAuth = (SecurityAuthorizationPtr)LookupIDByType(authId, - SecurityAuthorizationResType); - if (pAuth) - { /* it is a generated authorization */ - pAuth->refcnt++; - if (pAuth->refcnt == 1) - { - if (pAuth->timer) TimerCancel(pAuth->timer); - } - TRUSTLEVEL(client) = pAuth->trustLevel; - } - break; - } - case ClientStateGone: - case ClientStateRetained: /* client disconnected */ - { - SecurityAuthorizationPtr pAuth; - - /* client may not have any state (bad authorization) */ - if (!STATEPTR(client)) - break; - - pAuth = (SecurityAuthorizationPtr)LookupIDByType(AUTHID(client), - SecurityAuthorizationResType); - if (pAuth) - { /* it is a generated authorization */ - pAuth->refcnt--; - if (pAuth->refcnt == 0) - { - SecurityStartAuthorizationTimer(pAuth); - } - } - break; - } - default: break; - } -} /* SecurityClientStateCallback */ + if (SecurityDoCheck(subj, obj, requested, allowed) == Success) + return; -CALLBACK(SecurityCheckDrawableAccess) -{ - XaceDrawableAccessRec *rec = (XaceDrawableAccessRec*)calldata; +#ifdef XAPPGROUP + if (rec->id == XagDefaultColormap(rec->client)) + return; +#endif - if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted) - rec->rval = FALSE; + SecurityAudit("Security: denied client %d access %x to resource 0x%x " + "of client %d on request %s\n", rec->client->index, + requested, rec->id, cid, + SecurityLookupRequestName(rec->client)); + rec->status = BadAccess; /* deny access */ } -CALLBACK(SecurityCheckMapAccess) -{ - XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata; - WindowPtr pWin = rec->pWin; - - if (STATEPTR(rec->client) && - (TRUSTLEVEL(rec->client) != XSecurityClientTrusted) && - (pWin->drawable.class == InputOnly) && - pWin->parent && pWin->parent->parent && - (TRUSTLEVEL(wClient(pWin->parent)) == XSecurityClientTrusted)) - rec->rval = FALSE; -} - -CALLBACK(SecurityCheckBackgrndAccess) +static void +SecurityExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata) { - XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata; - - if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted) - rec->rval = FALSE; + XaceExtAccessRec *rec = calldata; + SecurityStateRec *subj; + int i = 0; + + subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); + + if (subj->haveState && subj->trustLevel != XSecurityClientTrusted) + while (SecurityUntrustedExtensions[i]) + if (!strcmp(SecurityUntrustedExtensions[i++], rec->ext->name)) { + SecurityAudit("Security: denied client %d access to extension " + "%s on request %s\n", + rec->client->index, rec->ext->name, + SecurityLookupRequestName(rec->client)); + rec->status = BadAccess; + return; + } } -CALLBACK(SecurityCheckExtAccess) +static void +SecurityServer(CallbackListPtr *pcbl, pointer unused, pointer calldata) { - XaceExtAccessRec *rec = (XaceExtAccessRec*)calldata; - - if ((TRUSTLEVEL(rec->client) != XSecurityClientTrusted) && - !STATEVAL(rec->ext)) - - rec->rval = FALSE; -} + XaceServerAccessRec *rec = calldata; + SecurityStateRec *subj, *obj; + Mask requested = rec->access_mode; + Mask allowed = SecurityServerMask; -CALLBACK(SecurityCheckHostlistAccess) -{ - XaceHostlistAccessRec *rec = (XaceHostlistAccessRec*)calldata; + subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); + obj = dixLookupPrivate(&serverClient->devPrivates, stateKey); - if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted) - { - rec->rval = FALSE; - if (rec->access_mode == DixWriteAccess) - SecurityAudit("client %d attempted to change host access\n", - rec->client->index); - else - SecurityAudit("client %d attempted to list hosts\n", - rec->client->index); + if (SecurityDoCheck(subj, obj, requested, allowed) != Success) { + SecurityAudit("Security: denied client %d access to server " + "configuration request %s\n", rec->client->index, + SecurityLookupRequestName(rec->client)); + rec->status = BadAccess; } } -CALLBACK(SecurityDeclareExtSecure) -{ - XaceDeclareExtSecureRec *rec = (XaceDeclareExtSecureRec*)calldata; - - /* security state for extensions is simply a boolean trust value */ - STATEVAL(rec->ext) = rec->secure; -} - -/**********************************************************************/ - -typedef struct _PropertyAccessRec { - ATOM name; - ATOM mustHaveProperty; - char *mustHaveValue; - char windowRestriction; -#define SecurityAnyWindow 0 -#define SecurityRootWindow 1 -#define SecurityWindowWithProperty 2 - char readAction; - char writeAction; - char destroyAction; - struct _PropertyAccessRec *next; -} PropertyAccessRec, *PropertyAccessPtr; - -static PropertyAccessPtr PropertyAccessList = NULL; -static char SecurityDefaultAction = XaceErrorOperation; -static char *SecurityPolicyFile = DEFAULTPOLICYFILE; -static ATOM SecurityMaxPropertyName = 0; - -static char *SecurityKeywords[] = { -#define SecurityKeywordComment 0 - "#", -#define SecurityKeywordProperty 1 - "property", -#define SecurityKeywordSitePolicy 2 - "sitepolicy", -#define SecurityKeywordRoot 3 - "root", -#define SecurityKeywordAny 4 - "any" -}; - -#define NUMKEYWORDS (sizeof(SecurityKeywords) / sizeof(char *)) - -#undef PROPDEBUG -/*#define PROPDEBUG 1*/ - static void -SecurityFreePropertyAccessList(void) -{ - while (PropertyAccessList) - { - PropertyAccessPtr freeit = PropertyAccessList; - PropertyAccessList = PropertyAccessList->next; - xfree(freeit); - } -} /* SecurityFreePropertyAccessList */ - -#define SecurityIsWhitespace(c) ( (c == ' ') || (c == '\t') || (c == '\n') ) - -static char * -SecuritySkipWhitespace( - char *p) -{ - while (SecurityIsWhitespace(*p)) - p++; - return p; -} /* SecuritySkipWhitespace */ - - -static char * -SecurityParseString( - char **rest) -{ - char *startOfString; - char *s = *rest; - char endChar = 0; - - s = SecuritySkipWhitespace(s); - - if (*s == '"' || *s == '\'') - { - endChar = *s++; - startOfString = s; - while (*s && (*s != endChar)) - s++; - } - else - { - startOfString = s; - while (*s && !SecurityIsWhitespace(*s)) - s++; - } - if (*s) - { - *s = '\0'; - *rest = s + 1; - return startOfString; - } - else - { - *rest = s; - return (endChar) ? NULL : startOfString; - } -} /* SecurityParseString */ - - -static int -SecurityParseKeyword( - char **p) +SecurityClient(CallbackListPtr *pcbl, pointer unused, pointer calldata) { - int i; - char *s = *p; - s = SecuritySkipWhitespace(s); - for (i = 0; i < NUMKEYWORDS; i++) - { - int len = strlen(SecurityKeywords[i]); - if (strncmp(s, SecurityKeywords[i], len) == 0) - { - *p = s + len; - return (i); - } - } - *p = s; - return -1; -} /* SecurityParseKeyword */ - - -static Bool -SecurityParsePropertyAccessRule( - char *p) -{ - char *propname; - char c; - char action = SecurityDefaultAction; - char readAction, writeAction, destroyAction; - PropertyAccessPtr pacl, prev, cur; - char *mustHaveProperty = NULL; - char *mustHaveValue = NULL; - Bool invalid; - char windowRestriction; - int size; - int keyword; - - /* get property name */ - propname = SecurityParseString(&p); - if (!propname || (strlen(propname) == 0)) - return FALSE; - - /* get window on which property must reside for rule to apply */ - - keyword = SecurityParseKeyword(&p); - if (keyword == SecurityKeywordRoot) - windowRestriction = SecurityRootWindow; - else if (keyword == SecurityKeywordAny) - windowRestriction = SecurityAnyWindow; - else /* not root or any, must be a property name */ - { - mustHaveProperty = SecurityParseString(&p); - if (!mustHaveProperty || (strlen(mustHaveProperty) == 0)) - return FALSE; - windowRestriction = SecurityWindowWithProperty; - p = SecuritySkipWhitespace(p); - if (*p == '=') - { /* property value is specified too */ - p++; /* skip over '=' */ - mustHaveValue = SecurityParseString(&p); - if (!mustHaveValue) - return FALSE; - } - } - - /* get operations and actions */ - - invalid = FALSE; - readAction = writeAction = destroyAction = SecurityDefaultAction; - while ( (c = *p++) && !invalid) - { - switch (c) - { - case 'i': action = XaceIgnoreOperation; break; - case 'a': action = XaceAllowOperation; break; - case 'e': action = XaceErrorOperation; break; - - case 'r': readAction = action; break; - case 'w': writeAction = action; break; - case 'd': destroyAction = action; break; - - default : - if (!SecurityIsWhitespace(c)) - invalid = TRUE; - break; - } - } - if (invalid) - return FALSE; - - /* We've successfully collected all the information needed for this - * property access rule. Now record it in a PropertyAccessRec. - */ - size = sizeof(PropertyAccessRec); - - /* If there is a property value string, allocate space for it - * right after the PropertyAccessRec. - */ - if (mustHaveValue) - size += strlen(mustHaveValue) + 1; - pacl = (PropertyAccessPtr)Xalloc(size); - if (!pacl) - return FALSE; - - pacl->name = MakeAtom(propname, strlen(propname), TRUE); - if (pacl->name == BAD_RESOURCE) - { - Xfree(pacl); - return FALSE; - } - if (mustHaveProperty) - { - pacl->mustHaveProperty = MakeAtom(mustHaveProperty, - strlen(mustHaveProperty), TRUE); - if (pacl->mustHaveProperty == BAD_RESOURCE) - { - Xfree(pacl); - return FALSE; - } - } - else - pacl->mustHaveProperty = 0; - - if (mustHaveValue) - { - pacl->mustHaveValue = (char *)(pacl + 1); - strcpy(pacl->mustHaveValue, mustHaveValue); + XaceClientAccessRec *rec = calldata; + SecurityStateRec *subj, *obj; + Mask requested = rec->access_mode; + Mask allowed = SecurityClientMask; + + subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); + obj = dixLookupPrivate(&rec->target->devPrivates, stateKey); + + if (SecurityDoCheck(subj, obj, requested, allowed) != Success) { + SecurityAudit("Security: denied client %d access to client %d on " + "request %s\n", rec->client->index, rec->target->index, + SecurityLookupRequestName(rec->client)); + rec->status = BadAccess; } - else - pacl->mustHaveValue = NULL; - - SecurityMaxPropertyName = max(SecurityMaxPropertyName, pacl->name); - - pacl->windowRestriction = windowRestriction; - pacl->readAction = readAction; - pacl->writeAction = writeAction; - pacl->destroyAction = destroyAction; - - /* link the new rule into the list of rules in order of increasing - * property name (atom) value to make searching easier - */ +} - for (prev = NULL, cur = PropertyAccessList; - cur && cur->name <= pacl->name; - prev = cur, cur = cur->next) - ; - if (!prev) - { - pacl->next = cur; - PropertyAccessList = pacl; - } - else - { - prev->next = pacl; - pacl->next = cur; +static void +SecurityProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata) +{ + XacePropertyAccessRec *rec = calldata; + SecurityStateRec *subj, *obj; + ATOM name = (*rec->ppProp)->propertyName; + Mask requested = rec->access_mode; + Mask allowed = SecurityResourceMask | DixReadAccess; + + subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); + obj = dixLookupPrivate(&wClient(rec->pWin)->devPrivates, stateKey); + + if (SecurityDoCheck(subj, obj, requested, allowed) != Success) { + SecurityAudit("Security: denied client %d access to property %s " + "(atom 0x%x) window 0x%x of client %d on request %s\n", + rec->client->index, NameForAtom(name), name, + rec->pWin->drawable.id, wClient(rec->pWin)->index, + SecurityLookupRequestName(rec->client)); + rec->status = BadAccess; } - return TRUE; -} /* SecurityParsePropertyAccessRule */ - -static char **SecurityPolicyStrings = NULL; -static int nSecurityPolicyStrings = 0; +} -static Bool -SecurityParseSitePolicy( - char *p) +static void +SecuritySend(CallbackListPtr *pcbl, pointer unused, pointer calldata) { - char *policyStr = SecurityParseString(&p); - char *copyPolicyStr; - char **newStrings; - - if (!policyStr) - return FALSE; - - copyPolicyStr = (char *)Xalloc(strlen(policyStr) + 1); - if (!copyPolicyStr) - return TRUE; - strcpy(copyPolicyStr, policyStr); - newStrings = (char **)Xrealloc(SecurityPolicyStrings, - sizeof (char *) * (nSecurityPolicyStrings + 1)); - if (!newStrings) - { - Xfree(copyPolicyStr); - return TRUE; - } - - SecurityPolicyStrings = newStrings; - SecurityPolicyStrings[nSecurityPolicyStrings++] = copyPolicyStr; + XaceSendAccessRec *rec = calldata; + SecurityStateRec *subj, *obj; - return TRUE; + if (rec->client) { + int i; -} /* SecurityParseSitePolicy */ + subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); + obj = dixLookupPrivate(&wClient(rec->pWin)->devPrivates, stateKey); + if (SecurityDoCheck(subj, obj, DixSendAccess, 0) == Success) + return; -char ** -SecurityGetSitePolicyStrings(n) - int *n; -{ - *n = nSecurityPolicyStrings; - return SecurityPolicyStrings; -} /* SecurityGetSitePolicyStrings */ - -static void -SecurityFreeSitePolicyStrings(void) -{ - if (SecurityPolicyStrings) - { - assert(nSecurityPolicyStrings); - while (nSecurityPolicyStrings--) - { - Xfree(SecurityPolicyStrings[nSecurityPolicyStrings]); - } - Xfree(SecurityPolicyStrings); - SecurityPolicyStrings = NULL; - nSecurityPolicyStrings = 0; + for (i = 0; i < rec->count; i++) + if (rec->events[i].u.u.type != UnmapNotify && + rec->events[i].u.u.type != ConfigureRequest && + rec->events[i].u.u.type != ClientMessage) { + + SecurityAudit("Security: denied client %d from sending event " + "of type %s to window 0x%x of client %d\n", + rec->client->index, rec->pWin->drawable.id, + wClient(rec->pWin)->index, + LookupEventName(rec->events[i].u.u.type)); + rec->status = BadAccess; + return; + } } -} /* SecurityFreeSitePolicyStrings */ - +} static void -SecurityLoadPropertyAccessList(void) +SecurityReceive(CallbackListPtr *pcbl, pointer unused, pointer calldata) { - FILE *f; - int lineNumber = 0; + XaceReceiveAccessRec *rec = calldata; + SecurityStateRec *subj, *obj; - SecurityMaxPropertyName = 0; + subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); + obj = dixLookupPrivate(&wClient(rec->pWin)->devPrivates, stateKey); - if (!SecurityPolicyFile) + if (SecurityDoCheck(subj, obj, DixReceiveAccess, 0) == Success) return; - f = Fopen(SecurityPolicyFile, "r"); - if (!f) - { - ErrorF("error opening security policy file %s\n", - SecurityPolicyFile); - return; - } - - while (!feof(f)) - { - char buf[200]; - Bool validLine; - char *p; - - if (!(p = fgets(buf, sizeof(buf), f))) - break; - lineNumber++; - - /* if first line, check version number */ - if (lineNumber == 1) - { - char *v = SecurityParseString(&p); - if (strcmp(v, SECURITY_POLICY_FILE_VERSION) != 0) - { - ErrorF("%s: invalid security policy file version, ignoring file\n", - SecurityPolicyFile); - break; - } - validLine = TRUE; - } - else - { - switch (SecurityParseKeyword(&p)) - { - case SecurityKeywordComment: - validLine = TRUE; - break; - - case SecurityKeywordProperty: - validLine = SecurityParsePropertyAccessRule(p); - break; - - case SecurityKeywordSitePolicy: - validLine = SecurityParseSitePolicy(p); - break; - - default: - validLine = (*p == '\0'); /* blank lines OK, others not */ - break; - } - } - - if (!validLine) - ErrorF("Line %d of %s invalid, ignoring\n", - lineNumber, SecurityPolicyFile); - } /* end while more input */ - -#ifdef PROPDEBUG - { - PropertyAccessPtr pacl; - char *op = "aie"; - for (pacl = PropertyAccessList; pacl; pacl = pacl->next) - { - ErrorF("property %s ", NameForAtom(pacl->name)); - switch (pacl->windowRestriction) - { - case SecurityAnyWindow: ErrorF("any "); break; - case SecurityRootWindow: ErrorF("root "); break; - case SecurityWindowWithProperty: - { - ErrorF("%s ", NameForAtom(pacl->mustHaveProperty)); - if (pacl->mustHaveValue) - ErrorF(" = \"%s\" ", pacl->mustHaveValue); - - } - break; - } - ErrorF("%cr %cw %cd\n", op[pacl->readAction], - op[pacl->writeAction], op[pacl->destroyAction]); - } - } -#endif /* PROPDEBUG */ - - Fclose(f); -} /* SecurityLoadPropertyAccessList */ + SecurityAudit("Security: denied client %d from receiving an event " + "sent to window 0x%x of client %d\n", + rec->client->index, rec->pWin->drawable.id, + wClient(rec->pWin)->index); + rec->status = BadAccess; +} +/* SecurityClientStateCallback + * + * Arguments: + * pcbl is &ClientStateCallback. + * nullata is NULL. + * calldata is a pointer to a NewClientInfoRec (include/dixstruct.h) + * which contains information about client state changes. + * + * Returns: nothing. + * + * Side Effects: + * + * If a new client is connecting, its authorization ID is copied to + * client->authID. If this is a generated authorization, its reference + * count is bumped, its timer is cancelled if it was running, and its + * trustlevel is copied to TRUSTLEVEL(client). + * + * If a client is disconnecting and the client was using a generated + * authorization, the authorization's reference count is decremented, and + * if it is now zero, the timer for this authorization is started. + */ -static Bool -SecurityMatchString( - char *ws, - char *cs) +static void +SecurityClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata) { - while (*ws && *cs) - { - if (*ws == '*') - { - Bool match = FALSE; - ws++; - while (!(match = SecurityMatchString(ws, cs)) && *cs) - { - cs++; - } - return match; - } - else if (*ws == *cs) - { - ws++; - cs++; - } - else break; - } - return ( ( (*ws == '\0') || ((*ws == '*') && *(ws+1) == '\0') ) - && (*cs == '\0') ); -} /* SecurityMatchString */ - -#ifdef PROPDEBUG -#include <sys/types.h> -#include <sys/stat.h> -#endif + NewClientInfoRec *pci = calldata; + SecurityStateRec *state; + SecurityAuthorizationPtr pAuth; + int rc; + state = dixLookupPrivate(&pci->client->devPrivates, stateKey); -CALLBACK(SecurityCheckPropertyAccess) -{ - XacePropertyAccessRec *rec = (XacePropertyAccessRec*)calldata; - ClientPtr client = rec->client; - WindowPtr pWin = rec->pWin; - ATOM propertyName = rec->propertyName; - Mask access_mode = rec->access_mode; - PropertyAccessPtr pacl; - char action = SecurityDefaultAction; - - /* if client trusted or window untrusted, allow operation */ - - if ( (TRUSTLEVEL(client) == XSecurityClientTrusted) || - (TRUSTLEVEL(wClient(pWin)) != XSecurityClientTrusted) ) - return; + switch (pci->client->clientState) { + case ClientStateInitial: + state->trustLevel = XSecurityClientTrusted; + state->authId = None; + state->haveState = TRUE; + break; -#ifdef PROPDEBUG - /* For testing, it's more convenient if the property rules file gets - * reloaded whenever it changes, so we can rapidly try things without - * having to reset the server. - */ - { - struct stat buf; - static time_t lastmod = 0; - int ret = stat(SecurityPolicyFile , &buf); - if ( (ret == 0) && (buf.st_mtime > lastmod) ) - { - ErrorF("reloading property rules\n"); - SecurityFreePropertyAccessList(); - SecurityLoadPropertyAccessList(); - lastmod = buf.st_mtime; + case ClientStateRunning: + state->authId = AuthorizationIDOfClient(pci->client); + rc = dixLookupResource((pointer *)&pAuth, state->authId, + SecurityAuthorizationResType, serverClient, + DixGetAttrAccess); + if (rc == Success) { + /* it is a generated authorization */ + pAuth->refcnt++; + if (pAuth->refcnt == 1 && pAuth->timer) + TimerCancel(pAuth->timer); + + state->trustLevel = pAuth->trustLevel; } - } -#endif - - /* If the property atom is bigger than any atoms on the list, - * we know we won't find it, so don't even bother looking. - */ - if (propertyName <= SecurityMaxPropertyName) - { - /* untrusted client operating on trusted window; see if it's allowed */ - - for (pacl = PropertyAccessList; pacl; pacl = pacl->next) - { - if (pacl->name < propertyName) - continue; - if (pacl->name > propertyName) - break; + break; - /* pacl->name == propertyName, so see if it applies to this window */ + case ClientStateGone: + case ClientStateRetained: + rc = dixLookupResource((pointer *)&pAuth, state->authId, + SecurityAuthorizationResType, serverClient, + DixGetAttrAccess); + if (rc == Success) { + /* it is a generated authorization */ + pAuth->refcnt--; + if (pAuth->refcnt == 0) + SecurityStartAuthorizationTimer(pAuth); + } + break; - switch (pacl->windowRestriction) - { - case SecurityAnyWindow: /* always applies */ - break; - - case SecurityRootWindow: - { - /* if not a root window, this rule doesn't apply */ - if (pWin->parent) - continue; - } - break; - - case SecurityWindowWithProperty: - { - PropertyPtr pProp = wUserProps (pWin); - Bool match = FALSE; - char *p; - char *pEndData; - - while (pProp) - { - if (pProp->propertyName == pacl->mustHaveProperty) - break; - pProp = pProp->next; - } - if (!pProp) - continue; - if (!pacl->mustHaveValue) - break; - if (pProp->type != XA_STRING || pProp->format != 8) - continue; - - p = pProp->data; - pEndData = ((char *)pProp->data) + pProp->size; - while (!match && p < pEndData) - { - if (SecurityMatchString(pacl->mustHaveValue, p)) - match = TRUE; - else - { /* skip to the next string */ - while (*p++ && p < pEndData) - ; - } - } - if (!match) - continue; - } - break; /* end case SecurityWindowWithProperty */ - } /* end switch on windowRestriction */ - - /* If we get here, the property access rule pacl applies. - * If pacl doesn't apply, something above should have - * executed a continue, which will skip the follwing code. - */ - action = XaceAllowOperation; - if (access_mode & DixReadAccess) - action = max(action, pacl->readAction); - if (access_mode & DixWriteAccess) - action = max(action, pacl->writeAction); - if (access_mode & DixDestroyAccess) - action = max(action, pacl->destroyAction); - break; - } /* end for each pacl */ - } /* end if propertyName <= SecurityMaxPropertyName */ - - if (XaceAllowOperation != action) - { /* audit the access violation */ - int cid = CLIENT_ID(pWin->drawable.id); - int reqtype = ((xReq *)client->requestBuffer)->reqType; - char *actionstr = (XaceIgnoreOperation == action) ? - "ignored" : "error"; - SecurityAudit("client %d attempted request %d with window 0x%x property %s (atom 0x%x) of client %d, %s\n", - client->index, reqtype, pWin->drawable.id, - NameForAtom(propertyName), propertyName, cid, actionstr); + default: + break; } - /* return codes increase with strictness */ - if (action > rec->rval) - rec->rval = action; -} /* SecurityCheckPropertyAccess */ - +} /* SecurityResetProc * @@ -1836,66 +1068,19 @@ static void SecurityResetProc( ExtensionEntry *extEntry) { - SecurityFreePropertyAccessList(); - SecurityFreeSitePolicyStrings(); -} /* SecurityResetProc */ - - -int -XSecurityOptions(argc, argv, i) - int argc; - char **argv; - int i; -{ - if (strcmp(argv[i], "-sp") == 0) - { - if (i < argc) - SecurityPolicyFile = argv[++i]; - return (i + 1); - } - return (i); -} /* XSecurityOptions */ - - -/* SecurityExtensionSetup - * - * Arguments: none. - * - * Returns: nothing. - * - * Side Effects: - * Sets up the Security extension if possible. - * This function contains things that need to be done - * before any other extension init functions get called. - */ - -void -SecurityExtensionSetup(INITARGS) -{ - /* Allocate the client private index */ - securityClientPrivateIndex = AllocateClientPrivateIndex(); - if (!AllocateClientPrivate(securityClientPrivateIndex, - sizeof (SecurityClientStateRec))) - FatalError("SecurityExtensionSetup: Can't allocate client private.\n"); - - /* Allocate the extension private index */ - securityExtnsnPrivateIndex = AllocateExtensionPrivateIndex(); - if (!AllocateExtensionPrivate(securityExtnsnPrivateIndex, 0)) - FatalError("SecurityExtensionSetup: Can't allocate extnsn private.\n"); - - /* register callbacks */ -#define XaceRC XaceRegisterCallback - XaceRC(XACE_RESOURCE_ACCESS, SecurityCheckResourceIDAccess, NULL); - XaceRC(XACE_DEVICE_ACCESS, SecurityCheckDeviceAccess, NULL); - XaceRC(XACE_PROPERTY_ACCESS, SecurityCheckPropertyAccess, NULL); - XaceRC(XACE_DRAWABLE_ACCESS, SecurityCheckDrawableAccess, NULL); - XaceRC(XACE_MAP_ACCESS, SecurityCheckMapAccess, NULL); - XaceRC(XACE_BACKGRND_ACCESS, SecurityCheckBackgrndAccess, NULL); - XaceRC(XACE_EXT_DISPATCH, SecurityCheckExtAccess, NULL); - XaceRC(XACE_EXT_ACCESS, SecurityCheckExtAccess, NULL); - XaceRC(XACE_HOSTLIST_ACCESS, SecurityCheckHostlistAccess, NULL); - XaceRC(XACE_DECLARE_EXT_SECURE, SecurityDeclareExtSecure, NULL); -} /* SecurityExtensionSetup */ + /* Unregister callbacks */ + DeleteCallback(&ClientStateCallback, SecurityClientState, NULL); + + XaceDeleteCallback(XACE_EXT_DISPATCH, SecurityExtension, NULL); + XaceDeleteCallback(XACE_RESOURCE_ACCESS, SecurityResource, NULL); + XaceDeleteCallback(XACE_DEVICE_ACCESS, SecurityDevice, NULL); + XaceDeleteCallback(XACE_PROPERTY_ACCESS, SecurityProperty, NULL); + XaceDeleteCallback(XACE_SEND_ACCESS, SecuritySend, NULL); + XaceDeleteCallback(XACE_RECEIVE_ACCESS, SecurityReceive, NULL); + XaceDeleteCallback(XACE_CLIENT_ACCESS, SecurityClient, NULL); + XaceDeleteCallback(XACE_EXT_ACCESS, SecurityExtension, NULL); + XaceDeleteCallback(XACE_SERVER_ACCESS, SecurityServer, NULL); +} /* SecurityExtensionInit @@ -1912,6 +1097,7 @@ void SecurityExtensionInit(INITARGS) { ExtensionEntry *extEntry; + int ret = TRUE; SecurityAuthorizationResType = CreateNewResourceType(SecurityDeleteAuthorization); @@ -1923,10 +1109,30 @@ SecurityExtensionInit(INITARGS) return; RTEventClient |= RC_NEVERRETAIN; + RegisterResourceName(SecurityAuthorizationResType, "SecurityAuthorization"); + RegisterResourceName(RTEventClient, "SecurityEventClient"); - if (!AddCallback(&ClientStateCallback, SecurityClientStateCallback, NULL)) - return; + /* Allocate the private storage */ + if (!dixRequestPrivate(stateKey, sizeof(SecurityStateRec))) + FatalError("SecurityExtensionSetup: Can't allocate client private.\n"); + + /* Register callbacks */ + ret &= AddCallback(&ClientStateCallback, SecurityClientState, NULL); + + ret &= XaceRegisterCallback(XACE_EXT_DISPATCH, SecurityExtension, NULL); + ret &= XaceRegisterCallback(XACE_RESOURCE_ACCESS, SecurityResource, NULL); + ret &= XaceRegisterCallback(XACE_DEVICE_ACCESS, SecurityDevice, NULL); + ret &= XaceRegisterCallback(XACE_PROPERTY_ACCESS, SecurityProperty, NULL); + ret &= XaceRegisterCallback(XACE_SEND_ACCESS, SecuritySend, NULL); + ret &= XaceRegisterCallback(XACE_RECEIVE_ACCESS, SecurityReceive, NULL); + ret &= XaceRegisterCallback(XACE_CLIENT_ACCESS, SecurityClient, NULL); + ret &= XaceRegisterCallback(XACE_EXT_ACCESS, SecurityExtension, NULL); + ret &= XaceRegisterCallback(XACE_SERVER_ACCESS, SecurityServer, NULL); + if (!ret) + FatalError("SecurityExtensionSetup: Failed to register callbacks\n"); + + /* Add extension to server */ extEntry = AddExtension(SECURITY_EXTENSION_NAME, XSecurityNumberEvents, XSecurityNumberErrors, ProcSecurityDispatch, SProcSecurityDispatch, @@ -1938,6 +1144,6 @@ SecurityExtensionInit(INITARGS) EventSwapVector[SecurityEventBase + XSecurityAuthorizationRevoked] = (EventSwapPtr)SwapSecurityAuthorizationRevokedEvent; - SecurityLoadPropertyAccessList(); - -} /* SecurityExtensionInit */ + /* Label objects that were created before we could register ourself */ + SecurityLabelInitial(); +} |