Bug Summary

File:xdm/auth.c
Location:line 501, column 23
Description:Call to 'malloc' has an allocation size of 0 bytes

Annotated Source Code

1/*
2
3Copyright 1988, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from The Open Group.
26
27*/
28
29/*
30 * xdm - display manager daemon
31 * Author: Keith Packard, MIT X Consortium
32 *
33 * auth.c
34 *
35 * maintain the authorization generation daemon
36 */
37
38#include <X11/X.h>
39#include <X11/Xlibint.h>
40#include <sys/types.h>
41#include <sys/stat.h>
42
43#include "dm.h"
44#include "dm_auth.h"
45#include "dm_error.h"
46
47#include <errno(*__error()).h>
48
49#include <sys/ioctl.h>
50
51#ifdef TCPCONN1
52# include "dm_socket.h"
53#endif
54
55#if defined(hpux)
56# include <sys/utsname.h>
57#endif
58
59#if defined(SYSV) && defined(i386)
60# include <sys/stream.h>
61#endif /* i386 */
62
63#ifdef SVR4
64# include <netdb.h>
65# include <sys/sockio.h>
66# include <sys/stropts.h>
67#endif
68#ifdef __convex__
69# include <sync/queue.h>
70# include <sync/sema.h>
71#endif
72#ifdef __GNU__
73# include <netdb.h>
74# undef SIOCGIFCONF(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifconf) & 0x1fff) << 16) | ((('i')) << 8) | (
(36)))
75#else /* __GNU__ */
76# include <net/if.h>
77#endif /* __GNU__ */
78
79#if defined(TCPCONN1) && !defined(WIN32)
80# include <netinet/in.h>
81#endif
82
83/* Solaris provides an extended interface SIOCGLIFCONF for IPv6 support.
84 */
85#ifdef SIOCGLIFCONF
86# define USE_SIOCGLIFCONF
87#endif
88
89#if (defined(SVR4) && !defined(sun)) && \
90 defined(SIOCGIFCONF(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifconf) & 0x1fff) << 16) | ((('i')) << 8) | (
(36)))
) && !defined(USE_SIOCGLIFCONF)
91# define SYSV_SIOCGIFCONF
92#endif
93
94#ifdef HAVE_SYS_PARAM_H1
95# include <sys/param.h>
96# ifdef BSD199506
97# if (BSD199506 >= 199103)
98# define VARIABLE_IFREQ
99# endif
100# endif
101#endif
102
103#ifdef __UNIXOS2__
104# define link rename
105int chown(int a,int b,int c) {}
106# include <io.h>
107#endif
108
109struct AuthProtocol {
110 unsigned short name_length;
111 const char *name;
112 void (*InitAuth)(unsigned short len, char *name);
113 Xauth *(*GetAuth)(unsigned short len, char *name);
114 void (*GetXdmcpAuth)(
115 struct protoDisplay *pdpy,
116 unsigned short authorizationNameLen,
117 char *authorizationName);
118 int inited;
119};
120
121static struct AuthProtocol AuthProtocols[] = {
122{ (unsigned short) 18, "MIT-MAGIC-COOKIE-1",
123 MitInitAuth, MitGetAuth, NULL((void*)0)
124},
125#ifdef HASXDMAUTH1
126{ (unsigned short) 19, "XDM-AUTHORIZATION-1",
127 XdmInitAuth, XdmGetAuth, XdmGetXdmcpAuth,
128},
129#endif
130#ifdef SECURE_RPC
131{ (unsigned short) 9, "SUN-DES-1",
132 SecureRPCInitAuth, SecureRPCGetAuth, NULL((void*)0),
133},
134#endif
135#ifdef K5AUTH
136{ (unsigned short) 14, "MIT-KERBEROS-5",
137 Krb5InitAuth, Krb5GetAuth, NULL((void*)0),
138},
139#endif
140};
141
142#define NUM_AUTHORIZATION(sizeof (AuthProtocols) / sizeof (AuthProtocols[0])) (sizeof (AuthProtocols) / sizeof (AuthProtocols[0]))
143
144static struct AuthProtocol *
145findProtocol (unsigned short name_length, char *name)
146{
147 int i;
148
149 for (i = 0; i < NUM_AUTHORIZATION(sizeof (AuthProtocols) / sizeof (AuthProtocols[0])); i++)
150 if (AuthProtocols[i].name_length == name_length &&
151 memcmp(AuthProtocols[i].name, name, name_length) == 0)
152 {
153 return &AuthProtocols[i];
154 }
155 return (struct AuthProtocol *) 0;
156}
157
158int
159ValidAuthorization (unsigned short name_length, char *name)
160{
161 if (findProtocol (name_length, name))
162 return TRUE1;
163 return FALSE0;
164}
165
166static Xauth *
167GenerateAuthorization (unsigned short name_length, char *name)
168{
169 struct AuthProtocol *a;
170 Xauth *auth = NULL((void*)0);
171 int i;
172
173 Debug ("GenerateAuthorization %*.*s\n",
174 name_length, name_length, name);
175 a = findProtocol (name_length, name);
176 if (a)
177 {
178 if (!a->inited)
179 {
180 (*a->InitAuth) (name_length, name);
181 a->inited = TRUE1;
182 }
183 auth = (*a->GetAuth) (name_length, name);
184 if (auth)
185 {
186 Debug ("Got %p (%d %*.*s) ", auth,
187 auth->name_length, auth->name_length,
188 auth->name_length, auth->name);
189 for (i = 0; i < (int)auth->data_length; i++)
190 Debug (" %02x", auth->data[i] & 0xff);
191 Debug ("\n");
192 }
193 else
194 Debug ("Got (null)\n");
195 }
196 else
197 {
198 Debug ("Unknown authorization %*.*s\n", name_length, name_length, name);
199 }
200 return auth;
201}
202
203#ifdef XDMCP
204
205void
206SetProtoDisplayAuthorization (
207 struct protoDisplay *pdpy,
208 unsigned short authorizationNameLen,
209 char *authorizationName)
210{
211 struct AuthProtocol *a;
212 Xauth *auth;
213
214 a = findProtocol (authorizationNameLen, authorizationName);
215 pdpy->xdmcpAuthorization = pdpy->fileAuthorization = NULL((void*)0);
216 if (a)
217 {
218 if (!a->inited)
219 {
220 (*a->InitAuth) (authorizationNameLen, authorizationName);
221 a->inited = TRUE1;
222 }
223 if (a->GetXdmcpAuth)
224 {
225 (*a->GetXdmcpAuth) (pdpy, authorizationNameLen, authorizationName);
226 auth = pdpy->xdmcpAuthorization;
227 }
228 else
229 {
230 auth = (*a->GetAuth) (authorizationNameLen, authorizationName);
231 pdpy->fileAuthorization = auth;
232 pdpy->xdmcpAuthorization = NULL((void*)0);
233 }
234 if (auth)
235 Debug ("Got %p (%d %*.*s)\n", auth,
236 auth->name_length, auth->name_length,
237 auth->name_length, auth->name);
238 else
239 Debug ("Got (null)\n");
240 }
241}
242
243#endif /* XDMCP */
244
245void
246CleanUpFileName (char *src, char *dst, int len)
247{
248 while (*src) {
249 if (--len <= 0)
250 break;
251 switch (*src & 0x7f)
252 {
253 case '/':
254 *dst++ = '_';
255 break;
256 case '-':
257 *dst++ = '.';
258 break;
259 default:
260 *dst++ = (*src & 0x7f);
261 }
262 ++src;
263 }
264 *dst = '\0';
265}
266
267/* Checks to see if specified directory exists, makes it if not
268 * Returns: 0 if already exists, 1 if created, < 0 if error occured
269 */
270static int
271CheckServerAuthDir (const char *path, struct stat *statb, int mode)
272{
273 int r = stat(path, statb);
274
275 if (r != 0) {
276 if (errno(*__error()) == ENOENT2) {
277 r = mkdir(path, mode);
278 if (r < 0) {
279 LogError ("cannot make authentication directory %s: %s\n",
280 path, _SysErrorMsg (errno(*__error())));
281 } else {
282 r = 1;
283 }
284 } else {
285 LogError ("cannot access authentication directory %s: %s\n",
286 path, _SysErrorMsg (errno(*__error())));
287 }
288 } else { /* Directory already exists */
289 if (!S_ISDIR(statb->st_mode)(((statb->st_mode) & 0170000) == 0040000)) {
290 LogError ("cannot make authentication directory %s: %s\n",
291 path, "file with that name already exists");
292 return -1;
293 }
294 }
295
296 return r;
297}
298
299static char authdir1[] = "authdir";
300static char authdir2[] = "authfiles";
301
302static int
303MakeServerAuthFile (struct display *d, FILE ** file)
304{
305 int len;
306#ifdef MAXNAMELEN
307# define NAMELEN255 MAXNAMELEN
308#else
309# define NAMELEN255 255
310#endif
311 char cleanname[NAMELEN255];
312 int r;
313#ifdef HAVE_MKSTEMP1
314 int fd;
315#endif
316 struct stat statb;
317
318 *file = NULL((void*)0);
319
320 if (!d->authFile) {
321 if (d->clientAuthFile && *d->clientAuthFile) {
322 d->authFile = strdup(d->clientAuthFile);
323 if (!d->authFile)
324 return FALSE0;
325 } else {
326 CleanUpFileName (d->name, cleanname, NAMELEN255 - 8);
327
328 /* Make authDir if it doesn't already exist */
329 r = CheckServerAuthDir(authDir, &statb, 0755);
330 if (r < 0) {
331 return FALSE0;
332 }
333
334 len = strlen (authDir) + strlen (authdir1) + strlen (authdir2)
335 + strlen (cleanname) + 14;
336 d->authFile = malloc (len);
337 if (!d->authFile)
338 return FALSE0;
339
340 snprintf (d->authFile, len, "%s/%s", authDir, authdir1)__builtin___snprintf_chk (d->authFile, len, 0, __builtin_object_size
(d->authFile, 2 > 1 ? 1 : 0), "%s/%s", authDir, authdir1
)
;
341 r = CheckServerAuthDir(d->authFile, &statb, 0700);
342 if (r == 0) {
343 if (statb.st_uid != 0)
344 (void) chown(d->authFile, 0, statb.st_gid);
345 if ((statb.st_mode & 0077) != 0)
346 (void) chmod(d->authFile, statb.st_mode & 0700);
347 } else if (r < 0) {
348 free (d->authFile);
349 d->authFile = NULL((void*)0);
350 return FALSE0;
351 }
352
353 snprintf (d->authFile, len, "%s/%s/%s",__builtin___snprintf_chk (d->authFile, len, 0, __builtin_object_size
(d->authFile, 2 > 1 ? 1 : 0), "%s/%s/%s", authDir, authdir1
, authdir2)
354 authDir, authdir1, authdir2)__builtin___snprintf_chk (d->authFile, len, 0, __builtin_object_size
(d->authFile, 2 > 1 ? 1 : 0), "%s/%s/%s", authDir, authdir1
, authdir2)
;
355 r = CheckServerAuthDir(d->authFile, &statb, 0700);
356 if (r < 0) {
357 free (d->authFile);
358 d->authFile = NULL((void*)0);
359 return FALSE0;
360 }
361 snprintf (d->authFile, len, "%s/%s/%s/A%s-XXXXXX",__builtin___snprintf_chk (d->authFile, len, 0, __builtin_object_size
(d->authFile, 2 > 1 ? 1 : 0), "%s/%s/%s/A%s-XXXXXX", authDir
, authdir1, authdir2, cleanname)
362 authDir, authdir1, authdir2, cleanname)__builtin___snprintf_chk (d->authFile, len, 0, __builtin_object_size
(d->authFile, 2 > 1 ? 1 : 0), "%s/%s/%s/A%s-XXXXXX", authDir
, authdir1, authdir2, cleanname)
;
363#ifdef HAVE_MKSTEMP1
364 fd = mkstemp (d->authFile);
365 if (fd < 0) {
366 LogError ("cannot make authentication file %s: %s\n",
367 d->authFile, _SysErrorMsg (errno(*__error())));
368 free (d->authFile);
369 d->authFile = NULL((void*)0);
370 return FALSE0;
371 }
372
373 *file = fdopen(fd, "w");
374 if (!*file)
375 (void) close (fd);
376 return TRUE1;
377#else
378 (void) mktemp (d->authFile);
379#endif
380 }
381 }
382
383 (void) unlink (d->authFile);
384 *file = fopen (d->authFile, "w");
385 return TRUE1;
386}
387
388int
389SaveServerAuthorizations (
390 struct display *d,
391 Xauth **auths,
392 int count)
393{
394 FILE *auth_file;
395 mode_t mask;
396 int ret;
397 int i;
398 const char dummy_auth[] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
399 "XXXXXXXXXXXXXXXXX"; /* 64 "X"s */
400 int err = 0;
401
402 mask = umask (0077);
403 ret = MakeServerAuthFile(d, &auth_file);
404 umask (mask);
405 if (!ret)
406 return FALSE0;
407 if (!auth_file) {
408 LogError ("cannot open server authorization file %s: %s\n",
409 d->authFile, _SysErrorMsg (errno(*__error())));
410 ret = FALSE0;
411 }
412 else
413 {
414 Debug ("File: %s auth: %p\n", d->authFile, auths);
415 ret = TRUE1;
416 if (count == 0)
417 {
418 /*
419 * This is a crude hack to determine whether we really can
420 * write to the auth file even if we don't have real data
421 * to write right now.
422 */
423
424 /*
425 * Write garbage data to file to provoke ENOSPC and other
426 * errors.
427 */
428 (void) fprintf (auth_file, "%s", dummy_auth);
429 (void) fflush (auth_file);
430 if (ferror (auth_file))
431 {
432 err = errno(*__error());
433 ret = FALSE0;
434 }
435 /*
436 * Rewind so that the garbage data is overwritten later.
437 */
438 rewind(auth_file);
439 }
440 for (i = 0; i < count; i++)
441 {
442 /*
443 * User-based auths may not have data until
444 * a user logs in. In which case don't write
445 * to the auth file so xrdb and setup programs don't fail.
446 */
447 if (auths[i]->data_length > 0)
448 if (!XauWriteAuth (auth_file, auths[i]))
449 {
450 Debug ("XauWriteAuth() failed\n");
451 }
452 (void) fflush (auth_file);
453 if (ferror (auth_file))
454 {
455 err = errno(*__error());
456 ret = FALSE0;
457 }
458 }
459 /*
460 * XXX: This is not elegant, but stdio has no truncation function.
461 */
462 if (ftruncate(fileno(auth_file), ftell(auth_file)))
463 {
464 Debug ("ftruncate() failed\n");
465 }
466 fclose (auth_file);
467
468 }
469 if (ret == FALSE0)
470 {
471 LogError ("Cannot write to server authorization file %s%s%s\n",
472 d->authFile,
473 err ? ": " : "",
474 err ? _SysErrorMsg (errno(*__error())) : "");
475 free (d->authFile);
476 d->authFile = NULL((void*)0);
477 }
478 return ret;
479}
480
481void
482SetLocalAuthorization (struct display *d)
483{
484 Xauth *auth, **auths;
485 int i, j;
486
487 if (d->authorizations)
1
Taking false branch
488 {
489 for (i = 0; i < d->authNum; i++)
490 XauDisposeAuth (d->authorizations[i]);
491 free (d->authorizations);
492 d->authorizations = (Xauth **) NULL((void*)0);
493 d->authNum = 0;
494 }
495 if (!d->authNames)
2
Taking false branch
496 return;
497 for (i = 0; d->authNames[i]; i++)
3
Loop condition is false. Execution continues on line 499
498 ;
499 d->authNameNum = i;
500 free (d->authNameLens);
501 d->authNameLens = malloc (d->authNameNum * sizeof (unsigned short));
4
Call to 'malloc' has an allocation size of 0 bytes
502 if (!d->authNameLens)
503 return;
504 for (i = 0; i < d->authNameNum; i++)
505 d->authNameLens[i] = strlen (d->authNames[i]);
506 auths = malloc (d->authNameNum * sizeof (Xauth *));
507 if (!auths)
508 return;
509 j = 0;
510 for (i = 0; i < d->authNameNum; i++)
511 {
512 auth = GenerateAuthorization (d->authNameLens[i], d->authNames[i]);
513 if (auth)
514 auths[j++] = auth;
515 }
516 if (SaveServerAuthorizations (d, auths, j))
517 {
518 d->authorizations = auths;
519 d->authNum = j;
520 }
521 else
522 {
523 for (i = 0; i < j; i++)
524 XauDisposeAuth (auths[i]);
525 free (auths);
526 }
527}
528
529/*
530 * Set the authorization to use for xdm's initial connection
531 * to the X server. Cannot use user-based authorizations
532 * because no one has logged in yet, so we don't have any
533 * user credentials.
534 * Well, actually we could use SUN-DES-1 because we tell the server
535 * to allow root in. This is bogus and should be fixed.
536 */
537void
538SetAuthorization (struct display *d)
539{
540 register Xauth **auth = d->authorizations;
541 int i;
542
543 for (i = 0; i < d->authNum; i++)
544 {
545 if (auth[i]->name_length == 9 &&
546 memcmp(auth[i]->name, "SUN-DES-1", 9) == 0)
547 continue;
548 if (auth[i]->name_length == 14 &&
549 memcmp(auth[i]->name, "MIT-KERBEROS-5", 14) == 0)
550 continue;
551 XSetAuthorization (auth[i]->name, (int) auth[i]->name_length,
552 auth[i]->data, (int) auth[i]->data_length);
553 }
554}
555
556static int
557openFiles (char *name, char *new_name, FILE **oldp, FILE **newp)
558{
559 mode_t mask;
560 int newfd;
561
562 strcpy (new_name, name)__builtin___strcpy_chk (new_name, name, __builtin_object_size
(new_name, 2 > 1 ? 1 : 0))
;
563 strcat (new_name, "-n")__builtin___strcat_chk (new_name, "-n", __builtin_object_size
(new_name, 2 > 1 ? 1 : 0))
;
564 /*
565 * Set safe umask for file creation operations.
566 */
567 mask = umask (0077);
568 /*
569 * Unlink the authorization file we intend to create, and then open
570 * it with O_CREAT | O_EXCL to avoid race-based symlink attacks.
571 */
572 (void) unlink (new_name);
573 newfd = open (new_name, O_WRONLY0x0001 | O_CREAT0x0200 | O_EXCL0x0800, 0600);
574 if (newfd >= 0) {
575 *newp = fdopen (newfd, "w");
576 if (*newp == NULL((void*)0))
577 close(newfd);
578 }
579 else
580 {
581 LogError ("Cannot create file %s: %s\n", new_name,
582 _SysErrorMsg (errno(*__error())));
583 *newp = NULL((void*)0);
584 }
585 /*
586 * There are no more attempts to create files after this point;
587 * restore the original umask.
588 */
589 (void) umask (mask);
590 if (!*newp) {
591 Debug ("can't open new file %s\n", new_name);
592 return 0;
593 }
594 if (!*oldp)
595 *oldp = fopen (name, "r");
596 Debug ("opens succeeded %s %s\n", name, new_name);
597 return 1;
598}
599
600static int
601binaryEqual (char *a, char *b, unsigned short len)
602{
603 while (len-- > 0)
604 if (*a++ != *b++)
605 return FALSE0;
606 return TRUE1;
607}
608
609static void
610dumpBytes (unsigned short len, char *data)
611{
612 unsigned short i;
613
614 Debug ("%d: ", len);
615 for (i = 0; i < len; i++)
616 Debug ("%02x ", data[i] & 0377);
617 Debug ("\n");
618}
619
620static void
621dumpAuth (Xauth *auth)
622{
623 Debug ("family: %d\n", auth->family);
624 Debug ("addr: ");
625 dumpBytes (auth->address_length, auth->address);
626 Debug ("number: ");
627 dumpBytes (auth->number_length, auth->number);
628 Debug ("name: ");
629 dumpBytes (auth->name_length, auth->name);
630 Debug ("data: ");
631 dumpBytes (auth->data_length, auth->data);
632}
633
634struct addrList {
635 unsigned short family;
636 unsigned short address_length;
637 char *address;
638 unsigned short number_length;
639 char *number;
640 unsigned short name_length;
641 char *name;
642 struct addrList *next;
643};
644
645static struct addrList *addrs;
646
647static void
648initAddrs (void)
649{
650 addrs = NULL((void*)0);
651}
652
653static void
654doneAddrs (void)
655{
656 struct addrList *a, *n;
657 for (a = addrs; a; a = n) {
658 n = a->next;
659 free (a->address);
660 free (a->number);
661 free (a);
662 }
663}
664
665static int checkEntry (Xauth *auth);
666
667static void
668saveEntry (Xauth *auth)
669{
670 struct addrList *new;
671
672 new = malloc (sizeof (struct addrList));
673 if (!new) {
674 LogOutOfMem ("saveEntry");
675 return;
676 }
677 if ((new->address_length = auth->address_length) > 0) {
678 new->address = malloc (auth->address_length);
679 if (!new->address) {
680 LogOutOfMem ("saveEntry");
681 free (new);
682 return;
683 }
684 memmove( new->address, auth->address, (int) auth->address_length)__builtin___memmove_chk (new->address, auth->address, (
int) auth->address_length, __builtin_object_size (new->
address, 0))
;
685 } else
686 new->address = NULL((void*)0);
687 if ((new->number_length = auth->number_length) > 0) {
688 new->number = malloc (auth->number_length);
689 if (!new->number) {
690 LogOutOfMem ("saveEntry");
691 free (new->address);
692 free (new);
693 return;
694 }
695 memmove( new->number, auth->number, (int) auth->number_length)__builtin___memmove_chk (new->number, auth->number, (int
) auth->number_length, __builtin_object_size (new->number
, 0))
;
696 } else
697 new->number = NULL((void*)0);
698 if ((new->name_length = auth->name_length) > 0) {
699 new->name = malloc (auth->name_length);
700 if (!new->name) {
701 LogOutOfMem ("saveEntry");
702 free (new->number);
703 free (new->address);
704 free (new);
705 return;
706 }
707 memmove( new->name, auth->name, (int) auth->name_length)__builtin___memmove_chk (new->name, auth->name, (int) auth
->name_length, __builtin_object_size (new->name, 0))
;
708 } else
709 new->name = NULL((void*)0);
710 new->family = auth->family;
711 new->next = addrs;
712 addrs = new;
713}
714
715static int
716checkEntry (Xauth *auth)
717{
718 struct addrList *a;
719
720 for (a = addrs; a; a = a->next) {
721 if (a->family == auth->family &&
722 a->address_length == auth->address_length &&
723 binaryEqual (a->address, auth->address, auth->address_length) &&
724 a->number_length == auth->number_length &&
725 binaryEqual (a->number, auth->number, auth->number_length) &&
726 a->name_length == auth->name_length &&
727 binaryEqual (a->name, auth->name, auth->name_length))
728 {
729 return 1;
730 }
731 }
732 return 0;
733}
734
735static int doWrite;
736
737static void
738writeAuth (FILE *file, Xauth *auth)
739{
740 if (debugLevel >= 15) { /* normally too verbose */
741 Debug ("writeAuth: doWrite = %d\n", doWrite);
742 dumpAuth (auth); /* does Debug only */
743 }
744 if (doWrite)
745 XauWriteAuth (file, auth);
746}
747
748static void
749writeAddr (
750 int family,
751 int addr_length,
752 char *addr,
753 FILE *file,
754 Xauth *auth)
755{
756 auth->family = (unsigned short) family;
757 auth->address_length = addr_length;
758 auth->address = addr;
759 Debug ("writeAddr: writing and saving an entry\n");
760 writeAuth (file, auth);
761 saveEntry (auth);
762}
763
764static void
765DefineLocal (FILE *file, Xauth *auth)
766{
767 char displayname[100];
768 int len = _XGetHostname (displayname, sizeof(displayname));
769
770/* Make sure this produces the same string as _XGetHostname in lib/X/XlibInt.c.
771 * Otherwise, Xau will not be able to find your cookies in the Xauthority file.
772 *
773 * Note: POSIX says that the ``nodename'' member of utsname does _not_ have
774 * to have sufficient information for interfacing to the network,
775 * and so, you may be better off using gethostname (if it exists).
776 */
777
778#if defined(hpux)
779 /*
780 * For HP-UX, HP's Xlib expects a fully-qualified domain name, which
781 * is achieved by using gethostname(). For compatability, we must
782 * also still create the entry using uname().
783 */
784 char tmp_displayname[100];
785 struct utsname name;
786
787 tmp_displayname[0] = 0;
788 uname(&name);
789 snprintf(tmp_displayname, sizeof(tmp_displayname), "%s", name.nodename)__builtin___snprintf_chk (tmp_displayname, sizeof(tmp_displayname
), 0, __builtin_object_size (tmp_displayname, 2 > 1 ? 1 : 0
), "%s", name.nodename)
;
790 writeAddr (FamilyLocal(256), strlen (tmp_displayname), tmp_displayname,
791 file, auth);
792
793 /*
794 * If _XGetHostname() returned the same value as uname(), don't
795 * write a duplicate entry.
796 */
797 if (strcmp (displayname, tmp_displayname))
798#endif
799
800 writeAddr (FamilyLocal(256), len, displayname, file, auth);
801}
802
803#ifdef HAVE_GETIFADDRS1
804# include <ifaddrs.h>
805
806static void
807DefineSelf(int fd, FILE *file, Xauth *auth)
808{
809 struct ifaddrs *ifap, *ifr;
810 char *addr;
811 int family, len;
812
813 Debug("DefineSelf\n");
814 if (getifaddrs(&ifap) < 0)
815 return;
816 for (ifr = ifap; ifr != NULL((void*)0); ifr = ifr->ifa_next) {
817 len = sizeof(*(ifr->ifa_addr));
818 family = ConvertAddr((XdmcpNetaddr)(ifr->ifa_addr), &len, &addr);
819 if (family == -1 || family == FamilyLocal(256))
820 continue;
821 /*
822 * don't write out 'localhost' entries, as
823 * they may conflict with other local entries.
824 * DefineLocal will always be called to add
825 * the local entry anyway, so this one can
826 * be tossed.
827 */
828 if (family == FamilyInternet0 && len == 4 && addr[0] == 127)
829 {
830 Debug ("Skipping localhost address\n");
831 continue;
832 }
833# if defined(IPv61) && defined(AF_INET630)
834 if(family == FamilyInternet66) {
835 if (IN6_IS_ADDR_LOOPBACK(((struct in6_addr *)addr))((*(const __uint32_t *)(const void *)(&(((struct in6_addr
*)addr))->__u6_addr.__u6_addr8[0]) == 0) && (*(const
__uint32_t *)(const void *)(&(((struct in6_addr *)addr))
->__u6_addr.__u6_addr8[4]) == 0) && (*(const __uint32_t
*)(const void *)(&(((struct in6_addr *)addr))->__u6_addr
.__u6_addr8[8]) == 0) && (*(const __uint32_t *)(const
void *)(&(((struct in6_addr *)addr))->__u6_addr.__u6_addr8
[12]) == (__builtin_constant_p(1) ? ((__uint32_t)((((__uint32_t
)(1) & 0xff000000) >> 24) | (((__uint32_t)(1) &
0x00ff0000) >> 8) | (((__uint32_t)(1) & 0x0000ff00
) << 8) | (((__uint32_t)(1) & 0x000000ff) << 24
))) : _OSSwapInt32(1))))
) {
836 Debug ("Skipping IPv6 localhost address\n");
837 continue;
838 }
839 /* Also skip XDM-AUTHORIZATION-1 */
840 if (auth->name_length == 19 &&
841 strcmp(auth->name, "XDM-AUTHORIZATION-1") == 0) {
842 Debug ("Skipping IPv6 XDM-AUTHORIZATION-1\n");
843 continue;
844 }
845 }
846# endif
847 writeAddr(family, len, addr, file, auth);
848 }
849 freeifaddrs(ifap);
850 Debug("DefineSelf done\n");
851}
852#else /* GETIFADDRS */
853
854# ifdef SYSV_SIOCGIFCONF
855
856/* Deal with different SIOCGIFCONF ioctl semantics on SYSV, SVR4 */
857
858static int
859ifioctl (int fd, int cmd, char *arg)
860{
861 struct strioctl ioc;
862 int ret;
863
864 bzero((char *) &ioc, sizeof(ioc))__builtin___memset_chk ((char *) &ioc, 0, sizeof(ioc), __builtin_object_size
((char *) &ioc, 0))
;
865 ioc.ic_cmd = cmd;
866 ioc.ic_timout = 0;
867 if (cmd == SIOCGIFCONF(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifconf) & 0x1fff) << 16) | ((('i')) << 8) | (
(36)))
)
868 {
869 ioc.ic_len = ((struct ifconf *) arg)->ifc_len;
870 ioc.ic_dp = ((struct ifconf *) arg)->ifc_bufifc_ifcu.ifcu_buf;
871 }
872 else
873 {
874 ioc.ic_len = sizeof(struct ifreq);
875 ioc.ic_dp = arg;
876 }
877 ret = ioctl(fd, I_STR, (char *) &ioc);
878 if (ret >= 0 && cmd == SIOCGIFCONF(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifconf) & 0x1fff) << 16) | ((('i')) << 8) | (
(36)))
)
879 ((struct ifconf *) arg)->ifc_len = ioc.ic_len;
880 return(ret);
881}
882# else /* SYSV_SIOCGIFCONF */
883# define ifioctl ioctl
884# endif /* SYSV_SIOCGIFCONF */
885
886
887
888# if defined(SIOCGIFCONF(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifconf) & 0x1fff) << 16) | ((('i')) << 8) | (
(36)))
) || defined (USE_SIOCGLIFCONF)
889
890# ifdef USE_SIOCGLIFCONF
891# define ifr_type struct lifreq
892# else
893# define ifr_type struct ifreq
894# endif
895
896/* Handle variable length ifreq in BNR2 and later */
897# ifdef VARIABLE_IFREQ
898# define ifr_size(p) (sizeof (struct ifreq) + \
899 (p->ifr_addrifr_ifru.ifru_addr.sa_len > sizeof (p->ifr_addrifr_ifru.ifru_addr) ? \
900 p->ifr_addrifr_ifru.ifru_addr.sa_len - sizeof (p->ifr_addrifr_ifru.ifru_addr) : 0))
901# else
902# define ifr_size(p) (sizeof (ifr_type))
903# endif
904
905/* Define this host for access control. Find all the hosts the OS knows about
906 * for this fd and add them to the selfhosts list.
907 */
908static void
909DefineSelf (int fd, FILE *file, Xauth *auth)
910{
911 char buf[2048], *cp, *cplim;
912 int len;
913 char *addr;
914 int family;
915 register ifr_type *ifr;
916# ifdef USE_SIOCGLIFCONF
917 void * bufptr = buf;
918 size_t buflen = sizeof(buf);
919 struct lifconf ifc;
920# ifdef SIOCGLIFNUM
921 struct lifnum ifn;
922# endif
923# else
924 struct ifconf ifc;
925# endif
926
927# if defined(SIOCGLIFNUM) && defined(SIOCGLIFCONF)
928 ifn.lifn_family = AF_UNSPEC0;
929 ifn.lifn_flags = 0;
930 if (ioctl (fd, (int) SIOCGLIFNUM, (char *) &ifn) < 0)
931 LogError ("Failed getting interface count");
932 if (buflen < (ifn.lifn_count * sizeof(struct lifreq))) {
933 buflen = ifn.lifn_count * sizeof(struct lifreq);
934 bufptr = malloc(buflen);
935 }
936# endif
937
938# ifdef USE_SIOCGLIFCONF
939 ifc.lifc_family = AF_UNSPEC0;
940 ifc.lifc_flags = 0;
941 ifc.lifc_len = buflen;
942 ifc.lifc_buf = bufptr;
943
944# define IFC_IOCTL_REQ SIOCGLIFCONF
945# define IFC_IFC_REQ ifc.lifc_req
946# define IFC_IFC_LEN ifc.lifc_len
947# define IFR_IFR_ADDR ifr->lifr_addr
948# define IFR_IFR_NAME ifr->lifr_name
949
950# else
951 ifc.ifc_len = sizeof (buf);
952 ifc.ifc_bufifc_ifcu.ifcu_buf = buf;
953
954# define IFC_IOCTL_REQ SIOCGIFCONF(((__uint32_t)0x80000000|(__uint32_t)0x40000000) | ((sizeof(struct
ifconf) & 0x1fff) << 16) | ((('i')) << 8) | (
(36)))
955# define IFC_IFC_REQ ifc.ifc_reqifc_ifcu.ifcu_req
956# define IFC_IFC_LEN ifc.ifc_len
957# define IFR_IFR_ADDR ifr->ifr_addrifr_ifru.ifru_addr
958# define IFR_IFR_NAME ifr->ifr_name
959# endif
960
961 if (ifioctl (fd, IFC_IOCTL_REQ, (char *) &ifc) < 0) {
962 LogError ("Trouble getting network interface configuration");
963
964# ifdef USE_SIOCGLIFCONF
965 if (bufptr != buf) {
966 free(bufptr);
967 }
968# endif
969 return;
970 }
971
972 cplim = (char *) IFC_IFC_REQ + IFC_IFC_LEN;
973
974 for (cp = (char *) IFC_IFC_REQ; cp < cplim; cp += ifr_size (ifr))
975 {
976 ifr = (ifr_type *) cp;
977 family = ConvertAddr ((XdmcpNetaddr) &IFR_IFR_ADDR, &len, &addr);
978 if (family < 0)
979 continue;
980
981 if (len == 0)
982 {
983 Debug ("Skipping zero length address\n");
984 continue;
985 }
986 /*
987 * don't write out 'localhost' entries, as
988 * they may conflict with other local entries.
989 * DefineLocal will always be called to add
990 * the local entry anyway, so this one can
991 * be tossed.
992 */
993 if (family == FamilyInternet0 && len == 4 &&
994 addr[0] == 127 && addr[1] == 0 &&
995 addr[2] == 0 && addr[3] == 1)
996 {
997 Debug ("Skipping localhost address\n");
998 continue;
999 }
1000# if defined(IPv61) && defined(AF_INET630)
1001 if (family == FamilyInternet66) {
1002 if (IN6_IS_ADDR_LOOPBACK(((struct in6_addr *)addr))((*(const __uint32_t *)(const void *)(&(((struct in6_addr
*)addr))->__u6_addr.__u6_addr8[0]) == 0) && (*(const
__uint32_t *)(const void *)(&(((struct in6_addr *)addr))
->__u6_addr.__u6_addr8[4]) == 0) && (*(const __uint32_t
*)(const void *)(&(((struct in6_addr *)addr))->__u6_addr
.__u6_addr8[8]) == 0) && (*(const __uint32_t *)(const
void *)(&(((struct in6_addr *)addr))->__u6_addr.__u6_addr8
[12]) == (__builtin_constant_p(1) ? ((__uint32_t)((((__uint32_t
)(1) & 0xff000000) >> 24) | (((__uint32_t)(1) &
0x00ff0000) >> 8) | (((__uint32_t)(1) & 0x0000ff00
) << 8) | (((__uint32_t)(1) & 0x000000ff) << 24
))) : _OSSwapInt32(1))))
) {
1003 Debug ("Skipping IPv6 localhost address\n");
1004 continue;
1005 }
1006 /* Also skip XDM-AUTHORIZATION-1 */
1007 if (auth->name_length == 19 &&
1008 strcmp(auth->name, "XDM-AUTHORIZATION-1") == 0) {
1009 Debug ("Skipping IPv6 XDM-AUTHORIZATION-1\n");
1010 continue;
1011 }
1012 }
1013# endif
1014 Debug ("DefineSelf: write network address, length %d\n", len);
1015 writeAddr (family, len, addr, file, auth);
1016 }
1017}
1018
1019# else /* SIOCGIFCONF */
1020
1021/* Define this host for access control. Find all the hosts the OS knows about
1022 * for this fd and add them to the selfhosts list.
1023 */
1024static void
1025DefineSelf (int fd, int file, int auth)
1026{
1027 register int n;
1028 int len;
1029 caddr_t addr;
1030 int family;
1031
1032 struct utsname name;
1033 register struct hostent *hp;
1034
1035 union {
1036 struct sockaddr sa;
1037 struct sockaddr_in in;
1038 } saddr;
1039
1040 struct sockaddr_in *inetaddr;
1041
1042 /* hpux:
1043 * Why not use gethostname()? Well, at least on my system, I've had to
1044 * make an ugly kernel patch to get a name longer than 8 characters, and
1045 * uname() lets me access to the whole string (it smashes release, you
1046 * see), whereas gethostname() kindly truncates it for me.
1047 */
1048 uname(&name);
1049 hp = gethostbyname (name.nodename);
1050 if (hp != NULL((void*)0)) {
1051 saddr.sa.sa_family = hp->h_addrtype;
1052 inetaddr = (struct sockaddr_in *) (&(saddr.sa));
1053 memmove( (char *) &(inetaddr->sin_addr), (char *) hp->h_addr, (int) hp->h_length)__builtin___memmove_chk ((char *) &(inetaddr->sin_addr
), (char *) hp->h_addr, (int) hp->h_length, __builtin_object_size
((char *) &(inetaddr->sin_addr), 0))
;
1054 family = ConvertAddr ( &(saddr.sa), &len, &addr);
1055 if ( family >= 0) {
1056 writeAddr (FamilyInternet0, sizeof (inetaddr->sin_addr),
1057 (char *) (&inetaddr->sin_addr), file, auth);
1058 }
1059 }
1060}
1061
1062
1063# endif /* SIOCGIFCONF else */
1064#endif /* HAVE_GETIFADDRS */
1065
1066static void
1067setAuthNumber (Xauth *auth, char *name)
1068{
1069 char *colon;
1070 char *dot, *number;
1071
1072 Debug ("setAuthNumber %s\n", name);
1073 colon = strrchr(name, ':');
1074 if (colon) {
1075 ++colon;
1076 dot = strchr(colon, '.');
1077 if (dot)
1078 auth->number_length = dot - colon;
1079 else
1080 auth->number_length = strlen (colon);
1081 number = malloc (auth->number_length + 1);
1082 if (number) {
1083 strncpy (number, colon, auth->number_length)__builtin___strncpy_chk (number, colon, auth->number_length
, __builtin_object_size (number, 2 > 1 ? 1 : 0))
;
1084 number[auth->number_length] = '\0';
1085 } else {
1086 LogOutOfMem ("setAuthNumber");
1087 auth->number_length = 0;
1088 }
1089 auth->number = number;
1090 Debug ("setAuthNumber: %s\n", number);
1091 }
1092}
1093
1094static void
1095writeLocalAuth (FILE *file, Xauth *auth, char *name)
1096{
1097 int fd;
1098
1099 Debug ("writeLocalAuth: %s %.*s\n", name, auth->name_length, auth->name);
1100 setAuthNumber (auth, name);
1101#ifdef TCPCONN1
1102# if defined(IPv61) && defined(AF_INET630)
1103 fd = socket (AF_INET630, SOCK_STREAM1, 0);
1104 if (fd < 0)
1105# endif
1106 fd = socket (AF_INET2, SOCK_STREAM1, 0);
1107 DefineSelf (fd, file, auth);
1108 close (fd);
1109#endif
1110 DefineLocal (file, auth);
1111}
1112
1113#ifdef XDMCP
1114
1115static void
1116writeRemoteAuth (FILE *file, Xauth *auth, XdmcpNetaddr peer, int peerlen, char *name)
1117{
1118 int family = FamilyLocal(256);
1119 char *addr;
1120
1121 Debug ("writeRemoteAuth: %s %.*s\n", name, auth->name_length, auth->name);
1122 if (!peer || peerlen < 2)
1123 return;
1124 setAuthNumber (auth, name);
1125 family = ConvertAddr (peer, &peerlen, &addr);
1126 Debug ("writeRemoteAuth: family %d\n", family);
1127 if (family != FamilyLocal(256))
1128 {
1129 Debug ("writeRemoteAuth: %d, %d, %x\n",
1130 family, peerlen, *(int *)addr);
1131 writeAddr (family, peerlen, addr, file, auth);
1132 }
1133 else
1134 {
1135 writeLocalAuth (file, auth, name);
1136 }
1137}
1138
1139#endif /* XDMCP */
1140
1141void
1142SetUserAuthorization (struct display *d, struct verify_info *verify)
1143{
1144 FILE *old = NULL((void*)0), *new;
1145 char home_name[1024], backup_name[1024], new_name[1024];
1146 char *name = NULL((void*)0);
1147 char *home;
1148 char *envname = NULL((void*)0);
1149 int lockStatus;
1150 Xauth *entry, **auths;
1151 int setenv = 0;
1152 struct stat statb;
1153 int i;
1154 int magicCookie;
1155 int data_len;
1156#ifdef HAVE_MKSTEMP1
1157 int fd;
1158#endif
1159
1160 Debug ("SetUserAuthorization\n");
1161 auths = d->authorizations;
1162 if (auths) {
1163 home = getEnv (verify->userEnviron, "HOME");
1164 lockStatus = LOCK_ERROR1;
1165 if (home) {
1166 snprintf (home_name, sizeof(home_name), "%s/.Xauthority", home)__builtin___snprintf_chk (home_name, sizeof(home_name), 0, __builtin_object_size
(home_name, 2 > 1 ? 1 : 0), "%s/.Xauthority", home)
;
1167 Debug ("XauLockAuth %s\n", home_name);
1168 lockStatus = XauLockAuth (home_name, 1, 2, 10);
1169 Debug ("Lock is %d\n", lockStatus);
1170 if (lockStatus == LOCK_SUCCESS0) {
1171 if (openFiles (home_name, new_name, &old, &new)
1172 && (old != NULL((void*)0)) && (new != NULL((void*)0))) {
1173 name = home_name;
1174 setenv = 0;
1175 } else {
1176 Debug ("openFiles failed\n");
1177 XauUnlockAuth (home_name);
1178 lockStatus = LOCK_ERROR1;
1179 if (old != NULL((void*)0)) {
1180 (void) fclose (old);
1181 old = NULL((void*)0);
1182 }
1183 if (new != NULL((void*)0))
1184 (void) fclose (new);
1185 }
1186 }
1187 }
1188 if (lockStatus != LOCK_SUCCESS0) {
1189 snprintf (backup_name, sizeof(backup_name),__builtin___snprintf_chk (backup_name, sizeof(backup_name), 0
, __builtin_object_size (backup_name, 2 > 1 ? 1 : 0), "%s/.XauthXXXXXX"
, d->userAuthDir)
1190 "%s/.XauthXXXXXX", d->userAuthDir)__builtin___snprintf_chk (backup_name, sizeof(backup_name), 0
, __builtin_object_size (backup_name, 2 > 1 ? 1 : 0), "%s/.XauthXXXXXX"
, d->userAuthDir)
;
1191#ifdef HAVE_MKSTEMP1
1192 fd = mkstemp (backup_name);
1193 if (fd >= 0) {
1194 old = fdopen (fd, "r");
1195 if (old == NULL((void*)0))
1196 (void) close(fd);
1197 }
1198
1199 if (old != NULL((void*)0))
1200#else
1201 (void) mktemp (backup_name);
1202#endif
1203 {
1204 lockStatus = XauLockAuth (backup_name, 1, 2, 10);
1205 Debug ("backup lock is %d\n", lockStatus);
1206 if (lockStatus == LOCK_SUCCESS0) {
1207 if (openFiles (backup_name, new_name, &old, &new)
1208 && (old != NULL((void*)0)) && (new != NULL((void*)0))) {
1209 name = backup_name;
1210 setenv = 1;
1211 } else {
1212 XauUnlockAuth (backup_name);
1213 lockStatus = LOCK_ERROR1;
1214 if (old != NULL((void*)0)) {
1215 (void) fclose (old);
1216 old = NULL((void*)0);
1217 }
1218 if (new != NULL((void*)0))
1219 (void) fclose (new);
1220 }
1221#ifdef HAVE_MKSTEMP1
1222 } else {
1223 (void) fclose (old);
1224#endif
1225 }
1226 }
1227 }
1228 if (lockStatus != LOCK_SUCCESS0) {
1229 Debug ("can't lock auth file %s or backup %s\n",
1230 home_name, backup_name);
1231 LogError ("can't lock authorization file %s or backup %s\n",
1232 home_name, backup_name);
1233 return;
1234 }
1235 initAddrs ();
1236 doWrite = 1;
1237 Debug ("%d authorization protocols for %s\n", d->authNum, d->name);
1238 /*
1239 * Write MIT-MAGIC-COOKIE-1 authorization first, so that
1240 * R4 clients which only knew that, and used the first
1241 * matching entry will continue to function
1242 */
1243 magicCookie = -1;
1244 for (i = 0; i < d->authNum; i++)
1245 {
1246 if (auths[i]->name_length == 18 &&
1247 !strncmp (auths[i]->name, "MIT-MAGIC-COOKIE-1", 18))
1248 {
1249 magicCookie = i;
1250 if (d->displayType.location == Local1)
1251 writeLocalAuth (new, auths[i], d->name);
1252#ifdef XDMCP
1253 else
1254 writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
1255#endif
1256 break;
1257 }
1258 }
1259 /* now write other authorizations */
1260 for (i = 0; i < d->authNum; i++)
1261 {
1262 if (i != magicCookie)
1263 {
1264 data_len = auths[i]->data_length;
1265 /* client will just use default Kerberos cache, so don't
1266 * even write cache info into the authority file.
1267 */
1268 if (auths[i]->name_length == 14 &&
1269 !strncmp (auths[i]->name, "MIT-KERBEROS-5", 14))
1270 auths[i]->data_length = 0;
1271 if (d->displayType.location == Local1)
1272 writeLocalAuth (new, auths[i], d->name);
1273#ifdef XDMCP
1274 else
1275 writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
1276#endif
1277 auths[i]->data_length = data_len;
1278 }
1279 }
1280 if (old) {
1281 if (fstat (fileno (old), &statb) != -1)
1282 chmod (new_name, (int) (statb.st_mode & 0777));
1283 /*SUPPRESS 560*/
1284 while ((entry = XauReadAuth (old))) {
1285 if (!checkEntry (entry))
1286 {
1287 Debug ("Writing an entry\n");
1288 writeAuth (new, entry);
1289 }
1290 XauDisposeAuth (entry);
1291 }
1292 fclose (old);
1293 }
1294 doneAddrs ();
1295 fclose (new);
1296 if (unlink (name) == -1)
1297 if (errno(*__error()) != ENOENT2)
1298 LogError ("cannot remove old authorization file %s: %s\n",
1299 name, _SysErrorMsg (errno(*__error())));
1300 envname = name;
1301 if (link (new_name, name) == -1) {
1302 LogError ("cannot link temporary authorization file %s to old "
1303 "location %s: %s\n", new_name, name,
1304 _SysErrorMsg (errno(*__error())));
1305 setenv = 1;
1306 envname = new_name;
1307 } else {
1308 Debug ("authorization file %s successfully updated\n", name);
1309 if (unlink (new_name))
1310 if (errno(*__error()) != ENOENT2)
1311 LogError ("cannot remove new authorization file %s:"
1312 " %s\n", new_name, _SysErrorMsg (errno(*__error())));
1313 }
1314 if (setenv) {
1315 verify->userEnviron = setEnv (verify->userEnviron,
1316 "XAUTHORITY", envname);
1317 verify->systemEnviron = setEnv (verify->systemEnviron,
1318 "XAUTHORITY", envname);
1319 }
1320 XauUnlockAuth (name);
1321 if (envname)
1322 chown (envname, verify->uid, verify->gid);
1323 }
1324 Debug ("done SetUserAuthorization\n");
1325}
1326
1327void
1328RemoveUserAuthorization (struct display *d, struct verify_info *verify)
1329{
1330 char *home;
1331 Xauth **auths, *entry;
1332 char name[1024], new_name[1024];
1333 int lockStatus;
1334 FILE *old, *new;
1335 struct stat statb;
1336 int i;
1337
1338 if (!(auths = d->authorizations))
1339 return;
1340 home = getEnv (verify->userEnviron, "HOME");
1341 if (!home)
1342 return;
1343 Debug ("RemoveUserAuthorization\n");
1344 snprintf(name, sizeof(name), "%s/.Xauthority", home)__builtin___snprintf_chk (name, sizeof(name), 0, __builtin_object_size
(name, 2 > 1 ? 1 : 0), "%s/.Xauthority", home)
;
1345 Debug ("XauLockAuth %s\n", name);
1346 lockStatus = XauLockAuth (name, 1, 2, 10);
1347 Debug ("Lock is %d\n", lockStatus);
1348 if (lockStatus != LOCK_SUCCESS0)
1349 return;
1350 old = NULL((void*)0);
1351 if (openFiles (name, new_name, &old, &new))
1352 {
1353 initAddrs ();
1354 doWrite = 0;
1355 for (i = 0; i < d->authNum; i++)
1356 {
1357 if (d->displayType.location == Local1)
1358 writeLocalAuth (new, auths[i], d->name);
1359#ifdef XDMCP
1360 else
1361 writeRemoteAuth (new, auths[i], d->peer, d->peerlen, d->name);
1362#endif
1363 }
1364 doWrite = 1;
1365 if (old) {
1366 if (fstat (fileno (old), &statb) != -1)
1367 chmod (new_name, (int) (statb.st_mode & 0777));
1368 /*SUPPRESS 560*/
1369 while ((entry = XauReadAuth (old))) {
1370 if (!checkEntry (entry))
1371 {
1372 Debug ("Writing an entry\n");
1373 writeAuth (new, entry);
1374 }
1375 XauDisposeAuth (entry);
1376 }
1377 fclose (old);
1378 }
1379 doneAddrs ();
1380 fclose (new);
1381 if (unlink (name) == -1)
1382 if (errno(*__error()) != ENOENT2)
1383 LogError ("cannot remove new authorization file %s: %s\n",
1384 name, _SysErrorMsg (errno(*__error())));
1385 if (link (new_name, name) == -1) {
1386 LogError ("cannot link temporary authorization file %s to old "
1387 "location %s: %s\n", new_name, name,
1388 _SysErrorMsg (errno(*__error())));
1389 } else {
1390 Debug ("authorization file %s successfully updated\n", name);
1391 if (unlink (new_name))
1392 if (errno(*__error()) != ENOENT2)
1393 LogError ("cannot remove new authorization file %s:"
1394 " %s\n", new_name, _SysErrorMsg (errno(*__error())));
1395 }
1396 }
1397 XauUnlockAuth (name);
1398}