1088N/A/*
1088N/A * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A *
0N/A * Permission is hereby granted, free of charge, to any person obtaining a
919N/A * copy of this software and associated documentation files (the "Software"),
919N/A * to deal in the Software without restriction, including without limitation
919N/A * the rights to use, copy, modify, merge, publish, distribute, sublicense,
919N/A * and/or sell copies of the Software, and to permit persons to whom the
919N/A * Software is furnished to do so, subject to the following conditions:
0N/A *
919N/A * The above copyright notice and this permission notice (including the next
919N/A * paragraph) shall be included in all copies or substantial portions of the
919N/A * Software.
0N/A *
919N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
919N/A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
919N/A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
919N/A * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
919N/A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
919N/A * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
919N/A * DEALINGS IN THE SOFTWARE.
606N/A */
606N/A
606N/A
606N/A#ifdef HAVE_DIX_CONFIG_H
606N/A#include <dix-config.h>
606N/A#endif
0N/A
0N/A#include <sys/param.h>
0N/A#include <fcntl.h>
0N/A#include <sys/types.h>
0N/A#include <sys/stat.h>
0N/A#include <unistd.h>
0N/A#include <ucred.h>
0N/A#include <pwd.h>
0N/A#include <strings.h>
0N/A#include <sys/wait.h>
196N/A#include "auditwrite.h"
0N/A#include <bsm/libbsm.h>
0N/A#include <bsm/audit_uevents.h>
0N/A#include "tsol.h"
0N/A
0N/A#include "inputstr.h"
851N/A#include "xkbstr.h"
851N/A#include "xkbsrv.h"
0N/A
639N/A#include "dixevents.h"
0N/A#include "selection.h"
0N/A#include "osdep.h"
0N/A#include "tsolpolicy.h"
0N/A#include "swaprep.h"
0N/A#include "swapreq.h"
0N/A#include "servermd.h"
0N/A#ifdef PANORAMIX
0N/A#include "../Xext/panoramiXsrv.h"
0N/A#endif
0N/A#ifdef XCSECURITY
606N/A#include "../Xext/securitysrv.h"
0N/A#endif
606N/A#include "xace.h"
606N/A#include "xacestr.h"
606N/A
0N/A/*
0N/A * The event # here match those in /usr/include/bsm/audit_uevents.h.
0N/A * Changes in one should go with corresponding changes in another.
0N/A */
0N/A
0N/A#define MAX_AUDIT_EVENTS 100
0N/A
0N/Aint audit_eventsid[100][2] = {
606N/A { X_CreateWindow, AUE_CreateWindow },
606N/A { X_ChangeWindowAttributes, AUE_ChangeWindowAttributes },
606N/A { X_GetWindowAttributes, AUE_GetWindowAttributes },
606N/A { X_DestroyWindow, AUE_DestroyWindow },
606N/A { X_DestroySubwindows, AUE_DestroySubwindows },
606N/A { X_ChangeSaveSet, AUE_ChangeSaveSet },
606N/A { X_ReparentWindow, AUE_ReparentWindow },
606N/A { X_MapWindow, AUE_MapWindow },
606N/A { X_MapSubwindows, AUE_MapSubwindows },
606N/A { X_UnmapWindow, AUE_UnmapWindow },
606N/A { X_UnmapSubwindows, AUE_UnmapSubwindows },
606N/A { X_ConfigureWindow, AUE_ConfigureWindow },
606N/A { X_CirculateWindow, AUE_CirculateWindow },
606N/A { X_GetGeometry, AUE_GetGeometry },
606N/A { X_QueryTree, AUE_QueryTree },
606N/A { X_InternAtom, AUE_InternAtom },
606N/A { X_GetAtomName, AUE_GetAtomName },
606N/A { X_ChangeProperty, AUE_ChangeProperty },
606N/A { X_DeleteProperty, AUE_DeleteProperty },
606N/A { X_GetProperty, AUE_GetProperty },
606N/A { X_ListProperties, AUE_ListProperties },
606N/A { X_SetSelectionOwner, AUE_SetSelectionOwner },
606N/A { X_GetSelectionOwner, AUE_GetSelectionOwner },
606N/A { X_ConvertSelection, AUE_ConvertSelection },
606N/A { X_SendEvent, AUE_SendEvent },
606N/A { X_GrabPointer, AUE_GrabPointer },
606N/A { X_UngrabPointer, AUE_UngrabPointer },
606N/A { X_GrabButton, AUE_GrabButton },
606N/A { X_UngrabButton, AUE_UngrabButton },
606N/A { X_ChangeActivePointerGrab, AUE_ChangeActivePointerGrab },
606N/A { X_GrabKeyboard, AUE_GrabKeyboard },
606N/A { X_UngrabKeyboard, AUE_UngrabKeyboard },
606N/A { X_GrabKey, AUE_GrabKey },
606N/A { X_UngrabKey, AUE_UngrabKey },
606N/A { X_GrabServer, AUE_GrabServer },
606N/A { X_UngrabServer, AUE_UngrabServer },
606N/A { X_QueryPointer, AUE_QueryPointer },
606N/A { X_GetMotionEvents, AUE_GetMotionEvents },
606N/A { X_TranslateCoords, AUE_TranslateCoords },
606N/A { X_WarpPointer, AUE_WarpPointer },
606N/A { X_SetInputFocus, AUE_SetInputFocus },
606N/A { X_GetInputFocus, AUE_GetInputFocus },
606N/A { X_QueryKeymap, AUE_QueryKeymap },
606N/A { X_SetFontPath, AUE_SetFontPath },
606N/A { X_FreePixmap, AUE_FreePixmap },
606N/A { X_ChangeGC, AUE_ChangeGC },
606N/A { X_CopyGC, AUE_CopyGC },
606N/A { X_SetDashes, AUE_SetDashes },
606N/A { X_SetClipRectangles, AUE_SetClipRectangles },
606N/A { X_FreeGC, AUE_FreeGC },
606N/A { X_ClearArea, AUE_ClearArea },
606N/A { X_CopyArea, AUE_CopyArea },
606N/A { X_CopyPlane, AUE_CopyPlane },
606N/A { X_PolyPoint, AUE_PolyPoint },
606N/A { X_PolyLine, AUE_PolyLine },
606N/A { X_PolySegment, AUE_PolySegment },
606N/A { X_PolyRectangle, AUE_PolyRectangle },
606N/A { X_PolyArc, AUE_PolyArc },
606N/A { X_FillPoly, AUE_FillPolygon },
606N/A { X_PolyFillRectangle, AUE_PolyFillRectangle },
606N/A { X_PolyFillArc, AUE_PolyFillArc },
606N/A { X_PutImage, AUE_PutImage },
606N/A { X_GetImage, AUE_GetImage },
606N/A { X_PolyText8, AUE_PolyText8 },
606N/A { X_PolyText16, AUE_PolyText16 },
606N/A { X_ImageText8, AUE_ImageText8 },
606N/A { X_ImageText16, AUE_ImageText16 },
606N/A { X_CreateColormap, AUE_CreateColormap },
606N/A { X_FreeColormap, AUE_FreeColormap },
606N/A { X_CopyColormapAndFree, AUE_CopyColormapAndFree },
606N/A { X_InstallColormap, AUE_InstallColormap },
606N/A { X_UninstallColormap, AUE_UninstallColormap },
606N/A { X_ListInstalledColormaps, AUE_ListInstalledColormaps },
606N/A { X_AllocColor, AUE_AllocColor },
606N/A { X_AllocNamedColor, AUE_AllocNamedColor },
606N/A { X_AllocColorCells, AUE_AllocColorCells },
606N/A { X_AllocColorPlanes, AUE_AllocColorPlanes },
606N/A { X_FreeColors, AUE_FreeColors },
606N/A { X_StoreColors, AUE_StoreColors },
606N/A { X_StoreNamedColor, AUE_StoreNamedColor },
606N/A { X_QueryColors, AUE_QueryColors },
606N/A { X_LookupColor, AUE_LookupColor },
606N/A { X_CreateCursor, AUE_CreateCursor },
606N/A { X_CreateGlyphCursor, AUE_CreateGlyphCursor },
606N/A { X_FreeCursor, AUE_FreeCursor },
606N/A { X_RecolorCursor, AUE_RecolorCursor },
606N/A { X_ChangeKeyboardMapping, AUE_ChangeKeyboardMapping },
606N/A { X_ChangeKeyboardControl, AUE_ChangeKeyboardControl },
606N/A { X_Bell, AUE_Bell },
606N/A { X_ChangePointerControl, AUE_ChangePointerControl },
606N/A { X_SetScreenSaver, AUE_SetScreenSaver },
606N/A { X_ChangeHosts, AUE_ChangeHosts },
606N/A { X_SetAccessControl, AUE_SetAccessControl },
606N/A { X_SetCloseDownMode, AUE_SetCloseDownMode },
606N/A { X_KillClient, AUE_KillClient },
606N/A { X_RotateProperties, AUE_RotateProperties },
606N/A { X_ForceScreenSaver, AUE_ForceScreenSaver },
606N/A { X_SetPointerMapping, AUE_SetPointerMapping },
606N/A { X_SetModifierMapping, AUE_SetModifierMapping },
606N/A { X_NoOperation, AUE_XExtensions }
0N/A};
633N/A
799N/A
799N/Aextern priv_set_t *pset_win_config;
799N/Aextern TsolResPtr TsolDrawablePrivateate(DrawablePtr pDraw, ClientPtr client);
1088N/Aextern int tsol_check_policy(TsolInfoPtr tsolinfo, TsolResPtr tsolres,
1088N/A xpolicy_t flags, int reqcode);
799N/Aextern Bool client_has_privilege(TsolInfoPtr tsolinfo, priv_set_t *priv);
799N/A
0N/A
0N/A#define INITIAL_TSOL_NODELENGTH 1500
0N/A
0N/A/*
0N/A * Get number of atoms defined in the system
0N/A */
0N/Astatic Atom
606N/AGetLastAtom(void)
0N/A{
0N/A Atom a = (Atom) 1; /* atoms start at 1 */
0N/A
0N/A while (ValidAtom(a)) {
0N/A a++;
0N/A }
0N/A
0N/A return (--a);
0N/A}
0N/A
0N/A/*
0N/A * Update Tsol info for atoms. This function gets
0N/A * called typically during initialization. But, it could also get
0N/A * called if some atoms are created internally by server.
0N/A */
0N/Avoid
799N/AUpdateTsolNode(Atom thisAtom, ClientPtr client)
0N/A{
0N/A Atom lastAtom = GetLastAtom();
0N/A Atom ia;
799N/A int newsize;
0N/A
799N/A /* Allocate & Initialize the node for the first time */
799N/A if (tsol_node == NULL) {
1088N/A newsize = (lastAtom > INITIAL_TSOL_NODELENGTH ?
799N/A lastAtom : INITIAL_TSOL_NODELENGTH);
606N/A
1088N/A tsol_node = malloc((newsize + 1) * sizeof(TsolNodeRec));
799N/A if (tsol_node == NULL) {
799N/A ErrorF("Cannot allocate memory for Tsol node\n");
799N/A return;
799N/A }
0N/A
0N/A tsol_nodelength = newsize;
0N/A
799N/A /* Atom id 0 is invalid */
799N/A tsol_lastAtom = 0;
799N/A tsol_node[0].flags = 0;
799N/A tsol_node[0].slcount = 0;
799N/A tsol_node[0].sl = NULL;
799N/A tsol_node[0].slsize = 0;
799N/A tsol_node[0].IsSpecial = 0;
0N/A }
0N/A
799N/A /* If the node is already allocated, see if it needs to be extended */
799N/A if (lastAtom > tsol_lastAtom) {
1088N/A tsol_node = realloc(tsol_node,
1088N/A (lastAtom + 1) * sizeof(TsolNodeRec));
799N/A
799N/A if (tsol_node == NULL) {
799N/A ErrorF("Cannot allocate memory for Tsol node\n");
799N/A return;
799N/A }
799N/A
0N/A tsol_nodelength = lastAtom + 1;
799N/A
799N/A /*
799N/A * Initialize all the newly created atoms
799N/A */
799N/A for (ia = tsol_lastAtom + 1; ia <= lastAtom; ia++) {
799N/A const char *atomname = NameForAtom(ia);
0N/A
799N/A tsol_node[ia].slcount = 0;
799N/A tsol_node[ia].sl = NULL;
799N/A tsol_node[ia].slsize= 0;
1088N/A tsol_node[ia].flags = MatchTsolConfig(atomname,
1088N/A strlen(atomname));
1088N/A tsol_node[ia].IsSpecial = SpecialName(atomname,
1088N/A strlen(atomname));
799N/A if (client == NULL) {
1088N/A /* Mark as internal atom for
1088N/A GetAtomName to succeed */
799N/A tsol_node[ia].flags |= TSOLM_ATOM;
799N/A }
1088N/A
799N/A
799N/A }
799N/A tsol_lastAtom = lastAtom;
0N/A }
0N/A
799N/A /* Store the label info for non-global atoms */
1088N/A if (thisAtom != 0 && client != NULL &&
799N/A (tsol_node[thisAtom].flags & TSOLM_ATOM) == 0) {
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
799N/A TsolNodePtr tndp = &(tsol_node[thisAtom]);
799N/A int k;
799N/A
799N/A /* private atoms must have a matching sl */
799N/A for (k = 0; k < tndp->slcount; k++) {
799N/A if (tsolinfo->sl == tndp->sl[k]) {
799N/A return; /* found */
799N/A }
799N/A }
799N/A
799N/A /* Allocate storage for sl if needed */
799N/A if (tndp->sl == NULL) {
1088N/A tndp->sl = malloc(NODE_SLSIZE * (sizeof(bslabel_t *)));
0N/A
799N/A if (tndp->sl == NULL) {
799N/A ErrorF("Not enough memory for atoms\n");
799N/A }
799N/A
799N/A tndp->slcount = 0;
799N/A tndp->slsize = NODE_SLSIZE;
799N/A }
0N/A
799N/A /* Expand storage space for sl if needed */
799N/A if (tndp->slsize < tndp->slcount) {
799N/A newsize = tndp->slsize + NODE_SLSIZE;
1088N/A tndp->sl = realloc(tndp->sl,
1088N/A newsize * (sizeof(bslabel_t *)));
799N/A if (tndp->sl == NULL) {
799N/A ErrorF("Not enough memory for atoms\n");
799N/A }
799N/A tndp->slsize = newsize;
799N/A }
799N/A
799N/A
799N/A /* Store client's sl */
799N/A tndp->sl[tndp->slcount] = tsolinfo->sl;
799N/A tndp->slcount++;
0N/A }
0N/A}
0N/A
0N/Aint
606N/AProcTsolInternAtom(ClientPtr client)
0N/A{
0N/A Atom atom;
0N/A char *tchar;
0N/A REQUEST(xInternAtomReq);
0N/A
0N/A REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
0N/A if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
0N/A {
0N/A client->errorValue = stuff->onlyIfExists;
0N/A return(BadValue);
0N/A }
0N/A tchar = (char *) &stuff[1];
799N/A atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
799N/A
0N/A if (atom != BAD_RESOURCE)
0N/A {
799N/A /* Assign tsol attributes to this atom */
799N/A UpdateTsolNode(atom, client);
799N/A
0N/A xInternAtomReply reply;
0N/A reply.type = X_Reply;
0N/A reply.length = 0;
0N/A reply.sequenceNumber = client->sequence;
0N/A reply.atom = atom;
0N/A WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
0N/A return(client->noClientException);
0N/A }
0N/A else
0N/A return (BadAlloc);
0N/A}
0N/A
0N/Aint
606N/AProcTsolGetAtomName(ClientPtr client)
0N/A{
799N/A const char *str;
0N/A xGetAtomNameReply reply;
0N/A int len;
0N/A REQUEST(xResourceReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xResourceReq);
799N/A
799N/A if ((str = NameForAtom(stuff->id)))
0N/A {
799N/A char *blank_str = " ";
799N/A TsolNodePtr tndp;
799N/A
799N/A tndp = &(tsol_node[stuff->id]);
799N/A /* non-global atoms must have matching SL */
799N/A if ((tndp->flags & TSOLM_ATOM) == 0) {
799N/A int k;
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
799N/A
799N/A for (k = 0; k < tndp->slcount; k++) {
1088N/A if (tsolinfo->sl == tndp->sl[k])
799N/A break;
799N/A }
799N/A
799N/A /* SL can't be found, so return a blank string */
799N/A if (k == tndp->slcount)
799N/A str = blank_str;
799N/A }
799N/A
0N/A len = strlen(str);
0N/A reply.type = X_Reply;
0N/A reply.length = (len + 3) >> 2;
0N/A reply.sequenceNumber = client->sequence;
0N/A reply.nameLength = len;
0N/A WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
0N/A (void)WriteToClient(client, len, str);
0N/A return(client->noClientException);
0N/A }
1088N/A else
1088N/A {
0N/A client->errorValue = stuff->id;
0N/A return (BadAtom);
0N/A }
0N/A}
0N/A
0N/Aint
679N/ATsolInitWindow(ClientPtr client, WindowPtr pWin)
0N/A{
679N/A bslabel_t admin_low;
679N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
1088N/A TsolResPtr tsolres = TsolWindowPrivate(pWin);
0N/A
679N/A tsolres->uid = tsolinfo->uid;
679N/A tsolres->sl = tsolinfo->sl;
799N/A tsolres->pid = tsolinfo->pid;
799N/A
799N/A if (client == serverClient)
799N/A tsolres->internal = TRUE;
799N/A else
799N/A tsolres->internal = FALSE;
679N/A
679N/A bsllow(&admin_low);
679N/A if (blequal(tsolres->sl, &admin_low))
679N/A tsolres->flags = TRUSTED_MASK;
0N/A else
679N/A tsolres->flags = 0;
36N/A
36N/A return (Success);
0N/A}
0N/A
0N/Aint
679N/ATsolInitPixmap(ClientPtr client, PixmapPtr pMap)
0N/A{
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
1088N/A TsolResPtr tsolres = TsolPixmapPrivate(pMap);
0N/A
679N/A tsolres->uid = tsolinfo->uid;
679N/A tsolres->sl = tsolinfo->sl;
679N/A tsolres->flags = 0;
0N/A
679N/A return (Success);
0N/A}
0N/A
606N/A/* Generic ProcVector wrapper for functions which just need to set the
606N/A client's TrustLevel to Trusted before executing. */
606N/Astatic inline int
606N/AProcTsolUnwrapWithTrust(ClientPtr client, int majorop)
606N/A{
606N/A int result, savedtrust;
606N/A
606N/A savedtrust = setClientTrustLevel(client, XSecurityClientTrusted);
606N/A result = (*TsolSavedProcVector[majorop])(client);
606N/A setClientTrustLevel(client, savedtrust);
606N/A
606N/A return result;
606N/A}
606N/A
0N/A
36N/Astatic void
36N/AResetStripeWindow(ClientPtr client)
0N/A{
0N/A WindowPtr pParent;
36N/A WindowPtr pWin = NULL;
679N/A int rc;
0N/A
606N/A#if defined(PANORAMIX)
311N/A if (!noPanoramiXExtension)
311N/A {
470N/A PanoramiXRes *panres = NULL;
470N/A int j;
470N/A
470N/A if (tpwin) {
1088N/A rc = dixLookupResourceByType((pointer *) &panres,
1088N/A tpwin->drawable.id, XRT_WINDOW,
1088N/A client, DixReadAccess);
1088N/A if (rc != Success)
470N/A return;
470N/A }
470N/A
470N/A FOR_NSCREENS_BACKWARD(j)
470N/A {
470N/A if (panres == NULL)
470N/A return;
470N/A /* Validate trusted stripe window */
1088N/A rc = dixLookupWindow(&pWin, panres->info[j].id, client,
679N/A DixReadAccess);
679N/A if (rc != Success)
679N/A return;
470N/A
470N/A if (tpwin == NullWindow || pWin == NullWindow)
470N/A return;
470N/A
470N/A pParent = pWin->parent;
470N/A if (!pParent || pParent->firstChild == pWin)
470N/A return;
470N/A
470N/A ReflectStackChange(pWin, pParent->firstChild, VTStack);
470N/A }
311N/A } else
311N/A#endif
311N/A {
311N/A /* Validate trusted stripe window */
679N/A if (tpwin) {
1088N/A rc = dixLookupWindow(&pWin, tpwin->drawable.id, client,
679N/A DixReadAccess);
679N/A if (rc != Success)
679N/A return;
679N/A }
311N/A
311N/A if (tpwin == NullWindow || pWin == NullWindow)
311N/A return;
311N/A
311N/A pParent = tpwin->parent;
311N/A /* stripe is already at head, nothing to do */
311N/A if (!pParent || pParent->firstChild == tpwin)
311N/A return;
311N/A
311N/A ReflectStackChange(tpwin, pParent->firstChild, VTStack);
311N/A }
0N/A}
0N/A
606N/A
606N/A/* Generic ProcVector wrapper for functions which just need to have
606N/A ResetStripeWindow called after executing. */
606N/Astatic inline int
606N/AProcTsolUnwrapAndResetStripe(ClientPtr client, int majorop)
606N/A{
606N/A int result;
606N/A
606N/A result = (*TsolSavedProcVector[majorop])(client);
36N/A ResetStripeWindow(client);
0N/A
0N/A return result;
0N/A}
0N/A
0N/Aint
679N/AProcTsolCreateWindow(ClientPtr client)
679N/A{
679N/A return ProcTsolUnwrapAndResetStripe(client, X_CreateWindow);
679N/A}
679N/A
679N/Aint
679N/AProcTsolChangeWindowAttributes(ClientPtr client)
679N/A{
679N/A return ProcTsolUnwrapAndResetStripe(client, X_ChangeWindowAttributes);
679N/A}
679N/A
679N/Aint
606N/AProcTsolConfigureWindow(ClientPtr client)
0N/A{
606N/A return ProcTsolUnwrapAndResetStripe(client, X_ConfigureWindow);
0N/A}
0N/A
0N/Aint
606N/AProcTsolCirculateWindow(ClientPtr client)
0N/A{
606N/A return ProcTsolUnwrapAndResetStripe(client, X_CirculateWindow);
0N/A}
0N/A
0N/Aint
606N/AProcTsolReparentWindow(ClientPtr client)
0N/A{
606N/A return ProcTsolUnwrapAndResetStripe(client, X_ReparentWindow);
0N/A}
0N/A
0N/A/*
606N/A * HandleHotKey -
0N/A * HotKey is Meta(Diamond)+ Stop Key
705N/A * Breaks untrusted Ptr and Kbd grabs.
606N/A * Trusted Grabs are NOT broken
0N/A * Warps pointer to the Trusted Stripe if not Trusted grabs in force.
0N/A */
0N/Avoid
705N/AHandleHotKey(DeviceIntPtr keybd)
0N/A{
0N/A int x, y;
0N/A Bool trusted_grab = FALSE;
0N/A ClientPtr client;
705N/A DeviceIntPtr mouse = GetPairedDevice(keybd);
606N/A TsolInfoPtr tsolinfo;
705N/A GrabPtr ptrgrab = mouse->deviceGrab.grab;
705N/A GrabPtr kbdgrab = keybd->deviceGrab.grab;
0N/A ScreenPtr pScreen;
0N/A
0N/A if (kbdgrab)
0N/A {
0N/A client = clients[CLIENT_ID(kbdgrab->resource)];
0N/A tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (tsolinfo)
0N/A {
0N/A if (HasTrustedPath(tsolinfo))
0N/A trusted_grab = TRUE;
0N/A else
705N/A (*keybd->deviceGrab.DeactivateGrab)(keybd);
0N/A }
0N/A
0N/A if (ptrgrab)
0N/A {
0N/A client = clients[CLIENT_ID(ptrgrab->resource)];
0N/A tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (tsolinfo)
0N/A {
0N/A if (HasTrustedPath(tsolinfo))
0N/A trusted_grab = TRUE;
0N/A else
705N/A (*mouse->deviceGrab.DeactivateGrab)(mouse);
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (!trusted_grab)
0N/A {
0N/A /*
0N/A * Warp the pointer to the Trusted Stripe
0N/A */
0N/A pScreen = screenInfo.screens[0];
0N/A x = pScreen->width/2;
0N/A y = pScreen->height - StripeHeight/2;
705N/A (*pScreen->SetCursorPosition)(mouse, pScreen, x, y, TRUE);
0N/A }
0N/A}
0N/A
633N/A#ifdef UNUSED
0N/Avoid
606N/APrintSiblings(WindowPtr p1)
0N/A{
0N/A WindowPtr p2;
0N/A
0N/A if (p1 == NULL || p1->parent == NULL) return;
0N/A
0N/A p2 = p1->parent->firstChild;
0N/A while (p2)
0N/A {
606N/A ErrorF( "(%x, %d, %d, %x)\n", p2, p2->drawable.width,
0N/A p2->drawable.height, p2->prevSib);
0N/A p2 = p2->nextSib;
0N/A }
0N/A}
0N/A
0N/A/*
0N/A * Checks that tpwin & its siblings have same
0N/A * parents. Returns 0 if OK, a # indicating which
0N/A * Sibling has a bad parent
0N/A */
0N/Aint
606N/ACheckTPWin(void)
0N/A{
0N/A WindowPtr pWin;
0N/A int count = 1;
0N/A
0N/A pWin = tpwin->nextSib;
0N/A while (pWin)
0N/A {
0N/A if (pWin->parent->parent)
0N/A return count;
0N/A pWin = pWin->nextSib;
0N/A ++count;
0N/A }
0N/A return 0;
0N/A}
633N/A#endif /* UNUSED */
0N/A
0N/A/* NEW */
0N/A
0N/Aint
606N/AProcTsolGetGeometry(ClientPtr client)
0N/A{
0N/A xGetGeometryReply rep;
0N/A int status;
0N/A
0N/A REQUEST(xResourceReq);
0N/A
196N/A if ( noPanoramiXExtension )
0N/A {
196N/A if ((status = GetGeometry(client, &rep)) != Success)
196N/A return status;
196N/A
196N/A /* Reduce root window height = stripe height */
196N/A if (stuff->id == rep.root)
196N/A {
196N/A rep.height -= StripeHeight;
196N/A }
196N/A
196N/A WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
196N/A return(client->noClientException);
196N/A
606N/A } else
196N/A {
196N/A status = (*TsolSavedProcVector[X_GetGeometry])(client);
196N/A return (status);
0N/A }
0N/A}
0N/A
0N/Aint
606N/AProcTsolGrabServer(ClientPtr client)
0N/A{
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
633N/A /* REQUEST(xResourceReq); */
0N/A REQUEST_SIZE_MATCH(xReq);
0N/A
799N/A if (priv_win_config ||
799N/A client_has_privilege(tsolinfo, pset_win_config)) {
799N/A return (*TsolSavedProcVector[X_GrabServer])(client);
799N/A } else {
0N/A /* turn off auditing because operation ignored */
0N/A tsolinfo->flags &= ~TSOL_DOXAUDIT;
0N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
0N/A
0N/A return(client->noClientException);
0N/A }
0N/A}
0N/A
0N/Aint
606N/AProcTsolUngrabServer(ClientPtr client)
0N/A{
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
633N/A /* REQUEST(xResourceReq); */
0N/A REQUEST_SIZE_MATCH(xReq);
0N/A
799N/A if (priv_win_config ||
799N/A client_has_privilege(tsolinfo, pset_win_config)) {
799N/A return (*TsolSavedProcVector[X_UngrabServer])(client);
799N/A } else {
0N/A /* turn off auditing because operation ignored */
0N/A tsolinfo->flags &= ~TSOL_DOXAUDIT;
0N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
0N/A
0N/A return(client->noClientException);
0N/A }
0N/A}
0N/A
0N/Aint
606N/AProcTsolQueryTree(ClientPtr client)
0N/A{
0N/A xQueryTreeReply reply;
606N/A int rc, numChildren = 0;
606N/A WindowPtr pChild, pWin, pHead;
0N/A Window *childIDs = (Window *)NULL;
0N/A
0N/A#ifdef TSOL
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
799N/A TsolResPtr tsolres;
799N/A xpolicy_t flags;
0N/A#endif /* TSOL */
0N/A
0N/A REQUEST(xResourceReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xResourceReq);
606N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
606N/A if (rc != Success)
606N/A return rc;
0N/A
0N/A#ifdef TSOL
799N/A flags = (TSOL_MAC|TSOL_DAC|TSOL_READOP);
0N/A /*
0N/A * Because of its recursive nature, QuerryTree can leave a huge trail
0N/A * of audit records which could make deciphering the audit log for
0N/A * critical records difficult. So we turn off any more auditing of
0N/A * this protocol.
0N/A */
0N/A tsolinfo->flags &= ~TSOL_DOXAUDIT;
0N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
0N/A#endif /* TSOL */
0N/A
0N/A reply.type = X_Reply;
1088N/A reply.root = pWin->drawable.pScreen->root->drawable.id;
0N/A reply.sequenceNumber = client->sequence;
0N/A if (pWin->parent)
0N/A reply.parent = pWin->parent->drawable.id;
0N/A else
0N/A reply.parent = (Window)None;
0N/A pHead = RealChildHead(pWin);
0N/A for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
0N/A#ifdef TSOL
0N/A {
1088N/A tsolres = TsolWindowPrivate(pChild);
1088N/A if (tsol_check_policy(tsolinfo, tsolres, flags, MAJOROP_CODE) ==
1088N/A Success) {
799N/A numChildren++;
799N/A }
0N/A }
0N/A#else /* !TSOL */
0N/A numChildren++;
0N/A#endif /* TSOL */
0N/A if (numChildren)
0N/A {
0N/A int curChild = 0;
0N/A
1088N/A childIDs = malloc(numChildren * sizeof(Window));
0N/A if (!childIDs)
0N/A return BadAlloc;
0N/A for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
0N/A#ifdef TSOL
0N/A {
0N/A
1088N/A tsolres = TsolWindowPrivate(pChild);
1088N/A if (tsol_check_policy(tsolinfo, tsolres, flags, MAJOROP_CODE) ==
1088N/A Success) {
0N/A childIDs[curChild++] = pChild->drawable.id;
799N/A }
799N/A }
0N/A#else /* !TSOL */
0N/A childIDs[curChild++] = pChild->drawable.id;
0N/A#endif /* TSOL */
0N/A }
606N/A
0N/A reply.nChildren = numChildren;
0N/A reply.length = (numChildren * sizeof(Window)) >> 2;
606N/A
0N/A WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
0N/A if (numChildren)
0N/A {
0N/A client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
0N/A WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
1088N/A free(childIDs);
0N/A }
0N/A
0N/A return(client->noClientException);
0N/A}
0N/A
606N/ACALLBACK(
606N/ATsolAuditStart)
0N/A{
606N/A XaceAuditRec *rec = (XaceAuditRec *) calldata;
606N/A ClientPtr client = rec->client;
606N/A
0N/A unsigned int protocol;
633N/A int xevent_num = -1;
0N/A int count = 0;
0N/A int status = 0;
0N/A Bool do_x_audit = FALSE;
0N/A Bool audit_event = FALSE;
0N/A TsolInfoPtr tsolinfo = (TsolInfoPtr)NULL;
0N/A tsolinfo = GetClientTsolInfo(client);
606N/A if (system_audit_on &&
36N/A (tsolinfo->amask.am_success || tsolinfo->amask.am_failure)) {
36N/A
36N/A do_x_audit = TRUE;
36N/A auditwrite(AW_PRESELECT, &(tsolinfo->amask), AW_END);
606N/A
36N/A /*
36N/A * X audit events start from 9101 in audit_uevents.h. The first two
36N/A * events are non-protocol ones viz. ClientConnect, mapped to 9101
36N/A * and ClientDisconnect, mapped to 9102.
36N/A * The protocol events are mapped from 9103 onwards in the serial
36N/A * order of their respective protocol opcode, for eg, the protocol
36N/A * UngrabPointer which is has a protocol opcode 27 is mapped to
36N/A * 9129 (9102 + 27).
36N/A * All extension protocols are mapped to a single audit event
36N/A * AUE_XExtension as opcodes are assigined dynamically to these
36N/A * protocols. We set the extension protocol opcode to be 128, one
36N/A * more than the last standard opcode.
36N/A */
799N/A protocol = (unsigned int)MAJOROP_CODE;
36N/A if (protocol > X_NoOperation) {
36N/A xevent_num = audit_eventsid[MAX_AUDIT_EVENTS - 1][1];
36N/A audit_event = TRUE;
36N/A } else {
36N/A for (count = 0; count < MAX_AUDIT_EVENTS; count++) {
36N/A if (protocol == audit_eventsid[count][0]) {
36N/A xevent_num = audit_eventsid[count][1];
0N/A audit_event = TRUE;
0N/A break;
36N/A }
36N/A }
36N/A }
0N/A
36N/A /*
36N/A * Exclude Clients with Trusted Path such as tsoldtwm, tsoldtsession etc
36N/A * from generating the audit records for X protocols
36N/A */
36N/A if (audit_event && do_x_audit && !HasTrustedPath(tsolinfo) &&
36N/A (au_preselect(xevent_num, &(tsolinfo->amask), AU_PRS_BOTH,
36N/A AU_PRS_USECACHE) == 1)) {
36N/A tsolinfo->flags |= TSOL_AUDITEVENT;
36N/A status = auditwrite(AW_EVENTNUM, xevent_num, AW_APPEND, AW_END);
36N/A } else {
36N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
36N/A tsolinfo->flags &= ~TSOL_DOXAUDIT;
36N/A }
36N/A }
0N/A}
0N/A
606N/ACALLBACK(
606N/ATsolAuditEnd)
0N/A{
606N/A XaceAuditRec *rec = (XaceAuditRec *) calldata;
606N/A ClientPtr client = rec->client;
606N/A int result = rec->requestResult;
606N/A
0N/A char audit_ret = (char)NULL;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (tsolinfo->flags & TSOL_DOXAUDIT)
0N/A {
0N/A tsolinfo->flags &= ~TSOL_DOXAUDIT;
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
0N/A if (result != Success)
0N/A audit_ret = -1;
0N/A else
0N/A audit_ret = 0;
0N/A auditwrite(AW_RETURN, audit_ret, (u_int)result,
0N/A AW_WRITE, AW_END);
0N/A }
0N/A else if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A {
0N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
0N/A auditwrite(AW_DISCARDRD, -1, AW_END);
0N/A }
0N/A}
0N/A
0N/Aint
606N/AProcTsolQueryPointer(ClientPtr client)
0N/A{
0N/A xQueryPointerReply rep;
606N/A WindowPtr pWin, ptrWin;
705N/A DeviceIntPtr mouse = PickPointer(client);
851N/A DeviceIntPtr keyboard;
851N/A SpritePtr pSprite;
606N/A int rc;
799N/A TsolResPtr tsolres;
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
799N/A xpolicy_t flags;
799N/A
606N/A REQUEST(xResourceReq);
0N/A REQUEST_SIZE_MATCH(xResourceReq);
606N/A
606N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
606N/A if (rc != Success)
606N/A return rc;
851N/A rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess);
851N/A if (rc != Success && rc != BadAccess)
851N/A return rc;
851N/A
851N/A keyboard = GetPairedDevice(mouse);
851N/A
851N/A pSprite = mouse->spriteInfo->sprite;
0N/A
705N/A ptrWin = GetSpriteWindow(mouse);
1088N/A tsolres = TsolWindowPrivate(ptrWin);
799N/A flags = (TSOL_MAC|TSOL_DAC|TSOL_READOP);
799N/A
799N/A if (tsol_check_policy(tsolinfo, tsolres, flags, MAJOROP_CODE) == Success) {
0N/A return (*TsolSavedProcVector[X_QueryPointer])(client);
799N/A }
0N/A
0N/A if (mouse->valuator->motionHintWindow)
0N/A MaybeStopHint(mouse, client);
851N/A memset(&rep, 0, sizeof(xQueryPointerReply));
0N/A rep.type = X_Reply;
0N/A rep.sequenceNumber = client->sequence;
851N/A rep.mask = mouse->button ? (mouse->button->state) : 0;
851N/A rep.mask |= XkbStateFieldFromRec(&keyboard->key->xkbInfo->state);
0N/A rep.length = 0;
0N/A rep.root = RootOf(pWin);
0N/A rep.rootX = 0;
0N/A rep.rootY = 0;
0N/A rep.child = None;
0N/A rep.sameScreen = xTrue;
0N/A rep.winX = 0;
0N/A rep.winY = 0;
0N/A
0N/A WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
0N/A
606N/A return(Success);
606N/A}
606N/A
606N/A
606N/Aint
606N/AProcTsolQueryExtension(ClientPtr client)
606N/A{
606N/A /* Allow extensions in the labeled zones */
606N/A return ProcTsolUnwrapWithTrust(client, X_QueryExtension);
0N/A}
36N/A
36N/Aint
606N/AProcTsolListExtensions(ClientPtr client)
36N/A{
36N/A /* Allow extensions in the labeled zones */
606N/A return ProcTsolUnwrapWithTrust(client, X_ListExtensions);
36N/A}
36N/A
36N/Aint
606N/AProcTsolMapWindow(ClientPtr client)
36N/A{
606N/A return ProcTsolUnwrapWithTrust(client, X_MapWindow);
36N/A}
36N/A
36N/Aint
606N/AProcTsolMapSubwindows(ClientPtr client)
36N/A{
606N/A return ProcTsolUnwrapWithTrust(client, X_MapSubwindows);
36N/A}
64N/A
64N/Astatic int
606N/ATsolDoGetImage(
799N/A ClientPtr client,
799N/A int format,
606N/A Drawable drawable,
606N/A int x, int y, int width, int height,
606N/A Mask planemask,
606N/A xGetImageReply **im_return)
64N/A{
606N/A DrawablePtr pDraw;
606N/A int nlines, linesPerBuf, rc;
64N/A register int linesDone;
64N/A long widthBytesLine, length;
64N/A Mask plane = 0;
64N/A char *pBuf;
64N/A xGetImageReply xgi;
64N/A
64N/A#ifdef TSOL
64N/A Bool getimage_ok = TRUE; /* if false get all 0s */
64N/A Bool overlap = FALSE;
64N/A Bool not_root_window = FALSE;
633N/A WindowPtr pHead = NULL, pWin = NULL, pRoot;
64N/A TsolResPtr tsolres_win;
64N/A BoxRec winbox, box;
64N/A BoxPtr pwinbox;
64N/A DrawablePtr pDrawtmp;
799N/A TsolResPtr tsolres;
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
799N/A xpolicy_t flags;
64N/A#endif /* TSOL */
64N/A
64N/A if ((format != XYPixmap) && (format != ZPixmap))
64N/A {
64N/A client->errorValue = format;
64N/A return(BadValue);
64N/A }
606N/A rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess);
606N/A if (rc != Success)
606N/A return rc;
606N/A
73N/A
73N/A#ifdef TSOL
799N/A flags = (TSOL_MAC|TSOL_DAC|TSOL_READOP);
799N/A tsolres = TsolDrawablePrivate(pDraw, client);
799N/A if (tsol_check_policy(tsolinfo, tsolres, flags, MAJOROP_CODE) == Success)
64N/A {
606N/A return DoGetImage(client, format, drawable, x, y,
73N/A width, height, planemask, im_return);
73N/A }
73N/A
73N/A if (pDraw->type == DRAWABLE_WINDOW)
73N/A {
64N/A if (DrawableIsRoot(pDraw))
64N/A {
1188N/A DeviceIntPtr pDev = PickPointer(client);
1188N/A SpritePtr pSprite = pDev->spriteInfo->sprite;
1188N/A pWin = XYToWindow(pSprite, x, y);
64N/A if (!WindowIsRoot(pWin))
64N/A {
64N/A pDrawtmp = &(pWin->parent->drawable);
64N/A if (((WindowPtr) pDrawtmp)->realized)
64N/A {
73N/A int tmpx, tmpy;
73N/A
73N/A tmpx = x - pDrawtmp->x;
73N/A tmpy = y - pDrawtmp->y;
73N/A
73N/A /* requested area must be a subset of the window area */
73N/A if (tmpx >= 0 && tmpy >= 0 &&
73N/A width <= pDrawtmp->width &&
73N/A height <= pDrawtmp->height)
73N/A {
73N/A pDraw = pDrawtmp;
73N/A x = tmpx;
73N/A y = tmpy;
73N/A not_root_window = TRUE;
73N/A }
64N/A }
64N/A }
64N/A }
64N/A else
64N/A {
64N/A not_root_window = TRUE;
64N/A }
64N/A
64N/A if (not_root_window)
64N/A {
64N/A Window root;
64N/A WindowPtr tmpwin;
679N/A int rc;
64N/A
73N/A not_root_window = TRUE;
679N/A rc = dixLookupWindow(&tmpwin, pDraw->id, client, DixReadAccess);
679N/A if (rc != Success)
679N/A return rc;
679N/A
64N/A while (tmpwin)
64N/A {
64N/A if (tmpwin->parent && WindowIsRoot(tmpwin->parent))
64N/A {
64N/A pWin = tmpwin;
64N/A break;
64N/A }
64N/A tmpwin = tmpwin->parent;
64N/A }
64N/A pwinbox = WindowExtents(pWin, &winbox);
64N/A box.x1 = pwinbox->x1;
64N/A box.y1 = pwinbox->y1;
64N/A box.x2 = pwinbox->x2;
64N/A box.y2 = box.y1;
1088N/A tsolres_win = TsolWindowPrivate(pWin);
1088N/A root = pWin->drawable.pScreen->root->drawable.id;
679N/A rc = dixLookupWindow(&pRoot, root, client, DixReadAccess);
679N/A if (rc != Success)
679N/A return rc;
64N/A pHead = pRoot->firstChild;
64N/A }
64N/A
799N/A tsolres = TsolDrawablePrivate(pDraw, client);
799N/A if (tsol_check_policy(tsolinfo, tsolres, flags, MAJOROP_CODE) == Success)
799N/A getimage_ok = TRUE;
799N/A else
64N/A getimage_ok = FALSE;
73N/A }
64N/A#endif /* TSOL */
64N/A
73N/A if(pDraw->type == DRAWABLE_WINDOW)
73N/A {
73N/A
64N/A if( /* check for being viewable */
64N/A !((WindowPtr) pDraw)->realized ||
64N/A /* check for being on screen */
64N/A pDraw->x + x < 0 ||
64N/A pDraw->x + x + width > pDraw->pScreen->width ||
64N/A pDraw->y + y < 0 ||
64N/A pDraw->y + y + height > pDraw->pScreen->height ||
64N/A /* check for being inside of border */
64N/A x < - wBorderWidth((WindowPtr)pDraw) ||
64N/A x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
64N/A y < -wBorderWidth((WindowPtr)pDraw) ||
64N/A y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
64N/A )
64N/A return(BadMatch);
64N/A xgi.visual = wVisual (((WindowPtr) pDraw));
64N/A }
64N/A else
64N/A {
64N/A if(x < 0 ||
64N/A x+width > (int)pDraw->width ||
64N/A y < 0 ||
64N/A y+height > (int)pDraw->height
64N/A )
64N/A return(BadMatch);
64N/A xgi.visual = None;
64N/A }
64N/A
64N/A xgi.type = X_Reply;
64N/A xgi.sequenceNumber = client->sequence;
64N/A xgi.depth = pDraw->depth;
64N/A if(format == ZPixmap)
64N/A {
64N/A widthBytesLine = PixmapBytePad(width, pDraw->depth);
64N/A length = widthBytesLine * height;
64N/A
64N/A }
606N/A else
64N/A {
64N/A widthBytesLine = BitmapBytePad(width);
64N/A plane = ((Mask)1) << (pDraw->depth - 1);
64N/A /* only planes asked for */
64N/A length = widthBytesLine * height *
64N/A Ones(planemask & (plane | (plane - 1)));
64N/A
64N/A }
64N/A
64N/A xgi.length = length;
64N/A
64N/A if (im_return) {
1088N/A pBuf = malloc(sz_xGetImageReply + length);
64N/A if (!pBuf)
64N/A return (BadAlloc);
64N/A if (widthBytesLine == 0)
64N/A linesPerBuf = 0;
64N/A else
64N/A linesPerBuf = height;
64N/A *im_return = (xGetImageReply *)pBuf;
64N/A *(xGetImageReply *)pBuf = xgi;
64N/A pBuf += sz_xGetImageReply;
64N/A } else {
64N/A xgi.length = (xgi.length + 3) >> 2;
64N/A if (widthBytesLine == 0 || height == 0)
64N/A linesPerBuf = 0;
64N/A else if (widthBytesLine >= IMAGE_BUFSIZE)
64N/A linesPerBuf = 1;
64N/A else
64N/A {
64N/A linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
64N/A if (linesPerBuf > height)
64N/A linesPerBuf = height;
64N/A }
64N/A length = linesPerBuf * widthBytesLine;
64N/A if (linesPerBuf < height)
64N/A {
64N/A /* we have to make sure intermediate buffers don't need padding */
64N/A while ((linesPerBuf > 1) &&
64N/A (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
64N/A {
64N/A linesPerBuf--;
64N/A length -= widthBytesLine;
64N/A }
64N/A while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
64N/A {
64N/A linesPerBuf++;
64N/A length += widthBytesLine;
64N/A }
64N/A }
1088N/A if(!(pBuf = malloc(length)))
64N/A return (BadAlloc);
64N/A WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
64N/A }
64N/A
64N/A if (linesPerBuf == 0)
64N/A {
64N/A /* nothing to do */
64N/A }
64N/A else if (format == ZPixmap)
64N/A {
64N/A linesDone = 0;
64N/A while (height - linesDone > 0)
64N/A {
64N/A nlines = min(linesPerBuf, height - linesDone);
64N/A (*pDraw->pScreen->GetImage) (pDraw,
64N/A x,
64N/A y + linesDone,
606N/A width,
64N/A nlines,
64N/A format,
64N/A planemask,
64N/A (pointer) pBuf);
64N/A#ifdef TSOL
64N/A if (not_root_window)
64N/A {
64N/A WindowPtr over_win = (WindowPtr)NULL;
64N/A
64N/A box.y1 = y + linesDone + pDraw->y;
64N/A box.y2 = box.y1 + nlines;
64N/A over_win = AnyWindowOverlapsJustMe(pWin, pHead, &box);
799N/A if (over_win)
799N/A {
1088N/A tsolres = TsolWindowPrivate(over_win);
1088N/A if (tsol_check_policy(tsolinfo, tsolres, flags, MAJOROP_CODE) != Success)
799N/A overlap = TRUE;
64N/A }
64N/A }
64N/A
64N/A /*
64N/A * fill the buffer with zeros in case of security failure
64N/A */
64N/A if (!getimage_ok || overlap)
64N/A {
64N/A if (overlap)
64N/A overlap = FALSE;
64N/A memset(pBuf, 0, (int)(nlines * widthBytesLine));
64N/A
64N/A }
64N/A#endif /* TSOL */
64N/A
64N/A /* Note that this is NOT a call to WriteSwappedDataToClient,
64N/A as we do NOT byte swap */
64N/A if (!im_return)
64N/A {
64N/A/* Don't split me, gcc pukes when you do */
64N/A (void)WriteToClient(client,
64N/A (int)(nlines * widthBytesLine),
64N/A pBuf);
64N/A }
64N/A linesDone += nlines;
64N/A }
64N/A }
64N/A else /* XYPixmap */
64N/A {
64N/A for (; plane; plane >>= 1)
64N/A {
64N/A if (planemask & plane)
64N/A {
64N/A linesDone = 0;
64N/A while (height - linesDone > 0)
64N/A {
64N/A nlines = min(linesPerBuf, height - linesDone);
64N/A (*pDraw->pScreen->GetImage) (pDraw,
64N/A x,
64N/A y + linesDone,
606N/A width,
64N/A nlines,
64N/A format,
64N/A plane,
64N/A (pointer)pBuf);
64N/A#ifdef TSOL
64N/A if (not_root_window)
64N/A {
64N/A WindowPtr over_win = (WindowPtr)NULL;
64N/A
64N/A box.y1 = y + linesDone + pDraw->y;
64N/A box.y2 = box.y1 + nlines;
64N/A over_win = AnyWindowOverlapsJustMe(pWin, pHead, &box);
799N/A if (over_win)
799N/A {
1088N/A tsolres = TsolWindowPrivate(over_win);
1088N/A if (tsol_check_policy(tsolinfo, tsolres, flags,
1088N/A MAJOROP_CODE) != Success)
799N/A overlap = TRUE;
799N/A }
64N/A }
64N/A /*
64N/A * fill the buffer with zeros in case of security failure
64N/A */
64N/A if (!getimage_ok || overlap)
64N/A {
64N/A if (overlap)
64N/A overlap = FALSE;
64N/A memset(pBuf, 0, (int)(nlines * widthBytesLine));
64N/A
64N/A }
64N/A#endif /* TSOL */
64N/A
64N/A /* Note: NOT a call to WriteSwappedDataToClient,
64N/A as we do NOT byte swap */
64N/A if (im_return) {
64N/A pBuf += nlines * widthBytesLine;
64N/A } else {
64N/A/* Don't split me, gcc pukes when you do */
64N/A (void)WriteToClient(client,
64N/A (int)(nlines * widthBytesLine),
64N/A pBuf);
64N/A }
64N/A linesDone += nlines;
64N/A }
64N/A }
64N/A }
64N/A }
64N/A
64N/A if (!im_return)
1088N/A free(pBuf);
64N/A return (client->noClientException);
64N/A}
64N/A
64N/Aint
606N/AProcTsolGetImage(ClientPtr client)
64N/A{
64N/A REQUEST(xGetImageReq);
64N/A
64N/A REQUEST_SIZE_MATCH(xGetImageReq);
64N/A
799N/A return TsolDoGetImage(client, stuff->format, stuff->drawable,
64N/A stuff->x, stuff->y,
64N/A (int)stuff->width, (int)stuff->height,
64N/A stuff->planeMask, (xGetImageReply **)NULL);
64N/A}
64N/A
64N/Aint
606N/AProcTsolPolySegment(ClientPtr client)
64N/A{
64N/A int status;
64N/A GC *pGC;
64N/A DrawablePtr pDraw;
799N/A TsolResPtr tsolres;
799N/A xpolicy_t flags;
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
799N/A
64N/A REQUEST(xPolySegmentReq);
64N/A REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
64N/A
606N/A VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
64N/A
799N/A flags = (TSOL_MAC|TSOL_DAC|TSOL_WRITEOP);
799N/A tsolres = TsolDrawablePrivate(pDraw, client);
799N/A if (tsol_check_policy(tsolinfo, tsolres, flags, MAJOROP_CODE) != Success) {
799N/A /* ignore the error message */
799N/A return(client->noClientException);
64N/A }
64N/A
64N/A status = (*TsolSavedProcVector[X_PolySegment])(client);
64N/A
64N/A return (status);
64N/A}
64N/A
64N/Aint
606N/AProcTsolPolyRectangle (ClientPtr client)
64N/A{
64N/A int status;
64N/A GC *pGC;
64N/A DrawablePtr pDraw;
799N/A TsolResPtr tsolres;
799N/A xpolicy_t flags;
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
64N/A
64N/A REQUEST(xPolyRectangleReq);
64N/A REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
64N/A
606N/A VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
64N/A
799N/A flags = (TSOL_MAC|TSOL_DAC|TSOL_WRITEOP);
799N/A tsolres = TsolDrawablePrivate(pDraw, client);
799N/A if (tsol_check_policy(tsolinfo, tsolres, flags, MAJOROP_CODE) != Success) {
64N/A /* ignore the error message */
799N/A return(client->noClientException);
64N/A }
64N/A
64N/A status = (*TsolSavedProcVector[X_PolyRectangle])(client);
64N/A
64N/A return (status);
64N/A}
64N/A
64N/Aint
606N/AProcTsolCopyArea (ClientPtr client)
64N/A{
64N/A int status;
606N/A DrawablePtr pDst;
606N/A DrawablePtr pSrc;
606N/A GC *pGC;
606N/A int rc;
799N/A TsolResPtr tsolres;
799N/A xpolicy_t flags;
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
606N/A
64N/A REQUEST(xCopyAreaReq);
64N/A
64N/A REQUEST_SIZE_MATCH(xCopyAreaReq);
64N/A
606N/A VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
64N/A
64N/A if (stuff->dstDrawable != stuff->srcDrawable)
64N/A {
606N/A rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
606N/A DixReadAccess);
606N/A if (rc != Success)
606N/A return rc;
64N/A if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
64N/A {
64N/A client->errorValue = stuff->dstDrawable;
64N/A return (BadMatch);
64N/A }
64N/A }
64N/A else
64N/A pSrc = pDst;
64N/A
799N/A flags = (TSOL_MAC|TSOL_DAC|TSOL_READOP);
799N/A tsolres = TsolDrawablePrivate(pSrc, client);
799N/A if (tsol_check_policy(tsolinfo, tsolres, flags, MAJOROP_CODE) != Success) {
64N/A /* ignore the error message for DnD zap effect */
64N/A return(client->noClientException);
64N/A }
799N/A
799N/A flags = (TSOL_MAC|TSOL_DAC|TSOL_WRITEOP);
799N/A tsolres = TsolDrawablePrivate(pDst, client);
799N/A if (tsol_check_policy(tsolinfo, tsolres, flags, MAJOROP_CODE) != Success) {
64N/A /* ignore the error message for DnD zap effect */
64N/A return(client->noClientException);
64N/A }
64N/A
64N/A status = (*TsolSavedProcVector[X_CopyArea])(client);
64N/A
64N/A return (status);
64N/A}
64N/A
64N/Aint
606N/AProcTsolCopyPlane(ClientPtr client)
64N/A{
64N/A int savedtrust;
64N/A int status;
606N/A DrawablePtr psrcDraw, pdstDraw;
606N/A GC *pGC;
799N/A TsolResPtr tsolres;
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
799N/A xpolicy_t flags;
799N/A int rc;
799N/A
64N/A REQUEST(xCopyPlaneReq);
64N/A
64N/A REQUEST_SIZE_MATCH(xCopyPlaneReq);
64N/A
606N/A savedtrust = setClientTrustLevel(client, XSecurityClientTrusted);
606N/A
606N/A VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
64N/A
64N/A if (stuff->dstDrawable != stuff->srcDrawable)
64N/A {
606N/A rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
606N/A DixReadAccess);
606N/A if (rc != Success)
606N/A return rc;
606N/A
64N/A if (pdstDraw->pScreen != psrcDraw->pScreen)
64N/A {
64N/A client->errorValue = stuff->dstDrawable;
64N/A return (BadMatch);
64N/A }
64N/A }
64N/A else
64N/A psrcDraw = pdstDraw;
64N/A
799N/A flags = (TSOL_MAC|TSOL_DAC|TSOL_READOP);
799N/A tsolres = TsolDrawablePrivate(psrcDraw, client);
799N/A if (tsol_check_policy(tsolinfo, tsolres, flags, MAJOROP_CODE) != Success) {
64N/A /* ignore the error message for DnD zap effect */
64N/A return(client->noClientException);
64N/A }
799N/A
799N/A flags = (TSOL_MAC|TSOL_DAC|TSOL_WRITEOP);
799N/A tsolres = TsolDrawablePrivate(pdstDraw, client);
799N/A if (tsol_check_policy(tsolinfo, tsolres, flags, MAJOROP_CODE) != Success) {
799N/A /* ignore the error message for DnD zap effect */
799N/A return(client->noClientException);
64N/A }
64N/A
64N/A status = (*TsolSavedProcVector[X_CopyPlane])(client);
64N/A
64N/A return (status);
64N/A}