tsolextension.c revision 606
1117N/A/* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
1117N/A *
1117N/A * Permission is hereby granted, free of charge, to any person obtaining a
1117N/A * copy of this software and associated documentation files (the
1117N/A * "Software"), to deal in the Software without restriction, including
1117N/A * without limitation the rights to use, copy, modify, merge, publish,
1117N/A * distribute, and/or sell copies of the Software, and to permit persons
1117N/A * to whom the Software is furnished to do so, provided that the above
1117N/A * copyright notice(s) and this permission notice appear in all copies of
1117N/A * the Software and that both the above copyright notice(s) and this
1117N/A * permission notice appear in supporting documentation.
1117N/A *
1117N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1117N/A * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1117N/A * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
1117N/A * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
1117N/A * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
1117N/A * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
1117N/A * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
1117N/A * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
1117N/A * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1117N/A *
1117N/A * Except as contained in this notice, the name of a copyright holder
1117N/A * shall not be used in advertising or otherwise to promote the sale, use
1117N/A * or other dealings in this Software without prior written authorization
1117N/A * of the copyright holder.
1117N/A */
1117N/A
1117N/A#pragma ident "@(#)tsolextension.c 1.31 09/01/14 SMI"
1117N/A
1117N/A#include <stdio.h>
1117N/A#include "auditwrite.h"
1117N/A#include <bsm/libbsm.h>
1117N/A#include <bsm/audit_uevents.h>
1117N/A#include <sys/param.h>
1117N/A#include <sys/types.h>
1117N/A#include <sys/socket.h>
1117N/A#include <sys/wait.h>
1117N/A#include <ucred.h>
1117N/A#include <netinet/in.h>
1117N/A#include <netdb.h>
1117N/A#include <arpa/inet.h>
1117N/A#include <sys/tsol/tndb.h>
1117N/A#include <strings.h>
1117N/A#include <string.h>
1117N/A#include <pwd.h>
1117N/A#include <unistd.h>
1117N/A#include <sys/stat.h>
1117N/A#include <rpc/rpc.h>
1117N/A#include <zone.h>
1117N/A
1117N/A
1117N/A#define NEED_REPLIES
1117N/A
1117N/A#ifdef HAVE_DIX_CONFIG_H
1117N/A#include <dix-config.h>
1117N/A#endif
1117N/A
1117N/A#include "misc.h"
1117N/A#include "osdep.h"
1117N/A#include <X11/Xauth.h>
1117N/A#include "tsol.h"
1117N/A#include "inputstr.h"
1117N/A#include "extnsionst.h"
1117N/A#include "dixstruct.h"
1117N/A#include "xace.h"
1117N/A#include "xacestr.h"
1117N/A#ifdef PANORAMIX
1117N/A#include "../Xext/panoramiXsrv.h"
1117N/A#endif
1117N/A#ifdef XCSECURITY
1117N/A#define _SECURITY_SERVER
1117N/A#include "security.h"
1117N/A#include "../Xext/securitysrv.h"
1117N/A#endif
1117N/A#include "tsolpolicy.h"
1117N/A
1117N/A#define BadCmapCookie 0
1117N/A#define Tsolextension 0x0080 /* Tsol extensions begin at 128 */
1117N/A#define MAX_SCREENS 3 /* screens allowed */
1117N/A#define EXTNSIZE 128
1117N/A
1117N/A#define SECURE_RPC_AUTH "SUN-DES-1"
1117N/A#define SECURE_RPC_LEN 9
1117N/A
1117N/A#define CALLBACK(name) void \
1117N/Aname(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
1117N/A
1117N/Astatic int ProcTsolDispatch(ClientPtr);
1117N/Astatic int ProcSetPolyInstInfo(ClientPtr);
1117N/Astatic int ProcSetPropLabel(ClientPtr);
1117N/Astatic int ProcSetPropUID(ClientPtr);
1117N/Astatic int ProcSetResLabel(ClientPtr);
1117N/Astatic int ProcSetResUID(ClientPtr);
1117N/Astatic int ProcGetClientAttributes(ClientPtr);
1117N/Astatic int ProcGetClientLabel(ClientPtr);
1117N/Astatic int ProcGetPropAttributes(ClientPtr);
1117N/Astatic int ProcGetResAttributes(ClientPtr);
1117N/Astatic int ProcMakeTPWindow(ClientPtr);
1117N/Astatic int ProcMakeTrustedWindow(ClientPtr);
1117N/Astatic int ProcMakeUntrustedWindow(ClientPtr);
1117N/A
1117N/Astatic int SProcTsolDispatch(ClientPtr);
1117N/Astatic int SProcSetPolyInstInfo(ClientPtr);
1117N/Astatic int SProcSetPropLabel(ClientPtr);
1117N/Astatic int SProcSetPropUID(ClientPtr);
1117N/Astatic int SProcSetResLabel(ClientPtr);
1117N/Astatic int SProcSetResUID(ClientPtr);
1117N/Astatic int SProcGetClientAttributes(ClientPtr);
1117N/Astatic int SProcGetClientLabel(ClientPtr);
1117N/Astatic int SProcGetPropAttributes(ClientPtr);
1117N/Astatic int SProcGetResAttributes(ClientPtr);
1117N/Astatic int SProcMakeTPWindow(ClientPtr);
1117N/Astatic int SProcMakeTrustedWindow(ClientPtr);
1117N/Astatic int SProcMakeUntrustedWindow(ClientPtr);
1117N/A
1117N/Astatic void TsolReset(ExtensionEntry *extension);
1117N/Astatic void BreakAllGrabs(ClientPtr client);
1117N/A
1117N/Aextern void init_xtsol(void);
1117N/Aextern int DoScreenStripeHeight(int screen_num);
1117N/Aextern int AddUID(int *userid);
1117N/A
1117N/Astatic unsigned char TsolReqCode = 0;
1117N/Astatic int tsolEventBase = -1;
1117N/Aextern unsigned int StripeHeight;
1117N/Aint ScreenStripeHeight[MAX_SCREENS - 1] = {0, 0};
1117N/A
1117N/Astatic HotKeyRec hotkey = {FALSE, 0, 0, 0, 0};
1117N/A
1117N/Aint tsolMultiLevel = TRUE;
1117N/A
1117N/Aint OwnerUIDint;
1117N/Aextern uid_t OwnerUID;
1117N/Auid_t PublicObjUID = 0;
1117N/Aextern WindowPtr tpwin;
1117N/Aextern bclear_t SessionHI; /* HI Clearance */
1117N/Aextern bclear_t SessionLO; /* LO Clearance */
1117N/Aextern TsolPolyInstInfoRec tsolpolyinstinfo;
1117N/A
1117N/Aextern void LoadTsolConfig(void);
1117N/Aextern void MakeTSOLAtoms(void);
1117N/Aextern void UpdateTsolNode(void);
1117N/A
1117N/Aint (*TsolSavedProcVector[PROCVECTORSIZE])(ClientPtr client);
1117N/Aint (*TsolSavedSwappedProcVector[PROCVECTORSIZE])(ClientPtr client);
1117N/A
1117N/Aextern SecurityHookPtr pSecHook;
1117N/ASecurityHook tsolSecHook;
1117N/A
1117N/AXID TsolCheckAuthorization (unsigned int name_length,
1117N/A char *name, unsigned int data_length,
1117N/A char *data, ClientPtr client, char **reason);
1117N/Avoid TsolDeleteClientFromAnySelections(ClientPtr);
1117N/Avoid TsolDeleteWindowFromAnySelections(WindowPtr);
1117N/A
1117N/Aextern int TsolChangeWindowProperty(ClientPtr, WindowPtr, Atom, Atom, int, int,
1117N/A unsigned long, pointer, Bool);
1117N/Aextern int TsolDeleteProperty(ClientPtr, WindowPtr, Atom);
1117N/Aextern int TsolInitWindow(ClientPtr, WindowPtr);
1117N/Astatic void TsolSetClientInfo(ClientPtr client);
1117N/A
1117N/A/* XACE hook callbacks */
1117N/Astatic CALLBACK(TsolCheckExtensionAccess);
1117N/Astatic CALLBACK(TsolCheckPropertyAccess);
1117N/Astatic CALLBACK(TsolCheckResourceIDAccess);
1117N/Astatic CALLBACK(TsolProcessKeyboard);
1117N/Aextern CALLBACK(TsolAuditStart);
1117N/Aextern CALLBACK(TsolAuditEnd);
1117N/A
1117N/A/* other callbacks */
1117N/Astatic CALLBACK(TsolClientStateCallback);
1117N/A
1117N/Aextern int ProcTsolInternAtom(ClientPtr client);
1117N/Aextern int ProcTsolSetSelectionOwner(ClientPtr client);
1117N/Aextern int ProcTsolGetSelectionOwner(ClientPtr client);
1117N/Aextern int ProcTsolConvertSelection(ClientPtr client);
1117N/Aextern int ProcTsolGetProperty(ClientPtr client);
1117N/Aextern int ProcTsolListProperties(ClientPtr client);
1117N/Aextern int ProcTsolChangeKeyboardMapping(ClientPtr client);
1117N/Aextern int ProcTsolSetPointerMapping(ClientPtr client);
1117N/Aextern int ProcTsolChangeKeyboardControl(ClientPtr client);
1117N/Aextern int ProcTsolBell(ClientPtr client);
1117N/Aextern int ProcTsolChangePointerControl(ClientPtr client);
1117N/Aextern int ProcTsolSetModifierMapping(ClientPtr client);
1117N/A
1117N/Aextern int ProcTsolCreateWindow(ClientPtr client);
1117N/Aextern int ProcTsolChangeWindowAttributes(ClientPtr client);
1117N/Aextern int ProcTsolConfigureWindow(ClientPtr client);
1117N/Aextern int ProcTsolCirculateWindow(ClientPtr client);
1117N/Aextern int ProcTsolReparentWindow(ClientPtr client);
1117N/Aextern int ProcTsolSetInputFocus(ClientPtr client);
1117N/Aextern int ProcTsolGetInputFocus(ClientPtr client);
1117N/Aextern int ProcTsolSendEvent(ClientPtr client);
1117N/Aextern int ProcTsolSetInputFocus(ClientPtr client);
1117N/Aextern int ProcTsolGetInputFocus(ClientPtr client);
1117N/Aextern int ProcTsolGetGeometry(ClientPtr client);
1117N/Aextern int ProcTsolGrabServer(ClientPtr client);
1117N/Aextern int ProcTsolUngrabServer(ClientPtr client);
1117N/Aextern int ProcTsolCreatePixmap(ClientPtr client);
1117N/Aextern int ProcTsolSetScreenSaver(ClientPtr client);
1117N/Aextern int ProcTsolChangeHosts(ClientPtr client);
1117N/Aextern int ProcTsolChangeAccessControl(ClientPtr client);
1117N/Aextern int ProcTsolKillClient(ClientPtr client);
1117N/Aextern int ProcTsolSetFontPath(ClientPtr client);
1117N/Aextern int ProcTsolChangeCloseDownMode(ClientPtr client);
1117N/Aextern int ProcTsolListInstalledColormaps(ClientPtr client);
1117N/Aextern int ProcTsolGetImage(ClientPtr client);
1117N/Aextern int ProcTsolQueryTree(ClientPtr client);
1117N/Aextern int ProcTsolQueryPointer(ClientPtr client);
1117N/Aextern int ProcTsolQueryExtension(ClientPtr client);
1117N/Aextern int ProcTsolListExtensions(ClientPtr client);
1117N/Aextern int ProcTsolMapWindow(ClientPtr client);
1117N/Aextern int ProcTsolMapSubwindows(ClientPtr client);
1117N/Aextern int ProcTsolCopyArea(ClientPtr client);
1117N/Aextern int ProcTsolCopyPlane(ClientPtr client);
1117N/Aextern int ProcTsolPolySegment(ClientPtr client);
1117N/Aextern int ProcTsolPolyRectangle(ClientPtr client);
1117N/A
1117N/Aextern int TsolPanoramiXGetGeometry(ClientPtr client);
1117N/A
1117N/A/*
1117N/A * Initialize the extension. Main entry point for this loadable
1117N/A * module.
1117N/A */
1117N/A
1117N/Avoid
1117N/ATsolExtensionInit(void)
1117N/A{
1117N/A ExtensionEntry *extEntry;
1117N/A int i;
1117N/A
1117N/A /* sleep(20); */
1117N/A
1117N/A /* This extension is supported on a labeled system */
1117N/A if (!is_system_labeled()) {
1117N/A return;
1117N/A }
1117N/A
tsolMultiLevel = TRUE;
(void) setpflags(PRIV_AWARE, 1);
init_xtsol();
init_win_privsets();
extEntry = AddExtension(TSOLNAME, TSOL_NUM_EVENTS, TSOL_NUM_ERRORS,
ProcTsolDispatch, SProcTsolDispatch, TsolReset,
StandardMinorOpcode);
if (extEntry == NULL) {
ErrorF("TsolExtensionInit: AddExtension failed for X Trusted Extensions\n");
return;
}
TsolReqCode = (unsigned char) extEntry->base;
tsolEventBase = extEntry->eventBase;
if (!AddCallback(&ClientStateCallback, TsolClientStateCallback, NULL))
return;
/* Allocate storage in devPrivates */
if (!dixRequestPrivate(tsolPrivKey, sizeof (TsolPrivRec))) {
ErrorF("TsolExtensionInit: Cannot allocate devPrivate.\n");
return;
}
LoadTsolConfig();
MakeTSOLAtoms();
UpdateTsolNode();
/* Initialize security hooks */
tsolSecHook.CheckAuthorization = TsolCheckAuthorization;
tsolSecHook.ChangeWindowProperty = TsolChangeWindowProperty;
tsolSecHook.DeleteProperty = TsolDeleteProperty;
tsolSecHook.DeleteClientFromAnySelections = TsolDeleteClientFromAnySelections;
tsolSecHook.DeleteWindowFromAnySelections = TsolDeleteWindowFromAnySelections;
pSecHook = &tsolSecHook;
XaceRegisterCallback(XACE_RESOURCE_ACCESS, TsolCheckResourceIDAccess,
NULL);
XaceRegisterCallback(XACE_PROPERTY_ACCESS, TsolCheckPropertyAccess,
NULL);
XaceRegisterCallback(XACE_EXT_ACCESS, TsolCheckExtensionAccess, NULL);
XaceRegisterCallback(XACE_KEY_AVAIL, TsolProcessKeyboard, NULL);
XaceRegisterCallback(XACE_AUDIT_BEGIN, TsolAuditStart, NULL);
XaceRegisterCallback(XACE_AUDIT_END, TsolAuditEnd, NULL);
/* Save original Proc vectors */
for (i = 0; i < PROCVECTORSIZE; i++) {
TsolSavedProcVector[i] = ProcVector[i];
TsolSavedSwappedProcVector[i] = SwappedProcVector[i];
}
/* Replace some of the original Proc vectors with our own TBD */
ProcVector[X_InternAtom] = ProcTsolInternAtom;
ProcVector[X_SetSelectionOwner] = ProcTsolSetSelectionOwner;
ProcVector[X_GetSelectionOwner] = ProcTsolGetSelectionOwner;
ProcVector[X_ConvertSelection] = ProcTsolConvertSelection;
ProcVector[X_GetProperty] = ProcTsolGetProperty;
ProcVector[X_ListProperties] = ProcTsolListProperties;
ProcVector[X_ChangeKeyboardMapping] = ProcTsolChangeKeyboardMapping;
ProcVector[X_SetPointerMapping] = ProcTsolSetPointerMapping;
ProcVector[X_ChangeKeyboardControl] = ProcTsolChangeKeyboardControl;
ProcVector[X_Bell] = ProcTsolBell;
ProcVector[X_ChangePointerControl] = ProcTsolChangePointerControl;
ProcVector[X_SetModifierMapping] = ProcTsolSetModifierMapping;
ProcVector[X_CreateWindow] = ProcTsolCreateWindow;
ProcVector[X_ChangeWindowAttributes] = ProcTsolChangeWindowAttributes;
ProcVector[X_ConfigureWindow] = ProcTsolConfigureWindow;
ProcVector[X_CirculateWindow] = ProcTsolCirculateWindow;
ProcVector[X_ReparentWindow] = ProcTsolReparentWindow;
ProcVector[X_SetInputFocus] = ProcTsolSetInputFocus;
ProcVector[X_GetInputFocus] = ProcTsolGetInputFocus;
ProcVector[X_SendEvent] = ProcTsolSendEvent;
ProcVector[X_SetInputFocus] = ProcTsolSetInputFocus;
ProcVector[X_GetInputFocus] = ProcTsolGetInputFocus;
ProcVector[X_GetGeometry] = ProcTsolGetGeometry;
ProcVector[X_GrabServer] = ProcTsolGrabServer;
ProcVector[X_UngrabServer] = ProcTsolUngrabServer;
ProcVector[X_CreatePixmap] = ProcTsolCreatePixmap;
ProcVector[X_SetScreenSaver] = ProcTsolSetScreenSaver;
ProcVector[X_ChangeHosts] = ProcTsolChangeHosts;
ProcVector[X_SetAccessControl] = ProcTsolChangeAccessControl;
ProcVector[X_KillClient] = ProcTsolKillClient;
ProcVector[X_SetFontPath] = ProcTsolSetFontPath;
ProcVector[X_SetCloseDownMode] = ProcTsolChangeCloseDownMode;
ProcVector[X_ListInstalledColormaps] = ProcTsolListInstalledColormaps;
ProcVector[X_GetImage] = ProcTsolGetImage;
ProcVector[X_QueryTree] = ProcTsolQueryTree;
ProcVector[X_QueryPointer] = ProcTsolQueryPointer;
ProcVector[X_QueryExtension] = ProcTsolQueryExtension;
ProcVector[X_ListExtensions] = ProcTsolListExtensions;
ProcVector[X_MapWindow] = ProcTsolMapWindow;
ProcVector[X_MapSubwindows] = ProcTsolMapSubwindows;
ProcVector[X_CopyArea] = ProcTsolCopyArea;
ProcVector[X_CopyPlane] = ProcTsolCopyPlane;
ProcVector[X_PolySegment] = ProcTsolPolySegment;
ProcVector[X_PolyRectangle] = ProcTsolPolyRectangle;
}
static CALLBACK(
TsolCheckResourceIDAccess)
{
XaceResourceAccessRec *rec = calldata;
ClientPtr client = rec->client;
XID id = rec->id;
RESTYPE rtype = rec->rtype;
pointer rval = rec->res;
Mask access_mode = rec->access_mode;
int cid = CLIENT_ID(id);
int reqtype;
if (client->requestBuffer) {
reqtype = MAJOROP; /* protocol */
} else {
reqtype = -1;
}
switch (rtype) {
case RT_GC:
if (access_mode & DixReadAccess) {
if (xtsol_policy(TSOL_RES_GC, TSOL_READ, (void *)id,
client, TSOL_ALL, (void *)MAJOROP))
rec->status = BadAccess;
}
if (access_mode & DixWriteAccess) {
if (xtsol_policy(TSOL_RES_GC, TSOL_MODIFY, (void *)id,
client, TSOL_ALL, (void *)MAJOROP))
rec->status = BadAccess;
}
if (access_mode & DixDestroyAccess) {
if (xtsol_policy(TSOL_RES_GC, TSOL_DESTROY, (void *)id,
client, TSOL_ALL, (void *)MAJOROP))
rec->status = BadAccess;
}
break;
case RT_WINDOW: /* Drawables */
if (access_mode & DixCreateAccess) {
/* Replaces InitWindow hook */
TsolInitWindow(client, (WindowPtr) rval);
}
/* The rest falls through to code shared with RT_PIXMAP */
case RT_PIXMAP:
/* Drawing operations use pixel access policy */
switch (reqtype) {
case X_PolyPoint:
case X_PolyLine:
case X_PolyArc:
case X_FillPoly:
case X_PolyFillRectangle:
case X_PolyFillArc:
case X_PutImage:
case X_PolyText8:
case X_PolyText16:
case X_ImageText8:
case X_ImageText16:
if (access_mode & DixReadAccess) {
if (xtsol_policy(TSOL_RES_PIXEL, TSOL_READ,
(void *)rval, client, TSOL_ALL,
(void *)MAJOROP))
rec->status = BadAccess;
}
if (access_mode & DixWriteAccess) {
if (xtsol_policy(TSOL_RES_PIXEL, TSOL_MODIFY,
(void *)rval, client, TSOL_ALL,
(void *)MAJOROP))
rec->status = BadAccess;
}
break;
/* Property protocols */
case X_ChangeProperty:
case X_DeleteProperty:
case X_GetProperty:
case X_ListProperties:
case X_RotateProperties:
if (access_mode & DixReadAccess) {
if (xtsol_policy(TSOL_RES_PROPWIN, TSOL_READ,
(void *)rval, client, TSOL_ALL,
(void *)MAJOROP))
rec->status = BadAccess;
}
if (access_mode & DixWriteAccess) {
if (xtsol_policy(TSOL_RES_PROPWIN, TSOL_MODIFY,
(void *)rval, client, TSOL_ALL,
(void *)MAJOROP))
rec->status = BadAccess;
}
break;
}
break;
}
if (rec->status == BadAccess) {
TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
ErrorF("Access failed: cid = %d, rtype=%X, access=%d,"
" xid=%X, proto = %d, pid = %d\n",
cid, (uint_t) rtype, access_mode, id, reqtype, tsolinfo->pid);
}
}
static
CALLBACK(TsolClientStateCallback)
{
NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
ClientPtr client = pci->client;
TsolInfoPtr tsolinfo = TsolClientPriv(client);
switch (client->clientState) {
case ClientStateInitial:
/* Got a new connection */
TsolSetClientInfo(client);
break;
case ClientStateRunning:
break;
case ClientStateRetained: /* client disconnected */
break;
case ClientStateGone:
if (tpwin && wClient(tpwin) == client)
tpwin = NULL; /* reset tpwin */
if (tsolinfo != NULL && tsolinfo->privs != NULL) {
priv_freeset(tsolinfo->privs);
}
/* Audit disconnect */
if (system_audit_on && (au_preselect(AUE_ClientDisconnect, &(tsolinfo->amask),
AU_PRS_BOTH, AU_PRS_USECACHE) == 1)) {
auditwrite(AW_PRESELECT, &(tsolinfo->amask),AW_END);
auditwrite(AW_EVENTNUM, AUE_ClientDisconnect,
AW_XCLIENT, client->index,
AW_SLABEL, tsolinfo->sl,
AW_RETURN, 0, 0, AW_WRITE, AW_END);
tsolinfo->flags &= ~TSOL_DOXAUDIT;
tsolinfo->flags &= ~TSOL_AUDITEVENT;
auditwrite(AW_FLUSH, AW_END);
auditwrite(AW_DISCARDRD, tsolinfo->asaverd, AW_END);
auditwrite(AW_NOPRESELECT, AW_END);
}
break;
default:
break;
}
}
static void
TsolReset(ExtensionEntry *extension)
{
free_win_privsets();
XaceDeleteCallback(XACE_RESOURCE_ACCESS, TsolCheckResourceIDAccess, NULL);
XaceDeleteCallback(XACE_PROPERTY_ACCESS, TsolCheckPropertyAccess, NULL);
XaceDeleteCallback(XACE_EXT_ACCESS, TsolCheckExtensionAccess, NULL);
XaceDeleteCallback(XACE_KEY_AVAIL, TsolProcessKeyboard, NULL);
XaceDeleteCallback(XACE_AUDIT_BEGIN, TsolAuditStart, NULL);
XaceDeleteCallback(XACE_AUDIT_END, TsolAuditEnd, NULL);
}
/*
* Dispatch routine
*
*/
static int
ProcTsolDispatch(register ClientPtr client)
{
int retval;
REQUEST(xReq);
switch (stuff->data)
{
case X_SetPolyInstInfo:
retval = ProcSetPolyInstInfo(client);
break;
case X_SetPropLabel:
retval = ProcSetPropLabel(client);
break;
case X_SetPropUID:
retval = ProcSetPropUID(client);
break;
case X_SetResLabel:
retval = ProcSetResLabel(client);
break;
case X_SetResUID:
retval = ProcSetResUID(client);
break;
case X_GetClientAttributes:
retval = ProcGetClientAttributes(client);
break;
case X_GetClientLabel:
retval = ProcGetClientLabel(client);
break;
case X_GetPropAttributes:
retval = ProcGetPropAttributes(client);
break;
case X_GetResAttributes:
retval = ProcGetResAttributes(client);
break;
case X_MakeTPWindow:
retval = ProcMakeTPWindow(client);
break;
case X_MakeTrustedWindow:
retval = ProcMakeTrustedWindow(client);
break;
case X_MakeUntrustedWindow:
retval = ProcMakeUntrustedWindow(client);
break;
default:
SendErrorToClient(client, TsolReqCode, stuff->data, 0, BadRequest);
retval = BadRequest;
}
return (retval);
}
static int
SProcTsolDispatch(register ClientPtr client)
{
int n;
int retval;
REQUEST(xReq);
swaps(&stuff->length, n);
switch (stuff->data)
{
case X_SetPolyInstInfo:
retval = SProcSetPolyInstInfo(client);
break;
case X_SetPropLabel:
retval = SProcSetPropLabel(client);
break;
case X_SetPropUID:
retval = SProcSetPropUID(client);
break;
case X_SetResLabel:
retval = SProcSetResLabel(client);
break;
case X_SetResUID:
retval = SProcSetResUID(client);
break;
case X_GetClientAttributes:
retval = SProcGetClientAttributes(client);
break;
case X_GetClientLabel:
retval = SProcGetClientLabel(client);
break;
case X_GetPropAttributes:
retval = SProcGetPropAttributes(client);
break;
case X_GetResAttributes:
retval = SProcGetResAttributes(client);
break;
case X_MakeTPWindow:
retval = SProcMakeTPWindow(client);
break;
case X_MakeTrustedWindow:
retval = SProcMakeTrustedWindow(client);
break;
case X_MakeUntrustedWindow:
retval = SProcMakeUntrustedWindow(client);
break;
default:
SendErrorToClient(client, TsolReqCode, stuff->data, 0, BadRequest);
retval = BadRequest;
}
return (retval);
}
/*
* Individual routines
*/
static int
SProcSetPolyInstInfo(ClientPtr client)
{
int n;
REQUEST(xSetPolyInstInfoReq);
swapl(&stuff->uid, n);
swapl(&stuff->enabled, n);
swaps(&stuff->sllength, n);
return (ProcSetPolyInstInfo(client));
}
static int
SProcSetPropLabel(ClientPtr client)
{
int n;
REQUEST(xSetPropLabelReq);
swapl(&stuff->id, n);
swapl(&stuff->atom, n);
swaps(&stuff->labelType, n);
swaps(&stuff->sllength, n);
swaps(&stuff->illength, n);
return (ProcSetPropLabel(client));
}
static int
SProcSetPropUID(ClientPtr client)
{
int n;
REQUEST(xSetPropUIDReq);
swapl(&stuff->id, n);
swapl(&stuff->atom, n);
swapl(&stuff->uid, n);
return (ProcSetPropUID(client));
}
static int
SProcSetResLabel(ClientPtr client)
{
int n;
REQUEST(xSetResLabelReq);
swapl(&stuff->id, n);
swaps(&stuff->resourceType, n);
swaps(&stuff->labelType, n);
swaps(&stuff->sllength, n);
swaps(&stuff->illength, n);
return (ProcSetResLabel(client));
}
static int
SProcSetResUID(ClientPtr client)
{
int n;
REQUEST(xSetResUIDReq);
swapl(&stuff->id, n);
swaps(&stuff->resourceType, n);
swapl(&stuff->uid, n);
return (ProcSetResUID(client));
}
static int
SProcGetClientAttributes(ClientPtr client)
{
int n;
REQUEST(xGetClientAttributesReq);
swapl(&stuff->id, n);
return (ProcGetClientAttributes(client));
}
static int
SProcGetClientLabel(ClientPtr client)
{
int n;
REQUEST(xGetClientLabelReq);
swapl(&stuff->id, n);
swaps(&stuff->mask, n);
return (ProcGetClientLabel(client));
}
static int
SProcGetPropAttributes(ClientPtr client)
{
int n;
REQUEST(xGetPropAttributesReq);
swapl(&stuff->id, n);
swapl(&stuff->atom, n);
swaps(&stuff->mask, n);
return (ProcGetPropAttributes(client));
}
static int
SProcGetResAttributes(ClientPtr client)
{
int n;
REQUEST(xGetResAttributesReq);
swapl(&stuff->id, n);
swaps(&stuff->resourceType, n);
swaps(&stuff->mask, n);
return (ProcGetResAttributes(client));
}
static int
SProcMakeTPWindow(ClientPtr client)
{
int n;
REQUEST(xMakeTPWindowReq);
swapl(&stuff->id, n);
return (ProcMakeTPWindow(client));
}
static int
SProcMakeTrustedWindow(ClientPtr client)
{
int n;
REQUEST(xMakeTrustedWindowReq);
swapl(&stuff->id, n);
return (ProcMakeTrustedWindow(client));
}
static int
SProcMakeUntrustedWindow(ClientPtr client)
{
int n;
REQUEST(xMakeUntrustedWindowReq);
swapl(&stuff->id, n);
return (ProcMakeUntrustedWindow(client));
}
/*
* Set PolyInstantiation Info.
* Normally a get(prop) will
* get the prop. that has match sl, uid of the client. Setting
* enabled to true will get only the prop. corresponding to
* sl, uid specified instead of that of client. This is used
* by dtwm/dtfile in special motif lib.
*/
static int
ProcSetPolyInstInfo(ClientPtr client)
{
bslabel_t *sl;
int err_code;
REQUEST(xSetPolyInstInfoReq);
REQUEST_AT_LEAST_SIZE(xSetPolyInstInfoReq);
/*
* Check for policy here
*/
if (err_code = xtsol_policy(TSOL_RES_POLYINFO, TSOL_MODIFY, NULL,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
sl = (bslabel_t *)(stuff + 1);
tsolpolyinstinfo.enabled = stuff->enabled;
tsolpolyinstinfo.uid = (uid_t) stuff->uid;
tsolpolyinstinfo.sl = lookupSL(sl);
return (client->noClientException);
}
static int
ProcSetPropLabel(ClientPtr client)
{
bslabel_t *sl;
WindowPtr pWin;
TsolPropPtr tsolprop;
TsolPropPtr *tsolpropP;
PropertyPtr pProp;
int err_code;
REQUEST(xSetPropLabelReq);
REQUEST_AT_LEAST_SIZE(xSetPropLabelReq);
pWin = LookupWindow(stuff->id, client);
if (!pWin)
{
client->errorValue = stuff->id;
return (BadWindow);
}
if (err_code = xtsol_policy(TSOL_RES_WINDOW, TSOL_MODIFY, pWin,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
if (!ValidAtom(stuff->atom))
{
client->errorValue = stuff->atom;
return (BadAtom);
}
/* first see if property already exists */
pProp = wUserProps (pWin);
while (pProp)
{
if (pProp->propertyName == stuff->atom)
break;
pProp = pProp->next;
}
if (!pProp)
{
/* property does not exist */
client->errorValue = stuff->atom;
return (BadAtom);
}
/* Initialize property created internally by server */
tsolpropP = TsolPropertyPriv(pProp);
if (*tsolpropP == NULL)
{
*tsolpropP = (pointer)AllocServerTsolProp();
if (*tsolpropP == NULL)
return(BadAlloc);
}
tsolprop = *tsolpropP;
sl = (bslabel_t *)(stuff + 1);
if (!blequal(tsolprop->sl, sl))
{
if (err_code = xtsol_policy(TSOL_RES_SL, TSOL_MODIFY, sl,
client, TSOL_ALL, tsolprop->sl))
{
return (err_code);
}
tsolprop->sl = lookupSL(sl);
}
return (client->noClientException);
}
static int
ProcSetPropUID(ClientPtr client)
{
WindowPtr pWin;
TsolPropPtr tsolprop;
TsolPropPtr *tsolpropP;
PropertyPtr pProp;
int err_code;
REQUEST(xSetPropUIDReq);
REQUEST_SIZE_MATCH(xSetPropUIDReq);
pWin = LookupWindow(stuff->id, client);
if (!pWin)
{
client->errorValue = stuff->id;
return (BadWindow);
}
if (err_code = xtsol_policy(TSOL_RES_WINDOW, TSOL_MODIFY, pWin,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
if (!ValidAtom(stuff->atom))
{
client->errorValue = stuff->atom;
return (BadAtom);
}
/* first see if property already exists */
pProp = wUserProps (pWin);
while (pProp)
{
if (pProp->propertyName == stuff->atom)
break;
pProp = pProp->next;
}
if (!pProp)
{
/* property does not exist */
client->errorValue = stuff->atom;
return (BadAtom);
}
if (err_code = xtsol_policy(TSOL_RES_UID, TSOL_MODIFY, NULL,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
/* Initialize property created internally by server */
tsolpropP = TsolPropertyPriv(pProp);
if (*tsolpropP == NULL)
{
*tsolpropP = AllocServerTsolProp();
if (*tsolpropP == NULL)
return (BadAlloc);
}
tsolprop = *tsolpropP;
tsolprop->uid = stuff->uid;
return (client->noClientException);
}
static int
ProcSetResLabel(ClientPtr client)
{
bslabel_t *sl;
PixmapPtr pMap;
WindowPtr pWin;
xEvent message;
TsolResPtr tsolres;
int err_code;
REQUEST(xSetResLabelReq);
REQUEST_AT_LEAST_SIZE(xSetResLabelReq);
sl = (bslabel_t *)(stuff + 1);
switch (stuff->resourceType)
{
case SESSIONHI: /* set server session HI */
if (err_code = xtsol_policy(TSOL_RES_SL, TSOL_MODIFY, sl,
client, TSOL_ALL, (void *)NULL))
{
return (err_code);
}
memcpy(&SessionHI, sl, SL_SIZE);
return (client->noClientException);
case SESSIONLO: /* set server session LO */
if (err_code = xtsol_policy(TSOL_RES_SL, TSOL_MODIFY, sl,
client, TSOL_ALL, (void *)NULL))
{
return (err_code);
}
memcpy(&SessionLO, sl, SL_SIZE);
return (client->noClientException);
case IsWindow:
pWin = LookupWindow(stuff->id, client);
if (pWin)
{
tsolres = TsolWindowPriv(pWin);
}
else
{
client->errorValue = stuff->id;
return (BadWindow);
}
if (err_code = xtsol_policy(TSOL_RES_WINDOW, TSOL_MODIFY, pWin,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
break;
case IsPixmap:
pMap = (PixmapPtr)LookupIDByType(stuff->id, RT_PIXMAP);
if (pMap)
{
tsolres = TsolPixmapPriv(pMap);
}
else
{
client->errorValue = stuff->id;
return (BadPixmap);
}
if (err_code = xtsol_policy(TSOL_RES_PIXMAP, TSOL_MODIFY, pMap,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
break;
}
if (!blequal(tsolres->sl, sl))
{
if (err_code = xtsol_policy(TSOL_RES_SL, TSOL_MODIFY, sl,
client, TSOL_ALL, tsolres->sl))
{
return (err_code);
}
tsolres->sl = lookupSL(sl);
}
/* generate the notify event for windows */
if (stuff->resourceType == IsWindow)
{
pWin = LookupWindow(stuff->id, client);
message.u.u.type = ClientMessage; /* 33 */
message.u.u.detail = 32;
message.u.clientMessage.window = RootOf(pWin);
message.u.clientMessage.u.l.type =
MakeAtom("_TSOL_CMWLABEL_CHANGE", 21, 1);
message.u.clientMessage.u.l.longs0 = RootOfClient(pWin);
message.u.clientMessage.u.l.longs1 = stuff->id;
DeliverEventsToWindow(pWin, &message, 1,
SubstructureRedirectMask, NullGrab, 0);
}
return (client->noClientException);
}
static int
ProcSetResUID(ClientPtr client)
{
int ScreenNumber;
PixmapPtr pMap;
WindowPtr pWin;
TsolResPtr tsolres;
int err_code;
REQUEST(xSetResUIDReq);
REQUEST_SIZE_MATCH(xSetResUIDReq);
switch (stuff->resourceType)
{
case STRIPEHEIGHT:
if (err_code = xtsol_policy(TSOL_RES_STRIPE, TSOL_MODIFY, NULL,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
StripeHeight = stuff->uid;
ScreenNumber = stuff->id;
/* set Screen Stripe Size */
DoScreenStripeHeight(ScreenNumber);
ScreenStripeHeight [ScreenNumber] = StripeHeight;
return (client->noClientException);
case RES_OUID:
if (err_code = xtsol_policy(TSOL_RES_WOWNER, TSOL_MODIFY, NULL,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
OwnerUID = stuff->uid;
OwnerUIDint = OwnerUID;
AddUID(&OwnerUIDint);
return (client->noClientException);
case IsWindow:
pWin = LookupWindow(stuff->id, client);
if (pWin)
{
tsolres = TsolWindowPriv(pWin);
}
else
{
client->errorValue = stuff->id;
return (BadWindow);
}
if (err_code = xtsol_policy(TSOL_RES_WINDOW, TSOL_MODIFY, pWin,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
break;
case IsPixmap:
pMap = (PixmapPtr)LookupIDByType(stuff->id, RT_PIXMAP);
if (pMap)
{
tsolres = TsolPixmapPriv(pMap);
}
else
{
client->errorValue = stuff->id;
return (BadPixmap);
}
if (err_code = xtsol_policy(TSOL_RES_PIXMAP, TSOL_MODIFY, pMap,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
break;
default:
return (BadValue);
}
if (err_code = xtsol_policy(TSOL_RES_UID, TSOL_MODIFY, NULL,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
tsolres->uid = stuff->uid;
return (client->noClientException);
}
static int
ProcGetClientAttributes(ClientPtr client)
{
int n;
int err_code;
ClientPtr res_client; /* resource owner client */
TsolInfoPtr tsolinfo, res_tsolinfo;
WindowPtr pWin;
xGetClientAttributesReply rep;
REQUEST(xGetClientAttributesReq);
REQUEST_SIZE_MATCH(xGetClientAttributesReq);
/* Valid window check */
/* Valid window check */
if ((pWin = LookupWindow(stuff->id, client)) == NULL)
{
client->errorValue = stuff->id;
return (BadWindow);
}
if (!(res_client = clients[CLIENT_ID(stuff->id)]))
{
client->errorValue = stuff->id;
return (BadWindow);
}
if (err_code = xtsol_policy(TSOL_RES_CLIENT, TSOL_READ, (void *)stuff->id,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
tsolinfo = GetClientTsolInfo(client);
res_tsolinfo = GetClientTsolInfo(res_client);
/* Transfer the client info to reply rec */
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.trustflag = (res_tsolinfo->forced_trust == 1
|| res_tsolinfo->trusted_path) ? (BYTE)1 : (BYTE)0;
rep.uid = (CARD32) res_tsolinfo->uid;
rep.pid = (CARD32) res_tsolinfo->pid;
rep.gid = (CARD32) res_tsolinfo->gid;
rep.auditid = (CARD32) res_tsolinfo->auid;
rep.sessionid = (CARD32) res_tsolinfo->asid;
rep.iaddr = (CARD32) res_tsolinfo->iaddr;
rep.length = (CARD32) 0;
if (client->swapped)
{
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.uid, n);
swapl(&rep.pid, n);
swapl(&rep.gid, n);
swapl(&rep.auditid, n);
swapl(&rep.sessionid, n);
swapl(&rep.iaddr, n);
}
WriteToClient(client, sizeof(xGetClientAttributesReply), (char *)&rep);
return (client->noClientException);
}
static int
ProcGetClientLabel(ClientPtr client)
{
int n;
int reply_length;
int err_code;
Bool write_to_client = 0;
bslabel_t *sl;
ClientPtr res_client; /* resource owner client */
TsolInfoPtr tsolinfo, res_tsolinfo;
WindowPtr pWin;
xGenericReply rep;
REQUEST(xGetClientLabelReq);
REQUEST_SIZE_MATCH(xGetClientLabelReq);
/* Valid window check */
if ((pWin = LookupWindow(stuff->id, client)) == NULL)
{
client->errorValue = stuff->id;
return (BadWindow);
}
if (!(res_client = clients[CLIENT_ID(stuff->id)]))
{
client->errorValue = stuff->id;
return (BadWindow);
}
if (err_code = xtsol_policy(TSOL_RES_CLIENT, TSOL_READ, (void *)stuff->id,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
tsolinfo = GetClientTsolInfo(client);
res_tsolinfo = GetClientTsolInfo(res_client);
/* Transfer the client info to reply rec */
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
/* allocate temp storage for labels */
sl = (bslabel_t *)(xalloc(SL_SIZE));
rep.data00 = rep.data01 = 0;
if (sl == NULL)
return (BadAlloc);
/* fill the fields as per request mask */
if (stuff->mask & RES_SL)
{
memcpy(sl, res_tsolinfo->sl, SL_SIZE);
rep.data00 = SL_SIZE;
}
rep.length = (CARD32)(rep.data00)/4;
if (rep.length > 0)
{
reply_length = rep.length*4;
write_to_client = 1;
}
if (client->swapped)
{
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.data00, n);
swapl(&rep.data01, n);
}
WriteToClient(client, sizeof(xGenericReply), (char *)&rep);
if (write_to_client == 1)
{
WriteToClient(client, reply_length, (char *)sl);
}
xfree(sl);
return (client->noClientException);
}
static int
ProcGetPropAttributes(ClientPtr client)
{
int n;
int reply_length;
int err_code;
Bool write_to_client = 0;
PropertyPtr pProp;
bslabel_t *sl;
WindowPtr pWin;
TsolPropPtr tsolprop, tmp_prop;
TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
xGetPropAttributesReply rep;
REQUEST(xGetPropAttributesReq);
REQUEST_SIZE_MATCH(xGetPropAttributesReq);
pWin = LookupWindow(stuff->id, client);
if (!pWin)
{
client->errorValue = stuff->id;
return (BadWindow);
}
if (err_code = xtsol_policy(TSOL_RES_WINDOW, TSOL_READ, pWin,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
if (!ValidAtom(stuff->atom))
{
client->errorValue = stuff->atom;
return (BadAtom);
}
/* first see if property already exists */
pProp = wUserProps (pWin);
while (pProp)
{
if (pProp->propertyName == stuff->atom)
break;
pProp = pProp->next;
}
if (!pProp)
{
/* property does not exist */
client->errorValue = stuff->atom;
return (BadAtom);
}
tsolprop = TsolPropertyPriv(pProp);
tmp_prop = tsolprop;
while (tmp_prop)
{
if (tsolpolyinstinfo.enabled)
{
if (tmp_prop->uid == tsolpolyinstinfo.uid &&
tmp_prop->sl == tsolpolyinstinfo.sl)
{
tsolprop = tmp_prop;
break;
}
}
else
{
if (tmp_prop->uid == tsolinfo->uid &&
tmp_prop->sl == tsolinfo->sl)
{
tsolprop = tmp_prop;
break;
}
}
tmp_prop = tmp_prop->next;
}
if (!tsolprop)
{
return (client->noClientException);
}
if (stuff->mask & RES_UID)
{
rep.uid = tsolprop->uid;
}
/* allocate temp storage for labels */
sl = (bslabel_t *)(xalloc(SL_SIZE));
rep.sllength = rep.illength = 0;
if (sl == NULL)
return (BadAlloc);
/* fill the fields as per request mask */
if (stuff->mask & RES_SL)
{
memcpy(sl, tsolprop->sl, SL_SIZE);
rep.sllength = SL_SIZE;
}
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = (CARD32) (rep.sllength)/4;
if (rep.length > 0)
{
reply_length = rep.length*4;
write_to_client = 1;
}
if (client->swapped)
{
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.uid, n);
swaps(&rep.sllength, n);
swaps(&rep.illength, n);
}
WriteToClient(client, sizeof(xGetPropAttributesReply), (char *)&rep);
if (write_to_client == 1)
{
WriteToClient(client, reply_length, (char *)sl);
}
xfree(sl);
return (client->noClientException);
}
static int
ProcGetResAttributes(ClientPtr client)
{
int n;
int reply_length;
int err_code;
Bool write_to_client = 0;
bslabel_t *sl;
PixmapPtr pMap;
WindowPtr pWin;
TsolResPtr tsolres;
xGetResAttributesReply rep;
REQUEST(xGetResAttributesReq);
REQUEST_SIZE_MATCH(xGetResAttributesReq);
if (stuff->mask & RES_STRIPE)
{
rep.uid = ScreenStripeHeight[stuff->id];
}
if (stuff->mask & RES_OUID)
{
rep.owneruid = OwnerUID;
}
if (stuff->resourceType == IsWindow &&
(stuff->mask & (RES_UID | RES_SL )))
{
pWin = LookupWindow(stuff->id, client);
if (pWin)
{
tsolres = TsolWindowPriv(pWin);
}
else
{
client->errorValue = stuff->id;
return (BadWindow);
}
if (err_code = xtsol_policy(TSOL_RES_WINDOW, TSOL_READ, pWin,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
}
if (stuff->resourceType == IsPixmap &&
(stuff->mask & (RES_UID | RES_SL )))
{
pMap = (PixmapPtr)LookupIDByType(stuff->id, RT_PIXMAP);
if (pMap)
{
tsolres = TsolPixmapPriv(pMap);
}
else
{
client->errorValue = stuff->id;
return (BadPixmap);
}
if (err_code = xtsol_policy(TSOL_RES_PIXMAP, TSOL_READ, pMap,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
}
if (stuff->mask & RES_UID)
{
rep.uid = tsolres->uid;
}
/* allocate temp storage for labels */
sl = (bslabel_t *)(xalloc(SL_SIZE));
rep.sllength = rep.illength = rep.iillength = 0;
if (sl == NULL)
return (BadAlloc);
/* fill the fields as per request mask */
if (stuff->mask & RES_SL)
{
memcpy(sl, tsolres->sl, SL_SIZE);
rep.sllength = SL_SIZE;
}
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = (CARD32) (rep.sllength)/4;
if (rep.length > 0)
{
reply_length = rep.length*4;
write_to_client = 1;
}
if (client->swapped)
{
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.uid, n);
swapl(&rep.owneruid, n);
swaps(&rep.sllength, n);
swaps(&rep.illength, n);
swaps(&rep.iillength, n);
}
WriteToClient(client, sizeof(xGetResAttributesReply), (char *)&rep);
if (write_to_client == 1)
{
WriteToClient(client, reply_length, (char *)sl);
}
xfree(sl);
return (client->noClientException);
}
int
ProcMakeTPWindow(ClientPtr client)
{
WindowPtr pWin, pParent;
int err_code;
TsolInfoPtr tsolinfo;
extern void ReflectStackChange(WindowPtr, WindowPtr, VTKind);
REQUEST(xMakeTPWindowReq);
REQUEST_SIZE_MATCH(xMakeTPWindowReq);
/*
* Session type single-level? This is set by the
* label builder
*/
tsolinfo = GetClientTsolInfo(client);
if (tsolinfo && HasTrustedPath(tsolinfo) &&
blequal(&SessionLO, &SessionHI) && stuff->id == 0) {
tsolMultiLevel = FALSE;
return (client->noClientException);
}
#if defined(PANORAMIX)
if (!noPanoramiXExtension)
{
PanoramiXRes *panres = NULL;
int j;
if ((panres = (PanoramiXRes *)LookupIDByType(stuff->id, XRT_WINDOW))
== NULL)
return BadWindow;
FOR_NSCREENS_BACKWARD(j)
{
pWin = LookupWindow(panres->info[j].id, client);
/* window should not be root but child of root */
if (!pWin || (!pWin->parent))
{
client->errorValue = stuff->id;
return (BadWindow);
}
if (err_code = xtsol_policy(TSOL_RES_TPWIN, TSOL_MODIFY, pWin,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
pParent = pWin->parent;
if (pParent->firstChild != pWin)
{
tpwin = (WindowPtr)NULL;
ReflectStackChange(pWin, pParent->firstChild, VTStack);
}
}
} else
#endif
{
pWin = LookupWindow(stuff->id, client);
/* window should not be root but child of root */
if (!pWin || (!pWin->parent))
{
client->errorValue = stuff->id;
return (BadWindow);
}
if (err_code = xtsol_policy(TSOL_RES_TPWIN, TSOL_MODIFY, pWin,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
pParent = pWin->parent;
if (pParent->firstChild != pWin)
{
tpwin = (WindowPtr)NULL;
ReflectStackChange(pWin, pParent->firstChild, VTStack);
}
}
tpwin = pWin;
/*
* Force kbd & ptr ungrab. This will cause
* screen to lock even when kbd/ptr grabbed by
* a client
*/
BreakAllGrabs(client);
return (client->noClientException);
}
/*
* Turn on window's Trusted bit
*/
static int
ProcMakeTrustedWindow(ClientPtr client)
{
WindowPtr pWin;
int err_code;
TsolInfoPtr tsolinfo;
REQUEST(xMakeTrustedWindowReq);
REQUEST_SIZE_MATCH(xMakeTrustedWindowReq);
pWin = LookupWindow(stuff->id, client);
/* window should not be root but child of root */
if (!pWin || (!pWin->parent))
{
client->errorValue = stuff->id;
return (BadWindow);
}
if (err_code = xtsol_policy(TSOL_RES_TPWIN, TSOL_MODIFY, pWin,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
tsolinfo = GetClientTsolInfo(client);
/* Turn on Trusted bit of the window */
tsolinfo->forced_trust = 1;
return (client->noClientException);
}
/*
* Turn off window's Trusted bit
*/
static int
ProcMakeUntrustedWindow(ClientPtr client)
{
WindowPtr pWin;
int err_code;
TsolInfoPtr tsolinfo;
REQUEST(xMakeUntrustedWindowReq);
REQUEST_SIZE_MATCH(xMakeUntrustedWindowReq);
pWin = LookupWindow(stuff->id, client);
/* window should not be root but child of root */
if (!pWin || (!pWin->parent))
{
client->errorValue = stuff->id;
return (BadWindow);
}
if (err_code = xtsol_policy(TSOL_RES_TPWIN, TSOL_MODIFY, pWin,
client, TSOL_ALL, (void *)MAJOROP))
{
return (err_code);
}
tsolinfo = GetClientTsolInfo(client);
tsolinfo->forced_trust = 0;
tsolinfo->trusted_path = FALSE;
return (client->noClientException);
}
/*
* Break keyboard & ptr grabs of clients other than
* the requesting client.
* Called from ProcMakeTPWindow.
*/
static void
BreakAllGrabs(ClientPtr client)
{
ClientPtr grabclient;
DeviceIntPtr keybd = inputInfo.keyboard;
GrabPtr kbdgrab = keybd->grab;
DeviceIntPtr mouse = inputInfo.pointer;
GrabPtr ptrgrab = mouse->grab;
if (kbdgrab) {
grabclient = clients[CLIENT_ID(kbdgrab->resource)];
if (client->index != grabclient->index)
(*keybd->DeactivateGrab)(keybd);
}
if (ptrgrab) {
grabclient = clients[CLIENT_ID(ptrgrab->resource)];
if (client->index != grabclient->index)
(*mouse->DeactivateGrab)(mouse);
}
}
/*
* Trusted Network interface module. Uses tsix API
*/
static void
TsolSetClientInfo(ClientPtr client)
{
bslabel_t *sl;
bslabel_t admin_low;
priv_set_t *privs;
const au_mask_t *amask;
socklen_t namelen;
struct auditinfo auinfo;
struct auditinfo *pauinfo;
OsCommPtr oc = (OsCommPtr)client->osPrivate;
int fd = oc->fd;
ucred_t *uc = NULL;
extern au_id_t ucred_getauid(const ucred_t *uc);
extern au_asid_t ucred_getasid(const ucred_t *uc);
extern const au_mask_t *ucred_getamask(const ucred_t *uc);
TsolInfoPtr tsolinfo = TsolClientPriv(client);
/* Get client attributes from the socket */
if (getpeerucred(fd, &uc) == -1) {
tsolinfo->uid = (uid_t)(-1);
tsolinfo->sl = NULL;
perror("getpeerucred failed\n");
ErrorF("SUN_TSOL: Cannot get client attributes\n");
return;
}
/* Extract individual fields from the cred structure */
tsolinfo->zid = ucred_getzoneid(uc);
tsolinfo->uid = ucred_getruid(uc);
tsolinfo->euid = ucred_geteuid(uc);
tsolinfo->gid = ucred_getrgid(uc);
tsolinfo->egid = ucred_getegid(uc);
tsolinfo->pid = ucred_getpid(uc);
sl = ucred_getlabel(uc);
tsolinfo->sl = (bslabel_t *)lookupSL(sl);
/* Set privileges */
if ((tsolinfo->privs = priv_allocset()) != NULL) {
if (tsolMultiLevel) {
privs = (priv_set_t *)ucred_getprivset(uc, PRIV_EFFECTIVE);
if (privs == NULL) {
priv_emptyset(tsolinfo->privs);
} else {
priv_copyset(privs, tsolinfo->privs);
}
} else {
priv_fillset(tsolinfo->privs);
}
}
tsolinfo->priv_debug = FALSE;
/*
* For remote hosts, the uid is determined during access control
* using Secure RPC
*/
if (tsolinfo->zid == (zoneid_t)-1) {
tsolinfo->client_type = CLIENT_REMOTE;
} else {
tsolinfo->client_type = CLIENT_LOCAL;
}
/* Set Trusted Path for local clients */
if (tsolinfo->zid == GLOBAL_ZONEID) {
tsolinfo->trusted_path = TRUE;
}else {
tsolinfo->trusted_path = FALSE;
}
if (tsolinfo->trusted_path || !tsolMultiLevel)
setClientTrustLevel(client, XSecurityClientTrusted);
else
setClientTrustLevel(client, XSecurityClientUntrusted);
tsolinfo->forced_trust = 0;
tsolinfo->iaddr = 0;
bsllow(&admin_low);
/* Set reasonable defaults for remote clients */
namelen = sizeof (tsolinfo->saddr);
if (getpeername(fd, (struct sockaddr *)&tsolinfo->saddr, &namelen) == 0
&& (tsolinfo->client_type == CLIENT_REMOTE)) {
int errcode;
char hostbuf[NI_MAXHOST];
tsol_host_type_t host_type;
extern tsol_host_type_t tsol_getrhtype(char *);
/* Use NI_NUMERICHOST to avoid DNS lookup */
errcode = getnameinfo((struct sockaddr *)&(tsolinfo->saddr), namelen,
hostbuf, sizeof(hostbuf), NULL, 0, NI_NUMERICHOST);
if (errcode) {
perror(gai_strerror(errcode));
} else {
host_type = tsol_getrhtype(hostbuf);
if ((host_type == SUN_CIPSO) &&
blequal(tsolinfo->sl, &admin_low)) {
tsolinfo->trusted_path = TRUE;
setClientTrustLevel(client,
XSecurityClientTrusted);
priv_fillset(tsolinfo->privs);
}
}
}
/* setup audit context */
if (getaudit(&auinfo) == 0) {
pauinfo = &auinfo;
} else {
pauinfo = NULL;
}
/* Audit id */
tsolinfo->auid = ucred_getauid(uc);
if (tsolinfo->auid == AU_NOAUDITID) {
tsolinfo->auid = UID_NOBODY;
}
/* session id */
tsolinfo->asid = ucred_getasid(uc);
/* Audit mask */
if ((amask = ucred_getamask(uc)) != NULL) {
tsolinfo->amask = *amask;
} else {
if (pauinfo != NULL) {
tsolinfo->amask = pauinfo->ai_mask;
} else {
tsolinfo->amask.am_failure = 0; /* clear the masks */
tsolinfo->amask.am_success = 0;
}
}
tsolinfo->asaverd = 0;
ucred_free(uc);
}
static enum auth_stat tsol_why;
static char *
tsol_authdes_decode(char *inmsg, int len)
{
struct rpc_msg msg;
char cred_area[MAX_AUTH_BYTES];
char verf_area[MAX_AUTH_BYTES];
char *temp_inmsg;
struct svc_req r;
bool_t res0, res1;
XDR xdr;
SVCXPRT xprt;
extern bool_t xdr_opaque_auth(XDR *, struct opaque_auth *);
temp_inmsg = (char *) xalloc(len);
memmove(temp_inmsg, inmsg, len);
memset((char *)&msg, 0, sizeof(msg));
memset((char *)&r, 0, sizeof(r));
memset(cred_area, 0, sizeof(cred_area));
memset(verf_area, 0, sizeof(verf_area));
msg.rm_call.cb_cred.oa_base = cred_area;
msg.rm_call.cb_verf.oa_base = verf_area;
tsol_why = AUTH_FAILED;
xdrmem_create(&xdr, temp_inmsg, len, XDR_DECODE);
if ((r.rq_clntcred = (caddr_t) xalloc(MAX_AUTH_BYTES)) == NULL)
goto bad1;
r.rq_xprt = &xprt;
/* decode into msg */
res0 = xdr_opaque_auth(&xdr, &(msg.rm_call.cb_cred));
res1 = xdr_opaque_auth(&xdr, &(msg.rm_call.cb_verf));
if ( ! (res0 && res1) )
goto bad2;
/* do the authentication */
r.rq_cred = msg.rm_call.cb_cred; /* read by opaque stuff */
if (r.rq_cred.oa_flavor != AUTH_DES) {
tsol_why = AUTH_TOOWEAK;
goto bad2;
}
#ifdef SVR4
if ((tsol_why = __authenticate(&r, &msg)) != AUTH_OK) {
#else
if ((tsol_why = _authenticate(&r, &msg)) != AUTH_OK) {
#endif
goto bad2;
}
return (((struct authdes_cred *) r.rq_clntcred)->adc_fullname.name);
bad2:
Xfree(r.rq_clntcred);
bad1:
return ((char *)0); /* ((struct authdes_cred *) NULL); */
}
static Bool
TsolCheckNetName (unsigned char *addr, short len, pointer closure)
{
return (len == (short) strlen ((char *) closure) &&
strncmp ((char *) addr, (char *) closure, len) == 0);
}
XID
TsolCheckAuthorization(unsigned int name_length, char *name, unsigned int data_length,
char *data, ClientPtr client, char **reason)
{
char domainname[128];
char netname[128];
char audit_ret;
u_int audit_val;
uid_t client_uid;
gid_t client_gid;
int client_gidlen;
char *fullname;
gid_t client_gidlist;
XID auth_token = (XID)(-1);
TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
extern int getdomainname(char *, int);
if (tsolinfo->uid == -1) {
/* Retrieve uid from SecureRPC */
if (strncmp(name, SECURE_RPC_AUTH, (size_t)name_length) == 0) {
fullname = tsol_authdes_decode(data, data_length);
if (fullname == NULL) {
ErrorF("Unable to authenticate Secure RPC client");
} else {
if (netname2user(fullname,
&client_uid, &client_gid,
&client_gidlen, &client_gidlist)) {
tsolinfo->uid = client_uid;
} else {
ErrorF("netname2user failed");
}
}
}
}
if (tsolinfo->uid == (uid_t)-1) {
tsolinfo->uid = UID_NOBODY; /* uid not available */
}
/*
* For multilevel desktop, limit connections to the trusted path
* i.e. global zone until a user logs in and the trusted stripe
* is in place. Unlabeled connections are rejected.
*/
if ((OwnerUID == (uid_t )(-1)) || (tsolMultiLevel && tpwin == NULL)) {
if (HasTrustedPath(tsolinfo)) {
auth_token = CheckAuthorization(name_length, name, data_length,
data, client, reason);
}
} else {
/*
* Workstation Owner set, client must be within label
* range or have trusted path
*/
if (tsolinfo->uid == OwnerUID) {
if ((tsolinfo->sl != NULL &&
(bldominates(tsolinfo->sl, &SessionLO) &&
bldominates(&SessionHI, tsolinfo->sl))) ||
(HasTrustedPath(tsolinfo))) {
auth_token = (XID)(tsolinfo->uid);
}
} else {
/* Allow root from global zone */
if (tsolinfo->uid == 0 && HasTrustedPath(tsolinfo)) {
auth_token = (XID)(tsolinfo->uid);
} else {
/*
* Access check based on uid. Check if
* roles or other uids have been added by
* xhost +role@
*/
getdomainname(domainname, sizeof(domainname));
if (!user2netname(netname, tsolinfo->uid, domainname)) {
return ((XID)-1);
}
if (ForEachHostInFamily (FamilyNetname, TsolCheckNetName,
(pointer) netname)) {
return ((XID)(tsolinfo->uid));
} else {
return (CheckAuthorization(name_length, name, data_length,
data, client, reason));
}
}
}
}
/* Audit the connection */
if (auth_token == (XID)(-1)) {
audit_ret = (char )-1; /* failure */
audit_val = 1;
} else {
audit_ret = 0; /* success */
audit_val = 0;
}
if (system_audit_on &&
(au_preselect(AUE_ClientConnect, &(tsolinfo->amask),
AU_PRS_BOTH, AU_PRS_USECACHE) == 1)) {
int status;
u_short connect_port = 0;
struct in_addr *connect_addr = NULL;
struct sockaddr_in *sin;
struct sockaddr_in6 *sin6;
switch (tsolinfo->saddr.ss_family) {
case AF_INET:
sin = (struct sockaddr_in *)&(tsolinfo->saddr);
connect_addr = &(sin->sin_addr);
connect_port = sin->sin_port;
break;
case AF_INET6:
sin6 = (struct sockaddr_in6 *)&(tsolinfo->saddr);
connect_addr = (struct in_addr *)&(sin6->sin6_addr);
connect_port = sin6->sin6_port;
break;
}
if (connect_addr == NULL || connect_port == 0) {
status = auditwrite(AW_EVENTNUM, AUE_ClientConnect,
AW_XCLIENT, client->index,
AW_SLABEL, tsolinfo->sl,
AW_RETURN, audit_ret, audit_val,
AW_WRITE, AW_END);
} else {
status = auditwrite(AW_EVENTNUM, AUE_ClientConnect,
AW_XCLIENT, client->index,
AW_SLABEL, tsolinfo->sl,
AW_INADDR, connect_addr,
AW_IPORT, connect_port,
AW_RETURN, audit_ret, audit_val,
AW_WRITE, AW_END);
}
if (!status)
(void) auditwrite(AW_FLUSH, AW_END);
tsolinfo->flags &= ~TSOL_DOXAUDIT;
tsolinfo->flags &= ~TSOL_AUDITEVENT;
}
return (auth_token);
}
static CALLBACK(
TsolProcessKeyboard)
{
XaceKeyAvailRec *rec = (XaceKeyAvailRec *) calldata;
xEvent *xE = rec->event;
DeviceIntPtr keybd = rec->keybd;
/* int count = rec->count; */
KeyClassPtr keyc = keybd->key;
extern void InitHotKey(HotKeyPtr hk);
extern void HandleHotKey(void);
if (xE->u.u.type == KeyPress)
{
if (!hotkey.initialized)
InitHotKey(&hotkey);
if (((xE->u.u.detail == hotkey.key) &&
(keyc->state != 0 && keyc->state == hotkey.shift)) ||
((xE->u.u.detail == hotkey.altkey) &&
(keyc->state != 0 && keyc->state == hotkey.altshift)))
HandleHotKey();
}
}
static CALLBACK(
TsolCheckPropertyAccess)
{
XacePropertyAccessRec *rec = (XacePropertyAccessRec *) calldata;
ClientPtr client = rec->client;
WindowPtr pWin = rec->pWin;
PropertyPtr pProp = *rec->ppProp;
Atom propertyName = pProp->propertyName;
Mask access_mode = rec->access_mode;
if (pProp == NULL) {
return;
}
if (access_mode & DixReadAccess) {
if (!PolyProperty(propertyName, pWin) &&
xtsol_policy(TSOL_RES_PROPERTY, TSOL_READ,
pProp, client, TSOL_ALL, (void *)MAJOROP))
rec->status = BadAccess;
/* this used to be:
return SecurityIgnoreOperation;
else
return SecurityAllowOperation;
*/
}
if (access_mode & DixWriteAccess) {
if (!PolyProperty(propertyName, pWin) &&
xtsol_policy(TSOL_RES_PROPERTY, TSOL_MODIFY,
pProp, client, TSOL_ALL, (void *)MAJOROP))
rec->status = BadAccess;
/* this used to be:
return SecurityIgnoreOperation;
else
return SecurityAllowOperation;
*/
}
if (access_mode & DixDestroyAccess) {
if (!PolyProperty(propertyName, pWin) &&
xtsol_policy(TSOL_RES_PROPERTY, TSOL_DESTROY,
pProp, client, TSOL_ALL, (void *)MAJOROP))
rec->status = BadAccess;
/* this used to be:
return SecurityIgnoreOperation;
else
return SecurityAllowOperation;
*/
}
}
static CALLBACK(
TsolCheckExtensionAccess)
{
XaceExtAccessRec *rec = (XaceExtAccessRec *) calldata;
if (TsolDisabledExtension(rec->ext->name)) {
rec->status = BadAccess;
}
}
#ifdef UNUSED
/*
* Return TRUE if host is cipso
*/
int
host_is_cipso(int fd)
{
struct sockaddr sname;
socklen_t namelen;
char *rhost;
tsol_host_type_t host_type;
struct sockaddr_in *so = (struct sockaddr_in *)&sname;
extern tsol_host_type_t tsol_getrhtype(char *);
namelen = sizeof (sname);
if (getpeername(fd, &sname, &namelen) == -1) {
perror("getsockname: failed\n");
return FALSE;
}
rhost = inet_ntoa(so->sin_addr);
host_type = tsol_getrhtype(rhost);
if (host_type == SUN_CIPSO) {
return TRUE;
}
return FALSE;
}
#endif