tsolextension.c revision 679
606N/A/* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
0N/A *
0N/A * Permission is hereby granted, free of charge, to any person obtaining a
0N/A * copy of this software and associated documentation files (the
0N/A * "Software"), to deal in the Software without restriction, including
0N/A * without limitation the rights to use, copy, modify, merge, publish,
0N/A * distribute, and/or sell copies of the Software, and to permit persons
0N/A * to whom the Software is furnished to do so, provided that the above
0N/A * copyright notice(s) and this permission notice appear in all copies of
0N/A * the Software and that both the above copyright notice(s) and this
0N/A * permission notice appear in supporting documentation.
0N/A *
0N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0N/A * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0N/A * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
0N/A * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
0N/A * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
0N/A * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
0N/A * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
0N/A * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
0N/A * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0N/A *
0N/A * Except as contained in this notice, the name of a copyright holder
0N/A * shall not be used in advertising or otherwise to promote the sale, use
0N/A * or other dealings in this Software without prior written authorization
0N/A * of the copyright holder.
606N/A */
0N/A
679N/A#pragma ident "@(#)tsolextension.c 1.37 09/04/02 SMI"
0N/A
0N/A#include <stdio.h>
196N/A#include "auditwrite.h"
0N/A#include <bsm/libbsm.h>
0N/A#include <bsm/audit_uevents.h>
0N/A#include <sys/param.h>
0N/A#include <sys/types.h>
0N/A#include <sys/socket.h>
0N/A#include <sys/wait.h>
0N/A#include <ucred.h>
0N/A#include <netinet/in.h>
36N/A#include <netdb.h>
0N/A#include <arpa/inet.h>
0N/A#include <sys/tsol/tndb.h>
0N/A#include <strings.h>
0N/A#include <string.h>
0N/A#include <pwd.h>
0N/A#include <unistd.h>
0N/A#include <sys/stat.h>
0N/A#include <rpc/rpc.h>
0N/A#include <zone.h>
0N/A
0N/A
0N/A#define NEED_REPLIES
0N/A
98N/A#ifdef HAVE_DIX_CONFIG_H
98N/A#include <dix-config.h>
98N/A#endif
0N/A
0N/A#include "misc.h"
0N/A#include "osdep.h"
98N/A#include <X11/Xauth.h>
0N/A#include "tsol.h"
0N/A#include "inputstr.h"
0N/A#include "extnsionst.h"
606N/A#include "dixstruct.h"
606N/A#include "xace.h"
606N/A#include "xacestr.h"
311N/A#ifdef PANORAMIX
311N/A#include "../Xext/panoramiXsrv.h"
311N/A#endif
0N/A#ifdef XCSECURITY
0N/A#define _SECURITY_SERVER
0N/A#include "security.h"
606N/A#include "../Xext/securitysrv.h"
0N/A#endif
0N/A#include "tsolpolicy.h"
0N/A
0N/A#define BadCmapCookie 0
0N/A#define Tsolextension 0x0080 /* Tsol extensions begin at 128 */
0N/A#define MAX_SCREENS 3 /* screens allowed */
0N/A#define EXTNSIZE 128
0N/A
36N/A#define SECURE_RPC_AUTH "SUN-DES-1"
36N/A#define SECURE_RPC_LEN 9
0N/A
0N/Astatic int ProcTsolDispatch(ClientPtr);
0N/Astatic int ProcSetPolyInstInfo(ClientPtr);
0N/Astatic int ProcSetPropLabel(ClientPtr);
0N/Astatic int ProcSetPropUID(ClientPtr);
0N/Astatic int ProcSetResLabel(ClientPtr);
0N/Astatic int ProcSetResUID(ClientPtr);
0N/Astatic int ProcGetClientAttributes(ClientPtr);
0N/Astatic int ProcGetClientLabel(ClientPtr);
0N/Astatic int ProcGetPropAttributes(ClientPtr);
0N/Astatic int ProcGetResAttributes(ClientPtr);
0N/Astatic int ProcMakeTPWindow(ClientPtr);
0N/Astatic int ProcMakeTrustedWindow(ClientPtr);
0N/Astatic int ProcMakeUntrustedWindow(ClientPtr);
0N/A
0N/Astatic int SProcTsolDispatch(ClientPtr);
0N/Astatic int SProcSetPolyInstInfo(ClientPtr);
0N/Astatic int SProcSetPropLabel(ClientPtr);
0N/Astatic int SProcSetPropUID(ClientPtr);
0N/Astatic int SProcSetResLabel(ClientPtr);
0N/Astatic int SProcSetResUID(ClientPtr);
0N/Astatic int SProcGetClientAttributes(ClientPtr);
0N/Astatic int SProcGetClientLabel(ClientPtr);
0N/Astatic int SProcGetPropAttributes(ClientPtr);
0N/Astatic int SProcGetResAttributes(ClientPtr);
0N/Astatic int SProcMakeTPWindow(ClientPtr);
0N/Astatic int SProcMakeTrustedWindow(ClientPtr);
0N/Astatic int SProcMakeUntrustedWindow(ClientPtr);
0N/A
606N/Astatic void TsolReset(ExtensionEntry *extension);
0N/Astatic void BreakAllGrabs(ClientPtr client);
0N/A
0N/Astatic unsigned char TsolReqCode = 0;
0N/Astatic int tsolEventBase = -1;
633N/Astatic int ScreenStripeHeight[MAX_SCREENS] = {0, 0};
0N/A
0N/Astatic HotKeyRec hotkey = {FALSE, 0, 0, 0, 0};
73N/A
73N/Aint tsolMultiLevel = TRUE;
0N/A
633N/Astatic int OwnerUIDint;
679N/Astatic Selection *tsol_sel_agnt = NULL; /* entry in CurrentSelection to get seln */
679N/Astatic Atom tsol_atom_sel_agnt = 0; /* selection agent atom created during init */
0N/A
0N/Aint (*TsolSavedProcVector[PROCVECTORSIZE])(ClientPtr client);
0N/Aint (*TsolSavedSwappedProcVector[PROCVECTORSIZE])(ClientPtr client);
0N/A
633N/Astatic SecurityHook tsolSecHook;
0N/A
633N/Astatic XID TsolCheckAuthorization (unsigned int name_length,
606N/A char *name, unsigned int data_length,
0N/A char *data, ClientPtr client, char **reason);
0N/A
606N/Astatic void TsolSetClientInfo(ClientPtr client);
0N/A
606N/A/* XACE hook callbacks */
606N/Astatic CALLBACK(TsolCheckExtensionAccess);
679N/Astatic CALLBACK(TsolCheckPropertyAccess);
606N/Astatic CALLBACK(TsolCheckResourceIDAccess);
679N/Astatic CALLBACK(TsolCheckSendAccess);
679N/Astatic CALLBACK(TsolCheckReceiveAccess);
679N/Astatic CALLBACK(TsolCheckDeviceAccess);
679N/Astatic CALLBACK(TsolCheckSelectionAccess);
606N/Astatic CALLBACK(TsolProcessKeyboard);
606N/A
606N/A/* other callbacks */
606N/Astatic CALLBACK(TsolClientStateCallback);
679N/Astatic CALLBACK(TsolSelectionCallback);
0N/A
196N/A
0N/A/*
0N/A * Initialize the extension. Main entry point for this loadable
0N/A * module.
0N/A */
0N/A
633N/A_X_EXPORT void
606N/ATsolExtensionInit(void)
0N/A{
0N/A ExtensionEntry *extEntry;
0N/A int i;
0N/A
0N/A /* sleep(20); */
0N/A
228N/A /* This extension is supported on a labeled system */
0N/A if (!is_system_labeled()) {
0N/A return;
0N/A }
0N/A
36N/A tsolMultiLevel = TRUE;
0N/A (void) setpflags(PRIV_AWARE, 1);
0N/A
0N/A init_xtsol();
36N/A init_win_privsets();
0N/A
0N/A extEntry = AddExtension(TSOLNAME, TSOL_NUM_EVENTS, TSOL_NUM_ERRORS,
606N/A ProcTsolDispatch, SProcTsolDispatch, TsolReset,
0N/A StandardMinorOpcode);
0N/A
0N/A if (extEntry == NULL) {
0N/A ErrorF("TsolExtensionInit: AddExtension failed for X Trusted Extensions\n");
0N/A return;
0N/A }
0N/A
0N/A TsolReqCode = (unsigned char) extEntry->base;
0N/A tsolEventBase = extEntry->eventBase;
0N/A
0N/A if (!AddCallback(&ClientStateCallback, TsolClientStateCallback, NULL))
0N/A return;
0N/A
679N/A if (!AddCallback(&SelectionCallback, TsolSelectionCallback, NULL))
679N/A return;
679N/A
606N/A /* Allocate storage in devPrivates */
606N/A if (!dixRequestPrivate(tsolPrivKey, sizeof (TsolPrivRec))) {
606N/A ErrorF("TsolExtensionInit: Cannot allocate devPrivate.\n");
0N/A return;
0N/A }
0N/A
679N/A /* Initialize the client info for server itself */
679N/A if (serverClient) {
679N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(serverClient);
679N/A if (tsolinfo->sl == NULL) {
679N/A tsolinfo->sl = (bslabel_t *)lookupSL_low();
679N/A tsolinfo->uid = 0;
679N/A tsolinfo->pid = getpid();
679N/A snprintf(tsolinfo->pname, MAXNAME, "client id %d (pid %d)",
679N/A serverClient->index, tsolinfo->pid);
679N/A }
679N/A }
679N/A
0N/A LoadTsolConfig();
0N/A
0N/A MakeTSOLAtoms();
0N/A UpdateTsolNode();
0N/A
679N/A tsol_atom_sel_agnt = MakeAtom("_TSOL_SEL_AGNT", 14, 1);
679N/A
606N/A /* Initialize security hooks */
606N/A tsolSecHook.CheckAuthorization = TsolCheckAuthorization;
679N/A/*
606N/A tsolSecHook.DeleteClientFromAnySelections = TsolDeleteClientFromAnySelections;
606N/A tsolSecHook.DeleteWindowFromAnySelections = TsolDeleteWindowFromAnySelections;
679N/A*/
606N/A pSecHook = &tsolSecHook;
606N/A
679N/A XaceRegisterCallback(XACE_RESOURCE_ACCESS, TsolCheckResourceIDAccess, NULL);
679N/A XaceRegisterCallback(XACE_PROPERTY_ACCESS, TsolCheckPropertyAccess, NULL);
679N/A XaceRegisterCallback(XACE_SEND_ACCESS, TsolCheckSendAccess, NULL);
679N/A XaceRegisterCallback(XACE_RECEIVE_ACCESS, TsolCheckReceiveAccess, NULL);
606N/A XaceRegisterCallback(XACE_EXT_ACCESS, TsolCheckExtensionAccess, NULL);
679N/A XaceRegisterCallback(XACE_DEVICE_ACCESS, TsolCheckDeviceAccess, NULL);
679N/A XaceRegisterCallback(XACE_SELECTION_ACCESS, TsolCheckSelectionAccess, NULL);
606N/A XaceRegisterCallback(XACE_KEY_AVAIL, TsolProcessKeyboard, NULL);
606N/A XaceRegisterCallback(XACE_AUDIT_BEGIN, TsolAuditStart, NULL);
606N/A XaceRegisterCallback(XACE_AUDIT_END, TsolAuditEnd, NULL);
606N/A
0N/A /* Save original Proc vectors */
0N/A for (i = 0; i < PROCVECTORSIZE; i++) {
0N/A TsolSavedProcVector[i] = ProcVector[i];
0N/A TsolSavedSwappedProcVector[i] = SwappedProcVector[i];
0N/A }
0N/A
0N/A /* Replace some of the original Proc vectors with our own TBD */
0N/A ProcVector[X_InternAtom] = ProcTsolInternAtom;
0N/A
0N/A ProcVector[X_CreateWindow] = ProcTsolCreateWindow;
679N/A ProcVector[X_ChangeWindowAttributes] = ProcTsolChangeWindowAttributes;
0N/A ProcVector[X_ConfigureWindow] = ProcTsolConfigureWindow;
0N/A ProcVector[X_CirculateWindow] = ProcTsolCirculateWindow;
0N/A ProcVector[X_ReparentWindow] = ProcTsolReparentWindow;
0N/A ProcVector[X_GetGeometry] = ProcTsolGetGeometry;
0N/A ProcVector[X_GrabServer] = ProcTsolGrabServer;
0N/A ProcVector[X_UngrabServer] = ProcTsolUngrabServer;
0N/A ProcVector[X_SetScreenSaver] = ProcTsolSetScreenSaver;
0N/A ProcVector[X_ChangeHosts] = ProcTsolChangeHosts;
0N/A ProcVector[X_SetAccessControl] = ProcTsolChangeAccessControl;
0N/A ProcVector[X_KillClient] = ProcTsolKillClient;
0N/A ProcVector[X_SetFontPath] = ProcTsolSetFontPath;
0N/A ProcVector[X_SetCloseDownMode] = ProcTsolChangeCloseDownMode;
0N/A ProcVector[X_ListInstalledColormaps] = ProcTsolListInstalledColormaps;
679N/A /* ProcVector[X_GetImage] = ProcTsolGetImage; */
0N/A ProcVector[X_QueryTree] = ProcTsolQueryTree;
0N/A ProcVector[X_QueryPointer] = ProcTsolQueryPointer;
36N/A ProcVector[X_QueryExtension] = ProcTsolQueryExtension;
36N/A ProcVector[X_ListExtensions] = ProcTsolListExtensions;
36N/A ProcVector[X_MapWindow] = ProcTsolMapWindow;
36N/A ProcVector[X_MapSubwindows] = ProcTsolMapSubwindows;
64N/A ProcVector[X_CopyArea] = ProcTsolCopyArea;
64N/A ProcVector[X_CopyPlane] = ProcTsolCopyPlane;
64N/A ProcVector[X_PolySegment] = ProcTsolPolySegment;
64N/A ProcVector[X_PolyRectangle] = ProcTsolPolyRectangle;
196N/A
0N/A}
0N/A
606N/Astatic CALLBACK(
606N/A TsolCheckResourceIDAccess)
0N/A{
606N/A XaceResourceAccessRec *rec = calldata;
606N/A ClientPtr client = rec->client;
606N/A XID id = rec->id;
606N/A RESTYPE rtype = rec->rtype;
606N/A pointer rval = rec->res;
606N/A Mask access_mode = rec->access_mode;
606N/A
639N/A Mask check_mode = access_mode;
639N/A TsolInfoPtr tsolinfo;
639N/A int msgType;
639N/A int msgVerb;
606N/A int reqtype;
0N/A
606N/A if (client->requestBuffer) {
606N/A reqtype = MAJOROP; /* protocol */
606N/A } else {
606N/A reqtype = -1;
606N/A }
0N/A
639N/A#define CHECK_RESOURCE_POLICY(DIX_MODE, TSOL_TYPE, TSOL_MODE, VAL, ID) \
639N/A if (check_mode & (DIX_MODE)) { \
679N/A rec->status = xtsol_policy((TSOL_TYPE), (TSOL_MODE), \
679N/A (VAL), (ID), client, TSOL_ALL, &reqtype); \
639N/A check_mode &= ~(DIX_MODE); \
606N/A }
0N/A
639N/A switch (rtype) {
639N/A case RT_GC:
679N/A CHECK_RESOURCE_POLICY((DixReadAccess|DixGetAttrAccess|DixUseAccess),
679N/A TSOL_RES_GC, TSOL_READ, NULL, id);
679N/A CHECK_RESOURCE_POLICY((DixWriteAccess|DixSetAttrAccess),
679N/A TSOL_RES_GC, TSOL_MODIFY, NULL, id);
639N/A CHECK_RESOURCE_POLICY(DixCreateAccess, TSOL_RES_GC, TSOL_CREATE,
639N/A NULL, id);
639N/A CHECK_RESOURCE_POLICY(DixDestroyAccess, TSOL_RES_GC, TSOL_DESTROY,
639N/A NULL, id);
0N/A
606N/A break;
0N/A
0N/A case RT_WINDOW: /* Drawables */
679N/A switch (reqtype) {
679N/A case X_SetInputFocus:
679N/A CHECK_RESOURCE_POLICY(DixSetAttrAccess,
679N/A TSOL_RES_FOCUSWIN, TSOL_MODIFY, rval, 0);
679N/A break;
679N/A case X_GetInputFocus:
679N/A CHECK_RESOURCE_POLICY(DixGetAttrAccess,
679N/A TSOL_RES_FOCUSWIN, TSOL_READ, rval, 0);
679N/A break;
679N/A case X_ChangeWindowAttributes:
679N/A CHECK_RESOURCE_POLICY((DixSetAttrAccess|DixReceiveAccess),
679N/A TSOL_RES_WINDOW, TSOL_SPECIAL, rval, 0);
679N/A if (rec->status != Success) {
679N/A WindowPtr pWin = (WindowPtr)rval;
679N/A if (WindowIsRoot(pWin))
679N/A rec->status = Success;
679N/A }
679N/A break;
679N/A case X_GrabPointer:
679N/A case X_UngrabPointer:
679N/A case X_GrabKeyboard:
679N/A case X_UngrabKeyboard:
679N/A case X_GrabKey:
679N/A case X_UngrabKey:
679N/A case X_GrabButton:
679N/A case X_UngrabButton:
679N/A CHECK_RESOURCE_POLICY(DixSetAttrAccess,
679N/A TSOL_RES_GRABWIN, TSOL_MODIFY, rval, 0);
679N/A break;
679N/A
679N/A default:
679N/A /* CreateWindow, policy check on the parent */
679N/A CHECK_RESOURCE_POLICY((DixAddAccess|DixRemoveAccess),
679N/A TSOL_RES_WINDOW, TSOL_CREATE, rval, 0);
679N/A
679N/A /* Newly created window. Just initialize it. */
679N/A if (check_mode & DixCreateAccess) {
679N/A TsolInitWindow(client, (WindowPtr) rval);
679N/A check_mode &= ~(DixCreateAccess);
679N/A }
679N/A
679N/A CHECK_RESOURCE_POLICY((DixReadAccess|DixGetAttrAccess|DixListAccess),
679N/A TSOL_RES_WINDOW, TSOL_READ, rval, 0);
679N/A CHECK_RESOURCE_POLICY((DixWriteAccess|DixSetAttrAccess|DixShowAccess|
679N/A DixHideAccess|DixManageAccess),
679N/A TSOL_RES_WINDOW, TSOL_MODIFY, rval, 0);
679N/A CHECK_RESOURCE_POLICY(DixDestroyAccess, TSOL_RES_WINDOW,
679N/A TSOL_DESTROY, rval, 0);
679N/A
679N/A /* Event access, actual policy is implemented in the hook */
679N/A CHECK_RESOURCE_POLICY(DixSendAccess, TSOL_RES_WINDOW,
679N/A TSOL_SPECIAL, rval, 0);
679N/A CHECK_RESOURCE_POLICY(DixReceiveAccess, TSOL_RES_WINDOW,
679N/A TSOL_SPECIAL, rval, 0);
679N/A
679N/A /* Property related access */
679N/A CHECK_RESOURCE_POLICY((DixGetPropAccess|DixListPropAccess),
679N/A TSOL_RES_PROPWIN, TSOL_READ, rval, 0);
679N/A CHECK_RESOURCE_POLICY(DixSetPropAccess,
679N/A TSOL_RES_PROPWIN, TSOL_MODIFY, rval, 0);
679N/A
679N/A break;
667N/A }
606N/A /* The rest falls through to code shared with RT_PIXMAP */
0N/A case RT_PIXMAP:
0N/A /* Drawing operations use pixel access policy */
0N/A switch (reqtype) {
679N/A case X_CreatePixmap:
679N/A /* Newly created window. Just initialize it. */
679N/A if (check_mode & DixCreateAccess) {
679N/A TsolInitPixmap(client, (PixmapPtr) rval);
679N/A check_mode &= ~(DixCreateAccess);
679N/A }
679N/A break;
0N/A case X_PolyPoint:
0N/A case X_PolyLine:
0N/A case X_PolyArc:
0N/A case X_FillPoly:
0N/A case X_PolyFillRectangle:
0N/A case X_PolyFillArc:
0N/A case X_PutImage:
0N/A case X_PolyText8:
0N/A case X_PolyText16:
0N/A case X_ImageText8:
0N/A case X_ImageText16:
639N/A CHECK_RESOURCE_POLICY((DixReadAccess | DixBlendAccess),
679N/A TSOL_RES_PIXEL, TSOL_READ, rval, 0);
639N/A CHECK_RESOURCE_POLICY(DixWriteAccess,
679N/A TSOL_RES_PIXEL, TSOL_MODIFY, rval, 0);
0N/A break;
679N/A case X_GetImage:
667N/A case X_ClearArea:
667N/A rec->status = Success;
667N/A break;
679N/A default:
679N/A if (check_mode & (DixReadAccess|DixWriteAccess)) {
679N/A check_mode &= ~(DixReadAccess|DixWriteAccess);
679N/A rec->status = Success;
679N/A }
679N/A/*
679N/A CHECK_RESOURCE_POLICY(DixReadAccess,
679N/A TSOL_RES_PIXMAP, TSOL_READ, rval, 0);
679N/A CHECK_RESOURCE_POLICY(DixWriteAccess,
679N/A TSOL_RES_PIXMAP, TSOL_MODIFY, rval, 0);
679N/A*/
679N/A break;
606N/A }
606N/A break;
667N/A
679N/A case RT_CURSOR:
679N/A CHECK_RESOURCE_POLICY((DixUseAccess|DixWriteAccess),
679N/A TSOL_RES_CURSOR, TSOL_MODIFY, NULL, id);
679N/A CHECK_RESOURCE_POLICY(DixCreateAccess,
679N/A TSOL_RES_CURSOR, TSOL_CREATE, NULL, id);
679N/A break;
679N/A case RT_FONT:
679N/A CHECK_RESOURCE_POLICY(DixUseAccess,
679N/A TSOL_RES_CURSOR, TSOL_READ, NULL, id);
679N/A break;
679N/A
679N/A default:
667N/A rec->status = Success;
667N/A break;
0N/A }
0N/A
639N/A#ifndef NO_TSOL_DEBUG_MESSAGES
639N/A if (check_mode) { /* Any access mode bits not yet handled ? */
639N/A LogMessageVerb(X_NOT_IMPLEMENTED, TSOL_MSG_UNIMPLEMENTED,
639N/A TSOL_LOG_PREFIX
639N/A "policy not implemented for CheckResourceAccess, "
639N/A "rtype=0x%x (%s), mode=0x%x (%s)\n",
639N/A (int) rtype, TsolResourceTypeString(rtype),
639N/A check_mode, TsolDixAccessModeNameString(check_mode));
639N/A }
639N/A#endif /* !NO_TSOL_DEBUG_MESSAGES */
0N/A
679N/A if (rec->status != Success) {
639N/A msgType = X_ERROR;
639N/A msgVerb = TSOL_MSG_ERROR;
639N/A } else {
639N/A#ifdef NO_TSOL_DEBUG_MESSAGES
639N/A /* rest of the function is just printing error or debug messages */
639N/A return;
639N/A#else
639N/A /* Trace messages for debugging */
639N/A msgType = X_INFO;
639N/A msgVerb = TSOL_MSG_ACCESS_TRACE;
639N/A#endif /* NO_TSOL_DEBUG_MESSAGES */
0N/A }
639N/A
639N/A tsolinfo = GetClientTsolInfo(client);
639N/A LogMessageVerb(msgType, msgVerb,
639N/A TSOL_LOG_PREFIX
639N/A "CheckResourceAccess(%s, %s, 0x%x, %s, %s) = %s\n",
639N/A tsolinfo->pname,
639N/A TsolResourceTypeString(rtype), id,
639N/A TsolDixAccessModeNameString(access_mode),
639N/A TsolRequestNameString(reqtype),
639N/A TsolErrorNameString(rec->status));
0N/A}
0N/A
606N/Astatic
679N/ACALLBACK(TsolSelectionCallback)
679N/A{
679N/A SelectionInfoRec *pselinfo = (SelectionInfoRec *)calldata;
679N/A Selection *pSel = pselinfo->selection;
679N/A TsolSelnPtr tsolseln = TsolSelectionPriv(pSel);
679N/A
679N/A switch (pselinfo->kind) {
679N/A case SelectionClientClose:
679N/A if (tsol_sel_agnt && pSel->selection == tsol_sel_agnt->selection) {
679N/A tsol_sel_agnt = NULL; /* selection manager died. */
679N/A }
679N/A /* fall through to reset the SL */
679N/A
679N/A case SelectionWindowDestroy:
679N/A tsolseln->sl = NULL;
679N/A break;
679N/A
679N/A default:
679N/A /* All others handled in SelectionAccess handler */
679N/A break;
679N/A }
679N/A}
679N/A
679N/Astatic
606N/ACALLBACK(TsolClientStateCallback)
0N/A{
0N/A NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
0N/A ClientPtr client = pci->client;
606N/A TsolInfoPtr tsolinfo = TsolClientPriv(client);
0N/A
0N/A switch (client->clientState) {
0N/A
0N/A case ClientStateInitial:
0N/A /* Got a new connection */
0N/A TsolSetClientInfo(client);
0N/A break;
0N/A
0N/A case ClientStateRunning:
0N/A break;
0N/A
0N/A case ClientStateRetained: /* client disconnected */
0N/A break;
0N/A case ClientStateGone:
0N/A if (tpwin && wClient(tpwin) == client)
0N/A tpwin = NULL; /* reset tpwin */
0N/A
0N/A if (tsolinfo != NULL && tsolinfo->privs != NULL) {
0N/A priv_freeset(tsolinfo->privs);
0N/A }
36N/A /* Audit disconnect */
36N/A if (system_audit_on && (au_preselect(AUE_ClientDisconnect, &(tsolinfo->amask),
36N/A AU_PRS_BOTH, AU_PRS_USECACHE) == 1)) {
36N/A auditwrite(AW_PRESELECT, &(tsolinfo->amask),AW_END);
36N/A auditwrite(AW_EVENTNUM, AUE_ClientDisconnect,
36N/A AW_XCLIENT, client->index,
36N/A AW_SLABEL, tsolinfo->sl,
36N/A AW_RETURN, 0, 0, AW_WRITE, AW_END);
36N/A
36N/A tsolinfo->flags &= ~TSOL_DOXAUDIT;
36N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
36N/A auditwrite(AW_FLUSH, AW_END);
36N/A auditwrite(AW_DISCARDRD, tsolinfo->asaverd, AW_END);
36N/A auditwrite(AW_NOPRESELECT, AW_END);
36N/A }
0N/A break;
36N/A
0N/A default:
0N/A break;
0N/A }
0N/A
0N/A}
0N/A
0N/Astatic void
606N/ATsolReset(ExtensionEntry *extension)
0N/A{
606N/A free_win_privsets();
606N/A XaceDeleteCallback(XACE_RESOURCE_ACCESS, TsolCheckResourceIDAccess, NULL);
679N/A XaceDeleteCallback(XACE_PROPERTY_ACCESS, TsolCheckPropertyAccess, NULL);
679N/A XaceDeleteCallback(XACE_SEND_ACCESS, TsolCheckSendAccess, NULL);
679N/A XaceDeleteCallback(XACE_RECEIVE_ACCESS, TsolCheckReceiveAccess, NULL);
606N/A XaceDeleteCallback(XACE_EXT_ACCESS, TsolCheckExtensionAccess, NULL);
679N/A XaceDeleteCallback(XACE_DEVICE_ACCESS, TsolCheckDeviceAccess, NULL);
679N/A XaceDeleteCallback(XACE_SELECTION_ACCESS, TsolCheckSelectionAccess, NULL);
606N/A XaceDeleteCallback(XACE_KEY_AVAIL, TsolProcessKeyboard, NULL);
606N/A XaceDeleteCallback(XACE_AUDIT_BEGIN, TsolAuditStart, NULL);
606N/A XaceDeleteCallback(XACE_AUDIT_END, TsolAuditEnd, NULL);
0N/A}
0N/A
0N/A/*
0N/A * Dispatch routine
0N/A *
0N/A */
0N/Astatic int
606N/AProcTsolDispatch(register ClientPtr client)
0N/A{
0N/A int retval;
0N/A
0N/A REQUEST(xReq);
0N/A
0N/A switch (stuff->data)
0N/A {
0N/A case X_SetPolyInstInfo:
0N/A retval = ProcSetPolyInstInfo(client);
0N/A break;
0N/A case X_SetPropLabel:
0N/A retval = ProcSetPropLabel(client);
0N/A break;
0N/A case X_SetPropUID:
0N/A retval = ProcSetPropUID(client);
0N/A break;
0N/A case X_SetResLabel:
0N/A retval = ProcSetResLabel(client);
0N/A break;
0N/A case X_SetResUID:
0N/A retval = ProcSetResUID(client);
0N/A break;
0N/A case X_GetClientAttributes:
0N/A retval = ProcGetClientAttributes(client);
0N/A break;
0N/A case X_GetClientLabel:
0N/A retval = ProcGetClientLabel(client);
0N/A break;
0N/A case X_GetPropAttributes:
0N/A retval = ProcGetPropAttributes(client);
606N/A break;
0N/A case X_GetResAttributes:
0N/A retval = ProcGetResAttributes(client);
0N/A break;
0N/A case X_MakeTPWindow:
0N/A retval = ProcMakeTPWindow(client);
0N/A break;
0N/A case X_MakeTrustedWindow:
0N/A retval = ProcMakeTrustedWindow(client);
0N/A break;
0N/A case X_MakeUntrustedWindow:
0N/A retval = ProcMakeUntrustedWindow(client);
0N/A break;
0N/A default:
0N/A SendErrorToClient(client, TsolReqCode, stuff->data, 0, BadRequest);
0N/A retval = BadRequest;
0N/A }
0N/A return (retval);
0N/A}
0N/A
0N/A
0N/Astatic int
606N/ASProcTsolDispatch(register ClientPtr client)
0N/A{
0N/A int n;
0N/A int retval;
0N/A
0N/A REQUEST(xReq);
0N/A
0N/A swaps(&stuff->length, n);
0N/A switch (stuff->data)
0N/A {
0N/A case X_SetPolyInstInfo:
0N/A retval = SProcSetPolyInstInfo(client);
0N/A break;
0N/A case X_SetPropLabel:
0N/A retval = SProcSetPropLabel(client);
0N/A break;
0N/A case X_SetPropUID:
0N/A retval = SProcSetPropUID(client);
0N/A break;
0N/A case X_SetResLabel:
0N/A retval = SProcSetResLabel(client);
0N/A break;
0N/A case X_SetResUID:
0N/A retval = SProcSetResUID(client);
0N/A break;
0N/A case X_GetClientAttributes:
0N/A retval = SProcGetClientAttributes(client);
0N/A break;
0N/A case X_GetClientLabel:
0N/A retval = SProcGetClientLabel(client);
0N/A break;
0N/A case X_GetPropAttributes:
0N/A retval = SProcGetPropAttributes(client);
606N/A break;
0N/A case X_GetResAttributes:
0N/A retval = SProcGetResAttributes(client);
0N/A break;
0N/A case X_MakeTPWindow:
0N/A retval = SProcMakeTPWindow(client);
0N/A break;
0N/A case X_MakeTrustedWindow:
0N/A retval = SProcMakeTrustedWindow(client);
0N/A break;
0N/A case X_MakeUntrustedWindow:
0N/A retval = SProcMakeUntrustedWindow(client);
0N/A break;
0N/A default:
0N/A SendErrorToClient(client, TsolReqCode, stuff->data, 0, BadRequest);
0N/A retval = BadRequest;
0N/A }
0N/A return (retval);
0N/A}
0N/A
0N/A
0N/A/*
0N/A * Individual routines
0N/A */
0N/A
0N/Astatic int
0N/ASProcSetPolyInstInfo(ClientPtr client)
0N/A{
0N/A int n;
0N/A
0N/A REQUEST(xSetPolyInstInfoReq);
0N/A swapl(&stuff->uid, n);
0N/A swapl(&stuff->enabled, n);
0N/A swaps(&stuff->sllength, n);
0N/A
0N/A return (ProcSetPolyInstInfo(client));
0N/A}
0N/A
0N/Astatic int
0N/ASProcSetPropLabel(ClientPtr client)
0N/A{
0N/A int n;
0N/A
0N/A REQUEST(xSetPropLabelReq);
0N/A swapl(&stuff->id, n);
0N/A swapl(&stuff->atom, n);
0N/A swaps(&stuff->labelType, n);
0N/A swaps(&stuff->sllength, n);
0N/A swaps(&stuff->illength, n);
0N/A
0N/A return (ProcSetPropLabel(client));
0N/A}
0N/A
0N/Astatic int
0N/ASProcSetPropUID(ClientPtr client)
0N/A{
0N/A int n;
0N/A
0N/A REQUEST(xSetPropUIDReq);
0N/A swapl(&stuff->id, n);
0N/A swapl(&stuff->atom, n);
0N/A swapl(&stuff->uid, n);
0N/A
0N/A return (ProcSetPropUID(client));
0N/A}
0N/A
0N/Astatic int
0N/ASProcSetResLabel(ClientPtr client)
0N/A{
0N/A int n;
0N/A
0N/A REQUEST(xSetResLabelReq);
0N/A swapl(&stuff->id, n);
0N/A swaps(&stuff->resourceType, n);
0N/A swaps(&stuff->labelType, n);
0N/A swaps(&stuff->sllength, n);
0N/A swaps(&stuff->illength, n);
0N/A
0N/A return (ProcSetResLabel(client));
0N/A}
0N/A
0N/Astatic int
0N/ASProcSetResUID(ClientPtr client)
0N/A{
0N/A int n;
0N/A
0N/A REQUEST(xSetResUIDReq);
0N/A swapl(&stuff->id, n);
0N/A swaps(&stuff->resourceType, n);
0N/A swapl(&stuff->uid, n);
0N/A
0N/A return (ProcSetResUID(client));
0N/A}
0N/A
0N/Astatic int
0N/ASProcGetClientAttributes(ClientPtr client)
0N/A{
0N/A int n;
0N/A
0N/A REQUEST(xGetClientAttributesReq);
0N/A swapl(&stuff->id, n);
0N/A
0N/A return (ProcGetClientAttributes(client));
0N/A}
0N/A
0N/Astatic int
0N/ASProcGetClientLabel(ClientPtr client)
0N/A{
0N/A int n;
0N/A
0N/A REQUEST(xGetClientLabelReq);
0N/A swapl(&stuff->id, n);
0N/A swaps(&stuff->mask, n);
0N/A
0N/A return (ProcGetClientLabel(client));
0N/A}
0N/A
0N/Astatic int
0N/ASProcGetPropAttributes(ClientPtr client)
0N/A{
0N/A int n;
0N/A
0N/A REQUEST(xGetPropAttributesReq);
0N/A swapl(&stuff->id, n);
0N/A swapl(&stuff->atom, n);
0N/A swaps(&stuff->mask, n);
0N/A
0N/A return (ProcGetPropAttributes(client));
0N/A}
0N/A
0N/Astatic int
0N/ASProcGetResAttributes(ClientPtr client)
0N/A{
0N/A int n;
0N/A
0N/A REQUEST(xGetResAttributesReq);
0N/A swapl(&stuff->id, n);
0N/A swaps(&stuff->resourceType, n);
0N/A swaps(&stuff->mask, n);
0N/A
0N/A return (ProcGetResAttributes(client));
0N/A}
0N/A
0N/Astatic int
0N/ASProcMakeTPWindow(ClientPtr client)
0N/A{
0N/A int n;
0N/A
0N/A REQUEST(xMakeTPWindowReq);
0N/A swapl(&stuff->id, n);
0N/A
0N/A return (ProcMakeTPWindow(client));
0N/A}
0N/A
0N/Astatic int
0N/ASProcMakeTrustedWindow(ClientPtr client)
0N/A{
0N/A int n;
0N/A
0N/A REQUEST(xMakeTrustedWindowReq);
0N/A swapl(&stuff->id, n);
0N/A
0N/A return (ProcMakeTrustedWindow(client));
0N/A}
0N/A
0N/Astatic int
0N/ASProcMakeUntrustedWindow(ClientPtr client)
0N/A{
0N/A int n;
0N/A
0N/A REQUEST(xMakeUntrustedWindowReq);
0N/A swapl(&stuff->id, n);
0N/A
0N/A return (ProcMakeUntrustedWindow(client));
0N/A}
0N/A
0N/A/*
606N/A * Set PolyInstantiation Info.
0N/A * Normally a get(prop) will
0N/A * get the prop. that has match sl, uid of the client. Setting
0N/A * enabled to true will get only the prop. corresponding to
0N/A * sl, uid specified instead of that of client. This is used
606N/A * by dtwm/dtfile in special motif lib.
0N/A */
0N/Astatic int
0N/AProcSetPolyInstInfo(ClientPtr client)
0N/A{
0N/A bslabel_t *sl;
0N/A int err_code;
0N/A
0N/A REQUEST(xSetPolyInstInfoReq);
0N/A REQUEST_AT_LEAST_SIZE(xSetPolyInstInfoReq);
0N/A
0N/A /*
0N/A * Check for policy here
0N/A */
633N/A if ((err_code = xtsol_policy(TSOL_RES_POLYINFO, TSOL_MODIFY, NULL, 0,
633N/A client, TSOL_ALL, &(MAJOROP))))
0N/A {
0N/A return (err_code);
0N/A }
0N/A sl = (bslabel_t *)(stuff + 1);
0N/A
0N/A tsolpolyinstinfo.enabled = stuff->enabled;
0N/A tsolpolyinstinfo.uid = (uid_t) stuff->uid;
0N/A tsolpolyinstinfo.sl = lookupSL(sl);
0N/A
0N/A return (client->noClientException);
0N/A}
0N/A
0N/Astatic int
0N/AProcSetPropLabel(ClientPtr client)
0N/A{
0N/A bslabel_t *sl;
0N/A WindowPtr pWin;
0N/A TsolPropPtr tsolprop;
0N/A PropertyPtr pProp;
0N/A int err_code;
679N/A int rc;
606N/A
0N/A REQUEST(xSetPropLabelReq);
0N/A
0N/A REQUEST_AT_LEAST_SIZE(xSetPropLabelReq);
0N/A
0N/A
679N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
679N/A if (rc != Success)
679N/A return rc;
679N/A
0N/A if (!pWin)
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (BadWindow);
0N/A }
633N/A if ((err_code = xtsol_policy(TSOL_RES_WINDOW, TSOL_MODIFY, pWin, 0,
633N/A client, TSOL_ALL, &(MAJOROP))))
0N/A {
0N/A return (err_code);
0N/A }
0N/A if (!ValidAtom(stuff->atom))
0N/A {
0N/A client->errorValue = stuff->atom;
0N/A return (BadAtom);
0N/A }
0N/A
0N/A /* first see if property already exists */
0N/A pProp = wUserProps (pWin);
0N/A while (pProp)
0N/A {
0N/A if (pProp->propertyName == stuff->atom)
0N/A break;
0N/A pProp = pProp->next;
0N/A }
0N/A
0N/A if (!pProp)
0N/A {
0N/A /* property does not exist */
0N/A client->errorValue = stuff->atom;
0N/A return (BadAtom);
0N/A }
168N/A
168N/A /* Initialize property created internally by server */
679N/A tsolprop = TsolPropertyPriv(pProp);
0N/A
0N/A sl = (bslabel_t *)(stuff + 1);
0N/A
0N/A if (!blequal(tsolprop->sl, sl))
0N/A {
633N/A if ((err_code = xtsol_policy(TSOL_RES_SL, TSOL_MODIFY, sl, 0,
633N/A client, TSOL_ALL, tsolprop->sl)))
0N/A {
0N/A return (err_code);
0N/A }
0N/A tsolprop->sl = lookupSL(sl);
0N/A }
606N/A
0N/A return (client->noClientException);
0N/A}
0N/A
0N/Astatic int
0N/AProcSetPropUID(ClientPtr client)
0N/A{
0N/A WindowPtr pWin;
0N/A TsolPropPtr tsolprop;
0N/A PropertyPtr pProp;
0N/A int err_code;
679N/A int rc;
0N/A
0N/A REQUEST(xSetPropUIDReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xSetPropUIDReq);
606N/A
679N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
679N/A if (rc != Success)
679N/A return rc;
679N/A
0N/A if (!pWin)
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (BadWindow);
0N/A }
679N/A
0N/A if (!ValidAtom(stuff->atom))
0N/A {
0N/A client->errorValue = stuff->atom;
0N/A return (BadAtom);
0N/A }
0N/A
0N/A /* first see if property already exists */
0N/A pProp = wUserProps (pWin);
0N/A while (pProp)
0N/A {
0N/A if (pProp->propertyName == stuff->atom)
0N/A break;
0N/A pProp = pProp->next;
0N/A }
0N/A
0N/A if (!pProp)
0N/A {
0N/A /* property does not exist */
0N/A client->errorValue = stuff->atom;
0N/A return (BadAtom);
0N/A }
633N/A if ((err_code = xtsol_policy(TSOL_RES_UID, TSOL_MODIFY, NULL, 0,
633N/A client, TSOL_ALL, &(MAJOROP))))
0N/A {
0N/A return (err_code);
0N/A }
168N/A /* Initialize property created internally by server */
679N/A tsolprop = TsolPropertyPriv(pProp);
168N/A
0N/A tsolprop->uid = stuff->uid;
0N/A
0N/A return (client->noClientException);
0N/A}
0N/A
0N/Astatic int
0N/AProcSetResLabel(ClientPtr client)
0N/A{
0N/A bslabel_t *sl;
0N/A PixmapPtr pMap;
0N/A WindowPtr pWin;
0N/A xEvent message;
0N/A TsolResPtr tsolres;
0N/A int err_code;
679N/A int rc;
606N/A
0N/A REQUEST(xSetResLabelReq);
0N/A
0N/A REQUEST_AT_LEAST_SIZE(xSetResLabelReq);
0N/A
0N/A sl = (bslabel_t *)(stuff + 1);
0N/A switch (stuff->resourceType)
0N/A {
0N/A case SESSIONHI: /* set server session HI */
633N/A if ((err_code = xtsol_policy(TSOL_RES_SL, TSOL_MODIFY, sl, 0,
633N/A client, TSOL_ALL, NULL)))
0N/A {
0N/A return (err_code);
0N/A }
0N/A memcpy(&SessionHI, sl, SL_SIZE);
0N/A return (client->noClientException);
0N/A case SESSIONLO: /* set server session LO */
633N/A if ((err_code = xtsol_policy(TSOL_RES_SL, TSOL_MODIFY, sl, 0,
633N/A client, TSOL_ALL, NULL)))
0N/A {
0N/A return (err_code);
0N/A }
0N/A memcpy(&SessionLO, sl, SL_SIZE);
0N/A return (client->noClientException);
0N/A case IsWindow:
679N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixWriteAccess);
679N/A if (rc != Success)
679N/A return rc;
679N/A
0N/A if (pWin)
0N/A {
606N/A tsolres = TsolWindowPriv(pWin);
0N/A }
0N/A else
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (BadWindow);
0N/A }
0N/A break;
0N/A case IsPixmap:
679N/A rc = dixLookupResource((pointer *)&pMap, stuff->id, RT_PIXMAP,
679N/A client, DixWriteAccess);
679N/A if (rc != Success)
679N/A return rc;
0N/A if (pMap)
0N/A {
606N/A tsolres = TsolPixmapPriv(pMap);
0N/A }
0N/A else
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (BadPixmap);
0N/A }
0N/A break;
633N/A default:
633N/A client->errorValue = stuff->resourceType;
633N/A return (BadValue);
0N/A }
0N/A
0N/A if (!blequal(tsolres->sl, sl))
0N/A {
633N/A if ((err_code = xtsol_policy(TSOL_RES_SL, TSOL_MODIFY, sl, 0,
633N/A client, TSOL_ALL, tsolres->sl)))
0N/A {
0N/A return (err_code);
0N/A }
0N/A tsolres->sl = lookupSL(sl);
0N/A }
0N/A
0N/A /* generate the notify event for windows */
0N/A
0N/A if (stuff->resourceType == IsWindow)
0N/A {
679N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
679N/A if (rc != Success)
679N/A return rc;
679N/A
0N/A message.u.u.type = ClientMessage; /* 33 */
0N/A message.u.u.detail = 32;
0N/A message.u.clientMessage.window = RootOf(pWin);
0N/A message.u.clientMessage.u.l.type =
0N/A MakeAtom("_TSOL_CMWLABEL_CHANGE", 21, 1);
0N/A message.u.clientMessage.u.l.longs0 = RootOfClient(pWin);
0N/A message.u.clientMessage.u.l.longs1 = stuff->id;
0N/A DeliverEventsToWindow(pWin, &message, 1,
0N/A SubstructureRedirectMask, NullGrab, 0);
0N/A
0N/A }
0N/A return (client->noClientException);
0N/A}
0N/A
0N/Astatic int
0N/AProcSetResUID(ClientPtr client)
0N/A{
0N/A int ScreenNumber;
0N/A PixmapPtr pMap;
0N/A WindowPtr pWin;
0N/A TsolResPtr tsolres;
0N/A int err_code;
679N/A int rc;
0N/A
0N/A REQUEST(xSetResUIDReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xSetResUIDReq);
0N/A
0N/A switch (stuff->resourceType)
0N/A {
0N/A case STRIPEHEIGHT:
633N/A if ((err_code = xtsol_policy(TSOL_RES_STRIPE, TSOL_MODIFY, NULL, 0,
633N/A client, TSOL_ALL, &(MAJOROP))))
0N/A {
0N/A return (err_code);
0N/A }
0N/A StripeHeight = stuff->uid;
0N/A ScreenNumber = stuff->id;
0N/A
0N/A /* set Screen Stripe Size */
0N/A DoScreenStripeHeight(ScreenNumber);
0N/A ScreenStripeHeight [ScreenNumber] = StripeHeight;
0N/A
0N/A return (client->noClientException);
0N/A case RES_OUID:
633N/A if ((err_code = xtsol_policy(TSOL_RES_WOWNER, TSOL_MODIFY, NULL, 0,
633N/A client, TSOL_ALL, &(MAJOROP))))
0N/A {
0N/A return (err_code);
0N/A }
0N/A OwnerUID = stuff->uid;
0N/A OwnerUIDint = OwnerUID;
0N/A AddUID(&OwnerUIDint);
0N/A return (client->noClientException);
0N/A case IsWindow:
679N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixWriteAccess);
679N/A if (rc != Success)
679N/A return rc;
679N/A
0N/A if (pWin)
0N/A {
606N/A tsolres = TsolWindowPriv(pWin);
0N/A }
0N/A else
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (BadWindow);
0N/A }
0N/A break;
0N/A case IsPixmap:
679N/A rc = dixLookupResource((pointer *)&pMap, stuff->id, RT_PIXMAP,
679N/A client, DixWriteAccess);
679N/A if (rc != Success)
679N/A return rc;
679N/A
0N/A if (pMap)
0N/A {
606N/A tsolres = TsolPixmapPriv(pMap);
0N/A }
0N/A else
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (BadPixmap);
0N/A }
0N/A break;
0N/A default:
0N/A return (BadValue);
0N/A }
606N/A
633N/A if ((err_code = xtsol_policy(TSOL_RES_UID, TSOL_MODIFY, NULL, 0,
633N/A client, TSOL_ALL, &(MAJOROP))))
0N/A {
0N/A return (err_code);
0N/A }
0N/A tsolres->uid = stuff->uid;
0N/A
0N/A return (client->noClientException);
0N/A}
0N/A
0N/Astatic int
0N/AProcGetClientAttributes(ClientPtr client)
0N/A{
0N/A int n;
0N/A int err_code;
679N/A int rc;
0N/A ClientPtr res_client; /* resource owner client */
0N/A TsolInfoPtr tsolinfo, res_tsolinfo;
0N/A WindowPtr pWin;
0N/A
0N/A xGetClientAttributesReply rep;
606N/A
0N/A REQUEST(xGetClientAttributesReq);
0N/A REQUEST_SIZE_MATCH(xGetClientAttributesReq);
0N/A
0N/A /* Valid window check */
679N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
679N/A if (rc != Success)
679N/A return rc;
0N/A
0N/A if (!(res_client = clients[CLIENT_ID(stuff->id)]))
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (BadWindow);
0N/A }
633N/A if ((err_code = xtsol_policy(TSOL_RES_CLIENT, TSOL_READ, NULL, stuff->id,
633N/A client, TSOL_ALL, &(MAJOROP))))
0N/A {
0N/A return (err_code);
0N/A }
0N/A tsolinfo = GetClientTsolInfo(client);
0N/A res_tsolinfo = GetClientTsolInfo(res_client);
0N/A
0N/A /* Transfer the client info to reply rec */
0N/A rep.type = X_Reply;
0N/A rep.sequenceNumber = client->sequence;
606N/A rep.trustflag = (res_tsolinfo->forced_trust == 1
0N/A || res_tsolinfo->trusted_path) ? (BYTE)1 : (BYTE)0;
0N/A rep.uid = (CARD32) res_tsolinfo->uid;
0N/A rep.pid = (CARD32) res_tsolinfo->pid;
0N/A rep.gid = (CARD32) res_tsolinfo->gid;
0N/A rep.auditid = (CARD32) res_tsolinfo->auid;
36N/A rep.sessionid = (CARD32) res_tsolinfo->asid;
0N/A rep.iaddr = (CARD32) res_tsolinfo->iaddr;
0N/A rep.length = (CARD32) 0;
0N/A
0N/A if (client->swapped)
0N/A {
0N/A swaps(&rep.sequenceNumber, n);
0N/A swapl(&rep.length, n);
0N/A swapl(&rep.uid, n);
0N/A swapl(&rep.pid, n);
0N/A swapl(&rep.gid, n);
0N/A swapl(&rep.auditid, n);
0N/A swapl(&rep.sessionid, n);
0N/A swapl(&rep.iaddr, n);
0N/A }
0N/A
0N/A WriteToClient(client, sizeof(xGetClientAttributesReply), (char *)&rep);
0N/A
0N/A return (client->noClientException);
0N/A}
0N/A
0N/Astatic int
0N/AProcGetClientLabel(ClientPtr client)
0N/A{
0N/A int n;
633N/A int reply_length = 0;
679N/A int rc;
0N/A int err_code;
0N/A Bool write_to_client = 0;
0N/A bslabel_t *sl;
0N/A ClientPtr res_client; /* resource owner client */
0N/A TsolInfoPtr tsolinfo, res_tsolinfo;
0N/A WindowPtr pWin;
0N/A
0N/A xGenericReply rep;
0N/A
0N/A REQUEST(xGetClientLabelReq);
0N/A REQUEST_SIZE_MATCH(xGetClientLabelReq);
0N/A
0N/A /* Valid window check */
679N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
679N/A if (rc != Success)
679N/A return rc;
0N/A
0N/A if (!(res_client = clients[CLIENT_ID(stuff->id)]))
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (BadWindow);
0N/A }
633N/A if ((err_code = xtsol_policy(TSOL_RES_CLIENT, TSOL_READ, NULL, stuff->id,
633N/A client, TSOL_ALL, &(MAJOROP))))
0N/A {
0N/A return (err_code);
0N/A }
0N/A tsolinfo = GetClientTsolInfo(client);
0N/A res_tsolinfo = GetClientTsolInfo(res_client);
0N/A
0N/A /* Transfer the client info to reply rec */
0N/A rep.type = X_Reply;
0N/A rep.sequenceNumber = client->sequence;
0N/A
0N/A /* allocate temp storage for labels */
606N/A sl = (bslabel_t *)(xalloc(SL_SIZE));
0N/A rep.data00 = rep.data01 = 0;
0N/A if (sl == NULL)
0N/A return (BadAlloc);
606N/A
0N/A /* fill the fields as per request mask */
0N/A if (stuff->mask & RES_SL)
0N/A {
0N/A memcpy(sl, res_tsolinfo->sl, SL_SIZE);
0N/A rep.data00 = SL_SIZE;
0N/A }
606N/A
0N/A rep.length = (CARD32)(rep.data00)/4;
0N/A
0N/A if (rep.length > 0)
0N/A {
0N/A reply_length = rep.length*4;
0N/A write_to_client = 1;
0N/A }
0N/A if (client->swapped)
0N/A {
0N/A swaps(&rep.sequenceNumber, n);
0N/A swapl(&rep.length, n);
0N/A swapl(&rep.data00, n);
0N/A swapl(&rep.data01, n);
0N/A }
0N/A
0N/A WriteToClient(client, sizeof(xGenericReply), (char *)&rep);
0N/A
0N/A if (write_to_client == 1)
0N/A {
0N/A WriteToClient(client, reply_length, (char *)sl);
0N/A }
606N/A xfree(sl);
0N/A
0N/A return (client->noClientException);
0N/A}
0N/A
0N/Astatic int
0N/AProcGetPropAttributes(ClientPtr client)
0N/A{
0N/A int n;
633N/A int reply_length = 0;
679N/A int rc;
0N/A Bool write_to_client = 0;
0N/A PropertyPtr pProp;
0N/A bslabel_t *sl;
0N/A WindowPtr pWin;
679N/A TsolPropPtr tsolprop;
679N/A TsolResPtr tsolres;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A xGetPropAttributesReply rep;
0N/A
0N/A REQUEST(xGetPropAttributesReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xGetPropAttributesReq);
0N/A
679N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
679N/A if (rc != Success)
679N/A return rc;
679N/A
0N/A if (!ValidAtom(stuff->atom))
0N/A {
0N/A client->errorValue = stuff->atom;
0N/A return (BadAtom);
0N/A }
0N/A
0N/A /* first see if property already exists */
0N/A pProp = wUserProps (pWin);
0N/A while (pProp)
0N/A {
679N/A tsolprop = TsolPropertyPriv(pProp);
679N/A
679N/A if (pProp->propertyName == stuff->atom) {
679N/A
679N/A if (tsolpolyinstinfo.enabled) {
679N/A if (tsolprop->uid == tsolpolyinstinfo.uid &&
679N/A tsolprop->sl == tsolpolyinstinfo.sl)
679N/A break; /* match found */
679N/A } else {
679N/A if (tsolprop->uid == tsolinfo->uid &&
679N/A tsolprop->sl == tsolinfo->sl) {
679N/A break; /* match found */
679N/A }
679N/A }
679N/A }
0N/A pProp = pProp->next;
0N/A }
0N/A
0N/A if (!pProp)
0N/A {
679N/A /* property does not exist, use window's attributes */
679N/A tsolres = TsolWindowPriv(pWin);
679N/A tsolprop = NULL;
0N/A }
679N/A
0N/A if (stuff->mask & RES_UID)
0N/A {
679N/A rep.uid = tsolprop ? tsolprop->uid : tsolres->uid;
0N/A }
0N/A
0N/A /* allocate temp storage for labels */
606N/A sl = (bslabel_t *)(xalloc(SL_SIZE));
0N/A rep.sllength = rep.illength = 0;
0N/A if (sl == NULL)
0N/A return (BadAlloc);
606N/A
0N/A /* fill the fields as per request mask */
0N/A if (stuff->mask & RES_SL)
0N/A {
679N/A memcpy(sl, tsolprop ? tsolprop->sl : tsolres->sl, SL_SIZE);
0N/A rep.sllength = SL_SIZE;
0N/A }
0N/A
0N/A rep.type = X_Reply;
0N/A rep.sequenceNumber = client->sequence;
0N/A rep.length = (CARD32) (rep.sllength)/4;
0N/A
0N/A if (rep.length > 0)
0N/A {
0N/A reply_length = rep.length*4;
0N/A write_to_client = 1;
0N/A }
0N/A if (client->swapped)
0N/A {
0N/A swaps(&rep.sequenceNumber, n);
0N/A swapl(&rep.length, n);
0N/A swapl(&rep.uid, n);
0N/A swaps(&rep.sllength, n);
0N/A swaps(&rep.illength, n);
0N/A }
0N/A
0N/A WriteToClient(client, sizeof(xGetPropAttributesReply), (char *)&rep);
0N/A
0N/A if (write_to_client == 1)
0N/A {
0N/A WriteToClient(client, reply_length, (char *)sl);
0N/A }
606N/A xfree(sl);
0N/A
0N/A return (client->noClientException);
0N/A}
0N/A
0N/Astatic int
0N/AProcGetResAttributes(ClientPtr client)
0N/A{
0N/A int n;
633N/A int reply_length = 0;
679N/A int rc;
0N/A Bool write_to_client = 0;
0N/A bslabel_t *sl;
0N/A PixmapPtr pMap;
0N/A WindowPtr pWin;
633N/A TsolResPtr tsolres = NULL;
0N/A
0N/A xGetResAttributesReply rep;
0N/A
0N/A REQUEST(xGetResAttributesReq);
0N/A
0N/A REQUEST_SIZE_MATCH(xGetResAttributesReq);
0N/A
0N/A if (stuff->mask & RES_STRIPE)
0N/A {
0N/A rep.uid = ScreenStripeHeight[stuff->id];
0N/A }
0N/A if (stuff->mask & RES_OUID)
0N/A {
0N/A rep.owneruid = OwnerUID;
0N/A }
606N/A if (stuff->resourceType == IsWindow &&
0N/A (stuff->mask & (RES_UID | RES_SL )))
0N/A {
679N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
679N/A if (rc != Success)
679N/A return rc;
679N/A
679N/A tsolres = TsolWindowPriv(pWin);
0N/A }
679N/A
606N/A if (stuff->resourceType == IsPixmap &&
0N/A (stuff->mask & (RES_UID | RES_SL )))
0N/A {
679N/A rc = dixLookupResource((pointer *)&pMap, stuff->id, RT_PIXMAP,
679N/A client, DixWriteAccess);
679N/A if (rc != Success)
679N/A return rc;
679N/A
679N/A tsolres = TsolPixmapPriv(pMap);
0N/A }
0N/A
0N/A if (stuff->mask & RES_UID)
0N/A {
0N/A rep.uid = tsolres->uid;
0N/A }
0N/A
0N/A /* allocate temp storage for labels */
606N/A sl = (bslabel_t *)(xalloc(SL_SIZE));
0N/A rep.sllength = rep.illength = rep.iillength = 0;
0N/A if (sl == NULL)
0N/A return (BadAlloc);
606N/A
0N/A /* fill the fields as per request mask */
0N/A if (stuff->mask & RES_SL)
0N/A {
0N/A memcpy(sl, tsolres->sl, SL_SIZE);
0N/A rep.sllength = SL_SIZE;
0N/A }
0N/A
0N/A rep.type = X_Reply;
0N/A rep.sequenceNumber = client->sequence;
0N/A rep.length = (CARD32) (rep.sllength)/4;
0N/A
0N/A if (rep.length > 0)
0N/A {
0N/A reply_length = rep.length*4;
0N/A write_to_client = 1;
0N/A }
0N/A if (client->swapped)
0N/A {
0N/A swaps(&rep.sequenceNumber, n);
0N/A swapl(&rep.length, n);
0N/A swapl(&rep.uid, n);
0N/A swapl(&rep.owneruid, n);
0N/A swaps(&rep.sllength, n);
0N/A swaps(&rep.illength, n);
0N/A swaps(&rep.iillength, n);
0N/A }
0N/A
0N/A WriteToClient(client, sizeof(xGetResAttributesReply), (char *)&rep);
0N/A
0N/A if (write_to_client == 1)
0N/A {
0N/A WriteToClient(client, reply_length, (char *)sl);
0N/A }
606N/A xfree(sl);
0N/A
0N/A return (client->noClientException);
0N/A}
0N/A
0N/Aint
0N/AProcMakeTPWindow(ClientPtr client)
0N/A{
633N/A WindowPtr pWin = NULL, pParent;
679N/A int rc;
0N/A int err_code;
36N/A TsolInfoPtr tsolinfo;
0N/A
0N/A REQUEST(xMakeTPWindowReq);
0N/A REQUEST_SIZE_MATCH(xMakeTPWindowReq);
0N/A
36N/A /*
606N/A * Session type single-level? This is set by the
36N/A * label builder
36N/A */
36N/A tsolinfo = GetClientTsolInfo(client);
606N/A if (tsolinfo && HasTrustedPath(tsolinfo) &&
36N/A blequal(&SessionLO, &SessionHI) && stuff->id == 0) {
36N/A tsolMultiLevel = FALSE;
36N/A return (client->noClientException);
36N/A }
36N/A
606N/A#if defined(PANORAMIX)
606N/A if (!noPanoramiXExtension)
0N/A {
470N/A PanoramiXRes *panres = NULL;
470N/A int j;
470N/A
470N/A if ((panres = (PanoramiXRes *)LookupIDByType(stuff->id, XRT_WINDOW))
470N/A == NULL)
470N/A return BadWindow;
470N/A
470N/A FOR_NSCREENS_BACKWARD(j)
470N/A {
679N/A rc = dixLookupWindow(&pWin, panres->info[j].id,
679N/A client, DixWriteAccess);
679N/A if (rc != Success)
679N/A return rc;
470N/A
470N/A /* window should not be root but child of root */
470N/A if (!pWin || (!pWin->parent))
470N/A {
470N/A client->errorValue = stuff->id;
470N/A return (BadWindow);
470N/A }
633N/A if ((err_code = xtsol_policy(TSOL_RES_TPWIN, TSOL_MODIFY, pWin,
633N/A 0, client, TSOL_ALL, &(MAJOROP))))
470N/A {
470N/A return (err_code);
470N/A }
470N/A
470N/A pParent = pWin->parent;
470N/A if (pParent->firstChild != pWin)
470N/A {
470N/A tpwin = (WindowPtr)NULL;
470N/A ReflectStackChange(pWin, pParent->firstChild, VTStack);
470N/A }
470N/A }
606N/A } else
311N/A#endif
311N/A {
679N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixWriteAccess);
679N/A if (rc != Success)
679N/A return rc;
679N/A
311N/A
311N/A /* window should not be root but child of root */
311N/A if (!pWin || (!pWin->parent))
311N/A {
311N/A client->errorValue = stuff->id;
311N/A return (BadWindow);
311N/A }
633N/A if ((err_code = xtsol_policy(TSOL_RES_TPWIN, TSOL_MODIFY, pWin, 0,
633N/A client, TSOL_ALL, &(MAJOROP))))
311N/A {
311N/A return (err_code);
311N/A }
311N/A
311N/A pParent = pWin->parent;
311N/A if (pParent->firstChild != pWin)
311N/A {
311N/A tpwin = (WindowPtr)NULL;
311N/A ReflectStackChange(pWin, pParent->firstChild, VTStack);
311N/A }
0N/A }
0N/A
0N/A tpwin = pWin;
0N/A
0N/A /*
0N/A * Force kbd & ptr ungrab. This will cause
0N/A * screen to lock even when kbd/ptr grabbed by
0N/A * a client
0N/A */
0N/A BreakAllGrabs(client);
0N/A return (client->noClientException);
0N/A}
0N/A
0N/A/*
0N/A * Turn on window's Trusted bit
0N/A */
0N/Astatic int
0N/AProcMakeTrustedWindow(ClientPtr client)
0N/A{
0N/A WindowPtr pWin;
679N/A int rc;
0N/A int err_code;
0N/A TsolInfoPtr tsolinfo;
0N/A
0N/A REQUEST(xMakeTrustedWindowReq);
0N/A REQUEST_SIZE_MATCH(xMakeTrustedWindowReq);
0N/A
679N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixWriteAccess);
679N/A if (rc != Success)
679N/A return rc;
0N/A
0N/A /* window should not be root but child of root */
0N/A if (!pWin || (!pWin->parent))
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (BadWindow);
0N/A }
633N/A if ((err_code = xtsol_policy(TSOL_RES_TPWIN, TSOL_MODIFY, pWin, 0,
633N/A client, TSOL_ALL, &(MAJOROP))))
0N/A {
0N/A return (err_code);
0N/A }
606N/A tsolinfo = GetClientTsolInfo(client);
0N/A /* Turn on Trusted bit of the window */
0N/A tsolinfo->forced_trust = 1;
0N/A return (client->noClientException);
0N/A}
0N/A
0N/A/*
0N/A * Turn off window's Trusted bit
0N/A */
0N/Astatic int
0N/AProcMakeUntrustedWindow(ClientPtr client)
0N/A{
0N/A WindowPtr pWin;
679N/A int rc;
0N/A int err_code;
0N/A TsolInfoPtr tsolinfo;
0N/A
0N/A REQUEST(xMakeUntrustedWindowReq);
0N/A REQUEST_SIZE_MATCH(xMakeUntrustedWindowReq);
0N/A
679N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixWriteAccess);
679N/A if (rc != Success)
679N/A return rc;
0N/A
0N/A /* window should not be root but child of root */
0N/A if (!pWin || (!pWin->parent))
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (BadWindow);
0N/A }
633N/A if ((err_code = xtsol_policy(TSOL_RES_TPWIN, TSOL_MODIFY, pWin, 0,
633N/A client, TSOL_ALL, &(MAJOROP))))
0N/A {
0N/A return (err_code);
0N/A }
606N/A tsolinfo = GetClientTsolInfo(client);
0N/A tsolinfo->forced_trust = 0;
0N/A tsolinfo->trusted_path = FALSE;
606N/A
0N/A return (client->noClientException);
0N/A}
0N/A
0N/A/*
0N/A * Break keyboard & ptr grabs of clients other than
0N/A * the requesting client.
0N/A * Called from ProcMakeTPWindow.
0N/A */
0N/Astatic void
0N/ABreakAllGrabs(ClientPtr client)
0N/A{
0N/A ClientPtr grabclient;
0N/A DeviceIntPtr keybd = inputInfo.keyboard;
0N/A GrabPtr kbdgrab = keybd->grab;
0N/A DeviceIntPtr mouse = inputInfo.pointer;
0N/A GrabPtr ptrgrab = mouse->grab;
0N/A
0N/A if (kbdgrab) {
0N/A grabclient = clients[CLIENT_ID(kbdgrab->resource)];
0N/A if (client->index != grabclient->index)
0N/A (*keybd->DeactivateGrab)(keybd);
0N/A }
0N/A
0N/A if (ptrgrab) {
0N/A grabclient = clients[CLIENT_ID(ptrgrab->resource)];
0N/A if (client->index != grabclient->index)
0N/A (*mouse->DeactivateGrab)(mouse);
0N/A }
0N/A}
0N/A
0N/A/*
0N/A * Trusted Network interface module. Uses tsix API
0N/A */
633N/Aextern au_id_t ucred_getauid(const ucred_t *uc);
633N/Aextern au_asid_t ucred_getasid(const ucred_t *uc);
633N/Aextern const au_mask_t *ucred_getamask(const ucred_t *uc);
633N/Aextern tsol_host_type_t tsol_getrhtype(char *);
0N/A
0N/Astatic void
0N/ATsolSetClientInfo(ClientPtr client)
0N/A{
0N/A bslabel_t *sl;
0N/A bslabel_t admin_low;
0N/A priv_set_t *privs;
0N/A const au_mask_t *amask;
36N/A socklen_t namelen;
36N/A struct auditinfo auinfo;
36N/A struct auditinfo *pauinfo;
0N/A OsCommPtr oc = (OsCommPtr)client->osPrivate;
0N/A int fd = oc->fd;
0N/A ucred_t *uc = NULL;
0N/A
606N/A TsolInfoPtr tsolinfo = TsolClientPriv(client);
0N/A
0N/A /* Get client attributes from the socket */
0N/A if (getpeerucred(fd, &uc) == -1) {
639N/A const char *errmsg = strerror(errno);
639N/A
0N/A tsolinfo->uid = (uid_t)(-1);
0N/A tsolinfo->sl = NULL;
639N/A snprintf(tsolinfo->pname, MAXNAME,
639N/A "client id %d (pid unknown)", client->index);
639N/A LogMessageVerb(X_ERROR, TSOL_MSG_ERROR,
639N/A TSOL_LOG_PREFIX "Cannot get client attributes"
639N/A " for %s, getpeerucred failed: %s\n",
639N/A tsolinfo->pname, errmsg);
0N/A return;
0N/A }
0N/A
0N/A /* Extract individual fields from the cred structure */
0N/A tsolinfo->zid = ucred_getzoneid(uc);
0N/A tsolinfo->uid = ucred_getruid(uc);
0N/A tsolinfo->euid = ucred_geteuid(uc);
0N/A tsolinfo->gid = ucred_getrgid(uc);
0N/A tsolinfo->egid = ucred_getegid(uc);
0N/A tsolinfo->pid = ucred_getpid(uc);
0N/A sl = ucred_getlabel(uc);
0N/A tsolinfo->sl = (bslabel_t *)lookupSL(sl);
0N/A
639N/A /* store a string for debug/error messages - would be nice to
639N/A get the real process name out of /proc in the future
639N/A */
639N/A snprintf(tsolinfo->pname, MAXNAME, "client id %d (pid %d)",
639N/A client->index, tsolinfo->pid);
639N/A
0N/A /* Set privileges */
0N/A if ((tsolinfo->privs = priv_allocset()) != NULL) {
36N/A if (tsolMultiLevel) {
36N/A privs = (priv_set_t *)ucred_getprivset(uc, PRIV_EFFECTIVE);
36N/A if (privs == NULL) {
36N/A priv_emptyset(tsolinfo->privs);
36N/A } else {
36N/A priv_copyset(privs, tsolinfo->privs);
36N/A }
0N/A } else {
606N/A priv_fillset(tsolinfo->privs);
0N/A }
0N/A }
0N/A
0N/A tsolinfo->priv_debug = FALSE;
0N/A
0N/A
606N/A /*
0N/A * For remote hosts, the uid is determined during access control
0N/A * using Secure RPC
0N/A */
0N/A if (tsolinfo->zid == (zoneid_t)-1) {
0N/A tsolinfo->client_type = CLIENT_REMOTE;
0N/A } else {
0N/A tsolinfo->client_type = CLIENT_LOCAL;
0N/A }
0N/A
606N/A
0N/A /* Set Trusted Path for local clients */
0N/A if (tsolinfo->zid == GLOBAL_ZONEID) {
0N/A tsolinfo->trusted_path = TRUE;
0N/A }else {
0N/A tsolinfo->trusted_path = FALSE;
36N/A }
36N/A
36N/A if (tsolinfo->trusted_path || !tsolMultiLevel)
606N/A setClientTrustLevel(client, XSecurityClientTrusted);
36N/A else
606N/A setClientTrustLevel(client, XSecurityClientUntrusted);
0N/A
0N/A tsolinfo->forced_trust = 0;
0N/A tsolinfo->iaddr = 0;
0N/A
0N/A bsllow(&admin_low);
36N/A
311N/A /* Set reasonable defaults for remote clients */
36N/A namelen = sizeof (tsolinfo->saddr);
311N/A if (getpeername(fd, (struct sockaddr *)&tsolinfo->saddr, &namelen) == 0
311N/A && (tsolinfo->client_type == CLIENT_REMOTE)) {
36N/A int errcode;
36N/A char hostbuf[NI_MAXHOST];
606N/A tsol_host_type_t host_type;
0N/A
36N/A /* Use NI_NUMERICHOST to avoid DNS lookup */
36N/A errcode = getnameinfo((struct sockaddr *)&(tsolinfo->saddr), namelen,
36N/A hostbuf, sizeof(hostbuf), NULL, 0, NI_NUMERICHOST);
36N/A
36N/A if (errcode) {
36N/A perror(gai_strerror(errcode));
36N/A } else {
36N/A host_type = tsol_getrhtype(hostbuf);
606N/A if ((host_type == SUN_CIPSO) &&
36N/A blequal(tsolinfo->sl, &admin_low)) {
0N/A tsolinfo->trusted_path = TRUE;
606N/A setClientTrustLevel(client,
606N/A XSecurityClientTrusted);
0N/A priv_fillset(tsolinfo->privs);
0N/A }
0N/A }
0N/A }
36N/A
36N/A /* setup audit context */
36N/A if (getaudit(&auinfo) == 0) {
36N/A pauinfo = &auinfo;
36N/A } else {
36N/A pauinfo = NULL;
36N/A }
36N/A
36N/A /* Audit id */
36N/A tsolinfo->auid = ucred_getauid(uc);
36N/A if (tsolinfo->auid == AU_NOAUDITID) {
36N/A tsolinfo->auid = UID_NOBODY;
0N/A }
36N/A
36N/A /* session id */
36N/A tsolinfo->asid = ucred_getasid(uc);
36N/A
36N/A /* Audit mask */
36N/A if ((amask = ucred_getamask(uc)) != NULL) {
36N/A tsolinfo->amask = *amask;
36N/A } else {
36N/A if (pauinfo != NULL) {
36N/A tsolinfo->amask = pauinfo->ai_mask;
36N/A } else {
36N/A tsolinfo->amask.am_failure = 0; /* clear the masks */
36N/A tsolinfo->amask.am_success = 0;
36N/A }
36N/A }
36N/A
36N/A tsolinfo->asaverd = 0;
36N/A
36N/A ucred_free(uc);
0N/A}
0N/A
36N/Astatic enum auth_stat tsol_why;
633N/Aextern bool_t xdr_opaque_auth(XDR *, struct opaque_auth *);
36N/A
606N/Astatic char *
606N/Atsol_authdes_decode(char *inmsg, int len)
36N/A{
36N/A struct rpc_msg msg;
36N/A char cred_area[MAX_AUTH_BYTES];
36N/A char verf_area[MAX_AUTH_BYTES];
36N/A char *temp_inmsg;
36N/A struct svc_req r;
606N/A bool_t res0, res1;
36N/A XDR xdr;
36N/A SVCXPRT xprt;
36N/A
36N/A temp_inmsg = (char *) xalloc(len);
36N/A memmove(temp_inmsg, inmsg, len);
36N/A
36N/A memset((char *)&msg, 0, sizeof(msg));
36N/A memset((char *)&r, 0, sizeof(r));
36N/A memset(cred_area, 0, sizeof(cred_area));
36N/A memset(verf_area, 0, sizeof(verf_area));
36N/A
36N/A msg.rm_call.cb_cred.oa_base = cred_area;
36N/A msg.rm_call.cb_verf.oa_base = verf_area;
606N/A tsol_why = AUTH_FAILED;
36N/A xdrmem_create(&xdr, temp_inmsg, len, XDR_DECODE);
36N/A
36N/A if ((r.rq_clntcred = (caddr_t) xalloc(MAX_AUTH_BYTES)) == NULL)
36N/A goto bad1;
36N/A r.rq_xprt = &xprt;
36N/A
36N/A /* decode into msg */
606N/A res0 = xdr_opaque_auth(&xdr, &(msg.rm_call.cb_cred));
36N/A res1 = xdr_opaque_auth(&xdr, &(msg.rm_call.cb_verf));
36N/A if ( ! (res0 && res1) )
36N/A goto bad2;
36N/A
36N/A /* do the authentication */
36N/A
36N/A r.rq_cred = msg.rm_call.cb_cred; /* read by opaque stuff */
36N/A if (r.rq_cred.oa_flavor != AUTH_DES) {
36N/A tsol_why = AUTH_TOOWEAK;
36N/A goto bad2;
36N/A }
36N/A#ifdef SVR4
36N/A if ((tsol_why = __authenticate(&r, &msg)) != AUTH_OK) {
36N/A#else
36N/A if ((tsol_why = _authenticate(&r, &msg)) != AUTH_OK) {
36N/A#endif
36N/A goto bad2;
36N/A }
606N/A return (((struct authdes_cred *) r.rq_clntcred)->adc_fullname.name);
36N/A
36N/Abad2:
36N/A Xfree(r.rq_clntcred);
36N/Abad1:
36N/A return ((char *)0); /* ((struct authdes_cred *) NULL); */
36N/A}
606N/A
0N/Astatic Bool
36N/ATsolCheckNetName (unsigned char *addr, short len, pointer closure)
0N/A{
36N/A return (len == (short) strlen ((char *) closure) &&
0N/A strncmp ((char *) addr, (char *) closure, len) == 0);
0N/A}
0N/A
633N/Aextern int getdomainname(char *, int);
0N/A
633N/Astatic XID
633N/ATsolCheckAuthorization(unsigned int name_length, char *name,
633N/A unsigned int data_length, char *data,
633N/A ClientPtr client, char **reason)
0N/A{
0N/A char domainname[128];
0N/A char netname[128];
36N/A char audit_ret;
36N/A u_int audit_val;
36N/A uid_t client_uid;
36N/A gid_t client_gid;
36N/A int client_gidlen;
36N/A char *fullname;
36N/A gid_t client_gidlist;
36N/A XID auth_token = (XID)(-1);
36N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
633N/A if (tsolinfo->uid == (uid_t) -1) {
36N/A /* Retrieve uid from SecureRPC */
36N/A if (strncmp(name, SECURE_RPC_AUTH, (size_t)name_length) == 0) {
36N/A fullname = tsol_authdes_decode(data, data_length);
36N/A if (fullname == NULL) {
36N/A ErrorF("Unable to authenticate Secure RPC client");
36N/A } else {
606N/A if (netname2user(fullname,
606N/A &client_uid, &client_gid,
36N/A &client_gidlen, &client_gidlist)) {
36N/A tsolinfo->uid = client_uid;
36N/A } else {
36N/A ErrorF("netname2user failed");
36N/A }
36N/A }
36N/A }
36N/A }
606N/A
36N/A if (tsolinfo->uid == (uid_t)-1) {
36N/A tsolinfo->uid = UID_NOBODY; /* uid not available */
36N/A }
36N/A
606N/A /*
196N/A * For multilevel desktop, limit connections to the trusted path
606N/A * i.e. global zone until a user logs in and the trusted stripe
196N/A * is in place. Unlabeled connections are rejected.
196N/A */
196N/A if ((OwnerUID == (uid_t )(-1)) || (tsolMultiLevel && tpwin == NULL)) {
0N/A if (HasTrustedPath(tsolinfo)) {
36N/A auth_token = CheckAuthorization(name_length, name, data_length,
36N/A data, client, reason);
0N/A }
0N/A } else {
606N/A /*
0N/A * Workstation Owner set, client must be within label
0N/A * range or have trusted path
0N/A */
0N/A if (tsolinfo->uid == OwnerUID) {
606N/A if ((tsolinfo->sl != NULL &&
606N/A (bldominates(tsolinfo->sl, &SessionLO) &&
606N/A bldominates(&SessionHI, tsolinfo->sl))) ||
606N/A (HasTrustedPath(tsolinfo))) {
606N/A auth_token = (XID)(tsolinfo->uid);
0N/A }
0N/A } else {
461N/A /* Allow root from global zone */
461N/A if (tsolinfo->uid == 0 && HasTrustedPath(tsolinfo)) {
461N/A auth_token = (XID)(tsolinfo->uid);
461N/A } else {
606N/A /*
461N/A * Access check based on uid. Check if
461N/A * roles or other uids have been added by
461N/A * xhost +role@
461N/A */
0N/A getdomainname(domainname, sizeof(domainname));
0N/A if (!user2netname(netname, tsolinfo->uid, domainname)) {
0N/A return ((XID)-1);
0N/A }
36N/A if (ForEachHostInFamily (FamilyNetname, TsolCheckNetName,
0N/A (pointer) netname)) {
0N/A return ((XID)(tsolinfo->uid));
0N/A } else {
0N/A return (CheckAuthorization(name_length, name, data_length,
0N/A data, client, reason));
0N/A }
0N/A }
0N/A }
0N/A }
36N/A
36N/A /* Audit the connection */
36N/A if (auth_token == (XID)(-1)) {
36N/A audit_ret = (char )-1; /* failure */
36N/A audit_val = 1;
36N/A } else {
36N/A audit_ret = 0; /* success */
36N/A audit_val = 0;
36N/A }
36N/A
36N/A if (system_audit_on &&
36N/A (au_preselect(AUE_ClientConnect, &(tsolinfo->amask),
36N/A AU_PRS_BOTH, AU_PRS_USECACHE) == 1)) {
36N/A int status;
36N/A u_short connect_port = 0;
36N/A struct in_addr *connect_addr = NULL;
36N/A struct sockaddr_in *sin;
36N/A struct sockaddr_in6 *sin6;
36N/A
36N/A switch (tsolinfo->saddr.ss_family) {
36N/A case AF_INET:
36N/A sin = (struct sockaddr_in *)&(tsolinfo->saddr);
36N/A connect_addr = &(sin->sin_addr);
36N/A connect_port = sin->sin_port;
36N/A break;
36N/A case AF_INET6:
36N/A sin6 = (struct sockaddr_in6 *)&(tsolinfo->saddr);
36N/A connect_addr = (struct in_addr *)&(sin6->sin6_addr);
36N/A connect_port = sin6->sin6_port;
36N/A break;
36N/A }
36N/A
36N/A if (connect_addr == NULL || connect_port == 0) {
36N/A status = auditwrite(AW_EVENTNUM, AUE_ClientConnect,
36N/A AW_XCLIENT, client->index,
36N/A AW_SLABEL, tsolinfo->sl,
36N/A AW_RETURN, audit_ret, audit_val,
36N/A AW_WRITE, AW_END);
36N/A } else {
36N/A status = auditwrite(AW_EVENTNUM, AUE_ClientConnect,
36N/A AW_XCLIENT, client->index,
36N/A AW_SLABEL, tsolinfo->sl,
36N/A AW_INADDR, connect_addr,
36N/A AW_IPORT, connect_port,
36N/A AW_RETURN, audit_ret, audit_val,
36N/A AW_WRITE, AW_END);
36N/A }
36N/A
36N/A if (!status)
36N/A (void) auditwrite(AW_FLUSH, AW_END);
36N/A tsolinfo->flags &= ~TSOL_DOXAUDIT;
36N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
36N/A }
196N/A
196N/A return (auth_token);
0N/A}
0N/A
606N/Astatic CALLBACK(
606N/ATsolProcessKeyboard)
0N/A{
606N/A XaceKeyAvailRec *rec = (XaceKeyAvailRec *) calldata;
606N/A xEvent *xE = rec->event;
606N/A DeviceIntPtr keybd = rec->keybd;
606N/A/* int count = rec->count; */
606N/A KeyClassPtr keyc = keybd->key;
606N/A
0N/A if (xE->u.u.type == KeyPress)
0N/A {
0N/A if (!hotkey.initialized)
0N/A InitHotKey(&hotkey);
0N/A
0N/A if (((xE->u.u.detail == hotkey.key) &&
0N/A (keyc->state != 0 && keyc->state == hotkey.shift)) ||
0N/A ((xE->u.u.detail == hotkey.altkey) &&
0N/A (keyc->state != 0 && keyc->state == hotkey.altshift)))
0N/A HandleHotKey();
0N/A }
0N/A}
0N/A
679N/Astatic CALLBACK(
679N/ATsolCheckSendAccess)
614N/A{
679N/A XaceSendAccessRec *rec = (XaceSendAccessRec *) calldata;
679N/A ClientPtr client = rec->client;
679N/A WindowPtr pWin = rec->pWin;
679N/A
679N/A if (client == NULL) {
679N/A rec->status = Success;
679N/A return;
679N/A }
679N/A
679N/A rec->status = xtsol_policy(TSOL_RES_EVENTWIN, TSOL_MODIFY,
679N/A pWin, 0, client, TSOL_ALL, (&(MAJOROP)));
679N/A}
679N/A
679N/Astatic CALLBACK(
679N/ATsolCheckReceiveAccess)
679N/A{
679N/A XaceReceiveAccessRec *rec = (XaceReceiveAccessRec *) calldata;
679N/A
679N/A rec->status = Success;
679N/A}
679N/A
679N/Astatic CALLBACK(
679N/ATsolCheckDeviceAccess)
679N/A{
679N/A XaceDeviceAccessRec *rec = (XaceDeviceAccessRec *) calldata;
679N/A ClientPtr client = rec->client;
679N/A Mask access_mode = rec->access_mode;
639N/A int reqtype;
679N/A TsolInfoPtr tsolinfo;
614N/A
639N/A if (client->requestBuffer) {
639N/A reqtype = MAJOROP; /* protocol */
639N/A } else {
639N/A reqtype = -1;
614N/A }
614N/A
679N/A /*
679N/A * The Create case seems to be for initialization, so we don't
679N/A * want it to fail and there isn't a corresponding protocol request type.
679N/A */
679N/A if (access_mode & DixCreateAccess) {
679N/A rec->status = Success;
679N/A return;
679N/A }
679N/A
679N/A switch (reqtype) {
679N/A case X_Bell:
679N/A rec->status = xtsol_policy(TSOL_RES_BELL, TSOL_MODIFY,
679N/A NULL, 0, client, TSOL_ALL, &(MAJOROP));
679N/A break;
679N/A
679N/A case X_GetPointerControl:
679N/A rec->status = xtsol_policy(TSOL_RES_PTRCTL, TSOL_READ,
679N/A NULL, 0, client, TSOL_ALL, &(MAJOROP));
679N/A break;
679N/A
679N/A case X_ChangePointerControl:
679N/A rec->status = xtsol_policy(TSOL_RES_PTRCTL, TSOL_MODIFY,
679N/A NULL, 0, client, TSOL_ALL, &(MAJOROP));
679N/A break;
679N/A
679N/A case X_GetKeyboardControl:
679N/A rec->status = xtsol_policy(TSOL_RES_KBDCTL, TSOL_READ,
679N/A NULL, 0, client, TSOL_ALL, &(MAJOROP));
679N/A break;
679N/A case X_ChangeKeyboardControl:
679N/A rec->status = xtsol_policy(TSOL_RES_KBDCTL, TSOL_MODIFY,
679N/A NULL, 0, client, TSOL_ALL, &(MAJOROP));
679N/A break;
679N/A
679N/A case X_GetKeyboardMapping:
679N/A rec->status = xtsol_policy(TSOL_RES_KEYMAP, TSOL_READ,
679N/A NULL, 0, client, TSOL_ALL, &(MAJOROP));
679N/A break;
679N/A
679N/A case X_ChangeKeyboardMapping:
679N/A rec->status = xtsol_policy(TSOL_RES_KEYMAP, TSOL_MODIFY,
679N/A NULL, 0, client, TSOL_ALL, &(MAJOROP));
679N/A break;
679N/A
679N/A case X_GetMotionEvents:
679N/A rec->status = xtsol_policy(TSOL_RES_PTRMOTION, TSOL_READ,
679N/A NULL, 0, client, TSOL_ALL, &(MAJOROP));
679N/A break;
679N/A
679N/A case X_QueryKeymap:
679N/A rec->status = xtsol_policy(TSOL_RES_KEYMAP, TSOL_READ,
679N/A NULL, 0, client, TSOL_ALL, &(MAJOROP));
679N/A break;
679N/A
679N/A case X_SetModifierMapping:
679N/A rec->status = xtsol_policy(TSOL_RES_MODMAP, TSOL_MODIFY,
679N/A NULL, 0, client, TSOL_ALL, &(MAJOROP));
679N/A break;
639N/A
679N/A default:
679N/A#ifndef NO_TSOL_DEBUG_MESSAGES
679N/A tsolinfo = GetClientTsolInfo(client);
679N/A LogMessageVerb(X_NOT_IMPLEMENTED, TSOL_MSG_UNIMPLEMENTED,
679N/A TSOL_LOG_PREFIX
679N/A "policy not implemented for CheckDeviceAccess(%s, %s, %s) = %s\n",
679N/A tsolinfo->pname,
679N/A TsolDixAccessModeNameString(access_mode),
679N/A TsolRequestNameString(reqtype),
679N/A TsolErrorNameString(rec->status));
679N/A#endif /* !NO_TSOL_DEBUG_MESSAGES */
679N/A rec->status = Success;
679N/A break;
679N/A }
679N/A}
679N/A
639N/A
679N/Astatic CALLBACK(
679N/ATsolCheckSelectionAccess)
679N/A{
679N/A XaceSelectionAccessRec *rec = (XaceSelectionAccessRec *) calldata;
679N/A ClientPtr client = rec->client;
679N/A Selection *pSel = *rec->ppSel;
679N/A Atom selAtom = pSel->selection;
679N/A Mask access_mode = rec->access_mode;
679N/A int reqtype;
679N/A TsolSelnPtr tsolseln;
679N/A TsolInfoPtr tsolinfo; /* tsol client info */
679N/A tsolinfo = GetClientTsolInfo(client);
679N/A int polySelection = PolySelection(selAtom);
679N/A
679N/A rec->status = Success;
679N/A
679N/A if (client->requestBuffer) {
679N/A reqtype = MAJOROP; /* protocol */
679N/A } else {
679N/A reqtype = -1;
679N/A }
679N/A
679N/A switch (reqtype) {
679N/A case X_SetSelectionOwner:
679N/A /*
679N/A * Special processing for selection agent. This is how
679N/A * we know who to redirect privileged ConvertSelection requests.
679N/A * This is also used to fake the onwership of GetSelectionOwner requests.
679N/A */
679N/A if (selAtom == tsol_atom_sel_agnt) {
679N/A if (HasWinSelection(tsolinfo)) {
679N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
679N/A auditwrite(AW_USEOFPRIV, 1, PRIV_WIN_SELECTION,
679N/A AW_APPEND, AW_END);
679N/A tsol_sel_agnt = pSel; /* owner of this seln */
679N/A } else {
679N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
679N/A auditwrite(AW_USEOFPRIV, 0, PRIV_WIN_SELECTION,
679N/A AW_APPEND, AW_END);
679N/A client->errorValue = selAtom;
679N/A rec->status = BadAtom;
679N/A return;
679N/A }
639N/A }
639N/A
679N/A /*
679N/A * The callback function is only called if at least one matching selection exists.
679N/A * If it has no tsol attributes then we know it is the only match so we don't need to
679N/A * check for polyinstantiation. Just initialize it and return.
679N/A */
679N/A
679N/A tsolseln = TsolSelectionPriv(pSel);
679N/A
679N/A if (tsolseln->sl == NULL) {
679N/A tsolseln->sl = tsolinfo->sl;
679N/A tsolseln->uid = tsolinfo->uid;
679N/A break;
679N/A }
679N/A
679N/A if (polySelection) {
679N/A
679N/A /* for poly-selections, search from the beginning to see if sl,uid match */
679N/A for (pSel = CurrentSelections; pSel; pSel = pSel->next) {
639N/A
679N/A if (pSel->selection == selAtom) {
679N/A tsolseln = TsolSelectionPriv(pSel);
679N/A if (tsolseln->uid == tsolinfo->uid &&
679N/A tsolseln->sl == tsolinfo->sl)
679N/A break;
679N/A }
679N/A }
679N/A
679N/A if (pSel) {
679N/A /* found a match */
679N/A *rec->ppSel = pSel;
679N/A } else {
679N/A /*
679N/A * Doesn't match yet; we'll get called again
679N/A * After it gets created.
679N/A */
679N/A rec->status = BadMatch;
679N/A }
679N/A } else {
679N/A /* Assign the sl & uid */
679N/A tsolseln->sl = tsolinfo->sl;
679N/A tsolseln->uid = tsolinfo->uid;
639N/A }
679N/A break;
679N/A
679N/A case X_GetSelectionOwner:
679N/A case X_ConvertSelection:
679N/A if (polySelection) {
679N/A
679N/A /* for poly-selections, search from the beginning to see if sl,uid match */
679N/A for (pSel = CurrentSelections; pSel; pSel = pSel->next) {
679N/A
679N/A if (pSel->selection == selAtom) {
679N/A tsolseln = TsolSelectionPriv(pSel);
679N/A if (tsolseln->uid == tsolinfo->uid &&
679N/A tsolseln->sl == tsolinfo->sl)
679N/A break;
679N/A }
679N/A }
614N/A
679N/A if (pSel) {
679N/A *rec->ppSel = pSel; /* found match */
679N/A } else {
679N/A /*
679N/A * Doesn't match yet; we'll get called again
679N/A * After it gets created.
679N/A */
679N/A rec->status = BadMatch;
679N/A return;
679N/A }
679N/A }
679N/A
679N/A /*
679N/A * Selection Agent processing. Override the owner
679N/A */
679N/A tsolseln = TsolSelectionPriv(pSel);
679N/A if (!HasWinSelection(tsolinfo) &&
679N/A (tsolseln->uid != tsolinfo->uid ||
679N/A tsolseln->sl != tsolinfo->sl) &&
679N/A pSel->window != None && tsol_sel_agnt != NULL) {
679N/A pSel = tsol_sel_agnt;
679N/A } else {
679N/A if (HasWinSelection(tsolinfo) &&
679N/A (tsolinfo->flags & TSOL_AUDITEVENT)) {
679N/A auditwrite(AW_USEOFPRIV, 1, PRIV_WIN_SELECTION, AW_APPEND, AW_END);
679N/A }
679N/A }
679N/A *rec->ppSel = pSel;
679N/A break;
679N/A
679N/A default:
639N/A#ifndef NO_TSOL_DEBUG_MESSAGES
679N/A tsolinfo = GetClientTsolInfo(client);
679N/A LogMessageVerb(X_NOT_IMPLEMENTED, TSOL_MSG_UNIMPLEMENTED,
679N/A TSOL_LOG_PREFIX
679N/A "policy not implemented for CheckSelectionAccess(%s, %s, %s, %s) = %s\n",
679N/A tsolinfo->pname,
679N/A TsolDixAccessModeNameString(access_mode),
679N/A TsolRequestNameString(reqtype),
679N/A NameForAtom(selAtom),
679N/A TsolErrorNameString(rec->status));
639N/A#endif /* !NO_TSOL_DEBUG_MESSAGES */
679N/A break;
679N/A }
614N/A}
614N/A
606N/Astatic CALLBACK(
679N/ATsolCheckPropertyAccess)
0N/A{
606N/A XacePropertyAccessRec *rec = (XacePropertyAccessRec *) calldata;
606N/A ClientPtr client = rec->client;
606N/A WindowPtr pWin = rec->pWin;
606N/A PropertyPtr pProp = *rec->ppProp;
606N/A Atom propertyName = pProp->propertyName;
606N/A Mask access_mode = rec->access_mode;
679N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
679N/A int reqtype;
679N/A TsolPropPtr tsolprop;
679N/A TsolResPtr tsolres;
679N/A int tsol_method;
679N/A Status retcode;
0N/A
679N/A
679N/A if (client->requestBuffer) {
679N/A reqtype = MAJOROP; /* protocol */
679N/A } else {
679N/A reqtype = -1;
679N/A }
679N/A
679N/A if (pProp != NULL) {
679N/A int polyprop = PolyProperty(propertyName, pWin);
679N/A
679N/A tsolprop = TsolPropertyPriv(pProp);
679N/A
679N/A if (!polyprop) {
679N/A
679N/A tsolres = TsolWindowPriv(pWin);
679N/A if (tsolprop->sl == NULL) {
679N/A /* Initialize with label/uid etc */
679N/A if (WindowIsRoot(pWin)) {
679N/A tsolprop->sl = tsolinfo->sl; /* use client's sl/uid */
679N/A tsolprop->uid = tsolinfo->uid;
679N/A tsolprop->pid = tsolinfo->pid;
679N/A } else {
679N/A tsolprop->sl = tsolres->sl; /* use window's sl/uid */
679N/A tsolprop->uid = tsolres->uid;
679N/A tsolprop->pid = tsolres->pid;
679N/A }
679N/A }
679N/A
679N/A if (access_mode & (DixReadAccess | DixGetAttrAccess))
679N/A tsol_method = TSOL_READ;
679N/A else
679N/A tsol_method = TSOL_MODIFY;
679N/A
679N/A retcode = xtsol_policy(TSOL_RES_PROPERTY, tsol_method, pProp, 0,
679N/A client, TSOL_ALL, &reqtype);
679N/A if (retcode != Success && (access_mode & DixGetAttrAccess)) {
679N/A /* If current property is not accessible, move on to
679N/A * next one for ListProperty
679N/A */
679N/A retcode = Success;
679N/A *rec->ppProp = pProp->next; /* ignore failurefor List Prop */
679N/A }
679N/A rec->status = retcode;
679N/A } else {
679N/A /* Handle polyinstantiated property */
679N/A if (tsolprop->sl == NULL) { /* New PolyProp */
679N/A if (!(access_mode & DixCreateAccess)) {
679N/A rec->status = BadImplementation;
679N/A return;
679N/A }
679N/A /* Initialize with label/uid */
679N/A tsolprop->sl = tsolinfo->sl;
679N/A tsolprop->uid = tsolinfo->uid;
679N/A tsolprop->next = (TsolPropPtr)NULL;
679N/A rec->status = Success;
679N/A } else {
679N/A /* search for a matching (sl, uid) pair */
679N/A while (pProp) {
679N/A tsolprop = TsolPropertyPriv(pProp);
679N/A if (pProp->propertyName == propertyName &&
679N/A tsolprop->sl == tsolinfo->sl &&
679N/A tsolprop->uid == tsolinfo->uid)
679N/A break; /* match found */
679N/A pProp = pProp->next;
679N/A }
679N/A
679N/A if (pProp) {
679N/A *rec->ppProp = pProp; /* found */
679N/A rec->status = Success;
679N/A } else {
679N/A rec->status = BadMatch;
679N/A }
679N/A }
679N/A }
679N/A#ifndef NO_TSOL_DEBUG_MESSAGES
679N/A LogMessageVerb(X_INFO, TSOL_MSG_ACCESS_TRACE,
679N/A TSOL_LOG_PREFIX
679N/A "TsolCheckPropertyAccess(%s, 0x%x, %s, %s) = %s\n",
679N/A tsolinfo->pname, pWin->drawable.id,
679N/A NameForAtom(propertyName),
679N/A TsolDixAccessModeNameString(access_mode),
679N/A TsolPolicyReturnString(rec->status));
679N/A#endif /* !NO_TSOL_DEBUG_MESSAGES */
606N/A }
0N/A}
0N/A
606N/Astatic CALLBACK(
606N/ATsolCheckExtensionAccess)
606N/A{
606N/A XaceExtAccessRec *rec = (XaceExtAccessRec *) calldata;
606N/A
606N/A if (TsolDisabledExtension(rec->ext->name)) {
606N/A rec->status = BadAccess;
606N/A }
606N/A}
606N/A
606N/A#ifdef UNUSED
0N/A/*
0N/A * Return TRUE if host is cipso
0N/A */
0N/Aint
0N/Ahost_is_cipso(int fd)
0N/A{
0N/A struct sockaddr sname;
0N/A socklen_t namelen;
0N/A char *rhost;
606N/A tsol_host_type_t host_type;
0N/A struct sockaddr_in *so = (struct sockaddr_in *)&sname;
0N/A extern tsol_host_type_t tsol_getrhtype(char *);
0N/A
0N/A namelen = sizeof (sname);
0N/A if (getpeername(fd, &sname, &namelen) == -1) {
0N/A perror("getsockname: failed\n");
0N/A return FALSE;
0N/A }
0N/A
0N/A rhost = inet_ntoa(so->sin_addr);
0N/A host_type = tsol_getrhtype(rhost);
0N/A if (host_type == SUN_CIPSO) {
0N/A return TRUE;
0N/A }
0N/A
0N/A return FALSE;
0N/A}
606N/A#endif