tsolextension.c revision 1088
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 */
0N/A
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
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
851N/A#include <X11/extensions/secur.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
73N/Aint tsolMultiLevel = TRUE;
799N/Aint tsol_mac_enabled;
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
1088N/A/*
1088N/A * Key to lookup devPrivate data in various structures
1088N/A */
1088N/ADevPrivateKeyRec tsolClientPrivateKeyRec;
1088N/ADevPrivateKeyRec tsolPixmapPrivateKeyRec;
1088N/ADevPrivateKeyRec tsolWindowPrivateKeyRec;
1088N/ADevPrivateKeyRec tsolPropertyPrivateKeyRec;
1088N/ADevPrivateKeyRec tsolSelectionPrivateKeyRec;
1088N/ADevPrivateKeyRec tsolDevicePrivateKeyRec;
1088N/A
1088N/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(TsolCheckSelectionAccess);
606N/Astatic CALLBACK(TsolProcessKeyboard);
799N/ACALLBACK(TsolCheckDeviceAccess);
799N/ACALLBACK(TsolCheckServerAccess);
799N/ACALLBACK(TsolCheckClientAccess);
606N/A
606N/A/* other callbacks */
606N/Astatic CALLBACK(TsolClientStateCallback);
679N/Astatic CALLBACK(TsolSelectionCallback);
0N/A
1088N/Aextern int tsol_check_policy(TsolInfoPtr tsolinfo, TsolResPtr tsolres,
799N/A xpolicy_t flags, int reqcode);
1088N/Aextern void TsolCheckDrawableAccess(CallbackListPtr *pcbl, pointer nulldata,
799N/A pointer calldata);
1088N/Aextern void TsolCheckXIDAccess(CallbackListPtr *pcbl, pointer nulldata,
799N/A pointer calldata);
799N/Aextern Bool client_has_privilege(TsolInfoPtr tsolinfo, priv_set_t *priv);
799N/A
799N/Aextern priv_set_t *pset_win_mac_write;
799N/Aextern priv_set_t *pset_win_dac_write;
799N/Aextern priv_set_t *pset_win_config;
196N/A
877N/Aextern RESTYPE RREventType;
877N/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
1088N/A /* MAC/Label support is available only if labeld svc is enabled */
799N/A if (is_system_labeled()) {
799N/A tsol_mac_enabled = TRUE;
799N/A } else {
799N/A /* DAC support can be added in future */
799N/A tsol_mac_enabled = FALSE;
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 */
1088N/A if (!dixRegisterPrivateKey(tsolClientPrivateKey, PRIVATE_CLIENT,
1088N/A sizeof (TsolInfoRec))) {
1088N/A ErrorF("TsolExtensionInit: Cannot allocate client private.\n");
1088N/A return;
1088N/A }
1088N/A
1088N/A if (!dixRegisterPrivateKey(tsolPixmapPrivateKey, PRIVATE_PIXMAP,
1088N/A sizeof (TsolResRec))) {
1088N/A ErrorF("TsolExtensionInit: Cannot allocate pixmap private.\n");
1088N/A return;
1088N/A }
1088N/A
1088N/A if (!dixRegisterPrivateKey(tsolWindowPrivateKey, PRIVATE_WINDOW,
1088N/A sizeof (TsolResRec))) {
1088N/A ErrorF("TsolExtensionInit: Cannot allocate window private.\n");
1088N/A return;
1088N/A }
1088N/A
1088N/A if (!dixRegisterPrivateKey(tsolPropertyPrivateKey, PRIVATE_PROPERTY,
1088N/A sizeof (TsolResRec))) {
1088N/A ErrorF("TsolExtensionInit: Cannot allocate property private.\n");
1088N/A return;
1088N/A }
1088N/A
1088N/A if (!dixRegisterPrivateKey(tsolSelectionPrivateKey, PRIVATE_SELECTION,
1088N/A sizeof (TsolResRec))) {
1088N/A ErrorF("TsolExtensionInit: Cannot allocate selection private.\n");
1088N/A return;
1088N/A }
1088N/A
1088N/A if (!dixRegisterPrivateKey(tsolDevicePrivateKey, PRIVATE_DEVICE,
1088N/A sizeof (HotKeyRec))) {
1088N/A ErrorF("TsolExtensionInit: Cannot allocate device private.\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();
1088N/A snprintf(tsolinfo->pname, MAXNAME,
1088N/A "client id %d (pid %d)",
1088N/A serverClient->index, tsolinfo->pid);
679N/A }
679N/A }
679N/A
0N/A LoadTsolConfig();
0N/A
0N/A MakeTSOLAtoms();
799N/A UpdateTsolNode(0, NULL);
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;
606N/A pSecHook = &tsolSecHook;
606N/A
712N/A XaceRegisterCallback(XACE_EXT_DISPATCH, TsolCheckExtensionAccess, NULL);
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);
799N/A XaceRegisterCallback(XACE_SCREEN_ACCESS, TsolCheckDeviceAccess, NULL);
799N/A XaceRegisterCallback(XACE_SCREENSAVER_ACCESS, TsolCheckDeviceAccess, NULL);
679N/A XaceRegisterCallback(XACE_SELECTION_ACCESS, TsolCheckSelectionAccess, NULL);
799N/A XaceRegisterCallback(XACE_SERVER_ACCESS, TsolCheckServerAccess, NULL);
799N/A XaceRegisterCallback(XACE_CLIENT_ACCESS, TsolCheckClientAccess, 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 ProcVector[X_InternAtom] = ProcTsolInternAtom;
799N/A ProcVector[X_GetAtomName] = ProcTsolGetAtomName;
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_GrabServer] = ProcTsolGrabServer;
0N/A ProcVector[X_UngrabServer] = ProcTsolUngrabServer;
799N/A ProcVector[X_GetImage] = ProcTsolGetImage;
0N/A ProcVector[X_QueryTree] = ProcTsolQueryTree;
0N/A ProcVector[X_QueryPointer] = ProcTsolQueryPointer;
799N/A ProcVector[X_GetGeometry] = ProcTsolGetGeometry;
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{
799N/A XaceResourceAccessRec *rec = calldata;
799N/A RESTYPE rtype = rec->rtype;
679N/A
799N/A switch (rtype) {
799N/A case RT_WINDOW:
1088N/A case RT_PIXMAP:
799N/A /* Drawables policy */
799N/A TsolCheckDrawableAccess(pcbl, nulldata, calldata);
0N/A break;
0N/A
799N/A case RT_GC:
799N/A case RT_CURSOR:
799N/A case RT_FONT:
799N/A TsolCheckXIDAccess(pcbl, nulldata, calldata);
799N/A break;
877N/A default:
1088N/A /*
877N/A * Handle other resource types.
1088N/A * In RANDR extension, usual window policy is
877N/A * enforced before checking for RREventType.
877N/A */
877N/A if (rtype == RREventType) {
877N/A rec->status = Success;
877N/A }
877N/A break;
799N/A }
0N/A}
0N/A
606N/Astatic
679N/ACALLBACK(TsolSelectionCallback)
679N/A{
679N/A SelectionInfoRec *pselinfo = (SelectionInfoRec *)calldata;
679N/A Selection *pSel = pselinfo->selection;
1088N/A TsolResPtr tsolseln = TsolSelectionPrivate(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:
1088N/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;
799N/A TsolInfoPtr tsolinfo = TsolClientPrivate(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
799N/A
0N/Astatic void
606N/ATsolReset(ExtensionEntry *extension)
0N/A{
606N/A free_win_privsets();
712N/A XaceDeleteCallback(XACE_EXT_DISPATCH, TsolCheckExtensionAccess, NULL);
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);
799N/A XaceDeleteCallback(XACE_SCREEN_ACCESS, TsolCheckDeviceAccess, NULL);
799N/A XaceDeleteCallback(XACE_SCREENSAVER_ACCESS, TsolCheckDeviceAccess, NULL);
679N/A XaceDeleteCallback(XACE_SELECTION_ACCESS, TsolCheckSelectionAccess, NULL);
799N/A XaceDeleteCallback(XACE_SERVER_ACCESS, TsolCheckServerAccess, NULL);
799N/A XaceDeleteCallback(XACE_CLIENT_ACCESS, TsolCheckClientAccess, 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{
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A bslabel_t *sl;
799N/A extern priv_set_t *pset_win_mac_write;
0N/A
0N/A REQUEST(xSetPolyInstInfoReq);
0N/A REQUEST_AT_LEAST_SIZE(xSetPolyInstInfoReq);
0N/A
799N/A /* Requires win_mac_write privilege */
799N/A if (!client_has_privilege(tsolinfo, pset_win_mac_write)) {
799N/A return (BadAccess);
0N/A }
799N/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{
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A bslabel_t *sl;
0N/A WindowPtr pWin;
799N/A TsolResPtr tsolprop;
0N/A PropertyPtr pProp;
679N/A int rc;
606N/A
0N/A REQUEST(xSetPropLabelReq);
0N/A
0N/A REQUEST_AT_LEAST_SIZE(xSetPropLabelReq);
0N/A
0N/A
799N/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 {
0N/A client->errorValue = stuff->id;
0N/A return (BadWindow);
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
799N/A /* Requires win_mac_write privilege */
799N/A if (!client_has_privilege(tsolinfo, pset_win_mac_write)) {
799N/A return (BadAccess);
799N/A }
799N/A
168N/A /* Initialize property created internally by server */
1088N/A tsolprop = TsolPropertyPrivate(pProp);
0N/A
0N/A sl = (bslabel_t *)(stuff + 1);
0N/A
799N/A if (!blequal(tsolprop->sl, sl)) {
799N/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{
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A WindowPtr pWin;
799N/A TsolResPtr tsolprop;
0N/A PropertyPtr pProp;
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 }
799N/A
799N/A /* Requires win_mac_write privilege */
799N/A if (!client_has_privilege(tsolinfo, pset_win_mac_write)) {
799N/A return (BadAccess);
0N/A }
799N/A
168N/A /* Initialize property created internally by server */
1088N/A tsolprop = TsolPropertyPrivate(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{
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A bslabel_t *sl;
0N/A PixmapPtr pMap;
0N/A WindowPtr pWin;
0N/A xEvent message;
0N/A TsolResPtr tsolres;
679N/A int rc;
606N/A
0N/A REQUEST(xSetResLabelReq);
0N/A
0N/A REQUEST_AT_LEAST_SIZE(xSetResLabelReq);
0N/A
799N/A /* Requires win_mac_write privilege */
799N/A if (!client_has_privilege(tsolinfo, pset_win_mac_write)) {
799N/A return (BadAccess);
799N/A }
799N/A
0N/A sl = (bslabel_t *)(stuff + 1);
799N/A switch (stuff->resourceType) {
0N/A case SESSIONHI: /* set server session HI */
0N/A memcpy(&SessionHI, sl, SL_SIZE);
0N/A return (client->noClientException);
799N/A
0N/A case SESSIONLO: /* set server session LO */
0N/A memcpy(&SessionLO, sl, SL_SIZE);
0N/A return (client->noClientException);
799N/A
0N/A case IsWindow:
679N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixWriteAccess);
1088N/A if (rc != Success)
679N/A return rc;
679N/A
0N/A if (pWin)
0N/A {
1088N/A tsolres = TsolWindowPrivate(pWin);
0N/A }
0N/A else
0N/A {
0N/A client->errorValue = stuff->id;
0N/A return (BadWindow);
0N/A }
0N/A break;
799N/A
0N/A case IsPixmap:
851N/A rc = dixLookupDrawable((DrawablePtr *)&pMap, stuff->id, client,
851N/A M_DRAWABLE_PIXMAP, DixWriteAccess);
1088N/A if (rc != Success)
679N/A return rc;
0N/A if (pMap)
0N/A {
1088N/A tsolres = TsolPixmapPrivate(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
799N/A if (!blequal(tsolres->sl, sl)) {
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;
705N/A DeliverEventsToWindow(PickPointer(client), pWin, &message, 1,
851N/A SubstructureRedirectMask, NullGrab);
0N/A
0N/A }
0N/A return (client->noClientException);
0N/A}
0N/A
0N/Astatic int
0N/AProcSetResUID(ClientPtr client)
0N/A{
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A int ScreenNumber;
0N/A PixmapPtr pMap;
0N/A WindowPtr pWin;
0N/A TsolResPtr tsolres;
679N/A int rc;
799N/A extern priv_set_t *pset_win_dac_write;
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:
799N/A if (!HasTrustedPath(tsolinfo))
799N/A return (BadAccess);
0N/A StripeHeight = stuff->uid;
0N/A ScreenNumber = stuff->id;
0N/A
799N/A /* set Screen Stripe Size */
799N/A DoScreenStripeHeight(ScreenNumber);
799N/A ScreenStripeHeight [ScreenNumber] = StripeHeight;
799N/A return (client->noClientException);
0N/A
0N/A case RES_OUID:
799N/A if (!HasTrustedPath(tsolinfo))
799N/A return (BadAccess);
799N/A
0N/A OwnerUID = stuff->uid;
0N/A OwnerUIDint = OwnerUID;
0N/A AddUID(&OwnerUIDint);
0N/A return (client->noClientException);
799N/A
0N/A case IsWindow:
679N/A rc = dixLookupWindow(&pWin, stuff->id, client, DixWriteAccess);
1088N/A if (rc != Success)
679N/A return rc;
679N/A
0N/A if (pWin)
0N/A {
1088N/A tsolres = TsolWindowPrivate(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:
851N/A rc = dixLookupDrawable((DrawablePtr *)&pMap, stuff->id, client,
851N/A M_DRAWABLE_PIXMAP, DixWriteAccess);
851N/A if (rc != Success)
679N/A return rc;
679N/A
0N/A if (pMap)
0N/A {
1088N/A tsolres = TsolPixmapPrivate(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
799N/A /* Requires win_dac_write privilege */
799N/A if (!client_has_privilege(tsolinfo, pset_win_dac_write)) {
799N/A return (BadAccess);
0N/A }
799N/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;
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 }
799N/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 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 }
799N/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 */
1088N/A sl = malloc(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 }
1088N/A free(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;
799N/A TsolResPtr 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 {
1088N/A tsolprop = TsolPropertyPrivate(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 */
1088N/A tsolres = TsolWindowPrivate(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 */
1088N/A sl = malloc(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 }
1088N/A free(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
1088N/A tsolres = TsolWindowPrivate(pWin);
0N/A }
679N/A
606N/A if (stuff->resourceType == IsPixmap &&
0N/A (stuff->mask & (RES_UID | RES_SL )))
0N/A {
851N/A rc = dixLookupDrawable((DrawablePtr *)&pMap, stuff->id, client,
851N/A M_DRAWABLE_PIXMAP, DixWriteAccess);
679N/A if (rc != Success)
679N/A return rc;
679N/A
1088N/A tsolres = TsolPixmapPrivate(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 */
1088N/A sl = malloc(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 }
1088N/A free(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;
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
1088N/A rc = dixLookupResourceByType((pointer *) &panres, stuff->id,
1088N/A XRT_WINDOW, client, DixWriteAccess);
1088N/A if (rc != Success)
1088N/A return rc;
470N/A
470N/A FOR_NSCREENS_BACKWARD(j)
470N/A {
1088N/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 }
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 }
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 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 }
606N/A tsolinfo = GetClientTsolInfo(client);
799N/A
799N/A if (!HasTrustedPath(tsolinfo))
799N/A return (BadAccess);
799N/A
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 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 }
799N/A
606N/A tsolinfo = GetClientTsolInfo(client);
799N/A if (!HasTrustedPath(tsolinfo))
799N/A return (BadAccess);
799N/A
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;
705N/A DeviceIntPtr keybd = PickKeyboard(client);
705N/A GrabPtr kbdgrab = keybd->deviceGrab.grab;
705N/A DeviceIntPtr mouse = PickPointer(client);
705N/A GrabPtr ptrgrab = mouse->deviceGrab.grab;
0N/A
0N/A if (kbdgrab) {
1088N/A grabclient = clients[CLIENT_ID(kbdgrab->resource)];
0N/A if (client->index != grabclient->index)
705N/A (*keybd->deviceGrab.DeactivateGrab)(keybd);
0N/A }
0N/A
0N/A if (ptrgrab) {
1088N/A grabclient = clients[CLIENT_ID(ptrgrab->resource)];
0N/A if (client->index != grabclient->index)
705N/A (*mouse->deviceGrab.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
799N/A TsolInfoPtr tsolinfo = TsolClientPrivate(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
1088N/A temp_inmsg = malloc(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
1088N/A if ((r.rq_clntcred = malloc(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:
1088N/A free(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;
1088N/A uint_t 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 */
1088N/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;
1088N/A ushort_t 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; */
851N/A HotKeyPtr hotkey = TsolKeyboardPrivate(keybd);
606N/A
0N/A if (xE->u.u.type == KeyPress)
0N/A {
851N/A if (!hotkey->initialized)
851N/A InitHotKey(keybd);
0N/A
851N/A if (((xE->u.u.detail == hotkey->key) &&
851N/A (xE->u.keyButtonPointer.state != 0 &&
851N/A xE->u.keyButtonPointer.state == hotkey->shift)) ||
851N/A ((xE->u.u.detail == hotkey->altkey) &&
851N/A (xE->u.keyButtonPointer.state != 0 &&
851N/A xE->u.keyButtonPointer.state == hotkey->altshift)))
851N/A {
851N/A HandleHotKey(keybd);
851N/A }
0N/A }
0N/A}
0N/A
679N/Astatic CALLBACK(
679N/ATsolCheckSendAccess)
614N/A{
799N/A XaceSendAccessRec *rec = (XaceSendAccessRec *) calldata;
799N/A ClientPtr client = rec->client;
799N/A WindowPtr pWin = rec->pWin;
799N/A TsolResPtr tsolres;
799N/A xpolicy_t flags;
799N/A TsolInfoPtr tsolinfo;
799N/A
799N/A rec->status = BadAccess;
799N/A if (client == NULL) {
799N/A rec->status = Success;
799N/A return;
799N/A }
679N/A
799N/A if (WindowIsRoot(pWin) || XTSOLTrusted(pWin)) {
799N/A rec->status = Success;
799N/A return;
799N/A }
799N/A
799N/A tsolinfo = GetClientTsolInfo(client);
1088N/A tsolres = TsolWindowPrivate(pWin);
799N/A flags = (TSOL_MAC|TSOL_DAC|TSOL_DOMINATE|TSOL_READOP);
799N/A rec->status = tsol_check_policy(tsolinfo, tsolres, flags, MAJOROP_CODE);
799N/A
799N/A#ifndef NO_TSOL_DEBUG_MESSAGES
799N/A if (rec->status != Success) {
799N/A tsolinfo = GetClientTsolInfo(client);
799N/A LogMessageVerb(X_ERROR, TSOL_MSG_ERROR,
799N/A TSOL_LOG_PREFIX
799N/A "TsolCheckSendAccess(%s, %s) = %s\n",
799N/A tsolinfo->pname,
799N/A TsolRequestNameString(MAJOROP_CODE),
799N/A TsolErrorNameString(rec->status));
679N/A }
679N/A
799N/A#endif /* !NO_TSOL_DEBUG_MESSAGES */
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/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;
799N/A TsolResPtr tsolseln;
679N/A TsolInfoPtr tsolinfo; /* tsol client info */
679N/A tsolinfo = GetClientTsolInfo(client);
679N/A int polySelection = PolySelection(selAtom);
679N/A
799N/A reqtype = MAJOROP_CODE;
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
1088N/A tsolseln = TsolSelectionPrivate(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) {
1088N/A tsolseln = TsolSelectionPrivate(pSel);
679N/A if (tsolseln->uid == tsolinfo->uid &&
679N/A tsolseln->sl == tsolinfo->sl)
679N/A break;
679N/A }
1088N/A }
679N/A
679N/A if (pSel) {
679N/A /* found a match */
1088N/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) {
1088N/A tsolseln = TsolSelectionPrivate(pSel);
679N/A if (tsolseln->uid == tsolinfo->uid &&
679N/A tsolseln->sl == tsolinfo->sl)
679N/A break;
679N/A }
1088N/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 */
1088N/A tsolseln = TsolSelectionPrivate(pSel);
679N/A if (!HasWinSelection(tsolinfo) &&
679N/A (tsolseln->uid != tsolinfo->uid ||
1088N/A tsolseln->sl != tsolinfo->sl) &&
679N/A pSel->window != None && tsol_sel_agnt != NULL) {
679N/A pSel = tsol_sel_agnt;
679N/A } else {
1088N/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;
799N/A TsolResPtr tsolprop;
679N/A TsolResPtr tsolres;
679N/A Status retcode;
799N/A xpolicy_t flags = 0;
679N/A
799N/A reqtype = MAJOROP_CODE;
1088N/A tsolres = TsolWindowPrivate(pWin);
679N/A if (pProp != NULL) {
679N/A int polyprop = PolyProperty(propertyName, pWin);
679N/A
1088N/A tsolprop = TsolPropertyPrivate(pProp);
679N/A
679N/A if (!polyprop) {
679N/A
1088N/A tsolres = TsolWindowPrivate(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))
799N/A flags = (TSOL_MAC|TSOL_DAC|TSOL_DOMINATE|TSOL_READOP);
679N/A
799N/A if (access_mode & (DixWriteAccess | DixSetAttrAccess))
799N/A flags = (TSOL_MAC|TSOL_DAC|TSOL_WRITEOP);
799N/A
799N/A retcode = tsol_check_policy(tsolinfo, tsolprop, flags, MAJOROP_CODE);
679N/A if (retcode != Success && (access_mode & DixGetAttrAccess)) {
1088N/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 rec->status = Success;
679N/A } else {
679N/A /* search for a matching (sl, uid) pair */
679N/A while (pProp) {
1088N/A tsolprop = TsolPropertyPrivate(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;
1088N/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;
712N/A } else {
712N/A rec->status = Success;
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