/*
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <fcntl.h>
#include <unistd.h>
#include <ucred.h>
#include <pwd.h>
#include <strings.h>
#include "auditwrite.h"
#include <bsm/audit_uevents.h>
#include "tsol.h"
#include "inputstr.h"
#include "xkbstr.h"
#include "xkbsrv.h"
#include "dixevents.h"
#include "selection.h"
#include "osdep.h"
#include "tsolpolicy.h"
#include "swaprep.h"
#include "swapreq.h"
#include "servermd.h"
#ifdef PANORAMIX
#include "../Xext/panoramiXsrv.h"
#endif
#ifdef XCSECURITY
#include "../Xext/securitysrv.h"
#endif
#include "xace.h"
#include "xacestr.h"
/*
* The event # here match those in /usr/include/bsm/audit_uevents.h.
* Changes in one should go with corresponding changes in another.
*/
{ X_MapWindow, AUE_MapWindow },
{ X_UnmapWindow, AUE_UnmapWindow },
{ X_GetGeometry, AUE_GetGeometry },
{ X_QueryTree, AUE_QueryTree },
{ X_InternAtom, AUE_InternAtom },
{ X_GetAtomName, AUE_GetAtomName },
{ X_GetProperty, AUE_GetProperty },
{ X_SendEvent, AUE_SendEvent },
{ X_GrabPointer, AUE_GrabPointer },
{ X_GrabButton, AUE_GrabButton },
{ X_GrabKey, AUE_GrabKey },
{ X_UngrabKey, AUE_UngrabKey },
{ X_GrabServer, AUE_GrabServer },
{ X_WarpPointer, AUE_WarpPointer },
{ X_QueryKeymap, AUE_QueryKeymap },
{ X_SetFontPath, AUE_SetFontPath },
{ X_FreePixmap, AUE_FreePixmap },
{ X_ChangeGC, AUE_ChangeGC },
{ X_CopyGC, AUE_CopyGC },
{ X_SetDashes, AUE_SetDashes },
{ X_FreeGC, AUE_FreeGC },
{ X_ClearArea, AUE_ClearArea },
{ X_CopyArea, AUE_CopyArea },
{ X_CopyPlane, AUE_CopyPlane },
{ X_PolyPoint, AUE_PolyPoint },
{ X_PolyLine, AUE_PolyLine },
{ X_PolySegment, AUE_PolySegment },
{ X_PolyArc, AUE_PolyArc },
{ X_FillPoly, AUE_FillPolygon },
{ X_PolyFillArc, AUE_PolyFillArc },
{ X_PutImage, AUE_PutImage },
{ X_GetImage, AUE_GetImage },
{ X_PolyText8, AUE_PolyText8 },
{ X_PolyText16, AUE_PolyText16 },
{ X_ImageText8, AUE_ImageText8 },
{ X_ImageText16, AUE_ImageText16 },
{ X_AllocColor, AUE_AllocColor },
{ X_FreeColors, AUE_FreeColors },
{ X_StoreColors, AUE_StoreColors },
{ X_QueryColors, AUE_QueryColors },
{ X_LookupColor, AUE_LookupColor },
{ X_FreeCursor, AUE_FreeCursor },
{ X_ChangeHosts, AUE_ChangeHosts },
{ X_KillClient, AUE_KillClient },
};
extern priv_set_t *pset_win_config;
/*
* Get number of atoms defined in the system
*/
static Atom
GetLastAtom(void)
{
while (ValidAtom(a)) {
a++;
}
return (--a);
}
/*
* Update Tsol info for atoms. This function gets
* called typically during initialization. But, it could also get
* called if some atoms are created internally by server.
*/
void
{
int newsize;
/* Allocate & Initialize the node for the first time */
ErrorF("Cannot allocate memory for Tsol node\n");
return;
}
/* Atom id 0 is invalid */
tsol_lastAtom = 0;
}
/* If the node is already allocated, see if it needs to be extended */
if (lastAtom > tsol_lastAtom) {
ErrorF("Cannot allocate memory for Tsol node\n");
return;
}
/*
* Initialize all the newly created atoms
*/
/* Mark as internal atom for
GetAtomName to succeed */
}
}
}
/* Store the label info for non-global atoms */
int k;
/* private atoms must have a matching sl */
return; /* found */
}
}
/* Allocate storage for sl if needed */
ErrorF("Not enough memory for atoms\n");
}
}
/* Expand storage space for sl if needed */
ErrorF("Not enough memory for atoms\n");
}
}
/* Store client's sl */
}
}
int
{
char *tchar;
{
return(BadValue);
}
if (atom != BAD_RESOURCE)
{
/* Assign tsol attributes to this atom */
return(client->noClientException);
}
else
return (BadAlloc);
}
int
{
const char *str;
int len;
{
/* non-global atoms must have matching SL */
int k;
break;
}
/* SL can't be found, so return a blank string */
}
return(client->noClientException);
}
else
{
return (BadAtom);
}
}
int
{
if (client == serverClient)
else
else
return (Success);
}
int
{
return (Success);
}
/* Generic ProcVector wrapper for functions which just need to set the
client's TrustLevel to Trusted before executing. */
static inline int
{
return result;
}
static void
{
int rc;
#if defined(PANORAMIX)
if (!noPanoramiXExtension)
{
int j;
if (tpwin) {
return;
}
{
return;
/* Validate trusted stripe window */
return;
return;
return;
}
} else
#endif
{
/* Validate trusted stripe window */
if (tpwin) {
return;
}
return;
/* stripe is already at head, nothing to do */
return;
}
}
/* Generic ProcVector wrapper for functions which just need to have
ResetStripeWindow called after executing. */
static inline int
{
int result;
return result;
}
int
{
}
int
{
}
int
{
}
int
{
}
int
{
}
/*
* HandleHotKey -
* HotKey is Meta(Diamond)+ Stop Key
* Breaks untrusted Ptr and Kbd grabs.
* Trusted Grabs are NOT broken
* Warps pointer to the Trusted Stripe if not Trusted grabs in force.
*/
void
{
int x, y;
if (kbdgrab)
{
if (tsolinfo)
{
if (HasTrustedPath(tsolinfo))
trusted_grab = TRUE;
else
}
if (ptrgrab)
{
if (tsolinfo)
{
if (HasTrustedPath(tsolinfo))
trusted_grab = TRUE;
else
}
}
}
if (!trusted_grab)
{
/*
* Warp the pointer to the Trusted Stripe
*/
}
}
#ifdef UNUSED
void
{
while (p2)
{
}
}
/*
* Checks that tpwin & its siblings have same
* parents. Returns 0 if OK, a # indicating which
* Sibling has a bad parent
*/
int
CheckTPWin(void)
{
while (pWin)
{
return count;
++count;
}
return 0;
}
#endif /* UNUSED */
/* NEW */
int
{
int status;
if ( noPanoramiXExtension )
{
return status;
/* Reduce root window height = stripe height */
{
}
return(client->noClientException);
} else
{
return (status);
}
}
int
{
/* REQUEST(xResourceReq); */
if (priv_win_config ||
} else {
/* turn off auditing because operation ignored */
return(client->noClientException);
}
}
int
{
/* REQUEST(xResourceReq); */
if (priv_win_config ||
} else {
/* turn off auditing because operation ignored */
return(client->noClientException);
}
}
int
{
#ifdef TSOL
#endif /* TSOL */
return rc;
#ifdef TSOL
/*
* Because of its recursive nature, QuerryTree can leave a huge trail
* of audit records which could make deciphering the audit log for
* critical records difficult. So we turn off any more auditing of
* this protocol.
*/
#endif /* TSOL */
else
#ifdef TSOL
{
Success) {
numChildren++;
}
}
#else /* !TSOL */
numChildren++;
#endif /* TSOL */
if (numChildren)
{
int curChild = 0;
if (!childIDs)
return BadAlloc;
#ifdef TSOL
{
Success) {
}
}
#else /* !TSOL */
#endif /* TSOL */
}
if (numChildren)
{
}
return(client->noClientException);
}
{
unsigned int protocol;
int count = 0;
int status = 0;
if (system_audit_on &&
do_x_audit = TRUE;
/*
* X audit events start from 9101 in audit_uevents.h. The first two
* events are non-protocol ones viz. ClientConnect, mapped to 9101
* and ClientDisconnect, mapped to 9102.
* The protocol events are mapped from 9103 onwards in the serial
* order of their respective protocol opcode, for eg, the protocol
* UngrabPointer which is has a protocol opcode 27 is mapped to
* 9129 (9102 + 27).
* All extension protocols are mapped to a single audit event
* AUE_XExtension as opcodes are assigined dynamically to these
* protocols. We set the extension protocol opcode to be 128, one
* more than the last standard opcode.
*/
protocol = (unsigned int)MAJOROP_CODE;
if (protocol > X_NoOperation) {
audit_event = TRUE;
} else {
audit_event = TRUE;
break;
}
}
}
/*
* Exclude Clients with Trusted Path such as tsoldtwm, tsoldtsession etc
* from generating the audit records for X protocols
*/
AU_PRS_USECACHE) == 1)) {
} else {
}
}
}
{
{
audit_ret = -1;
else
audit_ret = 0;
}
{
}
}
int
{
int rc;
return rc;
return rc;
}
return(Success);
}
int
{
/* Allow extensions in the labeled zones */
}
int
{
/* Allow extensions in the labeled zones */
}
int
{
}
int
{
}
static int
int format,
{
register int linesDone;
char *pBuf;
#ifdef TSOL
#endif /* TSOL */
{
return(BadValue);
}
return rc;
#ifdef TSOL
{
}
{
if (DrawableIsRoot(pDraw))
{
if (!WindowIsRoot(pWin))
{
{
/* requested area must be a subset of the window area */
{
x = tmpx;
y = tmpy;
}
}
}
}
else
{
}
if (not_root_window)
{
int rc;
return rc;
while (tmpwin)
{
{
break;
}
}
return rc;
}
getimage_ok = TRUE;
else
getimage_ok = FALSE;
}
#endif /* TSOL */
{
if( /* check for being viewable */
/* check for being on screen */
pDraw->x + x < 0 ||
pDraw->y + y < 0 ||
/* check for being inside of border */
)
return(BadMatch);
}
else
{
if(x < 0 ||
y < 0 ||
)
return(BadMatch);
}
{
}
else
{
/* only planes asked for */
}
if (im_return) {
if (!pBuf)
return (BadAlloc);
if (widthBytesLine == 0)
linesPerBuf = 0;
else
} else {
if (widthBytesLine == 0 || height == 0)
linesPerBuf = 0;
else if (widthBytesLine >= IMAGE_BUFSIZE)
linesPerBuf = 1;
else
{
if (linesPerBuf > height)
}
if (linesPerBuf < height)
{
/* we have to make sure intermediate buffers don't need padding */
while ((linesPerBuf > 1) &&
{
linesPerBuf--;
length -= widthBytesLine;
}
{
linesPerBuf++;
length += widthBytesLine;
}
}
return (BadAlloc);
}
if (linesPerBuf == 0)
{
/* nothing to do */
}
{
linesDone = 0;
{
x,
y + linesDone,
#ifdef TSOL
if (not_root_window)
{
if (over_win)
{
}
}
/*
* fill the buffer with zeros in case of security failure
*/
if (!getimage_ok || overlap)
{
if (overlap)
}
#endif /* TSOL */
/* Note that this is NOT a call to WriteSwappedDataToClient,
as we do NOT byte swap */
if (!im_return)
{
/* Don't split me, gcc pukes when you do */
(void)WriteToClient(client,
(int)(nlines * widthBytesLine),
pBuf);
}
}
}
else /* XYPixmap */
{
{
{
linesDone = 0;
{
x,
y + linesDone,
#ifdef TSOL
if (not_root_window)
{
if (over_win)
{
MAJOROP_CODE) != Success)
}
}
/*
* fill the buffer with zeros in case of security failure
*/
if (!getimage_ok || overlap)
{
if (overlap)
}
#endif /* TSOL */
/* Note: NOT a call to WriteSwappedDataToClient,
as we do NOT byte swap */
if (im_return) {
} else {
/* Don't split me, gcc pukes when you do */
(void)WriteToClient(client,
(int)(nlines * widthBytesLine),
pBuf);
}
}
}
}
}
if (!im_return)
return (client->noClientException);
}
int
{
}
int
{
int status;
/* ignore the error message */
return(client->noClientException);
}
return (status);
}
int
{
int status;
/* ignore the error message */
return(client->noClientException);
}
return (status);
}
int
{
int status;
int rc;
{
return rc;
{
return (BadMatch);
}
}
else
/* ignore the error message for DnD zap effect */
return(client->noClientException);
}
/* ignore the error message for DnD zap effect */
return(client->noClientException);
}
return (status);
}
int
{
int savedtrust;
int status;
int rc;
{
return rc;
{
return (BadMatch);
}
}
else
/* ignore the error message for DnD zap effect */
return(client->noClientException);
}
/* ignore the error message for DnD zap effect */
return(client->noClientException);
}
return (status);
}