diff options
64 files changed, 7235 insertions, 8356 deletions
@@ -1,3 +1,150 @@ +2007-04-02 William Jon McCann <mccann@jhu.edu> + + * common/Makefile.am: + * common/gdm-common.c: (v4_v4_equal), (v6_v6_equal), + (gdm_address_equal), (gdm_address_is_loopback), + (gdm_address_get_info): + * common/gdm-common.h: + * common/gdm-config.c: (gdm_config_peek_value), + (gdm_config_get_value), (gdm_config_peek_value_for_id), + (gdm_config_peek_string_for_id), (gdm_config_get_string_for_id), + (gdm_config_get_int_for_id), (gdm_config_set_int_for_id): + * common/gdm-config.h: + * common/gdm-log.c: (log_level_to_priority_and_prefix), + (gdm_log_default_handler), (gdm_log_set_debug), (gdm_log_init), + (gdm_log_shutdown): + * common/gdm-log.h: + * configure.ac: + * daemon/Makefile.am: + * daemon/auth.c: (add_auth_entry), (add_auth_entry_for_addr), + (get_local_auths), (gdm_auth_user_add), (gdm_auth_set_local_auth), + (gdm_auth_free_auth_list): + * daemon/choose.c: (get_first_address_for_node), (gdm_choose_data), + (gdm_choose_indirect_alloc), + (gdm_choose_indirect_dispose_empty_id), + (gdm_choose_indirect_lookup_by_chosen), + (gdm_choose_indirect_lookup), (gdm_choose_indirect_dispose): + * daemon/choose.h: + * daemon/cookie.c: + * daemon/cookie.h: + * daemon/display.c: (gdm_display_manage), (count_session_limits), + (gdm_display_dispose), (gdm_display_lookup): + * daemon/display.h: + * daemon/errorgui.c: (setup_dialog), (gdm_errorgui_error_box_full), + (gdm_errorgui_error_box), (gdm_errorgui_failsafe_question), + (gdm_errorgui_failsafe_yesno), (gdm_errorgui_failsafe_ask_buttons): + * daemon/errorgui.h: + * daemon/filecheck.c: (gdm_file_check), (gdm_auth_file_check): + * daemon/gdm-daemon-config.c: (gdm_daemon_config_get_display_list), + (gdm_daemon_config_display_list_append), + (gdm_daemon_config_display_list_insert), + (gdm_daemon_config_display_list_remove), + (gdm_daemon_config_get_bool_for_id), + (gdm_daemon_config_get_int_for_id), + (gdm_daemon_config_get_string_for_id), (handle_no_displays), + (gdm_daemon_config_parse): + * daemon/gdm-daemon-config.h: + * daemon/gdm-net.c: + * daemon/gdm-net.h: + * daemon/gdm.c: (mark_display_exists), (gdm_daemonify), + (gdm_start_first_unborn_local), (gdm_final_cleanup), + (deal_with_x_crashes), (gdm_safe_restart), (gdm_try_logout_action), + (main), (order_exists), (get_new_order), (gdm_handle_message), + (find_display), (handle_flexi_server), (handle_dynamic_server), + (gdm_handle_user_message): + * daemon/gdm.h: + * daemon/gdmconsolekit.c: (get_path_array_from_iter): + * daemon/gdmconsolekit.h: + * daemon/md5.h: + * daemon/misc.c: (gdm_clearenv_no_lang), (gdm_get_free_display), + (gdm_exec_wait), (gdm_fork_extra), (gdm_wait_for_extra), + (gdm_address_peek_local_list), (gdm_address_is_local), + (fillout_addrinfo), (gdm_gethostbyname), (gdm_gethostbyaddr), + (gdm_hostent_copy): + * daemon/misc.h: + * daemon/server.c: (gdm_exec_fbconsole), (gdm_server_spawn): + * daemon/server.h: + * daemon/slave.c: (get_runlevel), (gdm_slave_start), + (focus_first_x_window), (run_config), (play_login_sound), + (gdm_slave_greeter), (send_chosen_host), (gdm_slave_chooser), + (session_child_run), (gdm_slave_session_start), + (gdm_slave_session_stop), (check_for_interruption), + (gdm_child_exit), (gdm_slave_exec_script), + (gdm_parse_enriched_login), (gdm_is_user_valid): + * daemon/slave.h: + * daemon/verify-crypt.c: (gdm_verify_user), + (gdm_verify_setup_user): + * daemon/verify-pam.c: (gdm_verify_pam_conv), + (gdm_verify_standalone_pam_conv), (gdm_verify_user), + (gdm_verify_setup_user), (gdm_verify_cleanup), (gdm_verify_check): + * daemon/verify-shadow.c: (gdm_verify_user), + (gdm_verify_setup_user): + * daemon/verify.h: + * daemon/xdmcp.c: (gdm_xdmcp_displays_from_host), + (gdm_xdmcp_display_lookup_by_host), (ai_family_str), (ai_type_str), + (ai_protocol_str), (ai_flags_str), (debug_addrinfo), + (gdm_xdmcp_create_socket), (gdm_xdmcp_bind), (gdm_xdmcp_init), + (gdm_xdmcp_run), (gdm_xdmcp_close), (gdm_xdmcp_decode_packet), + (gdm_xdmcp_handle_query), (set_port_for_request), + (set_address_for_request), (gdm_xdmcp_send_forward_query), + (gdm_forward_query_alloc), (gdm_forward_query_lookup), + (gdm_forward_query_dispose), (create_sa_from_request), + (gdm_xdmcp_handle_forward_query), (gdm_xdmcp_send_willing), + (gdm_xdmcp_send_unwilling), + (gdm_xdmcp_really_send_managed_forward), (managed_forward_handler), + (gdm_xdmcp_send_managed_forward), + (gdm_xdmcp_send_got_managed_forward), (gdm_xdmcp_handle_request), + (gdm_xdmcp_send_accept), (gdm_xdmcp_send_decline), + (gdm_xdmcp_handle_manage), (gdm_xdmcp_handle_managed_forward), + (gdm_xdmcp_whack_queued_managed_forwards), + (gdm_xdmcp_handle_got_managed_forward), (gdm_xdmcp_send_refuse), + (gdm_xdmcp_send_failed), (gdm_xdmcp_handle_keepalive), + (gdm_xdmcp_send_alive), (gdm_xdmcp_host_allow), + (gdm_xdmcp_display_alloc), (gdm_xdmcp_display_lookup), + (gdm_xdmcp_display_dispose_check), (gdm_xdmcp_displays_check), + (gdm_xdmcp_recount_sessions): + * daemon/xdmcp.h: + * gui/Makefile.am: + * gui/gdmXnestchooser.c: + * gui/gdmchooser.c: (gdm_chooser_host_alloc), (gdm_chooser_cancel), + (gdm_chooser_manage), (gdm_read_config), (gdm_reread_config), + (main): + * gui/gdmcomm.c: (do_command), (gdmcomm_call_gdm_real): + * gui/gdmcommon.c: (gdm_common_log_init), + (gdm_common_log_set_debug), (gdm_common_fail_exit), + (gdm_common_fail_greeter), (gdm_common_info), (gdm_common_error), + (gdm_common_warning), (gdm_common_debug), (gdm_common_expand_text): + * gui/gdmcommon.h: + * gui/gdmconfig.c: + * gui/gdmdynamic.c: (main): + * gui/gdmflexiserver.c: (main): + * gui/gdmlanguages.c: + * gui/gdmlogin.c: (gdm_login_restart_handler), + (gdm_login_halt_handler), (gdm_login_use_chooser_handler), + (gdm_read_config), (gdm_reread_config), (main): + * gui/gdmsession.c: + * gui/gdmsetup.c: + * gui/gdmuser.c: + * gui/gdmwm.c: + * gui/greeter/greeter.c: (gdm_read_config), + (greeter_reread_config), (main): + * gui/greeter/greeter_item_customlist.c: + * gui/greeter/greeter_item_pam.c: + * gui/greeter/greeter_item_timed.c: + * gui/greeter/greeter_item_ulist.c: + * gui/greeter/greeter_parser.c: (parse_show): + * gui/greeter/greeter_system.c: (query_greeter_restart_handler), + (query_greeter_halt_handler), (greeter_restart_handler), + (greeter_halt_handler), (greeter_chooser_handler): + + Use fewer global variables. + Separate monolithic gdm.h into component parts. + Use the Glib message logging API to write to syslog. + Cleans up the ipv4/6 handling in the daemon to use a common code + patch and be mostly AF- independent. + Add a few convenience functions to gdm-config for get/set by ID. + Patch from bug #376010 + 2006-04-02 Brian Cameron <brian.cameron@sun.com> * configure.ac, po/POTFILES.skip, gui/Makefile.am, diff --git a/common/Makefile.am b/common/Makefile.am index a67468c1..d55fff78 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -34,12 +34,15 @@ libgdmcommon_a_SOURCES = \ gdm-common-config.c \ gdm-config.h \ gdm-config.c \ + gdm-log.h \ + gdm-log.c \ ve-signal.h \ ve-signal.c \ $(NULL) noinst_PROGRAMS = \ test-config \ + test-log \ $(NULL) test_config_SOURCES = \ @@ -51,3 +54,12 @@ test_config_LDADD = \ $(top_builddir)/common/libgdmcommon.a \ $(GLIB_LIBS) \ $(NULL) + +test_log_SOURCES = \ + test-log.c \ + $(NULL) + +test_log_LDADD = \ + $(top_builddir)/common/libgdmcommon.a \ + $(GLIB_LIBS) \ + $(NULL) diff --git a/common/gdm-common.c b/common/gdm-common.c index 30c93ca7..dbb3ff31 100644 --- a/common/gdm-common.c +++ b/common/gdm-common.c @@ -32,6 +32,93 @@ #include "gdm-common.h" +static gboolean +v4_v4_equal (const struct sockaddr_in *a, + const struct sockaddr_in *b) +{ + return a->sin_addr.s_addr == b->sin_addr.s_addr; +} + +#ifdef ENABLE_IPV6 +static gboolean +v6_v6_equal (struct sockaddr_in6 *a, + struct sockaddr_in6 *b) +{ + return IN6_ARE_ADDR_EQUAL (&a->sin6_addr, &b->sin6_addr); +} +#endif + +#define SA(__s) ((struct sockaddr *) __s) +#define SIN(__s) ((struct sockaddr_in *) __s) +#define SIN6(__s) ((struct sockaddr_in6 *) __s) + +gboolean +gdm_address_equal (struct sockaddr_storage *sa, + struct sockaddr_storage *sb) +{ + guint8 fam_a; + guint8 fam_b; + + g_return_val_if_fail (sa != NULL, FALSE); + g_return_val_if_fail (sb != NULL, FALSE); + + fam_a = sa->ss_family; + fam_b = sb->ss_family; + + if (fam_a == AF_INET && fam_b == AF_INET) { + return v4_v4_equal (SIN (sa), SIN (sb)); + } +#ifdef ENABLE_IPV6 + else if (fam_a == AF_INET6 && fam_b == AF_INET6) { + return v6_v6_equal (SIN6 (sa), SIN6 (sb)); + } +#endif + return FALSE; +} + +gboolean +gdm_address_is_loopback (struct sockaddr_storage *sa) +{ + switch(sa->ss_family){ +#ifdef AF_INET6 + case AF_INET6: + return IN6_IS_ADDR_LOOPBACK (&((struct sockaddr_in6 *)sa)->sin6_addr); + break; +#endif + case AF_INET: + return (INADDR_LOOPBACK == (((struct sockaddr_in *)sa)->sin_addr.s_addr)); + break; + default: + break; + } + + return FALSE; +} + +void +gdm_address_get_info (struct sockaddr_storage *ss, + char **hostp, + char **servp) +{ + char host [NI_MAXHOST]; + char serv [NI_MAXSERV]; + + host [0] = '\0'; + serv [0] = '\0'; + getnameinfo ((const struct sockaddr *)ss, + sizeof (struct sockaddr_storage), + host, sizeof (host), + serv, sizeof (serv), + NI_NUMERICHOST | NI_NUMERICSERV); + + if (servp != NULL) { + *servp = g_strdup (serv); + } + if (hostp != NULL) { + *hostp = g_strdup (host); + } +} + /** * ve_clearenv: * diff --git a/common/gdm-common.h b/common/gdm-common.h index 09c8960a..c189d41a 100644 --- a/common/gdm-common.h +++ b/common/gdm-common.h @@ -28,13 +28,24 @@ #include <errno.h> #include <sys/types.h> #include <sys/wait.h> +#include <sys/socket.h> #include <locale.h> +#include <netdb.h> #include "ve-signal.h" #include "gdm-common-config.h" #include "gdm-config.h" G_BEGIN_DECLS + + +gboolean gdm_address_equal (struct sockaddr_storage *sa, + struct sockaddr_storage *sb); +gboolean gdm_address_is_loopback (struct sockaddr_storage *sa); +void gdm_address_get_info (struct sockaddr_storage *sa, + char **host, + char **port); + void ve_clearenv (void); char * ve_first_word (const char *s); gboolean ve_first_word_executable (const char *s, diff --git a/common/gdm-config.c b/common/gdm-config.c index 38748655..52cfaf04 100644 --- a/common/gdm-config.c +++ b/common/gdm-config.c @@ -1107,14 +1107,14 @@ gdm_config_process_all (GdmConfig *config, } gboolean -gdm_config_get_value (GdmConfig *config, - const char *group, - const char *key, - GdmConfigValue **valuep) +gdm_config_peek_value (GdmConfig *config, + const char *group, + const char *key, + const GdmConfigValue **valuep) { - gboolean ret; - char *key_path; - GdmConfigValue *value; + gboolean ret; + char *key_path; + const GdmConfigValue *value; g_return_val_if_fail (config != NULL, FALSE); @@ -1128,7 +1128,7 @@ gdm_config_get_value (GdmConfig *config, if (valuep != NULL) { if (ret) { - *valuep = gdm_config_value_copy (value); + *valuep = value; } else { *valuep = NULL; } @@ -1138,6 +1138,23 @@ gdm_config_get_value (GdmConfig *config, } gboolean +gdm_config_get_value (GdmConfig *config, + const char *group, + const char *key, + GdmConfigValue **valuep) +{ + gboolean res; + const GdmConfigValue *value; + + res = gdm_config_peek_value (config, group, key, &value); + if (valuep != NULL) { + *valuep = (value == NULL) ? NULL : gdm_config_value_copy (value); + } + + return res; +} + +gboolean gdm_config_set_value (GdmConfig *config, const char *group, const char *key, @@ -1153,6 +1170,23 @@ gdm_config_set_value (GdmConfig *config, return TRUE; } +static gboolean +gdm_config_peek_value_for_id (GdmConfig *config, + int id, + const GdmConfigValue **valuep) +{ + const GdmConfigEntry *entry; + + g_return_val_if_fail (config != NULL, FALSE); + + entry = gdm_config_lookup_entry_for_id (config, id); + if (entry == NULL) { + return FALSE; + } + + return gdm_config_peek_value (config, entry->group, entry->key, valuep); +} + gboolean gdm_config_get_value_for_id (GdmConfig *config, int id, @@ -1188,27 +1222,41 @@ gdm_config_set_value_for_id (GdmConfig *config, } gboolean -gdm_config_get_string_for_id (GdmConfig *config, - int id, - char **strp) +gdm_config_peek_string_for_id (GdmConfig *config, + int id, + const char **strp) { - GdmConfigValue *value; - const char *str; - gboolean res; + const GdmConfigValue *value; + const char *str; + gboolean res; g_return_val_if_fail (config != NULL, FALSE); - res = gdm_config_get_value_for_id (config, id, &value); + res = gdm_config_peek_value_for_id (config, id, &value); if (! res) { return FALSE; } str = gdm_config_value_get_string (value); if (strp != NULL) { - *strp = g_strdup (str); + *strp = str; } - gdm_config_value_free (value); + return res; +} + +gboolean +gdm_config_get_string_for_id (GdmConfig *config, + int id, + char **strp) +{ + gboolean res; + const char *str; + + res = gdm_config_peek_string_for_id (config, id, &str); + if (strp != NULL) { + *strp = g_strdup (str); + } return res; } @@ -1240,6 +1288,32 @@ gdm_config_get_bool_for_id (GdmConfig *config, } gboolean +gdm_config_get_int_for_id (GdmConfig *config, + int id, + int *integerp) +{ + GdmConfigValue *value; + gboolean integer; + gboolean res; + + g_return_val_if_fail (config != NULL, FALSE); + + res = gdm_config_get_value_for_id (config, id, &value); + if (! res) { + return FALSE; + } + + integer = gdm_config_value_get_int (value); + if (integerp != NULL) { + *integerp = integer; + } + + gdm_config_value_free (value); + + return res; +} + +gboolean gdm_config_set_string_for_id (GdmConfig *config, int id, char *str) @@ -1276,3 +1350,22 @@ gdm_config_set_bool_for_id (GdmConfig *config, return res; } + +gboolean +gdm_config_set_int_for_id (GdmConfig *config, + int id, + int integer) +{ + GdmConfigValue *value; + gboolean res; + + g_return_val_if_fail (config != NULL, FALSE); + + value = gdm_config_value_new (GDM_CONFIG_VALUE_INT); + gdm_config_value_set_int (value, integer); + + res = gdm_config_set_value_for_id (config, id, value); + gdm_config_value_free (value); + + return res; +} diff --git a/common/gdm-config.h b/common/gdm-config.h index 554a96cb..eb3831ea 100644 --- a/common/gdm-config.h +++ b/common/gdm-config.h @@ -125,7 +125,10 @@ char ** gdm_config_get_keys_for_group (GdmConfig *confi gsize *length, GError **error); - +gboolean gdm_config_peek_value (GdmConfig *config, + const char *group, + const char *key, + const GdmConfigValue **value); gboolean gdm_config_get_value (GdmConfig *config, const char *group, const char *key, @@ -135,6 +138,7 @@ gboolean gdm_config_set_value (GdmConfig *confi const char *key, GdmConfigValue *value); +/* convenience functions */ gboolean gdm_config_get_value_for_id (GdmConfig *config, int id, GdmConfigValue **value); @@ -142,18 +146,27 @@ gboolean gdm_config_set_value_for_id (GdmConfig *confi int id, GdmConfigValue *value); +gboolean gdm_config_peek_string_for_id (GdmConfig *config, + int id, + const char **str); gboolean gdm_config_get_string_for_id (GdmConfig *config, int id, char **str); gboolean gdm_config_get_bool_for_id (GdmConfig *config, int id, gboolean *bool); +gboolean gdm_config_get_int_for_id (GdmConfig *config, + int id, + int *integer); gboolean gdm_config_set_string_for_id (GdmConfig *config, int id, char *str); gboolean gdm_config_set_bool_for_id (GdmConfig *config, int id, gboolean bool); +gboolean gdm_config_set_int_for_id (GdmConfig *config, + int id, + int integer); /* Config Values */ diff --git a/common/gdm-log.c b/common/gdm-log.c new file mode 100644 index 00000000..9182359e --- /dev/null +++ b/common/gdm-log.c @@ -0,0 +1,185 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * 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. + * + * Authors: William Jon McCann <mccann@jhu.edu> + * + */ + +#include "config.h" + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <signal.h> +#include <time.h> +#include <unistd.h> + +#include <syslog.h> + +#include <glib.h> +#include <glib/gstdio.h> + +#include "gdm-log.h" + +static gboolean initialized = FALSE; +static int syslog_levels = (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING); + +static void +log_level_to_priority_and_prefix (GLogLevelFlags log_level, + int *priorityp, + const char **prefixp) +{ + int priority; + const char *prefix; + + /* Process the message prefix and priority */ + switch (log_level & G_LOG_LEVEL_MASK) { + case G_LOG_FLAG_FATAL: + priority = LOG_EMERG; + prefix = "FATAL"; + break; + case G_LOG_LEVEL_ERROR: + priority = LOG_ERR; + prefix = "ERROR"; + break; + case G_LOG_LEVEL_CRITICAL: + priority = LOG_CRIT; + prefix = "CRITICAL"; + break; + case G_LOG_LEVEL_WARNING: + priority = LOG_WARNING; + prefix = "WARNING"; + break; + case G_LOG_LEVEL_MESSAGE: + priority = LOG_NOTICE; + prefix = "MESSAGE"; + break; + case G_LOG_LEVEL_INFO: + priority = LOG_INFO; + prefix = "INFO"; + break; + case G_LOG_LEVEL_DEBUG: + /* if debug was requested then bump this up to ERROR + * to ensure it is seen in a log */ + if (syslog_levels & G_LOG_LEVEL_DEBUG) { + priority = LOG_WARNING; + } else { + priority = LOG_DEBUG; + } + prefix = "DEBUG"; + break; + default: + priority = LOG_DEBUG; + prefix = "UNKNOWN"; + break; + } + + if (priorityp != NULL) { + *priorityp = priority; + } + if (prefixp != NULL) { + *prefixp = prefix; + } +} + +void +gdm_log_default_handler (const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, + gpointer unused_data) +{ + GString *gstring; + int priority; + const char *level_prefix; + char *string; + gboolean do_log; + gboolean is_fatal; + + is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0; + + do_log = (log_level & syslog_levels); + if (! do_log) { + return; + } + + if (! initialized) { + gdm_log_init (); + } + + log_level_to_priority_and_prefix (log_level, + &priority, + &level_prefix); + + gstring = g_string_new (NULL); + + if (log_domain != NULL) { + g_string_append (gstring, log_domain); + g_string_append_c (gstring, '-'); + } + g_string_append (gstring, level_prefix); + + g_string_append (gstring, ": "); + if (message == NULL) { + g_string_append (gstring, "(NULL) message"); + } else { + g_string_append (gstring, message); + } + if (is_fatal) { + g_string_append (gstring, "\naborting...\n"); + } else { + g_string_append (gstring, "\n"); + } + + string = g_string_free (gstring, FALSE); + + syslog (priority, "%s", string); + + g_free (string); +} + +void +gdm_log_set_debug (gboolean debug) +{ + if (debug) { + syslog_levels |= G_LOG_LEVEL_DEBUG; + } else { + syslog_levels &= ~G_LOG_LEVEL_DEBUG; + } +} + +void +gdm_log_init (void) +{ + const char *prg_name; + + g_log_set_default_handler (gdm_log_default_handler, NULL); + + prg_name = g_get_prgname (); + + openlog (prg_name, LOG_PERROR|LOG_PID, LOG_DAEMON); + + initialized = TRUE; +} + +void +gdm_log_shutdown (void) +{ + closelog (); + initialized = FALSE; +} + diff --git a/common/gdm-log.h b/common/gdm-log.h new file mode 100644 index 00000000..3d6effbc --- /dev/null +++ b/common/gdm-log.h @@ -0,0 +1,50 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * 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. + * + * Authors: William Jon McCann <mccann@jhu.edu> + * + */ + +#ifndef __GDM_LOG_H +#define __GDM_LOG_H + +#include <stdarg.h> +#include <glib.h> + +G_BEGIN_DECLS + +void gdm_log_default_handler (const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, + gpointer unused_data); +void gdm_log_set_debug (gboolean debug); +void gdm_log_init (void); +void gdm_log_shutdown (void); + +/* compatibility */ +#define gdm_fail g_critical +#define gdm_error g_warning +#define gdm_info g_message +#define gdm_debug g_debug + +#define gdm_assert g_assert +#define gdm_assert_not_reached g_assert_not_reached + +G_END_DECLS + +#endif /* __GDM_LOG_H */ diff --git a/config/gdm.conf.in b/config/gdm.conf.in index a5452148..588b5149 100644 --- a/config/gdm.conf.in +++ b/config/gdm.conf.in @@ -339,7 +339,7 @@ Enable=false #PositionY=0 # Enable the Face browser. Note that the Browser key is only used by the -# standard login (gdmlogin) program. The Face Browser is enabled in +# standard login (gdmlogin) program. The Face Browser is enabled in # the Graphical greeter by selecting a theme that includes the Face # Browser, such as happygnome-list. The other configuration values that # affect the Face Browser (MinimalUID, DefaultFace, Include, Exclude, diff --git a/configure.ac b/configure.ac index c545316a..d7c35f16 100644 --- a/configure.ac +++ b/configure.ac @@ -1135,7 +1135,7 @@ AC_ARG_WITH(pid-file, [ --with-pid-file=<file> pid file]) if ! test -z "$with_pid_file"; then GDM_PID_FILE=$with_pid_file else - GDM_PID_FILE=${LOCALSTATEDIR}/run/gdm.pid + GDM_PID_FILE=/var/run/gdm.pid fi AC_SUBST(GDM_PID_FILE) diff --git a/daemon/Makefile.am b/daemon/Makefile.am index b85fd08e..f37b09da 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -1,4 +1,4 @@ -## Process this file with automake to produce makefile.in +NULL = # Note that we have cflags for just about everything even if # we don't link to everything @@ -35,7 +35,8 @@ INCLUDES = \ # -DGNOME_DISABLE_DEPRECATED \ # -sbin_PROGRAMS = gdm-binary +sbin_PROGRAMS = gdm-binary \ + $(NULL) gdm_binary_SOURCES = \ gdm.c \ @@ -71,20 +72,27 @@ gdm_binary_SOURCES = \ gdm-net.c \ gdm-net.h \ getvt.c \ - getvt.h + getvt.h \ + $(NULL) -EXTRA_gdm_binary_SOURCES = verify-pam.c verify-crypt.c verify-shadow.c +EXTRA_gdm_binary_SOURCES = \ + verify-pam.c \ + verify-crypt.c \ + verify-shadow.c \ + $(NULL) -CONSOLE_KIT_SOURCES = \ - gdmconsolekit.c \ - gdmconsolekit.h +CONSOLE_KIT_SOURCES = \ + gdmconsolekit.c \ + gdmconsolekit.h \ + $(NULL) EXTRA_gdm_binary_SOURCES += $(CONSOLE_KIT_SOURCES) # Note that these libs are in LDFLAGS because they should come before # everything else on the link line as they may override stuff -gdm_binary_LDFLAGS = \ - $(EXTRA_DAEMON_LIBS) +gdm_binary_LDFLAGS = \ + $(EXTRA_DAEMON_LIBS) \ + $(NULL) gdm_binary_LDADD = \ $(DAEMON_LIBS) \ @@ -99,7 +107,7 @@ gdm_binary_LDADD = \ -lXau \ -lX11 \ -lXext \ - -lpopt + $(NULL) if WITH_CONSOLE_KIT gdm_binary_SOURCES += $(CONSOLE_KIT_SOURCES) diff --git a/daemon/auth.c b/daemon/auth.c index df1a8810..b9a66e6f 100644 --- a/daemon/auth.c +++ b/daemon/auth.c @@ -1,4 +1,6 @@ -/* GDM - The GNOME Display Manager +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * 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 @@ -41,6 +43,7 @@ #include "auth.h" #include "gdm-common.h" +#include "gdm-log.h" #include "gdm-daemon-config.h" /* Ensure we know about FamilyInternetV6 even if what we're compiling @@ -76,10 +79,13 @@ display_add_error (GdmDisplay *d) } static gboolean -add_auth_entry (GdmDisplay *d, +add_auth_entry (GdmDisplay *d, GSList **authlist, - FILE *af, FILE *af2, - unsigned short family, const char *addr, int addrlen) + FILE *af, + FILE *af2, + unsigned short family, + const char *addr, + int addrlen) { Xauth *xa; gchar *dispnum; @@ -168,350 +174,319 @@ add_auth_entry (GdmDisplay *d, gboolean gdm_auth_secure_display (GdmDisplay *d) { - FILE *af, *af_gdm; - int closeret; - - if G_UNLIKELY (!d) - return FALSE; - - umask (022); - - gdm_debug ("gdm_auth_secure_display: Setting up access for %s", d->name); - - g_free (d->authfile); - d->authfile = NULL; - g_free (d->authfile_gdm); - d->authfile_gdm = NULL; - - if (d->server_uid != 0) { - int authfd; - - /* Note, nested display can't use the GDM_KEY_SERV_AUTHDIR unless - * running as root, which is rare anyway. */ - - d->authfile = g_build_filename (gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHDIR_FALLBACK), ".gdmXXXXXX", NULL); - - umask (077); - authfd = g_mkstemp (d->authfile); - umask (022); - - if G_UNLIKELY (authfd == -1) { - gdm_error (_("%s: Could not make new cookie file in %s"), - "gdm_auth_secure_display", gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHDIR_FALLBACK)); - g_free (d->authfile); - d->authfile = NULL; - return FALSE; - } - - /* Make it owned by the user that nested display is started as */ - fchown (authfd, d->server_uid, -1); - - VE_IGNORE_EINTR (af = fdopen (authfd, "w")); - - if G_UNLIKELY (af == NULL) { - g_free (d->authfile); - d->authfile = NULL; - return FALSE; - } - - /* Make another authfile since the greeter can't read the server/user - * readable file */ - d->authfile_gdm = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), d->name, ".Xauth"); - af_gdm = gdm_safe_fopen_w (d->authfile_gdm); - - if G_UNLIKELY (af_gdm == NULL) { - gdm_error (_("%s: Cannot safely open %s"), - "gdm_auth_secure_display", - d->authfile_gdm); - - g_free (d->authfile_gdm); - d->authfile_gdm = NULL; - g_free (d->authfile); - d->authfile = NULL; - VE_IGNORE_EINTR (fclose (af)); - return FALSE; - } - } else { - /* gdm and xserver authfile can be the same, server will run as root */ - d->authfile = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), d->name, ".Xauth"); - af = gdm_safe_fopen_w (d->authfile); - - if G_UNLIKELY (af == NULL) { - gdm_error (_("%s: Cannot safely open %s"), - "gdm_auth_secure_display", - d->authfile); - - g_free (d->authfile); - d->authfile = NULL; - return FALSE; - } - - af_gdm = NULL; - } - - /* If this is a local display the struct hasn't changed and we - * have to eat up old authentication cookies before baking new - * ones... */ - if (SERVER_IS_LOCAL (d) && d->auths) { - gdm_auth_free_auth_list (d->auths); - d->auths = NULL; - - g_free (d->cookie); - d->cookie = NULL; - g_free (d->bcookie); - d->bcookie = NULL; - } - - /* Create new random cookie */ - gdm_cookie_generate (d); - - /* reget local host if local as it may have changed */ - if (SERVER_IS_LOCAL (d)) { - char hostname[1024]; - - hostname[1023] = '\0'; - if G_LIKELY (gethostname (hostname, 1023) == 0) { - g_free (d->hostname); - d->hostname = g_strdup (hostname); - } - } - - if ( ! add_auth_entry (d, &(d->auths), af, af_gdm, FamilyWild, NULL, 0)) - return FALSE; - - gdm_debug ("gdm_auth_secure_display: Setting up access"); - - VE_IGNORE_EINTR (closeret = fclose (af)); - if G_UNLIKELY (closeret < 0) { - display_add_error (d); - return FALSE; - } - if (af_gdm != NULL) { - VE_IGNORE_EINTR (closeret = fclose (af_gdm)); - if G_UNLIKELY (closeret < 0) { - display_add_error (d); - return FALSE; - } - } - g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE); - - if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG)) - gdm_debug ("gdm_auth_secure_display: Setting up access for %s - %d entries", - d->name, g_slist_length (d->auths)); - - return TRUE; + FILE *af, *af_gdm; + int closeret; + + if G_UNLIKELY (!d) + return FALSE; + + umask (022); + + gdm_debug ("gdm_auth_secure_display: Setting up access for %s", d->name); + + g_free (d->authfile); + d->authfile = NULL; + g_free (d->authfile_gdm); + d->authfile_gdm = NULL; + + if (d->server_uid != 0) { + int authfd; + + /* Note, nested display can't use the GDM_KEY_SERV_AUTHDIR unless + * running as root, which is rare anyway. */ + + d->authfile = g_build_filename (gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHDIR_FALLBACK), ".gdmXXXXXX", NULL); + + umask (077); + authfd = g_mkstemp (d->authfile); + umask (022); + + if G_UNLIKELY (authfd == -1) { + gdm_error (_("%s: Could not make new cookie file in %s"), + "gdm_auth_secure_display", gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHDIR_FALLBACK)); + g_free (d->authfile); + d->authfile = NULL; + return FALSE; + } + + /* Make it owned by the user that nested display is started as */ + fchown (authfd, d->server_uid, -1); + + VE_IGNORE_EINTR (af = fdopen (authfd, "w")); + + if G_UNLIKELY (af == NULL) { + g_free (d->authfile); + d->authfile = NULL; + return FALSE; + } + + /* Make another authfile since the greeter can't read the server/user + * readable file */ + d->authfile_gdm = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), d->name, ".Xauth"); + af_gdm = gdm_safe_fopen_w (d->authfile_gdm); + + if G_UNLIKELY (af_gdm == NULL) { + gdm_error (_("%s: Cannot safely open %s"), + "gdm_auth_secure_display", + d->authfile_gdm); + + g_free (d->authfile_gdm); + d->authfile_gdm = NULL; + g_free (d->authfile); + d->authfile = NULL; + VE_IGNORE_EINTR (fclose (af)); + return FALSE; + } + } else { + /* gdm and xserver authfile can be the same, server will run as root */ + d->authfile = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), d->name, ".Xauth"); + af = gdm_safe_fopen_w (d->authfile); + + if G_UNLIKELY (af == NULL) { + gdm_error (_("%s: Cannot safely open %s"), + "gdm_auth_secure_display", + d->authfile); + + g_free (d->authfile); + d->authfile = NULL; + return FALSE; + } + + af_gdm = NULL; + } + + /* If this is a local display the struct hasn't changed and we + * have to eat up old authentication cookies before baking new + * ones... */ + if (SERVER_IS_LOCAL (d) && d->auths) { + gdm_auth_free_auth_list (d->auths); + d->auths = NULL; + + g_free (d->cookie); + d->cookie = NULL; + g_free (d->bcookie); + d->bcookie = NULL; + } + + /* Create new random cookie */ + gdm_cookie_generate (d); + + /* reget local host if local as it may have changed */ + if (SERVER_IS_LOCAL (d)) { + char hostname[1024]; + + hostname[1023] = '\0'; + if G_LIKELY (gethostname (hostname, 1023) == 0) { + g_free (d->hostname); + d->hostname = g_strdup (hostname); + } + } + + if ( ! add_auth_entry (d, &(d->auths), af, af_gdm, FamilyWild, NULL, 0)) + return FALSE; + + gdm_debug ("gdm_auth_secure_display: Setting up access"); + + VE_IGNORE_EINTR (closeret = fclose (af)); + if G_UNLIKELY (closeret < 0) { + display_add_error (d); + return FALSE; + } + if (af_gdm != NULL) { + VE_IGNORE_EINTR (closeret = fclose (af_gdm)); + if G_UNLIKELY (closeret < 0) { + display_add_error (d); + return FALSE; + } + } + g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE); + + if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG)) + gdm_debug ("gdm_auth_secure_display: Setting up access for %s - %d entries", + d->name, g_slist_length (d->auths)); + + return TRUE; +} + +#define SA(__s) ((struct sockaddr *) __s) +#define SIN(__s) ((struct sockaddr_in *) __s) +#define SIN6(__s) ((struct sockaddr_in6 *) __s) + +static gboolean +add_auth_entry_for_addr (GdmDisplay *d, + GSList **authlist, + struct sockaddr_storage *ss) +{ + const char *addr; + int len; + unsigned short family; + + switch (ss->ss_family) { +#if IPV6_ENABLED + case AF_INET6: + family = FamilyInternetV6; + addr = (const char *) &SIN6 (ss)->sin6_addr; + len = sizeof (struct in6_addr); + break; +#endif + case AF_INET: + default: + family = FamilyInternet; + addr = (const char *) &SIN (ss)->sin_addr; + len = sizeof (struct in_addr); + break; + } + + return add_auth_entry (d, authlist, NULL, NULL, family, addr, len); } static GSList * get_local_auths (GdmDisplay *d) { - gboolean is_local = FALSE; - const char lo[] = {127,0,0,1}; -#ifdef ENABLE_IPV6 - const char lo6[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; -#endif - guint i; - const GList *local_addys = NULL; - gboolean added_lo = FALSE; - GSList *auths = NULL; + gboolean is_local = FALSE; + guint i; + const GList *local_addys = NULL; + gboolean added_lo = FALSE; + GSList *auths = NULL; - if G_UNLIKELY (!d) - return NULL; + if G_UNLIKELY (!d) + return NULL; - if (SERVER_IS_LOCAL (d)) { - char hostname[1024]; - - /* reget local host if local as it may have changed */ - hostname[1023] = '\0'; - if G_LIKELY (gethostname (hostname, 1023) == 0) { - g_free (d->hostname); - d->hostname = g_strdup (hostname); - } - if ( ! d->tcp_disallowed) - local_addys = gdm_peek_local_address_list (); - - is_local = TRUE; - } else { - is_local = FALSE; -#ifdef ENABLE_IPV6 - if (d->addrtype == AF_INET6) { - if (gdm_is_local_addr6 (&(d->addr6))) - is_local = TRUE; - } - else -#endif - { - if (gdm_is_local_addr (&(d->addr))) - is_local = TRUE; - } + if (SERVER_IS_LOCAL (d)) { + char hostname[1024]; - for (i = 0; ! is_local && i < d->addr_count; i++) { -#ifdef ENABLE_IPV6 - if (d->addrs[i].ss_family == AF_INET6) { - if (gdm_is_local_addr6 (&((struct sockaddr_in6 *)(&(d->addrs[i])))->sin6_addr)) { - is_local = TRUE; - break; - } - } - else -#endif - { - if (gdm_is_local_addr (&((struct sockaddr_in *)(&(d->addrs[i])))->sin_addr)) { - is_local = TRUE; - break; - } - } - } - } - - /* Local access also in case the host is very local */ - if (is_local) { - gdm_debug ("get_local_auths: Setting up socket access"); - - if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyLocal, - d->hostname, strlen (d->hostname))) - goto get_local_auth_error; - - /* local machine but not local if you get my meaning, add - * the host gotten by gethostname as well if it's different - * since the above is probably localhost */ - if ( ! SERVER_IS_LOCAL (d)) { - char hostname[1024]; - - hostname[1023] = '\0'; - if (gethostname (hostname, 1023) == 0 && - strcmp (hostname, d->hostname) != 0) { - if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyLocal, - hostname, - strlen (hostname))) - goto get_local_auth_error; - } - } else { - /* local machine, perhaps we haven't added - * localhost.localdomain to socket access */ - const char *localhost = "localhost.localdomain"; - if (strcmp (localhost, d->hostname) != 0) { - if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyLocal, - localhost, - strlen (localhost))) { - goto get_local_auth_error; - } - } - } - } - - gdm_debug ("get_local_auths: Setting up network access"); - - if ( ! SERVER_IS_LOCAL (d)) { - /* we should write out an entry for d->addr since - possibly it is not in d->addrs */ -#ifdef ENABLE_IPV6 - if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternetV6, (char *)((d->addr6).s6_addr), sizeof (struct in6_addr))) - goto get_local_auth_error; - else -#endif - if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternet, (char *)&(d->addr), sizeof (struct in_addr))) - goto get_local_auth_error; + /* reget local host if local as it may have changed */ + hostname[1023] = '\0'; + if G_LIKELY (gethostname (hostname, 1023) == 0) { + g_free (d->hostname); + d->hostname = g_strdup (hostname); + } + if ( ! d->tcp_disallowed) + local_addys = gdm_address_peek_local_list (); -#ifdef ENABLE_IPV6 - if (d->addrtype == AF_INET6 && gdm_is_loopback_addr6 (&(d->addr6))) - added_lo = TRUE; -#endif - if (d->addrtype == AF_INET && gdm_is_loopback_addr (&(d->addr))) - added_lo = TRUE; - } - - /* Network access: Write out an authentication entry for each of - * this host's official addresses */ - for (i = 0; i < d->addr_count; i++) { -#ifdef ENABLE_IPV6 - struct in6_addr *ia6; -#endif - struct in_addr *ia; + is_local = TRUE; + } else { + is_local = FALSE; -#ifdef ENABLE_IPV6 - if (d->addrs[i].ss_family == AF_INET6) { - ia6 = &(((struct sockaddr_in6 *)(&(d->addrs[i])))->sin6_addr); - if (memcmp (ia6, &(d->addr6), sizeof (struct in6_addr)) == 0) - continue; - - if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternetV6, (char *)(ia6->s6_addr), sizeof (struct in6_addr))) - goto get_local_auth_error; - - if (gdm_is_loopback_addr6 (ia6)) - added_lo = TRUE; - } - else -#endif - { - ia = &(((struct sockaddr_in *)(&(d->addrs[i])))->sin_addr); - if (memcmp (ia, &(d->addr), sizeof (struct in_addr)) == 0) - continue; - - if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternet, (char *)&ia->s_addr, sizeof (struct in_addr))) - goto get_local_auth_error; - - if (gdm_is_loopback_addr (ia)) - added_lo = TRUE; - } - } - - /* Network access: Write out an authentication entry for each of - * this host's local addresses if any */ - for (; local_addys != NULL; local_addys = local_addys->next) { - struct sockaddr *ia = (struct sockaddr *) local_addys->data; - - if (ia == NULL) - break; + if (gdm_address_is_local (&(d->addr))) { + is_local = TRUE; + } -#ifdef ENABLE_IPV6 - if (ia->sa_family == AF_INET6) { - if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternetV6, (char *)(((struct sockaddr_in6 *)ia)->sin6_addr.s6_addr), sizeof (struct in6_addr))) - goto get_local_auth_error; - - if (gdm_is_loopback_addr6 (&((struct sockaddr_in6 *)ia)->sin6_addr)) - added_lo = TRUE; - } - else -#endif - { - if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternet, (char *)&((struct sockaddr_in *)ia)->sin_addr, sizeof (struct in_addr))) - goto get_local_auth_error; + for (i = 0; ! is_local && i < d->addr_count; i++) { + if (gdm_address_is_local (&d->addrs[i])) { + is_local = TRUE; + break; + } + } + } - if (gdm_is_loopback_addr (&((struct sockaddr_in *)ia)->sin_addr)) - added_lo = TRUE; + /* Local access also in case the host is very local */ + if (is_local) { + gdm_debug ("get_local_auths: Setting up socket access"); + + if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyLocal, + d->hostname, strlen (d->hostname))) + goto get_local_auth_error; + + /* local machine but not local if you get my meaning, add + * the host gotten by gethostname as well if it's different + * since the above is probably localhost */ + if ( ! SERVER_IS_LOCAL (d)) { + char hostname[1024]; + + hostname[1023] = '\0'; + if (gethostname (hostname, 1023) == 0 && + strcmp (hostname, d->hostname) != 0) { + if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyLocal, + hostname, + strlen (hostname))) + goto get_local_auth_error; + } + } else { + /* local machine, perhaps we haven't added + * localhost.localdomain to socket access */ + const char *localhost = "localhost.localdomain"; + if (strcmp (localhost, d->hostname) != 0) { + if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyLocal, + localhost, + strlen (localhost))) { + goto get_local_auth_error; + } + } + } + } - } - } + gdm_debug ("get_local_auths: Setting up network access"); - /* if local server add loopback */ - if (SERVER_IS_LOCAL (d) && ! added_lo && ! d->tcp_disallowed) { + if ( ! SERVER_IS_LOCAL (d)) { + /* we should write out an entry for d->addr since + possibly it is not in d->addrs */ -#ifdef ENABLE_IPV6 - if (d->addrtype == AF_INET6) { - if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternetV6, lo6, sizeof (struct in6_addr))) - goto get_local_auth_error; - } - else -#endif - { - if ( ! add_auth_entry (d, &auths, NULL, NULL, FamilyInternet, lo, sizeof (struct in_addr))) - goto get_local_auth_error; - } + if (! add_auth_entry_for_addr (d, &auths, &d->addr)) { + goto get_local_auth_error; + } + + if (gdm_address_is_loopback (&(d->addr))) { + added_lo = TRUE; + } + } + + /* Network access: Write out an authentication entry for each of + * this host's official addresses */ + for (i = 0; i < d->addr_count; i++) { + struct sockaddr_storage *sa; + + sa = &d->addrs[i]; + if (gdm_address_equal (sa, &d->addr)) { + continue; + } + + if (! add_auth_entry_for_addr (d, &auths, sa)) { + goto get_local_auth_error; + } + + if (gdm_address_is_loopback (sa)) { + added_lo = TRUE; + } + } + + /* Network access: Write out an authentication entry for each of + * this host's local addresses if any */ + for (; local_addys != NULL; local_addys = local_addys->next) { + struct sockaddr_storage *ia = local_addys->data; + + if (ia == NULL) + break; - } + if (! add_auth_entry_for_addr (d, &auths, ia)) { + goto get_local_auth_error; + } + + if (gdm_address_is_loopback (ia)) { + added_lo = TRUE; + } + } + + /* if local server add loopback */ + if (SERVER_IS_LOCAL (d) && ! added_lo && ! d->tcp_disallowed) { + struct sockaddr_storage *lo_ss = NULL; + /* FIXME: get loobback ss */ + if (! add_auth_entry_for_addr (d, &auths, lo_ss)) { + goto get_local_auth_error; + } + } - if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG)) - gdm_debug ("get_local_auths: Setting up access for %s - %d entries", - d->name, g_slist_length (auths)); + if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG)) + gdm_debug ("get_local_auths: Setting up access for %s - %d entries", + d->name, g_slist_length (auths)); - return auths; + return auths; -get_local_auth_error: + get_local_auth_error: - gdm_auth_free_auth_list (auths); + gdm_auth_free_auth_list (auths); - return NULL; + return NULL; } static gboolean @@ -552,208 +527,228 @@ try_open_read_as_root (const char *file) * @d: Pointer to a GdmDisplay struct * @user: Userid of the user whose cookie file to add entries to * @homedir: The user's home directory - * + * * Remove all cookies referring to this display from user's cookie * file and append the ones specified in the display's authlist. * - * Returns TRUE on success and FALSE on error. + * Returns TRUE on success and FALSE on error. */ gboolean gdm_auth_user_add (GdmDisplay *d, uid_t user, const char *homedir) { - char *authdir; - gint authfd; - FILE *af; - GSList *auths = NULL; - const gchar *userauthdir; - const gchar *userauthfile; - gboolean ret = TRUE; - gboolean automatic_tmp_dir = FALSE; - gboolean authdir_is_tmp_dir = FALSE; - gboolean locked; - gboolean user_auth_exists; - int closeret; - - if (!d) - return FALSE; - - if (d->local_auths != NULL) { - gdm_auth_free_auth_list (d->local_auths); - d->local_auths = NULL; - } - - d->local_auths = get_local_auths (d); - - if (d->local_auths == NULL) { - gdm_error ("Can't make cookies"); - return FALSE; - } - - gdm_debug ("gdm_auth_user_add: Adding cookie for %d", user); - - userauthdir = gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHDIR); - userauthfile = gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHFILE); - - /* Determine whether UserAuthDir is specified. Otherwise ~user is used */ - if ( ! ve_string_empty (userauthdir) && - strcmp (userauthdir, "~") != 0) { - if (strncmp (userauthdir, "~/", 2) == 0) { - authdir = g_build_filename (homedir, &userauthdir[2], NULL); - } else { - authdir = g_strdup (userauthdir); - automatic_tmp_dir = TRUE; - authdir_is_tmp_dir = TRUE; - } - } else { - authdir = g_strdup (homedir); - } - -try_user_add_again: - - locked = FALSE; - - umask (077); - - if (authdir == NULL) - d->userauth = NULL; - else - d->userauth = g_build_filename (authdir, userauthfile, NULL); - - user_auth_exists = (d->userauth != NULL && - g_access (d->userauth, F_OK) == 0); - - /* Find out if the Xauthority file passes the paranoia check */ - /* Note that this is not very efficient, we stat the files over - and over, but we don't care, we don't do this too often */ - if (automatic_tmp_dir || - authdir == NULL || - - /* first the standard paranoia check (this checks the home dir - * too which is useful here) */ - ! gdm_file_check ("gdm_auth_user_add", user, authdir, userauthfile, - TRUE, FALSE, gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE), - gdm_daemon_config_get_value_int (GDM_KEY_RELAX_PERM)) || - - /* now the auth file checking routine */ - ! gdm_auth_file_check ("gdm_auth_user_add", user, d->userauth, TRUE /* absentok */, NULL) || - - /* now see if we can actually append this file */ - ! try_open_append (d->userauth) || - - /* try opening as root, if we can't open as root, - then this is a NFS mounted directory with root squashing, - and we don't want to write cookies over NFS */ - (gdm_daemon_config_get_value_bool (GDM_KEY_NEVER_PLACE_COOKIES_ON_NFS) && - ! try_open_read_as_root (d->userauth))) { - - /* if the userauth file didn't exist and we were looking at it, - it likely exists now but empty, so just whack it - (it may not exist if the file didn't exist and the directory - was of wrong permissions, but more likely this is - file on NFS dir with root-squashing enabled) */ - if ( ! user_auth_exists && d->userauth != NULL) - g_unlink (d->userauth); - - /* No go. Let's create a fallback file in GDM_KEY_USER_AUTHDIR_FALLBACK (/tmp) - * or perhaps userauthfile directory (usually would be /tmp) */ - d->authfb = TRUE; - g_free (d->userauth); - if (authdir_is_tmp_dir && authdir != NULL) - d->userauth = g_build_filename (authdir, ".gdmXXXXXX", NULL); - else - d->userauth = g_build_filename (gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHDIR_FALLBACK), ".gdmXXXXXX", NULL); - authfd = g_mkstemp (d->userauth); + char *authdir; + gint authfd; + FILE *af; + GSList *auths = NULL; + const gchar *userauthdir; + const gchar *userauthfile; + gboolean ret = TRUE; + gboolean automatic_tmp_dir = FALSE; + gboolean authdir_is_tmp_dir = FALSE; + gboolean locked; + gboolean user_auth_exists; + int closeret; + + if (!d) + return FALSE; - if G_UNLIKELY (authfd < 0 && authdir_is_tmp_dir) { - g_free (d->userauth); - d->userauth = NULL; + if (d->local_auths != NULL) { + gdm_auth_free_auth_list (d->local_auths); + d->local_auths = NULL; + } - umask (022); + d->local_auths = get_local_auths (d); - authdir_is_tmp_dir = FALSE; - goto try_user_add_again; + if (d->local_auths == NULL) { + gdm_error ("Can't make cookies"); + return FALSE; } - if G_UNLIKELY (authfd < 0) { - gdm_error (_("%s: Could not open cookie file %s"), - "gdm_auth_user_add", - d->userauth); - g_free (d->userauth); - d->userauth = NULL; + gdm_debug ("gdm_auth_user_add: Adding cookie for %d", user); - umask (022); + userauthdir = gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHDIR); + userauthfile = gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHFILE); - g_free (authdir); - return FALSE; + /* Determine whether UserAuthDir is specified. Otherwise ~user is used */ + if ( ! ve_string_empty (userauthdir) && + strcmp (userauthdir, "~") != 0) { + if (strncmp (userauthdir, "~/", 2) == 0) { + authdir = g_build_filename (homedir, &userauthdir[2], NULL); + } else { + authdir = g_strdup (userauthdir); + automatic_tmp_dir = TRUE; + authdir_is_tmp_dir = TRUE; + } + } else { + authdir = g_strdup (homedir); } - d->last_auth_touch = time (NULL); + try_user_add_again: - VE_IGNORE_EINTR (af = fdopen (authfd, "w")); - } - else { /* User's Xauthority file is ok */ - d->authfb = FALSE; + locked = FALSE; - /* FIXME: Better implement my own locking. The libXau one is not kosher */ - if G_UNLIKELY (XauLockAuth (d->userauth, 3, 3, 0) != LOCK_SUCCESS) { - gdm_error (_("%s: Could not lock cookie file %s"), - "gdm_auth_user_add", - d->userauth); - g_free (d->userauth); - d->userauth = NULL; + umask (077); - umask (022); + if (authdir == NULL) + d->userauth = NULL; + else + d->userauth = g_build_filename (authdir, userauthfile, NULL); + + user_auth_exists = (d->userauth != NULL && + g_access (d->userauth, F_OK) == 0); + + /* Find out if the Xauthority file passes the paranoia check */ + /* Note that this is not very efficient, we stat the files over + and over, but we don't care, we don't do this too often */ + if (automatic_tmp_dir || + authdir == NULL || + + /* first the standard paranoia check (this checks the home dir + * too which is useful here) */ + ! gdm_file_check ("gdm_auth_user_add", user, authdir, userauthfile, + TRUE, FALSE, gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE), + gdm_daemon_config_get_value_int (GDM_KEY_RELAX_PERM)) || + + /* now the auth file checking routine */ + ! gdm_auth_file_check ("gdm_auth_user_add", user, d->userauth, TRUE /* absentok */, NULL) || + + /* now see if we can actually append this file */ + ! try_open_append (d->userauth) || + + /* try opening as root, if we can't open as root, + then this is a NFS mounted directory with root squashing, + and we don't want to write cookies over NFS */ + (gdm_daemon_config_get_value_bool (GDM_KEY_NEVER_PLACE_COOKIES_ON_NFS) && + ! try_open_read_as_root (d->userauth))) { + + /* if the userauth file didn't exist and we were looking at it, + it likely exists now but empty, so just whack it + (it may not exist if the file didn't exist and the directory + was of wrong permissions, but more likely this is + file on NFS dir with root-squashing enabled) */ + if ( ! user_auth_exists && d->userauth != NULL) + g_unlink (d->userauth); + + /* No go. Let's create a fallback file in GDM_KEY_USER_AUTHDIR_FALLBACK (/tmp) + * or perhaps userauthfile directory (usually would be /tmp) */ + d->authfb = TRUE; + g_free (d->userauth); + if (authdir_is_tmp_dir && authdir != NULL) + d->userauth = g_build_filename (authdir, ".gdmXXXXXX", NULL); + else + d->userauth = g_build_filename (gdm_daemon_config_get_value_string (GDM_KEY_USER_AUTHDIR_FALLBACK), ".gdmXXXXXX", NULL); + authfd = g_mkstemp (d->userauth); + + if G_UNLIKELY (authfd < 0 && authdir_is_tmp_dir) { + g_free (d->userauth); + d->userauth = NULL; - automatic_tmp_dir = TRUE; - goto try_user_add_again; - } + umask (022); - locked = TRUE; + authdir_is_tmp_dir = FALSE; + goto try_user_add_again; + } - af = gdm_safe_fopen_ap (d->userauth); - } + if G_UNLIKELY (authfd < 0) { + gdm_error (_("%s: Could not open cookie file %s"), + "gdm_auth_user_add", + d->userauth); + g_free (d->userauth); + d->userauth = NULL; - /* Set to NULL, because can goto try_user_add_again. */ - g_free (authdir); - authdir = NULL; + umask (022); - if G_UNLIKELY (af == NULL) { - /* Really no need to clean up here - this process is a goner anyway */ - gdm_error (_("%s: Could not open cookie file %s"), - "gdm_auth_user_add", - d->userauth); - if (locked) - XauUnlockAuth (d->userauth); - g_free (d->userauth); - d->userauth = NULL; + g_free (authdir); + return FALSE; + } - umask (022); + d->last_auth_touch = time (NULL); + + VE_IGNORE_EINTR (af = fdopen (authfd, "w")); + } else { /* User's Xauthority file is ok */ + d->authfb = FALSE; + + /* FIXME: Better implement my own locking. The libXau one is not kosher */ + if G_UNLIKELY (XauLockAuth (d->userauth, 3, 3, 0) != LOCK_SUCCESS) { + gdm_error (_("%s: Could not lock cookie file %s"), + "gdm_auth_user_add", + d->userauth); + g_free (d->userauth); + d->userauth = NULL; + + umask (022); + + automatic_tmp_dir = TRUE; + goto try_user_add_again; + } + + locked = TRUE; + + af = gdm_safe_fopen_ap (d->userauth); + } + + /* Set to NULL, because can goto try_user_add_again. */ + g_free (authdir); + authdir = NULL; - if ( ! d->authfb) { - automatic_tmp_dir = TRUE; - goto try_user_add_again; + if G_UNLIKELY (af == NULL) { + /* Really no need to clean up here - this process is a goner anyway */ + gdm_error (_("%s: Could not open cookie file %s"), + "gdm_auth_user_add", + d->userauth); + if (locked) + XauUnlockAuth (d->userauth); + g_free (d->userauth); + d->userauth = NULL; + + umask (022); + + if ( ! d->authfb) { + automatic_tmp_dir = TRUE; + goto try_user_add_again; + } + + return FALSE; } - return FALSE; - } + gdm_debug ("gdm_auth_user_add: Using %s for cookies", d->userauth); - gdm_debug ("gdm_auth_user_add: Using %s for cookies", d->userauth); + /* If not a fallback file, nuke any existing cookies for this display */ + if (! d->authfb) + af = gdm_auth_purge (d, af, FALSE /* remove when empty */); - /* If not a fallback file, nuke any existing cookies for this display */ - if (! d->authfb) - af = gdm_auth_purge (d, af, FALSE /* remove when empty */); + /* Append the authlist for this display to the cookie file */ + auths = d->local_auths; - /* Append the authlist for this display to the cookie file */ - auths = d->local_auths; + while (auths) { + if G_UNLIKELY ( ! XauWriteAuth (af, auths->data)) { + gdm_error (_("%s: Could not write cookie"), + "gdm_auth_user_add"); + + if ( ! d->authfb) { + VE_IGNORE_EINTR (fclose (af)); + if (locked) + XauUnlockAuth (d->userauth); + g_free (d->userauth); + d->userauth = NULL; + automatic_tmp_dir = TRUE; + goto try_user_add_again; + } + + ret = FALSE; + break; + } + + auths = auths->next; + } - while (auths) { - if G_UNLIKELY ( ! XauWriteAuth (af, auths->data)) { + VE_IGNORE_EINTR (closeret = fclose (af)); + if G_UNLIKELY (closeret < 0) { gdm_error (_("%s: Could not write cookie"), "gdm_auth_user_add"); if ( ! d->authfb) { - VE_IGNORE_EINTR (fclose (af)); if (locked) XauUnlockAuth (d->userauth); g_free (d->userauth); @@ -763,36 +758,15 @@ try_user_add_again: } ret = FALSE; - break; } - auths = auths->next; - } - - VE_IGNORE_EINTR (closeret = fclose (af)); - if G_UNLIKELY (closeret < 0) { - gdm_error (_("%s: Could not write cookie"), - "gdm_auth_user_add"); - - if ( ! d->authfb) { - if (locked) - XauUnlockAuth (d->userauth); - g_free (d->userauth); - d->userauth = NULL; - automatic_tmp_dir = TRUE; - goto try_user_add_again; - } - - ret = FALSE; - } - - if (locked) - XauUnlockAuth (d->userauth); + if (locked) + XauUnlockAuth (d->userauth); - gdm_debug ("gdm_auth_user_add: Done"); + gdm_debug ("gdm_auth_user_add: Done"); - umask (022); - return ret; + umask (022); + return ret; } @@ -808,105 +782,105 @@ try_user_add_again: void gdm_auth_user_remove (GdmDisplay *d, uid_t user) { - FILE *af; - gchar *authfile; - gchar *authdir; - mode_t oldmode; + FILE *af; + gchar *authfile; + gchar *authdir; + mode_t oldmode; + + if G_UNLIKELY (!d || !d->userauth) + return; + + gdm_debug ("gdm_auth_user_remove: Removing cookie from %s (%d)", d->userauth, d->authfb); + + /* If we are using the fallback cookie location, simply nuke the + * cookie file */ + if (d->authfb) { + VE_IGNORE_EINTR (g_unlink (d->userauth)); + g_free (d->userauth); + d->userauth = NULL; + return; + } - if G_UNLIKELY (!d || !d->userauth) - return; + /* if the file doesn't exist, oh well, just ignore this then */ + if G_UNLIKELY (g_access (d->userauth, F_OK) != 0) { + g_free (d->userauth); + d->userauth = NULL; + return; + } - gdm_debug ("gdm_auth_user_remove: Removing cookie from %s (%d)", d->userauth, d->authfb); + authfile = g_path_get_basename (d->userauth); + authdir = g_path_get_dirname (d->userauth); - /* If we are using the fallback cookie location, simply nuke the - * cookie file */ - if (d->authfb) { - VE_IGNORE_EINTR (g_unlink (d->userauth)); - g_free (d->userauth); - d->userauth = NULL; - return; - } + if (ve_string_empty (authfile) || + ve_string_empty (authdir)) { + g_free (authdir); + g_free (authfile); + return; + } - /* if the file doesn't exist, oh well, just ignore this then */ - if G_UNLIKELY (g_access (d->userauth, F_OK) != 0) { - g_free (d->userauth); - d->userauth = NULL; - return; - } - - authfile = g_path_get_basename (d->userauth); - authdir = g_path_get_dirname (d->userauth); - - if (ve_string_empty (authfile) || - ve_string_empty (authdir)) { - g_free (authdir); - g_free (authfile); - return; - } - - /* Now, the cookie file could be owned by a malicious user who - * decided to concatenate something like his entire MP3 collection - * to it. So we better play it safe... */ - - if G_UNLIKELY ( ! gdm_file_check ("gdm_auth_user_remove", user, authdir, authfile, - TRUE, FALSE, gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE), - gdm_daemon_config_get_value_int (GDM_KEY_RELAX_PERM)) || - /* be even paranoider with permissions */ - ! gdm_auth_file_check ("gdm_auth_user_remove", user, d->userauth, FALSE /* absentok */, NULL)) { - g_free (authdir); - g_free (authfile); - gdm_error (_("%s: Ignoring suspiciously looking cookie file %s"), - "gdm_auth_user_remove", - d->userauth); - - return; - } - - g_free (authdir); - g_free (authfile); - - /* Lock user's cookie jar and open it for writing */ - if G_UNLIKELY (XauLockAuth (d->userauth, 3, 3, 0) != LOCK_SUCCESS) { - g_free (d->userauth); - d->userauth = NULL; - return; - } + /* Now, the cookie file could be owned by a malicious user who + * decided to concatenate something like his entire MP3 collection + * to it. So we better play it safe... */ + + if G_UNLIKELY ( ! gdm_file_check ("gdm_auth_user_remove", user, authdir, authfile, + TRUE, FALSE, gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE), + gdm_daemon_config_get_value_int (GDM_KEY_RELAX_PERM)) || + /* be even paranoider with permissions */ + ! gdm_auth_file_check ("gdm_auth_user_remove", user, d->userauth, FALSE /* absentok */, NULL)) { + g_free (authdir); + g_free (authfile); + gdm_error (_("%s: Ignoring suspiciously looking cookie file %s"), + "gdm_auth_user_remove", + d->userauth); + + return; + } - oldmode = umask (077); - af = gdm_safe_fopen_ap (d->userauth); - umask (oldmode); + g_free (authdir); + g_free (authfile); - if G_UNLIKELY (af == NULL) { - XauUnlockAuth (d->userauth); + /* Lock user's cookie jar and open it for writing */ + if G_UNLIKELY (XauLockAuth (d->userauth, 3, 3, 0) != LOCK_SUCCESS) { + g_free (d->userauth); + d->userauth = NULL; + return; + } - gdm_error (_("%s: Cannot safely open %s"), - "gdm_auth_user_remove", - d->userauth); + oldmode = umask (077); + af = gdm_safe_fopen_ap (d->userauth); + umask (oldmode); - g_free (d->userauth); - d->userauth = NULL; + if G_UNLIKELY (af == NULL) { + XauUnlockAuth (d->userauth); - return; - } + gdm_error (_("%s: Cannot safely open %s"), + "gdm_auth_user_remove", + d->userauth); - /* Purge entries for this display from the cookie jar */ - af = gdm_auth_purge (d, af, TRUE /* remove when empty */); + g_free (d->userauth); + d->userauth = NULL; - /* Close the file and unlock it */ - if (af != NULL) { - /* FIXME: what about out of diskspace errors on errors close */ - errno = 0; - VE_IGNORE_EINTR (fclose (af)); - if G_UNLIKELY (errno != 0) { - gdm_error (_("Can't write to %s: %s"), d->userauth, - strerror (errno)); - } - } + return; + } - XauUnlockAuth (d->userauth); + /* Purge entries for this display from the cookie jar */ + af = gdm_auth_purge (d, af, TRUE /* remove when empty */); - g_free (d->userauth); - d->userauth = NULL; + /* Close the file and unlock it */ + if (af != NULL) { + /* FIXME: what about out of diskspace errors on errors close */ + errno = 0; + VE_IGNORE_EINTR (fclose (af)); + if G_UNLIKELY (errno != 0) { + gdm_error (_("Can't write to %s: %s"), d->userauth, + strerror (errno)); + } + } + + XauUnlockAuth (d->userauth); + + g_free (d->userauth); + d->userauth = NULL; } static gboolean @@ -945,87 +919,89 @@ auth_same_except_data (Xauth *xa, Xauth *xb) * @d: Pointer to a GdmDisplay struct * @af: File handle to a cookie file * @remove_when_empty: remove the file when empty - * + * * Remove all cookies referring to this display a cookie file. */ static FILE * gdm_auth_purge (GdmDisplay *d, FILE *af, gboolean remove_when_empty) { - Xauth *xa; - GSList *keep = NULL, *li; - mode_t oldmode; - int cnt; - - if G_UNLIKELY (!d || !af) - return af; - - gdm_debug ("gdm_auth_purge: %s", d->name); + Xauth *xa; + GSList *keep = NULL, *li; + mode_t oldmode; + int cnt; + + if G_UNLIKELY (!d || !af) + return af; + + gdm_debug ("gdm_auth_purge: %s", d->name); + + fseek (af, 0L, SEEK_SET); + + /* Read the user's entire Xauth file into memory to avoid + * temporary file issues. Then remove any instance of this display + * in the cookie jar... */ + + cnt = 0; + + while ( (xa = XauReadAuth (af)) != NULL ) { + GSList *li; + /* We look at the current auths, but those may + have different cookies then what is in the file, + so don't compare those, but we wish to purge all + the entries that we'd normally write */ + for (li = d->local_auths; li != NULL; li = li->next) { + Xauth *xb = li->data; + if (auth_same_except_data (xa, xb)) { + XauDisposeAuth (xa); + xa = NULL; + break; + } + } + if (xa != NULL) + keep = g_slist_append (keep, xa); - fseek (af, 0L, SEEK_SET); + /* just being ultra anal */ + cnt++; + if (cnt > 500) + break; + } - /* Read the user's entire Xauth file into memory to avoid - * temporary file issues. Then remove any instance of this display - * in the cookie jar... */ + VE_IGNORE_EINTR (fclose (af)); - cnt = 0; + if (remove_when_empty && + keep == NULL) { + VE_IGNORE_EINTR (g_unlink (d->userauth)); + return NULL; + } - while ( (xa = XauReadAuth (af)) != NULL ) { - GSList *li; - /* We look at the current auths, but those may - have different cookies then what is in the file, - so don't compare those, but we wish to purge all - the entries that we'd normally write */ - for (li = d->local_auths; li != NULL; li = li->next) { - Xauth *xb = li->data; - if (auth_same_except_data (xa, xb)) { - XauDisposeAuth (xa); - xa = NULL; - break; - } + oldmode = umask (077); + af = gdm_safe_fopen_w (d->userauth); + umask (oldmode); + + /* Write out remaining entries */ + for (li = keep; li != NULL; li = li->next) { + /* FIXME: is this correct, if we can't open + * this is quite bad isn't it ... */ + if G_LIKELY (af != NULL) + XauWriteAuth (af, li->data); + /* FIXME: what about errors? */ + XauDisposeAuth (li->data); + li->data = NULL; } - if (xa != NULL) - keep = g_slist_append (keep, xa); - /* just being ultra anal */ - cnt++; - if (cnt > 500) - break; - } - - VE_IGNORE_EINTR (fclose (af)); - - if (remove_when_empty && - keep == NULL) { - VE_IGNORE_EINTR (g_unlink (d->userauth)); - return NULL; - } - - oldmode = umask (077); - af = gdm_safe_fopen_w (d->userauth); - umask (oldmode); - - /* Write out remaining entries */ - for (li = keep; li != NULL; li = li->next) { - /* FIXME: is this correct, if we can't open - * this is quite bad isn't it ... */ - if G_LIKELY (af != NULL) - XauWriteAuth (af, li->data); - /* FIXME: what about errors? */ - XauDisposeAuth (li->data); - li->data = NULL; - } - - g_slist_free (keep); - - return af; + g_slist_free (keep); + + return af; } void gdm_auth_set_local_auth (GdmDisplay *d) { - XSetAuthorization ((char *)"MIT-MAGIC-COOKIE-1", (int) strlen ("MIT-MAGIC-COOKIE-1"), - (char *)d->bcookie, (int) 16); + XSetAuthorization ((char *)"MIT-MAGIC-COOKIE-1", + (int) strlen ("MIT-MAGIC-COOKIE-1"), + (char *)d->bcookie, + (int) 16); } void @@ -1040,5 +1016,3 @@ gdm_auth_free_auth_list (GSList *list) g_slist_free (list); } - -/* EOF */ diff --git a/daemon/choose.c b/daemon/choose.c index 5ed57fa6..7779bedb 100644 --- a/daemon/choose.c +++ b/daemon/choose.c @@ -1,4 +1,6 @@ -/* GDM - The GNOME Display Manager +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * 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 @@ -22,7 +24,6 @@ #include <stdio.h> #include <stdlib.h> -#include <syslog.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/wait.h> @@ -44,8 +45,11 @@ #include "xdmcp.h" #include "gdm-common.h" +#include "gdm-log.h" #include "gdm-daemon-config.h" +#include "gdm-socket-protocol.h" + static gint ipending = 0; static GSList *indirect = NULL; @@ -76,75 +80,93 @@ remove_oldest_pending (void) } } +static gboolean +get_first_address_for_node (const char *node, + struct sockaddr_storage **sa) +{ + struct addrinfo hints; + struct addrinfo *ai_list; + struct addrinfo *ai; + int gaierr; + gboolean found; + char strport[NI_MAXSERV]; + + found = FALSE; + + memset (&hints, 0, sizeof (hints)); + hints.ai_family = AF_UNSPEC; + + snprintf (strport, sizeof (strport), "%u", XDM_UDP_PORT); + + if ((gaierr = getaddrinfo (node, strport, &hints, &ai_list)) != 0) { + g_warning ("Unable get address: %s", gai_strerror (gaierr)); + return FALSE; + } + + for (ai = ai_list; ai != NULL; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) { + continue; + } +#ifndef ENABLE_IPV6 + if (ai->ai_family == AF_INET6) { + continue; + } +#endif + found = TRUE; + break; + } + + if (ai != NULL) { + if (sa != NULL) { + *sa = g_memdup (ai->ai_addr, ai->ai_addrlen); + } + } + + freeaddrinfo (ai_list); + + return found; +} + gboolean gdm_choose_data (const char *data) { int id; - int t; - int status = 0; /* 4 for IPv4 and 6 for IPv6 */ - struct in_addr addr; -#ifdef ENABLE_IPV6 - struct in6_addr addr6; -#endif + struct sockaddr_storage *sa; GSList *li; - char *msg = g_strdup (data); + char *msg; char *p; + char *host; + gboolean ret; + + msg = g_strdup (data); + sa = NULL; + ret = FALSE; p = strtok (msg, " "); if (p == NULL || strcmp (GDM_SOP_CHOSEN, p) != 0) { - g_free (msg); - return FALSE; + goto out; } p = strtok (NULL, " "); if (p == NULL || sscanf (p, "%d", &id) != 1) { - g_free (msg); - return FALSE; + goto out; } p = strtok (NULL, " "); if (p == NULL) { - g_free (msg); - return FALSE; - } - - t = inet_pton (AF_INET, p, &addr); /* Check if address is IPv4 */ - - if (t > 0) - status = AF_INET; /* Yes, it's an IPv4 address */ - else - { - if (t == 0) { /* It might be an IPv6 one */ -#ifdef ENABLE_IPV6 - t = inet_pton (AF_INET6, p, &addr6); -#endif - if (t > 0) - status = AF_INET6; - } - } - - if (p == NULL || t <= 0) { - g_free (msg); - return FALSE; + goto out; } - g_free (msg); - - -#ifdef ENABLE_IPV6 - if (status == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; - - gdm_debug ("gdm_choose_data: got indirect id: %d address: %s", id, inet_ntop (AF_INET6, &addr6, buffer6, INET6_ADDRSTRLEN)); + if (! get_first_address_for_node (p, &sa)) { + goto out; } - else -#endif - { - char buffer[INET_ADDRSTRLEN]; - gdm_debug ("gdm_choose_data: got indirect id: %d address: %s", id, inet_ntop (AF_INET, &addr, buffer, INET_ADDRSTRLEN)); - } + gdm_address_get_info (sa, &host, NULL); + gdm_debug ("gdm_choose_data: got indirect id: %d address: %s", + id, + host); + g_free (host); for (li = indirect; li != NULL; li = li->next) { GdmIndirectDisplay *idisp = li->data; @@ -155,77 +177,56 @@ gdm_choose_data (const char *data) ; idisp->acctime = time (NULL); -#ifdef ENABLE_IPV6 - if (status == AF_INET6) { - g_free (idisp->chosen_host6); - idisp->chosen_host6 = g_new (struct in6_addr, 1); - memcpy (idisp->chosen_host6, &addr6, sizeof (struct in6_addr)); - } - else -#endif - { - g_free (idisp->chosen_host); - idisp->chosen_host = g_new (struct in_addr, 1); - memcpy (idisp->chosen_host, &addr, sizeof (struct in_addr)); - } + + g_free (idisp->chosen_host); + idisp->chosen_host = g_memdup (sa, sizeof (struct sockaddr_storage)); /* Now this display is pending */ ipending++; - return TRUE; + ret = TRUE; + break; } } + out: + g_free (sa); + g_free (msg); - return FALSE; + return ret; } GdmIndirectDisplay * -#ifdef ENABLE_IPV6 gdm_choose_indirect_alloc (struct sockaddr_storage *clnt_sa) -#else -gdm_choose_indirect_alloc (struct sockaddr_in *clnt_sa) -#endif { - GdmIndirectDisplay *id; + GdmIndirectDisplay *id; + char *host; - if (clnt_sa == NULL) - return NULL; + if (clnt_sa == NULL) + return NULL; - id = g_new0 (GdmIndirectDisplay, 1); - id->id = indirect_id++; - /* deal with a rollover, that will NEVER EVER happen, - * but I'm a paranoid bastard */ - if (id->id == 0) + id = g_new0 (GdmIndirectDisplay, 1); + id->id = indirect_id++; + /* deal with a rollover, that will NEVER EVER happen, + * but I'm a paranoid bastard */ + if (id->id == 0) id->id = indirect_id++; -#ifdef ENABLE_IPV6 - id->dsp_sa = g_new0 (struct sockaddr_storage, 1); - memcpy (id->dsp_sa, clnt_sa, sizeof (struct sockaddr_storage)); - id->chosen_host6 = NULL; -#else - id->dsp_sa = g_new0 (struct sockaddr_in, 1); - memcpy (id->dsp_sa, clnt_sa, sizeof (struct sockaddr_in)); -#endif - id->acctime = 0; - id->chosen_host = NULL; - - indirect = g_slist_prepend (indirect, id); - -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; - - gdm_debug ("gdm_choose_display_alloc: display=%s, pending=%d ", inet_ntop (AF_INET6, &(((struct sockaddr_in6 *)(id->dsp_sa))->sin6_addr), buffer6, INET6_ADDRSTRLEN), ipending); - } - else -#endif - { - char buffer[INET_ADDRSTRLEN]; - gdm_debug ("gdm_choose_display_alloc: display=%s, pending=%d ", inet_ntop (AF_INET, &((struct sockaddr_in *)(id->dsp_sa))->sin_addr, buffer, INET_ADDRSTRLEN), ipending); - } + id->dsp_sa = g_memdup (clnt_sa, sizeof (struct sockaddr_storage)); + id->chosen_host = NULL; + + id->acctime = 0; + + indirect = g_slist_prepend (indirect, id); + + gdm_address_get_info (id->dsp_sa, &host, NULL); - return (id); + gdm_debug ("gdm_choose_display_alloc: display=%s, pending=%d ", + host, + ipending); + g_free (host); + + return (id); } /* dispose of indirect display of id, if no host is set */ @@ -233,7 +234,7 @@ void gdm_choose_indirect_dispose_empty_id (guint id) { GSList *li; - + if (id == 0) return; @@ -244,188 +245,114 @@ gdm_choose_indirect_dispose_empty_id (guint id) continue; if (idisp->id == id) { - if ( -#ifdef ENABLE_IPV6 - (idisp->chosen_host6 == NULL) || -#endif - (idisp->chosen_host == NULL)) + if (idisp->chosen_host == NULL) gdm_choose_indirect_dispose (idisp); return; } } } -#ifdef ENABLE_IPV6 GdmIndirectDisplay * -gdm_choose_indirect_lookup_by_chosen6 (struct in6_addr *chosen, - struct in6_addr *origin) +gdm_choose_indirect_lookup_by_chosen (struct sockaddr_storage *chosen, + struct sockaddr_storage *origin) { GSList *li; - char buffer6[INET6_ADDRSTRLEN]; + char *host; for (li = indirect; li != NULL; li = li->next) { GdmIndirectDisplay *id = li->data; if (id != NULL && - id->chosen_host6 != NULL && - id->chosen_host6->s6_addr == chosen->s6_addr) { - - if (((struct sockaddr_in6 *)(id->dsp_sa))->sin6_addr.s6_addr == origin->s6_addr) { + id->chosen_host != NULL && + gdm_address_equal (id->chosen_host, chosen)) { + if (gdm_address_equal (id->dsp_sa, origin)) { return id; - } else if (gdm_is_loopback_addr6 (&(((struct sockaddr_in6 *)(id->dsp_sa))->sin6_addr)) && gdm_is_local_addr6 (origin)) { + } else if (gdm_address_is_loopback (id->dsp_sa) && + gdm_address_is_local (origin)) { return id; } } } - - gdm_debug ("gdm_choose_indirect_lookup_by_chosen: Chosen %s host not found", inet_ntop (AF_INET6, chosen, buffer6, INET6_ADDRSTRLEN)); - - gdm_debug ("gdm_choose_indirect_lookup_by_chosen: Origin was: %s", inet_ntop (AF_INET6, origin, buffer6, INET6_ADDRSTRLEN)); - return NULL; -} -#endif - - -GdmIndirectDisplay * -gdm_choose_indirect_lookup_by_chosen (struct in_addr *chosen, - struct in_addr *origin) -{ - GSList *li; + gdm_address_get_info (chosen, &host, NULL); - for (li = indirect; li != NULL; li = li->next) { - GdmIndirectDisplay *id = li->data; - if (id != NULL && - id->chosen_host != NULL && - id->chosen_host->s_addr == chosen->s_addr) { - if (((struct sockaddr_in *)(id->dsp_sa))->sin_addr.s_addr == origin->s_addr) { - return id; - } else if (gdm_is_loopback_addr (&(((struct sockaddr_in *)(id->dsp_sa))->sin_addr)) && - gdm_is_local_addr (origin)) { - return id; - } - } - } - gdm_debug ("gdm_choose_indirect_lookup_by_chosen: Chosen %s host not found", - inet_ntoa (*chosen)); + host); gdm_debug ("gdm_choose_indirect_lookup_by_chosen: Origin was: %s", - inet_ntoa (*origin)); + host); + g_free (host); return NULL; } GdmIndirectDisplay * -#ifdef ENABLE_IPV6 gdm_choose_indirect_lookup (struct sockaddr_storage *clnt_sa) -#else -gdm_choose_indirect_lookup (struct sockaddr_in *clnt_sa) -#endif { - GSList *li, *ilist; - GdmIndirectDisplay *id; - time_t curtime = time (NULL); - - ilist = g_slist_copy (indirect); - - for (li = ilist; li != NULL; li = li->next) { - id = (GdmIndirectDisplay *) li->data; - if (id == NULL) - continue; + GSList *li, *ilist; + GdmIndirectDisplay *id; + time_t curtime = time (NULL); + char *host; - if (id->acctime > 0 && - curtime > id->acctime + gdm_daemon_config_get_value_int (GDM_KEY_MAX_WAIT_INDIRECT)) { -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; + ilist = g_slist_copy (indirect); - gdm_debug ("gdm_choose_indirect_check: Disposing stale INDIRECT query from %s", inet_ntop (AF_INET6, &(((struct sockaddr_in6 *)clnt_sa)->sin6_addr), buffer6, INET6_ADDRSTRLEN)); - } - else -#endif - { - char buffer[INET_ADDRSTRLEN]; + for (li = ilist; li != NULL; li = li->next) { + id = (GdmIndirectDisplay *) li->data; + if (id == NULL) + continue; - gdm_debug ("gdm_choose_indirect_check: Disposing stale INDIRECT query from %s", inet_ntop (AF_INET, &((struct sockaddr_in *)clnt_sa)->sin_addr, buffer, INET_ADDRSTRLEN)); - } + if (id->acctime > 0 && + curtime > id->acctime + gdm_daemon_config_get_value_int (GDM_KEY_MAX_WAIT_INDIRECT)) { - gdm_choose_indirect_dispose (id); - continue; - } - -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - if (memcmp (((struct sockaddr_in6 *)(id->dsp_sa))->sin6_addr.s6_addr, ((struct sockaddr_in6 *)clnt_sa)->sin6_addr.s6_addr, sizeof (struct in6_addr)) == 0) { - g_slist_free (ilist); - return id; - } - } - else -#endif - { - if (((struct sockaddr_in *)(id->dsp_sa))->sin_addr.s_addr == ((struct sockaddr_in *)clnt_sa)->sin_addr.s_addr) { - g_slist_free (ilist); - return id; - } + gdm_address_get_info (clnt_sa, &host, NULL); + gdm_debug ("gdm_choose_indirect_check: Disposing stale INDIRECT query from %s", + host); + g_free (host); + + gdm_choose_indirect_dispose (id); + continue; + } + + if (gdm_address_equal (id->dsp_sa, clnt_sa)) { + g_slist_free (ilist); + return id; + } } - } - g_slist_free (ilist); - -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; - - gdm_debug ("gdm_choose_indirect_lookup: Host %s not found", inet_ntop (AF_INET6, &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, buffer6, INET6_ADDRSTRLEN)); - } - else -#endif - { - char buffer[INET_ADDRSTRLEN]; + g_slist_free (ilist); - gdm_debug ("gdm_choose_indirect_lookup: Host %s not found", inet_ntop (AF_INET, &((struct sockaddr_in *)clnt_sa)->sin_addr, buffer, INET_ADDRSTRLEN)); - } + gdm_address_get_info (clnt_sa, &host, NULL); + gdm_debug ("gdm_choose_indirect_lookup: Host %s not found", + host); + g_free (host); - return NULL; + return NULL; } void gdm_choose_indirect_dispose (GdmIndirectDisplay *id) { - if (id == NULL) - return; + char *host; - indirect = g_slist_remove (indirect, id); + if (id == NULL) + return; - if (id->acctime > 0) - ipending--; - id->acctime = 0; + indirect = g_slist_remove (indirect, id); -#ifdef ENABLE_IPV6 - if (id->dsp_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; + if (id->acctime > 0) + ipending--; + id->acctime = 0; - gdm_debug ("gdm_choose_indirect_dispose: Disposing %s", inet_ntop (AF_INET6, &(((struct sockaddr_in6 *)(id->dsp_sa))->sin6_addr), buffer6, INET6_ADDRSTRLEN)); - g_free (id->chosen_host6); - id->chosen_host6 = NULL; - } - else -#endif - { - char buffer[INET_ADDRSTRLEN]; + gdm_address_get_info (id->dsp_sa, &host, NULL); + gdm_debug ("gdm_choose_indirect_dispose: Disposing %s", + host); + g_free (host); - gdm_debug ("gdm_choose_indirect_dispose: Disposing %s", inet_ntop (AF_INET, &((struct sockaddr_in *)(id->dsp_sa))->sin_addr, -buffer, INET_ADDRSTRLEN)); - g_free (id->chosen_host); - id->chosen_host = NULL; - } + g_free (id->chosen_host); + id->chosen_host = NULL; - g_free (id->dsp_sa); - id->dsp_sa = NULL; + g_free (id->dsp_sa); + id->dsp_sa = NULL; - g_free (id); + g_free (id); } - - -/* EOF */ diff --git a/daemon/choose.h b/daemon/choose.h index 625077de..87b675f0 100644 --- a/daemon/choose.h +++ b/daemon/choose.h @@ -1,4 +1,6 @@ -/* GDM - The GNOME Display Manager +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * 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 @@ -20,18 +22,21 @@ #define CHOOSE_H #include "gdm.h" - -#ifdef ENABLE_IPV6 -GdmIndirectDisplay * gdm_choose_indirect_alloc (struct sockaddr_storage *clnt_sa); -GdmIndirectDisplay * gdm_choose_indirect_lookup (struct sockaddr_storage *clnt_sa); -GdmIndirectDisplay * gdm_choose_indirect_lookup_by_chosen6 (struct in6_addr *chosen, struct in6_addr *origin); -#else -GdmIndirectDisplay * gdm_choose_indirect_alloc (struct sockaddr_in *clnt_sa); -GdmIndirectDisplay * gdm_choose_indirect_lookup (struct sockaddr_in *clnt_sa); -#endif -GdmIndirectDisplay * gdm_choose_indirect_lookup_by_chosen (struct in_addr *chosen, - struct in_addr *origin); -void gdm_choose_indirect_dispose (GdmIndirectDisplay *id); +#include "xdmcp.h" + +typedef struct _GdmIndirectDisplay GdmIndirectDisplay; +struct _GdmIndirectDisplay { + int id; + struct sockaddr_storage* dsp_sa; + struct sockaddr_storage* chosen_host; + time_t acctime; +}; + +GdmIndirectDisplay * gdm_choose_indirect_alloc (struct sockaddr_storage *clnt_sa); +GdmIndirectDisplay * gdm_choose_indirect_lookup (struct sockaddr_storage *clnt_sa); +GdmIndirectDisplay * gdm_choose_indirect_lookup_by_chosen (struct sockaddr_storage *chosen, + struct sockaddr_storage *origin); +void gdm_choose_indirect_dispose (GdmIndirectDisplay *id); /* dispose of indirect display of id, if no host is set */ void gdm_choose_indirect_dispose_empty_id (guint id); diff --git a/daemon/cookie.c b/daemon/cookie.c index c8a0af45..2a3a17c9 100644 --- a/daemon/cookie.c +++ b/daemon/cookie.c @@ -31,7 +31,6 @@ #include <stdio.h> #include <stdlib.h> -#include <syslog.h> #include <string.h> #include <fcntl.h> #include <sys/time.h> diff --git a/daemon/cookie.h b/daemon/cookie.h index 836d7162..13cb1a89 100644 --- a/daemon/cookie.h +++ b/daemon/cookie.h @@ -20,6 +20,7 @@ #define GDM_COOKIE_H #include "gdm.h" +#include "display.h" void gdm_cookie_generate (GdmDisplay *); /* Add some more time based randomness, should be done diff --git a/daemon/display.c b/daemon/display.c index 15f9b1eb..ea374fa4 100644 --- a/daemon/display.c +++ b/daemon/display.c @@ -21,7 +21,6 @@ #include "config.h" #include <glib/gi18n.h> -#include <syslog.h> #include <signal.h> #include <sys/wait.h> #include <sys/types.h> @@ -41,18 +40,15 @@ #include "gdm-net.h" #include "gdm-common.h" +#include "gdm-log.h" #include "gdm-daemon-config.h" /* External vars */ -extern gint xdmcp_sessions; -extern gint flexi_servers; -extern gint xdmcp_pending; -extern gboolean gdm_in_final_cleanup; -extern GSList *displays; extern GdmConnection *fifoconn; extern GdmConnection *pipeconn; extern GdmConnection *unixconn; extern int slave_fifo_pipe_fd; /* the slavepipe (like fifo) connection, this is the write end */ +extern gint flexi_servers; static gboolean gdm_display_check_loop (GdmDisplay *disp) @@ -276,6 +272,8 @@ gdm_display_manage (GdmDisplay *d) d->managetime = time (NULL); + g_debug ("Forking slave process"); + /* Fork slave process */ pid = d->slavepid = fork (); @@ -306,7 +304,7 @@ gdm_display_manage (GdmDisplay *d) gdm_connection_close (unixconn); unixconn = NULL; - closelog (); + gdm_log_shutdown (); /* Close everything */ gdm_close_all_descriptors (0 /* from */, fds[0] /* except */, slave_fifo_pipe_fd /* except2 */); @@ -317,7 +315,7 @@ gdm_display_manage (GdmDisplay *d) gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */ gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */ - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_init (); d->slave_notify_fd = fds[0]; @@ -405,19 +403,17 @@ static void count_session_limits (void) { GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); + + gdm_xdmcp_recount_sessions (); - xdmcp_sessions = 0; - xdmcp_pending = 0; flexi_servers = 0; for (li = displays; li != NULL; li = li->next) { GdmDisplay *d = li->data; - if (SERVER_IS_XDMCP (d)) { - if (d->dispstat == XDMCP_MANAGED) - xdmcp_sessions++; - else if (d->dispstat == XDMCP_PENDING) - xdmcp_pending++; - } + if (SERVER_IS_FLEXI (d)) { flexi_servers++; } @@ -434,6 +430,7 @@ count_session_limits (void) void gdm_display_dispose (GdmDisplay *d) { + if (d == NULL) return; @@ -457,7 +454,7 @@ gdm_display_dispose (GdmDisplay *d) d->master_notify_fd = -1; } - displays = g_slist_remove (displays, d); + gdm_daemon_config_display_list_remove (d); d->dispstat = DISPLAY_DEAD; d->type = -1; @@ -577,6 +574,9 @@ GdmDisplay * gdm_display_lookup (pid_t pid) { GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); /* Find slave in display list */ for (li = displays; li != NULL; li = li->next) { diff --git a/daemon/display.h b/daemon/display.h index 07fa89a3..3fb281c9 100644 --- a/daemon/display.h +++ b/daemon/display.h @@ -1,4 +1,6 @@ -/* GDM - The GNOME Display Manager +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * 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 @@ -16,16 +18,199 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef GDM_DISPLAY_H -#define GDM_DISPLAY_H +#ifndef _GDM_DISPLAY_H +#define _GDM_DISPLAY_H + +#include <X11/Xlib.h> /* for Display */ +#include <X11/Xmd.h> /* for CARD32 */ +#include <netinet/in.h> /* for in_addr */ + +typedef struct _GdmDisplay GdmDisplay; + +#include "gdm-net.h" /* for GdmConnection */ + +#define TYPE_STATIC 1 /* X server defined in GDM configuration */ +#define TYPE_XDMCP 2 /* Remote display/Xserver */ +#define TYPE_FLEXI 3 /* Local Flexi X server */ +#define TYPE_FLEXI_XNEST 4 /* Local Flexi Nested server */ +#define TYPE_XDMCP_PROXY 5 /* Proxy X server for XDMCP */ + +#define SERVER_IS_LOCAL(d) ((d)->type == TYPE_STATIC || \ + (d)->type == TYPE_FLEXI || \ + (d)->type == TYPE_FLEXI_XNEST || \ + (d)->type == TYPE_XDMCP_PROXY) +#define SERVER_IS_FLEXI(d) ((d)->type == TYPE_FLEXI || \ + (d)->type == TYPE_FLEXI_XNEST || \ + (d)->type == TYPE_XDMCP_PROXY) +#define SERVER_IS_PROXY(d) ((d)->type == TYPE_FLEXI_XNEST || \ + (d)->type == TYPE_XDMCP_PROXY) +#define SERVER_IS_XDMCP(d) ((d)->type == TYPE_XDMCP || \ + (d)->type == TYPE_XDMCP_PROXY) + +/* Use this to get the right authfile name */ +#define GDM_AUTHFILE(display) \ + (display->authfile_gdm != NULL ? display->authfile_gdm : display->authfile) + +/* Values between GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST and + GDM_LOGOUT_ACTION_CUSTOM_CMD_LAST are reserved and should not be used */ +typedef enum { + GDM_LOGOUT_ACTION_NONE = 0, + GDM_LOGOUT_ACTION_HALT, + GDM_LOGOUT_ACTION_REBOOT, + GDM_LOGOUT_ACTION_SUSPEND, + GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST, + GDM_LOGOUT_ACTION_CUSTOM_CMD_LAST, + GDM_LOGOUT_ACTION_LAST +} GdmLogoutAction; + +struct _GdmDisplay +{ + + /* ALL DISPLAY TYPES */ + + guint8 type; + Display *dsp; + + gchar *name; /* value of DISPLAY */ + gchar *hostname; /* remote hostname */ + + guint8 dispstat; + guint16 dispnum; + + gboolean logged_in; /* TRUE if someone is logged in */ + char *login; + + gboolean attached; /* Display is physically attached to the machine. */ + + gboolean handled; + gboolean tcp_disallowed; + int priority; + + gboolean timed_login_ok; + + gboolean try_different_greeter; + char *theme_name; + + time_t managetime; /* time the display was managed */ + + /* loop check stuff */ + time_t last_start_time; + time_t last_loop_start_time; + gint retry_count; + int sleep_before_run; + + gchar *cookie; + gchar *bcookie; + + gchar *authfile; /* authfile for the server */ + gchar *authfile_gdm; /* authfile readable by gdm user + if necessary */ + GSList *auths; + GSList *local_auths; + gchar *userauth; + gboolean authfb; + time_t last_auth_touch; + + int screenx; + int screeny; + int screenwidth; /* Note 0 means use the gdk size */ + int screenheight; + int lrh_offsetx; /* lower right hand corner x offset */ + int lrh_offsety; /* lower right hand corner y offset */ + + pid_t slavepid; + pid_t greetpid; + pid_t sesspid; + int last_sess_status; /* status returned by last session */ + + /* Notification connection */ + int master_notify_fd; /* write part of the connection */ + int slave_notify_fd; /* read part of the connection */ + /* The xsession-errors connection */ + int xsession_errors_fd; /* write to the file */ + int session_output_fd; /* read from the session */ + int xsession_errors_bytes; +#define MAX_XSESSION_ERRORS_BYTES (80*2500) /* maximum number of bytes in + the ~/.xsession-errors file */ + char *xsession_errors_filename; /* if NULL then there is no .xsession-errors + file */ + + /* chooser stuff */ + pid_t chooserpid; + gboolean use_chooser; /* run chooser instead of greeter */ + gchar *chosen_hostname; /* locally chosen hostname if not NULL, + "-query chosen_hostname" is appened to server command line */ + int chooser_output_fd; /* from the chooser */ + char *chooser_last_line; + guint indirect_id; + + gboolean is_emergency_server; + gboolean failsafe_xserver; + + /* Only set in the main daemon as that's the only place that cares */ + GdmLogoutAction logout_action; + + + /* XDMCP TYPE */ + + time_t acctime; + + int xdmcp_dispnum; + CARD32 sessionid; + + struct sockaddr_storage addr; + struct sockaddr_storage *addrs; /* array of addresses */ + int addr_count; /* number of addresses in array */ + /* Note that the above may in fact be empty even though + addr is set, these are just extra addresses + (it could also contain addr for all we know) */ + + + /* ALL LOCAL TYPE (static, flexi) */ + + int vt; + pid_t servpid; + guint8 servstat; + gchar *command; + time_t starttime; + /* order in the Xservers file for sessreg, -1 if unset yet */ + int x_servers_order; + + + /* STATIC TYPE */ + + gboolean removeconf; /* used to mark "dynamic" static displays for removal */ + gboolean busy_display; /* only needed on static displays since flexi try another */ + time_t last_x_failed; + int x_faileds; + + + /* FLEXI TYPE */ + + char *preset_user; + uid_t server_uid; + GdmConnection *socket_conn; + + + /* PROXY/Parented TYPE (flexi-xnest or xdmcp proxy) */ + + char *parent_disp; + Display *parent_dsp; + + + /* XDMCP PROXY TYPE */ + + char *parent_auth_file; + -#include "gdm.h" + /* FLEXI XNEST TYPE */ + char *parent_temp_auth_file; +}; gboolean gdm_display_manage (GdmDisplay *d); void gdm_display_dispose (GdmDisplay *d); void gdm_display_unmanage (GdmDisplay *d); GdmDisplay *gdm_display_lookup (pid_t pid); -#endif /* GDM_DISPLAY_H */ +#endif /* _GDM_DISPLAY_H */ -/* EOF */ diff --git a/daemon/errorgui.c b/daemon/errorgui.c index b771a627..082c7770 100644 --- a/daemon/errorgui.c +++ b/daemon/errorgui.c @@ -1,4 +1,6 @@ -/* GDM - The GNOME Display Manager +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * 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 @@ -16,13 +18,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* This is the gdm slave process. gdmslave runs the chooser, greeter - * and the user's session scripts. */ - #include "config.h" +#include <stdlib.h> #include <unistd.h> -#include <syslog.h> +#include <string.h> #include <grp.h> #include <sys/types.h> #include <sys/wait.h> @@ -43,12 +43,10 @@ #include "slave.h" #include "gdm-common.h" +#include "gdm-log.h" #include "gdm-daemon-config.h" -/* set in the main function */ -extern char **stored_argv; -extern int stored_argc; -extern char *stored_path; +#include "gdm-socket-protocol.h" static int screenx = 0; static int screeny = 0; @@ -195,7 +193,7 @@ setup_dialog (GdmDisplay *d, const char *name, int closefdexcept, gboolean set_g char **argv; struct passwd *pw; - closelog (); + gdm_log_shutdown (); /* No error checking here - if it's messed the best response * is to ignore & try to continue */ @@ -217,7 +215,7 @@ setup_dialog (GdmDisplay *d, const char *name, int closefdexcept, gboolean set_g /* restore initial environment */ gdm_restoreenv (); - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_init (); g_setenv ("LOGNAME", gdm_daemon_config_get_value_string (GDM_KEY_USER), TRUE); g_setenv ("USER", gdm_daemon_config_get_value_string (GDM_KEY_USER), TRUE); @@ -301,13 +299,19 @@ dialog_failed (int status) } void -gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error, - const char *details_label, const char *details_file, - uid_t uid, gid_t gid) +gdm_errorgui_error_box_full (GdmDisplay *d, + GtkMessageType type, + const char *error, + const char *details_label, + const char *details_file, + uid_t uid, + gid_t gid) { GdkDisplay *gdk_display; pid_t pid; + g_debug ("Forking extra process: error dialog"); + pid = gdm_fork_extra (); if (pid == 0) { @@ -355,7 +359,7 @@ gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error, if (S_ISREG (s.st_mode)) { VE_IGNORE_EINTR (fp = fopen (details_file, "r")); } else { - loc = gdm_locale_to_utf8 (_("%s not a regular file!\n")); + loc = g_locale_to_utf8 (_("%s not a regular file!\n"), -1, NULL, NULL, NULL); g_string_printf (gs, loc, details_file); g_free (loc); } @@ -372,7 +376,7 @@ gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error, /* cap the lines at 500, that's already a possibility of 128k of data */ if (lines++ > 500) { - loc = gdm_locale_to_utf8 (_("\n... File too long to display ...\n")); + loc = g_locale_to_utf8 (_("\n... File too long to display ...\n"), -1, NULL, NULL, NULL); g_string_append (gs, loc); g_free (loc); break; @@ -381,7 +385,7 @@ gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error, } VE_IGNORE_EINTR (fclose (fp)); } else { - loc = gdm_locale_to_utf8 (_("%s could not be opened")); + loc = g_locale_to_utf8 (_("%s could not be opened"), -1, NULL, NULL, NULL); g_string_append_printf (gs, loc, details_file); g_free (loc); } @@ -389,7 +393,7 @@ gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error, details = g_string_free (gs, FALSE); if ( ! valid_utf8) { - char *tmp = gdm_locale_to_utf8 (details); + char *tmp = g_locale_to_utf8 (details, -1, NULL, NULL, NULL); g_free (details); details = tmp; } @@ -399,7 +403,7 @@ gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error, setup_dialog (d, "gtk-error-box", -1, TRUE, uid); - loc = gdm_locale_to_utf8 (error); + loc = g_locale_to_utf8 (error, -1, NULL, NULL, NULL); dlg = gtk_message_dialog_new (NULL /* parent */, 0 /* flags */, @@ -414,7 +418,7 @@ gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error, if (details_label != NULL) { GtkWidget *text = get_error_text_view (details); - loc = gdm_locale_to_utf8 (details_label); + loc = g_locale_to_utf8 (details_label, -1, NULL, NULL, NULL); button = gtk_check_button_new_with_label (loc); g_free (loc); @@ -475,26 +479,26 @@ gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error, _exit (0); } else if (pid > 0) { int status; - gdm_wait_for_extra (&status); + gdm_wait_for_extra (pid, &status); if (dialog_failed (status)) { if ( ! inhibit_gtk_themes) { /* on failure try again, this time without any themes which may be causing a crash */ inhibit_gtk_themes = TRUE; - gdm_error_box_full (d, type, error, details_label, details_file, uid, gid); + gdm_errorgui_error_box_full (d, type, error, details_label, details_file, uid, gid); inhibit_gtk_themes = FALSE; } else if ( ! inhibit_gtk_modules) { /* on failure try again, this time without any modules which may be causing a crash */ inhibit_gtk_modules = TRUE; - gdm_error_box_full (d, type, error, details_label, details_file, uid, gid); + gdm_errorgui_error_box_full (d, type, error, details_label, details_file, uid, gid); inhibit_gtk_modules = FALSE; } } } else { gdm_error (_("%s: Cannot fork to display error/info box"), - "gdm_error_box"); + "gdm_errorgui_error_box"); } } @@ -506,7 +510,7 @@ press_ok (GtkWidget *entry, gpointer data) } void -gdm_error_box (GdmDisplay *d, GtkMessageType type, const char *error) +gdm_errorgui_error_box (GdmDisplay *d, GtkMessageType type, const char *error) { char *msg; int id = 0; @@ -519,9 +523,9 @@ gdm_error_box (GdmDisplay *d, GtkMessageType type, const char *error) } char * -gdm_failsafe_question (GdmDisplay *d, - const char *question, - gboolean echo) +gdm_errorgui_failsafe_question (GdmDisplay *d, + const char *question, + gboolean echo) { GdkDisplay *gdk_display; pid_t pid; @@ -530,6 +534,8 @@ gdm_failsafe_question (GdmDisplay *d, if G_UNLIKELY (pipe (p) < 0) return NULL; + g_debug ("Forking extra process: failsafe question"); + pid = gdm_fork_extra (); if (pid == 0) { guint sid; @@ -538,7 +544,7 @@ gdm_failsafe_question (GdmDisplay *d, setup_dialog (d, "gtk-failsafe-question", p[1], TRUE /* set_gdm_ids */, 0); - loc = gdm_locale_to_utf8 (question); + loc = g_locale_to_utf8 (question, -1, NULL, NULL, NULL); dlg = gtk_dialog_new_with_buttons (loc, NULL /* parent */, @@ -595,7 +601,7 @@ gdm_failsafe_question (GdmDisplay *d, gtk_dialog_run (GTK_DIALOG (dlg)); - loc = gdm_locale_from_utf8 (ve_sure_string (gtk_entry_get_text (GTK_ENTRY (entry)))); + loc = g_locale_from_utf8 (ve_sure_string (gtk_entry_get_text (GTK_ENTRY (entry))), -1, NULL, NULL, NULL); gdm_fdprintf (p[1], "%s", ve_sure_string (loc)); @@ -612,7 +618,7 @@ gdm_failsafe_question (GdmDisplay *d, VE_IGNORE_EINTR (close (p[1])); - gdm_wait_for_extra (&status); + gdm_wait_for_extra (pid, &status); if (dialog_failed (status)) { char *ret = NULL; @@ -621,13 +627,13 @@ gdm_failsafe_question (GdmDisplay *d, /* on failure try again, this time without any themes which may be causing a crash */ inhibit_gtk_themes = TRUE; - ret = gdm_failsafe_question (d, question, echo); + ret = gdm_errorgui_failsafe_question (d, question, echo); inhibit_gtk_themes = FALSE; } else if ( ! inhibit_gtk_modules) { /* on failure try again, this time without any modules which may be causing a crash */ inhibit_gtk_modules = TRUE; - ret = gdm_failsafe_question (d, question, echo); + ret = gdm_errorgui_failsafe_question (d, question, echo); inhibit_gtk_modules = FALSE; } return ret; @@ -642,14 +648,14 @@ gdm_failsafe_question (GdmDisplay *d, VE_IGNORE_EINTR (close (p[0])); } else { gdm_error (_("%s: Cannot fork to display error/info box"), - "gdm_failsafe_question"); + "gdm_errorgui_failsafe_question"); } return NULL; } gboolean -gdm_failsafe_yesno (GdmDisplay *d, - const char *question) +gdm_errorgui_failsafe_yesno (GdmDisplay *d, + const char *question) { GdkDisplay *gdk_display; pid_t pid; @@ -658,6 +664,8 @@ gdm_failsafe_yesno (GdmDisplay *d, if G_UNLIKELY (pipe (p) < 0) return FALSE; + g_debug ("Forking extra process: failsafe yes/no"); + pid = gdm_fork_extra (); if (pid == 0) { guint sid; @@ -666,7 +674,7 @@ gdm_failsafe_yesno (GdmDisplay *d, setup_dialog (d, "gtk-failsafe-yesno", p[1], TRUE /* set_gdm_ids */, 0); - loc = gdm_locale_to_utf8 (question); + loc = g_locale_to_utf8 (question, -1, NULL, NULL, NULL); dlg = gtk_message_dialog_new (NULL /* parent */, 0 /* flags */, @@ -721,7 +729,7 @@ gdm_failsafe_yesno (GdmDisplay *d, VE_IGNORE_EINTR (close (p[1])); - gdm_wait_for_extra (&status); + gdm_wait_for_extra (pid, &status); if (dialog_failed (status)) { gboolean ret = FALSE; @@ -730,13 +738,13 @@ gdm_failsafe_yesno (GdmDisplay *d, /* on failure try again, this time without any themes which may be causing a crash */ inhibit_gtk_themes = TRUE; - ret = gdm_failsafe_yesno (d, question); + ret = gdm_errorgui_failsafe_yesno (d, question); inhibit_gtk_themes = FALSE; } else if ( ! inhibit_gtk_modules) { /* on failure try again, this time without any modules which may be causing a crash */ inhibit_gtk_modules = TRUE; - ret = gdm_failsafe_yesno (d, question); + ret = gdm_errorgui_failsafe_yesno (d, question); inhibit_gtk_modules = FALSE; } return ret; @@ -753,15 +761,15 @@ gdm_failsafe_yesno (GdmDisplay *d, VE_IGNORE_EINTR (close (p[0])); } else { gdm_error (_("%s: Cannot fork to display error/info box"), - "gdm_failsafe_yesno"); + "gdm_errorgui_failsafe_yesno"); } return FALSE; } int -gdm_failsafe_ask_buttons (GdmDisplay *d, - const char *question, - char **but) +gdm_errorgui_failsafe_ask_buttons (GdmDisplay *d, + const char *question, + char **but) { GdkDisplay *gdk_display; pid_t pid; @@ -770,6 +778,8 @@ gdm_failsafe_ask_buttons (GdmDisplay *d, if G_UNLIKELY (pipe (p) < 0) return -1; + g_debug ("Forking extra process: failsafe ask buttons"); + pid = gdm_fork_extra (); if (pid == 0) { int i; @@ -779,7 +789,7 @@ gdm_failsafe_ask_buttons (GdmDisplay *d, setup_dialog (d, "gtk-failsafe-ask-buttons", p[1], TRUE /* set_gdm_ids */, 0); - loc = gdm_locale_to_utf8 (question); + loc = g_locale_to_utf8 (question, -1, NULL, NULL, NULL); dlg = gtk_message_dialog_new (NULL /* parent */, 0 /* flags */, @@ -790,7 +800,7 @@ gdm_failsafe_ask_buttons (GdmDisplay *d, g_free (loc); gtk_widget_set_events (dlg, GDK_ALL_EVENTS_MASK); for (i = 0; but[i] != NULL && strcmp (but[i], "NIL"); i++) { - loc = gdm_locale_to_utf8 (but[i]); + loc = g_locale_to_utf8 (but[i], -1, NULL, NULL, NULL); gtk_dialog_add_button (GTK_DIALOG (dlg), loc, i); g_free (loc); @@ -840,7 +850,7 @@ gdm_failsafe_ask_buttons (GdmDisplay *d, VE_IGNORE_EINTR (close (p[1])); - gdm_wait_for_extra (&status); + gdm_wait_for_extra (pid, &status); if (dialog_failed (status)) { int ret = -1; @@ -849,13 +859,13 @@ gdm_failsafe_ask_buttons (GdmDisplay *d, /* on failure try again, this time without any themes which may be causing a crash */ inhibit_gtk_themes = TRUE; - ret = gdm_failsafe_ask_buttons (d, question, but); + ret = gdm_errorgui_failsafe_ask_buttons (d, question, but); inhibit_gtk_themes = FALSE; } else if ( ! inhibit_gtk_modules) { /* on failure try again, this time without any modules which may be causing a crash */ inhibit_gtk_modules = TRUE; - ret = gdm_failsafe_ask_buttons (d, question, but); + ret = gdm_errorgui_failsafe_ask_buttons (d, question, but); inhibit_gtk_modules = FALSE; } return ret; @@ -874,9 +884,7 @@ gdm_failsafe_ask_buttons (GdmDisplay *d, VE_IGNORE_EINTR (close (p[0])); } else { gdm_error (_("%s: Cannot fork to display error/info box"), - "gdm_failsafe_ask_buttons"); + "gdm_errorgui_failsafe_ask_buttons"); } return -1; } - -/* EOF */ diff --git a/daemon/errorgui.h b/daemon/errorgui.h index 65cf054b..15d245cd 100644 --- a/daemon/errorgui.h +++ b/daemon/errorgui.h @@ -22,30 +22,30 @@ #include "gdm.h" #include <gtk/gtkmessagedialog.h> -void gdm_error_box_full (GdmDisplay *d, - GtkMessageType type, - const char *error, - const char *details_label, - const char *details_file, - /* zero doesn't mean root, - we never wish to run as root, - zero means use the gdm user */ - uid_t uid, - gid_t gid); - -void gdm_error_box (GdmDisplay *d, - GtkMessageType type, - const char *error); - -char * gdm_failsafe_question (GdmDisplay *d, - const char *question, - gboolean echo); - -gboolean gdm_failsafe_yesno (GdmDisplay *d, - const char *question); -int gdm_failsafe_ask_buttons (GdmDisplay *d, - const char *question, - char **but); +void gdm_errorgui_error_box_full (GdmDisplay *d, + GtkMessageType type, + const char *error, + const char *details_label, + const char *details_file, + /* zero doesn't mean root, + we never wish to run as root, + zero means use the gdm user */ + uid_t uid, + gid_t gid); + +void gdm_errorgui_error_box (GdmDisplay *d, + GtkMessageType type, + const char *error); + +char * gdm_errorgui_failsafe_question (GdmDisplay *d, + const char *question, + gboolean echo); + +gboolean gdm_errorgui_failsafe_yesno (GdmDisplay *d, + const char *question); +int gdm_errorgui_failsafe_ask_buttons (GdmDisplay *d, + const char *question, + char **but); #endif /* GDM_ERRORGUI_H */ diff --git a/daemon/filecheck.c b/daemon/filecheck.c index 49405afe..b08ae94d 100644 --- a/daemon/filecheck.c +++ b/daemon/filecheck.c @@ -1,4 +1,6 @@ -/* GDM - The GNOME Display Manager +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * 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 @@ -19,7 +21,6 @@ #include "config.h" #include <glib/gi18n.h> -#include <syslog.h> #include <sys/stat.h> #include "gdm.h" @@ -30,7 +31,7 @@ /** * gdm_file_check: - * @caller: String to be prepended to syslog error messages. + * @caller: String to be prepended to error messages. * @user: User id for the user owning the file/dir. * @dir: Directory to be examined. * @file: File to be examined. @@ -44,171 +45,178 @@ /* we should be euid the user BTW */ gboolean -gdm_file_check (const gchar *caller, uid_t user, const gchar *dir, - const gchar *file, gboolean absentok, - gboolean absentdirok, gint maxsize, gint perms) +gdm_file_check (const gchar *caller, + uid_t user, + const gchar *dir, + const gchar *file, + gboolean absentok, + gboolean absentdirok, + gint maxsize, + gint perms) { - struct stat statbuf; - gchar *fullpath; - gchar *dirautofs; - int r; - - if (ve_string_empty (dir) || - ve_string_empty (file)) - return FALSE; - - /* Stat on automounted directory - append the '/.' to dereference mount point. - Do this only if GdmSupportAutomount is true (default is false) - 2006-09-22, Jerzy Borkowski, CAMK */ - if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_SUPPORT_AUTOMOUNT)) { - dirautofs = g_strconcat(dir, "/.", NULL); - VE_IGNORE_EINTR (r = stat (dirautofs, &statbuf)); - g_free(dirautofs); - } - /* Stat directory */ - else { - VE_IGNORE_EINTR (r = stat (dir, &statbuf)); - } - - if (r < 0) { - if ( ! absentdirok) - syslog (LOG_WARNING, _("%s: Directory %s does not exist."), - caller, dir); - return FALSE; - } - - /* Check if dir is owned by the user ... - Only, if GDM_KEY_CHECK_DIR_OWNER is true (default) - This is a "hack" for directories not owned by - the user. - 2004-06-22, Andreas Schubert, MATHEMA Software GmbH */ - - if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_CHECK_DIR_OWNER) && (statbuf.st_uid != user)) { - syslog (LOG_WARNING, _("%s: %s is not owned by uid %d."), caller, dir, user); - return FALSE; - } - - /* ... if group has write permission ... */ - if G_UNLIKELY (perms < 1 && (statbuf.st_mode & S_IWGRP) == S_IWGRP) { - syslog (LOG_WARNING, _("%s: %s is writable by group."), caller, dir); - return FALSE; - } - - /* ... and if others have write permission. */ - if G_UNLIKELY (perms < 2 && (statbuf.st_mode & S_IWOTH) == S_IWOTH) { - syslog (LOG_WARNING, _("%s: %s is writable by other."), caller, dir); - return FALSE; - } - - fullpath = g_build_filename (dir, file, NULL); - - /* Stat file */ - VE_IGNORE_EINTR (r = g_stat (fullpath, &statbuf)); - if (r < 0) { - /* Return true if file does not exist and that is ok */ - if (absentok) { - g_free (fullpath); - return TRUE; + struct stat statbuf; + gchar *fullpath; + gchar *dirautofs; + int r; + + if (ve_string_empty (dir) || + ve_string_empty (file)) + return FALSE; + + /* Stat on automounted directory - append the '/.' to dereference mount point. + Do this only if GdmSupportAutomount is true (default is false) + 2006-09-22, Jerzy Borkowski, CAMK */ + if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_SUPPORT_AUTOMOUNT)) { + dirautofs = g_strconcat(dir, "/.", NULL); + VE_IGNORE_EINTR (r = stat (dirautofs, &statbuf)); + g_free(dirautofs); } + /* Stat directory */ else { - syslog (LOG_WARNING, _("%s: %s does not exist but must exist."), caller, fullpath); - g_free (fullpath); - return FALSE; + VE_IGNORE_EINTR (r = stat (dir, &statbuf)); } - } - /* Check that it is a regular file ... */ - if G_UNLIKELY (! S_ISREG (statbuf.st_mode)) { - syslog (LOG_WARNING, _("%s: %s is not a regular file."), caller, fullpath); - g_free (fullpath); - return FALSE; - } + if (r < 0) { + if ( ! absentdirok) + g_warning (_("%s: Directory %s does not exist."), + caller, dir); + return FALSE; + } - /* ... owned by the user ... */ - if G_UNLIKELY (statbuf.st_uid != user) { - syslog (LOG_WARNING, _("%s: %s is not owned by uid %d."), caller, fullpath, user); - g_free (fullpath); - return FALSE; - } + /* Check if dir is owned by the user ... + Only, if GDM_KEY_CHECK_DIR_OWNER is true (default) + This is a "hack" for directories not owned by + the user. + 2004-06-22, Andreas Schubert, MATHEMA Software GmbH */ - /* ... unwritable by group ... */ - if G_UNLIKELY (perms < 1 && (statbuf.st_mode & S_IWGRP) == S_IWGRP) { - syslog (LOG_WARNING, _("%s: %s is writable by group."), caller, fullpath); - g_free (fullpath); - return FALSE; - } + if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_CHECK_DIR_OWNER) && (statbuf.st_uid != user)) { + g_warning (_("%s: %s is not owned by uid %d."), caller, dir, user); + return FALSE; + } - /* ... unwritable by others ... */ - if G_UNLIKELY (perms < 2 && (statbuf.st_mode & S_IWOTH) == S_IWOTH) { - syslog (LOG_WARNING, _("%s: %s is writable by group/other."), caller, fullpath); - g_free (fullpath); - return FALSE; - } + /* ... if group has write permission ... */ + if G_UNLIKELY (perms < 1 && (statbuf.st_mode & S_IWGRP) == S_IWGRP) { + g_warning (_("%s: %s is writable by group."), caller, dir); + return FALSE; + } - /* ... and smaller than sysadmin specified limit. */ - if G_UNLIKELY (maxsize && statbuf.st_size > maxsize) { - syslog (LOG_WARNING, _("%s: %s is bigger than sysadmin specified maximum file size."), - caller, fullpath); - g_free (fullpath); - return FALSE; - } + /* ... and if others have write permission. */ + if G_UNLIKELY (perms < 2 && (statbuf.st_mode & S_IWOTH) == S_IWOTH) { + g_warning (_("%s: %s is writable by other."), caller, dir); + return FALSE; + } + + fullpath = g_build_filename (dir, file, NULL); + + /* Stat file */ + VE_IGNORE_EINTR (r = g_stat (fullpath, &statbuf)); + if (r < 0) { + /* Return true if file does not exist and that is ok */ + if (absentok) { + g_free (fullpath); + return TRUE; + } + else { + g_warning (_("%s: %s does not exist but must exist."), caller, fullpath); + g_free (fullpath); + return FALSE; + } + } + + /* Check that it is a regular file ... */ + if G_UNLIKELY (! S_ISREG (statbuf.st_mode)) { + g_warning (_("%s: %s is not a regular file."), caller, fullpath); + g_free (fullpath); + return FALSE; + } + + /* ... owned by the user ... */ + if G_UNLIKELY (statbuf.st_uid != user) { + g_warning (_("%s: %s is not owned by uid %d."), caller, fullpath, user); + g_free (fullpath); + return FALSE; + } + + /* ... unwritable by group ... */ + if G_UNLIKELY (perms < 1 && (statbuf.st_mode & S_IWGRP) == S_IWGRP) { + g_warning (_("%s: %s is writable by group."), caller, fullpath); + g_free (fullpath); + return FALSE; + } - g_free (fullpath); + /* ... unwritable by others ... */ + if G_UNLIKELY (perms < 2 && (statbuf.st_mode & S_IWOTH) == S_IWOTH) { + g_warning (_("%s: %s is writable by group/other."), caller, fullpath); + g_free (fullpath); + return FALSE; + } - /* Yeap, this file is ok */ - return TRUE; + /* ... and smaller than sysadmin specified limit. */ + if G_UNLIKELY (maxsize && statbuf.st_size > maxsize) { + g_warning (_("%s: %s is bigger than sysadmin specified maximum file size."), + caller, fullpath); + g_free (fullpath); + return FALSE; + } + + g_free (fullpath); + + /* Yeap, this file is ok */ + return TRUE; } /* we should be euid the user BTW */ gboolean -gdm_auth_file_check (const gchar *caller, uid_t user, const gchar *authfile, gboolean absentok, struct stat *s) +gdm_auth_file_check (const gchar *caller, + uid_t user, + const gchar *authfile, + gboolean absentok, + struct stat *s) { - struct stat statbuf; - gint usermaxfile; - int r; - - if (ve_string_empty (authfile)) - return FALSE; - - /* Stat file */ - VE_IGNORE_EINTR (r = g_lstat (authfile, &statbuf)); - if (s != NULL) - *s = statbuf; - if (r < 0) { - if (absentok) - return TRUE; - syslog (LOG_WARNING, _("%s: %s does not exist but must exist."), caller, authfile); - return FALSE; - } - - /* Check that it is a regular file ... */ - if G_UNLIKELY (! S_ISREG (statbuf.st_mode)) { - syslog (LOG_WARNING, _("%s: %s is not a regular file."), caller, authfile); - return FALSE; - } - - /* ... owned by the user ... */ - if G_UNLIKELY (statbuf.st_uid != user) { - syslog (LOG_WARNING, _("%s: %s is not owned by uid %d."), caller, authfile, user); - return FALSE; - } - - /* ... has right permissions ... */ - if G_UNLIKELY (statbuf.st_mode & 0077) { - syslog (LOG_WARNING, "%s: %s has wrong permissions (should be 0600)", caller, authfile); - return FALSE; - } - - usermaxfile = gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE); - /* ... and smaller than sysadmin specified limit. */ - if G_UNLIKELY (usermaxfile && statbuf.st_size > usermaxfile) { - syslog (LOG_WARNING, _("%s: %s is bigger than sysadmin specified maximum file size."), - caller, authfile); - return FALSE; - } - - /* Yeap, this file is ok */ - return TRUE; -} + struct stat statbuf; + gint usermaxfile; + int r; + + if (ve_string_empty (authfile)) + return FALSE; + + /* Stat file */ + VE_IGNORE_EINTR (r = g_lstat (authfile, &statbuf)); + if (s != NULL) + *s = statbuf; + if (r < 0) { + if (absentok) + return TRUE; + g_warning (_("%s: %s does not exist but must exist."), caller, authfile); + return FALSE; + } -/* EOF */ + /* Check that it is a regular file ... */ + if G_UNLIKELY (! S_ISREG (statbuf.st_mode)) { + g_warning (_("%s: %s is not a regular file."), caller, authfile); + return FALSE; + } + + /* ... owned by the user ... */ + if G_UNLIKELY (statbuf.st_uid != user) { + g_warning (_("%s: %s is not owned by uid %d."), caller, authfile, user); + return FALSE; + } + + /* ... has right permissions ... */ + if G_UNLIKELY (statbuf.st_mode & 0077) { + g_warning ("%s: %s has wrong permissions (should be 0600)", caller, authfile); + return FALSE; + } + + usermaxfile = gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE); + /* ... and smaller than sysadmin specified limit. */ + if G_UNLIKELY (usermaxfile && statbuf.st_size > usermaxfile) { + g_warning (_("%s: %s is bigger than sysadmin specified maximum file size."), + caller, authfile); + return FALSE; + } + + /* Yeap, this file is ok */ + return TRUE; +} diff --git a/daemon/gdm-daemon-config.c b/daemon/gdm-daemon-config.c index 375c2f39..dd241e29 100644 --- a/daemon/gdm-daemon-config.c +++ b/daemon/gdm-daemon-config.c @@ -38,6 +38,7 @@ #include <unistd.h> #include <ctype.h> #include <fcntl.h> +#include <string.h> #include <sys/types.h> #include <sys/resource.h> #include <sys/stat.h> @@ -49,8 +50,6 @@ #include <glib.h> #include <glib/gi18n.h> -#include "gdm-common.h" - #include "gdm.h" #include "verify.h" #include "gdm-net.h" @@ -59,19 +58,20 @@ #include "filecheck.h" #include "slave.h" +#include "gdm-common.h" #include "gdm-config.h" +#include "gdm-log.h" #include "gdm-daemon-config.h" -static GdmConfig *daemon_config = NULL; +#include "gdm-socket-protocol.h" -extern gboolean no_console; -extern gboolean gdm_emergency_server; +static GdmConfig *daemon_config = NULL; -GSList *displays = NULL; -GSList *xservers = NULL; +static GSList *displays = NULL; +static GSList *xservers = NULL; -gint high_display_num = 0; -char *custom_config_file = NULL; +static gint high_display_num = 0; +static char *custom_config_file = NULL; static uid_t GdmUserId; /* Userid under which gdm should run */ static gid_t GdmGroupId; /* Gruopid under which gdm should run */ @@ -138,6 +138,41 @@ gdm_daemon_config_get_custom_config_file (void) } /** + * gdm_daemon_config_get_display_list + * + * Returns the list of displays being used. + */ +GSList * +gdm_daemon_config_get_display_list (void) +{ + return displays; +} + +GSList * +gdm_daemon_config_display_list_append (GdmDisplay *display) +{ + displays = g_slist_append (displays, display); + return displays; +} + +GSList * +gdm_daemon_config_display_list_insert (GdmDisplay *display) +{ + displays = g_slist_insert_sorted (displays, + display, + gdm_daemon_config_compare_displays); + return displays; +} + +GSList * +gdm_daemon_config_display_list_remove (GdmDisplay *display) +{ + displays = g_slist_remove (displays, display); + + return displays; +} + +/** * gdm_daemon_config_get_value_int * * Gets an integer configuration option by key. The option must @@ -234,10 +269,61 @@ gdm_daemon_config_get_value_string (const char *keystring) } /** + * gdm_daemon_config_get_bool_for_id + * + * Gets a boolean configuration option by ID. The option must + * first be loaded, say, by calling gdm_daemon_config_parse. + */ +gboolean +gdm_daemon_config_get_bool_for_id (int id) +{ + gboolean val; + + val = FALSE; + gdm_config_get_bool_for_id (daemon_config, id, &val); + + return val; +} + +/** + * gdm_daemon_config_get_int_for_id + * + * Gets a integer configuration option by ID. The option must + * first be loaded, say, by calling gdm_daemon_config_parse. + */ +int +gdm_daemon_config_get_int_for_id (int id) +{ + int val; + + val = -1; + gdm_config_get_int_for_id (daemon_config, id, &val); + + return val; +} + +/** + * gdm_daemon_config_get_string_for_id + * + * Gets a string configuration option by ID. The option must + * first be loaded, say, by calling gdm_daemon_config_parse. + */ +const char * +gdm_daemon_config_get_string_for_id (int id) +{ + const char *val; + + val = NULL; + gdm_config_peek_string_for_id (daemon_config, id, &val); + + return val; +} + +/** * gdm_daemon_config_get_value_bool * * Gets a boolean configuration option by key. The option must - * first be loaded, say, by calling gdm_config_parse. + * first be loaded, say, by calling gdm_daemon_config_parse. */ gboolean gdm_daemon_config_get_value_bool (const char *keystring) @@ -1684,7 +1770,8 @@ notify_cb (GdmConfig *config, } static void -handle_no_displays (GdmConfig *config) +handle_no_displays (GdmConfig *config, + gboolean no_console) { const char *server; gboolean console_notify; @@ -1712,13 +1799,17 @@ handle_no_displays (GdmConfig *config) /* yay, we can add a backup emergency server */ if (server != NULL) { + GdmDisplay *d; + int num = gdm_get_free_display (0 /* start */, 0 /* server uid */); gdm_error (_("%s: XDMCP disabled and no static servers defined. Adding %s on :%d to allow configuration!"), "gdm_config_parse", server, num); - gdm_emergency_server = TRUE; - displays = g_slist_append (displays, gdm_server_alloc (num, server)); + d = gdm_server_alloc (num, server); + d->is_emergency_server = TRUE; + + displays = g_slist_append (displays, d); /* ALWAYS run the greeter and don't log anyone in, * this is just an emergency session */ @@ -1925,7 +2016,8 @@ gdm_daemon_check_permissions (GdmConfig *config, * Loads initial configuration settings. */ void -gdm_daemon_config_parse (const char *config_file) +gdm_daemon_config_parse (const char *config_file, + gboolean no_console) { uid_t uid; gid_t gid; @@ -1975,7 +2067,7 @@ gdm_daemon_config_parse (const char *config_file) dynamic_enabled = FALSE; gdm_config_get_bool_for_id (daemon_config, GDM_ID_DYNAMIC_XSERVERS, &dynamic_enabled); if G_UNLIKELY ((displays == NULL) && (! xdmcp_enabled) && (! dynamic_enabled)) { - handle_no_displays (daemon_config); + handle_no_displays (daemon_config, no_console); } /* If no displays were found, then obviously diff --git a/daemon/gdm-daemon-config.h b/daemon/gdm-daemon-config.h index 72a4f234..24fa70a0 100644 --- a/daemon/gdm-daemon-config.h +++ b/daemon/gdm-daemon-config.h @@ -22,13 +22,33 @@ #ifndef _GDM_DAEMON_CONFIG_H #define _GDM_DAEMON_CONFIG_H +#include "server.h" #include "gdm-daemon-config-entries.h" G_BEGIN_DECLS +const char * gdm_daemon_config_get_string_for_id (int id); +gboolean gdm_daemon_config_get_bool_for_id (int id); +int gdm_daemon_config_get_int_for_id (int id); + +void gdm_daemon_config_parse (const char *config_file, + gboolean no_console); +GdmXserver * gdm_daemon_config_find_xserver (const gchar *id); +gchar * gdm_daemon_config_get_xservers (void); +GSList * gdm_daemon_config_get_display_list (void); +GSList * gdm_daemon_config_display_list_append (GdmDisplay *display); +GSList * gdm_daemon_config_display_list_insert (GdmDisplay *display); +GSList * gdm_daemon_config_display_list_remove (GdmDisplay *display); +uid_t gdm_daemon_config_get_gdmuid (void); +uid_t gdm_daemon_config_get_gdmgid (void); +gint gdm_daemon_config_get_high_display_num (void); +void gdm_daemon_config_set_high_display_num (gint val); + +/* deprecated */ gchar* gdm_daemon_config_get_display_custom_config_file (const gchar *display); gchar* gdm_daemon_config_get_custom_config_file (void); + const char* gdm_daemon_config_get_value_string (const gchar *key); gboolean gdm_daemon_config_get_value_bool (const gchar *key); gint gdm_daemon_config_get_value_int (const gchar *key); @@ -39,7 +59,6 @@ gboolean gdm_daemon_config_get_value_bool_per_display (const gchar *disp gint gdm_daemon_config_get_value_int_per_display (const gchar *display, const gchar *key); - void gdm_daemon_config_set_value_string (const gchar *key, const gchar *value); void gdm_daemon_config_set_value_bool (const gchar *key, @@ -60,15 +79,8 @@ void gdm_daemon_config_to_string (const gchar *key, gboolean gdm_daemon_config_update_key (const gchar *key); -void gdm_daemon_config_parse (const char *config_file); -GdmXserver * gdm_daemon_config_find_xserver (const gchar *id); -gchar * gdm_daemon_config_get_xservers (void); int gdm_daemon_config_compare_displays (gconstpointer a, gconstpointer b); -uid_t gdm_daemon_config_get_gdmuid (void); -uid_t gdm_daemon_config_get_gdmgid (void); -gint gdm_daemon_config_get_high_display_num (void); -void gdm_daemon_config_set_high_display_num (gint val); gboolean gdm_daemon_config_is_valid_key (const gchar *key); gboolean gdm_daemon_config_signal_terminthup_was_notified (void); diff --git a/daemon/gdm-net.c b/daemon/gdm-net.c index e3f4fc12..aa972f93 100644 --- a/daemon/gdm-net.c +++ b/daemon/gdm-net.c @@ -30,13 +30,13 @@ #include <ctype.h> #include <fcntl.h> #include <errno.h> -#include <syslog.h> #include "gdm.h" #include "misc.h" #include "gdm-net.h" #include "gdm-common.h" +#include "gdm-log.h" #include "gdm-daemon-config.h" /* diff --git a/daemon/gdm-net.h b/daemon/gdm-net.h index 68719379..901c9762 100644 --- a/daemon/gdm-net.h +++ b/daemon/gdm-net.h @@ -21,15 +21,18 @@ #include <glib.h> -#ifndef TYPEDEF_GDM_CONNECTION -#define TYPEDEF_GDM_CONNECTION typedef struct _GdmConnection GdmConnection; -#endif /* TYPEDEF_GDM_CONNECTION */ -#ifndef TYPEDEF_GDM_DISPLAY -#define TYPEDEF_GDM_DISPLAY -typedef struct _GdmDisplay GdmDisplay; -#endif /* TYPEDEF_GDM_DISPLAY */ +#include "display.h" + +/* Macros to check authentication level */ +#define GDM_CONN_AUTHENTICATED(conn) \ + ((gdm_connection_get_user_flags (conn) & GDM_SUP_FLAG_AUTHENTICATED) || \ + (gdm_connection_get_user_flags (conn) & GDM_SUP_FLAG_AUTH_GLOBAL)) + +#define GDM_CONN_AUTH_GLOBAL(conn) \ + (gdm_connection_get_user_flags (conn) & GDM_SUP_FLAG_AUTH_GLOBAL) + /* Something that will get stuff line by line */ typedef void (* GdmConnectionHandler) (GdmConnection *conn, diff --git a/daemon/gdm.c b/daemon/gdm.c index 0f5acf7a..071a37f8 100644 --- a/daemon/gdm.c +++ b/daemon/gdm.c @@ -40,7 +40,6 @@ #include <grp.h> #include <fcntl.h> #include <errno.h> -#include <syslog.h> #include <locale.h> #include <dirent.h> #include <gtk/gtk.h> @@ -68,7 +67,9 @@ #include "filecheck.h" #include "errorgui.h" +#include "gdm-socket-protocol.h" #include "gdm-daemon-config.h" +#include "gdm-log.h" #define DYNAMIC_ADD 0 #define DYNAMIC_RELEASE 1 @@ -78,8 +79,6 @@ #include <libdevinfo.h> #endif /* HAVE_LOGINDEVPERM */ -extern GSList *displays; - /* Local functions */ static void gdm_handle_message (GdmConnection *conn, const gchar *msg, @@ -105,20 +104,17 @@ static void custom_cmd_restart (long cmd_id); static void custom_cmd_no_restart (long cmd_id); /* Global vars */ -gint xdmcp_sessions = 0; /* Number of remote sessions */ -gint xdmcp_pending = 0; /* Number of pending remote sessions */ gint flexi_servers = 0; /* Number of flexi servers */ -pid_t extra_process = 0; /* An extra process. Used for quickie +static pid_t extra_process = 0; /* An extra process. Used for quickie processes, so that they also get whacked */ -int extra_status = 0; /* Last status from the last extra process */ -pid_t gdm_main_pid = 0; /* PID of the main daemon */ +static int extra_status = 0; /* Last status from the last extra process */ gboolean gdm_wait_for_go = FALSE; /* wait for a GO in the fifo */ -gboolean print_version = FALSE; /* print version number and quit */ -gboolean preserve_ld_vars = FALSE; /* Preserve the ld environment variables */ -gboolean no_daemon = FALSE; /* Do not daemonize */ -gboolean no_console = FALSE; /* There are no static servers, this means, +static gboolean print_version = FALSE; /* print version number and quit */ +static gboolean preserve_ld_vars = FALSE; /* Preserve the ld environment variables */ +static gboolean no_daemon = FALSE; /* Do not daemonize */ +static gboolean no_console = FALSE; /* There are no static servers, this means, don't run static servers and second, don't display info on the console */ @@ -130,26 +126,9 @@ int slave_fifo_pipe_fd = -1; /* the slavepipe connection */ unsigned char *gdm_global_cookie = NULL; unsigned char *gdm_global_bcookie = NULL; -gchar *gdm_charset = NULL; - -char *gdm_system_locale = NULL; - -int gdm_normal_runlevel = -1; /* runlevel on linux that gdm was started in */ - -/* True if the server that was run was in actuallity not specified in the - * config file. That is if xdmcp was disabled and no static servers were - * defined. If the user kills all his static servers by mistake and keeps - * xdmcp on. Well then he's screwed. The configurator should be smarter - * about that. But by default xdmcp is disabled so we're likely to catch - * some errors like this. */ -gboolean gdm_emergency_server = FALSE; - gboolean gdm_first_login = TRUE; -int gdm_in_signal = 0; -gboolean gdm_in_final_cleanup = FALSE; - -GdmLogoutAction safe_logout_action = GDM_LOGOUT_ACTION_NONE; +static GdmLogoutAction safe_logout_action = GDM_LOGOUT_ACTION_NONE; /* set in the main function */ gchar **stored_argv = NULL; @@ -162,7 +141,6 @@ static GMainLoop *main_loop = NULL; static gboolean monte_carlo_sqrt2 = FALSE; - /* * lookup display number if the display number is * exists then clear the remove flag and return TRUE @@ -171,7 +149,10 @@ static gboolean monte_carlo_sqrt2 = FALSE; static gboolean mark_display_exists (int num) { - GSList *li; + GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); for (li = displays; li != NULL; li = li->next) { GdmDisplay *disp = li->data; @@ -223,7 +204,6 @@ gdm_daemonify (void) exit (EXIT_SUCCESS); } - gdm_main_pid = getpid (); if G_UNLIKELY (pid < 0) gdm_fail (_("%s: fork () failed!"), "gdm_daemonify"); @@ -248,6 +228,9 @@ static void gdm_start_first_unborn_local (int delay) { GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); /* tickle the random stuff */ gdm_random_tick (); @@ -302,10 +285,11 @@ gdm_final_cleanup (void) GSList *list, *li; const char *pidfile; gboolean first; + GSList *displays; - gdm_debug ("gdm_final_cleanup"); + displays = gdm_daemon_config_get_display_list (); - gdm_in_final_cleanup = TRUE; + gdm_debug ("gdm_final_cleanup"); if (extra_process > 1) { /* we sigterm extra processes, and we @@ -395,8 +379,6 @@ gdm_final_cleanup (void) unixconn = NULL; } - closelog (); - pidfile = GDM_PID_FILE; if (pidfile != NULL) { VE_IGNORE_EINTR (g_unlink (pidfile)); @@ -497,8 +479,6 @@ deal_with_x_crashes (GdmDisplay *d) if (gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP)) gdm_xdmcp_close (); - closelog (); - gdm_close_all_descriptors (0 /* from */, -1 /* except */, -1 /* except2 */); /* No error checking here - if it's messed the best response @@ -1187,6 +1167,9 @@ static void gdm_safe_restart (void) { GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); if ( ! gdm_restart_mode) return; @@ -1231,6 +1214,9 @@ static void gdm_try_logout_action (GdmDisplay *disp) { GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); if (disp != NULL && disp->logout_action != GDM_LOGOUT_ACTION_NONE && @@ -1477,26 +1463,6 @@ ensure_desc_012 (void) } } -static void -gdm_get_our_runlevel (void) -{ -#ifdef __linux__ - /* on linux we get our current runlevel, for use later - * to detect a shutdown going on, and not mess up. */ - if (g_access ("/sbin/runlevel", X_OK) == 0) { - char ign; - int rnl; - FILE *fp = popen ("/sbin/runlevel", "r"); - if (fp != NULL) { - if (fscanf (fp, "%c %d", &ign, &rnl) == 2) { - gdm_normal_runlevel = rnl; - } - pclose (fp); - } - } -#endif /* __linux__ */ -} - /* initially if we get a TERM or INT we just want to die, but we want to also kill an extra process if it exists */ static void @@ -1558,14 +1524,11 @@ main (int argc, char *argv[]) struct sigaction sig, child, abrt; GOptionContext *ctx; const char *pidfile; - const char *charset; int i; /* semi init pseudorandomness */ gdm_random_tick (); - gdm_main_pid = getpid (); - /* We here ensure descriptors 0, 1 and 2 */ ensure_desc_012 (); @@ -1573,7 +1536,6 @@ main (int argc, char *argv[]) store_argv (argc, argv); gdm_saveenv (); gdm_get_initial_limits (); - gdm_get_our_runlevel (); bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); textdomain (GETTEXT_PACKAGE); @@ -1610,6 +1572,11 @@ main (int argc, char *argv[]) exit (0); } + gdm_log_init (); + /* Parse configuration file */ + gdm_daemon_config_parse (config_file, no_console); + gdm_log_set_debug (gdm_daemon_config_get_bool_for_id (GDM_ID_DEBUG)); + /* XDM compliant error message */ if G_UNLIKELY (getuid () != 0) { /* make sure the pid file doesn't get wiped */ @@ -1618,24 +1585,12 @@ main (int argc, char *argv[]) } main_loop = g_main_loop_new (NULL, FALSE); - openlog ("gdm", LOG_PID, LOG_DAEMON); - - if ( ! g_get_charset (&charset)) { - gdm_charset = g_strdup (charset); - } - - if (setlocale (LC_CTYPE, NULL) != NULL) { - gdm_system_locale = g_strdup (setlocale (LC_CTYPE, NULL)); - } /* initial TERM/INT handler */ sig.sa_handler = initial_term_int; sig.sa_flags = SA_RESTART; sigemptyset (&sig.sa_mask); - /* Parse configuration file */ - gdm_daemon_config_parse (config_file); - /* * Do not call gdm_fail before calling gdm_config_parse () * since the gdm_fail function uses config data @@ -1846,6 +1801,9 @@ static gboolean order_exists (int order) { GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); for (li = displays; li != NULL; li = li->next) { GdmDisplay *d = li->data; if (d->x_servers_order == order) @@ -1859,6 +1817,9 @@ get_new_order (GdmDisplay *d) { int order; GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); /* first try the position in the 'displays' list as * our order */ for (order = 0, li = displays; li != NULL; order++, li = li->next) { @@ -2269,6 +2230,9 @@ gdm_handle_message (GdmConnection *conn, const char *msg, gpointer data) if (d != NULL) { GString *resp = NULL; GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); gdm_debug ("Got QUERYLOGIN %s", p); for (li = displays; li != NULL; li = li->next) { GdmDisplay *di = li->data; @@ -2309,6 +2273,9 @@ gdm_handle_message (GdmConnection *conn, const char *msg, gpointer data) long slave_pid; char *p; GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); if (sscanf (msg, GDM_SOP_MIGRATE " %ld", &slave_pid) != 1) return; @@ -2459,12 +2426,18 @@ gdm_handle_message (GdmConnection *conn, const char *msg, gpointer data) gdm_safe_restart (); } else if (strcmp (msg, GDM_SOP_DIRTY_SERVERS) == 0) { GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); for (li = displays; li != NULL; li = li->next) { GdmDisplay *d = li->data; send_slave_command (d, GDM_NOTIFY_DIRTY_SERVERS); } } else if (strcmp (msg, GDM_SOP_SOFT_RESTART_SERVERS) == 0) { GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); for (li = displays; li != NULL; li = li->next) { GdmDisplay *d = li->data; send_slave_command (d, GDM_NOTIFY_SOFT_RESTART_SERVERS); @@ -2492,12 +2465,16 @@ gdm_handle_message (GdmConnection *conn, const char *msg, gpointer data) return; p++; - syslog (type, "(child %ld) %s", pid, p); + /* FIXME: use g_critical or g_debug when required */ + g_warning ("(child %ld) %s", pid, p); } else if (strcmp (msg, GDM_SOP_START_NEXT_LOCAL) == 0) { gdm_start_first_unborn_local (3 /* delay */); } else if (strcmp (msg, GDM_SOP_HUP_ALL_GREETERS) == 0) { /* probably shouldn't be done too often */ GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); for (li = displays; li != NULL; li = li->next) { GdmDisplay *d = li->data; if (d->greetpid > 1) @@ -2508,6 +2485,9 @@ gdm_handle_message (GdmConnection *conn, const char *msg, gpointer data) } else if (strcmp (msg, GDM_SOP_GO) == 0) { GSList *li; gboolean old_wait = gdm_wait_for_go; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); gdm_wait_for_go = FALSE; for (li = displays; li != NULL; li = li->next) { GdmDisplay *d = li->data; @@ -2648,7 +2628,8 @@ gdm_handle_message (GdmConnection *conn, const char *msg, gpointer data) VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0644)); } - gdm_error_box_full (d, type, error, details_label, details_file, 0, 0); + /* FIXME: this is really bad */ + gdm_errorgui_error_box_full (d, type, error, details_label, details_file, 0, 0); if (GDM_AUTHFILE (d)) { VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0640)); @@ -2685,7 +2666,7 @@ gdm_handle_message (GdmConnection *conn, const char *msg, gpointer data) VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0644)); } - response_yesno = gdm_failsafe_yesno (d, yesno_msg); + response_yesno = gdm_errorgui_failsafe_yesno (d, yesno_msg); send_slave_ack_dialog_int (d, GDM_SLAVE_NOTIFY_YESNO_RESPONSE, response_yesno); @@ -2724,7 +2705,7 @@ gdm_handle_message (GdmConnection *conn, const char *msg, gpointer data) VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0644)); } - response_question = gdm_failsafe_question (d, question_msg, echo); + response_question = gdm_errorgui_failsafe_question (d, question_msg, echo); send_slave_ack_dialog_char (d, GDM_SLAVE_NOTIFY_QUESTION_RESPONSE, response_question); @@ -2777,7 +2758,7 @@ gdm_handle_message (GdmConnection *conn, const char *msg, gpointer data) VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0644)); } - response_askbuttons = gdm_failsafe_ask_buttons (d, askbuttons_msg, options); + response_askbuttons = gdm_errorgui_failsafe_ask_buttons (d, askbuttons_msg, options); send_slave_ack_dialog_int (d, GDM_SLAVE_NOTIFY_ASKBUTTONS_RESPONSE, response_askbuttons); if (GDM_AUTHFILE (d)) { @@ -2887,6 +2868,9 @@ static GdmDisplay * find_display (const char *name) { GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); for (li = displays; li != NULL; li = li->next) { GdmDisplay *disp = li->data; @@ -2996,10 +2980,13 @@ check_cookie (const gchar *file, const gchar *disp, const gchar *cookie) } static void -handle_flexi_server (GdmConnection *conn, int type, const gchar *server, +handle_flexi_server (GdmConnection *conn, + int type, + const gchar *server, gboolean handled, gboolean chooser, - const gchar *xnest_disp, uid_t xnest_uid, + const gchar *xnest_disp, + uid_t xnest_uid, const gchar *xnest_auth_file, const gchar *xnest_cookie, const gchar *username) @@ -3141,7 +3128,8 @@ handle_flexi_server (GdmConnection *conn, int type, const gchar *server, display->parent_auth_file = g_strdup (xnest_auth_file); if (conn != NULL) gdm_connection_set_close_notify (conn, display, close_conn); - displays = g_slist_append (displays, display); + gdm_daemon_config_display_list_append (display); + if ( ! gdm_display_manage (display)) { gdm_display_unmanage (display); if (conn != NULL) @@ -3205,9 +3193,8 @@ handle_dynamic_server (GdmConnection *conn, int type, gchar *key) gdm_connection_write (conn, "ERROR 4 Display startup failure\n"); return; } - displays = g_slist_insert_sorted (displays, - disp, - gdm_daemon_config_compare_displays); + + gdm_daemon_config_display_list_insert (disp); disp->dispstat = DISPLAY_CONFIG; disp->removeconf = FALSE; @@ -3222,6 +3209,10 @@ handle_dynamic_server (GdmConnection *conn, int type, gchar *key) if (type == DYNAMIC_REMOVE) { GSList *li; GSList *nli; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); + /* shutdown a dynamic X server */ for (li = displays; li != NULL; li = nli) { @@ -3245,6 +3236,9 @@ handle_dynamic_server (GdmConnection *conn, int type, gchar *key) GSList *li; GSList *nli; gboolean found = FALSE; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); for (li = displays; li != NULL; li = nli) { GdmDisplay *disp = li->data; @@ -3273,7 +3267,9 @@ handle_dynamic_server (GdmConnection *conn, int type, gchar *key) } static void -gdm_handle_user_message (GdmConnection *conn, const gchar *msg, gpointer data) +gdm_handle_user_message (GdmConnection *conn, + const gchar *msg, + gpointer data) { gint i; gboolean has_user; @@ -3292,6 +3288,10 @@ gdm_handle_user_message (GdmConnection *conn, const gchar *msg, gpointer data) GSList *li; gchar *cookie = g_strdup (&msg[strlen (GDM_SUP_AUTH_LOCAL " ")]); + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); + g_strstrip (cookie); if (strlen (cookie) != 16*2) /* 16 bytes in hex form */ { /* evil, just whack the connection in this case */ @@ -3467,6 +3467,9 @@ gdm_handle_user_message (GdmConnection *conn, const gchar *msg, gpointer data) const gchar *sep = " "; char *key; int msgLen=0; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); if (strncmp (msg, GDM_SUP_ATTACHED_SERVERS, strlen (GDM_SUP_ATTACHED_SERVERS)) == 0) @@ -3505,6 +3508,9 @@ gdm_handle_user_message (GdmConnection *conn, const gchar *msg, gpointer data) GString *msg; GSList *li; const gchar *sep = " "; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); msg = g_string_new ("OK"); for (li = displays; li != NULL; li = li->next) { @@ -3578,6 +3584,9 @@ gdm_handle_user_message (GdmConnection *conn, const gchar *msg, gpointer data) GString *msg; GSList *li; const gchar *sep = " "; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); msg = g_string_new ("OK"); for (li = displays; li != NULL; li = li->next) { @@ -3961,6 +3970,9 @@ gdm_handle_user_message (GdmConnection *conn, const gchar *msg, gpointer data) strlen (GDM_SUP_SET_VT " ")) == 0) { int vt; GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); if (sscanf (msg, GDM_SUP_SET_VT " %d", &vt) != 1 || vt < 0) { @@ -4034,4 +4046,3 @@ gdm_handle_user_message (GdmConnection *conn, const gchar *msg, gpointer data) } } -/* EOF */ diff --git a/daemon/gdm.h b/daemon/gdm.h index 00529a9a..e13e4185 100644 --- a/daemon/gdm.h +++ b/daemon/gdm.h @@ -21,47 +21,9 @@ #ifndef GDM_H #define GDM_H -#include <glib.h> -#include <glib/gstdio.h> -#include <X11/Xlib.h> -#include <X11/Xmd.h> -#include <X11/Xauth.h> -#include <netinet/in.h> -#include <time.h> - #define GDM_MAX_PASS 256 /* Define a value for password length. Glibc * leaves MAX_PASS undefined. */ -#define STX 0x2 /* Start of txt */ -#define BEL 0x7 /* Bell, used to interrupt login for - * say timed login or something similar */ - -#define TYPE_STATIC 1 /* X server defined in GDM configuration */ -#define TYPE_XDMCP 2 /* Remote display/Xserver */ -#define TYPE_FLEXI 3 /* Local Flexi X server */ -#define TYPE_FLEXI_XNEST 4 /* Local Flexi Nested server */ -#define TYPE_XDMCP_PROXY 5 /* Proxy X server for XDMCP */ - -#define SERVER_IS_LOCAL(d) ((d)->type == TYPE_STATIC || \ - (d)->type == TYPE_FLEXI || \ - (d)->type == TYPE_FLEXI_XNEST || \ - (d)->type == TYPE_XDMCP_PROXY) -#define SERVER_IS_FLEXI(d) ((d)->type == TYPE_FLEXI || \ - (d)->type == TYPE_FLEXI_XNEST || \ - (d)->type == TYPE_XDMCP_PROXY) -#define SERVER_IS_PROXY(d) ((d)->type == TYPE_FLEXI_XNEST || \ - (d)->type == TYPE_XDMCP_PROXY) -#define SERVER_IS_XDMCP(d) ((d)->type == TYPE_XDMCP || \ - (d)->type == TYPE_XDMCP_PROXY) - -/* These are the servstat values, also used as server - * process exit codes */ -#define SERVER_TIMEOUT 2 /* Server didn't start */ -#define SERVER_DEAD 250 /* Server stopped */ -#define SERVER_PENDING 251 /* Server started but not ready for connections yet */ -#define SERVER_RUNNING 252 /* Server running and ready for connections */ -#define SERVER_ABORT 253 /* Server failed badly. Suspending display. */ - /* DO NOTE USE 1, that's used as error if x connection fails usually */ /* Note that there is no reason why these were a power of two, and note * that they have to fit in 256 */ @@ -88,59 +50,7 @@ enum { DISPLAY_CONFIG /* in process of being configured */ }; -/* Opcodes for the highly sophisticated protocol used for - * daemon<->greeter communications */ - -/* This will change if there are incompatible - * protocol changes */ -#define GDM_GREETER_PROTOCOL_VERSION "3" - -#define GDM_MSG 'D' -#define GDM_NOECHO 'U' -#define GDM_PROMPT 'N' -#define GDM_SESS 'G' -#define GDM_LANG '&' -#define GDM_SSESS 'C' -#define GDM_SLANG 'R' -#define GDM_SETLANG 'L' -#define GDM_RESET 'A' -#define GDM_QUIT 'P' -/* Well these aren't as nice as above, oh well */ -#define GDM_STARTTIMER 's' -#define GDM_STOPTIMER 'S' -#define GDM_SETLOGIN 'l' /* this just sets the login to be this, just for - the greeters knowledge */ -#define GDM_DISABLE '-' /* disable the login screen */ -#define GDM_ENABLE '+' /* enable the login screen */ -#define GDM_RESETOK 'r' /* reset but don't shake */ -#define GDM_NEEDPIC '#' /* need a user picture?, sent after greeter - * is started */ -#define GDM_READPIC '%' /* Send a user picture in a temp file */ -#define GDM_ERRBOX 'e' /* Puts string in the error box */ -#define GDM_ERRDLG 'E' /* Puts string up in an error dialog */ -#define GDM_NOFOCUS 'f' /* Don't focus the login window (optional) */ -#define GDM_FOCUS 'F' /* Allow focus on the login window again (optional) */ -#define GDM_SAVEDIE '!' /* Save wm order and die (and set busy cursor) */ -#define GDM_QUERY_CAPSLOCK 'Q' /* Is capslock on? */ -#define GDM_ALWAYS_RESTART 'W' /* Retart greeter when the user accepts restarts */ - -/* Different login interruptions */ -#define GDM_INTERRUPT_TIMED_LOGIN 'T' -#define GDM_INTERRUPT_CONFIGURE 'C' -#define GDM_INTERRUPT_SUSPEND 'S' -#define GDM_INTERRUPT_SELECT_USER 'U' -#define GDM_INTERRUPT_LOGIN_SOUND 'L' -#define GDM_INTERRUPT_THEME 'H' -#define GDM_INTERRUPT_CUSTOM_CMD 'M' -#define GDM_INTERRUPT_CANCEL 'X' -#define GDM_INTERRUPT_SELECT_LANG 'O' - -/* List delimiter for config file lists */ -#define GDM_DELIMITER_MODULES ":" -#define GDM_DELIMITER_THEMES "/:" - /* The dreaded miscellaneous category */ -#define FIELD_SIZE 256 #define PIPE_SIZE 4096 /* @@ -170,977 +80,15 @@ enum { #define GDM_RESPONSE_CANCEL "GDM_RESPONSE_CANCEL" -#ifndef TYPEDEF_GDM_CONNECTION -#define TYPEDEF_GDM_CONNECTION -typedef struct _GdmConnection GdmConnection; -#endif /* TYPEDEF_GDM_CONNECTION */ - -#ifndef TYPEDEF_GDM_CUSTOM_CMD -#define TYPEDEF_GDM_CUSTOM_CMD -typedef struct _GdmCustomCmd GdmCustomCmd; -#endif /* TYPEDEF_GDM_CUSTOM_CMD */ -struct _GdmCustomCmd { - gchar *command; /* command(s) to execute */ - gchar *command_label; /* button/menu item label */ - gchar *command_lr_label; /* radio button/list item label */ - gchar *command_text; /* warning dialog text */ - gchar *command_tooltip; /* tooltip string */ - gboolean command_no_restart; /* no restart flag */ - gboolean command_is_persistent; /* persistence flag */ -}; - #define GDM_CUSTOM_COMMAND_MAX 10 /* maximum number of supported custom commands */ -/* Values between GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST and - GDM_LOGOUT_ACTION_CUSTOM_CMD_LAST are reserved and should not be used */ -typedef enum { - GDM_LOGOUT_ACTION_NONE = 0, - GDM_LOGOUT_ACTION_HALT, - GDM_LOGOUT_ACTION_REBOOT, - GDM_LOGOUT_ACTION_SUSPEND, - GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST, - GDM_LOGOUT_ACTION_CUSTOM_CMD_LAST = GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST + GDM_CUSTOM_COMMAND_MAX - 1, - GDM_LOGOUT_ACTION_LAST -} GdmLogoutAction; - -#ifndef TYPEDEF_GDM_DISPLAY -#define TYPEDEF_GDM_DISPLAY -typedef struct _GdmDisplay GdmDisplay; -#endif /* TYPEDEF_GDM_DISPLAY */ - -/* Use this to get the right authfile name */ -#define GDM_AUTHFILE(display) \ - (display->authfile_gdm != NULL ? display->authfile_gdm : display->authfile) - #ifdef sun #define SDTLOGIN_DIR "/var/dt/sdtlogin" #endif -struct _GdmDisplay { - CARD32 sessionid; - Display *dsp; - gchar *authfile; /* authfile for the server */ - gchar *authfile_gdm; /* authfile readable by gdm user - if necessary */ - GSList *auths; - GSList *local_auths; - gchar *userauth; - gboolean authfb; - time_t last_auth_touch; - gchar *command; - gboolean failsafe_xserver; - gboolean use_chooser; /* run chooser instead of greeter */ - gchar *chosen_hostname; /* locally chosen hostname if not NULL, - "-query chosen_hostname" is appened to server command line */ - guint indirect_id; - gchar *cookie; - gchar *bcookie; - gchar *name; - gchar *hostname; - struct in_addr addr; -#ifdef ENABLE_IPV6 - struct in6_addr addr6; - struct sockaddr_storage *addrs; /* array of addresses */ -#else - struct in_addr *addrs; /* array of addresses */ -#endif - int addrtype; /* Specifying the variable used, addr or addr6 */ - int addr_count; /* number of addresses in array */ - /* Note that the above may in fact be empty even though - addr is set, these are just extra addresses - (it could also contain addr for all we know) */ - - guint8 dispstat; - guint16 dispnum; - gboolean removeconf; - guint8 servstat; - time_t starttime; - time_t managetime; - guint8 type; - pid_t greetpid; - pid_t servpid; - pid_t sesspid; - int last_sess_status; /* status returned by last session */ - pid_t slavepid; - pid_t chooserpid; - time_t acctime; - - gboolean handled; - gboolean tcp_disallowed; - - int priority; - int vt; - - gboolean busy_display; - - gboolean attached; /* Display is physically attached to the machine. */ - /* TYPE_XDMCP would have this FALSE, eg. */ - - time_t last_start_time; - time_t last_loop_start_time; - gint retry_count; - - int sleep_before_run; - - time_t last_x_failed; - int x_faileds; - - gboolean try_different_greeter; - - gboolean logged_in; /* TRUE if someone is logged in */ - char *login; - - char *preset_user; - - gboolean timed_login_ok; - - int screenx; - int screeny; - int screenwidth; /* Note 0 means use the gdk size */ - int screenheight; - int lrh_offsetx; /* lower right hand corner x offset */ - int lrh_offsety; /* lower right hand corner y offset */ - - /* Flexi stuff */ - char *parent_disp; - Display *parent_dsp; - char *parent_auth_file; - char *parent_temp_auth_file; - uid_t server_uid; - GdmConnection *socket_conn; - - int xdmcp_dispnum; - - /* Notification connection */ - int master_notify_fd; /* write part of the connection */ - int slave_notify_fd; /* read part of the connection */ - - /* order in the Xservers file for sessreg, -1 if unset yet */ - int x_servers_order; - - /* The xsession-errors connection */ - int xsession_errors_fd; /* write to the file */ - int session_output_fd; /* read from the session */ - int xsession_errors_bytes; -#define MAX_XSESSION_ERRORS_BYTES (80*2500) /* maximum number of bytes in - the ~/.xsession-errors file */ - char *xsession_errors_filename; /* if NULL then there is no .xsession-errors - file */ - - int chooser_output_fd; /* from the chooser */ - char *chooser_last_line; - - /* Only set in the main daemon as that's the only place that cares */ - GdmLogoutAction logout_action; - - char *theme_name; -}; - -typedef struct _GdmXserver GdmXserver; -struct _GdmXserver { - char *id; - char *name; - char *command; - gboolean flexible; - gboolean choosable; /* not implemented yet */ - gboolean chooser; /* instead of greeter, run chooser */ - gboolean handled; - int number; - int priority; -}; - -typedef struct _GdmIndirectDisplay GdmIndirectDisplay; -struct _GdmIndirectDisplay { - int id; -#ifdef ENABLE_IPV6 - struct sockaddr_storage* dsp_sa; - struct in6_addr* chosen_host6; -#else - struct sockaddr_in* dsp_sa; -#endif - time_t acctime; - struct in_addr *chosen_host; -}; - -/* NOTE: Timeout and max are hardcoded */ -typedef struct _GdmForwardQuery GdmForwardQuery; -struct _GdmForwardQuery { - time_t acctime; -#ifdef ENABLE_IPV6 - struct sockaddr_storage* dsp_sa; - struct sockaddr_storage* from_sa; -#else - struct sockaddr_in* dsp_sa; - struct sockaddr_in* from_sa; -#endif -}; -#define GDM_MAX_FORWARD_QUERIES 10 -#define GDM_FORWARD_QUERY_TIMEOUT 30 - -/* some extra XDMCP opcodes that xdm will happily ignore since they'll be - * the wrong XDMCP version anyway */ -#define GDM_XDMCP_PROTOCOL_VERSION 1001 -enum { - GDM_XDMCP_FIRST_OPCODE = 1000, /*just a marker, not an opcode */ - - GDM_XDMCP_MANAGED_FORWARD = 1000, - /* manager (master) -> manager - * A packet with MANAGED_FORWARD is sent to the - * manager that sent the forward query from the manager to - * which forward query was sent. It indicates that the forward - * was fully processed and that the client now has either - * a managed session, or has been sent denial, refuse or failed. - * (if the denial gets lost then client gets dumped into the - * chooser again). This should be resent a few times - * until some (short) timeout or until GOT_MANAGED_FORWARD - * is sent. GDM sends at most 3 packates with 1.5 seconds - * between each. - * - * Argument is ARRAY8 with the address of the originating host */ - GDM_XDMCP_GOT_MANAGED_FORWARD, - /* manager -> manager (master) - * A single packet with GOT_MANAGED_FORWARD is sent to indicate - * that we did receive the MANAGED_FORWARD packet. The argument - * must match the MANAGED_FORWARD one or it will just be ignored. - * - * Argument is ARRAY8 with the address of the originating host */ - GDM_XDMCP_LAST_OPCODE /*just a marker, not an opcode */ -}; - /* If id == NULL, then get the first X server */ void gdm_final_cleanup (void); - -/* primitive protocol for controlling the daemon from slave - * or gdmconfig or whatnot */ - -/* The ones that pass a <slave pid> must be from a valid slave, and - * the slave will be sent a SIGUSR2. Nowdays there is a pipe that is - * used from inside slaves, so those messages may stop being processed - * by the fifo at some point perhaps. */ -/* The fifo protocol, used only by gdm internally */ -#define GDM_SOP_CHOSEN "CHOSEN" /* <indirect id> <ip addr> */ -#define GDM_SOP_CHOSEN_LOCAL "CHOSEN_LOCAL" /* <slave pid> <hostname> */ -#define GDM_SOP_XPID "XPID" /* <slave pid> <xpid> */ -#define GDM_SOP_SESSPID "SESSPID" /* <slave pid> <sesspid> */ -#define GDM_SOP_GREETPID "GREETPID" /* <slave pid> <greetpid> */ -#define GDM_SOP_CHOOSERPID "CHOOSERPID" /* <slave pid> <chooserpid> */ -#define GDM_SOP_LOGGED_IN "LOGGED_IN" /* <slave pid> <logged_in as int> */ -#define GDM_SOP_LOGIN "LOGIN" /* <slave pid> <username> */ -#define GDM_SOP_COOKIE "COOKIE" /* <slave pid> <cookie> */ -#define GDM_SOP_AUTHFILE "AUTHFILE" /* <slave pid> <authfile> */ -#define GDM_SOP_QUERYLOGIN "QUERYLOGIN" /* <slave pid> <username> */ -/* if user already logged in somewhere, the ack response will be - <display>,<migratable>,<display>,<migratable>,... */ -#define GDM_SOP_MIGRATE "MIGRATE" /* <slave pid> <display> */ -#define GDM_SOP_DISP_NUM "DISP_NUM" /* <slave pid> <display as int> */ -/* For Linux only currently */ -#define GDM_SOP_VT_NUM "VT_NUM" /* <slave pid> <vt as int> */ -#define GDM_SOP_FLEXI_ERR "FLEXI_ERR" /* <slave pid> <error num> */ - /* 3 = X failed */ - /* 4 = X too busy */ - /* 5 = Nest display can't connect */ -#define GDM_SOP_FLEXI_OK "FLEXI_OK" /* <slave pid> */ -#define GDM_SOP_SOFT_RESTART "SOFT_RESTART" /* no arguments */ -#define GDM_SOP_START_NEXT_LOCAL "START_NEXT_LOCAL" /* no arguments */ -#define GDM_SOP_HUP_ALL_GREETERS "HUP_ALL_GREETERS" /* no arguments */ - -/* stop waiting for this and go on with your life, useful with - the --wait-for-go command line option */ -#define GDM_SOP_GO "GO" /* no arguments */ - -/* sometimes we can't do a syslog so we tell the main daemon */ -#define GDM_SOP_SYSLOG "SYSLOG" /* <pid> <type> <message> */ - -/* write out a sessreg (xdm) compatible Xservers file - * in the ServAuthDir as <name>.Xservers */ -#define GDM_SOP_WRITE_X_SERVERS "WRITE_X_SERVERS" /* <slave pid> */ - -/* All X servers should be restarted rather then regenerated. Useful - * if you have updated the X configuration. Note that this happens - * only when the user logs out or when we otherwise would have restarted - * a server, nothing is done by this command. */ -#define GDM_SOP_DIRTY_SERVERS "DIRTY_SERVERS" /* no arguments */ - -/* restart all servers that people aren't logged in on. Maybe you may not - * want to do this on every change of X server config since this may cause - * flicker on screen and jumping around on the vt. Perhaps useful to do - * by asking the user if they want to do that. Note that this will not - * kill any logged in sessions. */ -#define GDM_SOP_SOFT_RESTART_SERVERS "SOFT_RESTART_SERVERS" /* no arguments */ -/* Suspend the machine if it is even allowed */ -#define GDM_SOP_SUSPEND_MACHINE "SUSPEND_MACHINE" /* no arguments */ -#define GDM_SOP_CHOSEN_THEME "CHOSEN_THEME" /* <slave pid> <theme name> */ - -/*Execute custom cmd*/ -#define GDM_SOP_CUSTOM_CMD "CUSTOM_CMD" /* <slave pid> <cmd id> */ - -/* Start a new standard X flexible server */ -#define GDM_SOP_FLEXI_XSERVER "FLEXI_XSERVER" /* no arguments */ - -#define GDM_SOP_SHOW_ERROR_DIALOG "SHOW_ERROR_DIALOG" /* show the error dialog from daemon */ -#define GDM_SOP_SHOW_YESNO_DIALOG "SHOW_YESNO_DIALOG" /* show the yesno dialog from daemon */ -#define GDM_SOP_SHOW_QUESTION_DIALOG "SHOW_QUESTION_DIALOG" /* show the question dialog from daemon */ -#define GDM_SOP_SHOW_ASKBUTTONS_DIALOG "SHOW_ASKBUTTON_DIALOG" /* show the askbutton dialog from daemon */ - - -/* Ack for a slave message */ -/* Note that an extra response can follow an 'ack' */ -#define GDM_SLAVE_NOTIFY_ACK 'A' -/* Update this key */ -#define GDM_SLAVE_NOTIFY_KEY '!' -/* notify a command */ -#define GDM_SLAVE_NOTIFY_COMMAND '#' -/* send the response */ -#define GDM_SLAVE_NOTIFY_RESPONSE 'R' -/* send the error dialog response */ -#define GDM_SLAVE_NOTIFY_ERROR_RESPONSE 'E' -/* send the yesno dialog response */ -#define GDM_SLAVE_NOTIFY_YESNO_RESPONSE 'Y' -/* send the askbuttons dialog response */ -#define GDM_SLAVE_NOTIFY_ASKBUTTONS_RESPONSE 'B' -/* send the question dialog response */ -#define GDM_SLAVE_NOTIFY_QUESTION_RESPONSE 'Q' - -/* - * Maximum number of messages allowed over the sockets protocol. This - * is set to 80 since the gdmlogin/gdmgreeter programs have ~60 config - * values that are pulled over the socket connection so it allows them - * all to be grabbed in one pull. - */ -#define GDM_SUP_MAX_MESSAGES 80 -#define GDM_SUP_SOCKET "/tmp/.gdm_socket" - -/* - * The user socket protocol. Each command is given on a separate line - * - * A user should first send a VERSION\n after connecting and only do - * anything else if gdm responds with the correct response. The version - * is the gdm version and not a "protocol" revision, so you can't check - * against a single version but check if the version is higher then some - * value. - * - * You can only send a few commands at a time, so if you keep getting error - * 200 try opening a new socket for every command you send. - */ -/* The user protocol, using /tmp/.gdm_socket */ - -#define GDM_SUP_VERSION "VERSION" /* no arguments */ -/* VERSION: Query GDM version - * Supported since: 2.2.4.0 - * Arguments: None - * Answers: - * GDM <gdm version> - * ERROR <err number> <english error description> - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_AUTH_LOCAL "AUTH_LOCAL" /* <xauth cookie> */ -/* AUTH_LOCAL: Setup this connection as authenticated for FLEXI_SERVER. - * Because all full blown (non-nested) displays can be started - * only from users logged in locally, and here gdm assumes - * only users logged in from gdm. They must pass the xauth - * MIT-MAGIC-COOKIE-1 that they were passed before the - * connection is authenticated. - * Note: The AUTH LOCAL command requires the --authenticate option, - * although only FLEXI XSERVER uses this currently. - * Note: Since 2.6.0.6 you can also use a global - * <ServAuthDir>/.cookie, which works for all authentication - * except for SET_LOGOUT_ACTION and QUERY_LOGOUT_ACTION - * and SET_SAFE_LOGOUT_ACTION which require a logged in - * display. - * Supported since: 2.2.4.0 - * Arguments: <xauth cookie> - * <xauth cookie> is in hex form with no 0x prefix - * Answers: - * OK - * ERROR <err number> <english error description> - * 0 = Not implemented - * 100 = Not authenticated - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_FLEXI_XSERVER "FLEXI_XSERVER" /* <xserver type> */ -/* FLEXI_XSERVER: Start a new X flexible display. Only supported on - * connection that passed AUTH_LOCAL - * Supported since: 2.2.4.0 - * Arguments: <xserver type> - * If no arguments, starts the standard X server - * Answers: - * OK <display> - * ERROR <err number> <english error description> - * 0 = Not implemented - * 1 = No more flexi servers - * 2 = Startup errors - * 3 = X failed - * 4 = X too busy - * 6 = No server binary - * 100 = Not authenticated - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_FLEXI_XSERVER_USER "FLEXI_XSERVER_USER" /* <username> <xserver type> */ -/* FLEXI_XSERVER_USER: Start a new X flexible display and initialize the - * greeter with the given username. Only supported on - * connection that passed AUTH_LOCAL - * Supported since: 2.17.7 - * Arguments: <username> <xserver type> - * If no server type specified, starts the standard X server - * Answers: - * OK <display> - * ERROR <err number> <english error description> - * 0 = Not implemented - * 1 = No more flexi servers - * 2 = Startup errors - * 3 = X failed - * 4 = X too busy - * 6 = No server binary - * 100 = Not authenticated - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_FLEXI_XNEST "FLEXI_XNEST" /* <display> <uid> <xauth cookie> <xauth file> */ -/* FLEXI_XNEXT: Start a new flexible nested display. - * Note: Supported on older versions from 2.2.4.0, later - * 2.2.4.2, but since 2.3.90.4 you must supply 4 - * arguments or ERROR 100 will be returned. This - * will start the nested Xserver command using the - * XAUTHORITY file supplied and as the uid same as - * the owner of that file (and same as you supply). - * You must also supply the cookie as the third - * argument for this display, to prove that you - * indeed are this user. Also this file must be - * readable ONLY by this user, that is have a mode - * of 0600. If this all is not met, ERROR 100 is - * returned. - * Note: The cookie should be the MIT-MAGIC-COOKIE-1, - * the first one gdm can find in the XAUTHORITY - * file for this display. If that's not what you - * use you should generate one first. The cookie - * should be in hex form. - * Supported since: 2.3.90.4 - * Arguments: <display to run on> <uid of requesting user> - * <xauth cookie for the display> <xauth file> - * Answers: - * OK <display> - * ERROR <err number> <english error description> - * 0 = Not implemented - * 1 = No more flexi servers - * 2 = Startup errors - * 3 = X failed - * 4 = X too busy - * 5 = Nested display can't connect - * 6 = No server binary - * 100 = Not authenticated - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_FLEXI_XNEST_USER "FLEXI_XNEST_USER" /* <username> <display> <uid> <xauth cookie> <xauth file> */ -/* FLEXI_XNEXT_USER: Start a new flexible nested display and - * initialize the greeter with the given username - * Note: The cookie should be the MIT-MAGIC-COOKIE-1, - * the first one gdm can find in the XAUTHORITY - * file for this display. If that's not what you - * use you should generate one first. The cookie - * should be in hex form. - * Supported since: 2.17.7 - * Arguments: <username> <display to run on> <uid of requesting user> - * <xauth cookie for the display> <xauth file> - * Answers: - * OK <display> - * ERROR <err number> <english error description> - * 0 = Not implemented - * 1 = No more flexi servers - * 2 = Startup errors - * 3 = X failed - * 4 = X too busy - * 5 = Nested display can't connect - * 6 = No server binary - * 100 = Not authenticated - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_ADD_DYNAMIC_DISPLAY "ADD_DYNAMIC_DISPLAY" -/* - * ADD_DYNAMIC_DISPLAY: Create a new server definition that will - * run on the specified display leaving it - * in DISPLAY_CONFIG state. - * Supported since: 2.8.0.0 - * Arguments: <display to run on>=<server> - * Where <server> is either a configuration named in the - * GDM configuration a literal command name. - * Answers: - * OK - * ERROR - * 0 = Not implemented - * 2 = Existing display - * 3 = No server string - * 4 = Display startup failure - * 100 = Not authenticated - * 200 - Dynamic Displays not allowed - * 999 = Unknown error - */ -#define GDM_SUP_RELEASE_DYNAMIC_DISPLAYS "RELEASE_DYNAMIC_DISPLAYS" -/* - * RELEASE_DYNAMIC_DISPLAYS: Release and begin managing dynamic displays - * currently in DISPLAY_CONFIG state - * Supported since: 2.8.0.0 - * Arguments: <display to release> - * Answers: - * OK - * ERROR - * 0 = Not implemented - * 1 = Bad display number - * 100 = Not authenticated - * 200 = Dynamic Displays not allowed - * 999 = Unknown error - */ -#define GDM_SUP_REMOVE_DYNAMIC_DISPLAY "REMOVE_DYNAMIC_DISPLAY" -/* - * REMOVE_DYNAMIC_DISPLAY: Remove a dynamic display, killing the server - * and purging the display configuration - * Supported since: 2.8.0.0 - * Arguments: <display to remove> - * Answers: - * OK - * ERROR - * 0 = Not implemented - * 1 = Bad display number - * 100 = Not authenticated - * 200 = Dynamic Displays not allowed - * 999 = Unknown error - */ -#define GDM_SUP_ATTACHED_SERVERS "ATTACHED_SERVERS" /* None */ -#define GDM_SUP_CONSOLE_SERVERS "CONSOLE_SERVERS" /* None */ -/* ATTACHED_SERVERS: List all attached displays. Doesn't list XDMCP - * and xnest non-attached displays. - * Note: This command used to be named CONSOLE_SERVERS, - * which is still recognized for backwards - * compatibility. The optional pattern argument - * is supported as of version 2.8.0.0. - * Supported since: 2.2.4.0 - * Arguments: <pattern> (optional) - * With no argument, all dynamic displays are returned. The optional - * <pattern> is a string that may contain glob characters '*', '?', and - * '[]'. Only displays that match the pattern will be returned. - * Answers: - * OK <server>;<server>;... - * - * <server> is <display>,<logged in user>,<vt or xnest display> - * - * <logged in user> can be empty in case no one logged in yet, - * and <vt> can be -1 if it's not known or not supported (on non-Linux - * for example). If the display is an xnest display and is an attached one - * (that is, it is an xnest inside another attached display) it is listed - * and instead of vt, it lists the parent display in standard form. - * - * ERROR <err number> <english error description> - * 0 = Not implemented - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_ALL_SERVERS "ALL_SERVERS" /* None */ -/* ALL_SERVERS: List all displays, including attached, remote, xnest. - * This can for example be useful to figure out if - * the display you are on is managed by the gdm daemon, - * by seeing if it is in the list. It is also somewhat - * like the 'w' command but for graphical sessions. - * Supported since: 2.4.2.96 - * Arguments: None - * Answers: - * OK <server>;<server>;... - * - * <server> is <display>,<logged in user> - * - * <logged in user> can be empty in case no one logged in yet - * - * ERROR <err number> <english error description> - * 0 = Not implemented - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_GET_SERVER_LIST "GET_SERVER_LIST" /* None */ -/* GET_SERVER_LIST: Get a list of the server sections from - * the configuration file. - * Supported since: 2.13.0.4 - * Arguments: None - * Answers: - * OK <value>;<value>;... - * ERROR <err number> <english error description> - * 0 = Not implemented - * 1 = No servers found - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_GET_SERVER_DETAILS "GET_SERVER_DETAILS" /* <server> <key> */ -/* GET_SERVER_DETAILS: Get detail information for a specific server. - * Supported since: 2.13.0.4 - * Arguments: <server> <key> - * Key values include: - * ID - Returns the server id - * NAME - Returns the server name - * COMMAND - Returns the server command - * FLEXIBLE - Returns "true" if flexible, "false" otherwise - * CHOOSABLE - Returns "true" if choosable, "false" otherwise - * HANDLED - Returns "true" if handled, "false" otherwise - * CHOOSER - Returns "true" if chooser, "false" otherwise - * PRIORITY - Returns process priority - * Answers: - * OK <value> - * ERROR <err number> <english error description> - * 0 = Not implemented - * 1 = Server not found - * 2 = Key not valid - * 50 = Unsupported key - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_GET_CONFIG "GET_CONFIG" /* <key> */ -/* GET_CONFIG: Get configuration value for key. Useful so - * that other applications can request configuration - * information from GDM. Any key defined as GDM_KEY_* - * in gdm.h is supported. Starting with version 2.13.0.2 - * translated keys (such as "greeter/GdmWelcome[cs]" are - * supported via GET_CONFIG. Also starting with version - * 2.13.0.2 it is no longer necessary to include the - * default value (i.e. you can use key "greeter/IncludeAll" - * instead of having to use "greeter/IncludeAll=false". - * Starting with version 2.14.4, GDM supports per-display - * configuration (for GUI slave clients only) and accepts - * the display argument to retrieve per-display value (if - * any. - * Supported since: 2.6.0.9 - * Arguments: <key> [<display>] - * Answers: - * OK <value> - * ERROR <err number> <english error description> - * 0 = Not implemented - * 50 = Unsupported key - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_GET_CONFIG_FILE "GET_CONFIG_FILE" /* None */ -/* GET_CONFIG_FILE: Get defaults config file location being used by - # the daemon. If the GDM daemon was started - * with the --config option, it will return - * the value passed in via that argument. - * Supported since: 2.8.0.2 - * Arguments: None - * Answers: - * OK <full path to GDM configuration file> - * ERROR <err number> <english error description> - * 0 = Not implemented - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_GET_CUSTOM_CONFIG_FILE "GET_CUSTOM_CONFIG_FILE" /* None */ -/* GET_CONFIG_FILE: Get custom config file location being used by - # the daemon. - * Supported since: 2.14.0.0 - * Arguments: None - * Answers: - * OK <full path to GDM custom configuration file> - * ERROR <err number> <english error description> - * 0 = Not implemented - * 1 = File not found - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_UPDATE_CONFIG "UPDATE_CONFIG" /* <key> */ -/* UPDATE_CONFIG: Tell the daemon to re-read a key from the - * GDM configuration file. Any user can request - * that values are re-read but the daemon will - * only do so if the file has been modified - * since GDM first read the file. Only users - * who can change the GDM configuration file - * (normally writable only by the root user) can - * actually modify the GDM configuration. This - * command is useful to cause the GDM to update - * itself to recognize a change made to the GDM - * configuration file by the root user. - * - * Starting with version 2.13.0.0, all GDM keys are - * supported except for the following: - * - * daemon/PidFile - * daemon/ConsoleNotify - * daemon/User - * daemon/Group - * daemon/LogDir - * daemon/ServAuthDir - * daemon/UserAuthDir - * daemon/UserAuthFile - * daemon/UserAuthFBDir - * - * GDM also supports the following Psuedokeys: - * - * xdmcp/PARAMETERS (2.3.90.2) updates the following: - * xdmcp/MaxPending - * xdmcp/MaxSessions - * xdmcp/MaxWait - * xdmcp/DisplaysPerHost - * xdmcp/HonorIndirect - * xdmcp/MaxPendingIndirect - * xdmcp/MaxWaitIndirect - * xdmcp/PingIntervalSeconds (only affects new connections) - * - * xservers/PARAMETERS (2.13.0.4) updates the following: - * all [server-foo] sections. - * - * Supported keys for previous versions of GDM: - * - * security/AllowRoot (2.3.90.2) - * security/AllowRemoteRoot (2.3.90.2) - * security/AllowRemoteAutoLogin (2.3.90.2) - * security/RetryDelay (2.3.90.2) - * security/DisallowTCP (2.4.2.0) - * daemon/Greeter (2.3.90.2) - * daemon/RemoteGreeter (2.3.90.2) - * xdmcp/Enable (2.3.90.2) - * xdmcp/Port (2.3.90.2) - * daemon/TimedLogin (2.3.90.3) - * daemon/TimedLoginEnable (2.3.90.3) - * daemon/TimedLoginDelay (2.3.90.3) - * greeter/SystemMenu (2.3.90.3) - * greeter/ConfigAvailable (2.3.90.3) - * greeter/ChooserButton (2.4.2.0) - * greeter/SoundOnLoginFile (2.5.90.0) - * daemon/AddGtkModules (2.5.90.0) - * daemon/GtkModulesList (2.5.90.0) - * Supported since: 2.3.90.2 - * Arguments: <key> - * <key> is just the base part of the key such as "security/AllowRemoteRoot" - * Answers: - * OK - * ERROR <err number> <english error description> - * 0 = Not implemented - * 50 = Unsupported key - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_GREETERPIDS "GREETERPIDS" /* None */ -/* GREETERPIDS: List all greeter pids so that one can send HUP - * to them for config rereading. Of course one - * must be root to do that. - * Supported since: 2.3.90.2 - * Arguments: None - * Answers: - * OK <pid>;<pid>;... - * ERROR <err number> <english error description> - * 0 = Not implemented - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_QUERY_LOGOUT_ACTION "QUERY_LOGOUT_ACTION" /* None */ -/* QUERY_LOGOUT_ACTION: Query which logout actions are possible - * Only supported on connections that passed - * AUTH_LOCAL. - * Supported since: 2.5.90.0 - * Answers: - * OK <action>;<action>;... - * Where action is one of HALT, REBOOT, SUSPEND or CUSTOM_CMDX (where X in [0,GDM_CUSTOM_COMMAND_MAX)). - * An empty list can also be returned if no action is possible. A '!' is appended - * to an action if it was already set with SET_LOGOUT_ACTION or - * SET_SAFE_LOGOUT_ACTION. Note that SET_LOGOUT_ACTION has precedence - * over SET_SAFE_LOGOUT_ACTION. - * ERROR <err number> <english error description> - * 0 = Not implemented - * 100 = Not authenticated - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_QUERY_CUSTOM_CMD_LABELS "QUERY_CUSTOM_CMD_LABELS" /* None */ -/* QUERY_CUSTOM_CMD_LABELS: Query labels belonging to exported custom commands - * Only supported on connections that passed - * AUTH_LOCAL. - * Supported since: 2.5.90.0 - * Answers: - * OK <label1>;<label2>;... - * Where labelX is one of the labels belonging to CUSTOM_CMDX (where X in [0,GDM_CUSTOM_COMMAND_MAX)). - * An empty list can also be returned if none of the custom commands are - * exported outside login manager (no CustomCommandIsPersistent options are set to true). - * ERROR <err number> <english error description> - * 0 = Not implemented - * 100 = Not authenticated - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_QUERY_CUSTOM_CMD_NO_RESTART_STATUS "QUERY_CUSTOM_CMD_NO_RESTART_STATUS" /* None */ -/* QUERY_CUSTOM_CMD_NO_RESTART_STATUS: Query NoRestart config options for each of custom commands - * Only supported on connections that passed - * AUTH_LOCAL. - * Supported since: 2.5.90.0 - * Answers: - * OK <status> - * Where each bit of the status represents NoRestart value for each of the custom commands. - * bit on (1): NoRestart = true, - * bit off (0): NoRestart = false. - * ERROR <err number> <english error description> - * 0 = Not implemented - * 100 = Not authenticated - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_SET_LOGOUT_ACTION "SET_LOGOUT_ACTION" /* <action> */ -/* SET_LOGOUT_ACTION: Tell the daemon to halt/restart/suspend after - * slave process exits. Only supported on - * connections that passed AUTH_LOCAL. - * Supported since: 2.5.90.0 - * Arguments: <action> - * NONE Set exit action to 'none' - * HALT Set exit action to 'halt' - * REBOOT Set exit action to 'reboot' - * SUSPEND Set exit action to 'suspend' - * CUSTOM_CMDX Set exit action to 'custom command X' where where X in [0,GDM_CUSTOM_COMMAND_MAX) - * Answers: - * OK - * ERROR <err number> <english error description> - * 0 = Not implemented - * 7 = Unknown logout action, or not available - * 100 = Not authenticated - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_SET_SAFE_LOGOUT_ACTION "SET_SAFE_LOGOUT_ACTION" /* <action> */ -/* SET_SAFE_LOGOUT_ACTION: Tell the daemon to halt/restart/suspend - * after everybody logs out. If only one - * person logs out, then this is obviously - * the same as the SET_LOGOUT_ACTION. Note - * that SET_LOGOUT_ACTION has precendence - * over SET_SAFE_LOGOUT_ACTION if it is set - * to something other then NONE. If no one - * is logged in, then the action takes effect - * immedeately. Only supported on connections - * that passed AUTH_LOCAL. - * Supported since: 2.5.90.0 - * Arguments: <action> - * NONE Set exit action to 'none' - * HALT Set exit action to 'halt' - * REBOOT Set exit action to 'reboot' - * SUSPEND Set exit action to 'suspend' - * CUSTOM_CMDX Set exit action to 'custom command X' where where X in [0,GDM_CUSTOM_COMMAND_MAX) - * - * Answers: - * OK - * ERROR <err number> <english error description> - * 0 = Not implemented - * 7 = Unknown logout action, or not available - * 100 = Not authenticated - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_LOGOUT_ACTION_NONE "NONE" -#define GDM_SUP_LOGOUT_ACTION_HALT "HALT" -#define GDM_SUP_LOGOUT_ACTION_REBOOT "REBOOT" -#define GDM_SUP_LOGOUT_ACTION_SUSPEND "SUSPEND" -#define GDM_SUP_LOGOUT_ACTION_CUSTOM_CMD_TEMPLATE "CUSTOM_CMD" -/* - */ -#define GDM_SUP_QUERY_VT "QUERY_VT" /* None */ -/* QUERY_VT: Ask the daemon about which VT we are currently on. - * This is useful for logins which don't own - * /dev/console but are still console logins. Only - * supported on Linux currently, other places will - * just get ERROR 8. This is also the way to query - * if VT support is available in the daemon in the - * first place. Only supported on connections that - * passed AUTH_LOCAL. - * Supported since: 2.5.90.0 - * Arguments: None - * Answers: - * OK <vt number> - * ERROR <err number> <english error description> - * 0 = Not implemented - * 8 = Virtual terminals not supported - * 100 = Not authenticated - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_SET_VT "SET_VT" /* <vt> */ -/* SET_VT: Change to the specified virtual terminal. - * This is useful for logins which don't own /dev/console - * but are still console logins. Only supported on Linux - * currently, other places will just get ERROR 8. - * Only supported on connections that passed AUTH_LOCAL. - * Supported since: 2.5.90.0 - * Arguments: None - * Answers: - * OK - * ERROR <err number> <english error description> - * 0 = Not implemented - * 8 = Virtual terminals not supported - * 9 = Invalid virtual terminal number - * 100 = Not authenticated - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_SERVER_BUSY "SERVER_BUSY" /* None */ -/* SERVER_BUSY: Returns true if half or more of the daemon's sockets are - * busy, false otherwise. Used by slave programs which want - * to ensure they do not overhwelm the server. - * Supported since: 2.13.0.8 - * Arguments: None - * Answers: - * OK <value> - * ERROR <err number> <english error description> - * 0 = Not implemented - * 200 = Too many messages - * 999 = Unknown error - */ -#define GDM_SUP_GET_SERVER_DETAILS "GET_SERVER_DETAILS" /* <server> <key> */ -#define GDM_SUP_CLOSE "CLOSE" /* None */ -/* CLOSE: Close sockets connection - * Supported since: 2.2.4.0 - * Arguments: None - * Answers: None - */ - -/* User flags for the SUP protocol */ -enum { - GDM_SUP_FLAG_AUTHENTICATED = 0x1, /* authenticated as a local user, - * from a local display we started */ - GDM_SUP_FLAG_AUTH_GLOBAL = 0x2 /* authenticated with global cookie */ -}; - -/* Macros to check authentication level */ -#define GDM_CONN_AUTHENTICATED(conn) \ - ((gdm_connection_get_user_flags (conn) & GDM_SUP_FLAG_AUTHENTICATED) || \ - (gdm_connection_get_user_flags (conn) & GDM_SUP_FLAG_AUTH_GLOBAL)) - -#define GDM_CONN_AUTH_GLOBAL(conn) \ - (gdm_connection_get_user_flags (conn) & GDM_SUP_FLAG_AUTH_GLOBAL) - - -#define NEVER_FAILS_seteuid(uid) \ - { int r = 0; \ - if (geteuid () != uid) \ - r = seteuid (uid); \ - if G_UNLIKELY (r != 0) \ - gdm_fail ("GDM file %s: line %d (%s): Cannot run seteuid to %d: %s", \ - __FILE__, \ - __LINE__, \ - __PRETTY_FUNCTION__, \ - (int)uid, \ - strerror (errno)); } -#define NEVER_FAILS_setegid(gid) \ - { int r = 0; \ - if (getegid () != gid) \ - r = setegid (gid); \ - if G_UNLIKELY (r != 0) \ - gdm_fail ("GDM file %s: line %d (%s): Cannot run setegid to %d: %s", \ - __FILE__, \ - __LINE__, \ - __PRETTY_FUNCTION__, \ - (int)gid, \ - strerror (errno)); } - -/* first goes to euid-root and then sets the egid and euid, to make sure - * this succeeds */ -#define NEVER_FAILS_root_set_euid_egid(uid,gid) \ - { NEVER_FAILS_seteuid (0); \ - NEVER_FAILS_setegid (gid); \ - if (uid != 0) { NEVER_FAILS_seteuid (uid); } } - #endif /* GDM_H */ /* EOF */ diff --git a/daemon/gdmconsolekit.c b/daemon/gdmconsolekit.c index c4d82669..ce366ae7 100644 --- a/daemon/gdmconsolekit.c +++ b/daemon/gdmconsolekit.c @@ -21,13 +21,16 @@ #include "config.h" #include <stdlib.h> +#include <string.h> #include <pwd.h> +#include <glib.h> + #define DBUS_API_SUBJECT_TO_CHANGE #include <dbus/dbus.h> #include <dbus/dbus-glib-lowlevel.h> -#include "misc.h" /* for gdm_debug */ +#include "gdm-log.h" /* for gdm_debug */ #include "gdmconsolekit.h" @@ -268,7 +271,7 @@ get_path_array_from_iter (DBusMessageIter *iter, return buffer; oom: - fprintf (stderr, "%s %d : error allocating memory\n", __FILE__, __LINE__); + g_warning ("%s %d : error allocating memory\n", __FILE__, __LINE__); return NULL; } diff --git a/daemon/gdmconsolekit.h b/daemon/gdmconsolekit.h index ea5afb95..69f9ce39 100644 --- a/daemon/gdmconsolekit.h +++ b/daemon/gdmconsolekit.h @@ -22,6 +22,10 @@ #ifndef __GDM_CONSOLE_KIT_H #define __GDM_CONSOLE_KIT_H +#include <pwd.h> + +#include "display.h" /* for GdmDisplay */ + G_BEGIN_DECLS char * open_ck_session (struct passwd *pwent, diff --git a/daemon/md5.h b/daemon/md5.h index 14ccf83c..38b992b0 100644 --- a/daemon/md5.h +++ b/daemon/md5.h @@ -19,6 +19,8 @@ #ifndef GdmMD5_H #define GdmMD5_H +#include <glib.h> + struct GdmMD5Context { guint32 buf[4]; guint32 bits[2]; diff --git a/daemon/misc.c b/daemon/misc.c index 0ed07c22..a4080795 100644 --- a/daemon/misc.c +++ b/daemon/misc.c @@ -1,4 +1,6 @@ -/* GDM - The GNOME Display Manager +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * 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 @@ -18,7 +20,6 @@ #include "config.h" -#include <syslog.h> #include <unistd.h> #include <stdlib.h> #include <dirent.h> @@ -57,18 +58,11 @@ #include "slave.h" #include "gdm-common.h" +#include "gdm-log.h" #include "gdm-daemon-config.h" extern char **environ; -extern pid_t extra_process; -extern int extra_status; -extern pid_t gdm_main_pid; -extern gboolean preserve_ld_vars; -extern int gdm_in_signal; -extern GSList *displays; -extern char *gdm_charset; - #ifdef ENABLE_IPV6 #ifdef __sun @@ -178,142 +172,6 @@ have_ipv6 (void) } #endif - -static void -do_syslog (int type, const char *s) -{ - if (gdm_in_signal > 0) { - char *m = g_strdup_printf (GDM_SOP_SYSLOG " %ld %d %s", - (long)getpid (), type, s); - gdm_slave_send (m, FALSE); - g_free (m); - } else { - syslog (type, "%s", s); - } -} - - -/** - * gdm_fail: - * @format: printf style format string - * @...: Optional arguments - * - * Logs fatal error condition and aborts master daemon. Also sleeps - * for 30 seconds to avoid looping if gdm is started by init. - */ -void -gdm_fail (const gchar *format, ...) -{ - va_list args; - char *s; - - va_start (args, format); - s = g_strdup_vprintf (format, args); - va_end (args); - - /* Log to both syslog and stderr */ - do_syslog (LOG_CRIT, s); - if (getpid () == gdm_main_pid) { - gdm_fdprintf (2, "%s\n", s); - } - - g_free (s); - - /* If main process do final cleanup to kill all processes */ - if (getpid () == gdm_main_pid) { - gdm_final_cleanup (); - } else if ( ! gdm_slave_final_cleanup ()) { - /* If we weren't even a slave do some random cleanup only */ - /* FIXME: is this all fine? */ - gdm_sigchld_block_push (); - if (extra_process > 1 && extra_process != getpid ()) { - /* we sigterm extra processes, and we don't wait */ - kill (-(extra_process), SIGTERM); - extra_process = 0; - } - gdm_sigchld_block_pop (); - } - - closelog (); - - /* Slow down respawning if we're started from init */ - if (getppid () == 1) - sleep (30); - - exit (EXIT_FAILURE); -} - - -/** - * gdm_info: - * @format: printf style format string - * @...: Optional arguments - * - * Log non-fatal information to syslog - */ -void -gdm_info (const gchar *format, ...) -{ - va_list args; - char *s; - - va_start (args, format); - s = g_strdup_vprintf (format, args); - va_end (args); - - do_syslog (LOG_INFO, s); - - g_free (s); -} - -/** - * gdm_error: - * @format: printf style format string - * @...: Optional arguments - * - * Log non-fatal error condition to syslog - */ -void -gdm_error (const gchar *format, ...) -{ - va_list args; - char *s; - - va_start (args, format); - s = g_strdup_vprintf (format, args); - va_end (args); - - do_syslog (LOG_ERR, s); - - g_free (s); -} - -/** - * gdm_debug: - * @format: printf style format string - * @...: Optional arguments - * - * Log debug information to syslog if debugging is enabled. - */ -void -gdm_debug (const gchar *format, ...) -{ - va_list args; - char *s; - - if G_LIKELY (! gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG)) - return; - - va_start (args, format); - s = g_strdup_vprintf (format, args); - va_end (args); - - do_syslog (LOG_ERR, s); /* Maybe should be LOG_DEBUG, but then normally - * you wouldn't get it in the log. ??? */ - - g_free (s); -} - void gdm_fdprintf (int fd, const gchar *format, ...) { @@ -348,7 +206,6 @@ gdm_fdprintf (int fd, const gchar *format, ...) /* * Clear environment, but keep the i18n ones, * note that this leaks memory so only use before exec - * (keep LD_* if preserve_ld_vars is true) */ void gdm_clearenv_no_lang (void) @@ -360,39 +217,9 @@ gdm_clearenv_no_lang (void) char *env = environ[i]; if (strncmp (env, "LC_", 3) == 0 || strncmp (env, "LANG", 4) == 0 || - strncmp (env, "LINGUAS", 7) == 0) - envs = g_list_prepend (envs, g_strdup (env)); - if (preserve_ld_vars && - strncmp (env, "LD_", 3) == 0) - envs = g_list_prepend (envs, g_strdup (env)); - } - - ve_clearenv (); - - for (li = envs; li != NULL; li = li->next) { - putenv (li->data); - } - - g_list_free (envs); -} - - -/* - * Clear environment completely - * note that this leaks memory so only use before exec - * (keep LD_* if preserve_ld_vars is true) - */ -void -gdm_clearenv (void) -{ - int i; - GList *li, *envs = NULL; - - for (i = 0; environ[i] != NULL; i++) { - char *env = environ[i]; - if (preserve_ld_vars && - strncmp (env, "LD_", 3) == 0) + strncmp (env, "LINGUAS", 7) == 0) { envs = g_list_prepend (envs, g_strdup (env)); + } } ve_clearenv (); @@ -458,7 +285,7 @@ gdm_get_free_display (int start, uid_t server_uid) { int sock; int i; - struct sockaddr_in serv_addr = {0}; + struct sockaddr_in serv_addr = { 0 }; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); @@ -473,6 +300,9 @@ gdm_get_free_display (int start, uid_t server_uid) char buf[256]; FILE *fp; int r; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); for (li = displays; li != NULL; li = li->next) { GdmDisplay *dsp = li->data; @@ -487,7 +317,7 @@ gdm_get_free_display (int start, uid_t server_uid) #ifdef ENABLE_IPV6 if (have_ipv6 ()) { - struct sockaddr_in6 serv6_addr= {0}; + struct sockaddr_in6 serv6_addr = { 0 }; sock = socket (AF_INET6, SOCK_STREAM,0); @@ -778,7 +608,8 @@ gdm_text_yesno_dialog (const char *msg, gboolean *ret) } int -gdm_exec_wait (char * const *argv, gboolean no_display, +gdm_exec_wait (char * const *argv, + gboolean no_display, gboolean de_setuid) { int status; @@ -789,9 +620,11 @@ gdm_exec_wait (char * const *argv, gboolean no_display, g_access (argv[0], X_OK) != 0) return -1; + g_debug ("Forking extra process: %s", argv[0]); + pid = gdm_fork_extra (); if (pid == 0) { - closelog (); + gdm_log_shutdown (); gdm_close_all_descriptors (0 /* from */, -1 /* except */, -1 /* except2 */); @@ -807,13 +640,13 @@ gdm_exec_wait (char * const *argv, gboolean no_display, gdm_desetuid (); } - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_init (); if (no_display) { g_unsetenv ("DISPLAY"); g_unsetenv ("XAUTHORITY"); } - + VE_IGNORE_EINTR (execv (argv[0], argv)); _exit (-1); @@ -822,7 +655,7 @@ gdm_exec_wait (char * const *argv, gboolean no_display, if (pid < 0) return -1; - gdm_wait_for_extra (&status); + gdm_wait_for_extra (pid, &status); if (WIFEXITED (status)) return WEXITSTATUS (status); @@ -929,9 +762,9 @@ gdm_fork_extra (void) gdm_sigchld_block_push (); gdm_sigterm_block_push (); - pid = extra_process = fork (); + pid = fork (); if (pid < 0) - extra_process = 0; + return 0; else if (pid == 0) /* * Unset signals here, and yet again @@ -968,17 +801,19 @@ gdm_fork_extra (void) } void -gdm_wait_for_extra (int *status) +gdm_wait_for_extra (pid_t pid, + int *statusp) { + int status; + gdm_sigchld_block_push (); - if (extra_process > 1) { - ve_waitpid_no_signal (extra_process, &extra_status, 0); + if (pid > 1) { + ve_waitpid_no_signal (pid, &status, 0); } - extra_process = 0; - if (status != NULL) - *status = extra_status; + if (statusp != NULL) + *statusp = status; gdm_sigchld_block_pop (); } @@ -1045,70 +880,49 @@ gdm_ensure_sanity (void) } const GList * -gdm_peek_local_address_list (void) +gdm_address_peek_local_list (void) { static GList *the_list = NULL; static time_t last_time = 0; - struct sockaddr_in *sin; -#ifdef ENABLE_IPV6 char hostbuf[BUFSIZ]; - struct sockaddr_in6 *sin6; - struct addrinfo hints, *result, *res; -#else /* ENABLE_IPV6 */ - int sockfd; -#ifdef SIOCGIFCONF - struct ifconf ifc; - struct ifreq *ifr; - char *buf; - int num; -#else /* SIOCGIFCONF */ - char hostbuf[BUFSIZ]; - struct hostent *he; -#endif -#endif + struct addrinfo hints; + struct addrinfo *result; + struct addrinfo *res; /* Don't check more then every 5 seconds */ - if (last_time + 5 > time (NULL)) + if (last_time + 5 > time (NULL)) { return the_list; + } g_list_foreach (the_list, (GFunc)g_free, NULL); g_list_free (the_list); the_list = NULL; last_time = time (NULL); -#ifdef ENABLE_IPV6 + hostbuf[BUFSIZ-1] = '\0'; if (gethostname (hostbuf, BUFSIZ-1) != 0) { - gdm_debug ("%s: Could not get server hostname", "gdm_peek_local_address_list"); - - sin6 = g_new0 (struct sockaddr_in6, 1); - sin6->sin6_family = AF_INET6; - sin6->sin6_addr = in6addr_loopback; - return g_list_append (the_list, sin6); + gdm_debug ("%s: Could not get server hostname, using localhost", "gdm_peek_local_address_list"); + snprintf (hostbuf, BUFSIZ-1, "localhost"); } + memset (&hints, 0, sizeof (hints)); + hints.ai_family = AF_INET; +#ifdef ENABLE_IPV6 + hints.ai_family |= AF_INET6; +#endif + if (getaddrinfo (hostbuf, NULL, &hints, &result) != 0) { gdm_debug ("%s: Could not get address from hostname!", "gdm_peek_local_address_list"); - sin6 = g_new0 (struct sockaddr_in6, 1); - sin6->sin6_family = AF_INET6; - sin6->sin6_addr = in6addr_loopback; - return g_list_append (the_list, sin6); + return NULL; } - for (res = result; res; res = res->ai_next) { - if (res->ai_family == AF_INET6) { - sin6 = g_new0 (struct sockaddr_in6, 1); - sin6->sin6_family = AF_INET6; - memcpy (sin6, res->ai_addr, res->ai_addrlen); - the_list = g_list_append (the_list, sin6); - } - else if (res->ai_family == AF_INET) { - sin = g_new0 (struct sockaddr_in, 1); - sin->sin_family = AF_INET; - memcpy (sin, res->ai_addr, res->ai_addrlen); - the_list = g_list_append (the_list, sin); - } + for (res = result; res != NULL; res = res->ai_next) { + struct sockaddr_storage *sa; + + sa = g_memdup (res->ai_addr, res->ai_addrlen); + the_list = g_list_append (the_list, sa); } if (result) { @@ -1116,168 +930,33 @@ gdm_peek_local_address_list (void) result = NULL; } -#else /* ENABLE_IPV6 */ - -#ifdef SIOCGIFCONF - /* Create an IPv4 socket to pick IPv4 addresses */ - sockfd = socket (AF_INET, SOCK_DGRAM, 0); /* UDP */ - -#ifdef SIOCGIFNUM - if (ioctl (sockfd, SIOCGIFNUM, &num) < 0) { - num = 64; - } -#else - num = 64; -#endif - - ifc.ifc_len = sizeof (struct ifreq) * num; - ifc.ifc_buf = buf = g_malloc0 (ifc.ifc_len); - if G_UNLIKELY (ioctl (sockfd, SIOCGIFCONF, &ifc) < 0) { - gdm_error (_("%s: Cannot get local addresses!"), - "gdm_peek_local_address_list"); - g_free (buf); - VE_IGNORE_EINTR (close (sockfd)); - sin = g_new0 (struct sockaddr_in, 1); - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = INADDR_LOOPBACK; - return g_list_append (NULL, sin); - } - - ifr = ifc.ifc_req; - num = ifc.ifc_len / sizeof (struct ifreq); - for (; num-- > 0; ifr++) { - struct sockaddr_in *addr; - - if (ioctl (sockfd, SIOCGIFFLAGS, ifr) < 0 || - ! (ifr->ifr_flags & IFF_UP)) - continue; -#ifdef IFF_UNNUMBERED - if (ifr->ifr_flags & IFF_UNNUMBERED) - continue; -#endif - if (ioctl (sockfd, SIOCGIFADDR, ifr) < 0) - continue; - - sin = (struct sockaddr_in *)&ifr->ifr_addr; - - if (sin->sin_family != AF_INET || - sin->sin_addr.s_addr == INADDR_ANY || - sin->sin_addr.s_addr == INADDR_LOOPBACK) - continue; - addr = g_new0 (struct sockaddr_in, 1); - memcpy (addr, sin, sizeof (struct sockaddr_in)); - the_list = g_list_append (the_list, addr); - } - - VE_IGNORE_EINTR (close (sockfd)); - g_free (buf); -#else /* SIOCGIFCONF */ - /* host based fallback, will likely only get 127.0.0.1 i think */ - - hostbuf[BUFSIZ-1] = '\0'; - sin = g_new0 (struct sockaddr_in, 1); - sin->sin_family = AF_INET; - if G_UNLIKELY (gethostname (hostbuf, BUFSIZ-1) != 0) { - gdm_debug ("%s: Could not get server hostname: %s!", - "gdm_peek_local_address_list", - strerror (errno)); - sin->sin_addr.s_addr = INADDR_LOOPBACK; - return g_list_append (NULL, sin); - } - he = gethostbyname (hostbuf); - if G_UNLIKELY (he == NULL) { - gdm_debug ("%s: Could not get address from hostname!", - "gdm_peek_local_address_list"); - sin->sin_addr.s_addr = INADDR_LOOPBACK; - return g_list_append (NULL, sin); - } - for (i = 0; he->h_addr_list[i] != NULL; i++) { - struct in_addr *laddr = (struct in_addr *)he->h_addr_list[i]; - - memcpy (&sin->sin_addr, laddr, sizeof (struct in_addr)); - the_list = g_list_append (the_list, sin); - } -#endif -#endif /* ENABLE_IPV6 */ - return the_list; } -#ifdef ENABLE_IPV6 -gboolean -gdm_is_local_addr6 (struct in6_addr* ia) -{ - - if (IN6_IS_ADDR_LOOPBACK (ia)) { - return TRUE; - - } else { - const GList *list = gdm_peek_local_address_list (); - - while (list != NULL) { - struct sockaddr *addr = list->data; - - if ((addr->sa_family == AF_INET6) && (memcmp (ia, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof (struct in6_addr)) == 0)) { - return TRUE; - } - - list = list->next; - } - - return FALSE; - } -} -#endif gboolean -gdm_is_local_addr (struct in_addr *ia) +gdm_address_is_local (struct sockaddr_storage *sa) { - const char lo[] = {127,0,0,1}; + const GList *list; - if (ia->s_addr == INADDR_LOOPBACK || - memcmp (&ia->s_addr, lo, 4) == 0) { + if (gdm_address_is_loopback (sa)) { return TRUE; - } else { - const GList *list = gdm_peek_local_address_list (); + } - while (list != NULL) { - struct sockaddr *addr = list->data; + list = gdm_address_peek_local_list (); - if ((addr->sa_family == AF_INET ) && - (memcmp (ia, &(((struct sockaddr_in *)addr)->sin_addr), 4) == 0)) { - return TRUE; - } + while (list != NULL) { + struct sockaddr_storage *addr = list->data; - list = list->next; + if (gdm_address_equal (sa, addr)) { + return TRUE; } - return FALSE; + list = list->next; } -} - -#ifdef ENABLE_IPV6 -gboolean -gdm_is_loopback_addr6 (struct in6_addr *ia) -{ - if (IN6_IS_ADDR_LOOPBACK(ia)) - return TRUE; return FALSE; } -#endif - -gboolean -gdm_is_loopback_addr (struct in_addr *ia) -{ - const char lo[] = {127,0,0,1}; - - if (ia->s_addr == INADDR_LOOPBACK || - memcmp (&ia->s_addr, lo, 4) == 0) { - return TRUE; - } else { - return FALSE; - } -} gboolean gdm_setup_gids (const char *login, gid_t gid) @@ -1505,7 +1184,7 @@ gdm_open_dev_null (mode_t mode) void gdm_unset_signals (void) { - sigset_t mask; + sigset_t mask; sigemptyset (&mask); sigprocmask (SIG_SETMASK, &mask, NULL); @@ -1555,84 +1234,21 @@ gdm_signal_default (int signal) "gdm_signal_ignore", signal, "SIG_DFL"); } - -static char * -ascify (const char *text) -{ - unsigned char *p; - char *t = g_strdup (text); - for (p = (unsigned char *)t; p != NULL && *p != '\0'; p++) { - if (*p > 127) - *p = '?'; - } - return t; -} - -char * -gdm_locale_to_utf8 (const char *text) -{ - GIConv cd; - char *out; - - if (gdm_charset == NULL) { - return g_strdup (text); - } - - cd = g_iconv_open ("UTF-8", gdm_charset); - if (cd == (GIConv)(-1)) { - return ascify (text); - } - - out = g_convert_with_iconv (text, -1, cd, NULL, NULL, NULL /* error */); - g_iconv_close (cd); - if (out == NULL) { - return ascify (text); - } - return out; -} - -char * -gdm_locale_from_utf8 (const char *text) -{ - GIConv cd; - char *out; - - if (gdm_charset == NULL) { - return g_strdup (text); - } - - cd = g_iconv_open (gdm_charset, "UTF-8"); - if (cd == (GIConv)(-1)) { - return ascify (text); - } - - out = g_convert_with_iconv (text, -1, cd, NULL, NULL, NULL /* error */); - g_iconv_close (cd); - if (out == NULL) - return ascify (text); - return out; -} - static GdmHostent * -#ifdef ENABLE_IPV6 -fillout_addrinfo (struct addrinfo *res, struct sockaddr *ia, const char *name) -#else -fillout_hostent (struct hostent *he_, struct in_addr *ia, const char *name) -#endif +fillout_addrinfo (struct addrinfo *res, + struct sockaddr *ia, + const char *name) { GdmHostent *he; - -#ifdef ENABLE_IPV6 gint i; gint addr_count = 0; struct addrinfo *tempaddrinfo; -#endif + he = g_new0 (GdmHostent, 1); he->addrs = NULL; he->addr_count = 0; -#ifdef ENABLE_IPV6 if (res != NULL && res->ai_canonname != NULL) { he->hostname = g_strdup (res->ai_canonname); he->not_found = FALSE; @@ -1641,23 +1257,25 @@ fillout_hostent (struct hostent *he_, struct in_addr *ia, const char *name) if (name != NULL) he->hostname = g_strdup (name); else { - static char buffer6[INET6_ADDRSTRLEN], buffer[INET_ADDRSTRLEN]; + static char buffer6[INET6_ADDRSTRLEN]; + static char buffer[INET_ADDRSTRLEN]; const char *new = NULL; if (ia->sa_family == AF_INET6) { - if (IN6_IS_ADDR_V4MAPPED (&((struct sockaddr_in6 *)ia)->sin6_addr)) + if (IN6_IS_ADDR_V4MAPPED (&((struct sockaddr_in6 *)ia)->sin6_addr)) { new = inet_ntop (AF_INET, &(((struct sockaddr_in6 *)ia)->sin6_addr.s6_addr[12]), buffer, sizeof (buffer)); - - else + } else { new = inet_ntop (AF_INET6, &((struct sockaddr_in6 *)ia)->sin6_addr, buffer6, sizeof (buffer6)); - } - else if (ia->sa_family == AF_INET) + } + } else if (ia->sa_family == AF_INET) { new = inet_ntop (AF_INET, &((struct sockaddr_in *)ia)->sin_addr, buffer, sizeof (buffer)); + } - if (new) + if (new != NULL) { he->hostname = g_strdup (new); - else + } else { he->hostname = NULL; + } } } @@ -1671,7 +1289,7 @@ fillout_hostent (struct hostent *he_, struct in_addr *ia, const char *name) he->addrs = g_new0 (struct sockaddr_storage, addr_count); he->addr_count = addr_count; res = tempaddrinfo; - for (i = 0; ;i++) { + for (i = 0; ; i++) { if (res == NULL) break; @@ -1687,43 +1305,7 @@ fillout_hostent (struct hostent *he_, struct in_addr *ia, const char *name) strncmp (he->hostname, "::ffff:", 7) == 0) { strcpy (he->hostname, he->hostname + 7); } -#else - /* - * Sometimes if we can't look things up, we could end - * up with a dot in the name field which would screw - * us up. Weird but apparently possible - */ - if (he_ != NULL && - he_->h_name != NULL && - he_->h_name[0] != '\0' && - strcmp (he_->h_name, ".") != 0) { - he->hostname = g_strdup (he_->h_name); - he->not_found = FALSE; - } else { - he->not_found = TRUE; - if (name != NULL) - he->hostname = g_strdup (name); - else /* Either ia or name is set */ - he->hostname = g_strdup (inet_ntoa (*ia)); - } - if (he_ != NULL && he_->h_addrtype == AF_INET) { - int i; - for (i = 0; ; i++) { - struct in_addr *ia_ = (struct in_addr *) (he_->h_addr_list[i]); - if (ia_ == NULL) - break; - } - he->addrs = g_new0 (struct in_addr, i); - he->addr_count = i; - for (i = 0; ; i++) { - struct in_addr *ia_ = (struct in_addr *) he_->h_addr_list[i]; - if (ia_ == NULL) - break; - (he->addrs)[i] = *ia_; - } - } -#endif return he; } @@ -1755,7 +1337,7 @@ jumpback_sighandler (int signal) the SIGTERM handler in slave.c might have in fact done the big Longjmp to the slave's death */ - + if (old_do_jumpback) { Longjmp (signal_jumpback, 1); } @@ -1808,14 +1390,10 @@ jumpback_sighandler (int signal) GdmHostent * gdm_gethostbyname (const char *name) { -#ifdef ENABLE_IPV6 struct addrinfo hints; /* static because of Setjmp */ static struct addrinfo *result; -#else - /* static because of Setjmp */ - static struct hostent * he_; -#endif + SETUP_INTERRUPTS_FOR_TERM_DECLS /* The cached address */ @@ -1823,10 +1401,6 @@ gdm_gethostbyname (const char *name) static time_t last_time = 0; static char *cached_hostname = NULL; -#ifndef ENABLE_IPV6 - he_ = NULL; -#endif - if (cached_hostname != NULL && strcmp (cached_hostname, name) == 0) { /* Don't check more then every 60 seconds */ @@ -1838,8 +1412,8 @@ gdm_gethostbyname (const char *name) if (Setjmp (signal_jumpback) == 0) { do_jumpback = TRUE; + /* Find client hostname */ -#ifdef ENABLE_IPV6 memset (&hints, 0, sizeof (hints)); hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_CANONNAME; @@ -1855,14 +1429,6 @@ gdm_gethostbyname (const char *name) /* Here we got interrupted */ result = NULL; } -#else - he_ = gethostbyname (name); - do_jumpback = FALSE; - } else { - /* Here we got interrupted */ - he_ = NULL; - } -#endif SETUP_INTERRUPTS_FOR_TERM_TEARDOWN @@ -1870,34 +1436,23 @@ gdm_gethostbyname (const char *name) cached_hostname = g_strdup (name); gdm_hostent_free (he); -#ifdef ENABLE_IPV6 + he = fillout_addrinfo (result, NULL, name); -#else - he = fillout_hostent (he_, NULL, name); -#endif last_time = time (NULL); return gdm_hostent_copy (he); } GdmHostent * -#ifdef ENABLE_IPV6 -gdm_gethostbyaddr (struct sockaddr_storage *ia) -#else -gdm_gethostbyaddr (struct sockaddr_in *ia) -#endif +gdm_gethostbyaddr (struct sockaddr_storage *ia) { -#ifdef ENABLE_IPV6 struct addrinfo hints; /* static because of Setjmp */ static struct addrinfo *result = NULL; struct sockaddr_in6 sin6; struct sockaddr_in sin; static struct in6_addr cached_addr6; -#else - /* static because of Setjmp */ - static struct hostent * he_; -#endif + SETUP_INTERRUPTS_FOR_TERM_DECLS /* The cached address */ @@ -1905,19 +1460,12 @@ gdm_gethostbyaddr (struct sockaddr_in *ia) static time_t last_time = 0; static struct in_addr cached_addr; -#ifndef ENABLE_IPV6 - he_ = NULL; -#endif - if (last_time != 0) { -#ifdef ENABLE_IPV6 if ((ia->ss_family == AF_INET6) && (memcmp (cached_addr6.s6_addr, ((struct sockaddr_in6 *) ia)->sin6_addr.s6_addr, sizeof (struct in6_addr)) == 0)) { /* Don't check more then every 60 seconds */ if (last_time + 60 > time (NULL)) return gdm_hostent_copy (he); - } else if (ia->ss_family == AF_INET) -#endif - { + } else if (ia->ss_family == AF_INET) { if (memcmp (&cached_addr, &(((struct sockaddr_in *)ia)->sin_addr), sizeof (struct in_addr)) == 0) { /* Don't check more then every 60 seconds */ if (last_time + 60 > time (NULL)) @@ -1930,9 +1478,8 @@ gdm_gethostbyaddr (struct sockaddr_in *ia) if (Setjmp (signal_jumpback) == 0) { do_jumpback = TRUE; - /* Find client hostname */ -#ifdef ENABLE_IPV6 + /* Find client hostname */ memset (&hints, 0, sizeof (hints)); hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_CANONNAME; @@ -1956,8 +1503,8 @@ gdm_gethostbyaddr (struct sockaddr_in *ia) strcpy (buffer6, temp); } getaddrinfo (buffer6, NULL, &hints, &result); - } - else if (ia->ss_family == AF_INET) { + + } else if (ia->ss_family == AF_INET) { char buffer[INET_ADDRSTRLEN]; inet_ntop (AF_INET, &((struct sockaddr_in *)ia)->sin_addr, buffer, sizeof (buffer)); @@ -1970,19 +1517,9 @@ gdm_gethostbyaddr (struct sockaddr_in *ia) /* Here we got interrupted */ result = NULL; } -#else - he_ = NULL; - he_ = gethostbyaddr ((gchar *) &(ia->sin_addr), sizeof (struct in_addr), AF_INET); - do_jumpback = FALSE; - } else { - /* Here we got interrupted */ - he_ = NULL; - } -#endif SETUP_INTERRUPTS_FOR_TERM_TEARDOWN -#ifdef ENABLE_IPV6 if (ia->ss_family == AF_INET6) { memcpy (cached_addr6.s6_addr, ((struct sockaddr_in6 *)ia)->sin6_addr.s6_addr, sizeof (struct in6_addr)); memset (&sin6, 0, sizeof (sin6)); @@ -1997,10 +1534,7 @@ gdm_gethostbyaddr (struct sockaddr_in *ia) sin.sin_family = AF_INET; he = fillout_addrinfo (result, (struct sockaddr *)&sin, NULL); } -#else - cached_addr = ia->sin_addr; - he = fillout_hostent (he_, &(ia->sin_addr), NULL); -#endif + last_time = time (NULL); return gdm_hostent_copy (he); } @@ -2021,13 +1555,8 @@ gdm_hostent_copy (GdmHostent *he) cpy->addrs = NULL; } else { cpy->addr_count = he->addr_count; -#ifdef ENABLE_IPV6 cpy->addrs = g_new0 (struct sockaddr_storage, he->addr_count); memcpy (cpy->addrs, he->addrs, sizeof (struct sockaddr_storage) * he->addr_count); -#else - cpy->addrs = g_new0 (struct in_addr, he->addr_count); - memcpy (cpy->addrs, he->addrs, sizeof (struct in_addr) * he->addr_count); -#endif } return cpy; } @@ -2612,7 +2141,7 @@ gdm_console_translate (const char *str) * This function is used to support systems that have the /etc/default/login * interface to control programs that affect security. This is a Solaris * thing, though some users on other systems may find it useful. - */ + */ gchar * gdm_read_default (gchar *key) { diff --git a/daemon/misc.h b/daemon/misc.h index 51edb497..2a93f69c 100644 --- a/daemon/misc.h +++ b/daemon/misc.h @@ -19,44 +19,19 @@ #ifndef GDM_MISC_H #define GDM_MISC_H -#ifndef __PRETTY_FUNCTION__ -#define __PRETTY_FUNCTION__ "N/A" -#endif - +#include <stdio.h> #include <sys/types.h> #include "gdm.h" - -void gdm_fail (const gchar *format, ...) G_GNUC_PRINTF (1, 2); -void gdm_info (const gchar *format, ...) G_GNUC_PRINTF (1, 2); -void gdm_error (const gchar *format, ...) G_GNUC_PRINTF (1, 2); -void gdm_debug (const gchar *format, ...) G_GNUC_PRINTF (1, 2); - -#define gdm_assert(expr) G_STMT_START{ \ - if G_LIKELY(expr) { } else \ - gdm_fail ("GDM file %s: line %d (%s): assertion failed: (%s)", \ - __FILE__, \ - __LINE__, \ - __PRETTY_FUNCTION__, \ - #expr); }G_STMT_END - -#define gdm_assert_not_reached() G_STMT_START{ \ - gdm_fail ("GDM file %s: line %d (%s): should not be reached", \ - __FILE__, \ - __LINE__, \ - __PRETTY_FUNCTION__); }G_STMT_END +#include "display.h" void gdm_fdprintf (int fd, const gchar *format, ...) G_GNUC_PRINTF (2, 3); int gdm_fdgetc (int fd); char *gdm_fdgets (int fd); -/* Note that these can actually clear environment without killing - * the LD_* env vars if --preserve-ld-vars was passed to the - * main daemon */ /* clear environment, but keep the i18n ones (LANG, LC_ALL, etc...), * note that this leak memory so only use before exec */ void gdm_clearenv_no_lang (void); -void gdm_clearenv (void); int gdm_get_free_display (int start, uid_t server_uid); @@ -79,16 +54,10 @@ void gdm_sigusr2_block_push (void); void gdm_sigusr2_block_pop (void); pid_t gdm_fork_extra (void); -void gdm_wait_for_extra (int *status); - -const GList * gdm_peek_local_address_list (void); -gboolean gdm_is_local_addr (struct in_addr *ia); -gboolean gdm_is_loopback_addr (struct in_addr *ia); +void gdm_wait_for_extra (pid_t pid, int *status); -#ifdef ENABLE_IPV6 -gboolean gdm_is_local_addr6 (struct in6_addr* ia); -gboolean gdm_is_loopback_addr6 (struct in6_addr *ia); -#endif +const GList * gdm_address_peek_local_list (void); +gboolean gdm_address_is_local (struct sockaddr_storage *sa); typedef struct { gboolean not_found; /* hostname below set to fallback, @@ -96,20 +65,14 @@ typedef struct { char *hostname; /* never a bogus dot, if invalid/unknown, then set to the ip address in string form */ -#ifdef ENABLE_IPV6 + struct sockaddr_storage *addrs; -#else - struct in_addr *addrs; /* array */ -#endif int addr_count; } GdmHostent; GdmHostent * gdm_gethostbyname (const char *name); -#ifdef ENABLE_IPV6 + GdmHostent *gdm_gethostbyaddr (struct sockaddr_storage *ia); -#else -GdmHostent * gdm_gethostbyaddr (struct sockaddr_in *ia); -#endif GdmHostent * gdm_hostent_copy (GdmHostent *he); void gdm_hostent_free (GdmHostent *he); @@ -125,9 +88,6 @@ int gdm_open_dev_null (mode_t mode); void gdm_unset_signals (void); -char * gdm_locale_to_utf8 (const char *text); -char * gdm_locale_from_utf8 (const char *text); - void gdm_saveenv (void); const char * gdm_saved_getenv (const char *var); /* leaks */ @@ -182,6 +142,34 @@ const char * gdm_console_translate (const char *str); gchar * gdm_read_default (gchar *key); -#endif /* GDM_MISC_H */ +#define NEVER_FAILS_seteuid(uid) \ + { int r = 0; \ + if (geteuid () != uid) \ + r = seteuid (uid); \ + if G_UNLIKELY (r != 0) \ + gdm_fail ("GDM file %s: line %d (%s): Cannot run seteuid to %d: %s", \ + __FILE__, \ + __LINE__, \ + __PRETTY_FUNCTION__, \ + (int)uid, \ + strerror (errno)); } +#define NEVER_FAILS_setegid(gid) \ + { int r = 0; \ + if (getegid () != gid) \ + r = setegid (gid); \ + if G_UNLIKELY (r != 0) \ + gdm_fail ("GDM file %s: line %d (%s): Cannot run setegid to %d: %s", \ + __FILE__, \ + __LINE__, \ + __PRETTY_FUNCTION__, \ + (int)gid, \ + strerror (errno)); } + +/* first goes to euid-root and then sets the egid and euid, to make sure + * this succeeds */ +#define NEVER_FAILS_root_set_euid_egid(uid,gid) \ + { NEVER_FAILS_seteuid (0); \ + NEVER_FAILS_setegid (gid); \ + if (uid != 0) { NEVER_FAILS_seteuid (uid); } } -/* EOF */ +#endif /* GDM_MISC_H */ diff --git a/daemon/server.c b/daemon/server.c index ca7d440c..e81c3e86 100644 --- a/daemon/server.c +++ b/daemon/server.c @@ -36,7 +36,6 @@ #include <sys/resource.h> #include <strings.h> #include <signal.h> -#include <syslog.h> #include <errno.h> #include <time.h> #include <ctype.h> @@ -52,22 +51,22 @@ #include "getvt.h" #include "gdm-common.h" +#include "gdm-log.h" #include "gdm-daemon-config.h" +#include "gdm-socket-protocol.h" + /* Local prototypes */ static void gdm_server_spawn (GdmDisplay *d, const char *vtarg); static void gdm_server_usr1_handler (gint); static void gdm_server_child_handler (gint); static char * get_font_path (const char *display); -extern pid_t extra_process; -extern int extra_status; -extern int gdm_in_signal; - /* Global vars */ static GdmDisplay *d = NULL; static gboolean server_signal_notified = FALSE; static int server_signal_pipe[2]; +static int gdm_in_signal = 0; static void do_server_wait (GdmDisplay *d); static gboolean setup_server_wait (GdmDisplay *d); @@ -145,6 +144,8 @@ gdm_exec_fbconsole (GdmDisplay *disp) argv[2] = disp->name; argv[3] = NULL; + g_debug ("Forking fbconsole"); + pid = fork (); if (pid == 0) { gdm_close_all_descriptors (0 /* from */, -1 /* except */, -1 /* except2 */) @@ -1180,6 +1181,8 @@ gdm_server_spawn (GdmDisplay *d, const char *vtarg) /* Fork into two processes. Parent remains the gdm process. Child * becomes the X server. */ + g_debug ("Forking X server process"); + gdm_sigterm_block_push (); pid = d->servpid = fork (); if (pid == 0) @@ -1193,7 +1196,7 @@ gdm_server_spawn (GdmDisplay *d, const char *vtarg) /* the pops whacked mask again */ gdm_unset_signals (); - closelog (); + gdm_log_shutdown (); /* close things */ gdm_close_all_descriptors (0 /* from */, -1 /* except */, -1 /* except2 */); @@ -1204,7 +1207,7 @@ gdm_server_spawn (GdmDisplay *d, const char *vtarg) gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */ gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */ - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_init (); /* Rotate the X server logs */ rotate_logs (d->name); @@ -1460,12 +1463,12 @@ gdm_server_child_handler (int signal) * Allocate display structure for a local X server */ -GdmDisplay * +GdmDisplay * gdm_server_alloc (gint id, const gchar *command) { gchar hostname[1024]; GdmDisplay *d; - + hostname[1023] = '\0'; if (gethostname (hostname, 1023) == -1) strcpy (hostname, "localhost.localdomain"); @@ -1527,7 +1530,7 @@ gdm_server_alloc (gint id, const gchar *command) d->chooser_last_line = NULL; d->theme_name = NULL; - + return d; } diff --git a/daemon/server.h b/daemon/server.h index cce65801..1b753486 100644 --- a/daemon/server.h +++ b/daemon/server.h @@ -1,4 +1,6 @@ -/* GDM - The GNOME Display Manager +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * 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 @@ -19,7 +21,30 @@ #ifndef GDM_SERVER_H #define GDM_SERVER_H -#include "gdm.h" +#include "display.h" + +typedef struct _GdmXserver GdmXserver; + +struct _GdmXserver +{ + char *id; + char *name; + char *command; + gboolean flexible; + gboolean choosable; /* not implemented yet */ + gboolean chooser; /* instead of greeter, run chooser */ + gboolean handled; + int number; + int priority; +}; + +/* These are the servstat values, also used as server + * process exit codes */ +#define SERVER_TIMEOUT 2 /* Server didn't start */ +#define SERVER_DEAD 250 /* Server stopped */ +#define SERVER_PENDING 251 /* Server started but not ready for connections yet */ +#define SERVER_RUNNING 252 /* Server running and ready for connections */ +#define SERVER_ABORT 253 /* Server failed badly. Suspending display. */ /* Wipe cookie files */ void gdm_server_wipe_cookies (GdmDisplay *disp); diff --git a/daemon/slave.c b/daemon/slave.c index 5b4c9813..e68b119f 100644 --- a/daemon/slave.c +++ b/daemon/slave.c @@ -62,7 +62,6 @@ #include <grp.h> #include <errno.h> #include <time.h> -#include <syslog.h> #ifdef HAVE_TSOL #include <user_attr.h> @@ -91,8 +90,11 @@ #include "display.h" #include "gdm-common.h" +#include "gdm-log.h" #include "gdm-daemon-config.h" +#include "gdm-socket-protocol.h" + #ifdef WITH_CONSOLE_KIT #include "gdmconsolekit.h" #endif @@ -108,7 +110,7 @@ static gboolean do_timed_login = FALSE; /* if this is true, login the timed login */ static gboolean do_configurator = FALSE; /* if this is true, login as root * and start the configurator */ -static gboolean do_cancel = FALSE; /* if this is true, go back to +static gboolean do_cancel = FALSE; /* if this is true, go back to username entry & unselect face browser (if present) */ static gboolean do_restart_greeter = FALSE; /* if this is true, whack the @@ -137,6 +139,11 @@ static gchar *ParsedTimedLogin = NULL; static int greeter_fd_out = -1; static int greeter_fd_in = -1; +static int gdm_in_signal = 0; +static int gdm_normal_runlevel = -1; +static pid_t extra_process = 0; +static int extra_status = 0; + #ifdef HAVE_TSOL static gboolean have_suntsol_extension = FALSE; #endif @@ -150,11 +157,6 @@ static int slave_waitpid_w = -1; static GSList *slave_waitpids = NULL; extern gboolean gdm_first_login; -extern gboolean gdm_emergency_server; -extern pid_t extra_process; -extern int extra_status; -extern int gdm_in_signal; -extern int gdm_normal_runlevel; /* The slavepipe (like fifo) connection, this is the write end */ extern int slave_fifo_pipe_fd; @@ -162,8 +164,6 @@ extern int slave_fifo_pipe_fd; /* wait for a GO in the SOP protocol */ extern gboolean gdm_wait_for_go; -extern char *gdm_system_locale; - /* Local prototypes */ static gint gdm_slave_xerror_handler (Display *disp, XErrorEvent *evt); static gint gdm_slave_xioerror_handler (Display *disp); @@ -278,7 +278,7 @@ run_session_output (gboolean read_until_eof) int r, written; uid_t old; gid_t oldg; - + old = geteuid (); oldg = getegid (); @@ -358,8 +358,8 @@ run_session_output (gboolean read_until_eof) if G_UNLIKELY (d->xsession_errors_bytes >= MAX_XSESSION_ERRORS_BYTES && ! got_xfsz_signal) { VE_IGNORE_EINTR (write (d->xsession_errors_fd, - "\n...Too much output, ignoring rest...\n", - strlen ("\n...Too much output, ignoring rest...\n"))); + "\n...Too much output, ignoring rest...\n", + strlen ("\n...Too much output, ignoring rest...\n"))); } /* there wasn't more then buf available, so no need to try reading @@ -724,9 +724,34 @@ gdm_slave_xfsz_handler (int signal) } #endif /* SIGXFSZ */ -void + +static int +get_runlevel (void) +{ + int rl; + + rl = -1; +#ifdef __linux__ + /* on linux we get our current runlevel, for use later + * to detect a shutdown going on, and not mess up. */ + if (g_access ("/sbin/runlevel", X_OK) == 0) { + char ign; + int rnl; + FILE *fp = popen ("/sbin/runlevel", "r"); + if (fp != NULL) { + if (fscanf (fp, "%c %d", &ign, &rnl) == 2) { + rl = rnl; + } + pclose (fp); + } + } +#endif /* __linux__ */ + return rl; +} + +void gdm_slave_start (GdmDisplay *display) -{ +{ time_t first_time; int death_count; struct sigaction alrm, term, child, usr2; @@ -744,6 +769,8 @@ gdm_slave_start (GdmDisplay *display) */ d = display; + gdm_normal_runlevel = get_runlevel (); + /* Ignore SIGUSR1/SIGPIPE, and especially ignore it before the Setjmp */ gdm_signal_ignore (SIGUSR1); @@ -824,7 +851,7 @@ gdm_slave_start (GdmDisplay *display) sigemptyset (&child.sa_mask); sigaddset (&child.sa_mask, SIGCHLD); - if G_UNLIKELY (sigaction (SIGCHLD, &child, NULL) < 0) + if G_UNLIKELY (sigaction (SIGCHLD, &child, NULL) < 0) gdm_slave_exit (DISPLAY_ABORT, _("%s: Error setting up %s signal handler: %s"), "gdm_slave_start", "CHLD", strerror (errno)); @@ -936,15 +963,15 @@ gdm_tsol_init (GdmDisplay *display) int firsterror; have_suntsol_extension = XQueryExtension (display->dsp, - "SUN_TSOL", - &opcode, - &firstevent, - &firsterror); + "SUN_TSOL", + &opcode, + &firstevent, + &firsterror); } #endif -static void -gdm_screen_init (GdmDisplay *display) +static void +gdm_screen_init (GdmDisplay *display) { #ifdef HAVE_XFREE_XINERAMA int (* old_xerror_handler) (Display *, XErrorEvent *); @@ -994,28 +1021,28 @@ gdm_screen_init (GdmDisplay *display) XFree (xscreens); } else #elif HAVE_SOLARIS_XINERAMA - /* This code from GDK, Copyright (C) 2002 Sun Microsystems */ - int opcode; + /* This code from GDK, Copyright (C) 2002 Sun Microsystems */ + int opcode; int firstevent; int firsterror; int n_monitors = 0; gboolean have_xinerama = FALSE; have_xinerama = XQueryExtension (display->dsp, - "XINERAMA", - &opcode, - &firstevent, - &firsterror); + "XINERAMA", + &opcode, + &firstevent, + &firsterror); if (have_xinerama) { - + int result; XRectangle monitors[MAXFRAMEBUFFERS]; unsigned char hints[16]; int xineramascreen; - + result = XineramaGetInfo (display->dsp, 0, monitors, hints, &n_monitors); - /* Yes I know it should be Success but the current implementation + /* Yes I know it should be Success but the current implementation * returns the num of monitor */ if G_UNLIKELY (result <= 0) @@ -1041,15 +1068,15 @@ gdm_screen_init (GdmDisplay *display) } else #endif - { - display->screenx = 0; - display->screeny = 0; - display->screenwidth = 0; /* we'll use the gdk size */ - display->screenheight = 0; - - display->lrh_offsetx = 0; - display->lrh_offsety = 0; - } + { + display->screenx = 0; + display->screeny = 0; + display->screenwidth = 0; /* we'll use the gdk size */ + display->screenheight = 0; + + display->lrh_offsetx = 0; + display->lrh_offsety = 0; + } } static void @@ -1151,7 +1178,7 @@ ask_migrate (const char *migrate_to) askbuttons_msg = g_strdup_printf ("askbuttons_msg=%s$$options_msg1=%s$$options_msg2=%s$$options_msg3=%s$$options_msg4=%s", msg, but[0], but[1], but[2], but[3]); - + gdm_slave_send_string (GDM_SOP_SHOW_ASKBUTTONS_DIALOG, askbuttons_msg); r = atoi (gdm_ack_response); @@ -1183,7 +1210,7 @@ gdm_slave_check_user_wants_to_log_in (const char *user) gdm_slave_send_string (GDM_SOP_QUERYLOGIN, user); if G_LIKELY (ve_string_empty (gdm_ack_response)) - return TRUE; + return TRUE; vec = g_strsplit (gdm_ack_response, ",", -1); if (vec == NULL) return TRUE; @@ -1259,7 +1286,7 @@ gdm_slave_check_user_wants_to_log_in (const char *user) if (migrate_to == NULL) return TRUE; - + gdm_slave_send_string (GDM_SOP_MIGRATE, migrate_to); g_free (migrate_to); @@ -1291,181 +1318,181 @@ gdm_slave_check_user_wants_to_log_in (const char *user) static gboolean do_xfailed_on_xio_error = FALSE; -static void +static void gdm_slave_run (GdmDisplay *display) -{ - gint openretries = 0; - gint maxtries = 0; - gint pinginterval = gdm_daemon_config_get_value_int (GDM_KEY_PING_INTERVAL); - - gdm_reset_locale (); - - /* Reset d since gdm_slave_run is called in a loop */ - d = display; - - gdm_random_tick (); - - if (d->sleep_before_run > 0) { - gdm_debug ("gdm_slave_run: Sleeping %d seconds before server start", d->sleep_before_run); - gdm_sleep_no_signal (d->sleep_before_run); - d->sleep_before_run = 0; - - check_notifies_now (); - } - - /* - * Set it before we run the server, it may be that we're using - * the XOpenDisplay to find out if a server is ready (as with - * nested display) - */ - d->dsp = NULL; - - /* if this is local display start a server if one doesn't - * exist */ - if (SERVER_IS_LOCAL (d) && - d->servpid <= 0) { - if G_UNLIKELY ( ! gdm_server_start (d, - TRUE /* try_again_if_busy */, - FALSE /* treat_as_flexi */, - 20 /* min_flexi_disp */, - 5 /* flexi_retries */)) { - /* We're really not sure what is going on, - * so we throw up our hands and tell the user - * that we've given up. The error is likely something - * internal. */ - gdm_text_message_dialog - (C_(N_("Could not start the X\n" - "server (your graphical environment)\n" - "due to some internal error.\n" - "Please contact your system administrator\n" - "or check your syslog to diagnose.\n" - "In the meantime this display will be\n" - "disabled. Please restart GDM when\n" - "the problem is corrected."))); - gdm_slave_quick_exit (DISPLAY_ABORT); - } - gdm_slave_send_num (GDM_SOP_XPID, d->servpid); - - check_notifies_now (); - } - - /* We can use d->handled from now on on this display, - * since the lookup was done in server start */ - - g_setenv ("DISPLAY", d->name, TRUE); - g_unsetenv ("XAUTHORITY"); /* just in case it's set */ - - gdm_auth_set_local_auth (d); - - if (d->handled) { - /* Now the display name and hostname is final */ - - const char *automaticlogin = gdm_daemon_config_get_value_string (GDM_KEY_AUTOMATIC_LOGIN); - const char *timedlogin = gdm_daemon_config_get_value_string (GDM_KEY_TIMED_LOGIN); - - if (gdm_daemon_config_get_value_bool (GDM_KEY_AUTOMATIC_LOGIN_ENABLE) && - ! ve_string_empty (automaticlogin)) { - g_free (ParsedAutomaticLogin); - ParsedAutomaticLogin = gdm_parse_enriched_login (automaticlogin, +{ + gint openretries = 0; + gint maxtries = 0; + gint pinginterval = gdm_daemon_config_get_value_int (GDM_KEY_PING_INTERVAL); + + gdm_reset_locale (); + + /* Reset d since gdm_slave_run is called in a loop */ + d = display; + + gdm_random_tick (); + + if (d->sleep_before_run > 0) { + gdm_debug ("gdm_slave_run: Sleeping %d seconds before server start", d->sleep_before_run); + gdm_sleep_no_signal (d->sleep_before_run); + d->sleep_before_run = 0; + + check_notifies_now (); + } + + /* + * Set it before we run the server, it may be that we're using + * the XOpenDisplay to find out if a server is ready (as with + * nested display) + */ + d->dsp = NULL; + + /* if this is local display start a server if one doesn't + * exist */ + if (SERVER_IS_LOCAL (d) && + d->servpid <= 0) { + if G_UNLIKELY ( ! gdm_server_start (d, + TRUE /* try_again_if_busy */, + FALSE /* treat_as_flexi */, + 20 /* min_flexi_disp */, + 5 /* flexi_retries */)) { + /* We're really not sure what is going on, + * so we throw up our hands and tell the user + * that we've given up. The error is likely something + * internal. */ + gdm_text_message_dialog + (C_(N_("Could not start the X\n" + "server (your graphical environment)\n" + "due to some internal error.\n" + "Please contact your system administrator\n" + "or check your syslog to diagnose.\n" + "In the meantime this display will be\n" + "disabled. Please restart GDM when\n" + "the problem is corrected."))); + gdm_slave_quick_exit (DISPLAY_ABORT); + } + gdm_slave_send_num (GDM_SOP_XPID, d->servpid); + + check_notifies_now (); + } + + /* We can use d->handled from now on on this display, + * since the lookup was done in server start */ + + g_setenv ("DISPLAY", d->name, TRUE); + g_unsetenv ("XAUTHORITY"); /* just in case it's set */ + + gdm_auth_set_local_auth (d); + + if (d->handled) { + /* Now the display name and hostname is final */ + + const char *automaticlogin = gdm_daemon_config_get_value_string (GDM_KEY_AUTOMATIC_LOGIN); + const char *timedlogin = gdm_daemon_config_get_value_string (GDM_KEY_TIMED_LOGIN); + + if (gdm_daemon_config_get_value_bool (GDM_KEY_AUTOMATIC_LOGIN_ENABLE) && + ! ve_string_empty (automaticlogin)) { + g_free (ParsedAutomaticLogin); + ParsedAutomaticLogin = gdm_parse_enriched_login (automaticlogin, + display); + } + + if (gdm_daemon_config_get_value_bool (GDM_KEY_TIMED_LOGIN_ENABLE) && + ! ve_string_empty (timedlogin)) { + g_free (ParsedTimedLogin); + ParsedTimedLogin = gdm_parse_enriched_login (timedlogin, display); - } - - if (gdm_daemon_config_get_value_bool (GDM_KEY_TIMED_LOGIN_ENABLE) && - ! ve_string_empty (timedlogin)) { - g_free (ParsedTimedLogin); - ParsedTimedLogin = gdm_parse_enriched_login (timedlogin, - display); - } - } - - /* X error handlers to avoid the default one (i.e. exit (1)) */ - do_xfailed_on_xio_error = TRUE; - XSetErrorHandler (gdm_slave_xerror_handler); - XSetIOErrorHandler (gdm_slave_xioerror_handler); - - /* We keep our own (windowless) connection (dsp) open to avoid the - * X server resetting due to lack of active connections. */ - - gdm_debug ("gdm_slave_run: Opening display %s", d->name); - - /* if local then the the server should be ready for openning, so - * don't try so long before killing it and trying again */ - if (SERVER_IS_LOCAL (d)) - maxtries = 2; - else - maxtries = 10; - - while (d->handled && - openretries < maxtries && - d->dsp == NULL && - ( ! SERVER_IS_LOCAL (d) || d->servpid > 1)) { + } + } - gdm_sigchld_block_push (); - d->dsp = XOpenDisplay (d->name); - gdm_sigchld_block_pop (); - - if G_UNLIKELY (d->dsp == NULL) { - gdm_debug ("gdm_slave_run: Sleeping %d on a retry", 1+openretries*2); - gdm_sleep_no_signal (1+openretries*2); - openretries++; - } - } - - /* Really this will only be useful for the first local server, - since that's the only time this can really be on */ - while G_UNLIKELY (gdm_wait_for_go) { - struct timeval tv; - /* Wait 1 second. */ - tv.tv_sec = 1; - tv.tv_usec = 0; - select (0, NULL, NULL, NULL, &tv); - /* don't want to use sleep since we're using alarm - for pinging */ - check_notifies_now (); - } - - /* Set the busy cursor */ - if (d->dsp != NULL) { - Cursor xcursor = XCreateFontCursor (d->dsp, GDK_WATCH); - XDefineCursor (d->dsp, - DefaultRootWindow (d->dsp), - xcursor); - XFreeCursor (d->dsp, xcursor); - XSync (d->dsp, False); - } - - /* Just a race avoiding sleep, probably not necessary though, - * but doesn't hurt anything */ - if ( ! d->handled) - gdm_sleep_no_signal (1); - - if (SERVER_IS_LOCAL (d)) { - gdm_slave_send (GDM_SOP_START_NEXT_LOCAL, FALSE); - } - - check_notifies_now (); - - /* something may have gone wrong, try xfailed, if local (non-flexi), - * the toplevel loop of death will handle us */ - if G_UNLIKELY (d->handled && d->dsp == NULL) { - if (d->type == TYPE_STATIC) - gdm_slave_quick_exit (DISPLAY_XFAILED); - else - gdm_slave_quick_exit (DISPLAY_ABORT); - } - - /* OK from now on it's really the user whacking us most likely, - * we have already started up well */ - do_xfailed_on_xio_error = FALSE; - - /* If XDMCP setup pinging */ - if ( ! SERVER_IS_LOCAL (d) && pinginterval > 0) { - alarm (pinginterval); - } - - /* checkout xinerama */ - if (d->handled) - gdm_screen_init (d); + /* X error handlers to avoid the default one (i.e. exit (1)) */ + do_xfailed_on_xio_error = TRUE; + XSetErrorHandler (gdm_slave_xerror_handler); + XSetIOErrorHandler (gdm_slave_xioerror_handler); + + /* We keep our own (windowless) connection (dsp) open to avoid the + * X server resetting due to lack of active connections. */ + + gdm_debug ("gdm_slave_run: Opening display %s", d->name); + + /* if local then the the server should be ready for openning, so + * don't try so long before killing it and trying again */ + if (SERVER_IS_LOCAL (d)) + maxtries = 2; + else + maxtries = 10; + + while (d->handled && + openretries < maxtries && + d->dsp == NULL && + ( ! SERVER_IS_LOCAL (d) || d->servpid > 1)) { + + gdm_sigchld_block_push (); + d->dsp = XOpenDisplay (d->name); + gdm_sigchld_block_pop (); + + if G_UNLIKELY (d->dsp == NULL) { + gdm_debug ("gdm_slave_run: Sleeping %d on a retry", 1+openretries*2); + gdm_sleep_no_signal (1+openretries*2); + openretries++; + } + } + + /* Really this will only be useful for the first local server, + since that's the only time this can really be on */ + while G_UNLIKELY (gdm_wait_for_go) { + struct timeval tv; + /* Wait 1 second. */ + tv.tv_sec = 1; + tv.tv_usec = 0; + select (0, NULL, NULL, NULL, &tv); + /* don't want to use sleep since we're using alarm + for pinging */ + check_notifies_now (); + } + + /* Set the busy cursor */ + if (d->dsp != NULL) { + Cursor xcursor = XCreateFontCursor (d->dsp, GDK_WATCH); + XDefineCursor (d->dsp, + DefaultRootWindow (d->dsp), + xcursor); + XFreeCursor (d->dsp, xcursor); + XSync (d->dsp, False); + } + + /* Just a race avoiding sleep, probably not necessary though, + * but doesn't hurt anything */ + if ( ! d->handled) + gdm_sleep_no_signal (1); + + if (SERVER_IS_LOCAL (d)) { + gdm_slave_send (GDM_SOP_START_NEXT_LOCAL, FALSE); + } + + check_notifies_now (); + + /* something may have gone wrong, try xfailed, if local (non-flexi), + * the toplevel loop of death will handle us */ + if G_UNLIKELY (d->handled && d->dsp == NULL) { + if (d->type == TYPE_STATIC) + gdm_slave_quick_exit (DISPLAY_XFAILED); + else + gdm_slave_quick_exit (DISPLAY_ABORT); + } + + /* OK from now on it's really the user whacking us most likely, + * we have already started up well */ + do_xfailed_on_xio_error = FALSE; + + /* If XDMCP setup pinging */ + if ( ! SERVER_IS_LOCAL (d) && pinginterval > 0) { + alarm (pinginterval); + } + + /* checkout xinerama */ + if (d->handled) + gdm_screen_init (d); #ifdef HAVE_TSOL /* Check out Solaris Trusted Xserver extension */ @@ -1473,107 +1500,107 @@ gdm_slave_run (GdmDisplay *display) gdm_tsol_init (d); #endif - /* check log stuff for the server, this is done here - * because it's really a race */ - if (SERVER_IS_LOCAL (d)) - gdm_server_checklog (d); - - if ( ! d->handled) { - /* yay, we now wait for the server to die */ - while (d->servpid > 0) { - pause (); - } - gdm_slave_quick_exit (DISPLAY_REMANAGE); - } else if (d->use_chooser) { - /* this usually doesn't return */ - gdm_slave_chooser (); /* Run the chooser */ - return; - } else if (d->type == TYPE_STATIC && - gdm_first_login && - ! ve_string_empty (ParsedAutomaticLogin) && - strcmp (ParsedAutomaticLogin, gdm_root_user ()) != 0) { - gdm_first_login = FALSE; - - d->logged_in = TRUE; - gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE); - gdm_slave_send_string (GDM_SOP_LOGIN, ParsedAutomaticLogin); - - if (setup_automatic_session (d, ParsedAutomaticLogin)) { - gdm_slave_session_start (); - } - - gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE); - d->logged_in = FALSE; - gdm_slave_send_string (GDM_SOP_LOGIN, ""); - logged_in_uid = -1; - logged_in_gid = -1; - - gdm_debug ("gdm_slave_run: Automatic login done"); - - if (remanage_asap) { - gdm_slave_quick_exit (DISPLAY_REMANAGE); - } - - /* return to gdm_slave_start so that the server - * can be reinitted and all that kind of fun stuff. */ - return; - } - - if (gdm_first_login) - gdm_first_login = FALSE; - - do { - check_notifies_now (); - - if ( ! greet) { - gdm_slave_greeter (); /* Start the greeter */ - greeter_no_focus = FALSE; - greeter_disabled = FALSE; - } - - gdm_slave_wait_for_login (); /* wait for a password */ - - d->logged_in = TRUE; - gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE); - - if (do_timed_login) { - /* timed out into a timed login */ - do_timed_login = FALSE; - if (setup_automatic_session (d, ParsedTimedLogin)) { - gdm_slave_send_string (GDM_SOP_LOGIN, - ParsedTimedLogin); - gdm_slave_session_start (); - } - } else { - gdm_slave_send_string (GDM_SOP_LOGIN, login); - gdm_slave_session_start (); - } - - gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE); - d->logged_in = FALSE; - gdm_slave_send_string (GDM_SOP_LOGIN, ""); - logged_in_uid = -1; - logged_in_gid = -1; - - if (remanage_asap) { - gdm_slave_quick_exit (DISPLAY_REMANAGE); - } - - if (greet) { - greeter_no_focus = FALSE; - gdm_slave_greeter_ctl_no_ret (GDM_FOCUS, ""); - greeter_disabled = FALSE; - gdm_slave_greeter_ctl_no_ret (GDM_ENABLE, ""); - gdm_slave_greeter_ctl_no_ret (GDM_RESETOK, ""); - } - /* Note that greet is only true if the above was no 'login', - * so no need to reinit the server nor rebake cookies - * nor such nonsense */ - } while (greet); - - /* If XDMCP stop pinging */ - if ( ! SERVER_IS_LOCAL (d)) - alarm (0); + /* check log stuff for the server, this is done here + * because it's really a race */ + if (SERVER_IS_LOCAL (d)) + gdm_server_checklog (d); + + if ( ! d->handled) { + /* yay, we now wait for the server to die */ + while (d->servpid > 0) { + pause (); + } + gdm_slave_quick_exit (DISPLAY_REMANAGE); + } else if (d->use_chooser) { + /* this usually doesn't return */ + gdm_slave_chooser (); /* Run the chooser */ + return; + } else if (d->type == TYPE_STATIC && + gdm_first_login && + ! ve_string_empty (ParsedAutomaticLogin) && + strcmp (ParsedAutomaticLogin, gdm_root_user ()) != 0) { + gdm_first_login = FALSE; + + d->logged_in = TRUE; + gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE); + gdm_slave_send_string (GDM_SOP_LOGIN, ParsedAutomaticLogin); + + if (setup_automatic_session (d, ParsedAutomaticLogin)) { + gdm_slave_session_start (); + } + + gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE); + d->logged_in = FALSE; + gdm_slave_send_string (GDM_SOP_LOGIN, ""); + logged_in_uid = -1; + logged_in_gid = -1; + + gdm_debug ("gdm_slave_run: Automatic login done"); + + if (remanage_asap) { + gdm_slave_quick_exit (DISPLAY_REMANAGE); + } + + /* return to gdm_slave_start so that the server + * can be reinitted and all that kind of fun stuff. */ + return; + } + + if (gdm_first_login) + gdm_first_login = FALSE; + + do { + check_notifies_now (); + + if ( ! greet) { + gdm_slave_greeter (); /* Start the greeter */ + greeter_no_focus = FALSE; + greeter_disabled = FALSE; + } + + gdm_slave_wait_for_login (); /* wait for a password */ + + d->logged_in = TRUE; + gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE); + + if (do_timed_login) { + /* timed out into a timed login */ + do_timed_login = FALSE; + if (setup_automatic_session (d, ParsedTimedLogin)) { + gdm_slave_send_string (GDM_SOP_LOGIN, + ParsedTimedLogin); + gdm_slave_session_start (); + } + } else { + gdm_slave_send_string (GDM_SOP_LOGIN, login); + gdm_slave_session_start (); + } + + gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE); + d->logged_in = FALSE; + gdm_slave_send_string (GDM_SOP_LOGIN, ""); + logged_in_uid = -1; + logged_in_gid = -1; + + if (remanage_asap) { + gdm_slave_quick_exit (DISPLAY_REMANAGE); + } + + if (greet) { + greeter_no_focus = FALSE; + gdm_slave_greeter_ctl_no_ret (GDM_FOCUS, ""); + greeter_disabled = FALSE; + gdm_slave_greeter_ctl_no_ret (GDM_ENABLE, ""); + gdm_slave_greeter_ctl_no_ret (GDM_RESETOK, ""); + } + /* Note that greet is only true if the above was no 'login', + * so no need to reinit the server nor rebake cookies + * nor such nonsense */ + } while (greet); + + /* If XDMCP stop pinging */ + if ( ! SERVER_IS_LOCAL (d)) + alarm (0); } /* A hack really, this will wait around until the first mapped window @@ -1591,6 +1618,8 @@ focus_first_x_window (const char *class_res_name) p[1] = -1; } + g_debug ("Forking process to focus first X11 window"); + pid = fork (); if G_UNLIKELY (pid < 0) { if (p[0] != -1) @@ -1625,7 +1654,7 @@ focus_first_x_window (const char *class_res_name) gdm_unset_signals (); - closelog (); + gdm_log_shutdown (); gdm_close_all_descriptors (0 /* from */, p[1] /* except */, -1 /* except2 */); @@ -1635,7 +1664,7 @@ focus_first_x_window (const char *class_res_name) gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */ gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */ - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_init (); /* just in case it's set */ g_unsetenv ("XAUTHORITY"); @@ -1708,20 +1737,20 @@ run_config (GdmDisplay *display, struct passwd *pwent) { pid_t pid; - /* Lets check if custom.conf exists. If not there + /* Lets check if custom.conf exists. If not there is no point in launching gdmsetup as it will fail. We don't need to worry about defaults.conf as the daemon wont start without it */ if (gdm_daemon_config_get_custom_config_file () == NULL) { - gdm_error_box (d, + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("Could not access configuration file (custom.conf). " "Make sure that the file exists before launching " " login manager config utility.")); return; } - + /* Set the busy cursor */ if (d->dsp != NULL) { Cursor xcursor = XCreateFontCursor (d->dsp, GDK_WATCH); @@ -1732,6 +1761,8 @@ run_config (GdmDisplay *display, struct passwd *pwent) XSync (d->dsp, False); } + g_debug ("Forking GDM configuration process"); + gdm_sigchld_block_push (); gdm_sigterm_block_push (); pid = d->sesspid = fork (); @@ -1746,7 +1777,7 @@ run_config (GdmDisplay *display, struct passwd *pwent) /* Can't fork */ display->sesspid = 0; - + xcursor = XCreateFontCursor (d->dsp, GDK_LEFT_PTR); XDefineCursor (d->dsp, DefaultRootWindow (d->dsp), @@ -1789,7 +1820,7 @@ run_config (GdmDisplay *display, struct passwd *pwent) g_setenv ("GDM_GTK_THEME", display->theme_name, TRUE); g_unsetenv ("MAIL"); /* Unset $MAIL for broken shells */ - closelog (); + gdm_log_shutdown (); gdm_close_all_descriptors (0 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */); @@ -1799,7 +1830,7 @@ run_config (GdmDisplay *display, struct passwd *pwent) gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */ gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */ - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_init (); VE_IGNORE_EINTR (g_chdir (pwent->pw_dir)); if G_UNLIKELY (errno != 0) @@ -1820,14 +1851,13 @@ run_config (GdmDisplay *display, struct passwd *pwent) g_strfreev (argv); - gdm_error_box (d, - GTK_MESSAGE_ERROR, - _("Could not execute the configuration " - "application. Make sure its path is set " - "correctly in the configuration file. " - "Attempting to start it from the default " - "location.")); - + gdm_errorgui_error_box (d, + GTK_MESSAGE_ERROR, + _("Could not execute the configuration " + "application. Make sure its path is set " + "correctly in the configuration file. " + "Attempting to start it from the default " + "location.")); s = LIBEXECDIR "/gdmsetup --disable-sound --disable-crash-dialog"; argv = NULL; g_shell_parse_argv (s, NULL, &argv, NULL); @@ -1838,16 +1868,16 @@ run_config (GdmDisplay *display, struct passwd *pwent) g_strfreev (argv); - gdm_error_box (d, - GTK_MESSAGE_ERROR, - _("Could not execute the configuration " - "application. Make sure its path is set " - "correctly in the configuration file.")); + gdm_errorgui_error_box (d, + GTK_MESSAGE_ERROR, + _("Could not execute the configuration " + "application. Make sure its path is set " + "correctly in the configuration file.")); _exit (0); } else { GdmWaitPid *wp; - + configurator = TRUE; gdm_sigchld_block_push (); @@ -1923,6 +1953,8 @@ play_login_sound (const char *sound_file) gdm_sigchld_block_push (); gdm_sigterm_block_push (); + g_debug ("Forking sound program: %s", soundprogram); + pid = fork (); if (pid == 0) gdm_unset_signals (); @@ -2275,7 +2307,7 @@ run_pictures (void) int written; VE_IGNORE_EINTR (bytes = fread (buf, sizeof (char), - max_write, fp)); + max_write, fp)); if (bytes <= 0) break; @@ -2325,7 +2357,7 @@ run_pictures (void) if (bytes > 0) i += bytes; } - + gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "done"); NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ()); @@ -2364,12 +2396,12 @@ copy_auth_file (uid_t fromuid, uid_t touid, const char *file) errno = 0; fromfd = open (file, O_RDONLY #ifdef O_NOCTTY - |O_NOCTTY + |O_NOCTTY #endif #ifdef O_NOFOLLOW - |O_NOFOLLOW + |O_NOFOLLOW #endif - ); + ); } while G_UNLIKELY (errno == EINTR); if G_UNLIKELY (fromfd < 0) { @@ -2380,7 +2412,7 @@ copy_auth_file (uid_t fromuid, uid_t touid, const char *file) NEVER_FAILS_root_set_euid_egid (0, 0); name = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), - d->name, ".XnestAuth"); + d->name, ".XnestAuth"); VE_IGNORE_EINTR (g_unlink (name)); VE_IGNORE_EINTR (authfd = open (name, O_EXCL|O_TRUNC|O_WRONLY|O_CREAT, 0600)); @@ -2476,274 +2508,269 @@ exec_command (const char *command, const char *extra_arg) static void gdm_slave_greeter (void) { - gint pipe1[2], pipe2[2]; - struct passwd *pwent; - pid_t pid; - const char *command; - const char *defaultpath; - const char *gdmuser; - const char *moduleslist; - const char *gdmlang; - - gdm_debug ("gdm_slave_greeter: Running greeter on %s", d->name); - - /* Run the init script. gdmslave suspends until script has terminated */ - gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_DISPLAY_INIT_DIR), - NULL, NULL, FALSE /* pass_stdout */); - - /* Open a pipe for greeter communications */ - if G_UNLIKELY (pipe (pipe1) < 0) - gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't init pipe to gdmgreeter"), - "gdm_slave_greeter"); - if G_UNLIKELY (pipe (pipe2) < 0) { - VE_IGNORE_EINTR (close (pipe1[0])); - VE_IGNORE_EINTR (close (pipe1[1])); - gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't init pipe to gdmgreeter"), - "gdm_slave_greeter"); - } - - /* hackish ain't it */ - create_temp_auth_file (); - - /* Fork. Parent is gdmslave, child is greeter process. */ - gdm_sigchld_block_push (); - gdm_sigterm_block_push (); - greet = TRUE; - pid = d->greetpid = fork (); - if (pid == 0) - gdm_unset_signals (); - gdm_sigterm_block_pop (); - gdm_sigchld_block_pop (); - - switch (pid) { - - case 0: - setsid (); + gint pipe1[2], pipe2[2]; + struct passwd *pwent; + pid_t pid; + const char *command; + const char *defaultpath; + const char *gdmuser; + const char *moduleslist; + const char *gdmlang; - gdm_unset_signals (); + gdm_debug ("gdm_slave_greeter: Running greeter on %s", d->name); - /* Plumbing */ - VE_IGNORE_EINTR (close (pipe1[1])); - VE_IGNORE_EINTR (close (pipe2[0])); + /* Run the init script. gdmslave suspends until script has terminated */ + gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_DISPLAY_INIT_DIR), + NULL, NULL, FALSE /* pass_stdout */); - VE_IGNORE_EINTR (dup2 (pipe1[0], STDIN_FILENO)); - VE_IGNORE_EINTR (dup2 (pipe2[1], STDOUT_FILENO)); + /* Open a pipe for greeter communications */ + if G_UNLIKELY (pipe (pipe1) < 0) + gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't init pipe to gdmgreeter"), + "gdm_slave_greeter"); + if G_UNLIKELY (pipe (pipe2) < 0) { + VE_IGNORE_EINTR (close (pipe1[0])); + VE_IGNORE_EINTR (close (pipe1[1])); + gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't init pipe to gdmgreeter"), + "gdm_slave_greeter"); + } - closelog (); + /* hackish ain't it */ + create_temp_auth_file (); - gdm_close_all_descriptors (2 /* from */, slave_fifo_pipe_fd/* except */, d->slave_notify_fd/* except2 */); + if (d->attached) + command = gdm_daemon_config_get_value_string (GDM_KEY_GREETER); + else + command = gdm_daemon_config_get_value_string (GDM_KEY_REMOTE_GREETER); - gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */ + g_debug ("Forking greeter process: %s", command); - openlog ("gdm", LOG_PID, LOG_DAEMON); - - if G_UNLIKELY (setgid (gdm_daemon_config_get_gdmgid ()) < 0) - gdm_child_exit (DISPLAY_ABORT, - _("%s: Couldn't set groupid to %d"), - "gdm_slave_greeter", gdm_daemon_config_get_gdmgid ()); - - gdmuser = gdm_daemon_config_get_value_string (GDM_KEY_USER); - if G_UNLIKELY (initgroups (gdmuser, gdm_daemon_config_get_gdmgid ()) < 0) - gdm_child_exit (DISPLAY_ABORT, - _("%s: initgroups () failed for %s"), - "gdm_slave_greeter", gdmuser); - - if G_UNLIKELY (setuid (gdm_daemon_config_get_gdmuid ()) < 0) - gdm_child_exit (DISPLAY_ABORT, - _("%s: Couldn't set userid to %d"), - "gdm_slave_greeter", gdm_daemon_config_get_gdmuid ()); - - gdm_restoreenv (); - gdm_reset_locale (); - - g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE); - g_setenv ("DISPLAY", d->name, TRUE); + /* Fork. Parent is gdmslave, child is greeter process. */ + gdm_sigchld_block_push (); + gdm_sigterm_block_push (); + greet = TRUE; + pid = d->greetpid = fork (); + if (pid == 0) + gdm_unset_signals (); + gdm_sigterm_block_pop (); + gdm_sigchld_block_pop (); - /* hackish ain't it */ - set_xnest_parent_stuff (); - - g_setenv ("LOGNAME", gdmuser, TRUE); - g_setenv ("USER", gdmuser, TRUE); - g_setenv ("USERNAME", gdmuser, TRUE); - g_setenv ("GDM_GREETER_PROTOCOL_VERSION", - GDM_GREETER_PROTOCOL_VERSION, TRUE); - g_setenv ("GDM_VERSION", VERSION, TRUE); - g_unsetenv ("MAIL"); /* Unset $MAIL for broken shells */ + switch (pid) { - pwent = getpwnam (gdmuser); - if G_LIKELY (pwent != NULL) { - /* Note that usually this doesn't exist */ - if (pwent->pw_dir != NULL && - g_file_test (pwent->pw_dir, G_FILE_TEST_EXISTS)) - g_setenv ("HOME", pwent->pw_dir, TRUE); - else - g_setenv ("HOME", - ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)), - TRUE); /* Hack */ - g_setenv ("SHELL", pwent->pw_shell, TRUE); - } else { - g_setenv ("HOME", - ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)), - TRUE); /* Hack */ - g_setenv ("SHELL", "/bin/sh", TRUE); - } + case 0: + setsid (); - defaultpath = gdm_daemon_config_get_value_string (GDM_KEY_PATH); - if (ve_string_empty (g_getenv ("PATH"))) { - g_setenv ("PATH", defaultpath, TRUE); - } else if ( ! ve_string_empty (defaultpath)) { - gchar *temp_string = g_strconcat (g_getenv ("PATH"), - ":", defaultpath, NULL); - g_setenv ("PATH", temp_string, TRUE); - g_free (temp_string); - } - g_setenv ("RUNNING_UNDER_GDM", "true", TRUE); - if ( ! ve_string_empty (d->theme_name)) - g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE); + gdm_unset_signals (); - if (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG_GESTURES)) { - g_setenv ("GDM_DEBUG_GESTURES", "true", TRUE); - } + /* Plumbing */ + VE_IGNORE_EINTR (close (pipe1[1])); + VE_IGNORE_EINTR (close (pipe2[0])); - /* Note that this is just informative, the slave will not listen to - * the greeter even if it does something it shouldn't on a non-local - * display so it's not a security risk */ - if (d->attached) { - g_setenv ("GDM_IS_LOCAL", "yes", TRUE); - } else { - g_unsetenv ("GDM_IS_LOCAL"); - } + VE_IGNORE_EINTR (dup2 (pipe1[0], STDIN_FILENO)); + VE_IGNORE_EINTR (dup2 (pipe2[1], STDOUT_FILENO)); - /* this is again informal only, if the greeter does time out it will - * not actually login a user if it's not enabled for this display */ - if (d->timed_login_ok) { - if (ParsedTimedLogin == NULL) - g_setenv ("GDM_TIMED_LOGIN_OK", " ", TRUE); - else - g_setenv ("GDM_TIMED_LOGIN_OK", ParsedTimedLogin, TRUE); - } else { - g_unsetenv ("GDM_TIMED_LOGIN_OK"); - } + gdm_log_shutdown (); - if (SERVER_IS_FLEXI (d)) { - g_setenv ("GDM_FLEXI_SERVER", "yes", TRUE); - } else { - g_unsetenv ("GDM_FLEXI_SERVER"); - } + gdm_close_all_descriptors (2 /* from */, slave_fifo_pipe_fd/* except */, d->slave_notify_fd/* except2 */); - if G_UNLIKELY (gdm_emergency_server) { - gdm_error_box (d, - GTK_MESSAGE_ERROR, - _("No servers were defined in the " - "configuration file and XDMCP was " - "disabled. This can only be a " - "configuration error. GDM has started " - "a single server for you. You should " - "log in and fix the configuration. " - "Note that automatic and timed logins " - "are disabled now.")); - g_unsetenv ("GDM_TIMED_LOGIN_OK"); - } - - if G_UNLIKELY (d->failsafe_xserver) { - gdm_error_box (d, - GTK_MESSAGE_ERROR, - _("Could not start the regular X " - "server (your graphical environment) " - "and so this is a failsafe X server. " - "You should log in and properly " - "configure the X server.")); - } - - if G_UNLIKELY (d->busy_display) { - char *msg = g_strdup_printf - (_("The specified display number was busy, so " - "this server was started on display %s."), - d->name); - gdm_error_box (d, GTK_MESSAGE_ERROR, msg); - g_free (msg); - } + gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */ - if (d->attached) - command = gdm_daemon_config_get_value_string (GDM_KEY_GREETER); - else - command = gdm_daemon_config_get_value_string (GDM_KEY_REMOTE_GREETER); + gdm_log_init (); - if G_UNLIKELY (d->try_different_greeter) { - /* FIXME: we should also really be able to do standalone failsafe - login, but that requires some work and is perhaps an overkill. */ - /* This should handle mostly the case where gdmgreeter is crashing - and we'd want to start gdmlogin for the user so that at least - something works instead of a flickering screen */ - gdm_error_box (d, - GTK_MESSAGE_ERROR, - _("The greeter application appears to be crashing. " - "Attempting to use a different one.")); - if (strstr (command, "gdmlogin") != NULL) { - /* in case it is gdmlogin that's crashing - try the themed greeter for luck */ - command = LIBEXECDIR "/gdmgreeter"; + if G_UNLIKELY (setgid (gdm_daemon_config_get_gdmgid ()) < 0) + gdm_child_exit (DISPLAY_ABORT, + _("%s: Couldn't set groupid to %d"), + "gdm_slave_greeter", gdm_daemon_config_get_gdmgid ()); + + gdmuser = gdm_daemon_config_get_value_string (GDM_KEY_USER); + if G_UNLIKELY (initgroups (gdmuser, gdm_daemon_config_get_gdmgid ()) < 0) + gdm_child_exit (DISPLAY_ABORT, + _("%s: initgroups () failed for %s"), + "gdm_slave_greeter", gdmuser); + + if G_UNLIKELY (setuid (gdm_daemon_config_get_gdmuid ()) < 0) + gdm_child_exit (DISPLAY_ABORT, + _("%s: Couldn't set userid to %d"), + "gdm_slave_greeter", gdm_daemon_config_get_gdmuid ()); + + gdm_restoreenv (); + gdm_reset_locale (); + + g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE); + g_setenv ("DISPLAY", d->name, TRUE); + + /* hackish ain't it */ + set_xnest_parent_stuff (); + + g_setenv ("LOGNAME", gdmuser, TRUE); + g_setenv ("USER", gdmuser, TRUE); + g_setenv ("USERNAME", gdmuser, TRUE); + g_setenv ("GDM_GREETER_PROTOCOL_VERSION", + GDM_GREETER_PROTOCOL_VERSION, TRUE); + g_setenv ("GDM_VERSION", VERSION, TRUE); + g_unsetenv ("MAIL"); /* Unset $MAIL for broken shells */ + + pwent = getpwnam (gdmuser); + if G_LIKELY (pwent != NULL) { + /* Note that usually this doesn't exist */ + if (pwent->pw_dir != NULL && + g_file_test (pwent->pw_dir, G_FILE_TEST_EXISTS)) + g_setenv ("HOME", pwent->pw_dir, TRUE); + else + g_setenv ("HOME", + ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)), + TRUE); /* Hack */ + g_setenv ("SHELL", pwent->pw_shell, TRUE); } else { - /* in all other cases, try the gdmlogin (standard greeter) - proggie */ - command = LIBEXECDIR "/gdmlogin"; + g_setenv ("HOME", + ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)), + TRUE); /* Hack */ + g_setenv ("SHELL", "/bin/sh", TRUE); + } + + defaultpath = gdm_daemon_config_get_value_string (GDM_KEY_PATH); + if (ve_string_empty (g_getenv ("PATH"))) { + g_setenv ("PATH", defaultpath, TRUE); + } else if ( ! ve_string_empty (defaultpath)) { + gchar *temp_string = g_strconcat (g_getenv ("PATH"), + ":", defaultpath, NULL); + g_setenv ("PATH", temp_string, TRUE); + g_free (temp_string); + } + g_setenv ("RUNNING_UNDER_GDM", "true", TRUE); + if ( ! ve_string_empty (d->theme_name)) + g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE); + + if (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG_GESTURES)) { + g_setenv ("GDM_DEBUG_GESTURES", "true", TRUE); + } + + /* Note that this is just informative, the slave will not listen to + * the greeter even if it does something it shouldn't on a non-local + * display so it's not a security risk */ + if (d->attached) { + g_setenv ("GDM_IS_LOCAL", "yes", TRUE); + } else { + g_unsetenv ("GDM_IS_LOCAL"); } - } - moduleslist = gdm_daemon_config_get_value_string (GDM_KEY_GTK_MODULES_LIST); + /* this is again informal only, if the greeter does time out it will + * not actually login a user if it's not enabled for this display */ + if (d->timed_login_ok) { + if (ParsedTimedLogin == NULL) + g_setenv ("GDM_TIMED_LOGIN_OK", " ", TRUE); + else + g_setenv ("GDM_TIMED_LOGIN_OK", ParsedTimedLogin, TRUE); + } else { + g_unsetenv ("GDM_TIMED_LOGIN_OK"); + } + + if (SERVER_IS_FLEXI (d)) { + g_setenv ("GDM_FLEXI_SERVER", "yes", TRUE); + } else { + g_unsetenv ("GDM_FLEXI_SERVER"); + } + + if G_UNLIKELY (d->is_emergency_server) { + gdm_errorgui_error_box (d, + GTK_MESSAGE_ERROR, + _("No servers were defined in the " + "configuration file and XDMCP was " + "disabled. This can only be a " + "configuration error. GDM has started " + "a single server for you. You should " + "log in and fix the configuration. " + "Note that automatic and timed logins " + "are disabled now.")); + g_unsetenv ("GDM_TIMED_LOGIN_OK"); + } + + if G_UNLIKELY (d->failsafe_xserver) { + gdm_errorgui_error_box (d, + GTK_MESSAGE_ERROR, + _("Could not start the regular X " + "server (your graphical environment) " + "and so this is a failsafe X server. " + "You should log in and properly " + "configure the X server.")); + } + + if G_UNLIKELY (d->busy_display) { + char *msg = g_strdup_printf + (_("The specified display number was busy, so " + "this server was started on display %s."), + d->name); + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, msg); + g_free (msg); + } + + if G_UNLIKELY (d->try_different_greeter) { + /* FIXME: we should also really be able to do standalone failsafe + login, but that requires some work and is perhaps an overkill. */ + /* This should handle mostly the case where gdmgreeter is crashing + and we'd want to start gdmlogin for the user so that at least + something works instead of a flickering screen */ + gdm_errorgui_error_box (d, + GTK_MESSAGE_ERROR, + _("The greeter application appears to be crashing. " + "Attempting to use a different one.")); + if (strstr (command, "gdmlogin") != NULL) { + /* in case it is gdmlogin that's crashing + try the themed greeter for luck */ + command = LIBEXECDIR "/gdmgreeter"; + } else { + /* in all other cases, try the gdmlogin (standard greeter) + proggie */ + command = LIBEXECDIR "/gdmlogin"; + } + } + + moduleslist = gdm_daemon_config_get_value_string (GDM_KEY_GTK_MODULES_LIST); + + if (gdm_daemon_config_get_value_bool (GDM_KEY_ADD_GTK_MODULES) && + ! ve_string_empty (moduleslist) && + /* don't add modules if we're trying to prevent crashes, + perhaps it's the modules causing the problem in the first place */ + ! d->try_different_greeter) { + gchar *modules = g_strdup_printf ("--gtk-module=%s", moduleslist); + exec_command (command, modules); + /* Something went wrong */ + gdm_error (_("%s: Cannot start greeter with gtk modules: %s. Trying without modules"), + "gdm_slave_greeter", + moduleslist); + g_free (modules); + } + exec_command (command, NULL); - if (gdm_daemon_config_get_value_bool (GDM_KEY_ADD_GTK_MODULES) && - ! ve_string_empty (moduleslist) && - /* don't add modules if we're trying to prevent crashes, - perhaps it's the modules causing the problem in the first place */ - ! d->try_different_greeter) { - gchar *modules = g_strdup_printf ("--gtk-module=%s", moduleslist); - exec_command (command, modules); - /* Something went wrong */ - gdm_error (_("%s: Cannot start greeter with gtk modules: %s. Trying without modules"), + gdm_error (_("%s: Cannot start greeter trying default: %s"), "gdm_slave_greeter", - moduleslist); - g_free (modules); - } - exec_command (command, NULL); + LIBEXECDIR "/gdmlogin"); - gdm_error (_("%s: Cannot start greeter trying default: %s"), - "gdm_slave_greeter", - LIBEXECDIR "/gdmlogin"); + g_setenv ("GDM_WHACKED_GREETER_CONFIG", "true", TRUE); - g_setenv ("GDM_WHACKED_GREETER_CONFIG", "true", TRUE); + exec_command (LIBEXECDIR "/gdmlogin", NULL); - exec_command (LIBEXECDIR "/gdmlogin", NULL); + VE_IGNORE_EINTR (execl (LIBEXECDIR "/gdmlogin", LIBEXECDIR "/gdmlogin", NULL)); - VE_IGNORE_EINTR (execl (LIBEXECDIR "/gdmlogin", LIBEXECDIR "/gdmlogin", NULL)); + gdm_errorgui_error_box (d, + GTK_MESSAGE_ERROR, + _("Cannot start the greeter application; " + "you will not be able to log in. " + "This display will be disabled. " + "Try logging in by other means and " + "editing the configuration file")); - gdm_error_box (d, - GTK_MESSAGE_ERROR, - _("Cannot start the greeter application; " - "you will not be able to log in. " - "This display will be disabled. " - "Try logging in by other means and " - "editing the configuration file")); - - /* If no greeter we really have to disable the display */ - gdm_child_exit (DISPLAY_ABORT, _("%s: Error starting greeter on display %s"), "gdm_slave_greeter", d->name); - - case -1: - d->greetpid = 0; - gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't fork gdmgreeter process"), "gdm_slave_greeter"); - - default: - VE_IGNORE_EINTR (close (pipe1[0])); - VE_IGNORE_EINTR (close (pipe2[1])); + /* If no greeter we really have to disable the display */ + gdm_child_exit (DISPLAY_ABORT, _("%s: Error starting greeter on display %s"), "gdm_slave_greeter", d->name); - whack_greeter_fds (); + case -1: + d->greetpid = 0; + gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't fork gdmgreeter process"), "gdm_slave_greeter"); - greeter_fd_out = pipe1[1]; - greeter_fd_in = pipe2[0]; - - gdm_debug ("gdm_slave_greeter: Greeter on pid %d", (int)pid); + default: + VE_IGNORE_EINTR (close (pipe1[0])); + VE_IGNORE_EINTR (close (pipe2[1])); - gdm_slave_send_num (GDM_SOP_GREETPID, d->greetpid); + whack_greeter_fds (); if (always_restart_greeter) gdm_slave_greeter_ctl_no_ret (GDM_ALWAYS_RESTART, "Y"); else @@ -2752,11 +2779,25 @@ gdm_slave_greeter (void) if (gdmlang) gdm_slave_greeter_ctl_no_ret (GDM_SETLANG, gdmlang); - run_pictures (); /* Append pictures to greeter if browsing is on */ + greeter_fd_out = pipe1[1]; + greeter_fd_in = pipe2[0]; - check_notifies_now (); - break; - } + gdm_debug ("gdm_slave_greeter: Greeter on pid %d", (int)pid); + + gdm_slave_send_num (GDM_SOP_GREETPID, d->greetpid); + if (always_restart_greeter) + gdm_slave_greeter_ctl_no_ret (GDM_ALWAYS_RESTART, "Y"); + else + gdm_slave_greeter_ctl_no_ret (GDM_ALWAYS_RESTART, "N"); + gdmlang = g_getenv ("GDM_LANG"); + if (gdmlang) + gdm_slave_greeter_ctl_no_ret (GDM_SETLANG, gdmlang); + + run_pictures (); /* Append pictures to greeter if browsing is on */ + + check_notifies_now (); + break; + } } /* This should not call anything that could cause a syslog in case we @@ -2792,7 +2833,7 @@ gdm_slave_send (const char *str, gboolean wait_for_ack) in main daemon just abort the main daemon. */ /* Use the fifo as a fallback only now that we have a pipe */ fifopath = g_build_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), - ".gdmfifo", NULL); + ".gdmfifo", NULL); old = geteuid (); if (old != 0) seteuid (0); @@ -2849,9 +2890,9 @@ gdm_slave_send (const char *str, gboolean wait_for_ack) } else { for (i = 0; wait_for_ack && - ! gdm_got_ack && - parent_exists () && - i < 10; + ! gdm_got_ack && + parent_exists () && + i < 10; i++) { if (in_usr2_signal > 0) { fd_set rfds; @@ -2874,7 +2915,7 @@ gdm_slave_send (const char *str, gboolean wait_for_ack) tv.tv_usec = 0; select (0, NULL, NULL, NULL, &tv); /* don't want to use sleep since we're using alarm - for pinging */ + for pinging */ } } } @@ -2942,54 +2983,30 @@ gdm_slave_send_string (const char *opcode, const char *str) } static void -send_chosen_host (GdmDisplay *disp, const char *hostname) +send_chosen_host (GdmDisplay *disp, + const char *hostname) { - GdmHostent *host; - struct in_addr ia; -#ifdef ENABLE_IPV6 + GdmHostent *hostent; struct sockaddr_storage ss; -#endif char *str = NULL; + char *host; - host = gdm_gethostbyname (hostname); + hostent = gdm_gethostbyname (hostname); - if G_UNLIKELY (host->addrs == NULL) { + if G_UNLIKELY (hostent->addrs == NULL) { gdm_error ("Cannot get address of host '%s'", hostname); - gdm_hostent_free (host); + gdm_hostent_free (hostent); return; } - /* take first address */ -#ifdef ENABLE_IPV6 - memcpy (&ss, &host->addrs[0], sizeof (struct sockaddr_storage)); - if (ss.ss_family == AF_INET6) { - struct in6_addr ia6; - char buffer6[INET6_ADDRSTRLEN]; - - memcpy (&ia6, &((struct sockaddr_in6 *)&ss)->sin6_addr, sizeof (struct in6_addr)); - gdm_hostent_free (host); - gdm_debug ("Sending chosen host address (%s) %s", hostname, inet_ntop (AF_INET6, &ia6, buffer6, sizeof (buffer6))); - str = g_strdup_printf ("%s %d %s", GDM_SOP_CHOSEN, disp->indirect_id, buffer6); - } - else if (ss.ss_family == AF_INET) { - char buffer[INET_ADDRSTRLEN]; - memcpy (&ia, &((struct sockaddr_in *)&ss)->sin_addr, sizeof (struct in_addr)); - gdm_hostent_free (host); - gdm_debug ("Sending chosen host address (%s) %s", hostname, inet_ntop (AF_INET, &ia, buffer, sizeof (buffer))); - str = g_strdup_printf ("%s %d %s", GDM_SOP_CHOSEN, disp->indirect_id, buffer); - } -#else - ia = host->addrs[0]; - gdm_hostent_free (host); - - gdm_debug ("Sending chosen host address (%s) %s", - hostname, inet_ntoa (ia)); + /* take first address */ + memcpy (&ss, &hostent->addrs[0], sizeof (struct sockaddr_storage)); - str = g_strdup_printf ("%s %d %s", GDM_SOP_CHOSEN, - disp->indirect_id, - inet_ntoa (ia)); + gdm_address_get_info (&ss, &host, NULL); + gdm_hostent_free (hostent); -#endif + gdm_debug ("Sending chosen host address (%s) %s", hostname, host); + str = g_strdup_printf ("%s %d %s", GDM_SOP_CHOSEN, disp->indirect_id, host); gdm_slave_send (str, FALSE); g_free (str); @@ -3017,6 +3034,8 @@ gdm_slave_chooser (void) gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_DISPLAY_INIT_DIR), NULL, NULL, FALSE /* pass_stdout */); + g_debug ("Forking chooser process: %s", gdm_daemon_config_get_value_string (GDM_KEY_CHOOSER)); + /* Fork. Parent is gdmslave, child is greeter process. */ gdm_sigchld_block_push (); gdm_sigterm_block_push (); @@ -3036,10 +3055,10 @@ gdm_slave_chooser (void) /* Plumbing */ VE_IGNORE_EINTR (close (p[0])); - if (p[1] != STDOUT_FILENO) + if (p[1] != STDOUT_FILENO) VE_IGNORE_EINTR (dup2 (p[1], STDOUT_FILENO)); - closelog (); + gdm_log_shutdown (); VE_IGNORE_EINTR (close (0)); gdm_close_all_descriptors (2 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */); @@ -3047,9 +3066,9 @@ gdm_slave_chooser (void) gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */ gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */ - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_init (); - if G_UNLIKELY (setgid (gdm_daemon_config_get_gdmgid ()) < 0) + if G_UNLIKELY (setgid (gdm_daemon_config_get_gdmgid ()) < 0) gdm_child_exit (DISPLAY_ABORT, _("%s: Couldn't set groupid to %d"), "gdm_slave_chooser", gdm_daemon_config_get_gdmgid ()); @@ -3060,7 +3079,7 @@ gdm_slave_chooser (void) _("%s: initgroups () failed for %s"), "gdm_slave_chooser", gdmuser); - if G_UNLIKELY (setuid (gdm_daemon_config_get_gdmuid ()) < 0) + if G_UNLIKELY (setuid (gdm_daemon_config_get_gdmuid ()) < 0) gdm_child_exit (DISPLAY_ABORT, _("%s: Couldn't set userid to %d"), "gdm_slave_chooser", gdm_daemon_config_get_gdmuid ()); @@ -3086,13 +3105,13 @@ gdm_slave_chooser (void) g_setenv ("HOME", pwent->pw_dir, TRUE); else g_setenv ("HOME", - ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)), - TRUE); /* Hack */ + ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)), + TRUE); /* Hack */ g_setenv ("SHELL", pwent->pw_shell, TRUE); } else { g_setenv ("HOME", - ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)), - TRUE); /* Hack */ + ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)), + TRUE); /* Hack */ g_setenv ("SHELL", "/bin/sh", TRUE); } @@ -3101,7 +3120,7 @@ gdm_slave_chooser (void) g_setenv ("PATH", defaultpath, TRUE); } else if ( ! ve_string_empty (defaultpath)) { gchar *temp_string = g_strconcat (g_getenv ("PATH"), - ":", defaultpath, NULL); + ":", defaultpath, NULL); g_setenv ("PATH", temp_string, TRUE); g_free (temp_string); } @@ -3118,7 +3137,7 @@ gdm_slave_chooser (void) exec_command (gdm_daemon_config_get_value_string (GDM_KEY_CHOOSER), NULL); - gdm_error_box (d, + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("Cannot start the chooser application. " "You will probably not be able to log in. " @@ -3406,7 +3425,7 @@ gdm_selinux_setup (const char *login) int ret=-1; char *seuser=NULL; char *level=NULL; - + /* If selinux is not enabled, then we don't do anything */ if (is_selinux_enabled () <= 0) return TRUE; @@ -3426,7 +3445,7 @@ gdm_selinux_setup (const char *login) if (setexeccon (scontext) != 0) { gdm_error ("SELinux gdm login: unable to set executable context %s.", - (char *)scontext); + (char *)scontext); gdm_fdprintf (2, "SELinux gdm login: unable to set executable context %s.", (char *)scontext); freecon (scontext); @@ -3507,13 +3526,13 @@ session_child_run (struct passwd *pwent, if (d->attached) { greeter = gdm_daemon_config_get_value_string (GDM_KEY_GREETER); } else { - greeter = gdm_daemon_config_get_value_string (GDM_KEY_REMOTE_GREETER); + greeter = gdm_daemon_config_get_value_string (GDM_KEY_REMOTE_GREETER); } - + if (strstr (greeter, "gdmlogin") != NULL) { - g_setenv ("GDM_GREETER_TYPE", "PLAIN", TRUE); + g_setenv ("GDM_GREETER_TYPE", "PLAIN", TRUE); } else if (strstr (greeter, "gdmgreeter") != NULL) { - g_setenv ("GDM_GREETER_TYPE", "THEMED", TRUE); + g_setenv ("GDM_GREETER_TYPE", "THEMED", TRUE); } else { /* huh? */ g_setenv ("GDM_GREETER_TYPE", "unknown", TRUE); @@ -3524,12 +3543,12 @@ session_child_run (struct passwd *pwent, pwent->pw_name, pwent, TRUE /* pass_stdout */) != EXIT_SUCCESS && /* ignore errors in failsafe modes */ - ! failsafe) + ! failsafe) /* If script fails reset X server and restart greeter */ gdm_child_exit (DISPLAY_REMANAGE, _("%s: Execution of PreSession script returned > 0. Aborting."), "session_child_run"); - gdm_clearenv (); + ve_clearenv (); /* Prepare user session */ g_setenv ("XAUTHORITY", d->userauth, TRUE); @@ -3578,7 +3597,7 @@ session_child_run (struct passwd *pwent, ! ve_locale_exists (language)) { char *msg = g_strdup_printf (_("Language %s does not exist; using %s"), language, _("System default")); - gdm_error_box (d, GTK_MESSAGE_ERROR, msg); + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, msg); language = NULL; g_free (msg); } @@ -3588,9 +3607,9 @@ session_child_run (struct passwd *pwent, VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0640)); setpgid (0, 0); - + umask (022); - + /* setup the verify env vars */ if G_UNLIKELY ( ! gdm_verify_setup_env (d)) gdm_child_exit (DISPLAY_REMANAGE, @@ -3613,15 +3632,15 @@ session_child_run (struct passwd *pwent, struct stat s0, s1, s2; gint s0_ret, s1_ret, s2_ret; gint iceauth_fd; - - NEVER_FAILS_root_set_euid_egid (0, 0); + + NEVER_FAILS_root_set_euid_egid (0, 0); iceauth_fd = open (".ICEauthority", O_RDONLY); - + s0_ret = stat (home_dir, &s0); s1_ret = lstat (".ICEauthority", &s1); s2_ret = fstat (iceauth_fd, &s2); - + if (iceauth_fd >= 0 && s0_ret == 0 && s0.st_uid == pwent->pw_uid && @@ -3648,7 +3667,7 @@ session_child_run (struct passwd *pwent, pwent->pw_gid); fchmod (iceauth_fd, S_IRUSR | S_IWUSR); } - + if (iceauth_fd >= 0) close (iceauth_fd); } @@ -3665,7 +3684,7 @@ session_child_run (struct passwd *pwent, "Aborting."), "session_child_run", login); #else - if G_UNLIKELY (setuid (pwent->pw_uid) < 0) + if G_UNLIKELY (setuid (pwent->pw_uid) < 0) gdm_child_exit (DISPLAY_REMANAGE, _("%s: Could not become %s. Aborting."), "session_child_run", login); #endif @@ -3680,15 +3699,15 @@ session_child_run (struct passwd *pwent, /* just in case there is some weirdness going on */ VE_IGNORE_EINTR (g_chdir (home_dir)); - + if (usrcfgok && home_dir_ok) gdm_daemon_config_set_user_session_lang (savesess, savelang, home_dir, save_session, language); - - closelog (); + + gdm_log_shutdown (); gdm_close_all_descriptors (3 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */); - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_init (); argv[0] = NULL; argv[1] = NULL; @@ -3704,15 +3723,15 @@ session_child_run (struct passwd *pwent, if (strcmp (session, GDM_SESSION_FAILSAFE_XTERM) != 0 && strcmp (session, GDM_SESSION_FAILSAFE_GNOME) != 0) { exec = gdm_daemon_config_get_session_exec (session, - FALSE /* check_try_exec */); + FALSE /* check_try_exec */); if G_UNLIKELY (exec == NULL) { gchar *msg = g_strdup_printf ( - _("No Exec line in the session file: %s. Running the GNOME failsafe session instead"), - session); + _("No Exec line in the session file: %s. Running the GNOME failsafe session instead"), + session); gdm_error (_("%s: %s"), "session_child_run", msg); - gdm_error_box (d, GTK_MESSAGE_ERROR, msg); + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, msg); g_free (msg); session = GDM_SESSION_FAILSAFE_GNOME; @@ -3735,7 +3754,7 @@ session_child_run (struct passwd *pwent, "session_child_run"); session = GDM_SESSION_FAILSAFE_GNOME; exec = NULL; - gdm_error_box + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("Cannot find or run the base session script. Running the GNOME failsafe session instead.")); } else { @@ -3764,7 +3783,7 @@ session_child_run (struct passwd *pwent, #ifdef HAVE_TSOL if (have_suntsol_extension == TRUE) { /* Trusted Path will be preserved as long as the sys admin - * doesn't put anything stupid in gdm.conf */ + * doesn't put anything stupid in gdm.conf */ argv[0] = g_strdup ("/usr/bin/tsoljdslabel"); argv[1] = find_prog ("gnome-session"); if G_UNLIKELY (argv[1] == NULL) { @@ -3772,7 +3791,7 @@ session_child_run (struct passwd *pwent, gdm_error (_("%s: gnome-session not found for a failsafe GNOME session, trying xterm"), "session_child_run"); session = GDM_SESSION_FAILSAFE_XTERM; - gdm_error_box + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("Could not find the GNOME installation, " "will try running the \"Failsafe xterm\" " @@ -3780,38 +3799,38 @@ session_child_run (struct passwd *pwent, } else { argv[2] = "--failsafe"; argv[3] = NULL; - gdm_error_box + gdm_errorgui_error_box (d, GTK_MESSAGE_INFO, _("This is the Failsafe GNOME session. " - "You will be logged into the 'Default' " - "session of GNOME without the startup scripts " - "being run. This should be used to fix problems " - "in your installation.")); + "You will be logged into the 'Default' " + "session of GNOME without the startup scripts " + "being run. This should be used to fix problems " + "in your installation.")); } } else { #endif - argv[0] = find_prog ("gnome-session"); - if G_UNLIKELY (argv[0] == NULL) { - /* yaikes */ - gdm_error (_("%s: gnome-session not found for a failsafe GNOME session; trying xterm"), - "session_child_run"); - session = GDM_SESSION_FAILSAFE_XTERM; - gdm_error_box - (d, GTK_MESSAGE_ERROR, - _("Could not find the GNOME installation. " - "Running the \"Failsafe xterm\" " - "session instead.")); - } else { - argv[1] = "--failsafe"; - argv[2] = NULL; - gdm_error_box - (d, GTK_MESSAGE_INFO, - _("This is the Failsafe GNOME session. " - "You will be logged into the 'Default' " - "session of GNOME without the startup scripts " - "being run. This should be used to fix problems " - "in your installation.")); - } + argv[0] = find_prog ("gnome-session"); + if G_UNLIKELY (argv[0] == NULL) { + /* yaikes */ + gdm_error (_("%s: gnome-session not found for a failsafe GNOME session; trying xterm"), + "session_child_run"); + session = GDM_SESSION_FAILSAFE_XTERM; + gdm_errorgui_error_box + (d, GTK_MESSAGE_ERROR, + _("Could not find the GNOME installation. " + "Running the \"Failsafe xterm\" " + "session instead.")); + } else { + argv[1] = "--failsafe"; + argv[2] = NULL; + gdm_errorgui_error_box + (d, GTK_MESSAGE_INFO, + _("This is the Failsafe GNOME session. " + "You will be logged into the 'Default' " + "session of GNOME without the startup scripts " + "being run. This should be used to fix problems " + "in your installation.")); + } #ifdef HAVE_TSOL } #endif @@ -3823,7 +3842,7 @@ session_child_run (struct passwd *pwent, if (strcmp (session, GDM_SESSION_FAILSAFE_XTERM) == 0) { argv[0] = find_prog ("xterm"); if (argv[0] == NULL) { - gdm_error_box (d, GTK_MESSAGE_ERROR, + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("Cannot find \"xterm\" to start " "a failsafe session.")); /* nyah nyah nyah nyah nyah */ @@ -3844,40 +3863,40 @@ session_child_run (struct passwd *pwent, */ if (pwent->pw_uid == 0) { argv[3] = argv[4] = argv[5] = argv[6] = NULL; - gdm_error_box + gdm_errorgui_error_box (d, GTK_MESSAGE_INFO, - _("This is the Failsafe xterm session. " - "You will be logged into a terminal " - "console so that you may fix your system " - "if you cannot log in any other way. " - "To exit the terminal emulator, type " - "'exit' and an enter into the window.")); + _("This is the Failsafe xterm session. " + "You will be logged into a terminal " + "console so that you may fix your system " + "if you cannot log in any other way. " + "To exit the terminal emulator, type " + "'exit' and an enter into the window.")); focus_first_x_window ("xterm"); } else if (gdm_can_i_assume_root_role (pwent) == TRUE) { argv[3] = "-C"; argv[4] = "-e"; argv[5] = "su"; argv[6] = NULL; - gdm_error_box + gdm_errorgui_error_box (d, GTK_MESSAGE_INFO, - _("This is the Failsafe xterm session. " - "You will be logged into a terminal " - "console and be prompted to enter the " - "password for root so that you may fix " - "your system if you cannot log in any " - "other way. To exit the terminal " - "emulator, type 'exit' and an enter " - "into the window.")); + _("This is the Failsafe xterm session. " + "You will be logged into a terminal " + "console and be prompted to enter the " + "password for root so that you may fix " + "your system if you cannot log in any " + "other way. To exit the terminal " + "emulator, type 'exit' and an enter " + "into the window.")); focus_first_x_window ("xterm"); } else { /* Normal user without root role - get lost */ - gdm_error_box + gdm_errorgui_error_box (d, GTK_MESSAGE_INFO, - _("The failsafe session is restricted to " - "users who have been assigned the root " - "role. If you cannot log in any other " - "way please contact your system " - "administrator")); + _("The failsafe session is restricted to " + "users who have been assigned the root " + "role. If you cannot log in any other " + "way please contact your system " + "administrator")); _exit (66); } #endif /* HAVE_TSOL */ @@ -3890,7 +3909,7 @@ session_child_run (struct passwd *pwent, #ifdef HAVE_TSOL argv[4] = argv[5] = argv[6] = NULL; #endif - gdm_error_box + gdm_errorgui_error_box (d, GTK_MESSAGE_INFO, _("This is the Failsafe xterm session. " "You will be logged into a terminal " @@ -3901,7 +3920,7 @@ session_child_run (struct passwd *pwent, focus_first_x_window ("xterm"); } failsafe = TRUE; - } + } #ifdef HAVE_TSOL gdm_debug ("Running %s %s %s %s %s %s for %s on %s", @@ -3932,7 +3951,7 @@ session_child_run (struct passwd *pwent, strcmp (shell, "/bin/true") == 0) { gdm_error (_("%s: User not allowed to log in"), "session_child_run"); - gdm_error_box (d, GTK_MESSAGE_ERROR, + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("The system administrator has " "disabled your account.")); /* ends as if nothing bad happened */ @@ -3944,7 +3963,7 @@ session_child_run (struct passwd *pwent, #ifdef CAN_USE_SETPENV /* Call the function setpenv which instanciates the extern variable "newenv" */ setpenv (login, (PENV_INIT | PENV_NOEXEC), NULL, NULL); - + /* Add the content of the "newenv" variable to the environment */ for (i=0; newenv != NULL && newenv[i] != NULL; i++) { char *env_str = g_strdup (newenv[i]); @@ -3963,7 +3982,7 @@ session_child_run (struct passwd *pwent, if ( ! gdm_selinux_setup (pwent->pw_name)) { /* 66 means no "session crashed" examine .xsession-errors dialog */ - gdm_error_box (d, GTK_MESSAGE_ERROR, + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("Error! Unable to set executable context.")); _exit (66); } @@ -3973,7 +3992,7 @@ session_child_run (struct passwd *pwent, /* will go to .xsession-errors */ #ifdef HAVE_TSOL - fprintf (stderr, _("%s: Could not exec %s %s %s %s %s %s"), + fprintf (stderr, _("%s: Could not exec %s %s %s %s %s %s"), "session_child_run", argv[0], ve_sure_string (argv[1]), @@ -3982,35 +4001,35 @@ session_child_run (struct passwd *pwent, ve_sure_string (argv[4]), ve_sure_string (argv[5])); - gdm_error ( _("%s: Could not exec %s %s %s %s %s %s"), - "session_child_run", - argv[0], - ve_sure_string (argv[1]), - ve_sure_string (argv[2]), - ve_sure_string (argv[3]), - ve_sure_string (argv[4]), - ve_sure_string (argv[5])); + gdm_error ( _("%s: Could not exec %s %s %s %s %s %s"), + "session_child_run", + argv[0], + ve_sure_string (argv[1]), + ve_sure_string (argv[2]), + ve_sure_string (argv[3]), + ve_sure_string (argv[4]), + ve_sure_string (argv[5])); #else - fprintf (stderr, _("%s: Could not exec %s %s %s"), - "session_child_run", - argv[0], - ve_sure_string (argv[1]), - ve_sure_string (argv[2])); - gdm_error ( _("%s: Could not exec %s %s %s"), + fprintf (stderr, _("%s: Could not exec %s %s %s"), "session_child_run", argv[0], ve_sure_string (argv[1]), ve_sure_string (argv[2])); + gdm_error ( _("%s: Could not exec %s %s %s"), + "session_child_run", + argv[0], + ve_sure_string (argv[1]), + ve_sure_string (argv[2])); #endif /* if we can't read and exec the session, then make a nice * error dialog */ - gdm_error_box + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, /* we can't really be any more specific */ _("Cannot start the session due to some " "internal error.")); - + /* ends as if nothing bad happened */ _exit (0); } @@ -4035,448 +4054,462 @@ finish_session_output (gboolean do_read) static void gdm_slave_session_start (void) { - struct passwd *pwent; - const char *home_dir = NULL; - char *save_session = NULL, *session = NULL, *language = NULL, *usrsess, *usrlang; - char *gnome_session = NULL; + struct passwd *pwent; + const char *home_dir = NULL; + char *save_session = NULL, *session = NULL, *language = NULL, *usrsess, *usrlang; + char *gnome_session = NULL; #ifdef WITH_CONSOLE_KIT - char *ck_session_cookie; + char *ck_session_cookie; #endif - char *tmp; - gboolean savesess = FALSE, savelang = FALSE; - gboolean usrcfgok = FALSE, authok = FALSE; - gboolean home_dir_ok = FALSE; - gboolean failsafe = FALSE; - time_t session_start_time, end_time; - pid_t pid; - GdmWaitPid *wp; - uid_t uid; - gid_t gid; - int logpipe[2]; - int logfilefd; - - gdm_debug ("gdm_slave_session_start: Attempting session for user '%s'", - login); - - pwent = getpwnam (login); - - if G_UNLIKELY (pwent == NULL) { - /* This is sort of an "assert", this should NEVER happen */ - if (greet) - gdm_slave_whack_greeter (); - gdm_slave_exit (DISPLAY_REMANAGE, - _("%s: User passed auth but getpwnam (%s) failed!"), "gdm_slave_session_start", login); - } - - logged_in_uid = uid = pwent->pw_uid; - logged_in_gid = gid = pwent->pw_gid; - - /* Run the PostLogin script */ - if G_UNLIKELY (gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_POSTLOGIN), - login, pwent, - TRUE /* pass_stdout */) != EXIT_SUCCESS && - /* ignore errors in failsafe modes */ - ! failsafe) { - gdm_verify_cleanup (d); - gdm_error (_("%s: Execution of PostLogin script returned > 0. Aborting."), "gdm_slave_session_start"); - /* script failed so just try again */ - return; - - - } - - /* - * Set euid, gid to user before testing for user's $HOME since root - * does not always have access to the user's $HOME directory. - */ - if G_UNLIKELY (setegid (pwent->pw_gid) != 0 || - seteuid (pwent->pw_uid) != 0) { - gdm_error ("Cannot set effective user/group id"); - gdm_verify_cleanup (d); - session_started = FALSE; - return; - } - - if G_UNLIKELY (pwent->pw_dir == NULL || - ! g_file_test (pwent->pw_dir, G_FILE_TEST_IS_DIR)) { - char *yesno_msg; - char *msg = g_strdup_printf ( - _("Your home directory is listed as: '%s' " - "but it does not appear to exist. " - "Do you want to log in with the / (root) " - "directory as your home directory? " - "It is unlikely anything will work unless " - "you use a failsafe session."), - ve_sure_string (pwent->pw_dir)); - - /* Set euid, egid to root:gdm to manage user interaction */ - seteuid (0); - setegid (gdm_daemon_config_get_gdmgid ()); - - gdm_error (_("%s: Home directory for %s: '%s' does not exist!"), - "gdm_slave_session_start", - login, - ve_sure_string (pwent->pw_dir)); - - /* Check what the user wants to do */ - yesno_msg = g_strdup_printf ("yesno_msg=%s", msg); - gdm_slave_send_string (GDM_SOP_SHOW_YESNO_DIALOG, yesno_msg); - - g_free (yesno_msg); - - if (strcmp (gdm_ack_response, "no") == 0) { - gdm_verify_cleanup (d); - session_started = FALSE; - - g_free (msg); - g_free (gdm_ack_response); - gdm_ack_response = NULL; - return; - } - - g_free (msg); - g_free (gdm_ack_response); - gdm_ack_response = NULL; - - /* Reset euid, egid back to user */ - if G_UNLIKELY (setegid (pwent->pw_gid) != 0 || - seteuid (pwent->pw_uid) != 0) { - gdm_error ("Cannot set effective user/group id"); - gdm_verify_cleanup (d); - session_started = FALSE; - return; - } - - home_dir_ok = FALSE; - home_dir = "/"; - } else { - home_dir_ok = TRUE; - home_dir = pwent->pw_dir; - } - - if G_LIKELY (home_dir_ok) { - /* Sanity check on ~user/.dmrc */ - usrcfgok = gdm_file_check ("gdm_slave_session_start", pwent->pw_uid, - home_dir, ".dmrc", TRUE, FALSE, - gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE), - gdm_daemon_config_get_value_int (GDM_KEY_RELAX_PERM)); - } else { - usrcfgok = FALSE; - } - - if G_LIKELY (usrcfgok) { - gdm_daemon_config_get_user_session_lang (&usrsess, &usrlang, home_dir, &savesess); - } else { - /* This won't get displayed if the .dmrc file simply doesn't - * exist since we pass absentok=TRUE when we call gdm_file_check + char *tmp; + gboolean savesess = FALSE, savelang = FALSE; + gboolean usrcfgok = FALSE, authok = FALSE; + gboolean home_dir_ok = FALSE; + gboolean failsafe = FALSE; + time_t session_start_time, end_time; + pid_t pid; + GdmWaitPid *wp; + uid_t uid; + gid_t gid; + int logpipe[2]; + int logfilefd; + + gdm_debug ("gdm_slave_session_start: Attempting session for user '%s'", + login); + + pwent = getpwnam (login); + + if G_UNLIKELY (pwent == NULL) { + /* This is sort of an "assert", this should NEVER happen */ + if (greet) + gdm_slave_whack_greeter (); + gdm_slave_exit (DISPLAY_REMANAGE, + _("%s: User passed auth but getpwnam (%s) failed!"), "gdm_slave_session_start", login); + } + + logged_in_uid = uid = pwent->pw_uid; + logged_in_gid = gid = pwent->pw_gid; + + /* Run the PostLogin script */ + if G_UNLIKELY (gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_POSTLOGIN), + login, pwent, + TRUE /* pass_stdout */) != EXIT_SUCCESS && + /* ignore errors in failsafe modes */ + ! failsafe) { + gdm_verify_cleanup (d); + gdm_error (_("%s: Execution of PostLogin script returned > 0. Aborting."), "gdm_slave_session_start"); + /* script failed so just try again */ + return; + } + + /* + * Set euid, gid to user before testing for user's $HOME since root + * does not always have access to the user's $HOME directory. */ - gdm_error_box (d, - GTK_MESSAGE_WARNING, - _("User's $HOME/.dmrc file is being ignored. " - "This prevents the default session " - "and language from being saved. File " - "should be owned by user and have 644 " - "permissions. User's $HOME directory " - "must be owned by user and not writable " - "by other users.")); - usrsess = g_strdup (""); - usrlang = g_strdup (""); - } - - NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ()); - - if (greet) { - tmp = gdm_ensure_extension (usrsess, ".desktop"); - session = gdm_slave_greeter_ctl (GDM_SESS, tmp); - g_free (tmp); - - if (session != NULL && - strcmp (session, GDM_RESPONSE_CANCEL) == 0) { - gdm_debug ("User canceled login"); - gdm_verify_cleanup (d); - session_started = FALSE; - g_free (usrlang); - return; - } - - language = gdm_slave_greeter_ctl (GDM_LANG, usrlang); - if (language != NULL && - strcmp (language, GDM_RESPONSE_CANCEL) == 0) { - gdm_debug ("User canceled login"); - gdm_verify_cleanup (d); - session_started = FALSE; - g_free (usrlang); - return; - } - } else { - session = g_strdup (usrsess); - language = g_strdup (usrlang); - } - - tmp = gdm_strip_extension (session, ".desktop"); - g_free (session); - session = tmp; - - if (ve_string_empty (session)) { - g_free (session); - session = find_a_session (); - if (session == NULL) { - /* we're running out of options */ - session = g_strdup (GDM_SESSION_FAILSAFE_GNOME); - } - } - - if G_LIKELY (ve_string_empty (language)) { - g_free (language); - language = NULL; - } - - g_free (usrsess); - - gdm_debug ("Initial setting: session: '%s' language: '%s'\n", - session, ve_sure_string (language)); - - /* save this session as the users session */ - save_session = g_strdup (session); - - if (greet) { - char *ret = gdm_slave_greeter_ctl (GDM_SSESS, ""); - if ( ! ve_string_empty (ret)) - savesess = TRUE; - g_free (ret); - - ret = gdm_slave_greeter_ctl (GDM_SLANG, ""); - if ( ! ve_string_empty (ret)) - savelang = TRUE; - g_free (ret); - - gdm_debug ("gdm_slave_session_start: Authentication completed. Whacking greeter"); - - gdm_slave_whack_greeter (); - } - - if (gdm_daemon_config_get_value_bool (GDM_KEY_KILL_INIT_CLIENTS)) - gdm_server_whack_clients (d->dsp); - - /* Now that we will set up the user authorization we will - need to run session_stop to whack it */ - session_started = TRUE; - - /* Setup cookie -- We need this information during cleanup, thus - * cookie handling is done before fork()ing */ - - if G_UNLIKELY (setegid (pwent->pw_gid) != 0 || - seteuid (pwent->pw_uid) != 0) { - gdm_error ("Cannot set effective user/group id"); - gdm_slave_quick_exit (DISPLAY_REMANAGE); - } - - authok = gdm_auth_user_add (d, pwent->pw_uid, - /* Only pass the home_dir if - * it was ok */ - home_dir_ok ? home_dir : NULL); - - /* FIXME: this should be smarter and only do this on out-of-diskspace - * errors */ - if G_UNLIKELY ( ! authok && home_dir_ok) { - /* try wiping the .xsession-errors file (and perhaps other things) - in an attempt to gain disk space */ - if (wipe_xsession_errors (pwent, home_dir, home_dir_ok)) { - gdm_error ("Tried wiping some old user session errors files " - "to make disk space and will try adding user auth " - "files again"); - /* Try again */ - authok = gdm_auth_user_add (d, pwent->pw_uid, - /* Only pass the home_dir if - * it was ok */ - home_dir_ok ? home_dir : NULL); - } - } - - NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ()); - - if G_UNLIKELY ( ! authok) { - gdm_debug ("gdm_slave_session_start: Auth not OK"); - - gdm_error_box (d, - GTK_MESSAGE_ERROR, - _("GDM could not write to your authorization " - "file. This could mean that you are out of " - "disk space or that your home directory could " - "not be opened for writing. In any case, it " - "is not possible to log in. Please contact " - "your system administrator")); - - gdm_slave_session_stop (FALSE /* run_post_session */, - FALSE /* no_shutdown_check */); - - gdm_slave_quick_exit (DISPLAY_REMANAGE); - } - - if G_UNLIKELY (strcmp (session, GDM_SESSION_FAILSAFE_GNOME) == 0 || - strcmp (session, GDM_SESSION_FAILSAFE_XTERM) == 0 || - g_ascii_strcasecmp (session, "failsafe") == 0 /* hack */) - failsafe = TRUE; - - if G_LIKELY ( ! failsafe) { - char *exec = gdm_daemon_config_get_session_exec (session, FALSE /* check_try_exec */); - if ( ! ve_string_empty (exec) && - strcmp (exec, "failsafe") == 0) - failsafe = TRUE; - g_free (exec); - } - - /* Write out the Xservers file */ - gdm_slave_send_num (GDM_SOP_WRITE_X_SERVERS, 0 /* bogus */); - - if G_LIKELY (d->dsp != NULL) { - Cursor xcursor; - - XSetInputFocus (d->dsp, PointerRoot, - RevertToPointerRoot, CurrentTime); - - /* return left pointer */ - xcursor = XCreateFontCursor (d->dsp, GDK_LEFT_PTR); - XDefineCursor (d->dsp, - DefaultRootWindow (d->dsp), - xcursor); - XFreeCursor (d->dsp, xcursor); - XSync (d->dsp, False); - } - - /* Init the ~/.xsession-errors stuff */ - d->xsession_errors_bytes = 0; - d->xsession_errors_fd = -1; - d->session_output_fd = -1; - - logfilefd = open_xsession_errors (pwent, - failsafe, - home_dir, - home_dir_ok); - if G_UNLIKELY (logfilefd < 0 || - pipe (logpipe) != 0) { - if (logfilefd >= 0) - VE_IGNORE_EINTR (close (logfilefd)); - logfilefd = -1; - } - - /* don't completely rely on this, the user - * could reset time or do other crazy things */ - session_start_time = time (NULL); + if G_UNLIKELY (setegid (pwent->pw_gid) != 0 || + seteuid (pwent->pw_uid) != 0) { + gdm_error ("Cannot set effective user/group id"); + gdm_verify_cleanup (d); + session_started = FALSE; + return; + } + + if G_UNLIKELY (pwent->pw_dir == NULL || + ! g_file_test (pwent->pw_dir, G_FILE_TEST_IS_DIR)) { + char *yesno_msg; + char *msg = g_strdup_printf ( + _("Your home directory is listed as: '%s' " + "but it does not appear to exist. " + "Do you want to log in with the / (root) " + "directory as your home directory? " + "It is unlikely anything will work unless " + "you use a failsafe session."), + ve_sure_string (pwent->pw_dir)); + + /* Set euid, egid to root:gdm to manage user interaction */ + seteuid (0); + setegid (gdm_daemon_config_get_gdmgid ()); + + gdm_error (_("%s: Home directory for %s: '%s' does not exist!"), + "gdm_slave_session_start", + login, + ve_sure_string (pwent->pw_dir)); + + /* Check what the user wants to do */ + yesno_msg = g_strdup_printf ("yesno_msg=%s", msg); + gdm_slave_send_string (GDM_SOP_SHOW_YESNO_DIALOG, yesno_msg); + + g_free (yesno_msg); + + if (strcmp (gdm_ack_response, "no") == 0) { + gdm_verify_cleanup (d); + session_started = FALSE; + + g_free (msg); + g_free (gdm_ack_response); + gdm_ack_response = NULL; + return; + } + + g_free (msg); + g_free (gdm_ack_response); + gdm_ack_response = NULL; + + /* Reset euid, egid back to user */ + if G_UNLIKELY (setegid (pwent->pw_gid) != 0 || + seteuid (pwent->pw_uid) != 0) { + gdm_error ("Cannot set effective user/group id"); + gdm_verify_cleanup (d); + session_started = FALSE; + return; + } + + home_dir_ok = FALSE; + home_dir = "/"; + } else { + home_dir_ok = TRUE; + home_dir = pwent->pw_dir; + } + + if G_LIKELY (home_dir_ok) { + /* Sanity check on ~user/.dmrc */ + usrcfgok = gdm_file_check ("gdm_slave_session_start", pwent->pw_uid, + home_dir, ".dmrc", TRUE, FALSE, + gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE), + gdm_daemon_config_get_value_int (GDM_KEY_RELAX_PERM)); + } else { + usrcfgok = FALSE; + } + + if G_LIKELY (usrcfgok) { + gdm_daemon_config_get_user_session_lang (&usrsess, &usrlang, home_dir, &savesess); + } else { + /* This won't get displayed if the .dmrc file simply doesn't + * exist since we pass absentok=TRUE when we call gdm_file_check + */ + gdm_errorgui_error_box (d, + GTK_MESSAGE_WARNING, + _("User's $HOME/.dmrc file is being ignored. " + "This prevents the default session " + "and language from being saved. File " + "should be owned by user and have 644 " + "permissions. User's $HOME directory " + "must be owned by user and not writable " + "by other users.")); + usrsess = g_strdup (""); + usrlang = g_strdup (""); + } + + NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ()); + + if (greet) { + tmp = gdm_ensure_extension (usrsess, ".desktop"); + session = gdm_slave_greeter_ctl (GDM_SESS, tmp); + g_free (tmp); + + if (session != NULL && + strcmp (session, GDM_RESPONSE_CANCEL) == 0) { + gdm_debug ("User canceled login"); + gdm_verify_cleanup (d); + session_started = FALSE; + g_free (usrlang); + return; + } + + language = gdm_slave_greeter_ctl (GDM_LANG, usrlang); + if (language != NULL && + strcmp (language, GDM_RESPONSE_CANCEL) == 0) { + gdm_debug ("User canceled login"); + gdm_verify_cleanup (d); + session_started = FALSE; + g_free (usrlang); + return; + } + } else { + session = g_strdup (usrsess); + language = g_strdup (usrlang); + } + + tmp = gdm_strip_extension (session, ".desktop"); + g_free (session); + session = tmp; + + if (ve_string_empty (session)) { + g_free (session); + session = find_a_session (); + if (session == NULL) { + /* we're running out of options */ + session = g_strdup (GDM_SESSION_FAILSAFE_GNOME); + } + } + + if G_LIKELY (ve_string_empty (language)) { + g_free (language); + language = NULL; + } + + g_free (usrsess); + + gdm_debug ("Initial setting: session: '%s' language: '%s'\n", + session, ve_sure_string (language)); + + /* save this session as the users session */ + save_session = g_strdup (session); + + if (greet) { + char *ret = gdm_slave_greeter_ctl (GDM_SSESS, ""); + if ( ! ve_string_empty (ret)) + savesess = TRUE; + g_free (ret); + + ret = gdm_slave_greeter_ctl (GDM_SLANG, ""); + if ( ! ve_string_empty (ret)) + savelang = TRUE; + g_free (ret); + + gdm_debug ("gdm_slave_session_start: Authentication completed. Whacking greeter"); + + gdm_slave_whack_greeter (); + } + + if (gdm_daemon_config_get_value_bool (GDM_KEY_KILL_INIT_CLIENTS)) + gdm_server_whack_clients (d->dsp); + + /* Now that we will set up the user authorization we will + need to run session_stop to whack it */ + session_started = TRUE; + + /* Setup cookie -- We need this information during cleanup, thus + * cookie handling is done before fork()ing */ + + if G_UNLIKELY (setegid (pwent->pw_gid) != 0 || + seteuid (pwent->pw_uid) != 0) { + gdm_error ("Cannot set effective user/group id"); + gdm_slave_quick_exit (DISPLAY_REMANAGE); + } + + authok = gdm_auth_user_add (d, pwent->pw_uid, + /* Only pass the home_dir if + * it was ok */ + home_dir_ok ? home_dir : NULL); + + /* FIXME: this should be smarter and only do this on out-of-diskspace + * errors */ + if G_UNLIKELY ( ! authok && home_dir_ok) { + /* try wiping the .xsession-errors file (and perhaps other things) + in an attempt to gain disk space */ + if (wipe_xsession_errors (pwent, home_dir, home_dir_ok)) { + gdm_error ("Tried wiping some old user session errors files " + "to make disk space and will try adding user auth " + "files again"); + /* Try again */ + authok = gdm_auth_user_add (d, pwent->pw_uid, + /* Only pass the home_dir if + * it was ok */ + home_dir_ok ? home_dir : NULL); + } + } + + NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ()); + + if G_UNLIKELY ( ! authok) { + gdm_debug ("gdm_slave_session_start: Auth not OK"); + + gdm_errorgui_error_box (d, + GTK_MESSAGE_ERROR, + _("GDM could not write to your authorization " + "file. This could mean that you are out of " + "disk space or that your home directory could " + "not be opened for writing. In any case, it " + "is not possible to log in. Please contact " + "your system administrator")); + + gdm_slave_session_stop (FALSE /* run_post_session */, + FALSE /* no_shutdown_check */); + + gdm_slave_quick_exit (DISPLAY_REMANAGE); + } + + if G_UNLIKELY (strcmp (session, GDM_SESSION_FAILSAFE_GNOME) == 0 || + strcmp (session, GDM_SESSION_FAILSAFE_XTERM) == 0 || + g_ascii_strcasecmp (session, "failsafe") == 0 /* hack */) + failsafe = TRUE; + + if G_LIKELY ( ! failsafe) { + char *exec = gdm_daemon_config_get_session_exec (session, FALSE /* check_try_exec */); + if ( ! ve_string_empty (exec) && + strcmp (exec, "failsafe") == 0) + failsafe = TRUE; + g_free (exec); + } + + /* Write out the Xservers file */ + gdm_slave_send_num (GDM_SOP_WRITE_X_SERVERS, 0 /* bogus */); + + if G_LIKELY (d->dsp != NULL) { + Cursor xcursor; + + XSetInputFocus (d->dsp, PointerRoot, + RevertToPointerRoot, CurrentTime); + + /* return left pointer */ + xcursor = XCreateFontCursor (d->dsp, GDK_LEFT_PTR); + XDefineCursor (d->dsp, + DefaultRootWindow (d->dsp), + xcursor); + XFreeCursor (d->dsp, xcursor); + XSync (d->dsp, False); + } + + /* Init the ~/.xsession-errors stuff */ + d->xsession_errors_bytes = 0; + d->xsession_errors_fd = -1; + d->session_output_fd = -1; + + logfilefd = open_xsession_errors (pwent, + failsafe, + home_dir, + home_dir_ok); + if G_UNLIKELY (logfilefd < 0 || + pipe (logpipe) != 0) { + if (logfilefd >= 0) + VE_IGNORE_EINTR (close (logfilefd)); + logfilefd = -1; + } + + /* don't completely rely on this, the user + * could reset time or do other crazy things */ + session_start_time = time (NULL); #ifdef WITH_CONSOLE_KIT - ck_session_cookie = open_ck_session (pwent, d, session); + ck_session_cookie = open_ck_session (pwent, d, session); #endif - /* Start user process */ - gdm_sigchld_block_push (); - gdm_sigterm_block_push (); - pid = d->sesspid = fork (); - if (pid == 0) - gdm_unset_signals (); - gdm_sigterm_block_pop (); - gdm_sigchld_block_pop (); - - switch (pid) { - - case -1: - gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Error forking user session"), "gdm_slave_session_start"); - - case 0: - if G_LIKELY (logfilefd >= 0) { - VE_IGNORE_EINTR (close (logpipe[0])); - } - /* Never returns */ - session_child_run (pwent, - logpipe[1], - failsafe, - home_dir, - home_dir_ok, + g_debug ("Forking user session"); + + /* Start user process */ + gdm_sigchld_block_push (); + gdm_sigterm_block_push (); + pid = d->sesspid = fork (); + if (pid == 0) + gdm_unset_signals (); + gdm_sigterm_block_pop (); + gdm_sigchld_block_pop (); + + switch (pid) { + + case -1: + gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Error forking user session"), "gdm_slave_session_start"); + + case 0: + { + const char *gdm_system_locale; + const char *lang; + gboolean has_language; + + has_language = (language != NULL) && (language[0] != '\0'); + + gdm_system_locale = setlocale (LC_CTYPE, NULL); + if ((gdm_system_locale != NULL) && (!has_language)) { + lang = gdm_system_locale; + } else { + lang = language; + } + + if G_LIKELY (logfilefd >= 0) { + VE_IGNORE_EINTR (close (logpipe[0])); + } + /* Never returns */ + session_child_run (pwent, + logpipe[1], + failsafe, + home_dir, + home_dir_ok, #ifdef WITH_CONSOLE_KIT - ck_session_cookie, + ck_session_cookie, #endif - session, - save_session, - - ((gdm_system_locale != (char *) NULL) && - ( (language == NULL) || - ((language != NULL) && (strcmp (language, "") == 0))) == TRUE ? - gdm_system_locale : language), - gnome_session, - usrcfgok, - savesess, - savelang); - gdm_assert_not_reached (); - - default: - always_restart_greeter = FALSE; - if (!savelang && language && strcmp (usrlang, language)) { - if (gdm_system_locale) { - g_setenv ("LANG", gdm_system_locale, TRUE); - setlocale (LC_ALL, ""); - g_unsetenv ("GDM_LANG"); - /* for "GDM_LANG" */ - gdm_clearenv_no_lang (); - gdm_saveenv (); + session, + save_session, + lang, + gnome_session, + usrcfgok, + savesess, + savelang); + g_assert_not_reached (); + } + + default: + always_restart_greeter = FALSE; + if (!savelang && language && strcmp (usrlang, language)) { + const char *gdm_system_locale; + + gdm_system_locale = setlocale (LC_CTYPE, NULL); + + if (gdm_system_locale != NULL) { + g_setenv ("LANG", gdm_system_locale, TRUE); + setlocale (LC_ALL, ""); + g_unsetenv ("GDM_LANG"); + /* for "GDM_LANG" */ + gdm_clearenv_no_lang (); + gdm_saveenv (); + } + gdm_slave_greeter_ctl_no_ret (GDM_SETLANG, DEFAULT_LANGUAGE); } - gdm_slave_greeter_ctl_no_ret (GDM_SETLANG, DEFAULT_LANGUAGE); - } - break; - } - - /* this clears internal cache */ - gdm_daemon_config_get_session_exec (NULL, FALSE); - - if G_LIKELY (logfilefd >= 0) { - d->xsession_errors_fd = logfilefd; - d->session_output_fd = logpipe[0]; - /* make the output read fd non-blocking */ - fcntl (d->session_output_fd, F_SETFL, O_NONBLOCK); - VE_IGNORE_EINTR (close (logpipe[1])); - } - - /* We must be root for this, and we are, but just to make sure */ - NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ()); - /* Reset all the process limits, pam may have set some up for our process and that - is quite evil. But pam is generally evil, so this is to be expected. */ - gdm_reset_limits (); - - g_free (session); - g_free (save_session); - g_free (language); - g_free (usrlang); - g_free (gnome_session); - - gdm_slave_send_num (GDM_SOP_SESSPID, pid); - - gdm_sigchld_block_push (); - wp = slave_waitpid_setpid (d->sesspid); - gdm_sigchld_block_pop (); - - slave_waitpid (wp); - - d->sesspid = 0; - - /* finish reading the session output if any of it is still there */ - finish_session_output (TRUE); - - /* Now still as root make the system authfile readable by others, - and therefore by the gdm user */ - VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0644)); - - end_time = time (NULL); - - gdm_debug ("Session: start_time: %ld end_time: %ld", - (long)session_start_time, (long)end_time); - - /* 66 is a very magical number signifying failure in GDM */ - if G_UNLIKELY ((d->last_sess_status != 66) && - (/* sanity */ end_time >= session_start_time) && - (end_time - 10 <= session_start_time) && - /* only if the X server still exist! */ - d->servpid > 1) { - char *msg_string; - char *error_msg = + break; + } + + /* this clears internal cache */ + gdm_daemon_config_get_session_exec (NULL, FALSE); + + if G_LIKELY (logfilefd >= 0) { + d->xsession_errors_fd = logfilefd; + d->session_output_fd = logpipe[0]; + /* make the output read fd non-blocking */ + fcntl (d->session_output_fd, F_SETFL, O_NONBLOCK); + VE_IGNORE_EINTR (close (logpipe[1])); + } + + /* We must be root for this, and we are, but just to make sure */ + NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ()); + /* Reset all the process limits, pam may have set some up for our process and that + is quite evil. But pam is generally evil, so this is to be expected. */ + gdm_reset_limits (); + + g_free (session); + g_free (save_session); + g_free (language); + g_free (gnome_session); + + gdm_slave_send_num (GDM_SOP_SESSPID, pid); + + gdm_sigchld_block_push (); + wp = slave_waitpid_setpid (d->sesspid); + gdm_sigchld_block_pop (); + + slave_waitpid (wp); + + d->sesspid = 0; + + /* finish reading the session output if any of it is still there */ + finish_session_output (TRUE); + + /* Now still as root make the system authfile readable by others, + and therefore by the gdm user */ + VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0644)); + + end_time = time (NULL); + + gdm_debug ("Session: start_time: %ld end_time: %ld", + (long)session_start_time, (long)end_time); + + /* 66 is a very magical number signifying failure in GDM */ + if G_UNLIKELY ((d->last_sess_status != 66) && + (/* sanity */ end_time >= session_start_time) && + (end_time - 10 <= session_start_time) && + /* only if the X server still exist! */ + d->servpid > 1) { + char *msg_string; + char *error_msg = _("Your session only lasted less than " "10 seconds. If you have not logged out " "yourself, this could mean that there is " @@ -4485,34 +4518,34 @@ gdm_slave_session_start (void) "one of the failsafe sessions to see if you " "can fix this problem."); - /* FIXME: perhaps do some checking to display a better error, - * such as gnome-session missing and such things. */ - gdm_debug ("Session less than 10 seconds!"); - msg_string = g_strdup_printf ("type=%d$$error_msg=%s$$details_label=%s$$details_file=%s$$uid=%d$$gid=%d", - GTK_MESSAGE_WARNING,error_msg, - (d->xsession_errors_filename != NULL) ? - _("View details (~/.xsession-errors file)") : - NULL, - d->xsession_errors_filename, - 0, 0); + /* FIXME: perhaps do some checking to display a better error, + * such as gnome-session missing and such things. */ + gdm_debug ("Session less than 10 seconds!"); + msg_string = g_strdup_printf ("type=%d$$error_msg=%s$$details_label=%s$$details_file=%s$$uid=%d$$gid=%d", + GTK_MESSAGE_WARNING,error_msg, + (d->xsession_errors_filename != NULL) ? + _("View details (~/.xsession-errors file)") : + NULL, + d->xsession_errors_filename, + 0, 0); - gdm_slave_send_string (GDM_SOP_SHOW_ERROR_DIALOG, msg_string); + gdm_slave_send_string (GDM_SOP_SHOW_ERROR_DIALOG, msg_string); - g_free (msg_string); + g_free (msg_string); - } + } #ifdef WITH_CONSOLE_KIT - if (ck_session_cookie != NULL) { - close_ck_session (ck_session_cookie); - g_free (ck_session_cookie); - } + if (ck_session_cookie != NULL) { + close_ck_session (ck_session_cookie); + g_free (ck_session_cookie); + } #endif - gdm_slave_session_stop (pid != 0 /* run_post_session */, - FALSE /* no_shutdown_check */); + gdm_slave_session_stop (pid != 0 /* run_post_session */, + FALSE /* no_shutdown_check */); - gdm_debug ("gdm_slave_session_start: Session ended OK (now all finished)"); + gdm_debug ("gdm_slave_session_start: Session ended OK (now all finished)"); } @@ -4521,137 +4554,129 @@ static void gdm_slave_session_stop (gboolean run_post_session, gboolean no_shutdown_check) { - struct passwd *pwent; - char *x_servers_file; - char *local_login; + struct passwd *pwent; + char *x_servers_file; + char *local_login; + + in_session_stop++; - in_session_stop++; + session_started = FALSE; - session_started = FALSE; + local_login = login; + login = NULL; - local_login = login; - login = NULL; + /* don't use NEVER_FAILS_ here this can be called from places + kind of exiting and it's ok if this doesn't work (when shouldn't + it work anyway? */ + seteuid (0); + setegid (0); - /* don't use NEVER_FAILS_ here this can be called from places - kind of exiting and it's ok if this doesn't work (when shouldn't - it work anyway? */ - seteuid (0); - setegid (0); + gdm_slave_send_num (GDM_SOP_SESSPID, 0); - gdm_slave_send_num (GDM_SOP_SESSPID, 0); + /* Now still as root make the system authfile not readable by others, + and therefore not by the gdm user */ + if (GDM_AUTHFILE (d) != NULL) { + VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0640)); + } - /* Now still as root make the system authfile not readable by others, - and therefore not by the gdm user */ - if (GDM_AUTHFILE (d) != NULL) { - VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0640)); - } + gdm_debug ("gdm_slave_session_stop: %s on %s", local_login, d->name); - gdm_debug ("gdm_slave_session_stop: %s on %s", local_login, d->name); + /* Note we use the info in the structure here since if we get passed + * a 0 that means the process is already dead. + * FIXME: Maybe we should waitpid here, note make sure this will + * not create a hang! */ + gdm_sigchld_block_push (); + if (d->sesspid > 1) + kill (- (d->sesspid), SIGTERM); + gdm_sigchld_block_pop (); - /* Note we use the info in the structure here since if we get passed - * a 0 that means the process is already dead. - * FIXME: Maybe we should waitpid here, note make sure this will - * not create a hang! */ - gdm_sigchld_block_push (); - if (d->sesspid > 1) - kill (- (d->sesspid), SIGTERM); - gdm_sigchld_block_pop (); + finish_session_output (run_post_session /* do_read */); - finish_session_output (run_post_session /* do_read */); - - if (local_login == NULL) - pwent = NULL; - else - pwent = getpwnam (local_login); /* PAM overwrites our pwent */ + if (local_login == NULL) + pwent = NULL; + else + pwent = getpwnam (local_login); /* PAM overwrites our pwent */ - x_servers_file = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), - d->name, ".Xservers"); + x_servers_file = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), + d->name, ".Xservers"); - /* if there was a session that ran, run the PostSession script */ - if (run_post_session) { - /* Execute post session script */ - gdm_debug ("gdm_slave_session_stop: Running post session script"); - gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_POSTSESSION), local_login, pwent, - FALSE /* pass_stdout */); - } + /* if there was a session that ran, run the PostSession script */ + if (run_post_session) { + /* Execute post session script */ + gdm_debug ("gdm_slave_session_stop: Running post session script"); + gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_POSTSESSION), local_login, pwent, + FALSE /* pass_stdout */); + } - VE_IGNORE_EINTR (g_unlink (x_servers_file)); - g_free (x_servers_file); + VE_IGNORE_EINTR (g_unlink (x_servers_file)); + g_free (x_servers_file); - g_free (local_login); + g_free (local_login); - if (pwent != NULL) { - seteuid (0); /* paranoia */ - /* Remove display from ~user/.Xauthority */ - if G_LIKELY (setegid (pwent->pw_gid) == 0 && - seteuid (pwent->pw_uid) == 0) { - gdm_auth_user_remove (d, pwent->pw_uid); - } + if (pwent != NULL) { + seteuid (0); /* paranoia */ + /* Remove display from ~user/.Xauthority */ + if G_LIKELY (setegid (pwent->pw_gid) == 0 && + seteuid (pwent->pw_uid) == 0) { + gdm_auth_user_remove (d, pwent->pw_uid); + } - /* don't use NEVER_FAILS_ here this can be called from places - kind of exiting and it's ok if this doesn't work (when shouldn't - it work anyway? */ - seteuid (0); - setegid (0); - } + /* don't use NEVER_FAILS_ here this can be called from places + kind of exiting and it's ok if this doesn't work (when shouldn't + it work anyway? */ + seteuid (0); + setegid (0); + } - logged_in_uid = -1; - logged_in_gid = -1; + logged_in_uid = -1; + logged_in_gid = -1; - /* things are going to be killed, so ignore errors */ - XSetErrorHandler (ignore_xerror_handler); + /* things are going to be killed, so ignore errors */ + XSetErrorHandler (ignore_xerror_handler); - gdm_verify_cleanup (d); + gdm_verify_cleanup (d); - in_session_stop --; + in_session_stop --; - if (need_to_quit_after_session_stop) { - gdm_debug ("gdm_slave_session_stop: Final cleanup"); + if (need_to_quit_after_session_stop) { + gdm_debug ("gdm_slave_session_stop: Final cleanup"); - gdm_slave_quick_exit (exit_code_to_use); - } + gdm_slave_quick_exit (exit_code_to_use); + } #ifdef __linux__ - /* If on Linux and the runlevel is 0 or 6 and not the runlevel that - we were started in, then we are restarting or halting the machine. - Probably the user selected halt or restart from the logout - menu. In this case we can really just sleep for a few seconds and - basically wait to be killed. I will set the default for 30 seconds - and let people yell at me if this breaks something. It shouldn't. - In fact it should fix things so that the login screen is not brought - up again and then whacked. Waiting is safer then DISPLAY_ABORT, - since if we really do get this wrong, then at the worst case the - user will wait for a few moments. */ - if ( ! need_to_quit_after_session_stop && - ! no_shutdown_check && - g_access ("/sbin/runlevel", X_OK) == 0) { - char ign; - int rnl; - FILE *fp = popen ("/sbin/runlevel", "r"); - if (fp != NULL && - fscanf (fp, "%c %d", &ign, &rnl) == 2 && - (rnl == 0 || rnl == 6) && - rnl != gdm_normal_runlevel) { - /* this is a stupid loop, but we may be getting signals, - so we don't want to just do sleep (30) */ - time_t c = time (NULL); - gdm_info (_("GDM detected a halt or restart " - "in progress.")); - pclose (fp); - while (c + 30 >= time (NULL)) { - struct timeval tv; - /* Wait 30 seconds. */ - tv.tv_sec = 30; - tv.tv_usec = 0; - select (0, NULL, NULL, NULL, &tv); - /* don't want to use sleep since we're using alarm - for pinging */ - } - /* hmm, didn't get TERM, weird */ - } else if (fp != NULL) { - pclose (fp); - } - } + /* If on Linux and the runlevel is 0 or 6 and not the runlevel that + we were started in, then we are restarting or halting the machine. + Probably the user selected halt or restart from the logout + menu. In this case we can really just sleep for a few seconds and + basically wait to be killed. I will set the default for 30 seconds + and let people yell at me if this breaks something. It shouldn't. + In fact it should fix things so that the login screen is not brought + up again and then whacked. Waiting is safer then DISPLAY_ABORT, + since if we really do get this wrong, then at the worst case the + user will wait for a few moments. */ + if ( ! need_to_quit_after_session_stop && + ! no_shutdown_check && + g_access ("/sbin/runlevel", X_OK) == 0) { + int rnl = get_runlevel (); + if ((rnl == 0 || rnl == 6) && rnl != gdm_normal_runlevel) { + /* this is a stupid loop, but we may be getting signals, + so we don't want to just do sleep (30) */ + time_t c = time (NULL); + gdm_info (_("GDM detected a halt or restart " + "in progress.")); + while (c + 30 >= time (NULL)) { + struct timeval tv; + /* Wait 30 seconds. */ + tv.tv_sec = 30; + tv.tv_usec = 0; + select (0, NULL, NULL, NULL, &tv); + /* don't want to use sleep since we're using alarm + for pinging */ + } + /* hmm, didn't get TERM, weird */ + } + } #endif /* __linux__ */ } @@ -4746,134 +4771,134 @@ gdm_slave_alrm_handler (int sig) } /* Called on every SIGCHLD */ -void +void gdm_slave_child_handler (int sig) { - gint status; - pid_t pid; - uid_t old; - - if G_UNLIKELY (already_in_slave_start_jmp) - return; - - gdm_in_signal++; - - old = geteuid (); - if (old != 0) - seteuid (0); - - while ((pid = waitpid (-1, &status, WNOHANG)) > 0) { - GSList *li; - - for (li = slave_waitpids; li != NULL; li = li->next) { - GdmWaitPid *wp = li->data; - if (wp->pid == pid) { - wp->pid = -1; - if (slave_waitpid_w >= 0) { - VE_IGNORE_EINTR (write (slave_waitpid_w, "!", 1)); + gint status; + pid_t pid; + uid_t old; + + if G_UNLIKELY (already_in_slave_start_jmp) + return; + + gdm_in_signal++; + + old = geteuid (); + if (old != 0) + seteuid (0); + + while ((pid = waitpid (-1, &status, WNOHANG)) > 0) { + GSList *li; + + for (li = slave_waitpids; li != NULL; li = li->next) { + GdmWaitPid *wp = li->data; + if (wp->pid == pid) { + wp->pid = -1; + if (slave_waitpid_w >= 0) { + VE_IGNORE_EINTR (write (slave_waitpid_w, "!", 1)); + } } } - } - - if (pid == d->greetpid && greet) { - if (WIFEXITED (status) && - WEXITSTATUS (status) == DISPLAY_RESTARTGREETER) { - /* FIXME: shouldn't do this from - a signal handler */ - /*gdm_slave_desensitize_config ();*/ - greet = FALSE; - d->greetpid = 0; - whack_greeter_fds (); - gdm_slave_send_num (GDM_SOP_GREETPID, 0); + if (pid == d->greetpid && greet) { + if (WIFEXITED (status) && + WEXITSTATUS (status) == DISPLAY_RESTARTGREETER) { + /* FIXME: shouldn't do this from + a signal handler */ + /*gdm_slave_desensitize_config ();*/ - do_restart_greeter = TRUE; - if (restart_greeter_now) { - slave_waitpid_notify (); - } else { - interrupted = TRUE; + greet = FALSE; + d->greetpid = 0; + whack_greeter_fds (); + gdm_slave_send_num (GDM_SOP_GREETPID, 0); + + do_restart_greeter = TRUE; + if (restart_greeter_now) { + slave_waitpid_notify (); + } else { + interrupted = TRUE; + } + continue; } - continue; - } - whack_greeter_fds (); + whack_greeter_fds (); - /* if greet is TRUE, then the greeter died outside of our - * control really, so clean up and die, something is wrong - * The greeter is only allowed to pass back these - * exit codes, else we'll just remanage */ - if (WIFEXITED (status) && - (WEXITSTATUS (status) == DISPLAY_ABORT || - WEXITSTATUS (status) == DISPLAY_REBOOT || - WEXITSTATUS (status) == DISPLAY_HALT || - WEXITSTATUS (status) == DISPLAY_SUSPEND || - WEXITSTATUS (status) == DISPLAY_RUN_CHOOSER || - WEXITSTATUS (status) == DISPLAY_RESTARTGDM || - WEXITSTATUS (status) == DISPLAY_GREETERFAILED)) { - exit_code_to_use = WEXITSTATUS (status); - SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY); - } else { - if (WIFSIGNALED (status) && - (WTERMSIG (status) == SIGSEGV || - WTERMSIG (status) == SIGABRT || - WTERMSIG (status) == SIGPIPE || - WTERMSIG (status) == SIGBUS)) { - exit_code_to_use = DISPLAY_GREETERFAILED; + /* if greet is TRUE, then the greeter died outside of our + * control really, so clean up and die, something is wrong + * The greeter is only allowed to pass back these + * exit codes, else we'll just remanage */ + if (WIFEXITED (status) && + (WEXITSTATUS (status) == DISPLAY_ABORT || + WEXITSTATUS (status) == DISPLAY_REBOOT || + WEXITSTATUS (status) == DISPLAY_HALT || + WEXITSTATUS (status) == DISPLAY_SUSPEND || + WEXITSTATUS (status) == DISPLAY_RUN_CHOOSER || + WEXITSTATUS (status) == DISPLAY_RESTARTGDM || + WEXITSTATUS (status) == DISPLAY_GREETERFAILED)) { + exit_code_to_use = WEXITSTATUS (status); SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY); } else { - /* weird error return, interpret as failure */ - if (WIFEXITED (status) && - WEXITSTATUS (status) == 1) + if (WIFSIGNALED (status) && + (WTERMSIG (status) == SIGSEGV || + WTERMSIG (status) == SIGABRT || + WTERMSIG (status) == SIGPIPE || + WTERMSIG (status) == SIGBUS)) { exit_code_to_use = DISPLAY_GREETERFAILED; - SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY); + SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY); + } else { + /* weird error return, interpret as failure */ + if (WIFEXITED (status) && + WEXITSTATUS (status) == 1) + exit_code_to_use = DISPLAY_GREETERFAILED; + SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY); + } } - } - } else if (pid != 0 && pid == d->sesspid) { - d->sesspid = 0; - if (WIFEXITED (status)) - d->last_sess_status = WEXITSTATUS (status); - else - d->last_sess_status = -1; - } else if (pid != 0 && pid == d->chooserpid) { - d->chooserpid = 0; - } else if (pid != 0 && pid == d->servpid) { - if (d->servstat == SERVER_RUNNING) - gdm_server_whack_lockfile (d); - d->servstat = SERVER_DEAD; - d->servpid = 0; - gdm_server_wipe_cookies (d); - gdm_slave_whack_temp_auth_file (); + } else if (pid != 0 && pid == d->sesspid) { + d->sesspid = 0; + if (WIFEXITED (status)) + d->last_sess_status = WEXITSTATUS (status); + else + d->last_sess_status = -1; + } else if (pid != 0 && pid == d->chooserpid) { + d->chooserpid = 0; + } else if (pid != 0 && pid == d->servpid) { + if (d->servstat == SERVER_RUNNING) + gdm_server_whack_lockfile (d); + d->servstat = SERVER_DEAD; + d->servpid = 0; + gdm_server_wipe_cookies (d); + gdm_slave_whack_temp_auth_file (); - gdm_slave_send_num (GDM_SOP_XPID, 0); + gdm_slave_send_num (GDM_SOP_XPID, 0); - /* whack the session good */ - if (d->sesspid > 1) { - gdm_slave_send_num (GDM_SOP_SESSPID, 0); - kill (- (d->sesspid), SIGTERM); - } - if (d->greetpid > 1) { - gdm_slave_send_num (GDM_SOP_GREETPID, 0); - kill (d->greetpid, SIGTERM); - } - if (d->chooserpid > 1) { - gdm_slave_send_num (GDM_SOP_CHOOSERPID, 0); - kill (d->chooserpid, SIGTERM); - } + /* whack the session good */ + if (d->sesspid > 1) { + gdm_slave_send_num (GDM_SOP_SESSPID, 0); + kill (- (d->sesspid), SIGTERM); + } + if (d->greetpid > 1) { + gdm_slave_send_num (GDM_SOP_GREETPID, 0); + kill (d->greetpid, SIGTERM); + } + if (d->chooserpid > 1) { + gdm_slave_send_num (GDM_SOP_CHOOSERPID, 0); + kill (d->chooserpid, SIGTERM); + } - /* just in case we restart again wait at least - one sec to avoid races */ - if (d->sleep_before_run < 1) - d->sleep_before_run = 1; - } else if (pid == extra_process) { - /* an extra process died, yay! */ - extra_process = 0; - extra_status = status; + /* just in case we restart again wait at least + one sec to avoid races */ + if (d->sleep_before_run < 1) + d->sleep_before_run = 1; + } else if (pid == extra_process) { + /* an extra process died, yay! */ + extra_process = 0; + extra_status = status; + } } - } - if (old != 0) - seteuid (old); + if (old != 0) + seteuid (old); - gdm_in_signal--; + gdm_in_signal--; } static void @@ -4949,7 +4974,7 @@ gdm_slave_handle_usr2_message (void) if (s[2] == '0') { gdm_ack_response = g_strdup ("no"); } else { - gdm_ack_response = g_strdup ("yes"); + gdm_ack_response = g_strdup ("yes"); } } else if (s[1] == GDM_SLAVE_NOTIFY_ASKBUTTONS_RESPONSE) { gdm_ack_response = g_strdup (&s[2]); @@ -4984,8 +5009,8 @@ gdm_slave_usr2_handler (int sig) static gint gdm_slave_xerror_handler (Display *disp, XErrorEvent *evt) { - gdm_debug ("gdm_slave_xerror_handler: X error - display doesn't respond"); - return (0); + gdm_debug ("gdm_slave_xerror_handler: X error - display doesn't respond"); + return (0); } /* We usually respond to fatal errors by restarting the display */ @@ -5054,7 +5079,7 @@ check_for_interruption (const char *msg) * it is allowed for this display (it's only allowed * for the first local display) and if it's set up * correctly */ - if ((d->attached || gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN)) + if ((d->attached || gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN)) && d->timed_login_ok && ! ve_string_empty (ParsedTimedLogin) && strcmp (ParsedTimedLogin, gdm_root_user ()) != 0 && @@ -5075,8 +5100,8 @@ check_for_interruption (const char *msg) gdm_daemon_config_get_value_bool_per_display (d->name, GDM_KEY_SYSTEM_MENU) && ! ve_string_empty (gdm_daemon_config_get_value_string (GDM_KEY_SUSPEND))) { gchar *msg = g_strdup_printf ("%s %ld", - GDM_SOP_SUSPEND_MACHINE, - (long)getpid ()); + GDM_SOP_SUSPEND_MACHINE, + (long)getpid ()); gdm_slave_send (msg, FALSE /* wait_for_ack */); g_free (msg); @@ -5101,8 +5126,8 @@ check_for_interruption (const char *msg) if (d->attached && ! ve_string_empty (&msg[2])) { gchar *message = g_strdup_printf ("%s %ld %s", - GDM_SOP_CUSTOM_CMD, - (long)getpid (), &msg[2]); + GDM_SOP_CUSTOM_CMD, + (long)getpid (), &msg[2]); gdm_slave_send (message, TRUE); g_free (message); @@ -5117,12 +5142,17 @@ check_for_interruption (const char *msg) return TRUE; case GDM_INTERRUPT_SELECT_LANG: if (msg + 2) { - gchar *locale = (gchar*)(msg + 3); + const char *locale; + const char *gdm_system_locale; + + locale = (gchar*)(msg + 3); + gdm_system_locale = setlocale (LC_CTYPE, NULL); always_restart_greeter = (gboolean)(*(msg + 2)); - gdm_clearenv (); - if (!strcmp (locale, DEFAULT_LANGUAGE)) + ve_clearenv (); + if (!strcmp (locale, DEFAULT_LANGUAGE)) { locale = gdm_system_locale; + } g_setenv ("GDM_LANG", locale, TRUE); g_setenv ("LANG", locale, TRUE); g_unsetenv ("LC_ALL"); @@ -5149,54 +5179,54 @@ check_for_interruption (const char *msg) } -char * +char * gdm_slave_greeter_ctl (char cmd, const char *str) { - char *buf = NULL; - int c; + char *buf = NULL; + int c; - /* There is no spoon^H^H^H^H^Hgreeter */ - if G_UNLIKELY ( ! greet) - return NULL; + /* There is no spoon^H^H^H^H^Hgreeter */ + if G_UNLIKELY ( ! greet) + return NULL; - check_notifies_now (); + check_notifies_now (); - if ( ! ve_string_empty (str)) { - gdm_fdprintf (greeter_fd_out, "%c%c%s\n", STX, cmd, str); - } else { - gdm_fdprintf (greeter_fd_out, "%c%c\n", STX, cmd); - } + if ( ! ve_string_empty (str)) { + gdm_fdprintf (greeter_fd_out, "%c%c%s\n", STX, cmd, str); + } else { + gdm_fdprintf (greeter_fd_out, "%c%c\n", STX, cmd); + } #if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD) - /* let the other process (greeter) do its stuff */ - sched_yield (); + /* let the other process (greeter) do its stuff */ + sched_yield (); #endif - do { - g_free (buf); - buf = NULL; - /* Skip random junk that might have accumulated */ - do { - c = gdm_fdgetc (greeter_fd_in); - } while (c != EOF && c != STX); - - if (c == EOF || - (buf = gdm_fdgets (greeter_fd_in)) == NULL) { - interrupted = TRUE; - /* things don't seem well with the greeter, it probably died */ - return NULL; - } - } while (check_for_interruption (buf) && ! interrupted); - - /* user responses take kind of random amount of time */ - gdm_random_tick (); - - if ( ! ve_string_empty (buf)) { - return buf; - } else { - g_free (buf); - return NULL; - } + do { + g_free (buf); + buf = NULL; + /* Skip random junk that might have accumulated */ + do { + c = gdm_fdgetc (greeter_fd_in); + } while (c != EOF && c != STX); + + if (c == EOF || + (buf = gdm_fdgets (greeter_fd_in)) == NULL) { + interrupted = TRUE; + /* things don't seem well with the greeter, it probably died */ + return NULL; + } + } while (check_for_interruption (buf) && ! interrupted); + + /* user responses take kind of random amount of time */ + gdm_random_tick (); + + if ( ! ve_string_empty (buf)) { + return buf; + } else { + g_free (buf); + return NULL; + } } void @@ -5205,92 +5235,92 @@ gdm_slave_greeter_ctl_no_ret (char cmd, const char *str) g_free (gdm_slave_greeter_ctl (cmd, str)); } -static void +static void gdm_slave_quick_exit (gint status) { - /* just for paranoia's sake */ - /* don't use NEVER_FAILS_ here this can be called from places - kind of exiting and it's ok if this doesn't work (when shouldn't - it work anyway? */ - seteuid (0); - setegid (0); + /* just for paranoia's sake */ + /* don't use NEVER_FAILS_ here this can be called from places + kind of exiting and it's ok if this doesn't work (when shouldn't + it work anyway? */ + seteuid (0); + setegid (0); - if (d != NULL) { - gdm_debug ("gdm_slave_quick_exit: Will kill everything from the display"); + if (d != NULL) { + gdm_debug ("gdm_slave_quick_exit: Will kill everything from the display"); - /* just in case we do get the XIOError, - don't run session_stop since we've - requested a quick exit */ - session_started = FALSE; + /* just in case we do get the XIOError, + don't run session_stop since we've + requested a quick exit */ + session_started = FALSE; - /* No need to send the PIDS to the daemon - * since we'll just exit cleanly */ + /* No need to send the PIDS to the daemon + * since we'll just exit cleanly */ - /* Push and never pop */ - gdm_sigchld_block_push (); + /* Push and never pop */ + gdm_sigchld_block_push (); - /* Kill children where applicable */ - if (d->greetpid > 1) - kill (d->greetpid, SIGTERM); - d->greetpid = 0; + /* Kill children where applicable */ + if (d->greetpid > 1) + kill (d->greetpid, SIGTERM); + d->greetpid = 0; - if (d->chooserpid > 1) - kill (d->chooserpid, SIGTERM); - d->chooserpid = 0; + if (d->chooserpid > 1) + kill (d->chooserpid, SIGTERM); + d->chooserpid = 0; - if (d->sesspid > 1) - kill (-(d->sesspid), SIGTERM); - d->sesspid = 0; + if (d->sesspid > 1) + kill (-(d->sesspid), SIGTERM); + d->sesspid = 0; - if (extra_process > 1) - kill (-(extra_process), SIGTERM); - extra_process = 0; + if (extra_process > 1) + kill (-(extra_process), SIGTERM); + extra_process = 0; - gdm_verify_cleanup (d); - gdm_server_stop (d); + gdm_verify_cleanup (d); + gdm_server_stop (d); - if (d->servpid > 1) - kill (d->servpid, SIGTERM); - d->servpid = 0; + if (d->servpid > 1) + kill (d->servpid, SIGTERM); + d->servpid = 0; - gdm_debug ("gdm_slave_quick_exit: Killed everything from the display"); - } + gdm_debug ("gdm_slave_quick_exit: Killed everything from the display"); + } - _exit (status); + _exit (status); } -static void +static void gdm_slave_exit (gint status, const gchar *format, ...) { - va_list args; - gchar *s; - - va_start (args, format); - s = g_strdup_vprintf (format, args); - va_end (args); - - gdm_error ("%s", s); - - g_free (s); - - gdm_slave_quick_exit (status); + va_list args; + gchar *s; + + va_start (args, format); + s = g_strdup_vprintf (format, args); + va_end (args); + + gdm_error ("%s", s); + + g_free (s); + + gdm_slave_quick_exit (status); } -static void +static void gdm_child_exit (gint status, const gchar *format, ...) { - va_list args; - gchar *s; - - va_start (args, format); - s = g_strdup_vprintf (format, args); - va_end (args); - - syslog (LOG_ERR, "%s", s); - - g_free (s); - - _exit (status); + va_list args; + gchar *s; + + va_start (args, format); + s = g_strdup_vprintf (format, args); + va_end (args); + + g_error ("%s", s); + + g_free (s); + + _exit (status); } void @@ -5333,7 +5363,7 @@ set_xnest_parent_stuff (void) g_setenv ("GDM_PARENT_DISPLAY", d->parent_disp, TRUE); if (d->parent_temp_auth_file != NULL) { g_setenv ("GDM_PARENT_XAUTHORITY", - d->parent_temp_auth_file, TRUE); + d->parent_temp_auth_file, TRUE); g_free (d->parent_temp_auth_file); d->parent_temp_auth_file = NULL; } @@ -5341,164 +5371,169 @@ set_xnest_parent_stuff (void) } static gint -gdm_slave_exec_script (GdmDisplay *d, const gchar *dir, const char *login, - struct passwd *pwent, gboolean pass_stdout) +gdm_slave_exec_script (GdmDisplay *d, + const gchar *dir, + const char *login, + struct passwd *pwent, + gboolean pass_stdout) { - pid_t pid; - char *script; - gchar **argv; - gint status; - char *x_servers_file; - - if G_UNLIKELY (!d || ve_string_empty (dir)) - return EXIT_SUCCESS; - - script = g_build_filename (dir, d->name, NULL); - if (g_access (script, R_OK|X_OK) != 0) { - g_free (script); - script = NULL; - } - if (script == NULL && - ! ve_string_empty (d->hostname)) { - script = g_build_filename (dir, d->hostname, NULL); - if (g_access (script, R_OK|X_OK) != 0) { - g_free (script); - script = NULL; - } - } - if (script == NULL && - SERVER_IS_XDMCP (d)) { - script = g_build_filename (dir, "XDMCP", NULL); - if (g_access (script, R_OK|X_OK) != 0) { - g_free (script); - script = NULL; - } - } - if (script == NULL && - SERVER_IS_FLEXI (d)) { - script = g_build_filename (dir, "Flexi", NULL); - if (g_access (script, R_OK|X_OK) != 0) { - g_free (script); - script = NULL; - } - } - if (script == NULL) { - script = g_build_filename (dir, "Default", NULL); - if (g_access (script, R_OK|X_OK) != 0) { - g_free (script); - script = NULL; - } - } - - if (script == NULL) { - return EXIT_SUCCESS; - } - - create_temp_auth_file (); - - pid = gdm_fork_extra (); - - switch (pid) { - - case 0: - closelog (); - - VE_IGNORE_EINTR (close (0)); - gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */ + pid_t pid; + char *script; + gchar **argv; + gint status; + char *x_servers_file; + + if G_UNLIKELY (!d || ve_string_empty (dir)) + return EXIT_SUCCESS; + + script = g_build_filename (dir, d->name, NULL); + if (g_access (script, R_OK|X_OK) != 0) { + g_free (script); + script = NULL; + } + if (script == NULL && + ! ve_string_empty (d->hostname)) { + script = g_build_filename (dir, d->hostname, NULL); + if (g_access (script, R_OK|X_OK) != 0) { + g_free (script); + script = NULL; + } + } + if (script == NULL && + SERVER_IS_XDMCP (d)) { + script = g_build_filename (dir, "XDMCP", NULL); + if (g_access (script, R_OK|X_OK) != 0) { + g_free (script); + script = NULL; + } + } + if (script == NULL && + SERVER_IS_FLEXI (d)) { + script = g_build_filename (dir, "Flexi", NULL); + if (g_access (script, R_OK|X_OK) != 0) { + g_free (script); + script = NULL; + } + } + if (script == NULL) { + script = g_build_filename (dir, "Default", NULL); + if (g_access (script, R_OK|X_OK) != 0) { + g_free (script); + script = NULL; + } + } - if ( ! pass_stdout) { - VE_IGNORE_EINTR (close (1)); - VE_IGNORE_EINTR (close (2)); - /* No error checking here - if it's messed the best response - * is to ignore & try to continue */ - gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */ - gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */ + if (script == NULL) { + return EXIT_SUCCESS; } - gdm_close_all_descriptors (3 /* from */, -1 /* except */, -1 /* except2 */); + create_temp_auth_file (); - openlog ("gdm", LOG_PID, LOG_DAEMON); + g_debug ("Forking extra process: %s", script); - if (login != NULL) { - g_setenv ("LOGNAME", login, TRUE); - g_setenv ("USER", login, TRUE); - g_setenv ("USERNAME", login, TRUE); - } else { - const char *gdmuser = gdm_daemon_config_get_value_string (GDM_KEY_USER); - g_setenv ("LOGNAME", gdmuser, TRUE); - g_setenv ("USER", gdmuser, TRUE); - g_setenv ("USERNAME", gdmuser, TRUE); - } - if (pwent != NULL) { - if (ve_string_empty (pwent->pw_dir)) { - g_setenv ("HOME", "/", TRUE); - g_setenv ("PWD", "/", TRUE); - VE_IGNORE_EINTR (g_chdir ("/")); + extra_process = pid = gdm_fork_extra (); + + switch (pid) { + case 0: + gdm_log_shutdown (); + + VE_IGNORE_EINTR (close (0)); + gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */ + + if ( ! pass_stdout) { + VE_IGNORE_EINTR (close (1)); + VE_IGNORE_EINTR (close (2)); + /* No error checking here - if it's messed the best response + * is to ignore & try to continue */ + gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */ + gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */ + } + + gdm_close_all_descriptors (3 /* from */, -1 /* except */, -1 /* except2 */); + + gdm_log_init (); + + if (login != NULL) { + g_setenv ("LOGNAME", login, TRUE); + g_setenv ("USER", login, TRUE); + g_setenv ("USERNAME", login, TRUE); } else { - g_setenv ("HOME", pwent->pw_dir, TRUE); - g_setenv ("PWD", pwent->pw_dir, TRUE); - VE_IGNORE_EINTR (g_chdir (pwent->pw_dir)); - if (errno != 0) { - VE_IGNORE_EINTR (g_chdir ("/")); + const char *gdmuser = gdm_daemon_config_get_value_string (GDM_KEY_USER); + g_setenv ("LOGNAME", gdmuser, TRUE); + g_setenv ("USER", gdmuser, TRUE); + g_setenv ("USERNAME", gdmuser, TRUE); + } + if (pwent != NULL) { + if (ve_string_empty (pwent->pw_dir)) { + g_setenv ("HOME", "/", TRUE); g_setenv ("PWD", "/", TRUE); + VE_IGNORE_EINTR (g_chdir ("/")); + } else { + g_setenv ("HOME", pwent->pw_dir, TRUE); + g_setenv ("PWD", pwent->pw_dir, TRUE); + VE_IGNORE_EINTR (g_chdir (pwent->pw_dir)); + if (errno != 0) { + VE_IGNORE_EINTR (g_chdir ("/")); + g_setenv ("PWD", "/", TRUE); + } } + g_setenv ("SHELL", pwent->pw_shell, TRUE); + } else { + g_setenv ("HOME", "/", TRUE); + g_setenv ("PWD", "/", TRUE); + VE_IGNORE_EINTR (g_chdir ("/")); + g_setenv ("SHELL", "/bin/sh", TRUE); } - g_setenv ("SHELL", pwent->pw_shell, TRUE); - } else { - g_setenv ("HOME", "/", TRUE); - g_setenv ("PWD", "/", TRUE); - VE_IGNORE_EINTR (g_chdir ("/")); - g_setenv ("SHELL", "/bin/sh", TRUE); - } - set_xnest_parent_stuff (); + set_xnest_parent_stuff (); - /* some env for use with the Pre and Post scripts */ - x_servers_file = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), - d->name, ".Xservers"); - g_setenv ("X_SERVERS", x_servers_file, TRUE); - g_free (x_servers_file); - if (SERVER_IS_XDMCP (d)) - g_setenv ("REMOTE_HOST", d->hostname, TRUE); + /* some env for use with the Pre and Post scripts */ + x_servers_file = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), + d->name, ".Xservers"); + g_setenv ("X_SERVERS", x_servers_file, TRUE); + g_free (x_servers_file); + if (SERVER_IS_XDMCP (d)) + g_setenv ("REMOTE_HOST", d->hostname, TRUE); - /* Runs as root */ - if (GDM_AUTHFILE (d) != NULL) - g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE); - else - g_unsetenv ("XAUTHORITY"); - g_setenv ("DISPLAY", d->name, TRUE); - g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_ROOT_PATH), TRUE); - g_setenv ("RUNNING_UNDER_GDM", "true", TRUE); - if ( ! ve_string_empty (d->theme_name)) - g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE); - g_unsetenv ("MAIL"); + /* Runs as root */ + if (GDM_AUTHFILE (d) != NULL) + g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE); + else + g_unsetenv ("XAUTHORITY"); + g_setenv ("DISPLAY", d->name, TRUE); + g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_ROOT_PATH), TRUE); + g_setenv ("RUNNING_UNDER_GDM", "true", TRUE); + if ( ! ve_string_empty (d->theme_name)) + g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE); + g_unsetenv ("MAIL"); - argv = NULL; - g_shell_parse_argv (script, NULL, &argv, NULL); + argv = NULL; + g_shell_parse_argv (script, NULL, &argv, NULL); - VE_IGNORE_EINTR (execv (argv[0], argv)); - syslog (LOG_ERR, _("%s: Failed starting: %s"), "gdm_slave_exec_script", - script); - _exit (EXIT_SUCCESS); - - case -1: - gdm_slave_whack_temp_auth_file (); - g_free (script); - syslog (LOG_ERR, _("%s: Can't fork script process!"), "gdm_slave_exec_script"); - return EXIT_SUCCESS; - - default: - gdm_wait_for_extra (&status); + VE_IGNORE_EINTR (execv (argv[0], argv)); + g_error (_("%s: Failed starting: %s"), + "gdm_slave_exec_script", + script); + _exit (EXIT_SUCCESS); - gdm_slave_whack_temp_auth_file (); + case -1: + gdm_slave_whack_temp_auth_file (); + g_free (script); + g_error (_("%s: Can't fork script process!"), "gdm_slave_exec_script"); + return EXIT_SUCCESS; - g_free (script); + default: + gdm_wait_for_extra (extra_process, &status); - if (WIFEXITED (status)) - return WEXITSTATUS (status); - else - return EXIT_SUCCESS; - } + gdm_slave_whack_temp_auth_file (); + + g_free (script); + + if (WIFEXITED (status)) + return WEXITSTATUS (status); + else + return EXIT_SUCCESS; + } } gboolean @@ -5524,150 +5559,151 @@ gdm_slave_action_pending (void) return TRUE; } -/* The user name for automatic/timed login may be parameterized by +/* The user name for automatic/timed login may be parameterized by host/display. */ static gchar * gdm_parse_enriched_login (const gchar *s, GdmDisplay *display) { - gchar cmd, in_buffer[20]; - GString *str; - gint pipe1[2], in_buffer_len; - gchar **argv; - pid_t pid; + gchar cmd, in_buffer[20]; + GString *str; + gint pipe1[2], in_buffer_len; + gchar **argv; + pid_t pid; + + if (s == NULL) + return (NULL); + + str = g_string_new (NULL); + + while (s[0] != '\0') { - if (s == NULL) - return (NULL); + if (s[0] == '%' && s[1] != 0) { + cmd = s[1]; + s++; - str = g_string_new (NULL); + switch (cmd) { - while (s[0] != '\0') { + case 'h': + g_string_append (str, display->hostname); + break; + + case 'd': + g_string_append (str, display->name); + break; - if (s[0] == '%' && s[1] != 0) { - cmd = s[1]; + case '%': + g_string_append_c (str, '%'); + break; + + default: + break; + }; + } else { + g_string_append_c (str, *s); + } s++; + } - switch (cmd) { + /* Sometimes it is not convenient to use the display or hostname as + user name. A script may be used to generate the automatic/timed + login name based on the display/host by ending the name with the + pipe symbol '|'. */ - case 'h': - g_string_append (str, display->hostname); - break; + if (str->len > 0 && str->str[str->len - 1] == '|') { + g_string_truncate (str, str->len - 1); + if G_UNLIKELY (pipe (pipe1) < 0) { + gdm_error (_("%s: Failed creating pipe"), + "gdm_parse_enriched_login"); + } else { + g_debug ("Forking extra process: %s", str->str); - case 'd': - g_string_append (str, display->name); - break; + extra_process = pid = gdm_fork_extra (); - case '%': - g_string_append_c (str, '%'); - break; + switch (pid) { + case 0: + /* The child will write the username to stdout based on the DISPLAY + environment variable. */ - default: - break; - }; - } else { - g_string_append_c (str, *s); - } - s++; - } - - /* Sometimes it is not convenient to use the display or hostname as - user name. A script may be used to generate the automatic/timed - login name based on the display/host by ending the name with the - pipe symbol '|'. */ - - if (str->len > 0 && str->str[str->len - 1] == '|') { - g_string_truncate (str, str->len - 1); - if G_UNLIKELY (pipe (pipe1) < 0) { - gdm_error (_("%s: Failed creating pipe"), - "gdm_parse_enriched_login"); - } else { - pid = gdm_fork_extra (); - - switch (pid) { - - case 0: - /* The child will write the username to stdout based on the DISPLAY - environment variable. */ - - VE_IGNORE_EINTR (close (pipe1[0])); - if G_LIKELY (pipe1[1] != STDOUT_FILENO) { - VE_IGNORE_EINTR (dup2 (pipe1[1], STDOUT_FILENO)); - } - - closelog (); - - gdm_close_all_descriptors (3 /* from */, pipe1[1] /* except */, -1 /* except2 */); - - openlog ("gdm", LOG_PID, LOG_DAEMON); - - /* runs as root */ - if (GDM_AUTHFILE (display) != NULL) - g_setenv ("XAUTHORITY", GDM_AUTHFILE (display), TRUE); - else - g_unsetenv ("XAUTHORITY"); - g_setenv ("DISPLAY", display->name, TRUE); - if (SERVER_IS_XDMCP (display)) - g_setenv ("REMOTE_HOST", display->hostname, TRUE); - g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_ROOT_PATH), TRUE); - g_setenv ("SHELL", "/bin/sh", TRUE); - g_setenv ("RUNNING_UNDER_GDM", "true", TRUE); - if ( ! ve_string_empty (d->theme_name)) - g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE); - g_unsetenv ("MAIL"); - - argv = NULL; - g_shell_parse_argv (str->str, NULL, &argv, NULL); - - VE_IGNORE_EINTR (execv (argv[0], argv)); - gdm_error (_("%s: Failed executing: %s"), - "gdm_parse_enriched_login", - str->str); - _exit (EXIT_SUCCESS); - - case -1: - gdm_error (_("%s: Can't fork script process!"), - "gdm_parse_enriched_login"); - VE_IGNORE_EINTR (close (pipe1[0])); - VE_IGNORE_EINTR (close (pipe1[1])); - break; - - default: - /* The parent reads username from the pipe a chunk at a time */ - VE_IGNORE_EINTR (close (pipe1[1])); - g_string_truncate (str, 0); - do { - VE_IGNORE_EINTR (in_buffer_len = read (pipe1[0], in_buffer, - sizeof (in_buffer) - 1)); - if (in_buffer_len > 0) { - in_buffer[in_buffer_len] = '\0'; - g_string_append (str, in_buffer); - } - } while (in_buffer_len > 0); - - if (str->len > 0 && str->str[str->len - 1] == '\n') - g_string_truncate (str, str->len - 1); - - VE_IGNORE_EINTR (close (pipe1[0])); - - gdm_wait_for_extra (NULL); - } - } - } - - if (!ve_string_empty(str->str) && gdm_is_user_valid(str->str)) - return g_string_free (str, FALSE); - else - { - /* "If an empty or otherwise invalid username is returned [by the script] - * automatic login [and timed login] is not performed." -- GDM manual - */ - /* fixme: also turn off automatic login */ - gdm_daemon_config_set_value_bool(GDM_KEY_TIMED_LOGIN_ENABLE, FALSE); - d->timed_login_ok = FALSE; - do_timed_login = FALSE; - g_string_free(str, TRUE); - return NULL; - } + VE_IGNORE_EINTR (close (pipe1[0])); + if G_LIKELY (pipe1[1] != STDOUT_FILENO) { + VE_IGNORE_EINTR (dup2 (pipe1[1], STDOUT_FILENO)); + } + + gdm_log_shutdown (); + + gdm_close_all_descriptors (3 /* from */, pipe1[1] /* except */, -1 /* except2 */); + + gdm_log_init (); + + /* runs as root */ + if (GDM_AUTHFILE (display) != NULL) + g_setenv ("XAUTHORITY", GDM_AUTHFILE (display), TRUE); + else + g_unsetenv ("XAUTHORITY"); + g_setenv ("DISPLAY", display->name, TRUE); + if (SERVER_IS_XDMCP (display)) + g_setenv ("REMOTE_HOST", display->hostname, TRUE); + g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_ROOT_PATH), TRUE); + g_setenv ("SHELL", "/bin/sh", TRUE); + g_setenv ("RUNNING_UNDER_GDM", "true", TRUE); + if ( ! ve_string_empty (d->theme_name)) + g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE); + g_unsetenv ("MAIL"); + + argv = NULL; + g_shell_parse_argv (str->str, NULL, &argv, NULL); + + VE_IGNORE_EINTR (execv (argv[0], argv)); + gdm_error (_("%s: Failed executing: %s"), + "gdm_parse_enriched_login", + str->str); + _exit (EXIT_SUCCESS); + + case -1: + gdm_error (_("%s: Can't fork script process!"), + "gdm_parse_enriched_login"); + VE_IGNORE_EINTR (close (pipe1[0])); + VE_IGNORE_EINTR (close (pipe1[1])); + break; + + default: + /* The parent reads username from the pipe a chunk at a time */ + VE_IGNORE_EINTR (close (pipe1[1])); + g_string_truncate (str, 0); + do { + VE_IGNORE_EINTR (in_buffer_len = read (pipe1[0], in_buffer, + sizeof (in_buffer) - 1)); + if (in_buffer_len > 0) { + in_buffer[in_buffer_len] = '\0'; + g_string_append (str, in_buffer); + } + } while (in_buffer_len > 0); + + if (str->len > 0 && str->str[str->len - 1] == '\n') + g_string_truncate (str, str->len - 1); + + VE_IGNORE_EINTR (close (pipe1[0])); + + gdm_wait_for_extra (extra_process, NULL); + } + } + } + + if (!ve_string_empty(str->str) && gdm_is_user_valid(str->str)) + return g_string_free (str, FALSE); + else + { + /* "If an empty or otherwise invalid username is returned [by the script] + * automatic login [and timed login] is not performed." -- GDM manual + */ + /* fixme: also turn off automatic login */ + gdm_daemon_config_set_value_bool(GDM_KEY_TIMED_LOGIN_ENABLE, FALSE); + d->timed_login_ok = FALSE; + do_timed_login = FALSE; + g_string_free(str, TRUE); + return NULL; + } } static void @@ -5722,7 +5758,7 @@ gdm_slave_handle_notify (const char *msg) strlen (GDM_NOTIFY_CUSTOM_CMD_TEMPLATE)) == 0) { if (sscanf (msg, GDM_NOTIFY_CUSTOM_CMD_TEMPLATE "%d", &val) == 1) { gchar * key_string = g_strdup_printf(_("%s%d="), GDM_KEY_CUSTOM_CMD_TEMPLATE, val); - /* This assumes that the number of commands is < 100, i.e two digits + /* This assumes that the number of commands is < 100, i.e two digits if that is not the case then this will fail */ gdm_daemon_config_set_value_string (key_string, ((gchar *)&msg[strlen (GDM_NOTIFY_CUSTOM_CMD_TEMPLATE) + 2])); g_free(key_string); @@ -5741,11 +5777,11 @@ gdm_slave_handle_notify (const char *msg) } } } - } + } } else if (strncmp (msg, GDM_NOTIFY_REMOTE_GREETER " ", strlen (GDM_NOTIFY_REMOTE_GREETER) + 1) == 0) { gdm_daemon_config_set_value_string (GDM_KEY_REMOTE_GREETER, - (gchar *)(&msg[strlen (GDM_NOTIFY_REMOTE_GREETER) + 1])); + (gchar *)(&msg[strlen (GDM_NOTIFY_REMOTE_GREETER) + 1])); if ( ! d->attached) { do_restart_greeter = TRUE; if (restart_greeter_now) { @@ -5779,25 +5815,25 @@ gdm_slave_handle_notify (const char *msg) } else if (strncmp (msg, GDM_NOTIFY_SOUND_ON_LOGIN_FILE " ", strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FILE) + 1) == 0) { gdm_daemon_config_set_value_string (GDM_KEY_SOUND_ON_LOGIN_FILE, - (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FILE) + 1])); + (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FILE) + 1])); if (d->greetpid > 1) kill (d->greetpid, SIGHUP); } else if (strncmp (msg, GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE " ", strlen (GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE) + 1) == 0) { gdm_daemon_config_set_value_string (GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE, - (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE) + 1])); + (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE) + 1])); if (d->greetpid > 1) kill (d->greetpid, SIGHUP); } else if (strncmp (msg, GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE " ", strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE) + 1) == 0) { gdm_daemon_config_set_value_string (GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE, - (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE) + 1])); + (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE) + 1])); if (d->greetpid > 1) kill (d->greetpid, SIGHUP); } else if (strncmp (msg, GDM_NOTIFY_GTK_MODULES_LIST " ", strlen (GDM_NOTIFY_GTK_MODULES_LIST) + 1) == 0) { gdm_daemon_config_set_value_string (GDM_KEY_GTK_MODULES_LIST, - (gchar *)(&msg[strlen (GDM_NOTIFY_GTK_MODULES_LIST) + 1])); + (gchar *)(&msg[strlen (GDM_NOTIFY_GTK_MODULES_LIST) + 1])); if (gdm_daemon_config_get_value_bool (GDM_KEY_ADD_GTK_MODULES)) { do_restart_greeter = TRUE; @@ -5857,7 +5893,7 @@ gdm_can_i_assume_root_role (struct passwd *pwent) return FALSE; freeroles = roles = g_strdup (kva_match (uattr->attr, USERATTR_ROLES_KW)); - if (roles == NULL) { + if (roles == NULL) { return FALSE; } @@ -5880,6 +5916,5 @@ gdm_can_i_assume_root_role (struct passwd *pwent) gboolean gdm_is_user_valid (const char *username) { - return (NULL != getpwnam (username)); + return (NULL != getpwnam (username)); } -/* EOF */ diff --git a/daemon/slave.h b/daemon/slave.h index 4aa33fc6..1f1599e0 100644 --- a/daemon/slave.h +++ b/daemon/slave.h @@ -20,8 +20,9 @@ #define GDM_SLAVE_H #include <glib.h> -#include <X11/Xlib.h> + #include "gdm.h" +#include "display.h" void gdm_slave_start (GdmDisplay *d); void gdm_slave_greeter_ctl_no_ret (char cmd, const char *str); diff --git a/daemon/verify-crypt.c b/daemon/verify-crypt.c index ae28efef..31df6c56 100644 --- a/daemon/verify-crypt.c +++ b/daemon/verify-crypt.c @@ -19,7 +19,6 @@ #include "config.h" #include <glib/gi18n.h> -#include <syslog.h> #include <pwd.h> #include <grp.h> #include <sys/types.h> @@ -280,7 +279,7 @@ authenticate_again: switch (passwdexpired (login, &info_msg)) { case 1 : gdm_error (_("Password of %s has expired"), login); - gdm_error_box (d, GTK_MESSAGE_ERROR, + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("You are required to change your password.\n" "Please choose a new one.")); g_free (info_msg); @@ -334,7 +333,7 @@ authenticate_again: } if (ret) { - gdm_error_box (d, GTK_MESSAGE_WARNING, + gdm_errorgui_error_box (d, GTK_MESSAGE_WARNING, _("Your password has been changed but " "you may have to change it again. " "Please try again later or contact " @@ -342,7 +341,7 @@ authenticate_again: } #else /* !CAN_CLEAR_ADMCHG */ - gdm_error_box (d, GTK_MESSAGE_WARNING, + gdm_errorgui_error_box (d, GTK_MESSAGE_WARNING, _("Your password has been changed but you " "may have to change it again. Please try again " "later or contact your system administrator.")); @@ -353,7 +352,7 @@ authenticate_again: case 2 : gdm_error (_("Password of %s has expired"), login); - gdm_error_box (d, GTK_MESSAGE_ERROR, + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("Your password has expired.\n" "Only a system administrator can now change it")); g_free (info_msg); @@ -362,7 +361,7 @@ authenticate_again: case -1 : gdm_error (_("Internal error on passwdexpired")); - gdm_error_box (d, GTK_MESSAGE_ERROR, + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("An internal error occurred. You will not be able to log in.\n" "Please try again later or contact your system administrator.")); g_free (info_msg); @@ -405,7 +404,7 @@ gdm_verify_setup_user (GdmDisplay *d, if ( ! gdm_setup_gids (login, pwent->pw_gid)) { gdm_error (_("Cannot set user group for %s"), login); - gdm_error_box (d, + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("\nCannot set your user group; " "you will not be able to log in. " diff --git a/daemon/verify-pam.c b/daemon/verify-pam.c index 103baadd..c95b3842 100644 --- a/daemon/verify-pam.c +++ b/daemon/verify-pam.c @@ -18,11 +18,12 @@ #include "config.h" +#include <unistd.h> +#include <stdlib.h> +#include <string.h> #include <grp.h> #include <sys/stat.h> #include <sys/types.h> -#include <unistd.h> -#include <stdlib.h> #include <syslog.h> #include <security/pam_appl.h> #include <pwd.h> @@ -39,8 +40,11 @@ #include "errorgui.h" #include "gdm-common.h" +#include "gdm-log.h" #include "gdm-daemon-config.h" +#include "gdm-socket-protocol.h" + #ifdef HAVE_LOGINDEVPERM #include <libdevinfo.h> #endif /* HAVE_LOGINDEVPERM */ @@ -515,9 +519,9 @@ gdm_verify_pam_conv (int num_msg, struct pam_message **msg, } /* Workaround to avoid gdm messages being logged as PAM_pwdb */ - closelog (); - openlog ("gdm", LOG_PID, LOG_DAEMON); - + gdm_log_shutdown (); + gdm_log_init (); + for (replies = 0; replies < num_msg; replies++) { const char *m = (*msg)[replies].msg; m = perhaps_translate_message (m); @@ -691,7 +695,7 @@ gdm_verify_standalone_pam_conv (int num_msg, struct pam_message **msg, case PAM_ERROR_MSG: /* PAM sent a message that should displayed to the user */ - gdm_error_box (cur_gdm_disp, + gdm_errorgui_error_box (cur_gdm_disp, GTK_MESSAGE_ERROR, m); reply[replies].resp_retcode = PAM_SUCCESS; @@ -700,7 +704,7 @@ gdm_verify_standalone_pam_conv (int num_msg, struct pam_message **msg, case PAM_TEXT_INFO: /* PAM sent a message that should displayed to the user */ - gdm_error_box (cur_gdm_disp, + gdm_errorgui_error_box (cur_gdm_disp, GTK_MESSAGE_INFO, m); reply[replies].resp_retcode = PAM_SUCCESS; @@ -1141,8 +1145,8 @@ authenticate_again: } /* Workaround to avoid gdm messages being logged as PAM_pwdb */ - closelog (); - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_shutdown (); + gdm_log_init (); cur_gdm_disp = NULL; @@ -1225,8 +1229,8 @@ authenticate_again: pamh = NULL; /* Workaround to avoid gdm messages being logged as PAM_pwdb */ - closelog (); - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_shutdown (); + gdm_log_init (); g_free (login); @@ -1307,7 +1311,7 @@ gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display, if ((pamerr = pam_authenticate (pamh, null_tok)) != PAM_SUCCESS) { if (gdm_slave_action_pending ()) { gdm_error (_("Couldn't authenticate user")); - gdm_error_box (cur_gdm_disp, + gdm_errorgui_error_box (cur_gdm_disp, GTK_MESSAGE_ERROR, _("Authentication failed")); } @@ -1319,7 +1323,7 @@ gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display, pretty much look as such, it shouldn't really happen */ gdm_error (_("Couldn't authenticate user")); - gdm_error_box (cur_gdm_disp, + gdm_errorgui_error_box (cur_gdm_disp, GTK_MESSAGE_ERROR, _("Authentication failed")); goto setup_pamerr; @@ -1349,7 +1353,7 @@ gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display, #if 0 /* don't change password */ if ((pamerr = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK)) != PAM_SUCCESS) { gdm_error (_("Authentication token change failed for user %s"), login); - gdm_error_box (cur_gdm_disp, + gdm_errorgui_error_box (cur_gdm_disp, GTK_MESSAGE_ERROR, _("\nThe change of the authentication token failed. " "Please try again later or contact the system administrator.")); @@ -1365,13 +1369,13 @@ gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display, break; case PAM_ACCT_EXPIRED : gdm_error (_("User %s no longer permitted to access the system"), login); - gdm_error_box (cur_gdm_disp, + gdm_errorgui_error_box (cur_gdm_disp, GTK_MESSAGE_ERROR, _("The system administrator has disabled your account.")); goto setup_pamerr; case PAM_PERM_DENIED : gdm_error (_("User %s not permitted to gain access at this time"), login); - gdm_error_box (cur_gdm_disp, + gdm_errorgui_error_box (cur_gdm_disp, GTK_MESSAGE_ERROR, _("The system administrator has disabled your access to the system temporarily.")); goto setup_pamerr; @@ -1385,7 +1389,7 @@ gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display, if (/* paranoia */ pwent == NULL || ! gdm_setup_gids (login, pwent->pw_gid)) { gdm_error (_("Cannot set user group for %s"), login); - gdm_error_box (cur_gdm_disp, + gdm_errorgui_error_box (cur_gdm_disp, GTK_MESSAGE_ERROR, _("Cannot set your user group; " "you will not be able to log in. " @@ -1433,8 +1437,8 @@ gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display, /* Workaround to avoid gdm messages being logged as PAM_pwdb */ - closelog (); - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_shutdown (); + gdm_log_init (); cur_gdm_disp = NULL; @@ -1478,8 +1482,8 @@ gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display, pamh = NULL; /* Workaround to avoid gdm messages being logged as PAM_pwdb */ - closelog (); - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_shutdown (); + gdm_log_init (); cur_gdm_disp = NULL; @@ -1557,8 +1561,8 @@ gdm_verify_cleanup (GdmDisplay *d) #endif /* HAVE_LOGINDEVPERM */ /* Workaround to avoid gdm messages being logged as PAM_pwdb */ - closelog (); - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_shutdown (); + gdm_log_init (); } /* Clear the group setup */ @@ -1591,8 +1595,8 @@ gdm_verify_check (void) &standalone_pamc, &ph) != PAM_SUCCESS) { ph = NULL; /* be anal */ - closelog (); - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_shutdown (); + gdm_log_init (); if (gdm_daemon_config_get_value_bool (GDM_KEY_CONSOLE_NOTIFY)) gdm_text_message_dialog @@ -1604,8 +1608,8 @@ gdm_verify_check (void) if (ph != NULL) pam_end (ph, PAM_SUCCESS); - closelog (); - openlog ("gdm", LOG_PID, LOG_DAEMON); + gdm_log_shutdown (); + gdm_log_init (); } /* used in pam */ diff --git a/daemon/verify-shadow.c b/daemon/verify-shadow.c index 94106222..ab1c0ec9 100644 --- a/daemon/verify-shadow.c +++ b/daemon/verify-shadow.c @@ -19,7 +19,6 @@ #include "config.h" #include <glib/gi18n.h> -#include <syslog.h> #include <pwd.h> #include <shadow.h> #include <grp.h> @@ -298,7 +297,7 @@ authenticate_again: switch (passwdexpired (login, &info_msg)) { case 1 : gdm_error (_("Password of %s has expired"), login); - gdm_error_box (d, GTK_MESSAGE_ERROR, + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("You are required to change your password.\n" "Please choose a new one.")); g_free (info_msg); @@ -353,7 +352,7 @@ authenticate_again: } if (ret) { - gdm_error_box (d, GTK_MESSAGE_WARNING, + gdm_errorgui_error_box (d, GTK_MESSAGE_WARNING, _("Your password has been changed but " "you may have to change it again. " "Please try again later or contact " @@ -361,7 +360,7 @@ authenticate_again: } #else /* !CAN_CLEAR_ADMCHG */ - gdm_error_box (d, GTK_MESSAGE_WARNING, + gdm_errorgui_error_box (d, GTK_MESSAGE_WARNING, _("Your password has been changed but you " "may have to change it again. Please try again " "later or contact your system administrator.")); @@ -372,7 +371,7 @@ authenticate_again: case 2 : gdm_error (_("Password of %s has expired"), login); - gdm_error_box (d, GTK_MESSAGE_ERROR, + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("Your password has expired.\n" "Only a system administrator can now change it")); g_free (info_msg); @@ -381,7 +380,7 @@ authenticate_again: case -1 : gdm_error (_("Internal error on passwdexpired")); - gdm_error_box (d, GTK_MESSAGE_ERROR, + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("An internal error occurred. You will not be able to log in.\n" "Please try again later or contact your system administrator.")); g_free (info_msg); @@ -423,7 +422,7 @@ gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display, if ( ! gdm_setup_gids (login, pwent->pw_gid)) { gdm_error (_("Cannot set user group for %s"), login); - gdm_error_box (d, + gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, _("\nCannot set your user group; " "you will not be able to log in. " diff --git a/daemon/verify.h b/daemon/verify.h index e7e983f9..d244e7b6 100644 --- a/daemon/verify.h +++ b/daemon/verify.h @@ -20,6 +20,7 @@ #define GDM_VERIFY_H #include "gdm.h" +#include "display.h" /* If username is NULL, we ask, if local is FALSE, don't start * the timed login timer */ diff --git a/daemon/xdmcp.c b/daemon/xdmcp.c index 0b444914..57c46267 100644 --- a/daemon/xdmcp.c +++ b/daemon/xdmcp.c @@ -1,4 +1,6 @@ -/* GDM - The GNOME Display Manager +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * 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 @@ -17,7 +19,7 @@ */ /* This file contains the XDMCP implementation for managing remote - * displays. + * displays. */ /* Theory of operation: @@ -26,12 +28,12 @@ * Incoming packets are decoded and checked against tcp_wrapper. * * A typical session looks like this: - * + * * Display sends Query/BroadcastQuery to Manager. * * Manager selects an appropriate authentication scheme from the * display's list of supported ones and sends Willing/Unwilling. - * + * * Assuming the display accepts the auth. scheme it sends back a * Request. * @@ -51,7 +53,7 @@ * * Similarly the manager xpings the display once in a while and shuts * down the connection on failure. - * + * */ #include "config.h" @@ -61,7 +63,6 @@ #include <unistd.h> #include <time.h> #include <stdlib.h> -#include <syslog.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/wait.h> @@ -103,18 +104,18 @@ #include "cookie.h" #include "gdm-common.h" +#include "gdm-log.h" #include "gdm-daemon-config.h" -/*This is to be changed when the Xdmcp Multicast address is decided */ +/* This is to be changed when the Xdmcp Multicast address is decided */ #define XDMCP_MULTICAST_ADDRESS "ff02::1" -int gdm_xdmcpfd = -1; +static int gdm_xdmcpfd = -1; -#ifdef HAVE_LIBXDMCP +static gint xdmcp_sessions = 0; /* Number of remote sessions */ +static gint xdmcp_pending = 0; /* Number of pending remote sessions */ -/* TCP Wrapper syslog control */ -gint allow_severity = LOG_INFO; -gint deny_severity = LOG_WARNING; +#ifdef HAVE_LIBXDMCP static guint xdmcp_source = 0; static CARD32 globsessid; @@ -123,26 +124,19 @@ static ARRAY8 servhost; static XdmcpBuffer buf; static gboolean initted = FALSE; -extern GSList *displays; -extern gint xdmcp_pending; -extern gint xdmcp_sessions; - /* Local prototypes */ static gboolean gdm_xdmcp_decode_packet (GIOChannel *source, GIOCondition cond, gpointer data); -/************************ IPv6 specific prototypes **************************/ - -#ifdef ENABLE_IPV6 - +static void gdm_xdmcp_handle_forward_query (struct sockaddr_storage *clnt_sa, + gint len); static void gdm_xdmcp_handle_query (struct sockaddr_storage *clnt_sa, gint len, gint type); -static void gdm_xdmcp_handle_forward_query (struct sockaddr_storage *clnt_sa, - gint len); static void gdm_xdmcp_handle_request (struct sockaddr_storage *clnt_sa, gint len); + static void gdm_xdmcp_handle_manage (struct sockaddr_storage *clnt_sa, gint len); static void gdm_xdmcp_handle_managed_forward (struct sockaddr_storage *clnt_sa, @@ -167,81 +161,30 @@ static void gdm_xdmcp_send_alive (struct sockaddr_storage *clnt_sa, CARD16 dspnum, CARD32 sessid); static void gdm_xdmcp_send_managed_forward (struct sockaddr_storage *clnt_sa, struct sockaddr_storage *origin); -static void gdm_xdmcp_send_forward_query6 (GdmIndirectDisplay *id, - struct sockaddr_in6 *clnt_sa, - struct in6_addr *display_addr, - ARRAYofARRAY8Ptr authlist); static gboolean gdm_xdmcp_host_allow (struct sockaddr_storage *clnt_sa); static GdmForwardQuery * gdm_forward_query_alloc (struct sockaddr_storage *mgr_sa, struct sockaddr_storage *dsp_sa); static GdmForwardQuery * gdm_forward_query_lookup (struct sockaddr_storage *clnt_sa); -static void gdm_xdmcp_whack_queued_managed_forwards6 (struct sockaddr_in6 *clnt_sa, - struct in6_addr *origin); -static void gdm_xdmcp_send_got_managed_forward6 (struct sockaddr_in6 *clnt_sa, - struct in6_addr *origin); static int gdm_xdmcp_displays_from_host (struct sockaddr_storage *addr); static GdmDisplay *gdm_xdmcp_display_lookup_by_host (struct sockaddr_storage *addr, - int dspnum); + int dspnum); static GdmDisplay *gdm_xdmcp_display_alloc (struct sockaddr_storage *addr, - GdmHostent *he, int displaynum); + GdmHostent *he, + int displaynum); -#else -/************************ IPv4 specific prototypes **************************/ +static void gdm_xdmcp_whack_queued_managed_forwards (struct sockaddr_storage *clnt_sa, + struct sockaddr_storage *origin); + +static void gdm_xdmcp_send_got_managed_forward (struct sockaddr_storage *clnt_sa, + struct sockaddr_storage *origin); -static void gdm_xdmcp_handle_forward_query (struct sockaddr_in *clnt_sa, - gint len); -static void gdm_xdmcp_handle_query (struct sockaddr_in *clnt_sa, - gint len, - gint type); - static void gdm_xdmcp_handle_request (struct sockaddr_in *clnt_sa, - gint len); - static void gdm_xdmcp_handle_manage (struct sockaddr_in *clnt_sa, - gint len); - static void gdm_xdmcp_handle_managed_forward (struct sockaddr_in *clnt_sa, - gint len); - static void gdm_xdmcp_handle_got_managed_forward (struct sockaddr_in *clnt_sa, - gint len); - static void gdm_xdmcp_handle_keepalive (struct sockaddr_in *clnt_sa, - gint len); - static void gdm_xdmcp_send_willing (struct sockaddr_in *clnt_sa); - static void gdm_xdmcp_send_unwilling (struct sockaddr_in *clnt_sa, - gint type); - static void gdm_xdmcp_send_accept (GdmHostent *he /* eaten and freed */, - struct sockaddr_in *clnt_sa, - int displaynum); -static void gdm_xdmcp_send_decline (struct sockaddr_in *clnt_sa, - const char *reason); - static void gdm_xdmcp_send_refuse (struct sockaddr_in *clnt_sa, - CARD32 sessid); - static void gdm_xdmcp_send_failed (struct sockaddr_in *clnt_sa, - CARD32 sessid); - static void gdm_xdmcp_send_alive (struct sockaddr_in *clnt_sa, - CARD16 dspnum, CARD32 sessid); - static void gdm_xdmcp_send_managed_forward (struct sockaddr_in *clnt_sa, - struct sockaddr_in *origin); - static gboolean gdm_xdmcp_host_allow (struct sockaddr_in *clnt_sa); -static GdmForwardQuery * gdm_forward_query_alloc (struct sockaddr_in *mgr_sa, - struct sockaddr_in *dsp_sa); -static GdmForwardQuery * gdm_forward_query_lookup (struct sockaddr_in *clnt_sa); -static int gdm_xdmcp_displays_from_host (struct sockaddr_in *addr); -static GdmDisplay *gdm_xdmcp_display_lookup_by_host (struct sockaddr_in *addr, - int dspnum); -static GdmDisplay *gdm_xdmcp_display_alloc (struct sockaddr_in *addr, - GdmHostent *he, int displaynum); -#endif /*IPv4 / IPv6*/ - -static void gdm_xdmcp_whack_queued_managed_forwards (struct sockaddr_in *clnt_sa, - struct in_addr *origin); -static void gdm_xdmcp_send_got_managed_forward (struct sockaddr_in *clnt_sa, - struct in_addr *origin); static void gdm_xdmcp_send_forward_query (GdmIndirectDisplay *id, - struct sockaddr_in *clnt_sa, - struct in_addr *display_addr, + struct sockaddr_storage *clnt_sa, + struct sockaddr_storage *display_addr, ARRAYofARRAY8Ptr authlist); -static void gdm_xdmcp_whack_queued_managed_forwards (struct sockaddr_in *clnt_sa, - struct in_addr *origin); -static void gdm_xdmcp_send_got_managed_forward (struct sockaddr_in *clnt_sa, - struct in_addr *origin); +static void gdm_xdmcp_whack_queued_managed_forwards (struct sockaddr_storage *clnt_sa, + struct sockaddr_storage *origin); + static GdmDisplay *gdm_xdmcp_display_lookup (CARD32 sessid); static void gdm_xdmcp_display_dispose_check (const gchar *hostname, int dspnum); static void gdm_xdmcp_displays_check (void); @@ -252,270 +195,400 @@ static GSList *forward_queries = NULL; typedef struct { int times; guint handler; -#ifdef ENABLE_IPV6 struct sockaddr_storage manager; struct sockaddr_storage origin; -#else - struct sockaddr_in manager; - struct sockaddr_in origin; -#endif } ManagedForward; #define MANAGED_FORWARD_INTERVAL 1500 /* 1.5 seconds */ static GSList *managed_forwards = NULL; - -/* +/* * We don't support XDM-AUTHENTICATION-1 and XDM-AUTHORIZATION-1. * * The latter would be quite useful to avoid sending unencrypted * cookies over the wire. Unfortunately it isn't supported without * XDM-AUTHENTICATION-1 which requires a key database with private * keys from all X terminals on your LAN. Fun, fun, fun. - * + * * Furthermore user passwords go over the wire in cleartext anyway, - * so protecting cookies is not that important. + * so protecting cookies is not that important. */ typedef struct _XdmAuth { - ARRAY8 authentication; - ARRAY8 authorization; + ARRAY8 authentication; + ARRAY8 authorization; } XdmAuthRec, *XdmAuthPtr; -static XdmAuthRec serv_authlist = { - { (CARD16) 0, (CARD8 *) 0 }, - { (CARD16) 0, (CARD8 *) 0 } +static XdmAuthRec serv_authlist = { + { (CARD16) 0, (CARD8 *) 0 }, + { (CARD16) 0, (CARD8 *) 0 } }; -#ifdef ENABLE_IPV6 -static gboolean have_ipv6 (void) -{ - int s; - - s = socket (AF_INET6, SOCK_STREAM, 0); - if (s != -1) { - VE_IGNORE_EINTR (close (s)); - return TRUE; - } - - return FALSE; -} -#endif - static int -#ifdef ENABLE_IPV6 gdm_xdmcp_displays_from_host (struct sockaddr_storage *addr) -#else -gdm_xdmcp_displays_from_host (struct sockaddr_in *addr) -#endif { GSList *li; int count = 0; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); for (li = displays; li != NULL; li = li->next) { GdmDisplay *disp = li->data; if (SERVER_IS_XDMCP (disp)) { -#ifdef ENABLE_IPV6 - if (disp->addrtype == AF_INET6 && - memcmp (&disp->addr6, - &((struct sockaddr_in6 *)addr)->sin6_addr, - sizeof (struct in6_addr)) == 0) - count++; - else -#endif - if (disp->addrtype == AF_INET && - memcmp (&disp->addr, - &((struct sockaddr_in *)addr)->sin_addr, - sizeof (struct in_addr)) == 0) - count++; + + if (gdm_address_equal (&disp->addr, addr)) { + count++; + } } } return count; } static GdmDisplay * -#ifdef ENABLE_IPV6 gdm_xdmcp_display_lookup_by_host (struct sockaddr_storage *addr, int dspnum) -#else -gdm_xdmcp_display_lookup_by_host (struct sockaddr_in *addr, int dspnum) -#endif { GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); for (li = displays; li != NULL; li = li->next) { GdmDisplay *disp = li->data; + if (SERVER_IS_XDMCP (disp)) { -#ifdef ENABLE_IPV6 - if (disp->addrtype == AF_INET6) { - if ((memcmp (&disp->addr6, - &((struct sockaddr_in6 *)addr)->sin6_addr, - sizeof (struct in6_addr)) == 0) && - disp->xdmcp_dispnum == dspnum) - return disp; - } - else -#endif - if ((memcmp (&disp->addr, - &((struct sockaddr_in *)addr)->sin_addr, - sizeof (struct in_addr)) == 0) && - disp->xdmcp_dispnum == dspnum) - return disp; + + if (gdm_address_equal (&disp->addr, addr) + && disp->xdmcp_dispnum == dspnum) { + return disp; + } } } return NULL; } +/* for debugging */ +static const char * +ai_family_str (struct addrinfo *ai) +{ + const char *str; + switch (ai->ai_family) { + case AF_INET: + str = "inet"; + break; + case AF_INET6: + str = "inet6"; + break; + case AF_UNIX: + str = "unix"; + break; + case AF_UNSPEC: + str = "unspecified"; + break; + default: + str = "unknown"; + break; + } + return str; +} + +/* for debugging */ +static const char * +ai_type_str (struct addrinfo *ai) +{ + const char *str; + switch (ai->ai_socktype) { + case SOCK_STREAM: + str = "stream"; + break; + case SOCK_DGRAM: + str = "datagram"; + break; + case SOCK_SEQPACKET: + str = "seqpacket"; + break; + case SOCK_RAW: + str = "raw"; + break; + default: + str = "unknown"; + break; + } + return str; +} + +/* for debugging */ +static const char * +ai_protocol_str (struct addrinfo *ai) +{ + const char *str; + switch (ai->ai_protocol) { + case 0: + str = "default"; + break; + case IPPROTO_TCP: + str = "TCP"; + break; + case IPPROTO_UDP: + str = "UDP"; + break; + case IPPROTO_RAW: + str = "raw"; + break; + default: + str = "unknown"; + break; + } + + return str; +} + +/* for debugging */ +static char * +ai_flags_str (struct addrinfo *ai) +{ + GString *str; + + str = g_string_new (""); + if (ai->ai_flags == 0) { + g_string_append (str, "none"); + } else { + if (ai->ai_flags & AI_PASSIVE) { + g_string_append (str, "passive "); + } + if (ai->ai_flags & AI_CANONNAME) { + g_string_append (str, "canon "); + } + if (ai->ai_flags & AI_NUMERICHOST) { + g_string_append (str, "numhost "); + } + if (ai->ai_flags & AI_NUMERICSERV) { + g_string_append (str, "numserv "); + } + if (ai->ai_flags & AI_V4MAPPED) { + g_string_append (str, "v4mapped "); + } + if (ai->ai_flags & AI_ALL) { + g_string_append (str, "all "); + } + } + return g_string_free (str, FALSE); +} + +/* for debugging */ +static void +debug_addrinfo (struct addrinfo *ai) +{ + char *str; + str = ai_flags_str (ai); + g_debug ("XDMCP: addrinfo family=%s type=%s proto=%s flags=%s", + ai_family_str (ai), + ai_type_str (ai), + ai_protocol_str (ai), + str); + g_free (str); +} + +static int +gdm_xdmcp_create_socket (struct addrinfo *ai) +{ + int sock; + + sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (sock < 0) { + g_warning ("socket: %s", g_strerror (errno)); + return sock; + } + + if (bind (sock, ai->ai_addr, ai->ai_addrlen) < 0) { + g_warning ("bind: %s", g_strerror (errno)); + close (sock); + return -1; + } + + return sock; +} + +static int +gdm_xdmcp_bind (guint port, + int family, + struct sockaddr_storage * hostaddr) +{ + struct addrinfo hints; + struct addrinfo *ai_list; + struct addrinfo *ai; + char strport[NI_MAXSERV]; + int gaierr; + int sock; + + sock = -1; + + memset (&hints, 0, sizeof (hints)); + hints.ai_family = family; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE; + + snprintf (strport, sizeof (strport), "%u", port); + if ((gaierr = getaddrinfo (NULL, strport, &hints, &ai_list)) != 0) { + g_error ("Unable to connect to socket: %s", gai_strerror (gaierr)); + return -1; + } + + /* should only be one but.. */ + for (ai = ai_list; ai != NULL; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) { + continue; + } + + debug_addrinfo (ai); + + if (sock < 0) { + char *host; + char *serv; + + gdm_address_get_info ((struct sockaddr_storage *)ai->ai_addr, &host, &serv); + g_debug ("XDMCP: Attempting to bind to host %s port %s", host, serv); + g_free (host); + g_free (serv); + sock = gdm_xdmcp_create_socket (ai); + if (sock >= 0) { + if (hostaddr != NULL) { + memcpy (hostaddr, ai->ai_addr, ai->ai_addrlen); + } + } + } + } + + freeaddrinfo (ai_list); + + return sock; +} gboolean gdm_xdmcp_init (void) { + struct sockaddr_storage serv_sa = { 0 }; + gchar hostbuf[1024]; + struct utsname name; + int udpport; + + if ( ! gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP)) + return TRUE; + + udpport = gdm_daemon_config_get_value_int (GDM_KEY_UDP_PORT); + globsessid = g_random_int (); + + /* Fetch and store local hostname in XDMCP friendly format */ + hostbuf[1023] = '\0'; + if G_UNLIKELY (gethostname (hostbuf, 1023) != 0) { + gdm_error (_("%s: Could not get server hostname: %s!"), + "gdm_xdmcp_init", strerror (errno)); + strcpy (hostbuf, "localhost.localdomain"); + } + + if ( ! initted) { + uname (&name); + sysid = g_strconcat (name.sysname, " ", + name.release, NULL); + servhost.data = (CARD8 *) g_strdup (hostbuf); + servhost.length = strlen ((char *) servhost.data); + + initted = TRUE; + } + + gdm_debug ("XDMCP: Start up on host %s, port %d", hostbuf, udpport); + + /* Open socket for communications */ #ifdef ENABLE_IPV6 - struct sockaddr_storage serv_sa = {0}; -#else - struct sockaddr_in serv_sa = {0}; -#endif - gint addrlen; - gchar hostbuf[1024]; - struct utsname name; - int udpport = gdm_daemon_config_get_value_int (GDM_KEY_UDP_PORT); - - if ( ! gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP)) - return TRUE; - - globsessid = g_random_int (); - - /* Fetch and store local hostname in XDMCP friendly format */ - hostbuf[1023] = '\0'; - if G_UNLIKELY (gethostname (hostbuf, 1023) != 0) { - gdm_error (_("%s: Could not get server hostname: %s!"), - "gdm_xdmcp_init", strerror (errno)); - strcpy (hostbuf, "localhost.localdomain"); - } - - if ( ! initted) { - uname (&name); - sysid = g_strconcat (name.sysname, " ", - name.release, NULL); - servhost.data = (CARD8 *) g_strdup (hostbuf); - servhost.length = strlen ((char *) servhost.data); - - initted = TRUE; - } - - gdm_debug ("XDMCP: Start up on host %s, port %d", hostbuf, udpport); - - /* Open socket for communications */ -#ifdef ENABLE_IPV6 - gdm_xdmcpfd = socket (AF_INET6, SOCK_DGRAM, 0); /* UDP */ - if (gdm_xdmcpfd < 0) + gdm_xdmcpfd = gdm_xdmcp_bind (udpport, AF_INET6, &serv_sa); + if (gdm_xdmcpfd < 0) #endif - gdm_xdmcpfd = socket (AF_INET, SOCK_DGRAM, 0); /* UDP */ - - if G_UNLIKELY (gdm_xdmcpfd < 0) { - gdm_error (_("%s: Could not create socket!"), "gdm_xdmcp_init"); - gdm_daemon_config_set_value_bool (GDM_KEY_XDMCP, FALSE); - return FALSE; - } + gdm_xdmcpfd = gdm_xdmcp_bind (udpport, AF_INET, &serv_sa); -#ifdef ENABLE_IPV6 - if (have_ipv6 ()) { - ((struct sockaddr_in6 *)(&serv_sa))->sin6_family = AF_INET6; - ((struct sockaddr_in6 *)(&serv_sa))->sin6_port = htons (udpport); /* UDP 177 */ - ((struct sockaddr_in6 *)(&serv_sa))->sin6_addr = in6addr_any; - addrlen = sizeof (struct sockaddr_in6); + if G_UNLIKELY (gdm_xdmcpfd < 0) { + gdm_error (_("%s: Could not create socket!"), "gdm_xdmcp_init"); + gdm_daemon_config_set_value_bool (GDM_KEY_XDMCP, FALSE); + return FALSE; + } +#ifdef ENABLE_IPV6 /* Checking and Setting Multicast options */ if (gdm_daemon_config_get_value_bool (GDM_KEY_MULTICAST)) { - /* - * socktemp is a temporary socket for getting info about - * available interfaces - */ - int socktemp; - int i, num; - char *buf; - struct ipv6_mreq mreq; - - /* For interfaces' list */ - struct ifconf ifc; - struct ifreq *ifr; - - /* Extract Multicast address for IPv6 */ - if (ve_string_empty (gdm_daemon_config_get_value_string (GDM_KEY_MULTICAST_ADDR))) { - - /* Stuff it with all-node multicast address */ - gdm_daemon_config_set_value_string (GDM_KEY_MULTICAST_ADDR, - XDMCP_MULTICAST_ADDRESS); - } - - socktemp = socket (AF_INET, SOCK_DGRAM, 0); + /* + * socktemp is a temporary socket for getting info about + * available interfaces + */ + int socktemp; + int i, num; + char *buf; + struct ipv6_mreq mreq; + + /* For interfaces' list */ + struct ifconf ifc; + struct ifreq *ifr; + + /* Extract Multicast address for IPv6 */ + if (ve_string_empty (gdm_daemon_config_get_value_string (GDM_KEY_MULTICAST_ADDR))) { + + /* Stuff it with all-node multicast address */ + gdm_daemon_config_set_value_string (GDM_KEY_MULTICAST_ADDR, + XDMCP_MULTICAST_ADDRESS); + } + + socktemp = socket (AF_INET, SOCK_DGRAM, 0); #ifdef SIOCGIFNUM - if (ioctl (socktemp, SIOCGIFNUM, &num) < 0) { - num = 64; - } + if (ioctl (socktemp, SIOCGIFNUM, &num) < 0) { + num = 64; + } #else - num = 64; + num = 64; #endif - ifc.ifc_len = sizeof (struct ifreq) * num; - ifc.ifc_buf = buf = malloc (ifc.ifc_len); - - if (ioctl (socktemp, SIOCGIFCONF, &ifc) >= 0) { - ifr = ifc.ifc_req; - num = ifc.ifc_len / sizeof (struct ifreq); /* No of interfaces */ - - /* Joining multicast group with all interfaces*/ - for (i = 0 ; i < num ; i++) { - struct ifreq ifreq; - int ifindex; - - memset (&ifreq, 0, sizeof (ifreq)); - strncpy (ifreq.ifr_name, ifr[i].ifr_name, sizeof (ifreq.ifr_name)); - /* paranoia */ - ifreq.ifr_name[sizeof (ifreq.ifr_name) - 1] = '\0'; - - if (ioctl (socktemp, SIOCGIFFLAGS, &ifreq) < 0) { - gdm_debug ("XDMCP: Could not get SIOCGIFFLAGS for %s", - ifr[i].ifr_name); - } - - ifindex = if_nametoindex (ifr[i].ifr_name); - - if ((!(ifreq.ifr_flags & IFF_UP) || - (ifreq.ifr_flags & IFF_LOOPBACK)) || - ((ifindex == 0 ) && (errno == ENXIO))) { - /* Not a valid interface or loopback interface*/ - continue; - } + ifc.ifc_len = sizeof (struct ifreq) * num; + ifc.ifc_buf = buf = malloc (ifc.ifc_len); + + if (ioctl (socktemp, SIOCGIFCONF, &ifc) >= 0) { + ifr = ifc.ifc_req; + num = ifc.ifc_len / sizeof (struct ifreq); /* No of interfaces */ + + /* Joining multicast group with all interfaces */ + for (i = 0 ; i < num ; i++) { + struct ifreq ifreq; + int ifindex; + + memset (&ifreq, 0, sizeof (ifreq)); + strncpy (ifreq.ifr_name, ifr[i].ifr_name, sizeof (ifreq.ifr_name)); + /* paranoia */ + ifreq.ifr_name[sizeof (ifreq.ifr_name) - 1] = '\0'; + + if (ioctl (socktemp, SIOCGIFFLAGS, &ifreq) < 0) { + gdm_debug ("XDMCP: Could not get SIOCGIFFLAGS for %s", + ifr[i].ifr_name); + } - mreq.ipv6mr_interface = ifindex; - inet_pton (AF_INET6, - gdm_daemon_config_get_value_string (GDM_KEY_MULTICAST_ADDR), - &mreq.ipv6mr_multiaddr); - setsockopt (gdm_xdmcpfd, IPPROTO_IPV6, IPV6_JOIN_GROUP, - &mreq, sizeof (mreq)); - } - } - g_free (buf); - close (socktemp); - } - } - else + ifindex = if_nametoindex (ifr[i].ifr_name); + + if ((!(ifreq.ifr_flags & IFF_UP) || + (ifreq.ifr_flags & IFF_LOOPBACK)) || + ((ifindex == 0 ) && (errno == ENXIO))) { + /* Not a valid interface or loopback interface*/ + continue; + } + + mreq.ipv6mr_interface = ifindex; + inet_pton (AF_INET6, + gdm_daemon_config_get_value_string (GDM_KEY_MULTICAST_ADDR), + &mreq.ipv6mr_multiaddr); + setsockopt (gdm_xdmcpfd, IPPROTO_IPV6, IPV6_JOIN_GROUP, + &mreq, sizeof (mreq)); + } + } + g_free (buf); + close (socktemp); + } #endif - { - ((struct sockaddr_in *)(&serv_sa))->sin_family = AF_INET; - ((struct sockaddr_in *)(&serv_sa))->sin_port = htons (udpport); /* UDP 177 */ - ((struct sockaddr_in *)(&serv_sa))->sin_addr.s_addr = htonl (INADDR_ANY); - addrlen = sizeof (struct sockaddr_in); - } - - if G_UNLIKELY (bind (gdm_xdmcpfd, (struct sockaddr*) &serv_sa, addrlen) == -1) { - gdm_error (_("%s: Could not bind to XDMCP socket!"), "gdm_xdmcp_init"); - gdm_xdmcp_close (); - gdm_daemon_config_set_value_bool (GDM_KEY_XDMCP, FALSE); - return FALSE; - } - return TRUE; + return TRUE; } void @@ -523,22 +596,37 @@ gdm_xdmcp_run (void) { GIOChannel *xdmcpchan; + if (gdm_xdmcpfd < 0) { + gdm_error ("XDMCP: socket is not open"); + return; + } + + if (xdmcp_source > 0) { + gdm_error ("XDMCP: already listening"); + return; + } + + g_debug ("XDMCP: Starting to listen on XDMCP port"); + xdmcpchan = g_io_channel_unix_new (gdm_xdmcpfd); g_io_channel_set_encoding (xdmcpchan, NULL, NULL); g_io_channel_set_buffered (xdmcpchan, FALSE); - xdmcp_source = g_io_add_watch_full - (xdmcpchan, G_PRIORITY_DEFAULT, - G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL, - gdm_xdmcp_decode_packet, NULL, NULL); + xdmcp_source = g_io_add_watch_full (xdmcpchan, + G_PRIORITY_DEFAULT, + G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL, + gdm_xdmcp_decode_packet, + NULL, + NULL); g_io_channel_unref (xdmcpchan); } - void gdm_xdmcp_close (void) { + g_debug ("XMCP: closing XDMCP listener"); + if (xdmcp_source > 0) { g_source_remove (xdmcp_source); xdmcp_source = 0; @@ -550,428 +638,312 @@ gdm_xdmcp_close (void) } } - static gboolean -gdm_xdmcp_decode_packet (GIOChannel *source, GIOCondition cond, gpointer data) +gdm_xdmcp_decode_packet (GIOChannel *source, + GIOCondition cond, + gpointer data) { -#ifdef ENABLE_IPV6 - struct sockaddr_storage clnt_sa; -#else - struct sockaddr_in clnt_sa; -#endif - gint sa_len = sizeof (clnt_sa); - XdmcpHeader header; - static const char * const opcode_names[] = { - NULL, - "BROADCAST_QUERY", "QUERY", "INDIRECT_QUERY", "FORWARD_QUERY", - "WILLING", "UNWILLING", "REQUEST", "ACCEPT", "DECLINE", "MANAGE", "REFUSE", - "FAILED", "KEEPALIVE", "ALIVE" - }; - static const char * const gdm_opcode_names[] = { - "MANAGED_FORWARD", "GOT_MANAGED_FORWARD" - }; - - /* packets come at somewhat random times */ - gdm_random_tick (); - - if (cond != G_IO_IN) - gdm_debug ("gdm_xdmcp_decode_packet: GIOCondition %d", (int)cond); - - if ( ! (cond & G_IO_IN)) - return TRUE; - - if G_UNLIKELY (!XdmcpFill (gdm_xdmcpfd, &buf, (XdmcpNetaddr)&clnt_sa, &sa_len)) { - gdm_debug (_("%s: Could not create XDMCP buffer!"), - "gdm_xdmcp_decode_packet"); - return TRUE; - } - - if G_UNLIKELY (!XdmcpReadHeader (&buf, &header)) { - gdm_error (_("%s: Could not read XDMCP header!"), - "gdm_xdmcp_decode_packet"); - return TRUE; - } - - if G_UNLIKELY (header.version != XDM_PROTOCOL_VERSION && - header.version != GDM_XDMCP_PROTOCOL_VERSION) { - gdm_error (_("%s: Incorrect XDMCP version!"), - "gdm_xdmcp_decode_packet"); - return TRUE; - } + struct sockaddr_storage clnt_sa; + gint sa_len = sizeof (clnt_sa); + XdmcpHeader header; + char *host; + char *port; - if (header.opcode <= ALIVE) { -#ifdef ENABLE_IPV6 - if (clnt_sa.ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; + static const char * const opcode_names[] = { + NULL, + "BROADCAST_QUERY", "QUERY", "INDIRECT_QUERY", "FORWARD_QUERY", + "WILLING", "UNWILLING", "REQUEST", "ACCEPT", "DECLINE", "MANAGE", "REFUSE", + "FAILED", "KEEPALIVE", "ALIVE" + }; + static const char * const gdm_opcode_names[] = { + "MANAGED_FORWARD", "GOT_MANAGED_FORWARD" + }; + + /* packets come at somewhat random times */ + gdm_random_tick (); + + gdm_debug ("gdm_xdmcp_decode_packet: GIOCondition %d", (int)cond); - gdm_debug ("gdm_xdmcp_decode: Received opcode %s from client %s", - opcode_names[header.opcode], - inet_ntop (AF_INET6, - &((struct sockaddr_in6 *)(&clnt_sa))->sin6_addr, - buffer6, INET6_ADDRSTRLEN)); + if ( ! (cond & G_IO_IN)) { + return TRUE; } - else -#endif - { - gdm_debug ("gdm_xdmcp_decode: Received opcode %s from client %s", - opcode_names[header.opcode], - inet_ntoa (((struct sockaddr_in *)(&clnt_sa))->sin_addr)); + + if G_UNLIKELY (!XdmcpFill (gdm_xdmcpfd, &buf, (XdmcpNetaddr)&clnt_sa, &sa_len)) { + gdm_debug (_("%s: Could not create XDMCP buffer!"), + "gdm_xdmcp_decode_packet"); + return TRUE; } - } - if (header.opcode >= GDM_XDMCP_FIRST_OPCODE && - header.opcode < GDM_XDMCP_LAST_OPCODE) { -#ifdef ENABLE_IPV6 - if (clnt_sa.ss_family == AF_INET6) { + if G_UNLIKELY (!XdmcpReadHeader (&buf, &header)) { + gdm_error (_("%s: Could not read XDMCP header!"), + "gdm_xdmcp_decode_packet"); + return TRUE; + } - char buffer6[INET6_ADDRSTRLEN]; + if G_UNLIKELY (header.version != XDM_PROTOCOL_VERSION && + header.version != GDM_XDMCP_PROTOCOL_VERSION) { + gdm_error (_("%s: Incorrect XDMCP version!"), + "gdm_xdmcp_decode_packet"); + return TRUE; + } - gdm_debug ("gdm_xdmcp_decode: Received opcode %s from client %s", - gdm_opcode_names[header.opcode - GDM_XDMCP_FIRST_OPCODE], - inet_ntop (AF_INET6, - &((struct sockaddr_in6 *)(&clnt_sa))->sin6_addr, - buffer6, INET6_ADDRSTRLEN)); + gdm_address_get_info (&clnt_sa, &host, &port); + + if (header.opcode <= ALIVE) { + g_debug ("gdm_xdmcp_decode: Received opcode %s from client %s : %s", + opcode_names[header.opcode], + host, + port); } - else -#endif - { - char buffer[INET_ADDRSTRLEN]; - - gdm_debug ("gdm_xdmcp_decode: Received opcode %s from client %s", - gdm_opcode_names[header.opcode - GDM_XDMCP_FIRST_OPCODE], - inet_ntop (AF_INET, - &((struct sockaddr_in *)(&clnt_sa))->sin_addr, - buffer, INET_ADDRSTRLEN)); - } - } - - switch (header.opcode) { - - case BROADCAST_QUERY: - gdm_xdmcp_handle_query (&clnt_sa, header.length, BROADCAST_QUERY); - break; - - case QUERY: - gdm_xdmcp_handle_query (&clnt_sa, header.length, QUERY); - break; - - case INDIRECT_QUERY: - gdm_xdmcp_handle_query (&clnt_sa, header.length, INDIRECT_QUERY); - break; - - case FORWARD_QUERY: - gdm_xdmcp_handle_forward_query (&clnt_sa, header.length); - break; - - case REQUEST: - gdm_xdmcp_handle_request (&clnt_sa, header.length); - break; - - case MANAGE: - gdm_xdmcp_handle_manage (&clnt_sa, header.length); - break; - - case KEEPALIVE: - gdm_xdmcp_handle_keepalive (&clnt_sa, header.length); - break; - - case GDM_XDMCP_MANAGED_FORWARD: - gdm_xdmcp_handle_managed_forward (&clnt_sa, header.length); - break; - - case GDM_XDMCP_GOT_MANAGED_FORWARD: - gdm_xdmcp_handle_got_managed_forward (&clnt_sa, header.length); - break; - - default: -#ifdef ENABLE_IPV6 - if (clnt_sa.ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; - gdm_error (_("%s: Unknown opcode from host %s"), - "gdm_xdmcp_decode_packet", - inet_ntop (AF_INET6, - &(((struct sockaddr_in6 *)(&clnt_sa))->sin6_addr), - buffer6, INET6_ADDRSTRLEN)); + if (header.opcode >= GDM_XDMCP_FIRST_OPCODE && + header.opcode < GDM_XDMCP_LAST_OPCODE) { + g_debug ("gdm_xdmcp_decode: Received opcode %s from client %s : %s", + gdm_opcode_names[header.opcode - GDM_XDMCP_FIRST_OPCODE], + host, + port); } - else -#endif - { - gdm_error (_("%s: Unknown opcode from host %s"), - "gdm_xdmcp_decode_packet", - inet_ntoa (((struct sockaddr_in *)(&clnt_sa))->sin_addr)); + + switch (header.opcode) { + + case BROADCAST_QUERY: + gdm_xdmcp_handle_query (&clnt_sa, header.length, BROADCAST_QUERY); + break; + + case QUERY: + gdm_xdmcp_handle_query (&clnt_sa, header.length, QUERY); + break; + + case INDIRECT_QUERY: + gdm_xdmcp_handle_query (&clnt_sa, header.length, INDIRECT_QUERY); + break; + + case FORWARD_QUERY: + gdm_xdmcp_handle_forward_query (&clnt_sa, header.length); + break; + + case REQUEST: + gdm_xdmcp_handle_request (&clnt_sa, header.length); + break; + + case MANAGE: + gdm_xdmcp_handle_manage (&clnt_sa, header.length); + break; + + case KEEPALIVE: + gdm_xdmcp_handle_keepalive (&clnt_sa, header.length); + break; + + case GDM_XDMCP_MANAGED_FORWARD: + gdm_xdmcp_handle_managed_forward (&clnt_sa, header.length); + break; + + case GDM_XDMCP_GOT_MANAGED_FORWARD: + gdm_xdmcp_handle_got_managed_forward (&clnt_sa, header.length); + break; + + default: + g_debug ("gdm_xdmcp_decode: Unknown opcode from client %s : %s", + host, + port); + + break; } - break; - } - return TRUE; + g_free (host); + g_free (port); + + return TRUE; } -static void -#ifdef ENABLE_IPV6 -gdm_xdmcp_handle_query (struct sockaddr_storage *clnt_sa, gint len, gint type) -#else -gdm_xdmcp_handle_query (struct sockaddr_in *clnt_sa, gint len, gint type) -#endif +static void +gdm_xdmcp_handle_query (struct sockaddr_storage *clnt_sa, + gint len, + gint type) { - ARRAYofARRAY8 clnt_authlist; - gint i = 0, explen = 1; + ARRAYofARRAY8 clnt_authlist; + gint i = 0, explen = 1; + char *host; + char *port; + + gdm_address_get_info (clnt_sa, &host, &port); + gdm_debug ("gdm_xdmcp_handle_query: Opcode %d from %s : %s", type, host, port); + g_free (host); + g_free (port); + + /* Extract array of authentication names from Xdmcp packet */ + if G_UNLIKELY (! XdmcpReadARRAYofARRAY8 (&buf, &clnt_authlist)) { + gdm_error (_("%s: Could not extract authlist from packet"), + "gdm_xdmcp_handle_query"); + return; + } -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; - - gdm_debug ("gdm_xdmcp_handle_query: Opcode %d from %s", type, - inet_ntop (AF_INET6, - &((struct sockaddr_in6 *)(clnt_sa))->sin6_addr, - buffer6, INET6_ADDRSTRLEN)); - } - else -#endif - { - gdm_debug ("gdm_xdmcp_handle_query: Opcode %d from %s", - type, inet_ntoa (((struct sockaddr_in *)(clnt_sa))->sin_addr)); - } - - /* Extract array of authentication names from Xdmcp packet */ - if G_UNLIKELY (! XdmcpReadARRAYofARRAY8 (&buf, &clnt_authlist)) { - gdm_error (_("%s: Could not extract authlist from packet"), - "gdm_xdmcp_handle_query"); - return; - } - - /* Crude checksumming */ - for (i = 0 ; i < clnt_authlist.length ; i++) { - if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG)) { - char *s = g_strndup ((char *) clnt_authlist.data[i].data, - clnt_authlist.length); - gdm_debug ("gdm_xdmcp_handle_query: authlist: %s", - ve_sure_string (s)); - g_free (s); - } - explen += 2+clnt_authlist.data[i].length; - } - - if G_UNLIKELY (len != explen) { - gdm_error (_("%s: Error in checksum"), - "gdm_xdmcp_handle_query"); - XdmcpDisposeARRAYofARRAY8 (&clnt_authlist); - return; - } + /* Crude checksumming */ + for (i = 0 ; i < clnt_authlist.length ; i++) { + if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG)) { + char *s = g_strndup ((char *) clnt_authlist.data[i].data, + clnt_authlist.length); + gdm_debug ("gdm_xdmcp_handle_query: authlist: %s", + ve_sure_string (s)); + g_free (s); + } + explen += 2+clnt_authlist.data[i].length; + } - /* Check with tcp_wrappers if client is allowed to access */ - if (gdm_xdmcp_host_allow (clnt_sa)) { + if G_UNLIKELY (len != explen) { + gdm_error (_("%s: Error in checksum"), + "gdm_xdmcp_handle_query"); + XdmcpDisposeARRAYofARRAY8 (&clnt_authlist); + return; + } - /* If this is an INDIRECT_QUERY, try to look up the display in - * the pending list. If found send a FORWARD_QUERY to the - * chosen manager. Otherwise alloc a new indirect display. */ + /* Check with tcp_wrappers if client is allowed to access */ + if (gdm_xdmcp_host_allow (clnt_sa)) { - if (gdm_daemon_config_get_value_bool (GDM_KEY_INDIRECT) && - type == INDIRECT_QUERY) { - GdmIndirectDisplay *id = gdm_choose_indirect_lookup (clnt_sa); + /* If this is an INDIRECT_QUERY, try to look up the display in + * the pending list. If found send a FORWARD_QUERY to the + * chosen manager. Otherwise alloc a new indirect display. */ - if (id != NULL && ( -#ifdef ENABLE_IPV6 - (id->chosen_host6 != NULL) || -#endif - (id->chosen_host != NULL))) - { - /* if user chose us, then just send willing */ - if ((((struct sockaddr_in *)clnt_sa)->sin_family == AF_INET && - gdm_is_local_addr ((struct in_addr *)(id->chosen_host))) -#ifdef ENABLE_IPV6 - || (clnt_sa->ss_family == AF_INET6 && - gdm_is_local_addr6 ((struct in6_addr *)(id->chosen_host6))) -#endif - ) { + if (gdm_daemon_config_get_value_bool (GDM_KEY_INDIRECT) && type == INDIRECT_QUERY) { - /* get rid of indirect, so that we don't get - * the chooser */ - gdm_choose_indirect_dispose (id); - gdm_xdmcp_send_willing (clnt_sa); - } - else - if ((((struct sockaddr_in *)clnt_sa)->sin_family == AF_INET && - gdm_is_loopback_addr (&(((struct sockaddr_in *)clnt_sa)->sin_addr))) -#ifdef ENABLE_IPV6 - || (clnt_sa->ss_family == AF_INET6 && - gdm_is_loopback_addr6 (&(((struct sockaddr_in6 *)clnt_sa)->sin6_addr))) -#endif - ) { + GdmIndirectDisplay *id = gdm_choose_indirect_lookup (clnt_sa); - /* woohoo! fun, I have no clue how to get - * the correct ip, SO I just send forward - * queries with all the different IPs */ - const GList *list = gdm_peek_local_address_list (); + if (id != NULL && id->chosen_host != NULL) { + /* if user chose us, then just send willing */ + if (gdm_address_is_local (id->chosen_host)) { + /* get rid of indirect, so that we don't get + * the chooser */ + gdm_choose_indirect_dispose (id); + gdm_xdmcp_send_willing (clnt_sa); + } else if (gdm_address_is_loopback (clnt_sa)) { + /* woohoo! fun, I have no clue how to get + * the correct ip, SO I just send forward + * queries with all the different IPs */ + const GList *list = gdm_address_peek_local_list (); - while (list != NULL) { - struct sockaddr *saddr = (struct sockaddr *)(list->data); -#ifdef ENABLE_IPV6 - struct in6_addr *addr6; -#endif - struct in_addr *addr; + while (list != NULL) { + struct sockaddr_storage *saddr = list->data; -#ifdef ENABLE_IPV6 - if (saddr->sa_family == AF_INET6) { - addr6 = &(((struct sockaddr_in6 *)saddr)->sin6_addr); - if ( ! gdm_is_loopback_addr6 (addr6)) { - /* forward query to * chosen host */ - gdm_xdmcp_send_forward_query6 (id, - (struct sockaddr_in6 *)clnt_sa, - addr6, &clnt_authlist); - } - } - else -#endif - { - addr = &(((struct sockaddr_in *)saddr)->sin_addr); - if ( ! gdm_is_loopback_addr (addr)) { + if (! gdm_address_is_loopback (saddr)) { /* forward query to * chosen host */ gdm_xdmcp_send_forward_query (id, - (struct sockaddr_in *)clnt_sa, - addr, &clnt_authlist); + clnt_sa, + saddr, + &clnt_authlist); } + list = list->next; } - - list = list->next; + } else { + /* or send forward query to chosen host */ + gdm_xdmcp_send_forward_query (id, + clnt_sa, + clnt_sa, + &clnt_authlist); } - } else { - /* or send forward query to chosen host */ -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) - { - gdm_xdmcp_send_forward_query6 - (id, (struct sockaddr_in6 *)clnt_sa, - &(((struct sockaddr_in6 *)clnt_sa)->sin6_addr), - &clnt_authlist); - } - else -#endif - { - gdm_xdmcp_send_forward_query - (id, (struct sockaddr_in *)clnt_sa, - &(((struct sockaddr_in *)clnt_sa)->sin_addr), - &clnt_authlist); + } else if (id == NULL) { + id = gdm_choose_indirect_alloc (clnt_sa); + if (id != NULL) { + gdm_xdmcp_send_willing (clnt_sa); } - } - } else if (id == NULL) { - id = gdm_choose_indirect_alloc (clnt_sa); - if (id != NULL) { + } else { gdm_xdmcp_send_willing (clnt_sa); } - } else { + } else { gdm_xdmcp_send_willing (clnt_sa); } - } else { - gdm_xdmcp_send_willing (clnt_sa); + } else if (type == QUERY) { + /* unwilling is ONLY sent for direct queries, never for broadcast + * nor indirects */ + gdm_xdmcp_send_unwilling (clnt_sa, type); } - } else if (type == QUERY) { - /* unwilling is ONLY sent for direct queries, never for broadcast - * nor indirects */ - gdm_xdmcp_send_unwilling (clnt_sa, type); - } - /* Dispose authlist from remote display */ - XdmcpDisposeARRAYofARRAY8 (&clnt_authlist); + /* Dispose authlist from remote display */ + XdmcpDisposeARRAYofARRAY8 (&clnt_authlist); } -#ifdef ENABLE_IPV6 +#define SIN(__s) ((struct sockaddr_in *) __s) +#define SIN6(__s) ((struct sockaddr_in6 *) __s) + static void -gdm_xdmcp_send_forward_query6 (GdmIndirectDisplay *id, - struct sockaddr_in6 *clnt_sa, - struct in6_addr *display_addr, - ARRAYofARRAY8Ptr authlist) +set_port_for_request (struct sockaddr_storage *ss, + ARRAY8 *port) { - struct sockaddr_in6 sock = {0}; - XdmcpHeader header; - int i, authlen; - ARRAY8 address; - ARRAY8 port; - char buffer6[INET6_ADDRSTRLEN]; - - g_assert (id != NULL); - g_assert (id->chosen_host6 != NULL); - - gdm_debug ("gdm_xdmcp_send_forward_query6: Sending forward query to %s", - inet_ntop (AF_INET6, &(id->chosen_host6), - buffer6, sizeof (buffer6))); - gdm_debug ("gdm_xdmcp_send_forward_query6: Query contains %s:%d", - inet_ntop (AF_INET6, display_addr, buffer6, sizeof (buffer6)), - (int) ntohs (clnt_sa->sin6_port)); - - authlen = 1; - for (i = 0 ; i < authlist->length ; i++) { - authlen += 2 + authlist->data[i].length; - } - /* we depend on this being 2 elsewhere as well */ - port.length = 2; - port.data = g_new (unsigned char, 2); - memcpy (port.data, &(clnt_sa->sin6_port), 2); - address.length = sizeof (struct in6_addr); - address.data = (void *)g_new (struct in6_addr, 1); - memcpy (address.data, display_addr, sizeof (struct in6_addr)); - - - header.opcode = (CARD16) FORWARD_QUERY; - header.length = authlen; - header.length += 2 + address.length; - header.length += 2 + port.length; - header.version = XDM_PROTOCOL_VERSION; - XdmcpWriteHeader (&buf, &header); + port->length = 2; + + switch (ss->ss_family) { + case AF_INET: + port->data = (CARD8 *)g_memdup (&(SIN (ss)->sin_port), port->length); + break; + case AF_INET6: + port->data = (CARD8 *)g_memdup (&(SIN6 (ss)->sin6_port), port->length); + break; + default: + port->data = NULL; + break; + } +} - XdmcpWriteARRAY8 (&buf, &address); - XdmcpWriteARRAY8 (&buf, &port); - XdmcpWriteARRAYofARRAY8 (&buf, authlist); +static void +set_address_for_request (struct sockaddr_storage *ss, + ARRAY8 *address) +{ - memset (&sock, 0, sizeof (sock)); + switch (ss->ss_family) { + case AF_INET: + address->length = sizeof (struct in_addr); + address->data = g_memdup (&SIN (ss)->sin_addr, address->length); + break; + case AF_INET6: + address->length = sizeof (struct in6_addr); + address->data = g_memdup (&SIN6 (ss)->sin6_addr, address->length); + break; + default: + address->length = 0; + address->data = NULL; + break; + } - sock.sin6_family = AF_INET6; - sock.sin6_port = htons (XDM_UDP_PORT); - memcpy (sock.sin6_addr.s6_addr, id->chosen_host6->s6_addr, - sizeof (struct in6_addr)); - XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr) &sock, - (int)sizeof (struct sockaddr_in6)); - g_free (port.data); - g_free (address.data); } -#endif static void -gdm_xdmcp_send_forward_query (GdmIndirectDisplay *id, - struct sockaddr_in *clnt_sa, - struct in_addr *display_addr, - ARRAYofARRAY8Ptr authlist) +gdm_xdmcp_send_forward_query (GdmIndirectDisplay *id, + struct sockaddr_storage *clnt_sa, + struct sockaddr_storage *display_addr, + ARRAYofARRAY8Ptr authlist) { - struct sockaddr_in sock = {0}; + struct sockaddr_storage *sa; XdmcpHeader header; int i, authlen; ARRAY8 address; ARRAY8 port; + char *host; + char *serv; gdm_assert (id != NULL); gdm_assert (id->chosen_host != NULL); + gdm_address_get_info (id->chosen_host, &host, NULL); gdm_debug ("gdm_xdmcp_send_forward_query: Sending forward query to %s", - inet_ntoa (*id->chosen_host)); - gdm_debug ("gdm_xdmcp_send_forward_query: Query contains %s:%d", - inet_ntoa (*display_addr), - (int) ntohs (clnt_sa->sin_port)); + host); + g_free (host); + + gdm_address_get_info (display_addr, &host, &serv); + gdm_debug ("gdm_xdmcp_send_forward_query: Query contains %s:%s", + host, serv); + g_free (host); + g_free (serv); authlen = 1; for (i = 0 ; i < authlist->length ; i++) { authlen += 2 + authlist->data[i].length; } - /* we depend on this being 2 elsewhere as well */ - port.length = 2; - port.data = (CARD8 *) g_new (char, 2); - memcpy (port.data, &(clnt_sa->sin_port), 2); + set_port_for_request (clnt_sa, &port); + set_address_for_request (display_addr, &address); - address.length = sizeof (struct in_addr); - address.data = (void *)g_new (struct in_addr, 1); - memcpy (address.data, display_addr, sizeof (struct in_addr)); + sa = g_memdup (id->chosen_host, sizeof (id->chosen_host)); header.opcode = (CARD16) FORWARD_QUERY; header.length = authlen; @@ -984,14 +956,14 @@ gdm_xdmcp_send_forward_query (GdmIndirectDisplay *id, XdmcpWriteARRAY8 (&buf, &port); XdmcpWriteARRAYofARRAY8 (&buf, authlist); - sock.sin_family = AF_INET; - sock.sin_port = htons (XDM_UDP_PORT); - sock.sin_addr.s_addr = id->chosen_host->s_addr; - XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr) &sock, - (int)sizeof (struct sockaddr_in)); + XdmcpFlush (gdm_xdmcpfd, + &buf, + (XdmcpNetaddr) sa, + (int)sizeof (struct sockaddr_storage)); g_free (port.data); g_free (address.data); + g_free (sa); } static gboolean @@ -1018,35 +990,20 @@ remove_oldest_forward (void) } static GdmForwardQuery * -#ifdef ENABLE_IPV6 gdm_forward_query_alloc (struct sockaddr_storage *mgr_sa, struct sockaddr_storage *dsp_sa) -#else -gdm_forward_query_alloc (struct sockaddr_in *mgr_sa, - struct sockaddr_in *dsp_sa) -#endif { GdmForwardQuery *q; int count; count = g_slist_length (forward_queries); - while (count > GDM_MAX_FORWARD_QUERIES && - remove_oldest_forward ()) - count --; + while (count > GDM_MAX_FORWARD_QUERIES && remove_oldest_forward ()) + count--; q = g_new0 (GdmForwardQuery, 1); -#ifdef ENABLE_IPV6 - q->dsp_sa = g_new0 (struct sockaddr_storage, 1); - memcpy (q->dsp_sa, dsp_sa, sizeof (struct sockaddr_storage)); - q->from_sa = g_new0 (struct sockaddr_storage, 1); - memcpy (q->from_sa, mgr_sa, sizeof (struct sockaddr_storage)); -#else - q->dsp_sa = g_new0 (struct sockaddr_in, 1); - memcpy (q->dsp_sa, dsp_sa, sizeof (struct sockaddr_in)); - q->from_sa = g_new0 (struct sockaddr_in, 1); - memcpy (q->from_sa, mgr_sa, sizeof (struct sockaddr_in)); -#endif + q->dsp_sa = g_memdup (dsp_sa, sizeof (struct sockaddr_storage)); + q->from_sa = g_memdup (mgr_sa, sizeof (struct sockaddr_storage)); forward_queries = g_slist_prepend (forward_queries, q); @@ -1054,11 +1011,7 @@ gdm_forward_query_alloc (struct sockaddr_in *mgr_sa, } static GdmForwardQuery * -#ifdef ENABLE_IPV6 gdm_forward_query_lookup (struct sockaddr_storage *clnt_sa) -#else -gdm_forward_query_lookup (struct sockaddr_in *clnt_sa) -#endif { GSList *li, *qlist; GdmForwardQuery *q; @@ -1070,67 +1023,42 @@ gdm_forward_query_lookup (struct sockaddr_in *clnt_sa) q = (GdmForwardQuery *) li->data; if (q == NULL) continue; -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - if (memcmp (((struct sockaddr_in6 *)(q->dsp_sa))->sin6_addr.s6_addr, - ((struct sockaddr_in6 *)clnt_sa)->sin6_addr.s6_addr, - sizeof (struct in6_addr)) == 0) { - g_slist_free (qlist); - return q; - } - - if (q->acctime > 0 && curtime > q->acctime + GDM_FORWARD_QUERY_TIMEOUT) { - char buffer6[INET6_ADDRSTRLEN]; - gdm_debug ("gdm_forward_query_lookup: Disposing stale forward query from %s", - inet_ntop (AF_INET6, - &((struct sockaddr_in6 *)q->dsp_sa)->sin6_addr, - buffer6, INET6_ADDRSTRLEN)); - gdm_forward_query_dispose (q); - continue; - } + if (gdm_address_equal (q->dsp_sa, clnt_sa)) { + g_slist_free (qlist); + return q; } - else -#endif - { - if (((struct sockaddr_in *)(q->dsp_sa))->sin_addr.s_addr == - ((struct sockaddr_in *)clnt_sa)->sin_addr.s_addr) { - g_slist_free (qlist); - return q; - } - if (q->acctime > 0 && - curtime > q->acctime + GDM_FORWARD_QUERY_TIMEOUT) { - gdm_debug ("gdm_forward_query_lookup: Disposing stale forward query from %s", - inet_ntoa (((struct sockaddr_in*)q->dsp_sa)->sin_addr)); - gdm_forward_query_dispose (q); - continue; - } - } + if (q->acctime > 0 && curtime > q->acctime + GDM_FORWARD_QUERY_TIMEOUT) { + char *host; + char *serv; - } - g_slist_free (qlist); + gdm_address_get_info (q->dsp_sa, &host, &serv); -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; + gdm_debug ("gdm_forward_query_lookup: Disposing stale forward query from %s:%s", + host, serv); + g_free (host); + g_free (serv); - gdm_debug ("gdm_forward_query_lookup: Host %s not found", - inet_ntop (AF_INET6, - &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, - buffer6, INET6_ADDRSTRLEN)); + gdm_forward_query_dispose (q); + continue; + } } - else -#endif + + g_slist_free (qlist); + { + char *host; + + gdm_address_get_info (clnt_sa, &host, NULL); gdm_debug ("gdm_forward_query_lookup: Host %s not found", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); + host); + g_free (host); } return NULL; } - static void gdm_forward_query_dispose (GdmForwardQuery *q) { @@ -1141,20 +1069,12 @@ gdm_forward_query_dispose (GdmForwardQuery *q) q->acctime = 0; -#ifdef ENABLE_IPV6 - if (q->dsp_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; - - gdm_debug ("gdm_forward_query_dispose: Disposing %s", - inet_ntop (AF_INET6, - &(((struct sockaddr_in6 *)(q->dsp_sa))->sin6_addr), - buffer6, INET6_ADDRSTRLEN)); - } - else -#endif { - gdm_debug ("gdm_forward_query_dispose: Disposing %s", - inet_ntoa (((struct sockaddr_in *)(q->dsp_sa))->sin_addr)); + char *host; + + gdm_address_get_info (q->dsp_sa, &host, NULL); + gdm_debug ("gdm_forward_query_dispose: Disposing %s", host); + g_free (host); } g_free (q->dsp_sa); @@ -1165,427 +1085,328 @@ gdm_forward_query_dispose (GdmForwardQuery *q) g_free (q); } - -static void -#ifdef ENABLE_IPV6 -gdm_xdmcp_handle_forward_query (struct sockaddr_storage *clnt_sa, gint len) -#else -gdm_xdmcp_handle_forward_query (struct sockaddr_in *clnt_sa, gint len) -#endif +static gboolean +create_sa_from_request (ARRAY8 *req_addr, + ARRAY8 *req_port, + int family, + struct sockaddr_storage **sap) { - ARRAY8 clnt_addr; - ARRAY8 clnt_port; - ARRAYofARRAY8 clnt_authlist; - gint i = 0, explen = 1; -#ifdef ENABLE_IPV6 - struct sockaddr_storage disp_sa = {0}; -#else - struct sockaddr_in disp_sa = {0}; -#endif + uint16_t port; + char host_buf [NI_MAXHOST]; + char serv_buf [NI_MAXSERV]; + char *serv; + const char *host; + struct addrinfo hints; + struct addrinfo *ai_list; + struct addrinfo *ai; + int gaierr; + gboolean found; + + if (sap != NULL) { + *sap = NULL; + } - /* Check with tcp_wrappers if client is allowed to access */ - if (! gdm_xdmcp_host_allow (clnt_sa)) { -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; + if (req_addr == NULL) { + return FALSE; + } - gdm_error ("%s: Got FORWARD_QUERY from banned host %s", - "gdm_xdmcp_handle_forward query", - inet_ntop (AF_INET6, - &(((struct sockaddr_in6 *)clnt_sa)->sin6_addr), - buffer6, INET6_ADDRSTRLEN)); - } - else -#endif - { - gdm_error ("%s: Got FORWARD_QUERY from banned host %s", - "gdm_xdmcp_handle_forward query", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - } - - return; - } - - /* Read display address */ - if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_addr)) { - gdm_error (_("%s: Could not read display address"), - "gdm_xdmcp_handle_forward_query"); - return; - } - - /* Read display port */ - if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_port)) { - XdmcpDisposeARRAY8 (&clnt_addr); - gdm_error (_("%s: Could not read display port number"), - "gdm_xdmcp_handle_forward_query"); - return; - } - - /* Extract array of authentication names from Xdmcp packet */ - if G_UNLIKELY (! XdmcpReadARRAYofARRAY8 (&buf, &clnt_authlist)) { - XdmcpDisposeARRAY8 (&clnt_addr); - XdmcpDisposeARRAY8 (&clnt_port); - gdm_error (_("%s: Could not extract authlist from packet"), - "gdm_xdmcp_handle_forward_query"); - return; - } - - /* Crude checksumming */ - explen = 1; - explen += 2+clnt_addr.length; - explen += 2+clnt_port.length; - - for (i = 0 ; i < clnt_authlist.length ; i++) { - if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG)) { - char *s = g_strndup ((char *) clnt_authlist.data[i].data, - clnt_authlist.length); - gdm_debug ("gdm_xdmcp_handle_forward_query: authlist: %s", - ve_sure_string (s)); - g_free (s); - } - explen += 2+clnt_authlist.data[i].length; - } - - if G_UNLIKELY (len != explen) { - gdm_error (_("%s: Error in checksum"), - "gdm_xdmcp_handle_forward_query"); - goto out; - } + serv = NULL; + if (req_port != NULL) { + /* port must always be length 2 */ + if (req_port->length != 2) { + return FALSE; + } -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; + memcpy (&port, req_port->data, 2); + snprintf (serv_buf, sizeof (serv_buf), "%d", ntohs (port)); + serv = serv_buf; + } else { + /* assume XDM_UDP_PORT */ + snprintf (serv_buf, sizeof (serv_buf), "%d", XDM_UDP_PORT); + serv = serv_buf; + } + + host = NULL; + if (req_addr->length == 4) { + host = inet_ntop (AF_INET, + (const void *)req_addr->data, + host_buf, + sizeof (host_buf)); + } else if (req_addr->length == 16) { + host = inet_ntop (AF_INET6, + (const void *)req_addr->data, + host_buf, + sizeof (host_buf)); + } + + if (host == NULL) { + gdm_error (_("Bad address")); + return FALSE; + } + + memset (&hints, 0, sizeof (hints)); + hints.ai_family = family; + hints.ai_flags = AI_V4MAPPED; /* this should convert IPv4 address to IPv6 if needed */ + if ((gaierr = getaddrinfo (host, serv, &hints, &ai_list)) != 0) { + g_warning ("Unable get address: %s", gai_strerror (gaierr)); + return FALSE; + } - struct in6_addr ipv6_addr; - struct in6_addr * ipv6_addr_ptr = NULL; + /* just take the first one */ + ai = ai_list; - if (clnt_port.length == 2 && - clnt_addr.length == 4) { - char * ipv4_addr; + found = FALSE; + if (ai != NULL) { + found = TRUE; + if (sap != NULL) { + *sap = g_memdup (ai->ai_addr, ai->ai_addrlen); + } + } - /* Convert IPv4 address to IPv6 if needed */ - struct sockaddr_in tmp_disp_sa = {0}; - ((struct sockaddr_in *)(&tmp_disp_sa))->sin_family = AF_INET; - memcpy (&((struct sockaddr_in *)(&tmp_disp_sa))->sin_port, - clnt_port.data, 2); - memcpy (&((struct sockaddr_in *)(&tmp_disp_sa))->sin_addr.s_addr, - clnt_addr.data, 4); + freeaddrinfo (ai_list); - ipv4_addr = inet_ntoa (((struct sockaddr_in *)(&tmp_disp_sa))->sin_addr); - strcpy (buffer6, "::ffff:"); - strncat (buffer6, ipv4_addr, INET_ADDRSTRLEN); + return found; +} - inet_pton (AF_INET6, buffer6, &ipv6_addr); - ipv6_addr_ptr = &ipv6_addr; +static void +gdm_xdmcp_handle_forward_query (struct sockaddr_storage *clnt_sa, + gint len) +{ + ARRAY8 clnt_addr; + ARRAY8 clnt_port; + ARRAYofARRAY8 clnt_authlist; + gint i = 0; + gint explen = 1; + struct sockaddr_storage *disp_sa; + char *host; + char *serv; - } else if (clnt_port.length == 2 && - clnt_addr.length == 16) { + disp_sa = NULL; - ipv6_addr_ptr = (struct in6_addr *)clnt_addr.data; + /* Check with tcp_wrappers if client is allowed to access */ + if (! gdm_xdmcp_host_allow (clnt_sa)) { + char *host; - } else { + gdm_address_get_info (clnt_sa, &host, NULL); - gdm_error (_("%s: Bad address"), - "gdm_xdmcp_handle_forward_query"); - goto out; + gdm_error ("%s: Got FORWARD_QUERY from banned host %s", + "gdm_xdmcp_handle_forward query", + host); + g_free (host); + return; } - g_assert (16 == sizeof (struct in6_addr)); + /* Read display address */ + if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_addr)) { + gdm_error (_("%s: Could not read display address"), + "gdm_xdmcp_handle_forward_query"); + return; + } - gdm_xdmcp_whack_queued_managed_forwards6 ((struct sockaddr_in6 *)clnt_sa, - ipv6_addr_ptr); + /* Read display port */ + if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_port)) { + XdmcpDisposeARRAY8 (&clnt_addr); + gdm_error (_("%s: Could not read display port number"), + "gdm_xdmcp_handle_forward_query"); + return; + } - ((struct sockaddr_in6 *)(&disp_sa))->sin6_family = AF_INET6; + /* Extract array of authentication names from Xdmcp packet */ + if G_UNLIKELY (! XdmcpReadARRAYofARRAY8 (&buf, &clnt_authlist)) { + XdmcpDisposeARRAY8 (&clnt_addr); + XdmcpDisposeARRAY8 (&clnt_port); + gdm_error (_("%s: Could not extract authlist from packet"), + "gdm_xdmcp_handle_forward_query"); + return; + } - /* Find client port number */ - memcpy (&((struct sockaddr_in6 *)(&disp_sa))->sin6_port, clnt_port.data, 2); + /* Crude checksumming */ + explen = 1; + explen += 2 + clnt_addr.length; + explen += 2 + clnt_port.length; - /* Find client address */ - memcpy (&((struct sockaddr_in6 *)(&disp_sa))->sin6_addr.s6_addr, - ipv6_addr_ptr, 16); + for (i = 0 ; i < clnt_authlist.length ; i++) { + char *s = g_strndup ((char *) clnt_authlist.data[i].data, + clnt_authlist.length); + gdm_debug ("gdm_xdmcp_handle_forward_query: authlist: %s", + ve_sure_string (s)); + g_free (s); - gdm_debug ("gdm_xdmcp_handle_forward_query: Got FORWARD_QUERY for display: %s, port %d", - inet_ntop (AF_INET6, - &((struct sockaddr_in6 *)(&disp_sa))->sin6_addr, - buffer6, INET6_ADDRSTRLEN), - ntohs (((struct sockaddr_in6 *)(&disp_sa))->sin6_port)); - } - else -#endif - { - if (clnt_port.length != 2 || - clnt_addr.length != 4) { - gdm_error (_("%s: Bad address"), - "gdm_xdmcp_handle_forward_query"); + explen += 2 + clnt_authlist.data[i].length; + } + + if G_UNLIKELY (len != explen) { + gdm_error (_("%s: Error in checksum"), + "gdm_xdmcp_handle_forward_query"); goto out; } - g_assert (4 == sizeof (struct in_addr)); - gdm_xdmcp_whack_queued_managed_forwards ((struct sockaddr_in *)clnt_sa, - (struct in_addr *)clnt_addr.data); - ((struct sockaddr_in *)(&disp_sa))->sin_family = AF_INET; - /* Find client port number */ - memcpy (&((struct sockaddr_in *)(&disp_sa))->sin_port, clnt_port.data, 2); - /* Find client address */ - memcpy (&((struct sockaddr_in *)(&disp_sa))->sin_addr.s_addr, - clnt_addr.data, 4); - gdm_debug ("gdm_xdmcp_handle_forward_query: Got FORWARD_QUERY for display: %s, port %d", - inet_ntoa (((struct sockaddr_in *)(&disp_sa))->sin_addr), - ntohs (((struct sockaddr_in *)(&disp_sa))->sin_port)); - } - - /* Check with tcp_wrappers if display is allowed to access */ - if (gdm_xdmcp_host_allow (&disp_sa)) { - GdmForwardQuery *q; - - q = gdm_forward_query_lookup (&disp_sa); - if (q != NULL) - gdm_forward_query_dispose (q); - gdm_forward_query_alloc (clnt_sa, &disp_sa); - - gdm_xdmcp_send_willing (&disp_sa); - } - - out: - /* Cleanup */ - XdmcpDisposeARRAYofARRAY8 (&clnt_authlist); - XdmcpDisposeARRAY8 (&clnt_port); - XdmcpDisposeARRAY8 (&clnt_addr); -} + if (! create_sa_from_request (&clnt_addr, &clnt_port, clnt_sa->ss_family, &disp_sa)) { + gdm_error ("Unable to parse address for request"); + goto out; + } + + gdm_xdmcp_whack_queued_managed_forwards (clnt_sa, + disp_sa); + + gdm_address_get_info (disp_sa, &host, &serv); + gdm_debug ("gdm_xdmcp_handle_forward_query: Got FORWARD_QUERY for display: %s, port %s", + host, serv); + g_free (host); + g_free (serv); + /* Check with tcp_wrappers if display is allowed to access */ + if (gdm_xdmcp_host_allow (disp_sa)) { + GdmForwardQuery *q; + + q = gdm_forward_query_lookup (disp_sa); + if (q != NULL) + gdm_forward_query_dispose (q); + gdm_forward_query_alloc (clnt_sa, disp_sa); + + gdm_xdmcp_send_willing (disp_sa); + } + + out: + + g_free (disp_sa); + XdmcpDisposeARRAYofARRAY8 (&clnt_authlist); + XdmcpDisposeARRAY8 (&clnt_port); + XdmcpDisposeARRAY8 (&clnt_addr); +} static void -#ifdef ENABLE_IPV6 gdm_xdmcp_send_willing (struct sockaddr_storage *clnt_sa) -#else -gdm_xdmcp_send_willing (struct sockaddr_in *clnt_sa) -#endif { - ARRAY8 status; - XdmcpHeader header; - static char *last_status = NULL; - static time_t last_willing = 0; - char *bin; - FILE *fd; - const char *willing = gdm_daemon_config_get_value_string (GDM_KEY_WILLING); - int dispperhost = gdm_daemon_config_get_value_int (GDM_KEY_DISPLAYS_PER_HOST); - -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; - - gdm_debug ("gdm_xdmcp_send_willing: Sending WILLING to %s", - inet_ntop (AF_INET6, - &(((struct sockaddr_in6 *)clnt_sa)->sin6_addr), - buffer6, INET6_ADDRSTRLEN)); - } - else -#endif - { - gdm_debug ("gdm_xdmcp_send_willing: Sending WILLING to %s", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - } - - if (last_willing == 0 || - time (NULL) - 3 > last_willing) { - char statusBuf[256] = ""; - bin = ve_first_word (willing); - - if ( ! ve_string_empty (bin) && - g_access (bin, X_OK) == 0 && - (fd = popen (willing, "r")) != NULL) { - - if (fgets (statusBuf, sizeof (statusBuf), fd) != NULL && - ! ve_string_empty (g_strstrip (statusBuf))) { - g_free (last_status); - last_status = g_strdup (statusBuf); - } else { - g_free (last_status); - last_status = g_strdup (sysid); - } - pclose (fd); - } else { - g_free (last_status); - last_status = g_strdup (sysid); - } - - last_willing = time (NULL); - g_free (bin); - } -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { + ARRAY8 status; + XdmcpHeader header; + static char *last_status = NULL; + static time_t last_willing = 0; + char *bin; + FILE *fd; + const char *willing = gdm_daemon_config_get_value_string (GDM_KEY_WILLING); + int dispperhost = gdm_daemon_config_get_value_int (GDM_KEY_DISPLAYS_PER_HOST); + char *host; + + gdm_address_get_info (clnt_sa, &host, NULL); + gdm_debug ("gdm_xdmcp_send_willing: Sending WILLING to %s", host); + g_free (host); + + if (last_willing == 0 || + time (NULL) - 3 > last_willing) { + char statusBuf[256] = ""; + bin = ve_first_word (willing); + + if ( ! ve_string_empty (bin) && + g_access (bin, X_OK) == 0 && + (fd = popen (willing, "r")) != NULL) { + + if (fgets (statusBuf, sizeof (statusBuf), fd) != NULL && + ! ve_string_empty (g_strstrip (statusBuf))) { + g_free (last_status); + last_status = g_strdup (statusBuf); + } else { + g_free (last_status); + last_status = g_strdup (sysid); + } + pclose (fd); + } else { + g_free (last_status); + last_status = g_strdup (sysid); + } - if ( ! gdm_is_local_addr6 (&(((struct sockaddr_in6 *)clnt_sa)->sin6_addr)) && - gdm_xdmcp_displays_from_host (clnt_sa) >= dispperhost) { - /* - * Don't translate, this goes over the wire to servers where we - * don't know the charset or language, so it must be ascii - */ - status.data = (CARD8 *) g_strdup_printf ("%s (Server is busy)", - last_status); - } else { - status.data = (CARD8 *) g_strdup (last_status); + last_willing = time (NULL); + g_free (bin); } - } - else -#endif - { - if ( ! gdm_is_local_addr (&(((struct sockaddr_in *)clnt_sa)->sin_addr)) && + + if (! gdm_address_is_local (clnt_sa) && gdm_xdmcp_displays_from_host (clnt_sa) >= dispperhost) { - /* Don't translate, this goes over the wire to servers where we - * don't know the charset or language, so it must be ascii */ + /* + * Don't translate, this goes over the wire to servers where we + * don't know the charset or language, so it must be ascii + */ status.data = (CARD8 *) g_strdup_printf ("%s (Server is busy)", - last_status); + last_status); } else { status.data = (CARD8 *) g_strdup (last_status); } - } - - status.length = strlen ((char *) status.data); - - header.opcode = (CARD16) WILLING; - header.length = 6 + serv_authlist.authentication.length; - header.length += servhost.length + status.length; - header.version = XDM_PROTOCOL_VERSION; - XdmcpWriteHeader (&buf, &header); - - /* Hardcoded authentication */ - XdmcpWriteARRAY8 (&buf, &serv_authlist.authentication); - XdmcpWriteARRAY8 (&buf, &servhost); - XdmcpWriteARRAY8 (&buf, &status); -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - XdmcpFlush (gdm_xdmcpfd, - &buf, - (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in6)); - } - else -#endif - { + status.length = strlen ((char *) status.data); + + header.opcode = (CARD16) WILLING; + header.length = 6 + serv_authlist.authentication.length; + header.length += servhost.length + status.length; + header.version = XDM_PROTOCOL_VERSION; + XdmcpWriteHeader (&buf, &header); + + /* Hardcoded authentication */ + XdmcpWriteARRAY8 (&buf, &serv_authlist.authentication); + XdmcpWriteARRAY8 (&buf, &servhost); + XdmcpWriteARRAY8 (&buf, &status); + XdmcpFlush (gdm_xdmcpfd, - &buf, - (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in)); - } + &buf, + (XdmcpNetaddr)clnt_sa, + (int)sizeof (struct sockaddr_storage)); - g_free (status.data); + g_free (status.data); } static void -#ifdef ENABLE_IPV6 gdm_xdmcp_send_unwilling (struct sockaddr_storage *clnt_sa, gint type) -#else -gdm_xdmcp_send_unwilling (struct sockaddr_in *clnt_sa, gint type) -#endif { - ARRAY8 status; - XdmcpHeader header; - static time_t last_time = 0; - - /* only send at most one packet per second, - no harm done if we don't send it at all */ - if (last_time + 1 >= time (NULL)) - return; - -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; - - gdm_debug ("gdm_xdmcp_send_unwilling: Sending UNWILLING to %s", - inet_ntop (AF_INET6, - &(((struct sockaddr_in6 *)clnt_sa)->sin6_addr), - buffer6, INET6_ADDRSTRLEN)); - gdm_error (_("Denied XDMCP query from host %s"), buffer6); - } - else -#endif - { - gdm_debug ("gdm_xdmcp_send_unwilling: Sending UNWILLING to %s", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - - gdm_error (_("Denied XDMCP query from host %s"), - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - } - - /* - * Don't translate, this goes over the wire to servers where we - * don't know the charset or language, so it must be ascii - */ - status.data = (CARD8 *) "Display not authorized to connect"; - status.length = strlen ((char *) status.data); - - header.opcode = (CARD16) UNWILLING; - header.length = 4 + servhost.length + status.length; - header.version = XDM_PROTOCOL_VERSION; - XdmcpWriteHeader (&buf, &header); - - XdmcpWriteARRAY8 (&buf, &servhost); - XdmcpWriteARRAY8 (&buf, &status); -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - XdmcpFlush (gdm_xdmcpfd, - &buf, - (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in6)); - } - else -#endif - { + ARRAY8 status; + XdmcpHeader header; + static time_t last_time = 0; + char *host; + + /* only send at most one packet per second, + no harm done if we don't send it at all */ + if (last_time + 1 >= time (NULL)) + return; + + gdm_address_get_info (clnt_sa, &host, NULL); + gdm_debug ("gdm_xdmcp_send_unwilling: Sending UNWILLING to %s", host); + gdm_error (_("Denied XDMCP query from host %s"), host); + g_free (host); + + /* + * Don't translate, this goes over the wire to servers where we + * don't know the charset or language, so it must be ascii + */ + status.data = (CARD8 *) "Display not authorized to connect"; + status.length = strlen ((char *) status.data); + + header.opcode = (CARD16) UNWILLING; + header.length = 4 + servhost.length + status.length; + header.version = XDM_PROTOCOL_VERSION; + XdmcpWriteHeader (&buf, &header); + + XdmcpWriteARRAY8 (&buf, &servhost); + XdmcpWriteARRAY8 (&buf, &status); XdmcpFlush (gdm_xdmcpfd, - &buf, - (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in)); - } + &buf, + (XdmcpNetaddr)clnt_sa, + (int)sizeof (struct sockaddr_storage)); - last_time = time (NULL); + last_time = time (NULL); } static void -#ifdef ENABLE_IPV6 gdm_xdmcp_really_send_managed_forward (struct sockaddr_storage *clnt_sa, - struct sockaddr_storage *origin) -#else -gdm_xdmcp_really_send_managed_forward (struct sockaddr_in *clnt_sa, - struct sockaddr_in *origin) -#endif + struct sockaddr_storage *origin) { ARRAY8 address; XdmcpHeader header; - struct in_addr addr; + char *host; -#ifdef ENABLE_IPV6 - struct in6_addr addr6; - - if (clnt_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; + gdm_address_get_info (clnt_sa, &host, NULL); + gdm_debug ("gdm_xdmcp_really_send_managed_forward: " + "Sending MANAGED_FORWARD to %s", + host); + g_free (host); - gdm_debug ("gdm_xdmcp_really_send_managed_forward: " - "Sending MANAGED_FORWARD to %s", - inet_ntop (AF_INET6, - &(((struct sockaddr_in6 *)clnt_sa)->sin6_addr), - buffer6, INET6_ADDRSTRLEN)); - - address.length = sizeof (struct in6_addr); - address.data = (void *)&addr6; - memcpy (address.data, - &(((struct sockaddr_in6 *)origin)->sin6_addr), - sizeof (struct in6_addr)); - } - else -#endif - { - gdm_debug ("gdm_xdmcp_really_send_managed_forward: " - "Sending MANAGED_FORWARD to %s", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - - address.length = sizeof (struct in_addr); - address.data = (void *)&addr; - memcpy (address.data, - &(((struct sockaddr_in *)origin)->sin_addr), - sizeof (struct in_addr)); - } + set_address_for_request (origin, &address); header.opcode = (CARD16) GDM_XDMCP_MANAGED_FORWARD; header.length = 4 + address.length; @@ -1593,28 +1414,17 @@ gdm_xdmcp_really_send_managed_forward (struct sockaddr_in *clnt_sa, XdmcpWriteHeader (&buf, &header); XdmcpWriteARRAY8 (&buf, &address); -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - XdmcpFlush (gdm_xdmcpfd, - &buf, - (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in6)); - } - else -#endif - { - XdmcpFlush (gdm_xdmcpfd, - &buf, - (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in)); - } + XdmcpFlush (gdm_xdmcpfd, + &buf, + (XdmcpNetaddr)clnt_sa, + (int)sizeof (struct sockaddr_storage)); + g_free (address.data); } static gboolean -managed_forward_handler (gpointer data) +managed_forward_handler (ManagedForward *mf) { - ManagedForward *mf = data; if (gdm_xdmcpfd > 0) gdm_xdmcp_really_send_managed_forward (&(mf->manager), &(mf->origin)); @@ -1629,13 +1439,8 @@ managed_forward_handler (gpointer data) } static void -#ifdef ENABLE_IPV6 gdm_xdmcp_send_managed_forward (struct sockaddr_storage *clnt_sa, - struct sockaddr_storage *origin) -#else -gdm_xdmcp_send_managed_forward (struct sockaddr_in *clnt_sa, - struct sockaddr_in *origin) -#endif + struct sockaddr_storage *origin) { ManagedForward *mf; @@ -1643,659 +1448,479 @@ gdm_xdmcp_send_managed_forward (struct sockaddr_in *clnt_sa, mf = g_new0 (ManagedForward, 1); mf->times = 0; -#ifdef ENABLE_IPV6 + memcpy (&(mf->manager), clnt_sa, sizeof (struct sockaddr_storage)); memcpy (&(mf->origin), origin, sizeof (struct sockaddr_storage)); -#else - memcpy (&(mf->manager), clnt_sa, sizeof (struct sockaddr_in)); - memcpy (&(mf->origin), origin, sizeof (struct sockaddr_in)); -#endif mf->handler = g_timeout_add_full (G_PRIORITY_DEFAULT, MANAGED_FORWARD_INTERVAL, - managed_forward_handler, + (GSourceFunc)managed_forward_handler, mf, (GDestroyNotify) g_free); managed_forwards = g_slist_prepend (managed_forwards, mf); } -#ifdef ENABLE_IPV6 static void -gdm_xdmcp_send_got_managed_forward6 (struct sockaddr_in6 *clnt_sa, - struct in6_addr *origin) +gdm_xdmcp_send_got_managed_forward (struct sockaddr_storage *clnt_sa, + struct sockaddr_storage *origin) { ARRAY8 address; XdmcpHeader header; - struct in6_addr addr; - char buffer6[INET6_ADDRSTRLEN]; + char *host; + gdm_address_get_info (clnt_sa, &host, NULL); gdm_debug ("gdm_xdmcp_send_managed_forward: " - "Sending GOT_MANAGED_FORWARD to %s", - inet_ntop (AF_INET6, - &clnt_sa->sin6_addr, - buffer6, INET6_ADDRSTRLEN)); + "Sending GOT_MANAGED_FORWARD to %s", + host); + g_free (host); - address.length = sizeof (struct in6_addr); - address.data = (void *)&addr; - memcpy (address.data, origin, sizeof (struct in6_addr)); + set_address_for_request (origin, &address); header.opcode = (CARD16) GDM_XDMCP_GOT_MANAGED_FORWARD; - header.length = 16 + address.length; + header.length = 4 + address.length; header.version = GDM_XDMCP_PROTOCOL_VERSION; XdmcpWriteHeader (&buf, &header); XdmcpWriteARRAY8 (&buf, &address); - XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in6)); + XdmcpFlush (gdm_xdmcpfd, + &buf, + (XdmcpNetaddr)clnt_sa, + (int)sizeof (struct sockaddr_storage)); } -#endif static void -gdm_xdmcp_send_got_managed_forward (struct sockaddr_in *clnt_sa, - struct in_addr *origin) +gdm_xdmcp_handle_request (struct sockaddr_storage *clnt_sa, + gint len) { - ARRAY8 address; - XdmcpHeader header; - struct in_addr addr; + CARD16 clnt_dspnum; + ARRAY16 clnt_conntyp; + ARRAYofARRAY8 clnt_addr; + ARRAY8 clnt_authname; + ARRAY8 clnt_authdata; + ARRAYofARRAY8 clnt_authorization; + ARRAY8 clnt_manufacturer; + gint explen; + gint i; + gboolean mitauth = FALSE; + gboolean entered = FALSE; + int maxsessions = gdm_daemon_config_get_value_int (GDM_KEY_MAX_SESSIONS); + int maxpending = gdm_daemon_config_get_value_int (GDM_KEY_MAX_PENDING); + int dispperhost = gdm_daemon_config_get_value_int (GDM_KEY_DISPLAYS_PER_HOST); + char *host; + + gdm_address_get_info (clnt_sa, &host, NULL); + gdm_debug ("gdm_xdmcp_handle_request: Got REQUEST from %s", host); - gdm_debug ("gdm_xdmcp_send_managed_forward: " - "Sending GOT_MANAGED_FORWARD to %s", - inet_ntoa (clnt_sa->sin_addr)); + /* Check with tcp_wrappers if client is allowed to access */ + if (! gdm_xdmcp_host_allow (clnt_sa)) { + gdm_error (_("%s: Got REQUEST from banned host %s"), + "gdm_xdmcp_handle_request", + host); + g_free (host); + return; + } + g_free (host); - address.length = sizeof (struct in_addr); - address.data = (void *)&addr; - memcpy (address.data, origin, sizeof (struct in_addr)); + gdm_xdmcp_displays_check (); /* Purge pending displays */ - header.opcode = (CARD16) GDM_XDMCP_GOT_MANAGED_FORWARD; - header.length = 4 + address.length; - header.version = GDM_XDMCP_PROTOCOL_VERSION; - XdmcpWriteHeader (&buf, &header); + /* Remote display number */ + if G_UNLIKELY (! XdmcpReadCARD16 (&buf, &clnt_dspnum)) { + gdm_error (_("%s: Could not read Display Number"), + "gdm_xdmcp_handle_request"); + return; + } - XdmcpWriteARRAY8 (&buf, &address); - XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in)); -} + /* We don't care about connection type. Address says it all */ + if G_UNLIKELY (! XdmcpReadARRAY16 (&buf, &clnt_conntyp)) { + gdm_error (_("%s: Could not read Connection Type"), + "gdm_xdmcp_handle_request"); + return; + } -static void -#ifdef ENABLE_IPV6 -gdm_xdmcp_handle_request (struct sockaddr_storage *clnt_sa, gint len) -#else -gdm_xdmcp_handle_request (struct sockaddr_in *clnt_sa, gint len) -#endif -{ - CARD16 clnt_dspnum; - ARRAY16 clnt_conntyp; - ARRAYofARRAY8 clnt_addr; - ARRAY8 clnt_authname; - ARRAY8 clnt_authdata; - ARRAYofARRAY8 clnt_authorization; - ARRAY8 clnt_manufacturer; - gint explen; - gint i; - gboolean mitauth = FALSE; - gboolean entered = FALSE; - int maxsessions = gdm_daemon_config_get_value_int (GDM_KEY_MAX_SESSIONS); - int maxpending = gdm_daemon_config_get_value_int (GDM_KEY_MAX_PENDING); - int dispperhost = gdm_daemon_config_get_value_int (GDM_KEY_DISPLAYS_PER_HOST); - -#ifdef ENABLE_IPV6 - char buffer6[INET6_ADDRSTRLEN]; + /* This is TCP/IP - we don't care */ + if G_UNLIKELY (! XdmcpReadARRAYofARRAY8 (&buf, &clnt_addr)) { + gdm_error (_("%s: Could not read Client Address"), + "gdm_xdmcp_handle_request"); + XdmcpDisposeARRAY16 (&clnt_conntyp); + return; + } - inet_ntop (AF_INET6, - &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, - buffer6, INET6_ADDRSTRLEN); + /* Read authentication type */ + if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_authname)) { + gdm_error (_("%s: Could not read Authentication Names"), + "gdm_xdmcp_handle_request"); + XdmcpDisposeARRAYofARRAY8 (&clnt_addr); + XdmcpDisposeARRAY16 (&clnt_conntyp); + return; + } - if (clnt_sa->ss_family == AF_INET6) { - gdm_debug ("gdm_xdmcp_handle_request: Got REQUEST from %s",buffer6); - } - else -#endif - { - gdm_debug ("gdm_xdmcp_handle_request: Got REQUEST from %s", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - } - - /* Check with tcp_wrappers if client is allowed to access */ - if (! gdm_xdmcp_host_allow (clnt_sa)) { -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - gdm_error (_("%s: Got REQUEST from banned host %s"), - "gdm_xdmcp_handle_request", - inet_ntop (AF_INET6, - &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, - buffer6, INET6_ADDRSTRLEN)); - } - else -#endif - { - gdm_error (_("%s: Got REQUEST from banned host %s"), - "gdm_xdmcp_handle_request", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - } - - return; - } - - gdm_xdmcp_displays_check (); /* Purge pending displays */ - - /* Remote display number */ - if G_UNLIKELY (! XdmcpReadCARD16 (&buf, &clnt_dspnum)) { - gdm_error (_("%s: Could not read Display Number"), - "gdm_xdmcp_handle_request"); - return; - } - - /* We don't care about connection type. Address says it all */ - if G_UNLIKELY (! XdmcpReadARRAY16 (&buf, &clnt_conntyp)) { - gdm_error (_("%s: Could not read Connection Type"), - "gdm_xdmcp_handle_request"); - return; - } - - /* This is TCP/IP - we don't care */ - if G_UNLIKELY (! XdmcpReadARRAYofARRAY8 (&buf, &clnt_addr)) { - gdm_error (_("%s: Could not read Client Address"), - "gdm_xdmcp_handle_request"); - XdmcpDisposeARRAY16 (&clnt_conntyp); - return; - } - - /* Read authentication type */ - if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_authname)) { - gdm_error (_("%s: Could not read Authentication Names"), - "gdm_xdmcp_handle_request"); - XdmcpDisposeARRAYofARRAY8 (&clnt_addr); - XdmcpDisposeARRAY16 (&clnt_conntyp); - return; - } - - /* Read authentication data */ - if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_authdata)) { - gdm_error (_("%s: Could not read Authentication Data"), - "gdm_xdmcp_handle_request"); - XdmcpDisposeARRAYofARRAY8 (&clnt_addr); - XdmcpDisposeARRAY16 (&clnt_conntyp); - XdmcpDisposeARRAY8 (&clnt_authname); - return; - } - - /* Read and select from supported authorization list */ - if G_UNLIKELY (! XdmcpReadARRAYofARRAY8 (&buf, &clnt_authorization)) { - gdm_error (_("%s: Could not read Authorization List"), - "gdm_xdmcp_handle_request"); - XdmcpDisposeARRAY8 (&clnt_authdata); - XdmcpDisposeARRAYofARRAY8 (&clnt_addr); - XdmcpDisposeARRAY16 (&clnt_conntyp); - XdmcpDisposeARRAY8 (&clnt_authname); - return; - } - - /* libXdmcp doesn't terminate strings properly so we cheat and use strncmp () */ - for (i = 0 ; i < clnt_authorization.length ; i++) - if (clnt_authorization.data[i].length == 18 && - strncmp ((char *) clnt_authorization.data[i].data, - "MIT-MAGIC-COOKIE-1", 18) == 0) - mitauth = TRUE; - - /* Manufacturer ID */ - if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_manufacturer)) { - gdm_error (_("%s: Could not read Manufacturer ID"), - "gdm_xdmcp_handle_request"); - XdmcpDisposeARRAY8 (&clnt_authname); - XdmcpDisposeARRAY8 (&clnt_authdata); - XdmcpDisposeARRAYofARRAY8 (&clnt_addr); - XdmcpDisposeARRAYofARRAY8 (&clnt_authorization); - XdmcpDisposeARRAY16 (&clnt_conntyp); - return; - } - - /* Crude checksumming */ - explen = 2; /* Display Number */ - explen += 1+2*clnt_conntyp.length; /* Connection Type */ - explen += 1; /* Connection Address */ - for (i = 0 ; i < clnt_addr.length ; i++) - explen += 2+clnt_addr.data[i].length; - explen += 2+clnt_authname.length; /* Authentication Name */ - explen += 2+clnt_authdata.length; /* Authentication Data */ - explen += 1; /* Authorization Names */ - for (i = 0 ; i < clnt_authorization.length ; i++) - explen += 2+clnt_authorization.data[i].length; - explen += 2+clnt_manufacturer.length; - - if G_UNLIKELY (explen != len) { -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - gdm_error (_("%s: Failed checksum from %s"), - "gdm_xdmcp_handle_request", - inet_ntop (AF_INET6, - &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, - buffer6, INET6_ADDRSTRLEN)); - } - else -#endif - { - gdm_error (_("%s: Failed checksum from %s"), - "gdm_xdmcp_handle_request", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); + /* Read authentication data */ + if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_authdata)) { + gdm_error (_("%s: Could not read Authentication Data"), + "gdm_xdmcp_handle_request"); + XdmcpDisposeARRAYofARRAY8 (&clnt_addr); + XdmcpDisposeARRAY16 (&clnt_conntyp); + XdmcpDisposeARRAY8 (&clnt_authname); + return; } - XdmcpDisposeARRAY8 (&clnt_authname); - XdmcpDisposeARRAY8 (&clnt_authdata); - XdmcpDisposeARRAY8 (&clnt_manufacturer); - XdmcpDisposeARRAYofARRAY8 (&clnt_addr); - XdmcpDisposeARRAYofARRAY8 (&clnt_authorization); - XdmcpDisposeARRAY16 (&clnt_conntyp); - return; - } - - if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG)) { - char *s = g_strndup ((char *) clnt_manufacturer.data, clnt_manufacturer.length); - gdm_debug ("gdm_xdmcp_handle_request: xdmcp_pending=%d, MaxPending=%d, xdmcp_sessions=%d, MaxSessions=%d, ManufacturerID=%s", - xdmcp_pending, maxpending, xdmcp_sessions, - maxsessions, ve_sure_string (s)); - g_free (s); - } - - /* Check if ok to manage display */ -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - if (mitauth && - xdmcp_sessions < maxsessions && - (gdm_is_local_addr6 (&((struct sockaddr_in6 *)clnt_sa)->sin6_addr) || - gdm_xdmcp_displays_from_host (clnt_sa) < dispperhost)) + /* Read and select from supported authorization list */ + if G_UNLIKELY (! XdmcpReadARRAYofARRAY8 (&buf, &clnt_authorization)) { + gdm_error (_("%s: Could not read Authorization List"), + "gdm_xdmcp_handle_request"); + XdmcpDisposeARRAY8 (&clnt_authdata); + XdmcpDisposeARRAYofARRAY8 (&clnt_addr); + XdmcpDisposeARRAY16 (&clnt_conntyp); + XdmcpDisposeARRAY8 (&clnt_authname); + return; + } + + /* libXdmcp doesn't terminate strings properly so we cheat and use strncmp () */ + for (i = 0 ; i < clnt_authorization.length ; i++) + if (clnt_authorization.data[i].length == 18 && + strncmp ((char *) clnt_authorization.data[i].data, + "MIT-MAGIC-COOKIE-1", 18) == 0) + mitauth = TRUE; + + /* Manufacturer ID */ + if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_manufacturer)) { + gdm_error (_("%s: Could not read Manufacturer ID"), + "gdm_xdmcp_handle_request"); + XdmcpDisposeARRAY8 (&clnt_authname); + XdmcpDisposeARRAY8 (&clnt_authdata); + XdmcpDisposeARRAYofARRAY8 (&clnt_addr); + XdmcpDisposeARRAYofARRAY8 (&clnt_authorization); + XdmcpDisposeARRAY16 (&clnt_conntyp); + return; + } + + /* Crude checksumming */ + explen = 2; /* Display Number */ + explen += 1 + 2 * clnt_conntyp.length; /* Connection Type */ + explen += 1; /* Connection Address */ + for (i = 0 ; i < clnt_addr.length ; i++) + explen += 2 + clnt_addr.data[i].length; + explen += 2 + clnt_authname.length; /* Authentication Name */ + explen += 2 + clnt_authdata.length; /* Authentication Data */ + explen += 1; /* Authorization Names */ + for (i = 0 ; i < clnt_authorization.length ; i++) + explen += 2 + clnt_authorization.data[i].length; + explen += 2 + clnt_manufacturer.length; + + if G_UNLIKELY (explen != len) { + gdm_address_get_info (clnt_sa, &host, NULL); + gdm_error (_("%s: Failed checksum from %s"), + "gdm_xdmcp_handle_request", + host); + g_free (host); + + XdmcpDisposeARRAY8 (&clnt_authname); + XdmcpDisposeARRAY8 (&clnt_authdata); + XdmcpDisposeARRAY8 (&clnt_manufacturer); + XdmcpDisposeARRAYofARRAY8 (&clnt_addr); + XdmcpDisposeARRAYofARRAY8 (&clnt_authorization); + XdmcpDisposeARRAY16 (&clnt_conntyp); + return; + } - entered = TRUE; - } else -#endif { + char *s = g_strndup ((char *) clnt_manufacturer.data, clnt_manufacturer.length); + gdm_debug ("gdm_xdmcp_handle_request: xdmcp_pending=%d, MaxPending=%d, xdmcp_sessions=%d, MaxSessions=%d, ManufacturerID=%s", + xdmcp_pending, maxpending, xdmcp_sessions, + maxsessions, ve_sure_string (s)); + g_free (s); + } + + /* Check if ok to manage display */ if (mitauth && xdmcp_sessions < maxsessions && - (gdm_is_local_addr (&(((struct sockaddr_in *)clnt_sa)->sin_addr)) || - gdm_xdmcp_displays_from_host (clnt_sa) < dispperhost)) - + (gdm_address_is_local (clnt_sa) || + gdm_xdmcp_displays_from_host (clnt_sa) < dispperhost)) { entered = TRUE; } if (entered) { - GdmHostent *he; + GdmHostent *he; he = gdm_gethostbyaddr (clnt_sa); - /* Check if we are already talking to this host */ - gdm_xdmcp_display_dispose_check (he->hostname, clnt_dspnum); - - if (xdmcp_pending >= maxpending) { - gdm_debug ("gdm_xdmcp_handle_request: maximum pending"); - /* Don't translate, this goes over the wire to servers where we - * don't know the charset or language, so it must be ascii */ - gdm_xdmcp_send_decline (clnt_sa, "Maximum pending servers"); - gdm_hostent_free (he); - } else { - /* the addrs are NOT copied */ - gdm_xdmcp_send_accept (he /* eaten and freed */, clnt_sa, clnt_dspnum); - } + /* Check if we are already talking to this host */ + gdm_xdmcp_display_dispose_check (he->hostname, clnt_dspnum); + + if (xdmcp_pending >= maxpending) { + gdm_debug ("gdm_xdmcp_handle_request: maximum pending"); + /* Don't translate, this goes over the wire to servers where we + * don't know the charset or language, so it must be ascii */ + gdm_xdmcp_send_decline (clnt_sa, "Maximum pending servers"); + gdm_hostent_free (he); + } else { + /* the addrs are NOT copied */ + gdm_xdmcp_send_accept (he /* eaten and freed */, clnt_sa, clnt_dspnum); + } } else { - /* Don't translate, this goes over the wire to servers where we - * don't know the charset or language, so it must be ascii */ - if ( ! mitauth) { - gdm_xdmcp_send_decline (clnt_sa, "Only MIT-MAGIC-COOKIE-1 supported"); - } else if (xdmcp_sessions >= maxsessions) { - gdm_info ("Maximum number of open XDMCP sessions reached"); - gdm_xdmcp_send_decline (clnt_sa, - "Maximum number of open sessions reached"); - } else { -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) - gdm_info ("Maximum number of open XDMCP sessions from host %s reached", - buffer6); - else -#endif - gdm_info ("Maximum number of open XDMCP sessions from host %s reached", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - gdm_xdmcp_send_decline (clnt_sa, - "Maximum number of open sessions from your host reached"); - } - } - - XdmcpDisposeARRAY8 (&clnt_authname); - XdmcpDisposeARRAY8 (&clnt_authdata); - XdmcpDisposeARRAY8 (&clnt_manufacturer); - XdmcpDisposeARRAYofARRAY8 (&clnt_addr); - XdmcpDisposeARRAYofARRAY8 (&clnt_authorization); - XdmcpDisposeARRAY16 (&clnt_conntyp); -} + /* Don't translate, this goes over the wire to servers where we + * don't know the charset or language, so it must be ascii */ + if ( ! mitauth) { + gdm_xdmcp_send_decline (clnt_sa, "Only MIT-MAGIC-COOKIE-1 supported"); + } else if (xdmcp_sessions >= maxsessions) { + gdm_info ("Maximum number of open XDMCP sessions reached"); + gdm_xdmcp_send_decline (clnt_sa, + "Maximum number of open sessions reached"); + } else { + gdm_info ("Maximum number of open XDMCP sessions from host %s reached", + host); + gdm_xdmcp_send_decline (clnt_sa, + "Maximum number of open sessions from your host reached"); + } + } + XdmcpDisposeARRAY8 (&clnt_authname); + XdmcpDisposeARRAY8 (&clnt_authdata); + XdmcpDisposeARRAY8 (&clnt_manufacturer); + XdmcpDisposeARRAYofARRAY8 (&clnt_addr); + XdmcpDisposeARRAYofARRAY8 (&clnt_authorization); + XdmcpDisposeARRAY16 (&clnt_conntyp); +} static void -gdm_xdmcp_send_accept (GdmHostent *he /* eaten and freed */, -#ifdef ENABLE_IPV6 +gdm_xdmcp_send_accept (GdmHostent *he /* eaten and freed */, struct sockaddr_storage *clnt_sa, -#else - struct sockaddr_in *clnt_sa, -#endif - gint displaynum) + gint displaynum) { - XdmcpHeader header; - ARRAY8 authentype; - ARRAY8 authendata; - ARRAY8 authname; - ARRAY8 authdata; - GdmDisplay *d; - - d = gdm_xdmcp_display_alloc (clnt_sa, - he /* eaten and freed */, - displaynum); - - authentype.data = (CARD8 *) 0; - authentype.length = (CARD16) 0; - - authendata.data = (CARD8 *) 0; - authendata.length = (CARD16) 0; - - authname.data = (CARD8 *) "MIT-MAGIC-COOKIE-1"; - authname.length = strlen ((char *) authname.data); - - authdata.data = (CARD8 *) d->bcookie; - authdata.length = 16; - - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16) ACCEPT; - header.length = 4; - header.length += 2 + authentype.length; - header.length += 2 + authendata.length; - header.length += 2 + authname.length; - header.length += 2 + authdata.length; - - XdmcpWriteHeader (&buf, &header); - XdmcpWriteCARD32 (&buf, d->sessionid); - XdmcpWriteARRAY8 (&buf, &authentype); - XdmcpWriteARRAY8 (&buf, &authendata); - XdmcpWriteARRAY8 (&buf, &authname); - XdmcpWriteARRAY8 (&buf, &authdata); -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; + XdmcpHeader header; + ARRAY8 authentype; + ARRAY8 authendata; + ARRAY8 authname; + ARRAY8 authdata; + GdmDisplay *d; + char *host; - XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in6)); + d = gdm_xdmcp_display_alloc (clnt_sa, + he /* eaten and freed */, + displaynum); - gdm_debug ("gdm_xdmcp_send_accept: Sending ACCEPT to %s with SessionID=%ld", - inet_ntop (AF_INET6, - &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, - buffer6, INET6_ADDRSTRLEN), (long)d->sessionid); - } - else -#endif - { - XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in)); + authentype.data = (CARD8 *) 0; + authentype.length = (CARD16) 0; + + authendata.data = (CARD8 *) 0; + authendata.length = (CARD16) 0; + + authname.data = (CARD8 *) "MIT-MAGIC-COOKIE-1"; + authname.length = strlen ((char *) authname.data); + + authdata.data = (CARD8 *) d->bcookie; + authdata.length = 16; + + header.version = XDM_PROTOCOL_VERSION; + header.opcode = (CARD16) ACCEPT; + header.length = 4; + header.length += 2 + authentype.length; + header.length += 2 + authendata.length; + header.length += 2 + authname.length; + header.length += 2 + authdata.length; + + XdmcpWriteHeader (&buf, &header); + XdmcpWriteCARD32 (&buf, d->sessionid); + XdmcpWriteARRAY8 (&buf, &authentype); + XdmcpWriteARRAY8 (&buf, &authendata); + XdmcpWriteARRAY8 (&buf, &authname); + XdmcpWriteARRAY8 (&buf, &authdata); + XdmcpFlush (gdm_xdmcpfd, + &buf, + (XdmcpNetaddr)clnt_sa, + (int)sizeof (struct sockaddr_storage)); + + gdm_address_get_info (clnt_sa, &host, NULL); gdm_debug ("gdm_xdmcp_send_accept: Sending ACCEPT to %s with SessionID=%ld", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr), (long)d->sessionid); - } - + host, + (long)d->sessionid); + g_free (host); } - static void -#ifdef ENABLE_IPV6 -gdm_xdmcp_send_decline (struct sockaddr_storage *clnt_sa, const char *reason) -#else -gdm_xdmcp_send_decline (struct sockaddr_in *clnt_sa, const char *reason) -#endif +gdm_xdmcp_send_decline (struct sockaddr_storage *clnt_sa, + const char *reason) { - XdmcpHeader header; - ARRAY8 authentype; - ARRAY8 authendata; - ARRAY8 status; - GdmForwardQuery *fq; - -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; + XdmcpHeader header; + ARRAY8 authentype; + ARRAY8 authendata; + ARRAY8 status; + GdmForwardQuery *fq; + char *host; + gdm_address_get_info (clnt_sa, &host, NULL); gdm_debug ("gdm_xdmcp_send_decline: Sending DECLINE to %s", - inet_ntop (AF_INET6, - &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, - buffer6, INET6_ADDRSTRLEN)); - } - else -#endif - { - gdm_debug ("gdm_xdmcp_send_decline: Sending DECLINE to %s", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - } - - - authentype.data = (CARD8 *) 0; - authentype.length = (CARD16) 0; - - authendata.data = (CARD8 *) 0; - authendata.length = (CARD16) 0; - - status.data = (CARD8 *) reason; - status.length = strlen ((char *) status.data); - - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16) DECLINE; - header.length = 2 + status.length; - header.length += 2 + authentype.length; - header.length += 2 + authendata.length; - - XdmcpWriteHeader (&buf, &header); - XdmcpWriteARRAY8 (&buf, &status); - XdmcpWriteARRAY8 (&buf, &authentype); - XdmcpWriteARRAY8 (&buf, &authendata); - -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in6)); - } - else -#endif - { - XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in)); - } - - /* Send MANAGED_FORWARD to indicate that the connection - * reached some sort of resolution */ - fq = gdm_forward_query_lookup (clnt_sa); - if (fq != NULL) { - gdm_xdmcp_send_managed_forward (fq->from_sa, clnt_sa); - gdm_forward_query_dispose (fq); - } -} + host); + g_free (host); + authentype.data = (CARD8 *) 0; + authentype.length = (CARD16) 0; -static void -#ifdef ENABLE_IPV6 -gdm_xdmcp_handle_manage (struct sockaddr_storage *clnt_sa, gint len) -#else -gdm_xdmcp_handle_manage (struct sockaddr_in *clnt_sa, gint len) -#endif + authendata.data = (CARD8 *) 0; + authendata.length = (CARD16) 0; + + status.data = (CARD8 *) reason; + status.length = strlen ((char *) status.data); + + header.version = XDM_PROTOCOL_VERSION; + header.opcode = (CARD16) DECLINE; + header.length = 2 + status.length; + header.length += 2 + authentype.length; + header.length += 2 + authendata.length; + + XdmcpWriteHeader (&buf, &header); + XdmcpWriteARRAY8 (&buf, &status); + XdmcpWriteARRAY8 (&buf, &authentype); + XdmcpWriteARRAY8 (&buf, &authendata); + + XdmcpFlush (gdm_xdmcpfd, + &buf, + (XdmcpNetaddr)clnt_sa, + (int)sizeof (struct sockaddr_storage)); + + /* Send MANAGED_FORWARD to indicate that the connection + * reached some sort of resolution */ + fq = gdm_forward_query_lookup (clnt_sa); + if (fq != NULL) { + gdm_xdmcp_send_managed_forward (fq->from_sa, clnt_sa); + gdm_forward_query_dispose (fq); + } +} + +static void +gdm_xdmcp_handle_manage (struct sockaddr_storage *clnt_sa, + gint len) { - CARD32 clnt_sessid; - CARD16 clnt_dspnum; - ARRAY8 clnt_dspclass; - GdmDisplay *d; - GdmIndirectDisplay *id; - GdmForwardQuery *fq; - -#ifdef ENABLE_IPV6 - char buffer6[INET6_ADDRSTRLEN]; + CARD32 clnt_sessid; + CARD16 clnt_dspnum; + ARRAY8 clnt_dspclass; + GdmDisplay *d; + GdmIndirectDisplay *id; + GdmForwardQuery *fq; + char *host; - inet_ntop (AF_INET6, &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, - buffer6, INET6_ADDRSTRLEN); + gdm_address_get_info (clnt_sa, &host, NULL); + gdm_debug ("gdm_xdmcp_handle_manage: Got MANAGE from %s", host); - if (clnt_sa->ss_family == AF_INET6) { - gdm_debug ("gdm_xdmcp_handle_manage: Got MANAGE from %s", buffer6); - } - else -#endif - { - gdm_debug ("gdm_xdmcp_handle_manage: Got MANAGE from %s", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - } - - - /* Check with tcp_wrappers if client is allowed to access */ - if (! gdm_xdmcp_host_allow (clnt_sa)) { -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - gdm_error (_("%s: Got Manage from banned host %s"), - "gdm_xdmcp_handle_manage", - buffer6); + /* Check with tcp_wrappers if client is allowed to access */ + if (! gdm_xdmcp_host_allow (clnt_sa)) { + gdm_error (_("%s: Got Manage from banned host %s"), + "gdm_xdmcp_handle_manage", + host); + g_free (host); + return; } - else -#endif - { - gdm_error (_("%s: Got Manage from banned host %s"), - "gdm_xdmcp_handle_manage", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - } - - return; - } - - /* SessionID */ - if G_UNLIKELY (! XdmcpReadCARD32 (&buf, &clnt_sessid)) { - gdm_error (_("%s: Could not read Session ID"), - "gdm_xdmcp_handle_manage"); - return; - } - - /* Remote display number */ - if G_UNLIKELY (! XdmcpReadCARD16 (&buf, &clnt_dspnum)) { - gdm_error (_("%s: Could not read Display Number"), - "gdm_xdmcp_handle_manage"); - return; - } - - /* Display Class */ - if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_dspclass)) { - gdm_error (_("%s: Could not read Display Class"), - "gdm_xdmcp_handle_manage"); - return; - } - - if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG)) { - char *s = g_strndup ((char *) clnt_dspclass.data, clnt_dspclass.length); + g_free (host); -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) + /* SessionID */ + if G_UNLIKELY (! XdmcpReadCARD32 (&buf, &clnt_sessid)) { + gdm_error (_("%s: Could not read Session ID"), + "gdm_xdmcp_handle_manage"); + return; + } + + /* Remote display number */ + if G_UNLIKELY (! XdmcpReadCARD16 (&buf, &clnt_dspnum)) { + gdm_error (_("%s: Could not read Display Number"), + "gdm_xdmcp_handle_manage"); + return; + } + + /* Display Class */ + if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_dspclass)) { + gdm_error (_("%s: Could not read Display Class"), + "gdm_xdmcp_handle_manage"); + return; + } + + if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG)) { + char *s = g_strndup ((char *) clnt_dspclass.data, clnt_dspclass.length); gdm_debug ("gdm_xdmcp-handle_manage: Got display=%d, SessionID=%ld Class=%s from %s", - (int)clnt_dspnum, (long)clnt_sessid, ve_sure_string (s), buffer6); - else -#endif - gdm_debug ("gdm_xdmcp_handle_manage: Got Display=%d, SessionID=%ld Class=%s from %s", - (int)clnt_dspnum, (long)clnt_sessid, ve_sure_string (s), - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - - g_free (s); - } - - - d = gdm_xdmcp_display_lookup (clnt_sessid); - if (d != NULL && - d->dispstat == XDMCP_PENDING) { - - gdm_debug ("gdm_xdmcp_handle_manage: Looked up %s", d->name); - - if (gdm_daemon_config_get_value_bool (GDM_KEY_INDIRECT)) { - id = gdm_choose_indirect_lookup (clnt_sa); - - /* This was an indirect thingie and nothing was yet chosen, - * use a chooser */ - if (d->dispstat == XDMCP_PENDING && - id != NULL && - id->chosen_host == NULL) { - d->use_chooser = TRUE; - d->indirect_id = id->id; + (int)clnt_dspnum, (long)clnt_sessid, ve_sure_string (s), host); + + g_free (s); + } + + d = gdm_xdmcp_display_lookup (clnt_sessid); + if (d != NULL && + d->dispstat == XDMCP_PENDING) { + + gdm_debug ("gdm_xdmcp_handle_manage: Looked up %s", d->name); + + if (gdm_daemon_config_get_value_bool (GDM_KEY_INDIRECT)) { + id = gdm_choose_indirect_lookup (clnt_sa); + + /* This was an indirect thingie and nothing was yet chosen, + * use a chooser */ + if (d->dispstat == XDMCP_PENDING && + id != NULL && + id->chosen_host == NULL) { + d->use_chooser = TRUE; + d->indirect_id = id->id; + } else { + d->indirect_id = 0; + d->use_chooser = FALSE; + if (id != NULL) + gdm_choose_indirect_dispose (id); + } } else { d->indirect_id = 0; d->use_chooser = FALSE; - if (id != NULL) - gdm_choose_indirect_dispose (id); } - } else { - d->indirect_id = 0; - d->use_chooser = FALSE; - } - /* this was from a forwarded query quite apparently so - * send MANAGED_FORWARD */ - fq = gdm_forward_query_lookup (clnt_sa); - if (fq != NULL) { - gdm_xdmcp_send_managed_forward (fq->from_sa, clnt_sa); - gdm_forward_query_dispose (fq); + /* this was from a forwarded query quite apparently so + * send MANAGED_FORWARD */ + fq = gdm_forward_query_lookup (clnt_sa); + if (fq != NULL) { + gdm_xdmcp_send_managed_forward (fq->from_sa, clnt_sa); + gdm_forward_query_dispose (fq); + } + + d->dispstat = XDMCP_MANAGED; + xdmcp_sessions++; + xdmcp_pending--; + + /* Start greeter/session */ + if G_UNLIKELY (!gdm_display_manage (d)) { + gdm_xdmcp_send_failed (clnt_sa, clnt_sessid); + XdmcpDisposeARRAY8(&clnt_dspclass); + return; + } } - - d->dispstat = XDMCP_MANAGED; - xdmcp_sessions++; - xdmcp_pending--; - - /* Start greeter/session */ - if G_UNLIKELY (!gdm_display_manage (d)) { - gdm_xdmcp_send_failed (clnt_sa, clnt_sessid); - XdmcpDisposeARRAY8(&clnt_dspclass); - return; - } - } - else if G_UNLIKELY (d != NULL && d->dispstat == XDMCP_MANAGED) { - gdm_debug ("gdm_xdmcp_handle_manage: Session id %ld already managed", - (long)clnt_sessid); - } - else { - gdm_debug ("gdm_xdmcp_handle_manage: Failed to look up session id %ld", - (long)clnt_sessid); - gdm_xdmcp_send_refuse (clnt_sa, clnt_sessid); - } - - XdmcpDisposeARRAY8(&clnt_dspclass); + else if G_UNLIKELY (d != NULL && d->dispstat == XDMCP_MANAGED) { + gdm_debug ("gdm_xdmcp_handle_manage: Session id %ld already managed", + (long)clnt_sessid); + } + else { + gdm_debug ("gdm_xdmcp_handle_manage: Failed to look up session id %ld", + (long)clnt_sessid); + gdm_xdmcp_send_refuse (clnt_sa, clnt_sessid); + } + + XdmcpDisposeARRAY8(&clnt_dspclass); } -static void -#ifdef ENABLE_IPV6 -gdm_xdmcp_handle_managed_forward (struct sockaddr_storage *clnt_sa, gint len) -#else -gdm_xdmcp_handle_managed_forward (struct sockaddr_in *clnt_sa, gint len) -#endif +static void +gdm_xdmcp_handle_managed_forward (struct sockaddr_storage *clnt_sa, + gint len) { ARRAY8 clnt_address; GdmIndirectDisplay *id; -#ifdef ENABLE_IPV6 - char buffer6[INET6_ADDRSTRLEN]; - - inet_ntop (AF_INET6, &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, - buffer6, INET6_ADDRSTRLEN); - - if (clnt_sa->ss_family == AF_INET6) { - gdm_debug ("gdm_xdmcp_handle_managed_forward: " - "Got MANAGED_FORWARD from %s", - buffer6); - /* Check with tcp_wrappers if client is allowed to access */ - if (! gdm_xdmcp_host_allow (clnt_sa)) { - gdm_error ("%s: Got MANAGED_FORWARD from banned host %s", - "gdm_xdmcp_handle_request", buffer6); - return; - } - } - else -#endif - { - gdm_debug ("gdm_xdmcp_handle_managed_forward: " - "Got MANAGED_FORWARD from %s", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); + char *host; + struct sockaddr_storage *disp_sa; - /* Check with tcp_wrappers if client is allowed to access */ - if (! gdm_xdmcp_host_allow (clnt_sa)) { - gdm_error ("%s: Got MANAGED_FORWARD from banned host %s", - "gdm_xdmcp_handle_request", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - return; - } + gdm_address_get_info (clnt_sa, &host, NULL); + gdm_debug ("gdm_xdmcp_handle_managed_forward: Got MANAGED_FORWARD from %s", + host); + + /* Check with tcp_wrappers if client is allowed to access */ + if (! gdm_xdmcp_host_allow (clnt_sa)) { + gdm_error ("%s: Got MANAGED_FORWARD from banned host %s", + "gdm_xdmcp_handle_request", host); + g_free (host); + return; } + g_free (host); /* Hostname */ if G_UNLIKELY ( ! XdmcpReadARRAY8 (&buf, &clnt_address)) { @@ -2303,67 +1928,37 @@ gdm_xdmcp_handle_managed_forward (struct sockaddr_in *clnt_sa, gint len) "gdm_xdmcp_handle_managed_forward"); return; } -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - if (clnt_address.length != sizeof (struct in6_addr)) { - gdm_error (_("%s: Could not read address"), - "gdm_xdmcp_handle_managed_forward"); - XdmcpDisposeARRAY8 (&clnt_address); - return; - } - - id = gdm_choose_indirect_lookup_by_chosen6 (&(((struct sockaddr_in6 *)clnt_sa)->sin6_addr), (struct in6_addr *)clnt_address.data); - } - else -#endif - { - if (clnt_address.length != sizeof (struct in_addr)) { - gdm_error (_("%s: Could not read address"), - "gdm_xdmcp_handle_managed_forward"); - XdmcpDisposeARRAY8 (&clnt_address); - return; - } - id = gdm_choose_indirect_lookup_by_chosen - (&(((struct sockaddr_in *)clnt_sa)->sin_addr), (struct in_addr *)clnt_address.data); + disp_sa = NULL; + if (! create_sa_from_request (&clnt_address, NULL, clnt_sa->ss_family, &disp_sa)) { + gdm_error ("Unable to parse address for request"); + XdmcpDisposeARRAY8 (&clnt_address); + return; } + id = gdm_choose_indirect_lookup_by_chosen (clnt_sa, disp_sa); if (id != NULL) { gdm_choose_indirect_dispose (id); } /* Note: we send GOT even on not found, just in case our previous * didn't get through and this was a second managed forward */ -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - gdm_xdmcp_send_got_managed_forward6 ((struct sockaddr_in6 *)clnt_sa, - (struct in6_addr *)clnt_address.data); - } - else -#endif - { - gdm_xdmcp_send_got_managed_forward ((struct sockaddr_in *)clnt_sa, - (struct in_addr *)clnt_address.data); - } + gdm_xdmcp_send_got_managed_forward (clnt_sa, disp_sa); XdmcpDisposeARRAY8 (&clnt_address); } -#ifdef ENABLE_IPV6 static void -gdm_xdmcp_whack_queued_managed_forwards6 (struct sockaddr_in6 *clnt_sa, - struct in6_addr *origin) +gdm_xdmcp_whack_queued_managed_forwards (struct sockaddr_storage *clnt_sa, + struct sockaddr_storage *origin) { GSList *li; for (li = managed_forwards; li != NULL; li = li->next) { ManagedForward *mf = li->data; - if ((memcmp (((struct sockaddr_in6 *)(&(mf->manager)))->sin6_addr.s6_addr, - (clnt_sa->sin6_addr.s6_addr), sizeof (struct in6_addr)) == 0) && - (memcmp (((struct sockaddr_in6 *)(&(mf->origin)))->sin6_addr.s6_addr, - origin->s6_addr, sizeof (struct in6_addr)) == 0)) { - + if (gdm_address_equal (&mf->manager, clnt_sa) && + gdm_address_equal (&mf->origin, origin)) { managed_forwards = g_slist_remove_link (managed_forwards, li); g_slist_free_1 (li); g_source_remove (mf->handler); @@ -2372,67 +1967,26 @@ gdm_xdmcp_whack_queued_managed_forwards6 (struct sockaddr_in6 *clnt_sa, } } } -#endif static void -gdm_xdmcp_whack_queued_managed_forwards (struct sockaddr_in *clnt_sa, - struct in_addr *origin) -{ - GSList *li; - - for (li = managed_forwards; li != NULL; li = li->next) { - ManagedForward *mf = li->data; - if (((struct sockaddr_in *)(&mf->manager))->sin_addr.s_addr == clnt_sa->sin_addr.s_addr && - ((struct sockaddr_in *)(&mf->origin))->sin_addr.s_addr == origin->s_addr) { - - managed_forwards = g_slist_remove_link (managed_forwards, li); - g_slist_free_1 (li); - g_source_remove (mf->handler); - /* mf freed by glib */ - return; - } - } -} - -static void -#ifdef ENABLE_IPV6 -gdm_xdmcp_handle_got_managed_forward (struct sockaddr_storage *clnt_sa, gint len) -#else -gdm_xdmcp_handle_got_managed_forward (struct sockaddr_in *clnt_sa, gint len) -#endif +gdm_xdmcp_handle_got_managed_forward (struct sockaddr_storage *clnt_sa, + gint len) { + struct sockaddr_storage *disp_sa; ARRAY8 clnt_address; + char *host; -#ifdef ENABLE_IPV6 - char buffer6[INET6_ADDRSTRLEN]; - - if (clnt_sa->ss_family == AF_INET6) { - gdm_debug ("gdm_xdmcp_handle_got_managed_forward: " - "Got MANAGED_FORWARD from %s", - inet_ntop (AF_INET6, - &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, - buffer6, INET6_ADDRSTRLEN)); - if (! gdm_xdmcp_host_allow (clnt_sa)) { - gdm_error ("%s: Got GOT_MANAGED_FORWARD from banned host %s", - "gdm_xdmcp_handle_request", buffer6); - return; - } - } - else -#endif - { - gdm_debug ("gdm_xdmcp_handle_got_managed_forward: " - "Got MANAGED_FORWARD from %s", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); + gdm_address_get_info (clnt_sa, &host, NULL); + gdm_debug ("gdm_xdmcp_handle_got_managed_forward: Got MANAGED_FORWARD from %s", + host); - /* Check with tcp_wrappers if client is allowed to access */ - if (! gdm_xdmcp_host_allow (clnt_sa)) { - gdm_error ("%s: Got GOT_MANAGED_FORWARD from banned host %s", - "gdm_xdmcp_handle_request", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - return; - } + if (! gdm_xdmcp_host_allow (clnt_sa)) { + gdm_error ("%s: Got GOT_MANAGED_FORWARD from banned host %s", + "gdm_xdmcp_handle_request", host); + g_free (host); + return; } + g_free (host); /* Hostname */ if G_UNLIKELY ( ! XdmcpReadARRAY8 (&buf, &clnt_address)) { @@ -2440,429 +1994,332 @@ gdm_xdmcp_handle_got_managed_forward (struct sockaddr_in *clnt_sa, gint len) "gdm_xdmcp_handle_got_managed_forward"); return; } -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - if (clnt_address.length != sizeof (struct in6_addr)) { - gdm_error (_("%s: Could not read address"), - "gdm_xdmcp_handle_got_managed_forward"); - XdmcpDisposeARRAY8 (&clnt_address); - return; - } - gdm_xdmcp_whack_queued_managed_forwards6 ((struct sockaddr_in6 *)clnt_sa, - (struct in6_addr *)clnt_address.data); - } - else -#endif - { - if (clnt_address.length != sizeof (struct in_addr)) { - gdm_error (_("%s: Could not read address"), - "gdm_xdmcp_handle_got_managed_forward"); - XdmcpDisposeARRAY8 (&clnt_address); - return; - } - gdm_xdmcp_whack_queued_managed_forwards ((struct sockaddr_in *)clnt_sa, - (struct in_addr *)clnt_address.data); + if (! create_sa_from_request (&clnt_address, NULL, clnt_sa->ss_family, &disp_sa)) { + gdm_error (_("%s: Could not read address"), + "gdm_xdmcp_handle_got_managed_forward"); + XdmcpDisposeARRAY8 (&clnt_address); + return; } + gdm_xdmcp_whack_queued_managed_forwards (clnt_sa, disp_sa); + XdmcpDisposeARRAY8 (&clnt_address); } - static void -#ifdef ENABLE_IPV6 -gdm_xdmcp_send_refuse (struct sockaddr_storage *clnt_sa, CARD32 sessid) -#else -gdm_xdmcp_send_refuse (struct sockaddr_in *clnt_sa, CARD32 sessid) -#endif +gdm_xdmcp_send_refuse (struct sockaddr_storage *clnt_sa, + CARD32 sessid) { - XdmcpHeader header; - GdmForwardQuery *fq; - - gdm_debug ("gdm_xdmcp_send_refuse: Sending REFUSE to %ld", - (long)sessid); - - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16) REFUSE; - header.length = 4; - - XdmcpWriteHeader (&buf, &header); - XdmcpWriteCARD32 (&buf, sessid); + XdmcpHeader header; + GdmForwardQuery *fq; -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in6)); - } - else -#endif - { - XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in)); - } - - /* - * This was from a forwarded query quite apparently so - * send MANAGED_FORWARD - */ - fq = gdm_forward_query_lookup (clnt_sa); - if (fq != NULL) { - gdm_xdmcp_send_managed_forward (fq->from_sa, clnt_sa); - gdm_forward_query_dispose (fq); - } -} + gdm_debug ("gdm_xdmcp_send_refuse: Sending REFUSE to %ld", + (long)sessid); + header.version = XDM_PROTOCOL_VERSION; + header.opcode = (CARD16) REFUSE; + header.length = 4; + + XdmcpWriteHeader (&buf, &header); + XdmcpWriteCARD32 (&buf, sessid); + + XdmcpFlush (gdm_xdmcpfd, + &buf, + (XdmcpNetaddr)clnt_sa, + (int)sizeof (struct sockaddr_storage)); + + /* + * This was from a forwarded query quite apparently so + * send MANAGED_FORWARD + */ + fq = gdm_forward_query_lookup (clnt_sa); + if (fq != NULL) { + gdm_xdmcp_send_managed_forward (fq->from_sa, clnt_sa); + gdm_forward_query_dispose (fq); + } +} static void -#ifdef ENABLE_IPV6 gdm_xdmcp_send_failed (struct sockaddr_storage *clnt_sa, CARD32 sessid) -#else -gdm_xdmcp_send_failed (struct sockaddr_in *clnt_sa, CARD32 sessid) -#endif { - XdmcpHeader header; - ARRAY8 status; - - gdm_debug ("gdm_xdmcp_send_failed: Sending FAILED to %ld", (long)sessid); - - /* - * Don't translate, this goes over the wire to servers where we - * don't know the charset or language, so it must be ascii - */ - status.data = (CARD8 *) "Failed to start session"; - status.length = strlen ((char *) status.data); - - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16) FAILED; - header.length = 6+status.length; - - XdmcpWriteHeader (&buf, &header); - XdmcpWriteCARD32 (&buf, sessid); - XdmcpWriteARRAY8 (&buf, &status); + XdmcpHeader header; + ARRAY8 status; -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in6)); - } - else -#endif - { - XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in)); - } + gdm_debug ("gdm_xdmcp_send_failed: Sending FAILED to %ld", (long)sessid); + + /* + * Don't translate, this goes over the wire to servers where we + * don't know the charset or language, so it must be ascii + */ + status.data = (CARD8 *) "Failed to start session"; + status.length = strlen ((char *) status.data); + + header.version = XDM_PROTOCOL_VERSION; + header.opcode = (CARD16) FAILED; + header.length = 6+status.length; + + XdmcpWriteHeader (&buf, &header); + XdmcpWriteCARD32 (&buf, sessid); + XdmcpWriteARRAY8 (&buf, &status); + + XdmcpFlush (gdm_xdmcpfd, + &buf, + (XdmcpNetaddr)clnt_sa, + (int)sizeof (struct sockaddr_storage)); } static void -#ifdef ENABLE_IPV6 -gdm_xdmcp_handle_keepalive (struct sockaddr_storage *clnt_sa, gint len) -#else -gdm_xdmcp_handle_keepalive (struct sockaddr_in *clnt_sa, gint len) -#endif +gdm_xdmcp_handle_keepalive (struct sockaddr_storage *clnt_sa, + gint len) { - CARD16 clnt_dspnum; - CARD32 clnt_sessid; - -#ifdef ENABLE_IPV6 - char buffer6[INET6_ADDRSTRLEN]; + CARD16 clnt_dspnum; + CARD32 clnt_sessid; + char *host; - if (clnt_sa->ss_family == AF_INET6) { + gdm_address_get_info (clnt_sa, &host, NULL); gdm_debug ("gdm_xdmcp_handle_keepalive: Got KEEPALIVE from %s", - inet_ntop (AF_INET6, - &(((struct sockaddr_in6 *)clnt_sa)->sin6_addr), -buffer6, INET6_ADDRSTRLEN)); + host); /* Check with tcp_wrappers if client is allowed to access */ if (! gdm_xdmcp_host_allow (clnt_sa)) { gdm_error (_("%s: Got KEEPALIVE from banned host %s"), - "gdm_xdmcp_handle_keepalive", buffer6); + "gdm_xdmcp_handle_keepalive", + host); + g_free (host); return; + } + g_free (host); + /* Remote display number */ + if G_UNLIKELY (! XdmcpReadCARD16 (&buf, &clnt_dspnum)) { + gdm_error (_("%s: Could not read Display Number"), + "gdm_xdmcp_handle_keepalive"); + return; } - } - else -#endif - { - gdm_debug ("gdm_xdmcp_handle_keepalive: Got KEEPALIVE from %s", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); - /* Check with tcp_wrappers if client is allowed to access */ - if (! gdm_xdmcp_host_allow (clnt_sa)) { - gdm_error (_("%s: Got KEEPALIVE from banned host %s"), - "gdm_xdmcp_handle_keepalive", - inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr)); + /* SessionID */ + if G_UNLIKELY (! XdmcpReadCARD32 (&buf, &clnt_sessid)) { + gdm_error (_("%s: Could not read Session ID"), + "gdm_xdmcp_handle_keepalive"); return; } - } - - /* Remote display number */ - if G_UNLIKELY (! XdmcpReadCARD16 (&buf, &clnt_dspnum)) { - gdm_error (_("%s: Could not read Display Number"), - "gdm_xdmcp_handle_keepalive"); - return; - } - - /* SessionID */ - if G_UNLIKELY (! XdmcpReadCARD32 (&buf, &clnt_sessid)) { - gdm_error (_("%s: Could not read Session ID"), - "gdm_xdmcp_handle_keepalive"); - return; - } - - gdm_xdmcp_send_alive (clnt_sa, clnt_dspnum, clnt_sessid); -} + gdm_xdmcp_send_alive (clnt_sa, clnt_dspnum, clnt_sessid); +} static void -#ifdef ENABLE_IPV6 gdm_xdmcp_send_alive (struct sockaddr_storage *clnt_sa, - CARD16 dspnum, CARD32 sessid) -#else -gdm_xdmcp_send_alive (struct sockaddr_in *clnt_sa, - CARD16 dspnum, CARD32 sessid) -#endif + CARD16 dspnum, + CARD32 sessid) { - XdmcpHeader header; - GdmDisplay *d; - int send_running = 0; - CARD32 send_sessid = 0; - - d = gdm_xdmcp_display_lookup (sessid); - if (d == NULL) - d = gdm_xdmcp_display_lookup_by_host (clnt_sa, dspnum); - - if (d != NULL) { - send_sessid = d->sessionid; - if (d->dispstat == XDMCP_MANAGED) - send_running = 1; - } - - gdm_debug ("Sending ALIVE to %ld (running %d, sessid %ld)", - (long)sessid, send_running, (long)send_sessid); - - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16) ALIVE; - header.length = 5; - - XdmcpWriteHeader (&buf, &header); - XdmcpWriteCARD8 (&buf, send_running); - XdmcpWriteCARD32 (&buf, send_sessid); -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in6)); - } - else -#endif - { - XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, - (int)sizeof (struct sockaddr_in)); - } -} + XdmcpHeader header; + GdmDisplay *d; + int send_running = 0; + CARD32 send_sessid = 0; + + d = gdm_xdmcp_display_lookup (sessid); + if (d == NULL) + d = gdm_xdmcp_display_lookup_by_host (clnt_sa, dspnum); + + if (d != NULL) { + send_sessid = d->sessionid; + if (d->dispstat == XDMCP_MANAGED) + send_running = 1; + } + + gdm_debug ("Sending ALIVE to %ld (running %d, sessid %ld)", + (long)sessid, send_running, (long)send_sessid); + + header.version = XDM_PROTOCOL_VERSION; + header.opcode = (CARD16) ALIVE; + header.length = 5; + + XdmcpWriteHeader (&buf, &header); + XdmcpWriteCARD8 (&buf, send_running); + XdmcpWriteCARD32 (&buf, send_sessid); + XdmcpFlush (gdm_xdmcpfd, + &buf, + (XdmcpNetaddr)clnt_sa, + (int)sizeof (struct sockaddr_storage)); +} static gboolean -gdm_xdmcp_host_allow ( -#ifdef ENABLE_IPV6 - struct sockaddr_storage *clnt_sa -#else - struct sockaddr_in *clnt_sa -#endif - ) +gdm_xdmcp_host_allow (struct sockaddr_storage *clnt_sa) { #ifdef HAVE_TCPWRAPPERS - - /* - * Avoids a warning, my tcpd.h file doesn't include this prototype, even - * though the library does include the function and the manpage mentions it - */ - extern int hosts_ctl (char *daemon, char *client_name, - char *client_addr, char *client_user); - - GdmHostent *client_he; - char *client; - gboolean ret; - - /* Find client hostname */ - client_he = gdm_gethostbyaddr (clnt_sa); - - if (client_he->not_found) { - client = "unknown"; - } else { - gdm_debug ("gdm_xdmcp_host_allow: client->hostname is %s\n", + + /* + * Avoids a warning, my tcpd.h file doesn't include this prototype, even + * though the library does include the function and the manpage mentions it + */ + extern int hosts_ctl (char *daemon, + char *client_name, + char *client_addr, + char *client_user); + + GdmHostent *client_he; + char *client; + gboolean ret; + char *host; + + /* Find client hostname */ + client_he = gdm_gethostbyaddr (clnt_sa); + + if (client_he->not_found) { + client = "unknown"; + } else { + gdm_debug ("gdm_xdmcp_host_allow: client->hostname is %s\n", client_he->hostname); - client = client_he->hostname; - } + client = client_he->hostname; + } - /* Check with tcp_wrappers if client is allowed to access */ -#ifdef ENABLE_IPV6 - if (clnt_sa->ss_family == AF_INET6) { - char buffer6[INET6_ADDRSTRLEN]; - - ret = (hosts_ctl ("gdm", client, - (char *) inet_ntop (AF_INET6, - &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, - buffer6, INET6_ADDRSTRLEN), "")); - } else -#endif - { - ret = (hosts_ctl ("gdm", client, inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr), "")); - } + /* Check with tcp_wrappers if client is allowed to access */ + host = NULL; + gdm_address_get_info (clnt_sa, &host, NULL); + ret = hosts_ctl ("gdm", client, host, ""); + g_free (host); - gdm_hostent_free (client_he); + gdm_hostent_free (client_he); - return ret; + return ret; #else /* HAVE_TCPWRAPPERS */ - return (TRUE); + return (TRUE); #endif /* HAVE_TCPWRAPPERS */ } - static GdmDisplay * -gdm_xdmcp_display_alloc ( -#ifdef ENABLE_IPV6 - struct sockaddr_storage *addr, -#else - struct sockaddr_in *addr, -#endif +gdm_xdmcp_display_alloc (struct sockaddr_storage *addr, GdmHostent *he /* eaten and freed */, int displaynum) { - GdmDisplay *d = NULL; - const char *proxycmd = gdm_daemon_config_get_value_string (GDM_KEY_XDMCP_PROXY_XSERVER); - - d = g_new0 (GdmDisplay, 1); - - if (gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP_PROXY) && proxycmd != NULL) { - d->type = TYPE_XDMCP_PROXY; - d->command = g_strdup (proxycmd); - gdm_debug ("Using proxy server for XDMCP: %s\n", d->command); - } else { - d->type = TYPE_XDMCP; - } - - d->logout_action = GDM_LOGOUT_ACTION_NONE; - d->authfile = NULL; - d->auths = NULL; - d->userauth = NULL; - d->greetpid = 0; - d->servpid = 0; - d->servstat = 0; - d->sesspid = 0; - d->slavepid = 0; - d->attached = FALSE; - d->dispstat = XDMCP_PENDING; - d->sessionid = globsessid++; - - if (d->sessionid == 0) - d->sessionid = globsessid++; - - d->acctime = time (NULL); - d->dispnum = displaynum; - d->xdmcp_dispnum = displaynum; - - d->handled = TRUE; - d->tcp_disallowed = FALSE; - d->vt = -1; - d->x_servers_order = -1; - d->logged_in = FALSE; - d->login = NULL; - d->sleep_before_run = 0; - - if (gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN) && - ! ve_string_empty (gdm_daemon_config_get_value_string (GDM_KEY_TIMED_LOGIN))) { - d->timed_login_ok = TRUE; - } else { - d->timed_login_ok = FALSE; - } - - d->name = g_strdup_printf ("%s:%d", he->hostname, - displaynum); -#ifdef ENABLE_IPV6 - if (addr->ss_family == AF_INET6) { - memcpy (&d->addr6, - &((struct sockaddr_in6 *)addr)->sin6_addr, - sizeof (struct in6_addr)); - d->addrtype = AF_INET6; - } - else -#endif - { - memcpy (&d->addr, - &((struct sockaddr_in *)addr)->sin_addr, - sizeof (struct in_addr)); - d->addrtype = AF_INET; - } - - d->hostname = he->hostname; - he->hostname = NULL; - d->addrs = he->addrs; - he->addrs = NULL; - d->addr_count = he->addr_count; - he->addr_count = 0; - - gdm_hostent_free (he); - - d->slave_notify_fd = -1; - d->master_notify_fd = -1; - d->xsession_errors_bytes = 0; - d->xsession_errors_fd = -1; - d->session_output_fd = -1; - d->chooser_output_fd = -1; - d->chooser_last_line = NULL; - d->theme_name = NULL; - - /* Secure display with cookie */ - if G_UNLIKELY (! gdm_auth_secure_display (d)) - gdm_error ("gdm_xdmcp_display_alloc: Error setting up cookies for %s", - d->name); - - if (d->type == TYPE_XDMCP_PROXY) { - d->parent_disp = d->name; - d->name = g_strdup (":-1"); - d->dispnum = -1; - d->server_uid = gdm_daemon_config_get_gdmuid (); - d->parent_auth_file = d->authfile; - d->authfile = NULL; - } - - displays = g_slist_append (displays, d); - - xdmcp_pending++; - - gdm_debug ("gdm_xdmcp_display_alloc: display=%s, session id=%ld, xdmcp_pending=%d", - d->name, (long)d->sessionid, xdmcp_pending); - - return d; -} + GdmDisplay *d = NULL; + const char *proxycmd = gdm_daemon_config_get_value_string (GDM_KEY_XDMCP_PROXY_XSERVER); + + d = g_new0 (GdmDisplay, 1); + + if (gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP_PROXY) && proxycmd != NULL) { + d->type = TYPE_XDMCP_PROXY; + d->command = g_strdup (proxycmd); + gdm_debug ("Using proxy server for XDMCP: %s\n", d->command); + } else { + d->type = TYPE_XDMCP; + } + + d->logout_action = GDM_LOGOUT_ACTION_NONE; + d->authfile = NULL; + d->auths = NULL; + d->userauth = NULL; + d->greetpid = 0; + d->servpid = 0; + d->servstat = 0; + d->sesspid = 0; + d->slavepid = 0; + d->attached = FALSE; + d->dispstat = XDMCP_PENDING; + d->sessionid = globsessid++; + + if (d->sessionid == 0) { + d->sessionid = globsessid++; + } + + d->acctime = time (NULL); + d->dispnum = displaynum; + d->xdmcp_dispnum = displaynum; + + d->handled = TRUE; + d->tcp_disallowed = FALSE; + d->vt = -1; + d->x_servers_order = -1; + d->logged_in = FALSE; + d->login = NULL; + d->sleep_before_run = 0; + + if (gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN) && + ! ve_string_empty (gdm_daemon_config_get_value_string (GDM_KEY_TIMED_LOGIN))) { + d->timed_login_ok = TRUE; + } else { + d->timed_login_ok = FALSE; + } + + d->name = g_strdup_printf ("%s:%d", + he->hostname, + displaynum); + + memcpy (&d->addr, addr, sizeof (struct sockaddr_storage)); + + d->hostname = he->hostname; + he->hostname = NULL; + d->addrs = he->addrs; + he->addrs = NULL; + d->addr_count = he->addr_count; + he->addr_count = 0; + + gdm_hostent_free (he); + + d->slave_notify_fd = -1; + d->master_notify_fd = -1; + d->xsession_errors_bytes = 0; + d->xsession_errors_fd = -1; + d->session_output_fd = -1; + d->chooser_output_fd = -1; + d->chooser_last_line = NULL; + d->theme_name = NULL; + + /* Secure display with cookie */ + if G_UNLIKELY (! gdm_auth_secure_display (d)) { + gdm_error ("gdm_xdmcp_display_alloc: Error setting up cookies for %s", + d->name); + } + + if (d->type == TYPE_XDMCP_PROXY) { + d->parent_disp = d->name; + d->name = g_strdup (":-1"); + d->dispnum = -1; + d->server_uid = gdm_daemon_config_get_gdmuid (); + d->parent_auth_file = d->authfile; + d->authfile = NULL; + } + + gdm_daemon_config_display_list_append (d); + xdmcp_pending++; + + gdm_debug ("gdm_xdmcp_display_alloc: display=%s, session id=%ld, xdmcp_pending=%d", + d->name, (long)d->sessionid, xdmcp_pending); + + return d; +} static GdmDisplay * gdm_xdmcp_display_lookup (CARD32 sessid) { - GSList *dlist = displays; - GdmDisplay *d; - - if (!sessid) - return (NULL); + GSList *dlist = gdm_daemon_config_get_display_list (); + GdmDisplay *d; - while (dlist) { - d = (GdmDisplay *) dlist->data; - - if (d && d->sessionid == sessid) - return (d); - - dlist = dlist->next; - } - - return (NULL); -} + if (!sessid) + return (NULL); + + while (dlist) { + d = (GdmDisplay *) dlist->data; + if (d && d->sessionid == sessid) + return (d); + + dlist = dlist->next; + } + + return (NULL); +} static void gdm_xdmcp_display_dispose_check (const gchar *hostname, int dspnum) { GSList *dlist; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); if (hostname == NULL) return; @@ -2891,11 +2348,14 @@ gdm_xdmcp_display_dispose_check (const gchar *hostname, int dspnum) } } -static void +static void gdm_xdmcp_displays_check (void) { GSList *dlist; time_t curtime = time (NULL); + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); dlist = displays; while (dlist != NULL) { @@ -3003,4 +2463,24 @@ gdm_xdmcp_migrate (GdmDisplay *from, GdmDisplay *to) #endif /* HAVE_LIBXDMCP */ -/* EOF */ +void +gdm_xdmcp_recount_sessions (void) +{ + GSList *li; + GSList *displays; + + displays = gdm_daemon_config_get_display_list (); + + xdmcp_sessions = 0; + xdmcp_pending = 0; + + for (li = displays; li != NULL; li = li->next) { + GdmDisplay *d = li->data; + if (SERVER_IS_XDMCP (d)) { + if (d->dispstat == XDMCP_MANAGED) + xdmcp_sessions++; + else if (d->dispstat == XDMCP_PENDING) + xdmcp_pending++; + } + } +} diff --git a/daemon/xdmcp.h b/daemon/xdmcp.h index ac0b8a65..7121dd21 100644 --- a/daemon/xdmcp.h +++ b/daemon/xdmcp.h @@ -1,4 +1,6 @@ -/* GDM - The GNOME Display Manager +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * 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 @@ -28,11 +30,54 @@ #include "gdm.h" #endif /* HAVE_LIBXDMCP */ +/* NOTE: Timeout and max are hardcoded */ +typedef struct _GdmForwardQuery GdmForwardQuery; +struct _GdmForwardQuery { + time_t acctime; + struct sockaddr_storage *dsp_sa; + struct sockaddr_storage *from_sa; +}; + +#define GDM_MAX_FORWARD_QUERIES 10 +#define GDM_FORWARD_QUERY_TIMEOUT 30 + +/* some extra XDMCP opcodes that xdm will happily ignore since they'll be + * the wrong XDMCP version anyway */ +#define GDM_XDMCP_PROTOCOL_VERSION 1001 +enum { + GDM_XDMCP_FIRST_OPCODE = 1000, /*just a marker, not an opcode */ + + GDM_XDMCP_MANAGED_FORWARD = 1000, + /* manager (master) -> manager + * A packet with MANAGED_FORWARD is sent to the + * manager that sent the forward query from the manager to + * which forward query was sent. It indicates that the forward + * was fully processed and that the client now has either + * a managed session, or has been sent denial, refuse or failed. + * (if the denial gets lost then client gets dumped into the + * chooser again). This should be resent a few times + * until some (short) timeout or until GOT_MANAGED_FORWARD + * is sent. GDM sends at most 3 packates with 1.5 seconds + * between each. + * + * Argument is ARRAY8 with the address of the originating host */ + GDM_XDMCP_GOT_MANAGED_FORWARD, + /* manager -> manager (master) + * A single packet with GOT_MANAGED_FORWARD is sent to indicate + * that we did receive the MANAGED_FORWARD packet. The argument + * must match the MANAGED_FORWARD one or it will just be ignored. + * + * Argument is ARRAY8 with the address of the originating host */ + GDM_XDMCP_LAST_OPCODE /*just a marker, not an opcode */ +}; + /* Note that these are defined as empty stubs if there is no XDMCP support */ gboolean gdm_xdmcp_init (void); void gdm_xdmcp_run (void); void gdm_xdmcp_close (void); +void gdm_xdmcp_recount_sessions (void); + void gdm_xdmcp_migrate (GdmDisplay *from, GdmDisplay *to); #ifdef HAVE_LIBXDMCP diff --git a/gui/Makefile.am b/gui/Makefile.am index 25413f7b..d0229359 100644 --- a/gui/Makefile.am +++ b/gui/Makefile.am @@ -81,12 +81,14 @@ libgdmcommon_a_SOURCES = \ gdmconfig.c \ gdmconfig.h \ gdmcommon.c \ - gdmcommon.h + gdmcommon.h \ + $(NULL) gdmchooser_SOURCES = \ gdmchooser.c \ misc.c \ - misc.h + misc.h \ + $(NULL) gdmlogin_SOURCES = \ gdmlogin.c @@ -112,7 +114,7 @@ gdmchooser_LDADD = \ $(X_LIBS) \ $(XDMCP_LIBS) \ -lX11 \ - -lpopt + $(NULL) gdmlogin_LDADD = \ libgdmwm.a \ @@ -128,7 +130,8 @@ gdmlogin_LDADD = \ $(X_EXTRA_LIBS) \ $(XINERAMA_LIBS) \ $(X_LIBS) \ - -lX11 + -lX11 \ + $(NULL) # LIBGNOMEUI should be removed from gdmsetup at some point. # It is needed because it uses gnome_help_display_uri(), which @@ -150,7 +153,8 @@ gdmsetup_LDADD = \ $(top_builddir)/common/libgdmcommon.a \ $(X_LIBS) \ -lXau \ - -lX11 + -lX11 \ + $(NULL) gdmphotosetup_LDADD = \ libgdmcommon.a \ @@ -177,7 +181,7 @@ gdmXnestchooser_LDADD = \ $(X_LIBS) \ -lXau \ -lX11 \ - -lpopt + $(NULL) gdmflexiserver_LDADD = \ libgdmcommon.a \ @@ -191,7 +195,7 @@ gdmflexiserver_LDADD = \ $(X_LIBS) \ -lX11 \ -lXau \ - -lpopt + $(NULL) gdmdynamic_LDADD = \ libgdmcommon.a \ @@ -204,7 +208,8 @@ gdmdynamic_LDADD = \ $(EXTRA_DYNAMIC_LIBS) \ $(X_LIBS) \ -lX11 \ - -lXau + -lXau \ + $(NULL) Settingsdir = $(datadir)/applications Settings_files = gdmphotosetup.desktop diff --git a/gui/gdmXnestchooser.c b/gui/gdmXnestchooser.c index c192aafb..cc5afecc 100644 --- a/gui/gdmXnestchooser.c +++ b/gui/gdmXnestchooser.c @@ -35,6 +35,8 @@ #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> + +#include <X11/Xlib.h> #include <X11/Xauth.h> #include "gdm.h" diff --git a/gui/gdmchooser.c b/gui/gdmchooser.c index e705ca0e..6defeb30 100644 --- a/gui/gdmchooser.c +++ b/gui/gdmchooser.c @@ -29,7 +29,6 @@ #include <dirent.h> #include <string.h> #include <unistd.h> -#include <syslog.h> #include <ctype.h> #include <fcntl.h> #include <signal.h> @@ -72,15 +71,15 @@ enum { typedef struct _GdmChooserHost GdmChooserHost; struct _GdmChooserHost { - gchar *name; - gchar *desc; + gchar *name; + gchar *desc; #ifdef ENABLE_IPV6 - struct in6_addr ia6; + struct in6_addr ia6; #endif - struct in_addr ia; - gint addrtype; /* Address stored is IPv4 or IPv6 */ - GdkPixbuf *picture; - gboolean willing; + struct in_addr ia; + gint addrtype; /* Address stored is IPv4 or IPv6 */ + GdkPixbuf *picture; + gboolean willing; }; @@ -110,7 +109,7 @@ void display_chooser_information (void); static guint add_check_handler = 0; /* if this is received, select that host automatically */ -#ifdef ENABLE_IPV6 +#ifdef ENABLE_IPV6 static struct in6_addr *added6_addr = NULL; #endif static struct in_addr *added_addr = NULL; @@ -132,13 +131,13 @@ int XdmcpReallocARRAY8 (ARRAY8Ptr array, int length); typedef struct _XdmAuth { - ARRAY8 authentication; - ARRAY8 authorization; + ARRAY8 authentication; + ARRAY8 authorization; } XdmAuthRec, *XdmAuthPtr; static XdmAuthRec authlist = { - { (CARD16) 0, (CARD8 *) 0 }, - { (CARD16) 0, (CARD8 *) 0 } + { (CARD16) 0, (CARD8 *) 0 }, + { (CARD16) 0, (CARD8 *) 0 } }; @@ -186,171 +185,172 @@ find_host_in_list (GdmChooserHost *host, GtkTreeIter *iter) static void gdm_chooser_host_dispose (GdmChooserHost *host) { - if (!host) - return; - - if (host->picture != NULL) - g_object_unref (G_OBJECT (host->picture)); - host->picture = NULL; - - g_free (host->name); - host->name = NULL; - g_free (host->desc); - host->desc = NULL; - g_free (host); + if (!host) + return; + + if (host->picture != NULL) + g_object_unref (G_OBJECT (host->picture)); + host->picture = NULL; + + g_free (host->name); + host->name = NULL; + g_free (host->desc); + host->desc = NULL; + g_free (host); } -static GdmChooserHost * +static GdmChooserHost * gdm_chooser_host_alloc (const char *hostname, const char *description, char *ia, int family, gboolean willing) { - GdmChooserHost *host; - GdkPixbuf *img; - gchar *hostimg; - gchar *hostimgdir; - - host = g_new0 (GdmChooserHost, 1); - host->name = g_strdup (hostname); - host->desc = g_strdup (description); - host->willing = willing; + GdmChooserHost *host; + GdkPixbuf *img; + gchar *hostimg; + gchar *hostimgdir; + + host = g_new0 (GdmChooserHost, 1); + host->name = g_strdup (hostname); + host->desc = g_strdup (description); + host->willing = willing; + #ifdef ENABLE_IPV6 - if (family == AF_INET6) - memcpy (&host->ia6, (struct in6_addr *)ia, sizeof (struct in6_addr)); - else + if (family == AF_INET6) + memcpy (&host->ia6, (struct in6_addr *)ia, sizeof (struct in6_addr)); + else #endif - memcpy (&host->ia, (struct in_addr *)ia, sizeof (struct in_addr)); + memcpy (&host->ia, (struct in_addr *)ia, sizeof (struct in_addr)); - host->addrtype = family; - chooser_hosts = g_list_prepend (chooser_hosts, host); + host->addrtype = family; + chooser_hosts = g_list_prepend (chooser_hosts, host); - if ( ! willing) - return host; + if ( ! willing) + return host; - hostimgdir = gdm_config_get_string (GDM_KEY_HOST_IMAGE_DIR); - hostimg = g_strconcat (hostimgdir, "/", hostname, NULL); - if (g_access (hostimg, R_OK) != 0) { - g_free (hostimg); - hostimg = g_strconcat (hostimgdir, "/", hostname, ".png", NULL); - } + hostimgdir = gdm_config_get_string (GDM_KEY_HOST_IMAGE_DIR); + hostimg = g_strconcat (hostimgdir, "/", hostname, NULL); + if (g_access (hostimg, R_OK) != 0) { + g_free (hostimg); + hostimg = g_strconcat (hostimgdir, "/", hostname, ".png", NULL); + } - if (g_access (hostimg, R_OK) == 0 && - (img = gdk_pixbuf_new_from_file (hostimg, NULL)) != NULL) { - gint w, h, maxw, maxh; + if (g_access (hostimg, R_OK) == 0 && + (img = gdk_pixbuf_new_from_file (hostimg, NULL)) != NULL) { + gint w, h, maxw, maxh; - w = gdk_pixbuf_get_width (img); - h = gdk_pixbuf_get_height (img); + w = gdk_pixbuf_get_width (img); + h = gdk_pixbuf_get_height (img); - maxw = gdm_config_get_int (GDM_KEY_MAX_ICON_WIDTH); - maxh = gdm_config_get_int (GDM_KEY_MAX_ICON_HEIGHT); + maxw = gdm_config_get_int (GDM_KEY_MAX_ICON_WIDTH); + maxh = gdm_config_get_int (GDM_KEY_MAX_ICON_HEIGHT); - if (w > h && w > maxw) { - h = h * ((gfloat) maxw / w); - w = maxw; - } else if (h > maxh) { - w = w * ((gfloat) maxh / h); - h = maxh; - } + if (w > h && w > maxw) { + h = h * ((gfloat) maxw / w); + w = maxw; + } else if (h > maxh) { + w = w * ((gfloat) maxh / h); + h = maxh; + } - if (w != gdk_pixbuf_get_width (img) || - h != gdk_pixbuf_get_height (img)) - host->picture = gdk_pixbuf_scale_simple (img, w, h, - GDK_INTERP_BILINEAR); - else - host->picture = g_object_ref (G_OBJECT (img)); + if (w != gdk_pixbuf_get_width (img) || + h != gdk_pixbuf_get_height (img)) + host->picture = gdk_pixbuf_scale_simple (img, w, h, + GDK_INTERP_BILINEAR); + else + host->picture = g_object_ref (G_OBJECT (img)); - g_object_unref (G_OBJECT (img)); - } else if (defhostimg != NULL) { - host->picture = (GdkPixbuf *)g_object_ref (G_OBJECT (defhostimg)); - } + g_object_unref (G_OBJECT (img)); + } else if (defhostimg != NULL) { + host->picture = (GdkPixbuf *)g_object_ref (G_OBJECT (defhostimg)); + } - g_free (hostimg); + g_free (hostimg); - return host; + return host; } static void gdm_chooser_browser_add_host (GdmChooserHost *host) { - gboolean add_this_host = FALSE; + gboolean add_this_host = FALSE; - if (host->willing) { - GtkTreeIter iter = {0}; - const char *addr; - char *label; - char *name, *desc; + if (host->willing) { + GtkTreeIter iter = {0}; + const char *addr; + char *label; + char *name, *desc; #ifdef ENABLE_IPV6 - if (host->addrtype == AF_INET6) { /* IPv6 address */ - static char buffer6[INET6_ADDRSTRLEN]; + if (host->addrtype == AF_INET6) { /* IPv6 address */ + static char buffer6[INET6_ADDRSTRLEN]; - addr = inet_ntop (AF_INET6, host->ia6.s6_addr, buffer6, INET6_ADDRSTRLEN); - } - else /* IPv4 address */ + addr = inet_ntop (AF_INET6, host->ia6.s6_addr, buffer6, INET6_ADDRSTRLEN); + } + else /* IPv4 address */ #endif - { - addr = inet_ntoa (host->ia); - } - - name = g_markup_escape_text (host->name, -1); - desc = g_markup_escape_text (host->desc, -1); - - if (strcmp (addr, host->name) == 0) - label = g_strdup_printf ("<b>%s</b>\n%s", - name, - desc); - else - label = g_strdup_printf ("<b>%s</b> (%s)\n%s", - name, - addr, - desc); - - g_free (name); - g_free (desc); - - gtk_list_store_append (GTK_LIST_STORE (browser_model), &iter); - gtk_list_store_set (GTK_LIST_STORE (browser_model), &iter, - CHOOSER_LIST_ICON_COLUMN, host->picture, - CHOOSER_LIST_LABEL_COLUMN, label, - CHOOSER_LIST_HOST_COLUMN, host, - -1); - g_free (label); + { + addr = inet_ntoa (host->ia); + } + + name = g_markup_escape_text (host->name, -1); + desc = g_markup_escape_text (host->desc, -1); + + if (strcmp (addr, host->name) == 0) + label = g_strdup_printf ("<b>%s</b>\n%s", + name, + desc); + else + label = g_strdup_printf ("<b>%s</b> (%s)\n%s", + name, + addr, + desc); + + g_free (name); + g_free (desc); + + gtk_list_store_append (GTK_LIST_STORE (browser_model), &iter); + gtk_list_store_set (GTK_LIST_STORE (browser_model), &iter, + CHOOSER_LIST_ICON_COLUMN, host->picture, + CHOOSER_LIST_LABEL_COLUMN, label, + CHOOSER_LIST_HOST_COLUMN, host, + -1); + g_free (label); #ifdef ENABLE_IPV6 - if (added6_addr != NULL && memcmp (&host->ia6, added6_addr, - sizeof (struct in6_addr)) == 0) { - added6_addr = NULL; - add_this_host = TRUE; - } + if (added6_addr != NULL && memcmp (&host->ia6, added6_addr, + sizeof (struct in6_addr)) == 0) { + added6_addr = NULL; + add_this_host = TRUE; + } #else - if (added_addr != NULL && - memcmp (&host->ia, added_addr, - sizeof (struct in_addr)) == 0) { - added_addr = NULL; - add_this_host = TRUE; - } + if (added_addr != NULL && + memcmp (&host->ia, added_addr, + sizeof (struct in_addr)) == 0) { + added_addr = NULL; + add_this_host = TRUE; + } #endif - if (add_this_host) { - GtkTreeSelection *selection; - GtkTreePath *path = gtk_tree_model_get_path (browser_model, &iter); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (browser)); - gtk_tree_selection_select_iter (selection, &iter); - gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (browser), - path, NULL, - FALSE, 0.0, 0.0); - gtk_tree_path_free (path); - gtk_widget_grab_focus (manage); - } - g_free (added_host); - added_host = NULL; - if (add_check_handler > 0) - g_source_remove (add_check_handler); - add_check_handler = 0; - } - - gtk_widget_set_sensitive (GTK_WIDGET (browser), TRUE); + if (add_this_host) { + GtkTreeSelection *selection; + GtkTreePath *path = gtk_tree_model_get_path (browser_model, &iter); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (browser)); + gtk_tree_selection_select_iter (selection, &iter); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (browser), + path, NULL, + FALSE, 0.0, 0.0); + gtk_tree_path_free (path); + gtk_widget_grab_focus (manage); + } + g_free (added_host); + added_host = NULL; + if (add_check_handler > 0) + g_source_remove (add_check_handler); + add_check_handler = 0; + } + + gtk_widget_set_sensitive (GTK_WIDGET (browser), TRUE); } static GdmChooserHost * @@ -369,12 +369,12 @@ gdm_host_known (char *ia, gint family) } else #endif - if (family == AF_INET) { - if (host->addrtype != AF_INET) - continue; - if ( ! memcmp (&host->ia, (struct in_addr *)ia, sizeof (struct in_addr))) - return host; - } + if (family == AF_INET) { + if (host->addrtype != AF_INET) + continue; + if ( ! memcmp (&host->ia, (struct in_addr *)ia, sizeof (struct in_addr))) + return host; + } } return NULL; } @@ -386,15 +386,15 @@ is_loopback_addr (char *ia, gint family) #ifdef ENABLE_IPV6 if (family == AF_INET6 && IN6_IS_ADDR_LOOPBACK ((struct in6_addr *)ia)) { - return TRUE; + return TRUE; } else #endif - if (((family == AF_INET) && (((struct in_addr *) ia)->s_addr == INADDR_LOOPBACK)) || memcmp (&((struct in_addr *)ia)->s_addr, lo, 4) == 0) { - return TRUE; - } - else { - return FALSE; - } + if (((family == AF_INET) && (((struct in_addr *) ia)->s_addr == INADDR_LOOPBACK)) || memcmp (&((struct in_addr *)ia)->s_addr, lo, 4) == 0) { + return TRUE; + } + else { + return FALSE; + } } static gboolean @@ -461,225 +461,225 @@ gdm_chooser_decode_packet (GIOChannel *source, gpointer data) { #ifdef ENABLE_IPV6 - char hbuf[NI_MAXHOST]; - struct sockaddr_in6 clnt6_sa; + char hbuf[NI_MAXHOST]; + struct sockaddr_in6 clnt6_sa; #endif - struct sockaddr_in clnt_sa; - gint sa_len; - static XdmcpBuffer buf; - XdmcpHeader header; - struct hostent *he; - gchar *hostname = NULL; - gchar *status = NULL; - ARRAY8 auth = {0}, host = {0}, stat = {0}; - GdmChooserHost *gh; - int pipe_buf; - gboolean host_not_willing = FALSE; + struct sockaddr_in clnt_sa; + gint sa_len; + static XdmcpBuffer buf; + XdmcpHeader header; + struct hostent *he; + gchar *hostname = NULL; + gchar *status = NULL; + ARRAY8 auth = {0}, host = {0}, stat = {0}; + GdmChooserHost *gh; + int pipe_buf; + gboolean host_not_willing = FALSE; #ifdef PIPE_BUF - pipe_buf = PIPE_BUF; + pipe_buf = PIPE_BUF; #else - /* apparently Hurd doesn't have PIPE_BUF */ - pipe_buf = fpathconf (1 /*stdout*/, _PC_PIPE_BUF); - /* could return -1 if no limit */ + /* apparently Hurd doesn't have PIPE_BUF */ + pipe_buf = fpathconf (1 /*stdout*/, _PC_PIPE_BUF); + /* could return -1 if no limit */ #endif - if ( ! (condition & G_IO_IN)) - return TRUE; + if ( ! (condition & G_IO_IN)) + return TRUE; #ifdef ENABLE_IPV6 - if (have_ipv6) { - sa_len = sizeof (struct sockaddr_in6); - if (! XdmcpFill (sockfd, &buf, (XdmcpNetaddr) &clnt6_sa, &sa_len)) - return TRUE; - } else + if (have_ipv6) { + sa_len = sizeof (struct sockaddr_in6); + if (! XdmcpFill (sockfd, &buf, (XdmcpNetaddr) &clnt6_sa, &sa_len)) + return TRUE; + } else #endif - { - sa_len = sizeof (struct sockaddr_in); - if (! XdmcpFill (sockfd, &buf, (XdmcpNetaddr) &clnt_sa, &sa_len)) - return TRUE; - } + { + sa_len = sizeof (struct sockaddr_in); + if (! XdmcpFill (sockfd, &buf, (XdmcpNetaddr) &clnt_sa, &sa_len)) + return TRUE; + } - if (! XdmcpReadHeader (&buf, &header)) - return TRUE; + if (! XdmcpReadHeader (&buf, &header)) + return TRUE; - if (header.version != XDM_PROTOCOL_VERSION) - return TRUE; + if (header.version != XDM_PROTOCOL_VERSION) + return TRUE; - if (header.opcode == WILLING) { - if (! XdmcpReadARRAY8 (&buf, &auth)) - goto done; + if (header.opcode == WILLING) { + if (! XdmcpReadARRAY8 (&buf, &auth)) + goto done; - if (! XdmcpReadARRAY8 (&buf, &host)) - goto done; + if (! XdmcpReadARRAY8 (&buf, &host)) + goto done; - if (! XdmcpReadARRAY8 (&buf, &stat)) - goto done; + if (! XdmcpReadARRAY8 (&buf, &stat)) + goto done; - status = g_strndup ((char *) stat.data, MIN (stat.length, 256)); - } else if (header.opcode == UNWILLING) { - /* immaterial, will not be shown */ - status = NULL; - } else { - return TRUE; - } + status = g_strndup ((char *) stat.data, MIN (stat.length, 256)); + } else if (header.opcode == UNWILLING) { + /* immaterial, will not be shown */ + status = NULL; + } else { + return TRUE; + } #ifdef ENABLE_IPV6 - /*Since, IPv4 addresses will get extracted as V4 mapped IPv6 address*/ - - if (have_ipv6 && - IN6_IS_ADDR_V4MAPPED (&(clnt6_sa.sin6_addr))) { - memset (&clnt_sa, 0, sizeof (clnt_sa)); - memcpy (&(clnt_sa.sin_addr), &(clnt6_sa.sin6_addr.s6_addr[12]), 4); - clnt_sa.sin_family = AF_INET; - clnt_sa.sin_port = clnt6_sa.sin6_port; - clnt6_sa.sin6_family = AF_INET; - } - - if (have_ipv6 && - ((struct sockaddr *) &clnt6_sa)->sa_family == AF_INET6) { - if ( ! is_loopback_addr ((gchar *) &clnt6_sa.sin6_addr, AF_INET6)) { - clnt6_sa.sin6_scope_id = 0; + /*Since, IPv4 addresses will get extracted as V4 mapped IPv6 address*/ + + if (have_ipv6 && + IN6_IS_ADDR_V4MAPPED (&(clnt6_sa.sin6_addr))) { + memset (&clnt_sa, 0, sizeof (clnt_sa)); + memcpy (&(clnt_sa.sin_addr), &(clnt6_sa.sin6_addr.s6_addr[12]), 4); + clnt_sa.sin_family = AF_INET; + clnt_sa.sin_port = clnt6_sa.sin6_port; + clnt6_sa.sin6_family = AF_INET; + } + + if (have_ipv6 && + ((struct sockaddr *) &clnt6_sa)->sa_family == AF_INET6) { + if ( ! is_loopback_addr ((gchar *) &clnt6_sa.sin6_addr, AF_INET6)) { + clnt6_sa.sin6_scope_id = 0; - getnameinfo ((struct sockaddr *)&clnt6_sa, sizeof (struct sockaddr_in6), hbuf, sizeof (hbuf), NULL, 0, 0); + getnameinfo ((struct sockaddr *)&clnt6_sa, sizeof (struct sockaddr_in6), hbuf, sizeof (hbuf), NULL, 0, 0); - hostname = hbuf; + hostname = hbuf; - if (strlen (hostname) + 1 > pipe_buf) - goto done; - hostname = g_strdup (hostname); + if (strlen (hostname) + 1 > pipe_buf) + goto done; + hostname = g_strdup (hostname); - } else { - hostname = g_new0 (char, 1024); + } else { + hostname = g_new0 (char, 1024); - if (gethostname (hostname, 1023) != 0) { + if (gethostname (hostname, 1023) != 0) { + g_free (hostname); + goto done; + } + added6_addr = NULL; + gh = gdm_host_known ((char *)&clnt6_sa.sin6_addr, AF_INET6); + } + } else +#endif + { + if ( !is_loopback_addr ((char *)&clnt_sa.sin_addr, AF_INET)) { + he = gethostbyaddr ((gchar *) &clnt_sa.sin_addr, + sizeof (struct in_addr), + AF_INET); + + hostname = (he && he->h_name) ? he->h_name : inet_ntoa (clnt_sa.sin_addr); + if (strlen (hostname) + 1 > pipe_buf) + goto done; + + hostname = g_strdup (hostname); + } else { + hostname = g_new0 (char, 1024); + if (gethostname (hostname, 1023) != 0) { + g_free (hostname); + goto done; + } + } + } + + /* We can't pipe hostnames larger than this */ + if (pipe_buf > 0 && strlen (hostname)+1 > pipe_buf) { g_free (hostname); goto done; - } - added6_addr = NULL; - gh = gdm_host_known ((char *)&clnt6_sa.sin6_addr, AF_INET6); - } - } else -#endif - { - if ( !is_loopback_addr ((char *)&clnt_sa.sin_addr, AF_INET)) { - he = gethostbyaddr ((gchar *) &clnt_sa.sin_addr, - sizeof (struct in_addr), - AF_INET); - - hostname = (he && he->h_name) ? he->h_name : inet_ntoa (clnt_sa.sin_addr); - if (strlen (hostname) + 1 > pipe_buf) - goto done; - - hostname = g_strdup (hostname); - } else { - hostname = g_new0 (char, 1024); - if (gethostname (hostname, 1023) != 0) { - g_free (hostname); - goto done; - } - } - } - - /* We can't pipe hostnames larger than this */ - if (pipe_buf > 0 && strlen (hostname)+1 > pipe_buf) { - g_free (hostname); - goto done; - } + } #ifdef ENABLE_IPV6 - if (have_ipv6 && ((struct sockaddr *) &clnt6_sa)->sa_family == AF_INET6) { - gh = gdm_host_known ((char *)&clnt6_sa.sin6_addr, AF_INET6); - if (gh == NULL) { - gh = gdm_chooser_host_alloc (hostname, status, (char *)&clnt6_sa.sin6_addr, AF_INET6, header.opcode == WILLING); - gdm_chooser_browser_add_host (gh); - } - } else + if (have_ipv6 && ((struct sockaddr *) &clnt6_sa)->sa_family == AF_INET6) { + gh = gdm_host_known ((char *)&clnt6_sa.sin6_addr, AF_INET6); + if (gh == NULL) { + gh = gdm_chooser_host_alloc (hostname, status, (char *)&clnt6_sa.sin6_addr, AF_INET6, header.opcode == WILLING); + gdm_chooser_browser_add_host (gh); + } + } else #endif - { - gh = gdm_host_known ((char *)&clnt_sa.sin_addr, AF_INET); - if (gh == NULL) { - gh = gdm_chooser_host_alloc (hostname, status, (char *)&clnt_sa.sin_addr, AF_INET, header.opcode == WILLING); - gdm_chooser_browser_add_host (gh); - } - } - if (gh != NULL) { - /* server changed it's mind */ - if (header.opcode == WILLING && - ! gh->willing) { - gh->willing = TRUE; - gdm_chooser_browser_add_host (gh); - } - /* hmmm what about the other change, just ignore - for now, it's kind of confusing to just remove - servers really */ - } + { + gh = gdm_host_known ((char *)&clnt_sa.sin_addr, AF_INET); + if (gh == NULL) { + gh = gdm_chooser_host_alloc (hostname, status, (char *)&clnt_sa.sin_addr, AF_INET, header.opcode == WILLING); + gdm_chooser_browser_add_host (gh); + } + } + if (gh != NULL) { + /* server changed it's mind */ + if (header.opcode == WILLING && + ! gh->willing) { + gh->willing = TRUE; + gdm_chooser_browser_add_host (gh); + } + /* hmmm what about the other change, just ignore + for now, it's kind of confusing to just remove + servers really */ + } #ifdef ENABLE_IPV6 - if (have_ipv6 && - ((struct sockaddr *) &clnt6_sa)->sa_family == AF_INET6 && - ! gh->willing && - added6_addr != NULL && - memcmp (&gh->ia6, added6_addr, sizeof (struct in6_addr)) == 0) { - - added6_addr = NULL; - host_not_willing = TRUE; - } - else + if (have_ipv6 && + ((struct sockaddr *) &clnt6_sa)->sa_family == AF_INET6 && + ! gh->willing && + added6_addr != NULL && + memcmp (&gh->ia6, added6_addr, sizeof (struct in6_addr)) == 0) { + + added6_addr = NULL; + host_not_willing = TRUE; + } + else #endif - if (clnt_sa.sin_family == AF_INET && - ! gh->willing && - added_addr != NULL && - memcmp (&gh->ia, added_addr, sizeof (struct in_addr)) == 0) { - - added_addr = NULL; - host_not_willing = TRUE; - } - - if (host_not_willing) { - GtkWidget *dialog; - gchar *msg; - - if (add_check_handler > 0) - g_source_remove (add_check_handler); - add_check_handler = 0; - - msg = g_strdup_printf (_("The host \"%s\" is not willing " - "to support a login session right now. " - "Please try again later."), - added_host); - - dialog = hig_dialog_new (GTK_WINDOW (chooser) /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Cannot connect to remote server"), - msg); - - g_free (msg); - - if (RUNNING_UNDER_GDM) - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gdm_wm_no_login_focus_push (); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - gdm_wm_no_login_focus_pop (); - - g_free (added_host); - added_host = NULL; - } - - g_free (hostname); + if (clnt_sa.sin_family == AF_INET && + ! gh->willing && + added_addr != NULL && + memcmp (&gh->ia, added_addr, sizeof (struct in_addr)) == 0) { + + added_addr = NULL; + host_not_willing = TRUE; + } + + if (host_not_willing) { + GtkWidget *dialog; + gchar *msg; + + if (add_check_handler > 0) + g_source_remove (add_check_handler); + add_check_handler = 0; + + msg = g_strdup_printf (_("The host \"%s\" is not willing " + "to support a login session right now. " + "Please try again later."), + added_host); + + dialog = hig_dialog_new (GTK_WINDOW (chooser) /* parent */, + GTK_DIALOG_MODAL /* flags */, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Cannot connect to remote server"), + msg); + + g_free (msg); + + if (RUNNING_UNDER_GDM) + gdm_wm_center_window (GTK_WINDOW (dialog)); + + gdm_wm_no_login_focus_push (); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + gdm_wm_no_login_focus_pop (); + + g_free (added_host); + added_host = NULL; + } + + g_free (hostname); done: - if (header.opcode == WILLING) { - XdmcpDisposeARRAY8 (&auth); - XdmcpDisposeARRAY8 (&host); - XdmcpDisposeARRAY8 (&stat); - } + if (header.opcode == WILLING) { + XdmcpDisposeARRAY8 (&auth); + XdmcpDisposeARRAY8 (&host); + XdmcpDisposeARRAY8 (&stat); + } - g_free (status); + g_free (status); - return TRUE; + return TRUE; } @@ -777,34 +777,34 @@ gdm_chooser_find_mcaddr (void) if (ioctl (sock, SIOCGIFCONF, &ifc) >= 0) ifr = ifc.ifc_req; - num = ifc.ifc_len / sizeof (struct ifreq); /* No of interfaces */ - for (i = 0 ; i < num ; i++) { - struct ifreq ifreq; - int ifindex; + num = ifc.ifc_len / sizeof (struct ifreq); /* No of interfaces */ + for (i = 0 ; i < num ; i++) { + struct ifreq ifreq; + int ifindex; - memset (&ifreq, 0, sizeof (ifreq)); - strncpy (ifreq.ifr_name, ifr[i].ifr_name, sizeof (ifreq.ifr_name)); - ifreq.ifr_name[sizeof (ifreq.ifr_name) - 1] = '\0'; + memset (&ifreq, 0, sizeof (ifreq)); + strncpy (ifreq.ifr_name, ifr[i].ifr_name, sizeof (ifreq.ifr_name)); + ifreq.ifr_name[sizeof (ifreq.ifr_name) - 1] = '\0'; - if (ioctl (sock, SIOCGIFFLAGS, &ifreq) < 0) - gdm_common_error ("Could not get interface flags for %s\n", ifr[i].ifr_name); - ifindex = if_nametoindex (ifr[i].ifr_name); + if (ioctl (sock, SIOCGIFFLAGS, &ifreq) < 0) + gdm_common_error ("Could not get interface flags for %s\n", ifr[i].ifr_name); + ifindex = if_nametoindex (ifr[i].ifr_name); - if ((!(ifreq.ifr_flags & IFF_UP) || (!(ifreq.ifr_flags & IFF_MULTICAST))) || (ifindex == 0 )) { + if ((!(ifreq.ifr_flags & IFF_UP) || (!(ifreq.ifr_flags & IFF_MULTICAST))) || (ifindex == 0 )) { /* Not a valid interface or Not up */ - continue; - } + continue; + } - sin6 = g_new0 (struct sockaddr_in6, 1); - sin6->sin6_family = AF_INET6; - sin6->sin6_port = htons (XDM_UDP_PORT); - sin6->sin6_scope_id = ifindex; - inet_pton (AF_INET6, gdm_config_get_string (GDM_KEY_MULTICAST_ADDR), - &sin6->sin6_addr); + sin6 = g_new0 (struct sockaddr_in6, 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = htons (XDM_UDP_PORT); + sin6->sin6_scope_id = ifindex; + inet_pton (AF_INET6, gdm_config_get_string (GDM_KEY_MULTICAST_ADDR), + &sin6->sin6_addr); - /* bcaddr is also serving for multicast address for IPv6 */ - bcaddr = g_slist_append (bcaddr, sin6); - } + /* bcaddr is also serving for multicast address for IPv6 */ + bcaddr = g_slist_append (bcaddr, sin6); + } } #endif @@ -830,86 +830,86 @@ chooser_scan_time_update (gpointer data) static void do_ping (gboolean full) { - struct sockaddr_in sock; - GSList *bl = bcaddr; - GSList *ql = queryaddr; - struct sockaddr *ia; + struct sockaddr_in sock; + GSList *bl = bcaddr; + GSList *ql = queryaddr; + struct sockaddr *ia; #ifdef ENABLE_IPV6 - struct sockaddr_in6 sock6; + struct sockaddr_in6 sock6; - memset (&sock6, 0, sizeof (sock6)); - sock6.sin6_family = AF_INET6; - sock6.sin6_port = htons (XDM_UDP_PORT); + memset (&sock6, 0, sizeof (sock6)); + sock6.sin6_family = AF_INET6; + sock6.sin6_port = htons (XDM_UDP_PORT); #endif - sock.sin_family = AF_INET; - sock.sin_port = htons (XDM_UDP_PORT); + sock.sin_family = AF_INET; + sock.sin_port = htons (XDM_UDP_PORT); - while (bl) { - ia = (struct sockaddr *) bl->data; + while (bl) { + ia = (struct sockaddr *) bl->data; #ifdef ENABLE_IPV6 - if (have_ipv6) { /* Convert the IPv4 broadcast address to v4 mapped v6 address.*/ - if (ia->sa_family == AF_INET) { - char tmpaddr[30]; - struct in6_addr in6; - - sprintf (tmpaddr, "::ffff:%s", inet_ntoa (((struct sockaddr_in *)(ia))->sin_addr)); - inet_pton (AF_INET6, tmpaddr, &in6); - memcpy (sock6.sin6_addr.s6_addr, in6.s6_addr, sizeof (struct in6_addr)); - XdmcpFlush (sockfd, &bcbuf, (XdmcpNetaddr) &sock6, (int) sizeof (struct sockaddr_in6)); - } + if (have_ipv6) { /* Convert the IPv4 broadcast address to v4 mapped v6 address.*/ + if (ia->sa_family == AF_INET) { + char tmpaddr[30]; + struct in6_addr in6; + + sprintf (tmpaddr, "::ffff:%s", inet_ntoa (((struct sockaddr_in *)(ia))->sin_addr)); + inet_pton (AF_INET6, tmpaddr, &in6); + memcpy (sock6.sin6_addr.s6_addr, in6.s6_addr, sizeof (struct in6_addr)); + XdmcpFlush (sockfd, &bcbuf, (XdmcpNetaddr) &sock6, (int) sizeof (struct sockaddr_in6)); + } - else if (ia->sa_family == AF_INET6) { - memcpy (sock6.sin6_addr.s6_addr, ((struct sockaddr_in6 *)ia)->sin6_addr.s6_addr, sizeof (struct in6_addr)); - XdmcpFlush (sockfd, &bcbuf, (XdmcpNetaddr) &sock6, (int) sizeof (struct sockaddr_in6)); + else if (ia->sa_family == AF_INET6) { + memcpy (sock6.sin6_addr.s6_addr, ((struct sockaddr_in6 *)ia)->sin6_addr.s6_addr, sizeof (struct in6_addr)); + XdmcpFlush (sockfd, &bcbuf, (XdmcpNetaddr) &sock6, (int) sizeof (struct sockaddr_in6)); + } } - } - else + else #endif - { - if (ia->sa_family == AF_INET) { - sock.sin_addr.s_addr = ((struct sockaddr_in *)ia)->sin_addr.s_addr; - XdmcpFlush (sockfd, &bcbuf, (XdmcpNetaddr) &sock, (int)sizeof (struct sockaddr_in)); - } - } - bl = bl->next; - } + { + if (ia->sa_family == AF_INET) { + sock.sin_addr.s_addr = ((struct sockaddr_in *)ia)->sin_addr.s_addr; + XdmcpFlush (sockfd, &bcbuf, (XdmcpNetaddr) &sock, (int)sizeof (struct sockaddr_in)); + } + } + bl = bl->next; + } - while (ql != NULL) { - ia = (struct sockaddr *) ql->data; + while (ql != NULL) { + ia = (struct sockaddr *) ql->data; #ifdef ENABLE_IPV6 - if (have_ipv6) { - if (ia->sa_family == AF_INET) { - char tmpaddr[30]; - struct in6_addr in6; - - sprintf (tmpaddr, "::ffff:%s", inet_ntoa (((struct sockaddr_in *)(ia))->sin_addr)); - inet_pton (AF_INET6, tmpaddr, &in6); - - if (full || ! gdm_host_known ((char *)&((struct sockaddr_in6 *)ia)->sin6_addr, AF_INET6)) { - memcpy (sock6.sin6_addr.s6_addr, in6.s6_addr, sizeof (struct in6_addr)); - XdmcpFlush (sockfd, &bcbuf, (XdmcpNetaddr) &sock6, (int) sizeof (struct sockaddr_in6)); - } - } + if (have_ipv6) { + if (ia->sa_family == AF_INET) { + char tmpaddr[30]; + struct in6_addr in6; + + sprintf (tmpaddr, "::ffff:%s", inet_ntoa (((struct sockaddr_in *)(ia))->sin_addr)); + inet_pton (AF_INET6, tmpaddr, &in6); - if (ia->sa_family == AF_INET6) { - if (full || ! gdm_host_known ((char *)&((struct sockaddr_in6 *)ia)->sin6_addr, AF_INET6)) { - memcpy (&sock6.sin6_addr, &((struct sockaddr_in6 *)ia)->sin6_addr, sizeof (struct in6_addr)); - XdmcpFlush (sockfd, &querybuf, (XdmcpNetaddr) &sock6, (int) sizeof (struct sockaddr_in6)); - } + if (full || ! gdm_host_known ((char *)&((struct sockaddr_in6 *)ia)->sin6_addr, AF_INET6)) { + memcpy (sock6.sin6_addr.s6_addr, in6.s6_addr, sizeof (struct in6_addr)); + XdmcpFlush (sockfd, &bcbuf, (XdmcpNetaddr) &sock6, (int) sizeof (struct sockaddr_in6)); + } + } + + if (ia->sa_family == AF_INET6) { + if (full || ! gdm_host_known ((char *)&((struct sockaddr_in6 *)ia)->sin6_addr, AF_INET6)) { + memcpy (&sock6.sin6_addr, &((struct sockaddr_in6 *)ia)->sin6_addr, sizeof (struct in6_addr)); + XdmcpFlush (sockfd, &querybuf, (XdmcpNetaddr) &sock6, (int) sizeof (struct sockaddr_in6)); + } + } } - } - else + else #endif - { - if (full || ! gdm_host_known ((char *)&((struct sockaddr_in *)ia)->sin_addr, AF_INET)) { - sock.sin_addr.s_addr = ((struct sockaddr_in *)ia)->sin_addr.s_addr; - XdmcpFlush (sockfd, &querybuf, (XdmcpNetaddr) &sock, (int)sizeof (struct sockaddr_in)); - } - } - ql = ql->next; - } + { + if (full || ! gdm_host_known ((char *)&((struct sockaddr_in *)ia)->sin_addr, AF_INET)) { + sock.sin_addr.s_addr = ((struct sockaddr_in *)ia)->sin_addr.s_addr; + XdmcpFlush (sockfd, &querybuf, (XdmcpNetaddr) &sock, (int)sizeof (struct sockaddr_in)); + } + } + ql = ql->next; + } } static gboolean @@ -927,45 +927,45 @@ ping_try (gpointer data) void gdm_chooser_xdmcp_discover (void) { - GList *hl = chooser_hosts; + GList *hl = chooser_hosts; - g_free (added_host); - added_host = NULL; + g_free (added_host); + added_host = NULL; #ifdef ENABLE_IPV6 - added6_addr = NULL; + added6_addr = NULL; #endif - added_addr = NULL; - if (add_check_handler > 0) - g_source_remove (add_check_handler); - add_check_handler = 0; - - gtk_widget_set_sensitive (GTK_WIDGET (manage), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (rescan), FALSE); - gtk_list_store_clear (GTK_LIST_STORE (browser_model)); - gtk_widget_set_sensitive (GTK_WIDGET (browser), FALSE); - gtk_label_set_label (GTK_LABEL (status_label), - _(scanning_message)); - - while (hl) { - gdm_chooser_host_dispose ((GdmChooserHost *) hl->data); - hl = hl->next; - } - - g_list_free (chooser_hosts); - chooser_hosts = NULL; - - do_ping (TRUE); - - if (scan_time_handler > 0) - g_source_remove (scan_time_handler); - scan_time_handler = g_timeout_add (gdm_config_get_int (GDM_KEY_SCAN_TIME) * 1000, - chooser_scan_time_update, NULL); - - /* Note we already used up one try */ - ping_tries = PING_TRIES - 1; - if (ping_try_handler > 0) - g_source_remove (ping_try_handler); - ping_try_handler = g_timeout_add (PING_TIMEOUT, ping_try, NULL); + added_addr = NULL; + if (add_check_handler > 0) + g_source_remove (add_check_handler); + add_check_handler = 0; + + gtk_widget_set_sensitive (GTK_WIDGET (manage), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (rescan), FALSE); + gtk_list_store_clear (GTK_LIST_STORE (browser_model)); + gtk_widget_set_sensitive (GTK_WIDGET (browser), FALSE); + gtk_label_set_label (GTK_LABEL (status_label), + _(scanning_message)); + + while (hl) { + gdm_chooser_host_dispose ((GdmChooserHost *) hl->data); + hl = hl->next; + } + + g_list_free (chooser_hosts); + chooser_hosts = NULL; + + do_ping (TRUE); + + if (scan_time_handler > 0) + g_source_remove (scan_time_handler); + scan_time_handler = g_timeout_add (gdm_config_get_int (GDM_KEY_SCAN_TIME) * 1000, + chooser_scan_time_update, NULL); + + /* Note we already used up one try */ + ping_tries = PING_TRIES - 1; + if (ping_try_handler > 0) + g_source_remove (ping_try_handler); + ping_try_handler = g_timeout_add (PING_TIMEOUT, ping_try, NULL); } #ifndef ishexdigit @@ -976,21 +976,21 @@ gdm_chooser_xdmcp_discover (void) static int from_hex (const char *s, char *d, int len) { - int t; - while (len >= 2) - { - if (!ishexdigit(*s)) - return 1; - t = HexChar(*s) << 4; - s++; - if (!ishexdigit(*s)) - return 1; - t += HexChar(*s); - s++; - *d++ = t; - len -= 2; - } - return len; + int t; + while (len >= 2) + { + if (!ishexdigit(*s)) + return 1; + t = HexChar(*s) << 4; + s++; + if (!ishexdigit(*s)) + return 1; + t += HexChar(*s); + s++; + *d++ = t; + len -= 2; + } + return len; } static void @@ -1025,9 +1025,9 @@ gdm_chooser_add_hosts (char **hosts) } #ifdef ENABLE_IPV6 if (used_addr == AF_INET6 || !qa6) { - qa6 = g_new0 (struct sockaddr_in6, 1); - memset (qa6, 0, sizeof (qa6)); - qa6->sin6_family = AF_INET6; + qa6 = g_new0 (struct sockaddr_in6, 1); + memset (qa6, 0, sizeof (qa6)); + qa6->sin6_family = AF_INET6; } result = NULL; @@ -1042,67 +1042,67 @@ gdm_chooser_add_hosts (char **hosts) } else #endif - if ((strlen (name) == 8) && (from_hex (name, (char *) &qa->sin_addr, strlen (name)) == 0)) { - queryaddr = g_slist_append (queryaddr, qa); + if ((strlen (name) == 8) && (from_hex (name, (char *) &qa->sin_addr, strlen (name)) == 0)) { + queryaddr = g_slist_append (queryaddr, qa); #ifdef ENABLE_IPV6 - g_free (qa6); - qa6 = NULL; + g_free (qa6); + qa6 = NULL; #endif - used_addr = AF_INET; - } - else -#ifdef ENABLE_IPV6 - if (inet_pton (AF_INET6, name, &qa6->sin6_addr) > 0) { - queryaddr = g_slist_append (queryaddr, qa6); - g_free (qa); - qa = NULL; - used_addr = AF_INET6; - } - else -#endif - if ((qa->sin_addr.s_addr = inet_addr (name)) != -1) { - queryaddr = g_slist_append (queryaddr, qa); -#ifdef ENABLE_IPV6 - g_free (qa6); - qa6 = NULL; -#endif - used_addr = AF_INET; - } - else + used_addr = AF_INET; + } + else #ifdef ENABLE_IPV6 - if (getaddrinfo (name, NULL, &hints, &result) == 0) { - for (res = result; res; res = res->ai_next) { - if (res && res->ai_family == AF_INET6) { - memmove (qa6, res->ai_addr, res->ai_addrlen); + if (inet_pton (AF_INET6, name, &qa6->sin6_addr) > 0) { queryaddr = g_slist_append (queryaddr, qa6); g_free (qa); qa = NULL; used_addr = AF_INET6; - } - if (res && res->ai_family == AF_INET) { - memmove (qa, res->ai_addr, res->ai_addrlen); - queryaddr = g_slist_append (queryaddr, qa); - g_free (qa6); - qa6 = NULL; - used_addr = AF_INET; } - } - } else + else #endif - if ((hostent = gethostbyname (name)) != NULL - && hostent->h_addrtype == AF_INET - && hostent->h_length == 4) { - qa->sin_family = AF_INET; - memmove (&qa->sin_addr, hostent->h_addr, 4); - queryaddr = g_slist_append (queryaddr, qa); + if ((qa->sin_addr.s_addr = inet_addr (name)) != -1) { + queryaddr = g_slist_append (queryaddr, qa); #ifdef ENABLE_IPV6 - g_free (qa6); - qa6 = NULL; + g_free (qa6); + qa6 = NULL; #endif - used_addr = AF_INET; - } else { - continue; /* not a valid address */ - } + used_addr = AF_INET; + } + else +#ifdef ENABLE_IPV6 + if (getaddrinfo (name, NULL, &hints, &result) == 0) { + for (res = result; res; res = res->ai_next) { + if (res && res->ai_family == AF_INET6) { + memmove (qa6, res->ai_addr, res->ai_addrlen); + queryaddr = g_slist_append (queryaddr, qa6); + g_free (qa); + qa = NULL; + used_addr = AF_INET6; + } + if (res && res->ai_family == AF_INET) { + memmove (qa, res->ai_addr, res->ai_addrlen); + queryaddr = g_slist_append (queryaddr, qa); + g_free (qa6); + qa6 = NULL; + used_addr = AF_INET; + } + } + } else +#endif + if ((hostent = gethostbyname (name)) != NULL + && hostent->h_addrtype == AF_INET + && hostent->h_length == 4) { + qa->sin_family = AF_INET; + memmove (&qa->sin_addr, hostent->h_addr, 4); + queryaddr = g_slist_append (queryaddr, qa); +#ifdef ENABLE_IPV6 + g_free (qa6); + qa6 = NULL; +#endif + used_addr = AF_INET; + } else { + continue; /* not a valid address */ + } } if (bcaddr == NULL && @@ -1113,176 +1113,176 @@ gdm_chooser_add_hosts (char **hosts) static void gdm_chooser_xdmcp_init (char **hosts) { - static XdmcpHeader header; - gint sockopts = 1; + static XdmcpHeader header; + gint sockopts = 1; - /* Open socket for communication */ + /* Open socket for communication */ #ifdef ENABLE_IPV6 - if ((sockfd = socket (AF_INET6, SOCK_DGRAM, 0)) == -1) - have_ipv6 = FALSE; - else - have_ipv6 = TRUE; + if ((sockfd = socket (AF_INET6, SOCK_DGRAM, 0)) == -1) + have_ipv6 = FALSE; + else + have_ipv6 = TRUE; #endif - if ( ! have_ipv6) { - if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) == -1) { - gdm_common_fail_exit ("Could not create socket!"); + if ( ! have_ipv6) { + if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) == -1) { + gdm_common_fail_exit ("Could not create socket!"); + } + } + + if (setsockopt (sockfd, SOL_SOCKET, SO_BROADCAST, + (char *) &sockopts, sizeof (sockopts)) < 0) { + gdm_common_fail_exit ("Could not set socket options!"); } - } - - if (setsockopt (sockfd, SOL_SOCKET, SO_BROADCAST, - (char *) &sockopts, sizeof (sockopts)) < 0) { - gdm_common_fail_exit ("Could not set socket options!"); - } - - /* Assemble XDMCP BROADCAST_QUERY packet in static buffer */ - header.opcode = (CARD16) BROADCAST_QUERY; - header.length = 1; - header.version = XDM_PROTOCOL_VERSION; - XdmcpWriteHeader (&bcbuf, &header); - XdmcpWriteARRAY8 (&bcbuf, &authlist.authentication); - - /* Assemble XDMCP QUERY packet in static buffer */ - header.opcode = (CARD16) QUERY; - header.length = 1; - header.version = XDM_PROTOCOL_VERSION; - XdmcpWriteHeader (&querybuf, &header); - XdmcpWriteARRAY8 (&querybuf, &authlist.authentication); - - gdm_chooser_add_hosts (hosts); - - channel = g_io_channel_unix_new (sockfd); - g_io_channel_set_encoding (channel, NULL, NULL); - g_io_channel_set_buffered (channel, FALSE); - g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, - G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL, - gdm_chooser_decode_packet, - GINT_TO_POINTER (sockfd), NULL); - g_io_channel_unref (channel); - - gdm_chooser_xdmcp_discover (); + + /* Assemble XDMCP BROADCAST_QUERY packet in static buffer */ + header.opcode = (CARD16) BROADCAST_QUERY; + header.length = 1; + header.version = XDM_PROTOCOL_VERSION; + XdmcpWriteHeader (&bcbuf, &header); + XdmcpWriteARRAY8 (&bcbuf, &authlist.authentication); + + /* Assemble XDMCP QUERY packet in static buffer */ + header.opcode = (CARD16) QUERY; + header.length = 1; + header.version = XDM_PROTOCOL_VERSION; + XdmcpWriteHeader (&querybuf, &header); + XdmcpWriteARRAY8 (&querybuf, &authlist.authentication); + + gdm_chooser_add_hosts (hosts); + + channel = g_io_channel_unix_new (sockfd); + g_io_channel_set_encoding (channel, NULL, NULL); + g_io_channel_set_buffered (channel, FALSE); + g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, + G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL, + gdm_chooser_decode_packet, + GINT_TO_POINTER (sockfd), NULL); + g_io_channel_unref (channel); + + gdm_chooser_xdmcp_discover (); } static void gdm_chooser_choose_host (const char *hostname) { - ARRAY8 tmparr; + ARRAY8 tmparr; #ifndef ENABLE_IPV6 - struct hostent *hentry; + struct hostent *hentry; #endif - printf ("\n%s\n", curhost->name); - fflush (stdout); - if (xdm_address != NULL) { + printf ("\n%s\n", curhost->name); + fflush (stdout); + if (xdm_address != NULL) { #ifdef ENABLE_IPV6 - int status; - struct sockaddr_in6 in6_addr; - struct addrinfo hints, *result; + int status; + struct sockaddr_in6 in6_addr; + struct addrinfo hints, *result; #endif - struct sockaddr_in in_addr; - char xdm_addr[32]; - char client_addr[32]; - int fd; - char buf[1024]; - XdmcpBuffer buffer; - long family, port, addr; - - if (strlen (xdm_address) > 64 || - from_hex (xdm_address, xdm_addr, strlen (xdm_address)) != 0) { - gdm_common_fail_exit ("gdm_chooser_chooser_host: Invalid xdm address."); - } - - family = (xdm_addr[0] << 8) | xdm_addr[1]; - port = (xdm_addr[2] << 8) | xdm_addr[3]; + struct sockaddr_in in_addr; + char xdm_addr[32]; + char client_addr[32]; + int fd; + char buf[1024]; + XdmcpBuffer buffer; + long family, port, addr; + + if (strlen (xdm_address) > 64 || + from_hex (xdm_address, xdm_addr, strlen (xdm_address)) != 0) { + gdm_common_fail_exit ("gdm_chooser_chooser_host: Invalid xdm address."); + } + + family = (xdm_addr[0] << 8) | xdm_addr[1]; + port = (xdm_addr[2] << 8) | xdm_addr[3]; #ifdef ENABLE_IPV6 - if (family == AF_INET6) { - memset (&in6_addr, 0, sizeof (in6_addr)); + if (family == AF_INET6) { + memset (&in6_addr, 0, sizeof (in6_addr)); - in6_addr.sin6_port = htons (port); - in6_addr.sin6_family = AF_INET6; + in6_addr.sin6_port = htons (port); + in6_addr.sin6_family = AF_INET6; - memcpy (&in6_addr.sin6_addr, &xdm_address[4], 16); + memcpy (&in6_addr.sin6_addr, &xdm_address[4], 16); - if ((fd = socket (PF_INET6, SOCK_STREAM, 0)) == -1) { - gdm_common_fail_exit ("gdm_chooser_choose_host: Could not create response socket."); - } + if ((fd = socket (PF_INET6, SOCK_STREAM, 0)) == -1) { + gdm_common_fail_exit ("gdm_chooser_choose_host: Could not create response socket."); + } - if (connect (fd, (struct sockaddr *) &in6_addr, - sizeof (in6_addr)) == -1) { + if (connect (fd, (struct sockaddr *) &in6_addr, + sizeof (in6_addr)) == -1) { - gdm_common_fail_exit ("gdm_chooser_chooser_host: Could not connect to xdm."); - } - } else + gdm_common_fail_exit ("gdm_chooser_chooser_host: Could not connect to xdm."); + } + } else #endif - { - addr = (xdm_addr[4] << 24) | (xdm_addr[5] << 16) | - (xdm_addr[6] << 8) | xdm_addr[7]; + { + addr = (xdm_addr[4] << 24) | (xdm_addr[5] << 16) | + (xdm_addr[6] << 8) | xdm_addr[7]; - in_addr.sin_family = AF_INET; - in_addr.sin_port = htons (port); - in_addr.sin_addr.s_addr = htonl (addr); + in_addr.sin_family = AF_INET; + in_addr.sin_port = htons (port); + in_addr.sin_addr.s_addr = htonl (addr); - if ((fd = socket (PF_INET, SOCK_STREAM, 0)) == -1) { - gdm_common_fail_exit ("gdm_chooser_chooser_host: Could not create response socket."); - } + if ((fd = socket (PF_INET, SOCK_STREAM, 0)) == -1) { + gdm_common_fail_exit ("gdm_chooser_chooser_host: Could not create response socket."); + } - if (connect (fd, (struct sockaddr *) &in_addr, - sizeof (in_addr)) == -1) { + if (connect (fd, (struct sockaddr *) &in_addr, + sizeof (in_addr)) == -1) { - gdm_common_fail_exit ("gdm_chooser_chooser_host: Could not connect to xdm."); - } - } + gdm_common_fail_exit ("gdm_chooser_chooser_host: Could not connect to xdm."); + } + } - buffer.data = (BYTE *) buf; - buffer.size = sizeof (buf); - buffer.pointer = 0; - buffer.count = 0; + buffer.data = (BYTE *) buf; + buffer.size = sizeof (buf); + buffer.pointer = 0; + buffer.count = 0; - if (strlen (client_address) > 64 || from_hex (client_address, - client_addr, strlen (client_address)) != 0) { + if (strlen (client_address) > 64 || from_hex (client_address, + client_addr, strlen (client_address)) != 0) { - gdm_common_fail_exit ("gdm_chooser_chooser_host: Invalid client address."); - } + gdm_common_fail_exit ("gdm_chooser_chooser_host: Invalid client address."); + } - tmparr.data = (BYTE *) client_addr; - tmparr.length = strlen (client_address) / 2; + tmparr.data = (BYTE *) client_addr; + tmparr.length = strlen (client_address) / 2; - XdmcpWriteARRAY8 (&buffer, &tmparr); - XdmcpWriteCARD16 (&buffer, (CARD16) connection_type); + XdmcpWriteARRAY8 (&buffer, &tmparr); + XdmcpWriteCARD16 (&buffer, (CARD16) connection_type); #ifdef ENABLE_IPV6 - result = NULL; - memset (&hints, 0, sizeof (hints)); - hints.ai_socktype = SOCK_STREAM; - - status = getaddrinfo (hostname, NULL, &hints, &result); - - if (status != 0) { - gdm_common_fail_exit ("gdm_chooser_chooser_host: Could not get host entry for %s", - hostname); - } - - if (result->ai_family == AF_INET6) - tmparr.length = 16; - if (result->ai_family == AF_INET) - tmparr.length = 4; - tmparr.data = (BYTE *) result->ai_addr; + result = NULL; + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_STREAM; + + status = getaddrinfo (hostname, NULL, &hints, &result); + + if (status != 0) { + gdm_common_fail_exit ("gdm_chooser_chooser_host: Could not get host entry for %s", + hostname); + } + + if (result->ai_family == AF_INET6) + tmparr.length = 16; + if (result->ai_family == AF_INET) + tmparr.length = 4; + tmparr.data = (BYTE *) result->ai_addr; #else - hentry = gethostbyname (hostname); + hentry = gethostbyname (hostname); - if (!hentry) { - gdm_common_fail_exit ("gdm_chooser_chooser_host: Could not get host entry for %s", - hostname); - } + if (!hentry) { + gdm_common_fail_exit ("gdm_chooser_chooser_host: Could not get host entry for %s", + hostname); + } - tmparr.data = (BYTE *) hentry->h_addr_list[0]; /* XXX */ - tmparr.length = 4; + tmparr.data = (BYTE *) hentry->h_addr_list[0]; /* XXX */ + tmparr.length = 4; #endif - XdmcpWriteARRAY8 (&buffer, &tmparr); - write (fd, (char *) buffer.data, buffer.pointer); - close (fd); - } + XdmcpWriteARRAY8 (&buffer, &tmparr); + write (fd, (char *) buffer.data, buffer.pointer); + close (fd); + } } static gboolean @@ -1295,8 +1295,8 @@ add_check (gpointer data) check = TRUE; else #endif - if ((! have_ipv6) && added_addr != NULL) - check = TRUE; + if ((! have_ipv6) && added_addr != NULL) + check = TRUE; if (check) { GtkWidget *dialog; @@ -1365,82 +1365,82 @@ gdm_chooser_add_host (void) else #endif - if (strlen (name) == 8 && - from_hex (name, (char *) &qa->sin_addr, strlen (name)) == 0) { + if (strlen (name) == 8 && + from_hex (name, (char *) &qa->sin_addr, strlen (name)) == 0) { #ifdef ENABLE_IPV6 - if (have_ipv6) { - char tmpaddr[30]; + if (have_ipv6) { + char tmpaddr[30]; - sprintf (tmpaddr, "::ffff:%s", inet_ntoa (qa->sin_addr)); - inet_pton (AF_INET6, tmpaddr, &qa6->sin6_addr); - } + sprintf (tmpaddr, "::ffff:%s", inet_ntoa (qa->sin_addr)); + inet_pton (AF_INET6, tmpaddr, &qa6->sin6_addr); + } #endif - } - else + } + else #ifdef ENABLE_IPV6 - if (have_ipv6 && inet_pton (AF_INET6, name, &qa6->sin6_addr) > 0) ; - else + if (have_ipv6 && inet_pton (AF_INET6, name, &qa6->sin6_addr) > 0) ; + else #endif - if (inet_aton (name, &(qa->sin_addr))) { + if (inet_aton (name, &(qa->sin_addr))) { #ifdef ENABLE_IPV6 - if (have_ipv6) { - char tmpaddr[30]; + if (have_ipv6) { + char tmpaddr[30]; - sprintf (tmpaddr, "::ffff:%s", inet_ntoa (qa->sin_addr)); - inet_pton (AF_INET6, tmpaddr, &qa6->sin6_addr); - } + sprintf (tmpaddr, "::ffff:%s", inet_ntoa (qa->sin_addr)); + inet_pton (AF_INET6, tmpaddr, &qa6->sin6_addr); + } #endif - } - else + } + else #ifdef ENABLE_IPV6 - if (getaddrinfo (name, NULL, &hints, &result) == 0) { - if (result->ai_family == AF_INET6) { - memcpy (qa6, (struct sockaddr_in6 *)result->ai_addr, result->ai_addrlen); - } - else if (result->ai_family == AF_INET) { - if (have_ipv6) { - char tmpaddr [30]; - - sprintf (tmpaddr, "::ffff:%s", - inet_ntoa (((struct sockaddr_in *)result->ai_addr)->sin_addr)); - inet_pton (AF_INET6, tmpaddr, &qa6->sin6_addr); - } - } - } - else + if (getaddrinfo (name, NULL, &hints, &result) == 0) { + if (result->ai_family == AF_INET6) { + memcpy (qa6, (struct sockaddr_in6 *)result->ai_addr, result->ai_addrlen); + } + else if (result->ai_family == AF_INET) { + if (have_ipv6) { + char tmpaddr [30]; + + sprintf (tmpaddr, "::ffff:%s", + inet_ntoa (((struct sockaddr_in *)result->ai_addr)->sin_addr)); + inet_pton (AF_INET6, tmpaddr, &qa6->sin6_addr); + } + } + } + else #endif - if ((hostent = gethostbyname (name)) != NULL && - hostent->h_addrtype == AF_INET && hostent->h_length == 4) { - memmove (&qa->sin_addr, hostent->h_addr, 4); - } else { - GtkWidget *dialog; - gchar *msg; - - msg = g_strdup_printf (_("Cannot find the host \"%s\". " - "Perhaps you have mistyped it."), - name); - - dialog = hig_dialog_new (GTK_WINDOW (chooser) /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Cannot find host"), - msg); - g_free (msg); - - if (RUNNING_UNDER_GDM) - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gdm_wm_no_login_focus_push (); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - gdm_wm_no_login_focus_pop (); - g_free (qa); + if ((hostent = gethostbyname (name)) != NULL && + hostent->h_addrtype == AF_INET && hostent->h_length == 4) { + memmove (&qa->sin_addr, hostent->h_addr, 4); + } else { + GtkWidget *dialog; + gchar *msg; + + msg = g_strdup_printf (_("Cannot find the host \"%s\". " + "Perhaps you have mistyped it."), + name); + + dialog = hig_dialog_new (GTK_WINDOW (chooser) /* parent */, + GTK_DIALOG_MODAL /* flags */, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Cannot find host"), + msg); + g_free (msg); + + if (RUNNING_UNDER_GDM) + gdm_wm_center_window (GTK_WINDOW (dialog)); + + gdm_wm_no_login_focus_push (); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + gdm_wm_no_login_focus_pop (); + g_free (qa); #ifdef ENABLE_IPV6 - g_free (qa6); + g_free (qa6); #endif - return; /* not a valid address */ - } + return; /* not a valid address */ + } #ifdef ENABLE_IPV6 if (have_ipv6) { @@ -1459,16 +1459,16 @@ gdm_chooser_add_host (void) host = gdm_host_known ((char *) &qa6->sin6_addr, AF_INET6); } else #endif - { - memset (&sock, 0, sizeof (struct sockaddr_in)); - sock.sin_family = AF_INET; - sock.sin_port = htons (XDM_UDP_PORT); - status = gdm_addr_known ((char *)&qa->sin_addr, AF_INET); - if ( ! status) { - queryaddr = g_slist_append (queryaddr, qa); + { + memset (&sock, 0, sizeof (struct sockaddr_in)); + sock.sin_family = AF_INET; + sock.sin_port = htons (XDM_UDP_PORT); + status = gdm_addr_known ((char *)&qa->sin_addr, AF_INET); + if ( ! status) { + queryaddr = g_slist_append (queryaddr, qa); + } + host = gdm_host_known ((char *) &qa->sin_addr, AF_INET); } - host = gdm_host_known ((char *) &qa->sin_addr, AF_INET); - } if (host != NULL) { GtkTreeIter iter = {0}; @@ -1494,11 +1494,11 @@ gdm_chooser_add_host (void) added_addr = (struct in_addr *)&(qa6->sin6_addr.s6_addr[12]); } else #endif - { - sock.sin_addr.s_addr = qa->sin_addr.s_addr; - XdmcpFlush (sockfd, &querybuf, (XdmcpNetaddr) &sock, (int)sizeof (struct sockaddr_in)); - added_addr = &qa->sin_addr; - } + { + sock.sin_addr.s_addr = qa->sin_addr.s_addr; + XdmcpFlush (sockfd, &querybuf, (XdmcpNetaddr) &sock, (int)sizeof (struct sockaddr_in)); + added_addr = &qa->sin_addr; + } g_free (added_host); added_host = g_strdup (name); @@ -1527,13 +1527,13 @@ gdm_chooser_add_host (void) XdmcpFlush (sockfd, &querybuf, (XdmcpNetaddr) &sock6, (int)sizeof (struct sockaddr_in6)); } else #endif - { - added_addr = &qa->sin_addr; + { + added_addr = &qa->sin_addr; - /* and send out the query */ - sock.sin_addr.s_addr = qa->sin_addr.s_addr; - XdmcpFlush (sockfd, &querybuf, (XdmcpNetaddr) &sock, (int)sizeof (struct sockaddr_in)); - } + /* and send out the query */ + sock.sin_addr.s_addr = qa->sin_addr.s_addr; + XdmcpFlush (sockfd, &querybuf, (XdmcpNetaddr) &sock, (int)sizeof (struct sockaddr_in)); + } g_free (added_host); added_host = g_strdup (name); if (add_check_handler > 0) @@ -1562,34 +1562,31 @@ gdm_chooser_add_entry_changed (void) void gdm_chooser_cancel (int sig) { - if (scan_time_handler > 0) { - g_source_remove (scan_time_handler); - scan_time_handler = 0; - } - - closelog (); - /* exit rather gtk_main_quit, it's just safer this way we don't - have to worry about random whackiness happening */ - exit (EXIT_SUCCESS); + if (scan_time_handler > 0) { + g_source_remove (scan_time_handler); + scan_time_handler = 0; + } + + /* exit rather gtk_main_quit, it's just safer this way we don't + have to worry about random whackiness happening */ + exit (EXIT_SUCCESS); } void gdm_chooser_manage (GtkButton *button, gpointer data) { - if (scan_time_handler > 0) { - g_source_remove (scan_time_handler); - scan_time_handler = 0; - } - - if (curhost) - gdm_chooser_choose_host (curhost->name); - - closelog (); - - /* exit rather gtk_main_quit, it's just safer this way we don't - have to worry about random whackiness happening */ - exit (EXIT_SUCCESS); + if (scan_time_handler > 0) { + g_source_remove (scan_time_handler); + scan_time_handler = 0; + } + + if (curhost) + gdm_chooser_choose_host (curhost->name); + + /* exit rather gtk_main_quit, it's just safer this way we don't + have to worry about random whackiness happening */ + exit (EXIT_SUCCESS); } static void @@ -1782,8 +1779,6 @@ gdm_read_config (void) /* Read config data in bulk */ gdmcomm_comm_bulk_start (); - gdmcomm_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG)); - /* * Read all the keys at once and close sockets connection so we do * not have to keep the socket open. @@ -1817,9 +1812,6 @@ gdm_reread_config (int sig, gpointer data) /* Read config data in bulk */ gdmcomm_comm_bulk_start (); - if (gdm_config_reload_bool (GDM_KEY_DEBUG)) - gdmcomm_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG)); - /* FIXME: The following is evil, we should update on the fly rather * then just restarting */ /* Also we may not need to check ALL those keys but just a few */ @@ -1855,7 +1847,7 @@ gdm_reread_config (int sig, gpointer data) if (gdm_config_get_int (GDM_KEY_BACKGROUND_TYPE) != GDM_BACKGROUND_NONE) { gdm_common_setup_background_color (gdm_config_get_string - (GDM_KEY_BACKGROUND_COLOR)); + (GDM_KEY_BACKGROUND_COLOR)); } } @@ -1868,56 +1860,56 @@ gdm_reread_config (int sig, gpointer data) static void gdm_chooser_signals_init (void) { - struct sigaction hup; - struct sigaction term; - sigset_t mask; - - ve_signal_add (SIGHUP, gdm_reread_config, NULL); - - hup.sa_handler = ve_signal_notify; - hup.sa_flags = 0; - sigemptyset (&hup.sa_mask); - sigaddset (&hup.sa_mask, SIGCHLD); - - term.sa_handler = gdm_chooser_cancel; - term.sa_flags = 0; - sigemptyset (&term.sa_mask); - - if (sigaction (SIGHUP, &hup, NULL) < 0) { - gdm_common_fail_exit ("%s: Error setting up %s signal handler: %s", - "gdm_signals_init", "HUP", strerror (errno)); - } - - if (sigaction (SIGINT, &term, NULL) < 0) { - gdm_common_fail_exit ("%s: Error setting up %s signal handler: %s", - "gdm_signals_init", "INT", strerror (errno)); - } - - if (sigaction (SIGTERM, &term, NULL) < 0) { - gdm_common_fail_exit ("%s: Error setting up %s signal handler: %s", - "gdm_signals_init", "TERM", strerror (errno)); - } - - sigfillset (&mask); - sigdelset (&mask, SIGTERM); - sigdelset (&mask, SIGHUP); - sigdelset (&mask, SIGINT); + struct sigaction hup; + struct sigaction term; + sigset_t mask; + + ve_signal_add (SIGHUP, gdm_reread_config, NULL); + + hup.sa_handler = ve_signal_notify; + hup.sa_flags = 0; + sigemptyset (&hup.sa_mask); + sigaddset (&hup.sa_mask, SIGCHLD); + + term.sa_handler = gdm_chooser_cancel; + term.sa_flags = 0; + sigemptyset (&term.sa_mask); + + if (sigaction (SIGHUP, &hup, NULL) < 0) { + gdm_common_fail_exit ("%s: Error setting up %s signal handler: %s", + "gdm_signals_init", "HUP", strerror (errno)); + } + + if (sigaction (SIGINT, &term, NULL) < 0) { + gdm_common_fail_exit ("%s: Error setting up %s signal handler: %s", + "gdm_signals_init", "INT", strerror (errno)); + } + + if (sigaction (SIGTERM, &term, NULL) < 0) { + gdm_common_fail_exit ("%s: Error setting up %s signal handler: %s", + "gdm_signals_init", "TERM", strerror (errno)); + } + + sigfillset (&mask); + sigdelset (&mask, SIGTERM); + sigdelset (&mask, SIGHUP); + sigdelset (&mask, SIGINT); - if (sigprocmask (SIG_SETMASK, &mask, NULL) == -1) - gdm_common_fail_exit ("Could not set signal mask!"); + if (sigprocmask (SIG_SETMASK, &mask, NULL) == -1) + gdm_common_fail_exit ("Could not set signal mask!"); } GOptionEntry chooser_options [] = { - { "xdmaddress", '\0', 0, G_OPTION_ARG_STRING, &xdm_address, + { "xdmaddress", '\0', 0, G_OPTION_ARG_STRING, &xdm_address, N_("Socket for xdm communication"), N_("SOCKET") }, - { "clientaddress", '\0', 0, G_OPTION_ARG_STRING, &client_address, + { "clientaddress", '\0', 0, G_OPTION_ARG_STRING, &client_address, N_("Client address to return in response to xdm"), N_("ADDRESS") }, - { "connectionType", '\0', 0, G_OPTION_ARG_INT, &connection_type, + { "connectionType", '\0', 0, G_OPTION_ARG_INT, &connection_type, N_("Connection type to return in response to xdm"), N_("TYPE") }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &chooser_hosts, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &chooser_hosts, NULL, NULL }, - { NULL } - }; + { NULL } +}; static gboolean gdm_event (GSignalInvocationHint *ihint, @@ -1933,7 +1925,7 @@ gdm_event (GSignalInvocationHint *ihint, * to a left mouse click */ if (n_param_values != 2 || !G_VALUE_HOLDS (¶m_values[1], GDK_TYPE_EVENT)) - return FALSE; + return FALSE; event = g_value_get_boxed (¶m_values[1]); if ((event->type == GDK_BUTTON_PRESS || @@ -1949,171 +1941,171 @@ gdm_event (GSignalInvocationHint *ihint, int main (int argc, char *argv[]) { - gchar *GdmHosts; - gchar **hosts_opt = NULL; - GOptionContext *ctx; - const char *gdm_version; - int i; - guint sid; - - stored_argv = g_new0 (char *, argc + 1); - for (i = 0; i < argc; i++) - stored_argv[i] = g_strdup (argv[i]); - stored_argv[i] = NULL; - stored_argc = argc; - - if (g_getenv ("RUNNING_UNDER_GDM") != NULL) - RUNNING_UNDER_GDM = TRUE; - - gdm_common_openlog ("gdmchooser", LOG_PID, LOG_DAEMON); - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); - - gtk_init (&argc, &argv); - - ctx = g_option_context_new (_("- gdm login chooser")); - g_option_context_add_main_entries(ctx, chooser_options, _("main options")); - g_option_context_parse(ctx, &argc, &argv, NULL); - g_option_context_free(ctx); - - glade_init (); - - /* Read all configuration at once, so the values get cached */ - gdm_read_config (); - - GdmHosts = g_strdup (gdm_config_get_string (GDM_KEY_HOSTS)); - - /* if broadcasting, then append BROADCAST to hosts */ - if (gdm_config_get_bool (GDM_KEY_BROADCAST)) { - gchar *tmp; - if (ve_string_empty (GdmHosts)) { - tmp = "BROADCAST"; - } else { - tmp = g_strconcat (GdmHosts, ",BROADCAST", NULL); - } - g_free (GdmHosts); - GdmHosts = tmp; - } + gchar *GdmHosts; + gchar **hosts_opt = NULL; + GOptionContext *ctx; + const char *gdm_version; + int i; + guint sid; + + stored_argv = g_new0 (char *, argc + 1); + for (i = 0; i < argc; i++) + stored_argv[i] = g_strdup (argv[i]); + stored_argv[i] = NULL; + stored_argc = argc; + + if (g_getenv ("RUNNING_UNDER_GDM") != NULL) + RUNNING_UNDER_GDM = TRUE; + + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + gtk_init (&argc, &argv); + + ctx = g_option_context_new (_("- gdm login chooser")); + g_option_context_add_main_entries(ctx, chooser_options, _("main options")); + g_option_context_parse(ctx, &argc, &argv, NULL); + g_option_context_free(ctx); + + glade_init (); + + gdm_common_log_init (); + gdm_common_log_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG)); + + /* Read all configuration at once, so the values get cached */ + gdm_read_config (); + + GdmHosts = g_strdup (gdm_config_get_string (GDM_KEY_HOSTS)); + + /* if broadcasting, then append BROADCAST to hosts */ + if (gdm_config_get_bool (GDM_KEY_BROADCAST)) { + gchar *tmp; + if (ve_string_empty (GdmHosts)) { + tmp = "BROADCAST"; + } else { + tmp = g_strconcat (GdmHosts, ",BROADCAST", NULL); + } + g_free (GdmHosts); + GdmHosts = tmp; + } #ifdef ENABLE_IPV6 - if (gdm_config_get_bool (GDM_KEY_MULTICAST)) { - gchar *tmp; - if (ve_string_empty (GdmHosts)) { - tmp = "MULTICAST"; - } else { - tmp = g_strconcat (GdmHosts, ",MULTICAST", NULL); - } - g_free (GdmHosts); - GdmHosts = tmp; - } + if (gdm_config_get_bool (GDM_KEY_MULTICAST)) { + gchar *tmp; + if (ve_string_empty (GdmHosts)) { + tmp = "MULTICAST"; + } else { + tmp = g_strconcat (GdmHosts, ",MULTICAST", NULL); + } + g_free (GdmHosts); + GdmHosts = tmp; + } #endif - if (RUNNING_UNDER_GDM) - gdm_wm_screen_init (gdm_config_get_int (GDM_KEY_XINERAMA_SCREEN)); + if (RUNNING_UNDER_GDM) + gdm_wm_screen_init (gdm_config_get_int (GDM_KEY_XINERAMA_SCREEN)); - gdm_version = g_getenv ("GDM_VERSION"); + gdm_version = g_getenv ("GDM_VERSION"); - /* Load the background as early as possible so GDM does not leave */ - /* the background unfilled. The cursor should be a watch already */ - /* but just in case */ - if (RUNNING_UNDER_GDM) { - if (gdm_config_get_int (GDM_KEY_BACKGROUND_TYPE) != GDM_BACKGROUND_NONE) - gdm_common_setup_background_color (gdm_config_get_string (GDM_KEY_BACKGROUND_COLOR)); + /* Load the background as early as possible so GDM does not leave */ + /* the background unfilled. The cursor should be a watch already */ + /* but just in case */ + if (RUNNING_UNDER_GDM) { + if (gdm_config_get_int (GDM_KEY_BACKGROUND_TYPE) != GDM_BACKGROUND_NONE) + gdm_common_setup_background_color (gdm_config_get_string (GDM_KEY_BACKGROUND_COLOR)); - gdm_common_setup_cursor (GDK_WATCH); - } + gdm_common_setup_cursor (GDK_WATCH); + } - if (RUNNING_UNDER_GDM && - gdm_version != NULL && - strcmp (gdm_version, VERSION) != 0) { - GtkWidget *dialog; - gchar *msg; + if (RUNNING_UNDER_GDM && + gdm_version != NULL && + strcmp (gdm_version, VERSION) != 0) { + GtkWidget *dialog; + gchar *msg; - gdm_wm_init (0); + gdm_wm_init (0); - gdm_wm_focus_new_windows (TRUE); + gdm_wm_focus_new_windows (TRUE); - msg = g_strdup_printf (_("The chooser version (%s) does not match the daemon " - "version (%s). " - "You have probably just upgraded GDM. " - "Please restart the GDM daemon or the computer."), - VERSION, gdm_version); + msg = g_strdup_printf (_("The chooser version (%s) does not match the daemon " + "version (%s). " + "You have probably just upgraded GDM. " + "Please restart the GDM daemon or the computer."), + VERSION, gdm_version); - dialog = hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Cannot run chooser"), - msg); - g_free (msg); + dialog = hig_dialog_new (NULL /* parent */, + GTK_DIALOG_MODAL /* flags */, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Cannot run chooser"), + msg); + g_free (msg); - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); + gtk_widget_show_all (dialog); + gdm_wm_center_window (GTK_WINDOW (dialog)); - gdm_common_setup_cursor (GDK_LEFT_PTR); + gdm_common_setup_cursor (GDK_LEFT_PTR); - gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_dialog_run (GTK_DIALOG (dialog)); - return EXIT_SUCCESS; - } + return EXIT_SUCCESS; + } - gtk_window_set_default_icon_from_file (DATADIR"/pixmaps/gdm-xnest.png", NULL); - - gdm_chooser_gui_init (); - gdm_chooser_signals_init (); - - /* when no hosts on the command line, take them from the config */ - if (hosts_opt == NULL || - hosts_opt[0] == NULL) { - int i; - hosts_opt = g_strsplit (GdmHosts, ",", -1); - for (i = 0; hosts_opt != NULL && hosts_opt[i] != NULL; i++) { - g_strstrip (hosts_opt[i]); - } - } - gdm_chooser_xdmcp_init (hosts_opt); - g_strfreev (hosts_opt); - - sid = g_signal_lookup ("event", - GTK_TYPE_WIDGET); - g_signal_add_emission_hook (sid, - 0 /* detail */, - gdm_event, - NULL /* data */, - NULL /* destroy_notify */); - - gtk_widget_queue_resize (chooser); - gtk_widget_show_now (chooser); - - if (RUNNING_UNDER_GDM) - gdm_wm_center_window (GTK_WINDOW (chooser)); - - if (RUNNING_UNDER_GDM && - /* can it ever happen that it'd be NULL here ??? */ - chooser->window != NULL) { - gdm_wm_init (GDK_WINDOW_XWINDOW (chooser->window)); - - /* Run the focus, note that this will work no matter what - * since gdm_wm_init will set the display to the gdk one - * if it fails */ - gdm_wm_focus_window (GDK_WINDOW_XWINDOW (chooser->window)); - } - - if (gdm_config_get_bool (GDM_KEY_ALLOW_ADD)) - gtk_widget_grab_focus (add_entry); - - gdm_chooser_add_entry_changed (); - - if (RUNNING_UNDER_GDM) { - gdm_wm_restore_wm_order (); - gdm_common_setup_cursor (GDK_LEFT_PTR); - } - - gtk_main (); - - exit (EXIT_SUCCESS); -} + gtk_window_set_default_icon_from_file (DATADIR"/pixmaps/gdm-xnest.png", NULL); + + gdm_chooser_gui_init (); + gdm_chooser_signals_init (); + + /* when no hosts on the command line, take them from the config */ + if (hosts_opt == NULL || + hosts_opt[0] == NULL) { + int i; + hosts_opt = g_strsplit (GdmHosts, ",", -1); + for (i = 0; hosts_opt != NULL && hosts_opt[i] != NULL; i++) { + g_strstrip (hosts_opt[i]); + } + } + gdm_chooser_xdmcp_init (hosts_opt); + g_strfreev (hosts_opt); + + sid = g_signal_lookup ("event", + GTK_TYPE_WIDGET); + g_signal_add_emission_hook (sid, + 0 /* detail */, + gdm_event, + NULL /* data */, + NULL /* destroy_notify */); + + gtk_widget_queue_resize (chooser); + gtk_widget_show_now (chooser); + + if (RUNNING_UNDER_GDM) + gdm_wm_center_window (GTK_WINDOW (chooser)); + if (RUNNING_UNDER_GDM && + /* can it ever happen that it'd be NULL here ??? */ + chooser->window != NULL) { + gdm_wm_init (GDK_WINDOW_XWINDOW (chooser->window)); + + /* Run the focus, note that this will work no matter what + * since gdm_wm_init will set the display to the gdk one + * if it fails */ + gdm_wm_focus_window (GDK_WINDOW_XWINDOW (chooser->window)); + } + + if (gdm_config_get_bool (GDM_KEY_ALLOW_ADD)) + gtk_widget_grab_focus (add_entry); + + gdm_chooser_add_entry_changed (); + + if (RUNNING_UNDER_GDM) { + gdm_wm_restore_wm_order (); + gdm_common_setup_cursor (GDK_LEFT_PTR); + } + + gtk_main (); + + exit (EXIT_SUCCESS); +} /* EOF */ diff --git a/gui/gdmcomm.c b/gui/gdmcomm.c index d20f7081..391ef661 100644 --- a/gui/gdmcomm.c +++ b/gui/gdmcomm.c @@ -1,21 +1,22 @@ -/* +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * * GDMcommunication routines * (c)2001 Queen of England, (c)2002,2003 George Lebl - * + * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * + * */ #include "config.h" @@ -41,28 +42,14 @@ #include "gdmconfig.h" #include "gdm-common.h" +#include "gdm-socket-protocol.h" #include "gdm-daemon-config-keys.h" static gboolean bulk_acs = FALSE; -static gboolean debug = FALSE; static gboolean quiet = FALSE; static int num_cmds = 0; /* - * Note, in this function we have to call gdm_common_error instead - * of gdm_common_debug, since gdm_common_debug accesses the - * GDM_KEY_DEBUG which can cause a sockets connection to get the - * config data, causing an infinite loop. This is why clients must - * call the gdmcomm_set_debug function to turn on debug for these - * functions. - */ -void -gdmcomm_set_debug (gboolean enable) -{ - debug = enable; -} - -/* * Normally errors are printed. Setting quiet to TRUE turns off * display of error messages. */ @@ -83,9 +70,7 @@ do_command (int fd, const char *command, gboolean get_response) void (*old_handler)(int); #endif - if (debug) { - gdm_common_error ("Sending command: '%s'", command); - } + gdm_common_debug ("Sending command: '%s'", command); cstr = g_strdup_printf ("%s\n", command); @@ -102,7 +87,7 @@ do_command (int fd, const char *command, gboolean get_response) if (ret < 0) { if ( !quiet) - gdm_common_error ("Command failed, no data returned"); + gdm_common_debug ("Command failed, no data returned"); return NULL; } @@ -116,8 +101,7 @@ do_command (int fd, const char *command, gboolean get_response) g_string_append_c (str, buf[0]); } - if (debug) - gdm_common_error (" Got response: '%s'", str->str); + gdm_common_debug (" Got response: '%s'", str->str); cstr = str->str; g_string_free (str, FALSE); @@ -135,7 +119,7 @@ do_command (int fd, const char *command, gboolean get_response) if (ve_string_empty (cstr) || strcmp (ve_sure_string (cstr), "ERROR 200 Too many messages") == 0) { if ( !quiet) - gdm_common_error ("Command failed, daemon busy."); + gdm_common_debug ("Command failed, daemon busy."); g_free (cstr); return NULL; } @@ -181,23 +165,22 @@ gdmcomm_call_gdm_real (const char *command, * and reopen. Subtract 1 to allow the "CLOSE" to get through. */ if (num_cmds == (GDM_SUP_MAX_MESSAGES - 1)) { - if (debug) - gdm_common_error (" Closing and reopening connection."); - do_command (comm_fd, GDM_SUP_CLOSE, FALSE); - VE_IGNORE_EINTR (close (comm_fd)); - comm_fd = 0; - num_cmds = 0; + gdm_common_debug (" Closing and reopening connection."); + do_command (comm_fd, GDM_SUP_CLOSE, FALSE); + VE_IGNORE_EINTR (close (comm_fd)); + comm_fd = 0; + num_cmds = 0; } if (tries <= 0) { if ( !quiet) - gdm_common_error (" Command failed %d times, aborting.", try_start); + gdm_common_debug (" Command failed %d times, aborting.", try_start); return NULL; } if (!quiet && tries != try_start) { - gdm_common_error (" Trying failed command again. Try %d of %d.", - (try_start - tries + 1), try_start); + gdm_common_debug (" Trying failed command again. Try %d of %d.", + (try_start - tries + 1), try_start); } if (comm_fd <= 0) { @@ -207,7 +190,7 @@ gdmcomm_call_gdm_real (const char *command, comm_fd = socket (AF_UNIX, SOCK_STREAM, 0); if (comm_fd < 0) { if ( !quiet) - gdm_common_error (" Failed to open socket"); + gdm_common_debug (" Failed to open socket"); return gdmcomm_call_gdm_real (command, auth_cookie, min_version, tries - 1, try_start); } @@ -235,17 +218,17 @@ gdmcomm_call_gdm_real (const char *command, */ if (tries > 1) { if ( !quiet) - gdm_common_error (" Failed to connect to socket, sleep 1 second and retry"); + gdm_common_debug (" Failed to connect to socket, sleep 1 second and retry"); sleep (1); } } else { if ( !quiet) - gdm_common_error (" Failed to connect to socket, not sleeping"); + gdm_common_debug (" Failed to connect to socket, not sleeping"); } VE_IGNORE_EINTR (close (comm_fd)); comm_fd = 0; return gdmcomm_call_gdm_real (command, auth_cookie, - min_version, tries - 1, try_start); + min_version, tries - 1, try_start); } /* @@ -260,15 +243,15 @@ gdmcomm_call_gdm_real (const char *command, ret = do_command (comm_fd, GDM_SUP_VERSION, TRUE); if (ret == NULL) { if ( !quiet) - gdm_common_error (" Version check failed"); + gdm_common_debug (" Version check failed"); VE_IGNORE_EINTR (close (comm_fd)); comm_fd = 0; return gdmcomm_call_gdm_real (command, auth_cookie, - min_version, tries - 1, try_start); + min_version, tries - 1, try_start); } if (strncmp (ret, "GDM ", strlen ("GDM ")) != 0) { if ( !quiet) - gdm_common_error (" Version check failed, bad name"); + gdm_common_debug (" Version check failed, bad name"); g_free (ret); do_command (comm_fd, GDM_SUP_CLOSE, FALSE); @@ -278,7 +261,7 @@ gdmcomm_call_gdm_real (const char *command, } if ( ! version_ok_p (&ret[4], min_version)) { if ( !quiet) - gdm_common_error (" Version check failed, bad version"); + gdm_common_debug (" Version check failed, bad version"); g_free (ret); do_command (comm_fd, GDM_SUP_CLOSE, FALSE); VE_IGNORE_EINTR (close (comm_fd)); @@ -298,12 +281,12 @@ gdmcomm_call_gdm_real (const char *command, VE_IGNORE_EINTR (close (comm_fd)); comm_fd = 0; return gdmcomm_call_gdm_real (command, auth_cookie, - min_version, tries - 1, try_start); + min_version, tries - 1, try_start); } /* not auth'ed */ if (strcmp (ve_sure_string (ret), "OK") != 0) { if ( !quiet) - gdm_common_error (" Error, auth check failed"); + gdm_common_debug (" Error, auth check failed"); do_command (comm_fd, GDM_SUP_CLOSE, FALSE); VE_IGNORE_EINTR (close (comm_fd)); comm_fd = 0; @@ -318,7 +301,7 @@ gdmcomm_call_gdm_real (const char *command, VE_IGNORE_EINTR (close (comm_fd)); comm_fd = 0; return gdmcomm_call_gdm_real (command, auth_cookie, - min_version, tries - 1, try_start); + min_version, tries - 1, try_start); } /* @@ -343,13 +326,13 @@ gdmcomm_call_gdm_real (const char *command, char * gdmcomm_call_gdm (const char *command, const char * auth_cookie, - const char *min_version, int tries) + const char *min_version, int tries) { char *retstr; retstr = gdmcomm_call_gdm_real (command, auth_cookie, min_version, - tries, tries); + tries, tries); /* * Disallow sleeping on future calls if it failed to connect. diff --git a/gui/gdmcommon.c b/gui/gdmcommon.c index 5692ea0a..eb478b50 100644 --- a/gui/gdmcommon.c +++ b/gui/gdmcommon.c @@ -27,7 +27,6 @@ #include <unistd.h> #include <locale.h> #include <string.h> -#include <syslog.h> #include <time.h> #include <sys/utsname.h> #include <sys/types.h> @@ -43,149 +42,157 @@ #include "gdmconfig.h" #include "gdm-common.h" +#include "gdm-log.h" +#include "gdm-socket-protocol.h" #include "gdm-daemon-config-keys.h" gint gdm_timed_delay = 0; static Atom AT_SPI_IOR; /* - * Some slaves want to send output to syslog and others (such as - * gdmflexiserver and gdmdynamic send error messages to stdout. + * Some slaves want to send output to syslog and others (such as + * gdmflexiserver and gdmdynamic send error messages to stdout. * Calling gdm_common_openlog to open the syslog sets the - * using_syslog flag so that calls to gdm_common_fail, - * gdm_common_info, gdm_common_error, and gdm_common_debug sends + * using_syslog flag so that calls to gdm_common_fail, + * gdm_common_info, gdm_common_error, and gdm_common_debug sends * output to the syslog if the syslog has been opened, otherwise * send to stdout. */ static gboolean using_syslog = FALSE; void -gdm_common_openlog (const char *ident, int logopt, int facility) +gdm_common_log_init (void) { - openlog (ident, logopt, facility); - using_syslog = TRUE; + gdm_log_init (); + + using_syslog = TRUE; +} + +void +gdm_common_log_set_debug (gboolean enable) +{ + gdm_log_set_debug (enable); } void gdm_common_fail_exit (const gchar *format, ...) { - va_list args; - gchar *s; + va_list args; + gchar *s; - if (!format) { - _exit (EXIT_FAILURE); - } + if (!format) { + _exit (EXIT_FAILURE); + } - va_start (args, format); - s = g_strdup_vprintf (format, args); - va_end (args); - - if (using_syslog) { - syslog (LOG_ERR, "%s", s); - closelog (); - } else - g_printf ("%s\n", s); + va_start (args, format); + s = g_strdup_vprintf (format, args); + va_end (args); - g_free (s); + if (using_syslog) { + g_critical ("%s", s); + } else { + g_printf ("%s\n", s); + } - _exit (EXIT_FAILURE); + g_free (s); + + _exit (EXIT_FAILURE); } void gdm_common_fail_greeter (const gchar *format, ...) { - va_list args; - gchar *s; + va_list args; + gchar *s; - if (!format) { - _exit (DISPLAY_GREETERFAILED); - } + if (!format) { + _exit (DISPLAY_GREETERFAILED); + } + + va_start (args, format); + s = g_strdup_vprintf (format, args); + va_end (args); - va_start (args, format); - s = g_strdup_vprintf (format, args); - va_end (args); - - if (using_syslog) { - syslog (LOG_ERR, "%s", s); - closelog (); - } else - g_printf ("%s\n", s); + if (using_syslog) { + g_critical ("%s", s); + } else + g_printf ("%s\n", s); - g_free (s); + g_free (s); - _exit (DISPLAY_GREETERFAILED); + _exit (DISPLAY_GREETERFAILED); } void gdm_common_info (const gchar *format, ...) { - va_list args; - gchar *s; - - va_start (args, format); - s = g_strdup_vprintf (format, args); - va_end (args); - - if (using_syslog) - syslog (LOG_INFO, "%s", s); - else - g_printf ("%s\n", s); - - g_free (s); + va_list args; + gchar *s; + + va_start (args, format); + s = g_strdup_vprintf (format, args); + va_end (args); + + if (using_syslog) { + g_message ("%s", s); + } else { + g_printf ("%s\n", s); + } + + g_free (s); } void gdm_common_error (const gchar *format, ...) { - va_list args; - gchar *s; - - va_start (args, format); - s = g_strdup_vprintf (format, args); - va_end (args); - - if (using_syslog) - syslog (LOG_ERR, "%s", s); - else - g_printf ("%s\n", s); - - g_free (s); + va_list args; + gchar *s; + + va_start (args, format); + s = g_strdup_vprintf (format, args); + va_end (args); + + if (using_syslog) { + g_critical ("%s", s); + } else { + g_printf ("%s\n", s); + } + + g_free (s); } void gdm_common_warning (const gchar *format, ...) { - va_list args; - gchar *s; - - va_start (args, format); - s = g_strdup_vprintf (format, args); - va_end (args); - - if (using_syslog) - syslog (LOG_WARNING, "%s", s); - else - g_printf ("%s\n", s); - - g_free (s); + va_list args; + gchar *s; + + va_start (args, format); + s = g_strdup_vprintf (format, args); + va_end (args); + + if (using_syslog) { + g_warning ("%s", s); + } else { + g_printf ("%s\n", s); + } + + g_free (s); } void gdm_common_debug (const gchar *format, ...) { - va_list args; - gchar *s; + va_list args; + gchar *s; - if G_LIKELY (! gdm_config_get_bool (GDM_KEY_DEBUG)) - return; + va_start (args, format); + s = g_strdup_vprintf (format, args); + va_end (args); - va_start (args, format); - s = g_strdup_vprintf (format, args); - va_end (args); + g_debug ("%s", s); - syslog (LOG_ERR, "%s", s); - closelog (); - g_free (s); + g_free (s); } void @@ -263,8 +270,7 @@ delay_noblink (GSignalInvocationHint *ihint, noblink_timeout = g_timeout_add (NOBLINK_TIMEOUT, no_blink, NULL); return TRUE; -} - +} void gdm_common_setup_blinking (void) @@ -272,37 +278,37 @@ gdm_common_setup_blinking (void) guint sid; if ( ! ve_string_empty (g_getenv ("GDM_IS_LOCAL")) && - strncmp (ve_sure_string (g_getenv ("DISPLAY")), ":0", 2) == 0) + strncmp (ve_sure_string (g_getenv ("DISPLAY")), ":0", 2) == 0) return; sid = g_signal_lookup ("activate", GTK_TYPE_MENU_ITEM); if (sid != 0) { - g_signal_add_emission_hook (sid, - 0 /* detail */, - delay_noblink, - NULL /* data */, - NULL /* destroy_notify */); + g_signal_add_emission_hook (sid, + 0 /* detail */, + delay_noblink, + NULL /* data */, + NULL /* destroy_notify */); } sid = g_signal_lookup ("key_press_event", GTK_TYPE_WIDGET); if (sid != 0) { - g_signal_add_emission_hook (sid, - 0 /* detail */, - delay_noblink, - NULL /* data */, - NULL /* destroy_notify */); + g_signal_add_emission_hook (sid, + 0 /* detail */, + delay_noblink, + NULL /* data */, + NULL /* destroy_notify */); } sid = g_signal_lookup ("button_press_event", GTK_TYPE_WIDGET); if (sid != 0) { - g_signal_add_emission_hook (sid, - 0 /* detail */, - delay_noblink, - NULL /* data */, - NULL /* destroy_notify */); + g_signal_add_emission_hook (sid, + 0 /* detail */, + delay_noblink, + NULL /* data */, + NULL /* destroy_notify */); } noblink_timeout = g_timeout_add (NOBLINK_TIMEOUT, no_blink, NULL); @@ -315,7 +321,7 @@ gdm_common_setup_blinking_entry (GtkWidget *entry) GtkSettings *settings; if ( ! ve_string_empty (g_getenv ("GDM_IS_LOCAL")) && - strncmp (ve_sure_string (g_getenv ("DISPLAY")), ":0", 2) == 0) + strncmp (ve_sure_string (g_getenv ("DISPLAY")), ":0", 2) == 0) return; eb = g_new0 (EntryBlink, 1); @@ -355,7 +361,7 @@ gdm_common_get_face (const char *filename, if (pixbuf) { guint w, h; - + w = gdk_pixbuf_get_width (pixbuf); h = gdk_pixbuf_get_height (pixbuf); @@ -380,7 +386,7 @@ gdm_common_get_face (const char *filename, return pixbuf; } -gchar * +gchar * gdm_common_get_config_file (void) { gchar *result; @@ -392,7 +398,7 @@ gdm_common_get_config_file (void) return NULL; if (ve_string_empty (result) || - strncmp (result, "OK ", 3) != 0) { + strncmp (result, "OK ", 3) != 0) { g_free (result); return NULL; } @@ -405,7 +411,7 @@ gdm_common_get_config_file (void) return config_file; } -gchar * +gchar * gdm_common_get_custom_config_file (void) { gchar *result; @@ -417,7 +423,7 @@ gdm_common_get_custom_config_file (void) return NULL; if (ve_string_empty (result) || - strncmp (result, "OK ", 3) != 0) { + strncmp (result, "OK ", 3) != 0) { g_free (result); return NULL; } @@ -443,10 +449,10 @@ gdm_common_select_time_format (void) atoi (val) != 0)) { return TRUE; } else if (val != NULL && - (val[0] == 'F' || - val[0] == 'f' || - val[0] == 'N' || - val[0] == 'n')) { + (val[0] == 'F' || + val[0] == 'f' || + val[0] == 'N' || + val[0] == 'n')) { return FALSE; } else { /* Value is "auto" (default), thus select according to @@ -469,34 +475,34 @@ gdm_common_select_time_format (void) void gdm_common_setup_background_color (gchar *bg_color) { - GdkColormap *colormap; - GdkColor color; - - if (bg_color == NULL || - bg_color[0] == '\0' || - ! gdk_color_parse (bg_color, &color)) - { - gdk_color_parse ("#007777", &color); - } - - g_free (bg_color); - - colormap = gdk_drawable_get_colormap - (gdk_get_default_root_window ()); - /* paranoia */ - if (colormap != NULL) - { - gboolean success; - gdk_error_trap_push (); - - gdk_colormap_alloc_colors (colormap, &color, 1, - FALSE, TRUE, &success); - gdk_window_set_background (gdk_get_default_root_window (), &color); - gdk_window_clear (gdk_get_default_root_window ()); - - gdk_flush (); - gdk_error_trap_pop (); - } + GdkColormap *colormap; + GdkColor color; + + if (bg_color == NULL || + bg_color[0] == '\0' || + ! gdk_color_parse (bg_color, &color)) + { + gdk_color_parse ("#007777", &color); + } + + g_free (bg_color); + + colormap = gdk_drawable_get_colormap + (gdk_get_default_root_window ()); + /* paranoia */ + if (colormap != NULL) + { + gboolean success; + gdk_error_trap_push (); + + gdk_colormap_alloc_colors (colormap, &color, 1, + FALSE, TRUE, &success); + gdk_window_set_background (gdk_get_default_root_window (), &color); + gdk_window_clear (gdk_get_default_root_window ()); + + gdk_flush (); + gdk_error_trap_pop (); + } } gchar * @@ -615,19 +621,18 @@ pre_atspi_launch (void){ } - -static GdkFilterReturn +static GdkFilterReturn filter_watch (GdkXEvent *xevent, GdkEvent *event, gpointer data){ - XEvent *xev = (XEvent *)xevent; + XEvent *xev = (XEvent *)xevent; + + if (xev->xany.type == PropertyNotify && + xev->xproperty.atom == AT_SPI_IOR){ + gtk_main_quit (); - if (xev->xany.type == PropertyNotify && - xev->xproperty.atom == AT_SPI_IOR){ - gtk_main_quit (); - - return GDK_FILTER_REMOVE; - } + return GDK_FILTER_REMOVE; + } - return GDK_FILTER_CONTINUE; + return GDK_FILTER_CONTINUE; } static gboolean @@ -643,21 +648,21 @@ filter_timeout (gpointer data) void gdm_common_atspi_launch (void) { - GdkWindow *w = gdk_get_default_root_window (); + GdkWindow *w = gdk_get_default_root_window (); gboolean a11y = gdm_config_get_bool (GDM_KEY_ADD_GTK_MODULES); guint tid; if (! a11y) return; - + if ( ! AT_SPI_IOR) AT_SPI_IOR = XInternAtom (GDK_DISPLAY (), "AT_SPI_IOR", False); - gdk_window_set_events (w, GDK_PROPERTY_CHANGE_MASK); - + gdk_window_set_events (w, GDK_PROPERTY_CHANGE_MASK); + if ( ! pre_atspi_launch ()) { gdm_common_info (_("The accessibility registry could not be started.")); - + return; } gdk_window_add_filter (w, filter_watch, NULL); @@ -733,145 +738,134 @@ gdm_common_get_clock (struct tm **the_tm) char * gdm_common_expand_text (const gchar *text) { - GString *str; - const char *p; - gchar *clock, *display; - int r, i, n_chars; - gboolean underline = FALSE; - gchar buf[256]; - struct utsname name; - struct tm *the_tm; - - str = g_string_sized_new (strlen (text)); - - p = text; - n_chars = g_utf8_strlen (text, -1); - i = 0; - - while (i < n_chars) - { - gunichar ch; - - ch = g_utf8_get_char (p); - - /* Backslash commands */ - if (ch == '\\') - { - p = g_utf8_next_char (p); - i++; - ch = g_utf8_get_char (p); - - if (i >= n_chars || ch == '\0') - { - g_warning ("Unescaped \\ at end of text\n"); - goto bail; - } - else if (ch == 'n') - g_string_append_unichar (str, '\n'); - else - g_string_append_unichar (str, ch); - } - else if (ch == '%') - { - p = g_utf8_next_char (p); - i++; - ch = g_utf8_get_char (p); - - if (i >= n_chars || ch == '\0') - { - g_warning ("Unescaped %% at end of text\n"); - goto bail; - } - - switch (ch) - { - case '%': - g_string_append (str, "%"); - break; - case 'c': - clock = gdm_common_get_clock (&the_tm); - g_string_append (str, clock); - g_free (clock); - break; - case 'd': - display = g_strdup (g_getenv ("DISPLAY")); - g_string_append (str, display); - break; - case 'h': - buf[sizeof (buf) - 1] = '\0'; - r = gethostname (buf, sizeof (buf) - 1); - if (r) - g_string_append (str, "localhost"); - else - g_string_append (str, buf); - break; - case 'm': - uname (&name); - g_string_append (str, name.machine); - break; - case 'n': - uname (&name); - g_string_append (str, name.nodename); - break; - case 'o': - buf[sizeof (buf) - 1] = '\0'; - r = getdomainname (buf, sizeof (buf) - 1); - if (r) - g_string_append (str, "localdomain"); - else - g_string_append (str, buf); - break; - case 'r': - uname (&name); - g_string_append (str, name.release); - break; - case 's': - uname (&name); - g_string_append (str, name.sysname); - break; - case 't': - g_string_append_printf (str, ngettext("%d second", "%d seconds", gdm_timed_delay), - gdm_timed_delay); - break; - case 'u': - g_string_append (str, ve_sure_string (g_getenv("GDM_TIMED_LOGIN_OK"))); - break; - default: - if (ch < 127) - g_warning ("unknown escape code %%%c in text\n", (char)ch); - else - g_warning ("unknown escape code %%(U%x) in text\n", (int)ch); - } - } - else if (ch == '_') - { - /* - * Could be true if an underscore was put right before a special - * character like % or / - */ - if (underline == FALSE) { - underline = TRUE; - g_string_append (str, "<u>"); - } - } - else - { - g_string_append_unichar (str, ch); - if (underline) - { - underline = FALSE; - g_string_append (str, "</u>"); - } + GString *str; + const char *p; + gchar *clock, *display; + int r, i, n_chars; + gboolean underline = FALSE; + gchar buf[256]; + struct utsname name; + struct tm *the_tm; + + str = g_string_sized_new (strlen (text)); + + p = text; + n_chars = g_utf8_strlen (text, -1); + i = 0; + + while (i < n_chars) { + gunichar ch; + + ch = g_utf8_get_char (p); + + /* Backslash commands */ + if (ch == '\\') { + p = g_utf8_next_char (p); + i++; + ch = g_utf8_get_char (p); + + if (i >= n_chars || ch == '\0') { + g_warning ("Unescaped \\ at end of text\n"); + goto bail; + } + else if (ch == 'n') + g_string_append_unichar (str, '\n'); + else + g_string_append_unichar (str, ch); + } + else if (ch == '%') { + p = g_utf8_next_char (p); + i++; + ch = g_utf8_get_char (p); + + if (i >= n_chars || ch == '\0') { + g_warning ("Unescaped %% at end of text\n"); + goto bail; + } + + switch (ch) { + case '%': + g_string_append (str, "%"); + break; + case 'c': + clock = gdm_common_get_clock (&the_tm); + g_string_append (str, clock); + g_free (clock); + break; + case 'd': + display = g_strdup (g_getenv ("DISPLAY")); + g_string_append (str, display); + break; + case 'h': + buf[sizeof (buf) - 1] = '\0'; + r = gethostname (buf, sizeof (buf) - 1); + if (r) + g_string_append (str, "localhost"); + else + g_string_append (str, buf); + break; + case 'm': + uname (&name); + g_string_append (str, name.machine); + break; + case 'n': + uname (&name); + g_string_append (str, name.nodename); + break; + case 'o': + buf[sizeof (buf) - 1] = '\0'; + r = getdomainname (buf, sizeof (buf) - 1); + if (r) + g_string_append (str, "localdomain"); + else + g_string_append (str, buf); + break; + case 'r': + uname (&name); + g_string_append (str, name.release); + break; + case 's': + uname (&name); + g_string_append (str, name.sysname); + break; + case 't': + g_string_append_printf (str, ngettext("%d second", "%d seconds", gdm_timed_delay), + gdm_timed_delay); + break; + case 'u': + g_string_append (str, ve_sure_string (g_getenv("GDM_TIMED_LOGIN_OK"))); + break; + default: + if (ch < 127) + g_warning ("unknown escape code %%%c in text\n", (char)ch); + else + g_warning ("unknown escape code %%(U%x) in text\n", (int)ch); + } + } else if (ch == '_') { + /* + * Could be true if an underscore was put right before a special + * character like % or / + */ + if (underline == FALSE) { + underline = TRUE; + g_string_append (str, "<u>"); + } + } else { + g_string_append_unichar (str, ch); + if (underline) { + underline = FALSE; + g_string_append (str, "</u>"); + } + } + p = g_utf8_next_char (p); + i++; } - p = g_utf8_next_char (p); - i++; - } - + bail: - if (underline) - g_string_append (str, "</u>"); + if (underline) + g_string_append (str, "</u>"); - return g_string_free (str, FALSE); + return g_string_free (str, FALSE); } diff --git a/gui/gdmcommon.h b/gui/gdmcommon.h index 58dd37b5..f6481e0d 100644 --- a/gui/gdmcommon.h +++ b/gui/gdmcommon.h @@ -24,14 +24,13 @@ #ifndef GDM_COMMON_H #define GDM_COMMON_H -#include <gtk/gtk.h> +#include <gtk/gtk.h> #include "misc.h" /* Handle error messages */ -void gdm_common_openlog (const char *ident, - int logopt, - int facility); +void gdm_common_log_init (void); +void gdm_common_log_set_debug (gboolean enable); void gdm_common_fail_exit (const gchar *format, ...) G_GNUC_PRINTF (1, 2); void gdm_common_fail_greeter (const gchar *format, ...) diff --git a/gui/gdmconfig.c b/gui/gdmconfig.c index 2d30dc05..90f43c9d 100644 --- a/gui/gdmconfig.c +++ b/gui/gdmconfig.c @@ -22,6 +22,7 @@ */ #include <stdlib.h> +#include <string.h> #include <gtk/gtk.h> #include "config.h" @@ -33,6 +34,8 @@ #include "gdm-common.h" +#include "server.h" + static GHashTable *int_hash = NULL; static GHashTable *bool_hash = NULL; static GHashTable *string_hash = NULL; diff --git a/gui/gdmdynamic.c b/gui/gdmdynamic.c index 293a0e37..d1eaf77d 100644 --- a/gui/gdmdynamic.c +++ b/gui/gdmdynamic.c @@ -42,6 +42,8 @@ #include "gdmconfig.h" #include "gdm-common.h" +#include "gdm-log.h" +#include "gdm-socket-protocol.h" #include "gdm-daemon-config-keys.h" static char *myname = NULL; /* name of this program */ @@ -172,7 +174,9 @@ main (int argc, char *argv[]) } } - gdmcomm_set_debug (verbose); + gdm_log_init (); + gdm_log_set_debug (verbose); + /* * If verbose is not on, then set quiet errors to TRUE since * errors are expected and managed by gdmdynamic, so we want diff --git a/gui/gdmflexiserver.c b/gui/gdmflexiserver.c index ef341d88..57cfca49 100644 --- a/gui/gdmflexiserver.c +++ b/gui/gdmflexiserver.c @@ -37,13 +37,18 @@ #include <gdk/gdkx.h> #include <gtk/gtk.h> +#include <X11/Xauth.h> + #include "gdm.h" #include "gdmcomm.h" #include "gdmcommon.h" #include "gdmconfig.h" #include "gdm-common.h" +#include "gdm-log.h" +#include "gdm-socket-protocol.h" #include "gdm-daemon-config-keys.h" +#include "server.h" static GSList *xservers = NULL; static const char *send_command = NULL; @@ -756,7 +761,8 @@ main (int argc, char *argv[]) return 0; } - gdmcomm_set_debug (debug_in); + gdm_log_init (); + gdm_log_set_debug (debug_in); if (args_remaining != NULL && args_remaining[0] != NULL) server = args_remaining[0]; diff --git a/gui/gdmlanguages.c b/gui/gdmlanguages.c index 55bee17a..da167a3c 100644 --- a/gui/gdmlanguages.c +++ b/gui/gdmlanguages.c @@ -34,6 +34,8 @@ #include "gdmconfig.h" #include "gdmlanguages.h" +#include "gdm-socket-protocol.h" + #define LAST_LANGUAGE "Last" #define DEFAULT_LANGUAGE "Default" diff --git a/gui/gdmlogin.c b/gui/gdmlogin.c index 1755bcf3..9e6a2a85 100644 --- a/gui/gdmlogin.c +++ b/gui/gdmlogin.c @@ -24,7 +24,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <syslog.h> #include <fcntl.h> #include <unistd.h> #include <ctype.h> @@ -62,6 +61,7 @@ #include "misc.h" #include "gdm-common.h" +#include "gdm-socket-protocol.h" #include "gdm-daemon-config-keys.h" /* @@ -696,8 +696,6 @@ gdm_login_restart_handler (void) _("Are you sure you want to restart the computer?"), "", _("_Restart"), NULL, TRUE) == GTK_RESPONSE_YES) { - closelog (); - gdm_kill_thingies (); _exit (DISPLAY_REBOOT); } @@ -727,8 +725,6 @@ gdm_login_halt_handler (void) _("Are you sure you want to Shut Down the computer?"), "", _("Shut _Down"), NULL, TRUE) == GTK_RESPONSE_YES) { - closelog (); - gdm_kill_thingies (); _exit (DISPLAY_HALT); } @@ -737,8 +733,6 @@ gdm_login_halt_handler (void) static void gdm_login_use_chooser_handler (void) { - closelog (); - gdm_kill_thingies (); _exit (DISPLAY_RUN_CHOOSER); } @@ -2861,8 +2855,6 @@ gdm_read_config (void) /* Read config data in bulk */ gdmcomm_comm_bulk_start (); - gdmcomm_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG)); - /* * Read all the keys at once and close sockets connection so we do * not have to keep the socket open. @@ -2969,9 +2961,6 @@ gdm_reread_config (int sig, gpointer data) /* Read config data in bulk */ gdmcomm_comm_bulk_start (); - if (gdm_config_reload_bool (GDM_KEY_DEBUG)) - gdmcomm_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG)); - /* reparse config stuff here. At least the ones we care about */ /* * We don't want to reload GDM_KEY_POSITION_X, GDM_KEY_POSITION_Y @@ -3183,8 +3172,6 @@ main (int argc, char *argv[]) if (g_getenv ("DOING_GDM_DEVELOPMENT") != NULL) DOING_GDM_DEVELOPMENT = TRUE; - gdm_common_openlog ("gdmlogin", LOG_PID, LOG_DAEMON); - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); @@ -3204,6 +3191,9 @@ main (int argc, char *argv[]) if (ve_string_empty (g_getenv ("GDM_IS_LOCAL"))) disable_system_menu_buttons = TRUE; + gdm_common_log_init (); + gdm_common_log_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG)); + /* Read all configuration at once, so the values get cached */ gdm_read_config (); diff --git a/gui/gdmsession.c b/gui/gdmsession.c index 377f66dd..02219602 100644 --- a/gui/gdmsession.c +++ b/gui/gdmsession.c @@ -23,7 +23,9 @@ #include "config.h" +#include <stdlib.h> #include <unistd.h> +#include <string.h> #include <dirent.h> #include <gtk/gtk.h> #include <glib/gi18n.h> diff --git a/gui/gdmsetup.c b/gui/gdmsetup.c index 641bddbb..a0240f3c 100644 --- a/gui/gdmsetup.c +++ b/gui/gdmsetup.c @@ -50,8 +50,11 @@ #include "gdmconfig.h" #include "gdm-common.h" +#include "gdm-socket-protocol.h" #include "gdm-daemon-config-keys.h" +#include "server.h" + static char *GdmSoundProgram = NULL; static gchar *GdmExclude = NULL; static gchar *GdmInclude = NULL; diff --git a/gui/gdmuser.c b/gui/gdmuser.c index d2d24533..b46f7b4f 100644 --- a/gui/gdmuser.c +++ b/gui/gdmuser.c @@ -35,6 +35,7 @@ #include "gdmconfig.h" #include "gdm-common.h" +#include "gdm-socket-protocol.h" #include "gdm-daemon-config-keys.h" static time_t time_started; diff --git a/gui/gdmwm.c b/gui/gdmwm.c index d6c47506..806b944a 100644 --- a/gui/gdmwm.c +++ b/gui/gdmwm.c @@ -20,6 +20,11 @@ #include "config.h" +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <pwd.h> + #include <X11/X.h> #include <X11/Xlib.h> #include <X11/Xatom.h> @@ -28,8 +33,6 @@ #elif HAVE_SOLARIS_XINERAMA #include <X11/extensions/xinerama.h> #endif -#include <pwd.h> -#include <unistd.h> #include "gdmwm.h" #include "gdm.h" diff --git a/gui/greeter/greeter.c b/gui/greeter/greeter.c index eca10d34..83e7d352 100644 --- a/gui/greeter/greeter.c +++ b/gui/greeter/greeter.c @@ -23,7 +23,6 @@ #include <string.h> #include <unistd.h> #include <signal.h> -#include <syslog.h> #include <errno.h> #if HAVE_PAM @@ -39,6 +38,7 @@ #include <libgnomecanvas/libgnomecanvas.h> #include "gdm-common.h" +#include "gdm-socket-protocol.h" #include "gdm-daemon-config-keys.h" #include "gdm.h" @@ -826,8 +826,6 @@ gdm_read_config (void) /* Read config data in bulk */ gdmcomm_comm_bulk_start (); - gdmcomm_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG)); - /* * Read all the keys at once and close sockets connection so we do * not have to keep the socket open. @@ -919,9 +917,6 @@ greeter_reread_config (int sig, gpointer data) /* Read config data in bulk */ gdmcomm_comm_bulk_start (); - if (gdm_config_reload_bool (GDM_KEY_DEBUG)) - gdmcomm_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG)); - /* FIXME: The following is evil, we should update on the fly rather * then just restarting */ /* Also we may not need to check ALL those keys but just a few */ @@ -1198,8 +1193,6 @@ main (int argc, char *argv[]) if (g_getenv ("DOING_GDM_DEVELOPMENT") != NULL) DOING_GDM_DEVELOPMENT = TRUE; - gdm_common_openlog ("gdmgreeter", LOG_PID, LOG_DAEMON); - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); @@ -1220,11 +1213,14 @@ main (int argc, char *argv[]) if (! DOING_GDM_DEVELOPMENT) { gdm_common_atspi_launch (); } - + gtk_init (&argc, &argv); gdm_common_setup_cursor (GDK_WATCH); + gdm_common_log_init (); + gdm_common_log_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG)); + /* Read all configuration at once, so the values get cached */ gdm_read_config (); diff --git a/gui/greeter/greeter_item_customlist.c b/gui/greeter/greeter_item_customlist.c index 9527370b..4b56120c 100644 --- a/gui/greeter/greeter_item_customlist.c +++ b/gui/greeter/greeter_item_customlist.c @@ -18,6 +18,8 @@ #include "config.h" +#include <stdlib.h> +#include <string.h> #include <glib/gi18n.h> #include <gtk/gtk.h> diff --git a/gui/greeter/greeter_item_pam.c b/gui/greeter/greeter_item_pam.c index 12ae10e1..e0d24ad4 100644 --- a/gui/greeter/greeter_item_pam.c +++ b/gui/greeter/greeter_item_pam.c @@ -24,6 +24,7 @@ #include <gdk/gdkkeysyms.h> #include "gdm-common.h" +#include "gdm-socket-protocol.h" #include "greeter.h" #include "greeter_item.h" diff --git a/gui/greeter/greeter_item_timed.c b/gui/greeter/greeter_item_timed.c index dddc259a..ea6a50b6 100644 --- a/gui/greeter/greeter_item_timed.c +++ b/gui/greeter/greeter_item_timed.c @@ -25,6 +25,7 @@ #include "gdmconfig.h" #include "gdm-common.h" +#include "gdm-socket-protocol.h" #include "gdm-daemon-config-keys.h" #include "greeter_parser.h" diff --git a/gui/greeter/greeter_item_ulist.c b/gui/greeter/greeter_item_ulist.c index e3e8d5a6..f35693f5 100644 --- a/gui/greeter/greeter_item_ulist.c +++ b/gui/greeter/greeter_item_ulist.c @@ -40,6 +40,7 @@ #include "gdmuser.h" #include "gdm-common.h" +#include "gdm-socket-protocol.h" #include "gdm-daemon-config-keys.h" #include "greeter.h" diff --git a/gui/greeter/greeter_parser.c b/gui/greeter/greeter_parser.c index c64bce4c..a2a4878b 100644 --- a/gui/greeter/greeter_parser.c +++ b/gui/greeter/greeter_parser.c @@ -25,7 +25,6 @@ #include <librsvg/rsvg.h> #include <math.h> #include <locale.h> -#include <syslog.h> #include <glib/gi18n.h> #include <gdk/gdkx.h> #include <syslog.h> @@ -607,7 +606,7 @@ parse_show (xmlNodePtr node, prop = xmlGetProp (node,(const xmlChar *) "min-screen-width"); if (prop != NULL) { - syslog (LOG_ERR, "minimum width is %d", info->minimum_required_screen_height); + g_warning ("minimum width is %d", info->minimum_required_screen_height); info->minimum_required_screen_width = atoi ((char *) prop); xmlFree (prop); } @@ -616,7 +615,7 @@ parse_show (xmlNodePtr node, if (prop != NULL) { info->minimum_required_screen_height = atoi ((char *) prop); - syslog (LOG_ERR, "minimum height is %d", info->minimum_required_screen_height); + g_warning ("minimum height is %d", info->minimum_required_screen_height); xmlFree (prop); } diff --git a/gui/greeter/greeter_system.c b/gui/greeter/greeter_system.c index 83b95b1f..deb80440 100644 --- a/gui/greeter/greeter_system.c +++ b/gui/greeter/greeter_system.c @@ -19,7 +19,6 @@ #include "config.h" #include <unistd.h> -#include <syslog.h> #include <gtk/gtk.h> #include <glib/gi18n.h> @@ -31,6 +30,7 @@ #include "misc.h" #include "gdm-common.h" +#include "gdm-socket-protocol.h" #include "gdm-daemon-config-keys.h" #include "greeter.h" @@ -78,8 +78,6 @@ query_greeter_restart_handler (void) { if (gdm_wm_warn_dialog (_("Are you sure you want to restart the computer?"), "", _("_Restart"), NULL, TRUE) == GTK_RESPONSE_YES) { - closelog (); - _exit (DISPLAY_REBOOT); } } @@ -104,8 +102,6 @@ query_greeter_halt_handler (void) { if (gdm_wm_warn_dialog (_("Are you sure you want to Shut Down the computer?"), "", _("Shut _Down"), NULL, TRUE) == GTK_RESPONSE_YES) { - closelog (); - _exit (DISPLAY_HALT); } } @@ -124,7 +120,6 @@ query_greeter_suspend_handler (void) static void greeter_restart_handler (void) { - closelog (); _exit (DISPLAY_REBOOT); } @@ -138,7 +133,6 @@ greeter_custom_cmd_handler (gint cmd_id) static void greeter_halt_handler (void) { - closelog (); _exit (DISPLAY_HALT); } @@ -168,7 +162,6 @@ greeter_config_handler (void) static void greeter_chooser_handler (void) { - closelog (); _exit (DISPLAY_RUN_CHOOSER); } |