165
175
gdm_auth_secure_display (GdmDisplay *d)
175
gdm_debug ("gdm_auth_secure_display: Setting up access for %s", d->name);
177
g_free (d->authfile);
179
g_free (d->authfile_gdm);
180
d->authfile_gdm = NULL;
182
if (d->server_uid != 0) {
185
/* Note, Xnest can't use the GDM_KEY_SERV_AUTHDIR unless running as
186
* root, which is rare anyway. */
188
d->authfile = g_build_filename (gdm_get_value_string (GDM_KEY_USER_AUTHDIR_FALLBACK), ".gdmXXXXXX", NULL);
191
authfd = g_mkstemp (d->authfile);
194
if G_UNLIKELY (authfd == -1) {
195
gdm_error (_("%s: Could not make new cookie file in %s"),
196
"gdm_auth_secure_display", gdm_get_value_string (GDM_KEY_USER_AUTHDIR_FALLBACK));
197
g_free (d->authfile);
202
/* Make it owned by the user that Xnest is started as */
203
fchown (authfd, d->server_uid, -1);
205
VE_IGNORE_EINTR (af = fdopen (authfd, "w"));
207
if G_UNLIKELY (af == NULL) {
208
g_free (d->authfile);
213
/* Make another authfile since the greeter can't read the server/user
215
d->authfile_gdm = gdm_make_filename (gdm_get_value_string (GDM_KEY_SERV_AUTHDIR), d->name, ".Xauth");
216
af_gdm = gdm_safe_fopen_w (d->authfile_gdm);
218
if G_UNLIKELY (af_gdm == NULL) {
219
gdm_error (_("%s: Cannot safely open %s"),
220
"gdm_auth_secure_display",
223
g_free (d->authfile_gdm);
224
d->authfile_gdm = NULL;
225
g_free (d->authfile);
227
VE_IGNORE_EINTR (fclose (af));
231
/* gdm and xserver authfile can be the same, server will run as root */
232
d->authfile = gdm_make_filename (gdm_get_value_string (GDM_KEY_SERV_AUTHDIR), d->name, ".Xauth");
233
af = gdm_safe_fopen_w (d->authfile);
235
if G_UNLIKELY (af == NULL) {
236
gdm_error (_("%s: Cannot safely open %s"),
237
"gdm_auth_secure_display",
240
g_free (d->authfile);
248
/* If this is a local display the struct hasn't changed and we
249
* have to eat up old authentication cookies before baking new
251
if (SERVER_IS_LOCAL (d) && d->auths) {
252
gdm_auth_free_auth_list (d->auths);
261
/* Create new random cookie */
262
gdm_cookie_generate (d);
264
/* reget local host if local as it may have changed */
265
if (SERVER_IS_LOCAL (d)) {
268
hostname[1023] = '\0';
269
if G_LIKELY (gethostname (hostname, 1023) == 0) {
270
g_free (d->hostname);
271
d->hostname = g_strdup (hostname);
275
if ( ! add_auth_entry (d, &(d->auths), af, af_gdm, FamilyWild, NULL, 0))
278
gdm_debug ("gdm_auth_secure_display: Setting up access");
280
VE_IGNORE_EINTR (closeret = fclose (af));
281
if G_UNLIKELY (closeret < 0) {
282
display_add_error (d);
285
if (af_gdm != NULL) {
286
VE_IGNORE_EINTR (closeret = fclose (af_gdm));
287
if G_UNLIKELY (closeret < 0) {
288
display_add_error (d);
292
g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
294
if G_UNLIKELY (gdm_get_value_bool (GDM_KEY_DEBUG))
295
gdm_debug ("gdm_auth_secure_display: Setting up access for %s - %d entries",
296
d->name, g_slist_length (d->auths));
185
gdm_debug ("gdm_auth_secure_display: Setting up access for %s", d->name);
187
g_free (d->authfile);
189
g_free (d->authfile_gdm);
190
d->authfile_gdm = NULL;
192
if (d->server_uid != 0) {
195
/* Note, nested display can't use the GDM_KEY_SERV_AUTHDIR unless
196
* running as root, which is rare anyway. */
198
d->authfile = g_build_filename (gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHDIR_FALLBACK), ".gdmXXXXXX", NULL);
201
authfd = g_mkstemp (d->authfile);
204
if G_UNLIKELY (authfd == -1) {
205
gdm_error (_("%s: Could not make new cookie file in %s"),
206
"gdm_auth_secure_display", gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHDIR_FALLBACK));
207
g_free (d->authfile);
212
/* Make it owned by the user that nested display is started as */
213
fchown (authfd, d->server_uid, -1);
215
VE_IGNORE_EINTR (af = fdopen (authfd, "w"));
217
if G_UNLIKELY (af == NULL) {
218
g_free (d->authfile);
223
/* Make another authfile since the greeter can't read the server/user
225
d->authfile_gdm = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), d->name, ".Xauth");
226
af_gdm = gdm_safe_fopen_w (d->authfile_gdm, 0644);
228
if G_UNLIKELY (af_gdm == NULL) {
229
gdm_error (_("%s: Cannot safely open %s"),
230
"gdm_auth_secure_display",
233
g_free (d->authfile_gdm);
234
d->authfile_gdm = NULL;
235
g_free (d->authfile);
237
VE_IGNORE_EINTR (fclose (af));
241
/* gdm and xserver authfile can be the same, server will run as root */
242
d->authfile = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), d->name, ".Xauth");
243
af = gdm_safe_fopen_w (d->authfile, 0644);
245
if G_UNLIKELY (af == NULL) {
246
gdm_error (_("%s: Cannot safely open %s"),
247
"gdm_auth_secure_display",
250
g_free (d->authfile);
258
/* If this is a local display the struct hasn't changed and we
259
* have to eat up old authentication cookies before baking new
261
if (SERVER_IS_LOCAL (d) && d->auths) {
262
gdm_auth_free_auth_list (d->auths);
271
/* Create new random cookie */
272
gdm_cookie_generate (&d->cookie, &d->bcookie);
274
/* reget local host if local as it may have changed */
275
if (SERVER_IS_LOCAL (d)) {
278
hostname[1023] = '\0';
279
if G_LIKELY (gethostname (hostname, 1023) == 0) {
280
g_free (d->hostname);
281
d->hostname = g_strdup (hostname);
285
if ( ! add_auth_entry (d, &(d->auths), af, af_gdm, FamilyWild, NULL, 0))
288
gdm_debug ("gdm_auth_secure_display: Setting up access");
290
VE_IGNORE_EINTR (closeret = fclose (af));
291
if G_UNLIKELY (closeret < 0) {
292
display_add_error (d);
295
if (af_gdm != NULL) {
296
VE_IGNORE_EINTR (closeret = fclose (af_gdm));
297
if G_UNLIKELY (closeret < 0) {
298
display_add_error (d);
302
g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
304
if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG))
305
gdm_debug ("gdm_auth_secure_display: Setting up access for %s - %d entries",
306
d->name, g_slist_length (d->auths));
311
#define SA(__s) ((struct sockaddr *) __s)
312
#define SIN(__s) ((struct sockaddr_in *) __s)
313
#define SIN6(__s) ((struct sockaddr_in6 *) __s)
316
add_auth_entry_for_addr (GdmDisplay *d,
318
struct sockaddr_storage *ss)
322
unsigned short family;
324
switch (ss->ss_family) {
327
family = FamilyInternetV6;
328
addr = (const char *) &SIN6 (ss)->sin6_addr;
329
len = sizeof (struct in6_addr);
334
family = FamilyInternet;
335
addr = (const char *) &SIN (ss)->sin_addr;
336
len = sizeof (struct in_addr);
340
return add_auth_entry (d, authlist, NULL, NULL, family, addr, len);
302
344
get_local_auths (GdmDisplay *d)
304
gboolean is_local = FALSE;
305
const char lo[] = {127,0,0,1};
307
const char lo6[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
310
const GList *local_addys = NULL;
311
gboolean added_lo = FALSE;
312
GSList *auths = NULL;
346
gboolean is_local = FALSE;
347
const char lo[] = {127,0,0,1};
349
const GList *local_addys = NULL;
350
gboolean added_lo = FALSE;
351
GSList *auths = NULL;
356
if (SERVER_IS_LOCAL (d)) {
359
/* reget local host if local as it may have changed */
360
hostname[1023] = '\0';
361
if G_LIKELY (gethostname (hostname, 1023) == 0) {
362
g_free (d->hostname);
363
d->hostname = g_strdup (hostname);
365
if ( ! d->tcp_disallowed)
366
local_addys = gdm_address_peek_local_list ();
372
if (gdm_address_is_local (&(d->addr))) {
376
for (i = 0; ! is_local && i < d->addr_count; i++) {
377
if (gdm_address_is_local (&d->addrs[i])) {
384
/* Local access also in case the host is very local */
386
gdm_debug ("get_local_auths: Setting up socket access");
388
if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyLocal,
389
d->hostname, strlen (d->hostname)))
390
goto get_local_auth_error;
392
/* local machine but not local if you get my meaning, add
393
* the host gotten by gethostname as well if it's different
394
* since the above is probably localhost */
395
if ( ! SERVER_IS_LOCAL (d)) {
398
hostname[1023] = '\0';
399
if (gethostname (hostname, 1023) == 0 &&
400
strcmp (hostname, d->hostname) != 0) {
401
if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyLocal,
404
goto get_local_auth_error;
407
/* local machine, perhaps we haven't added
408
* localhost.localdomain to socket access */
409
const char *localhost = "localhost.localdomain";
410
if (strcmp (localhost, d->hostname) != 0) {
411
if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyLocal,
413
strlen (localhost))) {
414
goto get_local_auth_error;
420
gdm_debug ("get_local_auths: Setting up network access");
422
if ( ! SERVER_IS_LOCAL (d)) {
423
/* we should write out an entry for d->addr since
424
possibly it is not in d->addrs */
426
if (! add_auth_entry_for_addr (d, &auths, &d->addr)) {
427
goto get_local_auth_error;
430
if (gdm_address_is_loopback (&(d->addr))) {
435
/* Network access: Write out an authentication entry for each of
436
* this host's official addresses */
437
for (i = 0; i < d->addr_count; i++) {
438
struct sockaddr_storage *sa;
441
if (gdm_address_equal (sa, &d->addr)) {
445
if (! add_auth_entry_for_addr (d, &auths, sa)) {
446
goto get_local_auth_error;
449
if (gdm_address_is_loopback (sa)) {
454
/* Network access: Write out an authentication entry for each of
455
* this host's local addresses if any */
456
for (; local_addys != NULL; local_addys = local_addys->next) {
457
struct sockaddr_storage *ia = local_addys->data;
462
if (! add_auth_entry_for_addr (d, &auths, ia)) {
463
goto get_local_auth_error;
466
if (gdm_address_is_loopback (ia)) {
471
/* If local server, then add loopback */
472
if (SERVER_IS_LOCAL (d) && ! added_lo && ! d->tcp_disallowed) {
473
if (! add_auth_entry (d, &auths, NULL, NULL, FamilyInternet,
474
lo, sizeof (struct in_addr))) {
475
goto get_local_auth_error;
479
if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG))
480
gdm_debug ("get_local_auths: Setting up access for %s - %d entries",
481
d->name, g_slist_length (auths));
485
get_local_auth_error:
487
gdm_auth_free_auth_list (auths);
317
if (SERVER_IS_LOCAL (d)) {
320
/* reget local host if local as it may have changed */
321
hostname[1023] = '\0';
322
if G_LIKELY (gethostname (hostname, 1023) == 0) {
323
g_free (d->hostname);
324
d->hostname = g_strdup (hostname);
326
if ( ! d->tcp_disallowed)
327
local_addys = gdm_peek_local_address_list ();
333
if (d->addrtype == AF_INET6) {
334
if (gdm_is_local_addr6 (&(d->addr6)))
340
if (gdm_is_local_addr (&(d->addr)))
344
for (i = 0; ! is_local && i < d->addr_count; i++) {
346
if (d->addrs[i].ss_family == AF_INET6) {
347
if (gdm_is_local_addr6 (&((struct sockaddr_in6 *)(&(d->addrs[i])))->sin6_addr)) {
355
if (gdm_is_local_addr (&((struct sockaddr_in *)(&(d->addrs[i])))->sin_addr)) {
363
/* Local access also in case the host is very local */
365
gdm_debug ("get_local_auths: Setting up socket access");
367
if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyLocal,
368
d->hostname, strlen (d->hostname)))
369
goto get_local_auth_error;
371
/* local machine but not local if you get my meaning, add
372
* the host gotten by gethostname as well if it's different
373
* since the above is probably localhost */
374
if ( ! SERVER_IS_LOCAL (d)) {
377
hostname[1023] = '\0';
378
if (gethostname (hostname, 1023) == 0 &&
379
strcmp (hostname, d->hostname) != 0) {
380
if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyLocal,
383
goto get_local_auth_error;
386
/* local machine, perhaps we haven't added
387
* localhost.localdomain to socket access */
388
const char *localhost = "localhost.localdomain";
389
if (strcmp (localhost, d->hostname) != 0) {
390
if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyLocal,
392
strlen (localhost))) {
393
goto get_local_auth_error;
399
gdm_debug ("get_local_auths: Setting up network access");
401
if ( ! SERVER_IS_LOCAL (d)) {
402
/* we should write out an entry for d->addr since
403
possibly it is not in d->addrs */
405
if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternetV6, (char *)((d->addr6).s6_addr), sizeof (struct in6_addr)))
406
goto get_local_auth_error;
409
if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternet, (char *)&(d->addr), sizeof (struct in_addr)))
410
goto get_local_auth_error;
413
if (d->addrtype == AF_INET6 && gdm_is_loopback_addr6 (&(d->addr6)))
416
if (d->addrtype == AF_INET && gdm_is_loopback_addr (&(d->addr)))
420
/* Network access: Write out an authentication entry for each of
421
* this host's official addresses */
422
for (i = 0; i < d->addr_count; i++) {
424
struct in6_addr *ia6;
429
if (d->addrs[i].ss_family == AF_INET6) {
430
ia6 = &(((struct sockaddr_in6 *)(&(d->addrs[i])))->sin6_addr);
431
if (memcmp (ia6, &(d->addr6), sizeof (struct in6_addr)) == 0)
434
if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternetV6, (char *)(ia6->s6_addr), sizeof (struct in6_addr)))
435
goto get_local_auth_error;
437
if (gdm_is_loopback_addr6 (ia6))
443
ia = &(((struct sockaddr_in *)(&(d->addrs[i])))->sin_addr);
444
if (memcmp (ia, &(d->addr), sizeof (struct in_addr)) == 0)
447
if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternet, (char *)&ia->s_addr, sizeof (struct in_addr)))
448
goto get_local_auth_error;
450
if (gdm_is_loopback_addr (ia))
455
/* Network access: Write out an authentication entry for each of
456
* this host's local addresses if any */
457
for (; local_addys != NULL; local_addys = local_addys->next) {
458
struct sockaddr *ia = (struct sockaddr *) local_addys->data;
464
if (ia->sa_family == AF_INET6) {
465
if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternetV6, (char *)(((struct sockaddr_in6 *)ia)->sin6_addr.s6_addr), sizeof (struct in6_addr)))
466
goto get_local_auth_error;
468
if (gdm_is_loopback_addr6 (&((struct sockaddr_in6 *)ia)->sin6_addr))
474
if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternet, (char *)&((struct sockaddr_in *)ia)->sin_addr, sizeof (struct in_addr)))
475
goto get_local_auth_error;
477
if (gdm_is_loopback_addr (&((struct sockaddr_in *)ia)->sin_addr))
483
/* if local server add loopback */
484
if (SERVER_IS_LOCAL (d) && ! added_lo && ! d->tcp_disallowed) {
487
if (d->addrtype == AF_INET6) {
488
if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternetV6, lo6, sizeof (struct in6_addr)))
489
goto get_local_auth_error;
494
if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternet, lo, sizeof (struct in_addr)))
495
goto get_local_auth_error;
500
if G_UNLIKELY (gdm_get_value_bool (GDM_KEY_DEBUG))
501
gdm_debug ("get_local_auths: Setting up access for %s - %d entries",
502
d->name, g_slist_length (auths));
506
get_local_auth_error:
508
gdm_auth_free_auth_list (auths);
548
527
* @d: Pointer to a GdmDisplay struct
549
528
* @user: Userid of the user whose cookie file to add entries to
550
529
* @homedir: The user's home directory
552
531
* Remove all cookies referring to this display from user's cookie
553
532
* file and append the ones specified in the display's authlist.
555
* Returns TRUE on success and FALSE on error.
534
* Returns TRUE on success and FALSE on error.
559
538
gdm_auth_user_add (GdmDisplay *d, uid_t user, const char *homedir)
564
GSList *auths = NULL;
568
gboolean automatic_tmp_dir = FALSE;
569
gboolean authdir_is_tmp_dir = FALSE;
571
gboolean user_auth_exists;
577
if (d->local_auths != NULL) {
578
gdm_auth_free_auth_list (d->local_auths);
579
d->local_auths = NULL;
582
d->local_auths = get_local_auths (d);
584
if (d->local_auths == NULL) {
585
gdm_error ("Can't make cookies");
589
gdm_debug ("gdm_auth_user_add: Adding cookie for %d", user);
591
userauthdir = gdm_get_value_string (GDM_KEY_USER_AUTHDIR);
592
userauthfile = gdm_get_value_string (GDM_KEY_USER_AUTHFILE);
594
/* Determine whether UserAuthDir is specified. Otherwise ~user is used */
595
if ( ! ve_string_empty (userauthdir) &&
596
strcmp (userauthdir, "~") != 0) {
597
if (strncmp (userauthdir, "~/", 2) == 0) {
598
authdir = g_build_filename (homedir, &userauthdir[2], NULL);
600
authdir = g_strdup (userauthdir);
601
automatic_tmp_dir = TRUE;
602
authdir_is_tmp_dir = TRUE;
605
authdir = g_strdup (homedir);
617
d->userauth = g_build_filename (authdir, userauthfile, NULL);
619
user_auth_exists = (d->userauth != NULL &&
620
g_access (d->userauth, F_OK) == 0);
622
/* Find out if the Xauthority file passes the paranoia check */
623
/* Note that this is not very efficient, we stat the files over
624
and over, but we don't care, we don't do this too often */
625
if (automatic_tmp_dir ||
628
/* first the standard paranoia check (this checks the home dir
629
* too which is useful here) */
630
! gdm_file_check ("gdm_auth_user_add", user, authdir, userauthfile,
631
TRUE, FALSE, gdm_get_value_int (GDM_KEY_USER_MAX_FILE),
632
gdm_get_value_int (GDM_KEY_RELAX_PERM)) ||
634
/* now the auth file checking routine */
635
! gdm_auth_file_check ("gdm_auth_user_add", user, d->userauth, TRUE /* absentok */, NULL) ||
637
/* now see if we can actually append this file */
638
! try_open_append (d->userauth) ||
640
/* try opening as root, if we can't open as root,
641
then this is a NFS mounted directory with root squashing,
642
and we don't want to write cookies over NFS */
643
(gdm_get_value_bool (GDM_KEY_NEVER_PLACE_COOKIES_ON_NFS) &&
644
! try_open_read_as_root (d->userauth))) {
646
/* if the userauth file didn't exist and we were looking at it,
647
it likely exists now but empty, so just whack it
648
(it may not exist if the file didn't exist and the directory
649
was of wrong permissions, but more likely this is
650
file on NFS dir with root-squashing enabled) */
651
if ( ! user_auth_exists && d->userauth != NULL)
652
g_unlink (d->userauth);
654
/* No go. Let's create a fallback file in GDM_KEY_USER_AUTHDIR_FALLBACK (/tmp)
655
* or perhaps userauthfile directory (usually would be /tmp) */
657
g_free (d->userauth);
658
if (authdir_is_tmp_dir && authdir != NULL)
659
d->userauth = g_build_filename (authdir, ".gdmXXXXXX", NULL);
543
GSList *auths = NULL;
544
const gchar *userauthdir;
545
const gchar *userauthfile;
547
gboolean automatic_tmp_dir = FALSE;
548
gboolean authdir_is_tmp_dir = FALSE;
550
gboolean user_auth_exists;
556
if (d->local_auths != NULL) {
557
gdm_auth_free_auth_list (d->local_auths);
558
d->local_auths = NULL;
561
d->local_auths = get_local_auths (d);
563
if (d->local_auths == NULL) {
564
gdm_error ("Can't make cookies");
568
gdm_debug ("gdm_auth_user_add: Adding cookie for %d", user);
570
userauthdir = gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHDIR);
571
userauthfile = gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHFILE);
573
/* Determine whether UserAuthDir is specified. Otherwise ~user is used */
574
if ( ! ve_string_empty (userauthdir) &&
575
strcmp (userauthdir, "~") != 0) {
576
if (strncmp (userauthdir, "~/", 2) == 0) {
577
authdir = g_build_filename (homedir, &userauthdir[2], NULL);
579
authdir = g_strdup (userauthdir);
580
automatic_tmp_dir = TRUE;
581
authdir_is_tmp_dir = TRUE;
584
authdir = g_strdup (homedir);
661
d->userauth = g_build_filename (gdm_get_value_string (GDM_KEY_USER_AUTHDIR_FALLBACK), ".gdmXXXXXX", NULL);
662
authfd = g_mkstemp (d->userauth);
664
if G_UNLIKELY (authfd < 0 && authdir_is_tmp_dir) {
665
g_free (d->userauth);
670
authdir_is_tmp_dir = FALSE;
671
goto try_user_add_again;
674
if G_UNLIKELY (authfd < 0) {
675
gdm_error (_("%s: Could not open cookie file %s"),
678
g_free (d->userauth);
687
d->last_auth_touch = time (NULL);
689
VE_IGNORE_EINTR (af = fdopen (authfd, "w"));
691
else { /* User's Xauthority file is ok */
694
/* FIXME: Better implement my own locking. The libXau one is not kosher */
695
if G_UNLIKELY (XauLockAuth (d->userauth, 3, 3, 0) != LOCK_SUCCESS) {
696
gdm_error (_("%s: Could not lock cookie file %s"),
699
g_free (d->userauth);
704
automatic_tmp_dir = TRUE;
705
goto try_user_add_again;
710
af = gdm_safe_fopen_ap (d->userauth);
713
/* Set to NULL, because can goto try_user_add_again. */
717
if G_UNLIKELY (af == NULL) {
718
/* Really no need to clean up here - this process is a goner anyway */
719
gdm_error (_("%s: Could not open cookie file %s"),
723
XauUnlockAuth (d->userauth);
724
g_free (d->userauth);
730
automatic_tmp_dir = TRUE;
731
goto try_user_add_again;
737
gdm_debug ("gdm_auth_user_add: Using %s for cookies", d->userauth);
739
/* If not a fallback file, nuke any existing cookies for this display */
741
af = gdm_auth_purge (d, af, FALSE /* remove when empty */);
743
/* Append the authlist for this display to the cookie file */
744
auths = d->local_auths;
747
if G_UNLIKELY ( ! XauWriteAuth (af, auths->data)) {
596
d->userauth = g_build_filename (authdir, userauthfile, NULL);
598
user_auth_exists = (d->userauth != NULL &&
599
g_access (d->userauth, F_OK) == 0);
601
/* Find out if the Xauthority file passes the paranoia check */
602
/* Note that this is not very efficient, we stat the files over
603
and over, but we don't care, we don't do this too often */
604
if (automatic_tmp_dir ||
607
/* first the standard paranoia check (this checks the home dir
608
* too which is useful here) */
609
! gdm_file_check ("gdm_auth_user_add", user, authdir, userauthfile,
610
TRUE, FALSE, gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE),
611
gdm_daemon_config_get_value_int (GDM_KEY_RELAX_PERM)) ||
613
/* now the auth file checking routine */
614
! gdm_auth_file_check ("gdm_auth_user_add", user, d->userauth, TRUE /* absentok */, NULL) ||
616
/* now see if we can actually append this file */
617
! try_open_append (d->userauth) ||
619
/* try opening as root, if we can't open as root,
620
then this is a NFS mounted directory with root squashing,
621
and we don't want to write cookies over NFS */
622
(gdm_daemon_config_get_value_bool (GDM_KEY_NEVER_PLACE_COOKIES_ON_NFS) &&
623
! try_open_read_as_root (d->userauth))) {
625
/* if the userauth file didn't exist and we were looking at it,
626
it likely exists now but empty, so just whack it
627
(it may not exist if the file didn't exist and the directory
628
was of wrong permissions, but more likely this is
629
file on NFS dir with root-squashing enabled) */
630
if ( ! user_auth_exists && d->userauth != NULL)
631
g_unlink (d->userauth);
633
/* No go. Let's create a fallback file in GDM_KEY_USER_AUTHDIR_FALLBACK (/tmp)
634
* or perhaps userauthfile directory (usually would be /tmp) */
636
g_free (d->userauth);
637
if (authdir_is_tmp_dir && authdir != NULL)
638
d->userauth = g_build_filename (authdir, ".gdmXXXXXX", NULL);
640
d->userauth = g_build_filename (gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHDIR_FALLBACK), ".gdmXXXXXX", NULL);
641
authfd = g_mkstemp (d->userauth);
643
if G_UNLIKELY (authfd < 0 && authdir_is_tmp_dir) {
644
g_free (d->userauth);
647
authdir_is_tmp_dir = FALSE;
648
goto try_user_add_again;
651
if G_UNLIKELY (authfd < 0) {
652
gdm_error (_("%s: Could not open cookie file %s"),
655
g_free (d->userauth);
664
d->last_auth_touch = time (NULL);
666
VE_IGNORE_EINTR (af = fdopen (authfd, "w"));
667
} else { /* User's Xauthority file is ok */
670
/* FIXME: Better implement my own locking. The libXau one is not kosher */
671
if G_UNLIKELY (XauLockAuth (d->userauth, 3, 3, 0) != LOCK_SUCCESS) {
672
gdm_error (_("%s: Could not lock cookie file %s"),
675
g_free (d->userauth);
678
automatic_tmp_dir = TRUE;
679
goto try_user_add_again;
684
af = gdm_safe_fopen_ap (d->userauth, 0600);
687
/* Set to NULL, because can goto try_user_add_again. */
691
if G_UNLIKELY (af == NULL) {
692
/* Really no need to clean up here - this process is a goner anyway */
693
gdm_error (_("%s: Could not open cookie file %s"),
697
XauUnlockAuth (d->userauth);
698
g_free (d->userauth);
702
automatic_tmp_dir = TRUE;
703
goto try_user_add_again;
710
gdm_debug ("gdm_auth_user_add: Using %s for cookies", d->userauth);
712
/* If not a fallback file, nuke any existing cookies for this display */
714
af = gdm_auth_purge (d, af, FALSE /* remove when empty */);
716
/* Append the authlist for this display to the cookie file */
717
auths = d->local_auths;
720
if G_UNLIKELY ( ! XauWriteAuth (af, auths->data)) {
721
gdm_error (_("%s: Could not write cookie"),
722
"gdm_auth_user_add");
725
VE_IGNORE_EINTR (fclose (af));
727
XauUnlockAuth (d->userauth);
728
g_free (d->userauth);
730
automatic_tmp_dir = TRUE;
731
goto try_user_add_again;
741
VE_IGNORE_EINTR (closeret = fclose (af));
742
if G_UNLIKELY (closeret < 0) {
748
743
gdm_error (_("%s: Could not write cookie"),
749
744
"gdm_auth_user_add");
751
746
if ( ! d->authfb) {
752
VE_IGNORE_EINTR (fclose (af));
754
748
XauUnlockAuth (d->userauth);
755
749
g_free (d->userauth);
805
778
gdm_auth_user_remove (GdmDisplay *d, uid_t user)
812
if G_UNLIKELY (!d || !d->userauth)
815
gdm_debug ("gdm_auth_user_remove: Removing cookie from %s (%d)", d->userauth, d->authfb);
817
/* If we are using the fallback cookie location, simply nuke the
820
VE_IGNORE_EINTR (g_unlink (d->userauth));
821
g_free (d->userauth);
826
/* if the file doesn't exist, oh well, just ignore this then */
827
if G_UNLIKELY (g_access (d->userauth, F_OK) != 0) {
828
g_free (d->userauth);
833
authfile = g_path_get_basename (d->userauth);
834
authdir = g_path_get_dirname (d->userauth);
836
if (ve_string_empty (authfile) ||
837
ve_string_empty (authdir)) {
843
/* Now, the cookie file could be owned by a malicious user who
844
* decided to concatenate something like his entire MP3 collection
845
* to it. So we better play it safe... */
847
if G_UNLIKELY ( ! gdm_file_check ("gdm_auth_user_remove", user, authdir, authfile,
848
TRUE, FALSE, gdm_get_value_int (GDM_KEY_USER_MAX_FILE),
849
gdm_get_value_int (GDM_KEY_RELAX_PERM)) ||
850
/* be even paranoider with permissions */
851
! gdm_auth_file_check ("gdm_auth_user_remove", user, d->userauth, FALSE /* absentok */, NULL)) {
854
gdm_error (_("%s: Ignoring suspiciously looking cookie file %s"),
855
"gdm_auth_user_remove",
864
/* Lock user's cookie jar and open it for writing */
865
if G_UNLIKELY (XauLockAuth (d->userauth, 3, 3, 0) != LOCK_SUCCESS) {
866
g_free (d->userauth);
871
oldmode = umask (077);
872
af = gdm_safe_fopen_ap (d->userauth);
875
if G_UNLIKELY (af == NULL) {
784
if G_UNLIKELY (!d || !d->userauth)
787
gdm_debug ("gdm_auth_user_remove: Removing cookie from %s (%d)", d->userauth, d->authfb);
789
/* If we are using the fallback cookie location, simply nuke the
792
VE_IGNORE_EINTR (g_unlink (d->userauth));
793
g_free (d->userauth);
798
/* if the file doesn't exist, oh well, just ignore this then */
799
if G_UNLIKELY (g_access (d->userauth, F_OK) != 0) {
800
g_free (d->userauth);
805
authfile = g_path_get_basename (d->userauth);
806
authdir = g_path_get_dirname (d->userauth);
808
if (ve_string_empty (authfile) ||
809
ve_string_empty (authdir)) {
815
/* Now, the cookie file could be owned by a malicious user who
816
* decided to concatenate something like his entire MP3 collection
817
* to it. So we better play it safe... */
819
if G_UNLIKELY ( ! gdm_file_check ("gdm_auth_user_remove", user, authdir, authfile,
820
TRUE, FALSE, gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE),
821
gdm_daemon_config_get_value_int (GDM_KEY_RELAX_PERM)) ||
822
/* be even paranoider with permissions */
823
! gdm_auth_file_check ("gdm_auth_user_remove", user, d->userauth, FALSE /* absentok */, NULL)) {
826
gdm_error (_("%s: Ignoring suspiciously looking cookie file %s"),
827
"gdm_auth_user_remove",
836
/* Lock user's cookie jar and open it for writing */
837
if G_UNLIKELY (XauLockAuth (d->userauth, 3, 3, 0) != LOCK_SUCCESS) {
838
g_free (d->userauth);
843
af = gdm_safe_fopen_ap (d->userauth, 0600);
845
if G_UNLIKELY (af == NULL) {
846
XauUnlockAuth (d->userauth);
848
gdm_error (_("%s: Cannot safely open %s"),
849
"gdm_auth_user_remove",
852
g_free (d->userauth);
858
/* Purge entries for this display from the cookie jar */
859
af = gdm_auth_purge (d, af, TRUE /* remove when empty */);
861
/* Close the file and unlock it */
863
/* FIXME: what about out of diskspace errors on errors close */
865
VE_IGNORE_EINTR (fclose (af));
866
if G_UNLIKELY (errno != 0) {
867
gdm_error (_("Can't write to %s: %s"), d->userauth,
876
872
XauUnlockAuth (d->userauth);
878
gdm_error (_("%s: Cannot safely open %s"),
879
"gdm_auth_user_remove",
882
874
g_free (d->userauth);
883
875
d->userauth = NULL;
888
/* Purge entries for this display from the cookie jar */
889
af = gdm_auth_purge (d, af, TRUE /* remove when empty */);
891
/* Close the file and unlock it */
893
/* FIXME: what about out of diskspace errors on errors close */
895
VE_IGNORE_EINTR (fclose (af));
896
if G_UNLIKELY (errno != 0) {
897
gdm_error (_("Can't write to %s: %s"), d->userauth,
902
XauUnlockAuth (d->userauth);
904
g_free (d->userauth);
941
911
* @d: Pointer to a GdmDisplay struct
942
912
* @af: File handle to a cookie file
943
913
* @remove_when_empty: remove the file when empty
945
915
* Remove all cookies referring to this display a cookie file.
949
919
gdm_auth_purge (GdmDisplay *d, FILE *af, gboolean remove_when_empty)
952
GSList *keep = NULL, *li;
956
if G_UNLIKELY (!d || !af)
922
GSList *keep = NULL, *li;
925
if G_UNLIKELY (!d || !af)
928
gdm_debug ("gdm_auth_purge: %s", d->name);
930
fseek (af, 0L, SEEK_SET);
932
/* Read the user's entire Xauth file into memory to avoid
933
* temporary file issues. Then remove any instance of this display
934
* in the cookie jar... */
938
while ( (xa = XauReadAuth (af)) != NULL ) {
940
/* We look at the current auths, but those may
941
have different cookies then what is in the file,
942
so don't compare those, but we wish to purge all
943
the entries that we'd normally write */
944
for (li = d->local_auths; li != NULL; li = li->next) {
945
Xauth *xb = li->data;
946
if (auth_same_except_data (xa, xb)) {
953
keep = g_slist_append (keep, xa);
955
/* just being ultra anal */
961
VE_IGNORE_EINTR (fclose (af));
963
if (remove_when_empty &&
965
VE_IGNORE_EINTR (g_unlink (d->userauth));
969
af = gdm_safe_fopen_w (d->userauth, 0600);
971
/* Write out remaining entries */
972
for (li = keep; li != NULL; li = li->next) {
973
/* FIXME: is this correct, if we can't open
974
* this is quite bad isn't it ... */
975
if G_LIKELY (af != NULL)
976
XauWriteAuth (af, li->data);
977
/* FIXME: what about errors? */
978
XauDisposeAuth (li->data);
959
gdm_debug ("gdm_auth_purge: %s", d->name);
961
fseek (af, 0L, SEEK_SET);
963
/* Read the user's entire Xauth file into memory to avoid
964
* temporary file issues. Then remove any instance of this display
965
* in the cookie jar... */
969
while ( (xa = XauReadAuth (af)) != NULL ) {
971
/* We look at the current auths, but those may
972
have different cookies then what is in the file,
973
so don't compare those, but we wish to purge all
974
the entries that we'd normally write */
975
for (li = d->local_auths; li != NULL; li = li->next) {
976
Xauth *xb = li->data;
977
if (auth_same_except_data (xa, xb)) {
984
keep = g_slist_append (keep, xa);
986
/* just being ultra anal */
992
VE_IGNORE_EINTR (fclose (af));
994
if (remove_when_empty &&
996
VE_IGNORE_EINTR (g_unlink (d->userauth));
1000
oldmode = umask (077);
1001
af = gdm_safe_fopen_w (d->userauth);
1004
/* Write out remaining entries */
1005
for (li = keep; li != NULL; li = li->next) {
1006
/* FIXME: is this correct, if we can't open
1007
* this is quite bad isn't it ... */
1008
if G_LIKELY (af != NULL)
1009
XauWriteAuth (af, li->data);
1010
/* FIXME: what about errors? */
1011
XauDisposeAuth (li->data);
1015
g_slist_free (keep);
1021
988
gdm_auth_set_local_auth (GdmDisplay *d)
1023
XSetAuthorization ((char *)"MIT-MAGIC-COOKIE-1", (int) strlen ("MIT-MAGIC-COOKIE-1"),
1024
(char *)d->bcookie, (int) 16);
990
XSetAuthorization ((char *)"MIT-MAGIC-COOKIE-1",
991
(int) strlen ("MIT-MAGIC-COOKIE-1"),