--- gdm-old/daemon/gdm-display-access-file.c	2011-04-06 11:01:23.000000000 +0800
+++ gdm-new/daemon/gdm-display-access-file.c	2011-04-06 15:19:40.000000000 +0800
@@ -44,6 +44,8 @@
 
 #include "gdm-display-access-file.h"
 #include "gdm-common.h"
+#include "gdm-address.h"
+#include "gdm-xdmcp-display.h"
 
 struct _GdmDisplayAccessFilePrivate
 {
@@ -397,74 +399,133 @@ gdm_display_access_file_open (GdmDisplay
         return TRUE;
 }
 
+static Xauth*
+auth_new (unsigned short family,
+          const char *address,
+          int address_len,
+          int display_number,
+          const char *cookie,
+          unsigned short cookie_size)
+{
+        Xauth *auth;
+
+        auth = g_new0 (Xauth, 1);
+        auth->family = family;
+        auth->address = g_malloc(address_len + 1);
+        memcpy (auth->address, address, address_len + 1);
+        auth->address_length = address_len;
+        auth->number = g_strdup_printf("%d", display_number);
+        auth->number_length = strlen (auth->number);
+        auth->name = g_strdup ("MIT-MAGIC-COOKIE-1");
+        auth->name_length = strlen (auth->name);
+
+        if (cookie) {
+                auth->data = g_strdup (cookie);
+                auth->data_length = cookie_size;
+        }
+
+        return auth;
+}
+
 static void
+auth_free (Xauth *auth)
+{
+        g_free (auth->address);
+        g_free (auth->number);
+        g_free (auth->name);
+        if (auth->data)
+                g_free (auth->data);
+        g_free (auth);
+}
+
+static GList *
 _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)
+                            const char           *cookie,
+                            unsigned short       cookie_size)
 {
         int display_number;
         gboolean is_local;
+        GList *list = NULL;
+        Xauth *auth;
+        char *hostname = NULL;
 
         gdm_display_is_local (display, &is_local, NULL);
+        gdm_display_get_x11_display_number (display, &display_number, NULL);
 
         if (is_local) {
-                *family = FamilyLocal;
-                *address = g_strdup ("localhost");
-        	*address_length = strlen (*address);
+                auth = auth_new (FamilyLocal, "localhost", strlen ("localhost"),
+                                display_number, cookie, cookie_size);
+                list = g_list_append (list, auth);
         } else {
 
-		char *hostname;
-		struct hostent *hp;
-		char *addr = NULL;
-		int addr_len;
+                GdmAddress *gdm_remote_address;
 
                 gdm_display_get_remote_hostname (display, &hostname, NULL);
-		hp = gethostbyname (hostname);
+                gdm_remote_address = gdm_xdmcp_display_get_remote_address (GDM_XDMCP_DISPLAY (display));
+                is_local = gdm_address_is_local (gdm_remote_address);
+                if (!is_local) {
+                        /*FIXME: should be checked in gdm_address_is_local */
+                        if ((hostname == NULL) || (*hostname == '\0') || (strncmp (hostname, "127", 3) == 0)) {
+                                is_local = TRUE;
+                        }
+                }
+
+                struct hostent *hp = NULL;
+                hp = gethostbyname (hostname);
+                /* remote display */
 		if (hp) {
 			if (hp->h_addrtype == AF_INET) {
 				struct sockaddr_in in;
 				struct sockaddr_in *inetaddr;
+                                char *addr;
+                                int addr_len;
 				inetaddr = (struct sockaddr_in *) (&(in));
 				memmove( (char *) &(inetaddr->sin_addr), (char *) hp->h_addr, (int) hp->h_length);
                  		addr = (char *) (&inetaddr->sin_addr);
 				addr_len = sizeof (inetaddr->sin_addr);
-                		*family = FamilyInternet;
+                                auth = auth_new (FamilyInternet, addr, addr_len,
+                                                 display_number, cookie, cookie_size);
+                                list = g_list_append (list, auth);
 			} else if (hp->h_addrtype == AF_INET6) {
 #ifdef ENABLE_IPV6
 				struct  sockaddr_in6  in;
 				struct  sockaddr_in6  *inetaddr;
+                                char *addr;
+                                int addr_len;
 				inetaddr = (struct sockaddr_in6 *) (&(in));
 				memmove( (char *) &(inetaddr->sin6_addr), (char *) hp->h_addr, (int) hp->h_length);
 				addr = (char *) (&inetaddr->sin6_addr);
 				addr_len = sizeof (inetaddr->sin6_addr);
-                		*family = FamilyInternet6;
+                                auth = auth_new (FamilyInternet6, addr, addr_len,
+                                                 display_number, cookie, cookie_size);
+                                list = g_list_append (list, auth);
 #endif
-			}
-		}
-		if (addr) {
-			g_free (hostname);
-			*address = malloc (addr_len);
-			memcpy (*address, addr, addr_len);
-			*address_length = addr_len;
+			} else {
+                                auth = auth_new (FamilyWild, hostname, strlen (hostname),
+                                                 display_number, cookie, cookie_size);
+                                list = g_list_append (list, auth);
+                        }
 		} else {
-                	*family = FamilyWild;
-			*address = hostname;
-	        	*address_length = strlen (*address);
-		}
-	}
+                        auth = auth_new (FamilyWild, hostname, strlen (hostname),
+                                         display_number, cookie, cookie_size);
+                        list = g_list_append (list, auth);
+                }
+                if (hostname)
+                       g_free (hostname);
+        } 
 
-        gdm_display_get_x11_display_number (display, &display_number, NULL);
-        *number = g_strdup_printf ("%d", display_number);
-        *number_length = strlen (*number);
+        if (is_local) {
+                /* Including the displays running by vncserver, rdpserver and the etc... */
+                char auth_host[256];  
+                memset (auth_host, 0, sizeof (auth_host));
+                gethostname (auth_host, sizeof (auth_host));
+                auth = auth_new (FamilyLocal, auth_host, strlen (auth_host),
+                                display_number, cookie, cookie_size);
+                list = g_list_append (list, auth);
+        }
 
-        *name = g_strdup ("MIT-MAGIC-COOKIE-1");
-        *name_length = strlen (*name);
+        return list;
 }
 
 gboolean
@@ -513,43 +574,34 @@ gdm_display_access_file_add_display_with
                                                  gsize                  cookie_size,
                                                  GError               **error)
 {
-        Xauth auth_entry;
+        GList *l, *auths;
+        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;
-        }
+        auths = _get_auth_info_for_display (file, display,
+                                            cookie, cookie_size);
 
+        display_added = TRUE;
+        for (l = auths; l; l = l->next) {
+                auth_entry = (Xauth*)(l->data);
+                /* 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;
+                }
+        }
 
-        g_free (auth_entry.address);
-        g_free (auth_entry.number);
-        g_free (auth_entry.name);
+        g_list_free (auths);
 
         return display_added;
 }
@@ -559,58 +611,52 @@ gdm_display_access_file_remove_display (
                                         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;
+        GList		*auths, *l;
+        gboolean        ret = TRUE;
+        Xauth           *auth_entry, *auth;
 
 
         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;
-        }
+        auths = _get_auth_info_for_display (file, display, NULL, 0);
 
-        XauDisposeAuth (auth_entry);
+       for (l = auths; l; l = l->next) {
+                auth = (Xauth*) (l->data);
+                auth_entry = XauGetAuthByAddr (auth->family,
+                                       auth->address_length,
+                                       auth->address,
+                                       auth->number_length,
+                                       auth->number,
+                                       auth->name_length,
+                                       auth->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");
+                        ret = FALSE;
+                        goto error;
+                } else {
+                        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;
+                if (fflush (file->priv->fp) == EOF) {
+                        g_set_error (error,
+                                     G_FILE_ERROR,
+                                     g_file_error_from_errno (errno),
+                                     "%s", g_strerror (errno));
+                        ret = FALSE;
+                        goto error;
+                }
         }
+error:
+        for (l = auths; l; l = l->next) 
+                auth_free ((Xauth*)l->data);
+        g_list_free (auths);
 
-        return TRUE;
+        return ret;
 }
 
 void
