5a1cfb
--- gdm-2.17.6/docs/C/gdm.xml.username	2007-01-22 00:31:17.000000000 -0500
5a1cfb
+++ gdm-2.17.6/docs/C/gdm.xml	2007-02-06 22:52:08.000000000 -0500
5a1cfb
@@ -2,8 +2,8 @@
5a1cfb
 
5a1cfb
     "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
5a1cfb
     
5a1cfb
-     
5a1cfb
-     
5a1cfb
+     
5a1cfb
+     
5a1cfb
 ]>
5a1cfb
 
5a1cfb
 <article id="index" lang="en">
5a1cfb
@@ -13,7 +13,7 @@
5a1cfb
     <revhistory>
5a1cfb
       <revision>
5a1cfb
         <revnumber>0.0</revnumber>
5a1cfb
-        <date>2006-12</date>
5a1cfb
+        <date>2007-01</date>
5a1cfb
       </revision>
5a1cfb
     </revhistory>
5a1cfb
 
5a1cfb
@@ -4515,7 +4515,9 @@
5a1cfb
 AUTH_LOCAL
5a1cfb
 CLOSE
5a1cfb
 FLEXI_XNEST
5a1cfb
+FLEXI_XNEST_USER
5a1cfb
 FLEXI_XSERVER
5a1cfb
+FLEXI_XSERVER_USER
5a1cfb
 GET_CONFIG
5a1cfb
 GET_CONFIG_FILE
5a1cfb
 GET_CUSTOM_CONFIG_FILE
5a1cfb
@@ -4699,6 +4701,36 @@
5a1cfb
 </screen>
5a1cfb
       </sect3>
5a1cfb
       
5a1cfb
+      <sect3 id="flexixnestuser">
5a1cfb
+      <title>FLEXI_XNEST_USER</title>
5a1cfb
+<screen>
5a1cfb
+FLEXI_XNEST_USER: Start a new flexible Xnest display and
5a1cfb
+                  initialize the greeter with the given username.
5a1cfb
+Note:             This is a variant of the FLEXI_XNEST command.
5a1cfb
+Note:             The cookie should be the MIT-MAGIC-COOKIE-1,
5a1cfb
+                  the first one GDM can find in the XAUTHORITY
5a1cfb
+                  file for this display.  If that's not what you
5a1cfb
+                  use you should generate one first.  The cookie
5a1cfb
+                  should be in hex form.
5a1cfb
+Supported since:  2.17.7
5a1cfb
+Arguments: <username> <display to run on> <uid of requesting user>
5a1cfb
+           <xauth cookie for the display> <xauth file>
5a1cfb
+Answers:
5a1cfb
+  OK <display>
5a1cfb
+  ERROR <err number> <english error description>
5a1cfb
+     0 = Not implemented
5a1cfb
+     1 = No more flexi servers
5a1cfb
+     2 = Startup errors
5a1cfb
+     3 = X failed
5a1cfb
+     4 = X too busy
5a1cfb
+     5 = Xnest can't connect
5a1cfb
+     6 = No server binary
5a1cfb
+     100 = Not authenticated
5a1cfb
+     200 = Too many messages
5a1cfb
+     999 = Unknown error
5a1cfb
+</screen>
5a1cfb
+      </sect3>
5a1cfb
+
5a1cfb
       <sect3 id="flexixserver">
5a1cfb
       <title>FLEXI_XSERVER</title>
5a1cfb
 <screen>
5a1cfb
@@ -4722,6 +4754,30 @@
5a1cfb
 </screen>
5a1cfb
       </sect3>
5a1cfb
       
5a1cfb
+      <sect3 id="flexixserveruser">
5a1cfb
+      <title>FLEXI_XSERVER_USER</title>
5a1cfb
+<screen>
5a1cfb
+FLEXI_XSERVER_USER: Start a new X flexible display and initialize the
5a1cfb
+                    greeter with the given username.  Only supported on
5a1cfb
+                    connection that passed AUTH_LOCAL
5a1cfb
+Supported since:    2.17.7 
5a1cfb
+Arguments: <username> <xserver type>
5a1cfb
+  If no server type specified, starts the standard X server
5a1cfb
+Answers:
5a1cfb
+  OK <display>
5a1cfb
+  ERROR <err number> <english error description>
5a1cfb
+     0 = Not implemented
5a1cfb
+     1 = No more flexi servers
5a1cfb
+     2 = Startup errors
5a1cfb
+     3 = X failed
5a1cfb
+     4 = X too busy
5a1cfb
+     6 = No server binary
5a1cfb
+     100 = Not authenticated
5a1cfb
+     200 = Too many messages
5a1cfb
+     999 = Unknown error
5a1cfb
+</screen>
5a1cfb
+      </sect3>
5a1cfb
+
5a1cfb
       <sect3 id="getconfig">
5a1cfb
       <title>GET_CONFIG</title> 
5a1cfb
 <screen>
5a1cfb
--- gdm-2.17.6/daemon/slave.c.username	2007-02-06 22:52:08.000000000 -0500
5a1cfb
+++ gdm-2.17.6/daemon/slave.c	2007-02-06 22:52:08.000000000 -0500
5a1cfb
@@ -1946,6 +1946,7 @@
5a1cfb
 gdm_slave_wait_for_login (void)
5a1cfb
 {
5a1cfb
 	char *successsound;
5a1cfb
+	char *username;
5a1cfb
 	g_free (login);
5a1cfb
 	login = NULL;
5a1cfb
 
5a1cfb
@@ -1970,10 +1971,14 @@
5a1cfb
 		NEVER_FAILS_root_set_euid_egid (0, 0);
5a1cfb
 
5a1cfb
 		gdm_debug ("gdm_slave_wait_for_login: In loop");
5a1cfb
+		username = d->preset_user;
5a1cfb
+		d->preset_user = NULL;
5a1cfb
 		login = gdm_verify_user (d /* the display */,
5a1cfb
-					 NULL /* username*/,
5a1cfb
+					 username /* username*/,
5a1cfb
 					 d->name /* display name */,
5a1cfb
 					 d->attached /* display attached? (bool) */);
5a1cfb
+		g_free (username);
5a1cfb
+
5a1cfb
 		gdm_debug ("gdm_slave_wait_for_login: end verify for '%s'",
5a1cfb
 			   ve_sure_string (login));
5a1cfb
 
5a1cfb
--- gdm-2.17.6/daemon/server.c.username	2007-01-22 00:20:40.000000000 -0500
5a1cfb
+++ gdm-2.17.6/daemon/server.c	2007-02-06 22:52:08.000000000 -0500
5a1cfb
@@ -1439,6 +1439,7 @@
5a1cfb
     d->retry_count = 0;
5a1cfb
     d->sleep_before_run = 0;
5a1cfb
     d->login = NULL;
5a1cfb
+    d->preset_user = NULL;
5a1cfb
 
5a1cfb
     d->timed_login_ok = FALSE;
5a1cfb
 
5a1cfb
--- gdm-2.17.6/daemon/gdm.h.username	2007-02-06 22:52:08.000000000 -0500
5a1cfb
+++ gdm-2.17.6/daemon/gdm.h	2007-02-06 22:52:08.000000000 -0500
5a1cfb
@@ -557,6 +557,8 @@
5a1cfb
     gboolean logged_in; /* TRUE if someone is logged in */
5a1cfb
     char *login;
5a1cfb
 
5a1cfb
+    char *preset_user;
5a1cfb
+
5a1cfb
     gboolean timed_login_ok;
5a1cfb
 
5a1cfb
     int screenx;
5a1cfb
@@ -874,6 +876,26 @@
5a1cfb
  *      200 = Too many messages
5a1cfb
  *      999 = Unknown error
5a1cfb
  */
5a1cfb
+#define GDM_SUP_FLEXI_XSERVER_USER  "FLEXI_XSERVER_USER" /* <username> <xserver type=""> */
5a1cfb
+/* FLEXI_XSERVER_USER: Start a new X flexible display and initialize the 
5a1cfb
+ *                greeter with the given username. Only supported on 
5a1cfb
+ *                connection that passed AUTH_LOCAL
5a1cfb
+ * Supported since: 2.17.7
5a1cfb
+ * Arguments: <username> <xserver type="">
5a1cfb
+ *   If no server type specified, starts the standard X server
5a1cfb
+ * Answers:
5a1cfb
+ *   OK <display>
5a1cfb
+ *   ERROR <err number=""> <english error="" description="">
5a1cfb
+ *      0 = Not implemented
5a1cfb
+ *      1 = No more flexi servers
5a1cfb
+ *      2 = Startup errors
5a1cfb
+ *      3 = X failed
5a1cfb
+ *      4 = X too busy
5a1cfb
+ *      6 = No server binary
5a1cfb
+ *      100 = Not authenticated
5a1cfb
+ *      200 = Too many messages
5a1cfb
+ *      999 = Unknown error
5a1cfb
+ */
5a1cfb
 #define GDM_SUP_FLEXI_XNEST  "FLEXI_XNEST" /* <display> <uid> <xauth cookie=""> <xauth file=""> */
5a1cfb
 /* FLEXI_XNEXT: Start a new flexible Xnest display.
5a1cfb
  * Note:        Supported on older versions from 2.2.4.0, later
5a1cfb
@@ -909,6 +931,31 @@
5a1cfb
  *      200 = Too many messages
5a1cfb
  *      999 = Unknown error
5a1cfb
  */
5a1cfb
+#define GDM_SUP_FLEXI_XNEST_USER  "FLEXI_XNEST_USER" /* <username> <display> <uid> <xauth cookie=""> <xauth file=""> */
5a1cfb
+/* FLEXI_XNEXT_USER: Start a new flexible Xnest display and 
5a1cfb
+ *              initialize the greeter with the given username
5a1cfb
+ * Note:        The cookie should be the MIT-MAGIC-COOKIE-1,
5a1cfb
+ *              the first one gdm can find in the XAUTHORITY
5a1cfb
+ *              file for this display.  If that's not what you
5a1cfb
+ *              use you should generate one first.  The cookie
5a1cfb
+ *              should be in hex form.
5a1cfb
+ * Supported since: 2.17.7
5a1cfb
+ * Arguments: <username> <display to="" run="" on=""> <uid of="" requesting="" user="">
5a1cfb
+ *            <xauth cookie="" for="" the="" display=""> <xauth file="">
5a1cfb
+ * Answers:
5a1cfb
+ *   OK <display>
5a1cfb
+ *   ERROR <err number=""> <english error="" description="">
5a1cfb
+ *      0 = Not implemented
5a1cfb
+ *      1 = No more flexi servers
5a1cfb
+ *      2 = Startup errors
5a1cfb
+ *      3 = X failed
5a1cfb
+ *      4 = X too busy
5a1cfb
+ *      5 = Xnest can't connect
5a1cfb
+ *      6 = No server binary
5a1cfb
+ *      100 = Not authenticated
5a1cfb
+ *      200 = Too many messages
5a1cfb
+ *      999 = Unknown error
5a1cfb
+ */
5a1cfb
 #define GDM_SUP_ADD_DYNAMIC_DISPLAY	"ADD_DYNAMIC_DISPLAY" 
5a1cfb
 /*
5a1cfb
  * ADD_DYNAMIC_DISPLAY: Create a new server definition that will
5a1cfb
--- gdm-2.17.6/daemon/display.c.username	2007-01-22 00:20:40.000000000 -0500
5a1cfb
+++ gdm-2.17.6/daemon/display.c	2007-02-06 22:52:08.000000000 -0500
5a1cfb
@@ -1,4 +1,6 @@
5a1cfb
-/* GDM - The GNOME Display Manager
5a1cfb
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
5a1cfb
+ *
5a1cfb
+ * GDM - The GNOME Display Manager
5a1cfb
  * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
5a1cfb
  *
5a1cfb
  * This program is free software; you can redistribute it and/or modify
5a1cfb
@@ -531,6 +533,9 @@
5a1cfb
     g_free (d->login);
5a1cfb
     d->login = NULL;
5a1cfb
 
5a1cfb
+    g_free (d->preset_user);
5a1cfb
+    d->preset_user = NULL;
5a1cfb
+
5a1cfb
     g_free (d->xsession_errors_filename);
5a1cfb
     d->xsession_errors_filename = NULL;
5a1cfb
 
5a1cfb
--- gdm-2.17.6/daemon/gdm.c.username	2007-02-06 22:52:08.000000000 -0500
5a1cfb
+++ gdm-2.17.6/daemon/gdm.c	2007-02-06 22:53:54.000000000 -0500
5a1cfb
@@ -1,4 +1,6 @@
5a1cfb
-/* GDM - The GNOME Display Manager
5a1cfb
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
5a1cfb
+ *
5a1cfb
+ * GDM - The GNOME Display Manager
5a1cfb
  * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
5a1cfb
  *
5a1cfb
  * This program is free software; you can redistribute it and/or modify
5a1cfb
@@ -103,7 +105,8 @@
5a1cfb
 				 const gchar *xnest_disp, 
5a1cfb
 				 uid_t xnest_uid,
5a1cfb
 				 const gchar *xnest_auth_file,
5a1cfb
-				 const gchar *xnest_cookie);
5a1cfb
+				 const gchar *xnest_cookie,
5a1cfb
+				 const gchar *username);
5a1cfb
 static void custom_cmd_restart (long cmd_id);
5a1cfb
 static void custom_cmd_no_restart (long cmd_id);
5a1cfb
 
5a1cfb
@@ -2563,7 +2566,7 @@
5a1cfb
 		handle_flexi_server (NULL, TYPE_FLEXI, gdm_get_value_string (GDM_KEY_STANDARD_XSERVER),
5a1cfb
 				     TRUE /* handled */,
5a1cfb
 				     FALSE /* chooser */,
5a1cfb
-				     NULL, 0, NULL, NULL);
5a1cfb
+				     NULL, 0, NULL, NULL, NULL);
5a1cfb
        } else if (strcmp (msg, GDM_SOP_CANCEL_LOGIN_REQUESTS) == 0) {
5a1cfb
                GSList *li;
5a1cfb
                for (li = displays; li != NULL; li = li->next) {
5a1cfb
@@ -2970,7 +2973,8 @@
5a1cfb
 		     gboolean chooser,
5a1cfb
 		     const gchar *xnest_disp, uid_t xnest_uid,
5a1cfb
 		     const gchar *xnest_auth_file,
5a1cfb
-		     const gchar *xnest_cookie)
5a1cfb
+		     const gchar *xnest_cookie,
5a1cfb
+		     const gchar *username)
5a1cfb
 {
5a1cfb
 	GdmDisplay *display;
5a1cfb
 	gchar *bin;
5a1cfb
@@ -3102,6 +3106,7 @@
5a1cfb
 
5a1cfb
 	flexi_servers++;
5a1cfb
 
5a1cfb
+	display->preset_user = g_strdup (username);
5a1cfb
 	display->type = type;
5a1cfb
 	display->socket_conn = conn;
5a1cfb
 	display->parent_disp = g_strdup (xnest_disp);
5a1cfb
@@ -3243,6 +3248,7 @@
5a1cfb
 gdm_handle_user_message (GdmConnection *conn, const gchar *msg, gpointer data)
5a1cfb
 {
5a1cfb
 	gint i;
5a1cfb
+	gboolean has_user;
5a1cfb
 
5a1cfb
 	gdm_debug ("Handling user message: '%s'", msg);
5a1cfb
 
5a1cfb
@@ -3311,12 +3317,16 @@
5a1cfb
 		handle_flexi_server (conn, TYPE_FLEXI, gdm_get_value_string (GDM_KEY_STANDARD_XSERVER),
5a1cfb
 				     TRUE /* handled */,
5a1cfb
 				     FALSE /* chooser */,
5a1cfb
-				     NULL, 0, NULL, NULL);
5a1cfb
-	} else if (strncmp (msg, GDM_SUP_FLEXI_XSERVER " ",
5a1cfb
-		            strlen (GDM_SUP_FLEXI_XSERVER " ")) == 0) {
5a1cfb
+				     NULL, 0, NULL, NULL, NULL);
5a1cfb
+	} else if (((has_user = strncmp (msg, GDM_SUP_FLEXI_XSERVER_USER " ", 
5a1cfb
+                                         strlen (GDM_SUP_FLEXI_XSERVER_USER " "))) == 0) ||
5a1cfb
+                   (strncmp (msg, GDM_SUP_FLEXI_XSERVER " ",
5a1cfb
+		            strlen (GDM_SUP_FLEXI_XSERVER " ")) == 0)) {
5a1cfb
 		gchar *name;
5a1cfb
 		const gchar *command = NULL;
5a1cfb
 		GdmXserver *svr;
5a1cfb
+		const gchar *rest;
5a1cfb
+		gchar *username, *end;
5a1cfb
 
5a1cfb
 		/* Only allow locally authenticated connections */
5a1cfb
 		if ( ! GDM_CONN_AUTHENTICATED(conn)) {
5a1cfb
@@ -3327,7 +3337,21 @@
5a1cfb
 			return;
5a1cfb
 		}
5a1cfb
 
5a1cfb
-		name = g_strdup (&msg[strlen (GDM_SUP_FLEXI_XSERVER " ")]);
5a1cfb
+		if (has_user == 0) {
5a1cfb
+			rest = msg + strlen (GDM_SUP_FLEXI_XSERVER_USER " ");
5a1cfb
+			end = strchr (rest, ' ');
5a1cfb
+			if (end) {
5a1cfb
+				username = g_strndup (rest, end - rest);
5a1cfb
+				rest = end + 1;
5a1cfb
+			} else {
5a1cfb
+				username = g_strdup (rest);
5a1cfb
+				rest = rest + strlen (rest);
5a1cfb
+			}
5a1cfb
+		} else {
5a1cfb
+			rest = msg + strlen (GDM_SUP_FLEXI_XSERVER " ");
5a1cfb
+			username = NULL;
5a1cfb
+		}
5a1cfb
+		name = g_strdup (rest);
5a1cfb
 		g_strstrip (name);
5a1cfb
 		if (ve_string_empty (name)) {
5a1cfb
 			g_free (name);
5a1cfb
@@ -3357,13 +3381,27 @@
5a1cfb
 					oh well, this makes other things simpler */
5a1cfb
 				     svr->handled,
5a1cfb
 				     svr->chooser,
5a1cfb
-				     NULL, 0, NULL, NULL);
5a1cfb
-	} else if (strncmp (msg, GDM_SUP_FLEXI_XNEST " ",
5a1cfb
-		            strlen (GDM_SUP_FLEXI_XNEST " ")) == 0) {
5a1cfb
+				     NULL, 0, NULL, NULL, username);
5a1cfb
+		g_free (username);
5a1cfb
+	} else if (((has_user = strncmp (msg, GDM_SUP_FLEXI_XNEST_USER " ",
5a1cfb
+                                         strlen (GDM_SUP_FLEXI_XNEST_USER " "))) == 0) || 
5a1cfb
+                   (strncmp (msg, GDM_SUP_FLEXI_XNEST " ",
5a1cfb
+		            strlen (GDM_SUP_FLEXI_XNEST " ")) == 0)) {
5a1cfb
 		gchar *dispname = NULL, *xauthfile = NULL, *cookie = NULL;
5a1cfb
 		uid_t uid;
5a1cfb
+		const gchar *rest;
5a1cfb
+		gchar *username, *end;
5a1cfb
+
5a1cfb
+                if (has_user == 0) {
5a1cfb
+			rest = msg + strlen (GDM_SUP_FLEXI_XNEST_USER " ");
5a1cfb
+			end = strchr (rest, ' ');
5a1cfb
+			username = g_strndup (rest, end - rest);
5a1cfb
+		} else {
5a1cfb
+			rest = msg;
5a1cfb
+			username = NULL;
5a1cfb
+		}
5a1cfb
 
5a1cfb
-		extract_dispname_uid_xauthfile_cookie (msg, &dispname, &uid,
5a1cfb
+		extract_dispname_uid_xauthfile_cookie (rest, &dispname, &uid,
5a1cfb
 						       &xauthfile, &cookie);
5a1cfb
 
5a1cfb
 		if (dispname == NULL) {
5a1cfb
@@ -3387,10 +3425,11 @@
5a1cfb
 		handle_flexi_server (conn, TYPE_FLEXI_XNEST, gdm_get_value_string (GDM_KEY_XNEST),
5a1cfb
 				     TRUE /* handled */,
5a1cfb
 				     FALSE /* chooser */,
5a1cfb
-				     dispname, uid, xauthfile, cookie);
5a1cfb
+				     dispname, uid, xauthfile, cookie, username);
5a1cfb
 
5a1cfb
 		g_free (dispname);
5a1cfb
 		g_free (xauthfile);
5a1cfb
+		g_free (username);
5a1cfb
 	} else if ((strncmp (msg, GDM_SUP_ATTACHED_SERVERS,
5a1cfb
 	                     strlen (GDM_SUP_ATTACHED_SERVERS)) == 0) ||
5a1cfb
 	           (strncmp (msg, GDM_SUP_CONSOLE_SERVERS,