Bug Summary

File:xdm/access.c
Location:line 316, column 9
Description:Result of 'malloc' is converted to a pointer of type 'HostEntry', which is incompatible with sizeof operand type 'DisplayEntry'

Annotated Source Code

1/*
2 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
3 *
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:
10 *
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.
14 *
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.
22 */
23/*
24 *
25Copyright 1990, 1998 The Open Group
26
27Permission to use, copy, modify, distribute, and sell this software and its
28documentation for any purpose is hereby granted without fee, provided that
29the above copyright notice appear in all copies and that both that
30copyright notice and this permission notice appear in supporting
31documentation.
32
33The above copyright notice and this permission notice shall be included in
34all copies or substantial portions of the Software.
35
36THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
39OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
40AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
41CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42
43Except as contained in this notice, the name of a copyright holder shall not be
44used in advertising or otherwise to promote the sale, use or other dealings
45in this Software without prior written authorization from the copyright holder.
46 *
47 * Author: Keith Packard, MIT X Consortium
48 */
49
50
51/*
52 * Access control for XDMCP - keep a database of allowable display addresses
53 * and (potentially) a list of hosts to send ForwardQuery packets to
54 */
55
56#include "dm.h"
57#include "dm_error.h"
58
59#ifdef XDMCP
60
61# include <X11/Xos.h>
62# include <X11/Xdmcp.h>
63# include <X11/X.h>
64# include <stdio.h>
65# include <ctype.h>
66
67# include "dm_socket.h"
68
69# include <netdb.h>
70
71# if defined(IPv61) && defined(AF_INET630)
72# include <arpa/inet.h>
73# endif
74
75# define ALIAS_CHARACTER'%' '%'
76# define NEGATE_CHARACTER'!' '!'
77# define CHOOSER_STRING"CHOOSER" "CHOOSER"
78# define BROADCAST_STRING"BROADCAST" "BROADCAST"
79# define NOBROADCAST_STRING"NOBROADCAST" "NOBROADCAST"
80# define LISTEN_STRING"LISTEN" "LISTEN"
81# define WILDCARD_STRING"*" "*"
82
83# define HOST_ALIAS0 0
84# define HOST_ADDRESS1 1
85# define HOST_BROADCAST2 2
86# define HOST_CHOOSER3 3
87# define HOST_NOBROADCAST4 4
88# define HOST_ANYADDR5 5
89
90typedef struct _hostEntry {
91 struct _hostEntry *next;
92 int type;
93 union _hostOrAlias {
94 char *aliasName;
95 ARRAY8 hostAddress;
96 } entry;
97 int hopCount;
98} HostEntry;
99
100# define DISPLAY_ALIAS0 0
101# define DISPLAY_PATTERN1 1
102# define DISPLAY_ADDRESS2 2
103# define DISPLAY_LISTEN3 3
104
105typedef struct _displayEntry {
106 struct _displayEntry *next;
107 int type;
108 int notAllowed;
109 int notBroadcast;
110 int chooser;
111 union _displayType {
112 char *aliasName;
113 char *displayPattern;
114 struct _display {
115 ARRAY8 clientAddress;
116 CARD16 connectionType;
117 } displayAddress;
118 } entry;
119 HostEntry *hosts;
120} DisplayEntry;
121
122static DisplayEntry *database;
123
124ARRAY8Ptr
125getLocalAddress (void)
126{
127 static ARRAY8 localAddress;
128 static int haveLocalAddress;
129
130 if (!haveLocalAddress)
131 {
132# if defined(IPv61) && defined(AF_INET630)
133 struct addrinfo *ai;
134
135 if (getaddrinfo(localHostname(), NULL((void*)0), NULL((void*)0), &ai) != 0) {
136 if (XdmcpAllocARRAY8 (&localAddress, 4)) {
137 localAddress.data[0] = 127;
138 localAddress.data[1] = 0;
139 localAddress.data[2] = 0;
140 localAddress.data[3] = 1;
141 haveLocalAddress = 1;
142 }
143 } else {
144 if (ai->ai_addr->sa_family == AF_INET2) {
145 if (XdmcpAllocARRAY8 (&localAddress, sizeof(struct in_addr))) {
146 memcpy(localAddress.data,__builtin___memcpy_chk (localAddress.data, &((struct sockaddr_in
*)ai->ai_addr)->sin_addr, sizeof(struct in_addr), __builtin_object_size
(localAddress.data, 0))
147 &((struct sockaddr_in *)ai->ai_addr)->sin_addr,__builtin___memcpy_chk (localAddress.data, &((struct sockaddr_in
*)ai->ai_addr)->sin_addr, sizeof(struct in_addr), __builtin_object_size
(localAddress.data, 0))
148 sizeof(struct in_addr))__builtin___memcpy_chk (localAddress.data, &((struct sockaddr_in
*)ai->ai_addr)->sin_addr, sizeof(struct in_addr), __builtin_object_size
(localAddress.data, 0))
;
149 haveLocalAddress = 1;
150 }
151 } else if (ai->ai_addr->sa_family == AF_INET630) {
152 if (XdmcpAllocARRAY8 (&localAddress, sizeof(struct in6_addr)))
153 {
154 memcpy(localAddress.data,__builtin___memcpy_chk (localAddress.data, &((struct sockaddr_in6
*)ai->ai_addr)->sin6_addr, sizeof(struct in6_addr), __builtin_object_size
(localAddress.data, 0))
155 &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr,__builtin___memcpy_chk (localAddress.data, &((struct sockaddr_in6
*)ai->ai_addr)->sin6_addr, sizeof(struct in6_addr), __builtin_object_size
(localAddress.data, 0))
156 sizeof(struct in6_addr))__builtin___memcpy_chk (localAddress.data, &((struct sockaddr_in6
*)ai->ai_addr)->sin6_addr, sizeof(struct in6_addr), __builtin_object_size
(localAddress.data, 0))
;
157 haveLocalAddress = 1;
158 }
159 }
160 freeaddrinfo(ai);
161 }
162# else
163 struct hostent *hostent;
164
165 hostent = gethostbyname (localHostname());
166 if (hostent != NULL((void*)0)) {
167 if (XdmcpAllocARRAY8 (&localAddress, hostent->h_length)) {
168 memmove(localAddress.data, hostent->h_addr, hostent->h_length)__builtin___memmove_chk (localAddress.data, hostent->h_addr_list
[0], hostent->h_length, __builtin_object_size (localAddress
.data, 0))
;
169 haveLocalAddress = 1;
170 }
171 } else {
172 /* Assume 127.0.0.1 */
173 if (XdmcpAllocARRAY8 (&localAddress, 4)) {
174 localAddress.data[0] = 127;
175 localAddress.data[1] = 0;
176 localAddress.data[2] = 0;
177 localAddress.data[3] = 1;
178 haveLocalAddress = 1;
179 }
180 }
181# endif
182
183 }
184 return &localAddress;
185}
186
187static void
188FreeHostEntry (HostEntry *h)
189{
190 switch (h->type) {
191 case HOST_ALIAS0:
192 free (h->entry.aliasName);
193 break;
194 case HOST_ADDRESS1:
195 XdmcpDisposeARRAY8 (&h->entry.hostAddress);
196 break;
197 case HOST_CHOOSER3:
198 break;
199 }
200 free (h);
201}
202
203static void
204FreeDisplayEntry (DisplayEntry *d)
205{
206 HostEntry *h, *next;
207 switch (d->type) {
208 case DISPLAY_ALIAS0:
209 free (d->entry.aliasName);
210 break;
211 case DISPLAY_PATTERN1:
212 free (d->entry.displayPattern);
213 break;
214 case DISPLAY_ADDRESS2:
215 XdmcpDisposeARRAY8 (&d->entry.displayAddress.clientAddress);
216 break;
217 case DISPLAY_LISTEN3:
218 /* do nothing - this case doesn't use the d->entry union */
219 break;
220 }
221 for (h = d->hosts; h; h = next) {
222 next = h->next;
223 FreeHostEntry (h);
224 }
225 free (d);
226}
227
228static void
229FreeAccessDatabase (void)
230{
231 DisplayEntry *d, *next;
232
233 for (d = database; d; d = next)
234 {
235 next = d->next;
236 FreeDisplayEntry (d);
237 }
238 database = NULL((void*)0);
239}
240
241# define WORD_LEN256 256
242static char wordBuffer[WORD_LEN256];
243static int nextIsEOF;
244
245static char *
246ReadWord (FILE *file, int EOFatEOL)
247{
248 int c;
249 char *wordp;
250 int quoted;
251
252 wordp = wordBuffer;
253 if (nextIsEOF)
254 {
255 nextIsEOF = FALSE0;
256 return NULL((void*)0);
257 }
258 quoted = FALSE0;
259 for (;wordp - wordBuffer < sizeof(wordBuffer)-2;) {
260 c = getc (file);
261 switch (c) {
262 case '#':
263 if (quoted)
264 {
265 *wordp++ = c;
266 break;
267 }
268 while ((c = getc (file)) != EOF(-1) && c != '\n')
269 ;
270 case '\n':
271 case EOF(-1):
272 if (c == EOF(-1) || (EOFatEOL && !quoted))
273 {
274 ungetc (c, file);
275 if (wordp == wordBuffer)
276 return NULL((void*)0);
277 *wordp = '\0';
278 nextIsEOF = TRUE1;
279 return wordBuffer;
280 }
281 case ' ':
282 case '\t':
283 if (wordp != wordBuffer)
284 {
285 ungetc (c, file);
286 *wordp = '\0';
287 return wordBuffer;
288 }
289 break;
290 case '\\':
291 if (!quoted)
292 {
293 quoted = TRUE1;
294 continue;
295 }
296 default:
297 if (wordp < &(wordBuffer[WORD_LEN256]))
298 *wordp++ = c;
299 break;
300 }
301 quoted = FALSE0;
302 }
303 return NULL((void*)0);
304}
305
306static HostEntry *
307ReadHostEntry (FILE *file)
308{
309 char *hostOrAlias;
310 HostEntry *h;
311
312tryagain:
313 hostOrAlias = ReadWord (file, TRUE1);
314 if (!hostOrAlias)
315 return NULL((void*)0);
316 h = malloc (sizeof (DisplayEntry));
Result of 'malloc' is converted to a pointer of type 'HostEntry', which is incompatible with sizeof operand type 'DisplayEntry'
317 if (!h)
318 {
319 LogOutOfMem ("ReadHostEntry: DisplayEntry\n");
320 return NULL((void*)0);
321 }
322 h->hopCount = 1;
323 if (*hostOrAlias == ALIAS_CHARACTER'%')
324 {
325 h->type = HOST_ALIAS0;
326 h->entry.aliasName = strdup (hostOrAlias);
327 if (!h->entry.aliasName) {
328 free (h);
329 return NULL((void*)0);
330 }
331 }
332 else if (!strcmp (hostOrAlias, CHOOSER_STRING"CHOOSER"))
333 {
334 h->type = HOST_CHOOSER3;
335 }
336 else if (!strcmp (hostOrAlias, BROADCAST_STRING"BROADCAST"))
337 {
338 h->type = HOST_BROADCAST2;
339 }
340 else if (!strcmp (hostOrAlias, NOBROADCAST_STRING"NOBROADCAST"))
341 {
342 h->type = HOST_NOBROADCAST4;
343 }
344 else if (!strcmp (hostOrAlias, WILDCARD_STRING"*"))
345 {
346 h->type = HOST_ANYADDR5;
347 h->entry.hostAddress.length = 0;
348 }
349 else
350 {
351 void *addr=NULL((void*)0);
352 size_t addr_length=0;
353# if defined(IPv61) && defined(AF_INET630)
354 struct addrinfo *ai = NULL((void*)0);
355# else
356 struct hostent *hostent = gethostbyname (hostOrAlias);
357# endif
358 char *hops = strrchr(hostOrAlias, '/');
359
360 if (hops) {
361 *(hops++) = '\0';
362 h->hopCount = strtol(hops, NULL((void*)0), 10);
363 if (h->hopCount < 1)
364 h->hopCount = 1;
365 }
366
367# if defined(IPv61) && defined(AF_INET630)
368 if (getaddrinfo(hostOrAlias, NULL((void*)0), NULL((void*)0), &ai) == 0) {
369 if (ai->ai_addr->sa_family == AF_INET2) {
370 addr = &((struct sockaddr_in *)ai->ai_addr)->sin_addr;
371 addr_length = sizeof(struct in_addr);
372 } else if (ai->ai_addr->sa_family == AF_INET630) {
373 addr = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
374 addr_length = sizeof(struct in6_addr);
375 }
376 }
377# else
378 if (hostent) {
379 addr = hostent->h_addrh_addr_list[0];
380 addr_length = hostent->h_length;
381 }
382# endif
383 h->type = HOST_ADDRESS1;
384
385 if (!addr)
386 {
387 Debug ("No such host %s\n", hostOrAlias);
388 LogError ("Access file \"%s\", host \"%s\" not found\n", accessFile, hostOrAlias);
389 free (h);
390# if defined(IPv61) && defined(AF_INET630)
391 if (ai)
392 freeaddrinfo(ai);
393# endif
394 goto tryagain;
395 }
396 if (!XdmcpAllocARRAY8 (&h->entry.hostAddress, addr_length))
397 {
398 LogOutOfMem ("ReadHostEntry\n");
399 free (h);
400# if defined(IPv61) && defined(AF_INET630)
401 if (ai)
402 freeaddrinfo(ai);
403# endif
404 return NULL((void*)0);
405 }
406 memmove( h->entry.hostAddress.data, addr, addr_length)__builtin___memmove_chk (h->entry.hostAddress.data, addr, addr_length
, __builtin_object_size (h->entry.hostAddress.data, 0))
;
407# if defined(IPv61) && defined(AF_INET630)
408 if (ai)
409 freeaddrinfo(ai);
410# endif
411 }
412 return h;
413}
414
415static int
416HasGlobCharacters (char *s)
417{
418 for (;;)
419 switch (*s++) {
420 case '?':
421 case '*':
422 return 1;
423 case '\0':
424 return 0;
425 }
426}
427
428static DisplayEntry *
429ReadDisplayEntry (FILE *file)
430{
431 char *displayOrAlias;
432 DisplayEntry *d;
433 struct _display *display;
434 HostEntry *h, **prev;
435
436tryagain:
437 displayOrAlias = ReadWord (file, FALSE0);
438 if (!displayOrAlias)
439 return NULL((void*)0);
440 d = malloc (sizeof (DisplayEntry));
441 if (!d)
442 {
443 LogOutOfMem ("ReadDisplayEntry: DisplayEntry\n");
444 return NULL((void*)0);
445 }
446 d->notAllowed = 0;
447 d->notBroadcast = 0;
448 d->chooser = 0;
449 if (*displayOrAlias == ALIAS_CHARACTER'%')
450 {
451 d->type = DISPLAY_ALIAS0;
452 d->entry.aliasName = strdup (displayOrAlias);
453 if (!d->entry.aliasName)
454 {
455 free (d);
456 return NULL((void*)0);
457 }
458 }
459 else if (!strcmp(displayOrAlias, LISTEN_STRING"LISTEN"))
460 {
461 d->type = DISPLAY_LISTEN3;
462 }
463 else
464 {
465 if (*displayOrAlias == NEGATE_CHARACTER'!')
466 {
467 d->notAllowed = 1;
468 ++displayOrAlias;
469 }
470 if (HasGlobCharacters (displayOrAlias))
471 {
472 d->type = DISPLAY_PATTERN1;
473 d->entry.displayPattern = strdup (displayOrAlias);
474 if (!d->entry.displayPattern)
475 {
476 free (d);
477 return NULL((void*)0);
478 }
479 }
480 else
481 {
482 void *addr = NULL((void*)0);
483 size_t addr_length = 0;
484 int addrtype = 0;
485
486# if defined(IPv61) && defined(AF_INET630)
487 struct addrinfo *ai = NULL((void*)0);
488
489 if (getaddrinfo(displayOrAlias, NULL((void*)0), NULL((void*)0), &ai) == 0) {
490 addrtype = ai->ai_addr->sa_family;
491 if (addrtype == AF_INET2) {
492 addr = &((struct sockaddr_in *)ai->ai_addr)->sin_addr;
493 addr_length = sizeof(struct in_addr);
494 } else if (addrtype == AF_INET630) {
495 addr = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
496 addr_length = sizeof(struct in6_addr);
497 }
498 }
499# else
500 struct hostent *hostent;
501
502 if ((hostent = gethostbyname (displayOrAlias)) != NULL((void*)0))
503 {
504 Debug("ReadDisplayEntry: %s\n", displayOrAlias);
505 addr = hostent->h_addrh_addr_list[0];
506 addrtype = hostent->h_addrtype;
507 addr_length = hostent->h_length;
508 }
509# endif
510 if (addr == NULL((void*)0))
511 {
512 LogError ("Access file %s, display %s unknown\n", accessFile, displayOrAlias);
513 free (d);
514# if defined(IPv61) && defined(AF_INET630)
515 if (ai)
516 freeaddrinfo(ai);
517# endif
518 goto tryagain;
519 }
520 d->type = DISPLAY_ADDRESS2;
521 display = &d->entry.displayAddress;
522 if (!XdmcpAllocARRAY8 (&display->clientAddress, addr_length))
523 {
524 free (d);
525# if defined(IPv61) && defined(AF_INET630)
526 if (ai)
527 freeaddrinfo(ai);
528# endif
529 return NULL((void*)0);
530 }
531 memmove( display->clientAddress.data, addr, addr_length)__builtin___memmove_chk (display->clientAddress.data, addr
, addr_length, __builtin_object_size (display->clientAddress
.data, 0))
;
532# if defined(IPv61) && defined(AF_INET630)
533 if (ai)
534 freeaddrinfo(ai);
535# endif
536 switch (addrtype)
537 {
538# ifdef AF_UNIX1
539 case AF_UNIX1:
540 display->connectionType = FamilyLocal(256);
541 break;
542# endif
543# ifdef AF_INET2
544 case AF_INET2:
545 display->connectionType = FamilyInternet0;
546 break;
547# endif
548# if defined(IPv61) && defined(AF_INET630)
549 case AF_INET630:
550 display->connectionType = FamilyInternet66;
551 break;
552# endif
553# ifdef AF_DECnet12
554 case AF_DECnet12:
555 display->connectionType = FamilyDECnet1;
556 break;
557# endif
558 default:
559 display->connectionType = FamilyLocal(256);
560 break;
561 }
562 }
563 }
564 prev = &d->hosts;
565 while ((h = ReadHostEntry (file)))
566 {
567 if (h->type == HOST_CHOOSER3)
568 {
569 FreeHostEntry (h);
570 d->chooser = 1;
571 } else if (h->type == HOST_NOBROADCAST4) {
572 FreeHostEntry (h);
573 d->notBroadcast = 1;
574 } else if (h->type == HOST_ANYADDR5) {
575 if (d->type == DISPLAY_LISTEN3) {
576 *prev = h;
577 prev = &h->next;
578 } else {
579 Debug("Wildcard host specified in Xaccess for type other than LISTEN -- ignoring\n");
580 FreeHostEntry (h);
581 }
582 } else {
583 *prev = h;
584 prev = &h->next;
585 }
586 }
587 *prev = NULL((void*)0);
588 return d;
589}
590
591static void
592ReadAccessDatabase (FILE *file)
593{
594 DisplayEntry *d, **prev;
595
596 prev = &database;
597 while ((d = ReadDisplayEntry (file)))
598 {
599 *prev = d;
600 prev = &d->next;
601 }
602 *prev = NULL((void*)0);
603}
604
605int
606ScanAccessDatabase (void)
607{
608 FILE *datafile;
609
610 FreeAccessDatabase ();
611 if (*accessFile)
612 {
613 datafile = fopen (accessFile, "r");
614 if (!datafile)
615 {
616 LogError ("Cannot open access control file %s, no XDMCP reqeusts will be granted\n", accessFile);
617 return 0;
618 }
619 ReadAccessDatabase (datafile);
620 fclose (datafile);
621 }
622 return 1;
623}
624
625/*
626 * calls the given function for each valid indirect entry. Returns TRUE if
627 * the local host exists on any of the lists, else FALSE
628 */
629
630# define MAX_DEPTH32 32
631
632static int indirectAlias (
633 char *alias,
634 ARRAY8Ptr clientAddress,
635 CARD16 connectionType,
636 ChooserFunc function,
637 char *closure,
638 int depth,
639 int broadcast);
640
641
642static int
643scanHostlist (
644 HostEntry *h,
645 ARRAY8Ptr clientAddress,
646 CARD16 connectionType,
647 ChooserFunc function,
648 char *closure,
649 int depth,
650 int broadcast)
651{
652 int haveLocalhost = 0;
653
654 for (; h; h = h->next)
655 {
656 switch (h->type) {
657 case HOST_ALIAS0:
658 if (indirectAlias (h->entry.aliasName, clientAddress,
659 connectionType, function, closure, depth,
660 broadcast))
661 haveLocalhost = 1;
662 break;
663 case HOST_ADDRESS1:
664 if (XdmcpARRAY8Equal (getLocalAddress(), &h->entry.hostAddress))
665 haveLocalhost = 1;
666 else if (function)
667 (*function) (connectionType, &h->entry.hostAddress, closure);
668 break;
669 case HOST_BROADCAST2:
670 if (broadcast)
671 {
672 ARRAY8 temp;
673
674 if (function)
675 {
676 temp.data = (BYTE *) BROADCAST_STRING"BROADCAST";
677 temp.length = strlen ((char *)temp.data);
678 (*function) (connectionType, &temp, closure);
679 }
680 }
681 break;
682 }
683 }
684 return haveLocalhost;
685}
686
687/* Returns non-0 iff string is matched by pattern. Does case folding.
688 */
689static int
690patternMatch (const char *string, char *pattern)
691{
692 int p, s;
693
694 if (!string)
695 string = "";
696
697 for (;;)
698 {
699 s = *string++;
700 switch (p = *pattern++) {
701 case '*':
702 if (!*pattern)
703 return 1;
704 for (string--; *string; string++)
705 if (patternMatch (string, pattern))
706 return 1;
707 return 0;
708 case '?':
709 if (s == '\0')
710 return 0;
711 break;
712 case '\0':
713 return s == '\0';
714 case '\\':
715 p = *pattern++;
716 /* fall through */
717 default:
718 if (isupper(p)) p = tolower(p);
719 if (isupper(s)) s = tolower(s);
720 if (p != s)
721 return 0;
722 }
723 }
724}
725
726static int
727indirectAlias (
728 char *alias,
729 ARRAY8Ptr clientAddress,
730 CARD16 connectionType,
731 ChooserFunc function,
732 char *closure,
733 int depth,
734 int broadcast)
735{
736 DisplayEntry *d;
737 int haveLocalhost = 0;
738
739 if (depth == MAX_DEPTH32)
740 return 0;
741 for (d = database; d; d = d->next)
742 {
743 if (d->type != DISPLAY_ALIAS0 || !patternMatch (alias, d->entry.aliasName))
744 continue;
745 if (scanHostlist (d->hosts, clientAddress, connectionType,
746 function, closure, depth + 1, broadcast))
747 {
748 haveLocalhost = 1;
749 }
750 }
751 return haveLocalhost;
752}
753
754int ForEachMatchingIndirectHost (
755 ARRAY8Ptr clientAddress,
756 CARD16 connectionType,
757 ChooserFunc function,
758 char *closure)
759{
760 int haveLocalhost = 0;
761 DisplayEntry *d;
762 char *clientName = NULL((void*)0);
763
764 for (d = database; d; d = d->next)
765 {
766 switch (d->type) {
767 case DISPLAY_ALIAS0:
768 case DISPLAY_LISTEN3:
769 continue;
770 case DISPLAY_PATTERN1:
771 if (!clientName)
772 clientName = NetworkAddressToHostname (connectionType,
773 clientAddress);
774 if (!patternMatch (clientName, d->entry.displayPattern))
775 continue;
776 break;
777 case DISPLAY_ADDRESS2:
778 if (d->entry.displayAddress.connectionType != connectionType ||
779 !XdmcpARRAY8Equal (&d->entry.displayAddress.clientAddress,
780 clientAddress))
781 {
782 continue;
783 }
784 break;
785 }
786 if (!d->hosts)
787 continue;
788 if (d->notAllowed)
789 break;
790 if (d->chooser)
791 {
792 ARRAY8Ptr choice;
793
794 choice = IndirectChoice (clientAddress, connectionType);
795 if (!choice || XdmcpARRAY8Equal (getLocalAddress(), choice))
796 haveLocalhost = 1;
797 else
798 (*function) (connectionType, choice, closure);
799 }
800 else if (scanHostlist (d->hosts, clientAddress, connectionType,
801 function, closure, 0, FALSE0))
802 {
803 haveLocalhost = 1;
804 }
805 break;
806 }
807 free (clientName);
808 return haveLocalhost;
809}
810
811int UseChooser (
812 ARRAY8Ptr clientAddress,
813 CARD16 connectionType)
814{
815 DisplayEntry *d;
816 char *clientName = NULL((void*)0);
817
818 for (d = database; d; d = d->next)
819 {
820 switch (d->type) {
821 case DISPLAY_ALIAS0:
822 case DISPLAY_LISTEN3:
823 continue;
824 case DISPLAY_PATTERN1:
825 if (!clientName)
826 clientName = NetworkAddressToHostname (connectionType,
827 clientAddress);
828 if (!patternMatch (clientName, d->entry.displayPattern))
829 continue;
830 break;
831 case DISPLAY_ADDRESS2:
832 if (d->entry.displayAddress.connectionType != connectionType ||
833 !XdmcpARRAY8Equal (&d->entry.displayAddress.clientAddress,
834 clientAddress))
835 {
836 continue;
837 }
838 break;
839 }
840 if (!d->hosts)
841 continue;
842 if (d->notAllowed)
843 break;
844 if (d->chooser && !IndirectChoice (clientAddress, connectionType)) {
845 free (clientName);
846 return 1;
847 }
848 break;
849 }
850 free (clientName);
851 return 0;
852}
853
854void ForEachChooserHost (
855 ARRAY8Ptr clientAddress,
856 CARD16 connectionType,
857 ChooserFunc function,
858 char *closure)
859{
860 int haveLocalhost = 0;
861 DisplayEntry *d;
862 char *clientName = NULL((void*)0);
863
864 for (d = database; d; d = d->next)
865 {
866 switch (d->type) {
867 case DISPLAY_ALIAS0:
868 case DISPLAY_LISTEN3:
869 continue;
870 case DISPLAY_PATTERN1:
871 if (!clientName)
872 clientName = NetworkAddressToHostname (connectionType,
873 clientAddress);
874 if (!patternMatch (clientName, d->entry.displayPattern))
875 continue;
876 break;
877 case DISPLAY_ADDRESS2:
878 if (d->entry.displayAddress.connectionType != connectionType ||
879 !XdmcpARRAY8Equal (&d->entry.displayAddress.clientAddress,
880 clientAddress))
881 {
882 continue;
883 }
884 break;
885 }
886 if (!d->hosts)
887 continue;
888 if (d->notAllowed)
889 break;
890 if (!d->chooser)
891 break;
892 if (scanHostlist (d->hosts, clientAddress, connectionType,
893 function, closure, 0, TRUE1))
894 {
895 haveLocalhost = 1;
896 }
897 break;
898 }
899 free (clientName);
900 if (haveLocalhost)
901 (*function) (connectionType, getLocalAddress(), closure);
902}
903
904/*
905 * returns TRUE if the given client is acceptable to the local host. The
906 * given display client is acceptable if it occurs without a host list.
907 */
908
909int AcceptableDisplayAddress (
910 ARRAY8Ptr clientAddress,
911 CARD16 connectionType,
912 xdmOpCode type)
913{
914 DisplayEntry *d;
915 char *clientName = NULL((void*)0);
916
917 if (!*accessFile)
918 return 1;
919 if (type == INDIRECT_QUERY)
920 return 1;
921 for (d = database; d; d = d->next)
922 {
923 if (d->hosts)
924 continue;
925 switch (d->type) {
926 case DISPLAY_ALIAS0:
927 case DISPLAY_LISTEN3:
928 continue;
929 case DISPLAY_PATTERN1:
930 if (!clientName)
931 clientName = NetworkAddressToHostname (connectionType,
932 clientAddress);
933 if (!patternMatch (clientName, d->entry.displayPattern))
934 continue;
935 break;
936 case DISPLAY_ADDRESS2:
937 if (d->entry.displayAddress.connectionType != connectionType ||
938 !XdmcpARRAY8Equal (&d->entry.displayAddress.clientAddress,
939 clientAddress))
940 {
941 continue;
942 }
943 break;
944 }
945 break;
946 }
947 free (clientName);
948 return (d != 0) && (d->notAllowed == 0)
949 && (type == BROADCAST_QUERY ? d->notBroadcast == 0 : 1);
950}
951
952void ForEachListenAddr (
953 ListenFunc listenfunction,
954 ListenFunc mcastfunction,
955 void **closure)
956{
957 DisplayEntry *d;
958 HostEntry *h;
959 int listenFound = 0;
960
961 for (d = database; d != NULL((void*)0) ; d = d->next)
962 {
963 if (d->type == DISPLAY_LISTEN3) {
964 listenFound = 1;
965 h = d->hosts;
966 if (h != NULL((void*)0)) {
967 (*listenfunction) (&h->entry.hostAddress, closure);
968 for (h = h->next; h != NULL((void*)0); h = h->next) {
969 (*mcastfunction) (&h->entry.hostAddress, closure);
970 }
971 }
972 }
973 }
974 if (!listenFound) {
975 (*listenfunction) (NULL((void*)0), closure);
976# if defined(IPv61) && defined(AF_INET630) && defined(XDM_DEFAULT_MCAST_ADDR6"ff02:0:0:0:0:0:0:12b")
977 { /* Join default IPv6 Multicast Group */
978
979 static ARRAY8 defaultMcastAddress;
980
981 if (defaultMcastAddress.length == 0) {
982 struct in6_addr addr6;
983
984 if (inet_pton(AF_INET630,XDM_DEFAULT_MCAST_ADDR6"ff02:0:0:0:0:0:0:12b",&addr6) == 1) {
985 if (!XdmcpAllocARRAY8 (&defaultMcastAddress,
986 sizeof(struct in6_addr))) {
987 LogOutOfMem ("ReadHostEntry\n");
988 defaultMcastAddress.length = -1;
989 } else {
990 memcpy(defaultMcastAddress.data, &addr6,__builtin___memcpy_chk (defaultMcastAddress.data, &addr6,
sizeof(struct in6_addr), __builtin_object_size (defaultMcastAddress
.data, 0))
991 sizeof(struct in6_addr))__builtin___memcpy_chk (defaultMcastAddress.data, &addr6,
sizeof(struct in6_addr), __builtin_object_size (defaultMcastAddress
.data, 0))
;
992 }
993 } else {
994 defaultMcastAddress.length = -1;
995 }
996 }
997 if ( defaultMcastAddress.length == sizeof(struct in6_addr) ) {
998 (*mcastfunction) (&defaultMcastAddress, closure);
999 }
1000 }
1001# endif
1002 }
1003}
1004
1005
1006#endif /* XDMCP */