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 return -1;
1225#endif
1226}
1227
1228void
1229FreeLocalClientCreds(LocalClientCredRec * lcc)
1230{
1231 if (lcc != NULL((void*)0)) {
1232 if (lcc->nSuppGids > 0) {
1233 free(lcc->pSuppGids);
1234 }
1235 free(lcc);
1236 }
1237}
1238
1239static int
1240AuthorizedClient(ClientPtr client)
1241{
1242 int rc;
1243
1244 if (!client || defeatAccessControl)
1245 return Success0;
1246
1247 /* untrusted clients can't change host access */
1248 rc = XaceHook(XACE_SERVER_ACCESS9, client, DixManageAccess(1<<25));
1249 if (rc != Success0)
1250 return rc;
1251
1252 return client->local ? Success0 : BadAccess10;
1253}
1254
1255/* Add a host to the access control list. This is the external interface
1256 * called from the dispatcher */
1257
1258int
1259AddHost(ClientPtr client, int family, unsigned length, /* of bytes in pAddr */
1260 const void *pAddr)
1261{
1262 int rc, len;
1263
1264 rc = AuthorizedClient(client);
1265 if (rc != Success0)
1266 return rc;
1267 switch (family) {
1268 case FamilyLocalHost(252):
1269 len = length;
1270 LocalHostEnabled = TRUE1;
1271 break;
1272#ifdef SECURE_RPC
1273 case FamilyNetname(254):
1274 len = length;
1275 SecureRPCInit();
1276 break;
1277#endif
1278 case FamilyInternet0:
1279#if defined(IPv61) && defined(AF_INET630)
1280 case FamilyInternet66:
1281#endif
1282 case FamilyDECnet1:
1283 case FamilyChaos2:
1284 case FamilyServerInterpreted5:
1285 if ((len = CheckAddr(family, pAddr, length)) < 0) {
1286 client->errorValue = length;
1287 return BadValue2;
1288 }
1289 break;
1290 case FamilyLocal(256):
1291 default:
1292 client->errorValue = family;
1293 return BadValue2;
1294 }
1295 if (NewHost(family, pAddr, len, FALSE0))
1296 return Success0;
1297 return BadAlloc11;
1298}
1299
1300Bool
1301ForEachHostInFamily(int family, Bool (*func) (unsigned char *addr,
1302 short len,
1303 void *closure),
1304 void *closure)
1305{
1306 HOST *host;
1307
1308 for (host = validhosts; host; host = host->next)
1309 if (family == host->family && func(host->addr, host->len, closure))
1310 return TRUE1;
1311 return FALSE0;
1312}
1313
1314/* Add a host to the access control list. This is the internal interface
1315 * called when starting or resetting the server */
1316static Bool
1317NewHost(int family, const void *addr, int len, int addingLocalHosts)
1318{
1319 register HOST *host;
1320
1321 for (host = validhosts; host; host = host->next) {
1322 if (addrEqual(family, addr, len, host)((family) == (host)->family && (len) == (host)->
len && !memcmp (addr, (host)->addr, len))
)
1323 return TRUE1;
1324 }
1325 if (!addingLocalHosts) { /* Fix for XFree86 bug #156 */
1326 for (host = selfhosts; host; host = host->next) {
1327 if (addrEqual(family, addr, len, host)((family) == (host)->family && (len) == (host)->
len && !memcmp (addr, (host)->addr, len))
) {
1328 host->requested = TRUE1;
1329 break;
1330 }
1331 }
1332 }
1333 MakeHost(host, len)(host)=malloc(sizeof *(host)+(len)); if (host) { (host)->addr
=(unsigned char *) ((host) + 1); (host)->requested = 0; }
1334 if (!host)
1335 return FALSE0;
1336 host->family = family;
1337 host->len = len;
1338 memcpy(host->addr, addr, len)__builtin___memcpy_chk (host->addr, addr, len, __builtin_object_size
(host->addr, 0))
;
1339 host->next = validhosts;
1340 validhosts = host;
1341 return TRUE1;
1342}
1343
1344/* Remove a host from the access control list */
1345
1346int
1347RemoveHost(ClientPtr client, int family, unsigned length, /* of bytes in pAddr */
1348 void *pAddr)
1349{
1350 int rc, len;
1351 register HOST *host, **prev;
1352
1353 rc = AuthorizedClient(client);
1354 if (rc != Success0)
1355 return rc;
1356 switch (family) {
1357 case FamilyLocalHost(252):
1358 len = length;
1359 LocalHostEnabled = FALSE0;
1360 break;
1361#ifdef SECURE_RPC
1362 case FamilyNetname(254):
1363 len = length;
1364 break;
1365#endif
1366 case FamilyInternet0:
1367#if defined(IPv61) && defined(AF_INET630)
1368 case FamilyInternet66:
1369#endif
1370 case FamilyDECnet1:
1371 case FamilyChaos2:
1372 case FamilyServerInterpreted5:
1373 if ((len = CheckAddr(family, pAddr, length)) < 0) {
1374 client->errorValue = length;
1375 return BadValue2;
1376 }
1377 break;
1378 case FamilyLocal(256):
1379 default:
1380 client->errorValue = family;
1381 return BadValue2;
1382 }
1383 for (prev = &validhosts;
1384 (host = *prev) && (!addrEqual(family, pAddr, len, host)((family) == (host)->family && (len) == (host)->
len && !memcmp (pAddr, (host)->addr, len))
);
1385 prev = &host->next);
1386 if (host) {
1387 *prev = host->next;
1388 FreeHost(host)free(host);
1389 }
1390 return Success0;
1391}
1392
1393/* Get all hosts in the access control list */
1394int
1395GetHosts(void **data, int *pnHosts, int *pLen, BOOL * pEnabled)
1396{
1397 int len;
1398 register int n = 0;
1399 register unsigned char *ptr;
1400 register HOST *host;
1401 int nHosts = 0;
1402
1403 *pEnabled = AccessEnabled ? EnableAccess1 : DisableAccess0;
1404 for (host = validhosts; host; host = host->next) {
1405 nHosts++;
1406 n += pad_to_int32(host->len) + sizeof(xHostEntry);
1407 /* Could check for INT_MAX, but in reality having more than 1mb of
1408 hostnames in the access list is ridiculous */
1409 if (n >= 1048576)
1410 break;
1411 }
1412 if (n) {
1413 *data = ptr = malloc(n);
1414 if (!ptr) {
1415 return BadAlloc11;
1416 }
1417 for (host = validhosts; host; host = host->next) {
1418 len = host->len;
1419 if ((ptr + sizeof(xHostEntry) + len) > ((unsigned char *) *data + n))
1420 break;
1421 ((xHostEntry *) ptr)->family = host->family;
1422 ((xHostEntry *) ptr)->length = len;
1423 ptr += sizeof(xHostEntry);
1424 memcpy(ptr, host->addr, len)__builtin___memcpy_chk (ptr, host->addr, len, __builtin_object_size
(ptr, 0))
;
1425 ptr += pad_to_int32(len);
1426 }
1427 }
1428 else {
1429 *data = NULL((void*)0);
1430 }
1431 *pnHosts = nHosts;
1432 *pLen = n;
1433 return Success0;
1434}
1435
1436/* Check for valid address family and length, and return address length. */
1437
1438 /*ARGSUSED*/ static int
1439CheckAddr(int family, const void *pAddr, unsigned length)
1440{
1441 int len;
1442
1443 switch (family) {
1444#if defined(TCPCONN1) || defined(STREAMSCONN)
1445 case FamilyInternet0:
1446 if (length == sizeof(struct in_addr))
1447 len = length;
1448 else
1449 len = -1;
1450 break;
1451#if defined(IPv61) && defined(AF_INET630)
1452 case FamilyInternet66:
1453 if (length == sizeof(struct in6_addr))
1454 len = length;
1455 else
1456 len = -1;
1457 break;
1458#endif
1459#endif
1460 case FamilyServerInterpreted5:
1461 len = siCheckAddr(pAddr, length);
1462 break;
1463 default:
1464 len = -1;
1465 }
1466 return len;
1467}
1468
1469/* Check if a host is not in the access control list.
1470 * Returns 1 if host is invalid, 0 if we've found it. */
1471
1472int
1473InvalidHost(register struct sockaddr *saddr, int len, ClientPtr client)
1474{
1475 int family;
1476 void *addr = NULL((void*)0);
1477 register HOST *selfhost, *host;
1478
1479 if (!AccessEnabled) /* just let them in */
1480 return 0;
1481 family = ConvertAddr(saddr, &len, (void **) &addr);
1482 if (family == -1)
1483 return 1;
1484 if (family == FamilyLocal(256)) {
1485 if (!LocalHostEnabled) {
1486 /*
1487 * check to see if any local address is enabled. This
1488 * implicitly enables local connections.
1489 */
1490 for (selfhost = selfhosts; selfhost; selfhost = selfhost->next) {
1491 for (host = validhosts; host; host = host->next) {
1492 if (addrEqual(selfhost->family, selfhost->addr,((selfhost->family) == (host)->family && (selfhost
->len) == (host)->len && !memcmp (selfhost->
addr, (host)->addr, selfhost->len))
1493 selfhost->len, host)((selfhost->family) == (host)->family && (selfhost
->len) == (host)->len && !memcmp (selfhost->
addr, (host)->addr, selfhost->len))
)
1494 return 0;
1495 }
1496 }
1497 }
1498 else
1499 return 0;
1500 }
1501 for (host = validhosts; host; host = host->next) {
1502 if (host->family == FamilyServerInterpreted5) {
1503 if (siAddrMatch(family, addr, len, host, client)) {
1504 return 0;
1505 }
1506 }
1507 else {
1508 if (addr && addrEqual(family, addr, len, host)((family) == (host)->family && (len) == (host)->
len && !memcmp (addr, (host)->addr, len))
)
1509 return 0;
1510 }
1511
1512 }
1513 return 1;
1514}
1515
1516static int
1517ConvertAddr(register struct sockaddr *saddr, int *len, void **addr)
1518{
1519 if (*len == 0)
1520 return FamilyLocal(256);
1521 switch (saddr->sa_family) {
1522 case AF_UNSPEC0:
1523#if defined(UNIXCONN1) || defined(LOCALCONN)
1524 case AF_UNIX1:
1525#endif
1526 return FamilyLocal(256);
1527#if defined(TCPCONN1) || defined(STREAMSCONN)
1528 case AF_INET2:
1529#ifdef WIN32
1530 if (16777343 == *(long *) &((struct sockaddr_in *) saddr)->sin_addr)
1531 return FamilyLocal(256);
1532#endif
1533 *len = sizeof(struct in_addr);
1534 *addr = (void *) &(((struct sockaddr_in *) saddr)->sin_addr);
1535 return FamilyInternet0;
1536#if defined(IPv61) && defined(AF_INET630)
1537 case AF_INET630:
1538 {
1539 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) saddr;
1540
1541 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))))
) {
1542 *len = sizeof(struct in_addr);
1543 *addr = (void *) &(saddr6->sin6_addr.s6_addr__u6_addr.__u6_addr8[12]);
1544 return FamilyInternet0;
1545 }
1546 else {
1547 *len = sizeof(struct in6_addr);
1548 *addr = (void *) &(saddr6->sin6_addr);
1549 return FamilyInternet66;
1550 }
1551 }
1552#endif
1553#endif
1554 default:
1555 return -1;
1556 }
1557}
1558
1559int
1560ChangeAccessControl(ClientPtr client, int fEnabled)
1561{
1562 int rc = AuthorizedClient(client);
1563
1564 if (rc != Success0)
1565 return rc;
1566 AccessEnabled = fEnabled;
1567 return Success0;
1568}
1569
1570/* returns FALSE if xhost + in effect, else TRUE */
1571int
1572GetAccessControl(void)
1573{
1574 return AccessEnabled;
1575}
1576
1577int
1578GetClientFd(ClientPtr client)
1579{
1580 return ((OsCommPtr) client->osPrivate)->fd;
1581}
1582
1583Bool
1584ClientIsLocal(ClientPtr client)
1585{
1586 XtransConnInfo ci = ((OsCommPtr) client->osPrivate)->trans_conn;
1587
1588 return _XSERVTransIsLocal(ci);
1589}
1590
1591/*****************************************************************************
1592 * FamilyServerInterpreted host entry implementation
1593 *
1594 * Supports an extensible system of host types which the server can interpret
1595 * See the IPv6 extensions to the X11 protocol spec for the definition.
1596 *
1597 * Currently supported schemes:
1598 *
1599 * hostname - hostname as defined in IETF RFC 2396
1600 * ipv6 - IPv6 literal address as defined in IETF RFC's 3513 and <TBD>
1601 *
1602 * See xc/doc/specs/SIAddresses for formal definitions of each type.
1603 */
1604
1605/* These definitions and the siTypeAdd function could be exported in the
1606 * future to enable loading additional host types, but that was not done for
1607 * the initial implementation.
1608 */
1609typedef Bool (*siAddrMatchFunc) (int family, void *addr, int len,
1610 const char *siAddr, int siAddrlen,
1611 ClientPtr client, void *siTypePriv);
1612typedef int (*siCheckAddrFunc) (const char *addrString, int length,
1613 void *siTypePriv);
1614
1615struct siType {
1616 struct siType *next;
1617 const char *typeName;
1618 siAddrMatchFunc addrMatch;
1619 siCheckAddrFunc checkAddr;
1620 void *typePriv; /* Private data for type routines */
1621};
1622
1623static struct siType *siTypeList;
1624
1625static int
1626siTypeAdd(const char *typeName, siAddrMatchFunc addrMatch,
1627 siCheckAddrFunc checkAddr, void *typePriv)
1628{
1629 struct siType *s, *p;
1630
1631 if ((typeName == NULL((void*)0)) || (addrMatch == NULL((void*)0)) || (checkAddr == NULL((void*)0)))
1632 return BadValue2;
1633
1634 for (s = siTypeList, p = NULL((void*)0); s != NULL((void*)0); p = s, s = s->next) {
1635 if (strcmp(typeName, s->typeName) == 0) {
1636 s->addrMatch = addrMatch;
1637 s->checkAddr = checkAddr;
1638 s->typePriv = typePriv;
1639 return Success0;
1640 }
1641 }
1642
1643 s = malloc(sizeof(struct siType));
1644 if (s == NULL((void*)0))
1645 return BadAlloc11;
1646
1647 if (p == NULL((void*)0))
1648 siTypeList = s;
1649 else
1650 p->next = s;
1651
1652 s->next = NULL((void*)0);
1653 s->typeName = typeName;
1654 s->addrMatch = addrMatch;
1655 s->checkAddr = checkAddr;
1656 s->typePriv = typePriv;
1657 return Success0;
1658}
1659
1660/* Checks to see if a host matches a server-interpreted host entry */
1661static Bool
1662siAddrMatch(int family, void *addr, int len, HOST * host, ClientPtr client)
1663{
1664 Bool matches = FALSE0;
1665 struct siType *s;
1666 const char *valueString;
1667 int addrlen;
1668
1669 valueString = (const char *) memchr(host->addr, '\0', host->len);
1670 if (valueString != NULL((void*)0)) {
1671 for (s = siTypeList; s != NULL((void*)0); s = s->next) {
1672 if (strcmp((char *) host->addr, s->typeName) == 0) {
1673 addrlen = host->len - (strlen((char *) host->addr) + 1);
1674 matches = s->addrMatch(family, addr, len,
1675 valueString + 1, addrlen, client,
1676 s->typePriv);
1677 break;
1678 }
1679 }
1680#ifdef FAMILY_SI_DEBUG
1681 ErrorF("Xserver: siAddrMatch(): type = %s, value = %*.*s -- %s\n",
1682 host->addr, addrlen, addrlen, valueString + 1,
1683 (matches) ? "accepted" : "rejected");
1684#endif
1685 }
1686 return matches;
1687}
1688
1689static int
1690siCheckAddr(const char *addrString, int length)
1691{
1692 const char *valueString;
1693 int addrlen, typelen;
1694 int len = -1;
1695 struct siType *s;
1696
1697 /* Make sure there is a \0 byte inside the specified length
1698 to separate the address type from the address value. */
1699 valueString = (const char *) memchr(addrString, '\0', length);
1700 if (valueString != NULL((void*)0)) {
1701 /* Make sure the first string is a recognized address type,
1702 * and the second string is a valid address of that type.
1703 */
1704 typelen = strlen(addrString) + 1;
1705 addrlen = length - typelen;
1706
1707 for (s = siTypeList; s != NULL((void*)0); s = s->next) {
1708 if (strcmp(addrString, s->typeName) == 0) {
1709 len = s->checkAddr(valueString + 1, addrlen, s->typePriv);
1710 if (len >= 0) {
1711 len += typelen;
1712 }
1713 break;
1714 }
1715 }
1716#ifdef FAMILY_SI_DEBUG
1717 {
1718 const char *resultMsg;
1719
1720 if (s == NULL((void*)0)) {
1721 resultMsg = "type not registered";
1722 }
1723 else {
1724 if (len == -1)
1725 resultMsg = "rejected";
1726 else
1727 resultMsg = "accepted";
1728 }
1729
1730 ErrorF
1731 ("Xserver: siCheckAddr(): type = %s, value = %*.*s, len = %d -- %s\n",
1732 addrString, addrlen, addrlen, valueString + 1, len, resultMsg);
1733 }
1734#endif
1735 }
1736 return len;
1737}
1738
1739/***
1740 * Hostname server-interpreted host type
1741 *
1742 * Stored as hostname string, explicitly defined to be resolved ONLY
1743 * at access check time, to allow for hosts with dynamic addresses
1744 * but static hostnames, such as found in some DHCP & mobile setups.
1745 *
1746 * Hostname must conform to IETF RFC 2396 sec. 3.2.2, which defines it as:
1747 * hostname = *( domainlabel "." ) toplabel [ "." ]
1748 * domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
1749 * toplabel = alpha | alpha *( alphanum | "-" ) alphanum
1750 */
1751
1752#ifdef NI_MAXHOST1025
1753#define SI_HOSTNAME_MAXLEN1025 NI_MAXHOST1025
1754#else
1755#ifdef MAXHOSTNAMELEN256
1756#define SI_HOSTNAME_MAXLEN1025 MAXHOSTNAMELEN256
1757#else
1758#define SI_HOSTNAME_MAXLEN1025 256
1759#endif
1760#endif
1761
1762static Bool
1763siHostnameAddrMatch(int family, void *addr, int len,
1764 const char *siAddr, int siAddrLen, ClientPtr client,
1765 void *typePriv)
1766{
1767 Bool res = FALSE0;
1768
1769/* Currently only supports checking against IPv4 & IPv6 connections, but
1770 * support for other address families, such as DECnet, could be added if
1771 * desired.
1772 */
1773#if defined(IPv61) && defined(AF_INET630)
1774 if ((family == FamilyInternet0) || (family == FamilyInternet66)) {
1775 char hostname[SI_HOSTNAME_MAXLEN1025];
1776 struct addrinfo *addresses;
1777 struct addrinfo *a;
1778 int f, hostaddrlen;
1779 void *hostaddr = NULL((void*)0);
1780
1781 if (siAddrLen >= sizeof(hostname))
1782 return FALSE0;
1783
1784 strlcpy(hostname, siAddr, siAddrLen + 1)__builtin___strlcpy_chk (hostname, siAddr, siAddrLen + 1, __builtin_object_size
(hostname, 2 > 1 ? 1 : 0))
;
1785
1786 if (getaddrinfo(hostname, NULL((void*)0), NULL((void*)0), &addresses) == 0) {
1787 for (a = addresses; a != NULL((void*)0); a = a->ai_next) {
1788 hostaddrlen = a->ai_addrlen;
1789 f = ConvertAddr(a->ai_addr, &hostaddrlen, &hostaddr);
1790 if ((f == family) && (len == hostaddrlen) && hostaddr &&
1791 (memcmp(addr, hostaddr, len) == 0)) {
1792 res = TRUE1;
1793 break;
1794 }
1795 }
1796 freeaddrinfo(addresses);
1797 }
1798 }
1799#else /* IPv6 not supported, use gethostbyname instead for IPv4 */
1800 if (family == FamilyInternet0) {
1801 register struct hostent *hp;
1802
1803#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
1804 _Xgethostbynameparams hparams;
1805#endif
1806 char hostname[SI_HOSTNAME_MAXLEN1025];
1807 int f, hostaddrlen;
1808 void *hostaddr;
1809 const char **addrlist;
1810
1811 if (siAddrLen >= sizeof(hostname))
1812 return FALSE0;
1813
1814 strlcpy(hostname, siAddr, siAddrLen + 1)__builtin___strlcpy_chk (hostname, siAddr, siAddrLen + 1, __builtin_object_size
(hostname, 2 > 1 ? 1 : 0))
;
1815
1816 if ((hp = _XGethostbyname(hostname, hparams)gethostbyname((hostname))) != NULL((void*)0)) {
1817#ifdef h_addrh_addr_list[0] /* new 4.3bsd version of gethostent */
1818 /* iterate over the addresses */
1819 for (addrlist = hp->h_addr_list; *addrlist; addrlist++)
1820#else
1821 addrlist = &hp->h_addrh_addr_list[0];
1822#endif
1823 {
1824 struct sockaddr_in sin;
1825
1826 sin.sin_family = hp->h_addrtype;
1827 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))
;
1828 hostaddrlen = sizeof(sin);
1829 f = ConvertAddr((struct sockaddr *) &sin,
1830 &hostaddrlen, &hostaddr);
1831 if ((f == family) && (len == hostaddrlen) &&
1832 (memcmp(addr, hostaddr, len) == 0)) {
1833 res = TRUE1;
1834 break;
1835 }
1836 }
1837 }
1838 }
1839#endif
1840 return res;
1841}
1842
1843static int
1844siHostnameCheckAddr(const char *valueString, int length, void *typePriv)
1845{
1846 /* Check conformance of hostname to RFC 2396 sec. 3.2.2 definition.
1847 * We do not use ctype functions here to avoid locale-specific
1848 * character sets. Hostnames must be pure ASCII.
1849 */
1850 int len = length;
1851 int i;
1852 Bool dotAllowed = FALSE0;
1853 Bool dashAllowed = FALSE0;
1854
1855 if ((length <= 0) || (length >= SI_HOSTNAME_MAXLEN1025)) {
1856 len = -1;
1857 }
1858 else {
1859 for (i = 0; i < length; i++) {
1860 char c = valueString[i];
1861
1862 if (c == 0x2E) { /* '.' */
1863 if (dotAllowed == FALSE0) {
1864 len = -1;
1865 break;
1866 }
1867 else {
1868 dotAllowed = FALSE0;
1869 dashAllowed = FALSE0;
1870 }
1871 }
1872 else if (c == 0x2D) { /* '-' */
1873 if (dashAllowed == FALSE0) {
1874 len = -1;
1875 break;
1876 }
1877 else {
1878 dotAllowed = FALSE0;
1879 }
1880 }
1881 else if (((c >= 0x30) && (c <= 0x3A)) /* 0-9 */ ||
1882 ((c >= 0x61) && (c <= 0x7A)) /* a-z */ ||
1883 ((c >= 0x41) && (c <= 0x5A)) /* A-Z */ ) {
1884 dotAllowed = TRUE1;
1885 dashAllowed = TRUE1;
1886 }
1887 else { /* Invalid character */
1888 len = -1;
1889 break;
1890 }
1891 }
1892 }
1893 return len;
1894}
1895
1896#if defined(IPv61) && defined(AF_INET630)
1897/***
1898 * "ipv6" server interpreted type
1899 *
1900 * Currently supports only IPv6 literal address as specified in IETF RFC 3513
1901 *
1902 * Once draft-ietf-ipv6-scoping-arch-00.txt becomes an RFC, support will be
1903 * added for the scoped address format it specifies.
1904 */
1905
1906/* Maximum length of an IPv6 address string - increase when adding support
1907 * for scoped address qualifiers. Includes room for trailing NUL byte.
1908 */
1909#define SI_IPv6_MAXLEN46 INET6_ADDRSTRLEN46
1910
1911static Bool
1912siIPv6AddrMatch(int family, void *addr, int len,
1913 const char *siAddr, int siAddrlen, ClientPtr client,
1914 void *typePriv)
1915{
1916 struct in6_addr addr6;
1917 char addrbuf[SI_IPv6_MAXLEN46];
1918
1919 if ((family != FamilyInternet66) || (len != sizeof(addr6)))
1920 return FALSE0;
1921
1922 memcpy(addrbuf, siAddr, siAddrlen)__builtin___memcpy_chk (addrbuf, siAddr, siAddrlen, __builtin_object_size
(addrbuf, 0))
;
1923 addrbuf[siAddrlen] = '\0';
1924
1925 if (inet_pton(AF_INET630, addrbuf, &addr6) != 1) {
1926 perror("inet_pton");
1927 return FALSE0;
1928 }
1929
1930 if (memcmp(addr, &addr6, len) == 0) {
1931 return TRUE1;
1932 }
1933 else {
1934 return FALSE0;
1935 }
1936}
1937
1938static int
1939siIPv6CheckAddr(const char *addrString, int length, void *typePriv)
1940{
1941 int len;
1942
1943 /* Minimum length is 3 (smallest legal address is "::1") */
1944 if (length < 3) {
1945 /* Address is too short! */
1946 len = -1;
1947 }
1948 else if (length >= SI_IPv6_MAXLEN46) {
1949 /* Address is too long! */
1950 len = -1;
1951 }
1952 else {
1953 /* Assume inet_pton is sufficient validation */
1954 struct in6_addr addr6;
1955 char addrbuf[SI_IPv6_MAXLEN46];
1956
1957 memcpy(addrbuf, addrString, length)__builtin___memcpy_chk (addrbuf, addrString, length, __builtin_object_size
(addrbuf, 0))
;
1958 addrbuf[length] = '\0';
1959
1960 if (inet_pton(AF_INET630, addrbuf, &addr6) != 1) {
1961 perror("inet_pton");
1962 len = -1;
1963 }
1964 else {
1965 len = length;
1966 }
1967 }
1968 return len;
1969}
1970#endif /* IPv6 */
1971
1972#if !defined(NO_LOCAL_CLIENT_CRED)
1973/***
1974 * "localuser" & "localgroup" server interpreted types
1975 *
1976 * Allows local connections from a given local user or group
1977 */
1978
1979#include <pwd.h>
1980#include <grp.h>
1981
1982#define LOCAL_USER1 1
1983#define LOCAL_GROUP2 2
1984
1985typedef struct {
1986 int credType;
1987} siLocalCredPrivRec, *siLocalCredPrivPtr;
1988
1989static siLocalCredPrivRec siLocalUserPriv = { LOCAL_USER1 };
1990static siLocalCredPrivRec siLocalGroupPriv = { LOCAL_GROUP2 };
1991
1992static Bool
1993siLocalCredGetId(const char *addr, int len, siLocalCredPrivPtr lcPriv, int *id)
1994{
1995 Bool parsedOK = FALSE0;
1996 char *addrbuf = malloc(len + 1);
1997
1998 if (addrbuf == NULL((void*)0)) {
1999 return FALSE0;
2000 }
2001
2002 memcpy(addrbuf, addr, len)__builtin___memcpy_chk (addrbuf, addr, len, __builtin_object_size
(addrbuf, 0))
;
2003 addrbuf[len] = '\0';
2004
2005 if (addr[0] == '#') { /* numeric id */
2006 char *cp;
2007
2008 errno(*__error()) = 0;
2009 *id = strtol(addrbuf + 1, &cp, 0);
2010 if ((errno(*__error()) == 0) && (cp != (addrbuf + 1))) {
2011 parsedOK = TRUE1;
2012 }
2013 }
2014 else { /* non-numeric name */
2015 if (lcPriv->credType == LOCAL_USER1) {
2016 struct passwd *pw = getpwnam(addrbuf);
2017
2018 if (pw != NULL((void*)0)) {
2019 *id = (int) pw->pw_uid;
2020 parsedOK = TRUE1;
2021 }
2022 }
2023 else { /* group */
2024 struct group *gr = getgrnam(addrbuf);
2025
2026 if (gr != NULL((void*)0)) {
2027 *id = (int) gr->gr_gid;
2028 parsedOK = TRUE1;
2029 }
2030 }
2031 }
2032
2033 free(addrbuf);
2034 return parsedOK;
2035}
2036
2037static Bool
2038siLocalCredAddrMatch(int family, void *addr, int len,
2039 const char *siAddr, int siAddrlen, ClientPtr client,
2040 void *typePriv)
2041{
2042 int siAddrId;
2043 LocalClientCredRec *lcc;
2044 siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv;
2045
2046 if (GetLocalClientCreds(client, &lcc) == -1) {
2047 return FALSE0;
2048 }
2049
2050#ifdef HAVE_GETZONEID /* Ensure process is in the same zone */
2051 if ((lcc->fieldsSet & LCC_ZID_SET(1 << 3)) && (lcc->zoneid != getzoneid())) {
2052 FreeLocalClientCreds(lcc);
2053 return FALSE0;
2054 }
2055#endif
2056
2057 if (siLocalCredGetId(siAddr, siAddrlen, lcPriv, &siAddrId) == FALSE0) {
2058 FreeLocalClientCreds(lcc);
2059 return FALSE0;
2060 }
2061
2062 if (lcPriv->credType == LOCAL_USER1) {
2063 if ((lcc->fieldsSet & LCC_UID_SET(1 << 0)) && (lcc->euid == siAddrId)) {
2064 FreeLocalClientCreds(lcc);
2065 return TRUE1;
2066 }
2067 }
2068 else {
2069 if ((lcc->fieldsSet & LCC_GID_SET(1 << 1)) && (lcc->egid == siAddrId)) {
2070 FreeLocalClientCreds(lcc);
2071 return TRUE1;
2072 }
2073 if (lcc->pSuppGids != NULL((void*)0)) {
2074 int i;
2075
2076 for (i = 0; i < lcc->nSuppGids; i++) {
2077 if (lcc->pSuppGids[i] == siAddrId) {
2078 FreeLocalClientCreds(lcc);
2079 return TRUE1;
2080 }
2081 }
2082 }
2083 }
2084 FreeLocalClientCreds(lcc);
2085 return FALSE0;
2086}
2087
2088static int
2089siLocalCredCheckAddr(const char *addrString, int length, void *typePriv)
2090{
2091 int len = length;
2092 int id;
2093
2094 if (siLocalCredGetId(addrString, length,
2095 (siLocalCredPrivPtr) typePriv, &id) == FALSE0) {
2096 len = -1;
2097 }
2098 return len;
2099}
2100#endif /* localuser */
2101
2102static void
2103siTypesInitialize(void)
2104{
2105 siTypeAdd("hostname", siHostnameAddrMatch, siHostnameCheckAddr, NULL((void*)0));
2106#if defined(IPv61) && defined(AF_INET630)
2107 siTypeAdd("ipv6", siIPv6AddrMatch, siIPv6CheckAddr, NULL((void*)0));
2108#endif
2109#if !defined(NO_LOCAL_CLIENT_CRED)
2110 siTypeAdd("localuser", siLocalCredAddrMatch, siLocalCredCheckAddr,
2111 &siLocalUserPriv);
2112 siTypeAdd("localgroup", siLocalCredAddrMatch, siLocalCredCheckAddr,
2113 &siLocalGroupPriv);
2114#endif
2115}