1 dawes 3.9 /* $XConsortium: access.c /main/62 1995/12/07 17:53:09 kaleb $ */
|
2 dawes 3.12 /* $XFree86: xc/programs/Xserver/os/access.c,v 3.11 1996/02/18 03:45:22 dawes Exp $ */
|
3 dawes 1.1 /***********************************************************
4
5 Copyright (c) 1987 X Consortium
6
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:
13
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
16
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.
23
24 dawes 1.1 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.
27
28
29 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
30
31 All Rights Reserved
32
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.
40
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 dawes 1.1 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
47 SOFTWARE.
48
49 ******************************************************************/
50
51 #include <stdio.h>
52 #include <X11/Xtrans.h>
53 #include <X11/Xauth.h>
54 #include "X.h"
55 #include "Xproto.h"
56 #include "misc.h"
57 #include "site.h"
58 #include <errno.h>
|
59 dawes 3.2 #if !defined(AMOEBA) && !defined(MINIX)
|
60 dawes 1.1 #ifdef ESIX
61 #include <lan/socket.h>
62 #else
63 #include <sys/socket.h>
64 #endif
65 #include <sys/ioctl.h>
|
66 dawes 3.0 #else
67 #ifdef AMOEBA
68 #define port am_port_t
69 #include <amoeba.h>
70 #include <cmdreg.h>
71 #include <stdcom.h>
72 #include <stderr.h>
73 #include <ampolicy.h>
74 #include <server/ip/hton.h>
75 #include <server/ip/types.h>
76 #include <server/ip/tcpip.h>
77 #include <server/ip/tcp_io.h>
78 #include <server/ip/gen/in.h>
79 #include <server/ip/gen/tcp.h>
80 #include <server/ip/gen/tcp_io.h>
81 #include <server/ip/gen/socket.h>
82 #undef port
83 #endif
|
84 dawes 3.2 #endif /* AMOEBA || MINIX */
|
85 dawes 1.1 #include <ctype.h>
86
|
87 dawes 3.3 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(ISC) || defined(SCO)
|
88 dawes 1.1 #include <netinet/in.h>
|
89 dawes 3.3 #endif /* TCPCONN || STREAMSCONN || ISC || SCO */
|
90 dawes 1.1 #ifdef DNETCONN
91 #include <netdnet/dn.h>
92 #include <netdnet/dnetdb.h>
93 #endif
94
|
95 dawes 3.2 #if !defined(AMOEBA)
|
96 dawes 1.1 #ifdef hpux
97 # include <sys/utsname.h>
98 # ifdef HAS_IFREQ
99 # include <net/if.h>
100 # endif
101 #else
|
102 dawes 3.2 #if defined(SVR4) || (defined(SYSV) && defined(i386)) || defined(MINIX)
|
103 dawes 1.1 # include <sys/utsname.h>
104 #endif
105 #if defined(SYSV) && defined(i386)
106 # include <sys/stream.h>
|
107 dawes 3.1 # ifdef ISC
108 # include <sys/stropts.h>
109 # include <sys/sioctl.h>
110 # endif /* ISC */
|
111 dawes 1.1 #endif
112 #ifdef ESIX
113 # include <lan/if.h>
114 #else
|
115 dawes 3.2 #ifndef MINIX
|
116 dawes 1.1 # include <net/if.h>
117 #endif
|
118 dawes 3.2 #endif
|
119 dawes 1.1 #endif /* hpux */
|
120 dawes 3.2 #endif /* !AMOEBA */
|
121 dawes 1.1
122 #ifdef SVR4
123 #include <sys/sockio.h>
|
124 dawes 3.1 #include <sys/stropts.h>
|
125 dawes 1.1 #endif
126
127 #ifdef ESIX
128 #include <lan/netdb.h>
129 #else
|
130 dawes 3.2 #if !defined(AMOEBA) && !defined(MINIX)
|
131 dawes 1.1 #include <netdb.h>
|
132 dawes 3.0 #else
133 #ifdef AMOEBA
134 #include <server/ip/gen/netdb.h>
|
135 dawes 1.1 #endif
|
136 dawes 3.2 #ifdef MINIX
137 #include <net/hton.h>
138 #include <net/gen/netdb.h>
139 #define INADDR_BROADCAST 0xFFFFFFFF
140 #endif
141 #endif /* AMOEBA || MINIX */
|
142 dawes 3.0 #endif /* ESIX */
|
143 dawes 1.1
|
144 dawes 3.7 #ifdef CSRG_BASED
145 #include <sys/param.h>
146 #if (BSD >= 199103)
147 #define VARIABLE_IFREQ
148 #endif
149 #endif
150
|
151 dawes 1.1 #include "dixstruct.h"
152 #include "osdep.h"
153
154 Bool defeatAccessControl = FALSE;
155
156 #define acmp(a1, a2, len) memcmp((char *)(a1), (char *)(a2), len)
157 #define acopy(a1, a2, len) memmove((char *)(a2), (char *)(a1), len)
158 #define addrEqual(fam, address, length, host) \
159 ((fam) == (host)->family &&\
160 (length) == (host)->len &&\
161 !acmp (address, (host)->addr, length))
162
163 static int ConvertAddr(
164 #if NeedFunctionPrototypes
165 struct sockaddr */*saddr*/,
166 int */*len*/,
167 pointer */*addr*/
168 #endif
169 );
170
171 static int CheckAddr(
172 dawes 1.1 #if NeedFunctionPrototypes
173 int /*family*/,
174 pointer /*pAddr*/,
175 unsigned /*length*/
176 #endif
177 );
178
179 static Bool NewHost(
180 #if NeedFunctionPrototypes
181 int /*family*/,
182 pointer /*addr*/,
183 int /*len*/
184 #endif
185 );
186
187 typedef struct _host {
188 short family;
189 short len;
190 unsigned char *addr;
191 struct _host *next;
192 } HOST;
193 dawes 1.1
194 #define MakeHost(h,l) (h)=(HOST *) xalloc(sizeof *(h)+(l));\
195 (h)->addr=(unsigned char *) ((h) + 1);
196 #define FreeHost(h) xfree(h)
197 static HOST *selfhosts = NULL;
198 static HOST *validhosts = NULL;
199 static int AccessEnabled = DEFAULT_ACCESS_CONTROL;
200 static int LocalHostEnabled = FALSE;
201 static int UsingXdmcp = FALSE;
202
203 /*
204 * called when authorization is not enabled to add the
205 * local host to the access list
206 */
207
208 void
209 EnableLocalHost ()
210 {
211 if (!UsingXdmcp)
212 {
213 LocalHostEnabled = TRUE;
214 dawes 1.1 AddLocalHosts ();
215 }
216 }
217
218 /*
219 * called when authorization is enabled to keep us secure
220 */
221 void
222 DisableLocalHost ()
223 {
224 HOST *self;
225
226 LocalHostEnabled = FALSE;
227 for (self = selfhosts; self; self = self->next)
228 (void) RemoveHost ((ClientPtr)NULL, self->family, self->len, (pointer)self->addr);
229 }
230
231 /*
232 * called at init time when XDMCP will be used; xdmcp always
233 * adds local hosts manually when needed
234 */
235 dawes 1.1
236 void
237 AccessUsingXdmcp ()
238 {
239 UsingXdmcp = TRUE;
240 LocalHostEnabled = FALSE;
241 }
242
243
|
244 dawes 3.4 #if ((defined(SVR4) && !defined(sun) && !defined(NCR)) || defined(ISC)) && defined(SIOCGIFCONF)
|
245 dawes 3.1
246 /* Deal with different SIOCGIFCONF ioctl semantics on these OSs */
247
248 static int
249 ifioctl (fd, cmd, arg)
250 int fd;
251 int cmd;
252 char *arg;
253 {
254 struct strioctl ioc;
255 int ret;
256
257 bzero((char *) &ioc, sizeof(ioc));
258 ioc.ic_cmd = cmd;
259 ioc.ic_timout = 0;
260 if (cmd == SIOCGIFCONF)
261 {
262 ioc.ic_len = ((struct ifconf *) arg)->ifc_len;
263 ioc.ic_dp = ((struct ifconf *) arg)->ifc_buf;
264 #ifdef ISC
265 /* SIOCGIFCONF is somewhat brain damaged on ISC. The argument
266 dawes 3.1 * buffer must contain the ifconf structure as header. Ifc_req
267 * is also not a pointer but a one element array of ifreq
268 * structures. On return this array is extended by enough
269 * ifreq fields to hold all interfaces. The return buffer length
270 * is placed in the buffer header.
271 */
272 ((struct ifconf *) ioc.ic_dp)->ifc_len =
273 ioc.ic_len - sizeof(struct ifconf);
274 #endif
275 }
276 else
277 {
278 ioc.ic_len = sizeof(struct ifreq);
279 ioc.ic_dp = arg;
280 }
281 ret = ioctl(fd, I_STR, (char *) &ioc);
282 if (ret >= 0 && cmd == SIOCGIFCONF)
283 #ifdef SVR4
284 ((struct ifconf *) arg)->ifc_len = ioc.ic_len;
285 #endif
286 #ifdef ISC
287 dawes 3.1 {
288 ((struct ifconf *) arg)->ifc_len =
289 ((struct ifconf *)ioc.ic_dp)->ifc_len;
290 ((struct ifconf *) arg)->ifc_buf =
291 (caddr_t)((struct ifconf *)ioc.ic_dp)->ifc_req;
292 }
293 #endif
294 return(ret);
295 }
296 #else /* ((SVR4 && !sun) || ISC) && SIOCGIFCONF */
297 #define ifioctl ioctl
298 #endif /* ((SVR4 && !sun) || ISC) && SIOCGIFCONF */
299
|
300 dawes 1.1 /*
301 * DefineSelf (fd):
302 *
303 * Define this host for access control. Find all the hosts the OS knows about
304 * for this fd and add them to the selfhosts list.
305 */
306
|
307 dawes 3.9 #ifdef WINTCP /* NCR Wollongong based TCP */
|
308 dawes 1.1
309 #include <sys/un.h>
310 #include <stropts.h>
311 #include <tiuser.h>
312
313 #include <sys/stream.h>
314 #include <net/if.h>
315 #include <netinet/ip.h>
316 #include <netinet/ip_var.h>
317 #include <netinet/in.h>
318 #include <netinet/in_var.h>
319
320 void
321 DefineSelf (fd)
322 int fd;
323 {
324 /*
325 * The Wolongong drivers used by NCR SVR4/MP-RAS don't understand the
326 * socket IO calls that most other drivers seem to like. Because of
327 * this, this routine must be special cased for NCR. Eventually,
328 * this will be cleared up.
329 dawes 1.1 */
330
331 struct ipb ifnet;
332 struct in_ifaddr ifaddr;
333 struct strioctl str;
334 unsigned char *addr;
335 register HOST *host;
336 int family, len;
337
338 if ((fd = open ("/dev/ip", O_RDWR, 0 )) < 0)
339 Error ("Getting interface configuration");
340
341 /* Indicate that we want to start at the begining */
342 ifnet.ib_next = (struct ipb *) 1;
343
344 while (ifnet.ib_next)
345 {
346 str.ic_cmd = IPIOC_GETIPB;
347 str.ic_timout = 0;
348 str.ic_len = sizeof (struct ipb);
349 str.ic_dp = (char *) &ifnet;
350 dawes 1.1
351 if (ioctl (fd, (int) I_STR, (char *) &str) < 0)
352 {
353 close (fd);
354 Error ("Getting interface configuration");
355 }
356
357 ifaddr.ia_next = (struct in_ifaddr *) ifnet.if_addrlist;
358 str.ic_cmd = IPIOC_GETINADDR;
359 str.ic_timout = 0;
360 str.ic_len = sizeof (struct in_ifaddr);
361 str.ic_dp = (char *) &ifaddr;
362
363 if (ioctl (fd, (int) I_STR, (char *) &str) < 0)
364 {
365 close (fd);
366 Error ("Getting interface configuration");
367 }
368
369 len = sizeof(struct sockaddr_in);
370 family = ConvertAddr (IA_SIN(&ifaddr), &len, (pointer *)&addr);
371 dawes 1.1 if (family == -1 || family == FamilyLocal)
372 continue;
373 for (host = selfhosts;
374 host && !addrEqual (family, addr, len, host);
375 host = host->next)
376 ;
377 if (host)
378 continue;
379 MakeHost(host,len)
380 if (host)
381 {
382 host->family = family;
383 host->len = len;
384 acopy(addr, host->addr, len);
385 host->next = selfhosts;
386 selfhosts = host;
387 }
388 #ifdef XDMCP
389 {
390 struct sockaddr broad_addr;
391
392 dawes 1.1 /*
393 * If this isn't an Internet Address, don't register it.
394 */
395 if (family != FamilyInternet)
396 continue;
397
398 /*
399 * ignore 'localhost' entries as they're not useful
400 * on the other end of the wire
401 */
402 if (len == 4 &&
403 addr[0] == 127 && addr[1] == 0 &&
404 addr[2] == 0 && addr[3] == 1)
405 continue;
406
407 XdmcpRegisterConnection (family, (char *)addr, len);
408
409
410 #define IA_BROADADDR(ia) ((struct sockaddr_in *)(&((struct in_ifaddr *)ia)->ia_broadaddr))
411
412 XdmcpRegisterBroadcastAddress (
413 dawes 1.1 (struct sockaddr_in *) IA_BROADADDR(&ifaddr));
414
415 #undef IA_BROADADDR
416 }
417 #endif /* XDMCP */
418 }
419
420 close(fd);
421
422 /*
423 * add something of FamilyLocalHost
424 */
425 for (host = selfhosts;
426 host && !addrEqual(FamilyLocalHost, "", 0, host);
427 host = host->next);
428 if (!host)
429 {
430 MakeHost(host, 0);
431 if (host)
432 {
433 host->family = FamilyLocalHost;
434 dawes 1.1 host->len = 0;
435 acopy("", host->addr, 0);
436 host->next = selfhosts;
437 selfhosts = host;
438 }
439 }
440 }
441
|
442 dawes 3.7 #else /* WINTCP */
|
443 dawes 1.1
444 #if !defined(SIOCGIFCONF) || (defined (hpux) && ! defined (HAS_IFREQ))
445 void
446 DefineSelf (fd)
447 int fd;
448 {
|
449 dawes 3.2 #if !defined(TCPCONN) && !defined(STREAMSCONN) && !defined(UNIXCONN) && !defined(MNX_TCPCONN)
|
450 dawes 1.1 return;
451 #else
452 register int n;
453 int len;
454 caddr_t addr;
455 int family;
456 register HOST *host;
457
458 struct utsname name;
459 register struct hostent *hp;
460
461 union {
462 struct sockaddr sa;
463 struct sockaddr_in in;
464 } saddr;
465
466 struct sockaddr_in *inetaddr;
467 struct sockaddr_in broad_addr;
468
469 /* Why not use gethostname()? Well, at least on my system, I've had to
470 * make an ugly kernel patch to get a name longer than 8 characters, and
471 dawes 1.1 * uname() lets me access to the whole string (it smashes release, you
472 * see), whereas gethostname() kindly truncates it for me.
473 */
474 uname(&name);
475 hp = gethostbyname (name.nodename);
476 if (hp != NULL)
477 {
478 saddr.sa.sa_family = hp->h_addrtype;
479 inetaddr = (struct sockaddr_in *) (&(saddr.sa));
480 acopy ( hp->h_addr, &(inetaddr->sin_addr), hp->h_length);
481 len = sizeof(saddr.sa);
482 family = ConvertAddr ( &(saddr.sa), &len, (pointer *)&addr);
483 if ( family != -1 && family != FamilyLocal )
484 {
485 for (host = selfhosts;
486 host && !addrEqual (family, addr, len, host);
487 host = host->next) ;
488 if (!host)
489 {
490 /* add this host to the host list. */
491 MakeHost(host,len)
492 dawes 1.1 if (host)
493 {
494 host->family = family;
495 host->len = len;
496 acopy ( addr, host->addr, len);
497 host->next = selfhosts;
498 selfhosts = host;
499 }
500 #ifdef XDMCP
501 /*
502 * If this is an Internet Address, but not the localhost
503 * address (127.0.0.1), register it.
504 */
505 if (family == FamilyInternet &&
506 !(len == 4 && addr[0] == 127 && addr[1] == 0 &&
507 addr[2] == 0 && addr[3] == 1)
508 )
509 {
510 XdmcpRegisterConnection (family, (char *)addr, len);
511 broad_addr = *inetaddr;
512 ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
513 dawes 1.1 htonl (INADDR_BROADCAST);
514 XdmcpRegisterBroadcastAddress ((struct sockaddr_in *)
515 &broad_addr);
516 }
|
517 dawes 3.2 #endif /* XDMCP */
|
518 dawes 1.1 }
519 }
520 }
521 /*
522 * now add a host of family FamilyLocalHost...
523 */
524 for (host = selfhosts;
525 host && !addrEqual(FamilyLocalHost, "", 0, host);
526 host = host->next);
527 if (!host)
528 {
529 MakeHost(host, 0);
530 if (host)
531 {
532 host->family = FamilyLocalHost;
533 host->len = 0;
534 acopy("", host->addr, 0);
535 host->next = selfhosts;
536 selfhosts = host;
537 }
538 }
|
539 dawes 3.2 #endif /* !TCPCONN && !STREAMSCONN && !UNIXCONN && !MNX_TCPCONN */
|
540 dawes 1.1 }
541
542 #else
|
543 dawes 3.1
|
544 dawes 3.7 #ifdef VARIABLE_IFREQ
|
545 dawes 3.1 #define ifr_size(p) (sizeof (struct ifreq) + \
546 (p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \
547 p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0))
548 #define ifraddr_size(a) (a.sa_len)
549 #else
550 #define ifr_size(p) (sizeof (struct ifreq))
551 #define ifraddr_size(a) (sizeof (a))
552 #endif
553
|
554 dawes 1.1 void
555 DefineSelf (fd)
556 int fd;
557 {
|
558 dawes 3.1 char buf[2048], *cp, *cplim;
|
559 dawes 1.1 struct ifconf ifc;
560 register int n;
561 int len;
562 unsigned char * addr;
563 int family;
564 register HOST *host;
565 register struct ifreq *ifr;
566
567 #ifdef DNETCONN
|
568 dawes 3.5 struct dn_naddr *dnaddr = getnodeadd();
|
569 dawes 1.1 /*
570 * AF_DECnet may not be listed in the interface list. Instead use
571 * the supported library call to find out the local address (if any).
572 */
573 if (dnaddr)
574 {
575 addr = (unsigned char *) dnaddr;
576 len = dnaddr->a_len + sizeof(dnaddr->a_len);
577 family = FamilyDECnet;
578 for (host = selfhosts;
579 host && !addrEqual (family, addr, len, host);
580 host = host->next)
581 ;
582 if (!host)
583 {
584 MakeHost(host,len)
585 if (host)
586 {
587 host->family = family;
588 host->len = len;
589 acopy(addr, host->addr, len);
590 dawes 1.1 host->next = selfhosts;
591 selfhosts = host;
592 }
593 }
594 }
595 #endif
596 ifc.ifc_len = sizeof (buf);
597 ifc.ifc_buf = buf;
|
598 dawes 3.1 if (ifioctl (fd, (int) SIOCGIFCONF, (pointer) &ifc) < 0)
|
599 dawes 1.1 Error ("Getting interface configuration");
|
600 dawes 3.1
601 #ifdef ISC
602 #define IFC_IFC_REQ (struct ifreq *) ifc.ifc_buf
|
603 dawes 1.1 #else
|
604 dawes 3.1 #define IFC_IFC_REQ ifc.ifc_req
|
605 dawes 1.1 #endif
|
606 dawes 3.1
607 cplim = (char *) IFC_IFC_REQ + ifc.ifc_len;
608
609 for (cp = (char *) IFC_IFC_REQ; cp < cplim; cp += ifr_size (ifr))
|
610 dawes 1.1 {
|
611 dawes 3.1 ifr = (struct ifreq *) cp;
612 len = ifraddr_size (ifr->ifr_addr);
|
613 dawes 1.1 #ifdef DNETCONN
614 /*
615 * DECnet was handled up above.
616 */
617 if (ifr->ifr_addr.sa_family == AF_DECnet)
618 continue;
619 #endif /* DNETCONN */
620 family = ConvertAddr (&ifr->ifr_addr, &len, (pointer *)&addr);
621 if (family == -1 || family == FamilyLocal)
622 continue;
|
623 dawes 3.1 #ifdef DEF_SELF_DEBUG
624 if (family == FamilyInternet)
625 ErrorF("Xserver: DefineSelf(): ifname = %s, addr = %d.%d.%d.%d\n",
626 ifr->ifr_name, addr[0], addr[1], addr[2], addr[3]);
627 #endif
|
628 dawes 1.1 for (host = selfhosts;
629 host && !addrEqual (family, addr, len, host);
630 host = host->next)
631 ;
632 if (host)
633 continue;
634 MakeHost(host,len)
635 if (host)
636 {
637 host->family = family;
638 host->len = len;
639 acopy(addr, host->addr, len);
640 host->next = selfhosts;
641 selfhosts = host;
642 }
643 #ifdef XDMCP
644 {
645 struct sockaddr broad_addr;
646
647 /*
648 * If this isn't an Internet Address, don't register it.
649 dawes 1.1 */
650 if (family != FamilyInternet)
651 continue;
652
653 /*
654 * ignore 'localhost' entries as they're not useful
655 * on the other end of the wire
656 */
657 if (len == 4 &&
658 addr[0] == 127 && addr[1] == 0 &&
659 addr[2] == 0 && addr[3] == 1)
660 continue;
661
662 XdmcpRegisterConnection (family, (char *)addr, len);
663 broad_addr = ifr->ifr_addr;
664 ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
665 htonl (INADDR_BROADCAST);
666 #ifdef SIOCGIFBRDADDR
667 {
668 struct ifreq broad_req;
669
670 dawes 1.1 broad_req = *ifr;
|
671 dawes 3.1 if (ifioctl (fd, SIOCGIFFLAGS, (char *) &broad_req) != -1 &&
|
672 dawes 1.1 (broad_req.ifr_flags & IFF_BROADCAST) &&
673 (broad_req.ifr_flags & IFF_UP)
674 )
675 {
676 broad_req = *ifr;
|
677 dawes 3.1 if (ifioctl (fd, SIOCGIFBRDADDR, &broad_req) != -1)
|
678 dawes 1.1 broad_addr = broad_req.ifr_addr;
679 else
680 continue;
681 }
682 else
683 continue;
684 }
|
685 dawes 3.1 #endif
686 #ifdef DEF_SELF_DEBUG
687 ErrorF("Xserver: DefineSelf(): ifname = %s, baddr = %s\n",
688 ifr->ifr_name,
689 inet_ntoa(((struct sockaddr_in *) &broad_addr)->sin_addr));
|
690 dawes 1.1 #endif
691 XdmcpRegisterBroadcastAddress ((struct sockaddr_in *) &broad_addr);
692 }
693 #endif
694 }
695 /*
696 * add something of FamilyLocalHost
697 */
698 for (host = selfhosts;
699 host && !addrEqual(FamilyLocalHost, "", 0, host);
700 host = host->next);
701 if (!host)
702 {
703 MakeHost(host, 0);
704 if (host)
705 {
706 host->family = FamilyLocalHost;
707 host->len = 0;
708 acopy("", host->addr, 0);
709 host->next = selfhosts;
710 selfhosts = host;
711 dawes 1.1 }
712 }
713 }
714 #endif /* hpux && !HAS_IFREQ */
|
715 dawes 3.7 #endif /* WINTCP */
|
716 dawes 1.1
717 #ifdef XDMCP
718 void
719 AugmentSelf(from, len)
720 pointer from;
721 int len;
722 {
723 int family;
724 pointer addr;
725 register HOST *host;
726
727 family = ConvertAddr(from, &len, (pointer *)&addr);
728 if (family == -1 || family == FamilyLocal)
729 return;
730 for (host = selfhosts; host; host = host->next)
731 {
732 if (addrEqual(family, addr, len, host))
733 return;
734 }
735 MakeHost(host,len)
736 if (!host)
737 dawes 1.1 return;
738 host->family = family;
739 host->len = len;
740 acopy(addr, host->addr, len);
741 host->next = selfhosts;
742 selfhosts = host;
743 }
744 #endif
745
746 void
747 AddLocalHosts ()
748 {
749 HOST *self;
750
751 for (self = selfhosts; self; self = self->next)
752 (void) NewHost (self->family, self->addr, self->len);
753 }
754
755 /* Reset access control list to initial hosts */
756 void
757 ResetHosts (display)
758 dawes 1.1 char *display;
759 {
760 register HOST *host;
761 char lhostname[120], ohostname[120];
762 char *hostname = ohostname;
|
763 dawes 3.10 char fname[100];
|
764 dawes 1.1 FILE *fd;
765 char *ptr;
766 int i, hostlen;
|
767 dawes 3.0 #ifndef AMOEBA
|
768 dawes 1.1 union {
769 struct sockaddr sa;
|
770 dawes 3.2 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
|
771 dawes 1.1 struct sockaddr_in in;
772 #endif /* TCPCONN || STREAMSCONN */
773 #ifdef DNETCONN
774 struct sockaddr_dn dn;
775 #endif
776 } saddr;
|
777 dawes 3.0 #endif /* AMOEBA */
|
778 dawes 1.1 #ifdef DNETCONN
779 struct nodeent *np;
780 struct dn_naddr dnaddr, *dnaddrp, *dnet_addr();
781 #endif
782 #ifdef K5AUTH
783 krb5_principal princ;
784 krb5_data kbuf;
785 #endif
786 int family;
787 pointer addr;
788 int len;
789 register struct hostent *hp;
790
791 AccessEnabled = defeatAccessControl ? FALSE : DEFAULT_ACCESS_CONTROL;
792 LocalHostEnabled = FALSE;
793 while (host = validhosts)
794 {
795 validhosts = host->next;
796 FreeHost (host);
797 }
|
798 dawes 3.10 #ifndef __EMX__
|
799 dawes 1.1 strcpy (fname, "/etc/X");
800 strcat (fname, display);
801 strcat (fname, ".hosts");
|
802 dawes 3.10 #else
803 sprintf (fname, "/XFree86/lib/X11/X%s.hosts",display);
|
804 dawes 3.12 strcpy(fname, (char*)__XOS2RedirRoot(fname));
|
805 dawes 3.10 #endif /* __EMX__ */
|
806 dawes 1.1 if (fd = fopen (fname, "r"))
807 {
808 while (fgets (ohostname, sizeof (ohostname), fd))
809 {
810 if (*ohostname == '#')
811 continue;
812 if (ptr = strchr(ohostname, '\n'))
813 *ptr = 0;
814 hostlen = strlen(ohostname) + 1;
815 for (i = 0; i < hostlen; i++)
816 lhostname[i] = tolower(ohostname[i]);
817 hostname = ohostname;
818 if (!strncmp("local:", lhostname, 6))
819 {
820 family = FamilyLocalHost;
821 NewHost(family, "", 0);
822 }
|
823 dawes 3.2 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
|
824 dawes 1.1 else if (!strncmp("inet:", lhostname, 5))
825 {
826 family = FamilyInternet;
827 hostname = ohostname + 5;
828 }
829 #endif
830 #ifdef DNETCONN
831 else if (!strncmp("dnet:", lhostname, 5))
832 {
833 family = FamilyDECnet;
834 hostname = ohostname + 5;
835 }
836 #endif
837 #ifdef SECURE_RPC
838 else if (!strncmp("nis:", lhostname, 4))
839 {
840 family = FamilyNetname;
841 hostname = ohostname + 4;
842 }
843 #endif
844 #ifdef K5AUTH
845 dawes 1.1 else if (!strncmp("krb:", lhostname, 4))
846 {
847 family = FamilyKrb5Principal;
848 hostname = ohostname + 4;
849 }
850 #endif
851 #ifdef DNETCONN
852 if ((family == FamilyDECnet) ||
853 (ptr = strchr(hostname, ':')) && (*(ptr + 1) == ':') &&
854 !(*ptr = '\0')) /* bash trailing colons if necessary */
855 {
856 /* node name (DECnet names end in "::") */
857 dnaddrp = dnet_addr(hostname);
858 if (!dnaddrp && (np = getnodebyname (hostname)))
859 {
860 /* node was specified by name */
861 saddr.sa.sa_family = np->n_addrtype;
862 len = sizeof(saddr.sa);
863 if (ConvertAddr (&saddr.sa, &len, (pointer *)&addr) == FamilyDECnet)
864 {
865 bzero ((char *) &dnaddr, sizeof (dnaddr));
866 dawes 1.1 dnaddr.a_len = np->n_length;
867 acopy (np->n_addr, dnaddr.a_addr, np->n_length);
868 dnaddrp = &dnaddr;
869 }
870 }
871 if (dnaddrp)
872 (void) NewHost(FamilyDECnet, (pointer)dnaddrp,
873 (int)(dnaddrp->a_len + sizeof(dnaddrp->a_len)));
874 }
875 else
876 #endif /* DNETCONN */
877 #ifdef K5AUTH
878 if (family == FamilyKrb5Principal)
879 {
880 krb5_parse_name(hostname, &princ);
881 XauKrb5Encode(princ, &kbuf);
882 (void) NewHost(FamilyKrb5Principal, kbuf.data, kbuf.length);
883 krb5_free_principal(princ);
884 }
885 else
886 #endif
887 dawes 1.1 #ifdef SECURE_RPC
888 if ((family == FamilyNetname) || (strchr(hostname, '@')))
889 {
890 SecureRPCInit ();
891 (void) NewHost (FamilyNetname, hostname, strlen (hostname));
892 }
893 else
894 #endif /* SECURE_RPC */
|
895 dawes 3.2 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
|
896 dawes 1.1 {
897 /* host name */
898 if (family == FamilyInternet && (hp = gethostbyname (hostname)) ||
899 (hp = gethostbyname (hostname)))
900 {
901 saddr.sa.sa_family = hp->h_addrtype;
902 len = sizeof(saddr.sa);
903 if ((family = ConvertAddr (&saddr.sa, &len, (pointer *)&addr)) != -1)
904 {
905 #ifdef h_addr /* new 4.3bsd version of gethostent */
906 char **list;
907
908 /* iterate over the addresses */
909 for (list = hp->h_addr_list; *list; list++)
910 (void) NewHost (family, (pointer)*list, len);
911 #else
912 (void) NewHost (family, (pointer)hp->h_addr, len);
913 #endif
914 }
915 }
916 }
917 dawes 1.1 #endif /* TCPCONN || STREAMSCONN */
918 family = FamilyWild;
919 }
920 fclose (fd);
921 }
922 }
923
924 static Bool
925 AuthorizedClient(client)
926 ClientPtr client;
927 {
928 int alen, family, notused;
929 Xtransaddr *from = NULL;
930 pointer addr;
931 register HOST *host;
932
933 if (!client || defeatAccessControl)
934 return TRUE;
935 if (!_XSERVTransGetPeerAddr (((OsCommPtr)client->osPrivate)->trans_conn,
936 ¬used, &alen, &from))
937 {
938 dawes 1.1 family = ConvertAddr ((struct sockaddr *) from,
939 &alen, (pointer *)&addr);
940 if (family == -1)
941 {
942 xfree ((char *) from);
943 return FALSE;
944 }
945 if (family == FamilyLocal)
946 {
947 xfree ((char *) from);
948 return TRUE;
949 }
950 for (host = selfhosts; host; host = host->next)
951 {
952 if (addrEqual (family, addr, alen, host))
953 return TRUE;
954 }
955 xfree ((char *) from);
956 }
957 return FALSE;
958 }
959 dawes 1.1
960 /* Add a host to the access control list. This is the external interface
961 * called from the dispatcher */
962
963 int
964 AddHost (client, family, length, pAddr)
965 ClientPtr client;
966 int family;
967 unsigned length; /* of bytes in pAddr */
968 pointer pAddr;
969 {
970 int len;
971
972 if (!AuthorizedClient(client))
973 return(BadAccess);
974 switch (family) {
975 case FamilyLocalHost:
976 len = length;
977 LocalHostEnabled = TRUE;
978 break;
979 #ifdef K5AUTH
980 dawes 1.1 case FamilyKrb5Principal:
981 len = length;
982 break;
983 #endif
984 #ifdef SECURE_RPC
985 case FamilyNetname:
986 len = length;
987 SecureRPCInit ();
988 break;
989 #endif
990 case FamilyInternet:
991 case FamilyDECnet:
992 case FamilyChaos:
993 if ((len = CheckAddr (family, pAddr, length)) < 0)
994 {
995 client->errorValue = length;
996 return (BadValue);
997 }
998 break;
999 case FamilyLocal:
1000 default:
1001 dawes 1.1 client->errorValue = family;
1002 return (BadValue);
1003 }
1004 if (NewHost (family, pAddr, len))
1005 return Success;
1006 return BadAlloc;
1007 }
1008
1009 Bool
|
1010 dawes 3.11 #if NeedFunctionPrototypes
1011 ForEachHostInFamily (
1012 int family,
1013 Bool (*func)(
1014 #if NeedNestedPrototypes
1015 unsigned char * /* addr */,
1016 short /* len */,
1017 pointer /* closure */
1018 #endif
1019 ),
1020 pointer closure)
1021 #else
|
1022 dawes 1.1 ForEachHostInFamily (family, func, closure)
1023 int family;
1024 Bool (*func)();
1025 pointer closure;
|
1026 dawes 3.11 #endif
|
1027 dawes 1.1 {
1028 HOST *host;
1029
1030 for (host = validhosts; host; host = host->next)
1031 if (family == host->family && func (host->addr, host->len, closure))
1032 return TRUE;
1033 return FALSE;
1034 }
1035
1036 /* Add a host to the access control list. This is the internal interface
1037 * called when starting or resetting the server */
1038 static Bool
1039 NewHost (family, addr, len)
1040 int family;
1041 pointer addr;
1042 int len;
1043 {
1044 register HOST *host;
1045
1046 for (host = validhosts; host; host = host->next)
1047 {
1048 dawes 1.1 if (addrEqual (family, addr, len, host))
1049 return TRUE;
1050 }
1051 MakeHost(host,len)
1052 if (!host)
1053 return FALSE;
1054 host->family = family;
1055 host->len = len;
1056 acopy(addr, host->addr, len);
1057 host->next = validhosts;
1058 validhosts = host;
1059 return TRUE;
1060 }
1061
1062 /* Remove a host from the access control list */
1063
1064 int
1065 RemoveHost (client, family, length, pAddr)
1066 ClientPtr client;
1067 int family;
1068 unsigned length; /* of bytes in pAddr */
1069 dawes 1.1 pointer pAddr;
1070 {
1071 int len;
1072 register HOST *host, **prev;
1073
1074 if (!AuthorizedClient(client))
1075 return(BadAccess);
1076 switch (family) {
1077 case FamilyLocalHost:
1078 len = length;
1079 LocalHostEnabled = FALSE;
1080 break;
1081 #ifdef K5AUTH
1082 case FamilyKrb5Principal:
1083 len = length;
1084 break;
1085 #endif
1086 #ifdef SECURE_RPC
1087 case FamilyNetname:
1088 len = length;
1089 break;
1090 dawes 1.1 #endif
1091 case FamilyInternet:
1092 case FamilyDECnet:
1093 case FamilyChaos:
1094 if ((len = CheckAddr (family, pAddr, length)) < 0)
1095 {
1096 client->errorValue = length;
1097 return(BadValue);
1098 }
1099 break;
1100 case FamilyLocal:
1101 default:
1102 client->errorValue = family;
1103 return(BadValue);
1104 }
1105 for (prev = &validhosts;
1106 (host = *prev) && (!addrEqual (family, pAddr, len, host));
1107 prev = &host->next)
1108 ;
1109 if (host)
1110 {
1111 dawes 1.1 *prev = host->next;
1112 FreeHost (host);
1113 }
1114 return (Success);
1115 }
1116
1117 /* Get all hosts in the access control list */
1118 int
1119 GetHosts (data, pnHosts, pLen, pEnabled)
1120 pointer *data;
1121 int *pnHosts;
1122 int *pLen;
1123 BOOL *pEnabled;
1124 {
1125 int len;
1126 register int n = 0;
1127 register unsigned char *ptr;
1128 register HOST *host;
1129 int nHosts = 0;
1130
1131 *pEnabled = AccessEnabled ? EnableAccess : DisableAccess;
1132 dawes 1.1 for (host = validhosts; host; host = host->next)
1133 {
1134 nHosts++;
1135 n += (((host->len + 3) >> 2) << 2) + sizeof(xHostEntry);
1136 }
1137 if (n)
1138 {
1139 *data = ptr = (pointer) xalloc (n);
1140 if (!ptr)
1141 {
1142 return(BadAlloc);
1143 }
1144 for (host = validhosts; host; host = host->next)
1145 {
1146 len = host->len;
1147 ((xHostEntry *)ptr)->family = host->family;
1148 ((xHostEntry *)ptr)->length = len;
1149 ptr += sizeof(xHostEntry);
1150 acopy (host->addr, ptr, len);
1151 ptr += ((len + 3) >> 2) << 2;
1152 }
1153 dawes 1.1 } else {
1154 *data = NULL;
1155 }
1156 *pnHosts = nHosts;
1157 *pLen = n;
1158 return(Success);
1159 }
1160
1161 /* Check for valid address family and length, and return address length. */
1162
1163 /*ARGSUSED*/
1164 static int
1165 CheckAddr (family, pAddr, length)
1166 int family;
1167 pointer pAddr;
1168 unsigned length;
1169 {
1170 int len;
1171
1172 switch (family)
1173 {
|
1174 dawes 3.2 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(AMTCPCONN) || defined(MNX_TCPCONN)
|
1175 dawes 1.1 case FamilyInternet:
|
1176 dawes 3.2 #if !defined(AMOEBA)
|
1177 dawes 1.1 if (length == sizeof (struct in_addr))
|
1178 dawes 3.0 #else
1179 if (length == sizeof(ipaddr_t))
1180 #endif
|
1181 dawes 1.1 len = length;
1182 else
1183 len = -1;
1184 break;
1185 #endif
1186 #ifdef DNETCONN
1187 case FamilyDECnet:
1188 {
1189 struct dn_naddr *dnaddr = (struct dn_naddr *) pAddr;
1190
1191 if ((length < sizeof(dnaddr->a_len)) ||
1192 (length < dnaddr->a_len + sizeof(dnaddr->a_len)))
1193 len = -1;
1194 else
1195 len = dnaddr->a_len + sizeof(dnaddr->a_len);
1196 if (len > sizeof(struct dn_naddr))
1197 len = -1;
1198 }
1199 break;
1200 #endif
1201 default:
1202 dawes 1.1 len = -1;
1203 }
1204 return (len);
1205 }
1206
1207 /* Check if a host is not in the access control list.
1208 * Returns 1 if host is invalid, 0 if we've found it. */
1209
1210 InvalidHost (saddr, len)
|
1211 dawes 3.0 #ifndef AMOEBA_ORIG
|
1212 dawes 1.1 register struct sockaddr *saddr;
|
1213 dawes 3.0 #else
1214 register ipaddr_t *saddr;
1215 #endif
|
1216 dawes 1.1 int len;
1217 {
1218 int family;
1219 pointer addr;
1220 register HOST *selfhost, *host;
1221
1222 if (!AccessEnabled) /* just let them in */
1223 return(0);
1224 family = ConvertAddr (saddr, &len, (pointer *)&addr);
1225 if (family == -1)
1226 return 1;
1227 if (family == FamilyLocal)
1228 {
1229 if (!LocalHostEnabled)
1230 {
1231 /*
1232 * check to see if any local address is enabled. This
1233 * implicitly enables local connections.
1234 */
1235 for (selfhost = selfhosts; selfhost; selfhost=selfhost->next)
1236 {
1237 dawes 1.1 for (host = validhosts; host; host=host->next)
1238 {
1239 if (addrEqual (selfhost->family, selfhost->addr,
1240 selfhost->len, host))
1241 return 0;
1242 }
1243 }
1244 return 1;
1245 } else
1246 return 0;
1247 }
1248 for (host = validhosts; host; host = host->next)
1249 {
1250 if (addrEqual (family, addr, len, host))
1251 return (0);
1252 }
1253 return (1);
1254 }
1255
1256 static int
1257 ConvertAddr (saddr, len, addr)
|
1258 dawes 3.0 #ifndef AMOEBA_ORIG
|
1259 dawes 1.1 register struct sockaddr *saddr;
|
1260 dawes 3.0 #else
1261 register ipaddr_t *saddr;
1262 #endif
|
1263 dawes 1.1 int *len;
1264 pointer *addr;
1265 {
|
1266 dawes 3.0 #ifndef AMOEBA
|
1267 dawes 1.1 if (*len == 0)
1268 return (FamilyLocal);
1269 switch (saddr->sa_family)
1270 {
1271 case AF_UNSPEC:
|
1272 dawes 3.6 #if defined(UNIXCONN) || defined(LOCALCONN)
|
1273 dawes 1.1 case AF_UNIX:
1274 #endif
1275 return FamilyLocal;
|
1276 dawes 3.2 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
|
1277 dawes 1.1 case AF_INET:
1278 *len = sizeof (struct in_addr);
1279 *addr = (pointer) &(((struct sockaddr_in *) saddr)->sin_addr);
1280 return FamilyInternet;
1281 #endif
1282 #ifdef DNETCONN
1283 case AF_DECnet:
1284 {
1285 struct sockaddr_dn *sdn = (struct sockaddr_dn *) saddr;
1286 *len = sdn->sdn_nodeaddrl + sizeof(sdn->sdn_nodeaddrl);
1287 *addr = (pointer) &(sdn->sdn_add);
1288 }
1289 return FamilyDECnet;
1290 #endif
1291 #ifdef CHAOSCONN
1292 case AF_CHAOS:
1293 {
1294 not implemented
1295 }
1296 return FamilyChaos;
1297 #endif
1298 dawes 1.1 default:
1299 return -1;
1300 }
|
1301 dawes 3.0 #else /* AMOEBA */
1302 if (*len == 0) return -1;
1303 *len = sizeof (ipaddr_t);
1304 *addr = (pointer) saddr;
1305 return FamilyInternet;
1306 #endif /* AMOEBA */
|
1307 dawes 1.1 }
1308
1309 int
1310 ChangeAccessControl(client, fEnabled)
1311 ClientPtr client;
1312 int fEnabled;
1313 {
1314 if (!AuthorizedClient(client))
1315 return BadAccess;
1316 AccessEnabled = fEnabled;
1317 return Success;
1318 }
|