1088N/A/*
1379N/A * Copyright (c) 2004, 2014, 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
606N/A#ifdef HAVE_DIX_CONFIG_H
606N/A#include <dix-config.h>
606N/A#endif
98N/A
606N/A#include <X11/X.h>
0N/A#include <stdio.h>
36N/A#include <sys/types.h>
36N/A#include <unistd.h>
196N/A#include "auditwrite.h"
0N/A#include <bsm/audit_kevents.h>
0N/A#include <bsm/audit_uevents.h>
98N/A#include <X11/Xproto.h>
606N/A#include "dix.h"
0N/A#include "misc.h"
0N/A#include "scrnintstr.h"
0N/A#include "os.h"
0N/A#include "regionstr.h"
0N/A#include "validate.h"
0N/A#include "windowstr.h"
0N/A#include "propertyst.h"
0N/A#include "input.h"
0N/A#include "inputstr.h"
0N/A#include "resource.h"
0N/A#include "colormapst.h"
0N/A#include "cursorstr.h"
0N/A#include "dixstruct.h"
0N/A#include "selection.h"
0N/A#include "gcstruct.h"
0N/A#include "servermd.h"
0N/A#include <syslog.h>
470N/A#include "extnsionst.h"
606N/A#include "registry.h"
799N/A#include "xace.h"
799N/A#include "xacestr.h"
470N/A#ifdef PANORAMIX
470N/A#include "../Xext/panoramiXsrv.h"
470N/A#endif
606N/A#include "tsol.h"
0N/A#include "tsolinfo.h"
0N/A#include "tsolpolicy.h"
0N/A
799N/Apriv_set_t *pset_win_mac_write = NULL;
799N/Apriv_set_t *pset_win_dac_write = NULL;
799N/Apriv_set_t *pset_win_config = NULL;
799N/A
36N/Astatic priv_set_t *pset_win_mac_read = NULL;
36N/Astatic priv_set_t *pset_win_dac_read = NULL;
36N/Astatic priv_set_t *pset_win_devices = NULL;
36N/Astatic priv_set_t *pset_win_fontpath = NULL;
36N/Astatic priv_set_t *pset_win_colormap = NULL;
36N/Astatic priv_set_t *pset_win_upgrade_sl = NULL;
36N/Astatic priv_set_t *pset_win_downgrade_sl = NULL;
36N/Astatic priv_set_t *pset_win_selection = NULL;
36N/A
0N/A#define SAMECLIENT(client, xid) ((client)->index == CLIENT_ID(xid))
0N/A
639N/A/* Unless NO_TSOL_DEBUG_MESSAGES is defined, admins will be able to enable
639N/A debugging messages at runtime via Xorg -logverbose */
639N/A#ifndef NO_TSOL_DEBUG_MESSAGES
633N/Astatic char *xsltos(bslabel_t *sl);
633N/A
639N/A#endif /* NO_TSOL_DEBUG_MESSAGES */
0N/A
799N/Aextern int tsol_mac_enabled;
0N/A
0N/Astatic void
0N/Aset_audit_flags(TsolInfoPtr tsolinfo)
0N/A{
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
0N/A if (!(tsolinfo->flags & TSOL_DOXAUDIT))
0N/A tsolinfo->flags |= TSOL_DOXAUDIT;
606N/A
0N/A}
0N/A
0N/Astatic void
0N/Aunset_audit_flags(TsolInfoPtr tsolinfo)
0N/A{
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A tsolinfo->flags &= ~TSOL_AUDITEVENT;
0N/A if (tsolinfo->flags & TSOL_DOXAUDIT)
0N/A tsolinfo->flags &= ~TSOL_DOXAUDIT;
606N/A
0N/A}
0N/A/*
1088N/A * returns
799N/A * TRUE - if client/subject has the required privilege
799N/A * FALSE - otherwise
0N/A */
0N/A
799N/ABool
799N/Aclient_has_privilege(TsolInfoPtr tsolinfo, priv_set_t *priv)
0N/A{
0N/A
799N/A if (tsolinfo->privs == NULL) {
799N/A return TRUE; /* server itself */
0N/A }
799N/A
799N/A if (priv_issubset(priv, tsolinfo->privs)) {
799N/A if (tsolinfo->flags & TSOL_AUDITEVENT) {
1088N/A auditwrite(AW_USEOFPRIV, AUDIT_SUCCESS, priv,
799N/A AW_APPEND, AW_END);
0N/A }
799N/A
799N/A return TRUE;
799N/A } else
799N/A return FALSE;
799N/A}
799N/A
799N/Aint
1088N/Atsol_check_policy(TsolInfoPtr tsolinfo, TsolResPtr tsolres,
1088N/A xpolicy_t flags, int reqcode)
799N/A{
799N/A int status = BadAccess;
799N/A
799N/A /* Check for Trusted Path (TP) */
799N/A if (flags & TSOL_TP) {
799N/A if (HasTrustedPath(tsolinfo)) {
799N/A status = Success;
799N/A } else {
799N/A goto bad;
0N/A }
0N/A }
0N/A
799N/A /* Check for Mandatory Access Control (MAC) */
799N/A if (tsol_mac_enabled & flags & TSOL_MAC) {
799N/A if (flags & TSOL_READOP) {
799N/A if (blequal(tsolinfo->sl, tsolres->sl) ||
799N/A (blequal(tsolres->sl, &PublicObjSL) &&
1088N/A reqcode != X_GetImage) ||
1088N/A ((flags & TSOL_DOMINATE) &&
799N/A bldominates(tsolinfo->sl, tsolres->sl)) ||
799N/A client_has_privilege(tsolinfo, pset_win_mac_read) ||
799N/A HasTrustedPath(tsolinfo)) {
799N/A
799N/A status = Success;
799N/A } else {
799N/A goto bad;
0N/A }
0N/A }
1088N/A
799N/A if (flags & TSOL_WRITEOP) {
799N/A if (blequal(tsolinfo->sl, tsolres->sl) ||
799N/A client_has_privilege(tsolinfo, pset_win_mac_write)) {
799N/A status = Success;
799N/A } else {
799N/A goto bad;
0N/A }
0N/A }
0N/A }
0N/A
799N/A /* Check for Discretionary Access Control (DAC) */
799N/A if (flags & TSOL_DAC) {
799N/A if (flags & TSOL_READOP) {
799N/A if ((tsolinfo->uid == tsolres->uid) ||
799N/A tsolres->internal ||
1088N/A ((tsolres->uid == OwnerUID) &&
799N/A /* ((tsolres->uid == OwnerUID || tsolres->uid == DEF_UID) && */
1088N/A blequal(tsolres->sl, &PublicObjSL)) ||
799N/A client_has_privilege(tsolinfo, pset_win_dac_read)) {
470N/A
799N/A status = Success;
799N/A } else {
799N/A goto bad;
0N/A }
0N/A }
0N/A
799N/A if (flags & TSOL_WRITEOP) {
799N/A if ((tsolinfo->uid == tsolres->uid) ||
864N/A (tsolinfo->uid == OwnerUID &&
864N/A reqcode == X_ChangeWindowAttributes) ||
799N/A client_has_privilege(tsolinfo, pset_win_dac_write)) {
606N/A
799N/A status = Success;
799N/A } else {
799N/A goto bad;
0N/A }
0N/A }
0N/A }
0N/A
799N/A return Success;
0N/A
799N/Abad:
799N/A /* Access denied */
1209N/A LogMessageVerb(X_WARNING, TSOL_MSG_WARNING,
799N/A TSOL_LOG_PREFIX
799N/A "tsol_check_policy(%s, %s, %d, pid=%d, %s, %d, %s) = %s\n",
1088N/A tsolinfo->pname, xsltos(tsolinfo->sl), tsolinfo->uid,
1088N/A tsolres->pid, xsltos(tsolres->sl), tsolres->uid,
799N/A TsolRequestNameString(reqcode),
799N/A "BadAccess");
0N/A
799N/A return BadAccess;
0N/A}
0N/A
0N/A
639N/A#ifndef NO_TSOL_DEBUG_MESSAGES
0N/A/*
0N/A * Converts SL to string
0N/A */
633N/Astatic char *
0N/Axsltos(bslabel_t *sl)
0N/A{
0N/A char *slstring = NULL;
0N/A
606N/A if (bsltos(sl, &slstring, 0,
0N/A VIEW_INTERNAL|SHORT_CLASSIFICATION | LONG_WORDS | ALL_ENTRIES) <= 0)
0N/A return (NULL);
0N/A else
0N/A return slstring;
0N/A}
639N/A#endif /* !NO_TSOL_DEBUG_MESSAGES */
0N/A
36N/A
36N/A/*
36N/A * Allocate a single privilege set
36N/A */
36N/Astatic priv_set_t *
36N/Aalloc_win_priv(const char *priv)
36N/A{
36N/A priv_set_t *pset;
36N/A
36N/A if ((pset = priv_allocset()) == NULL) {
36N/A perror("priv_allocset");
36N/A FatalError("Cannot allocate privilege set");
36N/A }
36N/A priv_emptyset(pset);
36N/A priv_addset(pset, priv);
36N/A
36N/A return pset;
36N/A}
36N/A
36N/A/*
36N/A * Initialize all string window privileges to the binary equivalent.
36N/A * Binary privilege testing is much faster than the string testing
36N/A */
36N/Avoid
606N/Ainit_win_privsets(void)
36N/A{
36N/A
36N/A pset_win_mac_read = alloc_win_priv(PRIV_WIN_MAC_READ);
36N/A pset_win_mac_write = alloc_win_priv(PRIV_WIN_MAC_WRITE);
36N/A pset_win_dac_read = alloc_win_priv(PRIV_WIN_DAC_READ);
36N/A pset_win_dac_write = alloc_win_priv(PRIV_WIN_DAC_WRITE);
36N/A pset_win_config = alloc_win_priv(PRIV_WIN_CONFIG);
36N/A pset_win_devices = alloc_win_priv(PRIV_WIN_DEVICES);
36N/A pset_win_fontpath = alloc_win_priv(PRIV_WIN_FONTPATH);
36N/A pset_win_colormap = alloc_win_priv(PRIV_WIN_COLORMAP);
36N/A pset_win_upgrade_sl = alloc_win_priv(PRIV_WIN_UPGRADE_SL);
36N/A pset_win_downgrade_sl = alloc_win_priv(PRIV_WIN_DOWNGRADE_SL);
36N/A pset_win_selection = alloc_win_priv(PRIV_WIN_SELECTION);
36N/A}
36N/A
36N/Avoid
606N/Afree_win_privsets(void)
36N/A{
36N/A priv_freeset(pset_win_mac_read);
36N/A priv_freeset(pset_win_mac_write);
36N/A priv_freeset(pset_win_dac_read);
36N/A priv_freeset(pset_win_dac_write);
36N/A priv_freeset(pset_win_config);
36N/A priv_freeset(pset_win_devices);
36N/A priv_freeset(pset_win_fontpath);
36N/A priv_freeset(pset_win_colormap);
36N/A priv_freeset(pset_win_upgrade_sl);
36N/A priv_freeset(pset_win_downgrade_sl);
36N/A priv_freeset(pset_win_selection);
36N/A}
36N/A
36N/Aint
36N/AHasWinSelection(TsolInfoPtr tsolinfo)
36N/A{
36N/A return (priv_issubset(pset_win_selection, (tsolinfo->privs)));
36N/A}
36N/A
799N/Avoid
799N/ATsolCheckDrawableAccess(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
799N/A{
799N/A XaceResourceAccessRec *rec = calldata;
799N/A ClientPtr client = rec->client;
799N/A XID id = rec->id;
799N/A RESTYPE rtype = rec->rtype;
799N/A Mask access_mode = rec->access_mode;
799N/A DeviceIntPtr device = PickPointer(client);
799N/A WindowPtr pWin;
799N/A PixmapPtr pMap;
799N/A Mask modes;
799N/A int obj_code;
799N/A int status;
799N/A int err_code;
799N/A
799N/A Mask check_mode = access_mode;
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
799N/A TsolResPtr tsolres;
799N/A xpolicy_t flags;
799N/A int reqtype;
799N/A
799N/A if (client->requestBuffer) {
799N/A reqtype = MAJOROP; /* protocol */
799N/A } else {
799N/A reqtype = -1;
799N/A }
799N/A
799N/A status = BadAccess;
799N/A
799N/A switch (rtype) {
799N/A case RT_WINDOW:
799N/A obj_code = AW_XWINDOW;
799N/A pWin = (WindowPtr ) (rec->res);
1088N/A tsolres = TsolWindowPrivate(pWin);
799N/A err_code = BadWindow;
799N/A break;
799N/A case RT_PIXMAP:
799N/A obj_code = AW_XPIXMAP;
799N/A pMap = (PixmapPtr ) (rec->res);
1088N/A tsolres = TsolPixmapPrivate(pMap);
799N/A err_code = BadDrawable;
799N/A break;
799N/A }
799N/A
1379N/A /* Ignore unlabeled resources */
1379N/A if (tsolres->sl == NULL) {
1379N/A tsolres->sl= tsolinfo->sl;
1379N/A tsolres->uid = tsolinfo->uid;
1379N/A tsolres->pid = tsolinfo->pid;
1379N/A }
1379N/A
799N/A switch (reqtype) {
799N/A case X_GetImage:
799N/A case X_CopyArea:
799N/A case X_CopyPlane:
1088N/A /*
799N/A * Image operations are allowed here for lookup reasons.
799N/A * The actual policy enforcement is in the protocol handler.
799N/A */
799N/A if (check_mode & DixReadAccess) {
799N/A status = Success;
799N/A check_mode &= ~DixReadAccess;
799N/A }
799N/A break;
1088N/A
799N/A
799N/A case X_ClearArea:
799N/A if (check_mode & DixWriteAccess) {
799N/A status = Success;
799N/A check_mode &= ~DixWriteAccess;
799N/A }
799N/A break;
799N/A
799N/A case X_GrabPointer:
799N/A case X_UngrabPointer:
799N/A case X_GrabKeyboard:
799N/A case X_UngrabKeyboard:
799N/A case X_GrabKey:
799N/A case X_UngrabKey:
799N/A case X_GrabButton:
799N/A case X_UngrabButton:
1379N/A case X_WarpPointer:
799N/A /*
799N/A * Allow pointer grab on root window, as long as
799N/A * pointer is currently in a window owned by
799N/A * requesting client.
799N/A */
799N/A
799N/A if (WindowIsRoot(pWin)) {
799N/A pWin = GetSpriteWindow(device);
1088N/A tsolres = TsolWindowPrivate(pWin);
799N/A }
799N/A break;
799N/A
799N/A case X_ChangeSaveSet:
799N/A modes = (DixManageAccess|DixSetAttrAccess);
799N/A if (check_mode & modes) {
799N/A if (priv_win_config ||
799N/A client_has_privilege(tsolinfo, pset_win_config)) {
799N/A status = Success;
799N/A }
799N/A check_mode &= ~modes;
799N/A
799N/A }
799N/A break;
799N/A
799N/A }
799N/A
799N/A {
799N/A /* Perform the standard MAC/DAC tests here */
799N/A modes = (DixAddAccess|DixRemoveAccess|DixReadAccess|DixGetAttrAccess|
799N/A DixSetAttrAccess|
799N/A DixGetPropAccess|DixListPropAccess|DixSetPropAccess);
799N/A if (rtype == RT_WINDOW && check_mode & modes) {
799N/A if (WindowIsRoot(pWin) || XTSOLTrusted(pWin)) {
799N/A status = Success;
799N/A check_mode &= ~modes;
799N/A }
799N/A }
799N/A
799N/A /* Newly created drawable. Initialize it. */
799N/A if (check_mode & DixCreateAccess) {
799N/A if (rtype == RT_WINDOW)
799N/A TsolInitWindow(client, pWin);
799N/A if (rtype == RT_PIXMAP)
799N/A TsolInitPixmap(client, pMap);
799N/A
799N/A status = Success;
799N/A check_mode &= ~(DixCreateAccess);
799N/A }
799N/A
799N/A modes = (DixReadAccess|DixGetAttrAccess|
799N/A DixShowAccess|DixHideAccess|
799N/A DixListAccess|DixGetPropAccess|DixListPropAccess);
799N/A if (check_mode & modes) {
799N/A flags = (TSOL_MAC|TSOL_DAC|TSOL_READOP);
799N/A if (reqtype == X_GetInputFocus)
799N/A flags |= TSOL_DOMINATE;
799N/A status = tsol_check_policy(tsolinfo, tsolres, flags, reqtype);
799N/A check_mode &= ~modes;
799N/A }
799N/A
799N/A modes = (DixWriteAccess|DixSetAttrAccess|DixDestroyAccess|
799N/A DixManageAccess|
799N/A DixGrabAccess|DixSetAttrAccess|DixSetPropAccess|
799N/A DixAddAccess|DixRemoveAccess);
799N/A if (check_mode & modes) {
799N/A flags = (TSOL_MAC|TSOL_DAC|TSOL_WRITEOP);
799N/A status = tsol_check_policy(tsolinfo, tsolres, flags, reqtype);
799N/A check_mode &= ~modes;
799N/A }
799N/A
799N/A /* Event access, actual policy is implemented in the hook */
799N/A modes = (DixSendAccess|DixReceiveAccess);
799N/A if (check_mode & modes) {
799N/A status = Success;
799N/A check_mode &= ~modes;
799N/A }
799N/A }
1088N/A
799N/A if (tsolinfo->flags & TSOL_AUDITEVENT) {
799N/A set_audit_flags(tsolinfo);
799N/A auditwrite(obj_code, id, tsolres->uid,
799N/A AW_SLABEL, tsolres->sl,
799N/A AW_APPEND, AW_END);
799N/A }
799N/A
799N/A if (status == Success)
799N/A rec->status = Success;
799N/A else
799N/A rec->status = err_code;
799N/A
799N/A#ifndef NO_TSOL_DEBUG_MESSAGES
799N/A if (check_mode) { /* Any access mode bits not yet handled ? */
799N/A LogMessageVerb(X_NOT_IMPLEMENTED, TSOL_MSG_UNIMPLEMENTED,
799N/A TSOL_LOG_PREFIX
799N/A "policy not implemented for TsolCheckWindowAccess, "
799N/A "rtype=0x%x (%s), mode=0x%x (%s)\n",
799N/A (int) rtype, TsolResourceTypeString(rtype),
799N/A check_mode, TsolDixAccessModeNameString(check_mode));
799N/A }
799N/A
799N/A if (rec->status != Success) {
799N/A tsolinfo = GetClientTsolInfo(client);
1209N/A LogMessageVerb(X_WARNING, TSOL_MSG_WARNING,
799N/A TSOL_LOG_PREFIX
799N/A "TsolCheckDrawableAccess(%s, %s, 0x%x, %s, %s) = %s\n",
799N/A tsolinfo->pname,
799N/A TsolResourceTypeString(rtype), id,
799N/A TsolDixAccessModeNameString(access_mode),
799N/A TsolRequestNameString(reqtype),
799N/A TsolErrorNameString(rec->status));
799N/A }
799N/A
799N/A#endif /* !NO_TSOL_DEBUG_MESSAGES */
799N/A
799N/A}
799N/A
799N/Avoid
799N/ATsolCheckXIDAccess(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
799N/A{
799N/A XaceResourceAccessRec *rec = calldata;
799N/A ClientPtr client = rec->client;
799N/A XID id = rec->id;
799N/A RESTYPE rtype = rec->rtype;
799N/A Mask access_mode = rec->access_mode;
799N/A Mask modes;
799N/A int object_code;
799N/A int err_code;
799N/A
799N/A Mask check_mode = access_mode;
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
799N/A int reqtype;
799N/A
799N/A if (client->requestBuffer) {
799N/A reqtype = MAJOROP; /* protocol */
799N/A } else {
799N/A reqtype = -1;
799N/A }
799N/A
799N/A switch (rtype) {
799N/A case RT_FONT:
799N/A err_code = BadFont;
799N/A object_code = AW_XFONT;
799N/A break;
799N/A case RT_GC:
799N/A err_code = BadGC;
799N/A object_code = AW_XGC;
799N/A break;
799N/A case RT_CURSOR:
799N/A err_code = BadCursor;
799N/A object_code = AW_XCURSOR;
799N/A break;
799N/A case RT_COLORMAP:
799N/A err_code = BadColor;
799N/A object_code = AW_XCOLORMAP;
799N/A break;
799N/A default:
799N/A err_code = BadValue;
799N/A break;
799N/A }
799N/A
799N/A /* Anyone can create an object */
799N/A if (check_mode & DixCreateAccess) {
799N/A rec->status = Success;
799N/A check_mode &= ~DixCreateAccess;
799N/A }
799N/A
799N/A /* DAC check is based on client isolation */
1088N/A modes = (DixReadAccess|DixGetAttrAccess|DixUseAccess);
799N/A if (check_mode & modes) {
799N/A if (!client_private(client, id) &&
799N/A (!client_has_privilege(tsolinfo, pset_win_dac_read))) {
799N/A rec->status = err_code;
799N/A }
799N/A check_mode &= ~modes;
799N/A }
799N/A
799N/A modes = (DixWriteAccess|DixSetAttrAccess|DixDestroyAccess);
799N/A if (check_mode & modes) {
799N/A if (!client_private(client, id) &&
799N/A (!client_has_privilege(tsolinfo, pset_win_dac_write))) {
799N/A rec->status = err_code;
799N/A }
799N/A check_mode &= ~modes;
799N/A }
1088N/A
799N/A if (tsolinfo->flags & TSOL_AUDITEVENT) {
799N/A set_audit_flags(tsolinfo);
1088N/A auditwrite(object_code, (ulong_t)id, tsolinfo->uid,
799N/A AW_APPEND, AW_END);
799N/A }
799N/A
799N/A#ifndef NO_TSOL_DEBUG_MESSAGES
799N/A if (check_mode) { /* Any access mode bits not yet handled ? */
799N/A LogMessageVerb(X_NOT_IMPLEMENTED, TSOL_MSG_UNIMPLEMENTED,
799N/A TSOL_LOG_PREFIX
799N/A "policy not implemented for TsolCheckXIDAccess, "
799N/A "rtype=0x%x (%s), mode=0x%x (%s)\n",
799N/A (int) rtype, TsolResourceTypeString(rtype),
799N/A check_mode, TsolDixAccessModeNameString(check_mode));
799N/A }
799N/A
799N/A if (rec->status != Success) {
799N/A tsolinfo = GetClientTsolInfo(client);
1209N/A LogMessageVerb(X_WARNING, TSOL_MSG_WARNING,
799N/A TSOL_LOG_PREFIX
799N/A "TsolCheckXIDAccess(%s, %s, 0x%x, %s, %s) = %s\n",
799N/A tsolinfo->pname,
799N/A TsolResourceTypeString(rtype), id,
799N/A TsolDixAccessModeNameString(access_mode),
799N/A TsolRequestNameString(reqtype),
799N/A TsolErrorNameString(rec->status));
799N/A }
799N/A#endif /* !NO_TSOL_DEBUG_MESSAGES */
799N/A}
799N/A
799N/Avoid
799N/ATsolCheckServerAccess(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
799N/A{
799N/A XaceServerAccessRec *rec = calldata;
799N/A ClientPtr client = rec->client;
799N/A Mask access_mode = rec->access_mode;
799N/A Mask modes;
799N/A int object_code = 0;
799N/A
799N/A Mask check_mode = access_mode;
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
799N/A int reqtype;
799N/A
799N/A if (client->requestBuffer) {
799N/A reqtype = MAJOROP; /* protocol */
799N/A } else {
799N/A reqtype = -1;
799N/A }
799N/A
799N/A /* rec->status = Success; return; */
799N/A
799N/A rec->status = BadAccess;
799N/A
799N/A modes = (DixManageAccess);
799N/A if (check_mode & modes) {
799N/A switch (reqtype) {
799N/A case X_SetFontPath:
799N/A if (priv_win_fontpath ||
1088N/A client_has_privilege(tsolinfo,
1088N/A pset_win_fontpath)) {
799N/A rec->status = Success;
799N/A }
799N/A object_code = AW_XFONT;
799N/A break;
799N/A
799N/A case X_ChangeHosts:
799N/A case X_SetAccessControl:
799N/A if (priv_win_config ||
1088N/A client_has_privilege(tsolinfo,
1088N/A pset_win_config)) {
799N/A rec->status = Success;
799N/A }
799N/A object_code = AW_XCLIENT;
799N/A break;
799N/A }
799N/A
799N/A check_mode &= ~modes;
799N/A
799N/A if (tsolinfo->flags & TSOL_AUDITEVENT && object_code != 0) {
799N/A set_audit_flags(tsolinfo);
1088N/A auditwrite(object_code, (ulong_t)client->index,
1088N/A tsolinfo->uid,
1088N/A AW_SLABEL, tsolinfo->sl,
1088N/A AW_APPEND, AW_END);
799N/A }
799N/A }
799N/A
799N/A /* Allow get/read attributes, grab is enforced in protocol handler */
1088N/A modes = (DixReadAccess|DixGetAttrAccess|DixGrabAccess);
799N/A if (check_mode & modes) {
799N/A rec->status = Success;
799N/A check_mode &= ~modes;
799N/A }
799N/A
799N/A#ifndef NO_TSOL_DEBUG_MESSAGES
799N/A if (check_mode) { /* Any access mode bits not yet handled ? */
799N/A LogMessageVerb(X_NOT_IMPLEMENTED, TSOL_MSG_UNIMPLEMENTED,
799N/A TSOL_LOG_PREFIX
799N/A "policy not implemented for TsolCheckServerAccess, "
799N/A "mode=0x%x (%s)\n",
799N/A check_mode, TsolDixAccessModeNameString(check_mode));
799N/A }
799N/A
799N/A if (rec->status != Success) {
799N/A tsolinfo = GetClientTsolInfo(client);
1209N/A LogMessageVerb(X_WARNING, TSOL_MSG_WARNING,
799N/A TSOL_LOG_PREFIX
799N/A "TsolCheckServerAccess(%s, %s, %s) = %s\n",
799N/A tsolinfo->pname,
799N/A TsolDixAccessModeNameString(access_mode),
799N/A TsolRequestNameString(reqtype),
799N/A TsolErrorNameString(rec->status));
799N/A }
799N/A
799N/A#endif /* !NO_TSOL_DEBUG_MESSAGES */
799N/A}
799N/A
799N/Avoid
799N/ATsolCheckClientAccess(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
799N/A{
799N/A XaceClientAccessRec *rec = calldata;
799N/A ClientPtr client = rec->client;
799N/A Mask access_mode = rec->access_mode;
799N/A Mask modes;
799N/A
799N/A Mask check_mode = access_mode;
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
799N/A int reqtype;
799N/A
799N/A if (client->requestBuffer) {
799N/A reqtype = MAJOROP; /* protocol */
799N/A } else {
799N/A reqtype = -1;
799N/A }
799N/A
799N/A rec->status = BadAccess;
799N/A
799N/A modes = (DixManageAccess|DixDestroyAccess);
799N/A if (check_mode & modes) {
799N/A if (priv_win_config ||
1088N/A client_has_privilege(tsolinfo, pset_win_config)) {
799N/A rec->status = Success;
799N/A }
799N/A check_mode &= ~modes;
799N/A
799N/A if (tsolinfo->flags & TSOL_AUDITEVENT) {
799N/A set_audit_flags(tsolinfo);
1088N/A auditwrite(AW_XCLIENT, (ulong_t)client->index,
1088N/A tsolinfo->uid,
1088N/A AW_SLABEL, tsolinfo->sl,
1088N/A AW_APPEND, AW_END);
799N/A }
799N/A }
799N/A
799N/A#ifndef NO_TSOL_DEBUG_MESSAGES
799N/A if (check_mode) { /* Any access mode bits not yet handled ? */
799N/A LogMessageVerb(X_NOT_IMPLEMENTED, TSOL_MSG_UNIMPLEMENTED,
799N/A TSOL_LOG_PREFIX
799N/A "policy not implemented for TsolCheckClientAccess, "
799N/A "mode=0x%x (%s)\n",
799N/A check_mode, TsolDixAccessModeNameString(check_mode));
799N/A }
799N/A
799N/A if (rec->status != Success) {
799N/A tsolinfo = GetClientTsolInfo(client);
1209N/A LogMessageVerb(X_WARNING, TSOL_MSG_WARNING,
799N/A TSOL_LOG_PREFIX
799N/A "TsolCheckClientAccess(%s, %s, %s) = %s\n",
799N/A tsolinfo->pname,
799N/A TsolDixAccessModeNameString(access_mode),
799N/A TsolRequestNameString(reqtype),
799N/A TsolErrorNameString(rec->status));
799N/A }
799N/A
799N/A#endif /* !NO_TSOL_DEBUG_MESSAGES */
799N/A
799N/A}
799N/A
799N/Avoid
799N/ATsolCheckDeviceAccess(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
799N/A{
799N/A XaceDeviceAccessRec *rec = (XaceDeviceAccessRec *) calldata;
799N/A ClientPtr client = rec->client;
799N/A Mask access_mode = rec->access_mode;
799N/A Mask check_mode = access_mode;
799N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
799N/A int reqtype;
799N/A Mask modes;
799N/A
799N/A if (client->requestBuffer) {
799N/A reqtype = MAJOROP; /* protocol */
799N/A } else {
799N/A reqtype = -1;
799N/A }
799N/A
799N/A rec->status = BadWindow;
799N/A
1209N/A /* Allow all device access to the server itself */
1209N/A if (client == serverClient) {
1209N/A rec->status = Success;
1209N/A check_mode = 0;
1209N/A }
1209N/A
799N/A /* get/read access is allowed */
1088N/A modes = (DixCreateAccess | DixGetAttrAccess | DixGetFocusAccess |
1088N/A DixReadAccess | DixShowAccess | DixHideAccess |
1088N/A DixUseAccess | DixBellAccess);
799N/A if (check_mode & modes) {
799N/A rec->status = Success;
799N/A check_mode &= ~modes;
799N/A }
799N/A
799N/A /* change/set access requires privilege */
1088N/A modes = (DixFreezeAccess | DixGrabAccess | DixManageAccess |
1379N/A DixSetAttrAccess | DixSetFocusAccess | DixForceAccess |
1379N/A DixWriteAccess);
799N/A if (check_mode & modes) {
1088N/A if (priv_win_devices ||
1088N/A client_has_privilege(tsolinfo, pset_win_devices))
799N/A rec->status = Success;
1088N/A if (tsolinfo->flags & TSOL_AUDITEVENT) {
1088N/A set_audit_flags(tsolinfo);
1088N/A auditwrite(AW_XCLIENT, client->index,
1088N/A AW_APPEND, AW_END);
1088N/A }
799N/A check_mode &= ~modes;
799N/A }
799N/A
799N/A#ifndef NO_TSOL_DEBUG_MESSAGES
799N/A if (check_mode) { /* Any access mode bits not yet handled ? */
799N/A LogMessageVerb(X_NOT_IMPLEMENTED, TSOL_MSG_UNIMPLEMENTED,
799N/A TSOL_LOG_PREFIX
799N/A "policy not implemented for TsolCheckDeviceAccess, %s, %s\n",
799N/A TsolDixAccessModeNameString(check_mode),
799N/A TsolRequestNameString(reqtype));
799N/A }
799N/A
799N/A if (rec->status != Success) {
799N/A tsolinfo = GetClientTsolInfo(client);
1209N/A LogMessageVerb(X_WARNING, TSOL_MSG_WARNING,
799N/A TSOL_LOG_PREFIX
799N/A "TsolCheckDeviceAccess(%s, %s, %s) = %s\n",
799N/A tsolinfo->pname,
799N/A TsolDixAccessModeNameString(access_mode),
799N/A TsolRequestNameString(reqtype),
799N/A TsolErrorNameString(rec->status));
799N/A }
799N/A
799N/A#endif /* !NO_TSOL_DEBUG_MESSAGES */
1088N/A}
799N/A
1088N/ATsolResPtr
799N/ATsolDrawablePrivate(DrawablePtr pDraw, ClientPtr client)
799N/A{
799N/A int rc;
799N/A TsolResPtr tsolres = NULL;
799N/A PixmapPtr pMap = NullPixmap;
799N/A WindowPtr pWin = NullWindow;
799N/A
799N/A if (pDraw->type == DRAWABLE_WINDOW) {
799N/A rc = dixLookupWindow(&pWin, pDraw->id, client, DixReadAccess);
799N/A if (rc == Success && pWin != NullWindow)
1088N/A tsolres = TsolWindowPrivate(pWin);
799N/A }
799N/A else if (pDraw->type == DRAWABLE_PIXMAP)
799N/A {
851N/A rc = dixLookupDrawable((DrawablePtr *)&pMap, pDraw->id, client,
851N/A M_DRAWABLE_PIXMAP, DixReadAccess);
799N/A if (rc == Success && pMap != NullPixmap)
1088N/A tsolres = TsolPixmapPrivate(pMap);
799N/A }
799N/A
799N/A return tsolres;
799N/A}