aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/Xext/xselinux_ext.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2011-02-03 11:20:18 +0000
committermarha <marha@users.sourceforge.net>2011-02-03 11:20:18 +0000
commit46fbac6f1b19416ee1dbca883f0d09d9fd75d1eb (patch)
tree2ddc90cb6bc4f04db80d66a334ecaabf139c0176 /xorg-server/Xext/xselinux_ext.c
parent97f3d3043a79d6031787c246a67d2a02ff0a8d08 (diff)
parent83a4fe0dc71aafbef11477b284abe530d3877556 (diff)
downloadvcxsrv-46fbac6f1b19416ee1dbca883f0d09d9fd75d1eb.tar.gz
vcxsrv-46fbac6f1b19416ee1dbca883f0d09d9fd75d1eb.tar.bz2
vcxsrv-46fbac6f1b19416ee1dbca883f0d09d9fd75d1eb.zip
svn merge ^/branches/released .
Diffstat (limited to 'xorg-server/Xext/xselinux_ext.c')
-rw-r--r--xorg-server/Xext/xselinux_ext.c1466
1 files changed, 732 insertions, 734 deletions
diff --git a/xorg-server/Xext/xselinux_ext.c b/xorg-server/Xext/xselinux_ext.c
index 0076cedb4..374571c4b 100644
--- a/xorg-server/Xext/xselinux_ext.c
+++ b/xorg-server/Xext/xselinux_ext.c
@@ -1,734 +1,732 @@
-/************************************************************
-
-Author: Eamon Walsh <ewalsh@tycho.nsa.gov>
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-this permission notice appear in supporting documentation. This permission
-notice shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-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 OR OTHER DEALINGS IN THE SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "selection.h"
-#include "inputstr.h"
-#include "windowstr.h"
-#include "propertyst.h"
-#include "extnsionst.h"
-#include "modinit.h"
-#include "xselinuxint.h"
-
-#define CTX_DEV offsetof(SELinuxSubjectRec, dev_create_sid)
-#define CTX_WIN offsetof(SELinuxSubjectRec, win_create_sid)
-#define CTX_PRP offsetof(SELinuxSubjectRec, prp_create_sid)
-#define CTX_SEL offsetof(SELinuxSubjectRec, sel_create_sid)
-#define USE_PRP offsetof(SELinuxSubjectRec, prp_use_sid)
-#define USE_SEL offsetof(SELinuxSubjectRec, sel_use_sid)
-
-typedef struct {
- security_context_t octx;
- security_context_t dctx;
- CARD32 octx_len;
- CARD32 dctx_len;
- CARD32 id;
-} SELinuxListItemRec;
-
-
-/*
- * Extension Dispatch
- */
-
-static security_context_t
-SELinuxCopyContext(char *ptr, unsigned len)
-{
- security_context_t copy = malloc(len + 1);
- if (!copy)
- return NULL;
- strncpy(copy, ptr, len);
- copy[len] = '\0';
- return copy;
-}
-
-static int
-ProcSELinuxQueryVersion(ClientPtr client)
-{
- SELinuxQueryVersionReply rep;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.server_major = SELINUX_MAJOR_VERSION;
- rep.server_minor = SELINUX_MINOR_VERSION;
- if (client->swapped) {
- int n;
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.server_major, n);
- swaps(&rep.server_minor, n);
- }
- WriteToClient(client, sizeof(rep), (char *)&rep);
- return Success;
-}
-
-static int
-SELinuxSendContextReply(ClientPtr client, security_id_t sid)
-{
- SELinuxGetContextReply rep;
- security_context_t ctx = NULL;
- int len = 0;
-
- if (sid) {
- if (avc_sid_to_context_raw(sid, &ctx) < 0)
- return BadValue;
- len = strlen(ctx) + 1;
- }
-
- rep.type = X_Reply;
- rep.length = bytes_to_int32(len);
- rep.sequenceNumber = client->sequence;
- rep.context_len = len;
-
- if (client->swapped) {
- int n;
- swapl(&rep.length, n);
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.context_len, n);
- }
-
- WriteToClient(client, sizeof(SELinuxGetContextReply), (char *)&rep);
- WriteToClient(client, len, ctx);
- freecon(ctx);
- return Success;
-}
-
-static int
-ProcSELinuxSetCreateContext(ClientPtr client, unsigned offset)
-{
- PrivateRec **privPtr = &client->devPrivates;
- security_id_t *pSid;
- security_context_t ctx = NULL;
- char *ptr;
- int rc;
-
- REQUEST(SELinuxSetCreateContextReq);
- REQUEST_FIXED_SIZE(SELinuxSetCreateContextReq, stuff->context_len);
-
- if (stuff->context_len > 0) {
- ctx = SELinuxCopyContext((char *)(stuff + 1), stuff->context_len);
- if (!ctx)
- return BadAlloc;
- }
-
- ptr = dixLookupPrivate(privPtr, subjectKey);
- pSid = (security_id_t *)(ptr + offset);
- *pSid = NULL;
-
- rc = Success;
- if (stuff->context_len > 0) {
- if (security_check_context_raw(ctx) < 0 ||
- avc_context_to_sid_raw(ctx, pSid) < 0)
- rc = BadValue;
- }
-
- free(ctx);
- return rc;
-}
-
-static int
-ProcSELinuxGetCreateContext(ClientPtr client, unsigned offset)
-{
- security_id_t *pSid;
- char *ptr;
-
- REQUEST_SIZE_MATCH(SELinuxGetCreateContextReq);
-
- if (offset == CTX_DEV)
- ptr = dixLookupPrivate(&serverClient->devPrivates, subjectKey);
- else
- ptr = dixLookupPrivate(&client->devPrivates, subjectKey);
-
- pSid = (security_id_t *)(ptr + offset);
- return SELinuxSendContextReply(client, *pSid);
-}
-
-static int
-ProcSELinuxSetDeviceContext(ClientPtr client)
-{
- security_context_t ctx;
- security_id_t sid;
- DeviceIntPtr dev;
- SELinuxSubjectRec *subj;
- SELinuxObjectRec *obj;
- int rc;
-
- REQUEST(SELinuxSetContextReq);
- REQUEST_FIXED_SIZE(SELinuxSetContextReq, stuff->context_len);
-
- if (stuff->context_len < 1)
- return BadLength;
- ctx = SELinuxCopyContext((char *)(stuff + 1), stuff->context_len);
- if (!ctx)
- return BadAlloc;
-
- rc = dixLookupDevice(&dev, stuff->id, client, DixManageAccess);
- if (rc != Success)
- goto out;
-
- if (security_check_context_raw(ctx) < 0 ||
- avc_context_to_sid_raw(ctx, &sid) < 0) {
- rc = BadValue;
- goto out;
- }
-
- subj = dixLookupPrivate(&dev->devPrivates, subjectKey);
- subj->sid = sid;
- obj = dixLookupPrivate(&dev->devPrivates, objectKey);
- obj->sid = sid;
-
- rc = Success;
-out:
- free(ctx);
- return rc;
-}
-
-static int
-ProcSELinuxGetDeviceContext(ClientPtr client)
-{
- DeviceIntPtr dev;
- SELinuxSubjectRec *subj;
- int rc;
-
- REQUEST(SELinuxGetContextReq);
- REQUEST_SIZE_MATCH(SELinuxGetContextReq);
-
- rc = dixLookupDevice(&dev, stuff->id, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- subj = dixLookupPrivate(&dev->devPrivates, subjectKey);
- return SELinuxSendContextReply(client, subj->sid);
-}
-
-static int
-ProcSELinuxGetDrawableContext(ClientPtr client)
-{
- DrawablePtr pDraw;
- PrivateRec **privatePtr;
- SELinuxObjectRec *obj;
- int rc;
-
- REQUEST(SELinuxGetContextReq);
- REQUEST_SIZE_MATCH(SELinuxGetContextReq);
-
- rc = dixLookupDrawable(&pDraw, stuff->id, client,
- M_WINDOW | M_DRAWABLE_PIXMAP,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- if (pDraw->type == M_DRAWABLE_PIXMAP)
- privatePtr = &((PixmapPtr)pDraw)->devPrivates;
- else
- privatePtr = &((WindowPtr)pDraw)->devPrivates;
-
- obj = dixLookupPrivate(privatePtr, objectKey);
- return SELinuxSendContextReply(client, obj->sid);
-}
-
-static int
-ProcSELinuxGetPropertyContext(ClientPtr client, pointer privKey)
-{
- WindowPtr pWin;
- PropertyPtr pProp;
- SELinuxObjectRec *obj;
- int rc;
-
- REQUEST(SELinuxGetPropertyContextReq);
- REQUEST_SIZE_MATCH(SELinuxGetPropertyContextReq);
-
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetPropAccess);
- if (rc != Success)
- return rc;
-
- rc = dixLookupProperty(&pProp, pWin, stuff->property, client,
- DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- obj = dixLookupPrivate(&pProp->devPrivates, privKey);
- return SELinuxSendContextReply(client, obj->sid);
-}
-
-static int
-ProcSELinuxGetSelectionContext(ClientPtr client, pointer privKey)
-{
- Selection *pSel;
- SELinuxObjectRec *obj;
- int rc;
-
- REQUEST(SELinuxGetContextReq);
- REQUEST_SIZE_MATCH(SELinuxGetContextReq);
-
- rc = dixLookupSelection(&pSel, stuff->id, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- obj = dixLookupPrivate(&pSel->devPrivates, privKey);
- return SELinuxSendContextReply(client, obj->sid);
-}
-
-static int
-ProcSELinuxGetClientContext(ClientPtr client)
-{
- ClientPtr target;
- SELinuxSubjectRec *subj;
- int rc;
-
- REQUEST(SELinuxGetContextReq);
- REQUEST_SIZE_MATCH(SELinuxGetContextReq);
-
- rc = dixLookupClient(&target, stuff->id, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- subj = dixLookupPrivate(&target->devPrivates, subjectKey);
- return SELinuxSendContextReply(client, subj->sid);
-}
-
-static int
-SELinuxPopulateItem(SELinuxListItemRec *i, PrivateRec **privPtr, CARD32 id,
- int *size)
-{
- SELinuxObjectRec *obj = dixLookupPrivate(privPtr, objectKey);
- SELinuxObjectRec *data = dixLookupPrivate(privPtr, dataKey);
-
- if (avc_sid_to_context_raw(obj->sid, &i->octx) < 0)
- return BadValue;
- if (avc_sid_to_context_raw(data->sid, &i->dctx) < 0)
- return BadValue;
-
- i->id = id;
- i->octx_len = bytes_to_int32(strlen(i->octx) + 1);
- i->dctx_len = bytes_to_int32(strlen(i->dctx) + 1);
-
- *size += i->octx_len + i->dctx_len + 3;
- return Success;
-}
-
-static void
-SELinuxFreeItems(SELinuxListItemRec *items, int count)
-{
- int k;
- for (k = 0; k < count; k++) {
- freecon(items[k].octx);
- freecon(items[k].dctx);
- }
- free(items);
-}
-
-static int
-SELinuxSendItemsToClient(ClientPtr client, SELinuxListItemRec *items,
- int size, int count)
-{
- int rc, k, n, pos = 0;
- SELinuxListItemsReply rep;
- CARD32 *buf;
-
- buf = calloc(size, sizeof(CARD32));
- if (size && !buf) {
- rc = BadAlloc;
- goto out;
- }
-
- /* Fill in the buffer */
- for (k = 0; k < count; k++) {
- buf[pos] = items[k].id;
- if (client->swapped)
- swapl(buf + pos, n);
- pos++;
-
- buf[pos] = items[k].octx_len * 4;
- if (client->swapped)
- swapl(buf + pos, n);
- pos++;
-
- buf[pos] = items[k].dctx_len * 4;
- if (client->swapped)
- swapl(buf + pos, n);
- pos++;
-
- memcpy((char *)(buf + pos), items[k].octx, strlen(items[k].octx) + 1);
- pos += items[k].octx_len;
- memcpy((char *)(buf + pos), items[k].dctx, strlen(items[k].dctx) + 1);
- pos += items[k].dctx_len;
- }
-
- /* Send reply to client */
- rep.type = X_Reply;
- rep.length = size;
- rep.sequenceNumber = client->sequence;
- rep.count = count;
-
- if (client->swapped) {
- swapl(&rep.length, n);
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.count, n);
- }
-
- WriteToClient(client, sizeof(SELinuxListItemsReply), (char *)&rep);
- WriteToClient(client, size * 4, (char *)buf);
-
- /* Free stuff and return */
- rc = Success;
- free(buf);
-out:
- SELinuxFreeItems(items, count);
- return rc;
-}
-
-static int
-ProcSELinuxListProperties(ClientPtr client)
-{
- WindowPtr pWin;
- PropertyPtr pProp;
- SELinuxListItemRec *items;
- int rc, count, size, i;
- CARD32 id;
-
- REQUEST(SELinuxGetContextReq);
- REQUEST_SIZE_MATCH(SELinuxGetContextReq);
-
- rc = dixLookupWindow(&pWin, stuff->id, client, DixListPropAccess);
- if (rc != Success)
- return rc;
-
- /* Count the number of properties and allocate items */
- count = 0;
- for (pProp = wUserProps(pWin); pProp; pProp = pProp->next)
- count++;
- items = calloc(count, sizeof(SELinuxListItemRec));
- if (count && !items)
- return BadAlloc;
-
- /* Fill in the items and calculate size */
- i = 0;
- size = 0;
- for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) {
- id = pProp->propertyName;
- rc = SELinuxPopulateItem(items + i, &pProp->devPrivates, id, &size);
- if (rc != Success) {
- SELinuxFreeItems(items, count);
- return rc;
- }
- i++;
- }
-
- return SELinuxSendItemsToClient(client, items, size, count);
-}
-
-static int
-ProcSELinuxListSelections(ClientPtr client)
-{
- Selection *pSel;
- SELinuxListItemRec *items;
- int rc, count, size, i;
- CARD32 id;
-
- REQUEST_SIZE_MATCH(SELinuxGetCreateContextReq);
-
- /* Count the number of selections and allocate items */
- count = 0;
- for (pSel = CurrentSelections; pSel; pSel = pSel->next)
- count++;
- items = calloc(count, sizeof(SELinuxListItemRec));
- if (count && !items)
- return BadAlloc;
-
- /* Fill in the items and calculate size */
- i = 0;
- size = 0;
- for (pSel = CurrentSelections; pSel; pSel = pSel->next) {
- id = pSel->selection;
- rc = SELinuxPopulateItem(items + i, &pSel->devPrivates, id, &size);
- if (rc != Success) {
- SELinuxFreeItems(items, count);
- return rc;
- }
- i++;
- }
-
- return SELinuxSendItemsToClient(client, items, size, count);
-}
-
-static int
-ProcSELinuxDispatch(ClientPtr client)
-{
- REQUEST(xReq);
- switch (stuff->data) {
- case X_SELinuxQueryVersion:
- return ProcSELinuxQueryVersion(client);
- case X_SELinuxSetDeviceCreateContext:
- return ProcSELinuxSetCreateContext(client, CTX_DEV);
- case X_SELinuxGetDeviceCreateContext:
- return ProcSELinuxGetCreateContext(client, CTX_DEV);
- case X_SELinuxSetDeviceContext:
- return ProcSELinuxSetDeviceContext(client);
- case X_SELinuxGetDeviceContext:
- return ProcSELinuxGetDeviceContext(client);
- case X_SELinuxSetDrawableCreateContext:
- return ProcSELinuxSetCreateContext(client, CTX_WIN);
- case X_SELinuxGetDrawableCreateContext:
- return ProcSELinuxGetCreateContext(client, CTX_WIN);
- case X_SELinuxGetDrawableContext:
- return ProcSELinuxGetDrawableContext(client);
- case X_SELinuxSetPropertyCreateContext:
- return ProcSELinuxSetCreateContext(client, CTX_PRP);
- case X_SELinuxGetPropertyCreateContext:
- return ProcSELinuxGetCreateContext(client, CTX_PRP);
- case X_SELinuxSetPropertyUseContext:
- return ProcSELinuxSetCreateContext(client, USE_PRP);
- case X_SELinuxGetPropertyUseContext:
- return ProcSELinuxGetCreateContext(client, USE_PRP);
- case X_SELinuxGetPropertyContext:
- return ProcSELinuxGetPropertyContext(client, objectKey);
- case X_SELinuxGetPropertyDataContext:
- return ProcSELinuxGetPropertyContext(client, dataKey);
- case X_SELinuxListProperties:
- return ProcSELinuxListProperties(client);
- case X_SELinuxSetSelectionCreateContext:
- return ProcSELinuxSetCreateContext(client, CTX_SEL);
- case X_SELinuxGetSelectionCreateContext:
- return ProcSELinuxGetCreateContext(client, CTX_SEL);
- case X_SELinuxSetSelectionUseContext:
- return ProcSELinuxSetCreateContext(client, USE_SEL);
- case X_SELinuxGetSelectionUseContext:
- return ProcSELinuxGetCreateContext(client, USE_SEL);
- case X_SELinuxGetSelectionContext:
- return ProcSELinuxGetSelectionContext(client, objectKey);
- case X_SELinuxGetSelectionDataContext:
- return ProcSELinuxGetSelectionContext(client, dataKey);
- case X_SELinuxListSelections:
- return ProcSELinuxListSelections(client);
- case X_SELinuxGetClientContext:
- return ProcSELinuxGetClientContext(client);
- default:
- return BadRequest;
- }
-}
-
-static int
-SProcSELinuxQueryVersion(ClientPtr client)
-{
- REQUEST(SELinuxQueryVersionReq);
- int n;
-
- REQUEST_SIZE_MATCH(SELinuxQueryVersionReq);
- swaps(&stuff->client_major, n);
- swaps(&stuff->client_minor, n);
- return ProcSELinuxQueryVersion(client);
-}
-
-static int
-SProcSELinuxSetCreateContext(ClientPtr client, unsigned offset)
-{
- REQUEST(SELinuxSetCreateContextReq);
- int n;
-
- REQUEST_AT_LEAST_SIZE(SELinuxSetCreateContextReq);
- swapl(&stuff->context_len, n);
- return ProcSELinuxSetCreateContext(client, offset);
-}
-
-static int
-SProcSELinuxSetDeviceContext(ClientPtr client)
-{
- REQUEST(SELinuxSetContextReq);
- int n;
-
- REQUEST_AT_LEAST_SIZE(SELinuxSetContextReq);
- swapl(&stuff->id, n);
- swapl(&stuff->context_len, n);
- return ProcSELinuxSetDeviceContext(client);
-}
-
-static int
-SProcSELinuxGetDeviceContext(ClientPtr client)
-{
- REQUEST(SELinuxGetContextReq);
- int n;
-
- REQUEST_SIZE_MATCH(SELinuxGetContextReq);
- swapl(&stuff->id, n);
- return ProcSELinuxGetDeviceContext(client);
-}
-
-static int
-SProcSELinuxGetDrawableContext(ClientPtr client)
-{
- REQUEST(SELinuxGetContextReq);
- int n;
-
- REQUEST_SIZE_MATCH(SELinuxGetContextReq);
- swapl(&stuff->id, n);
- return ProcSELinuxGetDrawableContext(client);
-}
-
-static int
-SProcSELinuxGetPropertyContext(ClientPtr client, pointer privKey)
-{
- REQUEST(SELinuxGetPropertyContextReq);
- int n;
-
- REQUEST_SIZE_MATCH(SELinuxGetPropertyContextReq);
- swapl(&stuff->window, n);
- swapl(&stuff->property, n);
- return ProcSELinuxGetPropertyContext(client, privKey);
-}
-
-static int
-SProcSELinuxGetSelectionContext(ClientPtr client, pointer privKey)
-{
- REQUEST(SELinuxGetContextReq);
- int n;
-
- REQUEST_SIZE_MATCH(SELinuxGetContextReq);
- swapl(&stuff->id, n);
- return ProcSELinuxGetSelectionContext(client, privKey);
-}
-
-static int
-SProcSELinuxListProperties(ClientPtr client)
-{
- REQUEST(SELinuxGetContextReq);
- int n;
-
- REQUEST_SIZE_MATCH(SELinuxGetContextReq);
- swapl(&stuff->id, n);
- return ProcSELinuxListProperties(client);
-}
-
-static int
-SProcSELinuxGetClientContext(ClientPtr client)
-{
- REQUEST(SELinuxGetContextReq);
- int n;
-
- REQUEST_SIZE_MATCH(SELinuxGetContextReq);
- swapl(&stuff->id, n);
- return ProcSELinuxGetClientContext(client);
-}
-
-static int
-SProcSELinuxDispatch(ClientPtr client)
-{
- REQUEST(xReq);
- int n;
-
- swaps(&stuff->length, n);
-
- switch (stuff->data) {
- case X_SELinuxQueryVersion:
- return SProcSELinuxQueryVersion(client);
- case X_SELinuxSetDeviceCreateContext:
- return SProcSELinuxSetCreateContext(client, CTX_DEV);
- case X_SELinuxGetDeviceCreateContext:
- return ProcSELinuxGetCreateContext(client, CTX_DEV);
- case X_SELinuxSetDeviceContext:
- return SProcSELinuxSetDeviceContext(client);
- case X_SELinuxGetDeviceContext:
- return SProcSELinuxGetDeviceContext(client);
- case X_SELinuxSetDrawableCreateContext:
- return SProcSELinuxSetCreateContext(client, CTX_WIN);
- case X_SELinuxGetDrawableCreateContext:
- return ProcSELinuxGetCreateContext(client, CTX_WIN);
- case X_SELinuxGetDrawableContext:
- return SProcSELinuxGetDrawableContext(client);
- case X_SELinuxSetPropertyCreateContext:
- return SProcSELinuxSetCreateContext(client, CTX_PRP);
- case X_SELinuxGetPropertyCreateContext:
- return ProcSELinuxGetCreateContext(client, CTX_PRP);
- case X_SELinuxSetPropertyUseContext:
- return SProcSELinuxSetCreateContext(client, USE_PRP);
- case X_SELinuxGetPropertyUseContext:
- return ProcSELinuxGetCreateContext(client, USE_PRP);
- case X_SELinuxGetPropertyContext:
- return SProcSELinuxGetPropertyContext(client, objectKey);
- case X_SELinuxGetPropertyDataContext:
- return SProcSELinuxGetPropertyContext(client, dataKey);
- case X_SELinuxListProperties:
- return SProcSELinuxListProperties(client);
- case X_SELinuxSetSelectionCreateContext:
- return SProcSELinuxSetCreateContext(client, CTX_SEL);
- case X_SELinuxGetSelectionCreateContext:
- return ProcSELinuxGetCreateContext(client, CTX_SEL);
- case X_SELinuxSetSelectionUseContext:
- return SProcSELinuxSetCreateContext(client, USE_SEL);
- case X_SELinuxGetSelectionUseContext:
- return ProcSELinuxGetCreateContext(client, USE_SEL);
- case X_SELinuxGetSelectionContext:
- return SProcSELinuxGetSelectionContext(client, objectKey);
- case X_SELinuxGetSelectionDataContext:
- return SProcSELinuxGetSelectionContext(client, dataKey);
- case X_SELinuxListSelections:
- return ProcSELinuxListSelections(client);
- case X_SELinuxGetClientContext:
- return SProcSELinuxGetClientContext(client);
- default:
- return BadRequest;
- }
-}
-
-
-/*
- * Extension Setup / Teardown
- */
-
-static void
-SELinuxResetProc(ExtensionEntry *extEntry)
-{
- SELinuxFlaskReset();
- SELinuxLabelReset();
-}
-
-void
-SELinuxExtensionInit(INITARGS)
-{
- ExtensionEntry *extEntry;
-
- /* Check SELinux mode on system, configuration file, and boolean */
- if (!is_selinux_enabled()) {
- LogMessage(X_INFO, "SELinux: Disabled on system\n");
- return;
- }
- if (selinuxEnforcingState == SELINUX_MODE_DISABLED) {
- LogMessage(X_INFO, "SELinux: Disabled in configuration file\n");
- return;
- }
- if (!security_get_boolean_active("xserver_object_manager")) {
- LogMessage(X_INFO, "SELinux: Disabled by boolean\n");
- return;
- }
-
- /* Set up XACE hooks */
- SELinuxLabelInit();
- SELinuxFlaskInit();
-
- /* Add extension to server */
- extEntry = AddExtension(SELINUX_EXTENSION_NAME,
- SELinuxNumberEvents, SELinuxNumberErrors,
- ProcSELinuxDispatch, SProcSELinuxDispatch,
- SELinuxResetProc, StandardMinorOpcode);
-
- AddExtensionAlias("Flask", extEntry);
-}
+/************************************************************
+
+Author: Eamon Walsh <ewalsh@tycho.nsa.gov>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+this permission notice appear in supporting documentation. This permission
+notice shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+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 OR OTHER DEALINGS IN THE SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "selection.h"
+#include "inputstr.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#include "extnsionst.h"
+#include "modinit.h"
+#include "xselinuxint.h"
+
+#define CTX_DEV offsetof(SELinuxSubjectRec, dev_create_sid)
+#define CTX_WIN offsetof(SELinuxSubjectRec, win_create_sid)
+#define CTX_PRP offsetof(SELinuxSubjectRec, prp_create_sid)
+#define CTX_SEL offsetof(SELinuxSubjectRec, sel_create_sid)
+#define USE_PRP offsetof(SELinuxSubjectRec, prp_use_sid)
+#define USE_SEL offsetof(SELinuxSubjectRec, sel_use_sid)
+
+typedef struct {
+ security_context_t octx;
+ security_context_t dctx;
+ CARD32 octx_len;
+ CARD32 dctx_len;
+ CARD32 id;
+} SELinuxListItemRec;
+
+
+/*
+ * Extension Dispatch
+ */
+
+static security_context_t
+SELinuxCopyContext(char *ptr, unsigned len)
+{
+ security_context_t copy = malloc(len + 1);
+ if (!copy)
+ return NULL;
+ strncpy(copy, ptr, len);
+ copy[len] = '\0';
+ return copy;
+}
+
+static int
+ProcSELinuxQueryVersion(ClientPtr client)
+{
+ SELinuxQueryVersionReply rep;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.server_major = SELINUX_MAJOR_VERSION;
+ rep.server_minor = SELINUX_MINOR_VERSION;
+ if (client->swapped) {
+ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.server_major, n);
+ swaps(&rep.server_minor, n);
+ }
+ WriteToClient(client, sizeof(rep), (char *)&rep);
+ return Success;
+}
+
+static int
+SELinuxSendContextReply(ClientPtr client, security_id_t sid)
+{
+ SELinuxGetContextReply rep;
+ security_context_t ctx = NULL;
+ int len = 0;
+
+ if (sid) {
+ if (avc_sid_to_context_raw(sid, &ctx) < 0)
+ return BadValue;
+ len = strlen(ctx) + 1;
+ }
+
+ rep.type = X_Reply;
+ rep.length = bytes_to_int32(len);
+ rep.sequenceNumber = client->sequence;
+ rep.context_len = len;
+
+ if (client->swapped) {
+ int n;
+ swapl(&rep.length, n);
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.context_len, n);
+ }
+
+ WriteToClient(client, sizeof(SELinuxGetContextReply), (char *)&rep);
+ WriteToClient(client, len, ctx);
+ freecon(ctx);
+ return Success;
+}
+
+static int
+ProcSELinuxSetCreateContext(ClientPtr client, unsigned offset)
+{
+ PrivateRec **privPtr = &client->devPrivates;
+ security_id_t *pSid;
+ security_context_t ctx = NULL;
+ char *ptr;
+ int rc;
+
+ REQUEST(SELinuxSetCreateContextReq);
+ REQUEST_FIXED_SIZE(SELinuxSetCreateContextReq, stuff->context_len);
+
+ if (stuff->context_len > 0) {
+ ctx = SELinuxCopyContext((char *)(stuff + 1), stuff->context_len);
+ if (!ctx)
+ return BadAlloc;
+ }
+
+ ptr = dixLookupPrivate(privPtr, subjectKey);
+ pSid = (security_id_t *)(ptr + offset);
+ *pSid = NULL;
+
+ rc = Success;
+ if (stuff->context_len > 0) {
+ if (security_check_context_raw(ctx) < 0 ||
+ avc_context_to_sid_raw(ctx, pSid) < 0)
+ rc = BadValue;
+ }
+
+ free(ctx);
+ return rc;
+}
+
+static int
+ProcSELinuxGetCreateContext(ClientPtr client, unsigned offset)
+{
+ security_id_t *pSid;
+ char *ptr;
+
+ REQUEST_SIZE_MATCH(SELinuxGetCreateContextReq);
+
+ if (offset == CTX_DEV)
+ ptr = dixLookupPrivate(&serverClient->devPrivates, subjectKey);
+ else
+ ptr = dixLookupPrivate(&client->devPrivates, subjectKey);
+
+ pSid = (security_id_t *)(ptr + offset);
+ return SELinuxSendContextReply(client, *pSid);
+}
+
+static int
+ProcSELinuxSetDeviceContext(ClientPtr client)
+{
+ security_context_t ctx;
+ security_id_t sid;
+ DeviceIntPtr dev;
+ SELinuxSubjectRec *subj;
+ SELinuxObjectRec *obj;
+ int rc;
+
+ REQUEST(SELinuxSetContextReq);
+ REQUEST_FIXED_SIZE(SELinuxSetContextReq, stuff->context_len);
+
+ if (stuff->context_len < 1)
+ return BadLength;
+ ctx = SELinuxCopyContext((char *)(stuff + 1), stuff->context_len);
+ if (!ctx)
+ return BadAlloc;
+
+ rc = dixLookupDevice(&dev, stuff->id, client, DixManageAccess);
+ if (rc != Success)
+ goto out;
+
+ if (security_check_context_raw(ctx) < 0 ||
+ avc_context_to_sid_raw(ctx, &sid) < 0) {
+ rc = BadValue;
+ goto out;
+ }
+
+ subj = dixLookupPrivate(&dev->devPrivates, subjectKey);
+ subj->sid = sid;
+ obj = dixLookupPrivate(&dev->devPrivates, objectKey);
+ obj->sid = sid;
+
+ rc = Success;
+out:
+ free(ctx);
+ return rc;
+}
+
+static int
+ProcSELinuxGetDeviceContext(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ SELinuxSubjectRec *subj;
+ int rc;
+
+ REQUEST(SELinuxGetContextReq);
+ REQUEST_SIZE_MATCH(SELinuxGetContextReq);
+
+ rc = dixLookupDevice(&dev, stuff->id, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ subj = dixLookupPrivate(&dev->devPrivates, subjectKey);
+ return SELinuxSendContextReply(client, subj->sid);
+}
+
+static int
+ProcSELinuxGetDrawableContext(ClientPtr client)
+{
+ DrawablePtr pDraw;
+ PrivateRec **privatePtr;
+ SELinuxObjectRec *obj;
+ int rc;
+
+ REQUEST(SELinuxGetContextReq);
+ REQUEST_SIZE_MATCH(SELinuxGetContextReq);
+
+ rc = dixLookupDrawable(&pDraw, stuff->id, client, 0, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ if (pDraw->type == DRAWABLE_PIXMAP)
+ privatePtr = &((PixmapPtr)pDraw)->devPrivates;
+ else
+ privatePtr = &((WindowPtr)pDraw)->devPrivates;
+
+ obj = dixLookupPrivate(privatePtr, objectKey);
+ return SELinuxSendContextReply(client, obj->sid);
+}
+
+static int
+ProcSELinuxGetPropertyContext(ClientPtr client, pointer privKey)
+{
+ WindowPtr pWin;
+ PropertyPtr pProp;
+ SELinuxObjectRec *obj;
+ int rc;
+
+ REQUEST(SELinuxGetPropertyContextReq);
+ REQUEST_SIZE_MATCH(SELinuxGetPropertyContextReq);
+
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetPropAccess);
+ if (rc != Success)
+ return rc;
+
+ rc = dixLookupProperty(&pProp, pWin, stuff->property, client,
+ DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ obj = dixLookupPrivate(&pProp->devPrivates, privKey);
+ return SELinuxSendContextReply(client, obj->sid);
+}
+
+static int
+ProcSELinuxGetSelectionContext(ClientPtr client, pointer privKey)
+{
+ Selection *pSel;
+ SELinuxObjectRec *obj;
+ int rc;
+
+ REQUEST(SELinuxGetContextReq);
+ REQUEST_SIZE_MATCH(SELinuxGetContextReq);
+
+ rc = dixLookupSelection(&pSel, stuff->id, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ obj = dixLookupPrivate(&pSel->devPrivates, privKey);
+ return SELinuxSendContextReply(client, obj->sid);
+}
+
+static int
+ProcSELinuxGetClientContext(ClientPtr client)
+{
+ ClientPtr target;
+ SELinuxSubjectRec *subj;
+ int rc;
+
+ REQUEST(SELinuxGetContextReq);
+ REQUEST_SIZE_MATCH(SELinuxGetContextReq);
+
+ rc = dixLookupClient(&target, stuff->id, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ subj = dixLookupPrivate(&target->devPrivates, subjectKey);
+ return SELinuxSendContextReply(client, subj->sid);
+}
+
+static int
+SELinuxPopulateItem(SELinuxListItemRec *i, PrivateRec **privPtr, CARD32 id,
+ int *size)
+{
+ SELinuxObjectRec *obj = dixLookupPrivate(privPtr, objectKey);
+ SELinuxObjectRec *data = dixLookupPrivate(privPtr, dataKey);
+
+ if (avc_sid_to_context_raw(obj->sid, &i->octx) < 0)
+ return BadValue;
+ if (avc_sid_to_context_raw(data->sid, &i->dctx) < 0)
+ return BadValue;
+
+ i->id = id;
+ i->octx_len = bytes_to_int32(strlen(i->octx) + 1);
+ i->dctx_len = bytes_to_int32(strlen(i->dctx) + 1);
+
+ *size += i->octx_len + i->dctx_len + 3;
+ return Success;
+}
+
+static void
+SELinuxFreeItems(SELinuxListItemRec *items, int count)
+{
+ int k;
+ for (k = 0; k < count; k++) {
+ freecon(items[k].octx);
+ freecon(items[k].dctx);
+ }
+ free(items);
+}
+
+static int
+SELinuxSendItemsToClient(ClientPtr client, SELinuxListItemRec *items,
+ int size, int count)
+{
+ int rc, k, n, pos = 0;
+ SELinuxListItemsReply rep;
+ CARD32 *buf;
+
+ buf = calloc(size, sizeof(CARD32));
+ if (size && !buf) {
+ rc = BadAlloc;
+ goto out;
+ }
+
+ /* Fill in the buffer */
+ for (k = 0; k < count; k++) {
+ buf[pos] = items[k].id;
+ if (client->swapped)
+ swapl(buf + pos, n);
+ pos++;
+
+ buf[pos] = items[k].octx_len * 4;
+ if (client->swapped)
+ swapl(buf + pos, n);
+ pos++;
+
+ buf[pos] = items[k].dctx_len * 4;
+ if (client->swapped)
+ swapl(buf + pos, n);
+ pos++;
+
+ memcpy((char *)(buf + pos), items[k].octx, strlen(items[k].octx) + 1);
+ pos += items[k].octx_len;
+ memcpy((char *)(buf + pos), items[k].dctx, strlen(items[k].dctx) + 1);
+ pos += items[k].dctx_len;
+ }
+
+ /* Send reply to client */
+ rep.type = X_Reply;
+ rep.length = size;
+ rep.sequenceNumber = client->sequence;
+ rep.count = count;
+
+ if (client->swapped) {
+ swapl(&rep.length, n);
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.count, n);
+ }
+
+ WriteToClient(client, sizeof(SELinuxListItemsReply), (char *)&rep);
+ WriteToClient(client, size * 4, (char *)buf);
+
+ /* Free stuff and return */
+ rc = Success;
+ free(buf);
+out:
+ SELinuxFreeItems(items, count);
+ return rc;
+}
+
+static int
+ProcSELinuxListProperties(ClientPtr client)
+{
+ WindowPtr pWin;
+ PropertyPtr pProp;
+ SELinuxListItemRec *items;
+ int rc, count, size, i;
+ CARD32 id;
+
+ REQUEST(SELinuxGetContextReq);
+ REQUEST_SIZE_MATCH(SELinuxGetContextReq);
+
+ rc = dixLookupWindow(&pWin, stuff->id, client, DixListPropAccess);
+ if (rc != Success)
+ return rc;
+
+ /* Count the number of properties and allocate items */
+ count = 0;
+ for (pProp = wUserProps(pWin); pProp; pProp = pProp->next)
+ count++;
+ items = calloc(count, sizeof(SELinuxListItemRec));
+ if (count && !items)
+ return BadAlloc;
+
+ /* Fill in the items and calculate size */
+ i = 0;
+ size = 0;
+ for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) {
+ id = pProp->propertyName;
+ rc = SELinuxPopulateItem(items + i, &pProp->devPrivates, id, &size);
+ if (rc != Success) {
+ SELinuxFreeItems(items, count);
+ return rc;
+ }
+ i++;
+ }
+
+ return SELinuxSendItemsToClient(client, items, size, count);
+}
+
+static int
+ProcSELinuxListSelections(ClientPtr client)
+{
+ Selection *pSel;
+ SELinuxListItemRec *items;
+ int rc, count, size, i;
+ CARD32 id;
+
+ REQUEST_SIZE_MATCH(SELinuxGetCreateContextReq);
+
+ /* Count the number of selections and allocate items */
+ count = 0;
+ for (pSel = CurrentSelections; pSel; pSel = pSel->next)
+ count++;
+ items = calloc(count, sizeof(SELinuxListItemRec));
+ if (count && !items)
+ return BadAlloc;
+
+ /* Fill in the items and calculate size */
+ i = 0;
+ size = 0;
+ for (pSel = CurrentSelections; pSel; pSel = pSel->next) {
+ id = pSel->selection;
+ rc = SELinuxPopulateItem(items + i, &pSel->devPrivates, id, &size);
+ if (rc != Success) {
+ SELinuxFreeItems(items, count);
+ return rc;
+ }
+ i++;
+ }
+
+ return SELinuxSendItemsToClient(client, items, size, count);
+}
+
+static int
+ProcSELinuxDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_SELinuxQueryVersion:
+ return ProcSELinuxQueryVersion(client);
+ case X_SELinuxSetDeviceCreateContext:
+ return ProcSELinuxSetCreateContext(client, CTX_DEV);
+ case X_SELinuxGetDeviceCreateContext:
+ return ProcSELinuxGetCreateContext(client, CTX_DEV);
+ case X_SELinuxSetDeviceContext:
+ return ProcSELinuxSetDeviceContext(client);
+ case X_SELinuxGetDeviceContext:
+ return ProcSELinuxGetDeviceContext(client);
+ case X_SELinuxSetDrawableCreateContext:
+ return ProcSELinuxSetCreateContext(client, CTX_WIN);
+ case X_SELinuxGetDrawableCreateContext:
+ return ProcSELinuxGetCreateContext(client, CTX_WIN);
+ case X_SELinuxGetDrawableContext:
+ return ProcSELinuxGetDrawableContext(client);
+ case X_SELinuxSetPropertyCreateContext:
+ return ProcSELinuxSetCreateContext(client, CTX_PRP);
+ case X_SELinuxGetPropertyCreateContext:
+ return ProcSELinuxGetCreateContext(client, CTX_PRP);
+ case X_SELinuxSetPropertyUseContext:
+ return ProcSELinuxSetCreateContext(client, USE_PRP);
+ case X_SELinuxGetPropertyUseContext:
+ return ProcSELinuxGetCreateContext(client, USE_PRP);
+ case X_SELinuxGetPropertyContext:
+ return ProcSELinuxGetPropertyContext(client, objectKey);
+ case X_SELinuxGetPropertyDataContext:
+ return ProcSELinuxGetPropertyContext(client, dataKey);
+ case X_SELinuxListProperties:
+ return ProcSELinuxListProperties(client);
+ case X_SELinuxSetSelectionCreateContext:
+ return ProcSELinuxSetCreateContext(client, CTX_SEL);
+ case X_SELinuxGetSelectionCreateContext:
+ return ProcSELinuxGetCreateContext(client, CTX_SEL);
+ case X_SELinuxSetSelectionUseContext:
+ return ProcSELinuxSetCreateContext(client, USE_SEL);
+ case X_SELinuxGetSelectionUseContext:
+ return ProcSELinuxGetCreateContext(client, USE_SEL);
+ case X_SELinuxGetSelectionContext:
+ return ProcSELinuxGetSelectionContext(client, objectKey);
+ case X_SELinuxGetSelectionDataContext:
+ return ProcSELinuxGetSelectionContext(client, dataKey);
+ case X_SELinuxListSelections:
+ return ProcSELinuxListSelections(client);
+ case X_SELinuxGetClientContext:
+ return ProcSELinuxGetClientContext(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcSELinuxQueryVersion(ClientPtr client)
+{
+ REQUEST(SELinuxQueryVersionReq);
+ int n;
+
+ REQUEST_SIZE_MATCH(SELinuxQueryVersionReq);
+ swaps(&stuff->client_major, n);
+ swaps(&stuff->client_minor, n);
+ return ProcSELinuxQueryVersion(client);
+}
+
+static int
+SProcSELinuxSetCreateContext(ClientPtr client, unsigned offset)
+{
+ REQUEST(SELinuxSetCreateContextReq);
+ int n;
+
+ REQUEST_AT_LEAST_SIZE(SELinuxSetCreateContextReq);
+ swapl(&stuff->context_len, n);
+ return ProcSELinuxSetCreateContext(client, offset);
+}
+
+static int
+SProcSELinuxSetDeviceContext(ClientPtr client)
+{
+ REQUEST(SELinuxSetContextReq);
+ int n;
+
+ REQUEST_AT_LEAST_SIZE(SELinuxSetContextReq);
+ swapl(&stuff->id, n);
+ swapl(&stuff->context_len, n);
+ return ProcSELinuxSetDeviceContext(client);
+}
+
+static int
+SProcSELinuxGetDeviceContext(ClientPtr client)
+{
+ REQUEST(SELinuxGetContextReq);
+ int n;
+
+ REQUEST_SIZE_MATCH(SELinuxGetContextReq);
+ swapl(&stuff->id, n);
+ return ProcSELinuxGetDeviceContext(client);
+}
+
+static int
+SProcSELinuxGetDrawableContext(ClientPtr client)
+{
+ REQUEST(SELinuxGetContextReq);
+ int n;
+
+ REQUEST_SIZE_MATCH(SELinuxGetContextReq);
+ swapl(&stuff->id, n);
+ return ProcSELinuxGetDrawableContext(client);
+}
+
+static int
+SProcSELinuxGetPropertyContext(ClientPtr client, pointer privKey)
+{
+ REQUEST(SELinuxGetPropertyContextReq);
+ int n;
+
+ REQUEST_SIZE_MATCH(SELinuxGetPropertyContextReq);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ return ProcSELinuxGetPropertyContext(client, privKey);
+}
+
+static int
+SProcSELinuxGetSelectionContext(ClientPtr client, pointer privKey)
+{
+ REQUEST(SELinuxGetContextReq);
+ int n;
+
+ REQUEST_SIZE_MATCH(SELinuxGetContextReq);
+ swapl(&stuff->id, n);
+ return ProcSELinuxGetSelectionContext(client, privKey);
+}
+
+static int
+SProcSELinuxListProperties(ClientPtr client)
+{
+ REQUEST(SELinuxGetContextReq);
+ int n;
+
+ REQUEST_SIZE_MATCH(SELinuxGetContextReq);
+ swapl(&stuff->id, n);
+ return ProcSELinuxListProperties(client);
+}
+
+static int
+SProcSELinuxGetClientContext(ClientPtr client)
+{
+ REQUEST(SELinuxGetContextReq);
+ int n;
+
+ REQUEST_SIZE_MATCH(SELinuxGetContextReq);
+ swapl(&stuff->id, n);
+ return ProcSELinuxGetClientContext(client);
+}
+
+static int
+SProcSELinuxDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ int n;
+
+ swaps(&stuff->length, n);
+
+ switch (stuff->data) {
+ case X_SELinuxQueryVersion:
+ return SProcSELinuxQueryVersion(client);
+ case X_SELinuxSetDeviceCreateContext:
+ return SProcSELinuxSetCreateContext(client, CTX_DEV);
+ case X_SELinuxGetDeviceCreateContext:
+ return ProcSELinuxGetCreateContext(client, CTX_DEV);
+ case X_SELinuxSetDeviceContext:
+ return SProcSELinuxSetDeviceContext(client);
+ case X_SELinuxGetDeviceContext:
+ return SProcSELinuxGetDeviceContext(client);
+ case X_SELinuxSetDrawableCreateContext:
+ return SProcSELinuxSetCreateContext(client, CTX_WIN);
+ case X_SELinuxGetDrawableCreateContext:
+ return ProcSELinuxGetCreateContext(client, CTX_WIN);
+ case X_SELinuxGetDrawableContext:
+ return SProcSELinuxGetDrawableContext(client);
+ case X_SELinuxSetPropertyCreateContext:
+ return SProcSELinuxSetCreateContext(client, CTX_PRP);
+ case X_SELinuxGetPropertyCreateContext:
+ return ProcSELinuxGetCreateContext(client, CTX_PRP);
+ case X_SELinuxSetPropertyUseContext:
+ return SProcSELinuxSetCreateContext(client, USE_PRP);
+ case X_SELinuxGetPropertyUseContext:
+ return ProcSELinuxGetCreateContext(client, USE_PRP);
+ case X_SELinuxGetPropertyContext:
+ return SProcSELinuxGetPropertyContext(client, objectKey);
+ case X_SELinuxGetPropertyDataContext:
+ return SProcSELinuxGetPropertyContext(client, dataKey);
+ case X_SELinuxListProperties:
+ return SProcSELinuxListProperties(client);
+ case X_SELinuxSetSelectionCreateContext:
+ return SProcSELinuxSetCreateContext(client, CTX_SEL);
+ case X_SELinuxGetSelectionCreateContext:
+ return ProcSELinuxGetCreateContext(client, CTX_SEL);
+ case X_SELinuxSetSelectionUseContext:
+ return SProcSELinuxSetCreateContext(client, USE_SEL);
+ case X_SELinuxGetSelectionUseContext:
+ return ProcSELinuxGetCreateContext(client, USE_SEL);
+ case X_SELinuxGetSelectionContext:
+ return SProcSELinuxGetSelectionContext(client, objectKey);
+ case X_SELinuxGetSelectionDataContext:
+ return SProcSELinuxGetSelectionContext(client, dataKey);
+ case X_SELinuxListSelections:
+ return ProcSELinuxListSelections(client);
+ case X_SELinuxGetClientContext:
+ return SProcSELinuxGetClientContext(client);
+ default:
+ return BadRequest;
+ }
+}
+
+
+/*
+ * Extension Setup / Teardown
+ */
+
+static void
+SELinuxResetProc(ExtensionEntry *extEntry)
+{
+ SELinuxFlaskReset();
+ SELinuxLabelReset();
+}
+
+void
+SELinuxExtensionInit(INITARGS)
+{
+ ExtensionEntry *extEntry;
+
+ /* Check SELinux mode on system, configuration file, and boolean */
+ if (!is_selinux_enabled()) {
+ LogMessage(X_INFO, "SELinux: Disabled on system\n");
+ return;
+ }
+ if (selinuxEnforcingState == SELINUX_MODE_DISABLED) {
+ LogMessage(X_INFO, "SELinux: Disabled in configuration file\n");
+ return;
+ }
+ if (!security_get_boolean_active("xserver_object_manager")) {
+ LogMessage(X_INFO, "SELinux: Disabled by boolean\n");
+ return;
+ }
+
+ /* Set up XACE hooks */
+ SELinuxLabelInit();
+ SELinuxFlaskInit();
+
+ /* Add extension to server */
+ extEntry = AddExtension(SELINUX_EXTENSION_NAME,
+ SELinuxNumberEvents, SELinuxNumberErrors,
+ ProcSELinuxDispatch, SProcSELinuxDispatch,
+ SELinuxResetProc, StandardMinorOpcode);
+
+ AddExtensionAlias("Flask", extEntry);
+}