tsolpolicy.c revision 196
98N/A/* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
0N/A *
0N/A * Permission is hereby granted, free of charge, to any person obtaining a
0N/A * copy of this software and associated documentation files (the
0N/A * "Software"), to deal in the Software without restriction, including
0N/A * without limitation the rights to use, copy, modify, merge, publish,
0N/A * distribute, and/or sell copies of the Software, and to permit persons
0N/A * to whom the Software is furnished to do so, provided that the above
0N/A * copyright notice(s) and this permission notice appear in all copies of
0N/A * the Software and that both the above copyright notice(s) and this
0N/A * permission notice appear in supporting documentation.
0N/A *
0N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0N/A * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0N/A * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
0N/A * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
0N/A * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
0N/A * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
0N/A * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
0N/A * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
0N/A * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0N/A *
0N/A * Except as contained in this notice, the name of a copyright holder
0N/A * shall not be used in advertising or otherwise to promote the sale, use
0N/A * or other dealings in this Software without prior written authorization
0N/A * of the copyright holder.
0N/A */
0N/A
196N/A#pragma ident "@(#)tsolpolicy.c 1.19 07/07/31 SMI"
0N/A
168N/A#ifdef HAVE_DIX_CONFIG_H
168N/A#include <dix-config.h>
168N/A#endif
98N/A
168N/A#include <X11/X.h>
0N/A#define NEED_REPLIES
0N/A#define NEED_EVENTS
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>
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>
0N/A#include "tsolinfo.h"
0N/A#include "tsolpolicy.h"
0N/A
36N/Astatic priv_set_t *pset_win_mac_read = NULL;
36N/Astatic priv_set_t *pset_win_mac_write = NULL;
36N/Astatic priv_set_t *pset_win_dac_read = NULL;
36N/Astatic priv_set_t *pset_win_dac_write = NULL;
36N/Astatic priv_set_t *pset_win_config = 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/Aextern TsolInfoPtr GetClientTsolInfo();
0N/Aextern int tsolWindowPrivateIndex;
0N/Aextern int tsolPixmapPrivateIndex;
0N/Aextern WindowPtr TsolPointerWindow();
0N/Aextern char *NameForAtom(Atom atom);
0N/Aextern char *xsltos(bslabel_t *sl);
0N/Aextern char *ProtoNames[];
0N/Aextern InputInfo inputInfo;
0N/A
0N/Aextern unsigned long tsoldebug; /* from tsolutils.c */
0N/Aextern Bool priv_win_colormap;
0N/Aextern Bool priv_win_config;
0N/Aextern Bool priv_win_devices;
0N/Aextern Bool priv_win_dga;
0N/Aextern Bool priv_win_fontpath;
73N/Aextern int tsolMultiLevel;
0N/A
0N/A#define SAMECLIENT(client, xid) ((client)->index == CLIENT_ID(xid))
0N/A
36N/Aint access_xid(xresource_t res, xmethod_t method, void *resource,
36N/A void *subject, xpolicy_t policy_flags, void *misc,
36N/A RESTYPE res_type, priv_set_t *which_priv);
36N/A
36N/Aint check_priv(xresource_t res, xmethod_t method, void *resource,
36N/A void *subject, xpolicy_t policy_flags, void *misc, priv_set_t *priv);
36N/A
0N/A#ifdef DEBUG
0N/A
0N/Aint xtsol_debug = XTSOL_FAIL; /* set it to 0 if no logging is required */
0N/Avoid XTsolErr(char *err_type, int protocol, bslabel_t *osl,
0N/A uid_t ouid, pid_t opid, char *opname,
0N/A bslabel_t *ssl, uid_t suid, pid_t spid,
0N/A char *spname, char *method, int isstring, void *xid);
0N/A
0N/A#define XTSOLERR(err_type, protocol, osl, ouid, opid, opname,\
0N/A ssl, suid, spid, spname, method, xid)\
0N/A (void) XTsolErr(err_type, protocol, osl, ouid, opid,\
0N/A opname, ssl, suid, spid, spname, method,\
0N/A 0, (void *) xid)
0N/A#define SXTSOLERR(err_type, protocol, osl, ouid, opid, opname,\
0N/A ssl, suid, spid, spname, method, xid)\
0N/A (void) XTsolErr(err_type, protocol, osl, ouid, opid,\
0N/A opname, ssl, suid, spid, spname,\
0N/A method, 1, (void *) xid)
0N/A#else /* !DEBUG */
0N/A#define XTSOLERR(err_type, protocol, osl, ouid, opid, opname,\
0N/A ssl, suid, spid, spname, method, xid)
0N/A#define SXTSOLERR(err_type, protocol, osl, ouid, opid, opname,\
0N/A ssl, suid, spid, spname, method, xid)
0N/A#endif /* DEBUG */
0N/A
0N/Aint object_float(TsolInfoPtr, WindowPtr);
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;
0N/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;
0N/A
0N/A}
0N/A
0N/A/*
0N/A * return 1 for success and 0 for failure
0N/A * this routine contains the privd debugging for the system
0N/A * as well as auditing the success or failure of use of priv.
0N/A * Priv debugging will be done later TBD
0N/A */
0N/A
0N/Aint
36N/Axpriv_policy(priv_set_t *set, priv_set_t *priv, xresource_t res,
0N/A xmethod_t method, void *subject, Bool do_audit)
0N/A{
0N/A int i;
0N/A static int logopened = FALSE;
0N/A int status = 0;
0N/A int audit_status = 0;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
36N/A if (priv_issubset(priv, set))
0N/A {
0N/A status = 1;
0N/A audit_status = 1;
0N/A }
0N/A else
0N/A {
0N/A audit_status = 0;
0N/A if (!logopened)
0N/A {
0N/A /* LOG_USER doesn't work */
0N/A openlog("xsun", 0, LOG_LOCAL0);
0N/A logopened = TRUE;
0N/A }
0N/A /* if priv debugging is on, allow this priv to succeed */
0N/A if (tsolinfo->priv_debug)
0N/A {
0N/A#ifdef DEBUG
0N/A ErrorF("%s:Allowed priv %ld\n", tsolinfo->pname, priv);
0N/A#endif /* DEBUG */
0N/A syslog(LOG_DEBUG|LOG_LOCAL0,
0N/A "DEBUG: %s pid %ld lacking privilege %d to %d %d",
0N/A "xclient", tsolinfo->pid, priv, method, res);
0N/A status = 1;
0N/A audit_status = 1;
0N/A }
0N/A }
0N/A if (do_audit)
0N/A auditwrite(AW_USEOFPRIV, audit_status, priv, AW_APPEND, AW_END);
0N/A return (status);
0N/A} /* xpriv_policy */
0N/A
0N/A
0N/A/*
0N/A * The read/modify window policy are for window attributes & not
0N/A * for window contents. read/modify pixel handle the contents policy
0N/A */
0N/A/*
0N/A * read_window
0N/A */
0N/Aint
0N/Aread_window(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadWindow;
0N/A WindowPtr pWin = resource;
0N/A ClientPtr client = subject;
0N/A ClientPtr ownerclient;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolInfoPtr tsolownerinfo; /*client who owns the window */
0N/A TsolResPtr tsolres =
0N/A (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A
0N/A ownerclient = clients[CLIENT_ID(pWin->drawable.id)];
0N/A tsolownerinfo = GetClientTsolInfo(ownerclient);
0N/A /*
0N/A * Anyone can read RootWindow attributes
0N/A */
0N/A if (WindowIsRoot(pWin))
0N/A {
0N/A return (PASSED);
0N/A }
0N/A /* optimization based on client id */
0N/A if (SAMECLIENT(client, pWin->drawable.id))
0N/A {
0N/A return PASSED;
0N/A }
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!(blequal(tsolinfo->sl, tsolres->sl)))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_read,
0N/A res, method, client, do_audit) ||
0N/A (tsolownerinfo && HasWinSelection(tsolownerinfo)))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read window", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A /* uid == DEF_UID means public window, shared read */
0N/A if (!(XTSOLTrusted(pWin) ||
0N/A tsolres->uid == DEF_UID ||
0N/A tsolinfo->uid == tsolres->uid))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_read,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read window", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XWINDOW, pWin->drawable.id, tsolres->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* read_window */
0N/A
0N/A/*
0N/A * modify_window
0N/A */
0N/Aint
0N/Amodify_window(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadWindow;
0N/A WindowPtr pWin = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres =
0N/A (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A
0N/A /* optimization based on client id */
0N/A if (SAMECLIENT(client, pWin->drawable.id))
0N/A {
0N/A return PASSED;
0N/A }
0N/A /*
0N/A * Trusted Path Windows require Trusted Path attrib
0N/A */
0N/A if (XTSOLTrusted(pWin) && !HasTrustedPath(tsolinfo))
0N/A {
0N/A XTSOLERR("tp", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify window", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, tsolres->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify window", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != tsolres->uid)
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify window", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XWINDOW, pWin->drawable.id, tsolres->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* modify_window */
0N/A
0N/A/*
0N/A * create_window
0N/A */
0N/Aint
0N/Acreate_window(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadWindow;
0N/A WindowPtr pWin = resource; /* parent window */
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres =
0N/A (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A
0N/A /*
0N/A * Anyone can create a child of root window
0N/A */
0N/A if (WindowIsRoot(pWin))
0N/A {
0N/A return (PASSED);
0N/A }
0N/A /*
0N/A * Trusted Path Windows required Trusted Path attrib
0N/A */
0N/A if (XTSOLTrusted(pWin))
0N/A {
0N/A if (!HasTrustedPath(tsolinfo))
0N/A {
0N/A /*
0N/A XTSOLERR("tp", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "create window", pWin->drawable.id); */
0N/A return (err_code);
0N/A }
0N/A }
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, tsolres->sl))
0N/A {
0N/A if (!SAMECLIENT(client, pWin->parent->drawable.id) &&
0N/A (tsolinfo->flags & TSOL_AUDITEVENT))
0N/A {
0N/A do_audit = TRUE;
0N/A }
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "create window", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != tsolres->uid)
0N/A {
0N/A if (!SAMECLIENT(client, pWin->parent->drawable.id) &&
0N/A (tsolinfo->flags & TSOL_AUDITEVENT))
0N/A {
0N/A do_audit = TRUE;
0N/A }
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "create window", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XWINDOW, pWin->drawable.id, tsolres->uid,
0N/A AW_SLABEL, tsolres->sl,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A
0N/A return (ret_stat);
0N/A} /* create_window */
0N/A
0N/A/*
0N/A * destroy_window
0N/A */
0N/Aint
0N/Adestroy_window(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadWindow;
0N/A WindowPtr pWin = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres =
0N/A (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A
0N/A /*
0N/A * Trusted Path Windows required Trusted Path attrib
0N/A */
0N/A if (XTSOLTrusted(pWin))
0N/A {
0N/A if (!HasTrustedPath(tsolinfo))
0N/A {
0N/A XTSOLERR("tp", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "destroy window", pWin->drawable.id);
0N/A return (err_code);
0N/A }
0N/A }
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, tsolres->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "destroy window", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != tsolres->uid ||
0N/A !same_client(client, pWin->drawable.id))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "destroy window", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XWINDOW, pWin->drawable.id, tsolres->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* destroy_window */
0N/A
0N/A/*
0N/A * read_pixel: used for reading contents of drawable like GetImage
0N/A */
0N/Aint
0N/Aread_pixel(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadDrawable;
0N/A int obj_code = 0;
0N/A XID obj_id = (XID)NULL;
0N/A DrawablePtr pDraw = resource;
0N/A ClientPtr client = subject;
0N/A PixmapPtr pMap = NullPixmap;
0N/A WindowPtr pWin = NullWindow;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres;
0N/A
0N/A /*
0N/A * Public/default objects check here
0N/A */
0N/A
0N/A if (pDraw->type == DRAWABLE_WINDOW)
0N/A {
0N/A pWin = (WindowPtr)LookupWindow(pDraw->id, client);
0N/A if (pWin == NULL)
0N/A return (PASSED); /* server will handle bad params */
0N/A tsolres = (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A obj_code = AW_XWINDOW;
0N/A obj_id = pWin->drawable.id;
0N/A }
0N/A else if (pDraw->type == DRAWABLE_PIXMAP)
0N/A {
0N/A pMap = (PixmapPtr)LookupIDByType(pDraw->id, RT_PIXMAP);
0N/A if (pMap == NULL)
0N/A return (PASSED); /* server will handle bad params */
0N/A tsolres = (TsolResPtr)(pMap->devPrivates[tsolPixmapPrivateIndex].ptr);
0N/A obj_code = AW_XPIXMAP;
0N/A obj_id = pMap->drawable.id;
0N/A }
0N/A else
0N/A return (PASSED); /* UNDRAWABLE_WINDOW */
0N/A
0N/A /* based on client id bypass MAC/DAC */
0N/A if (!SAMECLIENT(client, pDraw->id))
0N/A {
0N/A /*
73N/A * Client must have Trusted Path to access root window
73N/A * in multilevel desktop.
0N/A */
73N/A if (tsolMultiLevel && DrawableIsRoot(pDraw) &&
73N/A !HasTrustedPath(tsolinfo))
64N/A return (err_code);
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!bldominates(tsolinfo->sl, tsolres->sl))
0N/A {
0N/A if (!(tsolinfo->flags & MAC_READ_AUDITED) &&
0N/A (tsolinfo->flags & TSOL_AUDITEVENT))
0N/A {
0N/A do_audit = TRUE;
0N/A tsolinfo->flags |= MAC_READ_AUDITED;
0N/A }
0N/A /* PRIV override? */
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_read,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read pixel", pDraw->id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != tsolres->uid)
0N/A {
0N/A if (!(tsolinfo->flags & DAC_READ_AUDITED) &&
0N/A (tsolinfo->flags & TSOL_AUDITEVENT))
0N/A {
0N/A do_audit = TRUE;
0N/A tsolinfo->flags |= DAC_READ_AUDITED;
0N/A }
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_read,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read pixel", pDraw->id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A } /* end if !SAMECLIENT */
0N/A
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(obj_code, obj_id, tsolres->uid, AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* read_pixel */
0N/A
0N/A/*
0N/A * modify_pixel
0N/A */
0N/Aint
0N/Amodify_pixel(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadDrawable;
0N/A int obj_code = 0;
0N/A XID obj_id = (XID)NULL;
0N/A DrawablePtr pDraw = resource;
0N/A ClientPtr client = subject;
0N/A PixmapPtr pMap = NullPixmap;
0N/A WindowPtr pWin = NullWindow;
0N/A TsolInfoPtr tsolinfo;
0N/A TsolResPtr tsolres;
0N/A
0N/A /*
0N/A * Trusted Path Windows required Trusted Path attrib
0N/A */
0N/A tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (pDraw->type == DRAWABLE_WINDOW)
0N/A {
0N/A pWin = (WindowPtr)LookupWindow(pDraw->id, client);
0N/A if (pWin == NULL)
0N/A return (PASSED);
0N/A tsolres = (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A obj_code = AW_XWINDOW;
0N/A obj_id = pWin->drawable.id;
0N/A }
0N/A else if (pDraw->type == DRAWABLE_PIXMAP)
0N/A {
0N/A pMap = (PixmapPtr)LookupIDByType(pDraw->id, RT_PIXMAP);
0N/A if (pMap == NULL)
0N/A return (PASSED);
0N/A tsolres = (TsolResPtr) (pMap->devPrivates[tsolPixmapPrivateIndex].ptr);
0N/A obj_code = AW_XPIXMAP;
0N/A obj_id = pMap->drawable.id;
0N/A }
0N/A else
0N/A return (PASSED); /* UNDRAWABLE_WINDOW */
0N/A
0N/A /* optimization based on client id */
0N/A if (!SAMECLIENT(client, pDraw->id))
0N/A {
0N/A /*
0N/A * Trusted Path Windows require Trusted Path attrib
0N/A */
0N/A if ((pDraw->type == DRAWABLE_WINDOW) &&
0N/A XTSOLTrusted(pWin) &&
0N/A !HasTrustedPath(tsolinfo))
0N/A {
0N/A XTSOLERR("tp", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify pixel", pWin->drawable.id);
0N/A return (err_code);
0N/A }
0N/A /*
0N/A * You need win_config priv to write to root window
0N/A */
0N/A if (!priv_win_config && (pWin && WindowIsRoot(pWin)))
0N/A {
0N/A if (!(tsolinfo->flags & CONFIG_AUDITED) &&
0N/A (tsolinfo->flags & TSOL_AUDITEVENT))
0N/A {
0N/A do_audit = TRUE;
0N/A tsolinfo->flags |= CONFIG_AUDITED;
0N/A }
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_config,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify pixel", pDraw->id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, tsolres->sl))
0N/A {
0N/A if (!(tsolinfo->flags & MAC_WRITE_AUDITED) &&
0N/A (tsolinfo->flags & TSOL_AUDITEVENT))
0N/A {
0N/A do_audit = TRUE;
0N/A tsolinfo->flags |= MAC_WRITE_AUDITED;
0N/A }
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify pixel", pDraw->id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != tsolres->uid)
0N/A {
0N/A if (!(tsolinfo->flags & DAC_WRITE_AUDITED) &&
0N/A (tsolinfo->flags & TSOL_AUDITEVENT))
0N/A {
0N/A do_audit = TRUE;
0N/A tsolinfo->flags |= DAC_WRITE_AUDITED;
0N/A }
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify pixel", pDraw->id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A } /* end if SAMECLIENT */
0N/A
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(obj_code, obj_id, tsolres->uid, AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* modify_pixel */
0N/A
0N/A/*
0N/A * read_pixmap
0N/A */
0N/Aint
0N/Aread_pixmap(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadPixmap;
0N/A PixmapPtr pMap = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres =
0N/A (TsolResPtr)(pMap->devPrivates[tsolPixmapPrivateIndex].ptr);
0N/A
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!bldominates(tsolinfo->sl, tsolres->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_read,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read pixmap", pMap->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != tsolres->uid)
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_read,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read pixmap", pMap->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XPIXMAP, pMap->drawable.id, tsolres->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* read_pixmap */
0N/A
0N/A/*
0N/A * modify_pixmap
0N/A */
0N/Aint
0N/Amodify_pixmap(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadPixmap;
0N/A PixmapPtr pMap = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres =
0N/A (TsolResPtr)(pMap->devPrivates[tsolPixmapPrivateIndex].ptr);
0N/A
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, tsolres->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify pixmap", pMap->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != tsolres->uid)
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify pixmap", pMap->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XPIXMAP, pMap->drawable.id, tsolres->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* modify_pixmap */
0N/A
0N/A/*
0N/A * destroy_pixmap
0N/A */
0N/Aint
0N/Adestroy_pixmap(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadPixmap;
0N/A PixmapPtr pMap = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres =
0N/A (TsolResPtr)(pMap->devPrivates[tsolPixmapPrivateIndex].ptr);
0N/A
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, tsolres->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "destroy pixmap", pMap->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != tsolres->uid)
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "destroy pixmap", pMap->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XPIXMAP, pMap->drawable.id, tsolres->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* destroy_pixmap */
0N/A
0N/A/*
0N/A * read_client
0N/A */
0N/Aint
0N/Aread_client(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A ClientPtr res_client;
0N/A int err_code = BadAccess;
0N/A Bool do_audit = FALSE;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr res_tsolinfo;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (!(res_client = clients[CLIENT_ID((XID)resource)]))
0N/A {
0N/A return (BadValue);
0N/A }
0N/A res_tsolinfo = GetClientTsolInfo(res_client);
0N/A
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, res_tsolinfo->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_read,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, res_tsolinfo->sl,
0N/A res_tsolinfo->uid, res_tsolinfo->pid,
0N/A res_tsolinfo->pname, tsolinfo->sl,
0N/A tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read client", resource);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != res_tsolinfo->uid)
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_read,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, res_tsolinfo->sl,
0N/A res_tsolinfo->uid, res_tsolinfo->pid,
0N/A res_tsolinfo->pname, tsolinfo->sl,
0N/A tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read client", resource);
0N/A ret_stat = ret_stat;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * Trusted Path Windows required Trusted Path attrib
0N/A */
0N/A if ((ret_stat == PASSED) && HasTrustedPath(res_tsolinfo))
0N/A {
0N/A if (!HasTrustedPath(tsolinfo))
0N/A {
0N/A XTSOLERR("tp", (int) misc, res_tsolinfo->sl,
0N/A res_tsolinfo->uid, res_tsolinfo->pid,
0N/A res_tsolinfo->pname, tsolinfo->sl,
0N/A tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read client", resource);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XCLIENT, res_client->index, AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* read client */
0N/A
0N/A/*
0N/A * modify_client
0N/A * Special win_config priv used for ChangeSaveSet, SetCloseDownMode
0N/A */
0N/Aint
0N/Amodify_client(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A int err_code = BadValue;
0N/A Bool do_audit = FALSE;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (priv_win_config)
0N/A return (PASSED);
0N/A
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
0N/A /*
0N/A * Needs win_config priv
0N/A */
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_config,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A ret_stat = err_code;
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XCLIENT, client->index, AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* modify_client */
0N/A
0N/A/*
0N/A * destroy_client
0N/A */
0N/Aint
0N/Adestroy_client(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A ClientPtr res_client;
0N/A int err_code = BadValue;
0N/A Bool do_audit = FALSE;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr res_tsolinfo;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (!(res_client = clients[CLIENT_ID((XID)resource)]))
0N/A {
0N/A return (BadValue);
0N/A }
0N/A
0N/A res_tsolinfo = GetClientTsolInfo(res_client);
0N/A
0N/A /* Server a special client */
0N/A if (res_client == serverClient || res_tsolinfo == NULL)
0N/A {
0N/A if (client != serverClient)
0N/A return (BadValue);
0N/A else
0N/A return (PASSED); /* internal request */
0N/A }
0N/A
0N/A
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, res_tsolinfo->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, res_tsolinfo->sl,
0N/A res_tsolinfo->uid, res_tsolinfo->pid,
0N/A res_tsolinfo->pname, tsolinfo->sl,
0N/A tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "destroy client", resource);
0N/A ret_stat = ret_stat;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != res_tsolinfo->uid)
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, res_tsolinfo->sl,
0N/A res_tsolinfo->uid, res_tsolinfo->pid,
0N/A res_tsolinfo->pname, tsolinfo->sl,
0N/A tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "destroy client", resource);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * Trusted Path Windows required Trusted Path attrib
0N/A */
0N/A if ((ret_stat == PASSED) && HasTrustedPath(res_tsolinfo))
0N/A {
0N/A if (!HasTrustedPath(tsolinfo))
0N/A {
0N/A XTSOLERR("tp", (int) misc, res_tsolinfo->sl,
0N/A res_tsolinfo->uid, res_tsolinfo->pid,
0N/A res_tsolinfo->pname, tsolinfo->sl,
0N/A tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "destroy client", resource);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XCLIENT, res_client->index, AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* destroy_client */
0N/A
0N/A/*
0N/A * read_gc
0N/A */
0N/Aint
0N/Aread_gc(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A return (access_xid(res, method, resource, subject, policy_flags,
36N/A misc, RT_GC, pset_win_dac_read));
0N/A}
0N/A
0N/A/*
0N/A * modify_gc
0N/A */
0N/Aint
0N/Amodify_gc(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A unsigned int protocol = (unsigned int)misc;
0N/A
0N/A return (access_xid(res, method, resource, subject, policy_flags,
36N/A misc, RT_GC, pset_win_dac_write));
0N/A}
0N/A
0N/A/*
0N/A * read_font
0N/A */
0N/Aint
0N/Aread_font(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A return (access_xid(res, method, resource, subject, policy_flags,
36N/A misc, RT_FONT, pset_win_dac_read));
0N/A}
0N/A
0N/A/*
0N/A * modify_font
0N/A */
0N/Aint
0N/Amodify_font(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A return (access_xid(res, method, resource, subject, policy_flags,
36N/A misc,RT_FONT, pset_win_dac_write));
0N/A}
0N/A
0N/A/*
0N/A * modify_cursor
0N/A */
0N/Aint
0N/Amodify_cursor(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A return (access_xid(res, method, resource, subject, policy_flags,
36N/A misc, RT_CURSOR, pset_win_dac_write));
0N/A}
0N/A
0N/A/*
0N/A * access_ccell: access policy for color cells.
0N/A */
0N/Aint
0N/Aaccess_ccell(xresource_t res, xmethod_t method, void *resource, void *subject,
0N/A xpolicy_t policy_flags, void *misc)
0N/A{
0N/A#if TBD
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A priv_t priv;
0N/A XID cmap_id = (XID)misc;
0N/A EntrySecAttrPtr pentp = (EntrySecAttrPtr)resource;
0N/A ClientPtr client = (ClientPtr)subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A /*
0N/A * MAC check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, pentp->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
0N/A priv =
36N/A (method == TSOL_READ) ? pset_win_mac_read : pset_win_mac_write;
0N/A /*
0N/A * any colorcell owned by root is readable by all
0N/A */
36N/A if ((priv == pset_win_mac_read) && (pentp->uid == 0))
0N/A ret_stat = PASSED;
0N/A else if (xpriv_policy(tsolinfo->privs, priv,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("clientid mac", (int)NULL, tsolinfo->sl,
0N/A tsolinfo->uid, tsolinfo->pid, tsolinfo->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "access ccell", cmap_id);
0N/A ret_stat = BadAccess;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != pentp->uid)
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
0N/A priv = (method == TSOL_READ) ?
36N/A pset_win_dac_read : pset_win_dac_write;
0N/A /*
0N/A * any colorcell owned by root is readable by all
0N/A */
36N/A if ((priv == pset_win_dac_read) && (pentp->uid == 0))
0N/A ret_stat = PASSED;
0N/A else if (xpriv_policy(tsolinfo->privs, priv,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("clientid dac", (int)NULL, tsolinfo->sl,
0N/A tsolinfo->uid, tsolinfo->pid, tsolinfo->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "access ccell", cmap_id);
0N/A ret_stat = BadAccess;
0N/A }
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XCOLORMAP, (u_long)cmap_id, tsolinfo->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A
0N/A return (ret_stat);
0N/A#endif
0N/A return (PASSED);
0N/A}
0N/A
0N/A/*
0N/A * read_ccell
0N/A */
0N/Aint
0N/Aread_ccell(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A if (priv_win_colormap)
0N/A return (PASSED);
0N/A else
0N/A return (access_ccell(res, method, resource, subject,
0N/A policy_flags, misc));
0N/A}
0N/A
0N/A/*
0N/A * modify_ccell
0N/A */
0N/Aint
0N/Amodify_ccell(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A if (priv_win_colormap)
0N/A return (PASSED);
0N/A else
0N/A return (access_ccell(res, method, resource, subject,
0N/A policy_flags, misc));
0N/A}
0N/A
0N/A/*
0N/A * destroy_ccell
0N/A */
0N/Aint
0N/Adestroy_ccell(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A#ifdef TBD
0N/A EntrySecAttrPtr pentp = (EntrySecAttrPtr)resource;
0N/A
0N/A if (priv_win_colormap)
0N/A return (PASSED);
0N/A else if ( pentp->sl == NULL) /* The cell is allocated by server */
0N/A return (PASSED);
0N/A else
0N/A return (access_ccell(res, method, resource, subject,
0N/A policy_flags, misc));
0N/A#endif
0N/A return (PASSED);
0N/A}
0N/A
0N/A/*
0N/A * read_cmap
0N/A */
0N/Aint
0N/Aread_cmap(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A ColormapPtr pcmp = (ColormapPtr ) resource;
0N/A
0N/A /* handle default colormap */
0N/A if (pcmp->flags & IsDefault)
0N/A return (PASSED);
0N/A
0N/A return (access_xid(res, method, (void *)(pcmp->mid), subject, policy_flags,
36N/A misc, RT_COLORMAP, pset_win_dac_read));
0N/A}
0N/A
0N/A/*
0N/A * modify_cmap: resource passed is ColormapPtr & not an XID
0N/A */
0N/Aint
0N/Amodify_cmap(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A ColormapPtr pcmp = (ColormapPtr ) resource;
0N/A
0N/A /* modify default colormap ok */
0N/A if (pcmp->flags & IsDefault)
0N/A return (PASSED);
0N/A
0N/A return (access_xid(res, method,(void *)(pcmp->mid) , subject, policy_flags,
36N/A misc, RT_COLORMAP, pset_win_dac_write));
0N/A}
0N/A
0N/A/*
0N/A * install_cmap: both install/uninstall
0N/A */
0N/Aint
0N/Ainstall_cmap(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A ColormapPtr pcmp = (ColormapPtr ) resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A int err_code = BadColor;
0N/A
0N/A /* handle default colormap */
0N/A if (pcmp->flags & IsDefault)
0N/A return (PASSED);
0N/A
0N/A if (priv_win_colormap)
0N/A return (PASSED);
0N/A
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
0N/A
0N/A /*
0N/A * check only win_colormap priv
0N/A */
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_colormap,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("install_cmap", (int) misc, tsolinfo->sl,
0N/A tsolinfo->uid, tsolinfo->pid, tsolinfo->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "install_cmap", pcmp->mid);
0N/A ret_stat = err_code;
0N/A }
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XCOLORMAP, pcmp->mid, tsolinfo->uid, AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A}
0N/A
0N/A/*
0N/A * access_xid: access policy for XIDs
0N/A */
0N/Aint
0N/Aaccess_xid(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc,
36N/A RESTYPE res_type, priv_set_t *which_priv)
0N/A{
0N/A int ret_stat = PASSED;
0N/A int object_code = 0;
0N/A int err_code; /* depends on type of XID */
0N/A Bool do_audit = FALSE;
0N/A XID object = (XID) resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = (TsolInfoPtr)NULL;
0N/A
0N/A if (res_type == RT_NONE)
0N/A res_type = RES_TYPE(object);
0N/A /*
0N/A * assign appropriate error code
0N/A */
0N/A switch (res_type) {
0N/A case RT_PIXMAP:
0N/A err_code = BadPixmap;
0N/A object_code = AW_XPIXMAP;
0N/A break;
0N/A case RT_FONT:
0N/A err_code = BadFont;
0N/A object_code = AW_XFONT;
0N/A break;
0N/A case RT_GC:
0N/A err_code = BadGC;
0N/A object_code = AW_XGC;
0N/A break;
0N/A case RT_CURSOR:
0N/A err_code = BadCursor;
0N/A object_code = AW_XCURSOR;
0N/A break;
0N/A case RT_COLORMAP:
0N/A err_code = BadColor;
0N/A object_code = AW_XCOLORMAP;
0N/A break;
0N/A default:
0N/A err_code = BadValue;
0N/A break;
0N/A }
0N/A /*
0N/A * DAC check is based on client isolation.
0N/A */
0N/A if (policy_flags & TSOL_DAC)
0N/A {
0N/A if (!client_private(client, object))
0N/A {
0N/A tsolinfo = GetClientTsolInfo(client);
0N/A if (!tsolinfo)
0N/A return (err_code);
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
0N/A /* PRIV override? */
0N/A if (xpriv_policy(tsolinfo->privs, which_priv, res,
0N/A method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("clientid", (int) misc, tsolinfo->sl,
0N/A tsolinfo->uid, tsolinfo->pid, tsolinfo->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "access xid", object);
0N/A ret_stat = err_code;
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(object_code, (u_long)object, tsolinfo->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A }
0N/A }
0N/A return (ret_stat);
0N/A} /* access_xid */
0N/A
0N/A/*
0N/A * modify_fontpath: requires win_fontpath priv
0N/A */
0N/Aint
0N/Amodify_fontpath(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A int err_code = BadFont;
0N/A Bool do_audit = FALSE;
0N/A XID object = (XID)resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (priv_win_fontpath)
0N/A return (PASSED);
0N/A
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
0N/A
0N/A /*
0N/A * No MAC & DAC. Check win_fontpath priv only
0N/A */
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_fontpath,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A ret_stat = err_code;
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XFONT, (u_long)object, tsolinfo->uid, AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A}
0N/A
0N/A/*
0N/A * read_devices: All kbd/ptr ctrl/mapping related access.
0N/A * requires win_devices priv
0N/A * BadAccess is not a valid error code for many protocols
0N/A * and does not work especially for SetPointerModifierMapping etc
0N/A */
0N/Aint
0N/Aread_devices(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A int err_code = BadValue;
0N/A Bool do_audit = FALSE;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (priv_win_devices)
0N/A return (PASSED);
0N/A
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
0N/A
0N/A /*
0N/A * No MAC/DAC check. Needs win_devices priv
0N/A */
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_devices,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A ret_stat = err_code;
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XCLIENT, client->index, AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A}
0N/A
0N/A/*
0N/A * modify_devices: All kbd/ptr ctrl/mapping related access.
0N/A * requires win_devices priv
0N/A */
0N/Aint
0N/Amodify_devices(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A int err_code = BadAccess;
0N/A Bool do_audit = FALSE;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (priv_win_devices)
0N/A return (PASSED);
0N/A
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
0N/A
0N/A /*
0N/A * No MAC/DAC check. Needs win_devices priv
0N/A */
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_devices,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A ret_stat = err_code;
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XCLIENT, client->index, AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A}
0N/A
0N/A/*
0N/A * modify_acl
0N/A */
0N/Aint
0N/Amodify_acl(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A int err_code = BadValue;
0N/A Bool do_audit = FALSE;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (priv_win_config)
0N/A return (PASSED);
0N/A
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
0N/A
0N/A /*
0N/A * Needs win_config priv
0N/A */
0N/A if (tsolinfo->uid != OwnerUID)
0N/A {
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_config, res,
0N/A method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XCLIENT, client->index, AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A}
0N/A
0N/A/*
0N/A * read_atom
0N/A */
0N/Aint
0N/Aread_atom(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A
0N/A return PASSED;
0N/A#if 0
0N/A int ret_stat = PASSED;
0N/A int err_code = BadAtom;
0N/A Bool do_audit = FALSE;
0N/A NodePtr node = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A int i, status;
0N/A int protocol = (int)(misc);
0N/A
0N/A /*
0N/A * MAC Check is slightly different. We do a series of
0N/A * MAC checks for all SLs in the table before we
0N/A * apply privs
0N/A */
0N/A status = FAILED;
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A for ( i = 0; i < node->clientCount; i++)
0N/A {
0N/A if (bldominates(tsolinfo->sl, node->sl[i]))
0N/A {
0N/A status = PASSED;
0N/A break;
0N/A }
0N/A }
0N/A if (status == FAILED)
0N/A {
0N/A#ifdef DEBUG
0N/A if (xtsol_debug >= XTSOL_FAIL)
0N/A {
0N/A ErrorF("\nmac failed:%s,subj(%s,%d,%d,%s),",
0N/A ProtoNames[protocol], xsltos(tsolinfo->sl),
0N/A tsolinfo->uid, tsolinfo->pid, tsolinfo->pname);
0N/A ErrorF("read atom, xid %s\n", NameForAtom(node->a));
0N/A }
0N/A#endif /* DEBUG */
0N/A /* PRIV override? */
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_read,
0N/A res, method, client, do_audit))
0N/A {
0N/A status = PASSED;
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * No DAC check
0N/A */
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XATOM, NameForAtom(node->a), AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A#endif
0N/A
0N/A} /* read_atom */
0N/A
0N/A/*
0N/A * The read/modify window policy are for window attributes & not
0N/A * for window contents. read/modify pixel handle the contents policy
0N/A */
0N/A/*
0N/A * read_property
0N/A */
0N/Aint
0N/Aread_property(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadAtom;
0N/A PropertyPtr pProp = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
168N/A TsolPropPtr tsolprop;
0N/A
0N/A /* Initialize property created internally by server */
168N/A if (pProp->secPrivate == NULL)
0N/A {
168N/A pProp->secPrivate = (pointer)AllocServerTsolProp();
168N/A if (pProp->secPrivate == NULL)
168N/A return(BadAlloc);
168N/A }
0N/A
168N/A tsolprop = (TsolPropPtr)(pProp->secPrivate);
0N/A
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!bldominates(tsolinfo->sl, tsolprop->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_read,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A SXTSOLERR("mac", (int) misc, tsolprop->sl,
0N/A tsolprop->uid, tsolprop->pid, tsolprop->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read property",
0N/A NameForAtom(pProp->propertyName));
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
168N/A extern bslabel_t PublicObjSL;
168N/A /*
168N/A * workstation owner can read properties created internally by loadable modules.
168N/A * roles can read property created by workstation owner at admin_low.
168N/A */
168N/A
168N/A if (!((tsolprop->serverOwned && tsolinfo->uid == OwnerUID) ||
168N/A (tsolprop->uid == OwnerUID && blequal(tsolprop->sl, &PublicObjSL)) ||
168N/A tsolprop->uid == tsolinfo->uid))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
168N/A
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_read,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XPROPERTY, tsolinfo->uid, tsolprop->uid,
0N/A NameForAtom(pProp->propertyName), AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* read_property */
0N/A
0N/A/*
0N/A * modify_property
0N/A */
0N/Aint
0N/Amodify_property(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadAtom;
0N/A PropertyPtr pProp = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
168N/A TsolPropPtr tsolprop;
0N/A
0N/A /* Initialize property created internally by server */
168N/A if (pProp->secPrivate == NULL)
0N/A {
168N/A pProp->secPrivate = (pointer)AllocServerTsolProp();
168N/A if (pProp->secPrivate == NULL)
168N/A return(BadAlloc);
168N/A }
0N/A
168N/A tsolprop = (TsolPropPtr)(pProp->secPrivate);
0N/A
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, tsolprop->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A SXTSOLERR("mac", (int) misc, tsolprop->sl,
0N/A tsolprop->uid, tsolprop->pid, tsolprop->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify property",
0N/A NameForAtom(pProp->propertyName));
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
168N/A /*
168N/A * workstation owner can write properties created internally by loadable modules.
168N/A */
168N/A
168N/A if (!((tsolprop->serverOwned && tsolinfo->uid == OwnerUID) || tsolprop->uid == tsolinfo->uid))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
168N/A
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XPROPERTY, tsolinfo->uid, tsolprop->uid,
0N/A NameForAtom(pProp->propertyName), AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* modify_property */
0N/A
0N/A/*
0N/A * destroy_property
0N/A */
0N/Aint
0N/Adestroy_property(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadAtom;
0N/A PropertyPtr pProp = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
168N/A TsolPropPtr tsolprop;
168N/A
168N/A /* Initialize property created internally by server */
168N/A if (pProp->secPrivate == NULL)
168N/A {
168N/A pProp->secPrivate = (pointer)AllocServerTsolProp();
168N/A if (pProp->secPrivate == NULL)
168N/A return(BadAlloc);
168N/A }
168N/A
168N/A tsolprop = (TsolPropPtr)(pProp->secPrivate);
0N/A
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, tsolprop->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A SXTSOLERR("mac", (int) misc, tsolprop->sl,
0N/A tsolprop->uid, tsolprop->pid, tsolprop->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "destroy property",
0N/A NameForAtom(pProp->propertyName));
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != tsolprop->uid)
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A SXTSOLERR("dac", (int) misc, tsolprop->sl,
0N/A tsolprop->uid, tsolprop->pid, tsolprop->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "destroy property",
0N/A NameForAtom(pProp->propertyName));
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XPROPERTY, tsolinfo->uid, tsolprop->uid,
0N/A NameForAtom(pProp->propertyName), AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* destroy_property */
0N/A
0N/A/*
0N/A * modify_grabwin
0N/A */
0N/Aint
0N/Amodify_grabwin(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A int err_code = BadWindow;
0N/A Bool do_audit = FALSE;
0N/A WindowPtr pWin = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres;
0N/A
0N/A /*
0N/A * Allow pointer grab on root window, as long as
0N/A * pointer is currently in a window owned by
0N/A * requesting client.
0N/A */
0N/A
0N/A if (WindowIsRoot(pWin))
0N/A {
0N/A pWin = TsolPointerWindow();
0N/A if (WindowIsRoot(pWin))
0N/A return (PASSED);
0N/A }
0N/A tsolres = (TsolResPtr) (pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, tsolres->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read grabwin", pWin->drawable.id);
0N/A do_audit = FALSE; /* don't audit this */
0N/A unset_audit_flags(tsolinfo);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != tsolres->uid /* && tsolres->uid != 0 */)
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read grabwin", pWin->drawable.id);
0N/A do_audit = FALSE; /* don't audit this */
0N/A unset_audit_flags(tsolinfo);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /* Grab on trusted window requires TP */
0N/A if ((ret_stat == PASSED) && XTSOLTrusted(pWin))
0N/A {
0N/A if (!HasTrustedPath(tsolinfo))
0N/A ret_stat = err_code;
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XWINDOW, pWin->drawable.id, tsolres->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* modify_grabwin */
0N/A
0N/A/*
0N/A * modify_confwin - ConfineTo window access
0N/A */
0N/Aint
0N/Amodify_confwin(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadWindow;
0N/A WindowPtr pWin = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres =
0N/A (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A
0N/A /*if (priv_win_devices)
0N/A return (PASSED);*/
0N/A
0N/A /*
0N/A * confine window can be None. Root window is OK
0N/A */
0N/A
0N/A if (pWin == NullWindow || WindowIsRoot(pWin))
0N/A {
0N/A return (PASSED);
0N/A }
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, tsolres->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read grabwin", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != tsolres->uid /* && tsolres->uid != 0 */)
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read grabwin", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /* Trusted window requires TP */
0N/A if ((ret_stat == PASSED) && XTSOLTrusted(pWin))
0N/A {
0N/A if (!HasTrustedPath(tsolinfo))
0N/A ret_stat = err_code;
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XWINDOW, pWin->drawable.id, tsolres->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* modify_confwin */
0N/A
0N/A/*
0N/A * create_srvgrab: GrabServer requires a priv
0N/A */
0N/Aint
0N/Acreate_srvgrab(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A if (priv_win_config)
0N/A {
0N/A return (PASSED);
0N/A }
0N/A else
0N/A {
0N/A return (check_priv(res, method, resource, subject, policy_flags,
36N/A misc, pset_win_config));
0N/A }
0N/A}
0N/A
0N/A/*
0N/A * destroy_srvgrab: GrabServer requires a priv
0N/A */
0N/Aint
0N/Adestroy_srvgrab(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A if (priv_win_config)
0N/A {
0N/A return (PASSED);
0N/A }
0N/A else
0N/A {
0N/A return (check_priv(res, method, resource, subject, policy_flags,
36N/A misc, pset_win_config));
0N/A }
0N/A}
0N/A
0N/A/*
0N/A * check_priv: Use this for all policies that require
0N/A * no MAC/DAC, but a priv
0N/A */
0N/Aint
0N/Acheck_priv(xresource_t res, xmethod_t method, void *resource,
36N/A void *subject, xpolicy_t policy_flags, void *misc, priv_set_t *priv)
0N/A{
0N/A int ret_stat = PASSED;
0N/A int err_code = BadValue;
0N/A Bool do_audit = FALSE;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A /*
0N/A * No MAC/DAC check.
0N/A */
0N/A if (tsolinfo->flags & CONFIG_AUDITED)
0N/A {
0N/A do_audit = FALSE;
0N/A }
0N/A else if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A {
0N/A do_audit = TRUE;
0N/A tsolinfo->flags |= CONFIG_AUDITED;
0N/A }
0N/A if (xpriv_policy(tsolinfo->privs, priv, res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A ret_stat = err_code;
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XCLIENT, client->index, AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A}
0N/A
0N/A/*
0N/A * Converts SL to string
0N/A */
0N/Achar *
0N/Axsltos(bslabel_t *sl)
0N/A{
0N/A char *slstring = NULL;
0N/A
0N/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}
0N/A
0N/A/*
0N/A * read_selection
0N/A */
0N/Aint
0N/Aread_selection(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadAtom;
0N/A Selection *selection = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolSelnPtr tsolseln = (TsolSelnPtr)(selection->secPrivate);
0N/A
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!bldominates(tsolinfo->sl, tsolseln->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_read,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A SXTSOLERR("mac", (int) misc, tsolseln->sl,
0N/A tsolseln->uid, tsolseln->pid, tsolseln->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read selection",
0N/A NameForAtom(selection->selection));
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A /* uid == DEF_UID means public window, shared read */
0N/A if (!(tsolseln->uid == DEF_UID || tsolinfo->uid == tsolseln->uid))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_read,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A SXTSOLERR("dac", (int) misc, tsolseln->sl,
0N/A tsolseln->uid, tsolseln->pid, tsolseln->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read selection",
0N/A NameForAtom(selection->selection));
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XATOM, NameForAtom(selection->selection),
0N/A AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* read_selection */
0N/A
0N/A/*
0N/A * modify_propwin. This is slightly different from modify_window in that
0N/A * Anyone can create/change properties on root.
0N/A */
0N/Aint
0N/Amodify_propwin(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadWindow;
0N/A WindowPtr pWin = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres =
0N/A (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A
0N/A /*
0N/A * Anyone can modify properties on RootWindow subjected to
0N/A * property policies.
0N/A */
0N/A if (WindowIsRoot(pWin))
0N/A {
0N/A return (PASSED);
0N/A }
0N/A/*
0N/A if (XTSOLTrusted(pWin))
0N/A {
0N/A if (!HasTrustedPath(tsolinfo))
0N/A {
0N/A XTSOLERR("tp", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify propwin", pWin->drawable.id);
0N/A return (err_code);
0N/A }
0N/A }
0N/A*/
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, tsolres->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify propwin", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != tsolres->uid)
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify propwin", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XWINDOW, pWin->drawable.id, tsolres->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* modify_propwin */
0N/A
0N/A/*
0N/A * modify_focuswin - Focus Window policy
0N/A * Focus window can be None is checked outside of this func
0N/A */
0N/Aint
0N/Amodify_focuswin(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadWindow;
0N/A WindowPtr pWin = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres =
0N/A (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A GrabPtr grab;
0N/A
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, tsolres->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify focuswin", pWin->drawable.id);
0N/A do_audit = FALSE; /* don't audit this */
0N/A unset_audit_flags(tsolinfo);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != tsolres->uid)
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify focuswin", pWin->drawable.id);
0N/A do_audit = FALSE; /* don't audit this */
0N/A unset_audit_flags(tsolinfo);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * Trusted Path Windows require Trusted Path attrib
0N/A */
0N/A if ((ret_stat == PASSED) && XTSOLTrusted(pWin))
0N/A {
0N/A if (!HasTrustedPath(tsolinfo))
0N/A {
0N/A XTSOLERR("tp", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify focuswin", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A#if 0
0N/A /*
0N/A * This causes problems when dragging cmdtool
0N/A * TBD later
0N/A * If ptr/kbd is grabbed, then this client must be
0N/A * the grabbing client
0N/A */
0N/A grab = inputInfo.pointer->grab;
0N/A if (grab == NULL)
0N/A grab = inputInfo.keyboard->grab;
0N/A if (grab)
0N/A {
0N/A if (!SameClient(grab, client))
0N/A {
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_devices,
0N/A res, method, client))
0N/A {
0N/A /* audit? */
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("tp", (int) misc,
0N/A tsolres->sl, tsolres->uid, tsolres->pid, tsolres->pname, \
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid, tsolinfo->pname, \
0N/A "modify focuswin", pWin->drawable.id);
0N/A return (err_code);
0N/A }
0N/A }
0N/A }
0N/A#endif
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XWINDOW, pWin->drawable.id, tsolres->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* modify_focuswin */
0N/A
0N/A/*
0N/A * read_focuswin
0N/A */
0N/Aint
0N/Aread_focuswin(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadWindow;
0N/A WindowPtr pWin = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres =
0N/A (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A
0N/A /*
0N/A * Anyone can read RootWindow attributes
0N/A */
0N/A if (WindowIsRoot(pWin))
0N/A {
0N/A return (PASSED);
0N/A }
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!(bldominates(tsolinfo->sl, tsolres->sl)))
0N/A {
0N/A if (!(tsolinfo->flags & MAC_READ_AUDITED) &&
0N/A (tsolinfo->flags & TSOL_AUDITEVENT))
0N/A {
0N/A do_audit = TRUE;
0N/A tsolinfo->flags |= MAC_READ_AUDITED;
0N/A }
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_read,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read focuswin", pWin->drawable.id);
0N/A do_audit = FALSE; /* don't audit this */
0N/A unset_audit_flags(tsolinfo);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if ((tsolinfo->uid != tsolres->uid) && (tsolres->uid != 0))
0N/A {
0N/A if (!(tsolinfo->flags & DAC_READ_AUDITED) &&
0N/A (tsolinfo->flags & TSOL_AUDITEVENT))
0N/A {
0N/A do_audit = TRUE;
0N/A tsolinfo->flags |= DAC_READ_AUDITED;
0N/A }
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_read,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "read focuswin", pWin->drawable.id);
0N/A do_audit = FALSE; /* don't audit */
0N/A unset_audit_flags(tsolinfo);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XWINDOW, pWin->drawable.id, tsolres->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* read_focuswin */
0N/A
0N/A#ifdef DEBUG
0N/A/*
0N/A * XTsolErr : used for debugging.
0N/A * WARNING: ErrorF can take upto 10 args & no more
0N/A */
0N/Avoid
0N/AXTsolErr(char *err_type, int protocol, bslabel_t *osl, uid_t ouid, pid_t opid,
0N/A char *opname, bslabel_t *ssl, uid_t suid, pid_t spid, char *spname,
0N/A char *method, int isstring, void *xid)
0N/A{
0N/A if (xtsol_debug < XTSOL_FAIL)
0N/A return;
0N/A if (protocol == X_QueryTree || protocol == X_GetInputFocus)
0N/A return;
0N/A /* range check of protocol */
0N/A if (protocol > X_NoOperation)
0N/A protocol = 0; /* unknown or extension */
0N/A ErrorF("\n%s failed:%s,obj(%s,%d,%d,%s), subj(%s,%d,%d,%s),",
0N/A err_type, ProtoNames[protocol], xsltos(osl), ouid,
0N/A opid, opname, xsltos(ssl), suid, spid, spname);
0N/A if (isstring)
0N/A {
0N/A ErrorF("%s, xid=%s\n", method, (char *) xid); /* for atom/prop names */
0N/A }
0N/A else
0N/A {
0N/A ErrorF("%s, xid=%X\n", method, (long) xid); /* for window/pixmaps */
0N/A }
0N/A}
0N/A#endif /* DEBUG */
0N/A
0N/A/*
0N/A * read_extn
0N/A */
0N/Aint
0N/Aread_extn(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int err_code = BadAccess;
0N/A char *extn_name = (char *)resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A /*
0N/A * No policy for this
0N/A */
0N/A
0N/A /*
0N/A if (extn_name != NULL & *extn_name != '\0')
0N/A ErrorF("Access to %s extension allowed\n", extn_name);
0N/A */
0N/A return (PASSED);
0N/A}
0N/A
0N/A/*
0N/A * modify_window
0N/A */
0N/Aint
0N/Amodify_tpwin(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadWindow;
0N/A WindowPtr pWin = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres =
0N/A (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A
0N/A /*
0N/A * MAC Check
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!blequal(tsolinfo->sl, tsolres->sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify tpwin", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A if (tsolinfo->uid != tsolres->uid)
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify tpwin", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * Trusted Path Windows require Trusted Path attrib
0N/A */
0N/A if ((ret_stat == PASSED) && XTSOLTrusted(pWin))
0N/A {
0N/A if (!HasTrustedPath(tsolinfo))
0N/A {
0N/A XTSOLERR("tp", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify tpwin", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XWINDOW, pWin->drawable.id, tsolres->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* modify_tpwin */
0N/A
0N/A/*
0N/A * modify_sl
0N/A * requires win_upgrade/downgrade_sl privs
0N/A * misc parameter is actually sl of resource & not the protocol no.
0N/A * misc == NULL means we are trying to set session hi/lo clearance
0N/A */
0N/Aint
0N/Amodify_sl(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadAccess;
0N/A bslabel_t *sl = (bslabel_t *)resource; /* sl to be set */
0N/A bslabel_t *res_sl = (bslabel_t *)misc; /* resource sl */
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A /*
0N/A * Are we trying to check for session hi/lo clearance
0N/A */
0N/A if (misc == NULL)
0N/A {
0N/A if (priv_win_config)
0N/A return (ret_stat);
0N/A
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_config,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A#ifdef DEBUG
0N/A ErrorF("modify_sl: failed for %s\n", tsolinfo->pname);
0N/A#endif /* DEBUG */
0N/A ret_stat = err_code;
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_SLABEL, sl, AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A }
0N/A /*
0N/A * No MAC/DAC Check. Check only for upgrade/downgrade priv
0N/A */
0N/A if (bldominates(sl, res_sl))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_upgrade_sl,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A#ifdef DEBUG
0N/A ErrorF("modify_sl: failed for %s\n", tsolinfo->pname);
0N/A#endif /* DEBUG */
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A else
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_downgrade_sl,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A#ifdef DEBUG
0N/A ErrorF("modify_sl: failed for %s\n", tsolinfo->pname);
0N/A#endif /* DEBUG */
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_SLABEL, sl, AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* modify_sl */
0N/A
0N/A
0N/A/*
0N/A * modify_eventwin
0N/A */
0N/Aint
0N/Amodify_eventwin(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A Bool do_audit = FALSE;
0N/A int err_code = BadWindow;
0N/A WindowPtr pWin = resource;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A TsolResPtr tsolres =
0N/A (TsolResPtr)(pWin->devPrivates[tsolWindowPrivateIndex].ptr);
0N/A TsolInfoPtr tsolownerinfo; /*client who owns the window */
0N/A ClientPtr ownerclient;
0N/A
0N/A ownerclient = clients[CLIENT_ID(pWin->drawable.id)];
0N/A tsolownerinfo = GetClientTsolInfo(ownerclient);
0N/A
0N/A /*
0N/A * Anyone can send event to root win
0N/A */
0N/A if (WindowIsRoot(pWin) || XTSOLTrusted(pWin))
0N/A {
0N/A return (PASSED);
0N/A }
0N/A /*
0N/A * MAC Check
0N/A * NOTE: window sl must dominate the client's sl for send event
0N/A */
0N/A if (policy_flags & TSOL_MAC)
0N/A {
0N/A if (!bldominates(tsolres->sl, tsolinfo->sl))
0N/A {
0N/A /*
0N/A * event sends to windows owned by client with priv_win_seln
0N/A * particularly front panel whose sl is admin_low
0N/A */
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit) ||
0N/A (tsolownerinfo && HasWinSelection(tsolownerinfo)))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("mac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify eventwin", pWin->drawable.id);
0N/A ret_stat = ret_stat;
0N/A }
0N/A }
0N/A }
0N/A /*
0N/A * DAC Check
0N/A */
0N/A if ((ret_stat == PASSED) && policy_flags & TSOL_DAC)
0N/A {
0N/A /* uid == DEF_UID means public window */
0N/A if (!(XTSOLTrusted(pWin) ||
0N/A tsolres->uid == DEF_UID ||
0N/A tsolinfo->uid == tsolres->uid))
0N/A {
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A XTSOLERR("dac", (int) misc, tsolres->sl,
0N/A tsolres->uid, tsolres->pid, tsolres->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify eventwin", pWin->drawable.id);
0N/A ret_stat = err_code;
0N/A }
0N/A }
0N/A }
0N/A if (do_audit)
0N/A {
0N/A set_audit_flags(tsolinfo);
0N/A auditwrite(AW_XWINDOW, pWin->drawable.id, tsolres->uid,
0N/A AW_APPEND, AW_END);
0N/A }
0N/A return (ret_stat);
0N/A} /* modify_eventwin */
0N/A
0N/A/*
0N/A * modify_stripe
0N/A * Trusted stripe requires only trusted path attrib
0N/A */
0N/Aint
0N/Amodify_stripe(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int err_code = BadAccess;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (!HasTrustedPath(tsolinfo))
0N/A {
0N/A XTSOLERR("tp", (int) misc, tsolinfo->sl,
0N/A tsolinfo->uid, tsolinfo->pid, tsolinfo->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify stripe", 0);
0N/A return (err_code);
0N/A }
0N/A return (PASSED);
0N/A}
0N/A
0N/A/*
0N/A * modify_wowner
0N/A * set workstation owner
0N/A */
0N/Aint
0N/Amodify_wowner(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int err_code = BadAccess;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (!HasTrustedPath(tsolinfo))
0N/A {
0N/A XTSOLERR("tp", (int) misc, tsolinfo->sl,
0N/A tsolinfo->uid, tsolinfo->pid, tsolinfo->pname,
0N/A tsolinfo->sl, tsolinfo->uid, tsolinfo->pid,
0N/A tsolinfo->pname, "modify tpwin", 0);
0N/A return (err_code);
0N/A }
0N/A return (PASSED);
0N/A}
0N/A
0N/A/*
0N/A * modify_uid
0N/A * Set UID for resource
0N/A */
0N/Aint
0N/Amodify_uid(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A int err_code = BadAccess;
0N/A Bool do_audit = FALSE;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A {
0N/A#ifdef DEBUG
0N/A ErrorF("modify_uid: failed for %s\n", tsolinfo->pname);
0N/A#endif /* DEBUG */
0N/A ret_stat = err_code;
0N/A }
0N/A if (do_audit)
0N/A set_audit_flags(tsolinfo);
0N/A return (ret_stat);
0N/A}
0N/A
0N/A/*
0N/A * modify_polyinfo
0N/A * Modify polyinstantiation info(sl, uid)
0N/A */
0N/Aint
0N/Amodify_polyinfo(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int ret_stat = PASSED;
0N/A int err_code = BadAccess;
0N/A Bool do_audit = FALSE;
0N/A ClientPtr client = subject;
0N/A TsolInfoPtr tsolinfo = GetClientTsolInfo(client);
0N/A
0N/A if (tsolinfo->flags & TSOL_AUDITEVENT)
0N/A do_audit = TRUE;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_mac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
36N/A if (xpriv_policy(tsolinfo->privs, pset_win_dac_write,
0N/A res, method, client, do_audit))
0N/A {
0N/A ret_stat = PASSED;
0N/A }
0N/A else
0N/A ret_stat = err_code;
0N/A }
0N/A else
0N/A ret_stat = err_code;
0N/A#ifdef DEBUG
0N/A ErrorF("modify_polyinfo: failed for %s\n", tsolinfo->pname);
0N/A#endif /* DEBUG */
0N/A if (do_audit)
0N/A set_audit_flags(tsolinfo);
0N/A return (ret_stat);
0N/A}
0N/A
0N/A/*
0N/A * access_dbe - check whether the buffer is client-private
0N/A */
0N/Aint
0N/Aaccess_dbe(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A ClientPtr client = subject;
0N/A XID object = (XID) resource;
0N/A
0N/A if (client_private(client, object))
0N/A return (PASSED);
0N/A else
0N/A return BadAccess;
0N/A}
0N/A
0N/A/*
0N/A * swap_dbe - check if the window is created by the client
0N/A */
0N/Aint
0N/Aswap_dbe(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A WindowPtr pWin = resource;
0N/A ClientPtr client = subject;
0N/A
0N/A if (SAMECLIENT(client, pWin->drawable.id))
0N/A return PASSED;
0N/A else
0N/A return BadAccess;
0N/A}
0N/A
0N/A/*
0N/A * Return value of 0 success, errcode for failure
0N/A *
0N/A * Dummy function.
0N/A */
0N/Astatic int
0N/Ano_policy(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A#ifdef DEBUG
0N/A ErrorF("policy not implemented for res=%d, method=%d\n",
0N/A res, method);
0N/A#endif /* DEBUG */
0N/A return (PASSED);
0N/A}
0N/A
0N/A/*
0N/A * X POLICY FUNCTION TABLE. One row per resource.
0N/A *
0N/A * TSOL_RES_NAME READ MODIFY CREATE\
0N/A * DESTROY SPECIAL
0N/A */
0N/Astatic int (*XTSOL_policy_table[TSOL_MAX_XRES_TYPES][TSOL_MAX_XMETHODS])() = {
0N/A/* TSOL_RES_ACL */ no_policy, modify_acl, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_ATOM */ read_atom, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_BELL */ no_policy, modify_devices, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_BTNGRAB */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_CCELL */ read_ccell, modify_ccell, no_policy,\
0N/A destroy_ccell, no_policy,
0N/A/* TSOL_RES_CLIENT */ read_client, modify_client, no_policy,\
0N/A destroy_client, no_policy,
0N/A/* TSOL_RES_CMAP */ read_cmap, modify_cmap, no_policy,\
0N/A modify_cmap, install_cmap,
0N/A/* TSOL_RES_CONFWIN */ no_policy, modify_confwin, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_CURSOR */ no_policy, modify_cursor, no_policy,\
0N/A modify_cursor, no_policy,
0N/A/* TSOL_RES_EVENTWIN */ no_policy, modify_eventwin, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_EXTN */ read_extn, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_FOCUSWIN */ read_focuswin, modify_focuswin, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_FONT */ read_font, modify_font, no_policy,\
0N/A modify_font, no_policy,
0N/A/* TSOL_RES_FONTLIST */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_FONTPATH */ no_policy, modify_fontpath, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_GC */ read_gc, modify_gc, no_policy,\
0N/A modify_gc, no_policy,
0N/A/* TSOL_RES_GRABWIN */ no_policy, modify_grabwin, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_HOSTLIST */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_IL */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_KBDCTL */ no_policy, modify_devices, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_KBDGRAB */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_KEYGRAB */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_KEYMAP */ read_devices, modify_devices, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_MODMAP */ no_policy, modify_devices, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_PIXEL */ read_pixel, modify_pixel, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_PIXMAP */ read_pixmap, modify_pixmap, no_policy,\
0N/A destroy_pixmap, no_policy,
0N/A/* TSOL_RES_POLYINFO */ no_policy, modify_polyinfo, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_PROPERTY */ read_property, modify_property, no_policy,\
0N/A destroy_property, no_policy,
0N/A/* TSOL_RES_PROPWIN */ read_window, modify_propwin, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_IIL */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_PROP_SL */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_PROP_UID */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_PTRCTL */ no_policy, modify_devices, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_PTRGRAB */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_PTRLOC */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_PTRMAP */ no_policy, modify_devices, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_PTRMOTION */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_SCRSAVER */ no_policy, modify_devices, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_SELECTION */ read_selection, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_SELNWIN */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_SENDEVENT */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_SL */ no_policy, modify_sl, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_SRVGRAB */ no_policy, no_policy, create_srvgrab,\
0N/A destroy_srvgrab, no_policy,
0N/A/* TSOL_RES_STRIPE */ no_policy, modify_stripe, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_TPWIN */ no_policy, modify_tpwin, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_UID */ no_policy, modify_uid, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_VISUAL */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_WINATTR */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_WINDOW */ read_window, modify_window, create_window,\
0N/A destroy_window, no_policy,
0N/A/* TSOL_RES_WINLOC */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_WINMAP */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_WINSIZE */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_WINSTACK */ no_policy, no_policy, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_WOWNER */ no_policy, modify_wowner, no_policy,\
0N/A no_policy, no_policy,
0N/A/* TSOL_RES_DBE */ no_policy, no_policy, access_dbe,
0N/A access_dbe, swap_dbe
0N/A};
0N/A
0N/Astruct xpolicy_cache {
0N/A xresource_t res;
0N/A xmethod_t method;
0N/A void *resource;
0N/A void *subject;
0N/A xpolicy_t policy_flags;
0N/A int ret_value;
0N/A int count;
0N/A};
0N/Astatic struct xpolicy_cache policy_cache;
0N/A
0N/A/*
0N/A * main xtsol_policy. External interface to dix layer of X server
0N/A */
0N/Aint
0N/Axtsol_policy(xresource_t res, xmethod_t method, void *resource,
0N/A void *subject, xpolicy_t policy_flags, void *misc)
0N/A{
0N/A int res_type;
0N/A int ret_value;
0N/A
0N/A assert(res >= TSOL_START_XRES && res < TSOL_MAX_XRES_TYPES);
0N/A assert(method >= 0 && method < TSOL_MAX_XMETHODS);
0N/A assert(policy_flags != 0);
0N/A res_type = (int)(res - TSOL_START_XRES);
0N/A
0N/A if (policy_cache.subject == subject &&
0N/A policy_cache.res == res &&
0N/A policy_cache.method == method &&
0N/A policy_cache.resource == resource &&
0N/A policy_cache.policy_flags == policy_flags)
0N/A {
0N/A
0N/A policy_cache.count++;
0N/A return policy_cache.ret_value;
0N/A } else {
0N/A policy_cache.res = res;
0N/A policy_cache.method = method;
0N/A policy_cache.resource = resource;
0N/A policy_cache.subject = subject;
0N/A policy_cache.policy_flags = policy_flags;
0N/A
0N/A ret_value = ((XTSOL_policy_table[res_type][method]) (res,
0N/A method, resource, subject, policy_flags, misc));
0N/A policy_cache.ret_value = ret_value;
0N/A
0N/A return ret_value;
0N/A }
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
36N/Ainit_win_privsets()
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
36N/Afree_win_privsets()
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