home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / xdm / auth.c.orig < prev    next >
Encoding:
Text File  |  1993-07-21  |  23.3 KB  |  1,044 lines

  1. /*
  2.  * xdm - display manager daemon
  3.  *
  4.  * $XConsortium: auth.c,v 1.46 91/09/12 19:56:05 keith Exp $
  5.  *
  6.  * Copyright 1988 Massachusetts Institute of Technology
  7.  *
  8.  * Permission to use, copy, modify, and distribute this software and its
  9.  * documentation for any purpose and without fee is hereby granted, provided
  10.  * that the above copyright notice appear in all copies and that both that
  11.  * copyright notice and this permission notice appear in supporting
  12.  * documentation, and that the name of M.I.T. not be used in advertising or
  13.  * publicity pertaining to distribution of the software without specific,
  14.  * written prior permission.  M.I.T. makes no representations about the
  15.  * suitability of this software for any purpose.  It is provided "as is"
  16.  * without express or implied warranty.
  17.  *
  18.  * Author:  Keith Packard, MIT X Consortium
  19.  */
  20.  
  21. /*
  22.  * auth.c
  23.  *
  24.  * maintain the authorization generation daemon
  25.  */
  26.  
  27. #include "dm.h"
  28. #include <X11/X.h>
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #include <sys/socket.h>
  32. #ifndef ESIX
  33. # include <sys/ioctl.h>
  34. #endif /* !ESIX */
  35.  
  36. #ifdef TCPCONN
  37. # include <netinet/in.h>
  38. #endif
  39. #ifdef DNETCONN
  40. # include <netdnet/dn.h>
  41. # include <netdnet/dnetdb.h>
  42. #endif
  43.  
  44. #if defined(SYSV) && defined(SYSV386)
  45. # include <sys/utsname.h>
  46. # include <sys/stream.h>
  47. # ifdef ISC
  48. #  include <sys/sioctl.h>
  49. # endif /* ISC */
  50. # ifdef ESIX
  51. #  include <lan/net_ioctl.h>
  52. # endif /* ESIX */
  53. #endif /* SYSV386 */
  54.  
  55. #ifdef hpux
  56. # include <sys/utsname.h>
  57. #endif
  58. #ifdef SVR4
  59. # include <sys/utsname.h>
  60. # include <netdb.h>
  61. # include <sys/sockio.h>
  62. #endif
  63. #ifdef __convex__
  64. # include <sync/queue.h>
  65. # include <sync/sema.h>
  66. #endif
  67. #include <net/if.h>
  68.  
  69. extern int    MitInitAuth ();
  70. extern Xauth    *MitGetAuth ();
  71.  
  72. #ifdef HASXDMAUTH
  73. extern int    XdmInitAuth ();
  74. extern Xauth    *XdmGetAuth ();
  75. #ifdef XDMCP
  76. extern int    XdmGetXdmcpAuth ();
  77. #else
  78. #define XdmGetXdmcpAuth NULL
  79. #endif
  80. #endif
  81.  
  82. #ifdef SECURE_RPC
  83. extern int    SecureRPCInitAuth ();
  84. extern Xauth    *SecureRPCGetAuth ();
  85. #endif
  86.  
  87. struct AuthProtocol {
  88.     unsigned short  name_length;
  89.     char        *name;
  90.     int            (*InitAuth)();
  91.     Xauth        *(*GetAuth)();
  92.     int            (*GetXdmcpAuth)();
  93.     int            inited;
  94. };
  95.  
  96. static struct AuthProtocol AuthProtocols[] = {
  97. { (unsigned short) 18,    "MIT-MAGIC-COOKIE-1",
  98.     MitInitAuth, MitGetAuth, NULL
  99. },
  100. #ifdef HASXDMAUTH
  101. { (unsigned short) 19,    "XDM-AUTHORIZATION-1",
  102.     XdmInitAuth, XdmGetAuth, XdmGetXdmcpAuth,
  103. },
  104. #endif
  105. #ifdef SECURE_RPC
  106. { (unsigned short) 9, "SUN-DES-1",
  107.     SecureRPCInitAuth, SecureRPCGetAuth, NULL,
  108. },
  109. #endif
  110. };
  111.  
  112. #define NUM_AUTHORIZATION (sizeof (AuthProtocols) / sizeof (AuthProtocols[0]))
  113.  
  114. static struct AuthProtocol *
  115. findProtocol (name_length, name)
  116.     unsigned short  name_length;
  117.     char        *name;
  118. {
  119.     int    i;
  120.  
  121.     for (i = 0; i < NUM_AUTHORIZATION; i++)
  122.     if (AuthProtocols[i].name_length == name_length &&
  123.         bcmp (AuthProtocols[i].name, name, name_length) == 0)
  124.     {
  125.         return &AuthProtocols[i];
  126.     }
  127.     return (struct AuthProtocol *) 0;
  128. }
  129.  
  130. ValidAuthorization (name_length, name)
  131.     unsigned short  name_length;
  132.     char        *name;
  133. {
  134.     if (findProtocol (name_length, name))
  135.     return TRUE;
  136.     return FALSE;
  137. }
  138.  
  139. static Xauth *
  140. GenerateAuthorization (name_length, name)
  141. unsigned short    name_length;
  142. char        *name;
  143. {
  144.     struct AuthProtocol    *a;
  145.     Xauth   *auth = 0;
  146.     int        i;
  147.  
  148.     Debug ("GenerateAuthorization %*.*s\n",
  149.         name_length, name_length, name);
  150.     a = findProtocol (name_length, name);
  151.     if (a)
  152.     {
  153.     if (!a->inited)
  154.     {
  155.         (*a->InitAuth) (name_length, name);
  156.         a->inited = TRUE;
  157.     }
  158.     auth = (*a->GetAuth) (name_length, name);
  159.     if (auth)
  160.     {
  161.         Debug ("Got 0x%x (%d %*.*s) ", auth,
  162.         auth->name_length, auth->name_length,
  163.          auth->name_length, auth->name);
  164.         for (i = 0; i < (int)auth->data_length; i++)
  165.         Debug (" %02x", auth->data[i] & 0xff);
  166.         Debug ("\n");
  167.     }
  168.     else
  169.         Debug ("Got (null)\n");
  170.     }
  171.     else
  172.     {
  173.     Debug ("Unknown authorization %*.*s\n", name_length, name_length, name);
  174.     }
  175.     return auth;
  176. }
  177.  
  178. #ifdef XDMCP
  179.  
  180. SetProtoDisplayAuthorization (pdpy,
  181.     authorizationNameLen, authorizationName)
  182.     struct protoDisplay    *pdpy;
  183.     unsigned short    authorizationNameLen;
  184.     char        *authorizationName;
  185. {
  186.     struct AuthProtocol    *a;
  187.     Xauth   *auth;
  188.  
  189.     a = findProtocol (authorizationNameLen, authorizationName);
  190.     pdpy->xdmcpAuthorization = pdpy->fileAuthorization = 0;
  191.     if (a)
  192.     {
  193.     if (!a->inited)
  194.     {
  195.         (*a->InitAuth) (authorizationNameLen, authorizationName);
  196.         a->inited = TRUE;
  197.     }
  198.     if (a->GetXdmcpAuth)
  199.     {
  200.         (*a->GetXdmcpAuth) (pdpy, authorizationNameLen, authorizationName);
  201.         auth = pdpy->xdmcpAuthorization;
  202.     }
  203.     else
  204.     {
  205.         auth = (*a->GetAuth) (authorizationNameLen, authorizationName);
  206.         pdpy->fileAuthorization = auth;
  207.         pdpy->xdmcpAuthorization = 0;
  208.     }
  209.     if (auth)
  210.         Debug ("Got 0x%x (%d %*.*s)\n", auth,
  211.         auth->name_length, auth->name_length,
  212.          auth->name_length, auth->name);
  213.     else
  214.         Debug ("Got (null)\n");
  215.     }
  216. }
  217.  
  218. #endif /* XDMCP */
  219.  
  220. static
  221. CleanUpFileName (src, dst, len)
  222. char    *src, *dst;
  223. int    len;
  224. {
  225.     while (*src) {
  226.     if (--len <= 0)
  227.         break;
  228.     switch (*src & 0x7f)
  229.     {
  230.     case '/':
  231.         *dst++ = '_';
  232.         break;
  233.     case '-':
  234.         *dst++ = '.';
  235.         break;
  236.     default:
  237.         *dst++ = (*src & 0x7f);
  238.     }
  239.     ++src;
  240.     }
  241.     *dst = '\0';
  242. }
  243.  
  244. static
  245. MakeServerAuthFile (d)
  246.     struct display  *d;
  247. {
  248.     int len;
  249. #ifdef SYSV
  250. #define NAMELEN    14
  251. #else
  252. #define NAMELEN    255
  253. #endif
  254.     char    cleanname[NAMELEN];
  255.  
  256.     if (d->clientAuthFile && *d->clientAuthFile)
  257.     len = strlen (d->clientAuthFile) + 1;
  258.     else
  259.     {
  260.         CleanUpFileName (d->name, cleanname, NAMELEN - 8);
  261.         len = strlen (authDir) + strlen (cleanname) + 12;
  262.     }
  263.     if (d->authFile)
  264.     free (d->authFile);
  265.     d->authFile = malloc ((unsigned) len);
  266.     if (!d->authFile)
  267.     return FALSE;
  268.     if (d->clientAuthFile && *d->clientAuthFile)
  269.     strcpy (d->authFile, d->clientAuthFile);
  270.     else
  271.     {
  272.         sprintf (d->authFile, "%s/A%s-XXXXXX", authDir, cleanname);
  273.         (void) mktemp (d->authFile);
  274.     }
  275.     return TRUE;
  276. }
  277.  
  278. SaveServerAuthorizations (d, auths, count)
  279.     struct display  *d;
  280.     Xauth        **auths;
  281.     int            count;
  282. {
  283.     FILE    *auth_file;
  284.     int        mask;
  285.     int        ret;
  286.     int        i;
  287.  
  288.     mask = umask (0077);
  289.     if (!d->authFile && !MakeServerAuthFile (d))
  290.     return FALSE;
  291.     (void) unlink (d->authFile);
  292.     auth_file = fopen (d->authFile, "w");
  293.     umask (mask);
  294.     if (!auth_file) {
  295.     Debug ("Can't creat auth file %s\n", d->authFile);
  296.     LogError ("Cannot open server authorization file %s\n", d->authFile);
  297.     free (d->authFile);
  298.     d->authFile = NULL;
  299.     ret = FALSE;
  300.     }
  301.     else
  302.     {
  303.         Debug ("File: %s auth: %x\n", d->authFile, auths);
  304.     ret = TRUE;
  305.     for (i = 0; i < count; i++)
  306.     {
  307.         if (!XauWriteAuth (auth_file, auths[i]) ||
  308.         fflush (auth_file) == EOF)
  309.         {
  310.         LogError ("Cannot write server authorization file %s\n",
  311.               d->authFile);
  312.         ret = FALSE;
  313.         free (d->authFile);
  314.         d->authFile = NULL;
  315.         }
  316.         }
  317.     fclose (auth_file);
  318.     }
  319.     return ret;
  320. }
  321.  
  322. SetLocalAuthorization (d)
  323.     struct display    *d;
  324. {
  325.     Xauth    *auth, **auths;
  326.     int        i, j;
  327.  
  328.     if (d->authorizations)
  329.     {
  330.     for (i = 0; i < d->authNum; i++)
  331.         XauDisposeAuth (d->authorizations[i]);
  332.     free ((char *) d->authorizations);
  333.     d->authorizations = (Xauth **) NULL;
  334.     d->authNum = 0;
  335.     }
  336.     if (!d->authNames)
  337.     return;
  338.     for (i = 0; d->authNames[i]; i++)
  339.     ;
  340.     d->authNameNum = i;
  341.     if (d->authNameLens)
  342.     free ((char *) d->authNameLens);
  343.     d->authNameLens = (unsigned short *) malloc
  344.                 (d->authNameNum * sizeof (unsigned short));
  345.     if (!d->authNameLens)
  346.     return;
  347.     for (i = 0; i < d->authNameNum; i++)
  348.     d->authNameLens[i] = strlen (d->authNames[i]);
  349.     auths = (Xauth **) malloc (d->authNameNum * sizeof (Xauth *));
  350.     if (!auths)
  351.     return;
  352.     j = 0;
  353.     for (i = 0; i < d->authNameNum; i++)
  354.     {
  355.     auth = GenerateAuthorization (d->authNameLens[i], d->authNames[i]);
  356.     if (auth)
  357.         auths[j++] = auth;
  358.     }
  359.     if (SaveServerAuthorizations (d, auths, j))
  360.     {
  361.     d->authorizations = auths;
  362.     d->authNum = j;
  363.     }
  364.     else
  365.     {
  366.     for (i = 0; i < j; i++)
  367.         XauDisposeAuth (auths[i]);
  368.     free ((char *) auths);
  369.     }
  370. }
  371.  
  372. SetAuthorization (d)
  373.     struct display  *d;
  374. {
  375.     Xauth   **auth;
  376.  
  377.     auth = d->authorizations;
  378.     if (auth && *auth)
  379.     XSetAuthorization ((*auth)->name, (int) (*auth)->name_length,
  380.                (*auth)->data, (int) (*auth)->data_length);
  381. }
  382.  
  383. static
  384. openFiles (name, new_name, oldp, newp)
  385. char    *name, *new_name;
  386. FILE    **oldp, **newp;
  387. {
  388.     int    mask;
  389.  
  390.     strcpy (new_name, name);
  391.     strcat (new_name, "-n");
  392.     mask = umask (0077);
  393.     (void) unlink (new_name);
  394.     *newp = fopen (new_name, "w");
  395.     (void) umask (mask);
  396.     if (!*newp) {
  397.         Debug ("can't open new file %s\n", new_name);
  398.         return 0;
  399.     }
  400.     *oldp = fopen (name, "r");
  401.     Debug ("opens succeeded %s %s\n", name, new_name);
  402.     return 1;
  403. }
  404.  
  405. static
  406. binaryEqual (a, b, len)
  407. char    *a, *b;
  408. unsigned short    len;
  409. {
  410.     while (len-- > 0)
  411.         if (*a++ != *b++)
  412.             return 0;
  413.     return 1;
  414. }
  415.  
  416. static
  417. dumpBytes (len, data)
  418. unsigned short    len;
  419. char    *data;
  420. {
  421.     unsigned short    i;
  422.  
  423.     Debug ("%d: ", len);
  424.     for (i = 0; i < len; i++)
  425.         Debug ("%02x ", data[i] & 0377);
  426.     Debug ("\n");
  427. }
  428.  
  429. static
  430. dumpAuth (auth)
  431.     Xauth    *auth;
  432. {
  433.     Debug ("family: %d\n", auth->family);
  434.     Debug ("addr:   ");
  435.     dumpBytes (auth->address_length, auth->address);
  436.     Debug ("number: ");
  437.     dumpBytes (auth->number_length, auth->number);
  438.     Debug ("name:   ");
  439.     dumpBytes (auth->name_length, auth->name);
  440.     Debug ("data:   ");
  441.     dumpBytes (auth->data_length, auth->data);
  442. }
  443.  
  444. struct addrList {
  445.     unsigned short    family;
  446.     unsigned short    address_length;
  447.     char    *address;
  448.     unsigned short    number_length;
  449.     char    *number;
  450.     unsigned short    name_length;
  451.     char    *name;
  452.     struct addrList    *next;
  453. };
  454.  
  455. static struct addrList    *addrs;
  456.  
  457. static
  458. initAddrs ()
  459. {
  460.     addrs = 0;
  461. }
  462.  
  463. static
  464. doneAddrs ()
  465. {
  466.     struct addrList    *a, *n;
  467.     for (a = addrs; a; a = n) {
  468.         n = a->next;
  469.         if (a->address)
  470.             free (a->address);
  471.         if (a->number)
  472.             free (a->number);
  473.         free ((char *) a);
  474.     }
  475. }
  476.  
  477. static checkEntry ();
  478.  
  479. static
  480. saveEntry (auth)
  481.     Xauth    *auth;
  482. {
  483.     struct addrList    *new;
  484.  
  485.     new = (struct addrList *) malloc (sizeof (struct addrList));
  486.     if (!new) {
  487.         LogOutOfMem ("saveEntry");
  488.         return;
  489.     }
  490.     if ((new->address_length = auth->address_length) > 0) {
  491.         new->address = malloc (auth->address_length);
  492.         if (!new->address) {
  493.             LogOutOfMem ("saveEntry");
  494.             free ((char *) new);
  495.             return;
  496.         }
  497.         bcopy (auth->address, new->address, (int) auth->address_length);
  498.     } else
  499.         new->address = 0;
  500.     if ((new->number_length = auth->number_length) > 0) {
  501.         new->number = malloc (auth->number_length);
  502.         if (!new->number) {
  503.             LogOutOfMem ("saveEntry");
  504.             free (new->address);
  505.             free ((char *) new);
  506.             return;
  507.         }
  508.         bcopy (auth->number, new->number, (int) auth->number_length);
  509.     } else
  510.         new->number = 0;
  511.     if ((new->name_length = auth->name_length) > 0) {
  512.         new->name = malloc (auth->name_length);
  513.         if (!new->name) {
  514.             LogOutOfMem ("saveEntry");
  515.             free (new->number);
  516.             free (new->address);
  517.             free ((char *) new);
  518.             return;
  519.         }
  520.         bcopy (auth->name, new->name, (int) auth->name_length);
  521.     } else
  522.         new->name = 0;
  523.     new->family = auth->family;
  524.     new->next = addrs;
  525.     addrs = new;
  526. }
  527.  
  528. static
  529. checkEntry (auth)
  530.     Xauth    *auth;
  531. {
  532.     struct addrList    *a;
  533.  
  534.     for (a = addrs; a; a = a->next) {
  535.         if (a->family == auth->family &&
  536.             a->address_length == auth->address_length &&
  537.              binaryEqual (a->address, auth->address, auth->address_length) &&
  538.             a->number_length == auth->number_length &&
  539.              binaryEqual (a->number, auth->number, auth->number_length) &&
  540.             a->name_length == auth->name_length &&
  541.             binaryEqual (a->name, auth->name, auth->name_length))
  542.         {
  543.             return 1;
  544.         }
  545.     }
  546.     return 0;
  547. }
  548.  
  549. static int  doWrite;
  550.  
  551. static
  552. writeAuth (file, auth)
  553.     FILE    *file;
  554.     Xauth    *auth;
  555. {
  556.         Debug ("writeAuth: doWrite = %d\n", doWrite);
  557.     dumpAuth (auth);    /* does Debug only */
  558.     if (doWrite)
  559.         XauWriteAuth (file, auth);
  560. }
  561.  
  562. static
  563. writeAddr (family, addr_length, addr, file, auth)
  564.     int        family;
  565.     int        addr_length;
  566.     char    *addr;
  567.     FILE    *file;
  568.     Xauth    *auth;
  569. {
  570.     auth->family = (unsigned short) family;
  571.     auth->address_length = addr_length;
  572.     auth->address = addr;
  573.     Debug ("writeAddr: writing and saving an entry\n");
  574.     writeAuth (file, auth);
  575.     saveEntry (auth);
  576. }
  577.  
  578. static
  579. DefineLocal (file, auth)
  580.     FILE    *file;
  581.     Xauth    *auth;
  582. {
  583.     char    displayname[100];
  584.  
  585.     /* stolen from xinit.c */
  586. #ifdef hpux
  587.     /* Why not use gethostname()?  Well, at least on my system, I've had to
  588.      * make an ugly kernel patch to get a name longer than 8 characters, and
  589.      * uname() lets me access to the whole string (it smashes release, you
  590.      * see), whereas gethostname() kindly truncates it for me.
  591.      */
  592.     {
  593.     struct utsname name;
  594.  
  595.     uname(&name);
  596.     strcpy(displayname, name.nodename);
  597.     }
  598. #else
  599.     gethostname(displayname, sizeof(displayname));
  600. #endif
  601.     writeAddr (FamilyLocal, strlen (displayname), displayname, file, auth);
  602. }
  603.  
  604. #ifdef STREAMSCONN
  605.  
  606. #include <tiuser.h>
  607.  
  608. /* Define this host for access control.  Find all the hosts the OS knows about 
  609.  * for this fd and add them to the selfhosts list.
  610.  * TLI version, written without sufficient documentation.
  611.  */
  612. static
  613. DefineSelf (fd, file, auth)
  614.     int fd;
  615.     FILE    *file;
  616.     Xauth    *auth;
  617. {
  618.     struct netbuf    netb;
  619.     char        addrret[1024]; /* easier than t_alloc */
  620.     
  621.     netb.maxlen = sizeof(addrret);
  622.     netb.buf = addrret;
  623.     if (t_getname (fd, &netb, LOCALNAME) == -1)
  624.     t_error ("t_getname");
  625.     /* what a kludge */
  626.     writeAddr (FamilyInternet, 4, netb.buf+4, file, auth);
  627. }
  628.  
  629. #else /* STREAMSCONN */
  630. #ifdef SIOCGIFCONF
  631.  
  632. /* Define this host for access control.  Find all the hosts the OS knows about 
  633.  * for this fd and add them to the selfhosts list.
  634.  */
  635. static
  636. DefineSelf (fd, file, auth)
  637.     int fd;
  638.     FILE    *file;
  639.     Xauth    *auth;
  640. {
  641.     char        buf[2048];
  642.     struct ifconf    ifc;
  643.     register int    n;
  644.     int         len;
  645.     char         *addr;
  646.     int         family;
  647.     register struct ifreq *ifr;
  648.     
  649.     ifc.ifc_len = sizeof (buf);
  650.     ifc.ifc_buf = buf;
  651.     if (ioctl (fd, SIOCGIFCONF, (char *) &ifc) < 0)
  652.         LogError ("Trouble getting network interface configuration");
  653.     for (ifr = ifc.ifc_req, n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0;
  654.      ifr++)
  655.     {
  656. #ifdef DNETCONN
  657.     /*
  658.      * this is ugly but SIOCGIFCONF returns decnet addresses in
  659.      * a different form from other decnet calls
  660.      */
  661.     if (ifr->ifr_addr.sa_family == AF_DECnet) {
  662.         len = sizeof (struct dn_naddr);
  663.         addr = (char *)ifr->ifr_addr.sa_data;
  664.         family = FamilyDECnet;
  665.     } else
  666. #endif
  667.     {
  668.         if (ConvertAddr (&ifr->ifr_addr, &len, &addr) < 0)
  669.         continue;
  670.         if (len == 0)
  671.          {
  672.         Debug ("Skipping zero length address\n");
  673.         continue;
  674.         }
  675.         /*
  676.          * don't write out 'localhost' entries, as
  677.          * they may conflict with other local entries.
  678.          * DefineLocal will always be called to add
  679.          * the local entry anyway, so this one can
  680.          * be tossed.
  681.          */
  682.         if (len == 4 &&
  683.         addr[0] == 127 && addr[1] == 0 &&
  684.         addr[2] == 0 && addr[3] == 1)
  685.         {
  686.             Debug ("Skipping localhost address\n");
  687.             continue;
  688.         }
  689.         family = FamilyInternet;
  690.     }
  691.     Debug ("DefineSelf: write network address, length %d\n", len);
  692.     writeAddr (family, len, addr, file, auth);
  693.     }
  694. }
  695.  
  696. #else /* SIOCGIFCONF */
  697.  
  698. /* Define this host for access control.  Find all the hosts the OS knows about 
  699.  * for this fd and add them to the selfhosts list.
  700.  */
  701. static
  702. DefineSelf (fd, file, auth)
  703.     int fd;
  704. {
  705.     register int n;
  706.     int    len;
  707.     caddr_t    addr;
  708.     int        family;
  709.  
  710.     struct utsname name;
  711.     register struct hostent  *hp;
  712.  
  713.     union {
  714.     struct  sockaddr   sa;
  715.     struct  sockaddr_in  in;
  716.     } saddr;
  717.     
  718.     struct    sockaddr_in    *inetaddr;
  719.  
  720.     /* Why not use gethostname()?  Well, at least on my system, I've had to
  721.      * make an ugly kernel patch to get a name longer than 8 characters, and
  722.      * uname() lets me access to the whole string (it smashes release, you
  723.      * see), whereas gethostname() kindly truncates it for me.
  724.      */
  725.     uname(&name);
  726.     hp = gethostbyname (name.nodename);
  727.     if (hp != NULL) {
  728.     saddr.sa.sa_family = hp->h_addrtype;
  729.     inetaddr = (struct sockaddr_in *) (&(saddr.sa));
  730.     bcopy ( (char *) hp->h_addr, (char *) &(inetaddr->sin_addr), (int) hp->h_length);
  731.     family = ConvertAddr ( &(saddr.sa), &len, &addr);
  732.     if ( family >= 0) {
  733.         writeAddr (FamilyInternet, sizeof (inetaddr->sin_addr),
  734.             (char *) (&inetaddr->sin_addr), file, auth);
  735.     }
  736.     }
  737. }
  738.  
  739. #endif /* SIOCGIFCONF else */
  740. #endif /* STREAMSCONN else */
  741.  
  742. static
  743. setAuthNumber (auth, name)
  744.     Xauth   *auth;
  745.     char    *name;
  746. {
  747.     char    *colon;
  748.     char    *dot, *number;
  749.  
  750.     Debug ("setAuthNumber %s\n", name);
  751.     colon = rindex (name, ':');
  752.     if (colon) {
  753.     ++colon;
  754.     dot = index (colon, '.');
  755.     if (dot)
  756.         auth->number_length = dot - colon;
  757.     else
  758.         auth->number_length = strlen (colon);
  759.     number = malloc (auth->number_length + 1);
  760.     if (number) {
  761.         strncpy (number, colon, auth->number_length);
  762.         number[auth->number_length] = '\0';
  763.     } else {
  764.         LogOutOfMem ("setAuthNumber");
  765.         auth->number_length = 0;
  766.     }
  767.     auth->number = number;
  768.     Debug ("setAuthNumber: %s\n", number);
  769.     }
  770. }
  771.  
  772. static
  773. writeLocalAuth (file, auth, name)
  774.     FILE    *file;
  775.     Xauth    *auth;
  776.     char    *name;
  777. {
  778.     int    fd;
  779.  
  780.     Debug ("writeLocalAuth: %s %.*s\n", name, auth->name_length, auth->name);
  781.     setAuthNumber (auth, name);
  782. #ifdef TCPCONN
  783.     fd = socket (AF_INET, SOCK_STREAM, 0);
  784.     DefineSelf (fd, file, auth);
  785.     close (fd);
  786. #endif
  787. #ifdef DNETCONN
  788.     fd = socket (AF_DECnet, SOCK_STREAM, 0);
  789.     DefineSelf (fd, file, auth);
  790.     close (fd);
  791. #endif
  792.     DefineLocal (file, auth);
  793. }
  794.  
  795. #ifdef XDMCP
  796.  
  797. static
  798. writeRemoteAuth (file, auth, peer, peerlen, name)
  799.     FILE        *file;
  800.     Xauth        *auth;
  801.     struct sockaddr *peer;
  802.     int            peerlen;
  803.     char        *name;
  804. {
  805.     int        family = FamilyLocal;
  806.     char    *addr;
  807.     
  808.     Debug ("writeRemoteAuth: %s %.*s\n", name, auth->name_length, auth->name);
  809.     if (!peer || peerlen < 2)
  810.     return;
  811.     setAuthNumber (auth, name);
  812.     family = ConvertAddr (peer, &peerlen, &addr);
  813.     Debug ("writeRemoteAuth: family %d\n", family);
  814.     if (family != FamilyLocal)
  815.     {
  816.     Debug ("writeRemoteAuth: %d, %d, %x\n",
  817.         family, peerlen, *(int *)addr);
  818.     writeAddr (family, peerlen, addr, file, auth);
  819.     }
  820.     else
  821.     {
  822.     writeLocalAuth (file, auth, name);
  823.     }
  824. }
  825.  
  826. #endif /* XDMCP */
  827.  
  828. SetUserAuthorization (d, verify)
  829. struct display        *d;
  830. struct verify_info    *verify;
  831. {
  832.     FILE    *old, *new;
  833.     char    home_name[1024], backup_name[1024], new_name[1024];
  834.     char    *name;
  835.     char    *home;
  836.     char    *envname = 0;
  837.     int    lockStatus;
  838.     Xauth    *entry, **auths;
  839.     int    setenv;
  840.     char    **setEnv (), *getEnv ();
  841.     struct stat    statb;
  842.     int        i;
  843.     int        magicCookie;
  844.  
  845.     Debug ("SetUserAuthorization\n");
  846.     auths = d->authorizations;
  847.     if (auths) {
  848.     home = getEnv (verify->userEnviron, "HOME");
  849.     lockStatus = LOCK_ERROR;
  850.     if (home) {
  851.         strcpy (home_name, home);
  852.         if (home[strlen(home) - 1] != '/')
  853.         strcat (home_name, "/");
  854.         strcat (home_name, ".Xauthority");
  855.         Debug ("XauLockAuth %s\n", home_name);
  856.         lockStatus = XauLockAuth (home_name, 1, 2, 10);
  857.         Debug ("Lock is %d\n", lockStatus);
  858.         if (lockStatus == LOCK_SUCCESS) {
  859.         if (openFiles (home_name, new_name, &old, &new)) {
  860.             name = home_name;
  861.             setenv = 0;
  862.         } else {
  863.             Debug ("openFiles failed\n");
  864.             XauUnlockAuth (home_name);
  865.             lockStatus = LOCK_ERROR;
  866.         }    
  867.         }
  868.     }
  869.     if (lockStatus != LOCK_SUCCESS) {
  870.         sprintf (backup_name, "%s/.XauthXXXXXX", d->userAuthDir);
  871.         (void) mktemp (backup_name);
  872.         lockStatus = XauLockAuth (backup_name, 1, 2, 10);
  873.         Debug ("backup lock is %d\n", lockStatus);
  874.         if (lockStatus == LOCK_SUCCESS) {
  875.         if (openFiles (backup_name, new_name, &old, &new)) {
  876.             name = backup_name;
  877.             setenv = 1;
  878.         } else {
  879.             XauUnlockAuth (backup_name);
  880.             lockStatus = LOCK_ERROR;
  881.         }    
  882.         }
  883.     }
  884.     if (lockStatus != LOCK_SUCCESS) {
  885.         Debug ("can't lock auth file %s or backup %s\n",
  886.                 home_name, backup_name);
  887.         LogError ("can't lock authorization file %s or backup %s\n",
  888.                 home_name, backup_name);
  889.         return;
  890.     }
  891.     initAddrs ();
  892.     doWrite = 1;
  893.     Debug ("%d authorization protocols for %s\n", d->authNum, d->name);
  894.     /*
  895.      * Write MIT-MAGIC-COOKIE-1 authorization first, so that
  896.      * R4 clients which only knew that, and used the first
  897.      * matching entry will continue to function
  898.      */
  899.     magicCookie = -1;
  900.     for (i = 0; i < d->authNum; i++)
  901.     {
  902.         if (auths[i]->name_length == 18 &&
  903.         !strncmp (auths[i]->name, "MIT-MAGIC-COOKIE-1", 18))
  904.         {
  905.         magicCookie = i;
  906.             if (d->displayType.location == Local)
  907.                 writeLocalAuth (new, auths[i], d->name);
  908. #ifdef XDMCP
  909.             else
  910.                 writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
  911. #endif
  912.         break;
  913.         }
  914.     }
  915.     /* now write other authorizations */
  916.     for (i = 0; i < d->authNum; i++)
  917.     {
  918.         if (i != magicCookie)
  919.         {
  920.             if (d->displayType.location == Local)
  921.                 writeLocalAuth (new, auths[i], d->name);
  922. #ifdef XDMCP
  923.             else
  924.                 writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
  925. #endif
  926.         }
  927.     }
  928.     if (old) {
  929.         if (fstat (fileno (old), &statb) != -1)
  930.         chmod (new_name, (int) (statb.st_mode & 0777));
  931.         /*SUPPRESS 560*/
  932.         while (entry = XauReadAuth (old)) {
  933.         if (!checkEntry (entry))
  934.         {
  935.             Debug ("Writing an entry\n");
  936.             writeAuth (new, entry);
  937.         }
  938.         XauDisposeAuth (entry);
  939.         }
  940.         fclose (old);
  941.     }
  942.     doneAddrs ();
  943.     fclose (new);
  944.     if (unlink (name) == -1)
  945.         Debug ("unlink %s failed\n", name);
  946.     envname = name;
  947.     if (link (new_name, name) == -1) {
  948.         Debug ("link failed %s %s\n", new_name, name);
  949.         LogError ("Can't move authorization into place\n");
  950.         setenv = 1;
  951.         envname = new_name;
  952.     } else {
  953.         Debug ("new is in place, go for it!\n");
  954.         unlink (new_name);
  955.     }
  956.     if (setenv) {
  957.         verify->userEnviron = setEnv (verify->userEnviron,
  958.                     "XAUTHORITY", envname);
  959.         verify->systemEnviron = setEnv (verify->systemEnviron,
  960.                     "XAUTHORITY", envname);
  961.     }
  962.     XauUnlockAuth (name);
  963.     if (envname) {
  964. #ifdef NGROUPS_MAX
  965.         chown (envname, verify->uid, verify->groups[0]);
  966. #else
  967.         chown (envname, verify->uid, verify->gid);
  968. #endif
  969.     }
  970.     }
  971.     Debug ("done SetUserAuthorization\n");
  972. }
  973.  
  974. RemoveUserAuthorization (d, verify)
  975.     struct display    *d;
  976.     struct verify_info    *verify;
  977. {
  978.     char    *home;
  979.     Xauth   **auths, *entry;
  980.     char    name[1024], new_name[1024];
  981.     int        lockStatus;
  982.     FILE    *old, *new;
  983.     struct stat    statb;
  984.     int        i;
  985.     char    *getEnv ();
  986.  
  987.     if (!(auths = d->authorizations))
  988.     return;
  989.     home = getEnv (verify->userEnviron, "HOME");
  990.     if (!home)
  991.     return;
  992.     Debug ("RemoveUserAuthorization\n");
  993.     strcpy (name, home);
  994.     if (home[strlen(home) - 1] != '/')
  995.     strcat (name, "/");
  996.     strcat (name, ".Xauthority");
  997.     Debug ("XauLockAuth %s\n", name);
  998.     lockStatus = XauLockAuth (name, 1, 2, 10);
  999.     Debug ("Lock is %d\n", lockStatus);
  1000.     if (lockStatus != LOCK_SUCCESS)
  1001.     return;
  1002.     if (openFiles (name, new_name, &old, &new))
  1003.     {
  1004.     initAddrs ();
  1005.     doWrite = 0;
  1006.     for (i = 0; i < d->authNum; i++)
  1007.     {
  1008.         if (d->displayType.location == Local)
  1009.             writeLocalAuth (new, auths[i], d->name);
  1010. #ifdef XDMCP
  1011.         else
  1012.             writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
  1013. #endif
  1014.     }
  1015.     doWrite = 1;
  1016.     if (old) {
  1017.         if (fstat (fileno (old), &statb) != -1)
  1018.         chmod (new_name, (int) (statb.st_mode & 0777));
  1019.         /*SUPPRESS 560*/
  1020.         while (entry = XauReadAuth (old)) {
  1021.         if (!checkEntry (entry))
  1022.         {
  1023.             Debug ("Writing an entry\n");
  1024.             writeAuth (new, entry);
  1025.         }
  1026.         XauDisposeAuth (entry);
  1027.         }
  1028.         fclose (old);
  1029.     }
  1030.     doneAddrs ();
  1031.     fclose (new);
  1032.     if (unlink (name) == -1)
  1033.         Debug ("unlink %s failed\n", name);
  1034.     if (link (new_name, name) == -1) {
  1035.         Debug ("link failed %s %s\n", new_name, name);
  1036.         LogError ("Can't move authorization into place\n");
  1037.     } else {
  1038.         Debug ("new is in place, go for it!\n");
  1039.         unlink (new_name);
  1040.     }
  1041.     }
  1042.     XauUnlockAuth (name);
  1043. }
  1044.