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