Annotation of researchv9/X11/src/X.V11R1/server/os/4.2bsd/access.c, revision 1.1

1.1     ! root        1: /***********************************************************
        !             2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
        !             3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
        !             4: 
        !             5:                         All Rights Reserved
        !             6: 
        !             7: Permission to use, copy, modify, and distribute this software and its 
        !             8: documentation for any purpose and without fee is hereby granted, 
        !             9: provided that the above copyright notice appear in all copies and that
        !            10: both that copyright notice and this permission notice appear in 
        !            11: supporting documentation, and that the names of Digital or MIT not be
        !            12: used in advertising or publicity pertaining to distribution of the
        !            13: software without specific, written prior permission.  
        !            14: 
        !            15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
        !            16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
        !            17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
        !            18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
        !            19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
        !            20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
        !            21: SOFTWARE.
        !            22: 
        !            23: ******************************************************************/
        !            24: 
        !            25: /* $Header: access.c,v 1.18 87/09/03 14:24:02 toddb Exp $ */
        !            26: 
        !            27: #include "X.h"
        !            28: #include "Xproto.h"
        !            29: #include "misc.h"
        !            30: #include <errno.h>
        !            31: #include <sys/types.h>
        !            32: #include <sys/socket.h>
        !            33: #include <sys/ioctl.h>
        !            34: #include <net/if.h>
        !            35: #include <netdb.h>
        !            36: #ifdef TCPCONN
        !            37: #include <netinet/in.h>
        !            38: #endif /* TCPCONN */
        !            39: #ifdef DNETCONN
        !            40: #include <netdnet/dn.h>
        !            41: #include <netdnet/dnetdb.h>
        !            42: #endif
        !            43: #undef NULL
        !            44: #include <stdio.h>
        !            45: #include "dixstruct.h"
        !            46: #include "osdep.h"
        !            47: 
        !            48: 
        !            49: #define DONT_CHECK -1
        !            50: extern char    *index();
        !            51: 
        !            52: typedef struct _host {
        !            53:        short           family;
        !            54:        short           len;
        !            55:        unsigned char   addr[4];        /* will need to be bigger eventually */
        !            56:        struct _host *next;
        !            57: } HOST;
        !            58: 
        !            59: static HOST *selfhosts = NULL;
        !            60: static HOST *validhosts = NULL;
        !            61: static int AccessEnabled = TRUE;
        !            62: 
        !            63: typedef struct {
        !            64:     int af, xf;
        !            65: } FamilyMap;
        !            66: 
        !            67: static FamilyMap familyMap[] = {
        !            68: #ifdef     AF_DECnet
        !            69:     {AF_DECnet, FamilyDECnet},
        !            70: #endif /* AF_DECnet */
        !            71: #ifdef     AF_CHAOS
        !            72:     {AF_CHAOS, FamilyChaos},
        !            73: #endif /* AF_CHAOS */
        !            74: #ifdef    AF_INET
        !            75:     {AF_INET, FamilyInternet}
        !            76: #endif
        !            77: };
        !            78: 
        !            79: #define FAMILIES ((sizeof familyMap)/(sizeof familyMap[0]))
        !            80: 
        !            81: /* Define this host for access control.  Find all the hosts the OS knows about 
        !            82:  * for this fd and add them to the selfhosts list.
        !            83:  */
        !            84: DefineSelf (fd)
        !            85:     int fd;
        !            86: {
        !            87:     char               buf[2048];
        !            88:     struct ifconf      ifc;
        !            89:     register int       n;
        !            90:     int                len;
        !            91:     pointer            addr;
        !            92:     short              family;
        !            93:     register HOST      *host;
        !            94:     register struct ifreq *ifr;
        !            95:     
        !            96:     ifc.ifc_len = sizeof (buf);
        !            97:     ifc.ifc_buf = buf;
        !            98:     if (ioctl (fd, (int) SIOCGIFCONF, (pointer) &ifc) < 0)
        !            99:         Error ("Getting interface configuration");
        !           100:     for (ifr = ifc.ifc_req, n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0;
        !           101:      ifr++)
        !           102:     {
        !           103: #ifdef DNETCONN
        !           104:        /*
        !           105:         * this is ugly but SIOCGIFCONF returns decnet addresses in
        !           106:         * a different form from other decnet calls
        !           107:         */
        !           108:        if (ifr->ifr_addr.sa_family == AF_DECnet) {
        !           109:                len = sizeof (struct dn_naddr);
        !           110:                addr = (pointer)ifr->ifr_addr.sa_data;
        !           111:                family = AF_DECnet;
        !           112:        } else
        !           113: #endif /* DNETCONN */
        !           114:         if ((family = ConvertAddr (&ifr->ifr_addr, &len, &addr)) <= 0)
        !           115:            continue;
        !           116:         for (host = selfhosts; host && (family != host->family ||
        !           117:          bcmp (addr, host->addr, len)); host = host->next)
        !           118:            ;
        !           119:         if (host)
        !           120:            continue;
        !           121:         host = (HOST *) Xalloc (sizeof (HOST));
        !           122:         host->family = family;
        !           123:         host->len = len;
        !           124:         bcopy(addr, host->addr, len);
        !           125:         host->next = selfhosts;
        !           126:         selfhosts = host;
        !           127:     }
        !           128: }
        !           129: 
        !           130: /* Reset access control list to initial hosts */
        !           131: ResetHosts (display)
        !           132:     char *display;
        !           133: {
        !           134:     register HOST      *host, *self;
        !           135:     char               hostname[120];
        !           136:     char               fname[32];
        !           137:     FILE               *fd;
        !           138:     char               *ptr;
        !           139:     union {
        !           140:         struct sockaddr        sa;
        !           141: #ifdef TCPCONN
        !           142:         struct sockaddr_in in;
        !           143: #endif /* TCPCONN */
        !           144: #ifdef DNETCONN
        !           145:         struct sockaddr_dn dn;
        !           146: #endif
        !           147:     }                  saddr;
        !           148: #ifdef DNETCONN
        !           149:     struct nodeent     *np;
        !           150:     struct dn_naddr    dnaddr, *dnaddrp, *dnet_addr();
        !           151: #endif
        !           152:     short              family;
        !           153:     int                        len;
        !           154:     pointer            addr;
        !           155:     register struct hostent *hp;
        !           156: 
        !           157:     while (host = validhosts)
        !           158:     {
        !           159:         validhosts = host->next;
        !           160:         Xfree ((pointer) host);
        !           161:     }
        !           162:     for (self = selfhosts; self; self = self->next)
        !           163:     {
        !           164:         host = (HOST *) Xalloc (sizeof (HOST));
        !           165:         *host = *self;
        !           166:         host->next = validhosts;
        !           167:         validhosts = host;
        !           168:     }
        !           169:     strcpy (fname, "/etc/X");
        !           170:     strcat (fname, display);
        !           171:     strcat (fname, ".hosts");
        !           172:     if (fd = fopen (fname, "r")) 
        !           173:     {
        !           174:         while (fgets (hostname, sizeof (hostname), fd))
        !           175:        {
        !           176:        if (ptr = index (hostname, '\n'))
        !           177:            *ptr = 0;
        !           178: #ifdef DNETCONN
        !           179:        if ((ptr = index (hostname, ':')) && (*(ptr + 1) == ':'))
        !           180:        {
        !           181:            /* node name (DECnet names end in "::") */
        !           182:            *ptr = 0;
        !           183:            if (dnaddrp = dnet_addr(hostname))
        !           184:            {
        !           185:                    /* allow nodes to be specified by address */
        !           186:                    NewHost (AF_DECnet, (pointer) dnaddrp);
        !           187:            }
        !           188:            else
        !           189:            {
        !           190:                if (np = getnodebyname (hostname))
        !           191:                {
        !           192:                    /* node was specified by name */
        !           193:                    saddr.sa.sa_family = np->n_addrtype;
        !           194:                    if ((family = ConvertAddr (&saddr.sa, &len, &addr)) ==
        !           195:                      AF_DECnet)
        !           196:                    {
        !           197:                        bzero ((pointer) &dnaddr, sizeof (dnaddr));
        !           198:                        dnaddr.a_len = np->n_length;
        !           199:                        bcopy (np->n_addr, (pointer) dnaddr.a_addr,
        !           200:                          np->n_length);
        !           201:                        NewHost (family, (pointer) &dnaddr);
        !           202:                    }
        !           203:                }
        !           204:            }
        !           205:        }
        !           206:        else
        !           207:        {
        !           208: #endif /* DNETCONN */
        !           209: #ifdef TCPCONN
        !           210:            /* host name */
        !           211:            if (hp = gethostbyname (hostname))
        !           212:            {
        !           213:                saddr.sa.sa_family = hp->h_addrtype;
        !           214:                if ((family = ConvertAddr (&saddr.sa, &len, &addr)) > 0)
        !           215: #ifdef NEW_HEADER_WITH_OLD_LIBRARY
        !           216:                    NewHost (family, hp->h_addr_list);
        !           217: #else
        !           218:                    NewHost (family, hp->h_addr);
        !           219: #endif
        !           220: 
        !           221:            }
        !           222: #endif /* TCPCONN */
        !           223: #ifdef DNETCONN
        !           224:        }       
        !           225: #endif /* DNETCONN */
        !           226:         }
        !           227:         fclose (fd);
        !           228:     }
        !           229: }
        !           230: 
        !           231: /* Add a host to the access control list.  This is the external interface
        !           232:  * called from the dispatcher */
        !           233: 
        !           234: int
        !           235: AddHost (client, family, length, pAddr)
        !           236:     int                        client;
        !           237:     int                 family;
        !           238:     int                 length;        /* of bytes in pAddr */
        !           239:     pointer             pAddr;
        !           240: {
        !           241:     int                        len;
        !           242:     register HOST      *host;
        !           243:     int                 unixFamily;
        !           244: 
        !           245:     unixFamily = UnixFamily(family);
        !           246:     if ((len = CheckFamily (DONT_CHECK, unixFamily)) < 0)
        !           247:         return BadMatch;
        !           248: 
        !           249:     if (len != length)
        !           250:         return BadMatch;
        !           251:     for (host = validhosts; host; host = host->next)
        !           252:     {
        !           253:         if (unixFamily == host->family && !bcmp (pAddr, host->addr, len))
        !           254:            return Success;
        !           255:     }
        !           256:     host = (HOST *) Xalloc (sizeof (HOST));
        !           257:     host->family = unixFamily;
        !           258:     host->len = len;
        !           259:     bcopy(pAddr, host->addr, len);
        !           260:     host->next = validhosts;
        !           261:     validhosts = host;
        !           262:     return Success;
        !           263: }
        !           264: 
        !           265: /* Add a host to the access control list. This is the internal interface 
        !           266:  * called when starting or resetting the server */
        !           267: NewHost (family, addr)
        !           268:     short      family;
        !           269:     pointer    addr;
        !           270: {
        !           271:     int                len;
        !           272:     register HOST *host;
        !           273: 
        !           274:     if ((len = CheckFamily (DONT_CHECK, family)) < 0)
        !           275:         return;
        !           276:     for (host = validhosts; host; host = host->next)
        !           277:     {
        !           278:         if (family == host->family && !bcmp (addr, host->addr, len))
        !           279:        return;
        !           280:     }
        !           281:     host = (HOST *) Xalloc (sizeof (HOST));
        !           282:     host->family = family;
        !           283:     host->len = len;
        !           284:     bcopy(addr, host->addr, len);
        !           285:     host->next = validhosts;
        !           286:     validhosts = host;
        !           287: }
        !           288: 
        !           289: /* Remove a host from the access control list */
        !           290: 
        !           291: int
        !           292: RemoveHost (client, family, length, pAddr)
        !           293:     int                        client;
        !           294:     int                 family;
        !           295:     int                 length;        /* of bytes in pAddr */
        !           296:     pointer             pAddr;
        !           297: {
        !           298:     int                        len,
        !           299:                         unixFamily;
        !           300:     register HOST      *host, **prev;
        !           301: 
        !           302:     unixFamily = UnixFamily(family);
        !           303:     if ((len = CheckFamily (DONT_CHECK, unixFamily)) < 0)
        !           304:         return BadMatch;
        !           305:     if (len != length)
        !           306:         return BadMatch;
        !           307:     for (prev = &validhosts;
        !           308:          (host = *prev) && (unixFamily != host->family ||
        !           309:                            bcmp (pAddr, host->addr, len));
        !           310:          prev = &host->next)
        !           311:         ;
        !           312:     if (host)
        !           313:     {
        !           314:         *prev = host->next;
        !           315:         Xfree ((pointer) host);
        !           316:     }
        !           317:     return Success;
        !           318: }
        !           319: 
        !           320: /* Get all hosts in the access control list */
        !           321: int
        !           322: GetHosts (data, pnHosts, pEnabled)
        !           323:     pointer            *data;
        !           324:     int                        *pnHosts;
        !           325:     BOOL               *pEnabled;
        !           326: {
        !           327:     int                        len;
        !           328:     register int       n = 0;
        !           329:     register pointer   ptr;
        !           330:     register HOST      *host;
        !           331:     int                        nHosts = 0;
        !           332:     int                        *lengths = (int *) NULL;
        !           333: 
        !           334:     *pEnabled = AccessEnabled ? EnableAccess : DisableAccess;
        !           335:     for (host = validhosts; host; host = host->next)
        !           336:     {
        !           337:         if ((len = CheckFamily (DONT_CHECK, host->family)) < 0)
        !           338:             return (-1);
        !           339:        lengths = (int *) Xrealloc(lengths, (nHosts + 1) * sizeof(int));
        !           340:        lengths[nHosts++] = len;
        !           341:        n += (((len + 3) >> 2) << 2) + sizeof(xHostEntry);
        !           342:     }
        !           343:     if (n)
        !           344:     {
        !           345:         *data = ptr = (pointer) Xalloc (n);
        !           346:        nHosts = 0;
        !           347:         for (host = validhosts; host; host = host->next)
        !           348:        {
        !           349: 
        !           350:            len = lengths[nHosts++];
        !           351:            ((xHostEntry *)ptr)->family = XFamily(host->family);
        !           352:            ((xHostEntry *)ptr)->length = len;
        !           353:            ptr += sizeof(xHostEntry);
        !           354:            bcopy (host->addr, ptr, len);
        !           355:            ptr += ((len + 3) >> 2) << 2;
        !           356:         }
        !           357:     }
        !           358:     *pnHosts = nHosts;
        !           359:     Xfree(lengths);
        !           360:     return (n);
        !           361: }
        !           362: 
        !           363: /* Check for valid address family, and for local host if client modification.
        !           364:  * Return address length.
        !           365:  */
        !           366: 
        !           367: CheckFamily (connection, family)
        !           368:     int                        connection;
        !           369:     short              family;
        !           370: {
        !           371:     struct sockaddr    from;
        !           372:     int                        alen;
        !           373:     pointer            addr;
        !           374:     register HOST      *host;
        !           375:     int                len;
        !           376: 
        !           377:     switch (family)
        !           378:     {
        !           379: #ifdef TCPCONN
        !           380:       case AF_INET:
        !           381:         len = sizeof (struct in_addr);
        !           382:         break;
        !           383: #endif 
        !           384: #ifdef DNETCONN
        !           385:       case AF_DECnet:
        !           386:         len = sizeof (struct dn_naddr);
        !           387:         break;
        !           388: #endif
        !           389:       default:
        !           390:         /* BadValue */
        !           391:         return (-1);
        !           392:     }
        !           393:     if (connection == DONT_CHECK)
        !           394:         return (len);
        !           395:     alen = sizeof (from);
        !           396:     if (!getpeername (connection, &from, &alen))
        !           397:     {
        !           398:         if ((family = ConvertAddr (&from, &alen, &addr)) >= 0)
        !           399:        {
        !           400:            if (family == 0)
        !           401:                return (len);
        !           402:            for (host = selfhosts; host; host = host->next)
        !           403:            {
        !           404:                if (family == host->family &&
        !           405:                    !bcmp (addr, host->addr, alen))
        !           406:                    return (len);
        !           407:            }
        !           408:        }
        !           409:     }
        !           410:     /* Bad Access */
        !           411:     return (-1);
        !           412: }
        !           413: 
        !           414: /* Check if a host is not in the access control list. 
        !           415:  * Returns 1 if host is invalid, 0 if we've found it. */
        !           416: 
        !           417: InvalidHost (saddr, len)
        !           418:     register struct sockaddr   *saddr;
        !           419:     int                                len;
        !           420: {
        !           421:     short                      family;
        !           422:     pointer                    addr;
        !           423:     register HOST              *host;
        !           424:     if ((family = ConvertAddr (saddr, len ? &len : 0, &addr)) < 0)
        !           425:         return (1);
        !           426:     if (family == 0)
        !           427:         return (0);
        !           428:     if (!AccessEnabled)   /* just let them in */
        !           429:         return(0);    
        !           430:     for (host = validhosts; host; host = host->next)
        !           431:     {
        !           432:         if (family == host->family && !bcmp (addr, host->addr, len))
        !           433:            return (0);
        !           434:     }
        !           435:     return (1);
        !           436: }
        !           437: 
        !           438: ConvertAddr (saddr, len, addr)
        !           439:     register struct sockaddr   *saddr;
        !           440:     int                                *len;
        !           441:     pointer                    *addr;
        !           442: {
        !           443:     if (len == 0)
        !           444:         return (0);
        !           445:     switch (saddr->sa_family)
        !           446:     {
        !           447:       case AF_UNSPEC:
        !           448:       case AF_UNIX:
        !           449:         return (0);
        !           450:       case AF_INET:
        !           451: #ifdef TCPCONN
        !           452:         *len = sizeof (struct in_addr);
        !           453:         *addr = (pointer) &(((struct sockaddr_in *) saddr)->sin_addr);
        !           454:         return (AF_INET);
        !           455: #else TCPCONN
        !           456:         break;
        !           457: #endif TCPCONN
        !           458: 
        !           459: #ifdef DNETCONN
        !           460:       case AF_DECnet:
        !           461:         *len = sizeof (struct dn_naddr);
        !           462:         *addr = (pointer) &(((struct sockaddr_dn *) saddr)->sdn_add);
        !           463:         return (AF_DECnet);
        !           464: #else DNETCONN
        !           465:         break;
        !           466: #endif DNETCONN
        !           467: 
        !           468:       default:
        !           469:         break;
        !           470:     }
        !           471:     return (-1);
        !           472: }
        !           473: 
        !           474: ChangeAccessControl(client, fEnabled)
        !           475:     ClientPtr client;
        !           476:     int fEnabled;
        !           477: {
        !           478:     int                alen, family;
        !           479:     struct sockaddr    from;
        !           480:     pointer            addr;
        !           481:     register HOST      *host;
        !           482: 
        !           483:     alen = sizeof (from);
        !           484:     if (!getpeername (((osPrivPtr)client->osPrivate)->fd, &from, &alen))
        !           485:     {
        !           486:         if ((family = ConvertAddr (&from, &alen, &addr)) >= 0)
        !           487:        {
        !           488:            if (family == 0)
        !           489:                AccessEnabled = fEnabled;
        !           490:            for (host = selfhosts; host; host = host->next)
        !           491:            {
        !           492:                if (family == host->family &&
        !           493:                    !bcmp (addr, host->addr, alen))
        !           494:                    AccessEnabled = fEnabled;
        !           495:            }
        !           496:        }
        !           497:     }
        !           498: }
        !           499: 
        !           500: static int XFamily(af)
        !           501:     int af;
        !           502: {
        !           503:     int i;
        !           504:     for (i = 0; i < FAMILIES; i++)
        !           505:         if (familyMap[i].af == af)
        !           506:             return familyMap[i].xf;
        !           507:     return -1;
        !           508: }
        !           509: 
        !           510: static int UnixFamily(xf)
        !           511:     int xf;
        !           512: {
        !           513:     int i;
        !           514:     for (i = 0; i < FAMILIES; i++)
        !           515:         if (familyMap[i].xf == xf)
        !           516:             return familyMap[i].af;
        !           517:     return -1;
        !           518: }
        !           519: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.