diff -upr gdm-2.19.5-pre/configure.ac gdm-2.19.5-post/configure.ac --- gdm-2.19.5-pre/configure.ac 2007-07-30 13:51:49.000000000 -0500 +++ gdm-2.19.5-post/configure.ac 2007-08-16 15:31:56.000000000 -0500 @@ -902,6 +902,10 @@ AC_SUBST(GDMPREFETCH) AC_SUBST(GDMPREFETCHLIST) AC_SUBST(GDMPREFETCHCMD) +GDM_SCRATCH_DIR="${localstatedir}/gdm" +AC_DEFINE_UNQUOTED(GDM_SCRATCH_DIR, "$GDM_SCRATCH_DIR", [GDM scratch dir]) +AC_SUBST(GDM_SCRATCH_DIR) + AC_ARG_ENABLE(secureremote, [ --enable-secureremote=[yes/no] Enable to offer a secure X connection through ssh [default=no]],, enable_secureremote=no) diff -upr gdm-2.19.5-pre/daemon/gdm-daemon-config-entries.h gdm-2.19.5-post/daemon/gdm-daemon-config-entries.h --- gdm-2.19.5-pre/daemon/gdm-daemon-config-entries.h 2007-07-30 13:51:14.000000000 -0500 +++ gdm-2.19.5-post/daemon/gdm-daemon-config-entries.h 2007-08-16 15:42:57.000000000 -0500 @@ -185,6 +185,7 @@ typedef enum { GDM_ID_GRAPHICAL_THEME_RAND, GDM_ID_GRAPHICAL_THEME_DIR, GDM_ID_GRAPHICAL_THEMED_COLOR, + GDM_ID_SHOW_DOMAIN, GDM_ID_INFO_MSG_FILE, GDM_ID_INFO_MSG_FONT, GDM_ID_PRE_FETCH_PROGRAM, @@ -465,6 +466,7 @@ static const GdmConfigEntry gdm_daemon_c { GDM_CONFIG_GROUP_GREETER, "SoundOnLoginFile", GDM_CONFIG_VALUE_STRING, "", GDM_ID_SOUND_ON_LOGIN_FILE }, { GDM_CONFIG_GROUP_GREETER, "SoundOnLoginSuccessFile", GDM_CONFIG_VALUE_STRING, "", GDM_ID_SOUND_ON_LOGIN_SUCCESS_FILE }, { GDM_CONFIG_GROUP_GREETER, "SoundOnLoginFailureFile", GDM_CONFIG_VALUE_STRING, "", GDM_ID_SOUND_ON_LOGIN_FAILURE_FILE }, + { GDM_CONFIG_GROUP_GREETER, "ShowDomain", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_SHOW_DOMAIN }, { GDM_CONFIG_GROUP_DAEMON, "SoundProgram", GDM_CONFIG_VALUE_STRING, SOUND_PROGRAM, GDM_ID_SOUND_PROGRAM }, { GDM_CONFIG_GROUP_CHOOSER, "ScanTime", GDM_CONFIG_VALUE_INT, "4", GDM_ID_SCAN_TIME }, diff -upr gdm-2.19.5-pre/daemon/gdm-daemon-config-keys.h gdm-2.19.5-post/daemon/gdm-daemon-config-keys.h --- gdm-2.19.5-pre/daemon/gdm-daemon-config-keys.h 2007-07-30 13:51:14.000000000 -0500 +++ gdm-2.19.5-post/daemon/gdm-daemon-config-keys.h 2007-08-16 15:31:56.000000000 -0500 @@ -175,6 +175,7 @@ G_BEGIN_DECLS #define GDM_KEY_GRAPHICAL_THEME_RAND "greeter/GraphicalThemeRand=false" #define GDM_KEY_GRAPHICAL_THEME_DIR "greeter/GraphicalThemeDir=" DATADIR "/gdm/themes/" #define GDM_KEY_GRAPHICAL_THEMED_COLOR "greeter/GraphicalThemedColor=#76848F" +#define GDM_KEY_SHOW_DOMAIN "greeter/ShowDomain=false" #define GDM_KEY_INFO_MSG_FILE "greeter/InfoMsgFile=" #define GDM_KEY_INFO_MSG_FONT "greeter/InfoMsgFont=" #define GDM_KEY_PRE_FETCH_PROGRAM "greeter/PreFetchProgram=" @@ -217,6 +218,7 @@ G_BEGIN_DECLS #define GDM_NOTIFY_TIMED_LOGIN_DELAY "TimedLoginDelay" /* */ #define GDM_NOTIFY_TIMED_LOGIN_ENABLE "TimedLoginEnable" /* */ #define GDM_NOTIFY_DISALLOW_TCP "DisallowTCP" /* */ +#define GDM_NOTIFY_SHOW_DOMAIN "ShowDomain" /* */ #define GDM_NOTIFY_SOUND_ON_LOGIN_FILE "SoundOnLoginFile" /* */ #define GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE "SoundOnLoginSuccessFile" /* */ #define GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE "SoundOnLoginFailureFile" /* */ diff -upr gdm-2.19.5-pre/daemon/verify-pam.c gdm-2.19.5-post/daemon/verify-pam.c --- gdm-2.19.5-pre/daemon/verify-pam.c 2007-07-30 13:51:14.000000000 -0500 +++ gdm-2.19.5-post/daemon/verify-pam.c 2007-08-16 15:31:56.000000000 -0500 @@ -78,6 +78,8 @@ static unsigned auth_retries; /* this is another hack */ static gboolean did_we_ask_for_password = FALSE; +static gboolean is_account_disabled = FALSE; +static gboolean is_account_expired = FALSE; static char *selected_user = NULL; @@ -469,6 +471,7 @@ perhaps_translate_message (const char *m g_hash_table_insert (hash, "You are required to change your password immediately (password aged)", _("You are required to change your password immediately (password aged)")); g_hash_table_insert (hash, "You are required to change your password immediately (root enforced)", _("You are required to change your password immediately (root enforced)")); g_hash_table_insert (hash, "Your account has expired; please contact your system administrator", _("Your account has expired; please contact your system administrator")); + g_hash_table_insert (hash, "Your account is disabled. Please contact your system administrator", _("Your account is disabled. Please contact your system administrator")); g_hash_table_insert (hash, "No password supplied", _("No password supplied")); g_hash_table_insert (hash, "Password unchanged", _("Password unchanged")); g_hash_table_insert (hash, "Can not get username", _("Can not get username")); @@ -537,8 +540,8 @@ gdm_verify_pam_conv (int num_msg, struct gdm_log_init (); for (replies = 0; replies < num_msg; replies++) { - const char *m = (*msg)[replies].msg; - m = perhaps_translate_message (m); + const char *m_untranslated = (*msg)[replies].msg; + const char *m = perhaps_translate_message (m_untranslated); switch ((*msg)[replies].msg_style) { @@ -594,6 +597,12 @@ gdm_verify_pam_conv (int num_msg, struct case PAM_ERROR_MSG: /* PAM sent a message that should displayed to the user */ + + if (strstr (m_untranslated, "account is disabled")) + is_account_disabled = TRUE; + else if (strstr (m_untranslated, "account has expired")) + is_account_expired = TRUE; + gdm_slave_greeter_ctl_no_ret (GDM_ERRDLG, m); reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = NULL; @@ -1295,7 +1304,11 @@ gdm_verify_user (GdmDisplay *d, /* Only give this message if we actually asked for password, otherwise it would be silly to say that the password may have been wrong */ - if (did_we_ask_for_password) { + if (is_account_disabled) { + basemsg = _("\nYour account has been disabled."); + } else if (is_account_expired) { + basemsg = _("\nYour account has expired."); + } else if (did_we_ask_for_password) { basemsg = _("\nIncorrect username or password. " "Letters must be typed in the correct " "case."); @@ -1304,7 +1317,7 @@ gdm_verify_user (GdmDisplay *d, "Letters must be typed in the correct " "case."); } - if (is_capslock) { + if (is_capslock && !is_account_disabled && !is_account_expired) { msg = g_strconcat (basemsg, " ", _("Caps Lock is on."), NULL); @@ -1416,6 +1429,9 @@ gdm_verify_setup_user (GdmDisplay *d, co /* Start authentication session */ did_we_ask_for_password = FALSE; + is_account_disabled = FALSE; + is_account_expired = FALSE; + if ((pamerr = pam_authenticate (pamh, null_tok)) != PAM_SUCCESS) { if (gdm_slave_action_pending ()) { gdm_error (_("Couldn't authenticate user")); diff -upr gdm-2.19.5-pre/gui/gdmchooser.c gdm-2.19.5-post/gui/gdmchooser.c --- gdm-2.19.5-pre/gui/gdmchooser.c 2007-07-30 13:51:03.000000000 -0500 +++ gdm-2.19.5-post/gui/gdmchooser.c 2007-08-16 15:31:56.000000000 -0500 @@ -1799,6 +1799,7 @@ gdm_read_config (void) gdm_config_get_bool (GDM_KEY_ALLOW_ADD); gdm_config_get_bool (GDM_KEY_BROADCAST); gdm_config_get_bool (GDM_KEY_MULTICAST); + gdm_config_get_bool (GDM_KEY_SHOW_DOMAIN); gdmcomm_comm_bulk_stop (); @@ -1828,6 +1829,7 @@ gdm_reread_config (int sig, gpointer dat gdm_config_reload_int (GDM_KEY_SCAN_TIME) || gdm_config_reload_bool (GDM_KEY_ALLOW_ADD) || gdm_config_reload_bool (GDM_KEY_BROADCAST) || + gdm_config_reload_bool (GDM_KEY_SHOW_DOMAIN) || gdm_config_reload_bool (GDM_KEY_MULTICAST)) { if (RUNNING_UNDER_GDM) { diff -upr gdm-2.19.5-pre/gui/gdmlogin.c gdm-2.19.5-post/gui/gdmlogin.c --- gdm-2.19.5-pre/gui/gdmlogin.c 2007-07-30 13:51:02.000000000 -0500 +++ gdm-2.19.5-post/gui/gdmlogin.c 2007-08-16 15:31:56.000000000 -0500 @@ -2910,6 +2910,7 @@ gdm_read_config (void) gdm_config_get_bool (GDM_KEY_TIMED_LOGIN_ENABLE); gdm_config_get_bool (GDM_KEY_TITLE_BAR); gdm_config_get_bool (GDM_KEY_ADD_GTK_MODULES); + gdm_config_get_bool (GDM_KEY_SHOW_DOMAIN); /* Keys not to include in reread_config */ gdm_config_get_bool (GDM_KEY_LOCK_POSITION); @@ -2992,6 +2993,7 @@ gdm_reread_config (int sig, gpointer dat gdm_config_reload_bool (GDM_KEY_SYSTEM_MENU) || gdm_config_reload_bool (GDM_KEY_TIMED_LOGIN_ENABLE) || gdm_config_reload_bool (GDM_KEY_TITLE_BAR) || + gdm_config_reload_bool (GDM_KEY_SHOW_DOMAIN) || gdm_config_reload_bool (GDM_KEY_ADD_GTK_MODULES)) { /* Set busy cursor */ diff -upr gdm-2.19.5-pre/gui/greeter/greeter.c gdm-2.19.5-post/gui/greeter/greeter.c --- gdm-2.19.5-pre/gui/greeter/greeter.c 2007-08-16 15:31:59.000000000 -0500 +++ gdm-2.19.5-post/gui/greeter/greeter.c 2007-08-16 15:31:56.000000000 -0500 @@ -63,6 +63,13 @@ #include "greeter_session.h" #include "greeter_system.h" +static GtkWidget *hig_dialog_new (GtkWindow *parent, + GtkDialogFlags flags, + GtkMessageType type, + GtkButtonsType buttons, + const gchar *primary_message, + const gchar *secondary_message); + gboolean DOING_GDM_DEVELOPMENT = FALSE; GtkWidget *window; @@ -153,6 +160,53 @@ get_random_theme () return theme; } +static gchar *errdlg_message = NULL; + +static void +show_errdlg_messages (void) +{ + gchar *tmp; + GtkWidget *dlg; + + if (!errdlg_message) + return; + + /* we should be now fine for focusing new windows */ + gdm_wm_focus_new_windows (TRUE); + + tmp = ve_locale_to_utf8 (errdlg_message); + dlg = hig_dialog_new (NULL /* parent */, + GTK_DIALOG_MODAL /* flags */, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + tmp, + ""); + g_free (tmp); + g_free (errdlg_message); + errdlg_message = NULL; + + gdm_wm_center_window (GTK_WINDOW (dlg)); + + gdm_wm_no_login_focus_push (); + gtk_dialog_run (GTK_DIALOG (dlg)); + gtk_widget_destroy (dlg); + gdm_wm_no_login_focus_pop (); +} + +static void +append_errdlg_message (const gchar *message) +{ + if (errdlg_message) { + gchar *tmp; + + tmp = g_strjoin ("\n\n", errdlg_message, message, NULL); + g_free (errdlg_message); + errdlg_message = tmp; + } else { + errdlg_message = g_strdup (message); + } +} + static gboolean greeter_ctrl_handler (GIOChannel *source, GIOCondition cond, @@ -243,6 +297,8 @@ process_operation (guchar op_code, break; case GDM_PROMPT: + show_errdlg_messages (); + tmp = ve_locale_to_utf8 (args); if (tmp != NULL && strcmp (tmp, _("Username:")) == 0) { gdm_common_login_sound (gdm_config_get_string (GDM_KEY_SOUND_PROGRAM), @@ -265,6 +321,8 @@ process_operation (guchar op_code, break; case GDM_NOECHO: + show_errdlg_messages (); + tmp = ve_locale_to_utf8 (args); greeter_probably_login_prompt = FALSE; @@ -284,6 +342,8 @@ process_operation (guchar op_code, break; case GDM_MSG: + show_errdlg_messages (); + tmp = ve_locale_to_utf8 (args); greeter_item_pam_message (tmp); g_free (tmp); @@ -292,6 +352,8 @@ process_operation (guchar op_code, break; case GDM_ERRBOX: + show_errdlg_messages (); + tmp = ve_locale_to_utf8 (args); greeter_item_pam_error (tmp); g_free (tmp); @@ -301,30 +363,17 @@ process_operation (guchar op_code, break; case GDM_ERRDLG: - /* we should be now fine for focusing new windows */ - gdm_wm_focus_new_windows (TRUE); - tmp = ve_locale_to_utf8 (args); - dlg = hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - tmp, - ""); + append_errdlg_message (tmp); g_free (tmp); - gdm_wm_center_window (GTK_WINDOW (dlg)); - - gdm_wm_no_login_focus_push (); - gtk_dialog_run (GTK_DIALOG (dlg)); - gtk_widget_destroy (dlg); - gdm_wm_no_login_focus_pop (); - printf ("%c\n", STX); fflush (stdout); break; case GDM_SESS: + show_errdlg_messages (); + tmp = ve_locale_to_utf8 (args); session = gdm_session_lookup (tmp, &lookup_status); if (lookup_status != SESSION_LOOKUP_SUCCESS) { @@ -392,10 +441,14 @@ process_operation (guchar op_code, break; case GDM_LANG: + show_errdlg_messages (); + gdm_lang_op_lang (args); break; case GDM_SSESS: + show_errdlg_messages (); + if (gdm_get_save_session () == GTK_RESPONSE_YES) printf ("%cY\n", STX); else @@ -405,6 +458,8 @@ process_operation (guchar op_code, break; case GDM_SLANG: + show_errdlg_messages (); + gdm_lang_op_slang (args); break; @@ -447,6 +502,8 @@ process_operation (guchar op_code, break; case GDM_QUIT: + show_errdlg_messages (); + greeter_item_timed_stop (); if (require_quarter) { @@ -563,6 +620,8 @@ process_operation (guchar op_code, break; case GDM_SAVEDIE: + show_errdlg_messages (); + /* Set busy cursor */ gdm_common_setup_cursor (GDK_WATCH); @@ -582,6 +641,8 @@ process_operation (guchar op_code, break; default: + show_errdlg_messages (); + gdm_common_fail_greeter ("Unexpected greeter command received: '%c'", op_code); break; } @@ -918,6 +979,7 @@ gdm_read_config (void) gdm_config_get_bool (GDM_KEY_SOUND_ON_LOGIN); gdm_config_get_bool (GDM_KEY_DEFAULT_WELCOME); gdm_config_get_bool (GDM_KEY_DEFAULT_REMOTE_WELCOME); + gdm_config_get_bool (GDM_KEY_SHOW_DOMAIN); gdm_config_get_bool (GDM_KEY_ADD_GTK_MODULES); gdm_config_get_bool (GDM_KEY_BROWSER); @@ -1007,6 +1069,7 @@ greeter_reread_config (int sig, gpointer gdm_config_reload_bool (GDM_KEY_SHOW_LAST_SESSION) || gdm_config_reload_bool (GDM_KEY_ALLOW_ROOT) || gdm_config_reload_bool (GDM_KEY_ALLOW_REMOTE_ROOT) || + gdm_config_reload_bool (GDM_KEY_SHOW_DOMAIN) || gdm_config_reload_bool (GDM_KEY_ADD_GTK_MODULES) || gdm_config_reload_bool (GDM_KEY_BROWSER)) { diff -upr gdm-2.19.5-pre/gui/greeter/greeter_canvas_item.c gdm-2.19.5-post/gui/greeter/greeter_canvas_item.c --- gdm-2.19.5-pre/gui/greeter/greeter_canvas_item.c 2007-08-16 15:31:59.000000000 -0500 +++ gdm-2.19.5-post/gui/greeter/greeter_canvas_item.c 2007-08-16 15:31:56.000000000 -0500 @@ -20,6 +20,8 @@ #include #include +#include +#include #include #include #include @@ -46,6 +48,9 @@ #include "greeter_canvas_text.h" #include "greeter_parser.h" +#define WBINFO_DOMAINS_MAX 64 +#define WBINFO_READ_MAX 256 + /* Keep track of buttons so they can be set sensitive/insensitive */ GtkButton *gtk_ok_button = NULL; GtkButton *gtk_start_again_button = NULL; @@ -395,6 +400,189 @@ set_root_pixmap (GdkPixmap *pixmap) return FALSE; } +gboolean greeter_can_do_domain_login = FALSE; +gchar *greeter_domain_separator = NULL; + +gboolean greeter_wbinfo_was_run = FALSE; +gboolean greeter_wbinfo_is_running = FALSE; +GPid greeter_wbinfo_pid; +GIOChannel *greeter_wbinfo_channel; +GString *greeter_wbinfo_output; + +static void +wbinfo_end (void) +{ + GreeterItemInfo *domain_entry_item_info; + GtkWidget *domain_entry = NULL; + gint wbinfo_status = 0; + gchar *wbinfo_output; + GtkListStore *domain_list_store; + gchar **tokens = NULL; + gchar *own_domain = NULL; + gint select_index = 0; + GtkTreeIter iter; + const gchar *text; + gint i; + + if (!greeter_wbinfo_is_running) + return; + + greeter_wbinfo_is_running = FALSE; + waitpid (greeter_wbinfo_pid, &wbinfo_status, 0); + g_spawn_close_pid (greeter_wbinfo_pid); + + wbinfo_output = g_string_free (greeter_wbinfo_output, FALSE); + + domain_entry_item_info = greeter_lookup_id ("domain-entry"); + if (domain_entry_item_info && domain_entry_item_info->item && + GNOME_IS_CANVAS_WIDGET (domain_entry_item_info->item)) { + domain_entry = GNOME_CANVAS_WIDGET (domain_entry_item_info->item)->widget; + } else { + g_free (wbinfo_output); + return; + } + + /* Set up the domain store model */ + + domain_list_store = gtk_list_store_new (1, G_TYPE_STRING); + + /* The "local login" entry */ + + gtk_list_store_append (domain_list_store, &iter); + gtk_list_store_set (domain_list_store, &iter, + 0, _(""), + -1); + + /* Process wbinfo output, if any */ + + if (WEXITSTATUS (wbinfo_status) == 0 && wbinfo_output && *wbinfo_output) { + /* The first line of output should be the domain separator, + * and any remaining lines are trusted domains. */ + tokens = g_strsplit_set (wbinfo_output, "\n\r", WBINFO_DOMAINS_MAX + 1); + } + + g_free (wbinfo_output); + g_free (greeter_domain_separator); + greeter_domain_separator = NULL; + + if (tokens && tokens [0]) { + greeter_can_do_domain_login = TRUE; + greeter_domain_separator = g_strdup (tokens [0]); + + own_domain = tokens [1]; + + /* Generate a sorted list of domains for the domain selector combo. */ + + g_qsort_with_data (&tokens [1], + g_strv_length (tokens) - 1, + sizeof (gchar *), + (GCompareDataFunc) g_ascii_strcasecmp, + NULL); + + for (i = 1; tokens [i]; i++) { + /* Ensure no blank entries */ + if (!strlen (tokens [i])) + continue; + + gtk_list_store_append (domain_list_store, &iter); + gtk_list_store_set (domain_list_store, &iter, + 0, tokens [i], + -1); + + if (tokens [i] == own_domain) + select_index = i; + } + + } else { + greeter_can_do_domain_login = FALSE; + } + + if (tokens) + g_strfreev (tokens); + + /* Assign model and default selection to widget */ + + gtk_combo_box_set_model (GTK_COMBO_BOX (domain_entry), + GTK_TREE_MODEL (domain_list_store)); + gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (domain_entry), 0); + + /* Default to our own domain, but only if the entry was empty */ + text = gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (domain_entry)))); + if (!text || !*text) + gtk_combo_box_set_active (GTK_COMBO_BOX (domain_entry), select_index); + + g_object_unref (domain_list_store); +} + +static gboolean +wbinfo_on_output (GIOChannel *channel, GIOCondition condition, gpointer data) +{ + gchar buf [WBINFO_READ_MAX]; + gsize bytes_read; + GIOStatus status; + + status = g_io_channel_read_chars (channel, buf, WBINFO_READ_MAX, &bytes_read, NULL); + + if (bytes_read < 1) { + wbinfo_end (); + return FALSE; + } + + g_string_append_len (greeter_wbinfo_output, buf, bytes_read); + return TRUE; +} + +static void +wbinfo_begin (void) +{ + gchar *wbinfo_args [] = { "wbinfo", "--separator", "--own-domain", "--trusted-domains", NULL }; + gchar *wbinfo_env [] = { NULL }; + gint wbinfo_stdout_fd; + + if (greeter_wbinfo_was_run) + return; + + greeter_wbinfo_was_run = TRUE; + + /* Lame guess, in case winbind isn't running, but gets started later. This + * is a workaround for testing and broken systems. */ + greeter_domain_separator = g_strdup ("\\"); + + if (!g_spawn_async_with_pipes ("/", + wbinfo_args, + wbinfo_env, + G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL | + G_SPAWN_DO_NOT_REAP_CHILD, + NULL /* child setup function */, + NULL /* child setup user_data */, + &greeter_wbinfo_pid, + NULL /* &wbinfo_stdin_fd */, + &wbinfo_stdout_fd, + NULL /* &wbinfo_stderr_fd */, + NULL)) + return; + + greeter_wbinfo_is_running = TRUE; + greeter_wbinfo_output = g_string_new (""); + + fcntl (wbinfo_stdout_fd, F_SETFL, O_NONBLOCK); + + greeter_wbinfo_channel = g_io_channel_unix_new (wbinfo_stdout_fd); + g_io_channel_set_encoding (greeter_wbinfo_channel, NULL, NULL); + g_io_channel_set_close_on_unref (greeter_wbinfo_channel, TRUE); + g_io_add_watch (greeter_wbinfo_channel, G_IO_IN | G_IO_HUP, wbinfo_on_output, NULL); + g_io_channel_unref (greeter_wbinfo_channel); /* Watch holds remaining ref */ +} + +static gboolean +deselect_entry_text (GtkEntry *entry) +{ + gtk_editable_select_region (GTK_EDITABLE (entry), 0, 0); + gtk_editable_set_position (GTK_EDITABLE (entry), -1); + + return FALSE; +} + void greeter_item_create_canvas_item (GreeterItemInfo *item) { @@ -686,6 +874,48 @@ greeter_item_create_canvas_item (Greeter break; + case GREETER_ITEM_TYPE_COMBO_BOX_ENTRY: + entry = gtk_combo_box_entry_new (); + + gtk_widget_set_name (entry, "domain-entry"); + + gtk_entry_set_has_frame (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (entry))), FALSE); + gtk_widget_modify_font (entry, item->data.text.fonts[GREETER_ITEM_STATE_NORMAL]); + + get_gdk_color_from_rgb (&c, item->data.text.colors[GREETER_ITEM_STATE_NORMAL]); + gtk_widget_modify_text (entry, GTK_STATE_NORMAL, &c); + + item->item = gnome_canvas_item_new (group, + GNOME_TYPE_CANVAS_WIDGET, + "widget", entry, + "x", x1, + "y", y1, + "height", (double)rect.height, + "width", (double)rect.width, + NULL); + + /* cursor blinking is evil on remote displays, don't do it forever */ + gdm_common_setup_blinking_entry (gtk_bin_get_child (GTK_BIN (entry))); + + /* Recall the last used domain */ + if (g_file_get_contents (GDM_SCRATCH_DIR "/last_domain", &text, NULL, NULL)) { + GtkWidget *temp_entry; + + temp_entry = gtk_bin_get_child (GTK_BIN (entry)); + + gtk_entry_set_text (GTK_ENTRY (temp_entry), text); + + /* The set text gets selected. It looks bad. Avoid that. */ + g_idle_add_full (G_PRIORITY_LOW, (GSourceFunc) deselect_entry_text, temp_entry, NULL); + + g_free (text); + } + + /* Query wbinfo */ + wbinfo_begin (); + + break; + case GREETER_ITEM_TYPE_LIST: /* Note a list type must be setup later and we will add the list store * to it then, depending on the type. Likely userlist is the diff -upr gdm-2.19.5-pre/gui/greeter/greeter_configuration.h gdm-2.19.5-post/gui/greeter/greeter_configuration.h --- gdm-2.19.5-pre/gui/greeter/greeter_configuration.h 2007-07-30 13:51:01.000000000 -0500 +++ gdm-2.19.5-post/gui/greeter/greeter_configuration.h 2007-08-16 15:31:56.000000000 -0500 @@ -65,6 +65,7 @@ extern gchar *GdmSoundOnLoginFailureFile extern gboolean GdmSoundOnLoginReady; extern gboolean GdmSoundOnLoginSuccess; extern gboolean GdmSoundOnLoginFailure; +extern gboolean GdmShowDomain; extern gboolean GDM_IS_LOCAL; extern gboolean DOING_GDM_DEVELOPMENT; diff -upr gdm-2.19.5-pre/gui/greeter/greeter.h gdm-2.19.5-post/gui/greeter/greeter.h --- gdm-2.19.5-pre/gui/greeter/greeter.h 2007-07-30 13:51:01.000000000 -0500 +++ gdm-2.19.5-post/gui/greeter/greeter.h 2007-08-16 15:31:56.000000000 -0500 @@ -27,6 +27,9 @@ extern GtkWidget *window; extern gboolean greeter_probably_login_prompt; +extern gboolean greeter_can_do_domain_login; +extern gchar *greeter_domain_separator; + void greeter_ignore_buttons (gboolean val); #endif diff -upr gdm-2.19.5-pre/gui/greeter/greeter_item.c gdm-2.19.5-post/gui/greeter/greeter_item.c --- gdm-2.19.5-pre/gui/greeter/greeter_item.c 2007-07-30 13:51:01.000000000 -0500 +++ gdm-2.19.5-post/gui/greeter/greeter_item.c 2007-08-16 15:57:07.000000000 -0500 @@ -234,6 +234,11 @@ greeter_item_is_visible (GreeterItemInfo return FALSE; } + if ( ! gdm_config_get_bool (GDM_KEY_SHOW_DOMAIN) && + (info->show_type != NULL && + g_str_has_prefix (info->show_type, "domain"))) + return FALSE; + if (( ! gdm_config_get_bool (GDM_KEY_TIMED_LOGIN_ENABLE) || ve_string_empty (gdm_config_get_string (GDM_KEY_TIMED_LOGIN)) || NULL == g_getenv("GDM_TIMED_LOGIN_OK")) && diff -upr gdm-2.19.5-pre/gui/greeter/greeter_item.h gdm-2.19.5-post/gui/greeter/greeter_item.h --- gdm-2.19.5-pre/gui/greeter/greeter_item.h 2007-07-30 13:51:01.000000000 -0500 +++ gdm-2.19.5-post/gui/greeter/greeter_item.h 2007-08-16 15:31:56.000000000 -0500 @@ -47,7 +47,8 @@ enum _GreeterItemType { GREETER_ITEM_TYPE_LABEL, GREETER_ITEM_TYPE_ENTRY, GREETER_ITEM_TYPE_LIST, - GREETER_ITEM_TYPE_BUTTON + GREETER_ITEM_TYPE_BUTTON, + GREETER_ITEM_TYPE_COMBO_BOX_ENTRY }; /* Make sure to adjust the bitfield in the structure if @@ -154,7 +155,7 @@ struct _GreeterItemInfo { union { /* Note: we want to have alphas, colors and have_color coincide for * all types that have it */ -#define GREETER_ITEM_TYPE_IS_TEXT(info) ((info)->item_type == GREETER_ITEM_TYPE_LABEL || (info)->item_type == GREETER_ITEM_TYPE_ENTRY) +#define GREETER_ITEM_TYPE_IS_TEXT(info) ((info)->item_type == GREETER_ITEM_TYPE_LABEL || (info)->item_type == GREETER_ITEM_TYPE_ENTRY || (info)->item_type == GREETER_ITEM_TYPE_COMBO_BOX_ENTRY) struct { guint8 alphas[GREETER_ITEM_STATE_MAX]; guint32 colors[GREETER_ITEM_STATE_MAX]; diff -upr gdm-2.19.5-pre/gui/greeter/greeter_item_pam.c gdm-2.19.5-post/gui/greeter/greeter_item_pam.c --- gdm-2.19.5-pre/gui/greeter/greeter_item_pam.c 2007-07-30 13:51:01.000000000 -0500 +++ gdm-2.19.5-post/gui/greeter/greeter_item_pam.c 2007-08-16 15:31:56.000000000 -0500 @@ -25,6 +25,7 @@ #include "gdm-common.h" #include "gdm-socket-protocol.h" +#include "gdm-daemon-config-keys.h" #include "greeter.h" #include "greeter_item.h" @@ -37,6 +38,7 @@ #include "gdm.h" #include "gdmwm.h" #include "gdmcommon.h" +#include "gdmconfig.h" static gboolean messages_to_give = FALSE; static gboolean replace_msg = TRUE; @@ -116,11 +118,29 @@ set_text (GreeterItemInfo *info, const c info->item); } +static void +domain_entry_set_sensitive (gboolean sensitive) +{ + if (gdm_config_get_bool (GDM_KEY_SHOW_DOMAIN)) + { + GreeterItemInfo *domain_entry_item_info; + GtkWidget *domain_entry = NULL; + + domain_entry_item_info = greeter_lookup_id ("domain-entry"); + if (domain_entry_item_info && domain_entry_item_info->item && + GNOME_IS_CANVAS_WIDGET (domain_entry_item_info->item)) + domain_entry = GNOME_CANVAS_WIDGET (domain_entry_item_info->item)->widget; + + if (domain_entry) + gtk_widget_set_sensitive (domain_entry, sensitive); + } +} + void greeter_item_pam_login (GtkEntry *entry, GreeterItemInfo *info) { const char *str; - char *tmp; + char *tmp, *tmp2; GreeterItemInfo *error_info; if (gtk_ok_button != NULL) @@ -152,6 +172,7 @@ greeter_item_pam_login (GtkEntry *entry, } gtk_widget_set_sensitive (GTK_WIDGET (entry), FALSE); + domain_entry_set_sensitive (FALSE); /* clear the err_box */ if (err_box_clear_handler > 0) @@ -166,6 +187,33 @@ greeter_item_pam_login (GtkEntry *entry, } tmp = ve_locale_from_utf8 (str); + + /* Prepend the domain if applicable */ + if (greeter_probably_login_prompt && gdm_config_get_bool (GDM_KEY_SHOW_DOMAIN)) + { + GreeterItemInfo *domain_entry_item_info; + GtkWidget *domain_entry = NULL; + + domain_entry_item_info = greeter_lookup_id ("domain-entry"); + if (domain_entry_item_info && domain_entry_item_info->item && + GNOME_IS_CANVAS_WIDGET (domain_entry_item_info->item)) + domain_entry = GNOME_CANVAS_WIDGET (domain_entry_item_info->item)->widget; + + if (domain_entry && (str = gtk_combo_box_get_active_text (GTK_COMBO_BOX (domain_entry))) && *str && + strcmp (str, _(""))) + { + g_file_set_contents (GDM_SCRATCH_DIR "/last_domain", str, strlen (str), NULL); + + tmp2 = g_strdup_printf ("%s%s%s", str, greeter_domain_separator, tmp); + g_free (tmp); + tmp = tmp2; + } + else + { + g_remove (GDM_SCRATCH_DIR "/last_domain"); + } + } + printf ("%c%s\n", STX, tmp); fflush (stdout); g_free (tmp); @@ -224,6 +272,7 @@ greeter_item_pam_setup (void) /* initially insensitive */ gtk_widget_set_sensitive (entry, FALSE); + domain_entry_set_sensitive (FALSE); } g_signal_connect (entry, "activate", @@ -288,6 +337,9 @@ greeter_item_pam_prompt (const char *mes gtk_entry_set_max_length (GTK_ENTRY (entry), entry_len); gtk_entry_set_text (GTK_ENTRY (entry), ""); gtk_widget_grab_focus (entry); + + /* Domain selector should only be accessed when entering the user name */ + domain_entry_set_sensitive (entry_visible); } messages_to_give = FALSE; diff -upr gdm-2.19.5-pre/gui/greeter/greeter_parser.c gdm-2.19.5-post/gui/greeter/greeter_parser.c --- gdm-2.19.5-pre/gui/greeter/greeter_parser.c 2007-07-30 13:51:01.000000000 -0500 +++ gdm-2.19.5-post/gui/greeter/greeter_parser.c 2007-08-16 15:31:56.000000000 -0500 @@ -402,6 +402,11 @@ parse_stock (xmlNodePtr node, g_free (*translated_text); *translated_text = g_strdup (_("Username:")); } + else if (g_ascii_strcasecmp ((char *) prop, "domain-label") == 0) + { + g_free (*translated_text); + *translated_text = g_strdup (_("Domain:")); + } else if (g_ascii_strcasecmp ((char *) prop, "ok") == 0) { g_free (*translated_text); @@ -1649,6 +1654,15 @@ parse_entry (xmlNodePtr node, } static gboolean +parse_combo_box_entry (xmlNodePtr node, + GreeterItemInfo *info, + GError **error) +{ + /* A ComboBoxEntry is just an Entry with a dropdown list */ + return parse_entry (node, info, error); +} + +static gboolean parse_items (xmlNodePtr node, GList **items_out, GreeterItemInfo *parent, @@ -1704,6 +1718,8 @@ parse_items (xmlNodePtr node, item_type = GREETER_ITEM_TYPE_LIST; else if (strcmp ((char *) type, "button") == 0) item_type = GREETER_ITEM_TYPE_BUTTON; + else if (strcmp ((char *) type, "combo-box-entry") == 0) + item_type = GREETER_ITEM_TYPE_COMBO_BOX_ENTRY; else { g_set_error (error, @@ -1750,6 +1766,9 @@ parse_items (xmlNodePtr node, case GREETER_ITEM_TYPE_BUTTON: res = parse_gtkbutton (child, info, error); break; + case GREETER_ITEM_TYPE_COMBO_BOX_ENTRY: + res = parse_combo_box_entry (child, info, error); + break; default: g_set_error (error, GREETER_PARSER_ERROR,