1 /* $XConsortium: access.c /main/68 1996/12/15 22:57:09 rws $ */
2 /* $XFree86: xc/programs/Xserver/os/access.c,v 3.18.2.4 1998/02/21 06:07:16 robin Exp $ */
3 /***********************************************************
5 Copyright (c) 1987 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Except as contained in this notice, the name of the X Consortium shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from the X Consortium.
29 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
33 Permission to use, copy, modify, and distribute this software and its
34 documentation for any purpose and without fee is hereby granted,
35 provided that the above copyright notice appear in all copies and that
36 both that copyright notice and this permission notice appear in
37 supporting documentation, and that the name of Digital not be
38 used in advertising or publicity pertaining to distribution of the
39 software without specific, written prior permission.
41 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
42 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
43 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
44 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
45 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
46 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
49 ******************************************************************/
52 #include <X11/Xwinsock.h>
56 #include <X11/Xtrans.h>
57 #include <X11/Xauth.h>
63 #include <sys/types.h>
65 #if !defined(AMOEBA) && !defined(MINIX)
67 #include <lan/socket.h>
70 #include <sys/socket.h>
75 #include <sys/ioctl.h>
78 #define port am_port_t
84 #include <server/ip/hton.h>
85 #include <server/ip/types.h>
86 #include <server/ip/tcpip.h>
87 #include <server/ip/tcp_io.h>
88 #include <server/ip/gen/in.h>
89 #include <server/ip/gen/tcp.h>
90 #include <server/ip/gen/tcp_io.h>
91 #include <server/ip/gen/socket.h>
94 #endif /* AMOEBA || MINIX */
97 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(ISC) || defined(SCO)
98 #include <netinet/in.h>
99 #endif /* TCPCONN || STREAMSCONN || ISC || SCO */
101 #include <netdnet/dn.h>
102 #include <netdnet/dnetdb.h>
107 # include <sys/utsname.h>
112 #if defined(SVR4) || (defined(SYSV) && defined(i386)) || defined(MINIX)
113 # include <sys/utsname.h>
115 #if defined(SYSV) && defined(i386)
116 # include <sys/stream.h>
118 # include <sys/stropts.h>
119 # include <sys/sioctl.h>
134 #include <sys/sockio.h>
136 #include <sys/stropts.h>
140 #include <lan/netdb.h>
142 #if !defined(AMOEBA) && !defined(MINIX)
146 #include <server/ip/gen/netdb.h>
149 #include <net/hton.h>
150 #include <net/gen/netdb.h>
151 #define INADDR_BROADCAST 0xFFFFFFFF
153 #endif /* AMOEBA || MINIX */
157 #include <sys/param.h>
159 #define VARIABLE_IFREQ
163 #if defined(Lynx) && defined(BSD44SOCKETS)
164 #define VARIABLE_IFREQ
171 #include <sys/param.h>
177 #define PATH_MAX MAXPATHLEN
179 #define PATH_MAX 1024
184 #include "dixstruct.h"
188 #define _SECURITY_SERVER
189 #include "extensions/security.h"
192 Bool defeatAccessControl = FALSE;
194 #define acmp(a1, a2, len) memcmp((char *)(a1), (char *)(a2), len)
195 #define acopy(a1, a2, len) memmove((char *)(a2), (char *)(a1), len)
196 #define addrEqual(fam, address, length, host) \
197 ((fam) == (host)->family &&\
198 (length) == (host)->len &&\
199 !acmp (address, (host)->addr, length))
201 static int ConvertAddr(
202 #if NeedFunctionPrototypes
203 struct sockaddr */*saddr*/,
209 static int CheckAddr(
210 #if NeedFunctionPrototypes
218 #if NeedFunctionPrototypes
225 typedef struct _host {
232 #define MakeHost(h,l) (h)=(HOST *) xalloc(sizeof *(h)+(l));\
233 (h)->addr=(unsigned char *) ((h) + 1);
234 #define FreeHost(h) xfree(h)
235 static HOST *selfhosts = NULL;
236 static HOST *validhosts = NULL;
237 static int AccessEnabled = DEFAULT_ACCESS_CONTROL;
238 static int LocalHostEnabled = FALSE;
239 static int UsingXdmcp = FALSE;
243 * called when authorization is not enabled to add the
244 * local host to the access list
252 LocalHostEnabled = TRUE;
258 * called when authorization is enabled to keep us secure
265 LocalHostEnabled = FALSE;
266 for (self = selfhosts; self; self = self->next)
267 (void) RemoveHost ((ClientPtr)NULL, self->family, self->len, (pointer)self->addr);
271 * called at init time when XDMCP will be used; xdmcp always
272 * adds local hosts manually when needed
279 LocalHostEnabled = FALSE;
283 #if ((defined(SVR4) && !defined(SCO325) && !defined(sun) && !defined(NCR)) || defined(ISC)) && defined(SIOCGIFCONF)
285 /* Deal with different SIOCGIFCONF ioctl semantics on these OSs */
288 ifioctl (fd, cmd, arg)
296 bzero((char *) &ioc, sizeof(ioc));
299 if (cmd == SIOCGIFCONF)
301 ioc.ic_len = ((struct ifconf *) arg)->ifc_len;
302 ioc.ic_dp = ((struct ifconf *) arg)->ifc_buf;
304 /* SIOCGIFCONF is somewhat brain damaged on ISC. The argument
305 * buffer must contain the ifconf structure as header. Ifc_req
306 * is also not a pointer but a one element array of ifreq
307 * structures. On return this array is extended by enough
308 * ifreq fields to hold all interfaces. The return buffer length
309 * is placed in the buffer header.
311 ((struct ifconf *) ioc.ic_dp)->ifc_len =
312 ioc.ic_len - sizeof(struct ifconf);
317 ioc.ic_len = sizeof(struct ifreq);
320 ret = ioctl(fd, I_STR, (char *) &ioc);
321 if (ret >= 0 && cmd == SIOCGIFCONF)
323 ((struct ifconf *) arg)->ifc_len = ioc.ic_len;
327 ((struct ifconf *) arg)->ifc_len =
328 ((struct ifconf *)ioc.ic_dp)->ifc_len;
329 ((struct ifconf *) arg)->ifc_buf =
330 (caddr_t)((struct ifconf *)ioc.ic_dp)->ifc_req;
335 #else /* ((SVR4 && !sun) || ISC) && SIOCGIFCONF */
336 #define ifioctl ioctl
337 #endif /* ((SVR4 && !sun) || ISC) && SIOCGIFCONF */
342 * Define this host for access control. Find all the hosts the OS knows about
343 * for this fd and add them to the selfhosts list.
346 #ifdef WINTCP /* NCR Wollongong based TCP */
352 #include <sys/stream.h>
354 #include <netinet/ip.h>
355 #include <netinet/ip_var.h>
356 #include <netinet/in.h>
357 #include <netinet/in_var.h>
364 * The Wolongong drivers used by NCR SVR4/MP-RAS don't understand the
365 * socket IO calls that most other drivers seem to like. Because of
366 * this, this routine must be special cased for NCR. Eventually,
367 * this will be cleared up.
371 struct in_ifaddr ifaddr;
377 if ((fd = open ("/dev/ip", O_RDWR, 0 )) < 0)
378 Error ("Getting interface configuration (1)");
380 /* Indicate that we want to start at the begining */
381 ifnet.ib_next = (struct ipb *) 1;
383 while (ifnet.ib_next)
385 str.ic_cmd = IPIOC_GETIPB;
387 str.ic_len = sizeof (struct ipb);
388 str.ic_dp = (char *) &ifnet;
390 if (ioctl (fd, (int) I_STR, (char *) &str) < 0)
393 Error ("Getting interface configuration (2)");
396 ifaddr.ia_next = (struct in_ifaddr *) ifnet.if_addrlist;
397 str.ic_cmd = IPIOC_GETINADDR;
399 str.ic_len = sizeof (struct in_ifaddr);
400 str.ic_dp = (char *) &ifaddr;
402 if (ioctl (fd, (int) I_STR, (char *) &str) < 0)
405 Error ("Getting interface configuration (3)");
408 len = sizeof(struct sockaddr_in);
409 family = ConvertAddr (IA_SIN(&ifaddr), &len, (pointer *)&addr);
410 if (family == -1 || family == FamilyLocal)
412 for (host = selfhosts;
413 host && !addrEqual (family, addr, len, host);
421 host->family = family;
423 acopy(addr, host->addr, len);
424 host->next = selfhosts;
429 struct sockaddr broad_addr;
432 * If this isn't an Internet Address, don't register it.
434 if (family != FamilyInternet)
438 * ignore 'localhost' entries as they're not useful
439 * on the other end of the wire
442 addr[0] == 127 && addr[1] == 0 &&
443 addr[2] == 0 && addr[3] == 1)
446 XdmcpRegisterConnection (family, (char *)addr, len);
449 #define IA_BROADADDR(ia) ((struct sockaddr_in *)(&((struct in_ifaddr *)ia)->ia_broadaddr))
451 XdmcpRegisterBroadcastAddress (
452 (struct sockaddr_in *) IA_BROADADDR(&ifaddr));
462 * add something of FamilyLocalHost
464 for (host = selfhosts;
465 host && !addrEqual(FamilyLocalHost, "", 0, host);
472 host->family = FamilyLocalHost;
474 acopy("", host->addr, 0);
475 host->next = selfhosts;
483 #if !defined(SIOCGIFCONF) || (defined (hpux) && ! defined (HAS_IFREQ))
488 #if !defined(TCPCONN) && !defined(STREAMSCONN) && !defined(UNIXCONN) && !defined(MNX_TCPCONN)
498 register struct hostent *hp;
502 struct sockaddr_in in;
505 struct sockaddr_in *inetaddr;
506 struct sockaddr_in broad_addr;
508 /* Why not use gethostname()? Well, at least on my system, I've had to
509 * make an ugly kernel patch to get a name longer than 8 characters, and
510 * uname() lets me access to the whole string (it smashes release, you
511 * see), whereas gethostname() kindly truncates it for me.
514 hp = gethostbyname (name.nodename);
517 saddr.sa.sa_family = hp->h_addrtype;
518 inetaddr = (struct sockaddr_in *) (&(saddr.sa));
519 acopy ( hp->h_addr, &(inetaddr->sin_addr), hp->h_length);
520 len = sizeof(saddr.sa);
521 family = ConvertAddr ( &(saddr.sa), &len, (pointer *)&addr);
522 if ( family != -1 && family != FamilyLocal )
524 for (host = selfhosts;
525 host && !addrEqual (family, addr, len, host);
529 /* add this host to the host list. */
533 host->family = family;
535 acopy ( addr, host->addr, len);
536 host->next = selfhosts;
541 * If this is an Internet Address, but not the localhost
542 * address (127.0.0.1), register it.
544 if (family == FamilyInternet &&
545 !(len == 4 && addr[0] == 127 && addr[1] == 0 &&
546 addr[2] == 0 && addr[3] == 1)
549 XdmcpRegisterConnection (family, (char *)addr, len);
550 broad_addr = *inetaddr;
551 ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
552 htonl (INADDR_BROADCAST);
553 XdmcpRegisterBroadcastAddress ((struct sockaddr_in *)
561 * now add a host of family FamilyLocalHost...
563 for (host = selfhosts;
564 host && !addrEqual(FamilyLocalHost, "", 0, host);
571 host->family = FamilyLocalHost;
573 acopy("", host->addr, 0);
574 host->next = selfhosts;
578 #endif /* !TCPCONN && !STREAMSCONN && !UNIXCONN && !MNX_TCPCONN */
583 #ifdef VARIABLE_IFREQ
584 #define ifr_size(p) (sizeof (struct ifreq) + \
585 (p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \
586 p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0))
587 #define ifraddr_size(a) (a.sa_len)
589 #define ifr_size(p) (sizeof (struct ifreq))
590 #define ifraddr_size(a) (sizeof (a))
597 char buf[2048], *cp, *cplim;
601 unsigned char * addr;
604 register struct ifreq *ifr;
607 struct dn_naddr *dnaddr = getnodeadd();
609 * AF_DECnet may not be listed in the interface list. Instead use
610 * the supported library call to find out the local address (if any).
614 addr = (unsigned char *) dnaddr;
615 len = dnaddr->a_len + sizeof(dnaddr->a_len);
616 family = FamilyDECnet;
617 for (host = selfhosts;
618 host && !addrEqual (family, addr, len, host);
626 host->family = family;
628 acopy(addr, host->addr, len);
629 host->next = selfhosts;
635 ifc.ifc_len = sizeof (buf);
637 if (ifioctl (fd, (int) SIOCGIFCONF, (pointer) &ifc) < 0)
638 Error ("Getting interface configuration (4)");
641 #define IFC_IFC_REQ (struct ifreq *) ifc.ifc_buf
643 #define IFC_IFC_REQ ifc.ifc_req
646 cplim = (char *) IFC_IFC_REQ + ifc.ifc_len;
648 for (cp = (char *) IFC_IFC_REQ; cp < cplim; cp += ifr_size (ifr))
650 ifr = (struct ifreq *) cp;
651 len = ifraddr_size (ifr->ifr_addr);
654 * DECnet was handled up above.
656 if (ifr->ifr_addr.sa_family == AF_DECnet)
658 #endif /* DNETCONN */
659 family = ConvertAddr (&ifr->ifr_addr, &len, (pointer *)&addr);
660 if (family == -1 || family == FamilyLocal)
662 #ifdef DEF_SELF_DEBUG
663 if (family == FamilyInternet)
664 ErrorF("Xserver: DefineSelf(): ifname = %s, addr = %d.%d.%d.%d\n",
665 ifr->ifr_name, addr[0], addr[1], addr[2], addr[3]);
667 for (host = selfhosts;
668 host && !addrEqual (family, addr, len, host);
676 host->family = family;
678 acopy(addr, host->addr, len);
679 host->next = selfhosts;
684 struct sockaddr broad_addr;
687 * If this isn't an Internet Address, don't register it.
689 if (family != FamilyInternet)
693 * ignore 'localhost' entries as they're not useful
694 * on the other end of the wire
697 addr[0] == 127 && addr[1] == 0 &&
698 addr[2] == 0 && addr[3] == 1)
701 XdmcpRegisterConnection (family, (char *)addr, len);
702 broad_addr = ifr->ifr_addr;
703 ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
704 htonl (INADDR_BROADCAST);
705 #ifdef SIOCGIFBRDADDR
707 struct ifreq broad_req;
710 if (ifioctl (fd, SIOCGIFFLAGS, (char *) &broad_req) != -1 &&
711 (broad_req.ifr_flags & IFF_BROADCAST) &&
712 (broad_req.ifr_flags & IFF_UP)
716 if (ifioctl (fd, SIOCGIFBRDADDR, &broad_req) != -1)
717 broad_addr = broad_req.ifr_addr;
725 #ifdef DEF_SELF_DEBUG
726 ErrorF("Xserver: DefineSelf(): ifname = %s, baddr = %s\n",
728 inet_ntoa(((struct sockaddr_in *) &broad_addr)->sin_addr));
730 XdmcpRegisterBroadcastAddress ((struct sockaddr_in *) &broad_addr);
735 * add something of FamilyLocalHost
737 for (host = selfhosts;
738 host && !addrEqual(FamilyLocalHost, "", 0, host);
745 host->family = FamilyLocalHost;
747 acopy("", host->addr, 0);
748 host->next = selfhosts;
753 #endif /* hpux && !HAS_IFREQ */
758 AugmentSelf(from, len)
766 family = ConvertAddr(from, &len, (pointer *)&addr);
767 if (family == -1 || family == FamilyLocal)
769 for (host = selfhosts; host; host = host->next)
771 if (addrEqual(family, addr, len, host))
777 host->family = family;
779 acopy(addr, host->addr, len);
780 host->next = selfhosts;
790 for (self = selfhosts; self; self = self->next)
791 (void) NewHost (self->family, self->addr, self->len);
794 /* Reset access control list to initial hosts */
800 char lhostname[120], ohostname[120];
801 char *hostname = ohostname;
802 char fname[PATH_MAX + 1];
810 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
811 struct sockaddr_in in;
812 #endif /* TCPCONN || STREAMSCONN */
814 struct sockaddr_dn dn;
820 struct dn_naddr dnaddr, *dnaddrp, *dnet_addr();
823 krb5_principal princ;
829 register struct hostent *hp;
831 AccessEnabled = defeatAccessControl ? FALSE : DEFAULT_ACCESS_CONTROL;
832 LocalHostEnabled = FALSE;
833 while (host = validhosts)
835 validhosts = host->next;
839 #define ETC_HOST_PREFIX "/etc/X"
840 #define ETC_HOST_SUFFIX ".hosts"
842 #define ETC_HOST_PREFIX "/XFree86/lib/X11/X"
843 #define ETC_HOST_SUFFIX ".hosts"
845 fnamelen = strlen(ETC_HOST_PREFIX) + strlen(ETC_HOST_SUFFIX) +
847 if (fnamelen > sizeof(fname))
848 FatalError("Display name `%s' is too long\n");
849 sprintf(fname, ETC_HOST_PREFIX "%s" ETC_HOST_SUFFIX, display);
851 strcpy(fname, (char*)__XOS2RedirRoot(fname));
854 if (fd = fopen (fname, "r"))
856 while (fgets (ohostname, sizeof (ohostname), fd))
858 if (*ohostname == '#')
860 if (ptr = strchr(ohostname, '\n'))
863 if (ptr = strchr(ohostname, '\r'))
866 hostlen = strlen(ohostname) + 1;
867 for (i = 0; i < hostlen; i++)
868 lhostname[i] = tolower(ohostname[i]);
869 hostname = ohostname;
870 if (!strncmp("local:", lhostname, 6))
872 family = FamilyLocalHost;
873 NewHost(family, "", 0);
875 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
876 else if (!strncmp("inet:", lhostname, 5))
878 family = FamilyInternet;
879 hostname = ohostname + 5;
883 else if (!strncmp("dnet:", lhostname, 5))
885 family = FamilyDECnet;
886 hostname = ohostname + 5;
890 else if (!strncmp("nis:", lhostname, 4))
892 family = FamilyNetname;
893 hostname = ohostname + 4;
897 else if (!strncmp("krb:", lhostname, 4))
899 family = FamilyKrb5Principal;
900 hostname = ohostname + 4;
904 if ((family == FamilyDECnet) ||
905 (ptr = strchr(hostname, ':')) && (*(ptr + 1) == ':') &&
906 !(*ptr = '\0')) /* bash trailing colons if necessary */
908 /* node name (DECnet names end in "::") */
909 dnaddrp = dnet_addr(hostname);
910 if (!dnaddrp && (np = getnodebyname (hostname)))
912 /* node was specified by name */
913 saddr.sa.sa_family = np->n_addrtype;
914 len = sizeof(saddr.sa);
915 if (ConvertAddr (&saddr.sa, &len, (pointer *)&addr) == FamilyDECnet)
917 bzero ((char *) &dnaddr, sizeof (dnaddr));
918 dnaddr.a_len = np->n_length;
919 acopy (np->n_addr, dnaddr.a_addr, np->n_length);
924 (void) NewHost(FamilyDECnet, (pointer)dnaddrp,
925 (int)(dnaddrp->a_len + sizeof(dnaddrp->a_len)));
928 #endif /* DNETCONN */
930 if (family == FamilyKrb5Principal)
932 krb5_parse_name(hostname, &princ);
933 XauKrb5Encode(princ, &kbuf);
934 (void) NewHost(FamilyKrb5Principal, kbuf.data, kbuf.length);
935 krb5_free_principal(princ);
940 if ((family == FamilyNetname) || (strchr(hostname, '@')))
943 (void) NewHost (FamilyNetname, hostname, strlen (hostname));
946 #endif /* SECURE_RPC */
947 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
950 if (family == FamilyInternet && (hp = gethostbyname (hostname)) ||
951 (hp = gethostbyname (hostname)))
953 saddr.sa.sa_family = hp->h_addrtype;
954 len = sizeof(saddr.sa);
955 if ((family = ConvertAddr (&saddr.sa, &len, (pointer *)&addr)) != -1)
957 #ifdef h_addr /* new 4.3bsd version of gethostent */
960 /* iterate over the addresses */
961 for (list = hp->h_addr_list; *list; list++)
962 (void) NewHost (family, (pointer)*list, len);
964 (void) NewHost (family, (pointer)hp->h_addr, len);
969 #endif /* TCPCONN || STREAMSCONN */
976 /* Is client on the local host */
977 Bool LocalClient(client)
980 int alen, family, notused;
981 Xtransaddr *from = NULL;
986 /* untrusted clients can't change host access */
987 if (client->trustLevel != XSecurityClientTrusted)
989 SecurityAudit("client %d attempted to change host access\n",
995 if (!((OsCommPtr)client->osPrivate)->trans_conn)
998 if (!_XSERVTransGetPeerAddr (((OsCommPtr)client->osPrivate)->trans_conn,
999 ¬used, &alen, &from))
1001 family = ConvertAddr ((struct sockaddr *) from,
1002 &alen, (pointer *)&addr);
1005 xfree ((char *) from);
1008 if (family == FamilyLocal)
1010 xfree ((char *) from);
1013 for (host = selfhosts; host; host = host->next)
1015 if (addrEqual (family, addr, alen, host))
1018 xfree ((char *) from);
1024 AuthorizedClient(client)
1027 if (!client || defeatAccessControl)
1029 return LocalClient(client);
1032 /* Add a host to the access control list. This is the external interface
1033 * called from the dispatcher */
1036 AddHost (client, family, length, pAddr)
1039 unsigned length; /* of bytes in pAddr */
1044 if (!AuthorizedClient(client))
1047 case FamilyLocalHost:
1049 LocalHostEnabled = TRUE;
1052 case FamilyKrb5Principal:
1062 case FamilyInternet:
1065 if ((len = CheckAddr (family, pAddr, length)) < 0)
1067 client->errorValue = length;
1073 client->errorValue = family;
1076 if (NewHost (family, pAddr, len))
1082 #if NeedFunctionPrototypes
1083 ForEachHostInFamily (
1086 #if NeedNestedPrototypes
1087 unsigned char * /* addr */,
1089 pointer /* closure */
1094 ForEachHostInFamily (family, func, closure)
1102 for (host = validhosts; host; host = host->next)
1103 if (family == host->family && func (host->addr, host->len, closure))
1108 /* Add a host to the access control list. This is the internal interface
1109 * called when starting or resetting the server */
1111 NewHost (family, addr, len)
1116 register HOST *host;
1118 for (host = validhosts; host; host = host->next)
1120 if (addrEqual (family, addr, len, host))
1126 host->family = family;
1128 acopy(addr, host->addr, len);
1129 host->next = validhosts;
1134 /* Remove a host from the access control list */
1137 RemoveHost (client, family, length, pAddr)
1140 unsigned length; /* of bytes in pAddr */
1144 register HOST *host, **prev;
1146 if (!AuthorizedClient(client))
1149 case FamilyLocalHost:
1151 LocalHostEnabled = FALSE;
1154 case FamilyKrb5Principal:
1163 case FamilyInternet:
1166 if ((len = CheckAddr (family, pAddr, length)) < 0)
1168 client->errorValue = length;
1174 client->errorValue = family;
1177 for (prev = &validhosts;
1178 (host = *prev) && (!addrEqual (family, pAddr, len, host));
1189 /* Get all hosts in the access control list */
1191 GetHosts (data, pnHosts, pLen, pEnabled)
1199 register unsigned char *ptr;
1200 register HOST *host;
1203 *pEnabled = AccessEnabled ? EnableAccess : DisableAccess;
1204 for (host = validhosts; host; host = host->next)
1207 n += (((host->len + 3) >> 2) << 2) + sizeof(xHostEntry);
1211 *data = ptr = (pointer) xalloc (n);
1216 for (host = validhosts; host; host = host->next)
1219 ((xHostEntry *)ptr)->family = host->family;
1220 ((xHostEntry *)ptr)->length = len;
1221 ptr += sizeof(xHostEntry);
1222 acopy (host->addr, ptr, len);
1223 ptr += ((len + 3) >> 2) << 2;
1233 /* Check for valid address family and length, and return address length. */
1237 CheckAddr (family, pAddr, length)
1246 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(AMTCPCONN) || defined(MNX_TCPCONN)
1247 case FamilyInternet:
1248 #if !defined(AMOEBA)
1249 if (length == sizeof (struct in_addr))
1251 if (length == sizeof(ipaddr_t))
1261 struct dn_naddr *dnaddr = (struct dn_naddr *) pAddr;
1263 if ((length < sizeof(dnaddr->a_len)) ||
1264 (length < dnaddr->a_len + sizeof(dnaddr->a_len)))
1267 len = dnaddr->a_len + sizeof(dnaddr->a_len);
1268 if (len > sizeof(struct dn_naddr))
1279 /* Check if a host is not in the access control list.
1280 * Returns 1 if host is invalid, 0 if we've found it. */
1282 InvalidHost (saddr, len)
1284 register struct sockaddr *saddr;
1286 register ipaddr_t *saddr;
1292 register HOST *selfhost, *host;
1294 if (!AccessEnabled) /* just let them in */
1296 family = ConvertAddr (saddr, &len, (pointer *)&addr);
1299 if (family == FamilyLocal)
1301 if (!LocalHostEnabled)
1304 * check to see if any local address is enabled. This
1305 * implicitly enables local connections.
1307 for (selfhost = selfhosts; selfhost; selfhost=selfhost->next)
1309 for (host = validhosts; host; host=host->next)
1311 if (addrEqual (selfhost->family, selfhost->addr,
1312 selfhost->len, host))
1320 for (host = validhosts; host; host = host->next)
1322 if (addrEqual (family, addr, len, host))
1329 ConvertAddr (saddr, len, addr)
1331 register struct sockaddr *saddr;
1333 register ipaddr_t *saddr;
1340 return (FamilyLocal);
1341 switch (saddr->sa_family)
1344 #if defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN)
1348 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
1350 *len = sizeof (struct in_addr);
1351 *addr = (pointer) &(((struct sockaddr_in *) saddr)->sin_addr);
1352 return FamilyInternet;
1357 struct sockaddr_dn *sdn = (struct sockaddr_dn *) saddr;
1358 *len = sdn->sdn_nodeaddrl + sizeof(sdn->sdn_nodeaddrl);
1359 *addr = (pointer) &(sdn->sdn_add);
1361 return FamilyDECnet;
1374 if (*len == 0) return -1;
1375 *len = sizeof (ipaddr_t);
1376 *addr = (pointer) saddr;
1377 return FamilyInternet;
1382 ChangeAccessControl(client, fEnabled)
1386 if (!AuthorizedClient(client))
1388 AccessEnabled = fEnabled;
1392 /* returns FALSE if xhost + in effect, else TRUE */
1396 return AccessEnabled;