~ubuntu-branches/ubuntu/oneiric/gdm3/oneiric

« back to all changes in this revision

Viewing changes to daemon/gdm-display-access-file.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette
  • Date: 2010-03-25 20:02:20 UTC
  • Revision ID: james.westby@ubuntu.com-20100325200220-12cap62s6p304nuh
Tags: upstream-2.29.92
ImportĀ upstreamĀ versionĀ 2.29.92

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
2
 *
 
3
 * gdm-display-access-file.c - Abstraction around xauth cookies
 
4
 *
 
5
 * Copyright (C) 2007 Ray Strode <rstrode@redhat.com>
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2, or (at your option)
 
10
 * any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
20
 * 02111-1307, USA.
 
21
 */
 
22
 
 
23
#include "config.h"
 
24
 
 
25
#include <errno.h>
 
26
#include <limits.h>
 
27
#include <pwd.h>
 
28
#include <string.h>
 
29
#include <sys/types.h>
 
30
#include <unistd.h>
 
31
#include <sys/stat.h>
 
32
#include <fcntl.h>
 
33
 
 
34
#include <glib.h>
 
35
#include <glib-object.h>
 
36
#include <glib/gstdio.h>
 
37
#include <glib/gi18n.h>
 
38
 
 
39
#include <X11/Xauth.h>
 
40
 
 
41
#include "gdm-display-access-file.h"
 
42
#include "gdm-common.h"
 
43
 
 
44
struct _GdmDisplayAccessFilePrivate
 
45
{
 
46
        char *username;
 
47
        FILE *fp;
 
48
        char *path;
 
49
};
 
50
 
 
51
#ifndef GDM_DISPLAY_ACCESS_COOKIE_SIZE
 
52
#define GDM_DISPLAY_ACCESS_COOKIE_SIZE 16
 
53
#endif
 
54
 
 
55
#ifndef O_BINARY
 
56
#define O_BINARY 0
 
57
#endif
 
58
 
 
59
static void gdm_display_access_file_finalize (GObject * object);
 
60
 
 
61
enum
 
62
{
 
63
        PROP_0 = 0,
 
64
        PROP_USERNAME,
 
65
        PROP_PATH
 
66
};
 
67
 
 
68
G_DEFINE_TYPE (GdmDisplayAccessFile, gdm_display_access_file, G_TYPE_OBJECT)
 
69
 
 
70
static void
 
71
gdm_display_access_file_get_property (GObject    *object,
 
72
                                      guint       prop_id,
 
73
                                      GValue     *value,
 
74
                                      GParamSpec *pspec)
 
75
{
 
76
        GdmDisplayAccessFile *access_file;
 
77
 
 
78
        access_file = GDM_DISPLAY_ACCESS_FILE (object);
 
79
 
 
80
        switch (prop_id) {
 
81
            case PROP_USERNAME:
 
82
                g_value_set_string (value, access_file->priv->username);
 
83
                break;
 
84
 
 
85
            case PROP_PATH:
 
86
                g_value_set_string (value, access_file->priv->path);
 
87
                break;
 
88
 
 
89
            default:
 
90
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
91
        }
 
92
}
 
93
 
 
94
static void
 
95
gdm_display_access_file_set_property (GObject      *object,
 
96
                                      guint         prop_id,
 
97
                                      const GValue *value,
 
98
                                      GParamSpec   *pspec)
 
99
{
 
100
        GdmDisplayAccessFile *access_file;
 
101
 
 
102
        access_file = GDM_DISPLAY_ACCESS_FILE (object);
 
103
 
 
104
        switch (prop_id) {
 
105
            case PROP_USERNAME:
 
106
                g_assert (access_file->priv->username == NULL);
 
107
                access_file->priv->username = g_value_dup_string (value);
 
108
                break;
 
109
 
 
110
            default:
 
111
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
112
        }
 
113
}
 
114
 
 
115
static void
 
116
gdm_display_access_file_class_init (GdmDisplayAccessFileClass *access_file_class)
 
117
{
 
118
        GObjectClass *object_class;
 
119
        GParamSpec   *param_spec;
 
120
 
 
121
        object_class = G_OBJECT_CLASS (access_file_class);
 
122
 
 
123
        object_class->finalize = gdm_display_access_file_finalize;
 
124
        object_class->get_property = gdm_display_access_file_get_property;
 
125
        object_class->set_property = gdm_display_access_file_set_property;
 
126
 
 
127
        param_spec = g_param_spec_string ("username",
 
128
                                          "Username",
 
129
                                          "Owner of Xauthority file",
 
130
                                          NULL,
 
131
                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
 
132
        g_object_class_install_property (object_class, PROP_USERNAME, param_spec);
 
133
        param_spec = g_param_spec_string ("path",
 
134
                                          "Path",
 
135
                                          "Path to Xauthority file",
 
136
                                          NULL,
 
137
                                          G_PARAM_READABLE);
 
138
        g_object_class_install_property (object_class, PROP_PATH, param_spec);
 
139
        g_type_class_add_private (access_file_class, sizeof (GdmDisplayAccessFilePrivate));
 
140
}
 
141
 
 
142
static void
 
143
gdm_display_access_file_init (GdmDisplayAccessFile *access_file)
 
144
{
 
145
        access_file->priv = G_TYPE_INSTANCE_GET_PRIVATE (access_file,
 
146
                                                         GDM_TYPE_DISPLAY_ACCESS_FILE,
 
147
                                                         GdmDisplayAccessFilePrivate);
 
148
}
 
149
 
 
150
static void
 
151
gdm_display_access_file_finalize (GObject *object)
 
152
{
 
153
        GdmDisplayAccessFile *file;
 
154
        GObjectClass *parent_class;
 
155
 
 
156
        file = GDM_DISPLAY_ACCESS_FILE (object);
 
157
        parent_class = G_OBJECT_CLASS (gdm_display_access_file_parent_class);
 
158
 
 
159
        if (file->priv->fp != NULL) {
 
160
            gdm_display_access_file_close (file);
 
161
        }
 
162
        g_assert (file->priv->path == NULL);
 
163
 
 
164
        if (file->priv->username != NULL) {
 
165
                g_free (file->priv->username);
 
166
                file->priv->username = NULL;
 
167
                g_object_notify (object, "username");
 
168
        }
 
169
 
 
170
        if (parent_class->finalize != NULL) {
 
171
                parent_class->finalize (object);
 
172
        }
 
173
}
 
174
 
 
175
GQuark
 
176
gdm_display_access_file_error_quark (void)
 
177
{
 
178
        static GQuark error_quark = 0;
 
179
 
 
180
        if (error_quark == 0) {
 
181
                error_quark = g_quark_from_static_string ("gdm-display-access-file");
 
182
        }
 
183
 
 
184
        return error_quark;
 
185
}
 
186
 
 
187
GdmDisplayAccessFile *
 
188
gdm_display_access_file_new (const char *username)
 
189
{
 
190
        GdmDisplayAccessFile *access_file;
 
191
        g_return_val_if_fail (username != NULL, NULL);
 
192
 
 
193
        access_file = g_object_new (GDM_TYPE_DISPLAY_ACCESS_FILE,
 
194
                                    "username", username,
 
195
                                    NULL);
 
196
 
 
197
        return access_file;
 
198
}
 
199
 
 
200
static gboolean
 
201
_get_uid_and_gid_for_user (const char *username,
 
202
                           uid_t      *uid,
 
203
                           gid_t      *gid)
 
204
{
 
205
        struct passwd *passwd_entry;
 
206
 
 
207
        g_assert (username != NULL);
 
208
        g_assert (uid != NULL);
 
209
        g_assert (gid != NULL);
 
210
 
 
211
        errno = 0;
 
212
        passwd_entry = getpwnam (username);
 
213
 
 
214
        if (passwd_entry == NULL) {
 
215
                return FALSE;
 
216
        }
 
217
 
 
218
        *uid = passwd_entry->pw_uid;
 
219
        *gid = passwd_entry->pw_gid;
 
220
 
 
221
        return TRUE;
 
222
}
 
223
 
 
224
static void
 
225
clean_up_stale_auth_subdirs (void)
 
226
{
 
227
        GDir *dir;
 
228
        const char *filename;
 
229
 
 
230
        dir = g_dir_open (GDM_XAUTH_DIR, 0, NULL);
 
231
 
 
232
        if (dir == NULL) {
 
233
                return;
 
234
        }
 
235
 
 
236
        while ((filename = g_dir_read_name (dir)) != NULL) {
 
237
                char *path;
 
238
 
 
239
                path = g_build_filename (GDM_XAUTH_DIR, filename, NULL);
 
240
 
 
241
                /* Will only succeed if the directory is empty
 
242
                 */
 
243
                g_rmdir (path);
 
244
                g_free (path);
 
245
        }
 
246
        g_dir_close (dir);
 
247
}
 
248
 
 
249
static FILE *
 
250
_create_xauth_file_for_user (const char  *username,
 
251
                             char       **filename,
 
252
                             GError     **error)
 
253
{
 
254
        char   *template;
 
255
        const char *dir_name;
 
256
        char   *auth_filename;
 
257
        int     fd;
 
258
        FILE   *fp;
 
259
        uid_t   uid;
 
260
        gid_t   gid;
 
261
 
 
262
        g_assert (filename != NULL);
 
263
 
 
264
        *filename = NULL;
 
265
 
 
266
        template = NULL;
 
267
        auth_filename = NULL;
 
268
        fp = NULL;
 
269
        fd = -1;
 
270
 
 
271
        /* Create directory if not exist, then set permission 0711 and ownership root:gdm */
 
272
        if (g_file_test (GDM_XAUTH_DIR, G_FILE_TEST_IS_DIR) == FALSE) {
 
273
                g_unlink (GDM_XAUTH_DIR);
 
274
                if (g_mkdir (GDM_XAUTH_DIR, 0711) != 0) {
 
275
                        g_set_error (error,
 
276
                                     G_FILE_ERROR,
 
277
                                     g_file_error_from_errno (errno),
 
278
                                     "%s", g_strerror (errno));
 
279
                        goto out;
 
280
                }
 
281
 
 
282
                g_chmod (GDM_XAUTH_DIR, 0711);
 
283
                _get_uid_and_gid_for_user (GDM_USERNAME, &uid, &gid);
 
284
                if (chown (GDM_XAUTH_DIR, 0, gid) != 0) {
 
285
                        g_warning ("Unable to change owner of '%s'",
 
286
                                   GDM_XAUTH_DIR);
 
287
                }
 
288
        } else {
 
289
                /* if it does exist make sure it has correct mode 0711 */
 
290
                g_chmod (GDM_XAUTH_DIR, 0711);
 
291
 
 
292
                /* and clean up any stale auth subdirs */
 
293
                clean_up_stale_auth_subdirs ();
 
294
        }
 
295
 
 
296
        if (!_get_uid_and_gid_for_user (username, &uid, &gid)) {
 
297
                g_set_error (error,
 
298
                             GDM_DISPLAY_ERROR,
 
299
                             GDM_DISPLAY_ERROR_GETTING_USER_INFO,
 
300
                             _("could not find user \"%s\" on system"),
 
301
                             username);
 
302
                goto out;
 
303
 
 
304
        }
 
305
 
 
306
        template = g_strdup_printf (GDM_XAUTH_DIR
 
307
                                    "/auth-for-%s-XXXXXX",
 
308
                                    username);
 
309
 
 
310
        g_debug ("GdmDisplayAccessFile: creating xauth directory %s", template);
 
311
        /* Initially create with mode 01700 then later chmod after we create database */
 
312
        errno = 0;
 
313
        dir_name = gdm_make_temp_dir (template);
 
314
        if (dir_name == NULL) {
 
315
                g_set_error (error,
 
316
                             G_FILE_ERROR,
 
317
                             g_file_error_from_errno (errno),
 
318
                             "Unable to create temp dir from tempalte '%s': %s",
 
319
                             template,
 
320
                             g_strerror (errno));
 
321
                goto out;
 
322
        }
 
323
 
 
324
        g_debug ("GdmDisplayAccessFile: chowning %s to %u:%u",
 
325
                 dir_name, (guint)uid, (guint)gid);
 
326
        errno = 0;
 
327
        if (chown (dir_name, uid, gid) < 0) {
 
328
                g_set_error (error,
 
329
                             G_FILE_ERROR,
 
330
                             g_file_error_from_errno (errno),
 
331
                             "Unable to change permission of '%s': %s",
 
332
                             dir_name,
 
333
                             g_strerror (errno));
 
334
                goto out;
 
335
        }
 
336
 
 
337
        auth_filename = g_build_filename (dir_name, "database", NULL);
 
338
 
 
339
        g_debug ("GdmDisplayAccessFile: creating %s", auth_filename);
 
340
        /* mode 00600 */
 
341
        errno = 0;
 
342
        fd = g_open (auth_filename,
 
343
                     O_RDWR | O_CREAT | O_EXCL | O_BINARY,
 
344
                     S_IRUSR | S_IWUSR);
 
345
 
 
346
        if (fd < 0) {
 
347
                g_set_error (error,
 
348
                             G_FILE_ERROR,
 
349
                             g_file_error_from_errno (errno),
 
350
                             "Unable to open '%s': %s",
 
351
                             auth_filename,
 
352
                             g_strerror (errno));
 
353
                goto out;
 
354
        }
 
355
 
 
356
        g_debug ("GdmDisplayAccessFile: chowning %s to %u:%u", auth_filename, (guint)uid, (guint)gid);
 
357
        errno = 0;
 
358
        if (fchown (fd, uid, gid) < 0) {
 
359
                g_set_error (error,
 
360
                             G_FILE_ERROR,
 
361
                             g_file_error_from_errno (errno),
 
362
                             "Unable to change owner for '%s': %s",
 
363
                             auth_filename,
 
364
                             g_strerror (errno));
 
365
                close (fd);
 
366
                fd = -1;
 
367
                goto out;
 
368
        }
 
369
 
 
370
        /* now open up permissions on per-session directory */
 
371
        g_debug ("GdmDisplayAccessFile: chmoding %s to 0711", dir_name);
 
372
        g_chmod (dir_name, 0711);
 
373
 
 
374
        errno = 0;
 
375
        fp = fdopen (fd, "w");
 
376
        if (fp == NULL) {
 
377
                g_set_error (error,
 
378
                             G_FILE_ERROR,
 
379
                             g_file_error_from_errno (errno),
 
380
                             "%s", g_strerror (errno));
 
381
                close (fd);
 
382
                fd = -1;
 
383
                goto out;
 
384
        }
 
385
 
 
386
        *filename = auth_filename;
 
387
        auth_filename = NULL;
 
388
 
 
389
        /* don't close it */
 
390
        fd = -1;
 
391
out:
 
392
        g_free (template);
 
393
        g_free (auth_filename);
 
394
        if (fd != -1) {
 
395
                close (fd);
 
396
        }
 
397
 
 
398
        return fp;
 
399
}
 
400
 
 
401
gboolean
 
402
gdm_display_access_file_open (GdmDisplayAccessFile  *file,
 
403
                              GError               **error)
 
404
{
 
405
        GError *create_error;
 
406
 
 
407
        g_return_val_if_fail (file != NULL, FALSE);
 
408
        g_return_val_if_fail (file->priv->fp == NULL, FALSE);
 
409
        g_return_val_if_fail (file->priv->path == NULL, FALSE);
 
410
 
 
411
        create_error = NULL;
 
412
        file->priv->fp = _create_xauth_file_for_user (file->priv->username,
 
413
                                                      &file->priv->path,
 
414
                                                      &create_error);
 
415
 
 
416
        if (file->priv->fp == NULL) {
 
417
                g_propagate_error (error, create_error);
 
418
                return FALSE;
 
419
        }
 
420
 
 
421
        return TRUE;
 
422
}
 
423
 
 
424
static void
 
425
_get_auth_info_for_display (GdmDisplayAccessFile *file,
 
426
                            GdmDisplay           *display,
 
427
                            unsigned short       *family,
 
428
                            unsigned short       *address_length,
 
429
                            char                **address,
 
430
                            unsigned short       *number_length,
 
431
                            char                **number,
 
432
                            unsigned short       *name_length,
 
433
                            char                **name)
 
434
{
 
435
        int display_number;
 
436
        gboolean is_local;
 
437
 
 
438
        gdm_display_is_local (display, &is_local, NULL);
 
439
 
 
440
        if (is_local) {
 
441
                char localhost[HOST_NAME_MAX + 1] = "";
 
442
                *family = FamilyLocal;
 
443
                if (gethostname (localhost, HOST_NAME_MAX) == 0) {
 
444
                        *address = g_strdup (localhost);
 
445
                } else {
 
446
                        *address = g_strdup ("localhost");
 
447
                }
 
448
        } else {
 
449
                *family = FamilyWild;
 
450
                gdm_display_get_remote_hostname (display, address, NULL);
 
451
        }
 
452
        *address_length = strlen (*address);
 
453
 
 
454
        gdm_display_get_x11_display_number (display, &display_number, NULL);
 
455
        *number = g_strdup_printf ("%d", display_number);
 
456
        *number_length = strlen (*number);
 
457
 
 
458
        *name = g_strdup ("MIT-MAGIC-COOKIE-1");
 
459
        *name_length = strlen (*name);
 
460
}
 
461
 
 
462
gboolean
 
463
gdm_display_access_file_add_display (GdmDisplayAccessFile  *file,
 
464
                                     GdmDisplay            *display,
 
465
                                     char                 **cookie,
 
466
                                     gsize                 *cookie_size,
 
467
                                     GError               **error)
 
468
{
 
469
        GError  *add_error;
 
470
        gboolean display_added;
 
471
 
 
472
        g_return_val_if_fail (file != NULL, FALSE);
 
473
        g_return_val_if_fail (file->priv->path != NULL, FALSE);
 
474
        g_return_val_if_fail (cookie != NULL, FALSE);
 
475
 
 
476
        add_error = NULL;
 
477
        *cookie = gdm_generate_random_bytes (GDM_DISPLAY_ACCESS_COOKIE_SIZE,
 
478
                                             &add_error);
 
479
 
 
480
        if (*cookie == NULL) {
 
481
                g_propagate_error (error, add_error);
 
482
                return FALSE;
 
483
        }
 
484
 
 
485
        *cookie_size = GDM_DISPLAY_ACCESS_COOKIE_SIZE;
 
486
 
 
487
        display_added = gdm_display_access_file_add_display_with_cookie (file, display,
 
488
                                                                         *cookie,
 
489
                                                                         *cookie_size,
 
490
                                                                         &add_error);
 
491
        if (!display_added) {
 
492
                g_free (*cookie);
 
493
                *cookie = NULL;
 
494
                g_propagate_error (error, add_error);
 
495
                return FALSE;
 
496
        }
 
497
 
 
498
        return TRUE;
 
499
}
 
500
 
 
501
gboolean
 
502
gdm_display_access_file_add_display_with_cookie (GdmDisplayAccessFile  *file,
 
503
                                                 GdmDisplay            *display,
 
504
                                                 const char            *cookie,
 
505
                                                 gsize                  cookie_size,
 
506
                                                 GError               **error)
 
507
{
 
508
        Xauth auth_entry;
 
509
        gboolean display_added;
 
510
 
 
511
        g_return_val_if_fail (file != NULL, FALSE);
 
512
        g_return_val_if_fail (file->priv->path != NULL, FALSE);
 
513
        g_return_val_if_fail (cookie != NULL, FALSE);
 
514
 
 
515
        _get_auth_info_for_display (file, display,
 
516
                                    &auth_entry.family,
 
517
                                    &auth_entry.address_length,
 
518
                                    &auth_entry.address,
 
519
                                    &auth_entry.number_length,
 
520
                                    &auth_entry.number,
 
521
                                    &auth_entry.name_length,
 
522
                                    &auth_entry.name);
 
523
 
 
524
        auth_entry.data = (char *) cookie;
 
525
        auth_entry.data_length = cookie_size;
 
526
 
 
527
        /* FIXME: We should lock the file in case the X server is
 
528
         * trying to use it, too.
 
529
         */
 
530
        if (!XauWriteAuth (file->priv->fp, &auth_entry)
 
531
            || fflush (file->priv->fp) == EOF) {
 
532
                g_set_error (error,
 
533
                        G_FILE_ERROR,
 
534
                        g_file_error_from_errno (errno),
 
535
                        "%s", g_strerror (errno));
 
536
                display_added = FALSE;
 
537
        } else {
 
538
                display_added = TRUE;
 
539
        }
 
540
 
 
541
 
 
542
        g_free (auth_entry.address);
 
543
        g_free (auth_entry.number);
 
544
        g_free (auth_entry.name);
 
545
 
 
546
        return display_added;
 
547
}
 
548
 
 
549
gboolean
 
550
gdm_display_access_file_remove_display (GdmDisplayAccessFile  *file,
 
551
                                        GdmDisplay            *display,
 
552
                                        GError               **error)
 
553
{
 
554
        Xauth           *auth_entry;
 
555
        unsigned short  family;
 
556
        unsigned short  address_length;
 
557
        char           *address;
 
558
        unsigned short  number_length;
 
559
        char           *number;
 
560
        unsigned short  name_length;
 
561
        char           *name;
 
562
 
 
563
 
 
564
        g_return_val_if_fail (file != NULL, FALSE);
 
565
        g_return_val_if_fail (file->priv->path != NULL, FALSE);
 
566
 
 
567
        _get_auth_info_for_display (file, display,
 
568
                                    &family,
 
569
                                    &address_length,
 
570
                                    &address,
 
571
                                    &number_length,
 
572
                                    &number,
 
573
                                    &name_length,
 
574
                                    &name);
 
575
 
 
576
        auth_entry = XauGetAuthByAddr (family,
 
577
                                       address_length,
 
578
                                       address,
 
579
                                       number_length,
 
580
                                       number,
 
581
                                       name_length,
 
582
                                       name);
 
583
        g_free (address);
 
584
        g_free (number);
 
585
        g_free (name);
 
586
 
 
587
        if (auth_entry == NULL) {
 
588
                g_set_error (error,
 
589
                             GDM_DISPLAY_ACCESS_FILE_ERROR,
 
590
                             GDM_DISPLAY_ACCESS_FILE_ERROR_FINDING_AUTH_ENTRY,
 
591
                             "could not find authorization entry");
 
592
                return FALSE;
 
593
        }
 
594
 
 
595
        XauDisposeAuth (auth_entry);
 
596
 
 
597
        if (fflush (file->priv->fp) == EOF) {
 
598
                g_set_error (error,
 
599
                             G_FILE_ERROR,
 
600
                             g_file_error_from_errno (errno),
 
601
                             "%s", g_strerror (errno));
 
602
                return FALSE;
 
603
        }
 
604
 
 
605
        return TRUE;
 
606
}
 
607
 
 
608
void
 
609
gdm_display_access_file_close (GdmDisplayAccessFile  *file)
 
610
{
 
611
        char *auth_dir;
 
612
 
 
613
        g_return_if_fail (file != NULL);
 
614
        g_return_if_fail (file->priv->fp != NULL);
 
615
        g_return_if_fail (file->priv->path != NULL);
 
616
 
 
617
        errno = 0;
 
618
        if (g_unlink (file->priv->path) != 0) {
 
619
                g_warning ("GdmDisplayAccessFile: Unable to remove X11 authority database '%s': %s",
 
620
                           file->priv->path,
 
621
                           g_strerror (errno));
 
622
        }
 
623
 
 
624
        /* still try to remove dir even if file remove failed,
 
625
           may have already been removed by someone else */
 
626
        /* we own the parent directory too */
 
627
        auth_dir = g_path_get_dirname (file->priv->path);
 
628
        if (auth_dir != NULL) {
 
629
                errno = 0;
 
630
                if (g_rmdir (auth_dir) != 0) {
 
631
                        g_warning ("GdmDisplayAccessFile: Unable to remove X11 authority directory '%s': %s",
 
632
                                   auth_dir,
 
633
                                   g_strerror (errno));
 
634
                }
 
635
                g_free (auth_dir);
 
636
        }
 
637
 
 
638
        g_free (file->priv->path);
 
639
        file->priv->path = NULL;
 
640
        g_object_notify (G_OBJECT (file), "path");
 
641
 
 
642
        fclose (file->priv->fp);
 
643
        file->priv->fp = NULL;
 
644
}
 
645
 
 
646
char *
 
647
gdm_display_access_file_get_path (GdmDisplayAccessFile *access_file)
 
648
{
 
649
        return g_strdup (access_file->priv->path);
 
650
}