source: trunk/athena/etc/xdm/xdm/auth.c @ 6052

Revision 6052, 23.9 KB checked in by lwvanels, 33 years ago (diff)
Initial revision
Line 
1/*
2 * xdm - display manager daemon
3 *
4 * $XConsortium: auth.c,v 1.47 91/11/08 15:18:18 eswu 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(_POSIX_SOURCE) && !defined(AIXV3)) || defined(hpux) || defined(USG) || defined(SVR4)
45#define NEED_UTSNAME
46#include <sys/utsname.h>
47#endif
48
49#if defined(SYSV) && defined(SYSV386)
50# include <sys/stream.h>
51# ifdef ISC
52#  include <sys/sioctl.h>
53# endif /* ISC */
54# ifdef ESIX
55#  include <lan/net_ioctl.h>
56# endif /* ESIX */
57#endif /* SYSV386 */
58
59#ifdef SVR4
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
69extern int      MitInitAuth ();
70extern Xauth    *MitGetAuth ();
71
72#ifdef HASXDMAUTH
73extern int      XdmInitAuth ();
74extern Xauth    *XdmGetAuth ();
75#ifdef XDMCP
76extern int      XdmGetXdmcpAuth ();
77#else
78#define XdmGetXdmcpAuth NULL
79#endif
80#endif
81
82#ifdef SECURE_RPC
83extern int      SecureRPCInitAuth ();
84extern Xauth    *SecureRPCGetAuth ();
85#endif
86
87struct AuthProtocol {
88    unsigned short  name_length;
89    char            *name;
90    int             (*InitAuth)();
91    Xauth           *(*GetAuth)();
92    int             (*GetXdmcpAuth)();
93    int             inited;
94};
95
96static 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
114static struct AuthProtocol *
115findProtocol (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
130ValidAuthorization (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
139static Xauth *
140GenerateAuthorization (name_length, name)
141unsigned short  name_length;
142char            *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
180SetProtoDisplayAuthorization (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
220static
221CleanUpFileName (src, dst, len)
222char    *src, *dst;
223int     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
244static
245MakeServerAuthFile (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
278SaveServerAuthorizations (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
322SetLocalAuthorization (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
372SetAuthorization (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
383static
384openFiles (name, new_name, oldp, newp)
385char    *name, *new_name;
386FILE    **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
405static
406binaryEqual (a, b, len)
407char    *a, *b;
408unsigned short  len;
409{
410        while (len-- > 0)
411                if (*a++ != *b++)
412                        return 0;
413        return 1;
414}
415
416static
417dumpBytes (len, data)
418unsigned short  len;
419char    *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
429static
430dumpAuth (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
444struct 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
455static struct addrList  *addrs;
456
457static
458initAddrs ()
459{
460        addrs = 0;
461}
462
463static
464doneAddrs ()
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
477static checkEntry ();
478
479static
480saveEntry (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
528static
529checkEntry (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
549static int  doWrite;
550
551static
552writeAuth (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
562static
563writeAddr (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
578static
579DefineLocal (file, auth)
580    FILE        *file;
581    Xauth       *auth;
582{
583        char    displayname[100];
584
585        /* stolen from xinit.c */
586
587/* Make sure this produces the same string as _XGetHostname in lib/X/XlibInt.c.
588 * Otherwise, Xau will not be able to find your cookies in the Xauthority file.
589 *
590 * Note: POSIX says that the ``nodename'' member of utsname does _not_ have
591 *       to have sufficient information for interfacing to the network,
592 *       and so, you may be better off using gethostname (if it exists).
593 */
594
595#ifdef NEED_UTSNAME
596
597        /* hpux:
598         * Why not use gethostname()?  Well, at least on my system, I've had to
599         * make an ugly kernel patch to get a name longer than 8 characters, and
600         * uname() lets me access to the whole string (it smashes release, you
601         * see), whereas gethostname() kindly truncates it for me.
602         */
603        {
604        struct utsname name;
605
606        uname(&name);
607        strcpy(displayname, name.nodename);
608        }
609#else
610        /* AIXV3:
611         * In AIXV3, _POSIX_SOURCE is defined, but uname gives only first
612         * field of hostname. Thus, we use gethostname instead.
613         */
614
615        gethostname(displayname, sizeof(displayname));
616#endif
617        writeAddr (FamilyLocal, strlen (displayname), displayname, file, auth);
618}
619
620#ifdef STREAMSCONN
621
622#include <tiuser.h>
623
624/* Define this host for access control.  Find all the hosts the OS knows about
625 * for this fd and add them to the selfhosts list.
626 * TLI version, written without sufficient documentation.
627 */
628static
629DefineSelf (fd, file, auth)
630    int fd;
631    FILE        *file;
632    Xauth       *auth;
633{
634    struct netbuf       netb;
635    char                addrret[1024]; /* easier than t_alloc */
636   
637    netb.maxlen = sizeof(addrret);
638    netb.buf = addrret;
639    if (t_getname (fd, &netb, LOCALNAME) == -1)
640        t_error ("t_getname");
641    /* what a kludge */
642    writeAddr (FamilyInternet, 4, netb.buf+4, file, auth);
643}
644
645#else /* STREAMSCONN */
646#ifdef SIOCGIFCONF
647
648/* Define this host for access control.  Find all the hosts the OS knows about
649 * for this fd and add them to the selfhosts list.
650 */
651static
652DefineSelf (fd, file, auth)
653    int fd;
654    FILE        *file;
655    Xauth       *auth;
656{
657    char                buf[2048];
658    struct ifconf       ifc;
659    register int        n;
660    int                 len;
661    char                *addr;
662    int                 family;
663    register struct ifreq *ifr;
664   
665    ifc.ifc_len = sizeof (buf);
666    ifc.ifc_buf = buf;
667    if (ioctl (fd, SIOCGIFCONF, (char *) &ifc) < 0)
668        LogError ("Trouble getting network interface configuration");
669    for (ifr = ifc.ifc_req, n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0;
670     ifr++)
671    {
672#ifdef DNETCONN
673        /*
674         * this is ugly but SIOCGIFCONF returns decnet addresses in
675         * a different form from other decnet calls
676         */
677        if (ifr->ifr_addr.sa_family == AF_DECnet) {
678                len = sizeof (struct dn_naddr);
679                addr = (char *)ifr->ifr_addr.sa_data;
680                family = FamilyDECnet;
681        } else
682#endif
683        {
684            if (ConvertAddr (&ifr->ifr_addr, &len, &addr) < 0)
685                continue;
686            if (len == 0)
687            {
688                Debug ("Skipping zero length address\n");
689                continue;
690            }
691            /*
692             * don't write out 'localhost' entries, as
693             * they may conflict with other local entries.
694             * DefineLocal will always be called to add
695             * the local entry anyway, so this one can
696             * be tossed.
697             */
698            if (len == 4 &&
699                addr[0] == 127 && addr[1] == 0 &&
700                addr[2] == 0 && addr[3] == 1)
701            {
702                    Debug ("Skipping localhost address\n");
703                    continue;
704            }
705            family = FamilyInternet;
706        }
707        Debug ("DefineSelf: write network address, length %d\n", len);
708        writeAddr (family, len, addr, file, auth);
709    }
710}
711
712#else /* SIOCGIFCONF */
713
714/* Define this host for access control.  Find all the hosts the OS knows about
715 * for this fd and add them to the selfhosts list.
716 */
717static
718DefineSelf (fd, file, auth)
719    int fd;
720{
721    register int n;
722    int len;
723    caddr_t     addr;
724    int         family;
725
726    struct utsname name;
727    register struct hostent  *hp;
728
729    union {
730        struct  sockaddr   sa;
731        struct  sockaddr_in  in;
732    } saddr;
733       
734    struct      sockaddr_in     *inetaddr;
735
736    /* hpux:
737     * Why not use gethostname()?  Well, at least on my system, I've had to
738     * make an ugly kernel patch to get a name longer than 8 characters, and
739     * uname() lets me access to the whole string (it smashes release, you
740     * see), whereas gethostname() kindly truncates it for me.
741     */
742    uname(&name);
743    hp = gethostbyname (name.nodename);
744    if (hp != NULL) {
745        saddr.sa.sa_family = hp->h_addrtype;
746        inetaddr = (struct sockaddr_in *) (&(saddr.sa));
747        bcopy ( (char *) hp->h_addr, (char *) &(inetaddr->sin_addr), (int) hp->h_length);
748        family = ConvertAddr ( &(saddr.sa), &len, &addr);
749        if ( family >= 0) {
750            writeAddr (FamilyInternet, sizeof (inetaddr->sin_addr),
751                        (char *) (&inetaddr->sin_addr), file, auth);
752        }
753    }
754}
755
756#endif /* SIOCGIFCONF else */
757#endif /* STREAMSCONN else */
758
759static
760setAuthNumber (auth, name)
761    Xauth   *auth;
762    char    *name;
763{
764    char        *colon;
765    char        *dot, *number;
766
767    Debug ("setAuthNumber %s\n", name);
768    colon = rindex (name, ':');
769    if (colon) {
770        ++colon;
771        dot = index (colon, '.');
772        if (dot)
773            auth->number_length = dot - colon;
774        else
775            auth->number_length = strlen (colon);
776        number = malloc (auth->number_length + 1);
777        if (number) {
778            strncpy (number, colon, auth->number_length);
779            number[auth->number_length] = '\0';
780        } else {
781            LogOutOfMem ("setAuthNumber");
782            auth->number_length = 0;
783        }
784        auth->number = number;
785        Debug ("setAuthNumber: %s\n", number);
786    }
787}
788
789static
790writeLocalAuth (file, auth, name)
791    FILE        *file;
792    Xauth       *auth;
793    char        *name;
794{
795    int fd;
796
797    Debug ("writeLocalAuth: %s %.*s\n", name, auth->name_length, auth->name);
798    setAuthNumber (auth, name);
799#ifdef TCPCONN
800    fd = socket (AF_INET, SOCK_STREAM, 0);
801    DefineSelf (fd, file, auth);
802    close (fd);
803#endif
804#ifdef DNETCONN
805    fd = socket (AF_DECnet, SOCK_STREAM, 0);
806    DefineSelf (fd, file, auth);
807    close (fd);
808#endif
809    DefineLocal (file, auth);
810}
811
812#ifdef XDMCP
813
814static
815writeRemoteAuth (file, auth, peer, peerlen, name)
816    FILE            *file;
817    Xauth           *auth;
818    struct sockaddr *peer;
819    int             peerlen;
820    char            *name;
821{
822    int     family = FamilyLocal;
823    char    *addr;
824   
825    Debug ("writeRemoteAuth: %s %.*s\n", name, auth->name_length, auth->name);
826    if (!peer || peerlen < 2)
827        return;
828    setAuthNumber (auth, name);
829    family = ConvertAddr (peer, &peerlen, &addr);
830    Debug ("writeRemoteAuth: family %d\n", family);
831    if (family != FamilyLocal)
832    {
833        Debug ("writeRemoteAuth: %d, %d, %x\n",
834                family, peerlen, *(int *)addr);
835        writeAddr (family, peerlen, addr, file, auth);
836    }
837    else
838    {
839        writeLocalAuth (file, auth, name);
840    }
841}
842
843#endif /* XDMCP */
844
845SetUserAuthorization (d, verify)
846struct display          *d;
847struct verify_info      *verify;
848{
849    FILE        *old, *new;
850    char        home_name[1024], backup_name[1024], new_name[1024];
851    char        *name;
852    char        *home;
853    char        *envname = 0;
854    int lockStatus;
855    Xauth       *entry, **auths;
856    int setenv;
857    char        **setEnv (), *getEnv ();
858    struct stat statb;
859    int         i;
860    int         magicCookie;
861
862    Debug ("SetUserAuthorization\n");
863    auths = d->authorizations;
864    if (auths) {
865        home = getEnv (verify->userEnviron, "HOME");
866        lockStatus = LOCK_ERROR;
867        if (home) {
868            strcpy (home_name, home);
869            if (home[strlen(home) - 1] != '/')
870                strcat (home_name, "/");
871            strcat (home_name, ".Xauthority");
872            Debug ("XauLockAuth %s\n", home_name);
873            lockStatus = XauLockAuth (home_name, 1, 2, 10);
874            Debug ("Lock is %d\n", lockStatus);
875            if (lockStatus == LOCK_SUCCESS) {
876                if (openFiles (home_name, new_name, &old, &new)) {
877                    name = home_name;
878                    setenv = 0;
879                } else {
880                    Debug ("openFiles failed\n");
881                    XauUnlockAuth (home_name);
882                    lockStatus = LOCK_ERROR;
883                }       
884            }
885        }
886        if (lockStatus != LOCK_SUCCESS) {
887            sprintf (backup_name, "%s/.XauthXXXXXX", d->userAuthDir);
888            (void) mktemp (backup_name);
889            lockStatus = XauLockAuth (backup_name, 1, 2, 10);
890            Debug ("backup lock is %d\n", lockStatus);
891            if (lockStatus == LOCK_SUCCESS) {
892                if (openFiles (backup_name, new_name, &old, &new)) {
893                    name = backup_name;
894                    setenv = 1;
895                } else {
896                    XauUnlockAuth (backup_name);
897                    lockStatus = LOCK_ERROR;
898                }       
899            }
900        }
901        if (lockStatus != LOCK_SUCCESS) {
902            Debug ("can't lock auth file %s or backup %s\n",
903                            home_name, backup_name);
904            LogError ("can't lock authorization file %s or backup %s\n",
905                            home_name, backup_name);
906            return;
907        }
908        initAddrs ();
909        doWrite = 1;
910        Debug ("%d authorization protocols for %s\n", d->authNum, d->name);
911        /*
912         * Write MIT-MAGIC-COOKIE-1 authorization first, so that
913         * R4 clients which only knew that, and used the first
914         * matching entry will continue to function
915         */
916        magicCookie = -1;
917        for (i = 0; i < d->authNum; i++)
918        {
919            if (auths[i]->name_length == 18 &&
920                !strncmp (auths[i]->name, "MIT-MAGIC-COOKIE-1", 18))
921            {
922                magicCookie = i;
923                if (d->displayType.location == Local)
924                    writeLocalAuth (new, auths[i], d->name);
925#ifdef XDMCP
926                else
927                    writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
928#endif
929                break;
930            }
931        }
932        /* now write other authorizations */
933        for (i = 0; i < d->authNum; i++)
934        {
935            if (i != magicCookie)
936            {
937                if (d->displayType.location == Local)
938                    writeLocalAuth (new, auths[i], d->name);
939#ifdef XDMCP
940                else
941                    writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
942#endif
943            }
944        }
945        if (old) {
946            if (fstat (fileno (old), &statb) != -1)
947                chmod (new_name, (int) (statb.st_mode & 0777));
948            /*SUPPRESS 560*/
949            while (entry = XauReadAuth (old)) {
950                if (!checkEntry (entry))
951                {
952                    Debug ("Writing an entry\n");
953                    writeAuth (new, entry);
954                }
955                XauDisposeAuth (entry);
956            }
957            fclose (old);
958        }
959        doneAddrs ();
960        fclose (new);
961        if (unlink (name) == -1)
962            Debug ("unlink %s failed\n", name);
963        envname = name;
964        if (link (new_name, name) == -1) {
965            Debug ("link failed %s %s\n", new_name, name);
966            LogError ("Can't move authorization into place\n");
967            setenv = 1;
968            envname = new_name;
969        } else {
970            Debug ("new is in place, go for it!\n");
971            unlink (new_name);
972        }
973        if (setenv) {
974            verify->userEnviron = setEnv (verify->userEnviron,
975                                    "XAUTHORITY", envname);
976            verify->systemEnviron = setEnv (verify->systemEnviron,
977                                    "XAUTHORITY", envname);
978        }
979        XauUnlockAuth (name);
980        if (envname) {
981#ifdef NGROUPS_MAX
982            chown (envname, verify->uid, verify->groups[0]);
983#else
984            chown (envname, verify->uid, verify->gid);
985#endif
986        }
987    }
988    Debug ("done SetUserAuthorization\n");
989}
990
991RemoveUserAuthorization (d, verify)
992    struct display      *d;
993    struct verify_info  *verify;
994{
995    char    *home;
996    Xauth   **auths, *entry;
997    char    name[1024], new_name[1024];
998    int     lockStatus;
999    FILE    *old, *new;
1000    struct stat statb;
1001    int     i;
1002    char    *getEnv ();
1003
1004    if (!(auths = d->authorizations))
1005        return;
1006    home = getEnv (verify->userEnviron, "HOME");
1007    if (!home)
1008        return;
1009    Debug ("RemoveUserAuthorization\n");
1010    strcpy (name, home);
1011    if (home[strlen(home) - 1] != '/')
1012        strcat (name, "/");
1013    strcat (name, ".Xauthority");
1014    Debug ("XauLockAuth %s\n", name);
1015    lockStatus = XauLockAuth (name, 1, 2, 10);
1016    Debug ("Lock is %d\n", lockStatus);
1017    if (lockStatus != LOCK_SUCCESS)
1018        return;
1019    if (openFiles (name, new_name, &old, &new))
1020    {
1021        initAddrs ();
1022        doWrite = 0;
1023        for (i = 0; i < d->authNum; i++)
1024        {
1025            if (d->displayType.location == Local)
1026                writeLocalAuth (new, auths[i], d->name);
1027#ifdef XDMCP
1028            else
1029                writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
1030#endif
1031        }
1032        doWrite = 1;
1033        if (old) {
1034            if (fstat (fileno (old), &statb) != -1)
1035                chmod (new_name, (int) (statb.st_mode & 0777));
1036            /*SUPPRESS 560*/
1037            while (entry = XauReadAuth (old)) {
1038                if (!checkEntry (entry))
1039                {
1040                    Debug ("Writing an entry\n");
1041                    writeAuth (new, entry);
1042                }
1043                XauDisposeAuth (entry);
1044            }
1045            fclose (old);
1046        }
1047        doneAddrs ();
1048        fclose (new);
1049        if (unlink (name) == -1)
1050            Debug ("unlink %s failed\n", name);
1051        if (link (new_name, name) == -1) {
1052            Debug ("link failed %s %s\n", new_name, name);
1053            LogError ("Can't move authorization into place\n");
1054        } else {
1055            Debug ("new is in place, go for it!\n");
1056            unlink (new_name);
1057        }
1058    }
1059    XauUnlockAuth (name);
1060}
Note: See TracBrowser for help on using the repository browser.