1 /* $TOG: auth.c /main/6 1997/03/14 13:44:25 barstow $ */
2 /* (c) Copyright 1997 The Open Group */
4 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
5 * (c) Copyright 1993, 1994 International Business Machines Corp. *
6 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
7 * (c) Copyright 1993, 1994 Novell, Inc. *
16 * Revision 1.1.2.3 1995/06/06 20:21:58 Chris_Beute
17 * Code snapshot merge from March 15 and SIA changes
18 * [1995/05/31 20:09:58 Chris_Beute]
20 * Revision 1.1.2.2 1995/04/21 13:05:15 Peter_Derr
21 * dtlogin auth key fixes from deltacde
22 * [1995/04/12 19:20:51 Peter_Derr]
24 * R6 version of auth.c to handle multiple authentication protocols.
25 * [1995/04/12 18:05:30 Peter_Derr]
32 Copyright (c) 1988 X Consortium
34 Permission is hereby granted, free of charge, to any person obtaining
35 a copy of this software and associated documentation files (the
36 "Software"), to deal in the Software without restriction, including
37 without limitation the rights to use, copy, modify, merge, publish,
38 distribute, sublicense, and/or sell copies of the Software, and to
39 permit persons to whom the Software is furnished to do so, subject to
40 the following conditions:
42 The above copyright notice and this permission notice shall be included
43 in all copies or substantial portions of the Software.
45 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
46 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
47 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
48 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
49 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
50 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
51 OTHER DEALINGS IN THE SOFTWARE.
53 Except as contained in this notice, the name of the X Consortium shall
54 not be used in advertising or otherwise to promote the sale, use or
55 other dealings in this Software without prior written authorization
56 from the X Consortium.
61 * xdm - display manager daemon
62 * Author: Keith Packard, MIT X Consortium
66 * maintain the authorization generation daemon
73 #include <sys/types.h>
81 #include <sys/socket.h>
83 # include <sys/ioctl.h>
87 # include <netinet/in.h>
90 # include <netdnet/dn.h>
91 # include <netdnet/dnetdb.h>
94 #if (defined(_POSIX_SOURCE) && !defined(AIXV3)) || defined(hpux) || defined(USG) || defined(SVR4)
96 #include <sys/utsname.h>
99 #if defined(SYSV) && defined(SYSV386)
100 # include <sys/stream.h>
102 # include <sys/sioctl.h>
105 # include <lan/net_ioctl.h>
111 # include <sys/sockio.h>
113 # include <sys/stropts.h>
117 # include <sync/queue.h>
118 # include <sync/sema.h>
123 extern int SecureRPCInitAuth ();
124 extern Xauth *SecureRPCGetAuth ();
128 extern int Krb5InitAuth ();
129 extern Xauth *Krb5GetAuth ();
132 struct AuthProtocol {
133 unsigned short name_length;
137 #if NeedWidePrototypes
138 unsigned int name_len,
140 unsigned short name_len,
141 #endif /* NeedWidePrototypes */
145 #if NeedWidePrototypes
146 unsigned int namelen,
148 unsigned short namelen,
149 #endif /* NeedWidePrototypes */
152 void (*GetXdmcpAuth)();
156 static struct AuthProtocol AuthProtocols[] = {
157 { (unsigned short) 18, "MIT-MAGIC-COOKIE-1",
158 MitInitAuth, MitGetAuth, NULL
161 { (unsigned short) 19, "XDM-AUTHORIZATION-1",
162 XdmInitAuth, XdmGetAuth, XdmGetXdmcpAuth,
166 { (unsigned short) 9, "SUN-DES-1",
167 SecureRPCInitAuth, SecureRPCGetAuth, NULL,
171 { (unsigned short) 14, "MIT-KERBEROS-5",
172 Krb5InitAuth, Krb5GetAuth, NULL,
177 #define NUM_AUTHORIZATION (sizeof (AuthProtocols) / sizeof (AuthProtocols[0]))
179 static struct AuthProtocol *
180 findProtocol (name_length, name)
181 unsigned short name_length;
186 for (i = 0; i < NUM_AUTHORIZATION; i++)
187 if (AuthProtocols[i].name_length == name_length &&
188 memcmp(AuthProtocols[i].name, name, name_length) == 0)
190 return &AuthProtocols[i];
192 return (struct AuthProtocol *) 0;
195 ValidAuthorization (name_length, name)
196 #if NeedWidePrototypes
197 unsigned int name_length;
199 unsigned short name_length;
200 #endif /* NeedWidePrototypes */
203 if (findProtocol (name_length, name))
209 GenerateAuthorization (name_length, name)
210 unsigned short name_length;
213 struct AuthProtocol *a;
217 Debug ("GenerateAuthorization %*.*s\n",
218 name_length, name_length, name);
219 a = findProtocol (name_length, name);
224 (*a->InitAuth) (name_length, name);
227 auth = (*a->GetAuth) (name_length, name);
230 Debug ("Got 0x%x (%d %*.*s) ", auth,
231 auth->name_length, auth->name_length,
232 auth->name_length, auth->name);
233 for (i = 0; i < (int)auth->data_length; i++)
234 Debug (" %02x", auth->data[i] & 0xff);
238 Debug ("Got (null)\n");
242 Debug ("Unknown authorization %*.*s\n", name_length, name_length, name);
248 SetProtoDisplayAuthorization (pdpy,
249 authorizationNameLen, authorizationName)
250 struct protoDisplay *pdpy;
251 #if NeedWidePrototypes
252 unsigned int authorizationNameLen;
254 unsigned short authorizationNameLen;
255 #endif /* NeedWidePrototypes */
256 char *authorizationName;
258 struct AuthProtocol *a;
261 a = findProtocol (authorizationNameLen, authorizationName);
262 pdpy->xdmcpAuthorization = pdpy->fileAuthorization = 0;
267 (*a->InitAuth) (authorizationNameLen, authorizationName);
272 (*a->GetXdmcpAuth) (pdpy, authorizationNameLen, authorizationName);
273 auth = pdpy->xdmcpAuthorization;
277 auth = (*a->GetAuth) (authorizationNameLen, authorizationName);
278 pdpy->fileAuthorization = auth;
279 pdpy->xdmcpAuthorization = 0;
282 Debug ("Got 0x%x (%d %*.*s)\n", auth,
283 auth->name_length, auth->name_length,
284 auth->name_length, auth->name);
286 Debug ("Got (null)\n");
291 CleanUpFileName (src, dst, len)
307 *dst++ = (*src & 0x7f);
314 static char authdir1[] = "authdir";
315 static char authdir2[] = "authfiles";
318 MakeServerAuthFile (d)
327 char cleanname[NAMELEN];
331 if (d->clientAuthFile && *d->clientAuthFile)
332 len = strlen (d->clientAuthFile) + 1;
335 CleanUpFileName (d->name, cleanname, NAMELEN - 8);
336 len = strlen (authDir) + strlen (authdir1) + strlen (authdir2)
337 + strlen (cleanname) + 14;
341 d->authFile = malloc ((unsigned) len);
344 if (d->clientAuthFile && *d->clientAuthFile)
345 strcpy (d->authFile, d->clientAuthFile);
348 sprintf (d->authFile, "%s/%s", authDir, authdir1);
349 r = stat(d->authFile, &statb);
351 if (statb.st_uid != 0)
352 (void) chown(d->authFile, 0, statb.st_gid);
353 if ((statb.st_mode & 0077) != 0)
354 (void) chmod(d->authFile, statb.st_mode & 0700);
357 r = mkdir(d->authFile, 0700);
364 sprintf (d->authFile, "%s/%s/%s", authDir, authdir1, authdir2);
365 r = mkdir(d->authFile, 0700);
366 if (r < 0 && errno != EEXIST) {
371 sprintf (d->authFile, "%s/%s/%s/A%s-XXXXXX",
372 authDir, authdir1, authdir2, cleanname);
373 (void) mktemp (d->authFile);
378 SaveServerAuthorizations (d, auths, count)
389 if (!d->authFile && !MakeServerAuthFile (d))
391 (void) unlink (d->authFile);
392 auth_file = fopen (d->authFile, "w");
395 Debug ("Can't creat auth file %s\n", d->authFile);
396 LogError (ReadCatalog(MC_LOG_SET,MC_LOG_SRV_OPEN,MC_DEF_LOG_SRV_OPEN),
404 Debug ("File: %s auth: %x\n", d->authFile, auths);
406 for (i = 0; i < count; i++)
409 * User-based auths may not have data until
410 * a user logs in. In which case don't write
411 * to the auth file so xrdb and setup programs don't fail.
413 if (auths[i]->data_length > 0)
414 if (!XauWriteAuth (auth_file, auths[i]) ||
415 fflush (auth_file) == EOF)
418 ReadCatalog(MC_LOG_SET,MC_LOG_SRV_WRT,MC_DEF_LOG_SRV_WRT),
431 SetLocalAuthorization (d)
434 Xauth *auth, **auths;
437 if (d->authorizations)
439 for (i = 0; i < d->authNum; i++)
440 XauDisposeAuth (d->authorizations[i]);
441 free ((char *) d->authorizations);
442 d->authorizations = (Xauth **) NULL;
447 for (i = 0; d->authNames[i]; i++)
451 free ((char *) d->authNameLens);
452 d->authNameLens = (unsigned short *) malloc
453 (d->authNameNum * sizeof (unsigned short));
454 if (!d->authNameLens)
456 for (i = 0; i < d->authNameNum; i++)
457 d->authNameLens[i] = strlen (d->authNames[i]);
458 auths = (Xauth **) malloc (d->authNameNum * sizeof (Xauth *));
462 for (i = 0; i < d->authNameNum; i++)
464 auth = GenerateAuthorization (d->authNameLens[i], d->authNames[i]);
468 if (SaveServerAuthorizations (d, auths, j))
470 d->authorizations = auths;
475 for (i = 0; i < j; i++)
476 XauDisposeAuth (auths[i]);
477 free ((char *) auths);
482 * Set the authorization to use for xdm's initial connection
483 * to the X server. Cannot use user-based authorizations
484 * because no one has logged in yet, so we don't have any
486 * Well, actually we could use SUN-DES-1 because we tell the server
487 * to allow root in. This is bogus and should be fixed.
493 register Xauth **auth = d->authorizations;
496 for (i = 0; i < d->authNum; i++)
498 if (auth[i]->name_length == 9 &&
499 memcmp(auth[i]->name, "SUN-DES-1", 9) == 0)
501 if (auth[i]->name_length == 14 &&
502 memcmp(auth[i]->name, "MIT-KERBEROS-5", 14) == 0)
504 XSetAuthorization (auth[i]->name, (int) auth[i]->name_length,
505 auth[i]->data, (int) auth[i]->data_length);
510 openFiles (name, new_name, oldp, newp)
511 char *name, *new_name;
517 strcpy (new_name, name);
518 strcat (new_name, "-n");
520 (void) unlink (new_name);
521 *newp = fopen (new_name, "w");
524 Debug ("can't open new file %s\n", new_name);
528 * Make sure that the device is not 100% full by actually writing
531 if ((sizeof(int) != fwrite(&null_data, 1, sizeof(int), *newp))
533 Debug ("can't write to new file %s\n", new_name);
535 (void) unlink (new_name);
539 *oldp = fopen (name, "r");
540 Debug ("opens succeeded %s %s\n", name, new_name);
545 binaryEqual (a, b, len)
556 dumpBytes (len, data)
563 for (i = 0; i < len; i++)
564 Debug ("%02x ", data[i] & 0377);
572 Debug ("family: %d\n", auth->family);
574 dumpBytes (auth->address_length, auth->address);
576 dumpBytes (auth->number_length, auth->number);
578 dumpBytes (auth->name_length, auth->name);
580 dumpBytes (auth->data_length, auth->data);
584 unsigned short family;
585 unsigned short address_length;
587 unsigned short number_length;
589 unsigned short name_length;
591 struct addrList *next;
594 static struct addrList *addrs;
605 struct addrList *a, *n;
606 for (a = addrs; a; a = n) {
616 static checkEntry ();
622 struct addrList *new;
624 new = (struct addrList *) malloc (sizeof (struct addrList));
626 LogOutOfMem (ReadCatalog(
627 MC_LOG_SET,MC_LOG_SAVE_ADDR,MC_DEF_LOG_SAVE_ADDR));
630 if ((new->address_length = auth->address_length) > 0) {
631 new->address = malloc (auth->address_length);
633 LogOutOfMem (ReadCatalog(
634 MC_LOG_SET,MC_LOG_SAVE_ADDR,MC_DEF_LOG_SAVE_ADDR));
638 memmove( new->address, auth->address, (int) auth->address_length);
641 if ((new->number_length = auth->number_length) > 0) {
642 new->number = malloc (auth->number_length);
644 LogOutOfMem (ReadCatalog(
645 MC_LOG_SET,MC_LOG_SAVE_ADDR,MC_DEF_LOG_SAVE_ADDR));
650 memmove( new->number, auth->number, (int) auth->number_length);
653 if ((new->name_length = auth->name_length) > 0) {
654 new->name = malloc (auth->name_length);
656 LogOutOfMem (ReadCatalog(
657 MC_LOG_SET,MC_LOG_SAVE_ADDR,MC_DEF_LOG_SAVE_ADDR));
663 memmove( new->name, auth->name, (int) auth->name_length);
666 new->family = auth->family;
677 for (a = addrs; a; a = a->next) {
678 if (a->family == auth->family &&
679 a->address_length == auth->address_length &&
680 binaryEqual (a->address, auth->address, auth->address_length) &&
681 a->number_length == auth->number_length &&
682 binaryEqual (a->number, auth->number, auth->number_length) &&
683 a->name_length == auth->name_length &&
684 binaryEqual (a->name, auth->name, auth->name_length))
695 writeAuth (file, auth)
699 if (debugLevel >= 15) { /* normally too verbose */
700 Debug ("writeAuth: doWrite = %d\n", doWrite);
701 dumpAuth (auth); /* does Debug only */
705 if (!XauWriteAuth (file, auth) || fflush (file) == EOF) {
707 ReadCatalog(MC_LOG_SET,MC_LOG_SRV_WRT,MC_DEF_LOG_SRV_WRT),
716 writeAddr (family, addr_length, addr, file, auth)
723 auth->family = (unsigned short) family;
724 auth->address_length = addr_length;
725 auth->address = addr;
726 Debug ("writeAddr: writing and saving an entry\n");
727 writeAuth (file, auth);
732 DefineLocal (file, auth)
736 char displayname[100];
738 /* stolen from xinit.c */
740 /* Make sure this produces the same string as _XGetHostname in lib/X/XlibInt.c.
741 * Otherwise, Xau will not be able to find your cookies in the Xauthority file.
743 * Note: POSIX says that the ``nodename'' member of utsname does _not_ have
744 * to have sufficient information for interfacing to the network,
745 * and so, you may be better off using gethostname (if it exists).
751 * Why not use gethostname()? Well, at least on my system, I've had to
752 * make an ugly kernel patch to get a name longer than 8 characters, and
753 * uname() lets me access to the whole string (it smashes release, you
754 * see), whereas gethostname() kindly truncates it for me.
760 strcpy(displayname, name.nodename);
762 writeAddr (FamilyLocal, strlen (displayname), displayname, file, auth);
765 #if (!defined(NEED_UTSNAME) || defined (hpux))
767 * In AIXV3, _POSIX_SOURCE is defined, but uname gives only first
768 * field of hostname. Thus, we use gethostname instead.
772 * For HP-UX, HP's Xlib expects a fully-qualified domain name, which
773 * is achieved by using gethostname(). For compatability, we must
774 * also still create the entry using uname() above.
777 gethostname(displayname, sizeof(displayname));
778 writeAddr (FamilyLocal, strlen (displayname), displayname, file, auth);
783 /* Deal with different SIOCGIFCONF ioctl semantics on UnixWare */
785 ifioctl (fd, cmd, arg)
793 bzero((char *) &ioc, sizeof(ioc));
796 if (cmd == SIOCGIFCONF)
798 ioc.ic_len = ((struct ifconf *) arg)->ifc_len;
799 ioc.ic_dp = ((struct ifconf *) arg)->ifc_buf;
803 ioc.ic_len = sizeof(struct ifreq);
806 ret = ioctl(fd, I_STR, (char *) &ioc);
807 if (ret >= 0 && cmd == SIOCGIFCONF)
808 ((struct ifconf *) arg)->ifc_len = ioc.ic_len;
814 #ifdef WINTCP /* NCR with Wollongong TCP */
820 #include <sys/stream.h>
822 #include <netinet/ip.h>
823 #include <netinet/ip_var.h>
824 #include <netinet/in.h>
825 #include <netinet/in_var.h>
828 DefineSelf (fd, file, auth)
834 * The Wolongong drivers used by NCR SVR4/MP-RAS don't understand the
835 * socket IO calls that most other drivers seem to like. Because of
836 * this, this routine must be special cased for NCR. Eventually,
837 * this will be cleared up.
841 struct in_ifaddr ifaddr;
844 int family, len, ipfd;
846 if ((ipfd = open ("/dev/ip", O_RDWR, 0 )) < 0)
847 LogError ((unsigned char *)"Getting interface configuration");
849 /* Indicate that we want to start at the begining */
850 ifnet.ib_next = (struct ipb *) 1;
852 while (ifnet.ib_next)
854 str.ic_cmd = IPIOC_GETIPB;
856 str.ic_len = sizeof (struct ipb);
857 str.ic_dp = (char *) &ifnet;
859 if (ioctl (ipfd, (int) I_STR, (char *) &str) < 0)
862 LogError ((unsigned char *) "Getting interface configuration");
865 ifaddr.ia_next = (struct in_ifaddr *) ifnet.if_addrlist;
866 str.ic_cmd = IPIOC_GETINADDR;
868 str.ic_len = sizeof (struct in_ifaddr);
869 str.ic_dp = (char *) &ifaddr;
871 if (ioctl (ipfd, (int) I_STR, (char *) &str) < 0)
874 LogError ((unsigned char *) "Getting interface configuration");
878 * Ignore the 127.0.0.1 entry.
880 if (IA_SIN(&ifaddr)->sin_addr.s_addr == htonl(0x7f000001) )
883 writeAddr (FamilyInternet, 4, (char *)&(IA_SIN(&ifaddr)->sin_addr), file, auth);
894 #define DECnetInstalled (0 == access("/usr/shlib/libdnet.so", F_OK))
896 /* think of something... */
897 #define DECnetInstalled True
898 #endif /* __osf __ */
900 /* Define this host for access control. Find all the hosts the OS knows about
901 * for this fd and add them to the selfhosts list.
905 DefineSelf (fd, file, auth, addr_family)
907 DefineSelf (fd, file, auth)
919 register struct ifreq *ifr;
921 ifc.ifc_len = sizeof (buf);
925 if (ifioctl (fd, SIOCGIFCONF, (char *) &ifc) < 0)
927 if (ioctl (fd, SIOCGIFCONF, (char *) &ifc) < 0)
935 LogError ((unsigned char *)"Trouble getting Internet network interface configuration\n");
941 LogError ((unsigned char *)"Trouble getting DECnet network interface configuration\n");
945 LogError ((unsigned char *)"Trouble getting network interface configuration\n");
948 LogError ((unsigned char *)"Trouble getting network interface configuration");
951 for (ifr = ifc.ifc_req
952 #if defined(BSD44SOCKETS) || defined(CSRG_BASED)
953 ; (char *)ifr < ifc.ifc_buf + ifc.ifc_len;
954 ifr = (struct ifreq *)((char *)ifr + sizeof (struct ifreq) +
955 (ifr->ifr_addr.sa_len > sizeof (ifr->ifr_addr) ?
956 ifr->ifr_addr.sa_len - sizeof (ifr->ifr_addr) : 0))
958 , n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0; ifr++
964 * this is ugly but SIOCGIFCONF returns decnet addresses in
965 * a different form from other decnet calls
967 if (ifr->ifr_addr.sa_family == AF_DECnet) {
968 len = sizeof (struct dn_naddr);
969 addr = (char *)ifr->ifr_addr.sa_data;
970 family = FamilyDECnet;
974 if (ConvertAddr ((XdmcpNetaddr) &ifr->ifr_addr, &len, &addr) < 0)
978 Debug ("Skipping zero length address\n");
982 * don't write out 'localhost' entries, as
983 * they may conflict with other local entries.
984 * DefineLocal will always be called to add
985 * the local entry anyway, so this one can
989 addr[0] == 127 && addr[1] == 0 &&
990 addr[2] == 0 && addr[3] == 1)
992 Debug ("Skipping localhost address\n");
995 family = FamilyInternet;
997 Debug ("DefineSelf: write network address, length %d\n", len);
998 writeAddr (family, len, addr, file, auth);
1002 #else /* SIOCGIFCONF */
1004 /* Define this host for access control. Find all the hosts the OS knows about
1005 * for this fd and add them to the selfhosts list.
1008 DefineSelf (fd, file, auth)
1016 struct utsname name;
1017 register struct hostent *hp;
1021 struct sockaddr_in in;
1024 struct sockaddr_in *inetaddr;
1027 * Why not use gethostname()? Well, at least on my system, I've had to
1028 * make an ugly kernel patch to get a name longer than 8 characters, and
1029 * uname() lets me access to the whole string (it smashes release, you
1030 * see), whereas gethostname() kindly truncates it for me.
1033 hp = gethostbyname (name.nodename);
1035 saddr.sa.sa_family = hp->h_addrtype;
1036 inetaddr = (struct sockaddr_in *) (&(saddr.sa));
1037 memmove( (char *) &(inetaddr->sin_addr), (char *) hp->h_addr, (int) hp->h_length);
1038 family = ConvertAddr ( &(saddr.sa), &len, &addr);
1040 writeAddr (FamilyInternet, sizeof (inetaddr->sin_addr),
1041 (char *) (&inetaddr->sin_addr), file, auth);
1046 #endif /* SIOCGIFCONF else */
1052 setAuthNumber (auth, name)
1059 Debug ("setAuthNumber %s\n", name);
1060 colon = strrchr(name, ':');
1063 dot = strchr(colon, '.');
1065 auth->number_length = dot - colon;
1067 auth->number_length = strlen (colon);
1068 number = malloc (auth->number_length + 1);
1070 strncpy (number, colon, auth->number_length);
1071 number[auth->number_length] = '\0';
1073 LogOutOfMem (ReadCatalog(
1074 MC_LOG_SET,MC_LOG_NET_CFG,MC_DEF_LOG_NET_CFG));
1075 auth->number_length = 0;
1077 auth->number = number;
1078 Debug ("setAuthNumber: %s\n", number);
1083 writeLocalAuth (file, auth, name)
1090 Debug ("writeLocalAuth: %s %.*s\n", name, auth->name_length, auth->name);
1091 setAuthNumber (auth, name);
1093 fd = t_open ("/dev/tcp", O_RDWR, 0);
1094 t_bind(fd, NULL, NULL);
1095 DefineSelf (fd, file, auth);
1100 fd = socket (AF_INET, SOCK_STREAM, 0);
1101 DefineSelf (fd, file, auth);
1105 fd = socket (AF_DECnet, SOCK_STREAM, 0);
1106 DefineSelf (fd, file, auth);
1109 DefineLocal (file, auth);
1115 writeRemoteAuth (file, auth, peer, peerlen, name)
1122 int family = FamilyLocal;
1125 Debug ("writeRemoteAuth: %s %.*s\n", name, auth->name_length, auth->name);
1126 if (!peer || peerlen < 2)
1128 setAuthNumber (auth, name);
1129 family = ConvertAddr (peer, &peerlen, &addr);
1130 Debug ("writeRemoteAuth: family %d\n", family);
1131 if (family != FamilyLocal)
1133 Debug ("writeRemoteAuth: %d, %d, %x\n",
1134 family, peerlen, *(int *)addr);
1135 writeAddr (family, peerlen, addr, file, auth);
1139 writeLocalAuth (file, auth, name);
1146 SetUserAuthorization (d, verify)
1148 struct verify_info *verify;
1151 char home_name[1024], backup_name[1024], new_name[1024];
1156 Xauth *entry, **auths;
1158 char **setEnv (), *getEnv ();
1164 Debug ("SetUserAuthorization\n");
1165 auths = d->authorizations;
1167 home = getEnv (verify->userEnviron, "HOME");
1168 lockStatus = LOCK_ERROR;
1170 strcpy (home_name, home);
1171 if (home[strlen(home) - 1] != '/')
1172 strcat (home_name, "/");
1173 strcat (home_name, ".Xauthority");
1174 Debug ("XauLockAuth %s\n", home_name);
1175 lockStatus = XauLockAuth (home_name, 1, 2, 10);
1176 Debug ("Lock is %d\n", lockStatus);
1177 if (lockStatus == LOCK_SUCCESS) {
1178 if (openFiles (home_name, new_name, &old, &new)) {
1182 Debug ("openFiles failed\n");
1183 XauUnlockAuth (home_name);
1184 lockStatus = LOCK_ERROR;
1188 if (lockStatus != LOCK_SUCCESS) {
1189 sprintf (backup_name, "%s/.XauthXXXXXX", d->userAuthDir);
1190 (void) mktemp (backup_name);
1191 Debug ("XauLockAuth %s\n", backup_name);
1192 lockStatus = XauLockAuth (backup_name, 1, 2, 10);
1193 Debug ("backup lock is %d\n", lockStatus);
1194 if (lockStatus == LOCK_SUCCESS) {
1195 if (openFiles (backup_name, new_name, &old, &new)) {
1199 XauUnlockAuth (backup_name);
1200 lockStatus = LOCK_ERROR;
1204 * Won't be using this file so unlock it.
1206 XauUnlockAuth (home_name);
1208 if (lockStatus != LOCK_SUCCESS) {
1209 Debug ("can't lock auth file %s or backup %s\n",
1210 home_name, backup_name);
1211 LogError (ReadCatalog
1212 (MC_LOG_SET,MC_LOG_LCK_AUTH,MC_DEF_LOG_LCK_AUTH),
1213 home_name, backup_name);
1218 Debug ("%d authorization protocols for %s\n", d->authNum, d->name);
1220 * Write MIT-MAGIC-COOKIE-1 authorization first, so that
1221 * R4 clients which only knew that, and used the first
1222 * matching entry will continue to function
1225 for (i = 0; i < d->authNum; i++)
1227 if (auths[i]->name_length == 18 &&
1228 !strncmp (auths[i]->name, "MIT-MAGIC-COOKIE-1", 18))
1231 if (d->displayType.location == Local)
1232 writeLocalAuth (new, auths[i], d->name);
1235 writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
1240 /* now write other authorizations */
1241 for (i = 0; i < d->authNum; i++)
1243 Debug("SetUserAuthorization: checking authorization # %d\n", i+1);
1244 if (i != magicCookie)
1246 data_len = auths[i]->data_length;
1247 /* client will just use default Kerberos cache, so don't
1248 * even write cache info into the authority file.
1250 if (auths[i]->name_length == 14 &&
1251 !strncmp (auths[i]->name, "MIT-KERBEROS-5", 14))
1252 auths[i]->data_length = 0;
1253 if (d->displayType.location == Local)
1254 writeLocalAuth (new, auths[i], d->name);
1257 writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
1259 auths[i]->data_length = data_len;
1262 Debug ("SetUserAuthorization: old = %x\n", old);
1264 if (fstat (fileno (old), &statb) != -1)
1265 chmod (new_name, (int) (statb.st_mode & 0777));
1267 while (entry = XauReadAuth (old)) {
1268 if (!checkEntry (entry))
1270 Debug ("Writing an entry\n");
1271 writeAuth (new, entry);
1273 XauDisposeAuth (entry);
1279 Debug ("SetUserAuthorization: name = %s\n", name);
1280 Debug ("SetUserAuthorization: new_name = %s\n", new_name);
1281 Debug ("SetUserAuthorization: unlink(%s)\n", name);
1282 if (unlink (name) == -1)
1283 Debug ("SetUserAuthorization: unlink(%s) failed!\n", name);
1285 if (link (new_name, name) == -1) {
1286 Debug ("link failed %s %s\n", new_name, name);
1288 ReadCatalog(MC_LOG_SET,MC_LOG_NOT_AUTH,MC_DEF_LOG_NOT_AUTH));
1292 Debug ("SetUserAuthorization: link(%s,%s) OK\n", new_name, name);
1293 Debug ("SetUserAuthorization: unlink(%s)\n", new_name);
1297 Debug ("SetUserAuthorization: setenv(XAUTHORITY=%s)\n", envname);
1298 verify->userEnviron = setEnv (verify->userEnviron,
1299 "XAUTHORITY", envname);
1300 verify->systemEnviron = setEnv (verify->systemEnviron,
1301 "XAUTHORITY", envname);
1303 Debug ("SetUserAuthorization: XauUnLockAuth(%s)\n", name);
1304 XauUnlockAuth (name);
1305 Debug ("SetUserAuthorization: envname = %s\n", envname);
1308 Debug ("SetUserAuthorization: chown(%s,%d,%d)\n",
1309 envname, verify->uid, verify->groups[0]);
1310 chown (envname, verify->uid, verify->groups[0]);
1312 Debug ("SetUserAuthorization: chown(%s,%d,%d)\n",
1313 envname, verify->uid, verify->gid);
1314 chown (envname, verify->uid, verify->gid);
1315 #endif /* NGROUPS */
1318 Debug ("done SetUserAuthorization\n");
1322 RemoveUserAuthorization (d, verify)
1324 struct verify_info *verify;
1327 Xauth **auths, *entry;
1328 char name[1024], new_name[1024];
1335 if (!(auths = d->authorizations))
1337 home = getEnv (verify->userEnviron, "HOME");
1340 Debug ("RemoveUserAuthorization\n");
1341 strcpy (name, home);
1342 if (home[strlen(home) - 1] != '/')
1344 strcat (name, ".Xauthority");
1345 Debug ("XauLockAuth %s\n", name);
1346 lockStatus = XauLockAuth (name, 1, 2, 10);
1347 Debug ("Lock is %d\n", lockStatus);
1348 if (lockStatus != LOCK_SUCCESS)
1350 if (openFiles (name, new_name, &old, &new))
1354 for (i = 0; i < d->authNum; i++)
1356 if (d->displayType.location == Local)
1357 writeLocalAuth (new, auths[i], d->name);
1360 writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
1365 if (fstat (fileno (old), &statb) != -1)
1366 chmod (new_name, (int) (statb.st_mode & 0777));
1368 while (entry = XauReadAuth (old)) {
1369 if (!checkEntry (entry))
1371 Debug ("Writing an entry\n");
1372 writeAuth (new, entry);
1374 XauDisposeAuth (entry);
1380 if (unlink (name) == -1)
1381 Debug ("unlink %s failed\n", name);
1382 if (link (new_name, name) == -1) {
1383 Debug ("link failed %s %s\n", new_name, name);
1385 ReadCatalog(MC_LOG_SET,MC_LOG_NOT_AUTH,MC_DEF_LOG_NOT_AUTH));
1387 Debug ("new is in place, go for it!\n");
1391 XauUnlockAuth (name);