From 432768f75da13ee5343957df6ce5cd316a62929f Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Sat, 8 Jan 2011 19:40:59 +0000
Subject: xserver mesa libX11 xkbcomp pixman git update 8/1/2011

---
 xorg-server/os/access.c     | 4182 ++++++++++++++++++++++---------------------
 xorg-server/os/connection.c |    1 +
 xorg-server/os/osdep.h      |    4 +
 3 files changed, 2100 insertions(+), 2087 deletions(-)

(limited to 'xorg-server/os')

diff --git a/xorg-server/os/access.c b/xorg-server/os/access.c
index d43fdf8e4..b7e698c3b 100644
--- a/xorg-server/os/access.c
+++ b/xorg-server/os/access.c
@@ -1,2087 +1,2095 @@
-/***********************************************************
-
-Copyright 1987, 1998  The Open Group
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, and/or sell copies of the Software, and to permit persons
-to whom the Software is furnished to do so, provided that the above
-copyright notice(s) and this permission notice appear in all copies of
-the Software and that both the above copyright notice(s) and this
-permission notice appear in supporting documentation.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
-INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
-FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder
-shall not be used in advertising or otherwise to promote the sale, use
-or other dealings in this Software without prior written authorization
-of the copyright holder.
-
-X Window System is a trademark of The Open Group.
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its 
-documentation for any purpose and without fee is hereby granted, 
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in 
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifdef WIN32
-#include <X11/Xwinsock.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#define XSERV_t
-#define TRANS_SERVER
-#define TRANS_REOPEN
-#include <X11/Xtrans/Xtrans.h>
-#include <X11/Xauth.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "site.h"
-#include <errno.h>
-#include <sys/types.h>
-#ifndef WIN32
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <ctype.h>
-
-#if defined(TCPCONN) || defined(STREAMSCONN) 
-#include <netinet/in.h>
-#endif /* TCPCONN || STREAMSCONN */
-
-#ifdef HAS_GETPEERUCRED
-# include <ucred.h>
-# ifdef sun
-#  include <zone.h>
-# endif
-#endif
-
-#if defined(SVR4) ||  (defined(SYSV) && defined(__i386__)) || defined(__GNU__)
-# include <sys/utsname.h>
-#endif
-#if defined(SYSV) &&  defined(__i386__)
-# include <sys/stream.h>
-#endif
-#ifdef __GNU__
-#undef SIOCGIFCONF
-#include <netdb.h>
-#else /*!__GNU__*/
-# include <net/if.h>
-#endif /*__GNU__ */
-
-#ifdef SVR4
-#include <sys/sockio.h>
-#include <sys/stropts.h>
-#endif
-
-#include <netdb.h>
-
-#ifdef CSRG_BASED
-#include <sys/param.h>
-#if (BSD >= 199103)
-#define VARIABLE_IFREQ
-#endif
-#endif
-
-#ifdef BSD44SOCKETS
-#ifndef VARIABLE_IFREQ
-#define VARIABLE_IFREQ
-#endif
-#endif
-
-#ifdef HAS_GETIFADDRS
-#include <ifaddrs.h>
-#endif
-
-/* Solaris provides an extended interface SIOCGLIFCONF.  Other systems
- * may have this as well, but the code has only been tested on Solaris
- * so far, so we only enable it there.  Other platforms may be added as
- * needed.
- *
- * Test for Solaris commented out  --  TSI @ UQV  2003.06.13
- */
-#ifdef SIOCGLIFCONF
-/* #if defined(sun) */
-#define USE_SIOCGLIFCONF
-/* #endif */
-#endif
-
-#endif /* WIN32 */
-
-#ifndef PATH_MAX
-#include <sys/param.h>
-#ifndef PATH_MAX
-#ifdef MAXPATHLEN
-#define PATH_MAX MAXPATHLEN
-#else
-#define PATH_MAX 1024
-#endif
-#endif
-#endif 
-
-
-#define X_INCLUDE_NETDB_H
-#include <X11/Xos_r.h>
-
-#include "dixstruct.h"
-#include "osdep.h"
-
-#include "xace.h"
-
-#ifndef PATH_MAX
-#ifdef MAXPATHLEN
-#define PATH_MAX MAXPATHLEN
-#else
-#define PATH_MAX 1024
-#endif
-#endif
-
-Bool defeatAccessControl = FALSE;
-
-#define acmp(a1, a2, len) memcmp((char *)(a1), (char *)(a2), len)
-#define acopy(a1, a2, len) memmove((char *)(a2), (char *)(a1), len)
-#define addrEqual(fam, address, length, host) \
-			 ((fam) == (host)->family &&\
-			  (length) == (host)->len &&\
-			  !acmp (address, (host)->addr, length))
-
-static int ConvertAddr(struct sockaddr * /*saddr*/,
-		       int * /*len*/,
-		       pointer * /*addr*/);
-
-static int CheckAddr(int /*family*/,
-		     const void * /*pAddr*/,
-		     unsigned /*length*/);
-
-static Bool NewHost(int /*family*/,
-		    const void  * /*addr*/,
-		    int /*len*/,
-		    int /* addingLocalHosts */);
-
-/* XFree86 bug #156: To keep track of which hosts were explicitly requested in
-   /etc/X<display>.hosts, we've added a requested field to the HOST struct,
-   and a LocalHostRequested variable.  These default to FALSE, but are set
-   to TRUE in ResetHosts when reading in /etc/X<display>.hosts.  They are
-   checked in DisableLocalHost(), which is called to disable the default 
-   local host entries when stronger authentication is turned on. */
-
-typedef struct _host {
-	short		family;
-	short		len;
-	unsigned char	*addr;
-	struct _host *next;
-	int		requested;
-} HOST;
-
-#define MakeHost(h,l)	(h)=malloc(sizeof *(h)+(l));\
-			if (h) { \
-			   (h)->addr=(unsigned char *) ((h) + 1);\
-			   (h)->requested = FALSE; \
-			}
-#define FreeHost(h)	free(h)
-static HOST *selfhosts = NULL;
-static HOST *validhosts = NULL;
-static int AccessEnabled = DEFAULT_ACCESS_CONTROL;
-static int LocalHostEnabled = FALSE;
-static int LocalHostRequested = FALSE;
-static int UsingXdmcp = FALSE;
-
-/* FamilyServerInterpreted implementation */
-static Bool siAddrMatch(int family, pointer addr, int len, HOST *host, 
-	ClientPtr client);
-static int  siCheckAddr(const char *addrString, int length);
-static void siTypesInitialize(void);
-
-/*
- * called when authorization is not enabled to add the
- * local host to the access list
- */
-
-void
-EnableLocalHost (void)
-{
-    if (!UsingXdmcp)
-    {
-	LocalHostEnabled = TRUE;
-	AddLocalHosts ();
-    }
-}
-
-/*
- * called when authorization is enabled to keep us secure
- */
-void
-DisableLocalHost (void)
-{
-    HOST *self;
-
-    if (!LocalHostRequested)		/* Fix for XFree86 bug #156 */
-	LocalHostEnabled = FALSE;
-    for (self = selfhosts; self; self = self->next) {
-      if (!self->requested)		/* Fix for XFree86 bug #156 */
-	(void) RemoveHost ((ClientPtr)NULL, self->family, self->len, (pointer)self->addr);
-    }
-}
-
-/*
- * called at init time when XDMCP will be used; xdmcp always
- * adds local hosts manually when needed
- */
-
-void
-AccessUsingXdmcp (void)
-{
-    UsingXdmcp = TRUE;
-    LocalHostEnabled = FALSE;
-}
-
-
-#if  defined(SVR4) && !defined(sun)  && defined(SIOCGIFCONF) && !defined(USE_SIOCGLIFCONF)
-
-/* Deal with different SIOCGIFCONF ioctl semantics on these OSs */
-
-static int
-ifioctl (int fd, int cmd, char *arg)
-{
-    struct strioctl ioc;
-    int ret;
-
-    memset((char *) &ioc, 0, sizeof(ioc));
-    ioc.ic_cmd = cmd;
-    ioc.ic_timout = 0;
-    if (cmd == SIOCGIFCONF)
-    {
-	ioc.ic_len = ((struct ifconf *) arg)->ifc_len;
-	ioc.ic_dp = ((struct ifconf *) arg)->ifc_buf;
-    }
-    else
-    {
-	ioc.ic_len = sizeof(struct ifreq);
-	ioc.ic_dp = arg;
-    }
-    ret = ioctl(fd, I_STR, (char *) &ioc);
-    if (ret >= 0 && cmd == SIOCGIFCONF)
-#ifdef SVR4
-	((struct ifconf *) arg)->ifc_len = ioc.ic_len;
-#endif
-    return ret;
-}
-#else
-#define ifioctl ioctl
-#endif
-
-/*
- * DefineSelf (fd):
- *
- * Define this host for access control.  Find all the hosts the OS knows about 
- * for this fd and add them to the selfhosts list.
- */
-
-#if !defined(SIOCGIFCONF) 
-void
-DefineSelf (int fd)
-{
-#if !defined(TCPCONN) && !defined(STREAMSCONN) && !defined(UNIXCONN)
-    return;
-#else
-    register int n;
-    int	len;
-    caddr_t	addr;
-    int		family;
-    register HOST	*host;
-
-#ifndef WIN32
-    struct utsname name;
-#else
-    struct {
-        char  nodename[512];	    
-    } name;
-#endif
-
-    register struct hostent  *hp;
-
-    union {
-	struct  sockaddr   sa;
-	struct  sockaddr_in  in;
-#if defined(IPv6) && defined(AF_INET6)
-	struct  sockaddr_in6  in6;
-#endif
-    } saddr;
-	
-    struct	sockaddr_in	*inetaddr;
-    struct	sockaddr_in6	*inet6addr;
-    struct sockaddr_in broad_addr;
-#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
-    _Xgethostbynameparams hparams;
-#endif
-
-    /* Why not use gethostname()?  Well, at least on my system, I've had to
-     * make an ugly kernel patch to get a name longer than 8 characters, and
-     * uname() lets me access to the whole string (it smashes release, you
-     * see), whereas gethostname() kindly truncates it for me.
-     */
-#ifndef WIN32
-    uname(&name);
-#else
-    gethostname(name.nodename, sizeof(name.nodename));
-#endif
-
-    hp = _XGethostbyname(name.nodename, hparams);
-    if (hp != NULL)
-    {
-	saddr.sa.sa_family = hp->h_addrtype;
-	switch (hp->h_addrtype) {
-	case AF_INET:
-	    inetaddr = (struct sockaddr_in *) (&(saddr.sa));
-	    acopy ( hp->h_addr, &(inetaddr->sin_addr), hp->h_length);
-	    len = sizeof(saddr.sa);
-	    break;
-#if defined(IPv6) && defined(AF_INET6)
-	case AF_INET6:
-	    inet6addr = (struct sockaddr_in6 *) (&(saddr.sa));
-	    acopy ( hp->h_addr, &(inet6addr->sin6_addr), hp->h_length);
-	    len = sizeof(saddr.in6);
-	    break;
-#endif
-	default:
-	    goto DefineLocalHost;
-	}
-	family = ConvertAddr ( &(saddr.sa), &len, (pointer *)&addr);
-	if ( family != -1 && family != FamilyLocal )
-	{
-	    for (host = selfhosts;
-		 host && !addrEqual (family, addr, len, host);
-		 host = host->next) ;
-	    if (!host)
-	    {
-		/* add this host to the host list.	*/
-		MakeHost(host,len)
-		if (host)
-		{
-		    host->family = family;
-		    host->len = len;
-		    acopy ( addr, host->addr, len);
-		    host->next = selfhosts;
-		    selfhosts = host;
-		}
-#ifdef XDMCP
-		/*
-		 *  If this is an Internet Address, but not the localhost
-		 *  address (127.0.0.1), nor the bogus address (0.0.0.0),
-		 *  register it.
-		 */
-		if (family == FamilyInternet &&
-		    !(len == 4 &&
-		      ((addr[0] == 127) ||
-		       (addr[0] == 0 && addr[1] == 0 &&
-			addr[2] == 0 && addr[3] == 0)))
-		      )
-		{
-		    XdmcpRegisterConnection (family, (char *)addr, len);
-		    broad_addr = *inetaddr;
-		    ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
-			htonl (INADDR_BROADCAST);
-		    XdmcpRegisterBroadcastAddress ((struct sockaddr_in *)
-						   &broad_addr);
-		}
-#if defined(IPv6) && defined(AF_INET6)
-		else if (family == FamilyInternet6 &&
-		  !(IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr)))
-		{
-		    XdmcpRegisterConnection (family, (char *)addr, len);
-		}
-#endif
-
-#endif /* XDMCP */
-	    }
-	}
-    }
-    /*
-     * now add a host of family FamilyLocalHost...
-     */
-DefineLocalHost:
-    for (host = selfhosts;
-	 host && !addrEqual(FamilyLocalHost, "", 0, host);
-	 host = host->next);
-    if (!host)
-    {
-	MakeHost(host, 0);
-	if (host)
-	{
-	    host->family = FamilyLocalHost;
-	    host->len = 0;
-	    acopy("", host->addr, 0);
-	    host->next = selfhosts;
-	    selfhosts = host;
-	}
-    }
-#endif /* !TCPCONN && !STREAMSCONN && !UNIXCONN */
-}
-
-#else
-
-#ifdef USE_SIOCGLIFCONF
-#define ifr_type    struct lifreq
-#else
-#define ifr_type    struct ifreq
-#endif
-
-#ifdef VARIABLE_IFREQ
-#define ifr_size(p) (sizeof (struct ifreq) + \
-		     (p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \
-		      p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0))
-#define ifraddr_size(a) (a.sa_len)
-#else
-#define ifr_size(p) (sizeof (ifr_type))
-#define ifraddr_size(a) (sizeof (a))
-#endif
-
-#if defined(IPv6) && defined(AF_INET6)
-#include <arpa/inet.h>
-#endif
-
-#if defined(IPv6) && defined(AF_INET6)
-static void
-in6_fillscopeid(struct sockaddr_in6 *sin6)
-{
-#if defined(__KAME__)
-	if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
-		sin6->sin6_scope_id =
-			ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
-		sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
-	}
-#endif
-}
-#endif
-
-void
-DefineSelf (int fd)
-{
-#ifndef HAS_GETIFADDRS
-    char 		*cp, *cplim;
-# ifdef USE_SIOCGLIFCONF
-    struct sockaddr_storage buf[16];
-    struct lifconf	ifc;
-    register struct lifreq *ifr;
-#  ifdef SIOCGLIFNUM
-    struct lifnum	ifn;
-#  endif
-# else /* !USE_SIOCGLIFCONF */
-    char		buf[2048];
-    struct ifconf	ifc;
-    register struct ifreq *ifr;
-# endif
-    void *		bufptr = buf;   
-#else /* HAS_GETIFADDRS */
-    struct ifaddrs *	ifap, *ifr;
-#endif
-    int 		len;
-    unsigned char *	addr;
-    int 		family;
-    register HOST 	*host;
-    
-#ifndef HAS_GETIFADDRS
-
-    len = sizeof(buf);
-
-#ifdef USE_SIOCGLIFCONF
-    
-#ifdef SIOCGLIFNUM
-    ifn.lifn_family = AF_UNSPEC;
-    ifn.lifn_flags = 0;
-    if (ioctl (fd, SIOCGLIFNUM, (char *) &ifn) < 0)
-        Error ("Getting interface count");    
-    if (len < (ifn.lifn_count * sizeof(struct lifreq))) {
-	len = ifn.lifn_count * sizeof(struct lifreq);
-	bufptr = malloc(len);
-    }
-#endif
-    
-    ifc.lifc_family = AF_UNSPEC;
-    ifc.lifc_flags = 0;
-    ifc.lifc_len = len;
-    ifc.lifc_buf = bufptr;
-
-#define IFC_IOCTL_REQ SIOCGLIFCONF
-#define IFC_IFC_REQ ifc.lifc_req
-#define IFC_IFC_LEN ifc.lifc_len
-#define IFR_IFR_ADDR ifr->lifr_addr
-#define IFR_IFR_NAME ifr->lifr_name
-
-#else /* Use SIOCGIFCONF */
-    ifc.ifc_len = len;
-    ifc.ifc_buf = bufptr;
-
-#define IFC_IOCTL_REQ SIOCGIFCONF
-#define IFC_IFC_REQ ifc.ifc_req
-#define IFC_IFC_LEN ifc.ifc_len
-#define IFR_IFR_ADDR ifr->ifr_addr
-#define IFR_IFR_NAME ifr->ifr_name
-#endif
-
-    if (ifioctl (fd, IFC_IOCTL_REQ, (pointer) &ifc) < 0)
-        Error ("Getting interface configuration (4)");
-
-    cplim = (char *) IFC_IFC_REQ + IFC_IFC_LEN;
-    
-    for (cp = (char *) IFC_IFC_REQ; cp < cplim; cp += ifr_size (ifr))
-    {
-	ifr = (ifr_type *) cp;
-	len = ifraddr_size (IFR_IFR_ADDR);
-	family = ConvertAddr ((struct sockaddr *) &IFR_IFR_ADDR, 
-	  			&len, (pointer *)&addr);
-        if (family == -1 || family == FamilyLocal)
-	    continue;
-#if defined(IPv6) && defined(AF_INET6)
-	if (family == FamilyInternet6) 
-	    in6_fillscopeid((struct sockaddr_in6 *)&IFR_IFR_ADDR);
-#endif
-        for (host = selfhosts;
- 	     host && !addrEqual (family, addr, len, host);
-	     host = host->next)
-	    ;
-        if (host)
-	    continue;
-	MakeHost(host,len)
-	if (host)
-	{
-	    host->family = family;
-	    host->len = len;
-	    acopy(addr, host->addr, len);
-	    host->next = selfhosts;
-	    selfhosts = host;
-	}
-#ifdef XDMCP
-	{
-#ifdef USE_SIOCGLIFCONF
-	    struct sockaddr_storage broad_addr;
-#else
-	    struct sockaddr broad_addr;
-#endif
-
-	    /*
-	     * If this isn't an Internet Address, don't register it.
-	     */
-	    if (family != FamilyInternet
-#if defined(IPv6) && defined(AF_INET6)
-	      && family != FamilyInternet6
-#endif
-		)
-		continue;
-
-	    /*
- 	     * ignore 'localhost' entries as they're not useful
-	     * on the other end of the wire
-	     */
-	    if (family == FamilyInternet &&
-		addr[0] == 127 && addr[1] == 0 &&
-		addr[2] == 0 && addr[3] == 1)
-		continue;
-#if defined(IPv6) && defined(AF_INET6)
-	    else if (family == FamilyInternet6 && 
-	      IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr))
-		continue;
-#endif
-
-	    /*
-	     * Ignore '0.0.0.0' entries as they are
-	     * returned by some OSes for unconfigured NICs but they are
-	     * not useful on the other end of the wire.
-	     */
-	    if (len == 4 &&
-		addr[0] == 0 && addr[1] == 0 &&
-		addr[2] == 0 && addr[3] == 0)
-		continue;
-
-	    XdmcpRegisterConnection (family, (char *)addr, len);
-
-#if defined(IPv6) && defined(AF_INET6)
-	    /* IPv6 doesn't support broadcasting, so we drop out here */
-	    if (family == FamilyInternet6)
-		continue;
-#endif
-
-	    broad_addr = IFR_IFR_ADDR;
-
-	    ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
-		htonl (INADDR_BROADCAST);
-#if defined(USE_SIOCGLIFCONF) && defined(SIOCGLIFBRDADDR)
-	    {
-	    	struct lifreq    broad_req;
-    
-	    	broad_req = *ifr;
-		if (ioctl (fd, SIOCGLIFFLAGS, (char *) &broad_req) != -1 &&
-		    (broad_req.lifr_flags & IFF_BROADCAST) &&
-		    (broad_req.lifr_flags & IFF_UP)
-		    )
-		{
-		    broad_req = *ifr;
-		    if (ioctl (fd, SIOCGLIFBRDADDR, &broad_req) != -1)
-			broad_addr = broad_req.lifr_broadaddr;
-		    else
-			continue;
-		}
-		else
-		    continue;
-	    }
-
-#elif defined(SIOCGIFBRDADDR)
-	    {
-	    	struct ifreq    broad_req;
-    
-	    	broad_req = *ifr;
-		if (ifioctl (fd, SIOCGIFFLAGS, (pointer) &broad_req) != -1 &&
-		    (broad_req.ifr_flags & IFF_BROADCAST) &&
-		    (broad_req.ifr_flags & IFF_UP)
-		    )
-		{
-		    broad_req = *ifr;
-		    if (ifioctl (fd, SIOCGIFBRDADDR, (pointer) &broad_req) != -1)
-			broad_addr = broad_req.ifr_addr;
-		    else
-			continue;
-		}
-		else
-		    continue;
-	    }
-#endif /* SIOCGIFBRDADDR */
-	    XdmcpRegisterBroadcastAddress ((struct sockaddr_in *) &broad_addr);
-	}
-#endif /* XDMCP */
-    }
-    if (bufptr != buf)
-        free(bufptr);    
-#else /* HAS_GETIFADDRS */
-    if (getifaddrs(&ifap) < 0) {
-	ErrorF("Warning: getifaddrs returns %s\n", strerror(errno));
-	return;
-    }
-    for (ifr = ifap; ifr != NULL; ifr = ifr->ifa_next) {
-        if (!ifr->ifa_addr)
-            continue;
-	len = sizeof(*(ifr->ifa_addr));
-	family = ConvertAddr((struct sockaddr *) ifr->ifa_addr, &len,
-			     (pointer *)&addr);
-	if (family == -1 || family == FamilyLocal) 
-	    continue;
-#if defined(IPv6) && defined(AF_INET6)
-	if (family == FamilyInternet6) 
-	    in6_fillscopeid((struct sockaddr_in6 *)ifr->ifa_addr);
-#endif
-
-	for (host = selfhosts; 
-	     host != NULL && !addrEqual(family, addr, len, host);
-	     host = host->next) 
-	    ;
-	if (host != NULL) 
-	    continue;
-	MakeHost(host, len);
-	if (host != NULL) {
-	    host->family = family;
-	    host->len = len;
-	    acopy(addr, host->addr, len);
-	    host->next = selfhosts;
-	    selfhosts = host;
-	}
-#ifdef XDMCP
-	{
-	    /*
-	     * If this isn't an Internet Address, don't register it.
-	     */
-	    if (family != FamilyInternet
-#if defined(IPv6) && defined(AF_INET6)
-		&& family != FamilyInternet6
-#endif
-	    )
-		continue;
-
-	    /* 
-	     * ignore 'localhost' entries as they're not useful
-	     * on the other end of the wire
-	     */
-	    if (ifr->ifa_flags & IFF_LOOPBACK) 
-		    continue;
-
-	    if (family == FamilyInternet && 
-		addr[0] == 127 && addr[1] == 0 &&
-		addr[2] == 0 && addr[3] == 1) 
-		continue;
-
-	    /*
-	     * Ignore '0.0.0.0' entries as they are
-	     * returned by some OSes for unconfigured NICs but they are
-	     * not useful on the other end of the wire.
-	     */
-	    if (len == 4 &&
-		addr[0] == 0 && addr[1] == 0 &&
-		addr[2] == 0 && addr[3] == 0)
-		continue;
-#if defined(IPv6) && defined(AF_INET6)
-	    else if (family == FamilyInternet6 && 
-	      IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr))
-		continue;
-#endif
-	    XdmcpRegisterConnection(family, (char *)addr, len);
-#if defined(IPv6) && defined(AF_INET6)
-	    if (family == FamilyInternet6) 
-		/* IPv6 doesn't support broadcasting, so we drop out here */
-		continue;
-#endif
-	    if ((ifr->ifa_flags & IFF_BROADCAST) &&
-		(ifr->ifa_flags & IFF_UP) &&
-                ifr->ifa_broadaddr)
-		XdmcpRegisterBroadcastAddress(
-		    (struct sockaddr_in *) ifr->ifa_broadaddr);
-	    else
-		continue;
-	}
-#endif /* XDMCP */
-		
-    } /* for */
-    freeifaddrs(ifap);
-#endif /* HAS_GETIFADDRS */
-
-    /*
-     * add something of FamilyLocalHost
-     */
-    for (host = selfhosts;
-	 host && !addrEqual(FamilyLocalHost, "", 0, host);
-	 host = host->next);
-    if (!host)
-    {
-	MakeHost(host, 0);
-	if (host)
-	{
-	    host->family = FamilyLocalHost;
-	    host->len = 0;
-	    acopy("", host->addr, 0);
-	    host->next = selfhosts;
-	    selfhosts = host;
-	}
-    }
-}
-#endif /* hpux && !HAS_IFREQ */
-
-#ifdef XDMCP
-void
-AugmentSelf(pointer from, int len)
-{
-    int family;
-    pointer addr;
-    register HOST *host;
-
-    family = ConvertAddr(from, &len, (pointer *)&addr);
-    if (family == -1 || family == FamilyLocal)
-	return;
-    for (host = selfhosts; host; host = host->next)
-    {
-	if (addrEqual(family, addr, len, host))
-	    return;
-    }
-    MakeHost(host,len)
-    if (!host)
-	return;
-    host->family = family;
-    host->len = len;
-    acopy(addr, host->addr, len);
-    host->next = selfhosts;
-    selfhosts = host;
-}
-#endif
-
-void
-AddLocalHosts (void)
-{
-    HOST    *self;
-
-    for (self = selfhosts; self; self = self->next)
-	    /* Fix for XFree86 bug #156: pass addingLocal = TRUE to
-	     * NewHost to tell that we are adding the default local
-	     * host entries and not to flag the entries as being
-	     * explicitely requested */
-	(void) NewHost (self->family, self->addr, self->len, TRUE);
-}
-
-/* Reset access control list to initial hosts */
-void
-ResetHosts (char *display)
-{
-    register HOST	*host;
-    char                lhostname[120], ohostname[120];
-    char 		*hostname = ohostname;
-    char		fname[PATH_MAX + 1];
-    int			fnamelen;
-    FILE		*fd;
-    char		*ptr;
-    int                 i, hostlen;
-#if (defined(TCPCONN) || defined(STREAMSCONN) ) && \
-     (!defined(IPv6) || !defined(AF_INET6))
-    union {
-        struct sockaddr	sa;
-#if defined(TCPCONN) || defined(STREAMSCONN)
-	struct sockaddr_in in;
-#endif /* TCPCONN || STREAMSCONN */
-    }			saddr;
-#endif
-    int			family = 0;
-    pointer		addr;
-    int 		len;
-
-    siTypesInitialize();
-    AccessEnabled = defeatAccessControl ? FALSE : DEFAULT_ACCESS_CONTROL;
-    LocalHostEnabled = FALSE;
-    while ((host = validhosts) != 0)
-    {
-        validhosts = host->next;
-        FreeHost (host);
-    }
-
-#if defined WIN32 && defined __MINGW32__
-#define ETC_HOST_PREFIX "X"
-#else
-#define ETC_HOST_PREFIX "/etc/X"
-#endif
-#define ETC_HOST_SUFFIX ".hosts"
-    fnamelen = strlen(ETC_HOST_PREFIX) + strlen(ETC_HOST_SUFFIX) +
-		strlen(display) + 1;
-    if (fnamelen > sizeof(fname))
-	FatalError("Display name `%s' is too long\n", display);
-    snprintf(fname, sizeof(fname), ETC_HOST_PREFIX "%s" ETC_HOST_SUFFIX, 
-	     display);
-
-    if ((fd = fopen (fname, "r")) != 0)
-    {
-        while (fgets (ohostname, sizeof (ohostname), fd))
-	{
-	family = FamilyWild;
-	if (*ohostname == '#')
-	    continue;
-    	if ((ptr = strchr(ohostname, '\n')) != 0)
-    	    *ptr = 0;
-        hostlen = strlen(ohostname) + 1;
-        for (i = 0; i < hostlen; i++)
-	    lhostname[i] = tolower(ohostname[i]);
-	hostname = ohostname;
-	if (!strncmp("local:", lhostname, 6))
-	{
-	    family = FamilyLocalHost;
-	    NewHost(family, "", 0, FALSE);
-	    LocalHostRequested = TRUE;	/* Fix for XFree86 bug #156 */
-	}
-#if defined(TCPCONN) || defined(STREAMSCONN)
-	else if (!strncmp("inet:", lhostname, 5))
-	{
-	    family = FamilyInternet;
-	    hostname = ohostname + 5;
-	}
-#if defined(IPv6) && defined(AF_INET6)
-	else if (!strncmp("inet6:", lhostname, 6))
-	{
-	    family = FamilyInternet6;
-	    hostname = ohostname + 6;
-	}
-#endif
-#endif
-#ifdef SECURE_RPC
-	else if (!strncmp("nis:", lhostname, 4))
-	{
-	    family = FamilyNetname;
-	    hostname = ohostname + 4;
-	}
-#endif
-	else if (!strncmp("si:", lhostname, 3))
-	{
-	    family = FamilyServerInterpreted;
-	    hostname = ohostname + 3;
-	    hostlen -= 3;
-	}
-
-
-	if (family == FamilyServerInterpreted) 
-	{
-	    len = siCheckAddr(hostname, hostlen);
-	    if (len >= 0) {
-		NewHost(family, hostname, len, FALSE);
-	    }
-	}
-	else
-#ifdef SECURE_RPC
-	if ((family == FamilyNetname) || (strchr(hostname, '@')))
-	{
-	    SecureRPCInit ();
-	    (void) NewHost (FamilyNetname, hostname, strlen (hostname), FALSE);
-	}
-	else
-#endif /* SECURE_RPC */
-#if defined(TCPCONN) || defined(STREAMSCONN)
-	{
-#if defined(IPv6) && defined(AF_INET6)
-	    if ( (family == FamilyInternet) || (family == FamilyInternet6) ||
-		 (family == FamilyWild) ) 
-            {
-		struct addrinfo *addresses;
-		struct addrinfo *a;
-		int f;
-	    
-		if (getaddrinfo(hostname, NULL, NULL, &addresses) == 0) {
-		    for (a = addresses ; a != NULL ; a = a->ai_next) {
-			len = a->ai_addrlen;
-			f = ConvertAddr(a->ai_addr,&len,(pointer *)&addr);
-			if ( (family == f) || 
-			     ((family == FamilyWild) && (f != -1)) ) {
-			    NewHost(f, addr, len, FALSE);
-			}			
-		    }
-		    freeaddrinfo(addresses);
-		}
-	    }
-#else
-#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
-	    _Xgethostbynameparams hparams;
-#endif
-	    register struct hostent *hp;
-
-    	    /* host name */
-    	    if ((family == FamilyInternet &&
-		 ((hp = _XGethostbyname(hostname, hparams)) != 0)) ||
-		((hp = _XGethostbyname(hostname, hparams)) != 0))
-	    {
-    		saddr.sa.sa_family = hp->h_addrtype;
-		len = sizeof(saddr.sa);
-    		if ((family = ConvertAddr (&saddr.sa, &len, (pointer *)&addr)) != -1)
-		{
-#ifdef h_addr				/* new 4.3bsd version of gethostent */
-		    char **list;
-
-		    /* iterate over the addresses */
-		    for (list = hp->h_addr_list; *list; list++)
-			(void) NewHost (family, (pointer)*list, len, FALSE);
-#else
-    		    (void) NewHost (family, (pointer)hp->h_addr, len, FALSE);
-#endif
-		}
-    	    }
-#endif /* IPv6 */
-        }
-#endif /* TCPCONN || STREAMSCONN */
-	family = FamilyWild;
-        }
-        fclose (fd);
-    }
-}
-
-/* Is client on the local host */
-Bool LocalClient(ClientPtr client)
-{
-    int    		alen, family, notused;
-    Xtransaddr		*from = NULL;
-    pointer		addr;
-    register HOST	*host;
-
-    if (!client->osPrivate)
-        return FALSE;
-    if (!((OsCommPtr)client->osPrivate)->trans_conn)
-        return FALSE;
-
-    if (!_XSERVTransGetPeerAddr (((OsCommPtr)client->osPrivate)->trans_conn,
-	&notused, &alen, &from))
-    {
-	family = ConvertAddr ((struct sockaddr *) from,
-	    &alen, (pointer *)&addr);
-	if (family == -1)
-	{
-	    free(from);
-	    return FALSE;
-	}
-	if (family == FamilyLocal)
-	{
-	    free(from);
-	    return TRUE;
-	}
-	for (host = selfhosts; host; host = host->next)
-	{
-	    if (addrEqual (family, addr, alen, host))
-		return TRUE;
-	}
-	free(from);
-    }
-    return FALSE;
-}
-
-/*
- * Return the uid and gid of a connected local client
- * 
- * Used by XShm to test access rights to shared memory segments
- */
-int
-LocalClientCred(ClientPtr client, int *pUid, int *pGid)
-{
-    LocalClientCredRec *lcc;
-    int ret = GetLocalClientCreds(client, &lcc);
-
-    if (ret == 0) {
-#ifdef HAVE_GETZONEID /* only local if in the same zone */
-	if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) {
-	    FreeLocalClientCreds(lcc);
-	    return -1;
-	}	    
-#endif
-	if ((lcc->fieldsSet & LCC_UID_SET) && (pUid != NULL))
-	    *pUid = lcc->euid;
-	if ((lcc->fieldsSet & LCC_GID_SET) && (pGid != NULL))
-	    *pGid = lcc->egid;
-	FreeLocalClientCreds(lcc);
-    }
-    return ret;
-}
-
-/*
- * Return the uid and all gids of a connected local client
- * Allocates a LocalClientCredRec - caller must call FreeLocalClientCreds
- * 
- * Used by localuser & localgroup ServerInterpreted access control forms below
- * Used by AuthAudit to log who local connections came from
- */
-int
-GetLocalClientCreds(ClientPtr client, LocalClientCredRec **lccp)
-{
-#if defined(HAS_GETPEEREID) || defined(HAS_GETPEERUCRED) || defined(SO_PEERCRED)
-    int fd;
-    XtransConnInfo ci;
-    LocalClientCredRec *lcc;
-#ifdef HAS_GETPEEREID
-    uid_t uid;
-    gid_t gid;
-#elif defined(HAS_GETPEERUCRED)
-    ucred_t *peercred = NULL;
-    const gid_t *gids;
-#elif defined(SO_PEERCRED)
-    struct ucred peercred;
-    socklen_t so_len = sizeof(peercred);
-#endif
-
-    if (client == NULL)
-	return -1;
-    ci = ((OsCommPtr)client->osPrivate)->trans_conn;
-#if !(defined(sun) && defined(HAS_GETPEERUCRED))
-    /* Most implementations can only determine peer credentials for Unix 
-     * domain sockets - Solaris getpeerucred can work with a bit more, so 
-     * we just let it tell us if the connection type is supported or not
-     */
-    if (!_XSERVTransIsLocal(ci)) {
-	return -1;
-    }
-#endif
-
-    *lccp = calloc(1, sizeof(LocalClientCredRec));
-    if (*lccp == NULL)
-	return -1;
-    lcc = *lccp;
-        
-    fd = _XSERVTransGetConnectionNumber(ci);
-#ifdef HAS_GETPEEREID
-    if (getpeereid(fd, &uid, &gid) == -1) {
-	FreeLocalClientCreds(lcc);
-	return -1;
-    }
-    lcc->euid = uid;
-    lcc->egid = gid;
-    lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET;
-    return 0;
-#elif defined(HAS_GETPEERUCRED)
-    if (getpeerucred(fd, &peercred) < 0) {
-	FreeLocalClientCreds(lcc);
-    	return -1;
-    }
-    lcc->euid = ucred_geteuid(peercred);
-    if (lcc->euid != -1)
-	lcc->fieldsSet |= LCC_UID_SET;
-    lcc->egid = ucred_getegid(peercred);
-    if (lcc->egid != -1)
-	lcc->fieldsSet |= LCC_GID_SET;
-    lcc->pid = ucred_getpid(peercred);
-    if (lcc->pid != -1)
-	lcc->fieldsSet |= LCC_PID_SET;
-#ifdef HAVE_GETZONEID
-    lcc->zoneid = ucred_getzoneid(peercred);
-    if (lcc->zoneid != -1)
-	lcc->fieldsSet |= LCC_ZID_SET;
-#endif
-    lcc->nSuppGids = ucred_getgroups(peercred, &gids);
-    if (lcc->nSuppGids > 0) {
-	lcc->pSuppGids = calloc(lcc->nSuppGids, sizeof(int));
-	if (lcc->pSuppGids == NULL) {
-	    lcc->nSuppGids = 0;
-	} else {
-	    int i;
-	    for (i = 0 ; i < lcc->nSuppGids; i++) {
-		(lcc->pSuppGids)[i] = (int) gids[i];
-	    }
-	}
-    } else {
-	lcc->nSuppGids = 0;
-    }
-    ucred_free(peercred);
-    return 0;
-#elif defined(SO_PEERCRED)
-    if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) {
-	FreeLocalClientCreds(lcc);
-	return -1;
-    }
-    lcc->euid = peercred.uid;
-    lcc->egid = peercred.gid;
-    lcc->pid = peercred.pid;
-    lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET;
-    return 0;
-#endif
-#else
-    /* No system call available to get the credentials of the peer */
-#define NO_LOCAL_CLIENT_CRED
-    return -1;
-#endif
-}
-
-void
-FreeLocalClientCreds(LocalClientCredRec *lcc)
-{
-    if (lcc != NULL) {
-	if (lcc->nSuppGids > 0) {
-	    free(lcc->pSuppGids);
-	}
-	free(lcc);
-    }
-}
-
-static int
-AuthorizedClient(ClientPtr client)
-{
-    int rc;
-
-    if (!client || defeatAccessControl)
-	return Success;
-
-    /* untrusted clients can't change host access */
-    rc = XaceHook(XACE_SERVER_ACCESS, client, DixManageAccess);
-    if (rc != Success)
-	return rc;
-
-    return LocalClient(client) ? Success : BadAccess;
-}
-
-/* Add a host to the access control list.  This is the external interface
- * called from the dispatcher */
-
-int
-AddHost (ClientPtr	client,
-	 int            family,
-	 unsigned       length,        /* of bytes in pAddr */
-	 const void *   pAddr)
-{
-    int rc, len;
-
-    rc = AuthorizedClient(client);
-    if (rc != Success)
-	return rc;
-    switch (family) {
-    case FamilyLocalHost:
-	len = length;
-	LocalHostEnabled = TRUE;
-	break;
-#ifdef SECURE_RPC
-    case FamilyNetname:
-	len = length;
-	SecureRPCInit ();
-	break;
-#endif
-    case FamilyInternet:
-#if defined(IPv6) && defined(AF_INET6)
-    case FamilyInternet6:
-#endif
-    case FamilyDECnet:
-    case FamilyChaos:
-    case FamilyServerInterpreted:
-	if ((len = CheckAddr (family, pAddr, length)) < 0)
-	{
-	    client->errorValue = length;
-	    return BadValue;
-	}
-	break;
-    case FamilyLocal:
-    default:
-	client->errorValue = family;
-	return BadValue;
-    }
-    if (NewHost (family, pAddr, len, FALSE))
-	return Success;
-    return BadAlloc;
-}
-
-Bool
-ForEachHostInFamily (int	    family,
-		     Bool    (*func)(
-			 unsigned char * /* addr */,
-			 short           /* len */,
-			 pointer         /* closure */),
-		     pointer closure)
-{
-    HOST    *host;
-
-    for (host = validhosts; host; host = host->next)
-	if (family == host->family && func (host->addr, host->len, closure))
-	    return TRUE;
-    return FALSE;
-}
-
-/* Add a host to the access control list. This is the internal interface 
- * called when starting or resetting the server */
-static Bool
-NewHost (int		family,
-	 const void *	addr,
-	 int		len,
-	 int		addingLocalHosts)
-{
-    register HOST *host;
-
-    for (host = validhosts; host; host = host->next)
-    {
-        if (addrEqual (family, addr, len, host))
-	    return TRUE;
-    }
-    if (!addingLocalHosts) {			/* Fix for XFree86 bug #156 */
-	for (host = selfhosts; host; host = host->next) {
-	    if (addrEqual (family, addr, len, host)) {
-		host->requested = TRUE;
-		break;
-	    }	    
-	}
-    }
-    MakeHost(host,len)
-    if (!host)
-	return FALSE;
-    host->family = family;
-    host->len = len;
-    acopy(addr, host->addr, len);
-    host->next = validhosts;
-    validhosts = host;
-    return TRUE;
-}
-
-/* Remove a host from the access control list */
-
-int
-RemoveHost (
-    ClientPtr		client,
-    int                 family,
-    unsigned            length,        /* of bytes in pAddr */
-    pointer             pAddr)
-{
-    int rc, len;
-    register HOST	*host, **prev;
-
-    rc = AuthorizedClient(client);
-    if (rc != Success)
-	return rc;
-    switch (family) {
-    case FamilyLocalHost:
-	len = length;
-	LocalHostEnabled = FALSE;
-	break;
-#ifdef SECURE_RPC
-    case FamilyNetname:
-	len = length;
-	break;
-#endif
-    case FamilyInternet:
-#if defined(IPv6) && defined(AF_INET6)
-    case FamilyInternet6:
-#endif
-    case FamilyDECnet:
-    case FamilyChaos:
-    case FamilyServerInterpreted:
-    	if ((len = CheckAddr (family, pAddr, length)) < 0)
-    	{
-	    client->errorValue = length;
-            return BadValue;
-    	}
-	break;
-    case FamilyLocal:
-    default:
-	client->errorValue = family;
-        return BadValue;
-    }
-    for (prev = &validhosts;
-         (host = *prev) && (!addrEqual (family, pAddr, len, host));
-         prev = &host->next)
-        ;
-    if (host)
-    {
-        *prev = host->next;
-        FreeHost (host);
-    }
-    return Success;
-}
-
-/* Get all hosts in the access control list */
-int
-GetHosts (
-    pointer		*data,
-    int			*pnHosts,
-    int			*pLen,
-    BOOL		*pEnabled)
-{
-    int			len;
-    register int 	n = 0;
-    register unsigned char *ptr;
-    register HOST	*host;
-    int			nHosts = 0;
-
-    *pEnabled = AccessEnabled ? EnableAccess : DisableAccess;
-    for (host = validhosts; host; host = host->next)
-    {
-	nHosts++;
-	n += pad_to_int32(host->len) + sizeof(xHostEntry);
-    }
-    if (n)
-    {
-        *data = ptr = malloc(n);
-	if (!ptr)
-	{
-	    return BadAlloc;
-	}
-        for (host = validhosts; host; host = host->next)
-	{
-	    len = host->len;
-	    ((xHostEntry *)ptr)->family = host->family;
-	    ((xHostEntry *)ptr)->length = len;
-	    ptr += sizeof(xHostEntry);
-	    acopy (host->addr, ptr, len);
-	    ptr += pad_to_int32(len);
-        }
-    } else {
-	*data = NULL;
-    }
-    *pnHosts = nHosts;
-    *pLen = n;
-    return Success;
-}
-
-/* Check for valid address family and length, and return address length. */
-
-/*ARGSUSED*/
-static int
-CheckAddr (
-    int			family,
-    const void *	pAddr,
-    unsigned		length)
-{
-    int	len;
-
-    switch (family)
-    {
-#if defined(TCPCONN) || defined(STREAMSCONN)
-      case FamilyInternet:
-	if (length == sizeof (struct in_addr))
-	    len = length;
-	else
-	    len = -1;
-        break;
-#if defined(IPv6) && defined(AF_INET6)
-      case FamilyInternet6:
-	if (length == sizeof (struct in6_addr))
-	    len = length;
-	else
-	    len = -1;
-        break;
-#endif
-#endif 
-      case FamilyServerInterpreted:
-	len = siCheckAddr(pAddr, length);
-	break;
-      default:
-        len = -1;
-    }
-    return len;
-}
-
-/* Check if a host is not in the access control list. 
- * Returns 1 if host is invalid, 0 if we've found it. */
-
-int
-InvalidHost (
-    register struct sockaddr	*saddr,
-    int				len,
-    ClientPtr			client)
-{
-    int 			family;
-    pointer			addr;
-    register HOST 		*selfhost, *host;
-
-    if (!AccessEnabled)   /* just let them in */
-        return 0;
-    family = ConvertAddr (saddr, &len, (pointer *)&addr);
-    if (family == -1)
-        return 1;
-    if (family == FamilyLocal)
-    {
-	if (!LocalHostEnabled)
- 	{
-	    /*
-	     * check to see if any local address is enabled.  This 
-	     * implicitly enables local connections.
-	     */
-	    for (selfhost = selfhosts; selfhost; selfhost=selfhost->next)
- 	    {
-		for (host = validhosts; host; host=host->next)
-		{
-		    if (addrEqual (selfhost->family, selfhost->addr,
-				   selfhost->len, host))
-			return 0;
-		}
-	    }
-	} else
-	    return 0;
-    }
-    for (host = validhosts; host; host = host->next)
-    {
-	if ((host->family == FamilyServerInterpreted)) {
-	    if (siAddrMatch (family, addr, len, host, client)) {
-		return 0;
-	    }
-	} else {
-	    if (addrEqual (family, addr, len, host))
-		return 0;
-	}
-
-    }
-    return 1;
-}
-
-static int
-ConvertAddr (
-    register struct sockaddr	*saddr,
-    int				*len,
-    pointer			*addr)
-{
-    if (*len == 0)
-        return FamilyLocal;
-    switch (saddr->sa_family)
-    {
-    case AF_UNSPEC:
-#if defined(UNIXCONN) || defined(LOCALCONN)
-    case AF_UNIX:
-#endif
-        return FamilyLocal;
-#if defined(TCPCONN) || defined(STREAMSCONN)
-    case AF_INET:
-#ifdef WIN32
-        if (16777343 == *(long*)&((struct sockaddr_in *) saddr)->sin_addr)
-            return FamilyLocal;
-#endif
-        *len = sizeof (struct in_addr);
-        *addr = (pointer) &(((struct sockaddr_in *) saddr)->sin_addr);
-        return FamilyInternet;
-#if defined(IPv6) && defined(AF_INET6)
-    case AF_INET6: 
-    {
-	struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) saddr;
-	if (IN6_IS_ADDR_V4MAPPED(&(saddr6->sin6_addr))) {
-	    *len = sizeof (struct in_addr);
-	    *addr = (pointer) &(saddr6->sin6_addr.s6_addr[12]);
-	    return FamilyInternet;
-	} else {
-	    *len = sizeof (struct in6_addr);
-	    *addr = (pointer) &(saddr6->sin6_addr);
-	    return FamilyInternet6;
-	}
-    }
-#endif
-#endif
-    default:
-        return -1;
-    }
-}
-
-int
-ChangeAccessControl(
-    ClientPtr client,
-    int fEnabled)
-{
-    int rc = AuthorizedClient(client);
-    if (rc != Success)
-	return rc;
-    AccessEnabled = fEnabled;
-    return Success;
-}
-
-/* returns FALSE if xhost + in effect, else TRUE */
-int
-GetAccessControl(void)
-{
-    return AccessEnabled;
-}
-
-/*****************************************************************************
- * FamilyServerInterpreted host entry implementation
- *
- * Supports an extensible system of host types which the server can interpret
- * See the IPv6 extensions to the X11 protocol spec for the definition.
- *
- * Currently supported schemes:
- *
- * hostname	- hostname as defined in IETF RFC 2396
- * ipv6		- IPv6 literal address as defined in IETF RFC's 3513 and <TBD>
- *
- * See xc/doc/specs/SIAddresses for formal definitions of each type.
- */
-
-/* These definitions and the siTypeAdd function could be exported in the 
- * future to enable loading additional host types, but that was not done for
- * the initial implementation.
- */
-typedef Bool (*siAddrMatchFunc)(int family, pointer addr, int len, 
-  const char *siAddr, int siAddrlen, ClientPtr client, void *siTypePriv);
-typedef int  (*siCheckAddrFunc)(const char *addrString, int length, 
-  void *siTypePriv);
-
-struct siType {
-    struct siType *	next;
-    const char *	typeName;
-    siAddrMatchFunc	addrMatch;
-    siCheckAddrFunc	checkAddr;
-    void *		typePriv;	/* Private data for type routines */
-};
-
-static struct siType *siTypeList;
-
-static int
-siTypeAdd(const char *typeName, siAddrMatchFunc addrMatch,
-  siCheckAddrFunc checkAddr, void *typePriv)
-{
-    struct siType *s, *p;
-
-    if ((typeName == NULL) || (addrMatch == NULL) || (checkAddr == NULL))
-	return BadValue;
-
-    for (s = siTypeList, p = NULL; s != NULL ; p = s, s = s->next) {
-	if (strcmp(typeName, s->typeName) == 0) {
-	    s->addrMatch = addrMatch;
-	    s->checkAddr = checkAddr;
-	    s->typePriv = typePriv;
-	    return Success;
-	}
-    }
-
-    s = malloc(sizeof(struct siType));
-    if (s == NULL)
-	return BadAlloc;
-
-    if (p == NULL)
-	siTypeList = s;
-    else
-	p->next = s;
-
-    s->next = NULL;
-    s->typeName = typeName;
-    s->addrMatch = addrMatch;
-    s->checkAddr = checkAddr;
-    s->typePriv = typePriv;
-    return Success;
-}
-
-/* Checks to see if a host matches a server-interpreted host entry */
-static Bool 
-siAddrMatch(int family, pointer addr, int len, HOST *host, ClientPtr client)
-{
-    Bool matches = FALSE;
-    struct siType *s;
-    const char *valueString;
-    int addrlen;
-
-    valueString = (const char *) memchr(host->addr, '\0', host->len);
-    if (valueString != NULL) {
-	for (s = siTypeList; s != NULL ; s = s->next) {
-	    if (strcmp((char *) host->addr, s->typeName) == 0) {
-		addrlen = host->len - (strlen((char *)host->addr) + 1);
-		matches = s->addrMatch(family, addr, len, 
-		  valueString + 1, addrlen, client, s->typePriv);
-		break;
-	    }
-	}
-#ifdef FAMILY_SI_DEBUG
-	ErrorF(
-	    "Xserver: siAddrMatch(): type = %s, value = %*.*s -- %s\n",
-	      host->addr, addrlen, addrlen, valueString + 1,
-	      (matches) ? "accepted" : "rejected");
-#endif
-    }
-    return matches;
-}
-
-static int
-siCheckAddr(const char *addrString, int length)
-{
-    const char *valueString;
-    int addrlen, typelen;
-    int len = -1;
-    struct siType *s;
-
-    /* Make sure there is a \0 byte inside the specified length
-       to separate the address type from the address value. */
-    valueString = (const char *) memchr(addrString, '\0', length);
-    if (valueString != NULL) {
-	/* Make sure the first string is a recognized address type,
-	 * and the second string is a valid address of that type. 
-	 */
-	typelen = strlen(addrString) + 1;
-	addrlen = length - typelen;
-
-	for (s = siTypeList; s != NULL ; s = s->next) {
-	    if (strcmp(addrString, s->typeName) == 0) {
-		len = s->checkAddr(valueString + 1, addrlen, s->typePriv);
-		if (len >= 0) {
-		    len += typelen;
-		}
-		break;
-	    }
-	}
-#ifdef FAMILY_SI_DEBUG
-	{
-	    const char *resultMsg;
-
-	    if (s == NULL) {
-		resultMsg = "type not registered";
-	    } else {
-		if (len == -1) 
-		    resultMsg = "rejected";
-		else
-		    resultMsg = "accepted";
-	    }
-
-	    ErrorF("Xserver: siCheckAddr(): type = %s, value = %*.*s, len = %d -- %s\n",
-	      addrString, addrlen, addrlen, valueString + 1, len, resultMsg);
-	}
-#endif
-    }
-    return len;
-}
-
-
-/***
- * Hostname server-interpreted host type
- *
- * Stored as hostname string, explicitly defined to be resolved ONLY
- * at access check time, to allow for hosts with dynamic addresses
- * but static hostnames, such as found in some DHCP & mobile setups.
- *
- * Hostname must conform to IETF RFC 2396 sec. 3.2.2, which defines it as:
- * 	hostname     = *( domainlabel "." ) toplabel [ "." ]
- *	domainlabel  = alphanum | alphanum *( alphanum | "-" ) alphanum
- *	toplabel     = alpha | alpha *( alphanum | "-" ) alphanum
- */
-
-#ifdef NI_MAXHOST
-# define SI_HOSTNAME_MAXLEN NI_MAXHOST
-#else
-# ifdef MAXHOSTNAMELEN
-#  define SI_HOSTNAME_MAXLEN MAXHOSTNAMELEN
-# else
-#  define SI_HOSTNAME_MAXLEN 256
-# endif
-#endif
-
-static Bool 
-siHostnameAddrMatch(int family, pointer addr, int len,
-  const char *siAddr, int siAddrLen, ClientPtr client, void *typePriv)
-{
-    Bool res = FALSE;
-
-/* Currently only supports checking against IPv4 & IPv6 connections, but 
- * support for other address families, such as DECnet, could be added if 
- * desired.
- */
-#if defined(IPv6) && defined(AF_INET6)
-    if ((family == FamilyInternet) || (family == FamilyInternet6)) {
-	char hostname[SI_HOSTNAME_MAXLEN];
-	struct addrinfo *addresses;
-	struct addrinfo *a;
-	int f, hostaddrlen;
-	pointer hostaddr;
-
-	if (siAddrLen >= sizeof(hostname)) 
-	    return FALSE;
-
-	strncpy(hostname, siAddr, siAddrLen);
-	hostname[siAddrLen] = '\0';
-
-	if (getaddrinfo(hostname, NULL, NULL, &addresses) == 0) {
-	    for (a = addresses ; a != NULL ; a = a->ai_next) {
-		hostaddrlen = a->ai_addrlen;
-		f = ConvertAddr(a->ai_addr,&hostaddrlen,&hostaddr);
-		if ((f == family) && (len == hostaddrlen) &&
-		  (acmp (addr, hostaddr, len) == 0) ) {
-		    res = TRUE;
-		    break;
-		}
-	    }
-	    freeaddrinfo(addresses);
-	}
-    }
-#else /* IPv6 not supported, use gethostbyname instead for IPv4 */
-    if (family == FamilyInternet) {
-	register struct hostent *hp;
-#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
-	_Xgethostbynameparams hparams;
-#endif
-	char hostname[SI_HOSTNAME_MAXLEN];
-	int f, hostaddrlen;
-	pointer hostaddr;
-	const char **addrlist;
-
-	if (siAddrLen >= sizeof(hostname)) 
-	    return FALSE;
-
-	strncpy(hostname, siAddr, siAddrLen);
-	hostname[siAddrLen] = '\0';
-
-	if ((hp = _XGethostbyname(hostname, hparams)) != NULL) {
-#ifdef h_addr				/* new 4.3bsd version of gethostent */
-	    /* iterate over the addresses */
-	    for (addrlist = hp->h_addr_list; *addrlist; addrlist++)
-#else
-	    addrlist = &hp->h_addr;
-#endif
-	    {
-		struct  sockaddr_in  sin;
-
-    		sin.sin_family = hp->h_addrtype;
-		acopy ( *addrlist, &(sin.sin_addr), hp->h_length);
-		hostaddrlen = sizeof(sin);
-    		f = ConvertAddr ((struct sockaddr *)&sin, 
-		  &hostaddrlen, &hostaddr);
-		if ((f == family) && (len == hostaddrlen) &&
-		  (acmp (addr, hostaddr, len) == 0) ) {
-		    res = TRUE;
-		    break;
-		}
-    	    }
-        }
-    }
-#endif
-    return res;
-}
-
-
-static int
-siHostnameCheckAddr(const char *valueString, int length, void *typePriv)
-{
-    /* Check conformance of hostname to RFC 2396 sec. 3.2.2 definition.
-     * We do not use ctype functions here to avoid locale-specific
-     * character sets.  Hostnames must be pure ASCII.  
-     */
-    int len = length;
-    int i;
-    Bool dotAllowed = FALSE;
-    Bool dashAllowed = FALSE;
-		    
-    if ((length <= 0) || (length >= SI_HOSTNAME_MAXLEN)) {
-	len = -1;
-    } else {
-	for (i = 0; i < length; i++) {
-	    char c = valueString[i];
-
-	    if (c == 0x2E) { /* '.' */
-		if (dotAllowed == FALSE) {
-		    len = -1;
-		    break;
-		} else {
-		    dotAllowed = FALSE;
-		    dashAllowed = FALSE;
-		}
-	    } else if (c == 0x2D) { /* '-' */
-		if (dashAllowed == FALSE) {
-		    len = -1;
-		    break;
-		} else {
-		    dotAllowed = FALSE;
-		}
-	    } else if (((c >= 0x30) && (c <= 0x3A)) /* 0-9 */ ||
-		       ((c >= 0x61) && (c <= 0x7A)) /* a-z */ ||
-		       ((c >= 0x41) && (c <= 0x5A)) /* A-Z */) {
-		dotAllowed = TRUE;
-		dashAllowed = TRUE;
-	    } else { /* Invalid character */
-		len = -1;
-		break;
-	    }
-	}
-    }
-    return len;
-}
-
-#if defined(IPv6) && defined(AF_INET6)
-/***
- * "ipv6" server interpreted type
- *
- * Currently supports only IPv6 literal address as specified in IETF RFC 3513
- *
- * Once draft-ietf-ipv6-scoping-arch-00.txt becomes an RFC, support will be 
- * added for the scoped address format it specifies.
- */
-
-/* Maximum length of an IPv6 address string - increase when adding support 
- * for scoped address qualifiers.  Includes room for trailing NUL byte. 
- */
-#define SI_IPv6_MAXLEN INET6_ADDRSTRLEN
-
-static Bool 
-siIPv6AddrMatch(int family, pointer addr, int len,
-  const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
-{
-    struct in6_addr addr6;
-    char addrbuf[SI_IPv6_MAXLEN];
-
-    if ((family != FamilyInternet6) || (len != sizeof(addr6)))
-	return FALSE;
-
-    memcpy(addrbuf, siAddr, siAddrlen);
-    addrbuf[siAddrlen] = '\0';
-
-    if (inet_pton(AF_INET6, addrbuf, &addr6) != 1) {
-	perror("inet_pton");
-	return FALSE;
-    }
-
-    if (memcmp(addr, &addr6, len) == 0) {
-	return TRUE;
-    } else {
-	return FALSE;
-    }
-}
-
-static int
-siIPv6CheckAddr(const char *addrString, int length, void *typePriv)
-{
-    int len;
-
-    /* Minimum length is 3 (smallest legal address is "::1") */
-    if (length < 3) {
-	/* Address is too short! */
-	len = -1;
-    } else if (length >= SI_IPv6_MAXLEN) {
-	/* Address is too long! */
-	len = -1;
-    } else {
-	/* Assume inet_pton is sufficient validation */
-	struct in6_addr addr6;
-	char addrbuf[SI_IPv6_MAXLEN];
-
-	memcpy(addrbuf, addrString, length);
-	addrbuf[length] = '\0';
-
-	if (inet_pton(AF_INET6, addrbuf, &addr6) != 1) {
-	    perror("inet_pton");
-	    len = -1;
-	} else {
-	    len = length;
-	}
-    }
-    return len;
-}
-#endif /* IPv6 */
-
-#if !defined(NO_LOCAL_CLIENT_CRED)
-/***
- * "localuser" & "localgroup" server interpreted types
- *
- * Allows local connections from a given local user or group
- */
-
-#include <pwd.h>
-#include <grp.h>
-
-#define LOCAL_USER 1
-#define LOCAL_GROUP 2
-
-typedef struct {
-    int credType;
-} siLocalCredPrivRec, *siLocalCredPrivPtr;
-
-static siLocalCredPrivRec siLocalUserPriv = { LOCAL_USER };
-static siLocalCredPrivRec siLocalGroupPriv = { LOCAL_GROUP };
-
-static Bool
-siLocalCredGetId(const char *addr, int len, siLocalCredPrivPtr lcPriv, int *id)
-{
-    Bool parsedOK = FALSE;
-    char *addrbuf = malloc(len + 1);
-
-    if (addrbuf == NULL) {
-	return FALSE;
-    }
-
-    memcpy(addrbuf, addr, len);
-    addrbuf[len] = '\0';
-
-    if (addr[0] == '#') { /* numeric id */
-	char *cp;
-	errno = 0;
-	*id = strtol(addrbuf + 1, &cp, 0);
-	if ((errno == 0) && (cp != (addrbuf+1))) {
-	    parsedOK = TRUE;
-	}
-    } else { /* non-numeric name */
-	if (lcPriv->credType == LOCAL_USER) {
-	    struct passwd *pw = getpwnam(addrbuf);
-
-	    if (pw != NULL) {
-		*id = (int) pw->pw_uid;
-		parsedOK = TRUE;
-	    }
-	} else { /* group */
-	    struct group *gr = getgrnam(addrbuf);
-
-	    if (gr != NULL) {
-		*id = (int) gr->gr_gid;
-		parsedOK = TRUE;
-	    }
-	}
-    }
-
-    free(addrbuf);
-    return parsedOK;
-}
-
-static Bool 
-siLocalCredAddrMatch(int family, pointer addr, int len,
-  const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
-{
-    int siAddrId;
-    LocalClientCredRec *lcc;
-    siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv;
-
-    if (GetLocalClientCreds(client, &lcc) == -1) {
-	return FALSE;
-    }
-
-#ifdef HAVE_GETZONEID /* Ensure process is in the same zone */
-    if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) {
-	FreeLocalClientCreds(lcc);
-	return FALSE;
-    }
-#endif
-
-    if (siLocalCredGetId(siAddr, siAddrlen, lcPriv, &siAddrId) == FALSE) {
-	FreeLocalClientCreds(lcc);
-	return FALSE;
-    }
-
-    if (lcPriv->credType == LOCAL_USER) {
-	if ((lcc->fieldsSet & LCC_UID_SET) && (lcc->euid == siAddrId)) {
-	    FreeLocalClientCreds(lcc);
-	    return TRUE;
-	}
-    } else {
-	if ((lcc->fieldsSet & LCC_GID_SET) && (lcc->egid == siAddrId)) {
-	    FreeLocalClientCreds(lcc);
-	    return TRUE;
-	}
-	if (lcc->pSuppGids != NULL) {
-	    int i;
-
-	    for (i = 0 ; i < lcc->nSuppGids; i++) {
-		if (lcc->pSuppGids[i] == siAddrId) {
-		    FreeLocalClientCreds(lcc);
-		    return TRUE;
-		}
-	    }
-	}
-    }
-    FreeLocalClientCreds(lcc);
-    return FALSE;
-}
-
-static int
-siLocalCredCheckAddr(const char *addrString, int length, void *typePriv)
-{
-    int len = length;
-    int id;
-
-    if (siLocalCredGetId(addrString, length, 
-	(siLocalCredPrivPtr)typePriv, &id) == FALSE) {
-	len = -1;
-    }
-    return len;
-}
-#endif /* localuser */
-
-static void
-siTypesInitialize(void)
-{
-    siTypeAdd("hostname", siHostnameAddrMatch, siHostnameCheckAddr, NULL);
-#if defined(IPv6) && defined(AF_INET6)
-    siTypeAdd("ipv6", siIPv6AddrMatch, siIPv6CheckAddr, NULL);
-#endif
-#if !defined(NO_LOCAL_CLIENT_CRED)
-    siTypeAdd("localuser", siLocalCredAddrMatch, siLocalCredCheckAddr, 
-      &siLocalUserPriv);
-    siTypeAdd("localgroup", siLocalCredAddrMatch, siLocalCredCheckAddr, 
-      &siLocalGroupPriv);
-#endif
-}
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+X Window System is a trademark of The Open Group.
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef WIN32
+#include <X11/Xwinsock.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#define XSERV_t
+#define TRANS_SERVER
+#define TRANS_REOPEN
+#include <X11/Xtrans/Xtrans.h>
+#include <X11/Xauth.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "site.h"
+#include <errno.h>
+#include <sys/types.h>
+#ifndef WIN32
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <ctype.h>
+
+#if defined(TCPCONN) || defined(STREAMSCONN) 
+#include <netinet/in.h>
+#endif /* TCPCONN || STREAMSCONN */
+
+#ifdef HAS_GETPEERUCRED
+# include <ucred.h>
+# ifdef sun
+#  include <zone.h>
+# endif
+#endif
+
+#if defined(SVR4) ||  (defined(SYSV) && defined(__i386__)) || defined(__GNU__)
+# include <sys/utsname.h>
+#endif
+#if defined(SYSV) &&  defined(__i386__)
+# include <sys/stream.h>
+#endif
+#ifdef __GNU__
+#undef SIOCGIFCONF
+#include <netdb.h>
+#else /*!__GNU__*/
+# include <net/if.h>
+#endif /*__GNU__ */
+
+#ifdef SVR4
+#include <sys/sockio.h>
+#include <sys/stropts.h>
+#endif
+
+#include <netdb.h>
+
+#ifdef CSRG_BASED
+#include <sys/param.h>
+#if (BSD >= 199103)
+#define VARIABLE_IFREQ
+#endif
+#endif
+
+#ifdef BSD44SOCKETS
+#ifndef VARIABLE_IFREQ
+#define VARIABLE_IFREQ
+#endif
+#endif
+
+#ifdef HAS_GETIFADDRS
+#include <ifaddrs.h>
+#endif
+
+/* Solaris provides an extended interface SIOCGLIFCONF.  Other systems
+ * may have this as well, but the code has only been tested on Solaris
+ * so far, so we only enable it there.  Other platforms may be added as
+ * needed.
+ *
+ * Test for Solaris commented out  --  TSI @ UQV  2003.06.13
+ */
+#ifdef SIOCGLIFCONF
+/* #if defined(sun) */
+#define USE_SIOCGLIFCONF
+/* #endif */
+#endif
+
+#endif /* WIN32 */
+
+#ifndef PATH_MAX
+#include <sys/param.h>
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+#endif 
+
+
+#define X_INCLUDE_NETDB_H
+#include <X11/Xos_r.h>
+
+#include "dixstruct.h"
+#include "osdep.h"
+
+#include "xace.h"
+
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+
+Bool defeatAccessControl = FALSE;
+
+#define acmp(a1, a2, len) memcmp((char *)(a1), (char *)(a2), len)
+#define acopy(a1, a2, len) memmove((char *)(a2), (char *)(a1), len)
+#define addrEqual(fam, address, length, host) \
+			 ((fam) == (host)->family &&\
+			  (length) == (host)->len &&\
+			  !acmp (address, (host)->addr, length))
+
+static int ConvertAddr(struct sockaddr * /*saddr*/,
+		       int * /*len*/,
+		       pointer * /*addr*/);
+
+static int CheckAddr(int /*family*/,
+		     const void * /*pAddr*/,
+		     unsigned /*length*/);
+
+static Bool NewHost(int /*family*/,
+		    const void  * /*addr*/,
+		    int /*len*/,
+		    int /* addingLocalHosts */);
+
+/* XFree86 bug #156: To keep track of which hosts were explicitly requested in
+   /etc/X<display>.hosts, we've added a requested field to the HOST struct,
+   and a LocalHostRequested variable.  These default to FALSE, but are set
+   to TRUE in ResetHosts when reading in /etc/X<display>.hosts.  They are
+   checked in DisableLocalHost(), which is called to disable the default 
+   local host entries when stronger authentication is turned on. */
+
+typedef struct _host {
+	short		family;
+	short		len;
+	unsigned char	*addr;
+	struct _host *next;
+	int		requested;
+} HOST;
+
+#define MakeHost(h,l)	(h)=malloc(sizeof *(h)+(l));\
+			if (h) { \
+			   (h)->addr=(unsigned char *) ((h) + 1);\
+			   (h)->requested = FALSE; \
+			}
+#define FreeHost(h)	free(h)
+static HOST *selfhosts = NULL;
+static HOST *validhosts = NULL;
+static int AccessEnabled = DEFAULT_ACCESS_CONTROL;
+static int LocalHostEnabled = FALSE;
+static int LocalHostRequested = FALSE;
+static int UsingXdmcp = FALSE;
+
+/* FamilyServerInterpreted implementation */
+static Bool siAddrMatch(int family, pointer addr, int len, HOST *host, 
+	ClientPtr client);
+static int  siCheckAddr(const char *addrString, int length);
+static void siTypesInitialize(void);
+
+/*
+ * called when authorization is not enabled to add the
+ * local host to the access list
+ */
+
+void
+EnableLocalHost (void)
+{
+    if (!UsingXdmcp)
+    {
+	LocalHostEnabled = TRUE;
+	AddLocalHosts ();
+    }
+}
+
+/*
+ * called when authorization is enabled to keep us secure
+ */
+void
+DisableLocalHost (void)
+{
+    HOST *self;
+
+    if (!LocalHostRequested)		/* Fix for XFree86 bug #156 */
+	LocalHostEnabled = FALSE;
+    for (self = selfhosts; self; self = self->next) {
+      if (!self->requested)		/* Fix for XFree86 bug #156 */
+	(void) RemoveHost ((ClientPtr)NULL, self->family, self->len, (pointer)self->addr);
+    }
+}
+
+/*
+ * called at init time when XDMCP will be used; xdmcp always
+ * adds local hosts manually when needed
+ */
+
+void
+AccessUsingXdmcp (void)
+{
+    UsingXdmcp = TRUE;
+    LocalHostEnabled = FALSE;
+}
+
+
+#if  defined(SVR4) && !defined(sun)  && defined(SIOCGIFCONF) && !defined(USE_SIOCGLIFCONF)
+
+/* Deal with different SIOCGIFCONF ioctl semantics on these OSs */
+
+static int
+ifioctl (int fd, int cmd, char *arg)
+{
+    struct strioctl ioc;
+    int ret;
+
+    memset((char *) &ioc, 0, sizeof(ioc));
+    ioc.ic_cmd = cmd;
+    ioc.ic_timout = 0;
+    if (cmd == SIOCGIFCONF)
+    {
+	ioc.ic_len = ((struct ifconf *) arg)->ifc_len;
+	ioc.ic_dp = ((struct ifconf *) arg)->ifc_buf;
+    }
+    else
+    {
+	ioc.ic_len = sizeof(struct ifreq);
+	ioc.ic_dp = arg;
+    }
+    ret = ioctl(fd, I_STR, (char *) &ioc);
+    if (ret >= 0 && cmd == SIOCGIFCONF)
+#ifdef SVR4
+	((struct ifconf *) arg)->ifc_len = ioc.ic_len;
+#endif
+    return ret;
+}
+#else
+#define ifioctl ioctl
+#endif
+
+/*
+ * DefineSelf (fd):
+ *
+ * Define this host for access control.  Find all the hosts the OS knows about 
+ * for this fd and add them to the selfhosts list.
+ */
+
+#if !defined(SIOCGIFCONF) 
+void
+DefineSelf (int fd)
+{
+#if !defined(TCPCONN) && !defined(STREAMSCONN) && !defined(UNIXCONN)
+    return;
+#else
+    register int n;
+    int	len;
+    caddr_t	addr;
+    int		family;
+    register HOST	*host;
+
+#ifndef WIN32
+    struct utsname name;
+#else
+    struct {
+        char  nodename[512];	    
+    } name;
+#endif
+
+    register struct hostent  *hp;
+
+    union {
+	struct  sockaddr   sa;
+	struct  sockaddr_in  in;
+#if defined(IPv6) && defined(AF_INET6)
+	struct  sockaddr_in6  in6;
+#endif
+    } saddr;
+	
+    struct	sockaddr_in	*inetaddr;
+    struct	sockaddr_in6	*inet6addr;
+    struct sockaddr_in broad_addr;
+#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
+    _Xgethostbynameparams hparams;
+#endif
+
+    /* Why not use gethostname()?  Well, at least on my system, I've had to
+     * make an ugly kernel patch to get a name longer than 8 characters, and
+     * uname() lets me access to the whole string (it smashes release, you
+     * see), whereas gethostname() kindly truncates it for me.
+     */
+#ifndef WIN32
+    uname(&name);
+#else
+    gethostname(name.nodename, sizeof(name.nodename));
+#endif
+
+    hp = _XGethostbyname(name.nodename, hparams);
+    if (hp != NULL)
+    {
+	saddr.sa.sa_family = hp->h_addrtype;
+	switch (hp->h_addrtype) {
+	case AF_INET:
+	    inetaddr = (struct sockaddr_in *) (&(saddr.sa));
+	    acopy ( hp->h_addr, &(inetaddr->sin_addr), hp->h_length);
+	    len = sizeof(saddr.sa);
+	    break;
+#if defined(IPv6) && defined(AF_INET6)
+	case AF_INET6:
+	    inet6addr = (struct sockaddr_in6 *) (&(saddr.sa));
+	    acopy ( hp->h_addr, &(inet6addr->sin6_addr), hp->h_length);
+	    len = sizeof(saddr.in6);
+	    break;
+#endif
+	default:
+	    goto DefineLocalHost;
+	}
+	family = ConvertAddr ( &(saddr.sa), &len, (pointer *)&addr);
+	if ( family != -1 && family != FamilyLocal )
+	{
+	    for (host = selfhosts;
+		 host && !addrEqual (family, addr, len, host);
+		 host = host->next) ;
+	    if (!host)
+	    {
+		/* add this host to the host list.	*/
+		MakeHost(host,len)
+		if (host)
+		{
+		    host->family = family;
+		    host->len = len;
+		    acopy ( addr, host->addr, len);
+		    host->next = selfhosts;
+		    selfhosts = host;
+		}
+#ifdef XDMCP
+		/*
+		 *  If this is an Internet Address, but not the localhost
+		 *  address (127.0.0.1), nor the bogus address (0.0.0.0),
+		 *  register it.
+		 */
+		if (family == FamilyInternet &&
+		    !(len == 4 &&
+		      ((addr[0] == 127) ||
+		       (addr[0] == 0 && addr[1] == 0 &&
+			addr[2] == 0 && addr[3] == 0)))
+		      )
+		{
+		    XdmcpRegisterConnection (family, (char *)addr, len);
+		    broad_addr = *inetaddr;
+		    ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
+			htonl (INADDR_BROADCAST);
+		    XdmcpRegisterBroadcastAddress ((struct sockaddr_in *)
+						   &broad_addr);
+		}
+#if defined(IPv6) && defined(AF_INET6)
+		else if (family == FamilyInternet6 &&
+		  !(IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr)))
+		{
+		    XdmcpRegisterConnection (family, (char *)addr, len);
+		}
+#endif
+
+#endif /* XDMCP */
+	    }
+	}
+    }
+    /*
+     * now add a host of family FamilyLocalHost...
+     */
+DefineLocalHost:
+    for (host = selfhosts;
+	 host && !addrEqual(FamilyLocalHost, "", 0, host);
+	 host = host->next);
+    if (!host)
+    {
+	MakeHost(host, 0);
+	if (host)
+	{
+	    host->family = FamilyLocalHost;
+	    host->len = 0;
+	    acopy("", host->addr, 0);
+	    host->next = selfhosts;
+	    selfhosts = host;
+	}
+    }
+#endif /* !TCPCONN && !STREAMSCONN && !UNIXCONN */
+}
+
+#else
+
+#ifdef USE_SIOCGLIFCONF
+#define ifr_type    struct lifreq
+#else
+#define ifr_type    struct ifreq
+#endif
+
+#ifdef VARIABLE_IFREQ
+#define ifr_size(p) (sizeof (struct ifreq) + \
+		     (p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \
+		      p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0))
+#define ifraddr_size(a) (a.sa_len)
+#else
+#define ifr_size(p) (sizeof (ifr_type))
+#define ifraddr_size(a) (sizeof (a))
+#endif
+
+#if defined(IPv6) && defined(AF_INET6)
+#include <arpa/inet.h>
+#endif
+
+#if defined(IPv6) && defined(AF_INET6)
+static void
+in6_fillscopeid(struct sockaddr_in6 *sin6)
+{
+#if defined(__KAME__)
+	if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+		sin6->sin6_scope_id =
+			ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
+		sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
+	}
+#endif
+}
+#endif
+
+void
+DefineSelf (int fd)
+{
+#ifndef HAS_GETIFADDRS
+    char 		*cp, *cplim;
+# ifdef USE_SIOCGLIFCONF
+    struct sockaddr_storage buf[16];
+    struct lifconf	ifc;
+    register struct lifreq *ifr;
+#  ifdef SIOCGLIFNUM
+    struct lifnum	ifn;
+#  endif
+# else /* !USE_SIOCGLIFCONF */
+    char		buf[2048];
+    struct ifconf	ifc;
+    register struct ifreq *ifr;
+# endif
+    void *		bufptr = buf;   
+#else /* HAS_GETIFADDRS */
+    struct ifaddrs *	ifap, *ifr;
+#endif
+    int 		len;
+    unsigned char *	addr;
+    int 		family;
+    register HOST 	*host;
+    
+#ifndef HAS_GETIFADDRS
+
+    len = sizeof(buf);
+
+#ifdef USE_SIOCGLIFCONF
+    
+#ifdef SIOCGLIFNUM
+    ifn.lifn_family = AF_UNSPEC;
+    ifn.lifn_flags = 0;
+    if (ioctl (fd, SIOCGLIFNUM, (char *) &ifn) < 0)
+        Error ("Getting interface count");    
+    if (len < (ifn.lifn_count * sizeof(struct lifreq))) {
+	len = ifn.lifn_count * sizeof(struct lifreq);
+	bufptr = malloc(len);
+    }
+#endif
+    
+    ifc.lifc_family = AF_UNSPEC;
+    ifc.lifc_flags = 0;
+    ifc.lifc_len = len;
+    ifc.lifc_buf = bufptr;
+
+#define IFC_IOCTL_REQ SIOCGLIFCONF
+#define IFC_IFC_REQ ifc.lifc_req
+#define IFC_IFC_LEN ifc.lifc_len
+#define IFR_IFR_ADDR ifr->lifr_addr
+#define IFR_IFR_NAME ifr->lifr_name
+
+#else /* Use SIOCGIFCONF */
+    ifc.ifc_len = len;
+    ifc.ifc_buf = bufptr;
+
+#define IFC_IOCTL_REQ SIOCGIFCONF
+#define IFC_IFC_REQ ifc.ifc_req
+#define IFC_IFC_LEN ifc.ifc_len
+#define IFR_IFR_ADDR ifr->ifr_addr
+#define IFR_IFR_NAME ifr->ifr_name
+#endif
+
+    if (ifioctl (fd, IFC_IOCTL_REQ, (pointer) &ifc) < 0)
+        Error ("Getting interface configuration (4)");
+
+    cplim = (char *) IFC_IFC_REQ + IFC_IFC_LEN;
+    
+    for (cp = (char *) IFC_IFC_REQ; cp < cplim; cp += ifr_size (ifr))
+    {
+	ifr = (ifr_type *) cp;
+	len = ifraddr_size (IFR_IFR_ADDR);
+	family = ConvertAddr ((struct sockaddr *) &IFR_IFR_ADDR, 
+	  			&len, (pointer *)&addr);
+        if (family == -1 || family == FamilyLocal)
+	    continue;
+#if defined(IPv6) && defined(AF_INET6)
+	if (family == FamilyInternet6) 
+	    in6_fillscopeid((struct sockaddr_in6 *)&IFR_IFR_ADDR);
+#endif
+        for (host = selfhosts;
+ 	     host && !addrEqual (family, addr, len, host);
+	     host = host->next)
+	    ;
+        if (host)
+	    continue;
+	MakeHost(host,len)
+	if (host)
+	{
+	    host->family = family;
+	    host->len = len;
+	    acopy(addr, host->addr, len);
+	    host->next = selfhosts;
+	    selfhosts = host;
+	}
+#ifdef XDMCP
+	{
+#ifdef USE_SIOCGLIFCONF
+	    struct sockaddr_storage broad_addr;
+#else
+	    struct sockaddr broad_addr;
+#endif
+
+	    /*
+	     * If this isn't an Internet Address, don't register it.
+	     */
+	    if (family != FamilyInternet
+#if defined(IPv6) && defined(AF_INET6)
+	      && family != FamilyInternet6
+#endif
+		)
+		continue;
+
+	    /*
+ 	     * ignore 'localhost' entries as they're not useful
+	     * on the other end of the wire
+	     */
+	    if (family == FamilyInternet &&
+		addr[0] == 127 && addr[1] == 0 &&
+		addr[2] == 0 && addr[3] == 1)
+		continue;
+#if defined(IPv6) && defined(AF_INET6)
+	    else if (family == FamilyInternet6 && 
+	      IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr))
+		continue;
+#endif
+
+	    /*
+	     * Ignore '0.0.0.0' entries as they are
+	     * returned by some OSes for unconfigured NICs but they are
+	     * not useful on the other end of the wire.
+	     */
+	    if (len == 4 &&
+		addr[0] == 0 && addr[1] == 0 &&
+		addr[2] == 0 && addr[3] == 0)
+		continue;
+
+	    XdmcpRegisterConnection (family, (char *)addr, len);
+
+#if defined(IPv6) && defined(AF_INET6)
+	    /* IPv6 doesn't support broadcasting, so we drop out here */
+	    if (family == FamilyInternet6)
+		continue;
+#endif
+
+	    broad_addr = IFR_IFR_ADDR;
+
+	    ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
+		htonl (INADDR_BROADCAST);
+#if defined(USE_SIOCGLIFCONF) && defined(SIOCGLIFBRDADDR)
+	    {
+	    	struct lifreq    broad_req;
+    
+	    	broad_req = *ifr;
+		if (ioctl (fd, SIOCGLIFFLAGS, (char *) &broad_req) != -1 &&
+		    (broad_req.lifr_flags & IFF_BROADCAST) &&
+		    (broad_req.lifr_flags & IFF_UP)
+		    )
+		{
+		    broad_req = *ifr;
+		    if (ioctl (fd, SIOCGLIFBRDADDR, &broad_req) != -1)
+			broad_addr = broad_req.lifr_broadaddr;
+		    else
+			continue;
+		}
+		else
+		    continue;
+	    }
+
+#elif defined(SIOCGIFBRDADDR)
+	    {
+	    	struct ifreq    broad_req;
+    
+	    	broad_req = *ifr;
+		if (ifioctl (fd, SIOCGIFFLAGS, (pointer) &broad_req) != -1 &&
+		    (broad_req.ifr_flags & IFF_BROADCAST) &&
+		    (broad_req.ifr_flags & IFF_UP)
+		    )
+		{
+		    broad_req = *ifr;
+		    if (ifioctl (fd, SIOCGIFBRDADDR, (pointer) &broad_req) != -1)
+			broad_addr = broad_req.ifr_addr;
+		    else
+			continue;
+		}
+		else
+		    continue;
+	    }
+#endif /* SIOCGIFBRDADDR */
+	    XdmcpRegisterBroadcastAddress ((struct sockaddr_in *) &broad_addr);
+	}
+#endif /* XDMCP */
+    }
+    if (bufptr != buf)
+        free(bufptr);    
+#else /* HAS_GETIFADDRS */
+    if (getifaddrs(&ifap) < 0) {
+	ErrorF("Warning: getifaddrs returns %s\n", strerror(errno));
+	return;
+    }
+    for (ifr = ifap; ifr != NULL; ifr = ifr->ifa_next) {
+        if (!ifr->ifa_addr)
+            continue;
+	len = sizeof(*(ifr->ifa_addr));
+	family = ConvertAddr((struct sockaddr *) ifr->ifa_addr, &len,
+			     (pointer *)&addr);
+	if (family == -1 || family == FamilyLocal) 
+	    continue;
+#if defined(IPv6) && defined(AF_INET6)
+	if (family == FamilyInternet6) 
+	    in6_fillscopeid((struct sockaddr_in6 *)ifr->ifa_addr);
+#endif
+
+	for (host = selfhosts; 
+	     host != NULL && !addrEqual(family, addr, len, host);
+	     host = host->next) 
+	    ;
+	if (host != NULL) 
+	    continue;
+	MakeHost(host, len);
+	if (host != NULL) {
+	    host->family = family;
+	    host->len = len;
+	    acopy(addr, host->addr, len);
+	    host->next = selfhosts;
+	    selfhosts = host;
+	}
+#ifdef XDMCP
+	{
+	    /*
+	     * If this isn't an Internet Address, don't register it.
+	     */
+	    if (family != FamilyInternet
+#if defined(IPv6) && defined(AF_INET6)
+		&& family != FamilyInternet6
+#endif
+	    )
+		continue;
+
+	    /* 
+	     * ignore 'localhost' entries as they're not useful
+	     * on the other end of the wire
+	     */
+	    if (ifr->ifa_flags & IFF_LOOPBACK) 
+		    continue;
+
+	    if (family == FamilyInternet && 
+		addr[0] == 127 && addr[1] == 0 &&
+		addr[2] == 0 && addr[3] == 1) 
+		continue;
+
+	    /*
+	     * Ignore '0.0.0.0' entries as they are
+	     * returned by some OSes for unconfigured NICs but they are
+	     * not useful on the other end of the wire.
+	     */
+	    if (len == 4 &&
+		addr[0] == 0 && addr[1] == 0 &&
+		addr[2] == 0 && addr[3] == 0)
+		continue;
+#if defined(IPv6) && defined(AF_INET6)
+	    else if (family == FamilyInternet6 && 
+	      IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr))
+		continue;
+#endif
+	    XdmcpRegisterConnection(family, (char *)addr, len);
+#if defined(IPv6) && defined(AF_INET6)
+	    if (family == FamilyInternet6) 
+		/* IPv6 doesn't support broadcasting, so we drop out here */
+		continue;
+#endif
+	    if ((ifr->ifa_flags & IFF_BROADCAST) &&
+		(ifr->ifa_flags & IFF_UP) &&
+                ifr->ifa_broadaddr)
+		XdmcpRegisterBroadcastAddress(
+		    (struct sockaddr_in *) ifr->ifa_broadaddr);
+	    else
+		continue;
+	}
+#endif /* XDMCP */
+		
+    } /* for */
+    freeifaddrs(ifap);
+#endif /* HAS_GETIFADDRS */
+
+    /*
+     * add something of FamilyLocalHost
+     */
+    for (host = selfhosts;
+	 host && !addrEqual(FamilyLocalHost, "", 0, host);
+	 host = host->next);
+    if (!host)
+    {
+	MakeHost(host, 0);
+	if (host)
+	{
+	    host->family = FamilyLocalHost;
+	    host->len = 0;
+	    acopy("", host->addr, 0);
+	    host->next = selfhosts;
+	    selfhosts = host;
+	}
+    }
+}
+#endif /* hpux && !HAS_IFREQ */
+
+#ifdef XDMCP
+void
+AugmentSelf(pointer from, int len)
+{
+    int family;
+    pointer addr;
+    register HOST *host;
+
+    family = ConvertAddr(from, &len, (pointer *)&addr);
+    if (family == -1 || family == FamilyLocal)
+	return;
+    for (host = selfhosts; host; host = host->next)
+    {
+	if (addrEqual(family, addr, len, host))
+	    return;
+    }
+    MakeHost(host,len)
+    if (!host)
+	return;
+    host->family = family;
+    host->len = len;
+    acopy(addr, host->addr, len);
+    host->next = selfhosts;
+    selfhosts = host;
+}
+#endif
+
+void
+AddLocalHosts (void)
+{
+    HOST    *self;
+
+    for (self = selfhosts; self; self = self->next)
+	    /* Fix for XFree86 bug #156: pass addingLocal = TRUE to
+	     * NewHost to tell that we are adding the default local
+	     * host entries and not to flag the entries as being
+	     * explicitely requested */
+	(void) NewHost (self->family, self->addr, self->len, TRUE);
+}
+
+/* Reset access control list to initial hosts */
+void
+ResetHosts (char *display)
+{
+    register HOST	*host;
+    char                lhostname[120], ohostname[120];
+    char 		*hostname = ohostname;
+    char		fname[PATH_MAX + 1];
+    int			fnamelen;
+    FILE		*fd;
+    char		*ptr;
+    int                 i, hostlen;
+#if (defined(TCPCONN) || defined(STREAMSCONN) ) && \
+     (!defined(IPv6) || !defined(AF_INET6))
+    union {
+        struct sockaddr	sa;
+#if defined(TCPCONN) || defined(STREAMSCONN)
+	struct sockaddr_in in;
+#endif /* TCPCONN || STREAMSCONN */
+    }			saddr;
+#endif
+    int			family = 0;
+    pointer		addr;
+    int 		len;
+
+    siTypesInitialize();
+    AccessEnabled = defeatAccessControl ? FALSE : DEFAULT_ACCESS_CONTROL;
+    LocalHostEnabled = FALSE;
+    while ((host = validhosts) != 0)
+    {
+        validhosts = host->next;
+        FreeHost (host);
+    }
+
+#if defined WIN32 && defined __MINGW32__
+#define ETC_HOST_PREFIX "X"
+#else
+#define ETC_HOST_PREFIX "/etc/X"
+#endif
+#define ETC_HOST_SUFFIX ".hosts"
+    fnamelen = strlen(ETC_HOST_PREFIX) + strlen(ETC_HOST_SUFFIX) +
+		strlen(display) + 1;
+    if (fnamelen > sizeof(fname))
+	FatalError("Display name `%s' is too long\n", display);
+    snprintf(fname, sizeof(fname), ETC_HOST_PREFIX "%s" ETC_HOST_SUFFIX, 
+	     display);
+
+    if ((fd = fopen (fname, "r")) != 0)
+    {
+        while (fgets (ohostname, sizeof (ohostname), fd))
+	{
+	family = FamilyWild;
+	if (*ohostname == '#')
+	    continue;
+    	if ((ptr = strchr(ohostname, '\n')) != 0)
+    	    *ptr = 0;
+        hostlen = strlen(ohostname) + 1;
+        for (i = 0; i < hostlen; i++)
+	    lhostname[i] = tolower(ohostname[i]);
+	hostname = ohostname;
+	if (!strncmp("local:", lhostname, 6))
+	{
+	    family = FamilyLocalHost;
+	    NewHost(family, "", 0, FALSE);
+	    LocalHostRequested = TRUE;	/* Fix for XFree86 bug #156 */
+	}
+#if defined(TCPCONN) || defined(STREAMSCONN)
+	else if (!strncmp("inet:", lhostname, 5))
+	{
+	    family = FamilyInternet;
+	    hostname = ohostname + 5;
+	}
+#if defined(IPv6) && defined(AF_INET6)
+	else if (!strncmp("inet6:", lhostname, 6))
+	{
+	    family = FamilyInternet6;
+	    hostname = ohostname + 6;
+	}
+#endif
+#endif
+#ifdef SECURE_RPC
+	else if (!strncmp("nis:", lhostname, 4))
+	{
+	    family = FamilyNetname;
+	    hostname = ohostname + 4;
+	}
+#endif
+	else if (!strncmp("si:", lhostname, 3))
+	{
+	    family = FamilyServerInterpreted;
+	    hostname = ohostname + 3;
+	    hostlen -= 3;
+	}
+
+
+	if (family == FamilyServerInterpreted) 
+	{
+	    len = siCheckAddr(hostname, hostlen);
+	    if (len >= 0) {
+		NewHost(family, hostname, len, FALSE);
+	    }
+	}
+	else
+#ifdef SECURE_RPC
+	if ((family == FamilyNetname) || (strchr(hostname, '@')))
+	{
+	    SecureRPCInit ();
+	    (void) NewHost (FamilyNetname, hostname, strlen (hostname), FALSE);
+	}
+	else
+#endif /* SECURE_RPC */
+#if defined(TCPCONN) || defined(STREAMSCONN)
+	{
+#if defined(IPv6) && defined(AF_INET6)
+	    if ( (family == FamilyInternet) || (family == FamilyInternet6) ||
+		 (family == FamilyWild) ) 
+            {
+		struct addrinfo *addresses;
+		struct addrinfo *a;
+		int f;
+	    
+		if (getaddrinfo(hostname, NULL, NULL, &addresses) == 0) {
+		    for (a = addresses ; a != NULL ; a = a->ai_next) {
+			len = a->ai_addrlen;
+			f = ConvertAddr(a->ai_addr,&len,(pointer *)&addr);
+			if ( (family == f) || 
+			     ((family == FamilyWild) && (f != -1)) ) {
+			    NewHost(f, addr, len, FALSE);
+			}			
+		    }
+		    freeaddrinfo(addresses);
+		}
+	    }
+#else
+#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
+	    _Xgethostbynameparams hparams;
+#endif
+	    register struct hostent *hp;
+
+    	    /* host name */
+    	    if ((family == FamilyInternet &&
+		 ((hp = _XGethostbyname(hostname, hparams)) != 0)) ||
+		((hp = _XGethostbyname(hostname, hparams)) != 0))
+	    {
+    		saddr.sa.sa_family = hp->h_addrtype;
+		len = sizeof(saddr.sa);
+    		if ((family = ConvertAddr (&saddr.sa, &len, (pointer *)&addr)) != -1)
+		{
+#ifdef h_addr				/* new 4.3bsd version of gethostent */
+		    char **list;
+
+		    /* iterate over the addresses */
+		    for (list = hp->h_addr_list; *list; list++)
+			(void) NewHost (family, (pointer)*list, len, FALSE);
+#else
+    		    (void) NewHost (family, (pointer)hp->h_addr, len, FALSE);
+#endif
+		}
+    	    }
+#endif /* IPv6 */
+        }
+#endif /* TCPCONN || STREAMSCONN */
+	family = FamilyWild;
+        }
+        fclose (fd);
+    }
+}
+
+/* Is client on the local host */
+Bool
+ComputeLocalClient(ClientPtr client)
+{
+    int    		alen, family, notused;
+    Xtransaddr		*from = NULL;
+    pointer		addr;
+    register HOST	*host;
+    OsCommPtr           oc = (OsCommPtr) client->osPrivate;
+
+    if (!oc->trans_conn)
+        return FALSE;
+
+    if (!_XSERVTransGetPeerAddr (oc->trans_conn, &notused, &alen, &from))
+    {
+	family = ConvertAddr ((struct sockaddr *) from,
+	    &alen, (pointer *)&addr);
+	if (family == -1)
+	{
+	    free(from);
+	    return FALSE;
+	}
+	if (family == FamilyLocal)
+	{
+	    free(from);
+	    return TRUE;
+	}
+	for (host = selfhosts; host; host = host->next)
+	{
+	    if (addrEqual (family, addr, alen, host)) {
+		free(from);
+		return TRUE;
+	    }
+	}
+	free(from);
+    }
+    return FALSE;
+}
+
+Bool LocalClient(ClientPtr client)
+{
+    if (!client->osPrivate)
+        return FALSE;
+    return ((OsCommPtr)client->osPrivate)->local_client;
+}
+
+/*
+ * Return the uid and gid of a connected local client
+ * 
+ * Used by XShm to test access rights to shared memory segments
+ */
+int
+LocalClientCred(ClientPtr client, int *pUid, int *pGid)
+{
+    LocalClientCredRec *lcc;
+    int ret = GetLocalClientCreds(client, &lcc);
+
+    if (ret == 0) {
+#ifdef HAVE_GETZONEID /* only local if in the same zone */
+	if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) {
+	    FreeLocalClientCreds(lcc);
+	    return -1;
+	}	    
+#endif
+	if ((lcc->fieldsSet & LCC_UID_SET) && (pUid != NULL))
+	    *pUid = lcc->euid;
+	if ((lcc->fieldsSet & LCC_GID_SET) && (pGid != NULL))
+	    *pGid = lcc->egid;
+	FreeLocalClientCreds(lcc);
+    }
+    return ret;
+}
+
+/*
+ * Return the uid and all gids of a connected local client
+ * Allocates a LocalClientCredRec - caller must call FreeLocalClientCreds
+ * 
+ * Used by localuser & localgroup ServerInterpreted access control forms below
+ * Used by AuthAudit to log who local connections came from
+ */
+int
+GetLocalClientCreds(ClientPtr client, LocalClientCredRec **lccp)
+{
+#if defined(HAS_GETPEEREID) || defined(HAS_GETPEERUCRED) || defined(SO_PEERCRED)
+    int fd;
+    XtransConnInfo ci;
+    LocalClientCredRec *lcc;
+#ifdef HAS_GETPEEREID
+    uid_t uid;
+    gid_t gid;
+#elif defined(HAS_GETPEERUCRED)
+    ucred_t *peercred = NULL;
+    const gid_t *gids;
+#elif defined(SO_PEERCRED)
+    struct ucred peercred;
+    socklen_t so_len = sizeof(peercred);
+#endif
+
+    if (client == NULL)
+	return -1;
+    ci = ((OsCommPtr)client->osPrivate)->trans_conn;
+#if !(defined(sun) && defined(HAS_GETPEERUCRED))
+    /* Most implementations can only determine peer credentials for Unix 
+     * domain sockets - Solaris getpeerucred can work with a bit more, so 
+     * we just let it tell us if the connection type is supported or not
+     */
+    if (!_XSERVTransIsLocal(ci)) {
+	return -1;
+    }
+#endif
+
+    *lccp = calloc(1, sizeof(LocalClientCredRec));
+    if (*lccp == NULL)
+	return -1;
+    lcc = *lccp;
+        
+    fd = _XSERVTransGetConnectionNumber(ci);
+#ifdef HAS_GETPEEREID
+    if (getpeereid(fd, &uid, &gid) == -1) {
+	FreeLocalClientCreds(lcc);
+	return -1;
+    }
+    lcc->euid = uid;
+    lcc->egid = gid;
+    lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET;
+    return 0;
+#elif defined(HAS_GETPEERUCRED)
+    if (getpeerucred(fd, &peercred) < 0) {
+	FreeLocalClientCreds(lcc);
+    	return -1;
+    }
+    lcc->euid = ucred_geteuid(peercred);
+    if (lcc->euid != -1)
+	lcc->fieldsSet |= LCC_UID_SET;
+    lcc->egid = ucred_getegid(peercred);
+    if (lcc->egid != -1)
+	lcc->fieldsSet |= LCC_GID_SET;
+    lcc->pid = ucred_getpid(peercred);
+    if (lcc->pid != -1)
+	lcc->fieldsSet |= LCC_PID_SET;
+#ifdef HAVE_GETZONEID
+    lcc->zoneid = ucred_getzoneid(peercred);
+    if (lcc->zoneid != -1)
+	lcc->fieldsSet |= LCC_ZID_SET;
+#endif
+    lcc->nSuppGids = ucred_getgroups(peercred, &gids);
+    if (lcc->nSuppGids > 0) {
+	lcc->pSuppGids = calloc(lcc->nSuppGids, sizeof(int));
+	if (lcc->pSuppGids == NULL) {
+	    lcc->nSuppGids = 0;
+	} else {
+	    int i;
+	    for (i = 0 ; i < lcc->nSuppGids; i++) {
+		(lcc->pSuppGids)[i] = (int) gids[i];
+	    }
+	}
+    } else {
+	lcc->nSuppGids = 0;
+    }
+    ucred_free(peercred);
+    return 0;
+#elif defined(SO_PEERCRED)
+    if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) {
+	FreeLocalClientCreds(lcc);
+	return -1;
+    }
+    lcc->euid = peercred.uid;
+    lcc->egid = peercred.gid;
+    lcc->pid = peercred.pid;
+    lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET;
+    return 0;
+#endif
+#else
+    /* No system call available to get the credentials of the peer */
+#define NO_LOCAL_CLIENT_CRED
+    return -1;
+#endif
+}
+
+void
+FreeLocalClientCreds(LocalClientCredRec *lcc)
+{
+    if (lcc != NULL) {
+	if (lcc->nSuppGids > 0) {
+	    free(lcc->pSuppGids);
+	}
+	free(lcc);
+    }
+}
+
+static int
+AuthorizedClient(ClientPtr client)
+{
+    int rc;
+
+    if (!client || defeatAccessControl)
+	return Success;
+
+    /* untrusted clients can't change host access */
+    rc = XaceHook(XACE_SERVER_ACCESS, client, DixManageAccess);
+    if (rc != Success)
+	return rc;
+
+    return LocalClient(client) ? Success : BadAccess;
+}
+
+/* Add a host to the access control list.  This is the external interface
+ * called from the dispatcher */
+
+int
+AddHost (ClientPtr	client,
+	 int            family,
+	 unsigned       length,        /* of bytes in pAddr */
+	 const void *   pAddr)
+{
+    int rc, len;
+
+    rc = AuthorizedClient(client);
+    if (rc != Success)
+	return rc;
+    switch (family) {
+    case FamilyLocalHost:
+	len = length;
+	LocalHostEnabled = TRUE;
+	break;
+#ifdef SECURE_RPC
+    case FamilyNetname:
+	len = length;
+	SecureRPCInit ();
+	break;
+#endif
+    case FamilyInternet:
+#if defined(IPv6) && defined(AF_INET6)
+    case FamilyInternet6:
+#endif
+    case FamilyDECnet:
+    case FamilyChaos:
+    case FamilyServerInterpreted:
+	if ((len = CheckAddr (family, pAddr, length)) < 0)
+	{
+	    client->errorValue = length;
+	    return BadValue;
+	}
+	break;
+    case FamilyLocal:
+    default:
+	client->errorValue = family;
+	return BadValue;
+    }
+    if (NewHost (family, pAddr, len, FALSE))
+	return Success;
+    return BadAlloc;
+}
+
+Bool
+ForEachHostInFamily (int	    family,
+		     Bool    (*func)(
+			 unsigned char * /* addr */,
+			 short           /* len */,
+			 pointer         /* closure */),
+		     pointer closure)
+{
+    HOST    *host;
+
+    for (host = validhosts; host; host = host->next)
+	if (family == host->family && func (host->addr, host->len, closure))
+	    return TRUE;
+    return FALSE;
+}
+
+/* Add a host to the access control list. This is the internal interface 
+ * called when starting or resetting the server */
+static Bool
+NewHost (int		family,
+	 const void *	addr,
+	 int		len,
+	 int		addingLocalHosts)
+{
+    register HOST *host;
+
+    for (host = validhosts; host; host = host->next)
+    {
+        if (addrEqual (family, addr, len, host))
+	    return TRUE;
+    }
+    if (!addingLocalHosts) {			/* Fix for XFree86 bug #156 */
+	for (host = selfhosts; host; host = host->next) {
+	    if (addrEqual (family, addr, len, host)) {
+		host->requested = TRUE;
+		break;
+	    }	    
+	}
+    }
+    MakeHost(host,len)
+    if (!host)
+	return FALSE;
+    host->family = family;
+    host->len = len;
+    acopy(addr, host->addr, len);
+    host->next = validhosts;
+    validhosts = host;
+    return TRUE;
+}
+
+/* Remove a host from the access control list */
+
+int
+RemoveHost (
+    ClientPtr		client,
+    int                 family,
+    unsigned            length,        /* of bytes in pAddr */
+    pointer             pAddr)
+{
+    int rc, len;
+    register HOST	*host, **prev;
+
+    rc = AuthorizedClient(client);
+    if (rc != Success)
+	return rc;
+    switch (family) {
+    case FamilyLocalHost:
+	len = length;
+	LocalHostEnabled = FALSE;
+	break;
+#ifdef SECURE_RPC
+    case FamilyNetname:
+	len = length;
+	break;
+#endif
+    case FamilyInternet:
+#if defined(IPv6) && defined(AF_INET6)
+    case FamilyInternet6:
+#endif
+    case FamilyDECnet:
+    case FamilyChaos:
+    case FamilyServerInterpreted:
+    	if ((len = CheckAddr (family, pAddr, length)) < 0)
+    	{
+	    client->errorValue = length;
+            return BadValue;
+    	}
+	break;
+    case FamilyLocal:
+    default:
+	client->errorValue = family;
+        return BadValue;
+    }
+    for (prev = &validhosts;
+         (host = *prev) && (!addrEqual (family, pAddr, len, host));
+         prev = &host->next)
+        ;
+    if (host)
+    {
+        *prev = host->next;
+        FreeHost (host);
+    }
+    return Success;
+}
+
+/* Get all hosts in the access control list */
+int
+GetHosts (
+    pointer		*data,
+    int			*pnHosts,
+    int			*pLen,
+    BOOL		*pEnabled)
+{
+    int			len;
+    register int 	n = 0;
+    register unsigned char *ptr;
+    register HOST	*host;
+    int			nHosts = 0;
+
+    *pEnabled = AccessEnabled ? EnableAccess : DisableAccess;
+    for (host = validhosts; host; host = host->next)
+    {
+	nHosts++;
+	n += pad_to_int32(host->len) + sizeof(xHostEntry);
+    }
+    if (n)
+    {
+        *data = ptr = malloc(n);
+	if (!ptr)
+	{
+	    return BadAlloc;
+	}
+        for (host = validhosts; host; host = host->next)
+	{
+	    len = host->len;
+	    ((xHostEntry *)ptr)->family = host->family;
+	    ((xHostEntry *)ptr)->length = len;
+	    ptr += sizeof(xHostEntry);
+	    acopy (host->addr, ptr, len);
+	    ptr += pad_to_int32(len);
+        }
+    } else {
+	*data = NULL;
+    }
+    *pnHosts = nHosts;
+    *pLen = n;
+    return Success;
+}
+
+/* Check for valid address family and length, and return address length. */
+
+/*ARGSUSED*/
+static int
+CheckAddr (
+    int			family,
+    const void *	pAddr,
+    unsigned		length)
+{
+    int	len;
+
+    switch (family)
+    {
+#if defined(TCPCONN) || defined(STREAMSCONN)
+      case FamilyInternet:
+	if (length == sizeof (struct in_addr))
+	    len = length;
+	else
+	    len = -1;
+        break;
+#if defined(IPv6) && defined(AF_INET6)
+      case FamilyInternet6:
+	if (length == sizeof (struct in6_addr))
+	    len = length;
+	else
+	    len = -1;
+        break;
+#endif
+#endif 
+      case FamilyServerInterpreted:
+	len = siCheckAddr(pAddr, length);
+	break;
+      default:
+        len = -1;
+    }
+    return len;
+}
+
+/* Check if a host is not in the access control list. 
+ * Returns 1 if host is invalid, 0 if we've found it. */
+
+int
+InvalidHost (
+    register struct sockaddr	*saddr,
+    int				len,
+    ClientPtr			client)
+{
+    int 			family;
+    pointer			addr;
+    register HOST 		*selfhost, *host;
+
+    if (!AccessEnabled)   /* just let them in */
+        return 0;
+    family = ConvertAddr (saddr, &len, (pointer *)&addr);
+    if (family == -1)
+        return 1;
+    if (family == FamilyLocal)
+    {
+	if (!LocalHostEnabled)
+ 	{
+	    /*
+	     * check to see if any local address is enabled.  This 
+	     * implicitly enables local connections.
+	     */
+	    for (selfhost = selfhosts; selfhost; selfhost=selfhost->next)
+ 	    {
+		for (host = validhosts; host; host=host->next)
+		{
+		    if (addrEqual (selfhost->family, selfhost->addr,
+				   selfhost->len, host))
+			return 0;
+		}
+	    }
+	} else
+	    return 0;
+    }
+    for (host = validhosts; host; host = host->next)
+    {
+	if ((host->family == FamilyServerInterpreted)) {
+	    if (siAddrMatch (family, addr, len, host, client)) {
+		return 0;
+	    }
+	} else {
+	    if (addrEqual (family, addr, len, host))
+		return 0;
+	}
+
+    }
+    return 1;
+}
+
+static int
+ConvertAddr (
+    register struct sockaddr	*saddr,
+    int				*len,
+    pointer			*addr)
+{
+    if (*len == 0)
+        return FamilyLocal;
+    switch (saddr->sa_family)
+    {
+    case AF_UNSPEC:
+#if defined(UNIXCONN) || defined(LOCALCONN)
+    case AF_UNIX:
+#endif
+        return FamilyLocal;
+#if defined(TCPCONN) || defined(STREAMSCONN)
+    case AF_INET:
+#ifdef WIN32
+        if (16777343 == *(long*)&((struct sockaddr_in *) saddr)->sin_addr)
+            return FamilyLocal;
+#endif
+        *len = sizeof (struct in_addr);
+        *addr = (pointer) &(((struct sockaddr_in *) saddr)->sin_addr);
+        return FamilyInternet;
+#if defined(IPv6) && defined(AF_INET6)
+    case AF_INET6: 
+    {
+	struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) saddr;
+	if (IN6_IS_ADDR_V4MAPPED(&(saddr6->sin6_addr))) {
+	    *len = sizeof (struct in_addr);
+	    *addr = (pointer) &(saddr6->sin6_addr.s6_addr[12]);
+	    return FamilyInternet;
+	} else {
+	    *len = sizeof (struct in6_addr);
+	    *addr = (pointer) &(saddr6->sin6_addr);
+	    return FamilyInternet6;
+	}
+    }
+#endif
+#endif
+    default:
+        return -1;
+    }
+}
+
+int
+ChangeAccessControl(
+    ClientPtr client,
+    int fEnabled)
+{
+    int rc = AuthorizedClient(client);
+    if (rc != Success)
+	return rc;
+    AccessEnabled = fEnabled;
+    return Success;
+}
+
+/* returns FALSE if xhost + in effect, else TRUE */
+int
+GetAccessControl(void)
+{
+    return AccessEnabled;
+}
+
+/*****************************************************************************
+ * FamilyServerInterpreted host entry implementation
+ *
+ * Supports an extensible system of host types which the server can interpret
+ * See the IPv6 extensions to the X11 protocol spec for the definition.
+ *
+ * Currently supported schemes:
+ *
+ * hostname	- hostname as defined in IETF RFC 2396
+ * ipv6		- IPv6 literal address as defined in IETF RFC's 3513 and <TBD>
+ *
+ * See xc/doc/specs/SIAddresses for formal definitions of each type.
+ */
+
+/* These definitions and the siTypeAdd function could be exported in the 
+ * future to enable loading additional host types, but that was not done for
+ * the initial implementation.
+ */
+typedef Bool (*siAddrMatchFunc)(int family, pointer addr, int len, 
+  const char *siAddr, int siAddrlen, ClientPtr client, void *siTypePriv);
+typedef int  (*siCheckAddrFunc)(const char *addrString, int length, 
+  void *siTypePriv);
+
+struct siType {
+    struct siType *	next;
+    const char *	typeName;
+    siAddrMatchFunc	addrMatch;
+    siCheckAddrFunc	checkAddr;
+    void *		typePriv;	/* Private data for type routines */
+};
+
+static struct siType *siTypeList;
+
+static int
+siTypeAdd(const char *typeName, siAddrMatchFunc addrMatch,
+  siCheckAddrFunc checkAddr, void *typePriv)
+{
+    struct siType *s, *p;
+
+    if ((typeName == NULL) || (addrMatch == NULL) || (checkAddr == NULL))
+	return BadValue;
+
+    for (s = siTypeList, p = NULL; s != NULL ; p = s, s = s->next) {
+	if (strcmp(typeName, s->typeName) == 0) {
+	    s->addrMatch = addrMatch;
+	    s->checkAddr = checkAddr;
+	    s->typePriv = typePriv;
+	    return Success;
+	}
+    }
+
+    s = malloc(sizeof(struct siType));
+    if (s == NULL)
+	return BadAlloc;
+
+    if (p == NULL)
+	siTypeList = s;
+    else
+	p->next = s;
+
+    s->next = NULL;
+    s->typeName = typeName;
+    s->addrMatch = addrMatch;
+    s->checkAddr = checkAddr;
+    s->typePriv = typePriv;
+    return Success;
+}
+
+/* Checks to see if a host matches a server-interpreted host entry */
+static Bool 
+siAddrMatch(int family, pointer addr, int len, HOST *host, ClientPtr client)
+{
+    Bool matches = FALSE;
+    struct siType *s;
+    const char *valueString;
+    int addrlen;
+
+    valueString = (const char *) memchr(host->addr, '\0', host->len);
+    if (valueString != NULL) {
+	for (s = siTypeList; s != NULL ; s = s->next) {
+	    if (strcmp((char *) host->addr, s->typeName) == 0) {
+		addrlen = host->len - (strlen((char *)host->addr) + 1);
+		matches = s->addrMatch(family, addr, len, 
+		  valueString + 1, addrlen, client, s->typePriv);
+		break;
+	    }
+	}
+#ifdef FAMILY_SI_DEBUG
+	ErrorF(
+	    "Xserver: siAddrMatch(): type = %s, value = %*.*s -- %s\n",
+	      host->addr, addrlen, addrlen, valueString + 1,
+	      (matches) ? "accepted" : "rejected");
+#endif
+    }
+    return matches;
+}
+
+static int
+siCheckAddr(const char *addrString, int length)
+{
+    const char *valueString;
+    int addrlen, typelen;
+    int len = -1;
+    struct siType *s;
+
+    /* Make sure there is a \0 byte inside the specified length
+       to separate the address type from the address value. */
+    valueString = (const char *) memchr(addrString, '\0', length);
+    if (valueString != NULL) {
+	/* Make sure the first string is a recognized address type,
+	 * and the second string is a valid address of that type. 
+	 */
+	typelen = strlen(addrString) + 1;
+	addrlen = length - typelen;
+
+	for (s = siTypeList; s != NULL ; s = s->next) {
+	    if (strcmp(addrString, s->typeName) == 0) {
+		len = s->checkAddr(valueString + 1, addrlen, s->typePriv);
+		if (len >= 0) {
+		    len += typelen;
+		}
+		break;
+	    }
+	}
+#ifdef FAMILY_SI_DEBUG
+	{
+	    const char *resultMsg;
+
+	    if (s == NULL) {
+		resultMsg = "type not registered";
+	    } else {
+		if (len == -1) 
+		    resultMsg = "rejected";
+		else
+		    resultMsg = "accepted";
+	    }
+
+	    ErrorF("Xserver: siCheckAddr(): type = %s, value = %*.*s, len = %d -- %s\n",
+	      addrString, addrlen, addrlen, valueString + 1, len, resultMsg);
+	}
+#endif
+    }
+    return len;
+}
+
+
+/***
+ * Hostname server-interpreted host type
+ *
+ * Stored as hostname string, explicitly defined to be resolved ONLY
+ * at access check time, to allow for hosts with dynamic addresses
+ * but static hostnames, such as found in some DHCP & mobile setups.
+ *
+ * Hostname must conform to IETF RFC 2396 sec. 3.2.2, which defines it as:
+ * 	hostname     = *( domainlabel "." ) toplabel [ "." ]
+ *	domainlabel  = alphanum | alphanum *( alphanum | "-" ) alphanum
+ *	toplabel     = alpha | alpha *( alphanum | "-" ) alphanum
+ */
+
+#ifdef NI_MAXHOST
+# define SI_HOSTNAME_MAXLEN NI_MAXHOST
+#else
+# ifdef MAXHOSTNAMELEN
+#  define SI_HOSTNAME_MAXLEN MAXHOSTNAMELEN
+# else
+#  define SI_HOSTNAME_MAXLEN 256
+# endif
+#endif
+
+static Bool 
+siHostnameAddrMatch(int family, pointer addr, int len,
+  const char *siAddr, int siAddrLen, ClientPtr client, void *typePriv)
+{
+    Bool res = FALSE;
+
+/* Currently only supports checking against IPv4 & IPv6 connections, but 
+ * support for other address families, such as DECnet, could be added if 
+ * desired.
+ */
+#if defined(IPv6) && defined(AF_INET6)
+    if ((family == FamilyInternet) || (family == FamilyInternet6)) {
+	char hostname[SI_HOSTNAME_MAXLEN];
+	struct addrinfo *addresses;
+	struct addrinfo *a;
+	int f, hostaddrlen;
+	pointer hostaddr;
+
+	if (siAddrLen >= sizeof(hostname)) 
+	    return FALSE;
+
+	strncpy(hostname, siAddr, siAddrLen);
+	hostname[siAddrLen] = '\0';
+
+	if (getaddrinfo(hostname, NULL, NULL, &addresses) == 0) {
+	    for (a = addresses ; a != NULL ; a = a->ai_next) {
+		hostaddrlen = a->ai_addrlen;
+		f = ConvertAddr(a->ai_addr,&hostaddrlen,&hostaddr);
+		if ((f == family) && (len == hostaddrlen) &&
+		  (acmp (addr, hostaddr, len) == 0) ) {
+		    res = TRUE;
+		    break;
+		}
+	    }
+	    freeaddrinfo(addresses);
+	}
+    }
+#else /* IPv6 not supported, use gethostbyname instead for IPv4 */
+    if (family == FamilyInternet) {
+	register struct hostent *hp;
+#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
+	_Xgethostbynameparams hparams;
+#endif
+	char hostname[SI_HOSTNAME_MAXLEN];
+	int f, hostaddrlen;
+	pointer hostaddr;
+	const char **addrlist;
+
+	if (siAddrLen >= sizeof(hostname)) 
+	    return FALSE;
+
+	strncpy(hostname, siAddr, siAddrLen);
+	hostname[siAddrLen] = '\0';
+
+	if ((hp = _XGethostbyname(hostname, hparams)) != NULL) {
+#ifdef h_addr				/* new 4.3bsd version of gethostent */
+	    /* iterate over the addresses */
+	    for (addrlist = hp->h_addr_list; *addrlist; addrlist++)
+#else
+	    addrlist = &hp->h_addr;
+#endif
+	    {
+		struct  sockaddr_in  sin;
+
+    		sin.sin_family = hp->h_addrtype;
+		acopy ( *addrlist, &(sin.sin_addr), hp->h_length);
+		hostaddrlen = sizeof(sin);
+    		f = ConvertAddr ((struct sockaddr *)&sin, 
+		  &hostaddrlen, &hostaddr);
+		if ((f == family) && (len == hostaddrlen) &&
+		  (acmp (addr, hostaddr, len) == 0) ) {
+		    res = TRUE;
+		    break;
+		}
+    	    }
+        }
+    }
+#endif
+    return res;
+}
+
+
+static int
+siHostnameCheckAddr(const char *valueString, int length, void *typePriv)
+{
+    /* Check conformance of hostname to RFC 2396 sec. 3.2.2 definition.
+     * We do not use ctype functions here to avoid locale-specific
+     * character sets.  Hostnames must be pure ASCII.  
+     */
+    int len = length;
+    int i;
+    Bool dotAllowed = FALSE;
+    Bool dashAllowed = FALSE;
+		    
+    if ((length <= 0) || (length >= SI_HOSTNAME_MAXLEN)) {
+	len = -1;
+    } else {
+	for (i = 0; i < length; i++) {
+	    char c = valueString[i];
+
+	    if (c == 0x2E) { /* '.' */
+		if (dotAllowed == FALSE) {
+		    len = -1;
+		    break;
+		} else {
+		    dotAllowed = FALSE;
+		    dashAllowed = FALSE;
+		}
+	    } else if (c == 0x2D) { /* '-' */
+		if (dashAllowed == FALSE) {
+		    len = -1;
+		    break;
+		} else {
+		    dotAllowed = FALSE;
+		}
+	    } else if (((c >= 0x30) && (c <= 0x3A)) /* 0-9 */ ||
+		       ((c >= 0x61) && (c <= 0x7A)) /* a-z */ ||
+		       ((c >= 0x41) && (c <= 0x5A)) /* A-Z */) {
+		dotAllowed = TRUE;
+		dashAllowed = TRUE;
+	    } else { /* Invalid character */
+		len = -1;
+		break;
+	    }
+	}
+    }
+    return len;
+}
+
+#if defined(IPv6) && defined(AF_INET6)
+/***
+ * "ipv6" server interpreted type
+ *
+ * Currently supports only IPv6 literal address as specified in IETF RFC 3513
+ *
+ * Once draft-ietf-ipv6-scoping-arch-00.txt becomes an RFC, support will be 
+ * added for the scoped address format it specifies.
+ */
+
+/* Maximum length of an IPv6 address string - increase when adding support 
+ * for scoped address qualifiers.  Includes room for trailing NUL byte. 
+ */
+#define SI_IPv6_MAXLEN INET6_ADDRSTRLEN
+
+static Bool 
+siIPv6AddrMatch(int family, pointer addr, int len,
+  const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
+{
+    struct in6_addr addr6;
+    char addrbuf[SI_IPv6_MAXLEN];
+
+    if ((family != FamilyInternet6) || (len != sizeof(addr6)))
+	return FALSE;
+
+    memcpy(addrbuf, siAddr, siAddrlen);
+    addrbuf[siAddrlen] = '\0';
+
+    if (inet_pton(AF_INET6, addrbuf, &addr6) != 1) {
+	perror("inet_pton");
+	return FALSE;
+    }
+
+    if (memcmp(addr, &addr6, len) == 0) {
+	return TRUE;
+    } else {
+	return FALSE;
+    }
+}
+
+static int
+siIPv6CheckAddr(const char *addrString, int length, void *typePriv)
+{
+    int len;
+
+    /* Minimum length is 3 (smallest legal address is "::1") */
+    if (length < 3) {
+	/* Address is too short! */
+	len = -1;
+    } else if (length >= SI_IPv6_MAXLEN) {
+	/* Address is too long! */
+	len = -1;
+    } else {
+	/* Assume inet_pton is sufficient validation */
+	struct in6_addr addr6;
+	char addrbuf[SI_IPv6_MAXLEN];
+
+	memcpy(addrbuf, addrString, length);
+	addrbuf[length] = '\0';
+
+	if (inet_pton(AF_INET6, addrbuf, &addr6) != 1) {
+	    perror("inet_pton");
+	    len = -1;
+	} else {
+	    len = length;
+	}
+    }
+    return len;
+}
+#endif /* IPv6 */
+
+#if !defined(NO_LOCAL_CLIENT_CRED)
+/***
+ * "localuser" & "localgroup" server interpreted types
+ *
+ * Allows local connections from a given local user or group
+ */
+
+#include <pwd.h>
+#include <grp.h>
+
+#define LOCAL_USER 1
+#define LOCAL_GROUP 2
+
+typedef struct {
+    int credType;
+} siLocalCredPrivRec, *siLocalCredPrivPtr;
+
+static siLocalCredPrivRec siLocalUserPriv = { LOCAL_USER };
+static siLocalCredPrivRec siLocalGroupPriv = { LOCAL_GROUP };
+
+static Bool
+siLocalCredGetId(const char *addr, int len, siLocalCredPrivPtr lcPriv, int *id)
+{
+    Bool parsedOK = FALSE;
+    char *addrbuf = malloc(len + 1);
+
+    if (addrbuf == NULL) {
+	return FALSE;
+    }
+
+    memcpy(addrbuf, addr, len);
+    addrbuf[len] = '\0';
+
+    if (addr[0] == '#') { /* numeric id */
+	char *cp;
+	errno = 0;
+	*id = strtol(addrbuf + 1, &cp, 0);
+	if ((errno == 0) && (cp != (addrbuf+1))) {
+	    parsedOK = TRUE;
+	}
+    } else { /* non-numeric name */
+	if (lcPriv->credType == LOCAL_USER) {
+	    struct passwd *pw = getpwnam(addrbuf);
+
+	    if (pw != NULL) {
+		*id = (int) pw->pw_uid;
+		parsedOK = TRUE;
+	    }
+	} else { /* group */
+	    struct group *gr = getgrnam(addrbuf);
+
+	    if (gr != NULL) {
+		*id = (int) gr->gr_gid;
+		parsedOK = TRUE;
+	    }
+	}
+    }
+
+    free(addrbuf);
+    return parsedOK;
+}
+
+static Bool 
+siLocalCredAddrMatch(int family, pointer addr, int len,
+  const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
+{
+    int siAddrId;
+    LocalClientCredRec *lcc;
+    siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv;
+
+    if (GetLocalClientCreds(client, &lcc) == -1) {
+	return FALSE;
+    }
+
+#ifdef HAVE_GETZONEID /* Ensure process is in the same zone */
+    if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) {
+	FreeLocalClientCreds(lcc);
+	return FALSE;
+    }
+#endif
+
+    if (siLocalCredGetId(siAddr, siAddrlen, lcPriv, &siAddrId) == FALSE) {
+	FreeLocalClientCreds(lcc);
+	return FALSE;
+    }
+
+    if (lcPriv->credType == LOCAL_USER) {
+	if ((lcc->fieldsSet & LCC_UID_SET) && (lcc->euid == siAddrId)) {
+	    FreeLocalClientCreds(lcc);
+	    return TRUE;
+	}
+    } else {
+	if ((lcc->fieldsSet & LCC_GID_SET) && (lcc->egid == siAddrId)) {
+	    FreeLocalClientCreds(lcc);
+	    return TRUE;
+	}
+	if (lcc->pSuppGids != NULL) {
+	    int i;
+
+	    for (i = 0 ; i < lcc->nSuppGids; i++) {
+		if (lcc->pSuppGids[i] == siAddrId) {
+		    FreeLocalClientCreds(lcc);
+		    return TRUE;
+		}
+	    }
+	}
+    }
+    FreeLocalClientCreds(lcc);
+    return FALSE;
+}
+
+static int
+siLocalCredCheckAddr(const char *addrString, int length, void *typePriv)
+{
+    int len = length;
+    int id;
+
+    if (siLocalCredGetId(addrString, length, 
+	(siLocalCredPrivPtr)typePriv, &id) == FALSE) {
+	len = -1;
+    }
+    return len;
+}
+#endif /* localuser */
+
+static void
+siTypesInitialize(void)
+{
+    siTypeAdd("hostname", siHostnameAddrMatch, siHostnameCheckAddr, NULL);
+#if defined(IPv6) && defined(AF_INET6)
+    siTypeAdd("ipv6", siIPv6AddrMatch, siIPv6CheckAddr, NULL);
+#endif
+#if !defined(NO_LOCAL_CLIENT_CRED)
+    siTypeAdd("localuser", siLocalCredAddrMatch, siLocalCredCheckAddr, 
+      &siLocalUserPriv);
+    siTypeAdd("localgroup", siLocalCredAddrMatch, siLocalCredCheckAddr, 
+      &siLocalGroupPriv);
+#endif
+}
diff --git a/xorg-server/os/connection.c b/xorg-server/os/connection.c
index 8026423f7..4eb2c15c7 100644
--- a/xorg-server/os/connection.c
+++ b/xorg-server/os/connection.c
@@ -746,6 +746,7 @@ AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time)
 	free(oc);
 	return NullClient;
     }
+    oc->local_client = ComputeLocalClient(client);
 #if !defined(WIN32)
     ConnectionTranslation[fd] = client->index;
 #else
diff --git a/xorg-server/os/osdep.h b/xorg-server/os/osdep.h
index 491a746d4..d7756b67a 100644
--- a/xorg-server/os/osdep.h
+++ b/xorg-server/os/osdep.h
@@ -172,6 +172,7 @@ typedef struct _osComm {
     XID	auth_id;		/* authorization id */
     CARD32 conn_time;		/* timestamp if not established, else 0  */
     struct _XtransConnInfo *trans_conn; /* transport connection object */
+    Bool local_client;
 } OsCommRec, *OsCommPtr;
 
 extern int FlushClient(
@@ -217,6 +218,9 @@ typedef long int fd_mask;
 #define ffs mffs
 extern int mffs(fd_mask);
 
+/* in access.c */
+extern Bool ComputeLocalClient(ClientPtr client);
+
 /* in auth.c */
 extern void GenerateRandomData (int len, char *buf);
 
-- 
cgit v1.2.3