python-27: make tkinter-27 dependency actually conditional
[unleashed-userland.git] / components / x11 / xorg-server / srcs / tsol / tsolutils.c
blobe6b6c4d95696537a9f7e2b56217c58b1c5e59f90
1 /*
2 * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
25 #ifdef HAVE_DIX_CONFIG_H
26 #include <dix-config.h>
27 #endif
29 #include <stdio.h>
30 #include <X11/X.h>
31 #include <X11/Xproto.h>
32 #include <X11/Xprotostr.h>
33 #include "auditwrite.h"
34 #include <bsm/audit_uevents.h>
35 #include <regex.h>
36 #include <priv.h>
37 #include <X11/Xproto.h>
38 #include "windowstr.h"
39 #include "scrnintstr.h"
40 #include "xkbstr.h"
41 #include "xkbsrv.h"
42 #include "tsol.h"
43 #include "tsolinfo.h"
44 #include "tsolpolicy.h"
45 #include <X11/keysym.h>
46 #include "misc.h"
47 #include "inputstr.h"
48 #include "propertyst.h"
49 #include "panoramiXsrv.h"
50 #include "registry.h"
52 #define MAX_SL_ENTRY 256
53 #define MAX_UID_ENTRY 64
54 #define ALLOCATED 1
55 #define EMPTIED 0
56 #define FamilyTSOL 5
57 #define TSOLUIDlength 4
59 #define BOXES_OVERLAP(b1, b2) \
60 (!( ((b1)->x2 <= (b2)->x1) || \
61 ( ((b1)->x1 >= (b2)->x2)) || \
62 ( ((b1)->y2 <= (b2)->y1)) || \
63 ( ((b1)->y1 >= (b2)->y2)) ) )
65 Bool priv_win_colormap = FALSE;
66 Bool priv_win_config = FALSE;
67 Bool priv_win_devices = FALSE;
68 Bool priv_win_dga = FALSE;
69 Bool priv_win_fontpath = FALSE;
73 * The following need to be moved to tsolextension.c
74 * after all references in Xsun is pulled out
76 WindowPtr tpwin = NULL; /* only one trusted path window at a time */
77 TsolPolyInstInfoRec tsolpolyinstinfo;
78 #define TsolMaxPolyNameSize 80
80 * Use the NodeRec struct in tsolinfo.h. This is referenced
81 * in policy routines. So we had to move it there
83 static TsolPolyAtomRec tsolpolyprop = {FALSE, 0, 0, NULL};
84 static TsolPolyAtomRec tsolpolyseln = {TRUE, 0, 0, NULL};
86 bclear_t SessionHI; /* HI Clearance */
87 bclear_t SessionLO; /* LO Clearance */
88 unsigned int StripeHeight = 0;
89 uid_t OwnerUID = (uid_t)(-1);
90 bslabel_t PublicObjSL;
92 Atom tsol_lastAtom = None;
93 int tsol_nodelength = 0;
94 TsolNodePtr tsol_node = NULL;
96 /* This structure is used for protocol request ListHosts */
97 struct xUIDreply
99 unsigned char family;
100 unsigned char pad;
101 unsigned short length;
102 int uid; /* uid type */
105 struct slentry
107 bslabel_t senlabel;
108 char allocated;
111 static struct slentry sltable[MAX_SL_ENTRY];
113 /* This table contains list of users who can connect to the server */
114 struct uidentry
116 int userid; /* uid type */
117 char allocated;
120 static struct uidentry uidtable[MAX_UID_ENTRY];
122 /* Index must match with keywords */
123 static char *tsolconfig_keywords[] = {"atom", "property", "selection",
124 "extension", "privilege"};
126 #define KEYWORDCOUNT sizeof(tsolconfig_keywords)/sizeof(char *)
128 typedef struct _TsolConfig
130 int count;
131 char **list;
132 } TsolConfigRec;
134 static TsolConfigRec tsolconfig[KEYWORDCOUNT] = {
135 {0, NULL},
136 {0, NULL},
137 {0, NULL},
138 {0, NULL},
139 {0, NULL}
142 #define TSOL_ATOMCOUNT 4
143 static const char *tsolatomnames[TSOL_ATOMCOUNT] = {
144 "_TSOL_CMWLABEL_CHANGE",
145 "_TSOL_GRABNOTIFY",
146 "_TSOL_CLIENT_TERM",
147 "_TSOL_SEL_AGNT"
150 static void
151 init_TSOL_cached_SL(void)
153 sltable[0].allocated = ALLOCATED;
154 bsllow (&(sltable[0].senlabel));
156 sltable[1].allocated = ALLOCATED;
157 bslhigh(&(sltable[1].senlabel));
161 /* Initialize UID table, this table should at least contains owner UID */
162 static void
163 init_TSOL_uid_table(void)
165 uidtable[0].allocated = ALLOCATED;
166 uidtable[0].userid = 0;
169 #if UNUSED
170 /* Count how many valid entried in the uid table */
172 count_uid_table(void)
174 int i, count = 0;
176 /* Search entire table */
177 for (i = 0; i < MAX_UID_ENTRY; i++)
179 if (uidtable[i].allocated == ALLOCATED)
180 count++;
182 return (count);
185 /* return (1); if userid is in the table */
187 lookupUID(int userid)
189 int i;
190 for (i = 0; i < MAX_UID_ENTRY; i++)
192 if (uidtable[i].allocated == ALLOCATED &&
193 uidtable[i].userid == userid)
195 return (1); /* yes, found it */
198 return (0); /* not found */
201 /* Passed into a pointer to a storage which is used to store UID */
202 /* and nUid represents how many UID in the table(returned by count_uid_table) */
204 ListUID(
205 struct xUIDreply * uidaddr,
206 int nUid)
208 int i, j = 0;
210 for (i = 0; i < MAX_UID_ENTRY; i++)
212 if (uidtable[i].allocated == ALLOCATED)
214 uidaddr[j].family = FamilyTSOL;
215 uidaddr[j].length = TSOLUIDlength;
216 uidaddr[j].uid = uidtable[i].userid;
217 j++;
220 if (nUid != j)
222 ErrorF("Invalid no. of uid entries? \n");
223 return (0);
226 return (1);
228 #endif /* UNUSED */
230 /* add userid into UIDtable */
232 AddUID(int *userid)
235 int i = 0;
238 * Search entire uidtable, to prevent duplicate uid
239 * entry in the table
241 while (i < MAX_UID_ENTRY)
243 if ((uidtable[i].allocated == ALLOCATED) &&
244 (uidtable[i].userid == *userid))
246 /* this uid entry is already in the table; no-op */
247 return (1); /* Success, uid in the table */
249 i++;
252 i = 0;
254 * If we can find an empty entry, then add this uid
255 * into the table
257 while (i < MAX_UID_ENTRY)
259 if (uidtable[i].allocated != ALLOCATED)
261 uidtable[i].allocated = ALLOCATED;
262 uidtable[i].userid = *userid;
263 return (1); /* Success, uid in the table */
265 i++;
268 /* uidtable overflow */
269 ErrorF("Server problem: Please enlarge the table size of uidtable \n");
270 return (0);
273 #if UNUSED
274 /* remove userid from UIDtable */
276 RemoveUID(int *userid)
278 int i = 0;
280 if (*userid == 0)
282 ErrorF("\n UID 0 can not be removed from server UID list");
283 return (0);
286 while (i < MAX_UID_ENTRY)
288 if ((uidtable[i].allocated == ALLOCATED) &&
289 (uidtable[i].userid == *userid))
291 /* delete this entry in the table */
292 uidtable[i].allocated = EMPTIED;
293 return (1); /* Success, uid in the table */
296 i++;
299 /* no such entry in the table, why delete it? no-op */
300 return (0);
302 #endif
307 bslabel_t *
308 lookupSL_low(void)
310 return (&(sltable[0].senlabel));
314 bslabel_t *
315 lookupSL(bslabel_t *slptr)
317 int i = 0;
319 if (slptr == NULL)
320 return (slptr);
322 while ((i < MAX_SL_ENTRY) && sltable[i].allocated == ALLOCATED)
324 if (blequal(slptr, &(sltable[i].senlabel)))
326 /* found a matching sensitivity label in sltable */
327 return (&(sltable[i].senlabel));
329 i++;
332 if (i < MAX_SL_ENTRY)
335 * can't find a matching entry in sltable,
336 * however, we have empty entry to store this
337 * new sensitivity label; store it.
339 sltable[i].allocated = ALLOCATED;
340 memcpy (&(sltable[i].senlabel), slptr, sizeof (bslabel_t));
341 return (&(sltable[i].senlabel));
345 * no matching entry in sltable, and no room to
346 * store this new sensitivity label,
347 * the server needs to recomplie with a larger slabel
350 ErrorF("Server problem: Please enlarge the table size of sltable \n");
351 return (NULL);
354 static const int padlength[4] = {0, 3, 2, 1};
356 /* Updated version based roughly on RREditConnectionInfo in randr/rrscreen.c */
358 DoScreenStripeHeight(int screen_num)
360 int i, j;
361 xConnSetup *connSetup;
362 char *vendor;
363 xPixmapFormat *formats;
364 xWindowRoot *root;
365 xDepth *depth;
366 xVisualType *visual;
367 ScreenPtr pScreen;
368 int old_height;
369 float height_mult;
371 connSetup = (xConnSetup *) ConnectionInfo;
372 vendor = (char *) connSetup + sizeof (xConnSetup);
373 formats = (xPixmapFormat *) ((char *) vendor +
374 connSetup->nbytesVendor +
375 padlength[connSetup->nbytesVendor & 3]);
376 root = (xWindowRoot *) ((char *) formats +
377 sizeof (xPixmapFormat) *
378 screenInfo.numPixmapFormats);
379 for (i = 0; i < screen_num; i++)
381 depth = (xDepth *) ((char *) root +
382 sizeof (xWindowRoot));
383 for (j = 0; j < (int)root->nDepths; j++)
385 visual = (xVisualType *) ((char *) depth +
386 sizeof (xDepth));
387 depth = (xDepth *) ((char *) visual +
388 depth->nVisuals *
389 sizeof (xVisualType));
392 root = (xWindowRoot *) ((char *) depth);
394 old_height = root->pixHeight;
396 if (noPanoramiXExtension)
398 pScreen = screenInfo.screens[screen_num];
399 root->pixHeight = pScreen->height - StripeHeight;
400 } else
402 root->pixHeight = PanoramiXPixHeight - StripeHeight;
405 /* compute new millimeter height */
406 height_mult = (1.0 * root->pixHeight) / old_height;
407 root->mmHeight *= height_mult;
409 return (0);
412 void
413 init_xtsol(void)
415 bclearhigh(&SessionHI);
416 bclearlow(&SessionLO);
417 bsllow(&PublicObjSL);
418 init_TSOL_cached_SL();
419 init_TSOL_uid_table();
421 auditwrite(AW_QUEUE, XAUDIT_Q_SIZE, AW_END);
425 * Converts keycode to keysym, helper function.
426 * Modelled after Xlib code
428 static KeySym
429 KeycodetoKeysym(KeyCode keycode, int col, KeySymsPtr curKeySyms)
431 int per = curKeySyms->mapWidth;
432 KeySym *syms = curKeySyms->map;
433 KeySym lsym = 0, usym = 0;
435 if ((col < 0) || ((col >= per) && (col > 3)) ||
436 ((int)keycode < curKeySyms->minKeyCode) ||
437 ((int)keycode > curKeySyms->maxKeyCode))
438 return NoSymbol;
440 syms = &curKeySyms->map[(keycode - curKeySyms->minKeyCode) * per];
441 if (col < 4) {
442 if (col > 1) {
443 while ((per > 2) && (syms[per - 1] == NoSymbol))
444 per--;
445 if (per < 3)
446 col -= 2;
448 if ((per <= (col|1)) || (syms[col|1] == NoSymbol)) {
449 if (!(col & 1))
450 return lsym;
451 else if (usym == lsym)
452 return NoSymbol;
453 else
454 return usym;
457 return syms[col];
461 * Converts keysym to a keycode
462 * Modelled after Xlib code
464 static KeyCode
465 KeysymToKeycode(KeySym ks, KeySymsPtr curKeySyms)
467 int i, j;
469 for (j = 0; j < curKeySyms->mapWidth; j++) {
470 for (i = curKeySyms->minKeyCode; i <= curKeySyms->maxKeyCode; i++) {
471 if (KeycodetoKeysym((KeyCode) i, j, curKeySyms) == ks)
472 return i;
475 return 0;
479 * converts a keysym to modifier equivalent mask
480 * Modelled after Xlib
482 static unsigned
483 KeysymToModifier(KeySym ks, KeySymsPtr keysyms,
484 KeyCode *modifierKeyMap, int maxKeysPerModifier)
486 CARD8 code, mods;
487 KeySym *kmax;
488 KeySym *k;
490 kmax = keysyms->map + (keysyms->maxKeyCode - keysyms->minKeyCode + 1) *
491 keysyms->mapWidth;
492 k = keysyms->map;
493 mods = 0;
494 while (k < kmax) {
495 if (*k == ks ) {
496 int j = maxKeysPerModifier << 3;
498 code = (((k - keysyms->map) / keysyms->mapWidth) + keysyms->minKeyCode);
500 while (--j >= 0) {
501 if (code == modifierKeyMap[j])
502 mods |= (1 << (j / maxKeysPerModifier));
505 k++;
507 return mods;
511 * Initialize Hot Key keys. On A Sun type 5/6 keyboard
512 * It's Meta(Diamond) + Stop. On a non-Sun keyboard, it's
513 * Alt + Break(Pause) key. Hold down the meta or alt key
514 * press stop or break key.
516 * NOTE:
517 * Both Left & Right keys for (Meta or Alt) return the
518 * same modifier mask
520 void
521 InitHotKey(DeviceIntPtr keybd)
523 HotKeyPtr hk = TsolKeyboardPrivate(keybd);
524 KeySymsPtr curKeySyms = XkbGetCoreMap(keybd);
525 int rc;
526 int max_keys_per_mod = 0;
527 KeyCode *modkeymap = NULL;
529 rc = generate_modkeymap(serverClient, keybd,
530 &modkeymap, &max_keys_per_mod);
532 /* Meta + Stop */
533 hk->shift = KeysymToModifier(XK_Meta_L, curKeySyms,
534 modkeymap, max_keys_per_mod);
535 hk->key = KeysymToKeycode(XK_L1, curKeySyms);
537 /* Alt + Break/Pause */
538 hk->altshift = KeysymToModifier(XK_Alt_L, curKeySyms,
539 modkeymap, max_keys_per_mod);
540 hk->altkey = KeysymToKeycode(XK_Pause, curKeySyms);
542 hk->initialized = TRUE;
545 static void
546 UpdateTsolConfig(char *keyword, char *value)
548 int i;
549 int count;
550 char **newlist;
552 if (keyword == NULL || value == NULL)
553 return; /* ignore incomplete entries */
555 /* find a matching keyword */
556 for (i = 0; i < KEYWORDCOUNT; i++) {
557 if (strcmp(keyword, tsolconfig_keywords[i]) == 0) {
558 break;
562 /* Invalid keyword */
563 if (i >= KEYWORDCOUNT) {
564 ErrorF("Invalid keyword : %s\n", keyword);
565 return;
568 count = tsolconfig[i].count;
569 newlist = realloc(tsolconfig[i].list, (count + 1) * sizeof(char **));
570 if (newlist == NULL) {
571 ErrorF("Not enough memory for %s %s\n", keyword, value);
572 return;
575 newlist[count] = strdup(value);
576 tsolconfig[i].list = newlist;
577 tsolconfig[i].count++;
580 static void
581 InitPrivileges(void)
583 int i;
584 int count;
585 char **list;
587 count = tsolconfig[TSOL_PRIVILEGE].count;
588 list = tsolconfig[TSOL_PRIVILEGE].list;
590 for (i = 0; i < count; i++) {
591 if (strcmp(list[i], PRIV_WIN_COLORMAP) == 0)
592 priv_win_colormap = TRUE;
593 else if (strcmp(list[i], PRIV_WIN_CONFIG) == 0)
594 priv_win_config = TRUE;
595 else if (strcmp(list[i], PRIV_WIN_DEVICES) == 0)
596 priv_win_devices = TRUE;
597 else if (strcmp(list[i], PRIV_WIN_FONTPATH) == 0)
598 priv_win_fontpath = TRUE;
599 else if (strcmp(list[i], PRIV_WIN_DGA) == 0)
600 priv_win_dga = TRUE;
605 * Load Trusted Solaris configuration file
607 void
608 LoadTsolConfig(void)
610 FILE *fp;
611 char buf[BUFSIZ];
612 char *keyword;
613 char *value;
615 /* open the file from /etc first followed by /usr */
616 if ((fp = fopen(TSOLPOLICYFILE, "r")) == NULL) {
617 ErrorF("Cannot load %s. Some desktop applications may not\n"
618 "work correctly\n", TSOLPOLICYFILE);
619 return;
622 /* Read and parse the config file */
623 while (fgets(buf, sizeof (buf), fp) != NULL) {
625 /* ignore all comments, lines starting with white space */
626 if (buf[0] == '#' || isspace((int)buf[0]))
627 continue;
629 keyword = strtok(buf, " \t");
630 value = strtok(NULL, " \t\n");
631 UpdateTsolConfig(keyword, value);
633 fclose(fp);
635 InitPrivileges();
640 * It does not really tell if this atom is to be polyinstantiated
641 * or not. Further check should be done to determine this.
644 SpecialName(const char *string, int len)
647 return (MatchTsolConfig(string, len));
651 void
652 MakeTSOLAtoms(void)
654 int i;
655 char *atomname;
657 /* Create new TSOL atoms */
658 for (i = 0; i < TSOL_ATOMCOUNT; i++) {
659 if (MakeAtom(tsolatomnames[i], strlen(tsolatomnames[i]), TRUE) == None)
660 AtomError();
663 /* Create atoms defined in config file */
664 for (i = 0; i < tsolconfig[TSOL_ATOM].count; i++) {
665 atomname = tsolconfig[TSOL_ATOM].list[i];
666 if (MakeAtom(atomname, strlen(atomname), TRUE) == None) {
667 AtomError();
673 * Names starting with a slash in selection.atoms and property.atoms
674 * are treated as regular expressions to be matched against the
675 * selection and property names. They may optionally end with a slash.
677 static int
678 regexcompare(const char *string, int len, char *regexp)
680 int status;
681 regex_t compiledregexp;
682 char *regexpstrp;
683 int regexpstrlen;
684 char buffer[BUFSIZ];
686 if (regexp[0] == '/' && len < BUFSIZ) {
687 /* Extract regular expression from between slashes */
688 regexpstrp = regexp + 1;
689 regexpstrlen = strlen(regexpstrp);
690 if (regexpstrp[regexpstrlen - 1] == '/')
691 regexpstrp[regexpstrlen - 1] = '\0';
692 /* Compile the regular expression */
693 status = regcomp(&compiledregexp, regexpstrp,
694 REG_EXTENDED | REG_NOSUB);
695 if (status == 0) {
696 /* Make null-terminated copy of string */
697 memcpy(buffer, string, len);
698 buffer[len] = '\0';
699 /* Compare string to regular expression */
700 status = regexec(&compiledregexp,
701 buffer, (size_t) 0, NULL, 0);
702 regfree(&compiledregexp);
704 if (status == 0)
705 return (TRUE);
706 else
707 return (FALSE);
709 } else if (strncmp(string, regexp, len) == 0) {
710 return (TRUE);
713 return (FALSE);
717 MatchTsolConfig(const char *name, int len)
719 int i;
720 int count;
721 char **list;
722 unsigned int flags = 0;
724 count = tsolconfig[TSOL_PROPERTY].count;
725 list = tsolconfig[TSOL_PROPERTY].list;
726 for (i = 0; i < count; i++) {
727 if (regexcompare(name, len, list[i])) {
728 flags |= TSOLM_PROPERTY;
729 break;
733 count = tsolconfig[TSOL_SELECTION].count;
734 list = tsolconfig[TSOL_SELECTION].list;
735 for (i = 0; i < count; i++) {
736 if (regexcompare(name, len, list[i])) {
737 flags |= TSOLM_SELECTION;
738 break;
742 return (flags);
745 TsolInfoPtr
746 GetClientTsolInfo(ClientPtr client)
748 return TsolClientPrivate(client);
751 /* Property is polyinstantiated only on root window */
753 PolyProperty(Atom atom, WindowPtr pWin)
755 if (WindowIsRoot(pWin) &&
756 ((!tsolpolyprop.polyinst && !(tsol_node[atom].IsSpecial & TSOLM_PROPERTY)) ||
757 (tsolpolyprop.polyinst && (tsol_node[atom].IsSpecial & TSOLM_PROPERTY))))
758 return TRUE;
759 return FALSE;
763 PolySelection(Atom atom)
765 if ((tsolpolyseln.polyinst && (tsol_node[atom].IsSpecial & TSOLM_SELECTION)) ||
766 (!tsolpolyseln.polyinst && !(tsol_node[atom].IsSpecial & TSOLM_SELECTION)))
767 return TRUE;
768 return FALSE;
772 * client_private returns true if xid is owned/created by
773 * client or is a default server xid
776 client_private (ClientPtr client, XID xid)
778 if (same_client(client, xid) || (xid & SERVER_BIT))
779 return TRUE;
780 else
781 return FALSE;
784 * Same as TopClientWin()
785 * except that it returns a Window ID
786 * and not a ptr
788 Window
789 RootOfClient(WindowPtr pWin)
791 if (pWin)
793 return (TopClientWin(pWin)->drawable.id);
795 return (NULL);
798 #ifdef UNUSED
800 * Return root window of pWin
802 WindowPtr
803 RootWin(WindowPtr pWin)
805 if (pWin)
807 while (pWin->parent)
808 pWin = pWin->parent;
810 return (pWin);
812 #endif
814 Window
815 RootOf(WindowPtr pWin)
817 if (pWin)
819 while (pWin->parent)
820 pWin = pWin->parent;
821 return (pWin->drawable.id);
823 return (NULL);
828 * same_client returns true if xid is owned/created by
829 * client
832 same_client (ClientPtr client, XID xid)
834 TsolInfoPtr tsolinfo_client;
835 TsolInfoPtr tsolinfo_xid;
836 ClientPtr xid_client;
838 if (CLIENT_ID(xid) == 0 || (clients[CLIENT_ID(xid)] == NULL))
839 return FALSE;
841 if((SERVER_BIT & xid) == 0)
843 if (client->index == CLIENT_ID(xid))
844 return TRUE;
845 xid_client = clients[CLIENT_ID(xid)];
846 tsolinfo_client = GetClientTsolInfo(client);
847 tsolinfo_xid = GetClientTsolInfo(xid_client);
848 if (tsolinfo_client && tsolinfo_xid && tsolinfo_client->pid > 0)
850 if (tsolinfo_client->pid == tsolinfo_xid->pid)
851 return TRUE;
854 return FALSE;
857 WindowPtr
858 AnyWindowOverlapsJustMe(
859 WindowPtr pWin,
860 WindowPtr pHead,
861 register BoxPtr box)
863 register WindowPtr pSib;
864 BoxRec sboxrec;
865 register BoxPtr sbox;
866 TsolResPtr win_res = TsolWindowPrivate(pWin);
868 for (pSib = pWin->prevSib; (pSib != NULL && pSib != pHead); pSib = pSib->prevSib)
870 TsolResPtr sib_res = TsolWindowPrivate(pSib);
872 if (pSib->mapped && !bldominates(win_res->sl, sib_res->sl))
874 sbox = WindowExtents(pSib, &sboxrec);
875 if (BOXES_OVERLAP(sbox, box)
876 #ifdef SHAPE
877 && ShapeOverlap (pWin, box, pSib, sbox)
878 #endif
880 return(pSib);
883 return((WindowPtr)NULL);
886 * Return Top level client window of pWin
888 WindowPtr
889 TopClientWin(WindowPtr pWin)
891 ClientPtr client;
893 if (pWin)
895 client = wClient(pWin);
896 while (pWin->parent)
898 if (client != wClient(pWin->parent))
899 break;
900 pWin = pWin->parent;
903 return (pWin);
907 * Matches in the list of disabled extensions via
908 * the policy file (TrustedExtensionsPolicy)
909 * Returns
910 * TRUE - if a match is found
911 * FALSE - otherwise
914 TsolDisabledExtension(const char *extname)
916 int i;
918 for (i = 0; i < tsolconfig[TSOL_EXTENSION].count; i++) {
919 if (strcmp(extname, tsolconfig[TSOL_EXTENSION].list[i]) == 0) {
920 return TRUE;
924 return FALSE;
927 /*****************************************************************************/
928 /* Debug/error message utility functions */
930 /* Returns a string representation of the access mode for debugging messages */
931 _X_HIDDEN const char *
932 TsolDixAccessModeNameString(Mask access_mode) {
933 static char access_mode_str[1024];
934 int l = 0;
936 access_mode_str[0] = '\0';
938 #define APPEND_MODENAME_IF_SET(mode) \
939 if (access_mode & (mode)) \
940 l = strlcat(access_mode_str, #mode " | ", sizeof(access_mode_str))
942 APPEND_MODENAME_IF_SET(DixUnknownAccess);
943 APPEND_MODENAME_IF_SET(DixReadAccess);
944 APPEND_MODENAME_IF_SET(DixWriteAccess);
945 APPEND_MODENAME_IF_SET(DixDestroyAccess);
946 APPEND_MODENAME_IF_SET(DixCreateAccess);
947 APPEND_MODENAME_IF_SET(DixGetAttrAccess);
948 APPEND_MODENAME_IF_SET(DixSetAttrAccess);
949 APPEND_MODENAME_IF_SET(DixListPropAccess);
950 APPEND_MODENAME_IF_SET(DixGetPropAccess);
951 APPEND_MODENAME_IF_SET(DixSetPropAccess);
952 APPEND_MODENAME_IF_SET(DixGetFocusAccess);
953 APPEND_MODENAME_IF_SET(DixSetFocusAccess);
954 APPEND_MODENAME_IF_SET(DixListAccess);
955 APPEND_MODENAME_IF_SET(DixAddAccess);
956 APPEND_MODENAME_IF_SET(DixRemoveAccess);
957 APPEND_MODENAME_IF_SET(DixHideAccess);
958 APPEND_MODENAME_IF_SET(DixShowAccess);
959 APPEND_MODENAME_IF_SET(DixBlendAccess);
960 APPEND_MODENAME_IF_SET(DixGrabAccess);
961 APPEND_MODENAME_IF_SET(DixFreezeAccess);
962 APPEND_MODENAME_IF_SET(DixForceAccess);
963 APPEND_MODENAME_IF_SET(DixInstallAccess);
964 APPEND_MODENAME_IF_SET(DixUninstallAccess);
965 APPEND_MODENAME_IF_SET(DixSendAccess);
966 APPEND_MODENAME_IF_SET(DixReceiveAccess);
967 APPEND_MODENAME_IF_SET(DixUseAccess);
968 APPEND_MODENAME_IF_SET(DixManageAccess);
969 APPEND_MODENAME_IF_SET(DixDebugAccess);
970 APPEND_MODENAME_IF_SET(DixBellAccess);
972 if ( (l > 3) && (l < sizeof(access_mode_str)) ) {
973 /* strip off trailing " | " */
974 access_mode_str[l - 3] = '\0';
977 return access_mode_str;
980 /* Returns a string representation of the tsol policy for debugging messages */
981 _X_HIDDEN const char *
982 TsolPolicyReturnString(int pr)
984 if (pr == XTSOL_FAIL) {
985 return "FAIL";
986 } else if (pr == XTSOL_ALLOW) {
987 return "ALLOW";
988 } else if (pr == XTSOL_IGNORE) {
989 return "IGNORE";
990 } else {
991 static char str[32];
992 snprintf(str, sizeof(str), "<unknown value %d>", pr);
993 return str;
997 _X_HIDDEN const char *
998 TsolErrorNameString(int errcode)
1000 const char *regentry = LookupErrorName(errcode);
1002 if (strcmp(regentry, XREGISTRY_UNKNOWN) == 0) {
1003 static char unknown_string[32];
1005 snprintf(unknown_string, sizeof(unknown_string),
1006 "error code #%d", errcode);
1008 return unknown_string;
1011 return regentry;
1014 _X_HIDDEN const char *
1015 TsolResourceTypeString(RESTYPE resource)
1017 const char *regentry = LookupResourceName(resource);
1019 if (strcmp(regentry, XREGISTRY_UNKNOWN) == 0) {
1020 static char unknown_string[32];
1022 snprintf(unknown_string, sizeof(unknown_string),
1023 "resource type #%d", (uint_t) resource);
1025 return unknown_string;
1028 return regentry;
1031 _X_HIDDEN const char *
1032 TsolRequestNameString(int req)
1034 const char *regentry;
1036 if (req < 0) {
1037 return "<no request>";
1040 regentry = LookupMajorName(req);
1042 if (strcmp(regentry, XREGISTRY_UNKNOWN) == 0) {
1043 static char unknown_string[32];
1045 snprintf(unknown_string, sizeof(unknown_string),
1046 "request type #%d", req);
1048 return unknown_string;
1051 return regentry;