Bug Summary

File:os/access.c
Location:line 1078, column 13
Description:Value stored to 'family' is never read

Annotated Source Code

1/***********************************************************
2
3Copyright 1987, 1998 The Open Group
4
5All rights reserved.
6
7Permission is hereby granted, free of charge, to any person obtaining a
8copy of this software and associated documentation files (the
9"Software"), to deal in the Software without restriction, including
10without limitation the rights to use, copy, modify, merge, publish,
11distribute, and/or sell copies of the Software, and to permit persons
12to whom the Software is furnished to do so, provided that the above
13copyright notice(s) and this permission notice appear in all copies of
14the Software and that both the above copyright notice(s) and this
15permission notice appear in supporting documentation.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
20OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
22INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
23FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
24NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
25WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26
27Except as contained in this notice, the name of a copyright holder
28shall not be used in advertising or otherwise to promote the sale, use
29or other dealings in this Software without prior written authorization
30of the copyright holder.
31
32X Window System is a trademark of The Open Group.
33
34Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
35
36 All Rights Reserved
37
38Permission to use, copy, modify, and distribute this software and its
39documentation for any purpose and without fee is hereby granted,
40provided that the above copyright notice appear in all copies and that
41both that copyright notice and this permission notice appear in
42supporting documentation, and that the name of Digital not be
43used in advertising or publicity pertaining to distribution of the
44software without specific, written prior permission.
45
46DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
47ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
48DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
49ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
50WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
51ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
52SOFTWARE.
53
54******************************************************************/
55
56/*
57 * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
58 *
59 * Permission is hereby granted, free of charge, to any person obtaining a
60 * copy of this software and associated documentation files (the "Software"),
61 * to deal in the Software without restriction, including without limitation
62 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
63 * and/or sell copies of the Software, and to permit persons to whom the
64 * Software is furnished to do so, subject to the following conditions:
65 *
66 * The above copyright notice and this permission notice (including the next
67 * paragraph) shall be included in all copies or substantial portions of the
68 * Software.
69 *
70 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
71 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
72 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
73 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
74 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
75 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
76 * DEALINGS IN THE SOFTWARE.
77 */
78
79#ifdef HAVE_DIX_CONFIG_H1
80#include <dix-config.h>
81#endif
82
83#ifdef WIN32
84#include <X11/Xwinsock.h>
85#endif
86
87#include <stdio.h>
88#include <stdlib.h>
89#define XSERV_t
90#define TRANS_SERVER
91#define TRANS_REOPEN
92#include <X11/Xtrans/Xtrans.h>
93#include <X11/Xauth.h>
94#include <X11/X.h>
95#include <X11/Xproto.h>
96#include "misc.h"
97#include "site.h"
98#include <errno(*__error()).h>
99#include <sys/types.h>
100#ifndef WIN32
101#include <sys/socket.h>
102#include <sys/ioctl.h>
103#include <ctype.h>
104
105#ifndef NO_LOCAL_CLIENT_CRED
106#include <pwd.h>
107#endif
108
109#if defined(TCPCONN1) || defined(STREAMSCONN)
110#include <netinet/in.h>
111#endif /* TCPCONN || STREAMSCONN */
112
113#ifdef HAVE_GETPEERUCRED
114#include <ucred.h>
115#ifdef sun
116#include <zone.h>
117#endif
118#endif
119
120#if defined(SVR4) || (defined(SYSV) && defined(__i386__)) || defined(__GNU__)
121#include <sys/utsname.h>
122#endif
123#if defined(SYSV) && defined(__i386__)
124#include <sys/stream.h>
125#endif
126#ifdef __GNU__
127#undef SIOCGIFCONF(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifconf) & 0x1fff) << 16) | ((('i')) << 8) | (
(36)))
128#include <netdb.h>
129#else /*!__GNU__ */
130#include <net/if.h>
131#endif /*__GNU__ */
132
133#ifdef SVR4
134#include <sys/sockio.h>
135#include <sys/stropts.h>
136#endif
137
138#include <netdb.h>
139
140#ifdef CSRG_BASED1
141#include <sys/param.h>
142#if (BSD199506 >= 199103)
143#define VARIABLE_IFREQ
144#endif
145#endif
146
147#ifdef BSD44SOCKETS1
148#ifndef VARIABLE_IFREQ
149#define VARIABLE_IFREQ
150#endif
151#endif
152
153#ifdef HAVE_GETIFADDRS1
154#include <ifaddrs.h>
155#endif
156
157/* Solaris provides an extended interface SIOCGLIFCONF. Other systems
158 * may have this as well, but the code has only been tested on Solaris
159 * so far, so we only enable it there. Other platforms may be added as
160 * needed.
161 *
162 * Test for Solaris commented out -- TSI @ UQV 2003.06.13
163 */
164#ifdef SIOCGLIFCONF
165/* #if defined(sun) */
166#define USE_SIOCGLIFCONF
167/* #endif */
168#endif
169
170#if defined(IPv61) && defined(AF_INET630)
171#include <arpa/inet.h>
172#endif
173
174#endif /* WIN32 */
175
176#define X_INCLUDE_NETDB_H
177#include <X11/Xos_r.h>
178
179#include "dixstruct.h"
180#include "osdep.h"
181
182#include "xace.h"
183
184Bool defeatAccessControl = FALSE0;
185
186#define addrEqual(fam, address, length, host)((fam) == (host)->family && (length) == (host)->
len && !memcmp (address, (host)->addr, length))
\
187 ((fam) == (host)->family &&\
188 (length) == (host)->len &&\
189 !memcmp (address, (host)->addr, length))
190
191static int ConvertAddr(struct sockaddr * /*saddr */ ,
192 int * /*len */ ,
193 void ** /*addr */ );
194
195static int CheckAddr(int /*family */ ,
196 const void * /*pAddr */ ,
197 unsigned /*length */ );
198
199static Bool NewHost(int /*family */ ,
200 const void * /*addr */ ,
201 int /*len */ ,
202 int /* addingLocalHosts */ );
203
204/* XFree86 bug #156: To keep track of which hosts were explicitly requested in
205 /etc/X<display>.hosts, we've added a requested field to the HOST struct,
206 and a LocalHostRequested variable. These default to FALSE, but are set
207 to TRUE in ResetHosts when reading in /etc/X<display>.hosts. They are
208 checked in DisableLocalHost(), which is called to disable the default
209 local host entries when stronger authentication is turned on. */
210
211typedef struct _host {
212 short family;
213 short len;
214 unsigned char *addr;
215 struct _host *next;
216 int requested;
217} HOST;
218
219#define MakeHost(h,l)(h)=malloc(sizeof *(h)+(l)); if (h) { (h)->addr=(unsigned char
*) ((h) + 1); (h)->requested = 0; }
(h)=malloc(sizeof *(h)+(l));\
220 if (h) { \
221 (h)->addr=(unsigned char *) ((h) + 1);\
222 (h)->requested = FALSE0; \
223 }
224#define FreeHost(h)free(h) free(h)
225static HOST *selfhosts = NULL((void*)0);
226static HOST *validhosts = NULL((void*)0);
227static int AccessEnabled = DEFAULT_ACCESS_CONTROL1;
228static int LocalHostEnabled = FALSE0;
229static int LocalHostRequested = FALSE0;
230static int UsingXdmcp = FALSE0;
231
232static enum {
233 LOCAL_ACCESS_SCOPE_HOST = 0,
234#ifndef NO_LOCAL_CLIENT_CRED
235 LOCAL_ACCESS_SCOPE_USER,
236#endif
237} LocalAccessScope;
238
239/* FamilyServerInterpreted implementation */
240static Bool siAddrMatch(int family, void *addr, int len, HOST * host,
241 ClientPtr client);
242static int siCheckAddr(const char *addrString, int length);
243static void siTypesInitialize(void);
244
245/*
246 * called when authorization is not enabled to add the
247 * local host to the access list
248 */
249
250void
251EnableLocalAccess(void)
252{
253 switch (LocalAccessScope) {
254 case LOCAL_ACCESS_SCOPE_HOST:
255 EnableLocalHost();
256 break;
257#ifndef NO_LOCAL_CLIENT_CRED
258 case LOCAL_ACCESS_SCOPE_USER:
259 EnableLocalUser();
260 break;
261#endif
262 }
263}
264
265void
266EnableLocalHost(void)
267{
268 if (!UsingXdmcp) {
269 LocalHostEnabled = TRUE1;
270 AddLocalHosts();
271 }
272}
273
274/*
275 * called when authorization is enabled to keep us secure
276 */
277void
278DisableLocalAccess(void)
279{
280 switch (LocalAccessScope) {
281 case LOCAL_ACCESS_SCOPE_HOST:
282 DisableLocalHost();
283 break;
284#ifndef NO_LOCAL_CLIENT_CRED
285 case LOCAL_ACCESS_SCOPE_USER:
286 DisableLocalUser();
287 break;
288#endif
289 }
290}
291
292void
293DisableLocalHost(void)
294{
295 HOST *self;
296
297 if (!LocalHostRequested) /* Fix for XFree86 bug #156 */
298 LocalHostEnabled = FALSE0;
299 for (self = selfhosts; self; self = self->next) {
300 if (!self->requested) /* Fix for XFree86 bug #156 */
301 (void) RemoveHost((ClientPtr) NULL((void*)0), self->family, self->len,
302 (void *) self->addr);
303 }
304}
305
306#ifndef NO_LOCAL_CLIENT_CRED
307static int GetLocalUserAddr(char **addr)
308{
309 static const char *type = "localuser";
310 static const char delimiter = '\0';
311 static const char *value;
312 struct passwd *pw;
313 int length = -1;
314
315 pw = getpwuid(getuid());
316
317 if (pw == NULL((void*)0) || pw->pw_name == NULL((void*)0))
318 goto out;
319
320 value = pw->pw_name;
321
322 length = asprintf(addr, "%s%c%s", type, delimiter, value);
323
324 if (length == -1) {
325 goto out;
326 }
327
328 /* Trailing NUL */
329 length++;
330
331out:
332 return length;
333}
334
335void
336EnableLocalUser(void)
337{
338 char *addr = NULL((void*)0);
339 int length = -1;
340
341 length = GetLocalUserAddr(&addr);
342
343 if (length == -1)
344 return;
345
346 NewHost(FamilyServerInterpreted5, addr, length, TRUE1);
347
348 free(addr);
349}
350
351void
352DisableLocalUser(void)
353{
354 char *addr = NULL((void*)0);
355 int length = -1;
356
357 length = GetLocalUserAddr(&addr);
358
359 if (length == -1)
360 return;
361
362 RemoveHost(NULL((void*)0), FamilyServerInterpreted5, length, addr);
363
364 free(addr);
365}
366
367void
368LocalAccessScopeUser(void)
369{
370 LocalAccessScope = LOCAL_ACCESS_SCOPE_USER;
371}
372#endif
373
374/*
375 * called at init time when XDMCP will be used; xdmcp always
376 * adds local hosts manually when needed
377 */
378
379void
380AccessUsingXdmcp(void)
381{
382 UsingXdmcp = TRUE1;
383 LocalHostEnabled = FALSE0;
384}
385
386#if defined(SVR4) && !defined(sun) && defined(SIOCGIFCONF(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifconf) & 0x1fff) << 16) | ((('i')) << 8) | (
(36)))
) && !defined(USE_SIOCGLIFCONF)
387
388/* Deal with different SIOCGIFCONF ioctl semantics on these OSs */
389
390static int
391ifioctlioctl(int fd, int cmd, char *arg)
392{
393 struct strioctl ioc;
394 int ret;
395
396 memset((char *) &ioc, 0, sizeof(ioc))__builtin___memset_chk ((char *) &ioc, 0, sizeof(ioc), __builtin_object_size
((char *) &ioc, 0))
;
397 ioc.ic_cmd = cmd;
398 ioc.ic_timout = 0;
399 if (cmd == SIOCGIFCONF(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifconf) & 0x1fff) << 16) | ((('i')) << 8) | (
(36)))
) {
400 ioc.ic_len = ((struct ifconf *) arg)->ifc_len;
401 ioc.ic_dp = ((struct ifconf *) arg)->ifc_bufifc_ifcu.ifcu_buf;
402 }
403 else {
404 ioc.ic_len = sizeof(struct ifreq);
405 ioc.ic_dp = arg;
406 }
407 ret = ioctl(fd, I_STR, (char *) &ioc);
408 if (ret >= 0 && cmd == SIOCGIFCONF(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifconf) & 0x1fff) << 16) | ((('i')) << 8) | (
(36)))
)
409#ifdef SVR4
410 ((struct ifconf *) arg)->ifc_len = ioc.ic_len;
411#endif
412 return ret;
413}
414#else
415#define ifioctlioctl ioctl
416#endif
417
418/*
419 * DefineSelf (fd):
420 *
421 * Define this host for access control. Find all the hosts the OS knows about
422 * for this fd and add them to the selfhosts list.
423 */
424
425#if !defined(SIOCGIFCONF(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifconf) & 0x1fff) << 16) | ((('i')) << 8) | (
(36)))
)
426void
427DefineSelf(int fd)
428{
429#if !defined(TCPCONN1) && !defined(STREAMSCONN) && !defined(UNIXCONN1)
430 return;
431#else
432 register int n;
433 int len;
434 caddr_t addr;
435 int family;
436 register HOST *host;
437
438#ifndef WIN32
439 struct utsname name;
440#else
441 struct {
442 char nodename[512];
443 } name;
444#endif
445
446 register struct hostent *hp;
447
448 union {
449 struct sockaddr sa;
450 struct sockaddr_in in;
451#if defined(IPv61) && defined(AF_INET630)
452 struct sockaddr_in6 in6;
453#endif
454 } saddr;
455
456 struct sockaddr_in *inetaddr;
457 struct sockaddr_in6 *inet6addr;
458 struct sockaddr_in broad_addr;
459
460#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
461 _Xgethostbynameparams hparams;
462#endif
463
464 /* Why not use gethostname()? Well, at least on my system, I've had to
465 * make an ugly kernel patch to get a name longer than 8 characters, and
466 * uname() lets me access to the whole string (it smashes release, you
467 * see), whereas gethostname() kindly truncates it for me.
468 */
469#ifndef WIN32
470 uname(&name);
471#else
472 gethostname(name.nodename, sizeof(name.nodename));
473#endif
474
475 hp = _XGethostbyname(name.nodename, hparams)gethostbyname((name.nodename));
476 if (hp != NULL((void*)0)) {
477 saddr.sa.sa_family = hp->h_addrtype;
478 switch (hp->h_addrtype) {
479 case AF_INET2:
480 inetaddr = (struct sockaddr_in *) (&(saddr.sa));
481 memcpy(&(inetaddr->sin_addr), hp->h_addr, hp->h_length)__builtin___memcpy_chk (&(inetaddr->sin_addr), hp->
h_addr_list[0], hp->h_length, __builtin_object_size (&
(inetaddr->sin_addr), 0))
;
482 len = sizeof(saddr.sa);
483 break;
484#if defined(IPv61) && defined(AF_INET630)
485 case AF_INET630:
486 inet6addr = (struct sockaddr_in6 *) (&(saddr.sa));
487 memcpy(&(inet6addr->sin6_addr), hp->h_addr, hp->h_length)__builtin___memcpy_chk (&(inet6addr->sin6_addr), hp->
h_addr_list[0], hp->h_length, __builtin_object_size (&
(inet6addr->sin6_addr), 0))
;
488 len = sizeof(saddr.in6);
489 break;
490#endif
491 default:
492 goto DefineLocalHost;
493 }
494 family = ConvertAddr(&(saddr.sa), &len, (void **) &addr);
495 if (family != -1 && family != FamilyLocal(256)) {
496 for (host = selfhosts;
497 host && !addrEqual(family, addr, len, host)((family) == (host)->family && (len) == (host)->
len && !memcmp (addr, (host)->addr, len))
;
498 host = host->next);
499 if (!host) {
500 /* add this host to the host list. */
501 MakeHost(host, len)(host)=malloc(sizeof *(host)+(len)); if (host) { (host)->addr
=(unsigned char *) ((host) + 1); (host)->requested = 0; }
502 if (host) {
503 host->family = family;
504 host->len = len;
505 memcpy(host->addr, addr, len)__builtin___memcpy_chk (host->addr, addr, len, __builtin_object_size
(host->addr, 0))
;
506 host->next = selfhosts;
507 selfhosts = host;
508 }
509#ifdef XDMCP1
510 /*
511 * If this is an Internet Address, but not the localhost
512 * address (127.0.0.1), nor the bogus address (0.0.0.0),
513 * register it.
514 */
515 if (family == FamilyInternet0 &&
516 !(len == 4 &&
517 ((addr[0] == 127) ||
518 (addr[0] == 0 && addr[1] == 0 &&
519 addr[2] == 0 && addr[3] == 0)))
520 ) {
521 XdmcpRegisterConnection(family, (char *) addr, len);
522 broad_addr = *inetaddr;
523 ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
524 htonl(INADDR_BROADCAST)(__builtin_constant_p((u_int32_t)0xffffffff) ? ((__uint32_t)(
(((__uint32_t)((u_int32_t)0xffffffff) & 0xff000000) >>
24) | (((__uint32_t)((u_int32_t)0xffffffff) & 0x00ff0000
) >> 8) | (((__uint32_t)((u_int32_t)0xffffffff) & 0x0000ff00
) << 8) | (((__uint32_t)((u_int32_t)0xffffffff) & 0x000000ff
) << 24))) : _OSSwapInt32((u_int32_t)0xffffffff))
;
525 XdmcpRegisterBroadcastAddress((struct sockaddr_in *)
526 &broad_addr);
527 }
528#if defined(IPv61) && defined(AF_INET630)
529 else if (family == FamilyInternet66 &&
530 !(IN6_IS_ADDR_LOOPBACK((struct in6_addr *) addr)((*(const __uint32_t *)(const void *)(&((struct in6_addr *
) addr)->__u6_addr.__u6_addr8[0]) == 0) && (*(const
__uint32_t *)(const void *)(&((struct in6_addr *) addr)->
__u6_addr.__u6_addr8[4]) == 0) && (*(const __uint32_t
*)(const void *)(&((struct in6_addr *) addr)->__u6_addr
.__u6_addr8[8]) == 0) && (*(const __uint32_t *)(const
void *)(&((struct in6_addr *) addr)->__u6_addr.__u6_addr8
[12]) == (__builtin_constant_p(1) ? ((__uint32_t)((((__uint32_t
)(1) & 0xff000000) >> 24) | (((__uint32_t)(1) &
0x00ff0000) >> 8) | (((__uint32_t)(1) & 0x0000ff00
) << 8) | (((__uint32_t)(1) & 0x000000ff) << 24
))) : _OSSwapInt32(1))))
)) {
531 XdmcpRegisterConnection(family, (char *) addr, len);
532 }
533#endif
534
535#endif /* XDMCP */
536 }
537 }
538 }
539 /*
540 * now add a host of family FamilyLocalHost...
541 */
542 DefineLocalHost:
543 for (host = selfhosts;
544 host && !addrEqual(FamilyLocalHost, "", 0, host)(((252)) == (host)->family && (0) == (host)->len
&& !memcmp ("", (host)->addr, 0))
; host = host->next);
545 if (!host) {
546 MakeHost(host, 0)(host)=malloc(sizeof *(host)+(0)); if (host) { (host)->addr
=(unsigned char *) ((host) + 1); (host)->requested = 0; }
;
547 if (host) {
548 host->family = FamilyLocalHost(252);
549 host->len = 0;
550 /* Nothing to store in host->addr */
551 host->next = selfhosts;
552 selfhosts = host;
553 }
554 }
555#endif /* !TCPCONN && !STREAMSCONN && !UNIXCONN */
556}
557
558#else
559
560#ifdef USE_SIOCGLIFCONF
561#define ifr_typestruct ifreq struct lifreq
562#else
563#define ifr_typestruct ifreq struct ifreq
564#endif
565
566#ifdef VARIABLE_IFREQ
567#define ifr_size(p)(sizeof (struct ifreq) + (p->ifr_ifru.ifru_addr.sa_len >
sizeof (p->ifr_ifru.ifru_addr) ? p->ifr_ifru.ifru_addr
.sa_len - sizeof (p->ifr_ifru.ifru_addr) : 0))
(sizeof (struct ifreq) + \
568 (p->ifr_addrifr_ifru.ifru_addr.sa_len > sizeof (p->ifr_addrifr_ifru.ifru_addr) ? \
569 p->ifr_addrifr_ifru.ifru_addr.sa_len - sizeof (p->ifr_addrifr_ifru.ifru_addr) : 0))
570#define ifraddr_size(a)(a.sa_len) (a.sa_len)
571#else
572#define ifr_size(p)(sizeof (struct ifreq) + (p->ifr_ifru.ifru_addr.sa_len >
sizeof (p->ifr_ifru.ifru_addr) ? p->ifr_ifru.ifru_addr
.sa_len - sizeof (p->ifr_ifru.ifru_addr) : 0))
(sizeof (ifr_typestruct ifreq))
573#define ifraddr_size(a)(a.sa_len) (sizeof (a))
574#endif
575
576#if defined(IPv61) && defined(AF_INET630)
577static void
578in6_fillscopeid(struct sockaddr_in6 *sin6)
579{
580#if defined(__KAME__)
581 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)(((&sin6->sin6_addr)->__u6_addr.__u6_addr8[0] == 0xfe
) && (((&sin6->sin6_addr)->__u6_addr.__u6_addr8
[1] & 0xc0) == 0x80))
) {
582 sin6->sin6_scope_id =
583 ntohs(*(u_int16_t *) &sin6->sin6_addr.s6_addr[2])((__uint16_t)(__builtin_constant_p(*(u_int16_t *) &sin6->
sin6_addr.__u6_addr.__u6_addr8[2]) ? ((__uint16_t)((((__uint16_t
)(*(u_int16_t *) &sin6->sin6_addr.__u6_addr.__u6_addr8
[2]) & 0xff00) >> 8) | (((__uint16_t)(*(u_int16_t *
) &sin6->sin6_addr.__u6_addr.__u6_addr8[2]) & 0x00ff
) << 8))) : _OSSwapInt16(*(u_int16_t *) &sin6->sin6_addr
.__u6_addr.__u6_addr8[2])))
;
584 sin6->sin6_addr.s6_addr__u6_addr.__u6_addr8[2] = sin6->sin6_addr.s6_addr__u6_addr.__u6_addr8[3] = 0;
585 }
586#endif
587}
588#endif
589
590void
591DefineSelf(int fd)
592{
593#ifndef HAVE_GETIFADDRS1
594 char *cp, *cplim;
595
596#ifdef USE_SIOCGLIFCONF
597 struct sockaddr_storage buf[16];
598 struct lifconf ifc;
599 register struct lifreq *ifr;
600
601#ifdef SIOCGLIFNUM
602 struct lifnum ifn;
603#endif
604#else /* !USE_SIOCGLIFCONF */
605 char buf[2048];
606 struct ifconf ifc;
607 register struct ifreq *ifr;
608#endif
609 void *bufptr = buf;
610#else /* HAVE_GETIFADDRS */
611 struct ifaddrs *ifap, *ifr;
612#endif
613 int len;
614 unsigned char *addr;
615 int family;
616 register HOST *host;
617
618#ifndef HAVE_GETIFADDRS1
619
620 len = sizeof(buf);
621
622#ifdef USE_SIOCGLIFCONF
623
624#ifdef SIOCGLIFNUM
625 ifn.lifn_family = AF_UNSPEC0;
626 ifn.lifn_flags = 0;
627 if (ioctl(fd, SIOCGLIFNUM, (char *) &ifn) < 0)
628 ErrorF("Getting interface count: %s\n", strerror(errno(*__error())));
629 if (len < (ifn.lifn_count * sizeof(struct lifreq))) {
630 len = ifn.lifn_count * sizeof(struct lifreq);
631 bufptr = malloc(len);
632 }
633#endif
634
635 ifc.lifc_family = AF_UNSPEC0;
636 ifc.lifc_flags = 0;
637 ifc.lifc_len = len;
638 ifc.lifc_buf = bufptr;
639
640#define IFC_IOCTL_REQ SIOCGLIFCONF
641#define IFC_IFC_REQ ifc.lifc_req
642#define IFC_IFC_LEN ifc.lifc_len
643#define IFR_IFR_ADDR ifr->lifr_addr
644#define IFR_IFR_NAME ifr->lifr_name
645
646#else /* Use SIOCGIFCONF */
647 ifc.ifc_len = len;
648 ifc.ifc_bufifc_ifcu.ifcu_buf = bufptr;
649
650#define IFC_IOCTL_REQ SIOCGIFCONF(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifconf) & 0x1fff) << 16) | ((('i')) << 8) | (
(36)))
651#define IFC_IFC_REQ ifc.ifc_reqifc_ifcu.ifcu_req
652#define IFC_IFC_LEN ifc.ifc_len
653#define IFR_IFR_ADDR ifr->ifr_addrifr_ifru.ifru_addr
654#define IFR_IFR_NAME ifr->ifr_name
655#endif
656
657 if (ifioctlioctl(fd, IFC_IOCTL_REQ, (void *) &ifc) < 0)
658 ErrorF("Getting interface configuration (4): %s\n", strerror(errno(*__error())));
659
660 cplim = (char *) IFC_IFC_REQ + IFC_IFC_LEN;
661
662 for (cp = (char *) IFC_IFC_REQ; cp < cplim; cp += ifr_size(ifr)(sizeof (struct ifreq) + (ifr->ifr_ifru.ifru_addr.sa_len >
sizeof (ifr->ifr_ifru.ifru_addr) ? ifr->ifr_ifru.ifru_addr
.sa_len - sizeof (ifr->ifr_ifru.ifru_addr) : 0))
) {
663 ifr = (ifr_typestruct ifreq *) cp;
664 len = ifraddr_size(IFR_IFR_ADDR)(IFR_IFR_ADDR.sa_len);
665 family = ConvertAddr((struct sockaddr *) &IFR_IFR_ADDR,
666 &len, (void **) &addr);
667 if (family == -1 || family == FamilyLocal(256))
668 continue;
669#if defined(IPv61) && defined(AF_INET630)
670 if (family == FamilyInternet66)
671 in6_fillscopeid((struct sockaddr_in6 *) &IFR_IFR_ADDR);
672#endif
673 for (host = selfhosts;
674 host && !addrEqual(family, addr, len, host)((family) == (host)->family && (len) == (host)->
len && !memcmp (addr, (host)->addr, len))
; host = host->next);
675 if (host)
676 continue;
677 MakeHost(host, len)(host)=malloc(sizeof *(host)+(len)); if (host) { (host)->addr
=(unsigned char *) ((host) + 1); (host)->requested = 0; }
678 if (host) {
679 host->family = family;
680 host->len = len;
681 memcpy(host->addr, addr, len)__builtin___memcpy_chk (host->addr, addr, len, __builtin_object_size
(host->addr, 0))
;
682 host->next = selfhosts;
683 selfhosts = host;
684 }
685#ifdef XDMCP1
686 {
687#ifdef USE_SIOCGLIFCONF
688 struct sockaddr_storage broad_addr;
689#else
690 struct sockaddr broad_addr;
691#endif
692
693 /*
694 * If this isn't an Internet Address, don't register it.
695 */
696 if (family != FamilyInternet0
697#if defined(IPv61) && defined(AF_INET630)
698 && family != FamilyInternet66
699#endif
700 )
701 continue;
702
703 /*
704 * ignore 'localhost' entries as they're not useful
705 * on the other end of the wire
706 */
707 if (family == FamilyInternet0 &&
708 addr[0] == 127 && addr[1] == 0 && addr[2] == 0 && addr[3] == 1)
709 continue;
710#if defined(IPv61) && defined(AF_INET630)
711 else if (family == FamilyInternet66 &&
712 IN6_IS_ADDR_LOOPBACK((struct in6_addr *) addr)((*(const __uint32_t *)(const void *)(&((struct in6_addr *
) addr)->__u6_addr.__u6_addr8[0]) == 0) && (*(const
__uint32_t *)(const void *)(&((struct in6_addr *) addr)->
__u6_addr.__u6_addr8[4]) == 0) && (*(const __uint32_t
*)(const void *)(&((struct in6_addr *) addr)->__u6_addr
.__u6_addr8[8]) == 0) && (*(const __uint32_t *)(const
void *)(&((struct in6_addr *) addr)->__u6_addr.__u6_addr8
[12]) == (__builtin_constant_p(1) ? ((__uint32_t)((((__uint32_t
)(1) & 0xff000000) >> 24) | (((__uint32_t)(1) &
0x00ff0000) >> 8) | (((__uint32_t)(1) & 0x0000ff00
) << 8) | (((__uint32_t)(1) & 0x000000ff) << 24
))) : _OSSwapInt32(1))))
)
713 continue;
714#endif
715
716 /*
717 * Ignore '0.0.0.0' entries as they are
718 * returned by some OSes for unconfigured NICs but they are
719 * not useful on the other end of the wire.
720 */
721 if (len == 4 &&
722 addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0)
723 continue;
724
725 XdmcpRegisterConnection(family, (char *) addr, len);
726
727#if defined(IPv61) && defined(AF_INET630)
728 /* IPv6 doesn't support broadcasting, so we drop out here */
729 if (family == FamilyInternet66)
730 continue;
731#endif
732
733 broad_addr = IFR_IFR_ADDR;
734
735 ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
736 htonl(INADDR_BROADCAST)(__builtin_constant_p((u_int32_t)0xffffffff) ? ((__uint32_t)(
(((__uint32_t)((u_int32_t)0xffffffff) & 0xff000000) >>
24) | (((__uint32_t)((u_int32_t)0xffffffff) & 0x00ff0000
) >> 8) | (((__uint32_t)((u_int32_t)0xffffffff) & 0x0000ff00
) << 8) | (((__uint32_t)((u_int32_t)0xffffffff) & 0x000000ff
) << 24))) : _OSSwapInt32((u_int32_t)0xffffffff))
;
737#if defined(USE_SIOCGLIFCONF) && defined(SIOCGLIFBRDADDR)
738 {
739 struct lifreq broad_req;
740
741 broad_req = *ifr;
742 if (ioctl(fd, SIOCGLIFFLAGS, (char *) &broad_req) != -1 &&
743 (broad_req.lifr_flags & IFF_BROADCAST0x2) &&
744 (broad_req.lifr_flags & IFF_UP0x1)
745 ) {
746 broad_req = *ifr;
747 if (ioctl(fd, SIOCGLIFBRDADDR, &broad_req) != -1)
748 broad_addr = broad_req.lifr_broadaddr;
749 else
750 continue;
751 }
752 else
753 continue;
754 }
755
756#elif defined(SIOCGIFBRDADDR(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifreq) & 0x1fff) << 16) | ((('i')) << 8) | (
(35)))
)
757 {
758 struct ifreq broad_req;
759
760 broad_req = *ifr;
761 if (ifioctlioctl(fd, SIOCGIFFLAGS(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifreq) & 0x1fff) << 16) | ((('i')) << 8) | (
(17)))
, (void *) &broad_req) != -1 &&
762 (broad_req.ifr_flagsifr_ifru.ifru_flags & IFF_BROADCAST0x2) &&
763 (broad_req.ifr_flagsifr_ifru.ifru_flags & IFF_UP0x1)
764 ) {
765 broad_req = *ifr;
766 if (ifioctlioctl(fd, SIOCGIFBRDADDR(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifreq) & 0x1fff) << 16) | ((('i')) << 8) | (
(35)))
, (void *) &broad_req) != -1)
767 broad_addr = broad_req.ifr_addrifr_ifru.ifru_addr;
768 else
769 continue;
770 }
771 else
772 continue;
773 }
774#endif /* SIOCGIFBRDADDR */
775 XdmcpRegisterBroadcastAddress((struct sockaddr_in *) &broad_addr);
776 }
777#endif /* XDMCP */
778 }
779 if (bufptr != buf)
780 free(bufptr);
781#else /* HAVE_GETIFADDRS */
782 if (getifaddrs(&ifap) < 0) {
783 ErrorF("Warning: getifaddrs returns %s\n", strerror(errno(*__error())));
784 return;
785 }
786 for (ifr = ifap; ifr != NULL((void*)0); ifr = ifr->ifa_next) {
787 if (!ifr->ifa_addr)
788 continue;
789 len = sizeof(*(ifr->ifa_addr));
790 family = ConvertAddr((struct sockaddr *) ifr->ifa_addr, &len,
791 (void **) &addr);
792 if (family == -1 || family == FamilyLocal(256))
793 continue;
794#if defined(IPv61) && defined(AF_INET630)
795 if (family == FamilyInternet66)
796 in6_fillscopeid((struct sockaddr_in6 *) ifr->ifa_addr);
797#endif
798
799 for (host = selfhosts;
800 host != NULL((void*)0) && !addrEqual(family, addr, len, host)((family) == (host)->family && (len) == (host)->
len && !memcmp (addr, (host)->addr, len))
;
801 host = host->next);
802 if (host != NULL((void*)0))
803 continue;
804 MakeHost(host, len)(host)=malloc(sizeof *(host)+(len)); if (host) { (host)->addr
=(unsigned char *) ((host) + 1); (host)->requested = 0; }
;
805 if (host != NULL((void*)0)) {
806 host->family = family;
807 host->len = len;
808 memcpy(host->addr, addr, len)__builtin___memcpy_chk (host->addr, addr, len, __builtin_object_size
(host->addr, 0))
;
809 host->next = selfhosts;
810 selfhosts = host;
811 }
812#ifdef XDMCP1
813 {
814 /*
815 * If this isn't an Internet Address, don't register it.
816 */
817 if (family != FamilyInternet0
818#if defined(IPv61) && defined(AF_INET630)
819 && family != FamilyInternet66
820#endif
821 )
822 continue;
823
824 /*
825 * ignore 'localhost' entries as they're not useful
826 * on the other end of the wire
827 */
828 if (ifr->ifa_flags & IFF_LOOPBACK0x8)
829 continue;
830
831 if (family == FamilyInternet0 &&
832 addr[0] == 127 && addr[1] == 0 && addr[2] == 0 && addr[3] == 1)
833 continue;
834
835 /*
836 * Ignore '0.0.0.0' entries as they are
837 * returned by some OSes for unconfigured NICs but they are
838 * not useful on the other end of the wire.
839 */
840 if (len == 4 &&
841 addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0)
842 continue;
843#if defined(IPv61) && defined(AF_INET630)
844 else if (family == FamilyInternet66 &&
845 IN6_IS_ADDR_LOOPBACK((struct in6_addr *) addr)((*(const __uint32_t *)(const void *)(&((struct in6_addr *
) addr)->__u6_addr.__u6_addr8[0]) == 0) && (*(const
__uint32_t *)(const void *)(&((struct in6_addr *) addr)->
__u6_addr.__u6_addr8[4]) == 0) && (*(const __uint32_t
*)(const void *)(&((struct in6_addr *) addr)->__u6_addr
.__u6_addr8[8]) == 0) && (*(const __uint32_t *)(const
void *)(&((struct in6_addr *) addr)->__u6_addr.__u6_addr8
[12]) == (__builtin_constant_p(1) ? ((__uint32_t)((((__uint32_t
)(1) & 0xff000000) >> 24) | (((__uint32_t)(1) &
0x00ff0000) >> 8) | (((__uint32_t)(1) & 0x0000ff00
) << 8) | (((__uint32_t)(1) & 0x000000ff) << 24
))) : _OSSwapInt32(1))))
)
846 continue;
847#endif
848 XdmcpRegisterConnection(family, (char *) addr, len);
849#if defined(IPv61) && defined(AF_INET630)
850 if (family == FamilyInternet66)
851 /* IPv6 doesn't support broadcasting, so we drop out here */
852 continue;
853#endif
854 if ((ifr->ifa_flags & IFF_BROADCAST0x2) &&
855 (ifr->ifa_flags & IFF_UP0x1) && ifr->ifa_broadaddrifa_dstaddr)
856 XdmcpRegisterBroadcastAddress((struct sockaddr_in *) ifr->
857 ifa_broadaddrifa_dstaddr);
858 else
859 continue;
860 }
861#endif /* XDMCP */
862
863 } /* for */
864 freeifaddrs(ifap);
865#endif /* HAVE_GETIFADDRS */
866
867 /*
868 * add something of FamilyLocalHost
869 */
870 for (host = selfhosts;
871 host && !addrEqual(FamilyLocalHost, "", 0, host)(((252)) == (host)->family && (0) == (host)->len
&& !memcmp ("", (host)->addr, 0))
; host = host->next);
872 if (!host) {
873 MakeHost(host, 0)(host)=malloc(sizeof *(host)+(0)); if (host) { (host)->addr
=(unsigned char *) ((host) + 1); (host)->requested = 0; }
;
874 if (host) {
875 host->family = FamilyLocalHost(252);
876 host->len = 0;
877 /* Nothing to store in host->addr */
878 host->next = selfhosts;
879 selfhosts = host;
880 }
881 }
882}
883#endif /* hpux && !HAVE_IFREQ */
884
885#ifdef XDMCP1
886void
887AugmentSelf(void *from, int len)
888{
889 int family;
890 void *addr;
891 register HOST *host;
892
893 family = ConvertAddr(from, &len, (void **) &addr);
894 if (family == -1 || family == FamilyLocal(256))
895 return;
896 for (host = selfhosts; host; host = host->next) {
897 if (addrEqual(family, addr, len, host)((family) == (host)->family && (len) == (host)->
len && !memcmp (addr, (host)->addr, len))
)
898 return;
899 }
900 MakeHost(host, len)(host)=malloc(sizeof *(host)+(len)); if (host) { (host)->addr
=(unsigned char *) ((host) + 1); (host)->requested = 0; }
901 if (!host)
902 return;
903 host->family = family;
904 host->len = len;
905 memcpy(host->addr, addr, len)__builtin___memcpy_chk (host->addr, addr, len, __builtin_object_size
(host->addr, 0))
;
906 host->next = selfhosts;
907 selfhosts = host;
908}
909#endif
910
911void
912AddLocalHosts(void)
913{
914 HOST *self;
915
916 for (self = selfhosts; self; self = self->next)
917 /* Fix for XFree86 bug #156: pass addingLocal = TRUE to
918 * NewHost to tell that we are adding the default local
919 * host entries and not to flag the entries as being
920 * explicitely requested */
921 (void) NewHost(self->family, self->addr, self->len, TRUE1);
922}
923
924/* Reset access control list to initial hosts */
925void
926ResetHosts(const char *display)
927{
928 register HOST *host;
929 char lhostname[120], ohostname[120];
930 char *hostname = ohostname;
931 char fname[PATH_MAX1024 + 1];
932 int fnamelen;
933 FILE *fd;
934 char *ptr;
935 int i, hostlen;
936
937#if (defined(TCPCONN1) || defined(STREAMSCONN) ) && \
938 (!defined(IPv61) || !defined(AF_INET630))
939 union {
940 struct sockaddr sa;
941#if defined(TCPCONN1) || defined(STREAMSCONN)
942 struct sockaddr_in in;
943#endif /* TCPCONN || STREAMSCONN */
944 } saddr;
945#endif
946 int family = 0;
947 void *addr = NULL((void*)0);
948 int len;
949
950 siTypesInitialize();
951 AccessEnabled = defeatAccessControl ? FALSE0 : DEFAULT_ACCESS_CONTROL1;
952 LocalHostEnabled = FALSE0;
953 while ((host = validhosts) != 0) {
954 validhosts = host->next;
955 FreeHost(host)free(host);
956 }
957
958#if defined WIN32 && defined __MINGW32__
959#define ETC_HOST_PREFIX"/etc/X" "X"
960#else
961#define ETC_HOST_PREFIX"/etc/X" "/etc/X"
962#endif
963#define ETC_HOST_SUFFIX".hosts" ".hosts"
964 fnamelen = strlen(ETC_HOST_PREFIX"/etc/X") + strlen(ETC_HOST_SUFFIX".hosts") +
965 strlen(display) + 1;
966 if (fnamelen > sizeof(fname))
967 FatalError("Display name `%s' is too long\n", display);
968 snprintf(fname, sizeof(fname), ETC_HOST_PREFIX "%s" ETC_HOST_SUFFIX,__builtin___snprintf_chk (fname, sizeof(fname), 0, __builtin_object_size
(fname, 2 > 1 ? 1 : 0), "/etc/X" "%s" ".hosts", display)
969 display)__builtin___snprintf_chk (fname, sizeof(fname), 0, __builtin_object_size
(fname, 2 > 1 ? 1 : 0), "/etc/X" "%s" ".hosts", display)
;
970
971 if ((fd = fopen(fname, "r")) != 0) {
972 while (fgets(ohostname, sizeof(ohostname), fd)) {
973 family = FamilyWild(65535);
974 if (*ohostname == '#')
975 continue;
976 if ((ptr = strchr(ohostname, '\n')) != 0)
977 *ptr = 0;
978 hostlen = strlen(ohostname) + 1;
979 for (i = 0; i < hostlen; i++)
980 lhostname[i] = tolower(ohostname[i]);
981 hostname = ohostname;
982 if (!strncmp("local:", lhostname, 6)) {
983 family = FamilyLocalHost(252);
984 NewHost(family, "", 0, FALSE0);
985 LocalHostRequested = TRUE1; /* Fix for XFree86 bug #156 */
986 }
987#if defined(TCPCONN1) || defined(STREAMSCONN)
988 else if (!strncmp("inet:", lhostname, 5)) {
989 family = FamilyInternet0;
990 hostname = ohostname + 5;
991 }
992#if defined(IPv61) && defined(AF_INET630)
993 else if (!strncmp("inet6:", lhostname, 6)) {
994 family = FamilyInternet66;
995 hostname = ohostname + 6;
996 }
997#endif
998#endif
999#ifdef SECURE_RPC
1000 else if (!strncmp("nis:", lhostname, 4)) {
1001 family = FamilyNetname(254);
1002 hostname = ohostname + 4;
1003 }
1004#endif
1005 else if (!strncmp("si:", lhostname, 3)) {
1006 family = FamilyServerInterpreted5;
1007 hostname = ohostname + 3;
1008 hostlen -= 3;
1009 }
1010
1011 if (family == FamilyServerInterpreted5) {
1012 len = siCheckAddr(hostname, hostlen);
1013 if (len >= 0) {
1014 NewHost(family, hostname, len, FALSE0);
1015 }
1016 }
1017 else
1018#ifdef SECURE_RPC
1019 if ((family == FamilyNetname(254)) || (strchr(hostname, '@'))) {
1020 SecureRPCInit();
1021 (void) NewHost(FamilyNetname(254), hostname, strlen(hostname),
1022 FALSE0);
1023 }
1024 else
1025#endif /* SECURE_RPC */
1026#if defined(TCPCONN1) || defined(STREAMSCONN)
1027 {
1028#if defined(IPv61) && defined(AF_INET630)
1029 if ((family == FamilyInternet0) || (family == FamilyInternet66) ||
1030 (family == FamilyWild(65535))) {
1031 struct addrinfo *addresses;
1032 struct addrinfo *a;
1033 int f;
1034
1035 if (getaddrinfo(hostname, NULL((void*)0), NULL((void*)0), &addresses) == 0) {
1036 for (a = addresses; a != NULL((void*)0); a = a->ai_next) {
1037 len = a->ai_addrlen;
1038 f = ConvertAddr(a->ai_addr, &len,
1039 (void **) &addr);
1040 if (addr && ((family == f) ||
1041 ((family == FamilyWild(65535)) && (f != -1)))) {
1042 NewHost(f, addr, len, FALSE0);
1043 }
1044 }
1045 freeaddrinfo(addresses);
1046 }
1047 }
1048#else
1049#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
1050 _Xgethostbynameparams hparams;
1051#endif
1052 register struct hostent *hp;
1053
1054 /* host name */
1055 if ((family == FamilyInternet0 &&
1056 ((hp = _XGethostbyname(hostname, hparams)gethostbyname((hostname))) != 0)) ||
1057 ((hp = _XGethostbyname(hostname, hparams)gethostbyname((hostname))) != 0)) {
1058 saddr.sa.sa_family = hp->h_addrtype;
1059 len = sizeof(saddr.sa);
1060 if ((family =
1061 ConvertAddr(&saddr.sa, &len,
1062 (void **) &addr)) != -1) {
1063#ifdef h_addrh_addr_list[0] /* new 4.3bsd version of gethostent */
1064 char **list;
1065
1066 /* iterate over the addresses */
1067 for (list = hp->h_addr_list; *list; list++)
1068 (void) NewHost(family, (void *) *list, len, FALSE0);
1069#else
1070 (void) NewHost(family, (void *) hp->h_addrh_addr_list[0], len,
1071 FALSE0);
1072#endif
1073 }
1074 }
1075#endif /* IPv6 */
1076 }
1077#endif /* TCPCONN || STREAMSCONN */
1078 family = FamilyWild(65535);
Value stored to 'family' is never read
1079 }
1080 fclose(fd);
1081 }
1082}
1083
1084/* Is client on the local host */
1085Bool
1086ComputeLocalClient(ClientPtr client)
1087{
1088 int alen, family, notused;
1089 Xtransaddr *from = NULL((void*)0);
1090 void *addr;
1091 register HOST *host;
1092 OsCommPtr oc = (OsCommPtr) client->osPrivate;
1093
1094 if (!oc->trans_conn)
1095 return FALSE0;
1096
1097 if (!_XSERVTransGetPeerAddr(oc->trans_conn, &notused, &alen, &from)) {
1098 family = ConvertAddr((struct sockaddr *) from,
1099 &alen, (void **) &addr);
1100 if (family == -1) {
1101 free(from);
1102 return FALSE0;
1103 }
1104 if (family == FamilyLocal(256)) {
1105 free(from);
1106 return TRUE1;
1107 }
1108 for (host = selfhosts; host; host = host->next) {
1109 if (addrEqual(family, addr, alen, host)((family) == (host)->family && (alen) == (host)->
len && !memcmp (addr, (host)->addr, alen))
) {
1110 free(from);
1111 return TRUE1;
1112 }
1113 }
1114 free(from);
1115 }
1116 return FALSE0;
1117}
1118
1119/*
1120 * Return the uid and all gids of a connected local client
1121 * Allocates a LocalClientCredRec - caller must call FreeLocalClientCreds
1122 *
1123 * Used by localuser & localgroup ServerInterpreted access control forms below
1124 * Used by AuthAudit to log who local connections came from
1125 */
1126int
1127GetLocalClientCreds(ClientPtr client, LocalClientCredRec ** lccp)
1128{
1129#if defined(HAVE_GETPEEREID1) || defined(HAVE_GETPEERUCRED) || defined(SO_PEERCRED)
1130 int fd;
1131 XtransConnInfo ci;
1132 LocalClientCredRec *lcc;
1133
1134#ifdef HAVE_GETPEEREID1
1135 uid_t uid;
1136 gid_t gid;
1137#elif defined(HAVE_GETPEERUCRED)
1138 ucred_t *peercred = NULL((void*)0);
1139 const gid_t *gids;
1140#elif defined(SO_PEERCRED)
1141 struct ucred peercred;
1142 socklen_t so_len = sizeof(peercred);
1143#endif
1144
1145 if (client == NULL((void*)0))
1146 return -1;
1147 ci = ((OsCommPtr) client->osPrivate)->trans_conn;
1148#if !(defined(sun) && defined(HAVE_GETPEERUCRED))
1149 /* Most implementations can only determine peer credentials for Unix
1150 * domain sockets - Solaris getpeerucred can work with a bit more, so
1151 * we just let it tell us if the connection type is supported or not
1152 */
1153 if (!_XSERVTransIsLocal(ci)) {
1154 return -1;
1155 }
1156#endif
1157
1158 *lccp = calloc(1, sizeof(LocalClientCredRec));
1159 if (*lccp == NULL((void*)0))
1160 return -1;
1161 lcc = *lccp;
1162
1163 fd = _XSERVTransGetConnectionNumber(ci);
1164#ifdef HAVE_GETPEEREID1
1165 if (getpeereid(fd, &uid, &gid) == -1) {
1166 FreeLocalClientCreds(lcc);
1167 return -1;
1168 }
1169 lcc->euid = uid;
1170 lcc->egid = gid;
1171 lcc->fieldsSet = LCC_UID_SET(1 << 0) | LCC_GID_SET(1 << 1);
1172 return 0;
1173#elif defined(HAVE_GETPEERUCRED)
1174 if (getpeerucred(fd, &peercred) < 0) {
1175 FreeLocalClientCreds(lcc);
1176 return -1;
1177 }
1178 lcc->euid = ucred_geteuid(peercred);
1179 if (lcc->euid != -1)
1180 lcc->fieldsSet |= LCC_UID_SET(1 << 0);
1181 lcc->egid = ucred_getegid(peercred);
1182 if (lcc->egid != -1)
1183 lcc->fieldsSet |= LCC_GID_SET(1 << 1);
1184 lcc->pid = ucred_getpid(peercred);
1185 if (lcc->pid != -1)
1186 lcc->fieldsSet |= LCC_PID_SET(1 << 2);
1187#ifdef HAVE_GETZONEID
1188 lcc->zoneid = ucred_getzoneid(peercred);
1189 if (lcc->zoneid != -1)
1190 lcc->fieldsSet |= LCC_ZID_SET(1 << 3);
1191#endif
1192 lcc->nSuppGids = ucred_getgroups(peercred, &gids);
1193 if (lcc->nSuppGids > 0) {
1194 lcc->pSuppGids = calloc(lcc->nSuppGids, sizeof(int));
1195 if (lcc->pSuppGids == NULL((void*)0)) {
1196 lcc->nSuppGids = 0;
1197 }
1198 else {
1199 int i;
1200
1201 for (i = 0; i < lcc->nSuppGids; i++) {
1202 (lcc->pSuppGids)[i] = (int) gids[i];
1203 }
1204 }
1205 }
1206 else {
1207 lcc->nSuppGids = 0;
1208 }
1209 ucred_free(peercred);
1210 return 0;
1211#elif defined(SO_PEERCRED)
1212 if (getsockopt(fd, SOL_SOCKET0xffff, SO_PEERCRED, &peercred, &so_len) == -1) {
1213 FreeLocalClientCreds(lcc);
1214 return -1;
1215 }
1216 lcc->euid = peercred.uid;
1217 lcc->egid = peercred.gid;
1218 lcc->pid = peercred.pid;
1219 lcc->fieldsSet = LCC_UID_SET(1 << 0) | LCC_GID_SET(1 << 1) | LCC_PID_SET(1 << 2);
1220 return 0;
1221#endif
1222#else
1223 /* No system call available to get the credentials of the peer */
1224#define NO_LOCAL_CLIENT_CRED
1225 return -1;
1226#endif
1227}
1228
1229void
1230FreeLocalClientCreds(LocalClientCredRec * lcc)
1231{
1232 if (lcc != NULL((void*)0)) {
1233 if (lcc->nSuppGids > 0) {
1234 free(lcc->pSuppGids);
1235 }
1236 free(lcc);
1237 }
1238}
1239
1240static int
1241AuthorizedClient(ClientPtr client)
1242{
1243 int rc;
1244
1245 if (!client || defeatAccessControl)
1246 return Success0;
1247
1248 /* untrusted clients can't change host access */
1249 rc = XaceHook(XACE_SERVER_ACCESS9, client, DixManageAccess(1<<25));
1250 if (rc != Success0)
1251 return rc;
1252
1253 return client->local ? Success0 : BadAccess10;
1254}
1255
1256/* Add a host to the access control list. This is the external interface
1257 * called from the dispatcher */
1258
1259int
1260AddHost(ClientPtr client, int family, unsigned length, /* of bytes in pAddr */
1261 const void *pAddr)
1262{
1263 int rc, len;
1264
1265 rc = AuthorizedClient(client);
1266 if (rc != Success0)
1267 return rc;
1268 switch (family) {
1269 case FamilyLocalHost(252):
1270 len = length;
1271 LocalHostEnabled = TRUE1;
1272 break;
1273#ifdef SECURE_RPC
1274 case FamilyNetname(254):
1275 len = length;
1276 SecureRPCInit();
1277 break;
1278#endif
1279 case FamilyInternet0:
1280#if defined(IPv61) && defined(AF_INET630)
1281 case FamilyInternet66:
1282#endif
1283 case FamilyDECnet1:
1284 case FamilyChaos2:
1285 case FamilyServerInterpreted5:
1286 if ((len = CheckAddr(family, pAddr, length)) < 0) {
1287 client->errorValue = length;
1288 return BadValue2;
1289 }
1290 break;
1291 case FamilyLocal(256):
1292 default:
1293 client->errorValue = family;
1294 return BadValue2;
1295 }
1296 if (NewHost(family, pAddr, len, FALSE0))
1297 return Success0;
1298 return BadAlloc11;
1299}
1300
1301Bool
1302ForEachHostInFamily(int family, Bool (*func) (unsigned char *addr,
1303 short len,
1304 void *closure),
1305 void *closure)
1306{
1307 HOST *host;
1308
1309 for (host = validhosts; host; host = host->next)
1310 if (family == host->family && func(host->addr, host->len, closure))
1311 return TRUE1;
1312 return FALSE0;
1313}
1314
1315/* Add a host to the access control list. This is the internal interface
1316 * called when starting or resetting the server */
1317static Bool
1318NewHost(int family, const void *addr, int len, int addingLocalHosts)
1319{
1320 register HOST *host;
1321
1322 for (host = validhosts; host; host = host->next) {
1323 if (addrEqual(family, addr, len, host)((family) == (host)->family && (len) == (host)->
len && !memcmp (addr, (host)->addr, len))
)
1324 return TRUE1;
1325 }
1326 if (!addingLocalHosts) { /* Fix for XFree86 bug #156 */
1327 for (host = selfhosts; host; host = host->next) {
1328 if (addrEqual(family, addr, len, host)((family) == (host)->family && (len) == (host)->
len && !memcmp (addr, (host)->addr, len))
) {
1329 host->requested = TRUE1;
1330 break;
1331 }
1332 }
1333 }
1334 MakeHost(host, len)(host)=malloc(sizeof *(host)+(len)); if (host) { (host)->addr
=(unsigned char *) ((host) + 1); (host)->requested = 0; }
1335 if (!host)
1336 return FALSE0;
1337 host->family = family;
1338 host->len = len;
1339 memcpy(host->addr, addr, len)__builtin___memcpy_chk (host->addr, addr, len, __builtin_object_size
(host->addr, 0))
;
1340 host->next = validhosts;
1341 validhosts = host;
1342 return TRUE1;
1343}
1344
1345/* Remove a host from the access control list */
1346
1347int
1348RemoveHost(ClientPtr client, int family, unsigned length, /* of bytes in pAddr */
1349 void *pAddr)
1350{
1351 int rc, len;
1352 register HOST *host, **prev;
1353
1354 rc = AuthorizedClient(client);
1355 if (rc != Success0)
1356 return rc;
1357 switch (family) {
1358 case FamilyLocalHost(252):
1359 len = length;
1360 LocalHostEnabled = FALSE0;
1361 break;
1362#ifdef SECURE_RPC
1363 case FamilyNetname(254):
1364 len = length;
1365 break;
1366#endif
1367 case FamilyInternet0:
1368#if defined(IPv61) && defined(AF_INET630)
1369 case FamilyInternet66:
1370#endif
1371 case FamilyDECnet1:
1372 case FamilyChaos2:
1373 case FamilyServerInterpreted5:
1374 if ((len = CheckAddr(family, pAddr, length)) < 0) {
1375 client->errorValue = length;
1376 return BadValue2;
1377 }
1378 break;
1379 case FamilyLocal(256):
1380 default:
1381 client->errorValue = family;
1382 return BadValue2;
1383 }
1384 for (prev = &validhosts;
1385 (host = *prev) && (!addrEqual(family, pAddr, len, host)((family) == (host)->family && (len) == (host)->
len && !memcmp (pAddr, (host)->addr, len))
);
1386 prev = &host->next);
1387 if (host) {
1388 *prev = host->next;
1389 FreeHost(host)free(host);
1390 }
1391 return Success0;
1392}
1393
1394/* Get all hosts in the access control list */
1395int
1396GetHosts(void **data, int *pnHosts, int *pLen, BOOL * pEnabled)
1397{
1398 int len;
1399 register int n = 0;
1400 register unsigned char *ptr;
1401 register HOST *host;
1402 int nHosts = 0;
1403
1404 *pEnabled = AccessEnabled ? EnableAccess1 : DisableAccess0;
1405 for (host = validhosts; host; host = host->next) {
1406 nHosts++;
1407 n += pad_to_int32(host->len) + sizeof(xHostEntry);
1408 /* Could check for INT_MAX, but in reality having more than 1mb of
1409 hostnames in the access list is ridiculous */
1410 if (n >= 1048576)
1411 break;
1412 }
1413 if (n) {
1414 *data = ptr = malloc(n);
1415 if (!ptr) {
1416 return BadAlloc11;
1417 }
1418 for (host = validhosts; host; host = host->next) {
1419 len = host->len;
1420 if ((ptr + sizeof(xHostEntry) + len) > ((unsigned char *) *data + n))
1421 break;
1422 ((xHostEntry *) ptr)->family = host->family;
1423 ((xHostEntry *) ptr)->length = len;
1424 ptr += sizeof(xHostEntry);
1425 memcpy(ptr, host->addr, len)__builtin___memcpy_chk (ptr, host->addr, len, __builtin_object_size
(ptr, 0))
;
1426 ptr += pad_to_int32(len);
1427 }
1428 }
1429 else {
1430 *data = NULL((void*)0);
1431 }
1432 *pnHosts = nHosts;
1433 *pLen = n;
1434 return Success0;
1435}
1436
1437/* Check for valid address family and length, and return address length. */
1438
1439 /*ARGSUSED*/ static int
1440CheckAddr(int family, const void *pAddr, unsigned length)
1441{
1442 int len;
1443
1444 switch (family) {
1445#if defined(TCPCONN1) || defined(STREAMSCONN)
1446 case FamilyInternet0:
1447 if (length == sizeof(struct in_addr))
1448 len = length;
1449 else
1450 len = -1;
1451 break;
1452#if defined(IPv61) && defined(AF_INET630)
1453 case FamilyInternet66:
1454 if (length == sizeof(struct in6_addr))
1455 len = length;
1456 else
1457 len = -1;
1458 break;
1459#endif
1460#endif
1461 case FamilyServerInterpreted5:
1462 len = siCheckAddr(pAddr, length);
1463 break;
1464 default:
1465 len = -1;
1466 }
1467 return len;
1468}
1469
1470/* Check if a host is not in the access control list.
1471 * Returns 1 if host is invalid, 0 if we've found it. */
1472
1473int
1474InvalidHost(register struct sockaddr *saddr, int len, ClientPtr client)
1475{
1476 int family;
1477 void *addr = NULL((void*)0);
1478 register HOST *selfhost, *host;
1479
1480 if (!AccessEnabled) /* just let them in */
1481 return 0;
1482 family = ConvertAddr(saddr, &len, (void **) &addr);
1483 if (family == -1)
1484 return 1;
1485 if (family == FamilyLocal(256)) {
1486 if (!LocalHostEnabled) {
1487 /*
1488 * check to see if any local address is enabled. This
1489 * implicitly enables local connections.
1490 */
1491 for (selfhost = selfhosts; selfhost; selfhost = selfhost->next) {
1492 for (host = validhosts; host; host = host->next) {
1493 if (addrEqual(selfhost->family, selfhost->addr,((selfhost->family) == (host)->family && (selfhost
->len) == (host)->len && !memcmp (selfhost->
addr, (host)->addr, selfhost->len))
1494 selfhost->len, host)((selfhost->family) == (host)->family && (selfhost
->len) == (host)->len && !memcmp (selfhost->
addr, (host)->addr, selfhost->len))
)
1495 return 0;
1496 }
1497 }
1498 }
1499 else
1500 return 0;
1501 }
1502 for (host = validhosts; host; host = host->next) {
1503 if (host->family == FamilyServerInterpreted5) {
1504 if (siAddrMatch(family, addr, len, host, client)) {
1505 return 0;
1506 }
1507 }
1508 else {
1509 if (addr && addrEqual(family, addr, len, host)((family) == (host)->family && (len) == (host)->
len && !memcmp (addr, (host)->addr, len))
)
1510 return 0;
1511 }
1512
1513 }
1514 return 1;
1515}
1516
1517static int
1518ConvertAddr(register struct sockaddr *saddr, int *len, void **addr)
1519{
1520 if (*len == 0)
1521 return FamilyLocal(256);
1522 switch (saddr->sa_family) {
1523 case AF_UNSPEC0:
1524#if defined(UNIXCONN1) || defined(LOCALCONN)
1525 case AF_UNIX1:
1526#endif
1527 return FamilyLocal(256);
1528#if defined(TCPCONN1) || defined(STREAMSCONN)
1529 case AF_INET2:
1530#ifdef WIN32
1531 if (16777343 == *(long *) &((struct sockaddr_in *) saddr)->sin_addr)
1532 return FamilyLocal(256);
1533#endif
1534 *len = sizeof(struct in_addr);
1535 *addr = (void *) &(((struct sockaddr_in *) saddr)->sin_addr);
1536 return FamilyInternet0;
1537#if defined(IPv61) && defined(AF_INET630)
1538 case AF_INET630:
1539 {
1540 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) saddr;
1541
1542 if (IN6_IS_ADDR_V4MAPPED(&(saddr6->sin6_addr))((*(const __uint32_t *)(const void *)(&(&(saddr6->
sin6_addr))->__u6_addr.__u6_addr8[0]) == 0) && (*(
const __uint32_t *)(const void *)(&(&(saddr6->sin6_addr
))->__u6_addr.__u6_addr8[4]) == 0) && (*(const __uint32_t
*)(const void *)(&(&(saddr6->sin6_addr))->__u6_addr
.__u6_addr8[8]) == (__builtin_constant_p(0x0000ffff) ? ((__uint32_t
)((((__uint32_t)(0x0000ffff) & 0xff000000) >> 24) |
(((__uint32_t)(0x0000ffff) & 0x00ff0000) >> 8) | (
((__uint32_t)(0x0000ffff) & 0x0000ff00) << 8) | (((
__uint32_t)(0x0000ffff) & 0x000000ff) << 24))) : _OSSwapInt32
(0x0000ffff))))
) {
1543 *len = sizeof(struct in_addr);
1544 *addr = (void *) &(saddr6->sin6_addr.s6_addr__u6_addr.__u6_addr8[12]);
1545 return FamilyInternet0;
1546 }
1547 else {
1548 *len = sizeof(struct in6_addr);
1549 *addr = (void *) &(saddr6->sin6_addr);
1550 return FamilyInternet66;
1551 }
1552 }
1553#endif
1554#endif
1555 default:
1556 return -1;
1557 }
1558}
1559
1560int
1561ChangeAccessControl(ClientPtr client, int fEnabled)
1562{
1563 int rc = AuthorizedClient(client);
1564
1565 if (rc != Success0)
1566 return rc;
1567 AccessEnabled = fEnabled;
1568 return Success0;
1569}
1570
1571/* returns FALSE if xhost + in effect, else TRUE */
1572int
1573GetAccessControl(void)
1574{
1575 return AccessEnabled;
1576}
1577
1578/*****************************************************************************
1579 * FamilyServerInterpreted host entry implementation
1580 *
1581 * Supports an extensible system of host types which the server can interpret
1582 * See the IPv6 extensions to the X11 protocol spec for the definition.
1583 *
1584 * Currently supported schemes:
1585 *
1586 * hostname - hostname as defined in IETF RFC 2396
1587 * ipv6 - IPv6 literal address as defined in IETF RFC's 3513 and <TBD>
1588 *
1589 * See xc/doc/specs/SIAddresses for formal definitions of each type.
1590 */
1591
1592/* These definitions and the siTypeAdd function could be exported in the
1593 * future to enable loading additional host types, but that was not done for
1594 * the initial implementation.
1595 */
1596typedef Bool (*siAddrMatchFunc) (int family, void *addr, int len,
1597 const char *siAddr, int siAddrlen,
1598 ClientPtr client, void *siTypePriv);
1599typedef int (*siCheckAddrFunc) (const char *addrString, int length,
1600 void *siTypePriv);
1601
1602struct siType {
1603 struct siType *next;
1604 const char *typeName;
1605 siAddrMatchFunc addrMatch;
1606 siCheckAddrFunc checkAddr;
1607 void *typePriv; /* Private data for type routines */
1608};
1609
1610static struct siType *siTypeList;
1611
1612static int
1613siTypeAdd(const char *typeName, siAddrMatchFunc addrMatch,
1614 siCheckAddrFunc checkAddr, void *typePriv)
1615{
1616 struct siType *s, *p;
1617
1618 if ((typeName == NULL((void*)0)) || (addrMatch == NULL((void*)0)) || (checkAddr == NULL((void*)0)))
1619 return BadValue2;
1620
1621 for (s = siTypeList, p = NULL((void*)0); s != NULL((void*)0); p = s, s = s->next) {
1622 if (strcmp(typeName, s->typeName) == 0) {
1623 s->addrMatch = addrMatch;
1624 s->checkAddr = checkAddr;
1625 s->typePriv = typePriv;
1626 return Success0;
1627 }
1628 }
1629
1630 s = malloc(sizeof(struct siType));
1631 if (s == NULL((void*)0))
1632 return BadAlloc11;
1633
1634 if (p == NULL((void*)0))
1635 siTypeList = s;
1636 else
1637 p->next = s;
1638
1639 s->next = NULL((void*)0);
1640 s->typeName = typeName;
1641 s->addrMatch = addrMatch;
1642 s->checkAddr = checkAddr;
1643 s->typePriv = typePriv;
1644 return Success0;
1645}
1646
1647/* Checks to see if a host matches a server-interpreted host entry */
1648static Bool
1649siAddrMatch(int family, void *addr, int len, HOST * host, ClientPtr client)
1650{
1651 Bool matches = FALSE0;
1652 struct siType *s;
1653 const char *valueString;
1654 int addrlen;
1655
1656 valueString = (const char *) memchr(host->addr, '\0', host->len);
1657 if (valueString != NULL((void*)0)) {
1658 for (s = siTypeList; s != NULL((void*)0); s = s->next) {
1659 if (strcmp((char *) host->addr, s->typeName) == 0) {
1660 addrlen = host->len - (strlen((char *) host->addr) + 1);
1661 matches = s->addrMatch(family, addr, len,
1662 valueString + 1, addrlen, client,
1663 s->typePriv);
1664 break;
1665 }
1666 }
1667#ifdef FAMILY_SI_DEBUG
1668 ErrorF("Xserver: siAddrMatch(): type = %s, value = %*.*s -- %s\n",
1669 host->addr, addrlen, addrlen, valueString + 1,
1670 (matches) ? "accepted" : "rejected");
1671#endif
1672 }
1673 return matches;
1674}
1675
1676static int
1677siCheckAddr(const char *addrString, int length)
1678{
1679 const char *valueString;
1680 int addrlen, typelen;
1681 int len = -1;
1682 struct siType *s;
1683
1684 /* Make sure there is a \0 byte inside the specified length
1685 to separate the address type from the address value. */
1686 valueString = (const char *) memchr(addrString, '\0', length);
1687 if (valueString != NULL((void*)0)) {
1688 /* Make sure the first string is a recognized address type,
1689 * and the second string is a valid address of that type.
1690 */
1691 typelen = strlen(addrString) + 1;
1692 addrlen = length - typelen;
1693
1694 for (s = siTypeList; s != NULL((void*)0); s = s->next) {
1695 if (strcmp(addrString, s->typeName) == 0) {
1696 len = s->checkAddr(valueString + 1, addrlen, s->typePriv);
1697 if (len >= 0) {
1698 len += typelen;
1699 }
1700 break;
1701 }
1702 }
1703#ifdef FAMILY_SI_DEBUG
1704 {
1705 const char *resultMsg;
1706
1707 if (s == NULL((void*)0)) {
1708 resultMsg = "type not registered";
1709 }
1710 else {
1711 if (len == -1)
1712 resultMsg = "rejected";
1713 else
1714 resultMsg = "accepted";
1715 }
1716
1717 ErrorF
1718 ("Xserver: siCheckAddr(): type = %s, value = %*.*s, len = %d -- %s\n",
1719 addrString, addrlen, addrlen, valueString + 1, len, resultMsg);
1720 }
1721#endif
1722 }
1723 return len;
1724}
1725
1726/***
1727 * Hostname server-interpreted host type
1728 *
1729 * Stored as hostname string, explicitly defined to be resolved ONLY
1730 * at access check time, to allow for hosts with dynamic addresses
1731 * but static hostnames, such as found in some DHCP & mobile setups.
1732 *
1733 * Hostname must conform to IETF RFC 2396 sec. 3.2.2, which defines it as:
1734 * hostname = *( domainlabel "." ) toplabel [ "." ]
1735 * domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
1736 * toplabel = alpha | alpha *( alphanum | "-" ) alphanum
1737 */
1738
1739#ifdef NI_MAXHOST1025
1740#define SI_HOSTNAME_MAXLEN1025 NI_MAXHOST1025
1741#else
1742#ifdef MAXHOSTNAMELEN256
1743#define SI_HOSTNAME_MAXLEN1025 MAXHOSTNAMELEN256
1744#else
1745#define SI_HOSTNAME_MAXLEN1025 256
1746#endif
1747#endif
1748
1749static Bool
1750siHostnameAddrMatch(int family, void *addr, int len,
1751 const char *siAddr, int siAddrLen, ClientPtr client,
1752 void *typePriv)
1753{
1754 Bool res = FALSE0;
1755
1756/* Currently only supports checking against IPv4 & IPv6 connections, but
1757 * support for other address families, such as DECnet, could be added if
1758 * desired.
1759 */
1760#if defined(IPv61) && defined(AF_INET630)
1761 if ((family == FamilyInternet0) || (family == FamilyInternet66)) {
1762 char hostname[SI_HOSTNAME_MAXLEN1025];
1763 struct addrinfo *addresses;
1764 struct addrinfo *a;
1765 int f, hostaddrlen;
1766 void *hostaddr = NULL((void*)0);
1767
1768 if (siAddrLen >= sizeof(hostname))
1769 return FALSE0;
1770
1771 strlcpy(hostname, siAddr, siAddrLen + 1)__builtin___strlcpy_chk (hostname, siAddr, siAddrLen + 1, __builtin_object_size
(hostname, 2 > 1 ? 1 : 0))
;
1772
1773 if (getaddrinfo(hostname, NULL((void*)0), NULL((void*)0), &addresses) == 0) {
1774 for (a = addresses; a != NULL((void*)0); a = a->ai_next) {
1775 hostaddrlen = a->ai_addrlen;
1776 f = ConvertAddr(a->ai_addr, &hostaddrlen, &hostaddr);
1777 if ((f == family) && (len == hostaddrlen) && hostaddr &&
1778 (memcmp(addr, hostaddr, len) == 0)) {
1779 res = TRUE1;
1780 break;
1781 }
1782 }
1783 freeaddrinfo(addresses);
1784 }
1785 }
1786#else /* IPv6 not supported, use gethostbyname instead for IPv4 */
1787 if (family == FamilyInternet0) {
1788 register struct hostent *hp;
1789
1790#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
1791 _Xgethostbynameparams hparams;
1792#endif
1793 char hostname[SI_HOSTNAME_MAXLEN1025];
1794 int f, hostaddrlen;
1795 void *hostaddr;
1796 const char **addrlist;
1797
1798 if (siAddrLen >= sizeof(hostname))
1799 return FALSE0;
1800
1801 strlcpy(hostname, siAddr, siAddrLen + 1)__builtin___strlcpy_chk (hostname, siAddr, siAddrLen + 1, __builtin_object_size
(hostname, 2 > 1 ? 1 : 0))
;
1802
1803 if ((hp = _XGethostbyname(hostname, hparams)gethostbyname((hostname))) != NULL((void*)0)) {
1804#ifdef h_addrh_addr_list[0] /* new 4.3bsd version of gethostent */
1805 /* iterate over the addresses */
1806 for (addrlist = hp->h_addr_list; *addrlist; addrlist++)
1807#else
1808 addrlist = &hp->h_addrh_addr_list[0];
1809#endif
1810 {
1811 struct sockaddr_in sin;
1812
1813 sin.sin_family = hp->h_addrtype;
1814 memcpy(&(sin.sin_addr), *addrlist, hp->h_length)__builtin___memcpy_chk (&(sin.sin_addr), *addrlist, hp->
h_length, __builtin_object_size (&(sin.sin_addr), 0))
;
1815 hostaddrlen = sizeof(sin);
1816 f = ConvertAddr((struct sockaddr *) &sin,
1817 &hostaddrlen, &hostaddr);
1818 if ((f == family) && (len == hostaddrlen) &&
1819 (memcmp(addr, hostaddr, len) == 0)) {
1820 res = TRUE1;
1821 break;
1822 }
1823 }
1824 }
1825 }
1826#endif
1827 return res;
1828}
1829
1830static int
1831siHostnameCheckAddr(const char *valueString, int length, void *typePriv)
1832{
1833 /* Check conformance of hostname to RFC 2396 sec. 3.2.2 definition.
1834 * We do not use ctype functions here to avoid locale-specific
1835 * character sets. Hostnames must be pure ASCII.
1836 */
1837 int len = length;
1838 int i;
1839 Bool dotAllowed = FALSE0;
1840 Bool dashAllowed = FALSE0;
1841
1842 if ((length <= 0) || (length >= SI_HOSTNAME_MAXLEN1025)) {
1843 len = -1;
1844 }
1845 else {
1846 for (i = 0; i < length; i++) {
1847 char c = valueString[i];
1848
1849 if (c == 0x2E) { /* '.' */
1850 if (dotAllowed == FALSE0) {
1851 len = -1;
1852 break;
1853 }
1854 else {
1855 dotAllowed = FALSE0;
1856 dashAllowed = FALSE0;
1857 }
1858 }
1859 else if (c == 0x2D) { /* '-' */
1860 if (dashAllowed == FALSE0) {
1861 len = -1;
1862 break;
1863 }
1864 else {
1865 dotAllowed = FALSE0;
1866 }
1867 }
1868 else if (((c >= 0x30) && (c <= 0x3A)) /* 0-9 */ ||
1869 ((c >= 0x61) && (c <= 0x7A)) /* a-z */ ||
1870 ((c >= 0x41) && (c <= 0x5A)) /* A-Z */ ) {
1871 dotAllowed = TRUE1;
1872 dashAllowed = TRUE1;
1873 }
1874 else { /* Invalid character */
1875 len = -1;
1876 break;
1877 }
1878 }
1879 }
1880 return len;
1881}
1882
1883#if defined(IPv61) && defined(AF_INET630)
1884/***
1885 * "ipv6" server interpreted type
1886 *
1887 * Currently supports only IPv6 literal address as specified in IETF RFC 3513
1888 *
1889 * Once draft-ietf-ipv6-scoping-arch-00.txt becomes an RFC, support will be
1890 * added for the scoped address format it specifies.
1891 */
1892
1893/* Maximum length of an IPv6 address string - increase when adding support
1894 * for scoped address qualifiers. Includes room for trailing NUL byte.
1895 */
1896#define SI_IPv6_MAXLEN46 INET6_ADDRSTRLEN46
1897
1898static Bool
1899siIPv6AddrMatch(int family, void *addr, int len,
1900 const char *siAddr, int siAddrlen, ClientPtr client,
1901 void *typePriv)
1902{
1903 struct in6_addr addr6;
1904 char addrbuf[SI_IPv6_MAXLEN46];
1905
1906 if ((family != FamilyInternet66) || (len != sizeof(addr6)))
1907 return FALSE0;
1908
1909 memcpy(addrbuf, siAddr, siAddrlen)__builtin___memcpy_chk (addrbuf, siAddr, siAddrlen, __builtin_object_size
(addrbuf, 0))
;
1910 addrbuf[siAddrlen] = '\0';
1911
1912 if (inet_pton(AF_INET630, addrbuf, &addr6) != 1) {
1913 perror("inet_pton");
1914 return FALSE0;
1915 }
1916
1917 if (memcmp(addr, &addr6, len) == 0) {
1918 return TRUE1;
1919 }
1920 else {
1921 return FALSE0;
1922 }
1923}
1924
1925static int
1926siIPv6CheckAddr(const char *addrString, int length, void *typePriv)
1927{
1928 int len;
1929
1930 /* Minimum length is 3 (smallest legal address is "::1") */
1931 if (length < 3) {
1932 /* Address is too short! */
1933 len = -1;
1934 }
1935 else if (length >= SI_IPv6_MAXLEN46) {
1936 /* Address is too long! */
1937 len = -1;
1938 }
1939 else {
1940 /* Assume inet_pton is sufficient validation */
1941 struct in6_addr addr6;
1942 char addrbuf[SI_IPv6_MAXLEN46];
1943
1944 memcpy(addrbuf, addrString, length)__builtin___memcpy_chk (addrbuf, addrString, length, __builtin_object_size
(addrbuf, 0))
;
1945 addrbuf[length] = '\0';
1946
1947 if (inet_pton(AF_INET630, addrbuf, &addr6) != 1) {
1948 perror("inet_pton");
1949 len = -1;
1950 }
1951 else {
1952 len = length;
1953 }
1954 }
1955 return len;
1956}
1957#endif /* IPv6 */
1958
1959#if !defined(NO_LOCAL_CLIENT_CRED)
1960/***
1961 * "localuser" & "localgroup" server interpreted types
1962 *
1963 * Allows local connections from a given local user or group
1964 */
1965
1966#include <pwd.h>
1967#include <grp.h>
1968
1969#define LOCAL_USER1 1
1970#define LOCAL_GROUP2 2
1971
1972typedef struct {
1973 int credType;
1974} siLocalCredPrivRec, *siLocalCredPrivPtr;
1975
1976static siLocalCredPrivRec siLocalUserPriv = { LOCAL_USER1 };
1977static siLocalCredPrivRec siLocalGroupPriv = { LOCAL_GROUP2 };
1978
1979static Bool
1980siLocalCredGetId(const char *addr, int len, siLocalCredPrivPtr lcPriv, int *id)
1981{
1982 Bool parsedOK = FALSE0;
1983 char *addrbuf = malloc(len + 1);
1984
1985 if (addrbuf == NULL((void*)0)) {
1986 return FALSE0;
1987 }
1988
1989 memcpy(addrbuf, addr, len)__builtin___memcpy_chk (addrbuf, addr, len, __builtin_object_size
(addrbuf, 0))
;
1990 addrbuf[len] = '\0';
1991
1992 if (addr[0] == '#') { /* numeric id */
1993 char *cp;
1994
1995 errno(*__error()) = 0;
1996 *id = strtol(addrbuf + 1, &cp, 0);
1997 if ((errno(*__error()) == 0) && (cp != (addrbuf + 1))) {
1998 parsedOK = TRUE1;
1999 }
2000 }
2001 else { /* non-numeric name */
2002 if (lcPriv->credType == LOCAL_USER1) {
2003 struct passwd *pw = getpwnam(addrbuf);
2004
2005 if (pw != NULL((void*)0)) {
2006 *id = (int) pw->pw_uid;
2007 parsedOK = TRUE1;
2008 }
2009 }
2010 else { /* group */
2011 struct group *gr = getgrnam(addrbuf);
2012
2013 if (gr != NULL((void*)0)) {
2014 *id = (int) gr->gr_gid;
2015 parsedOK = TRUE1;
2016 }
2017 }
2018 }
2019
2020 free(addrbuf);
2021 return parsedOK;
2022}
2023
2024static Bool
2025siLocalCredAddrMatch(int family, void *addr, int len,
2026 const char *siAddr, int siAddrlen, ClientPtr client,
2027 void *typePriv)
2028{
2029 int siAddrId;
2030 LocalClientCredRec *lcc;
2031 siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv;
2032
2033 if (GetLocalClientCreds(client, &lcc) == -1) {
2034 return FALSE0;
2035 }
2036
2037#ifdef HAVE_GETZONEID /* Ensure process is in the same zone */
2038 if ((lcc->fieldsSet & LCC_ZID_SET(1 << 3)) && (lcc->zoneid != getzoneid())) {
2039 FreeLocalClientCreds(lcc);
2040 return FALSE0;
2041 }
2042#endif
2043
2044 if (siLocalCredGetId(siAddr, siAddrlen, lcPriv, &siAddrId) == FALSE0) {
2045 FreeLocalClientCreds(lcc);
2046 return FALSE0;
2047 }
2048
2049 if (lcPriv->credType == LOCAL_USER1) {
2050 if ((lcc->fieldsSet & LCC_UID_SET(1 << 0)) && (lcc->euid == siAddrId)) {
2051 FreeLocalClientCreds(lcc);
2052 return TRUE1;
2053 }
2054 }
2055 else {
2056 if ((lcc->fieldsSet & LCC_GID_SET(1 << 1)) && (lcc->egid == siAddrId)) {
2057 FreeLocalClientCreds(lcc);
2058 return TRUE1;
2059 }
2060 if (lcc->pSuppGids != NULL((void*)0)) {
2061 int i;
2062
2063 for (i = 0; i < lcc->nSuppGids; i++) {
2064 if (lcc->pSuppGids[i] == siAddrId) {
2065 FreeLocalClientCreds(lcc);
2066 return TRUE1;
2067 }
2068 }
2069 }
2070 }
2071 FreeLocalClientCreds(lcc);
2072 return FALSE0;
2073}
2074
2075static int
2076siLocalCredCheckAddr(const char *addrString, int length, void *typePriv)
2077{
2078 int len = length;
2079 int id;
2080
2081 if (siLocalCredGetId(addrString, length,
2082 (siLocalCredPrivPtr) typePriv, &id) == FALSE0) {
2083 len = -1;
2084 }
2085 return len;
2086}
2087#endif /* localuser */
2088
2089static void
2090siTypesInitialize(void)
2091{
2092 siTypeAdd("hostname", siHostnameAddrMatch, siHostnameCheckAddr, NULL((void*)0));
2093#if defined(IPv61) && defined(AF_INET630)
2094 siTypeAdd("ipv6", siIPv6AddrMatch, siIPv6CheckAddr, NULL((void*)0));
2095#endif
2096#if !defined(NO_LOCAL_CLIENT_CRED)
2097 siTypeAdd("localuser", siLocalCredAddrMatch, siLocalCredCheckAddr,
2098 &siLocalUserPriv);
2099 siTypeAdd("localgroup", siLocalCredAddrMatch, siLocalCredCheckAddr,
2100 &siLocalGroupPriv);
2101#endif
2102}