2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $TOG: auth.c /main/6 1997/03/14 13:44:25 barstow $ */
24 /* (c) Copyright 1997 The Open Group */
26 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
27 * (c) Copyright 1993, 1994 International Business Machines Corp. *
28 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
29 * (c) Copyright 1993, 1994 Novell, Inc. *
38 * Revision 1.1.2.3 1995/06/06 20:21:58 Chris_Beute
39 * Code snapshot merge from March 15 and SIA changes
40 * [1995/05/31 20:09:58 Chris_Beute]
42 * Revision 1.1.2.2 1995/04/21 13:05:15 Peter_Derr
43 * dtlogin auth key fixes from deltacde
44 * [1995/04/12 19:20:51 Peter_Derr]
46 * R6 version of auth.c to handle multiple authentication protocols.
47 * [1995/04/12 18:05:30 Peter_Derr]
54 Copyright (c) 1988 X Consortium
56 Permission is hereby granted, free of charge, to any person obtaining
57 a copy of this software and associated documentation files (the
58 "Software"), to deal in the Software without restriction, including
59 without limitation the rights to use, copy, modify, merge, publish,
60 distribute, sublicense, and/or sell copies of the Software, and to
61 permit persons to whom the Software is furnished to do so, subject to
62 the following conditions:
64 The above copyright notice and this permission notice shall be included
65 in all copies or substantial portions of the Software.
67 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
68 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
69 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
70 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
71 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
72 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
73 OTHER DEALINGS IN THE SOFTWARE.
75 Except as contained in this notice, the name of the X Consortium shall
76 not be used in advertising or otherwise to promote the sale, use or
77 other dealings in this Software without prior written authorization
78 from the X Consortium.
83 * xdm - display manager daemon
84 * Author: Keith Packard, MIT X Consortium
88 * maintain the authorization generation daemon
95 #include <sys/types.h>
103 #include <sys/socket.h>
105 # include <sys/ioctl.h>
109 # include <netinet/in.h>
112 # include <netdnet/dn.h>
113 # include <netdnet/dnetdb.h>
116 #if (defined(_POSIX_SOURCE) && !defined(AIXV3)) || defined(hpux) || defined(USG) || defined(SVR4)
118 #include <sys/utsname.h>
121 #if defined(SYSV) && defined(SYSV386)
122 # include <sys/stream.h>
124 # include <sys/sioctl.h>
127 # include <lan/net_ioctl.h>
133 # include <sys/sockio.h>
135 # include <sys/stropts.h>
139 # include <sync/queue.h>
140 # include <sync/sema.h>
145 extern int SecureRPCInitAuth ();
146 extern Xauth *SecureRPCGetAuth ();
150 extern int Krb5InitAuth ();
151 extern Xauth *Krb5GetAuth ();
154 struct AuthProtocol {
155 unsigned short name_length;
159 #if NeedWidePrototypes
160 unsigned int name_len,
162 unsigned short name_len,
163 #endif /* NeedWidePrototypes */
167 #if NeedWidePrototypes
168 unsigned int namelen,
170 unsigned short namelen,
171 #endif /* NeedWidePrototypes */
174 void (*GetXdmcpAuth)();
178 static struct AuthProtocol AuthProtocols[] = {
179 { (unsigned short) 18, "MIT-MAGIC-COOKIE-1",
180 MitInitAuth, MitGetAuth, NULL
183 { (unsigned short) 19, "XDM-AUTHORIZATION-1",
184 XdmInitAuth, XdmGetAuth, XdmGetXdmcpAuth,
188 { (unsigned short) 9, "SUN-DES-1",
189 SecureRPCInitAuth, SecureRPCGetAuth, NULL,
193 { (unsigned short) 14, "MIT-KERBEROS-5",
194 Krb5InitAuth, Krb5GetAuth, NULL,
199 #define NUM_AUTHORIZATION (sizeof (AuthProtocols) / sizeof (AuthProtocols[0]))
201 static struct AuthProtocol *
202 findProtocol (name_length, name)
203 unsigned short name_length;
208 for (i = 0; i < NUM_AUTHORIZATION; i++)
209 if (AuthProtocols[i].name_length == name_length &&
210 memcmp(AuthProtocols[i].name, name, name_length) == 0)
212 return &AuthProtocols[i];
214 return (struct AuthProtocol *) 0;
217 ValidAuthorization (name_length, name)
218 #if NeedWidePrototypes
219 unsigned int name_length;
221 unsigned short name_length;
222 #endif /* NeedWidePrototypes */
225 if (findProtocol (name_length, name))
231 GenerateAuthorization (name_length, name)
232 unsigned short name_length;
235 struct AuthProtocol *a;
239 Debug ("GenerateAuthorization %*.*s\n",
240 name_length, name_length, name);
241 a = findProtocol (name_length, name);
246 (*a->InitAuth) (name_length, name);
249 auth = (*a->GetAuth) (name_length, name);
252 Debug ("Got 0x%x (%d %*.*s) ", auth,
253 auth->name_length, auth->name_length,
254 auth->name_length, auth->name);
255 for (i = 0; i < (int)auth->data_length; i++)
256 Debug (" %02x", auth->data[i] & 0xff);
260 Debug ("Got (null)\n");
264 Debug ("Unknown authorization %*.*s\n", name_length, name_length, name);
270 SetProtoDisplayAuthorization (pdpy,
271 authorizationNameLen, authorizationName)
272 struct protoDisplay *pdpy;
273 #if NeedWidePrototypes
274 unsigned int authorizationNameLen;
276 unsigned short authorizationNameLen;
277 #endif /* NeedWidePrototypes */
278 char *authorizationName;
280 struct AuthProtocol *a;
283 a = findProtocol (authorizationNameLen, authorizationName);
284 pdpy->xdmcpAuthorization = pdpy->fileAuthorization = 0;
289 (*a->InitAuth) (authorizationNameLen, authorizationName);
294 (*a->GetXdmcpAuth) (pdpy, authorizationNameLen, authorizationName);
295 auth = pdpy->xdmcpAuthorization;
299 auth = (*a->GetAuth) (authorizationNameLen, authorizationName);
300 pdpy->fileAuthorization = auth;
301 pdpy->xdmcpAuthorization = 0;
304 Debug ("Got 0x%x (%d %*.*s)\n", auth,
305 auth->name_length, auth->name_length,
306 auth->name_length, auth->name);
308 Debug ("Got (null)\n");
313 CleanUpFileName (src, dst, len)
329 *dst++ = (*src & 0x7f);
336 static char authdir1[] = "authdir";
337 static char authdir2[] = "authfiles";
340 MakeServerAuthFile (d)
349 char cleanname[NAMELEN];
353 if (d->clientAuthFile && *d->clientAuthFile)
354 len = strlen (d->clientAuthFile) + 1;
357 CleanUpFileName (d->name, cleanname, NAMELEN - 8);
358 len = strlen (authDir) + strlen (authdir1) + strlen (authdir2)
359 + strlen (cleanname) + 14;
363 d->authFile = malloc ((unsigned) len);
366 if (d->clientAuthFile && *d->clientAuthFile)
367 strcpy (d->authFile, d->clientAuthFile);
370 sprintf (d->authFile, "%s/%s", authDir, authdir1);
371 r = stat(d->authFile, &statb);
373 if (statb.st_uid != 0)
374 (void) chown(d->authFile, 0, statb.st_gid);
375 if ((statb.st_mode & 0077) != 0)
376 (void) chmod(d->authFile, statb.st_mode & 0700);
379 r = mkdir(d->authFile, 0700);
386 sprintf (d->authFile, "%s/%s/%s", authDir, authdir1, authdir2);
387 r = mkdir(d->authFile, 0700);
388 if (r < 0 && errno != EEXIST) {
393 sprintf (d->authFile, "%s/%s/%s/A%s-XXXXXX",
394 authDir, authdir1, authdir2, cleanname);
395 (void) mktemp (d->authFile);
400 SaveServerAuthorizations (d, auths, count)
411 if (!d->authFile && !MakeServerAuthFile (d))
413 (void) unlink (d->authFile);
414 auth_file = fopen (d->authFile, "w");
417 Debug ("Can't creat auth file %s\n", d->authFile);
418 LogError (ReadCatalog(MC_LOG_SET,MC_LOG_SRV_OPEN,MC_DEF_LOG_SRV_OPEN),
426 Debug ("File: %s auth: %x\n", d->authFile, auths);
428 for (i = 0; i < count; i++)
431 * User-based auths may not have data until
432 * a user logs in. In which case don't write
433 * to the auth file so xrdb and setup programs don't fail.
435 if (auths[i]->data_length > 0)
436 if (!XauWriteAuth (auth_file, auths[i]) ||
437 fflush (auth_file) == EOF)
440 ReadCatalog(MC_LOG_SET,MC_LOG_SRV_WRT,MC_DEF_LOG_SRV_WRT),
453 SetLocalAuthorization (d)
456 Xauth *auth, **auths;
459 if (d->authorizations)
461 for (i = 0; i < d->authNum; i++)
462 XauDisposeAuth (d->authorizations[i]);
463 free ((char *) d->authorizations);
464 d->authorizations = (Xauth **) NULL;
469 for (i = 0; d->authNames[i]; i++)
473 free ((char *) d->authNameLens);
474 d->authNameLens = (unsigned short *) malloc
475 (d->authNameNum * sizeof (unsigned short));
476 if (!d->authNameLens)
478 for (i = 0; i < d->authNameNum; i++)
479 d->authNameLens[i] = strlen (d->authNames[i]);
480 auths = (Xauth **) malloc (d->authNameNum * sizeof (Xauth *));
484 for (i = 0; i < d->authNameNum; i++)
486 auth = GenerateAuthorization (d->authNameLens[i], d->authNames[i]);
490 if (SaveServerAuthorizations (d, auths, j))
492 d->authorizations = auths;
497 for (i = 0; i < j; i++)
498 XauDisposeAuth (auths[i]);
499 free ((char *) auths);
504 * Set the authorization to use for xdm's initial connection
505 * to the X server. Cannot use user-based authorizations
506 * because no one has logged in yet, so we don't have any
508 * Well, actually we could use SUN-DES-1 because we tell the server
509 * to allow root in. This is bogus and should be fixed.
515 register Xauth **auth = d->authorizations;
518 for (i = 0; i < d->authNum; i++)
520 if (auth[i]->name_length == 9 &&
521 memcmp(auth[i]->name, "SUN-DES-1", 9) == 0)
523 if (auth[i]->name_length == 14 &&
524 memcmp(auth[i]->name, "MIT-KERBEROS-5", 14) == 0)
526 XSetAuthorization (auth[i]->name, (int) auth[i]->name_length,
527 auth[i]->data, (int) auth[i]->data_length);
532 openFiles (name, new_name, oldp, newp)
533 char *name, *new_name;
539 strcpy (new_name, name);
540 strcat (new_name, "-n");
542 (void) unlink (new_name);
543 *newp = fopen (new_name, "w");
546 Debug ("can't open new file %s\n", new_name);
550 * Make sure that the device is not 100% full by actually writing
553 if ((sizeof(int) != fwrite(&null_data, 1, sizeof(int), *newp))
555 Debug ("can't write to new file %s\n", new_name);
557 (void) unlink (new_name);
561 *oldp = fopen (name, "r");
562 Debug ("opens succeeded %s %s\n", name, new_name);
567 binaryEqual (a, b, len)
578 dumpBytes (len, data)
585 for (i = 0; i < len; i++)
586 Debug ("%02x ", data[i] & 0377);
594 Debug ("family: %d\n", auth->family);
596 dumpBytes (auth->address_length, auth->address);
598 dumpBytes (auth->number_length, auth->number);
600 dumpBytes (auth->name_length, auth->name);
602 dumpBytes (auth->data_length, auth->data);
606 unsigned short family;
607 unsigned short address_length;
609 unsigned short number_length;
611 unsigned short name_length;
613 struct addrList *next;
616 static struct addrList *addrs;
627 struct addrList *a, *n;
628 for (a = addrs; a; a = n) {
638 static checkEntry ();
644 struct addrList *new;
646 new = (struct addrList *) malloc (sizeof (struct addrList));
648 LogOutOfMem (ReadCatalog(
649 MC_LOG_SET,MC_LOG_SAVE_ADDR,MC_DEF_LOG_SAVE_ADDR));
652 if ((new->address_length = auth->address_length) > 0) {
653 new->address = malloc (auth->address_length);
655 LogOutOfMem (ReadCatalog(
656 MC_LOG_SET,MC_LOG_SAVE_ADDR,MC_DEF_LOG_SAVE_ADDR));
660 memmove( new->address, auth->address, (int) auth->address_length);
663 if ((new->number_length = auth->number_length) > 0) {
664 new->number = malloc (auth->number_length);
666 LogOutOfMem (ReadCatalog(
667 MC_LOG_SET,MC_LOG_SAVE_ADDR,MC_DEF_LOG_SAVE_ADDR));
672 memmove( new->number, auth->number, (int) auth->number_length);
675 if ((new->name_length = auth->name_length) > 0) {
676 new->name = malloc (auth->name_length);
678 LogOutOfMem (ReadCatalog(
679 MC_LOG_SET,MC_LOG_SAVE_ADDR,MC_DEF_LOG_SAVE_ADDR));
685 memmove( new->name, auth->name, (int) auth->name_length);
688 new->family = auth->family;
699 for (a = addrs; a; a = a->next) {
700 if (a->family == auth->family &&
701 a->address_length == auth->address_length &&
702 binaryEqual (a->address, auth->address, auth->address_length) &&
703 a->number_length == auth->number_length &&
704 binaryEqual (a->number, auth->number, auth->number_length) &&
705 a->name_length == auth->name_length &&
706 binaryEqual (a->name, auth->name, auth->name_length))
717 writeAuth (file, auth)
721 if (debugLevel >= 15) { /* normally too verbose */
722 Debug ("writeAuth: doWrite = %d\n", doWrite);
723 dumpAuth (auth); /* does Debug only */
727 if (!XauWriteAuth (file, auth) || fflush (file) == EOF) {
729 ReadCatalog(MC_LOG_SET,MC_LOG_SRV_WRT,MC_DEF_LOG_SRV_WRT),
738 writeAddr (family, addr_length, addr, file, auth)
745 auth->family = (unsigned short) family;
746 auth->address_length = addr_length;
747 auth->address = addr;
748 Debug ("writeAddr: writing and saving an entry\n");
749 writeAuth (file, auth);
754 DefineLocal (file, auth)
758 char displayname[100];
760 /* stolen from xinit.c */
762 /* Make sure this produces the same string as _XGetHostname in lib/X/XlibInt.c.
763 * Otherwise, Xau will not be able to find your cookies in the Xauthority file.
765 * Note: POSIX says that the ``nodename'' member of utsname does _not_ have
766 * to have sufficient information for interfacing to the network,
767 * and so, you may be better off using gethostname (if it exists).
773 * Why not use gethostname()? Well, at least on my system, I've had to
774 * make an ugly kernel patch to get a name longer than 8 characters, and
775 * uname() lets me access to the whole string (it smashes release, you
776 * see), whereas gethostname() kindly truncates it for me.
782 strcpy(displayname, name.nodename);
784 writeAddr (FamilyLocal, strlen (displayname), displayname, file, auth);
787 #if (!defined(NEED_UTSNAME) || defined (hpux))
789 * In AIXV3, _POSIX_SOURCE is defined, but uname gives only first
790 * field of hostname. Thus, we use gethostname instead.
794 * For HP-UX, HP's Xlib expects a fully-qualified domain name, which
795 * is achieved by using gethostname(). For compatability, we must
796 * also still create the entry using uname() above.
799 gethostname(displayname, sizeof(displayname));
800 writeAddr (FamilyLocal, strlen (displayname), displayname, file, auth);
805 /* Deal with different SIOCGIFCONF ioctl semantics on UnixWare */
807 ifioctl (fd, cmd, arg)
815 bzero((char *) &ioc, sizeof(ioc));
818 if (cmd == SIOCGIFCONF)
820 ioc.ic_len = ((struct ifconf *) arg)->ifc_len;
821 ioc.ic_dp = ((struct ifconf *) arg)->ifc_buf;
825 ioc.ic_len = sizeof(struct ifreq);
828 ret = ioctl(fd, I_STR, (char *) &ioc);
829 if (ret >= 0 && cmd == SIOCGIFCONF)
830 ((struct ifconf *) arg)->ifc_len = ioc.ic_len;
836 #ifdef WINTCP /* NCR with Wollongong TCP */
842 #include <sys/stream.h>
844 #include <netinet/ip.h>
845 #include <netinet/ip_var.h>
846 #include <netinet/in.h>
847 #include <netinet/in_var.h>
850 DefineSelf (fd, file, auth)
856 * The Wolongong drivers used by NCR SVR4/MP-RAS don't understand the
857 * socket IO calls that most other drivers seem to like. Because of
858 * this, this routine must be special cased for NCR. Eventually,
859 * this will be cleared up.
863 struct in_ifaddr ifaddr;
866 int family, len, ipfd;
868 if ((ipfd = open ("/dev/ip", O_RDWR, 0 )) < 0)
869 LogError ((unsigned char *)"Getting interface configuration");
871 /* Indicate that we want to start at the begining */
872 ifnet.ib_next = (struct ipb *) 1;
874 while (ifnet.ib_next)
876 str.ic_cmd = IPIOC_GETIPB;
878 str.ic_len = sizeof (struct ipb);
879 str.ic_dp = (char *) &ifnet;
881 if (ioctl (ipfd, (int) I_STR, (char *) &str) < 0)
884 LogError ((unsigned char *) "Getting interface configuration");
887 ifaddr.ia_next = (struct in_ifaddr *) ifnet.if_addrlist;
888 str.ic_cmd = IPIOC_GETINADDR;
890 str.ic_len = sizeof (struct in_ifaddr);
891 str.ic_dp = (char *) &ifaddr;
893 if (ioctl (ipfd, (int) I_STR, (char *) &str) < 0)
896 LogError ((unsigned char *) "Getting interface configuration");
900 * Ignore the 127.0.0.1 entry.
902 if (IA_SIN(&ifaddr)->sin_addr.s_addr == htonl(0x7f000001) )
905 writeAddr (FamilyInternet, 4, (char *)&(IA_SIN(&ifaddr)->sin_addr), file, auth);
916 #define DECnetInstalled (0 == access("/usr/shlib/libdnet.so", F_OK))
918 /* think of something... */
919 #define DECnetInstalled True
920 #endif /* __osf __ */
922 /* Define this host for access control. Find all the hosts the OS knows about
923 * for this fd and add them to the selfhosts list.
927 DefineSelf (fd, file, auth, addr_family)
929 DefineSelf (fd, file, auth)
941 register struct ifreq *ifr;
943 ifc.ifc_len = sizeof (buf);
947 if (ifioctl (fd, SIOCGIFCONF, (char *) &ifc) < 0)
949 if (ioctl (fd, SIOCGIFCONF, (char *) &ifc) < 0)
957 LogError ((unsigned char *)"Trouble getting Internet network interface configuration\n");
963 LogError ((unsigned char *)"Trouble getting DECnet network interface configuration\n");
967 LogError ((unsigned char *)"Trouble getting network interface configuration\n");
970 LogError ((unsigned char *)"Trouble getting network interface configuration");
973 for (ifr = ifc.ifc_req
974 #if defined(BSD44SOCKETS) || defined(CSRG_BASED)
975 ; (char *)ifr < ifc.ifc_buf + ifc.ifc_len;
976 ifr = (struct ifreq *)((char *)ifr + sizeof (struct ifreq) +
977 (ifr->ifr_addr.sa_len > sizeof (ifr->ifr_addr) ?
978 ifr->ifr_addr.sa_len - sizeof (ifr->ifr_addr) : 0))
980 , n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0; ifr++
986 * this is ugly but SIOCGIFCONF returns decnet addresses in
987 * a different form from other decnet calls
989 if (ifr->ifr_addr.sa_family == AF_DECnet) {
990 len = sizeof (struct dn_naddr);
991 addr = (char *)ifr->ifr_addr.sa_data;
992 family = FamilyDECnet;
996 if (ConvertAddr ((XdmcpNetaddr) &ifr->ifr_addr, &len, &addr) < 0)
1000 Debug ("Skipping zero length address\n");
1004 * don't write out 'localhost' entries, as
1005 * they may conflict with other local entries.
1006 * DefineLocal will always be called to add
1007 * the local entry anyway, so this one can
1011 addr[0] == 127 && addr[1] == 0 &&
1012 addr[2] == 0 && addr[3] == 1)
1014 Debug ("Skipping localhost address\n");
1017 family = FamilyInternet;
1019 Debug ("DefineSelf: write network address, length %d\n", len);
1020 writeAddr (family, len, addr, file, auth);
1024 #else /* SIOCGIFCONF */
1026 /* Define this host for access control. Find all the hosts the OS knows about
1027 * for this fd and add them to the selfhosts list.
1030 DefineSelf (fd, file, auth)
1038 struct utsname name;
1039 register struct hostent *hp;
1043 struct sockaddr_in in;
1046 struct sockaddr_in *inetaddr;
1049 * Why not use gethostname()? Well, at least on my system, I've had to
1050 * make an ugly kernel patch to get a name longer than 8 characters, and
1051 * uname() lets me access to the whole string (it smashes release, you
1052 * see), whereas gethostname() kindly truncates it for me.
1055 hp = gethostbyname (name.nodename);
1057 saddr.sa.sa_family = hp->h_addrtype;
1058 inetaddr = (struct sockaddr_in *) (&(saddr.sa));
1059 memmove( (char *) &(inetaddr->sin_addr), (char *) hp->h_addr, (int) hp->h_length);
1060 family = ConvertAddr ( &(saddr.sa), &len, &addr);
1062 writeAddr (FamilyInternet, sizeof (inetaddr->sin_addr),
1063 (char *) (&inetaddr->sin_addr), file, auth);
1068 #endif /* SIOCGIFCONF else */
1074 setAuthNumber (auth, name)
1081 Debug ("setAuthNumber %s\n", name);
1082 colon = strrchr(name, ':');
1085 dot = strchr(colon, '.');
1087 auth->number_length = dot - colon;
1089 auth->number_length = strlen (colon);
1090 number = malloc (auth->number_length + 1);
1092 strncpy (number, colon, auth->number_length);
1093 number[auth->number_length] = '\0';
1095 LogOutOfMem (ReadCatalog(
1096 MC_LOG_SET,MC_LOG_NET_CFG,MC_DEF_LOG_NET_CFG));
1097 auth->number_length = 0;
1099 auth->number = number;
1100 Debug ("setAuthNumber: %s\n", number);
1105 writeLocalAuth (file, auth, name)
1112 Debug ("writeLocalAuth: %s %.*s\n", name, auth->name_length, auth->name);
1113 setAuthNumber (auth, name);
1115 fd = t_open ("/dev/tcp", O_RDWR, 0);
1116 t_bind(fd, NULL, NULL);
1117 DefineSelf (fd, file, auth);
1122 fd = socket (AF_INET, SOCK_STREAM, 0);
1123 DefineSelf (fd, file, auth);
1127 fd = socket (AF_DECnet, SOCK_STREAM, 0);
1128 DefineSelf (fd, file, auth);
1131 DefineLocal (file, auth);
1137 writeRemoteAuth (file, auth, peer, peerlen, name)
1144 int family = FamilyLocal;
1147 Debug ("writeRemoteAuth: %s %.*s\n", name, auth->name_length, auth->name);
1148 if (!peer || peerlen < 2)
1150 setAuthNumber (auth, name);
1151 family = ConvertAddr (peer, &peerlen, &addr);
1152 Debug ("writeRemoteAuth: family %d\n", family);
1153 if (family != FamilyLocal)
1155 Debug ("writeRemoteAuth: %d, %d, %x\n",
1156 family, peerlen, *(int *)addr);
1157 writeAddr (family, peerlen, addr, file, auth);
1161 writeLocalAuth (file, auth, name);
1168 SetUserAuthorization (d, verify)
1170 struct verify_info *verify;
1173 char home_name[1024], backup_name[1024], new_name[1024];
1178 Xauth *entry, **auths;
1180 char **setEnv (), *getEnv ();
1186 Debug ("SetUserAuthorization\n");
1187 auths = d->authorizations;
1189 home = getEnv (verify->userEnviron, "HOME");
1190 lockStatus = LOCK_ERROR;
1192 strcpy (home_name, home);
1193 if (home[strlen(home) - 1] != '/')
1194 strcat (home_name, "/");
1195 strcat (home_name, ".Xauthority");
1196 Debug ("XauLockAuth %s\n", home_name);
1197 lockStatus = XauLockAuth (home_name, 1, 2, 10);
1198 Debug ("Lock is %d\n", lockStatus);
1199 if (lockStatus == LOCK_SUCCESS) {
1200 if (openFiles (home_name, new_name, &old, &new)) {
1204 Debug ("openFiles failed\n");
1205 XauUnlockAuth (home_name);
1206 lockStatus = LOCK_ERROR;
1210 if (lockStatus != LOCK_SUCCESS) {
1211 sprintf (backup_name, "%s/.XauthXXXXXX", d->userAuthDir);
1212 (void) mktemp (backup_name);
1213 Debug ("XauLockAuth %s\n", backup_name);
1214 lockStatus = XauLockAuth (backup_name, 1, 2, 10);
1215 Debug ("backup lock is %d\n", lockStatus);
1216 if (lockStatus == LOCK_SUCCESS) {
1217 if (openFiles (backup_name, new_name, &old, &new)) {
1221 XauUnlockAuth (backup_name);
1222 lockStatus = LOCK_ERROR;
1226 * Won't be using this file so unlock it.
1228 XauUnlockAuth (home_name);
1230 if (lockStatus != LOCK_SUCCESS) {
1231 Debug ("can't lock auth file %s or backup %s\n",
1232 home_name, backup_name);
1233 LogError (ReadCatalog
1234 (MC_LOG_SET,MC_LOG_LCK_AUTH,MC_DEF_LOG_LCK_AUTH),
1235 home_name, backup_name);
1240 Debug ("%d authorization protocols for %s\n", d->authNum, d->name);
1242 * Write MIT-MAGIC-COOKIE-1 authorization first, so that
1243 * R4 clients which only knew that, and used the first
1244 * matching entry will continue to function
1247 for (i = 0; i < d->authNum; i++)
1249 if (auths[i]->name_length == 18 &&
1250 !strncmp (auths[i]->name, "MIT-MAGIC-COOKIE-1", 18))
1253 if (d->displayType.location == Local)
1254 writeLocalAuth (new, auths[i], d->name);
1257 writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
1262 /* now write other authorizations */
1263 for (i = 0; i < d->authNum; i++)
1265 Debug("SetUserAuthorization: checking authorization # %d\n", i+1);
1266 if (i != magicCookie)
1268 data_len = auths[i]->data_length;
1269 /* client will just use default Kerberos cache, so don't
1270 * even write cache info into the authority file.
1272 if (auths[i]->name_length == 14 &&
1273 !strncmp (auths[i]->name, "MIT-KERBEROS-5", 14))
1274 auths[i]->data_length = 0;
1275 if (d->displayType.location == Local)
1276 writeLocalAuth (new, auths[i], d->name);
1279 writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
1281 auths[i]->data_length = data_len;
1284 Debug ("SetUserAuthorization: old = %x\n", old);
1286 if (fstat (fileno (old), &statb) != -1)
1287 chmod (new_name, (int) (statb.st_mode & 0777));
1289 while (entry = XauReadAuth (old)) {
1290 if (!checkEntry (entry))
1292 Debug ("Writing an entry\n");
1293 writeAuth (new, entry);
1295 XauDisposeAuth (entry);
1301 Debug ("SetUserAuthorization: name = %s\n", name);
1302 Debug ("SetUserAuthorization: new_name = %s\n", new_name);
1303 Debug ("SetUserAuthorization: unlink(%s)\n", name);
1304 if (unlink (name) == -1)
1305 Debug ("SetUserAuthorization: unlink(%s) failed!\n", name);
1307 if (link (new_name, name) == -1) {
1308 Debug ("link failed %s %s\n", new_name, name);
1310 ReadCatalog(MC_LOG_SET,MC_LOG_NOT_AUTH,MC_DEF_LOG_NOT_AUTH));
1314 Debug ("SetUserAuthorization: link(%s,%s) OK\n", new_name, name);
1315 Debug ("SetUserAuthorization: unlink(%s)\n", new_name);
1319 Debug ("SetUserAuthorization: setenv(XAUTHORITY=%s)\n", envname);
1320 verify->userEnviron = setEnv (verify->userEnviron,
1321 "XAUTHORITY", envname);
1322 verify->systemEnviron = setEnv (verify->systemEnviron,
1323 "XAUTHORITY", envname);
1325 Debug ("SetUserAuthorization: XauUnLockAuth(%s)\n", name);
1326 XauUnlockAuth (name);
1327 Debug ("SetUserAuthorization: envname = %s\n", envname);
1330 Debug ("SetUserAuthorization: chown(%s,%d,%d)\n",
1331 envname, verify->uid, verify->groups[0]);
1332 chown (envname, verify->uid, verify->groups[0]);
1334 Debug ("SetUserAuthorization: chown(%s,%d,%d)\n",
1335 envname, verify->uid, verify->gid);
1336 chown (envname, verify->uid, verify->gid);
1337 #endif /* NGROUPS */
1340 Debug ("done SetUserAuthorization\n");
1344 RemoveUserAuthorization (d, verify)
1346 struct verify_info *verify;
1349 Xauth **auths, *entry;
1350 char name[1024], new_name[1024];
1357 if (!(auths = d->authorizations))
1359 home = getEnv (verify->userEnviron, "HOME");
1362 Debug ("RemoveUserAuthorization\n");
1363 strcpy (name, home);
1364 if (home[strlen(home) - 1] != '/')
1366 strcat (name, ".Xauthority");
1367 Debug ("XauLockAuth %s\n", name);
1368 lockStatus = XauLockAuth (name, 1, 2, 10);
1369 Debug ("Lock is %d\n", lockStatus);
1370 if (lockStatus != LOCK_SUCCESS)
1372 if (openFiles (name, new_name, &old, &new))
1376 for (i = 0; i < d->authNum; i++)
1378 if (d->displayType.location == Local)
1379 writeLocalAuth (new, auths[i], d->name);
1382 writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
1387 if (fstat (fileno (old), &statb) != -1)
1388 chmod (new_name, (int) (statb.st_mode & 0777));
1390 while (entry = XauReadAuth (old)) {
1391 if (!checkEntry (entry))
1393 Debug ("Writing an entry\n");
1394 writeAuth (new, entry);
1396 XauDisposeAuth (entry);
1402 if (unlink (name) == -1)
1403 Debug ("unlink %s failed\n", name);
1404 if (link (new_name, name) == -1) {
1405 Debug ("link failed %s %s\n", new_name, name);
1407 ReadCatalog(MC_LOG_SET,MC_LOG_NOT_AUTH,MC_DEF_LOG_NOT_AUTH));
1409 Debug ("new is in place, go for it!\n");
1413 XauUnlockAuth (name);