Bug Summary

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