Blob Blame History Raw
Index: common/gdm-common.c
===================================================================
--- common/gdm-common.c	(revision 5498)
+++ common/gdm-common.c	(working copy)
@@ -32,7 +32,6 @@
 #include <glib/gstdio.h>
 
 #include "gdm-common.h"
-#include "gdm-md5.h"
 
 void
 gdm_set_fatal_warnings_if_unstable (void)
@@ -273,203 +272,3 @@ gdm_string_hex_decode (const GString *so
 
         return retval;
 }
-
-static void
-_gdm_generate_pseudorandom_bytes_buffer (char *buffer,
-                                         int   n_bytes)
-{
-        int i;
-
-        /* fall back to pseudorandom */
-        g_debug ("Falling back to pseudorandom for %d bytes\n",
-                 n_bytes);
-
-        i = 0;
-        while (i < n_bytes) {
-                int b;
-
-                b = g_random_int_range (0, 255);
-
-                buffer[i] = b;
-
-                ++i;
-        }
-}
-
-static gboolean
-_gdm_generate_pseudorandom_bytes (GString *str,
-                                  int      n_bytes)
-{
-        int old_len;
-        char *p;
-
-        old_len = str->len;
-
-        str = g_string_set_size (str, old_len + n_bytes);
-
-        p = str->str + old_len;
-
-        _gdm_generate_pseudorandom_bytes_buffer (p, n_bytes);
-
-        return TRUE;
-}
-
-
-static int
-_gdm_fdread (int            fd,
-             GString       *buffer,
-             int            count)
-{
-        int   bytes_read;
-        int   start;
-        char *data;
-
-        g_assert (count >= 0);
-
-        start = buffer->len;
-
-        buffer = g_string_set_size (buffer, start + count);
-
-        data = buffer->str + start;
-
- again:
-        bytes_read = read (fd, data, count);
-
-        if (bytes_read < 0) {
-                if (errno == EINTR) {
-                        goto again;
-                } else {
-                        /* put length back (note that this doesn't actually realloc anything) */
-                        buffer = g_string_set_size (buffer, start);
-                        return -1;
-                }
-        } else {
-                /* put length back (doesn't actually realloc) */
-                buffer = g_string_set_size (buffer, start + bytes_read);
-
-                return bytes_read;
-        }
-}
-
-/**
- * Closes a file descriptor.
- *
- * @param fd the file descriptor
- * @param error error object
- * @returns #FALSE if error set
- */
-static gboolean
-_gdm_fdclose (int fd)
-{
- again:
-        if (close (fd) < 0) {
-                if (errno == EINTR)
-                        goto again;
-
-                g_warning ("Could not close fd %d: %s",
-                           fd,
-                           g_strerror (errno));
-                return FALSE;
-        }
-
-        return TRUE;
-}
-
-/**
- * Generates the given number of random bytes,
- * using the best mechanism we can come up with.
- *
- * @param str the string
- * @param n_bytes the number of random bytes to append to string
- */
-gboolean
-gdm_generate_random_bytes (GString *str,
-                           int      n_bytes)
-{
-        int old_len;
-        int fd;
-
-        /* FALSE return means "no memory", if it could
-         * mean something else then we'd need to return
-         * a DBusError. So we always fall back to pseudorandom
-         * if the I/O fails.
-         */
-
-        old_len = str->len;
-        fd = -1;
-
-        /* note, urandom on linux will fall back to pseudorandom */
-        fd = g_open ("/dev/urandom", O_RDONLY, 0);
-        if (fd < 0) {
-                return _gdm_generate_pseudorandom_bytes (str, n_bytes);
-        }
-
-        if (_gdm_fdread (fd, str, n_bytes) != n_bytes) {
-                _gdm_fdclose (fd);
-                str = g_string_set_size (str, old_len);
-                return _gdm_generate_pseudorandom_bytes (str, n_bytes);
-        }
-
-        g_debug ("Read %d bytes from /dev/urandom\n", n_bytes);
-
-        _gdm_fdclose (fd);
-
-        return TRUE;
-}
-
-/**
- * Computes the ASCII hex-encoded md5sum of the given data and
- * appends it to the output string.
- *
- * @param data input data to be hashed
- * @param ascii_output string to append ASCII md5sum to
- * @returns #FALSE if not enough memory
- */
-static gboolean
-gdm_md5_compute (const GString *data,
-                 GString       *ascii_output)
-{
-        GdmMD5Context context;
-        GString      *digest;
-
-        gdm_md5_init (&context);
-
-        gdm_md5_update (&context, data);
-
-        digest = g_string_new (NULL);
-        if (digest == NULL)
-                return FALSE;
-
-        if (! gdm_md5_final (&context, digest))
-                goto error;
-
-        if (! gdm_string_hex_encode (digest,
-                                     0,
-                                     ascii_output,
-                                     ascii_output->len))
-                goto error;
-
-        g_string_free (digest, TRUE);
-
-        return TRUE;
-
- error:
-        g_string_free (digest, TRUE);
-
-        return FALSE;
-}
-
-gboolean
-gdm_generate_cookie (GString *result)
-{
-        gboolean ret;
-        GString *data;
-
-        data = g_string_new (NULL);
-        gdm_generate_random_bytes (data, 16);
-
-        ret = gdm_md5_compute (data, result);
-        g_string_free (data, TRUE);
-
-        return ret;
-}
Index: common/gdm-common.h
===================================================================
--- common/gdm-common.h	(revision 5498)
+++ common/gdm-common.h	(working copy)
@@ -32,9 +32,6 @@ void           gdm_set_fatal_warnings_if
 int            gdm_signal_pid            (int pid,
                                           int signal);
 
-gboolean       gdm_generate_random_bytes (GString *str,
-                                          int      n_bytes);
-
 gboolean       gdm_string_hex_encode     (const GString *source,
                                           int            start,
                                           GString       *dest,
@@ -44,7 +41,6 @@ gboolean       gdm_string_hex_decode    
                                           int           *end_return,
                                           GString       *dest,
                                           int            insert_at);
-gboolean       gdm_generate_cookie       (GString *result);
 
 G_END_DECLS
 
Index: daemon/gdm-local-display-factory.c
===================================================================
--- daemon/gdm-local-display-factory.c	(revision 5498)
+++ daemon/gdm-local-display-factory.c	(working copy)
@@ -89,6 +89,12 @@ create_display_for_device (GdmLocalDispl
                 return;
         }
 
+        if (! gdm_display_create_authority (display)) {
+                g_warning ("Unable to set up access control for display %d",
+                           0);
+                return;
+        }
+
         gdm_display_store_add (store, display);
         /* let store own the ref */
         g_object_unref (display);
Index: daemon/gdm-server.c
===================================================================
--- daemon/gdm-server.c	(revision 5498)
+++ daemon/gdm-server.c	(working copy)
@@ -743,6 +743,14 @@ _gdm_server_set_display_name (GdmServer 
 }
 
 static void
+_gdm_server_set_auth_file (GdmServer  *server,
+                           const char *auth_file)
+{
+        g_free (server->priv->auth_file);
+        server->priv->auth_file = g_strdup (auth_file);
+}
+
+static void
 _gdm_server_set_user_name (GdmServer  *server,
                            const char *name)
 {
@@ -764,6 +772,9 @@ gdm_server_set_property (GObject      *o
         case PROP_DISPLAY_NAME:
                 _gdm_server_set_display_name (self, g_value_get_string (value));
                 break;
+        case PROP_AUTH_FILE:
+                _gdm_server_set_auth_file (self, g_value_get_string (value));
+                break;
         case PROP_USER_NAME:
                 _gdm_server_set_user_name (self, g_value_get_string (value));
                 break;
@@ -791,6 +802,9 @@ gdm_server_get_property (GObject    *obj
                 g_value_take_string (value,
                                      gdm_server_get_display_device (self));
                 break;
+        case PROP_AUTH_FILE:
+                g_value_set_string (value, self->priv->auth_file);
+                break;
         case PROP_USER_NAME:
                 g_value_set_string (value, self->priv->user_name);
                 break;
@@ -853,6 +867,13 @@ gdm_server_class_init (GdmServerClass *k
                                                               "Path to terminal display is running on",
                                                               NULL,
                                                               G_PARAM_READABLE));
+        g_object_class_install_property (object_class,
+                                         PROP_AUTH_FILE,
+                                         g_param_spec_string ("auth-file",
+                                                              "Authorization File",
+                                                              "Path to X authorization file",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
         g_object_class_install_property (object_class,
                                          PROP_USER_NAME,
@@ -897,12 +918,14 @@ gdm_server_finalize (GObject *object)
 }
 
 GdmServer *
-gdm_server_new (const char *display_name)
+gdm_server_new (const char *display_name,
+                const char *auth_file)
 {
         GObject *object;
 
         object = g_object_new (GDM_TYPE_SERVER,
                                "display-name", display_name,
+                               "auth-file", auth_file,
                                NULL);
 
         return GDM_SERVER (object);
Index: daemon/gdm-server.h
===================================================================
--- daemon/gdm-server.h	(revision 5498)
+++ daemon/gdm-server.h	(working copy)
@@ -49,7 +49,8 @@ typedef struct
 } GdmServerClass;
 
 GType               gdm_server_get_type  (void);
-GdmServer *         gdm_server_new       (const char *display_id);
+GdmServer *         gdm_server_new       (const char *display_id,
+                                          const char *auth_file);
 gboolean            gdm_server_start     (GdmServer   *server);
 gboolean            gdm_server_stop      (GdmServer   *server);
 char *              gdm_server_get_display_device (GdmServer *server);
Index: daemon/gdm-xdmcp-display.c
===================================================================
--- daemon/gdm-xdmcp-display.c	(revision 5498)
+++ daemon/gdm-xdmcp-display.c	(working copy)
@@ -42,8 +42,6 @@
 #include "gdm-common.h"
 #include "gdm-address.h"
 
-#include "auth.h"
-
 #define GDM_XDMCP_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_XDMCP_DISPLAY, GdmXdmcpDisplayPrivate))
 
 struct GdmXdmcpDisplayPrivate
@@ -83,75 +81,9 @@ gdm_xdmcp_display_get_remote_address (Gd
 static gboolean
 gdm_xdmcp_display_create_authority (GdmDisplay *display)
 {
-        FILE    *af;
-        int      closeret;
-        gboolean ret;
-        char    *authfile;
-        int      display_num;
-        char    *x11_display;
-        GString *cookie;
-        GSList  *authlist;
-        char    *basename;
-
-        ret = FALSE;
-        x11_display = NULL;
-
-        g_object_get (display,
-                      "x11-display-name", &x11_display,
-                      "x11-display-number", &display_num,
-                      NULL);
-
-        /* Create new random cookie */
-        cookie = g_string_new (NULL);
-        gdm_generate_cookie (cookie);
-
-        g_debug ("GdmXdmcpDisplay: Setting up access for %s", x11_display);
-
-        /* gdm and xserver authfile can be the same, server will run as root */
-        basename = g_strconcat (x11_display, ".Xauth", NULL);
-        authfile = g_build_filename (AUTHDIR, basename, NULL);
-        g_free (basename);
-
-        af = gdm_safe_fopen_w (authfile, 0644);
-        if (af == NULL) {
-                g_warning (_("Cannot safely open %s"), authfile);
-                g_free (authfile);
-                goto out;
-        }
-
-        g_debug ("GdmXdmcpDisplay: Adding auth entry for xdmcp display:%d cookie:%s", display_num, cookie->str);
-        authlist = NULL;
-        if (! gdm_auth_add_entry_for_display (display_num, NULL, cookie, af, &authlist)) {
-                goto out;
-        }
-
-        g_debug ("GdmXdmcpDisplay: Setting up access");
-
-        VE_IGNORE_EINTR (closeret = fclose (af));
-        if (closeret < 0) {
-                g_warning (_("Could not write new authorization entry: %s"),
-                           g_strerror (errno));
-                goto out;
-        }
-
-        g_debug ("GdmXdmcpDisplay: Set up access for %s - %d entries",
-                 x11_display,
-                 g_slist_length (authlist));
-
-        /* FIXME: save authlist */
-
-        g_object_set (display,
-                      "x11-authority-file", authfile,
-                      "x11-cookie", cookie->str,
-                      NULL);
-
-        ret = TRUE;
-
- out:
-        g_free (x11_display);
-        g_string_free (cookie, TRUE);
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
 
-        return ret;
+        return GDM_DISPLAY_CLASS (gdm_xdmcp_display_parent_class)->create_authority (display);
 }
 
 static gboolean
@@ -160,26 +92,7 @@ gdm_xdmcp_display_add_user_authorization
                                           char      **filename,
                                           GError    **error)
 {
-        gboolean res;
-        char    *cookie;
-        char    *hostname;
-        int      display_num;
-
-        res = gdm_display_get_x11_cookie (display, &cookie, NULL);
-        res = gdm_display_get_x11_display_number (display, &display_num, NULL);
-
-        hostname = NULL;
-        res = gdm_address_get_hostname (GDM_XDMCP_DISPLAY (display)->priv->remote_address, &hostname);
-        g_debug ("GdmXdmcpDisplay: add user auth for xdmcp display: %s host:%s", username, hostname);
-        gdm_address_debug (GDM_XDMCP_DISPLAY (display)->priv->remote_address);
-        g_free (hostname);
-
-        res = gdm_auth_user_add (display_num,
-                                 GDM_XDMCP_DISPLAY (display)->priv->remote_address,
-                                 username,
-                                 cookie,
-                                 filename);
-        return res;
+        return GDM_DISPLAY_CLASS (gdm_xdmcp_display_parent_class)->add_user_authorization (display, username, filename, error);
 }
 
 static gboolean
@@ -187,7 +100,7 @@ gdm_xdmcp_display_remove_user_authorizat
                                              const char *username,
                                              GError    **error)
 {
-        return TRUE;
+        return GDM_DISPLAY_CLASS (gdm_xdmcp_display_parent_class)->remove_user_authorization (display, username, error);
 }
 
 static gboolean
@@ -206,7 +119,6 @@ gdm_xdmcp_display_unmanage (GdmDisplay *
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
 
         GDM_DISPLAY_CLASS (gdm_xdmcp_display_parent_class)->unmanage (display);
-
         return TRUE;
 }
 
Index: daemon/gdm-product-slave.c
===================================================================
--- daemon/gdm-product-slave.c	(revision 5498)
+++ daemon/gdm-product-slave.c	(working copy)
@@ -335,11 +335,13 @@ static gboolean
 gdm_product_slave_create_server (GdmProductSlave *slave)
 {
         char    *display_name;
+        char    *auth_file;
         gboolean display_is_local;
 
         g_object_get (slave,
                       "display-is-local", &display_is_local,
                       "display-name", &display_name,
+                      "display-x11-authority-file", &auth_file,
                       NULL);
 
         /* if this is local display start a server if one doesn't
@@ -347,7 +349,7 @@ gdm_product_slave_create_server (GdmProd
         if (display_is_local) {
                 gboolean res;
 
-                slave->priv->server = gdm_server_new (display_name);
+                slave->priv->server = gdm_server_new (display_name, auth_file);
 
                 g_signal_connect (slave->priv->server,
                                   "ready",
@@ -373,6 +375,7 @@ gdm_product_slave_create_server (GdmProd
         }
 
         g_free (display_name);
+        g_free (auth_file);
 
         return TRUE;
 }
Index: daemon/auth.c
===================================================================
--- daemon/auth.c	(revision 5498)
+++ daemon/auth.c	(working copy)
@@ -1,240 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/* Code for cookie handling. This really needs to be modularized to
- * support other XAuth types and possibly DECnet... */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <pwd.h>
-
-#include <X11/Xauth.h>
-
-#include <glib.h>
-#include <glib/gi18n.h>
-
-#include "auth.h"
-
-#include "gdm-common.h"
-#include "gdm-address.h"
-#include "gdm-log.h"
-
-gboolean
-gdm_auth_add_entry (int            display_num,
-                    GdmAddress    *address,
-                    GString       *binary_cookie,
-                    FILE          *af,
-                    GSList       **authlist)
-{
-        Xauth *xa;
-        char  *dispnum;
-
-        xa = malloc (sizeof (Xauth));
-
-        if (xa == NULL) {
-                return FALSE;
-        }
-
-        if (address == NULL) {
-                xa->family = FamilyWild;
-                xa->address = NULL;
-                xa->address_length = 0;
-        } else {
-                gboolean res;
-                char    *hostname;
-
-                xa->family = gdm_address_get_family_type (address);
-
-                res = gdm_address_get_hostname (address, &hostname);
-                if (! res) {
-                        free (xa);
-                        return FALSE;
-                }
-
-                g_debug ("Got hostname: %s", hostname);
-
-                xa->address = hostname;
-                xa->address_length = strlen (xa->address);
-        }
-
-        dispnum = g_strdup_printf ("%d", display_num);
-        xa->number = strdup (dispnum);
-        xa->number_length = strlen (dispnum);
-        g_free (dispnum);
-
-        xa->name = strdup ("MIT-MAGIC-COOKIE-1");
-        xa->name_length = strlen ("MIT-MAGIC-COOKIE-1");
-        xa->data = malloc (16);
-        if (xa->data == NULL) {
-                free (xa->number);
-                free (xa->name);
-                free (xa->address);
-                free (xa);
-                return FALSE;
-        }
-
-        memcpy (xa->data, binary_cookie->str, binary_cookie->len);
-        xa->data_length = binary_cookie->len;
-
-        g_debug ("Writing auth for address:%p %s:%d", address, xa->address, display_num);
-
-        if (af != NULL) {
-                errno = 0;
-                if ( ! XauWriteAuth (af, xa)) {
-                        free (xa->data);
-                        free (xa->number);
-                        free (xa->name);
-                        free (xa->address);
-                        free (xa);
-
-                        if (errno != 0) {
-                                g_warning (_("%s: Could not write new authorization entry: %s"),
-                                           "add_auth_entry", g_strerror (errno));
-                        } else {
-                                g_warning (_("%s: Could not write new authorization entry.  "
-                                             "Possibly out of diskspace"),
-                                           "add_auth_entry");
-                        }
-
-                        return FALSE;
-                }
-        }
-
-        if (authlist != NULL) {
-                *authlist = g_slist_append (*authlist, xa);
-        }
-
-        return TRUE;
-}
-
-gboolean
-gdm_auth_add_entry_for_display (int         display_num,
-                                GdmAddress *address,
-                                GString    *cookie,
-                                FILE       *af,
-                                GSList    **authlist)
-{
-        GString *binary_cookie;
-        gboolean ret;
-
-        binary_cookie = g_string_new (NULL);
-
-        if (! gdm_string_hex_decode (cookie,
-                                     0,
-                                     NULL,
-                                     binary_cookie,
-                                     0)) {
-                ret = FALSE;
-                goto out;
-        }
-
-        ret = gdm_auth_add_entry (display_num,
-                                  address,
-                                  binary_cookie,
-                                  af,
-                                  authlist);
-
- out:
-        g_string_free (binary_cookie, TRUE);
-        return ret;
-}
-
-gboolean
-gdm_auth_user_add (int         display_num,
-                   GdmAddress *address,
-                   const char *username,
-                   const char *cookie,
-                   char      **filenamep)
-{
-        int            fd;
-        char          *filename;
-        GError        *error;
-        mode_t         old_mask;
-        FILE          *af;
-        gboolean       ret;
-        struct passwd *pwent;
-        GString       *cookie_str;
-
-        g_debug ("Add user auth for address:%p num:%d user:%s", address, display_num, username);
-
-        ret = FALSE;
-        filename = NULL;
-        af = NULL;
-        fd = -1;
-
-        old_mask = umask (077);
-
-        filename = NULL;
-        error = NULL;
-        fd = g_file_open_tmp (".gdmXXXXXX", &filename, &error);
-
-        umask (old_mask);
-
-        if (fd == -1) {
-                g_warning ("Unable to create temporary file: %s", error->message);
-                g_error_free (error);
-                goto out;
-        }
-
-        if (filenamep != NULL) {
-                *filenamep = g_strdup (filename);
-        }
-
-        VE_IGNORE_EINTR (af = fdopen (fd, "w"));
-        if (af == NULL) {
-                g_warning ("Unable to open cookie file: %s", filename);
-                goto out;
-        }
-
-        /* FIXME: clean old files? */
-
-        cookie_str = g_string_new (cookie);
-
-        /* FIXME: ?? */
-        /*gdm_auth_add_entry_for_display (display_num, address, cookie_str, af, NULL);*/
-        gdm_auth_add_entry_for_display (display_num, NULL, cookie_str, af, NULL);
-        g_string_free (cookie_str, TRUE);
-
-        pwent = getpwnam (username);
-        if (pwent == NULL) {
-                goto out;
-        }
-
-        fchown (fd, pwent->pw_uid, -1);
-
-        ret = TRUE;
- out:
-        g_free (filename);
-
-        if (af != NULL) {
-                fclose (af);
-        }
-
-        return ret;
-}
Index: daemon/auth.h
===================================================================
--- daemon/auth.h	(revision 5498)
+++ daemon/auth.h	(working copy)
@@ -1,49 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef GDM_AUTH_H
-#define GDM_AUTH_H
-
-#include <glib.h>
-#include "gdm-address.h"
-
-G_BEGIN_DECLS
-
-gboolean gdm_auth_add_entry_for_display (int         display_num,
-                                         GdmAddress *address,
-                                         GString    *cookie,
-                                         FILE       *af,
-                                         GSList    **authlist);
-
-gboolean gdm_auth_add_entry             (int         display_num,
-                                         GdmAddress *address,
-                                         GString    *binary_cookie,
-                                         FILE       *af,
-                                         GSList    **authlist);
-
-gboolean gdm_auth_user_add              (int         display_num,
-                                         GdmAddress *address,
-                                         const char *cookie,
-                                         const char *username,
-                                         char      **filenamep);
-
-void     gdm_auth_free_auth_list (GSList     *list);
-
-G_END_DECLS
-
-#endif /* GDM_AUTH_H */
Index: daemon/gdm-slave.c
===================================================================
--- daemon/gdm-slave.c	(revision 5498)
+++ daemon/gdm-slave.c	(working copy)
@@ -75,7 +75,6 @@ struct GdmSlavePrivate
         gboolean         display_is_local;
         gboolean         display_is_parented;
         char            *display_x11_authority_file;
-        char            *display_x11_cookie;
         char            *parent_display_name;
         char            *parent_display_x11_authority_file;
 
@@ -94,8 +93,7 @@ enum {
         PROP_DISPLAY_NUMBER,
         PROP_DISPLAY_HOSTNAME,
         PROP_DISPLAY_IS_LOCAL,
-        PROP_DISPLAY_X11_AUTHORITY_FILE,
-        PROP_DISPLAY_X11_COOKIE,
+        PROP_DISPLAY_X11_AUTHORITY_FILE
 };
 
 enum {
@@ -354,37 +352,6 @@ gdm_slave_set_busy_cursor (GdmSlave *sla
         }
 }
 
-static void
-set_local_auth (GdmSlave *slave)
-{
-        GString *binary_cookie;
-        GString *cookie;
-
-        g_debug ("GdmSlave: Setting authorization key for display %s", slave->priv->display_x11_cookie);
-
-        cookie = g_string_new (slave->priv->display_x11_cookie);
-        binary_cookie = g_string_new (NULL);
-        if (! gdm_string_hex_decode (cookie,
-                                     0,
-                                     NULL,
-                                     binary_cookie,
-                                     0)) {
-                g_warning ("Unable to decode hex cookie");
-                goto out;
-        }
-
-        g_debug ("GdmSlave: Decoded cookie len %d", (int) binary_cookie->len);
-
-        XSetAuthorization ("MIT-MAGIC-COOKIE-1",
-                           (int) strlen ("MIT-MAGIC-COOKIE-1"),
-                           (char *)binary_cookie->str,
-                           binary_cookie->len);
-
- out:
-        g_string_free (binary_cookie, TRUE);
-        g_string_free (cookie, TRUE);
-}
-
 gboolean
 gdm_slave_connect_to_x11_display (GdmSlave *slave)
 {
@@ -400,9 +367,7 @@ gdm_slave_connect_to_x11_display (GdmSla
         g_debug ("GdmSlave: Server is ready - opening display %s", slave->priv->display_name);
 
         g_setenv ("DISPLAY", slave->priv->display_name, TRUE);
-        g_unsetenv ("XAUTHORITY"); /* just in case it's set */
-
-        set_local_auth (slave);
+        g_setenv ("XAUTHORITY", slave->priv->display_x11_authority_file, TRUE);
 
 #if 0
         /* X error handlers to avoid the default one (i.e. exit (1)) */
@@ -574,24 +539,6 @@ gdm_slave_real_start (GdmSlave *slave)
 
         error = NULL;
         res = dbus_g_proxy_call (slave->priv->display_proxy,
-                                 "GetX11Cookie",
-                                 &error,
-                                 G_TYPE_INVALID,
-                                 G_TYPE_STRING, &slave->priv->display_x11_cookie,
-                                 G_TYPE_INVALID);
-        if (! res) {
-                if (error != NULL) {
-                        g_warning ("Failed to get value: %s", error->message);
-                        g_error_free (error);
-                } else {
-                        g_warning ("Failed to get value");
-                }
-
-                return FALSE;
-        }
-
-        error = NULL;
-        res = dbus_g_proxy_call (slave->priv->display_proxy,
                                  "GetX11AuthorityFile",
                                  &error,
                                  G_TYPE_INVALID,
@@ -743,14 +690,6 @@ _gdm_slave_set_display_x11_authority_fil
 }
 
 static void
-_gdm_slave_set_display_x11_cookie (GdmSlave   *slave,
-                                   const char *name)
-{
-        g_free (slave->priv->display_x11_cookie);
-        slave->priv->display_x11_cookie = g_strdup (name);
-}
-
-static void
 _gdm_slave_set_display_is_local (GdmSlave   *slave,
                                  gboolean    is)
 {
@@ -783,9 +722,6 @@ gdm_slave_set_property (GObject      *ob
         case PROP_DISPLAY_X11_AUTHORITY_FILE:
                 _gdm_slave_set_display_x11_authority_file (self, g_value_get_string (value));
                 break;
-        case PROP_DISPLAY_X11_COOKIE:
-                _gdm_slave_set_display_x11_cookie (self, g_value_get_string (value));
-                break;
         case PROP_DISPLAY_IS_LOCAL:
                 _gdm_slave_set_display_is_local (self, g_value_get_boolean (value));
                 break;
@@ -821,9 +757,6 @@ gdm_slave_get_property (GObject    *obje
         case PROP_DISPLAY_X11_AUTHORITY_FILE:
                 g_value_set_string (value, self->priv->display_x11_authority_file);
                 break;
-        case PROP_DISPLAY_X11_COOKIE:
-                g_value_set_string (value, self->priv->display_x11_cookie);
-                break;
         case PROP_DISPLAY_IS_LOCAL:
                 g_value_set_boolean (value, self->priv->display_is_local);
                 break;
@@ -938,13 +871,6 @@ gdm_slave_class_init (GdmSlaveClass *kla
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
         g_object_class_install_property (object_class,
-                                         PROP_DISPLAY_X11_COOKIE,
-                                         g_param_spec_string ("display-x11-cookie",
-                                                              "",
-                                                              "",
-                                                              NULL,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-        g_object_class_install_property (object_class,
                                          PROP_DISPLAY_IS_LOCAL,
                                          g_param_spec_boolean ("display-is-local",
                                                                "display is local",
Index: daemon/gdm-display-access-file.c
===================================================================
--- daemon/gdm-display-access-file.c	(revision 0)
+++ daemon/gdm-display-access-file.c	(revision 0)
@@ -0,0 +1,504 @@
+/* gdm-display-access-file.c - Abstraction around xauth cookies
+ *
+ * Copyright (C) 2007 Ray Strode <rstrode@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#include "config.h"
+#include "gdm-display-access-file.h"
+
+#include <errno.h>
+#include <pwd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n.h>
+
+#include <X11/Xauth.h>
+
+struct _GdmDisplayAccessFilePrivate
+{
+        char *username;
+        FILE *fp;
+        char *path;
+};
+
+#ifndef GDM_DISPLAY_ACCESS_COOKIE_SIZE
+#define GDM_DISPLAY_ACCESS_COOKIE_SIZE 16
+#endif
+
+static void gdm_display_access_file_finalize (GObject * object);
+
+enum
+{
+        PROP_0 = 0,
+        PROP_USERNAME,
+        PROP_PATH
+};
+
+G_DEFINE_TYPE (GdmDisplayAccessFile, gdm_display_access_file, G_TYPE_OBJECT);
+
+static void
+gdm_display_access_file_get_property (GObject    *object,
+                                      guint       prop_id,
+                                      GValue     *value,
+                                      GParamSpec *pspec)
+{
+        GdmDisplayAccessFile *access_file;
+
+        access_file = GDM_DISPLAY_ACCESS_FILE (object);
+
+        switch (prop_id) {
+            case PROP_USERNAME:
+                g_value_set_string (value, access_file->priv->username);
+                break;
+
+            case PROP_PATH:
+                g_value_set_string (value, access_file->priv->path);
+                break;
+
+            default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        }
+}
+
+static void
+gdm_display_access_file_set_property (GObject      *object,
+                                      guint         prop_id,
+                                      const GValue *value,
+                                      GParamSpec   *pspec)
+{
+        GdmDisplayAccessFile *access_file;
+
+        access_file = GDM_DISPLAY_ACCESS_FILE (object);
+
+        switch (prop_id) {
+            case PROP_USERNAME:
+                g_assert (access_file->priv->username == NULL);
+                access_file->priv->username = g_value_dup_string (value);
+                break;
+
+            default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        }
+}
+
+static void
+gdm_display_access_file_class_init (GdmDisplayAccessFileClass *access_file_class)
+{
+        GObjectClass *object_class;
+        GParamSpec   *param_spec;
+
+        object_class = G_OBJECT_CLASS (access_file_class);
+
+        object_class->finalize = gdm_display_access_file_finalize;
+        object_class->get_property = gdm_display_access_file_get_property;
+        object_class->set_property = gdm_display_access_file_set_property;
+
+        param_spec = g_param_spec_string ("username", "Username",
+                                          "Owner of Xauthority file",
+                                          NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+        g_object_class_install_property (object_class, PROP_USERNAME, param_spec);
+        param_spec = g_param_spec_string ("path", "Path",
+                                          "Path to Xauthority file",
+                                          NULL, G_PARAM_READABLE);
+        g_object_class_install_property (object_class, PROP_PATH, param_spec);
+        g_type_class_add_private (access_file_class, sizeof (GdmDisplayAccessFilePrivate));
+}
+
+static void
+gdm_display_access_file_init (GdmDisplayAccessFile *access_file)
+{
+        access_file->priv = G_TYPE_INSTANCE_GET_PRIVATE (access_file,
+                                                         GDM_TYPE_DISPLAY_ACCESS_FILE,
+                                                         GdmDisplayAccessFilePrivate);
+}
+
+static void
+gdm_display_access_file_finalize (GObject *object)
+{
+        GdmDisplayAccessFile *file;
+        GObjectClass *parent_class;
+
+        file = GDM_DISPLAY_ACCESS_FILE (object);
+        parent_class = G_OBJECT_CLASS (gdm_display_access_file_parent_class);
+
+        if (file->priv->fp != NULL) {
+            gdm_display_access_file_close (file);
+        }
+        g_assert (file->priv->path == NULL);
+
+        if (file->priv->username != NULL) {
+                g_free (file->priv->username);
+                file->priv->username = NULL;
+                g_object_notify (object, "username");
+        }
+
+        if (parent_class->finalize != NULL) {
+                parent_class->finalize (object);
+        }
+}
+
+GQuark
+gdm_display_access_file_error_quark (void)
+{
+        static GQuark error_quark = 0;
+
+        if (error_quark == 0) {
+                error_quark = g_quark_from_static_string ("gdm-display-access-file");
+        }
+
+        return error_quark;
+}
+
+GdmDisplayAccessFile *
+gdm_display_access_file_new (const char *username)
+{
+        GdmDisplayAccessFile *access_file;
+        g_return_val_if_fail (username != NULL, NULL);
+
+        access_file = g_object_new (GDM_TYPE_DISPLAY_ACCESS_FILE,
+                                    "username", username, NULL);
+
+        return access_file;
+}
+
+static gboolean
+_get_uid_and_gid_for_user (const char *username,
+                           uid_t      *uid,
+                           gid_t      *gid)
+{
+        struct passwd *passwd_entry;
+
+        g_assert (username != NULL);
+        g_assert (uid != NULL);
+        g_assert (gid != NULL);
+
+        errno = 0;
+        passwd_entry = getpwnam (username);
+
+        if (passwd_entry == NULL) {
+                return FALSE;
+        }
+
+        *uid = passwd_entry->pw_uid;
+        *gid = passwd_entry->pw_gid;
+
+        return TRUE;
+}
+
+static FILE *
+_create_xauth_file_for_user (const char  *username,
+                             char       **filename,
+                             GError     **error)
+{
+        char   *template;
+        GError *open_error;
+        int     fd;
+        FILE   *fp;
+        uid_t   uid;
+        gid_t   gid;
+
+        template = g_strdup_printf (".gdm-xauth-%s.XXXXXX", username);
+
+        open_error = NULL;
+        fd = g_file_open_tmp (template, filename, &open_error);
+        g_free (template);
+
+        if (fd < 0) {
+                g_propagate_error (error, open_error);
+                goto out;
+        }
+
+        if (!_get_uid_and_gid_for_user (username, &uid, &gid)) {
+                g_set_error (error,
+                             GDM_DISPLAY_ERROR,
+                             GDM_DISPLAY_ERROR_GETTING_USER_INFO,
+                             _("could not find user \"%s\" on system"),
+                             username);
+                close (fd);
+                fd = -1;
+                goto out;
+
+        }
+
+        if (fchown (fd, uid, gid) < 0) {
+                g_set_error (error,
+                             G_FILE_ERROR,
+                             g_file_error_from_errno (errno),
+                             "%s", g_strerror (errno));
+                close (fd);
+                fd = -1;
+                goto out;
+        }
+
+        fp = fdopen (fd, "w");
+
+        if (fp == NULL) {
+                g_set_error (error,
+                             G_FILE_ERROR,
+                             g_file_error_from_errno (errno),
+                             "%s", g_strerror (errno));
+                close (fd);
+                fd = -1;
+                goto out;
+        }
+out:
+        return fp;
+}
+
+gboolean
+gdm_display_access_file_open (GdmDisplayAccessFile  *file,
+                              GError               **error)
+{
+        GError *create_error;
+
+        g_return_val_if_fail (file != NULL, FALSE);
+        g_return_val_if_fail (file->priv->fp == NULL, FALSE);
+        g_return_val_if_fail (file->priv->path == NULL, FALSE);
+
+        create_error = NULL;
+        file->priv->fp = _create_xauth_file_for_user (file->priv->username,
+                                                      &file->priv->path,
+                                                      &create_error);
+
+        if (file->priv->fp == NULL) {
+                g_propagate_error (error, create_error);
+                return FALSE;
+        }
+
+        return TRUE;
+}
+
+static char *
+_generate_random_bytes (gsize size)
+{
+        char *bytes;
+        int i;
+
+        bytes = g_malloc (size);
+
+        for (i = 0; i < size; i++) {
+                guint8 byte;
+
+                byte = (guint8) g_random_int_range (0, G_MAXUINT8);
+
+                bytes[i] = (char) byte;
+        }
+
+        return bytes;
+}
+
+static void
+_get_auth_info_for_display (GdmDisplayAccessFile *file,
+                            GdmDisplay           *display,
+                            unsigned short       *family,
+                            unsigned short       *address_length,
+                            char                **address,
+                            unsigned short       *number_length,
+                            char                **number,
+                            unsigned short       *name_length,
+                            char                **name)
+{
+        int display_number;
+        gboolean is_local;
+
+        gdm_display_is_local (display, &is_local, NULL);
+
+        if (is_local) {
+                *family = FamilyLocal;
+                *address = g_strdup (g_get_host_name ());
+        } else {
+                *family = FamilyWild;
+                gdm_display_get_remote_hostname (display, address, NULL);
+        }
+        *address_length = strlen (*address);
+
+        gdm_display_get_x11_display_number (display, &display_number, NULL);
+        *number = g_strdup_printf ("%d", display_number);
+        *number_length = strlen (*number);
+
+        *name = g_strdup ("MIT-MAGIC-COOKIE-1");
+        *name_length = strlen (*name);
+}
+
+gboolean
+gdm_display_access_file_add_display (GdmDisplayAccessFile  *file,
+                                     GdmDisplay            *display,
+                                     char                 **cookie,
+                                     gsize                 *cookie_size,
+                                     GError               **error)
+{
+        GError *add_error;
+        gboolean display_added;
+
+        g_return_val_if_fail (file != NULL, FALSE);
+        g_return_val_if_fail (file->priv->path != NULL, FALSE);
+        g_return_val_if_fail (cookie != NULL, FALSE);
+
+        *cookie = _generate_random_bytes (GDM_DISPLAY_ACCESS_COOKIE_SIZE);
+        *cookie_size = GDM_DISPLAY_ACCESS_COOKIE_SIZE;
+
+        add_error = NULL;
+        display_added =
+            gdm_display_access_file_add_display_with_cookie (file, display,
+                                                             *cookie,
+                                                             *cookie_size,
+                                                             &add_error);
+        if (!display_added) {
+                g_free (*cookie);
+                *cookie = NULL;
+                g_propagate_error (error, add_error);
+                return FALSE;
+        }
+
+        return TRUE;
+}
+
+gboolean
+gdm_display_access_file_add_display_with_cookie (GdmDisplayAccessFile  *file,
+                                                 GdmDisplay            *display,
+                                                 const char            *cookie,
+                                                 gsize                  cookie_size,
+                                                 GError               **error)
+{
+        Xauth auth_entry;
+        gboolean display_added;
+
+        g_return_val_if_fail (file != NULL, FALSE);
+        g_return_val_if_fail (file->priv->path != NULL, FALSE);
+        g_return_val_if_fail (cookie != NULL, FALSE);
+
+        _get_auth_info_for_display (file, display,
+                                    &auth_entry.family,
+                                    &auth_entry.address_length,
+                                    &auth_entry.address,
+                                    &auth_entry.number_length,
+                                    &auth_entry.number,
+                                    &auth_entry.name_length,
+                                    &auth_entry.name);
+
+        auth_entry.data = (char *) cookie;
+        auth_entry.data_length = cookie_size;
+
+        /* FIXME: We should lock the file in case the X server is
+         * trying to use it, too.
+         */
+        if (!XauWriteAuth (file->priv->fp, &auth_entry)
+            || fflush (file->priv->fp) == EOF) {
+                g_set_error (error,
+                        G_FILE_ERROR,
+                        g_file_error_from_errno (errno),
+                        "%s", g_strerror (errno));
+                display_added = FALSE;
+        } else {
+                display_added = TRUE;
+        }
+
+
+        g_free (auth_entry.address);
+        g_free (auth_entry.number);
+        g_free (auth_entry.name);
+
+        return display_added;
+}
+
+gboolean
+gdm_display_access_file_remove_display (GdmDisplayAccessFile  *file,
+                                        GdmDisplay            *display,
+                                        GError               **error)
+{
+        Xauth           *auth_entry;
+        unsigned short  family;
+        unsigned short  address_length;
+        char           *address;
+        unsigned short  number_length;
+        char           *number;
+        unsigned short  name_length;
+        char           *name;
+
+
+        g_return_val_if_fail (file != NULL, FALSE);
+        g_return_val_if_fail (file->priv->path != NULL, FALSE);
+
+        _get_auth_info_for_display (file, display,
+                                    &family,
+                                    &address_length,
+                                    &address,
+                                    &number_length,
+                                    &number,
+                                    &name_length,
+                                    &name);
+
+        auth_entry = XauGetAuthByAddr (family,
+                                       address_length,
+                                       address,
+                                       number_length,
+                                       number,
+                                       name_length,
+                                       name);
+        g_free (address);
+        g_free (number);
+        g_free (name);
+
+        if (auth_entry == NULL) {
+                g_set_error (error,
+                             GDM_DISPLAY_ACCESS_FILE_ERROR,
+                             GDM_DISPLAY_ACCESS_FILE_ERROR_FINDING_AUTH_ENTRY,
+                             "could not find authorization entry");
+                return FALSE;
+        }
+
+        XauDisposeAuth (auth_entry);
+
+        if (fflush (file->priv->fp) == EOF) {
+                g_set_error (error,
+                             G_FILE_ERROR,
+                             g_file_error_from_errno (errno),
+                             "%s", g_strerror (errno));
+                return FALSE;
+        }
+
+        return TRUE;
+}
+
+void
+gdm_display_access_file_close (GdmDisplayAccessFile  *file)
+{
+        g_return_if_fail (file != NULL);
+        g_return_if_fail (file->priv->fp != NULL);
+        g_return_if_fail (file->priv->path != NULL);
+
+        g_unlink (file->priv->path);
+        if (file->priv->path != NULL) {
+                g_free (file->priv->path);
+                file->priv->path = NULL;
+                g_object_notify (G_OBJECT (file), "path");
+        }
+
+        fclose (file->priv->fp);
+        file->priv->fp = NULL;
+}
+
+char *
+gdm_display_access_file_get_path (GdmDisplayAccessFile *access_file)
+{
+        return g_strdup (access_file->priv->path);
+}
Index: daemon/gdm-display-access-file.h
===================================================================
--- daemon/gdm-display-access-file.h	(revision 0)
+++ daemon/gdm-display-access-file.h	(revision 0)
@@ -0,0 +1,86 @@
+/* gdm-display-access-file.h - Abstraction around xauth cookies
+ *
+ * Copyright (C) 2007 Ray Strode <rstrode@redhat.com>
+ *
+ * Written by Ray Strode <rstrode@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+#ifndef __GDM_DISPLAY_ACCESS_FILE_H__
+#define __GDM_DISPLAY_ACCESS_FILE_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "gdm-display.h"
+
+G_BEGIN_DECLS
+#define GDM_TYPE_DISPLAY_ACCESS_FILE            (gdm_display_access_file_get_type ())
+#define GDM_DISPLAY_ACCESS_FILE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDM_TYPE_DISPLAY_ACCESS_FILE, GdmDisplayAccessFile))
+#define GDM_DISPLAY_ACCESS_FILE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_DISPLAY_ACCESS_FILE, GdmDisplayAccessFileClass))
+#define GDM_IS_DISPLAY_ACCESS_FILE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDM_TYPE_DISPLAY_ACCESS_FILE))
+#define GDM_IS_DISPLAY_ACCESS_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_DISPLAY_ACCESS_FILE))
+#define GDM_DISPLAY_ACCESS_FILE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_DISPLAY_ACCESS_FILE, GdmDisplayAccessFileClass))
+#define GDM_DISPLAY_ACCESS_FILE_ERROR           (gdm_display_access_file_error_quark ())
+
+typedef struct _GdmDisplayAccessFile GdmDisplayAccessFile;
+typedef struct _GdmDisplayAccessFileClass GdmDisplayAccessFileClass;
+typedef struct _GdmDisplayAccessFilePrivate GdmDisplayAccessFilePrivate;
+typedef enum _GdmDisplayAccessFileError GdmDisplayAccessFileError;
+
+struct _GdmDisplayAccessFile
+{
+        GObject parent;
+
+        GdmDisplayAccessFilePrivate *priv;
+};
+
+struct _GdmDisplayAccessFileClass
+{
+        GObjectClass parent_class;
+};
+
+enum _GdmDisplayAccessFileError
+{
+        GDM_DISPLAY_ACCESS_FILE_ERROR_GENERAL = 0,
+        GDM_DISPLAY_ACCESS_FILE_ERROR_FINDING_AUTH_ENTRY
+};
+
+GQuark                gdm_display_access_file_error_quark             (void);
+GType                 gdm_display_access_file_get_type                (void);
+
+GdmDisplayAccessFile *gdm_display_access_file_new                     (const char            *username);
+gboolean              gdm_display_access_file_open                    (GdmDisplayAccessFile  *file,
+                                                                       GError               **error);
+gboolean              gdm_display_access_file_add_display             (GdmDisplayAccessFile  *file,
+                                                                       GdmDisplay            *display,
+                                                                       char                 **cookie,
+                                                                       gsize                 *cookie_size,
+                                                                       GError               **error);
+gboolean              gdm_display_access_file_add_display_with_cookie (GdmDisplayAccessFile  *file,
+                                                                       GdmDisplay            *display,
+                                                                       const char            *cookie,
+                                                                       gsize                  cookie_size,
+                                                                       GError               **error);
+gboolean              gdm_display_access_file_remove_display          (GdmDisplayAccessFile  *file,
+                                                                       GdmDisplay            *display,
+                                                                       GError               **error);
+
+void                  gdm_display_access_file_close                   (GdmDisplayAccessFile  *file);
+char                 *gdm_display_access_file_get_path                (GdmDisplayAccessFile  *file);
+
+G_END_DECLS
+#endif /* __GDM_DISPLAY_ACCESS_FILE_H__ */
Index: daemon/gdm-display.c
===================================================================
--- daemon/gdm-display.c	(revision 5498)
+++ daemon/gdm-display.c	(working copy)
@@ -35,11 +35,10 @@
 
 #include "gdm-display.h"
 #include "gdm-display-glue.h"
+#include "gdm-display-access-file.h"
 
 #include "gdm-slave-proxy.h"
 
-#include "auth.h"
-
 static guint32 display_serial = 1;
 
 #define GDM_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DISPLAY, GdmDisplayPrivate))
@@ -56,15 +55,18 @@ struct GdmDisplayPrivate
         char            *x11_display_name;
         int              status;
         time_t           creation_time;
-        char            *x11_cookie;
-        char            *x11_authority_file;
         char            *slave_command;
 
+        char                 *x11_cookie;
+        gsize                 x11_cookie_size;
+        GdmDisplayAccessFile *access_file;
+
         gboolean         is_local;
         guint            finish_idle_id;
 
         GdmSlaveProxy   *slave_proxy;
         DBusGConnection *connection;
+        GdmDisplayAccessFile *user_access_file;
 };
 
 enum {
@@ -127,10 +129,56 @@ gdm_display_get_status (GdmDisplay *disp
         return display->priv->status;
 }
 
+static GdmDisplayAccessFile *
+_create_access_file_for_user (GdmDisplay  *display,
+                              const char  *username,
+                              GError     **error)
+{
+        GdmDisplayAccessFile *access_file;
+        GError *file_error;
+
+        access_file = gdm_display_access_file_new (username);
+
+        file_error = NULL;
+        if (!gdm_display_access_file_open (access_file, &file_error)) {
+                g_propagate_error (error, file_error);
+                return FALSE;
+        }
+
+        return access_file;
+}
+
 static gboolean
 gdm_display_real_create_authority (GdmDisplay *display)
 {
+        GdmDisplayAccessFile *access_file;
+        GError *error;
+
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+        g_return_val_if_fail (display->priv->access_file == NULL, FALSE);
+
+        error = NULL;
+        access_file = _create_access_file_for_user (display, "gdm", &error);
+
+        if (access_file == NULL) {
+            g_critical ("could not create display access file: %s", error->message);
+            g_error_free (error);
+            return FALSE;
+        }
+
+        if (!gdm_display_access_file_add_display (access_file, display,
+                                                  &display->priv->x11_cookie,
+                                                  &display->priv->x11_cookie_size,
+                                                  &error)) {
+
+                g_critical ("could not add display to access file: %s", error->message);
+                g_error_free (error);
+                gdm_display_access_file_close (access_file);
+                g_object_unref (access_file);
+                return FALSE;
+        }
+
+        display->priv->access_file = access_file;
 
         return TRUE;
 }
@@ -155,11 +203,35 @@ gdm_display_real_add_user_authorization 
                                          char      **filename,
                                          GError    **error)
 {
-        gboolean ret;
+        GdmDisplayAccessFile *access_file;
+        GError *access_file_error;
 
-        ret = FALSE;
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+        g_return_val_if_fail (display->priv->access_file != NULL, FALSE);
 
-        return ret;
+        access_file_error = NULL;
+        access_file = _create_access_file_for_user (display, username,
+                                                    &access_file_error);
+
+        if (access_file == NULL) {
+            g_propagate_error (error, access_file_error);
+            return FALSE;
+        }
+
+        if (!gdm_display_access_file_add_display_with_cookie (access_file,
+                                                              display, display->priv->x11_cookie,
+                                                              display->priv->x11_cookie_size,
+                                                              &access_file_error)) {
+                g_propagate_error (error, access_file_error);
+                gdm_display_access_file_close (access_file);
+                g_object_unref (access_file);
+                return FALSE;
+        }
+
+        *filename = gdm_display_access_file_get_path (access_file);
+        display->priv->user_access_file = access_file;
+
+        return TRUE;
 }
 
 gboolean
@@ -186,11 +258,9 @@ gdm_display_real_remove_user_authorizati
                                             const char *username,
                                             GError    **error)
 {
-        gboolean ret;
+        gdm_display_access_file_close (display->priv->user_access_file);
 
-        ret = FALSE;
-
-        return ret;
+        return TRUE;
 }
 
 gboolean
@@ -214,12 +284,18 @@ gdm_display_remove_user_authorization (G
 gboolean
 gdm_display_get_x11_cookie (GdmDisplay *display,
                             char      **x11_cookie,
+                            gsize      *x11_cookie_size,
                             GError    **error)
 {
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
 
         if (x11_cookie != NULL) {
-                *x11_cookie = g_strdup (display->priv->x11_cookie);
+                *x11_cookie = g_memdup (display->priv->x11_cookie,
+                                        display->priv->x11_cookie_size);
+        }
+
+        if (x11_cookie_size != NULL) {
+                *x11_cookie_size = display->priv->x11_cookie_size;
         }
 
         return TRUE;
@@ -231,9 +307,12 @@ gdm_display_get_x11_authority_file (GdmD
                                     GError    **error)
 {
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+        g_return_val_if_fail (filename != NULL, FALSE);
 
-        if (filename != NULL) {
-                *filename = g_strdup (display->priv->x11_authority_file);
+        if (display->priv->access_file != NULL) {
+                *filename = gdm_display_access_file_get_path (display->priv->access_file);
+        } else {
+                *filename = NULL;
         }
 
         return TRUE;
@@ -398,6 +477,14 @@ gdm_display_real_unmanage (GdmDisplay *d
                 display->priv->slave_proxy = NULL;
         }
 
+        gdm_display_access_file_close (display->priv->user_access_file);
+        g_object_unref (display->priv->user_access_file);
+        display->priv->user_access_file = NULL;
+
+        gdm_display_access_file_close (display->priv->access_file);
+        g_object_unref (display->priv->access_file);
+        display->priv->access_file = NULL;
+
         return TRUE;
 }
 
@@ -507,14 +594,6 @@ _gdm_display_set_x11_cookie (GdmDisplay 
 }
 
 static void
-_gdm_display_set_x11_authority_file (GdmDisplay     *display,
-                                     const char     *file)
-{
-        g_free (display->priv->x11_authority_file);
-        display->priv->x11_authority_file = g_strdup (file);
-}
-
-static void
 _gdm_display_set_is_local (GdmDisplay     *display,
                            gboolean        is_local)
 {
@@ -558,9 +637,6 @@ gdm_display_set_property (GObject       
         case PROP_X11_COOKIE:
                 _gdm_display_set_x11_cookie (self, g_value_get_string (value));
                 break;
-        case PROP_X11_AUTHORITY_FILE:
-                _gdm_display_set_x11_authority_file (self, g_value_get_string (value));
-                break;
         case PROP_IS_LOCAL:
                 _gdm_display_set_is_local (self, g_value_get_boolean (value));
                 break;
@@ -603,7 +679,8 @@ gdm_display_get_property (GObject       
                 g_value_set_string (value, self->priv->x11_cookie);
                 break;
         case PROP_X11_AUTHORITY_FILE:
-                g_value_set_string (value, self->priv->x11_authority_file);
+                g_value_take_string (value,
+                                     gdm_display_access_file_get_path (self->priv->access_file));
                 break;
         case PROP_IS_LOCAL:
                 g_value_set_boolean (value, self->priv->is_local);
@@ -752,7 +829,7 @@ gdm_display_class_init (GdmDisplayClass 
                                                               "authority file",
                                                               "authority file",
                                                               NULL,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+                                                              G_PARAM_READABLE));
 
         g_object_class_install_property (object_class,
                                          PROP_IS_LOCAL,
@@ -803,8 +880,15 @@ gdm_display_finalize (GObject *object)
         g_free (display->priv->remote_hostname);
         g_free (display->priv->x11_display_name);
         g_free (display->priv->x11_cookie);
-        g_free (display->priv->x11_authority_file);
         g_free (display->priv->slave_command);
 
+        if (display->priv->access_file != NULL) {
+                g_object_unref (display->priv->access_file);
+        }
+
+        if (display->priv->user_access_file != NULL) {
+                g_object_unref (display->priv->user_access_file);
+        }
+
         G_OBJECT_CLASS (gdm_display_parent_class)->finalize (object);
 }
Index: daemon/gdm-display.h
===================================================================
--- daemon/gdm-display.h	(revision 5498)
+++ daemon/gdm-display.h	(working copy)
@@ -69,7 +69,8 @@ typedef struct
 
 typedef enum
 {
-         GDM_DISPLAY_ERROR_GENERAL
+         GDM_DISPLAY_ERROR_GENERAL,
+         GDM_DISPLAY_ERROR_GETTING_USER_INFO
 } GdmDisplayError;
 
 #define GDM_DISPLAY_ERROR gdm_display_error_quark ()
@@ -107,6 +108,7 @@ gboolean            gdm_display_is_local
 /* exported but protected */
 gboolean            gdm_display_get_x11_cookie                 (GdmDisplay *display,
                                                                 char      **x11_cookie,
+                                                                gsize      *cookie_size,
                                                                 GError    **error);
 gboolean            gdm_display_get_x11_authority_file         (GdmDisplay *display,
                                                                 char      **filename,
Index: daemon/gdm-manager.c
===================================================================
--- daemon/gdm-manager.c	(revision 5498)
+++ daemon/gdm-manager.c	(working copy)
@@ -60,7 +60,6 @@ struct GdmManagerPrivate
 
         gboolean                xdmcp_enabled;
 
-        GString                *global_cookie;
         gboolean                wait_for_go;
         gboolean                no_console;
 
@@ -137,38 +136,6 @@ gdm_manager_get_displays (GdmManager *ma
         return TRUE;
 }
 
-static void
-make_global_cookie (GdmManager *manager)
-{
-        FILE  *fp;
-        char  *file;
-
-        gdm_generate_cookie (manager->priv->global_cookie);
-
-        file = g_build_filename (AUTHDIR, ".cookie", NULL);
-        VE_IGNORE_EINTR (g_unlink (file));
-
-        fp = gdm_safe_fopen_w (file, 077);
-        if G_UNLIKELY (fp == NULL) {
-                g_warning (_("Can't open %s for writing"), file);
-                g_free (file);
-                return;
-        }
-
-        VE_IGNORE_EINTR (fprintf (fp, "%s\n", manager->priv->global_cookie->str));
-
-        /* FIXME: What about out of disk space errors? */
-        errno = 0;
-        VE_IGNORE_EINTR (fclose (fp));
-        if G_UNLIKELY (errno != 0) {
-                g_warning (_("Can't write to %s: %s"),
-                           file,
-                           g_strerror (errno));
-        }
-
-        g_free (file);
-}
-
 void
 gdm_manager_start (GdmManager *manager)
 {
@@ -420,10 +387,6 @@ gdm_manager_init (GdmManager *manager)
 
         manager->priv = GDM_MANAGER_GET_PRIVATE (manager);
 
-        manager->priv->global_cookie = g_string_new (NULL);
-
-        make_global_cookie (manager);
-
         manager->priv->display_store = gdm_display_store_new ();
 }
 
@@ -446,8 +409,6 @@ gdm_manager_finalize (GObject *object)
         gdm_display_store_clear (manager->priv->display_store);
         g_object_unref (manager->priv->display_store);
 
-        g_string_free (manager->priv->global_cookie, TRUE);
-
         G_OBJECT_CLASS (gdm_manager_parent_class)->finalize (object);
 }
 
Index: daemon/gdm-factory-slave.c
===================================================================
--- daemon/gdm-factory-slave.c	(revision 5498)
+++ daemon/gdm-factory-slave.c	(working copy)
@@ -565,11 +565,13 @@ static gboolean
 gdm_factory_slave_run (GdmFactorySlave *slave)
 {
         char    *display_name;
+        char    *auth_file;
         gboolean display_is_local;
 
         g_object_get (slave,
                       "display-is-local", &display_is_local,
                       "display-name", &display_name,
+                      "display-x11-authority-file", &auth_file,
                       NULL);
 
         /* if this is local display start a server if one doesn't
@@ -577,7 +579,7 @@ gdm_factory_slave_run (GdmFactorySlave *
         if (display_is_local) {
                 gboolean res;
 
-                slave->priv->server = gdm_server_new (display_name);
+                slave->priv->server = gdm_server_new (display_name, auth_file);
 
                 g_signal_connect (slave->priv->server,
                                   "ready",
@@ -603,6 +605,7 @@ gdm_factory_slave_run (GdmFactorySlave *
         }
 
         g_free (display_name);
+        g_free (auth_file);
 
         return TRUE;
 }
Index: daemon/gdm-static-display.c
===================================================================
--- daemon/gdm-static-display.c	(revision 5498)
+++ daemon/gdm-static-display.c	(working copy)
@@ -20,9 +20,11 @@
 
 #include "config.h"
 
+#include <errno.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
+#include <pwd.h>
 #include <unistd.h>
 #include <string.h>
 #include <signal.h>
@@ -34,6 +36,7 @@
 #include <glib/gi18n.h>
 #include <glib-object.h>
 
+#include "gdm-common.h"
 #include "gdm-display.h"
 #include "gdm-static-display.h"
 #include "gdm-static-display-glue.h"
@@ -71,7 +74,7 @@ gdm_static_display_add_user_authorizatio
                                            char      **filename,
                                            GError    **error)
 {
-        return TRUE;
+        return GDM_DISPLAY_CLASS (gdm_static_display_parent_class)->add_user_authorization (display, username, filename, error);
 }
 
 static gboolean
@@ -79,7 +82,7 @@ gdm_static_display_remove_user_authoriza
                                               const char *username,
                                               GError    **error)
 {
-        return TRUE;
+        return GDM_DISPLAY_CLASS (gdm_static_display_parent_class)->remove_user_authorization (display, username, error);
 }
 
 static gboolean
Index: daemon/gdm-simple-slave.c
===================================================================
--- daemon/gdm-simple-slave.c	(revision 5498)
+++ daemon/gdm-simple-slave.c	(working copy)
@@ -680,11 +680,13 @@ static gboolean
 gdm_simple_slave_run (GdmSimpleSlave *slave)
 {
         char    *display_name;
+        char    *auth_file;
         gboolean display_is_local;
 
         g_object_get (slave,
                       "display-is-local", &display_is_local,
                       "display-name", &display_name,
+                      "display-x11-authority-file", &auth_file,
                       NULL);
 
         /* if this is local display start a server if one doesn't
@@ -692,7 +694,7 @@ gdm_simple_slave_run (GdmSimpleSlave *sl
         if (display_is_local) {
                 gboolean res;
 
-                slave->priv->server = gdm_server_new (display_name);
+                slave->priv->server = gdm_server_new (display_name, auth_file);
 
                 g_signal_connect (slave->priv->server,
                                   "ready",
@@ -718,6 +720,7 @@ gdm_simple_slave_run (GdmSimpleSlave *sl
         }
 
         g_free (display_name);
+        g_free (auth_file);
 
         return TRUE;
 }
Index: daemon/gdm-xdmcp-display-factory.c
===================================================================
--- daemon/gdm-xdmcp-display-factory.c	(revision 5498)
+++ daemon/gdm-xdmcp-display-factory.c	(working copy)
@@ -57,8 +57,6 @@
 #include "gdm-xdmcp-display-factory.h"
 #include "gdm-display-store.h"
 
-#include "auth.h"
-
 /*
  * On Sun, we need to define allow_severity and deny_severity to link
  * against libwrap.
@@ -2043,57 +2041,29 @@ gdm_xdmcp_handle_request (GdmXdmcpDispla
                                                            clnt_dspnum);
 
                         if (display != NULL) {
-                                ARRAY8 authentication_name;
-                                ARRAY8 authentication_data;
-                                ARRAY8 authorization_name;
-                                ARRAY8 authorization_data;
-                                gint32 session_number;
-                                char    *x11_cookie;
-                                GString *cookie;
-                                GString *binary_cookie;
-                                GString *test_cookie;
-
-                                gdm_display_get_x11_cookie (display, &x11_cookie, NULL);
-                                cookie = g_string_new (x11_cookie);
-                                g_free (x11_cookie);
-
-                                binary_cookie = g_string_new (NULL);
-
-                                if (! gdm_string_hex_decode (cookie,
-                                                             0,
-                                                             NULL,
-                                                             binary_cookie,
-                                                             0)) {
-                                        g_warning ("Unable to decode hex cookie");
-                                        /* FIXME: handle error */
-                                }
+                                ARRAY8  authentication_name;
+                                ARRAY8  authentication_data;
+                                ARRAY8  authorization_name;
+                                ARRAY8  authorization_data;
+                                gint32  session_number;
+                                char   *cookie;
+                                gsize   cookie_size;
+                                char   *name;
+
+                                gdm_display_get_x11_cookie (display, &cookie,
+                                                            &cookie_size, NULL);
 
-                                test_cookie = g_string_new (NULL);
-                                if (! gdm_string_hex_encode (binary_cookie,
-                                                             0,
-                                                             test_cookie,
-                                                             0)) {
-                                        g_warning ("Unable to encode hex cookie");
-                                        /* FIXME: handle error */
-                                }
+                                gdm_display_get_x11_display_name (display, &name, NULL);
 
-                                /* sanity check cookie */
-                                g_debug ("GdmXdmcpDisplayFactory: Original cookie len:%d '%s'; Reencoded cookie len:%d '%s'",
-                                         (int) cookie->len,
-                                         cookie->str,
-                                         (int) test_cookie->len,
-                                         test_cookie->str);
-                                g_assert (test_cookie->len == cookie->len);
-                                g_assert (strcmp (test_cookie->str, cookie->str) == 0);
-                                g_string_free (test_cookie, TRUE);
+                                g_debug ("GdmXdmcpDisplayFactory: Sending authorization key for display %s", name);
+                                g_free (name);
 
-                                g_debug ("GdmXdmcpDisplayFactory: Sending authorization key for display %s", cookie->str);
-                                g_debug ("GdmXdmcpDisplayFactory: Decoded cookie len %d", (int) binary_cookie->len);
+                                g_debug ("GdmXdmcpDisplayFactory: cookie len %d", (int) cookie_size);
 
                                 session_number = gdm_xdmcp_display_get_session_number (GDM_XDMCP_DISPLAY (display));
 
                                 /* the send accept will fail if cookie is null */
-                                g_assert (binary_cookie != NULL);
+                                g_assert (cookie != NULL);
 
                                 authentication_name.data   = NULL;
                                 authentication_name.length = 0;
@@ -2103,8 +2073,8 @@ gdm_xdmcp_handle_request (GdmXdmcpDispla
                                 authorization_name.data     = (CARD8 *) "MIT-MAGIC-COOKIE-1";
                                 authorization_name.length   = strlen ((char *) authorization_name.data);
 
-                                authorization_data.data     = (CARD8 *) binary_cookie->str;
-                                authorization_data.length   = binary_cookie->len;
+                                authorization_data.data     = (CARD8 *) cookie;
+                                authorization_data.length   = cookie_size;
 
                                 /* the addrs are NOT copied */
                                 gdm_xdmcp_send_accept (factory,
@@ -2114,9 +2084,6 @@ gdm_xdmcp_handle_request (GdmXdmcpDispla
                                                        &authentication_data,
                                                        &authorization_name,
                                                        &authorization_data);
-
-                                g_string_free (binary_cookie, TRUE);
-                                g_string_free (cookie, TRUE);
                         }
                 }
         } else {
Index: daemon/Makefile.am
===================================================================
--- daemon/Makefile.am	(revision 5498)
+++ daemon/Makefile.am	(working copy)
@@ -125,8 +125,6 @@ gdm_simple_slave_SOURCES = 		\
 	gdm-slave.h			\
 	gdm-simple-slave.c		\
 	gdm-simple-slave.h		\
-	auth.c				\
-	auth.h				\
 	$(NULL)
 
 gdm_simple_slave_LDFLAGS =		\
@@ -190,8 +188,6 @@ gdm_product_slave_SOURCES = 		\
 	gdm-slave.h			\
 	gdm-product-slave.c		\
 	gdm-product-slave.h		\
-	auth.c				\
-	auth.h				\
 	$(NULL)
 
 gdm_product_slave_LDFLAGS =		\
@@ -226,6 +222,8 @@ sbin_PROGRAMS = 			\
 
 gdm_binary_SOURCES = 			\
 	main.c				\
+	gdm-display-access-file.c	\
+	gdm-display-access-file.h	\
 	gdm-display-store.c		\
 	gdm-display-store.h		\
 	gdm-display-factory.c		\
@@ -246,8 +244,6 @@ gdm_binary_SOURCES = 			\
 	gdm-manager.h			\
 	gdm-slave-proxy.c		\
 	gdm-slave-proxy.h		\
-	auth.c				\
-	auth.h				\
 	$(NULL)
 
 XDMCP_SOURCES =				\