summaryrefslogtreecommitdiff
path: root/daemon
diff options
context:
space:
mode:
Diffstat (limited to 'daemon')
-rw-r--r--daemon/.cvsignore6
-rw-r--r--daemon/Makefile.am129
-rw-r--r--daemon/auth.c1008
-rw-r--r--daemon/auth.h35
-rw-r--r--daemon/choose.c363
-rw-r--r--daemon/choose.h48
-rw-r--r--daemon/cookie.c272
-rw-r--r--daemon/cookie.h31
-rw-r--r--daemon/display.c671
-rw-r--r--daemon/display.h218
-rw-r--r--daemon/errorgui.c890
-rw-r--r--daemon/errorgui.h53
-rw-r--r--daemon/filecheck.c222
-rw-r--r--daemon/filecheck.h33
-rw-r--r--daemon/fstype.c423
-rw-r--r--daemon/gdm-daemon-config-entries.h569
-rw-r--r--daemon/gdm-daemon-config-keys.h232
-rw-r--r--daemon/gdm-daemon-config.c2889
-rw-r--r--daemon/gdm-daemon-config.h108
-rw-r--r--daemon/gdm-net.c682
-rw-r--r--daemon/gdm-net.h96
-rw-r--r--daemon/gdm-socket-protocol.h247
-rw-r--r--daemon/gdm-xdmcp-manager.c2932
-rw-r--r--daemon/gdm-xdmcp-manager.h70
-rw-r--r--daemon/gdm.c4340
-rw-r--r--daemon/gdm.h94
-rw-r--r--daemon/gdm.in34
-rw-r--r--daemon/gdmconsolekit.c538
-rw-r--r--daemon/gdmconsolekit.h40
-rw-r--r--daemon/getvt.c312
-rw-r--r--daemon/getvt.h41
-rw-r--r--daemon/md5.c267
-rw-r--r--daemon/md5.h41
-rw-r--r--daemon/misc.c2171
-rw-r--r--daemon/misc.h175
-rw-r--r--daemon/server.c1594
-rw-r--r--daemon/server.h76
-rw-r--r--daemon/slave.c5877
-rw-r--r--daemon/slave.h49
-rw-r--r--daemon/verify-crypt.c451
-rw-r--r--daemon/verify-pam.c1673
-rw-r--r--daemon/verify-shadow.c475
-rw-r--r--daemon/verify.h44
-rw-r--r--daemon/xdmcp.c141
-rw-r--r--daemon/xdmcp.h31
45 files changed, 0 insertions, 30691 deletions
diff --git a/daemon/.cvsignore b/daemon/.cvsignore
deleted file mode 100644
index 6f47639e..00000000
--- a/daemon/.cvsignore
+++ /dev/null
@@ -1,6 +0,0 @@
-Makefile
-Makefile.in
-.deps
-.libs
-gdm
-gdm-binary
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
deleted file mode 100644
index 3ccb4b61..00000000
--- a/daemon/Makefile.am
+++ /dev/null
@@ -1,129 +0,0 @@
-NULL =
-
-# Note that we have cflags for just about everything even if
-# we don't link to everything
-INCLUDES = \
- -I. \
- -I.. \
- -I$(top_srcdir)/common \
- -DAUTHDIR=\"$(authdir)\" \
- -DBINDIR=\"$(bindir)\" \
- -DDATADIR=\"$(datadir)\" \
- -DDMCONFDIR=\"$(dmconfdir)\" \
- -DGDMCONFDIR=\"$(gdmconfdir)\" \
- -DGDMLOCALEDIR=\"$(gdmlocaledir)\" \
- -DLIBDIR=\"$(libdir)\" \
- -DLIBEXECDIR=\"$(libexecdir)\" \
- -DLOGDIR=\"$(logdir)\" \
- -DPIXMAPDIR=\"$(pixmapdir)\" \
- -DSBINDIR=\"$(sbindir)\" \
- -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
- -DGDM_DEFAULTS_CONF=\"$(GDM_DEFAULTS_CONF)\" \
- -DGDM_CUSTOM_CONF=\"$(GDM_CUSTOM_CONF)\" \
- -DGDM_OLD_CONF=\"$(GDM_OLD_CONF)\" \
- $(GUI_CFLAGS) \
- $(DAEMON_CFLAGS) \
- -DLANG_CONFIG_FILE=\"$(LANG_CONFIG_FILE)\" \
- $(GNOME_INCLUDEDIR) \
- -DGREETERTHEMEDIR=\""$(datadir)/gdm/themes"\" \
- $(NULL)
-
-sbin_PROGRAMS = gdm-binary \
- $(NULL)
-
-gdm_binary_SOURCES = \
- gdm.c \
- gdm.h \
- gdm-daemon-config.c \
- gdm-daemon-config.h \
- gdm-daemon-config-entries.h \
- gdm-daemon-config-keys.h \
- gdm-socket-protocol.h \
- display.c \
- display.h \
- fstype.c \
- slave.c \
- slave.h \
- server.c \
- server.h \
- misc.c \
- misc.h \
- auth.c \
- auth.h \
- cookie.c \
- cookie.h \
- xdmcp.c \
- xdmcp.h \
- choose.c \
- choose.h \
- filecheck.c \
- filecheck.h \
- md5.c \
- md5.h \
- @VRFY@.c \
- verify.h \
- errorgui.c \
- errorgui.h \
- gdm-net.c \
- gdm-net.h \
- getvt.c \
- getvt.h \
- $(NULL)
-
-XDMCP_SOURCES = \
- gdm-xdmcp-manager.c \
- gdm-xdmcp-manager.h \
- $(NULL)
-
-if XDMCP_SUPPORT
-gdm_binary_SOURCES += $(XDMCP_SOURCES)
-endif
-
-EXTRA_gdm_binary_SOURCES = \
- verify-pam.c \
- verify-crypt.c \
- verify-shadow.c \
- $(XDMCP_SOURCES) \
- $(NULL)
-
-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) \
- $(NULL)
-
-gdm_binary_LDADD = \
- $(DAEMON_LIBS) \
- $(INTLLIBS) \
- $(GLIB_LIBS) \
- $(GOBJECT_LIBS) \
- $(GDK_LIBS) \
- $(top_builddir)/common/libgdmcommon.a \
- $(X_LIBS) \
- $(XINERAMA_LIBS) \
- $(XDMCP_LIBS) \
- -lXau \
- -lX11 \
- -lXext \
- $(NULL)
-
-if WITH_CONSOLE_KIT
-gdm_binary_SOURCES += $(CONSOLE_KIT_SOURCES)
-gdm_binary_LDADD += $(DBUS_LIBS)
-INCLUDES += $(DBUS_CFLAGS)
-endif
-
-sbin_SCRIPTS = gdm
-CLEANFILES = gdm
-
-gdm: $(srcdir)/gdm.in
- sed -e 's,[@]sbindir[@],$(sbindir),g' <$(srcdir)/gdm.in >gdm
-
-EXTRA_DIST = gdm.in
diff --git a/daemon/auth.c b/daemon/auth.c
deleted file mode 100644
index dfc514db..00000000
--- a/daemon/auth.c
+++ /dev/null
@@ -1,1008 +0,0 @@
-/* -*- 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
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* Code for cookie handling. This really needs to be modularized to
- * support other XAuth types and possibly DECnet... */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <netinet/in.h>
-#include <errno.h>
-
-#include <X11/Xauth.h>
-#include <glib/gi18n.h>
-
-#include "gdm.h"
-#include "cookie.h"
-#include "misc.h"
-#include "filecheck.h"
-#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
- against doesn't */
-#ifdef ENABLE_IPV6
-#ifndef FamilyInternetV6
-#define FamilyInternetV6 6
-#endif /* ! FamilyInternetV6 */
-#endif /* ENABLE_IPV6 */
-
-/* Local prototypes */
-static FILE *gdm_auth_purge (GdmDisplay *d, FILE *af, gboolean remove_when_empty);
-
-static void
-display_add_error (GdmDisplay *d)
-{
- if (errno != 0)
- gdm_error (_("%s: Could not write new authorization entry: %s"),
- "add_auth_entry", strerror (errno));
- else
- gdm_error (_("%s: Could not write new authorization entry. "
- "Possibly out of diskspace"),
- "add_auth_entry");
- if (d->attached) {
- char *s = g_strdup_printf
- (C_(N_("GDM could not write a new authorization "
- "entry to disk. Possibly out of diskspace.%s%s")),
- errno != 0 ? " Error: " : "",
- errno != 0 ? strerror (errno) : "");
- gdm_text_message_dialog (s);
- g_free (s);
- }
-}
-
-static gboolean
-add_auth_entry (GdmDisplay *d,
- GSList **authlist,
- FILE *af,
- FILE *af2,
- unsigned short family,
- const char *addr,
- int addrlen)
-{
- Xauth *xa;
- gchar *dispnum;
-
- if G_UNLIKELY (!d)
- return FALSE;
-
- xa = malloc (sizeof (Xauth));
-
- if G_UNLIKELY (xa == NULL)
- return FALSE;
-
- xa->family = family;
- if (addrlen == 0) {
- xa->address = NULL;
- xa->address_length = 0;
- } else {
- xa->address = malloc (addrlen);
- if G_UNLIKELY (xa->address == NULL) {
- free (xa);
- return FALSE;
- }
-
- memcpy (xa->address, addr, addrlen);
- xa->address_length = addrlen;
- }
-
- dispnum = g_strdup_printf ("%d", d->dispnum);
- xa->number = strdup (dispnum);
- xa->number_length = strlen (dispnum);
- g_free (dispnum);
-
- xa->name = strdup ("MIT-MAGIC-COOKIE-1");
- xa->name_length = strlen ("MIT-MAGIC-COOKIE-1");
- xa->data = malloc (16);
- if G_UNLIKELY (xa->data == NULL) {
- free (xa->number);
- free (xa->name);
- free (xa->address);
- free (xa);
- return FALSE;
- }
- memcpy (xa->data, d->bcookie, 16);
- xa->data_length = 16;
-
- if (af != NULL) {
- errno = 0;
- if G_UNLIKELY ( ! XauWriteAuth (af, xa)) {
- free (xa->data);
- free (xa->number);
- free (xa->name);
- free (xa->address);
- free (xa);
- display_add_error (d);
- return FALSE;
- }
-
- if (af2 != NULL) {
- errno = 0;
- if G_UNLIKELY ( ! XauWriteAuth (af2, xa)) {
- free (xa->data);
- free (xa->number);
- free (xa->name);
- free (xa->address);
- free (xa);
- display_add_error (d);
- return FALSE;
- }
- }
- }
-
- *authlist = g_slist_append (*authlist, xa);
-
- return TRUE;
-}
-
-/**
- * gdm_auth_secure_display:
- * @d: Pointer to a GdmDisplay struct
- *
- * Create authentication cookies for local and remote displays.
- *
- * Returns TRUE on success and FALSE on error.
- */
-
-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, 0644);
-
- 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, 0644);
-
- 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->cookie, &d->bcookie);
-
- /* 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};
- guint i;
- const GList *local_addys = NULL;
- gboolean added_lo = FALSE;
- GSList *auths = 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_address_peek_local_list ();
-
- is_local = TRUE;
- } else {
- is_local = FALSE;
-
- if (gdm_address_is_local (&(d->addr))) {
- is_local = TRUE;
- }
-
- for (i = 0; ! is_local && i < d->addr_count; i++) {
- if (gdm_address_is_local (&d->addrs[i])) {
- 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 */
-
- 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, then add loopback */
- if (SERVER_IS_LOCAL (d) && ! added_lo && ! d->tcp_disallowed) {
- struct sockaddr_storage *lo_ss = NULL;
- if (! add_auth_entry (d, &auths, NULL, NULL, FamilyInternet,
- lo, sizeof (struct in_addr))) {
- 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));
-
- return auths;
-
- get_local_auth_error:
-
- gdm_auth_free_auth_list (auths);
-
- return NULL;
-}
-
-static gboolean
-try_open_append (const char *file)
-{
- FILE *fp;
-
- VE_IGNORE_EINTR (fp = fopen (file, "a+"));
- if G_LIKELY (fp != NULL) {
- VE_IGNORE_EINTR (fclose (fp));
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-static gboolean
-try_open_read_as_root (const char *file)
-{
- int fd;
- uid_t oldeuid = geteuid ();
- uid_t oldegid = getegid ();
- NEVER_FAILS_root_set_euid_egid (0, 0);
-
- VE_IGNORE_EINTR (fd = open (file, O_RDONLY));
- if G_UNLIKELY (fd < 0) {
- NEVER_FAILS_root_set_euid_egid (oldeuid, oldegid);
- return FALSE;
- } else {
- VE_IGNORE_EINTR (close (fd));
- NEVER_FAILS_root_set_euid_egid (oldeuid, oldegid);
- return TRUE;
- }
-}
-
-/**
- * gdm_auth_user_add:
- * @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.
- */
-
-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);
-
- if G_UNLIKELY (authfd < 0 && authdir_is_tmp_dir) {
- g_free (d->userauth);
- d->userauth = NULL;
-
- authdir_is_tmp_dir = FALSE;
- goto try_user_add_again;
- }
-
- 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;
-
- umask (022);
-
- g_free (authdir);
- return FALSE;
- }
-
- 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;
-
- automatic_tmp_dir = TRUE;
- goto try_user_add_again;
- }
-
- locked = TRUE;
-
- af = gdm_safe_fopen_ap (d->userauth, 0600);
- }
-
- /* Set to NULL, because can goto try_user_add_again. */
- g_free (authdir);
- authdir = NULL;
-
- 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;
-
- if ( ! d->authfb) {
- automatic_tmp_dir = TRUE;
- goto try_user_add_again;
- }
-
- umask (022);
- return FALSE;
- }
-
- 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 */);
-
- /* 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;
- }
-
- 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);
-
- gdm_debug ("gdm_auth_user_add: Done");
-
- umask (022);
- return ret;
-}
-
-
-/**
- * gdm_auth_user_remove:
- * @d: Pointer to a GdmDisplay struct
- * @user: Userid of the user whose cookie file to remove entries from
- *
- * Remove all cookies referring to this display from user's cookie
- * file.
- */
-
-void
-gdm_auth_user_remove (GdmDisplay *d, uid_t user)
-{
- FILE *af;
- gchar *authfile;
- gchar *authdir;
-
- 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 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;
- }
-
- af = gdm_safe_fopen_ap (d->userauth, 0600);
-
- if G_UNLIKELY (af == NULL) {
- XauUnlockAuth (d->userauth);
-
- gdm_error (_("%s: Cannot safely open %s"),
- "gdm_auth_user_remove",
- d->userauth);
-
- g_free (d->userauth);
- d->userauth = NULL;
-
- return;
- }
-
- /* Purge entries for this display from the cookie jar */
- af = gdm_auth_purge (d, af, TRUE /* remove when empty */);
-
- /* 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
-memory_same (const char *sa, int lena, const char *sb, int lenb)
-{
- if (lena == lenb) {
- if (lena == 0)
- return TRUE;
- /* sanity */
- if G_UNLIKELY (sa == NULL || sb == NULL)
- return FALSE;
- return memcmp (sa, sb, lena) == 0;
- } else {
- return FALSE;
- }
-}
-
-static gboolean
-auth_same_except_data (Xauth *xa, Xauth *xb)
-{
- if (xa->family == xb->family &&
- memory_same (xa->number, xa->number_length,
- xb->number, xb->number_length) &&
- memory_same (xa->name, xa->name_length,
- xb->name, xb->name_length) &&
- memory_same (xa->address, xa->address_length,
- xb->address, xb->address_length))
- return TRUE;
- else
- return FALSE;
-}
-
-
-/**
- * gdm_auth_purge:
- * @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;
- 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);
-
- /* 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;
- }
-
- af = gdm_safe_fopen_w (d->userauth, 0600);
-
- /* 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;
-}
-
-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);
-}
-
-void
-gdm_auth_free_auth_list (GSList *list)
-{
- GSList *li;
-
- for (li = list; li != NULL; li = li->next) {
- XauDisposeAuth ((Xauth *) li->data);
- li->data = NULL;
- }
-
- g_slist_free (list);
-}
diff --git a/daemon/auth.h b/daemon/auth.h
deleted file mode 100644
index f01ebcbf..00000000
--- a/daemon/auth.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef GDM_AUTH_H
-#define GDM_AUTH_H
-
-#include "gdm.h"
-
-gboolean gdm_auth_secure_display (GdmDisplay *d);
-gboolean gdm_auth_user_add (GdmDisplay *d, uid_t user, const char *homedir);
-void gdm_auth_user_remove (GdmDisplay *d, uid_t user);
-
-/* Call XSetAuthorization */
-void gdm_auth_set_local_auth (GdmDisplay *d);
-
-void gdm_auth_free_auth_list (GSList *list);
-
-#endif /* GDM_AUTH_H */
-
-/* EOF */
diff --git a/daemon/choose.c b/daemon/choose.c
deleted file mode 100644
index bd08b10c..00000000
--- a/daemon/choose.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/* -*- 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
- * 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
- */
-
-/* This file contains the XDMCP chooser glue */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <X11/Xlib.h>
-#include <X11/Xmd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include "gdm.h"
-#include "misc.h"
-#include "choose.h"
-#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;
-
-static guint indirect_id = 1;
-
-static gboolean
-remove_oldest_pending (void)
-{
- GSList *li;
- GdmIndirectDisplay *oldest = NULL;
-
- for (li = indirect; li != NULL; li = li->next) {
- GdmIndirectDisplay *idisp = li->data;
- if (idisp->acctime == 0)
- continue;
-
- if (oldest == NULL ||
- idisp->acctime < oldest->acctime) {
- oldest = idisp;
- }
- }
-
- if (oldest != NULL) {
- gdm_choose_indirect_dispose (oldest);
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-#ifndef XDM_UDP_PORT
-#define XDM_UDP_PORT 177
-#endif
-
-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;
- struct sockaddr_storage *sa;
- GSList *li;
- 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) {
- goto out;
- }
-
- p = strtok (NULL, " ");
- if (p == NULL || sscanf (p, "%d", &id) != 1) {
- goto out;
- }
-
- p = strtok (NULL, " ");
-
- if (p == NULL) {
- goto out;
- }
-
- if (! get_first_address_for_node (p, &sa)) {
- goto out;
- }
-
- 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;
- if (idisp->id == id) {
- /* whack the oldest if more then allowed */
- while (ipending >= gdm_daemon_config_get_value_int (GDM_KEY_MAX_INDIRECT) &&
- remove_oldest_pending ())
- ;
-
- idisp->acctime = time (NULL);
-
- g_free (idisp->chosen_host);
- idisp->chosen_host = g_memdup (sa, sizeof (struct sockaddr_storage));
-
- /* Now this display is pending */
- ipending++;
-
- ret = TRUE;
- break;
- }
- }
- out:
- g_free (sa);
- g_free (msg);
-
- return ret;
-}
-
-
-GdmIndirectDisplay *
-gdm_choose_indirect_alloc (struct sockaddr_storage *clnt_sa)
-{
- GdmIndirectDisplay *id;
- char *host;
-
- 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->id = indirect_id++;
-
- 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);
-
- 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 */
-void
-gdm_choose_indirect_dispose_empty_id (guint id)
-{
- GSList *li;
-
- if (id == 0)
- return;
-
- for (li = indirect; li != NULL; li = li->next) {
- GdmIndirectDisplay *idisp = li->data;
-
- if (idisp == NULL)
- continue;
-
- if (idisp->id == id) {
- if (idisp->chosen_host == NULL)
- gdm_choose_indirect_dispose (idisp);
- return;
- }
- }
-}
-
-GdmIndirectDisplay *
-gdm_choose_indirect_lookup_by_chosen (struct sockaddr_storage *chosen,
- struct sockaddr_storage *origin)
-{
- GSList *li;
- char *host;
-
- for (li = indirect; li != NULL; li = li->next) {
- GdmIndirectDisplay *id = li->data;
-
- if (id != NULL &&
- id->chosen_host != NULL &&
- gdm_address_equal (id->chosen_host, chosen)) {
- if (gdm_address_equal (id->dsp_sa, origin)) {
- return id;
- } else if (gdm_address_is_loopback (id->dsp_sa) &&
- gdm_address_is_local (origin)) {
- return id;
- }
- }
- }
-
- gdm_address_get_info (chosen, &host, NULL);
-
- gdm_debug ("gdm_choose_indirect_lookup_by_chosen: Chosen %s host not found",
- host);
- gdm_debug ("gdm_choose_indirect_lookup_by_chosen: Origin was: %s",
- host);
- g_free (host);
-
- return NULL;
-}
-
-
-GdmIndirectDisplay *
-gdm_choose_indirect_lookup (struct sockaddr_storage *clnt_sa)
-{
- GSList *li, *ilist;
- GdmIndirectDisplay *id;
- time_t curtime = time (NULL);
- char *host;
-
- ilist = g_slist_copy (indirect);
-
- for (li = ilist; li != NULL; li = li->next) {
- id = (GdmIndirectDisplay *) li->data;
- if (id == NULL)
- continue;
-
- if (id->acctime > 0 &&
- curtime > id->acctime + gdm_daemon_config_get_value_int (GDM_KEY_MAX_WAIT_INDIRECT)) {
-
- 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);
-
- gdm_address_get_info (clnt_sa, &host, NULL);
- gdm_debug ("gdm_choose_indirect_lookup: Host %s not found",
- host);
- g_free (host);
-
- return NULL;
-}
-
-
-void
-gdm_choose_indirect_dispose (GdmIndirectDisplay *id)
-{
- char *host;
-
- if (id == NULL)
- return;
-
- indirect = g_slist_remove (indirect, id);
-
- if (id->acctime > 0)
- ipending--;
- id->acctime = 0;
-
- gdm_address_get_info (id->dsp_sa, &host, NULL);
- gdm_debug ("gdm_choose_indirect_dispose: Disposing %s",
- host);
- g_free (host);
-
- g_free (id->chosen_host);
- id->chosen_host = NULL;
-
- g_free (id->dsp_sa);
- id->dsp_sa = NULL;
-
- g_free (id);
-}
diff --git a/daemon/choose.h b/daemon/choose.h
deleted file mode 100644
index 3fface4d..00000000
--- a/daemon/choose.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- 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
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef CHOOSE_H
-#define CHOOSE_H
-
-#include "gdm.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);
-
-gboolean gdm_choose_data (const char *data);
-
-#endif /* CHOOSE_H */
-
-/* EOF */
-
diff --git a/daemon/cookie.c b/daemon/cookie.c
deleted file mode 100644
index 55f9621b..00000000
--- a/daemon/cookie.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * GDM - The GNOME Display Manager
- * Copyright (C) 2003 Red Hat, Inc.
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- * Copyright (C) Rik Faith <faith@precisioninsight.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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
- */
-
-/*
- * Functions for generating MIT-MAGIC-COOKIEs.
- *
- * This code was derived (i.e. stolen) from mcookie.c written by Rik Faith
- *
- * Note that this code goes to much greater lengths to be as random as possible.
- * Thus being more secure on systems without /dev/random and friends.
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "gdm.h"
-#include "md5.h"
-#include "cookie.h"
-
-#include "gdm-common.h"
-#include "gdm-daemon-config.h"
-
-#define MAXBUFFERSIZE 1024
-
-static struct rngs {
- const char *path; /* null is the authfile name */
- int length;
- off_t seek;
-} rngs[] = {
- { "/dev/random", 16, 0 },
-#ifdef __OpenBSD__
- { "/dev/srandom", 16, 0 },
-#endif
- { "/dev/urandom", 128, 0 },
- { "/proc/stat", MAXBUFFERSIZE, 0 },
- { "/proc/interrupts", MAXBUFFERSIZE, 0 },
- { "/proc/loadavg", MAXBUFFERSIZE, 0 },
- { "/proc/meminfo", MAXBUFFERSIZE, 0 },
-#if defined (__i386__) || defined (__386__) || defined (_M_IX86)
- /* On i386, we should not read the first 16megs */
- { "/dev/mem", MAXBUFFERSIZE, 0x100000 },
-#else
- { "/dev/mem", MAXBUFFERSIZE, 0 },
-#endif
- /* this will load the old authfile for the display */
- { NULL /* null means the authfile */, MAXBUFFERSIZE, 0 },
- { "/proc/net/dev", MAXBUFFERSIZE, 0 },
- { "/dev/audio", MAXBUFFERSIZE, 0 },
- { "/etc/shadow", MAXBUFFERSIZE, 0 },
- { "/var/log/messages", MAXBUFFERSIZE, 0 },
-};
-
-/* Some semi random spinners to spin,
- * this is 20 bytes of semi random data */
-#define RANDNUMS 5
-static guint32 randnums[RANDNUMS];
-
-/* stolen from XDM which in turn stole this
- from the C standard */
-static guint32
-next_rand_15 (guint32 num)
-{
- num = num * 1103515245 + 12345;
- return (unsigned int)(num/65536) % 32768;
-}
-
-/* really quite apparently only 31 bits of entropy result (from tests),
- but oh well */
-static guint32
-next_rand_32 (guint32 num)
-{
- int i;
- guint32 ret;
- guint8 *p = (guint8 *)&ret;
-
- for (i = 0; i < 4; i++) {
- num = next_rand_15 (num);
- p[i] = (num & 0xff00) >> 8;
- }
- return ret;
-}
-
-/* This adds a little bit of entropy to our buffer,
- just in case /dev/random doesn't work out for us
- really since that normally adds enough bytes of nice
- randomness already */
-void
-gdm_random_tick (void)
-{
- struct timeval tv;
- struct timezone tz;
-
- gettimeofday (&tv, &tz);
-
- /* the higher order bits of the seconds
- are quite uninteresting */
- randnums[0] ^= next_rand_32 ((tv.tv_sec << 20) ^ tv.tv_usec);
-
- /* different method of combining */
- randnums[1] ^= next_rand_32 (tv.tv_sec) ^ next_rand_32 (tv.tv_usec);
-
- /* probably unneeded, but just being anal */
- randnums[2] ^= (tv.tv_sec << 20) ^ tv.tv_usec;
-
- /* probably unneeded, to guess above
- the number of invocation is likely needed
- anyway */
- randnums[3]++;
-
- /* also hope that other places call
- g_random_int. Note that on systems
- without /dev/urandom, this will yet again
- measure time the first time it's called and
- we'll add entropy based on the speed of the
- computer. Yay */
- randnums[4] ^= g_random_int ();
-}
-
-/* check a few values and if we get the same
- value, it's not really random. Likely
- we got perhaps a string of zeros or some
- such. */
-static gboolean
-data_seems_random (const char buf[], int size)
-{
- int i, lastval = 0;
- if (size < 16)
- return FALSE;
- for (i = 0; i < 10; i++) {
- int idx = g_random_int_range (0, size);
- if G_LIKELY (i > 0 &&
- lastval != buf[idx])
- return TRUE;
- lastval = buf[idx];
- }
- return FALSE;
-}
-
-static unsigned char old_cookie[16];
-
-void
-gdm_cookie_generate (char **cookiep,
- char **bcookiep)
-{
- int i;
- struct GdmMD5Context ctx;
- unsigned char digest[16];
- unsigned char buf[MAXBUFFERSIZE];
- int fd;
- pid_t pid;
- int r;
- char cookie[40]; /* 2*16 == 32, so 40 is enough */
-
- cookie[0] = '\0';
-
- gdm_md5_init (&ctx);
-
- /* spin the spinners according to current time */
- gdm_random_tick ();
-
- gdm_md5_update (&ctx, (unsigned char *) randnums, sizeof (int) * RANDNUMS);
-
- /* use the last cookie */
- gdm_md5_update (&ctx, old_cookie, 16);
-
- /* use some uninitialized stack space */
- gdm_md5_update (&ctx, (unsigned char *) cookie, sizeof (cookie));
-
- pid = getppid ();
- gdm_md5_update (&ctx, (unsigned char *) &pid, sizeof (pid));
- pid = getpid ();
- gdm_md5_update (&ctx, (unsigned char *) &pid, sizeof (pid));
-
- for (i = 0; i < G_N_ELEMENTS (rngs); i++) {
- const char *file = rngs[i].path;
-
- if G_UNLIKELY (file == NULL)
- continue;
- do {
- int flags;
-
- flags = O_RDONLY | O_NONBLOCK;
-#ifdef O_NOCTTY
- flags |= O_NOCTTY;
-#endif
-#ifdef O_NOFOLLOW
- flags |= O_NOFOLLOW;
-#endif
-
- errno = 0;
- fd = open (file, flags);
-
- } while G_UNLIKELY (errno == EINTR);
-
- if G_LIKELY (fd >= 0) {
- /* Apparently this can sometimes block anyway even if it is O_NONBLOCK,
- so use select to figure out if there is something available */
- fd_set rfds;
- struct timeval tv;
-
- FD_ZERO (&rfds);
- FD_SET (fd, &rfds);
-
- tv.tv_sec = 0;
- tv.tv_usec = 10*1000 /* 10 ms */;
- r = 0;
-
- if G_UNLIKELY (rngs[i].seek > 0)
- lseek (fd, rngs[i].seek, SEEK_SET);
-
- if G_LIKELY (select (fd+1, &rfds, NULL, NULL, &tv) > 0) {
- VE_IGNORE_EINTR (r = read (fd, buf, MIN (sizeof (buf), rngs[i].length)));
- }
-
- if G_LIKELY (r > 0)
- gdm_md5_update (&ctx, buf, r);
- else
- r = 0;
-
- VE_IGNORE_EINTR (close (fd));
-
- if G_LIKELY (r >= rngs[i].length &&
- data_seems_random ((char *) buf, r))
- break;
- }
- }
-
- gdm_md5_final (digest, &ctx);
-
- for (i = 0; i < 16; i++) {
- char sub[3];
- g_snprintf (sub, sizeof (sub), "%02x", (guint)digest[i]);
- strcat (cookie, sub);
- }
-
- if (cookiep != NULL) {
- *cookiep = g_strdup (cookie);
- }
-
- if (bcookiep != NULL) {
- *bcookiep = g_new (char, 16);
- memcpy (*bcookiep, digest, 16);
- }
-
- memcpy (old_cookie, digest, 16);
-}
diff --git a/daemon/cookie.h b/daemon/cookie.h
deleted file mode 100644
index 9342f037..00000000
--- a/daemon/cookie.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef GDM_COOKIE_H
-#define GDM_COOKIE_H
-
-void gdm_cookie_generate (char **cookie,
- char **bcookie);
-
-/* Add some more time based randomness, should be done
- * at less predictable events */
-void gdm_random_tick (void);
-
-#endif /* GDM_COOKIE_H */
-
-/* EOF */
diff --git a/daemon/display.c b/daemon/display.c
deleted file mode 100644
index 311f5647..00000000
--- a/daemon/display.c
+++ /dev/null
@@ -1,671 +0,0 @@
-/* -*- 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
- * 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
- */
-
-#include "config.h"
-
-#include <glib/gi18n.h>
-#include <signal.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "gdm.h"
-#include "gdm-net.h"
-#include "server.h"
-#include "display.h"
-#include "slave.h"
-#include "misc.h"
-#include "choose.h"
-#include "auth.h"
-#include "gdm-net.h"
-
-#include "gdm-common.h"
-#include "gdm-log.h"
-#include "gdm-daemon-config.h"
-
-/* External vars */
-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;
-
-/**
- * gdm_display_alloc:
- * @id: Local display number
- * @command: Command line for starting the X server
- *
- * Allocate display structure for a local X server
- */
-
-GdmDisplay *
-gdm_display_alloc (gint id, const gchar *command)
-{
- gchar hostname[1024];
- GdmDisplay *d;
-
- hostname[1023] = '\0';
- if (gethostname (hostname, 1023) == -1)
- strcpy (hostname, "localhost.localdomain");
-
- d = g_new0 (GdmDisplay, 1);
-
- d->logout_action = GDM_LOGOUT_ACTION_NONE;
-
- d->authfile = NULL;
- d->authfile_gdm = NULL;
- d->auths = NULL;
- d->userauth = NULL;
- d->command = g_strdup (command);
- d->cookie = NULL;
- d->dispstat = DISPLAY_UNBORN;
- d->greetpid = 0;
- d->name = g_strdup_printf (":%d", id);
- d->hostname = g_strdup (hostname);
- /* Not really used for not XDMCP */
- memset (&(d->addr), 0, sizeof (d->addr));
- d->dispnum = id;
- d->servpid = 0;
- d->servstat = SERVER_DEAD;
- d->sesspid = 0;
- d->slavepid = 0;
- d->type = TYPE_STATIC;
- d->attached = TRUE;
- d->sessionid = 0;
- d->acctime = 0;
- d->dsp = NULL;
- d->screenx = 0; /* xinerama offset */
- d->screeny = 0;
-
- d->handled = TRUE;
- d->tcp_disallowed = FALSE;
-
- d->priority = 0;
- d->vt = -1;
-
- d->x_servers_order = -1;
-
- d->last_loop_start_time = 0;
- d->last_start_time = 0;
- d->retry_count = 0;
- d->sleep_before_run = 0;
- d->login = NULL;
- d->preset_user = NULL;
-
- d->timed_login_ok = FALSE;
-
- 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;
-
- return d;
-}
-
-static gboolean
-gdm_display_check_loop (GdmDisplay *disp)
-{
- time_t now;
- time_t since_last;
- time_t since_loop;
-
- now = time (NULL);
-
- gdm_debug ("loop check: last_start %ld, last_loop %ld, now: %ld, retry_count: %d", (long)disp->last_start_time, (long) disp->last_loop_start_time, (long) now, disp->retry_count);
-
- if (disp->last_loop_start_time > now || disp->last_loop_start_time == 0)
- {
- /* Reset everything if this is the first time in this
- * function, or if the system clock got reset backward.
- */
- disp->last_loop_start_time = now;
- disp->last_start_time = now;
- disp->retry_count = 1;
-
- gdm_debug ("Resetting counts for loop of death detection");
-
- return TRUE;
- }
-
- since_loop = now - disp->last_loop_start_time;
- since_last = now - disp->last_start_time;
-
- /* If it's been at least 1.5 minutes since the last startup loop
- * attempt, then we reset everything. Or if the last startup was more then
- * 30 seconds ago, then it was likely a successful session.
- */
-
- if (since_loop >= 90 || since_last >= 30)
- {
- disp->last_loop_start_time = now;
- disp->last_start_time = now;
- disp->retry_count = 1;
-
- gdm_debug ("Resetting counts for loop of death detection, 90 seconds elapsed since loop started or session lasted more then 30 seconds.");
-
- return TRUE;
- }
-
- /* If we've tried too many times we bail out. i.e. this means we
- * tried too many times in the 90-second period.
- */
- if (disp->retry_count >= 6) {
- /* This means we have no clue what's happening,
- * it's not X server crashing as we would have
- * cought that elsewhere. Things are just
- * not working out, so tell the user.
- * However this may have been caused by a malicious local user
- * zapping the display repeatedly, that shouldn't cause gdm
- * to stop working completely so just wait for 2 minutes,
- * that should give people ample time to stop gdm if needed,
- * or just wait for the stupid malicious user to get bored
- * and go away */
- char *s = g_strdup_printf (C_(N_("The display server has been shut down "
- "about 6 times in the last 90 seconds. "
- "It is likely that something bad is "
- "going on. Waiting for 2 minutes "
- "before trying again on display %s.")),
- disp->name);
- /* only display a dialog box if this is a local display */
- if (disp->type == TYPE_STATIC ||
- disp->type == TYPE_FLEXI) {
- gdm_text_message_dialog (s);
- }
- gdm_error ("%s", s);
- g_free (s);
-
- /* Wait 2 minutes */
- disp->sleep_before_run = 120;
- /* well, "last" start time will really be in the future */
- disp->last_start_time = now + disp->sleep_before_run;
-
- disp->retry_count = 1;
- /* this will reset stuff in the next run (after this
- "after-two-minutes" server starts) */
- disp->last_loop_start_time = 0;
-
- return TRUE;
- }
-
- /* At least 8 seconds between start attempts, but only after
- * the second start attempt, so you can try to kill gdm from the console
- * in these gaps.
- */
- if (disp->retry_count > 2 && since_last < 8)
- {
- gdm_debug ("Will sleep %ld seconds before next X server restart attempt",
- (long)(8 - since_last));
- now = time (NULL) + 8 - since_last;
- disp->sleep_before_run = 8 - since_last;
- /* well, "last" start time will really be in the future */
- disp->last_start_time = now + disp->sleep_before_run;
- }
- else
- {
- /* wait one second just for safety (avoids X server races) */
- disp->sleep_before_run = 1;
- disp->last_start_time = now;
- }
-
- disp->retry_count++;
-
- return TRUE;
-}
-
-static void
-whack_old_slave (GdmDisplay *d, gboolean kill_connection)
-{
- time_t t = time (NULL);
- gboolean waitsleep = TRUE;
-
- if (kill_connection) {
- /* This should never happen, but just in case */
- if (d->socket_conn != NULL) {
- GdmConnection *conn = d->socket_conn;
- d->socket_conn = NULL;
- gdm_connection_set_close_notify (conn, NULL, NULL);
- }
- }
-
- if (d->master_notify_fd >= 0) {
- VE_IGNORE_EINTR (close (d->master_notify_fd));
- d->master_notify_fd = -1;
- }
-
- /* if we have DISPLAY_DEAD set, then this has already been killed */
- if (d->dispstat == DISPLAY_DEAD)
- waitsleep = FALSE;
-
- /* Kill slave */
- if (d->slavepid > 1 &&
- (d->dispstat == DISPLAY_DEAD || kill (d->slavepid, SIGTERM) == 0)) {
- int exitstatus;
- int ret;
-wait_again:
-
- if (waitsleep)
- /* wait for some signal, yes this is a race */
- sleep (10);
- waitsleep = TRUE;
- errno = 0;
- ret = waitpid (d->slavepid, &exitstatus, WNOHANG);
- if (ret <= 0) {
- /* rekill the slave to tell it to
- hurry up and die if we're getting
- killed ourselves */
- if ((gdm_daemon_config_signal_terminthup_was_notified ()) ||
- (t + 10 <= time (NULL))) {
- gdm_debug ("whack_old_slave: GOT ANOTHER SIGTERM (or it was 10 secs already), killing slave again with SIGKILL");
- t = time (NULL);
- kill (d->slavepid, SIGKILL);
- goto wait_again;
- } else if (ret < 0 && errno == EINTR) {
- goto wait_again;
- }
- }
-
- if (WIFSIGNALED (exitstatus)) {
- gdm_debug ("whack_old_slave: Slave crashed (signal %d), killing its children",
- (int)WTERMSIG (exitstatus));
-
- if (d->sesspid > 1)
- kill (-(d->sesspid), SIGTERM);
- d->sesspid = 0;
- if (d->greetpid > 1)
- kill (-(d->greetpid), SIGTERM);
- d->greetpid = 0;
- if (d->chooserpid > 1)
- kill (-(d->chooserpid), SIGTERM);
- d->chooserpid = 0;
- if (d->servpid > 1)
- kill (d->servpid, SIGTERM);
- d->servpid = 0;
- }
- }
- d->slavepid = 0;
-}
-
-/**
- * gdm_display_manage:
- * @d: Pointer to a GdmDisplay struct
- *
- * Manage (Initialize and start login session) display
- */
-
-gboolean
-gdm_display_manage (GdmDisplay *d)
-{
- pid_t pid;
- int fds[2];
-
- if (!d)
- return FALSE;
-
- gdm_debug ("gdm_display_manage: Managing %s", d->name);
-
- if (pipe (fds) < 0) {
- gdm_error (_("%s: Cannot create pipe"), "gdm_display_manage");
- }
-
- if ( ! gdm_display_check_loop (d))
- return FALSE;
-
- if (d->slavepid != 0)
- gdm_debug ("gdm_display_manage: Old slave pid is %d", (int)d->slavepid);
-
- /* If we have an old slave process hanging around, kill it */
- /* This shouldn't be a normal code path however, so it doesn't matter
- * that we are hanging */
- whack_old_slave (d, FALSE /* kill_connection */);
-
- /* Ensure that /tmp/.ICE-unix and /tmp/.X11-unix exist and have the
- * correct permissions */
- gdm_ensure_sanity ();
-
- d->managetime = time (NULL);
-
- g_debug ("Forking slave process");
-
- /* Fork slave process */
- pid = d->slavepid = fork ();
-
- switch (pid) {
-
- case 0:
- setpgid (0, 0);
-
- /* Make the slave it's own leader. This 1) makes killing -pid of
- * the daemon work more sanely because the daemon can whack the
- * slave much better itself */
- setsid ();
-
- /* In the child setup empty mask and set all signals to
- * default values, we'll make them more fun later */
- gdm_unset_signals ();
-
- d->slavepid = getpid ();
-
- gdm_connection_close (fifoconn);
- fifoconn = NULL;
- gdm_connection_close (pipeconn);
- pipeconn = NULL;
- gdm_connection_close (unixconn);
- unixconn = NULL;
-
- gdm_log_shutdown ();
-
- /* Close everything */
- gdm_close_all_descriptors (0 /* from */, fds[0] /* except */, slave_fifo_pipe_fd /* except2 */);
-
- /* No error checking here - if it's messed the best response
- * is to ignore & try to continue */
- gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
- gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
- gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
-
- gdm_log_init ();
-
- d->slave_notify_fd = fds[0];
-
- fcntl (d->slave_notify_fd, F_SETFL, fcntl (d->slave_notify_fd, F_GETFL) | O_NONBLOCK);
-
- gdm_slave_start (d);
- /* should never retern */
-
- /* yaikes, how did we ever get here? */
- gdm_server_stop (d);
- _exit (DISPLAY_REMANAGE);
-
- break;
-
- case -1:
- d->slavepid = 0;
- gdm_error (_("%s: Failed forking GDM slave process for %s"),
- "gdm_display_manage",
- d->name);
-
- return FALSE;
-
- default:
- gdm_debug ("gdm_display_manage: Forked slave: %d",
- (int)pid);
- d->master_notify_fd = fds[1];
- VE_IGNORE_EINTR (close (fds[0]));
- break;
- }
-
- /* invalidate chosen hostname */
- g_free (d->chosen_hostname);
- d->chosen_hostname = NULL;
-
- /* use_chooser can only be temporary, if you want it permanent you set it up
- in the server definition with "chooser=true" and it will get set up during
- server command line resolution */
- d->use_chooser = FALSE;
-
- if (SERVER_IS_LOCAL (d)) {
- d->dispstat = DISPLAY_ALIVE;
- }
-
- /* reset sleep to 1, to sleep just in case (avoids X server races) */
- d->sleep_before_run = 1;
-
- return TRUE;
-}
-
-
-/**
- * gdm_display_unmanage:
- * @d: Pointer to a GdmDisplay struct
- *
- * Stop services for a display
- */
-void
-gdm_display_unmanage (GdmDisplay *d)
-{
- if (!d)
- return;
-
- gdm_debug ("gdm_display_unmanage: Stopping %s (slave pid: %d)",
- d->name, (int)d->slavepid);
-
- /* whack connections about this display */
- if (unixconn != NULL)
- gdm_kill_subconnections_with_display (unixconn, d);
-
- /* Kill slave, this may in fact hang for a bit at least until the
- * slave dies, which should be ASAP though */
- whack_old_slave (d, TRUE /* kill_connection */);
-
- d->dispstat = DISPLAY_DEAD;
- if (d->type != TYPE_STATIC || d->removeconf)
- gdm_display_dispose (d);
-
- gdm_debug ("gdm_display_unmanage: Display stopped");
-}
-
-
-/* Why recount? It's just a lot more robust this way and
- gets around those nasty one off errors and races. And we never
- have so many displays that this would get too slow. */
-static void
-count_session_limits (void)
-{
- GSList *li;
- GSList *displays;
-
- displays = gdm_daemon_config_get_display_list ();
-
- flexi_servers = 0;
-
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *d = li->data;
-
- if (SERVER_IS_FLEXI (d)) {
- flexi_servers++;
- }
- }
-}
-
-/**
- * gdm_display_dispose:
- * @d: Pointer to a GdmDisplay struct
- *
- * Deallocate display and all its resources
- */
-
-void
-gdm_display_dispose (GdmDisplay *d)
-{
-
- if (d == NULL)
- return;
-
- /* paranoia */
- if (unixconn != NULL)
- gdm_kill_subconnections_with_display (unixconn, d);
-
- if (d->socket_conn != NULL) {
- GdmConnection *conn = d->socket_conn;
- d->socket_conn = NULL;
- gdm_connection_set_close_notify (conn, NULL, NULL);
- }
-
- if (d->slave_notify_fd >= 0) {
- VE_IGNORE_EINTR (close (d->slave_notify_fd));
- d->slave_notify_fd = -1;
- }
-
- if (d->master_notify_fd >= 0) {
- VE_IGNORE_EINTR (close (d->master_notify_fd));
- d->master_notify_fd = -1;
- }
-
- gdm_daemon_config_display_list_remove (d);
-
- d->dispstat = DISPLAY_DEAD;
- d->type = -1;
-
- count_session_limits ();
-
- if (d->name) {
- gdm_debug ("gdm_display_dispose: Disposing %s", d->name);
- g_free (d->name);
- d->name = NULL;
- }
-
- g_free (d->chosen_hostname);
- d->chosen_hostname = NULL;
-
- g_free (d->hostname);
- d->hostname = NULL;
-
- g_free (d->addrs);
- d->addrs = NULL;
- d->addr_count = 0;
-
- g_free (d->authfile);
- d->authfile = NULL;
-
- g_free (d->authfile_gdm);
- d->authfile_gdm = NULL;
-
- if (d->type == TYPE_XDMCP_PROXY) {
- if (d->parent_auth_file != NULL) {
- VE_IGNORE_EINTR (g_unlink (d->parent_auth_file));
- }
- g_free (d->parent_auth_file);
- d->parent_auth_file = NULL;
- }
-
- if (d->parent_temp_auth_file != NULL) {
- VE_IGNORE_EINTR (g_unlink (d->parent_temp_auth_file));
- }
- g_free (d->parent_temp_auth_file);
- d->parent_temp_auth_file = NULL;
-
- if (d->auths) {
- gdm_auth_free_auth_list (d->auths);
- d->auths = NULL;
- }
-
- if (d->local_auths) {
- gdm_auth_free_auth_list (d->local_auths);
- d->local_auths = NULL;
- }
-
- g_free (d->userauth);
- d->userauth = NULL;
-
- g_free (d->command);
- d->command = NULL;
-
- g_free (d->cookie);
- d->cookie = NULL;
-
- g_free (d->bcookie);
- d->bcookie = NULL;
-
- if (d->indirect_id > 0)
- gdm_choose_indirect_dispose_empty_id (d->indirect_id);
- d->indirect_id = 0;
-
- g_free (d->parent_disp);
- d->parent_disp = NULL;
-
- g_free (d->parent_auth_file);
- d->parent_auth_file = NULL;
-
- g_free (d->login);
- d->login = NULL;
-
- g_free (d->preset_user);
- d->preset_user = NULL;
-
- g_free (d->xsession_errors_filename);
- d->xsession_errors_filename = NULL;
-
- if (d->session_output_fd >= 0) {
- VE_IGNORE_EINTR (close (d->session_output_fd));
- d->session_output_fd = -1;
- }
-
- if (d->xsession_errors_fd >= 0) {
- VE_IGNORE_EINTR (close (d->xsession_errors_fd));
- d->xsession_errors_fd = -1;
- }
-
- g_free (d->chooser_last_line);
- d->chooser_last_line = NULL;
-
- if (d->chooser_output_fd >= 0) {
- VE_IGNORE_EINTR (close (d->chooser_output_fd));
- d->chooser_output_fd = -1;
- }
-
- g_free (d->theme_name);
- d->theme_name = NULL;
-
- g_free (d->xserver_session_args);
- d->xserver_session_args = NULL;
-
- g_free (d);
-}
-
-
-/**
- * gdm_display_lookup:
- * @pid: pid of slave process to look up
- *
- * Return the display managed by pid
- */
-
-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) {
- GdmDisplay *d = li->data;
-
- if (d != NULL &&
- pid == d->slavepid)
- return d;
- }
-
- /* Slave not found */
- return NULL;
-}
-
-
-/* EOF */
diff --git a/daemon/display.h b/daemon/display.h
deleted file mode 100644
index f25373d5..00000000
--- a/daemon/display.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/* -*- 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
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _GDM_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;
-
- gchar *xserver_session_args;
-
- /* 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;
-
-
- /* FLEXI XNEST TYPE */
- char *parent_temp_auth_file;
-};
-
-GdmDisplay *gdm_display_alloc (gint id, const gchar *command);
-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 */
-
diff --git a/daemon/errorgui.c b/daemon/errorgui.c
deleted file mode 100644
index 082c7770..00000000
--- a/daemon/errorgui.c
+++ /dev/null
@@ -1,890 +0,0 @@
-/* -*- 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
- * 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
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <grp.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <pwd.h>
-#include <sys/types.h>
-#include <signal.h>
-
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-
-#include "gdm.h"
-#include "misc.h"
-#include "auth.h"
-#include "errorgui.h"
-#include "slave.h"
-
-#include "gdm-common.h"
-#include "gdm-log.h"
-#include "gdm-daemon-config.h"
-
-#include "gdm-socket-protocol.h"
-
-static int screenx = 0;
-static int screeny = 0;
-static int screenwidth = 0;
-static int screenheight = 0;
-
-static gboolean inhibit_gtk_modules = FALSE;
-static gboolean inhibit_gtk_themes = FALSE;
-
-static void
-setup_cursor (GdkCursorType type)
-{
- GdkCursor *cursor = gdk_cursor_new (type);
- gdk_window_set_cursor (gdk_get_default_root_window (), cursor);
- gdk_cursor_unref (cursor);
-}
-
-static gboolean
-gdm_event (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GdkEvent *event;
-
- /* HAAAAAAAAAAAAAAAAACK */
- /* Since the user has not logged in yet and may have left/right
- * mouse buttons switched, we just translate every right mouse click
- * to a left mouse click */
- if (n_param_values != 2 ||
- !G_VALUE_HOLDS (&param_values[1], GDK_TYPE_EVENT))
- return FALSE;
-
- event = g_value_get_boxed (&param_values[1]);
- if ((event->type == GDK_BUTTON_PRESS ||
- event->type == GDK_2BUTTON_PRESS ||
- event->type == GDK_3BUTTON_PRESS ||
- event->type == GDK_BUTTON_RELEASE)
- && event->button.button == 3)
- event->button.button = 1;
-
- return TRUE;
-}
-
-static void
-get_screen_size (GdmDisplay *d)
-{
- if (d != NULL) {
- screenx = d->screenx;
- screeny = d->screeny;
- screenwidth = d->screenwidth;
- screenheight = d->screenheight;
- }
-
- if (screenwidth <= 0)
- screenwidth = gdk_screen_width ();
- if (screenheight <= 0)
- screenheight = gdk_screen_height ();
-}
-
-static void
-center_window (GtkWidget *window)
-{
- int w, h;
-
- /* sanity, should never happen */
- if (window == NULL)
- return;
-
- gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-
- gtk_window_move (GTK_WINDOW (window),
- screenx +
- (screenwidth / 2) -
- (w / 2),
- screeny +
- (screenheight / 2) -
- (h / 2));
-}
-
-static void
-show_errors (GtkWidget *button, gpointer data)
-{
- GtkRequisition req;
- GtkWidget *textsw = data;
- GtkWidget *dlg = g_object_get_data (G_OBJECT (button), "dlg");
-
- if (GTK_TOGGLE_BUTTON (button)->active) {
- gtk_widget_show (textsw);
- } else {
- gtk_widget_hide (textsw);
- }
-
- /* keep window at the size request size */
- gtk_widget_size_request (dlg, &req);
- gtk_window_resize (GTK_WINDOW (dlg), req.width, req.height);
-}
-
-static GtkWidget *
-get_error_text_view (const char *details)
-{
- GtkWidget *sw;
- GtkWidget *tv;
- GtkTextBuffer *buf;
- GtkTextIter iter;
-
- tv = gtk_text_view_new ();
- buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
- gtk_text_view_set_editable (GTK_TEXT_VIEW (tv), FALSE);
- gtk_text_buffer_create_tag (buf, "foo",
- "editable", FALSE,
- "family", "monospace",
- NULL);
- gtk_text_buffer_get_iter_at_offset (buf, &iter, 0);
-
- gtk_text_buffer_insert_with_tags_by_name
- (buf, &iter,
- ve_sure_string (details), -1,
- "foo", NULL);
-
- sw = gtk_scrolled_window_new (NULL, NULL);
- if (gdk_screen_width () >= 800)
- gtk_widget_set_size_request (sw, 500, 150);
- else
- gtk_widget_set_size_request (sw, 200, 150);
-
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_ALWAYS);
-
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
- GTK_SHADOW_IN);
-
- gtk_container_add (GTK_CONTAINER (sw), tv);
- gtk_widget_show (tv);
-
- return sw;
-}
-
-static void
-setup_dialog (GdmDisplay *d, const char *name, int closefdexcept, gboolean set_gdm_ids, uid_t uid)
-{
- int argc = 1;
- char **argv;
- struct passwd *pw;
-
- gdm_log_shutdown ();
-
- /* No error checking here - if it's messed the best response
- * is to ignore & try to continue */
- gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
- gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
- gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
-
- if (set_gdm_ids) {
- setgid (gdm_daemon_config_get_gdmgid ());
- initgroups (gdm_daemon_config_get_value_string (GDM_KEY_USER), gdm_daemon_config_get_gdmgid ());
- setuid (gdm_daemon_config_get_gdmuid ());
- pw = NULL;
- } else {
- pw = getpwuid (uid);
- }
-
- gdm_desetuid ();
-
- /* restore initial environment */
- gdm_restoreenv ();
-
- 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);
- g_setenv ("USERNAME", gdm_daemon_config_get_value_string (GDM_KEY_USER), TRUE);
-
- g_setenv ("DISPLAY", d->name, TRUE);
- g_unsetenv ("XAUTHORITY");
-
- g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
-
- /* sanity env stuff */
- g_setenv ("SHELL", "/bin/sh", TRUE);
- /* set HOME to /, we don't need no stinking HOME anyway */
- if (pw == NULL ||
- ve_string_empty (pw->pw_dir))
- g_setenv ("HOME", ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)), TRUE);
- else
- g_setenv ("HOME", pw->pw_dir, TRUE);
-
- argv = g_new0 (char *, 3);
- argv[0] = (char *)name;
- argc = 1;
-
- if ( ! inhibit_gtk_modules &&
- gdm_daemon_config_get_value_bool (GDM_KEY_ADD_GTK_MODULES) &&
- ! ve_string_empty (gdm_daemon_config_get_value_string (GDM_KEY_GTK_MODULES_LIST))) {
- argv[1] = g_strdup_printf ("--gtk-module=%s", gdm_daemon_config_get_value_string (GDM_KEY_GTK_MODULES_LIST));
- argc = 2;
- }
-
- if (inhibit_gtk_modules) {
- g_unsetenv ("GTK_MODULES");
- }
-
- gtk_init (&argc, &argv);
-
- if ( ! inhibit_gtk_themes) {
- const char *theme_name;
- const gchar *gtkrc = gdm_daemon_config_get_value_string (GDM_KEY_GTKRC);
-
- if ( ! ve_string_empty (gtkrc) &&
- g_access (gtkrc, R_OK) == 0)
- gtk_rc_parse (gtkrc);
-
- theme_name = d->theme_name;
- if (ve_string_empty (theme_name))
- theme_name = gdm_daemon_config_get_value_string (GDM_KEY_GTK_THEME);
- if ( ! ve_string_empty (theme_name)) {
- gchar *theme_dir = gtk_rc_get_theme_dir ();
- char *theme = g_strdup_printf ("%s/%s/gtk-2.0/gtkrc", theme_dir, theme_name);
- g_free (theme_dir);
-
- if ( ! ve_string_empty (theme) &&
- g_access (theme, R_OK) == 0)
- gtk_rc_parse (theme);
-
- g_free (theme);
- }
- }
-
- get_screen_size (d);
-}
-
-static gboolean
-dialog_failed (int status)
-{
- if (WIFSIGNALED (status) &&
- (WTERMSIG (status) == SIGTERM ||
- WTERMSIG (status) == SIGINT ||
- WTERMSIG (status) == SIGQUIT ||
- WTERMSIG (status) == SIGHUP)) {
- return FALSE;
- } else if (WIFEXITED (status) &&
- WEXITSTATUS (status) == 0) {
- return FALSE;
- } else {
- gdm_error ("failsafe dialog failed (inhibitions: %d %d)",
- inhibit_gtk_modules, inhibit_gtk_themes);
- return TRUE;
- }
-}
-
-void
-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) {
- guint sid;
- GtkWidget *dlg;
- GtkWidget *button;
- char *loc;
- char *details;
-
- if (details_label != NULL) {
- if (strncmp (details_label, "NIL", 3) == 0)
- details_label = NULL;
- }
- if (details_file != NULL) {
- if (strncmp (details_file, "NIL", 3) == 0)
- details_file = NULL;
- }
-
- if (uid != 0) {
- gid_t groups[1] = { gid };
-
- /* if we for some reason fail here
- don't allow the file */
- if G_UNLIKELY (setgid (gid) != 0)
- details_file = NULL;
- if G_UNLIKELY (setgroups (1, groups) != 0)
- details_file = NULL;
- if G_UNLIKELY (setuid (uid) != 0)
- details_file = NULL;
-
- gdm_desetuid ();
- }
-
- /* First read the details if they exist */
- if (details_label != NULL && details_file != NULL) {
- FILE *fp;
- struct stat s;
- int r;
- gboolean valid_utf8 = TRUE;
- GString *gs = g_string_new (NULL);
-
- fp = NULL;
- VE_IGNORE_EINTR (r = g_lstat (details_file, &s));
- if (r == 0) {
- if (S_ISREG (s.st_mode)) {
- VE_IGNORE_EINTR (fp = fopen (details_file, "r"));
- } else {
- 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);
- }
- }
- if (fp != NULL) {
- char buf[256];
- int lines = 0;
- char *getsret;
- VE_IGNORE_EINTR (getsret = fgets (buf, sizeof (buf), fp));
- while (getsret != NULL) {
- if ( ! g_utf8_validate (buf, -1, NULL))
- valid_utf8 = FALSE;
- g_string_append (gs, buf);
- /* cap the lines at 500, that's already
- a possibility of 128k of data */
- if (lines++ > 500) {
- 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;
- }
- VE_IGNORE_EINTR (getsret = fgets (buf, sizeof (buf), fp));
- }
- VE_IGNORE_EINTR (fclose (fp));
- } else {
- 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);
- }
-
- details = g_string_free (gs, FALSE);
-
- if ( ! valid_utf8) {
- char *tmp = g_locale_to_utf8 (details, -1, NULL, NULL, NULL);
- g_free (details);
- details = tmp;
- }
- } else {
- details = NULL;
- }
-
- setup_dialog (d, "gtk-error-box", -1, TRUE, uid);
-
- loc = g_locale_to_utf8 (error, -1, NULL, NULL, NULL);
-
- dlg = gtk_message_dialog_new (NULL /* parent */,
- 0 /* flags */,
- type,
- GTK_BUTTONS_NONE,
- "%s",
- loc);
- g_free (loc);
- gtk_widget_set_events (dlg, GDK_ALL_EVENTS_MASK);
- gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
-
- if (details_label != NULL) {
- GtkWidget *text = get_error_text_view (details);
-
- loc = g_locale_to_utf8 (details_label, -1, NULL, NULL, NULL);
- button = gtk_check_button_new_with_label (loc);
- g_free (loc);
-
- gtk_widget_show (button);
- g_object_set_data (G_OBJECT (button), "dlg", dlg);
- g_signal_connect (button, "toggled",
- G_CALLBACK (show_errors),
- text);
-
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
- button, FALSE, FALSE, 6);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
- text, FALSE, FALSE, 6);
-
- g_signal_connect_after (dlg, "size_allocate",
- G_CALLBACK (center_window),
- NULL);
- }
-
- button = gtk_dialog_add_button (GTK_DIALOG (dlg),
- GTK_STOCK_OK,
- GTK_RESPONSE_OK);
- sid = g_signal_lookup ("event",
- GTK_TYPE_WIDGET);
- g_signal_add_emission_hook (sid,
- 0 /* detail */,
- gdm_event,
- NULL /* data */,
- NULL /* destroy_notify */);
-
- center_window (dlg);
-
- gtk_widget_grab_focus (button);
-
- gtk_widget_show_now (dlg);
-
- gdk_display = gdk_display_get_default ();
-
- if (dlg->window != NULL) {
- gdk_error_trap_push ();
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- GDK_WINDOW_XWINDOW (dlg->window),
- RevertToPointerRoot,
- CurrentTime);
- gdk_flush ();
- gdk_error_trap_pop ();
- }
-
- setup_cursor (GDK_LEFT_PTR);
-
- gtk_dialog_run (GTK_DIALOG (dlg));
-
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- PointerRoot,
- RevertToPointerRoot,
- CurrentTime);
-
- _exit (0);
- } else if (pid > 0) {
- int 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_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_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_errorgui_error_box");
- }
-}
-
-static void
-press_ok (GtkWidget *entry, gpointer data)
-{
- GtkWidget *dlg = data;
- gtk_dialog_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
-}
-
-void
-gdm_errorgui_error_box (GdmDisplay *d, GtkMessageType type, const char *error)
-{
- char *msg;
- int id = 0;
-
- msg = g_strdup_printf ("type=%d$$error=%s$$details_label=%s$$details_file=%s$$uid=%d$$gid=%d", type, error, "NIL", "NIL", id, id);
-
- gdm_slave_send_string (GDM_SOP_SHOW_ERROR_DIALOG, msg);
-
- g_free (msg);
-}
-
-char *
-gdm_errorgui_failsafe_question (GdmDisplay *d,
- const char *question,
- gboolean echo)
-{
- GdkDisplay *gdk_display;
- pid_t pid;
- int p[2];
-
- if G_UNLIKELY (pipe (p) < 0)
- return NULL;
-
- g_debug ("Forking extra process: failsafe question");
-
- pid = gdm_fork_extra ();
- if (pid == 0) {
- guint sid;
- GtkWidget *dlg, *label, *entry;
- char *loc;
-
- setup_dialog (d, "gtk-failsafe-question", p[1], TRUE /* set_gdm_ids */, 0);
-
- loc = g_locale_to_utf8 (question, -1, NULL, NULL, NULL);
-
- dlg = gtk_dialog_new_with_buttons (loc,
- NULL /* parent */,
- 0 /* flags */,
- GTK_STOCK_OK,
- GTK_RESPONSE_OK,
- NULL);
- gtk_widget_set_events (dlg, GDK_ALL_EVENTS_MASK);
- gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
- g_signal_connect (G_OBJECT (dlg), "delete_event",
- G_CALLBACK (gtk_true), NULL);
-
- label = gtk_label_new (loc);
- gtk_widget_show_all (label);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
- label, FALSE, FALSE, 0);
- entry = gtk_entry_new ();
- gtk_widget_show_all (entry);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
- entry, FALSE, FALSE, 0);
- if ( ! echo)
- gtk_entry_set_visibility (GTK_ENTRY (entry),
- FALSE /* visible */);
- g_signal_connect (G_OBJECT (entry), "activate",
- G_CALLBACK (press_ok), dlg);
-
- sid = g_signal_lookup ("event",
- GTK_TYPE_WIDGET);
- g_signal_add_emission_hook (sid,
- 0 /* detail */,
- gdm_event,
- NULL /* data */,
- NULL /* destroy_notify */);
-
- center_window (dlg);
-
- gtk_widget_show_now (dlg);
-
- gdk_display = gdk_display_get_default ();
-
- if (dlg->window != NULL) {
- gdk_error_trap_push ();
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- GDK_WINDOW_XWINDOW (dlg->window),
- RevertToPointerRoot,
- CurrentTime);
- gdk_flush ();
- gdk_error_trap_pop ();
- }
-
- gtk_widget_grab_focus (entry);
-
- setup_cursor (GDK_LEFT_PTR);
-
- gtk_dialog_run (GTK_DIALOG (dlg));
-
- 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));
-
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- PointerRoot,
- RevertToPointerRoot,
- CurrentTime);
-
- _exit (0);
- } else if (pid > 0) {
- int status;
- char buf[BUFSIZ];
- int bytes;
-
- VE_IGNORE_EINTR (close (p[1]));
-
- gdm_wait_for_extra (pid, &status);
-
- if (dialog_failed (status)) {
- char *ret = NULL;
- VE_IGNORE_EINTR (close (p[0]));
- if ( ! inhibit_gtk_themes) {
- /* on failure try again, this time without any themes
- which may be causing a crash */
- inhibit_gtk_themes = TRUE;
- 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_errorgui_failsafe_question (d, question, echo);
- inhibit_gtk_modules = FALSE;
- }
- return ret;
- }
-
- VE_IGNORE_EINTR (bytes = read (p[0], buf, BUFSIZ-1));
- if (bytes > 0) {
- VE_IGNORE_EINTR (close (p[0]));
- buf[bytes] = '\0';
- return g_strdup (buf);
- }
- VE_IGNORE_EINTR (close (p[0]));
- } else {
- gdm_error (_("%s: Cannot fork to display error/info box"),
- "gdm_errorgui_failsafe_question");
- }
- return NULL;
-}
-
-gboolean
-gdm_errorgui_failsafe_yesno (GdmDisplay *d,
- const char *question)
-{
- GdkDisplay *gdk_display;
- pid_t pid;
- int p[2];
-
- 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;
- GtkWidget *dlg;
- char *loc;
-
- setup_dialog (d, "gtk-failsafe-yesno", p[1], TRUE /* set_gdm_ids */, 0);
-
- loc = g_locale_to_utf8 (question, -1, NULL, NULL, NULL);
-
- dlg = gtk_message_dialog_new (NULL /* parent */,
- 0 /* flags */,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- "%s",
- loc);
- gtk_widget_set_events (dlg, GDK_ALL_EVENTS_MASK);
- gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
-
- sid = g_signal_lookup ("event",
- GTK_TYPE_WIDGET);
- g_signal_add_emission_hook (sid,
- 0 /* detail */,
- gdm_event,
- NULL /* data */,
- NULL /* destroy_notify */);
-
- center_window (dlg);
-
- gtk_widget_show_now (dlg);
-
- gdk_display = gdk_display_get_default ();
-
- if (dlg->window != NULL) {
- gdk_error_trap_push ();
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- GDK_WINDOW_XWINDOW (dlg->window),
- RevertToPointerRoot,
- CurrentTime);
- gdk_flush ();
- gdk_error_trap_pop ();
- }
-
- setup_cursor (GDK_LEFT_PTR);
-
- if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_YES)
- gdm_fdprintf (p[1], "yes\n");
- else
- gdm_fdprintf (p[1], "no\n");
-
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- PointerRoot,
- RevertToPointerRoot,
- CurrentTime);
-
- _exit (0);
- } else if (pid > 0) {
- int status;
- char buf[BUFSIZ];
- int bytes;
-
- VE_IGNORE_EINTR (close (p[1]));
-
- gdm_wait_for_extra (pid, &status);
-
- if (dialog_failed (status)) {
- gboolean ret = FALSE;
- VE_IGNORE_EINTR (close (p[0]));
- if ( ! inhibit_gtk_themes) {
- /* on failure try again, this time without any themes
- which may be causing a crash */
- inhibit_gtk_themes = TRUE;
- 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_errorgui_failsafe_yesno (d, question);
- inhibit_gtk_modules = FALSE;
- }
- return ret;
- }
-
- VE_IGNORE_EINTR (bytes = read (p[0], buf, BUFSIZ-1));
- if (bytes > 0) {
- VE_IGNORE_EINTR (close (p[0]));
- if (buf[0] == 'y')
- return TRUE;
- else
- return FALSE;
- }
- VE_IGNORE_EINTR (close (p[0]));
- } else {
- gdm_error (_("%s: Cannot fork to display error/info box"),
- "gdm_errorgui_failsafe_yesno");
- }
- return FALSE;
-}
-
-int
-gdm_errorgui_failsafe_ask_buttons (GdmDisplay *d,
- const char *question,
- char **but)
-{
- GdkDisplay *gdk_display;
- pid_t pid;
- int p[2];
-
- 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;
- guint sid;
- GtkWidget *dlg;
- char *loc;
-
- setup_dialog (d, "gtk-failsafe-ask-buttons", p[1], TRUE /* set_gdm_ids */, 0);
-
- loc = g_locale_to_utf8 (question, -1, NULL, NULL, NULL);
-
- dlg = gtk_message_dialog_new (NULL /* parent */,
- 0 /* flags */,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_NONE,
- "%s",
- loc);
- g_free (loc);
- gtk_widget_set_events (dlg, GDK_ALL_EVENTS_MASK);
- for (i = 0; but[i] != NULL && strcmp (but[i], "NIL"); i++) {
- loc = g_locale_to_utf8 (but[i], -1, NULL, NULL, NULL);
- gtk_dialog_add_button (GTK_DIALOG (dlg),
- loc, i);
- g_free (loc);
-
- }
- gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
-
- sid = g_signal_lookup ("event",
- GTK_TYPE_WIDGET);
- g_signal_add_emission_hook (sid,
- 0 /* detail */,
- gdm_event,
- NULL /* data */,
- NULL /* destroy_notify */);
-
- center_window (dlg);
-
- gtk_widget_show_now (dlg);
-
- gdk_display = gdk_display_get_default ();
-
- if (dlg->window != NULL) {
- gdk_error_trap_push ();
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- GDK_WINDOW_XWINDOW (dlg->window),
- RevertToPointerRoot,
- CurrentTime);
- gdk_flush ();
- gdk_error_trap_pop ();
- }
-
- setup_cursor (GDK_LEFT_PTR);
-
- i = gtk_dialog_run (GTK_DIALOG (dlg));
- gdm_fdprintf (p[1], "%d\n", i);
-
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- PointerRoot,
- RevertToPointerRoot,
- CurrentTime);
-
- _exit (0);
- } else if (pid > 0) {
- int status;
- char buf[BUFSIZ];
- int bytes;
-
- VE_IGNORE_EINTR (close (p[1]));
-
- gdm_wait_for_extra (pid, &status);
-
- if (dialog_failed (status)) {
- int ret = -1;
- VE_IGNORE_EINTR (close (p[0]));
- if ( ! inhibit_gtk_themes) {
- /* on failure try again, this time without any themes
- which may be causing a crash */
- inhibit_gtk_themes = TRUE;
- 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_errorgui_failsafe_ask_buttons (d, question, but);
- inhibit_gtk_modules = FALSE;
- }
- return ret;
- }
-
- VE_IGNORE_EINTR (bytes = read (p[0], buf, BUFSIZ-1));
- if (bytes > 0) {
- int i;
- VE_IGNORE_EINTR (close (p[0]));
- buf[bytes] = '\0';
- if (sscanf (buf, "%d", &i) == 1)
- return i;
- else
- return -1;
- }
- VE_IGNORE_EINTR (close (p[0]));
- } else {
- gdm_error (_("%s: Cannot fork to display error/info box"),
- "gdm_errorgui_failsafe_ask_buttons");
- }
- return -1;
-}
diff --git a/daemon/errorgui.h b/daemon/errorgui.h
deleted file mode 100644
index 15d245cd..00000000
--- a/daemon/errorgui.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef GDM_ERRORGUI_H
-#define GDM_ERRORGUI_H
-
-#include "gdm.h"
-#include <gtk/gtkmessagedialog.h>
-
-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 */
-
-/* EOF */
-
diff --git a/daemon/filecheck.c b/daemon/filecheck.c
deleted file mode 100644
index 027a5321..00000000
--- a/daemon/filecheck.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- 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
- * 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
- */
-
-#include "config.h"
-
-#include <glib/gi18n.h>
-#include <sys/stat.h>
-
-#include "gdm.h"
-#include "gdm-common.h"
-#include "gdm-daemon-config.h"
-
-#include "filecheck.h"
-
-/**
- * gdm_file_check:
- * @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.
- * @absentok: Accept absent files if TRUE.
- * @absentdirok: Absent directory returns FALSE but without complaining
- * @maxsize: Maximum acceptable filesize in KB. 0 to disable.
- * @perms: 0 to allow user writable file/dir only. 1 to allow group and 2 to allow global writable file/dir.
- *
- * Examines a file to determine whether it is safe for the daemon to write to it.
- */
-
-/* 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)
-{
- 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)
- g_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)) {
- g_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) {
- g_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) {
- 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;
- }
-
- /* ... 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;
- }
-
- /* ... 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)
-{
- 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;
- }
-
- /* 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/filecheck.h b/daemon/filecheck.h
deleted file mode 100644
index 7d71a691..00000000
--- a/daemon/filecheck.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef GDM_FILECHECK_H
-#define GDM_FILECHECK_H
-
-gboolean gdm_file_check (const gchar *caller, uid_t user, const gchar *dir,
- const gchar *file, gboolean absentok,
- gboolean absentdirok, gint maxsize,
- gint perms);
-
-/* more paranoid on the file itself, doesn't check directory (for all we know
- it could be /tmp) */
-gboolean gdm_auth_file_check (const gchar *caller, uid_t user, const gchar *authfile, gboolean absentok, struct stat *s);
-
-#endif /* GDM_FILECHECK_H */
-
-/* EOF */
diff --git a/daemon/fstype.c b/daemon/fstype.c
deleted file mode 100644
index 84936ab1..00000000
--- a/daemon/fstype.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/* fstype.c -- determine type of filesystems that files are on
- Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* This code was relicensed by the FSF on May 1 2002
-
- This file is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- this file 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
- */
-/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#else
-extern int errno;
-#endif
-#include <string.h>
-#ifdef HAVE_LIBGEN_H
-#include <libgen.h>
-#endif
-
-#if __STDC__
-# define P_(s) s
-#else
-# define P_(s) ()
-#endif
-
-static char *filesystem_type_uncached P_((char *path, char *relpath, struct stat *statp));
-
-void fstype_internal_error (int level, int num, char const *fmt, ...);
-
-#ifdef FSTYPE_MNTENT /* 4.3BSD etc. */
-static int xatoi P_((char *cp));
-#endif
-
-#ifdef FSTYPE_MNTENT /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
-#include <mntent.h>
-#if !defined(MOUNTED)
-# if defined(MNT_MNTTAB) /* HP-UX. */
-# define MOUNTED MNT_MNTTAB
-# endif
-# if defined(MNTTABNAME) /* Dynix. */
-# define MOUNTED MNTTABNAME
-# endif
-#endif
-#endif
-
-#ifdef FSTYPE_GETMNT /* Ultrix. */
-#include <sys/param.h>
-#include <sys/mount.h>
-#include <sys/fs_types.h>
-#endif
-
-#ifdef FSTYPE_USG_STATFS /* SVR3. */
-#include <sys/statfs.h>
-#include <sys/fstyp.h>
-#endif
-
-#ifdef FSTYPE_STATVFS /* SVR4. */
-#include <sys/statvfs.h>
-#include <sys/fstyp.h>
-#endif
-
-#ifdef FSTYPE_STATFS /* 4.4BSD. */
-#include <sys/param.h> /* NetBSD needs this. */
-#include <sys/mount.h>
-
-#ifndef MFSNAMELEN /* NetBSD defines this. */
-static char *
-fstype_to_string (t)
- short t;
-{
-#ifdef INITMOUNTNAMES /* Defined in 4.4BSD, not in NET/2. */
- static char *mn[] = INITMOUNTNAMES;
- if (t >= 0 && t <= MOUNT_MAXTYPE)
- return mn[t];
- else
- return "?";
-#else /* !INITMOUNTNAMES */
- switch (t)
- {
- case MOUNT_UFS:
- return "ufs";
- case MOUNT_NFS:
- return "nfs";
-#ifdef MOUNT_PC
- case MOUNT_PC:
- return "pc";
-#endif
-#ifdef MOUNT_MFS
- case MOUNT_MFS:
- return "mfs";
-#endif
-#ifdef MOUNT_LO
- case MOUNT_LO:
- return "lofs";
-#endif
-#ifdef MOUNT_TFS
- case MOUNT_TFS:
- return "tfs";
-#endif
-#ifdef MOUNT_TMP
- case MOUNT_TMP:
- return "tmp";
-#endif
-#ifdef MOUNT_MSDOS
- case MOUNT_MSDOS:
- return "msdos";
-#endif
-#ifdef MOUNT_ISO9660
- case MOUNT_ISO9660:
- return "iso9660fs";
-#endif
- default:
- return "?";
- }
-#endif /* !INITMOUNTNAMES */
-}
-#endif /* !MFSNAMELEN */
-#endif /* FSTYPE_STATFS */
-
-#ifdef FSTYPE_AIX_STATFS /* AIX. */
-#include <sys/vmount.h>
-#include <sys/statfs.h>
-
-#define FSTYPE_STATFS /* Otherwise like 4.4BSD. */
-#define f_type f_vfstype
-
-static char *
-fstype_to_string (t)
- short t;
-{
- switch (t)
- {
- case MNT_AIX:
-#if 0 /* NFS filesystems are actually MNT_AIX. */
- return "aix";
-#endif
- case MNT_NFS:
- return "nfs";
- case MNT_JFS:
- return "jfs";
- case MNT_CDROM:
- return "cdrom";
- default:
- return "?";
- }
-}
-#endif /* FSTYPE_AIX_STATFS */
-
-#ifdef AFS
-#include <netinet/in.h>
-#include <afs/venus.h>
-#if __STDC__
-/* On SunOS 4, afs/vice.h defines this to rely on a pre-ANSI cpp. */
-#undef _VICEIOCTL
-#define _VICEIOCTL(id) ((unsigned int ) _IOW('V', id, struct ViceIoctl))
-#endif
-#ifndef _IOW
-/* AFS on Solaris 2.3 doesn't get this definition. */
-#include <sys/ioccom.h>
-#endif
-
-static int
-in_afs (path)
- char *path;
-{
- static char space[2048];
- struct ViceIoctl vi;
-
- vi.in_size = 0;
- vi.out_size = sizeof (space);
- vi.out = space;
-
- if (pioctl (path, VIOC_FILE_CELL_NAME, &vi, 1)
- && (errno == EINVAL || errno == ENOENT))
- return 0;
- return 1;
-}
-#endif /* AFS */
-
-#include <glib.h>
-#include <glib/gstdio.h>
-
-/* Nonzero if the current filesystem's type is known. */
-static int fstype_known = 0;
-
-char *filesystem_type (char *path, char *relpath, struct stat *statp);
-/* Return a static string naming the type of filesystem that the file PATH,
- described by STATP, is on.
- RELPATH is the file name relative to the current directory.
- Return "unknown" if its filesystem type is unknown. */
-
-char *
-filesystem_type (char *path, char *relpath, struct stat *statp)
-{
- static char *current_fstype = NULL;
- static dev_t current_dev;
-
- if (current_fstype != NULL)
- {
- if (fstype_known && statp->st_dev == current_dev)
- return current_fstype; /* Cached value. */
- g_free (current_fstype);
- }
- current_dev = statp->st_dev;
- current_fstype = filesystem_type_uncached (path, relpath, statp);
- return current_fstype;
-}
-
-void
-fstype_internal_error (int level, int num, char const *fmt, ...)
-{
-}
-
-/* Return a newly allocated string naming the type of filesystem that the
- file PATH, described by STATP, is on.
- RELPATH is the file name relative to the current directory.
- Return "unknown" if its filesystem type is unknown. */
-
-static char *
-filesystem_type_uncached (char *path, char *relpath, struct stat *statp)
-{
- char *type = NULL;
-
-#ifdef FSTYPE_MNTENT /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
- char *table = MOUNTED;
- FILE *mfp;
- struct mntent *mnt;
-
- mfp = setmntent (table, "r");
- if (mfp == NULL) {
- fstype_internal_error (1, errno, "%s", table);
- goto no_mtab;
- }
-
- /* Find the entry with the same device number as STATP, and return
- that entry's fstype. */
- while (type == NULL && (mnt = getmntent (mfp)))
- {
- char *devopt;
- dev_t dev;
- struct stat disk_stats;
-
-#ifdef MNTTYPE_IGNORE
- if (!strcmp (mnt->mnt_type, MNTTYPE_IGNORE))
- continue;
-#endif
-
- /* Newer systems like SunOS 4.1 keep the dev number in the mtab,
- in the options string. For older systems, we need to stat the
- directory that the filesystem is mounted on to get it.
-
- Unfortunately, the HPUX 9.x mnttab entries created by automountq
- contain a dev= option but the option value does not match the
- st_dev value of the file (maybe the lower 16 bits match?). */
-
-#if !defined(hpux) && !defined(__hpux__)
- devopt = strstr (mnt->mnt_opts, "dev=");
- if (devopt)
- {
- if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
- dev = xatoi (devopt + 6);
- else
- dev = xatoi (devopt + 4);
- }
- else
-#endif /* not hpux */
- {
- if (g_stat (mnt->mnt_dir, &disk_stats) == -1) {
- if (errno == EACCES)
- continue;
- else
- fstype_internal_error (1, errno, "error in %s: %s", table, mnt->mnt_dir);
- }
- dev = disk_stats.st_dev;
- }
-
- if (dev == statp->st_dev)
- type = mnt->mnt_type;
- }
-
- if (endmntent (mfp) == 0)
- fstype_internal_error (0, errno, "%s", table);
- no_mtab:
-#endif
-
-#ifdef FSTYPE_GETMNT /* Ultrix. */
- int offset = 0;
- struct fs_data fsd;
-
- while (type == NULL
- && getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY, 0) > 0)
- {
- if (fsd.fd_req.dev == statp->st_dev)
- type = gt_names[fsd.fd_req.fstype];
- }
-#endif
-
-#ifdef FSTYPE_USG_STATFS /* SVR3. */
- struct statfs fss;
- char typebuf[FSTYPSZ];
-
- if (statfs (relpath, &fss, sizeof (struct statfs), 0) == -1)
- {
- /* Don't die if a file was just removed. */
- if (errno != ENOENT)
- fstype_internal_error (1, errno, "%s", path);
- }
- else if (!sysfs (GETFSTYP, fss.f_fstyp, typebuf))
- type = typebuf;
-#endif
-
-#ifdef FSTYPE_STATVFS /* SVR4. */
- struct statvfs fss;
-
- if (statvfs (relpath, &fss) == -1)
- {
- /* Don't die if a file was just removed. */
- if (errno != ENOENT)
- fstype_internal_error (1, errno, "%s", path);
- }
- else
- type = fss.f_basetype;
-#endif
-
-#ifdef FSTYPE_STATFS /* 4.4BSD. */
- struct statfs fss;
- char *p;
-
- if (S_ISLNK (statp->st_mode))
- p = dirname (relpath);
- else
- p = relpath;
-
- if (statfs (p, &fss) == -1)
- {
- /* Don't die if symlink to nonexisting file, or a file that was
- just removed. */
- if (errno != ENOENT)
- fstype_internal_error (1, errno, "%s", path);
- }
- else
- {
-#ifdef MFSNAMELEN /* NetBSD. */
- type = fss.f_fstypename;
-#else
- type = fstype_to_string (fss.f_type);
-#endif
- }
- if (p != relpath)
- free (p);
-#endif
-
-#ifdef AFS
- if ((!type || !strcmp (type, "xx")) && in_afs (relpath))
- type = "afs";
-#endif
-
- /* An unknown value can be caused by an ENOENT error condition.
- Don't cache those values. */
- fstype_known = (type != NULL);
-
- return g_strdup (type ? type : "unknown");
-}
-
-#ifdef FSTYPE_MNTENT /* 4.3BSD etc. */
-/* Return the value of the hexadecimal number represented by CP.
- No prefix (like '0x') or suffix (like 'h') is expected to be
- part of CP. */
-
-static int
-xatoi (char *cp)
-{
- int val;
-
- val = 0;
- while (*cp)
- {
- if (*cp >= 'a' && *cp <= 'f')
- val = val * 16 + *cp - 'a' + 10;
- else if (*cp >= 'A' && *cp <= 'F')
- val = val * 16 + *cp - 'A' + 10;
- else if (*cp >= '0' && *cp <= '9')
- val = val * 16 + *cp - '0';
- else
- break;
- cp++;
- }
- return val;
-}
-#endif
diff --git a/daemon/gdm-daemon-config-entries.h b/daemon/gdm-daemon-config-entries.h
deleted file mode 100644
index f335ed17..00000000
--- a/daemon/gdm-daemon-config-entries.h
+++ /dev/null
@@ -1,569 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _GDM_DAEMON_CONFIG_ENTRIES_H
-#define _GDM_DAEMON_CONFIG_ENTRIES_H
-
-#include <glib.h>
-
-#include "gdm-config.h"
-
-G_BEGIN_DECLS
-
-#define GDM_CONFIG_GROUP_NONE NULL
-#define GDM_CONFIG_GROUP_DAEMON "daemon"
-#define GDM_CONFIG_GROUP_SECURITY "security"
-#define GDM_CONFIG_GROUP_XDMCP "xdmcp"
-#define GDM_CONFIG_GROUP_GREETER "greeter"
-#define GDM_CONFIG_GROUP_GUI "gui"
-#define GDM_CONFIG_GROUP_CUSTOM_CMD "customcommand"
-#define GDM_CONFIG_GROUP_CHOOSER "chooser"
-#define GDM_CONFIG_GROUP_SERVERS "servers"
-#define GDM_CONFIG_GROUP_DEBUG "debug"
-
-#define GDM_CONFIG_GROUP_SERVER_PREFIX "server-"
-
-#include "gdm-daemon-config-keys.h"
-
-typedef enum {
- GDM_ID_NONE,
- GDM_ID_DEBUG,
- GDM_ID_DEBUG_GESTURES,
- GDM_ID_CHOOSER,
- GDM_ID_AUTOMATIC_LOGIN_ENABLE,
- GDM_ID_AUTOMATIC_LOGIN,
- GDM_ID_GREETER,
- GDM_ID_REMOTE_GREETER,
- GDM_ID_ADD_GTK_MODULES,
- GDM_ID_GTK_MODULES_LIST,
- GDM_ID_GROUP,
- GDM_ID_HALT,
- GDM_ID_DISPLAY_INIT_DIR,
- GDM_ID_KILL_INIT_CLIENTS,
- GDM_ID_LOG_DIR,
- GDM_ID_PATH,
- GDM_ID_POSTSESSION,
- GDM_ID_PRESESSION,
- GDM_ID_POSTLOGIN,
- GDM_ID_FAILSAFE_XSERVER,
- GDM_ID_X_KEEPS_CRASHING,
- GDM_ID_REBOOT ,
- GDM_ID_CUSTOM_CMD_TEMPLATE,
- GDM_ID_CUSTOM_CMD_LABEL_TEMPLATE,
- GDM_ID_CUSTOM_CMD_LR_LABEL_TEMPLATE,
- GDM_ID_CUSTOM_CMD_TEXT_TEMPLATE,
- GDM_ID_CUSTOM_CMD_TOOLTIP_TEMPLATE,
- GDM_ID_CUSTOM_CMD_NO_RESTART_TEMPLATE,
- GDM_ID_CUSTOM_CMD_IS_PERSISTENT_TEMPLATE,
- GDM_ID_ROOT_PATH,
- GDM_ID_SERV_AUTHDIR,
- GDM_ID_SESSION_DESKTOP_DIR,
- GDM_ID_BASE_XSESSION,
- GDM_ID_DEFAULT_SESSION,
- GDM_ID_SUSPEND,
- GDM_ID_USER_AUTHDIR,
- GDM_ID_USER_AUTHDIR_FALLBACK,
- GDM_ID_USER_AUTHFILE,
- GDM_ID_USER,
- GDM_ID_CONSOLE_NOTIFY,
- GDM_ID_DOUBLE_LOGIN_WARNING,
- GDM_ID_ALWAYS_LOGIN_CURRENT_SESSION,
- GDM_ID_DISPLAY_LAST_LOGIN,
- GDM_ID_TIMED_LOGIN_ENABLE,
- GDM_ID_TIMED_LOGIN,
- GDM_ID_TIMED_LOGIN_DELAY,
- GDM_ID_FLEXI_REAP_DELAY_MINUTES,
- GDM_ID_STANDARD_XSERVER,
- GDM_ID_FLEXIBLE_XSERVERS,
- GDM_ID_DYNAMIC_XSERVERS,
- GDM_ID_XNEST,
- GDM_ID_XNEST_UNSCALED_FONT_PATH,
- GDM_ID_FIRST_VT,
- GDM_ID_VT_ALLOCATION,
- GDM_ID_CONSOLE_CANNOT_HANDLE,
- GDM_ID_XSERVER_TIMEOUT,
- GDM_ID_SERVER_PREFIX,
- GDM_ID_SERVER_NAME,
- GDM_ID_SERVER_COMMAND,
- GDM_ID_SERVER_FLEXIBLE,
- GDM_ID_SERVER_CHOOSABLE,
- GDM_ID_SERVER_HANDLED,
- GDM_ID_SERVER_CHOOSER,
- GDM_ID_SERVER_PRIORITY,
- GDM_ID_ALLOW_ROOT,
- GDM_ID_ALLOW_REMOTE_ROOT,
- GDM_ID_ALLOW_REMOTE_AUTOLOGIN,
- GDM_ID_USER_MAX_FILE,
- GDM_ID_RELAX_PERM,
- GDM_ID_CHECK_DIR_OWNER,
- GDM_ID_SUPPORT_AUTOMOUNT,
- GDM_ID_RETRY_DELAY,
- GDM_ID_DISALLOW_TCP,
- GDM_ID_PAM_STACK,
- GDM_ID_NEVER_PLACE_COOKIES_ON_NFS,
- GDM_ID_PASSWORD_REQUIRED,
- GDM_ID_XDMCP,
- GDM_ID_MAX_PENDING,
- GDM_ID_MAX_SESSIONS,
- GDM_ID_MAX_WAIT,
- GDM_ID_DISPLAYS_PER_HOST,
- GDM_ID_UDP_PORT,
- GDM_ID_INDIRECT,
- GDM_ID_MAX_INDIRECT,
- GDM_ID_MAX_WAIT_INDIRECT,
- GDM_ID_PING_INTERVAL,
- GDM_ID_WILLING,
- GDM_ID_XDMCP_PROXY,
- GDM_ID_XDMCP_PROXY_XSERVER,
- GDM_ID_XDMCP_PROXY_RECONNECT,
- GDM_ID_GTK_THEME,
- GDM_ID_GTKRC,
- GDM_ID_MAX_ICON_WIDTH,
- GDM_ID_MAX_ICON_HEIGHT,
- GDM_ID_ALLOW_GTK_THEME_CHANGE,
- GDM_ID_GTK_THEMES_TO_ALLOW,
- GDM_ID_BROWSER,
- GDM_ID_INCLUDE,
- GDM_ID_EXCLUDE,
- GDM_ID_INCLUDE_ALL,
- GDM_ID_MINIMAL_UID,
- GDM_ID_DEFAULT_FACE,
- GDM_ID_GLOBAL_FACE_DIR,
- GDM_ID_LOCALE_FILE,
- GDM_ID_LOGO,
- GDM_ID_CHOOSER_BUTTON_LOGO,
- GDM_ID_QUIVER,
- GDM_ID_SYSTEM_MENU,
- GDM_ID_CONFIGURATOR,
- GDM_ID_CONFIG_AVAILABLE,
- GDM_ID_CHOOSER_BUTTON,
- GDM_ID_TITLE_BAR,
- GDM_ID_DEFAULT_WELCOME,
- GDM_ID_DEFAULT_REMOTE_WELCOME,
- GDM_ID_WELCOME,
- GDM_ID_REMOTE_WELCOME,
- GDM_ID_XINERAMA_SCREEN,
- GDM_ID_BACKGROUND_PROGRAM,
- GDM_ID_RUN_BACKGROUND_PROGRAM_ALWAYS,
- GDM_ID_BACKGROUND_PROGRAM_INITIAL_DELAY,
- GDM_ID_RESTART_BACKGROUND_PROGRAM,
- GDM_ID_BACKGROUND_PROGRAM_RESTART_DELAY,
- GDM_ID_BACKGROUND_IMAGE,
- GDM_ID_BACKGROUND_COLOR,
- GDM_ID_BACKGROUND_TYPE,
- GDM_ID_BACKGROUND_SCALE_TO_FIT,
- GDM_ID_BACKGROUND_REMOTE_ONLY_COLOR,
- GDM_ID_LOCK_POSITION,
- GDM_ID_SET_POSITION,
- GDM_ID_POSITION_X,
- GDM_ID_POSITION_Y,
- GDM_ID_USE_24_CLOCK,
- GDM_ID_ENTRY_CIRCLES,
- GDM_ID_ENTRY_INVISIBLE,
- GDM_ID_GRAPHICAL_THEME,
- GDM_ID_GRAPHICAL_THEMES,
- GDM_ID_GRAPHICAL_THEME_RAND,
- GDM_ID_GRAPHICAL_THEME_DIR,
- GDM_ID_GRAPHICAL_THEMED_COLOR,
- GDM_ID_INFO_MSG_FILE,
- GDM_ID_INFO_MSG_FONT,
- GDM_ID_PRE_FETCH_PROGRAM,
- GDM_ID_SOUND_ON_LOGIN,
- GDM_ID_SOUND_ON_LOGIN_SUCCESS,
- GDM_ID_SOUND_ON_LOGIN_FAILURE,
- GDM_ID_SOUND_ON_LOGIN_FILE,
- GDM_ID_SOUND_ON_LOGIN_SUCCESS_FILE,
- GDM_ID_SOUND_ON_LOGIN_FAILURE_FILE,
- GDM_ID_SOUND_PROGRAM,
- GDM_ID_SCAN_TIME,
- GDM_ID_DEFAULT_HOST_IMG,
- GDM_ID_HOST_IMAGE_DIR,
- GDM_ID_HOSTS,
- GDM_ID_MULTICAST,
- GDM_ID_MULTICAST_ADDR,
- GDM_ID_BROADCAST,
- GDM_ID_ALLOW_ADD,
- GDM_ID_SECTION_GREETER,
- GDM_ID_SECTION_SERVERS,
- GDM_ID_SHOW_GNOME_FAILSAFE,
- GDM_ID_SHOW_XTERM_FAILSAFE,
- GDM_ID_SHOW_LAST_SESSION,
- GDM_ID_SYSTEM_COMMANDS_IN_MENU,
- GDM_ID_ALLOW_LOGOUT_ACTIONS,
- GDM_ID_RBAC_SYSTEM_COMMAND_KEYS,
- GDK_ID_LAST
-} GdmConfigKey;
-
-
-/*
- * The following section contains keys used by the GDM configuration files.
- * The key/value pairs defined in the GDM configuration files are considered
- * "stable" interface and should only change in ways that are backwards
- * compatible. Please keep this in mind when changing GDM configuration.
- *
- * Developers who add new configuration options should ensure that they do the
- * following:
- *
- * + Add the key to config/gdm.conf.in file and specify the default value.
- * Include comments explaining what the key does.
- *
- * + Add the key as a #define to daemon/gdm-daemon-config-keys.h with
- * the same default value.
- *
- * + Update the GdmConfigKey enumeration and gdm_daemon_config_entries[] to
- * add the new key. Include some documentation about the new key,
- * following the style of existing comments.
- *
- * + Add any validation to the validate_cb function in
- * gdm-daemon-config.c, if validation is needed.
- *
- * + If GDM_UPDATE_CONFIG should not respond to this configuration setting,
- * update the gdm_daemon_config_update_key function in gdmconfig.c to
- * return FALSE for this key. Examples include changing the ServAuthDir
- * or other values that GDM should not change until it is restarted. If
- * this is true, the next bullet can be ignored.
- *
- * + If the option should cause the greeter (gdmlogin/gdmgreeter) program to
- * be updated immediately, update the notify_cb and lookup_notify_key
- * functions to handle this key.
- *
- * + Add the key to the gdm_read_config and gdm_reread_config functions in
- * gui/gdmlogin.c, gui/gdmchooser.c, and gui/greeter/greeter.c
- * if the key is used by those programs. Note that all GDM slaves load
- * all their configuration data between calls to gdmcomm_comm_bulk_start()
- * and gdmcomm_comm_bulk_stop(). This makes sure that the slave only uses
- * a single sockets connection to get all configuration data. If a new
- * config value is read by a slave, make sure to load the key in this
- * code section for best performance.
- *
- * + The gui/gdmsetup.c program should be updated to support the new option
- * unless there's a good reason not to.
- *
- * + Currently GDM treats any key in the "gui" and "greeter" categories,
- * and security/PamStack as available for per-display configuration.
- * If a key is appropriate for per-display configuration, and is not
- * in the "gui" or "greeter" categories, then it will need to be added
- * to the gdm_config_key_to_string_per_display function. It may make
- * sense for some keys used by the daemon to be per-display so this
- * will need to be coded (refer to GDM_ID_PAM_STACK for an example).
- *
- * + Update the docs/C/gdm.xml file to include information about the new
- * option. Include information about any other interfaces (such as
- * ENVIRONMENT variables) that may affect the configuration option.
- * Patches without documentation will not be accepted.
- *
- * Please do this work *before* submitting an patch. Patches that are not
- * complete will not likely be accepted.
- */
-
-#define GDM_DEFAULT_WELCOME_MSG "Welcome"
-#define GDM_DEFAULT_REMOTE_WELCOME_MSG "Welcome to %n"
-
-/* These are processed in order so debug should always be first */
-static const GdmConfigEntry gdm_daemon_config_entries [] = {
- { GDM_CONFIG_GROUP_DEBUG, "Enable", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_DEBUG },
- { GDM_CONFIG_GROUP_DEBUG, "Gestures", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_DEBUG_GESTURES },
-
-
- { GDM_CONFIG_GROUP_DAEMON, "Chooser", GDM_CONFIG_VALUE_STRING, LIBEXECDIR "/gdmchooser", GDM_ID_CHOOSER },
- { GDM_CONFIG_GROUP_DAEMON, "AutomaticLoginEnable", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_AUTOMATIC_LOGIN_ENABLE },
- { GDM_CONFIG_GROUP_DAEMON, "AutomaticLogin", GDM_CONFIG_VALUE_STRING, "", GDM_ID_AUTOMATIC_LOGIN },
-
- /* The SDTLOGIN feature is Solaris specific, and causes the Xserver to be
- * run with user permissionsinstead of as root, which adds security but,
- * disables the AlwaysRestartServer option as highlighted in the gdm
- * documentation */
-
- { GDM_CONFIG_GROUP_DAEMON, "Greeter", GDM_CONFIG_VALUE_STRING, LIBEXECDIR "/gdmlogin", GDM_ID_GREETER },
- { GDM_CONFIG_GROUP_DAEMON, "RemoteGreeter", GDM_CONFIG_VALUE_STRING, LIBEXECDIR "/gdmlogin", GDM_ID_REMOTE_GREETER },
- { GDM_CONFIG_GROUP_DAEMON, "AddGtkModules", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_ADD_GTK_MODULES },
- { GDM_CONFIG_GROUP_DAEMON, "GtkModulesList", GDM_CONFIG_VALUE_STRING, NULL, GDM_ID_GTK_MODULES_LIST },
-
- { GDM_CONFIG_GROUP_DAEMON, "User", GDM_CONFIG_VALUE_STRING, "gdm", GDM_ID_USER },
- { GDM_CONFIG_GROUP_DAEMON, "Group", GDM_CONFIG_VALUE_STRING, "gdm", GDM_ID_GROUP },
-
- { GDM_CONFIG_GROUP_DAEMON, "HaltCommand", GDM_CONFIG_VALUE_STRING_ARRAY, HALT_COMMAND, GDM_ID_HALT },
- { GDM_CONFIG_GROUP_DAEMON, "RebootCommand", GDM_CONFIG_VALUE_STRING_ARRAY, REBOOT_COMMAND, GDM_ID_REBOOT },
- { GDM_CONFIG_GROUP_DAEMON, "SuspendCommand", GDM_CONFIG_VALUE_STRING_ARRAY, SUSPEND_COMMAND, GDM_ID_SUSPEND },
-
- { GDM_CONFIG_GROUP_DAEMON, "DisplayInitDir", GDM_CONFIG_VALUE_STRING, GDMCONFDIR "/Init", GDM_ID_DISPLAY_INIT_DIR },
- { GDM_CONFIG_GROUP_DAEMON, "KillInitClients", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_KILL_INIT_CLIENTS },
- { GDM_CONFIG_GROUP_DAEMON, "LogDir", GDM_CONFIG_VALUE_STRING, LOGDIR, GDM_ID_LOG_DIR },
- { GDM_CONFIG_GROUP_DAEMON, "DefaultPath", GDM_CONFIG_VALUE_STRING, GDM_USER_PATH, GDM_ID_PATH },
- { GDM_CONFIG_GROUP_DAEMON, "PostSessionScriptDir", GDM_CONFIG_VALUE_STRING, GDMCONFDIR "/PostSession/", GDM_ID_POSTSESSION },
- { GDM_CONFIG_GROUP_DAEMON, "PreSessionScriptDir", GDM_CONFIG_VALUE_STRING, GDMCONFDIR "/PreSession/", GDM_ID_PRESESSION },
- { GDM_CONFIG_GROUP_DAEMON, "PostLoginScriptDir", GDM_CONFIG_VALUE_STRING, GDMCONFDIR "/PreSession/", GDM_ID_POSTLOGIN },
- { GDM_CONFIG_GROUP_DAEMON, "FailsafeXServer", GDM_CONFIG_VALUE_STRING, NULL, GDM_ID_FAILSAFE_XSERVER },
- { GDM_CONFIG_GROUP_DAEMON, "XKeepsCrashing", GDM_CONFIG_VALUE_STRING, GDMCONFDIR "/XKeepsCrashing", GDM_ID_X_KEEPS_CRASHING },
- { GDM_CONFIG_GROUP_DAEMON, "RootPath", GDM_CONFIG_VALUE_STRING, "/sbin:/usr/sbin:" GDM_USER_PATH, GDM_ID_ROOT_PATH },
- { GDM_CONFIG_GROUP_DAEMON, "ServAuthDir", GDM_CONFIG_VALUE_STRING, AUTHDIR, GDM_ID_SERV_AUTHDIR },
- { GDM_CONFIG_GROUP_DAEMON, "SessionDesktopDir", GDM_CONFIG_VALUE_STRING, "/etc/X11/sessions/:" DMCONFDIR "/Sessions/:" DATADIR "/gdm/BuiltInSessions/:" DATADIR "/xsessions/", GDM_ID_SESSION_DESKTOP_DIR },
- { GDM_CONFIG_GROUP_DAEMON, "BaseXsession", GDM_CONFIG_VALUE_STRING, GDMCONFDIR "/Xsession", GDM_ID_BASE_XSESSION },
- { GDM_CONFIG_GROUP_DAEMON, "DefaultSession", GDM_CONFIG_VALUE_STRING, "gnome.desktop", GDM_ID_DEFAULT_SESSION },
-
- { GDM_CONFIG_GROUP_DAEMON, "UserAuthDir", GDM_CONFIG_VALUE_STRING, "", GDM_ID_USER_AUTHDIR },
- { GDM_CONFIG_GROUP_DAEMON, "UserAuthFBDir", GDM_CONFIG_VALUE_STRING, "/tmp", GDM_ID_USER_AUTHDIR_FALLBACK },
- { GDM_CONFIG_GROUP_DAEMON, "UserAuthFile", GDM_CONFIG_VALUE_STRING, ".Xauthority", GDM_ID_USER_AUTHFILE },
- { GDM_CONFIG_GROUP_DAEMON, "ConsoleNotify", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_CONSOLE_NOTIFY },
-
- { GDM_CONFIG_GROUP_DAEMON, "DoubleLoginWarning", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_DOUBLE_LOGIN_WARNING },
- { GDM_CONFIG_GROUP_DAEMON, "AlwaysLoginCurrentSession", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_ALWAYS_LOGIN_CURRENT_SESSION },
-
- { GDM_CONFIG_GROUP_DAEMON, "DisplayLastLogin", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_DISPLAY_LAST_LOGIN },
-
- { GDM_CONFIG_GROUP_DAEMON, "TimedLoginEnable", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_TIMED_LOGIN_ENABLE },
- { GDM_CONFIG_GROUP_DAEMON, "TimedLogin", GDM_CONFIG_VALUE_STRING, "", GDM_ID_TIMED_LOGIN },
- { GDM_CONFIG_GROUP_DAEMON, "TimedLoginDelay", GDM_CONFIG_VALUE_INT, "30", GDM_ID_TIMED_LOGIN_DELAY },
-
- { GDM_CONFIG_GROUP_DAEMON, "FlexiReapDelayMinutes", GDM_CONFIG_VALUE_INT, "5", GDM_ID_FLEXI_REAP_DELAY_MINUTES },
-
- { GDM_CONFIG_GROUP_DAEMON, "StandardXServer", GDM_CONFIG_VALUE_STRING, X_SERVER, GDM_ID_STANDARD_XSERVER },
- { GDM_CONFIG_GROUP_DAEMON, "FlexibleXServers", GDM_CONFIG_VALUE_INT, "5", GDM_ID_FLEXIBLE_XSERVERS },
- { GDM_CONFIG_GROUP_DAEMON, "DynamicXServers", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_DYNAMIC_XSERVERS },
- { GDM_CONFIG_GROUP_DAEMON, "Xnest", GDM_CONFIG_VALUE_STRING, X_XNEST_CMD ", " X_XNEST_CONFIG_OPTIONS, GDM_ID_XNEST },
- { GDM_CONFIG_GROUP_DAEMON, "XnestUnscaledFontPath", GDM_CONFIG_VALUE_BOOL, X_XNEST_UNSCALED_FONTPATH, GDM_ID_XNEST_UNSCALED_FONT_PATH },
-
- /* Keys for automatic VT allocation rather then letting it up to the X server */
- { GDM_CONFIG_GROUP_DAEMON, "FirstVT", GDM_CONFIG_VALUE_INT, "7", GDM_ID_FIRST_VT },
- { GDM_CONFIG_GROUP_DAEMON, "VTAllocation", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_VT_ALLOCATION },
-
- { GDM_CONFIG_GROUP_DAEMON, "ConsoleCannotHandle", GDM_CONFIG_VALUE_STRING, "am,ar,az,bn,el,fa,gu,hi,ja,ko,ml,mr,pa,ta,zh", GDM_ID_CONSOLE_CANNOT_HANDLE },
-
- /* How long to wait before assuming an Xserver has timed out */
- { GDM_CONFIG_GROUP_DAEMON, "GdmXserverTimeout", GDM_CONFIG_VALUE_INT, "10", GDM_ID_XSERVER_TIMEOUT },
-
- { GDM_CONFIG_GROUP_DAEMON, "SystemCommandsInMenu", GDM_CONFIG_VALUE_STRING_ARRAY, "HALT;REBOOT;SUSPEND;CUSTOM_CMD", GDM_ID_SYSTEM_COMMANDS_IN_MENU },
- { GDM_CONFIG_GROUP_DAEMON, "AllowLogoutActions", GDM_CONFIG_VALUE_STRING_ARRAY, "HALT;REBOOT;SUSPEND;CUSTOM_CMD", GDM_ID_ALLOW_LOGOUT_ACTIONS },
- { GDM_CONFIG_GROUP_DAEMON, "RBACSystemCommandKeys", GDM_CONFIG_VALUE_STRING_ARRAY, GDM_RBAC_SYSCMD_KEYS, GDM_ID_RBAC_SYSTEM_COMMAND_KEYS },
-
- { GDM_CONFIG_GROUP_SECURITY, "AllowRoot", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_ALLOW_ROOT },
- { GDM_CONFIG_GROUP_SECURITY, "AllowRemoteRoot", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_ALLOW_REMOTE_ROOT },
- { GDM_CONFIG_GROUP_SECURITY, "AllowRemoteAutoLogin", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_ALLOW_REMOTE_AUTOLOGIN },
- { GDM_CONFIG_GROUP_SECURITY, "UserMaxFile", GDM_CONFIG_VALUE_INT, "65536", GDM_ID_USER_MAX_FILE },
- { GDM_CONFIG_GROUP_SECURITY, "RelaxPermissions", GDM_CONFIG_VALUE_INT, "0", GDM_ID_RELAX_PERM },
- { GDM_CONFIG_GROUP_SECURITY, "CheckDirOwner", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_CHECK_DIR_OWNER },
- { GDM_CONFIG_GROUP_SECURITY, "SupportAutomount", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_SUPPORT_AUTOMOUNT },
- { GDM_CONFIG_GROUP_SECURITY, "RetryDelay", GDM_CONFIG_VALUE_INT, "1", GDM_ID_RETRY_DELAY },
- { GDM_CONFIG_GROUP_SECURITY, "DisallowTCP", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_DISALLOW_TCP },
- { GDM_CONFIG_GROUP_SECURITY, "PamStack", GDM_CONFIG_VALUE_STRING, "gdm", GDM_ID_PAM_STACK },
-
- { GDM_CONFIG_GROUP_SECURITY, "NeverPlaceCookiesOnNFS", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_NEVER_PLACE_COOKIES_ON_NFS },
- { GDM_CONFIG_GROUP_SECURITY, "PasswordRequired", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_PASSWORD_REQUIRED },
-
- { GDM_CONFIG_GROUP_XDMCP, "Enable", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_XDMCP },
- { GDM_CONFIG_GROUP_XDMCP, "MaxPending", GDM_CONFIG_VALUE_INT, "4", GDM_ID_MAX_PENDING },
- { GDM_CONFIG_GROUP_XDMCP, "MaxSessions", GDM_CONFIG_VALUE_INT, "16", GDM_ID_MAX_SESSIONS },
- { GDM_CONFIG_GROUP_XDMCP, "MaxWait", GDM_CONFIG_VALUE_INT, "15", GDM_ID_MAX_WAIT },
- { GDM_CONFIG_GROUP_XDMCP, "DisplaysPerHost", GDM_CONFIG_VALUE_INT, "2", GDM_ID_DISPLAYS_PER_HOST },
- { GDM_CONFIG_GROUP_XDMCP, "Port", GDM_CONFIG_VALUE_INT, "177", GDM_ID_UDP_PORT },
- { GDM_CONFIG_GROUP_XDMCP, "HonorIndirect", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_INDIRECT },
- { GDM_CONFIG_GROUP_XDMCP, "MaxPendingIndirect", GDM_CONFIG_VALUE_INT, "4", GDM_ID_MAX_INDIRECT },
- { GDM_CONFIG_GROUP_XDMCP, "MaxWaitIndirect", GDM_CONFIG_VALUE_INT, "15", GDM_ID_MAX_WAIT_INDIRECT },
- { GDM_CONFIG_GROUP_XDMCP, "PingIntervalSeconds", GDM_CONFIG_VALUE_INT, "15", GDM_ID_PING_INTERVAL },
- { GDM_CONFIG_GROUP_XDMCP, "Willing", GDM_CONFIG_VALUE_STRING, GDMCONFDIR "/Xwilling", GDM_ID_WILLING },
-
- { GDM_CONFIG_GROUP_XDMCP, "EnableProxy", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_XDMCP_PROXY },
- { GDM_CONFIG_GROUP_XDMCP, "ProxyXServer", GDM_CONFIG_VALUE_STRING, "", GDM_ID_XDMCP_PROXY_XSERVER },
- { GDM_CONFIG_GROUP_XDMCP, "ProxyReconnect", GDM_CONFIG_VALUE_STRING, "", GDM_ID_XDMCP_PROXY_RECONNECT },
-
- { GDM_CONFIG_GROUP_GUI, "GtkTheme", GDM_CONFIG_VALUE_STRING, "Default", GDM_ID_GTK_THEME },
- { GDM_CONFIG_GROUP_GUI, "GtkRC", GDM_CONFIG_VALUE_STRING, DATADIR "/themes/Default/gtk-2.0/gtkrc", GDM_ID_GTKRC },
- { GDM_CONFIG_GROUP_GUI, "MaxIconWidth", GDM_CONFIG_VALUE_INT, "128", GDM_ID_MAX_ICON_WIDTH },
- { GDM_CONFIG_GROUP_GUI, "MaxIconHeight", GDM_CONFIG_VALUE_INT, "128", GDM_ID_MAX_ICON_HEIGHT },
-
- { GDM_CONFIG_GROUP_GUI, "AllowGtkThemeChange", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_ALLOW_GTK_THEME_CHANGE },
- { GDM_CONFIG_GROUP_GUI, "GtkThemesToAllow", GDM_CONFIG_VALUE_STRING, "all", GDM_ID_GTK_THEMES_TO_ALLOW },
-
- { GDM_CONFIG_GROUP_GREETER, "Browser", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_BROWSER },
- { GDM_CONFIG_GROUP_GREETER, "Include", GDM_CONFIG_VALUE_STRING, "", GDM_ID_INCLUDE },
- { GDM_CONFIG_GROUP_GREETER, "Exclude", GDM_CONFIG_VALUE_STRING, "bin,daemon,adm,lp,sync,shutdown,halt,mail,news,uucp,operator,nobody,gdm,postgres,pvm,rpm,nfsnobody,pcap", GDM_ID_EXCLUDE },
- { GDM_CONFIG_GROUP_GREETER, "IncludeAll", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_INCLUDE_ALL },
- { GDM_CONFIG_GROUP_GREETER, "MinimalUID", GDM_CONFIG_VALUE_INT, "100", GDM_ID_MINIMAL_UID },
- { GDM_CONFIG_GROUP_GREETER, "DefaultFace", GDM_CONFIG_VALUE_STRING, PIXMAPDIR "/nobody.png", GDM_ID_DEFAULT_FACE },
- { GDM_CONFIG_GROUP_GREETER, "GlobalFaceDir", GDM_CONFIG_VALUE_STRING, DATADIR "/pixmaps/faces/", GDM_ID_GLOBAL_FACE_DIR },
- { GDM_CONFIG_GROUP_GREETER, "LocaleFile", GDM_CONFIG_VALUE_STRING, GDMLOCALEDIR "/locale.alias", GDM_ID_LOCALE_FILE },
- { GDM_CONFIG_GROUP_GREETER, "Logo", GDM_CONFIG_VALUE_STRING, PIXMAPDIR "/gdm-foot-logo.png", GDM_ID_LOGO },
- { GDM_CONFIG_GROUP_GREETER, "ChooserButtonLogo", GDM_CONFIG_VALUE_STRING, PIXMAPDIR "/gdm-foot-logo.png", GDM_ID_CHOOSER_BUTTON_LOGO },
- { GDM_CONFIG_GROUP_GREETER, "Quiver", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_QUIVER },
- { GDM_CONFIG_GROUP_GREETER, "SystemMenu", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_SYSTEM_MENU },
- { GDM_CONFIG_GROUP_DAEMON, "Configurator", GDM_CONFIG_VALUE_STRING, SBINDIR "/gdmsetup --disable-sound --disable-crash-dialog", GDM_ID_CONFIGURATOR },
- { GDM_CONFIG_GROUP_GREETER, "ConfigAvailable", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_CONFIG_AVAILABLE },
- { GDM_CONFIG_GROUP_GREETER, "ChooserButton", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_CHOOSER_BUTTON },
- { GDM_CONFIG_GROUP_GREETER, "TitleBar", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_TITLE_BAR },
-
- /*
- * For backwards compatibility, do not set values for DEFAULT_WELCOME or
- * DEFAULT_REMOTEWELCOME. This will cause these values to always be
- * read from the config file, and will cause them to return FALSE if
- * no value is set in the config file. We want the value, "FALSE" if
- * the values don't exist in the config file. The daemon will compare
- * the Welcome/RemoveWelcome value with the default string and
- * automatically translate the text if the string is the same as the
- * default string. We set the default values of GDM_ID_WELCOME and
- * GDM_ID_REMOTEWELCOME so that the default value is returned when
- * you run GET_CONFIG on these keys.
- */
- { GDM_CONFIG_GROUP_GREETER, "DefaultWelcome", GDM_CONFIG_VALUE_BOOL, "", GDM_ID_DEFAULT_WELCOME },
- { GDM_CONFIG_GROUP_GREETER, "DefaultRemoteWelcome", GDM_CONFIG_VALUE_BOOL, "", GDM_ID_DEFAULT_REMOTE_WELCOME },
- { GDM_CONFIG_GROUP_GREETER, "Welcome", GDM_CONFIG_VALUE_LOCALE_STRING, GDM_DEFAULT_WELCOME_MSG, GDM_ID_WELCOME },
- { GDM_CONFIG_GROUP_GREETER, "RemoteWelcome", GDM_CONFIG_VALUE_LOCALE_STRING, GDM_DEFAULT_REMOTE_WELCOME_MSG, GDM_ID_REMOTE_WELCOME },
- { GDM_CONFIG_GROUP_GREETER, "XineramaScreen", GDM_CONFIG_VALUE_INT, "0", GDM_ID_XINERAMA_SCREEN },
- { GDM_CONFIG_GROUP_GREETER, "BackgroundProgram", GDM_CONFIG_VALUE_STRING, "", GDM_ID_BACKGROUND_PROGRAM },
- { GDM_CONFIG_GROUP_GREETER, "RunBackgroundProgramAlways", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_RUN_BACKGROUND_PROGRAM_ALWAYS },
- { GDM_CONFIG_GROUP_GREETER, "BackgroundProgramInitialDelay", GDM_CONFIG_VALUE_INT, "30", GDM_ID_BACKGROUND_PROGRAM_INITIAL_DELAY },
- { GDM_CONFIG_GROUP_GREETER, "RestartBackgroundProgram", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_RESTART_BACKGROUND_PROGRAM },
- { GDM_CONFIG_GROUP_GREETER, "BackgroundProgramRestartDelay", GDM_CONFIG_VALUE_INT, "30", GDM_ID_BACKGROUND_PROGRAM_RESTART_DELAY },
- { GDM_CONFIG_GROUP_GREETER, "BackgroundImage", GDM_CONFIG_VALUE_STRING, "", GDM_ID_BACKGROUND_IMAGE },
- { GDM_CONFIG_GROUP_GREETER, "BackgroundColor", GDM_CONFIG_VALUE_STRING, "#76848F", GDM_ID_BACKGROUND_COLOR },
- { GDM_CONFIG_GROUP_GREETER, "BackgroundType", GDM_CONFIG_VALUE_INT, "2", GDM_ID_BACKGROUND_TYPE },
- { GDM_CONFIG_GROUP_GREETER, "BackgroundScaleToFit", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_BACKGROUND_SCALE_TO_FIT },
- { GDM_CONFIG_GROUP_GREETER, "BackgroundRemoteOnlyColor", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_BACKGROUND_REMOTE_ONLY_COLOR },
- { GDM_CONFIG_GROUP_GREETER, "LockPosition", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_LOCK_POSITION },
- { GDM_CONFIG_GROUP_GREETER, "SetPosition", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_SET_POSITION },
- { GDM_CONFIG_GROUP_GREETER, "PositionX", GDM_CONFIG_VALUE_INT, "0", GDM_ID_POSITION_X },
- { GDM_CONFIG_GROUP_GREETER, "PositionY", GDM_CONFIG_VALUE_INT, "0", GDM_ID_POSITION_Y },
- { GDM_CONFIG_GROUP_GREETER, "Use24Clock", GDM_CONFIG_VALUE_STRING, "auto", GDM_ID_USE_24_CLOCK },
- { GDM_CONFIG_GROUP_GREETER, "UseCirclesInEntry", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_ENTRY_CIRCLES },
- { GDM_CONFIG_GROUP_GREETER, "UseInvisibleInEntry", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_ENTRY_INVISIBLE },
- { GDM_CONFIG_GROUP_GREETER, "GraphicalTheme", GDM_CONFIG_VALUE_STRING, "circles", GDM_ID_GRAPHICAL_THEME },
- { GDM_CONFIG_GROUP_GREETER, "GraphicalThemes", GDM_CONFIG_VALUE_STRING, "circles/:happygnome", GDM_ID_GRAPHICAL_THEMES },
- { GDM_CONFIG_GROUP_GREETER, "GraphicalThemeRand", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_GRAPHICAL_THEME_RAND },
- { GDM_CONFIG_GROUP_GREETER, "GraphicalThemeDir", GDM_CONFIG_VALUE_STRING, DATADIR "/gdm/themes/", GDM_ID_GRAPHICAL_THEME_DIR },
- { GDM_CONFIG_GROUP_GREETER, "GraphicalThemedColor", GDM_CONFIG_VALUE_STRING, "#76848F", GDM_ID_GRAPHICAL_THEMED_COLOR },
-
- { GDM_CONFIG_GROUP_GREETER, "InfoMsgFile", GDM_CONFIG_VALUE_STRING, "", GDM_ID_INFO_MSG_FILE },
- { GDM_CONFIG_GROUP_GREETER, "InfoMsgFont", GDM_CONFIG_VALUE_STRING, "", GDM_ID_INFO_MSG_FONT },
-
- { GDM_CONFIG_GROUP_GREETER, "PreFetchProgram", GDM_CONFIG_VALUE_STRING, "", GDM_ID_PRE_FETCH_PROGRAM },
-
- { GDM_CONFIG_GROUP_GREETER, "SoundOnLogin", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_SOUND_ON_LOGIN },
- { GDM_CONFIG_GROUP_GREETER, "SoundOnLoginSuccess", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_SOUND_ON_LOGIN_SUCCESS },
- { GDM_CONFIG_GROUP_GREETER, "SoundOnLoginFailure", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_SOUND_ON_LOGIN_FAILURE },
- { GDM_CONFIG_GROUP_GREETER, "SoundOnLoginFile", GDM_CONFIG_VALUE_STRING, "", GDM_ID_SOUND_ON_LOGIN_FILE },
- { GDM_CONFIG_GROUP_GREETER, "SoundOnLoginSuccessFile", GDM_CONFIG_VALUE_STRING, "", GDM_ID_SOUND_ON_LOGIN_SUCCESS_FILE },
- { GDM_CONFIG_GROUP_GREETER, "SoundOnLoginFailureFile", GDM_CONFIG_VALUE_STRING, "", GDM_ID_SOUND_ON_LOGIN_FAILURE_FILE },
- { GDM_CONFIG_GROUP_DAEMON, "SoundProgram", GDM_CONFIG_VALUE_STRING, SOUND_PROGRAM, GDM_ID_SOUND_PROGRAM },
-
- { GDM_CONFIG_GROUP_CHOOSER, "ScanTime", GDM_CONFIG_VALUE_INT, "4", GDM_ID_SCAN_TIME },
- { GDM_CONFIG_GROUP_CHOOSER, "DefaultHostImg", GDM_CONFIG_VALUE_STRING, PIXMAPDIR "/nohost.png", GDM_ID_DEFAULT_HOST_IMG },
- { GDM_CONFIG_GROUP_CHOOSER, "HostImageDir", GDM_CONFIG_VALUE_STRING, DATADIR "/hosts/", GDM_ID_HOST_IMAGE_DIR },
- { GDM_CONFIG_GROUP_CHOOSER, "Hosts", GDM_CONFIG_VALUE_STRING, "", GDM_ID_HOSTS },
- { GDM_CONFIG_GROUP_CHOOSER, "Multicast", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_MULTICAST },
- { GDM_CONFIG_GROUP_CHOOSER, "MulticastAddr", GDM_CONFIG_VALUE_STRING, "ff02::1", GDM_ID_MULTICAST_ADDR },
- { GDM_CONFIG_GROUP_CHOOSER, "Broadcast", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_BROADCAST },
- { GDM_CONFIG_GROUP_CHOOSER, "AllowAdd", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_ALLOW_ADD },
-
- { GDM_CONFIG_GROUP_GREETER, "ShowGnomeFailsafeSession", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_SHOW_GNOME_FAILSAFE },
- { GDM_CONFIG_GROUP_GREETER, "ShowXtermFailsafeSession", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_SHOW_XTERM_FAILSAFE },
- { GDM_CONFIG_GROUP_GREETER, "ShowLastSession", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_SHOW_LAST_SESSION },
-
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommand0", GDM_CONFIG_VALUE_STRING, NULL, GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLabel0", GDM_CONFIG_VALUE_STRING, "Custom_0", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLRLabel0", GDM_CONFIG_VALUE_STRING, "Execute custom command _0", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandText0", GDM_CONFIG_VALUE_STRING, "Are you sure?", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandTooltip0", GDM_CONFIG_VALUE_STRING, "Execute custom command 0", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandNoRestart0", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandIsPersistent0", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommand1", GDM_CONFIG_VALUE_STRING, NULL, GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLabel1", GDM_CONFIG_VALUE_STRING, "Custom_1", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLRLabel1", GDM_CONFIG_VALUE_STRING, "Execute custom command _1", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandText1", GDM_CONFIG_VALUE_STRING, "Are you sure?", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandTooltip1", GDM_CONFIG_VALUE_STRING, "Execute custom command 1", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandNoRestart1", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandIsPersistent1", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommand2", GDM_CONFIG_VALUE_STRING, NULL, GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLabel2", GDM_CONFIG_VALUE_STRING, "Custom_2", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLRLabel2", GDM_CONFIG_VALUE_STRING, "Execute custom command _2", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandText2", GDM_CONFIG_VALUE_STRING, "Are you sure?", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandTooltip2", GDM_CONFIG_VALUE_STRING, "Execute custom command 2", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandNoRestart2", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandIsPersistent2", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommand3", GDM_CONFIG_VALUE_STRING, NULL, GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLabel3", GDM_CONFIG_VALUE_STRING, "Custom_3", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLRLabel3", GDM_CONFIG_VALUE_STRING, "Execute custom command _3", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandText3", GDM_CONFIG_VALUE_STRING, "Are you sure?", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandTooltip3", GDM_CONFIG_VALUE_STRING, "Execute custom command 3", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandNoRestart3", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandIsPersistent3", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommand4", GDM_CONFIG_VALUE_STRING, NULL, GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLabel4", GDM_CONFIG_VALUE_STRING, "Custom_4", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLRLabel4", GDM_CONFIG_VALUE_STRING, "Execute custom command _4", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandText4", GDM_CONFIG_VALUE_STRING, "Are you sure?", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandTooltip4", GDM_CONFIG_VALUE_STRING, "Execute custom command 4", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandNoRestart4", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandIsPersistent4", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommand5", GDM_CONFIG_VALUE_STRING, NULL, GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLabel5", GDM_CONFIG_VALUE_STRING, "Custom_5", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLRLabel5", GDM_CONFIG_VALUE_STRING, "Execute custom command _5", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandText5", GDM_CONFIG_VALUE_STRING, "Are you sure?", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandTooltip5", GDM_CONFIG_VALUE_STRING, "Execute custom command 5", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandNoRestart5", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandIsPersistent5", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommand6", GDM_CONFIG_VALUE_STRING, NULL, GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLabel6", GDM_CONFIG_VALUE_STRING, "Custom_6", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLRLabel6", GDM_CONFIG_VALUE_STRING, "Execute custom command _6", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandText6", GDM_CONFIG_VALUE_STRING, "Are you sure?", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandTooltip6", GDM_CONFIG_VALUE_STRING, "Execute custom command 6", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandNoRestart6", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandIsPersistent6", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommand7", GDM_CONFIG_VALUE_STRING, NULL, GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLabel7", GDM_CONFIG_VALUE_STRING, "Custom_7", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLRLabel7", GDM_CONFIG_VALUE_STRING, "Execute custom command _7", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandText7", GDM_CONFIG_VALUE_STRING, "Are you sure?", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandTooltip7", GDM_CONFIG_VALUE_STRING, "Execute custom command 7", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandNoRestart7", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandIsPersistent7", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommand8", GDM_CONFIG_VALUE_STRING, NULL, GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLabel8", GDM_CONFIG_VALUE_STRING, "Custom_8", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLRLabel8", GDM_CONFIG_VALUE_STRING, "Execute custom command _8", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandText8", GDM_CONFIG_VALUE_STRING, "Are you sure?", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandTooltip8", GDM_CONFIG_VALUE_STRING, "Execute custom command 8", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandNoRestart8", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandIsPersistent8", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommand9", GDM_CONFIG_VALUE_STRING, NULL, GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLabel9", GDM_CONFIG_VALUE_STRING, "Custom_9", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandLRLabel9", GDM_CONFIG_VALUE_STRING, "Execute custom command _9", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandText9", GDM_CONFIG_VALUE_STRING, "Are you sure?", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandTooltip9", GDM_CONFIG_VALUE_STRING, "Execute custom command 9", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandNoRestart9", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
- { GDM_CONFIG_GROUP_CUSTOM_CMD, "CustomCommandIsPersistent9", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_NONE },
-
- { NULL }
-};
-
-static const GdmConfigEntry gdm_daemon_server_config_entries [] = {
- /* Per server definitions */
- { GDM_CONFIG_GROUP_NONE, "name", GDM_CONFIG_VALUE_STRING, "Standard server", GDM_ID_SERVER_NAME },
- { GDM_CONFIG_GROUP_NONE, "command", GDM_CONFIG_VALUE_STRING, X_SERVER, GDM_ID_SERVER_COMMAND },
- /* runnable as flexi server */
- { GDM_CONFIG_GROUP_NONE, "flexible", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_SERVER_FLEXIBLE },
- /* choosable from the login screen */
- { GDM_CONFIG_GROUP_NONE, "choosable", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_SERVER_CHOOSABLE },
- /* Login is handled by gdm, otherwise it's a remote server */
- { GDM_CONFIG_GROUP_NONE, "handled", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_SERVER_HANDLED },
- /* Instead of the greeter run the chooser */
- { GDM_CONFIG_GROUP_NONE, "chooser", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_SERVER_CHOOSER },
- /* select a nice level to run the X server at */
- { GDM_CONFIG_GROUP_NONE, "priority", GDM_CONFIG_VALUE_INT, "0", GDM_ID_SERVER_PRIORITY },
-};
-
-G_END_DECLS
-
-#endif /* _GDM_DAEMON_CONFIG_ENTRIES_H */
diff --git a/daemon/gdm-daemon-config-keys.h b/daemon/gdm-daemon-config-keys.h
deleted file mode 100644
index c34b85cc..00000000
--- a/daemon/gdm-daemon-config-keys.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _GDM_DAEMON_CONFIG_KEYS_H
-#define _GDM_DAEMON_CONFIG_KEYS_H
-
-#include <glib.h>
-
-#include "gdm-config.h"
-
-G_BEGIN_DECLS
-
-/* BEGIN LEGACY KEYS */
-#define GDM_KEY_CHOOSER "daemon/Chooser=" LIBEXECDIR "/gdmchooser"
-#define GDM_KEY_AUTOMATIC_LOGIN_ENABLE "daemon/AutomaticLoginEnable=false"
-#define GDM_KEY_AUTOMATIC_LOGIN "daemon/AutomaticLogin="
-#define GDM_KEY_GREETER "daemon/Greeter=" LIBEXECDIR "/gdmlogin"
-#define GDM_KEY_REMOTE_GREETER "daemon/RemoteGreeter=" LIBEXECDIR "/gdmlogin"
-#define GDM_KEY_ADD_GTK_MODULES "daemon/AddGtkModules=false"
-#define GDM_KEY_GTK_MODULES_LIST "daemon/GtkModulesList="
-#define GDM_KEY_GROUP "daemon/Group=gdm"
-#define GDM_KEY_HALT "daemon/HaltCommand=" HALT_COMMAND
-#define GDM_KEY_DISPLAY_INIT_DIR "daemon/DisplayInitDir=" GDMCONFDIR "/Init"
-#define GDM_KEY_KILL_INIT_CLIENTS "daemon/KillInitClients=true"
-#define GDM_KEY_LOG_DIR "daemon/LogDir=" LOGDIR
-#define GDM_KEY_PATH "daemon/DefaultPath=" GDM_USER_PATH
-#define GDM_KEY_PID_FILE "daemon/PidFile=" GDM_PID_FILE
-#define GDM_KEY_POSTSESSION "daemon/PostSessionScriptDir=" GDMCONFDIR "/PostSession/"
-#define GDM_KEY_PRESESSION "daemon/PreSessionScriptDir=" GDMCONFDIR "/PreSession/"
-#define GDM_KEY_POSTLOGIN "daemon/PostLoginScriptDir=" GDMCONFDIR "/PreSession/"
-#define GDM_KEY_FAILSAFE_XSERVER "daemon/FailsafeXServer="
-#define GDM_KEY_X_KEEPS_CRASHING "daemon/XKeepsCrashing=" GDMCONFDIR "/XKeepsCrashing"
-#define GDM_KEY_REBOOT "daemon/RebootCommand=" REBOOT_COMMAND
-#define GDM_KEY_CUSTOM_CMD_TEMPLATE "customcommand/CustomCommand"
-#define GDM_KEY_CUSTOM_CMD_LABEL_TEMPLATE "customcommand/CustomCommandLabel"
-#define GDM_KEY_CUSTOM_CMD_LR_LABEL_TEMPLATE "customcommand/CustomCommandLRLabel"
-#define GDM_KEY_CUSTOM_CMD_TEXT_TEMPLATE "customcommand/CustomCommandText"
-#define GDM_KEY_CUSTOM_CMD_TOOLTIP_TEMPLATE "customcommand/CustomCommandTooltip"
-#define GDM_KEY_CUSTOM_CMD_NO_RESTART_TEMPLATE "customcommand/CustomCommandNoRestart"
-#define GDM_KEY_CUSTOM_CMD_IS_PERSISTENT_TEMPLATE "customcommand/CustomCommandIsPersistent"
-#define GDM_KEY_ROOT_PATH "daemon/RootPath=/sbin:/usr/sbin:" GDM_USER_PATH
-#define GDM_KEY_SERV_AUTHDIR "daemon/ServAuthDir=" AUTHDIR
-#define GDM_KEY_SESSION_DESKTOP_DIR "daemon/SessionDesktopDir=/etc/X11/sessions/:" DMCONFDIR "/Sessions/:" DATADIR "/gdm/BuiltInSessions/:" DATADIR "/xsessions/"
-#define GDM_KEY_BASE_XSESSION "daemon/BaseXsession=" GDMCONFDIR "/Xsession"
-#define GDM_KEY_DEFAULT_SESSION "daemon/DefaultSession=gnome.desktop"
-#define GDM_KEY_SUSPEND "daemon/SuspendCommand=" SUSPEND_COMMAND
-#define GDM_KEY_USER_AUTHDIR "daemon/UserAuthDir="
-#define GDM_KEY_USER_AUTHDIR_FALLBACK "daemon/UserAuthFBDir=/tmp"
-#define GDM_KEY_USER_AUTHFILE "daemon/UserAuthFile=.Xauthority"
-#define GDM_KEY_USER "daemon/User=gdm"
-#define GDM_KEY_CONSOLE_NOTIFY "daemon/ConsoleNotify=true"
-#define GDM_KEY_DOUBLE_LOGIN_WARNING "daemon/DoubleLoginWarning=true"
-#define GDM_KEY_ALWAYS_LOGIN_CURRENT_SESSION "daemon/AlwaysLoginCurrentSession=true"
-#define GDM_KEY_DISPLAY_LAST_LOGIN "daemon/DisplayLastLogin=false"
-#define GDM_KEY_TIMED_LOGIN_ENABLE "daemon/TimedLoginEnable=false"
-#define GDM_KEY_TIMED_LOGIN "daemon/TimedLogin="
-#define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay=30"
-#define GDM_KEY_FLEXI_REAP_DELAY_MINUTES "daemon/FlexiReapDelayMinutes=5"
-#define GDM_KEY_STANDARD_XSERVER "daemon/StandardXServer=" X_SERVER
-#define GDM_KEY_FLEXIBLE_XSERVERS "daemon/FlexibleXServers=5"
-#define GDM_KEY_DYNAMIC_XSERVERS "daemon/DynamicXServers=false"
-#define GDM_KEY_XNEST "daemon/Xnest=" X_XNEST_CMD " " X_XNEST_CONFIG_OPTIONS
-#define GDM_KEY_XNEST_UNSCALED_FONT_PATH "daemon/XnestUnscaledFontPath=" X_XNEST_UNSCALED_FONTPATH
-#define GDM_KEY_FIRST_VT "daemon/FirstVT=7"
-#define GDM_KEY_VT_ALLOCATION "daemon/VTAllocation=true"
-#define GDM_KEY_CONSOLE_CANNOT_HANDLE "daemon/ConsoleCannotHandle=am,ar,az,bn,el,fa,gu,hi,ja,ko,ml,mr,pa,ta,zh"
-#define GDM_KEY_XSERVER_TIMEOUT "daemon/GdmXserverTimeout=10"
-#define GDM_KEY_SYSTEM_COMMANDS_IN_MENU "daemon/SystemCommandsInMenu=HALT;REBOOT;SUSPEND;CUSTOM_CMD"
-#define GDM_KEY_ALLOW_LOGOUT_ACTIONS "daemon/AllowLogoutActions=HALT;REBOOT;SUSPEND;CUSTOM_CMD"
-#define GDM_KEY_RBAC_SYSTEM_COMMAND_KEYS "daemon/RBACSystemCommandKeys=" GDM_RBAC_SYSCMD_KEYS
-
-#define GDM_KEY_SERVER_PREFIX "server-"
-#define GDM_KEY_SERVER_NAME "name=Standard server"
-#define GDM_KEY_SERVER_COMMAND "command=" X_SERVER
-#define GDM_KEY_SERVER_FLEXIBLE "flexible=true"
-#define GDM_KEY_SERVER_CHOOSABLE "choosable=false"
-#define GDM_KEY_SERVER_HANDLED "handled=true"
-#define GDM_KEY_SERVER_CHOOSER "chooser=false"
-#define GDM_KEY_SERVER_PRIORITY "priority=0"
-
-#define GDM_KEY_ALLOW_ROOT "security/AllowRoot=true"
-#define GDM_KEY_ALLOW_REMOTE_ROOT "security/AllowRemoteRoot=false"
-#define GDM_KEY_ALLOW_REMOTE_AUTOLOGIN "security/AllowRemoteAutoLogin=false"
-#define GDM_KEY_USER_MAX_FILE "security/UserMaxFile=65536"
-#define GDM_KEY_RELAX_PERM "security/RelaxPermissions=0"
-#define GDM_KEY_CHECK_DIR_OWNER "security/CheckDirOwner=true"
-#define GDM_KEY_SUPPORT_AUTOMOUNT "security/SupportAutomount=false"
-#define GDM_KEY_RETRY_DELAY "security/RetryDelay=1"
-#define GDM_KEY_DISALLOW_TCP "security/DisallowTCP=true"
-#define GDM_KEY_PAM_STACK "security/PamStack=gdm"
-#define GDM_KEY_NEVER_PLACE_COOKIES_ON_NFS "security/NeverPlaceCookiesOnNFS=true"
-#define GDM_KEY_PASSWORD_REQUIRED "security/PasswordRequired=false"
-#define GDM_KEY_XDMCP "xdmcp/Enable=false"
-#define GDM_KEY_MAX_PENDING "xdmcp/MaxPending=4"
-#define GDM_KEY_MAX_SESSIONS "xdmcp/MaxSessions=16"
-#define GDM_KEY_MAX_WAIT "xdmcp/MaxWait=15"
-#define GDM_KEY_DISPLAYS_PER_HOST "xdmcp/DisplaysPerHost=2"
-#define GDM_KEY_UDP_PORT "xdmcp/Port=177"
-#define GDM_KEY_INDIRECT "xdmcp/HonorIndirect=true"
-#define GDM_KEY_MAX_INDIRECT "xdmcp/MaxPendingIndirect=4"
-#define GDM_KEY_MAX_WAIT_INDIRECT "xdmcp/MaxWaitIndirect=15"
-#define GDM_KEY_PING_INTERVAL "xdmcp/PingIntervalSeconds=15"
-#define GDM_KEY_WILLING "xdmcp/Willing=" GDMCONFDIR "/Xwilling"
-#define GDM_KEY_XDMCP_PROXY "xdmcp/EnableProxy=false"
-#define GDM_KEY_XDMCP_PROXY_XSERVER "xdmcp/ProxyXServer="
-#define GDM_KEY_XDMCP_PROXY_RECONNECT "xdmcp/ProxyReconnect="
-#define GDM_KEY_GTK_THEME "gui/GtkTheme=Default"
-#define GDM_KEY_GTKRC "gui/GtkRC=" DATADIR "/themes/Default/gtk-2.0/gtkrc"
-#define GDM_KEY_MAX_ICON_WIDTH "gui/MaxIconWidth=128"
-#define GDM_KEY_MAX_ICON_HEIGHT "gui/MaxIconHeight=128"
-#define GDM_KEY_ALLOW_GTK_THEME_CHANGE "gui/AllowGtkThemeChange=true"
-#define GDM_KEY_GTK_THEMES_TO_ALLOW "gui/GtkThemesToAllow=all"
-#define GDM_KEY_BROWSER "greeter/Browser=false"
-#define GDM_KEY_INCLUDE "greeter/Include="
-#define GDM_KEY_EXCLUDE "greeter/Exclude=bin,daemon,adm,lp,sync,shutdown,halt,mail,news,uucp,operator,nobody,gdm,postgres,pvm,rpm,nfsnobody,pcap"
-#define GDM_KEY_INCLUDE_ALL "greeter/IncludeAll=false"
-#define GDM_KEY_MINIMAL_UID "greeter/MinimalUID=100"
-#define GDM_KEY_DEFAULT_FACE "greeter/DefaultFace=" PIXMAPDIR "/nobody.png"
-#define GDM_KEY_GLOBAL_FACE_DIR "greeter/GlobalFaceDir=" DATADIR "/pixmaps/faces/"
-#define GDM_KEY_LOCALE_FILE "greeter/LocaleFile=" GDMLOCALEDIR "/locale.alias"
-#define GDM_KEY_LOGO "greeter/Logo=" PIXMAPDIR "/gdm-foot-logo.png"
-#define GDM_KEY_CHOOSER_BUTTON_LOGO "greeter/ChooserButtonLogo=" PIXMAPDIR "/gdm-foot-logo.png"
-#define GDM_KEY_QUIVER "greeter/Quiver=true"
-#define GDM_KEY_SYSTEM_MENU "greeter/SystemMenu=true"
-#define GDM_KEY_CONFIGURATOR "daemon/Configurator=" SBINDIR "/gdmsetup --disable-sound --disable-crash-dialog"
-#define GDM_KEY_CONFIG_AVAILABLE "greeter/ConfigAvailable=true"
-#define GDM_KEY_CHOOSER_BUTTON "greeter/ChooserButton=true"
-#define GDM_KEY_TITLE_BAR "greeter/TitleBar=true"
-#define GDM_DEFAULT_WELCOME_MSG "Welcome"
-#define GDM_DEFAULT_REMOTE_WELCOME_MSG "Welcome to %n"
-#define GDM_KEY_DEFAULT_WELCOME "greeter/DefaultWelcome="
-#define GDM_KEY_DEFAULT_REMOTE_WELCOME "greeter/DefaultRemoteWelcome="
-#define GDM_KEY_WELCOME "greeter/Welcome=" GDM_DEFAULT_WELCOME_MSG
-#define GDM_KEY_REMOTE_WELCOME "greeter/RemoteWelcome=" GDM_DEFAULT_REMOTE_WELCOME_MSG
-#define GDM_KEY_XINERAMA_SCREEN "greeter/XineramaScreen=0"
-#define GDM_KEY_BACKGROUND_PROGRAM "greeter/BackgroundProgram="
-#define GDM_KEY_RUN_BACKGROUND_PROGRAM_ALWAYS "greeter/RunBackgroundProgramAlways=false"
-#define GDM_KEY_BACKGROUND_PROGRAM_INITIAL_DELAY "greeter/BackgroundProgramInitialDelay=30"
-#define GDM_KEY_RESTART_BACKGROUND_PROGRAM "greeter/RestartBackgroundProgram=true"
-#define GDM_KEY_BACKGROUND_PROGRAM_RESTART_DELAY "greeter/BackgroundProgramRestartDelay=30"
-#define GDM_KEY_BACKGROUND_IMAGE "greeter/BackgroundImage="
-#define GDM_KEY_BACKGROUND_COLOR "greeter/BackgroundColor=#76848F"
-#define GDM_KEY_BACKGROUND_TYPE "greeter/BackgroundType=2"
-#define GDM_KEY_BACKGROUND_SCALE_TO_FIT "greeter/BackgroundScaleToFit=true"
-#define GDM_KEY_BACKGROUND_REMOTE_ONLY_COLOR "greeter/BackgroundRemoteOnlyColor=true"
-#define GDM_KEY_LOCK_POSITION "greeter/LockPosition=false"
-#define GDM_KEY_SET_POSITION "greeter/SetPosition=false"
-#define GDM_KEY_POSITION_X "greeter/PositionX=0"
-#define GDM_KEY_POSITION_Y "greeter/PositionY=0"
-#define GDM_KEY_USE_24_CLOCK "greeter/Use24Clock=auto"
-#define GDM_KEY_ENTRY_CIRCLES "greeter/UseCirclesInEntry=false"
-#define GDM_KEY_ENTRY_INVISIBLE "greeter/UseInvisibleInEntry=false"
-#define GDM_KEY_GRAPHICAL_THEME "greeter/GraphicalTheme=circles"
-#define GDM_KEY_GRAPHICAL_THEMES "greeter/GraphicalThemes=circles/:happygnome"
-#define GDM_KEY_GRAPHICAL_THEME_RAND "greeter/GraphicalThemeRand=false"
-#define GDM_KEY_GRAPHICAL_THEME_DIR "greeter/GraphicalThemeDir=" DATADIR "/gdm/themes/"
-#define GDM_KEY_GRAPHICAL_THEMED_COLOR "greeter/GraphicalThemedColor=#76848F"
-#define GDM_KEY_INFO_MSG_FILE "greeter/InfoMsgFile="
-#define GDM_KEY_INFO_MSG_FONT "greeter/InfoMsgFont="
-#define GDM_KEY_PRE_FETCH_PROGRAM "greeter/PreFetchProgram="
-#define GDM_KEY_SOUND_ON_LOGIN "greeter/SoundOnLogin=true"
-#define GDM_KEY_SOUND_ON_LOGIN_SUCCESS "greeter/SoundOnLoginSuccess=false"
-#define GDM_KEY_SOUND_ON_LOGIN_FAILURE "greeter/SoundOnLoginFailure=false"
-#define GDM_KEY_SOUND_ON_LOGIN_FILE "greeter/SoundOnLoginFile="
-#define GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE "greeter/SoundOnLoginSuccessFile="
-#define GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE "greeter/SoundOnLoginFailureFile="
-#define GDM_KEY_SOUND_PROGRAM "daemon/SoundProgram=" SOUND_PROGRAM
-#define GDM_KEY_SCAN_TIME "chooser/ScanTime=4"
-#define GDM_KEY_DEFAULT_HOST_IMG "chooser/DefaultHostImg=" PIXMAPDIR "/nohost.png"
-#define GDM_KEY_HOST_IMAGE_DIR "chooser/HostImageDir=" DATADIR "/hosts/"
-#define GDM_KEY_HOSTS "chooser/Hosts="
-#define GDM_KEY_MULTICAST "chooser/Multicast=false"
-#define GDM_KEY_MULTICAST_ADDR "chooser/MulticastAddr=ff02::1"
-#define GDM_KEY_BROADCAST "chooser/Broadcast=true"
-#define GDM_KEY_ALLOW_ADD "chooser/AllowAdd=true"
-#define GDM_KEY_DEBUG "debug/Enable=false"
-#define GDM_KEY_DEBUG_GESTURES "debug/Gestures=false"
-#define GDM_KEY_SECTION_GREETER "greeter"
-#define GDM_KEY_SECTION_SERVERS "servers"
-#define GDM_KEY_SHOW_GNOME_FAILSAFE "greeter/ShowGnomeFailsafeSession=true"
-#define GDM_KEY_SHOW_XTERM_FAILSAFE "greeter/ShowXtermFailsafeSession=true"
-#define GDM_KEY_SHOW_LAST_SESSION "greeter/ShowLastSession=true"
-/* END LEGACY KEYS */
-
-/* Notification protocol */
-/* keys */
-#define GDM_NOTIFY_ALLOW_REMOTE_ROOT "AllowRemoteRoot" /* <true/false as int> */
-#define GDM_NOTIFY_ALLOW_ROOT "AllowRoot" /* <true/false as int> */
-#define GDM_NOTIFY_ALLOW_REMOTE_AUTOLOGIN "AllowRemoteAutoLogin" /* <true/false as int> */
-#define GDM_NOTIFY_SYSTEM_MENU "SystemMenu" /* <true/false as int> */
-#define GDM_NOTIFY_CONFIG_AVAILABLE "ConfigAvailable" /* <true/false as int> */
-#define GDM_NOTIFY_CHOOSER_BUTTON "ChooserButton" /* <true/false as int> */
-#define GDM_NOTIFY_RETRY_DELAY "RetryDelay" /* <seconds> */
-#define GDM_NOTIFY_GREETER "Greeter" /* <greeter binary> */
-#define GDM_NOTIFY_REMOTE_GREETER "RemoteGreeter" /* <greeter binary> */
-#define GDM_NOTIFY_TIMED_LOGIN "TimedLogin" /* <login> */
-#define GDM_NOTIFY_TIMED_LOGIN_DELAY "TimedLoginDelay" /* <seconds> */
-#define GDM_NOTIFY_TIMED_LOGIN_ENABLE "TimedLoginEnable" /* <true/false as int> */
-#define GDM_NOTIFY_DISALLOW_TCP "DisallowTCP" /* <true/false as int> */
-#define GDM_NOTIFY_SOUND_ON_LOGIN_FILE "SoundOnLoginFile" /* <sound file> */
-#define GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE "SoundOnLoginSuccessFile" /* <sound file> */
-#define GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE "SoundOnLoginFailureFile" /* <sound file> */
-#define GDM_NOTIFY_ADD_GTK_MODULES "AddGtkModules" /* <true/false as int> */
-#define GDM_NOTIFY_GTK_MODULES_LIST "GtkModulesList" /* <modules list> */
-#define GDM_NOTIFY_CUSTOM_CMD_TEMPLATE "CustomCommand" /* <custom command path> */
-
-/* commands, seel GDM_SLAVE_NOTIFY_COMMAND */
-#define GDM_NOTIFY_DIRTY_SERVERS "DIRTY_SERVERS"
-#define GDM_NOTIFY_SOFT_RESTART_SERVERS "SOFT_RESTART_SERVERS"
-#define GDM_NOTIFY_GO "GO"
-#define GDM_NOTIFY_TWIDDLE_POINTER "TWIDDLE_POINTER"
-
-G_END_DECLS
-
-#endif /* _GDM_DAEMON_CONFIG_KEYS_H */
diff --git a/daemon/gdm-daemon-config.c b/daemon/gdm-daemon-config.c
deleted file mode 100644
index 5576b0f6..00000000
--- a/daemon/gdm-daemon-config.c
+++ /dev/null
@@ -1,2889 +0,0 @@
-/* -*- 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>
- * Copyright (C) 2005 Brian Cameron <brian.cameron@sun.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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
- */
-
-/*
- * gdm-daemon-config.c isolates most logic that interacts with GDM
- * configuration into a single file and provides a mechanism for
- * interacting with GDM configuration optins via access functions for
- * getting/setting values. This logic also ensures that the same
- * configuration validation happens when loading the values initially
- * or setting them via the GDM_UPDATE_CONFIG socket command.
- *
- * When adding a new configuration option, simply add the new option
- * to gdm-daemon-config-entries.h. Any validation for the
- * configuration option should be placed in the validate_cb function.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/resource.h>
-#include <signal.h>
-#include <pwd.h>
-#include <grp.h>
-
-#include <glib.h>
-#include <glib/gi18n.h>
-
-#include "gdm.h"
-#include "verify.h"
-#include "gdm-net.h"
-#include "misc.h"
-#include "server.h"
-#include "filecheck.h"
-#include "slave.h"
-
-#include "gdm-common.h"
-#include "gdm-config.h"
-#include "gdm-log.h"
-#include "gdm-daemon-config.h"
-
-#include "gdm-socket-protocol.h"
-
-static GdmConfig *daemon_config = NULL;
-
-static GSList *displays = NULL;
-static GSList *xservers = 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 */
-
-/**
- * is_key
- *
- * Since GDM keys sometimes have default values defined in the gdm.h header
- * file (e.g. key=value), this function strips off the "=value" from both
- * keys passed and compares them, returning TRUE if they are the same,
- * FALSE otherwise.
- */
-static gboolean
-is_key (const gchar *key1, const gchar *key2)
-{
- gchar *key1d, *key2d, *p;
-
- key1d = g_strdup (key1);
- key2d = g_strdup (key2);
-
- g_strstrip (key1d);
- p = strchr (key1d, '=');
- if (p != NULL)
- *p = '\0';
-
- g_strstrip (key2d);
- p = strchr (key2d, '=');
- if (p != NULL)
- *p = '\0';
-
- if (strcmp (ve_sure_string (key1d), ve_sure_string (key2d)) == 0) {
- g_free (key1d);
- g_free (key2d);
- return TRUE;
- } else {
- g_free (key1d);
- g_free (key2d);
- return FALSE;
- }
-}
-
-/**
- * gdm_daemon_config_get_per_display_custom_config_file
- *
- * Returns the per-display config file for a given display
- * This is always the custom config file name with the display
- * appended, and never gdm.conf.
- */
-static gchar *
-gdm_daemon_config_get_per_display_custom_config_file (const gchar *display)
-{
- return g_strdup_printf ("%s%s", custom_config_file, display);
-}
-
-/**
- * gdm_daemon_config_get_custom_config_file
- *
- * Returns the custom config file being used.
- */
-gchar *
-gdm_daemon_config_get_custom_config_file (void)
-{
- return custom_config_file;
-}
-
-/**
- * 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
- * first be loaded, say, by calling gdm_config_parse.
- */
-gint
-gdm_daemon_config_get_value_int (const char *keystring)
-{
- gboolean res;
- GdmConfigValue *value;
- char *group;
- char *key;
- int result;
-
- result = 0;
-
- res = gdm_common_config_parse_key_string (keystring,
- &group,
- &key,
- NULL,
- NULL);
- if (! res) {
- gdm_error ("Could not parse configuration key %s", keystring);
- goto out;
- }
-
- res = gdm_config_get_value (daemon_config,
- group,
- key,
- &value);
- if (! res) {
- gdm_error ("Request for invalid configuration key %s", keystring);
- goto out;
- }
-
- if (value->type != GDM_CONFIG_VALUE_INT) {
- gdm_error ("Request for configuration key %s, but not type INT", keystring);
- goto out;
- }
-
- result = gdm_config_value_get_int (value);
- out:
- g_free (group);
- g_free (key);
-
- return result;
-}
-
-/**
- * gdm_daemon_config_get_value_string
- *
- * Gets a string configuration option by key. The option must
- * first be loaded, say, by calling gdm_daemon_config_parse.
- */
-const char *
-gdm_daemon_config_get_value_string (const char *keystring)
-{
- gboolean res;
- GdmConfigValue *value;
- char *group;
- char *key;
- const char *result;
-
- result = NULL;
-
- res = gdm_common_config_parse_key_string (keystring,
- &group,
- &key,
- NULL,
- NULL);
- if (! res) {
- gdm_error ("Could not parse configuration key %s", keystring);
- goto out;
- }
-
- res = gdm_config_get_value (daemon_config,
- group,
- key,
- &value);
- if (! res) {
- gdm_error ("Request for invalid configuration key %s", keystring);
- goto out;
- }
-
- if (value->type != GDM_CONFIG_VALUE_STRING) {
- gdm_error ("Request for configuration key %s, but not type STRING", keystring);
- goto out;
- }
-
- result = gdm_config_value_get_string (value);
- out:
- g_free (group);
- g_free (key);
-
- return result;
-}
-
-/**
- * gdm_daemon_config_get_value_string_array
- *
- * Gets a string configuration option by key. The option must
- * first be loaded, say, by calling gdm_daemon_config_parse.
- */
-const char **
-gdm_daemon_config_get_value_string_array (const char *keystring)
-{
- gboolean res;
- GdmConfigValue *value;
- char *group;
- char *key;
- const char **result;
-
- result = NULL;
-
- res = gdm_common_config_parse_key_string (keystring,
- &group,
- &key,
- NULL,
- NULL);
- if (! res) {
- gdm_error ("Could not parse configuration key %s", keystring);
- goto out;
- }
-
- res = gdm_config_get_value (daemon_config,
- group,
- key,
- &value);
- if (! res) {
- gdm_error ("Request for invalid configuration key %s", keystring);
- goto out;
- }
-
- if (value->type != GDM_CONFIG_VALUE_STRING_ARRAY) {
- gdm_error ("Request for configuration key %s, but not type STRING-ARRAY", keystring);
- goto out;
- }
-
- result = gdm_config_value_get_string_array (value);
- out:
- g_free (group);
- g_free (key);
-
- return result;
-}
-
-/**
- * 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_daemon_config_parse.
- */
-gboolean
-gdm_daemon_config_get_value_bool (const char *keystring)
-{
- gboolean res;
- GdmConfigValue *value;
- char *group;
- char *key;
- gboolean result;
-
- result = FALSE;
-
- res = gdm_common_config_parse_key_string (keystring,
- &group,
- &key,
- NULL,
- NULL);
- if (! res) {
- gdm_error ("Could not parse configuration key %s", keystring);
- goto out;
- }
-
- res = gdm_config_get_value (daemon_config,
- group,
- key,
- &value);
- if (! res) {
- gdm_error ("Request for invalid configuration key %s", keystring);
- goto out;
- }
-
- if (value->type != GDM_CONFIG_VALUE_BOOL) {
- gdm_error ("Request for configuration key %s, but not type BOOLEAN", keystring);
- goto out;
- }
-
- result = gdm_config_value_get_bool (value);
- out:
- g_free (group);
- g_free (key);
-
- return result;
-}
-
-/**
- * Note that some GUI configuration parameters are read by the daemon,
- * and in order for them to work, it is necessary for the daemon to
- * access a few keys in a per-display fashion. These access functions
- * allow the daemon to access these keys properly.
- */
-
-/**
- * gdm_daemon_config_get_value_int_per_display
- *
- * Gets the per-display version of the configuration, or the default
- * value if none exists.
- */
-int
-gdm_daemon_config_get_value_int_per_display (const char *key,
- const char *display)
-{
- char *perdispval;
- gboolean res;
-
- res = gdm_daemon_config_key_to_string_per_display (key, display, &perdispval);
-
- if (res) {
- int val;
- val = atoi (perdispval);
- g_free (perdispval);
- return val;
- } else {
- return gdm_daemon_config_get_value_int (key);
- }
-}
-
-/**
- * gdm_daemon_config_get_value_bool_per_display
- *
- * Gets the per-display version of the configuration, or the default
- * value if none exists.
- */
-gboolean
-gdm_daemon_config_get_value_bool_per_display (const char *key,
- const char *display)
-{
- char *perdispval;
- gboolean res;
-
- res = gdm_daemon_config_key_to_string_per_display (key, display, &perdispval);
-
- if (res) {
- if (perdispval[0] == 'T' ||
- perdispval[0] == 't' ||
- perdispval[0] == 'Y' ||
- perdispval[0] == 'y' ||
- atoi (perdispval) != 0) {
- g_free (perdispval);
- return TRUE;
- } else {
- return FALSE;
- }
- } else {
- return gdm_daemon_config_get_value_bool (key);
- }
-}
-
-/**
- * gdm_daemon_config_get_value_string_per_display
- *
- * Gets the per-display version of the configuration, or the default
- * value if none exists. Note that this value needs to be freed,
- * unlike the non-per-display version.
- */
-char *
-gdm_daemon_config_get_value_string_per_display (const char *key,
- const char *display)
-{
- char *perdispval;
- gboolean res;
-
- res = gdm_daemon_config_key_to_string_per_display (key, display, &perdispval);
-
- if (res) {
- return perdispval;
- } else {
- return g_strdup (gdm_daemon_config_get_value_string (key));
- }
-}
-
-/**
- * gdm_daemon_config_key_to_string_per_display
- *
- * If the key makes sense to be per-display, return the value,
- * otherwise return NULL. Keys that only apply to the daemon
- * process do not make sense for per-display configuration
- * Valid keys include any key in the greeter or gui categories,
- * and the GDM_KEY_PAM_STACK key.
- *
- * If additional keys make sense for per-display usage, make
- * sure they are added to the if-test below.
- */
-gboolean
-gdm_daemon_config_key_to_string_per_display (const char *keystring,
- const char *display,
- char **retval)
-{
- char *file;
- char *group;
- char *key;
- gboolean res;
- gboolean ret;
-
- ret = FALSE;
-
- *retval = NULL;
- group = key = NULL;
-
- if (display == NULL) {
- goto out;
- }
-
- g_debug ("Looking up per display value for %s", keystring);
-
- res = gdm_common_config_parse_key_string (keystring,
- &group,
- &key,
- NULL,
- NULL);
- if (! res) {
- goto out;
- }
-
- file = gdm_daemon_config_get_per_display_custom_config_file (display);
-
- if (strcmp (group, "greeter") == 0 ||
- strcmp (group, "gui") == 0 ||
- is_key (keystring, GDM_KEY_PAM_STACK)) {
- ret = gdm_daemon_config_key_to_string (file, keystring, retval);
- }
-
- g_free (file);
-
- out:
- g_free (group);
- g_free (key);
-
- return ret;
-}
-
-/**
- * gdm_daemon_config_key_to_string
- *
- * Gets a specific key from the config file.
- * Note this returns the value in string form, so the caller needs
- * to parse it properly if it is a bool or int.
- *
- * Returns TRUE if successful..
- */
-gboolean
-gdm_daemon_config_key_to_string (const char *file,
- const char *keystring,
- char **retval)
-{
- GKeyFile *config;
- GdmConfigValueType type;
- gboolean res;
- gboolean ret;
- char *group;
- char *key;
- char *locale;
- char *result;
- const GdmConfigEntry *entry;
-
- if (retval != NULL) {
- *retval = NULL;
- }
-
- ret = FALSE;
- result = NULL;
-
- group = key = locale = NULL;
- res = gdm_common_config_parse_key_string (keystring,
- &group,
- &key,
- &locale,
- NULL);
- g_debug ("Requesting group=%s key=%s locale=%s", group, key, locale ? locale : "(null)");
-
- if (! res) {
- gdm_error ("Could not parse configuration key %s", keystring);
- goto out;
- }
-
- entry = gdm_config_lookup_entry (daemon_config, group, key);
- if (entry == NULL) {
- gdm_error ("Request for invalid configuration key %s", keystring);
- goto out;
- }
- type = entry->type;
-
- config = gdm_common_config_load (file, NULL);
- /* If file doesn't exist, then just return */
- if (config == NULL) {
- goto out;
- }
-
- gdm_debug ("Returning value for key <%s>\n", keystring);
-
- switch (type) {
- case GDM_CONFIG_VALUE_BOOL:
- {
- gboolean value;
- res = gdm_common_config_get_boolean (config, keystring, &value, NULL);
- if (res) {
- if (value) {
- result = g_strdup ("true");
- } else {
- result = g_strdup ("false");
- }
- }
- }
- break;
- case GDM_CONFIG_VALUE_INT:
- {
- int value;
- res = gdm_common_config_get_int (config, keystring, &value, NULL);
- if (res) {
- result = g_strdup_printf ("%d", value);
- }
- }
- break;
- case GDM_CONFIG_VALUE_STRING:
- {
- char *value;
- res = gdm_common_config_get_string (config, keystring, &value, NULL);
- if (res) {
- result = value;
- }
- }
- break;
- case GDM_CONFIG_VALUE_LOCALE_STRING:
- {
- char *value;
- res = gdm_common_config_get_string (config, keystring, &value, NULL);
- if (res) {
- result = value;
- }
- }
- break;
- default:
- break;
- }
-
- if (res) {
- if (retval != NULL) {
- *retval = g_strdup (result);
- }
- ret = TRUE;
- }
-
- g_key_file_free (config);
- out:
- g_free (result);
- g_free (group);
- g_free (key);
- g_free (locale);
-
- return ret;
-}
-
-/**
- * gdm_daemon_config_to_string
- *
- * Returns a configuration option as a string. Used by GDM's
- * GET_CONFIG socket command.
- */
-gboolean
-gdm_daemon_config_to_string (const char *keystring,
- const char *display,
- char **retval)
-{
- gboolean res;
- gboolean ret;
- GdmConfigValue *value;
- char *group;
- char *key;
- char *locale;
- char *result;
-
- /*
- * See if there is a per-display config file, returning that value
- * if it exists.
- */
- if (display != NULL) {
- res = gdm_daemon_config_key_to_string_per_display (keystring, display, retval);
- if (res) {
- g_debug ("Using per display value for key: %s", keystring);
- return TRUE;
- }
- }
-
- ret = FALSE;
- result = NULL;
-
- g_debug ("Looking up key: %s", keystring);
-
- group = NULL;
- key = NULL;
- locale = NULL;
- res = gdm_common_config_parse_key_string (keystring,
- &group,
- &key,
- &locale,
- NULL);
- if (! res) {
- gdm_error ("Could not parse configuration key %s", keystring);
- goto out;
- }
-
- if (group == NULL || key == NULL) {
- gdm_error ("Request for invalid configuration key %s", keystring);
- goto out;
- }
-
- /* Backward Compatibility */
- if ((strcmp (group, "daemon") == 0) &&
- (strcmp (key, "PidFile") == 0)) {
- result = g_strdup (GDM_PID_FILE);
- goto out;
- } else if ((strcmp (group, "daemon") == 0) &&
- (strcmp (key, "AlwaysRestartServer") == 0)) {
- result = g_strdup ("true");
- }
-
- res = gdm_config_get_value (daemon_config,
- group,
- key,
- &value);
-
- if (! res) {
- gdm_error ("Request for invalid configuration key %s", keystring);
- goto out;
- }
-
- result = gdm_config_value_to_string (value);
- ret = TRUE;
-
- out:
- g_free (group);
- g_free (key);
- g_free (locale);
-
-
- *retval = result;
-
- return ret;
-}
-
-/**
- * gdm_daemon_config_compare_displays
- *
- * Support function for loading displays from the configuration
- * file
- */
-int
-gdm_daemon_config_compare_displays (gconstpointer a, gconstpointer b)
-{
- const GdmDisplay *d1 = a;
- const GdmDisplay *d2 = b;
- if (d1->dispnum < d2->dispnum)
- return -1;
- else if (d1->dispnum > d2->dispnum)
- return 1;
- else
- return 0;
-}
-
-static char *
-lookup_notify_key (GdmConfig *config,
- const char *group,
- const char *key)
-{
- char *nkey;
- char *keystring;
-
- keystring = g_strdup_printf ("%s/%s", group, key);
-
- /* pretty lame but oh well */
- nkey = NULL;
-
- /* bools */
- if (is_key (keystring, GDM_KEY_ALLOW_ROOT))
- nkey = g_strdup (GDM_NOTIFY_ALLOW_ROOT);
- else if (is_key (keystring, GDM_KEY_ALLOW_REMOTE_ROOT))
- nkey = g_strdup (GDM_NOTIFY_ALLOW_REMOTE_ROOT);
- else if (is_key (keystring, GDM_KEY_ALLOW_REMOTE_AUTOLOGIN))
- nkey = g_strdup (GDM_NOTIFY_ALLOW_REMOTE_AUTOLOGIN);
- else if (is_key (keystring, GDM_KEY_SYSTEM_MENU))
- nkey = g_strdup (GDM_NOTIFY_SYSTEM_MENU);
- else if (is_key (keystring, GDM_KEY_CONFIG_AVAILABLE))
- nkey = g_strdup (GDM_NOTIFY_CONFIG_AVAILABLE);
- else if (is_key (keystring, GDM_KEY_CHOOSER_BUTTON))
- nkey = g_strdup (GDM_NOTIFY_CHOOSER_BUTTON);
- else if (is_key (keystring, GDM_KEY_DISALLOW_TCP))
- nkey = g_strdup (GDM_NOTIFY_DISALLOW_TCP);
- else if (is_key (keystring, GDM_KEY_ADD_GTK_MODULES))
- nkey = g_strdup (GDM_NOTIFY_ADD_GTK_MODULES);
- else if (is_key (keystring, GDM_KEY_TIMED_LOGIN_ENABLE))
- nkey = g_strdup (GDM_NOTIFY_TIMED_LOGIN_ENABLE);
- /* ints */
- else if (is_key (keystring, GDM_KEY_RETRY_DELAY))
- nkey = g_strdup (GDM_NOTIFY_RETRY_DELAY);
- else if (is_key (keystring, GDM_KEY_TIMED_LOGIN_DELAY))
- nkey = g_strdup (GDM_NOTIFY_TIMED_LOGIN_DELAY);
- /* strings */
- else if (is_key (keystring, GDM_KEY_GREETER))
- nkey = g_strdup (GDM_NOTIFY_GREETER);
- else if (is_key (keystring, GDM_KEY_REMOTE_GREETER))
- nkey = g_strdup (GDM_NOTIFY_REMOTE_GREETER);
- else if (is_key (keystring, GDM_KEY_SOUND_ON_LOGIN_FILE))
- nkey = g_strdup (GDM_NOTIFY_SOUND_ON_LOGIN_FILE);
- else if (is_key (keystring, GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE))
- nkey = g_strdup (GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE);
- else if (is_key (keystring, GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE))
- nkey = g_strdup (GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE);
- else if (is_key (keystring, GDM_KEY_GTK_MODULES_LIST))
- nkey = g_strdup (GDM_NOTIFY_GTK_MODULES_LIST);
- else if (is_key (keystring, GDM_KEY_TIMED_LOGIN))
- nkey = g_strdup (GDM_NOTIFY_TIMED_LOGIN);
- else if (strcmp (group, GDM_CONFIG_GROUP_CUSTOM_CMD) == 0 &&
- g_str_has_prefix (key, "CustomCommand") &&
- strlen (key) == 14) {
- /* this should match 'CustomCommandN' */
- nkey = g_strdup (key);
- }
- g_free (keystring);
-
- return nkey;
-}
-
-/**
- * notify_displays_value
- *
- * This will notify the slave programs
- * (gdmgreeter, gdmlogin, etc.) that a configuration option has
- * been changed so the slave can update with the new option
- * value. GDM does this notify when it receives a
- * GDM_CONFIG_UPDATE socket command from gdmsetup or from the
- * gdmflexiserver --command option.
- */
-static void
-notify_displays_value (GdmConfig *config,
- const char *group,
- const char *key,
- GdmConfigValue *value)
-{
- GSList *li;
- char *valstr;
- char *keystr;
-
- keystr = lookup_notify_key (config, group, key);
-
- /* unfortunately, can't always gdm_config_value_to_string()
- * here because booleans need to be sent as ints
- */
- switch (value->type) {
- case GDM_CONFIG_VALUE_BOOL:
- if (gdm_config_value_get_bool (value)) {
- valstr = g_strdup ("1");
- } else {
- valstr = g_strdup ("0");
- }
- break;
- default:
- valstr = gdm_config_value_to_string (value);
- break;
- }
-
- if (valstr == NULL) {
- valstr = g_strdup (" ");
- }
-
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *disp = li->data;
-
- if (disp->master_notify_fd < 0) {
- /* no point */
- continue;
- }
-
- gdm_fdprintf (disp->master_notify_fd,
- "%c%s %s\n",
- GDM_SLAVE_NOTIFY_KEY,
- keystr,
- valstr);
-
- if (disp != NULL && disp->slavepid > 1) {
- kill (disp->slavepid, SIGUSR2);
- }
- }
-
- g_free (keystr);
- g_free (valstr);
-}
-
-/* The following were used to internally set the
- * stored configuration values. Now we'll just
- * ask the GdmConfig to store the entry. */
-void
-gdm_daemon_config_set_value_string (const gchar *keystring,
- const gchar *value_in)
-{
- char *group;
- char *key;
- gboolean res;
- GdmConfigValue *value;
-
- res = gdm_common_config_parse_key_string (keystring, &group, &key, NULL, NULL);
- if (! res) {
- gdm_error ("Could not parse configuration key %s", keystring);
- return;
- }
-
- value = gdm_config_value_new (GDM_CONFIG_VALUE_STRING);
- gdm_config_value_set_string (value, value_in);
-
- res = gdm_config_set_value (daemon_config, group, key, value);
-
- gdm_config_value_free (value);
- g_free (group);
- g_free (key);
-}
-
-void
-gdm_daemon_config_set_value_bool (const gchar *keystring,
- gboolean value_in)
-{
- char *group;
- char *key;
- gboolean res;
- GdmConfigValue *value;
-
- res = gdm_common_config_parse_key_string (keystring, &group, &key, NULL, NULL);
- if (! res) {
- gdm_error ("Could not parse configuration key %s", keystring);
- return;
- }
-
- value = gdm_config_value_new (GDM_CONFIG_VALUE_BOOL);
- gdm_config_value_set_bool (value, value_in);
-
- res = gdm_config_set_value (daemon_config, group, key, value);
-
- gdm_config_value_free (value);
- g_free (group);
- g_free (key);
-}
-
-void
-gdm_daemon_config_set_value_int (const gchar *keystring,
- gint value_in)
-{
- char *group;
- char *key;
- gboolean res;
- GdmConfigValue *value;
-
- res = gdm_common_config_parse_key_string (keystring, &group, &key, NULL, NULL);
- if (! res) {
- gdm_error ("Could not parse configuration key %s", keystring);
- return;
- }
-
- value = gdm_config_value_new (GDM_CONFIG_VALUE_INT);
- gdm_config_value_set_int (value, value_in);
-
- res = gdm_config_set_value (daemon_config, group, key, value);
-
- gdm_config_value_free (value);
- g_free (group);
- g_free (key);
-}
-
-/**
- * gdm_daemon_config_find_xserver
- *
- * Return an xserver with a given ID, or NULL if not found.
- */
-GdmXserver *
-gdm_daemon_config_find_xserver (const gchar *id)
-{
- GSList *li;
-
- if (xservers == NULL)
- return NULL;
-
- if (id == NULL)
- return xservers->data;
-
- for (li = xservers; li != NULL; li = li->next) {
- GdmXserver *svr = li->data;
- if (strcmp (ve_sure_string (svr->id), ve_sure_string (id)) == 0)
- return svr;
- }
-
- return NULL;
-}
-
-/**
- * gdm_daemon_config_get_xservers
- *
- * Prepare a string to be returned for the GET_SERVER_LIST
- * sockets command.
- */
-gchar *
-gdm_daemon_config_get_xservers (void)
-{
- GSList *li;
- gchar *retval = NULL;
-
- if (xservers == NULL)
- return NULL;
-
- for (li = xservers; li != NULL; li = li->next) {
- GdmXserver *svr = li->data;
- if (retval != NULL)
- retval = g_strconcat (retval, ";", svr->id, NULL);
- else
- retval = g_strdup (svr->id);
- }
-
- return retval;
-}
-
-/* PRIO_MIN and PRIO_MAX are not defined on Solaris, but are -20 and 20 */
-#if sun
-#ifndef PRIO_MIN
-#define PRIO_MIN -20
-#endif
-#ifndef PRIO_MAX
-#define PRIO_MAX 20
-#endif
-#endif
-
-/**
- * gdm_daemon_config_load_xserver
- *
- * Load [server-foo] sections from a configuration file.
- */
-static void
-gdm_daemon_config_load_xserver (GdmConfig *config,
- const char *key,
- const char *name)
-{
- GdmXserver *svr;
- int n;
- char *group;
- gboolean res;
- GdmConfigValue *value;
-
- /*
- * See if we already loaded a server with this id, skip if
- * one already exists.
- */
- if (gdm_daemon_config_find_xserver (name) != NULL) {
- return;
- }
-
- svr = g_new0 (GdmXserver, 1);
- svr->id = g_strdup (name);
-
- if (isdigit (*key)) {
- svr->number = atoi (key);
- }
-
- group = g_strdup_printf ("server-%s", name);
-
- /* string */
- res = gdm_config_get_value (config, group, "name", &value);
- if (res) {
- svr->name = g_strdup (gdm_config_value_get_string (value));
- }
- res = gdm_config_get_value (config, group, "command", &value);
- if (res) {
- svr->command = g_strdup (gdm_config_value_get_string (value));
- }
-
- gdm_debug ("Adding new server id=%s name=%s command=%s", name, svr->name, svr->command);
-
-
- /* bool */
- res = gdm_config_get_value (config, group, "flexible", &value);
- if (res) {
- svr->flexible = gdm_config_value_get_bool (value);
- }
- res = gdm_config_get_value (config, group, "choosable", &value);
- if (res) {
- svr->choosable = gdm_config_value_get_bool (value);
- }
- res = gdm_config_get_value (config, group, "handled", &value);
- if (res) {
- svr->handled = gdm_config_value_get_bool (value);
- }
- res = gdm_config_get_value (config, group, "chooser", &value);
- if (res) {
- svr->chooser = gdm_config_value_get_bool (value);
- }
-
- /* int */
- res = gdm_config_get_value (config, group, "priority", &value);
- if (res) {
- svr->priority = gdm_config_value_get_int (value);
- }
-
- /* do some bounds checking */
- n = svr->priority;
- if (n < PRIO_MIN)
- n = PRIO_MIN;
- else if (n > PRIO_MAX)
- n = PRIO_MAX;
-
- if (n != svr->priority) {
- gdm_error (_("%s: Priority out of bounds; changed to %d"),
- "gdm_config_parse", n);
- svr->priority = n;
- }
-
- if (ve_string_empty (svr->command)) {
- gdm_error (_("%s: Empty server command; "
- "using standard command."), "gdm_config_parse");
- g_free (svr->command);
- svr->command = g_strdup (X_SERVER);
- }
-
- xservers = g_slist_append (xservers, svr);
-}
-
-static void
-gdm_daemon_config_unload_xservers (GdmConfig *config)
-{
- GSList *xli;
-
- /* Free list if already loaded */
- for (xli = xservers; xli != NULL; xli = xli->next) {
- GdmXserver *xsvr = xli->data;
-
- g_free (xsvr->id);
- g_free (xsvr->name);
- g_free (xsvr->command);
- }
-
- if (xservers != NULL) {
- g_slist_free (xservers);
- xservers = NULL;
- }
-}
-
-static void
-gdm_daemon_config_ensure_one_xserver (GdmConfig *config)
-{
- /* If no "Standard" server was created, then add it */
- if (xservers == NULL || gdm_daemon_config_find_xserver (GDM_STANDARD) == NULL) {
- GdmXserver *svr = g_new0 (GdmXserver, 1);
-
- svr->id = g_strdup (GDM_STANDARD);
- svr->name = g_strdup ("Standard server");
- svr->command = g_strdup (X_SERVER);
- svr->flexible = TRUE;
- svr->choosable = TRUE;
- svr->handled = TRUE;
- svr->priority = 0;
-
- xservers = g_slist_append (xservers, svr);
- }
-}
-
-static void
-load_xservers_group (GdmConfig *config)
-{
- char **keys;
- gsize len;
- int i;
-
- keys = gdm_config_get_keys_for_group (config, GDM_CONFIG_GROUP_SERVERS, &len, NULL);
-
- /* now construct entries for these groups */
- for (i = 0; i < len; i++) {
- GdmConfigEntry entry;
- GdmConfigValue *value;
- char *new_group;
- gboolean res;
- int j;
- const char *name;
-
- entry.group = GDM_CONFIG_GROUP_SERVERS;
- entry.key = keys[i];
- entry.type = GDM_CONFIG_VALUE_STRING;
- entry.default_value = NULL;
- entry.id = GDM_CONFIG_INVALID_ID;
-
- gdm_config_add_entry (config, &entry);
- gdm_config_process_entry (config, &entry, NULL);
-
- res = gdm_config_get_value (config, entry.group, entry.key, &value);
- if (! res) {
- continue;
- }
-
- name = gdm_config_value_get_string (value);
- if (name == NULL || name[0] == '\0') {
- gdm_config_value_free (value);
- continue;
- }
-
- /* skip servers marked as inactive */
- if (g_ascii_strcasecmp (name, "inactive") == 0) {
- gdm_config_value_free (value);
- continue;
- }
-
- new_group = g_strdup_printf ("server-%s", name);
- for (j = 0; j < G_N_ELEMENTS (gdm_daemon_server_config_entries); j++) {
- GdmConfigEntry *srv_entry;
- if (gdm_daemon_server_config_entries[j].key == NULL) {
- continue;
- }
- srv_entry = gdm_config_entry_copy (&gdm_daemon_server_config_entries[j]);
- g_free (srv_entry->group);
- srv_entry->group = g_strdup (new_group);
- gdm_config_process_entry (config, srv_entry, NULL);
- gdm_config_entry_free (srv_entry);
- }
- g_free (new_group);
-
- /* now we can add this server */
- gdm_daemon_config_load_xserver (config, entry.key, gdm_config_value_get_string (value));
-
- gdm_config_value_free (value);
- }
-}
-
-static void
-gdm_daemon_config_load_xservers (GdmConfig *config)
-{
- gdm_daemon_config_unload_xservers (config);
- load_xservers_group (config);
- gdm_daemon_config_ensure_one_xserver (config);
-}
-
-/**
- * gdm_daemon_config_update_key
- *
- * Will cause a the GDM daemon to re-read the key from the configuration
- * file and cause notify signal to be sent to the slaves for the
- * specified key, if appropriate.
- * Obviously notification is not needed for configuration options only
- * used by the daemon. This function is called when the UPDDATE_CONFIG
- * sockets command is called.
- *
- * To add a new notification, a GDM_NOTIFY_* argument will need to be
- * defined in gdm-daemon-config-keys.h, supporting logic placed in the
- * notify_cb function and in the gdm_slave_handle_notify function
- * in slave.c.
- */
-gboolean
-gdm_daemon_config_update_key (const char *keystring)
-{
- gboolean rc;
- gboolean res;
- char *group;
- char *key;
- char *locale;
- const GdmConfigEntry *entry;
-
- rc = FALSE;
- group = key = locale = NULL;
-
- /*
- * Do not allow these keys to be updated, since GDM would need
- * additional work, or at least heavy testing, to make these keys
- * flexible enough to be changed at runtime.
- */
- if (is_key (keystring, GDM_KEY_PID_FILE) ||
- is_key (keystring, GDM_KEY_CONSOLE_NOTIFY) ||
- is_key (keystring, GDM_KEY_USER) ||
- is_key (keystring, GDM_KEY_GROUP) ||
- is_key (keystring, GDM_KEY_LOG_DIR) ||
- is_key (keystring, GDM_KEY_SERV_AUTHDIR) ||
- is_key (keystring, GDM_KEY_USER_AUTHDIR) ||
- is_key (keystring, GDM_KEY_USER_AUTHFILE) ||
- is_key (keystring, GDM_KEY_USER_AUTHDIR_FALLBACK)) {
- return FALSE;
- }
-
- /* reload backend files if necessary */
- gdm_config_load (daemon_config, NULL);
-
- /* Shortcut for updating all XDMCP parameters */
- if (is_key (keystring, "xdmcp/PARAMETERS")) {
- rc = gdm_daemon_config_update_key (GDM_KEY_DISPLAYS_PER_HOST);
- if (rc == TRUE)
- rc = gdm_daemon_config_update_key (GDM_KEY_MAX_PENDING);
- if (rc == TRUE)
- rc = gdm_daemon_config_update_key (GDM_KEY_MAX_WAIT);
- if (rc == TRUE)
- rc = gdm_daemon_config_update_key (GDM_KEY_MAX_SESSIONS);
- if (rc == TRUE)
- rc = gdm_daemon_config_update_key (GDM_KEY_INDIRECT);
- if (rc == TRUE)
- rc = gdm_daemon_config_update_key (GDM_KEY_MAX_INDIRECT);
- if (rc == TRUE)
- rc = gdm_daemon_config_update_key (GDM_KEY_MAX_WAIT_INDIRECT);
- if (rc == TRUE)
- rc = gdm_daemon_config_update_key (GDM_KEY_PING_INTERVAL);
- goto out;
- }
-
- /* find the entry for the key */
- res = gdm_common_config_parse_key_string (keystring,
- &group,
- &key,
- &locale,
- NULL);
- if (! res) {
- gdm_error ("Could not parse configuration key %s", keystring);
- goto out;
- }
-
- entry = gdm_config_lookup_entry (daemon_config, group, key);
- if (entry == NULL) {
- gdm_error ("Request for invalid configuration key %s", keystring);
- goto out;
- }
-
- rc = gdm_config_process_entry (daemon_config, entry, NULL);
-
- out:
- g_free (group);
- g_free (key);
- g_free (locale);
-
- return rc;
-}
-
-/**
- * check_logdir
- * check_servauthdir
- *
- * Support functions for gdm_config_parse.
- */
-static void
-check_logdir (void)
-{
- struct stat statbuf;
- int r;
- char *log_path;
- const char *auth_path;
- GdmConfigValue *value;
-
- log_path = NULL;
- auth_path = NULL;
-
- gdm_config_get_string_for_id (daemon_config, GDM_ID_LOG_DIR, &log_path);
-
- gdm_config_get_value_for_id (daemon_config, GDM_ID_SERV_AUTHDIR, &value);
- auth_path = gdm_config_value_get_string (value);
-
- VE_IGNORE_EINTR (r = g_stat (log_path, &statbuf));
- if (r < 0 || ! S_ISDIR (statbuf.st_mode)) {
- gdm_error (_("%s: Logdir %s does not exist or isn't a directory. Using ServAuthDir %s."),
- "gdm_config_parse",
- log_path,
- auth_path);
- gdm_config_set_value_for_id (daemon_config, GDM_ID_LOG_DIR, value);
- }
-
- g_free (log_path);
- gdm_config_value_free (value);
-}
-
-static void
-check_servauthdir (const char *auth_path,
- struct stat *statbuf)
-{
- int r;
- gboolean console_notify;
-
- console_notify = FALSE;
- gdm_config_get_bool_for_id (daemon_config, GDM_ID_CONSOLE_NOTIFY, &console_notify);
-
- /* Enter paranoia mode */
- VE_IGNORE_EINTR (r = g_stat (auth_path, statbuf));
- if G_UNLIKELY (r < 0) {
- if (console_notify) {
- gchar *s = g_strdup_printf (C_(N_("Server Authorization directory "
- "(daemon/ServAuthDir) is set to %s "
- "but this does not exist. Please "
- "correct GDM configuration and "
- "restart GDM.")),
- auth_path);
-
- gdm_text_message_dialog (s);
- g_free (s);
- }
-
- gdm_fail (_("%s: Authdir %s does not exist. Aborting."), "gdm_config_parse", auth_path);
- }
-
- if G_UNLIKELY (! S_ISDIR (statbuf->st_mode)) {
- if (console_notify) {
- gchar *s = g_strdup_printf (C_(N_("Server Authorization directory "
- "(daemon/ServAuthDir) is set to %s "
- "but this is not a directory. Please "
- "correct GDM configuration and "
- "restart GDM.")),
- auth_path);
-
- gdm_text_message_dialog (s);
- g_free (s);
- }
-
- gdm_fail (_("%s: Authdir %s is not a directory. Aborting."), "gdm_config_parse", auth_path);
- }
-}
-
-static gboolean
-have_display_for_number (int number)
-{
- GSList *l;
-
- for (l = displays; l != NULL; l = l->next) {
- GdmDisplay *disp = l->data;
- if (disp->dispnum == number) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static void
-gdm_daemon_config_load_displays (GdmConfig *config)
-{
- GSList *l;
-
- for (l = xservers; l != NULL; l = l->next) {
- GdmXserver *xserver;
- GdmDisplay *disp;
-
- xserver = l->data;
-
- gdm_debug ("Loading display for key '%d'", xserver->number);
-
- gdm_debug ("Got name for server: %s", xserver->id);
- /* Do not add if already in the list */
- if (have_display_for_number (xserver->number)) {
- continue;
- }
-
- disp = gdm_display_alloc (xserver->number, xserver->id);
- if (disp == NULL) {
- continue;
- }
-
- displays = g_slist_insert_sorted (displays, disp, gdm_daemon_config_compare_displays);
- if (xserver->number > high_display_num) {
- high_display_num = xserver->number;
- }
- }
-}
-
-static gboolean
-validate_path (GdmConfig *config,
- GdmConfigSourceType source,
- GdmConfigValue *value)
-{
- char *str;
-
- /* If the /etc/default has a PATH use that */
- str = gdm_read_default ("PATH=");
- if (str != NULL) {
- gdm_config_value_set_string (value, str);
- g_free (str);
- }
-
- return TRUE;
-}
-
-static gboolean
-validate_root_path (GdmConfig *config,
- GdmConfigSourceType source,
- GdmConfigValue *value)
-{
- char *str;
-
- /* If the /etc/default has a PATH use that */
- str = gdm_read_default ("SUPATH=");
- if (str != NULL) {
- gdm_config_value_set_string (value, str);
- g_free (str);
- }
-
- return TRUE;
-}
-
-static gboolean
-validate_base_xsession (GdmConfig *config,
- GdmConfigSourceType source,
- GdmConfigValue *value)
-{
- const char *str;
-
- str = gdm_config_value_get_string (value);
- if (str == NULL || str[0] == '\0') {
- char *path;
- path = g_build_filename (GDMCONFDIR, "gdm", "Xsession", NULL);
- gdm_info (_("%s: BaseXsession empty; using %s"), "gdm_config_parse", path);
- gdm_config_value_set_string (value, path);
- g_free (path);
- }
-
- return TRUE;
-}
-
-static gboolean
-validate_power_action (GdmConfig *config,
- GdmConfigSourceType source,
- GdmConfigValue *value)
-{
- /* FIXME: should weed out the commands that don't work */
-
- return TRUE;
-}
-
-static gboolean
-validate_standard_xserver (GdmConfig *config,
- GdmConfigSourceType source,
- GdmConfigValue *value)
-{
- gboolean res;
- gboolean is_ok;
- const char *str;
- char *new;
-
- is_ok = FALSE;
- new = NULL;
- str = gdm_config_value_get_string (value);
-
- if (str != NULL) {
- char **argv;
-
- if (g_shell_parse_argv (str, NULL, &argv, NULL)) {
- if (g_access (argv[0], X_OK) == 0) {
- is_ok = TRUE;
- }
- g_strfreev (argv);
- }
- }
-
- if G_UNLIKELY (! is_ok) {
- gdm_info (_("%s: Standard X server not found; trying alternatives"), "gdm_config_parse");
- if (g_access ("/usr/X11R6/bin/X", X_OK) == 0) {
- new = g_strdup ("/usr/X11R6/bin/X");
- } else if (g_access ("/opt/X11R6/bin/X", X_OK) == 0) {
- new = g_strdup ("/opt/X11R6/bin/X");
- } else if (g_access ("/usr/bin/X11/X", X_OK) == 0) {
- new = g_strdup ("/usr/bin/X11/X");
- }
- }
-
- if (new != NULL) {
- gdm_config_value_set_string (value, new);
- g_free (new);
- }
-
- res = TRUE;
-
- return res;
-}
-
-static gboolean
-validate_graphical_theme_dir (GdmConfig *config,
- GdmConfigSourceType source,
- GdmConfigValue *value)
-{
- const char *str;
-
- str = gdm_config_value_get_string (value);
-
- if (str == NULL || !g_file_test (str, G_FILE_TEST_IS_DIR)) {
- gdm_config_value_set_string (value, GREETERTHEMEDIR);
- }
-
- return TRUE;
-}
-
-static gboolean
-validate_graphical_theme (GdmConfig *config,
- GdmConfigSourceType source,
- GdmConfigValue *value)
-{
- const char *str;
-
- str = gdm_config_value_get_string (value);
-
- if (str == NULL || str[0] == '\0') {
- gdm_config_value_set_string (value, "circles");
- }
-
- return TRUE;
-}
-
-static gboolean
-validate_greeter (GdmConfig *config,
- GdmConfigSourceType source,
- GdmConfigValue *value)
-{
- const char *str;
-
- str = gdm_config_value_get_string (value);
-
- if (str == NULL || str[0] == '\0') {
- gdm_error (_("%s: No greeter specified."), "gdm_config_parse");
- }
-
- return TRUE;
-}
-
-static gboolean
-validate_remote_greeter (GdmConfig *config,
- GdmConfigSourceType source,
- GdmConfigValue *value)
-{
- const char *str;
-
- str = gdm_config_value_get_string (value);
-
- if (str == NULL || str[0] == '\0') {
- gdm_error (_("%s: No remote greeter specified."), "gdm_config_parse");
- }
-
- return TRUE;
-}
-
-static gboolean
-validate_session_desktop_dir (GdmConfig *config,
- GdmConfigSourceType source,
- GdmConfigValue *value)
-{
- const char *str;
-
- str = gdm_config_value_get_string (value);
-
- if (str == NULL || str[0] == '\0') {
- gdm_error (_("%s: No sessions directory specified."), "gdm_config_parse");
- }
-
- return TRUE;
-}
-
-static gboolean
-validate_password_required (GdmConfig *config,
- GdmConfigSourceType source,
- GdmConfigValue *value)
-{
- char *str;
-
- str = gdm_read_default ("PASSREQ=");
- if (str != NULL && str[0] == '\0') {
- gboolean val;
- val = (g_ascii_strcasecmp (str, "YES") == 0);
- gdm_config_value_set_bool (value, val);
- }
-
- return TRUE;
-}
-
-static gboolean
-validate_allow_remote_root (GdmConfig *config,
- GdmConfigSourceType source,
- GdmConfigValue *value)
-{
- char *str;
-
- str = gdm_read_default ("CONSOLE=");
- if (str != NULL && str[0] == '\0') {
- gboolean val;
- val = (g_ascii_strcasecmp (str, "/dev/console") != 0);
- gdm_config_value_set_bool (value, val);
- }
-
- return TRUE;
-}
-
-static gboolean
-validate_xdmcp (GdmConfig *config,
- GdmConfigSourceType source,
- GdmConfigValue *value)
-{
-
-#ifndef HAVE_LIBXDMCP
- if (gdm_config_value_get_bool (value)) {
- gdm_info (_("%s: XDMCP was enabled while there is no XDMCP support; turning it off"), "gdm_config_parse");
- gdm_config_value_set_bool (value, FALSE);
- }
-#endif
-
- return TRUE;
-}
-
-static gboolean
-validate_at_least_int (GdmConfig *config,
- GdmConfigSourceType source,
- GdmConfigValue *value,
- int minval,
- int defval)
-{
- if (gdm_config_value_get_int (value) < minval) {
- gdm_config_value_set_int (value, defval);
- }
-
- return TRUE;
-}
-
-static gboolean
-validate_cb (GdmConfig *config,
- GdmConfigSourceType source,
- const char *group,
- const char *key,
- GdmConfigValue *value,
- int id,
- gpointer data)
-{
- gboolean res;
-
- res = TRUE;
-
- switch (id) {
- case GDM_ID_PATH:
- res = validate_path (config, source, value);
- break;
- case GDM_ID_ROOT_PATH:
- res = validate_root_path (config, source, value);
- break;
- case GDM_ID_BASE_XSESSION:
- res = validate_base_xsession (config, source, value);
- break;
- case GDM_ID_HALT:
- case GDM_ID_REBOOT:
- case GDM_ID_SUSPEND:
- res = validate_power_action (config, source, value);
- break;
- case GDM_ID_STANDARD_XSERVER:
- res = validate_standard_xserver (config, source, value);
- break;
- case GDM_ID_GRAPHICAL_THEME_DIR:
- res = validate_graphical_theme_dir (config, source, value);
- break;
- case GDM_ID_GRAPHICAL_THEME:
- res = validate_graphical_theme (config, source, value);
- break;
- case GDM_ID_GREETER:
- res = validate_greeter (config, source, value);
- break;
- case GDM_ID_REMOTE_GREETER:
- res = validate_remote_greeter (config, source, value);
- break;
- case GDM_ID_SESSION_DESKTOP_DIR:
- res = validate_session_desktop_dir (config, source, value);
- break;
- case GDM_ID_PASSWORD_REQUIRED:
- res = validate_password_required (config, source, value);
- break;
- case GDM_ID_ALLOW_REMOTE_ROOT:
- res = validate_allow_remote_root (config, source, value);
- break;
- case GDM_ID_XDMCP:
- res = validate_xdmcp (config, source, value);
- break;
- case GDM_ID_MAX_INDIRECT:
- case GDM_ID_XINERAMA_SCREEN:
- res = validate_at_least_int (config, source, value, 0, 0);
- break;
- case GDM_ID_TIMED_LOGIN_DELAY:
- res = validate_at_least_int (config, source, value, 5, 5);
- break;
- case GDM_ID_MAX_ICON_WIDTH:
- case GDM_ID_MAX_ICON_HEIGHT:
- res = validate_at_least_int (config, source, value, 0, 128);
- break;
- case GDM_ID_SCAN_TIME:
- res = validate_at_least_int (config, source, value, 1, 1);
- break;
- case GDM_ID_NONE:
- case GDM_CONFIG_INVALID_ID:
- break;
- default:
- break;
- }
-
- return res;
-}
-
-static const char *
-source_to_name (GdmConfigSourceType source)
-{
- const char *name;
-
- switch (source) {
- case GDM_CONFIG_SOURCE_DEFAULT:
- name = "default";
- break;
- case GDM_CONFIG_SOURCE_MANDATORY:
- name = "mandatory";
- break;
- case GDM_CONFIG_SOURCE_CUSTOM:
- name = "custom";
- break;
- case GDM_CONFIG_SOURCE_BUILT_IN:
- name = "built-in";
- break;
- case GDM_CONFIG_SOURCE_RUNTIME_USER:
- name = "runtime-user";
- break;
- case GDM_CONFIG_SOURCE_INVALID:
- name = "Invalid";
- break;
- default:
- name = "Unknown";
- break;
- }
-
- return name;
-}
-
-static gboolean
-notify_cb (GdmConfig *config,
- GdmConfigSourceType source,
- const char *group,
- const char *key,
- GdmConfigValue *value,
- int id,
- gpointer data)
-{
- char *valstr;
-
- switch (id) {
- case GDM_ID_GREETER:
- case GDM_ID_REMOTE_GREETER:
- case GDM_ID_SOUND_ON_LOGIN_FILE:
- case GDM_ID_SOUND_ON_LOGIN_SUCCESS_FILE:
- case GDM_ID_SOUND_ON_LOGIN_FAILURE_FILE:
- case GDM_ID_GTK_MODULES_LIST:
- case GDM_ID_TIMED_LOGIN:
- case GDM_ID_ALLOW_ROOT:
- case GDM_ID_ALLOW_REMOTE_ROOT:
- case GDM_ID_ALLOW_REMOTE_AUTOLOGIN:
- case GDM_ID_SYSTEM_MENU:
- case GDM_ID_CONFIG_AVAILABLE:
- case GDM_ID_CHOOSER_BUTTON:
- case GDM_ID_DISALLOW_TCP:
- case GDM_ID_ADD_GTK_MODULES:
- case GDM_ID_TIMED_LOGIN_ENABLE:
- case GDM_ID_RETRY_DELAY:
- case GDM_ID_TIMED_LOGIN_DELAY:
- notify_displays_value (config, group, key, value);
- break;
- case GDM_ID_NONE:
- case GDM_CONFIG_INVALID_ID:
- {
- /* doesn't have an ID : match group/key */
- if (group != NULL) {
- if (strcmp (group, GDM_CONFIG_GROUP_SERVERS) == 0) {
- /* FIXME: handle this? */
- } else if (strcmp (group, GDM_CONFIG_GROUP_CUSTOM_CMD) == 0) {
- notify_displays_value (config, group, key, value);
- }
- }
- }
- break;
- default:
- break;
- }
-
- valstr = gdm_config_value_to_string (value);
- gdm_debug ("Got config %s/%s=%s <%s>\n",
- group,
- key,
- valstr,
- source_to_name (source));
- g_free (valstr);
-
- return TRUE;
-}
-
-static void
-handle_no_displays (GdmConfig *config,
- gboolean no_console)
-{
- const char *server;
- gboolean console_notify;
-
- console_notify = FALSE;
- gdm_config_get_bool_for_id (daemon_config, GDM_ID_CONSOLE_NOTIFY, &console_notify);
-
- /*
- * If we requested no static servers (there is no console),
- * then don't display errors in console messages
- */
- if (no_console) {
- gdm_fail (_("%s: XDMCP disabled and no static servers defined. Aborting!"), "gdm_config_parse");
- }
-
- server = X_SERVER;
- if G_LIKELY (g_access (server, X_OK) == 0) {
- } else if (g_access ("/usr/bin/X11/X", X_OK) == 0) {
- server = "/usr/bin/X11/X";
- } else if (g_access ("/usr/X11R6/bin/X", X_OK) == 0) {
- server = "/usr/X11R6/bin/X";
- } else if (g_access ("/opt/X11R6/bin/X", X_OK) == 0) {
- server = "/opt/X11R6/bin/X";
- }
-
- /* 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);
-
- d = gdm_display_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 */
- gdm_config_set_string_for_id (daemon_config, GDM_ID_AUTOMATIC_LOGIN, NULL);
- gdm_config_set_string_for_id (daemon_config, GDM_ID_TIMED_LOGIN, NULL);
-
- } else {
- if (console_notify) {
- gchar *s = g_strdup_printf (C_(N_("XDMCP is disabled and GDM "
- "cannot find any static server "
- "to start. Aborting! Please "
- "correct the configuration "
- "and restart GDM.")));
- gdm_text_message_dialog (s);
- g_free (s);
- }
-
- gdm_fail (_("%s: XDMCP disabled and no static servers defined. Aborting!"), "gdm_config_parse");
- }
-}
-
-static void
-gdm_daemon_change_user (GdmConfig *config,
- uid_t *uidp,
- gid_t *gidp)
-{
- gboolean console_notify;
- char *username;
- char *groupname;
- uid_t uid;
- gid_t gid;
- struct passwd *pwent;
- struct group *grent;
-
- console_notify = FALSE;
- username = NULL;
- groupname = NULL;
- uid = 0;
- gid = 0;
-
- gdm_config_get_bool_for_id (daemon_config, GDM_ID_CONSOLE_NOTIFY, &console_notify);
- gdm_config_get_string_for_id (daemon_config, GDM_ID_USER, &username);
- gdm_config_get_string_for_id (daemon_config, GDM_ID_GROUP, &groupname);
-
- /* Lookup user and groupid for the GDM user */
- pwent = getpwnam (username);
-
- /* Set uid and gid */
- if G_UNLIKELY (pwent == NULL) {
-
- if (console_notify) {
- gchar *s = g_strdup_printf (C_(N_("The GDM user '%s' does not exist. "
- "Please correct GDM configuration "
- "and restart GDM.")),
- username);
- gdm_text_message_dialog (s);
- g_free (s);
- }
-
- gdm_fail (_("%s: Can't find the GDM user '%s'. Aborting!"), "gdm_config_parse", username);
- } else {
- uid = pwent->pw_uid;
- }
-
- if G_UNLIKELY (uid == 0) {
- if (console_notify) {
- gchar *s = g_strdup_printf (C_(N_("The GDM user is set to be root, but "
- "this is not allowed since it can "
- "pose a security risk. Please "
- "correct GDM configuration and "
- "restart GDM.")));
-
- gdm_text_message_dialog (s);
- g_free (s);
- }
-
- gdm_fail (_("%s: The GDM user should not be root. Aborting!"), "gdm_config_parse");
- }
-
- grent = getgrnam (groupname);
-
- if G_UNLIKELY (grent == NULL) {
- if (console_notify) {
- gchar *s = g_strdup_printf (C_(N_("The GDM group '%s' does not exist. "
- "Please correct GDM configuration "
- "and restart GDM.")),
- groupname);
- gdm_text_message_dialog (s);
- g_free (s);
- }
-
- gdm_fail (_("%s: Can't find the GDM group '%s'. Aborting!"), "gdm_config_parse", groupname);
- } else {
- gid = grent->gr_gid;
- }
-
- if G_UNLIKELY (gid == 0) {
- if (console_notify) {
- gchar *s = g_strdup_printf (C_(N_("The GDM group is set to be root, but "
- "this is not allowed since it can "
- "pose a security risk. Please "
- "correct GDM configuration and "
- "restart GDM.")));
- gdm_text_message_dialog (s);
- g_free (s);
- }
-
- gdm_fail (_("%s: The GDM group should not be root. Aborting!"), "gdm_config_parse");
- }
-
- /* gid remains `gdm' */
- NEVER_FAILS_root_set_euid_egid (uid, gid);
-
- if (uidp != NULL) {
- *uidp = uid;
- }
-
- if (gidp != NULL) {
- *gidp = gid;
- }
-
- g_free (username);
- g_free (groupname);
-}
-
-static void
-gdm_daemon_check_permissions (GdmConfig *config,
- uid_t uid,
- gid_t gid)
-{
- struct stat statbuf;
- char *auth_path;
- gboolean console_notify;
-
- console_notify = FALSE;
- gdm_config_get_bool_for_id (daemon_config, GDM_ID_CONSOLE_NOTIFY, &console_notify);
- auth_path = NULL;
- gdm_config_get_string_for_id (config, GDM_ID_SERV_AUTHDIR, &auth_path);
-
- /* Enter paranoia mode */
- check_servauthdir (auth_path, &statbuf);
-
- NEVER_FAILS_root_set_euid_egid (0, 0);
-
- /* Now set things up for us as */
- chown (auth_path, 0, gid);
- g_chmod (auth_path, (S_IRWXU|S_IRWXG|S_ISVTX));
-
- NEVER_FAILS_root_set_euid_egid (uid, gid);
-
- /* Again paranoid */
- check_servauthdir (auth_path, &statbuf);
-
- if G_UNLIKELY (statbuf.st_uid != 0 || statbuf.st_gid != gid) {
- if (console_notify) {
- gchar *s = g_strdup_printf (C_(N_("Server Authorization directory "
- "(daemon/ServAuthDir) is set to %s "
- "but is not owned by user %d and group "
- "%d. Please correct the ownership or "
- "GDM configuration and restart "
- "GDM.")),
- auth_path,
- (int)uid,
- (int)gid);
- gdm_text_message_dialog (s);
- g_free (s);
- }
-
- gdm_fail (_("%s: Authdir %s is not owned by user %d, group %d. Aborting."),
- "gdm_config_parse",
- auth_path,
- (int)uid,
- (int)gid);
- }
-
- if G_UNLIKELY (statbuf.st_mode != (S_IFDIR|S_IRWXU|S_IRWXG|S_ISVTX)) {
- if (console_notify) {
- gchar *s = g_strdup_printf (C_(N_("Server Authorization directory "
- "(daemon/ServAuthDir) is set to %s "
- "but has the wrong permissions: it "
- "should have permissions of %o. "
- "Please correct the permissions or "
- "the GDM configuration and "
- "restart GDM.")),
- auth_path,
- (S_IRWXU|S_IRWXG|S_ISVTX));
- gdm_text_message_dialog (s);
- g_free (s);
- }
-
- gdm_fail (_("%s: Authdir %s has wrong permissions %o. Should be %o. Aborting."),
- "gdm_config_parse",
- auth_path,
- statbuf.st_mode,
- (S_IRWXU|S_IRWXG|S_ISVTX));
- }
-
- g_free (auth_path);
-}
-
-/**
- * gdm_daemon_config_parse
- *
- * Loads initial configuration settings.
- */
-void
-gdm_daemon_config_parse (const char *config_file,
- gboolean no_console)
-{
- uid_t uid;
- gid_t gid;
- GError *error;
- gboolean xdmcp_enabled;
- gboolean dynamic_enabled;
-
- displays = NULL;
- high_display_num = 0;
-
- /* Not NULL if config_file was set by command-line option. */
- if (config_file == NULL) {
- config_file = GDM_DEFAULTS_CONF;
- }
- custom_config_file = g_strdup (GDM_CUSTOM_CONF);
-
- daemon_config = gdm_config_new ();
-
- gdm_config_set_notify_func (daemon_config, notify_cb, NULL);
- gdm_config_set_validate_func (daemon_config, validate_cb, NULL);
-
- gdm_config_add_static_entries (daemon_config, gdm_daemon_config_entries);
-
- gdm_config_set_default_file (daemon_config, config_file);
- gdm_config_set_custom_file (daemon_config, custom_config_file);
-
- /* load the data files */
- error = NULL;
- gdm_config_load (daemon_config, &error);
- if (error != NULL) {
- gdm_error ("Unable to load configuration: %s", error->message);
- g_error_free (error);
- }
-
- /* populate the database with all specified entries */
- gdm_config_process_all (daemon_config, &error);
-
- gdm_daemon_config_load_xservers (daemon_config);
-
- /* Only read the list if no_console is FALSE at this stage */
- if (! no_console) {
- gdm_daemon_config_load_displays (daemon_config);
- }
-
- xdmcp_enabled = FALSE;
- gdm_config_get_bool_for_id (daemon_config, GDM_ID_XDMCP, &xdmcp_enabled);
- 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, no_console);
- }
-
- /* If no displays were found, then obviously
- we're in a no console mode */
- if (displays == NULL) {
- no_console = TRUE;
- }
-
- if (no_console) {
- gdm_config_set_bool_for_id (daemon_config, GDM_ID_CONSOLE_NOTIFY, FALSE);
- }
-
- gdm_daemon_change_user (daemon_config, &uid, &gid);
-
- gdm_daemon_check_permissions (daemon_config, uid, gid);
-
- NEVER_FAILS_root_set_euid_egid (0, 0);
-
- check_logdir ();
-
- GdmUserId = uid;
- GdmGroupId = gid;
-}
-
-/**
- * gdm_daemon_config_get_gdmuid
- * gdm_daemon_config_get_gdmgid
- *
- * Access functions for getting the GDM user ID and group ID.
- */
-uid_t
-gdm_daemon_config_get_gdmuid (void)
-{
- return GdmUserId;
-}
-
-gid_t
-gdm_daemon_config_get_gdmgid (void)
-{
- return GdmGroupId;
-}
-
-/**
- * gdm_daemon_config_get_high_display_num
- * gdm_daemon_config_get_high_display_num
- *
- * Access functions for getting the high display number.
- */
-gint
-gdm_daemon_config_get_high_display_num (void)
-{
- return high_display_num;
-}
-
-void
-gdm_daemon_config_set_high_display_num (gint val)
-{
- high_display_num = val;
-}
-
-/**
- * gdm_is_valid_key
- *
- * Returns TRUE if the key is a valid key, FALSE otherwise.
- */
-gboolean
-gdm_daemon_config_is_valid_key (const char *keystring)
-{
- char *group;
- char *key;
- gboolean ret;
- const GdmConfigEntry *entry;
-
- ret = gdm_common_config_parse_key_string (keystring,
- &group,
- &key,
- NULL,
- NULL);
- if (! ret) {
- goto out;
- }
-
-
- entry = gdm_config_lookup_entry (daemon_config, group, key);
- ret = (entry != NULL);
-
- g_free (group);
- g_free (key);
- out:
- return ret;
-}
-
-/**
- * gdm_signal_terminthup_was_notified
- *
- * returns TRUE if signal SIGTERM, SIGINT, or SIGHUP was received.
- * This just hides these vicious-extensions functions from the
- * other files
- */
-gboolean
-gdm_daemon_config_signal_terminthup_was_notified (void)
-{
- if (ve_signal_was_notified (SIGTERM) ||
- ve_signal_was_notified (SIGINT) ||
- ve_signal_was_notified (SIGHUP)) {
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-/**
- * check_user_file
- * check_global_file
- * is_in_trusted_pic_dir
- * get_facefile_from_gnome2_dir_config
- * path_is_local
- * gdm_daemon_config_get_facefile_from_home
- * gdm_daemon_config_get_facefile_from_global
- *
- * These functions are used for accessing the user's face image from their
- * home directory.
- */
-static gboolean
-check_user_file (const char *path,
- guint uid)
-{
- char *dir;
- char *file;
- gboolean is_ok;
-
- if (path == NULL)
- return FALSE;
-
- if (g_access (path, R_OK) != 0)
- return FALSE;
-
- dir = g_path_get_dirname (path);
- file = g_path_get_basename (path);
-
- is_ok = gdm_file_check ("run_pictures",
- uid,
- dir,
- file,
- TRUE, TRUE,
- gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE),
- gdm_daemon_config_get_value_int (GDM_KEY_RELAX_PERM));
- g_free (dir);
- g_free (file);
-
- return is_ok;
-}
-
-static gboolean
-check_global_file (const char *path,
- guint uid)
-{
- if (path == NULL)
- return FALSE;
-
- if (g_access (path, R_OK) != 0)
- return FALSE;
-
- return TRUE;
-}
-
-/* If path starts with a "trusted" directory, don't sanity check things */
-/* This is really somewhat "outdated" as we now really want things in
- * the picture dir or in ~/.gnome2/photo */
-static gboolean
-is_in_trusted_pic_dir (const char *path)
-{
- /* our own pixmap dir is trusted */
- if (strncmp (path, PIXMAPDIR, sizeof (PIXMAPDIR)) == 0)
- return TRUE;
-
- return FALSE;
-}
-
-static gchar *
-get_facefile_from_gnome2_dir_config (const char *homedir,
- guint uid)
-{
- char *picfile = NULL;
- char *cfgdir;
-
- /* Sanity check on ~user/.gnome2/gdm */
- cfgdir = g_build_filename (homedir, ".gnome2", "gdm", NULL);
- if (G_LIKELY (check_user_file (cfgdir, uid))) {
- GKeyFile *cfg;
- char *cfgfile;
-
- cfgfile = g_build_filename (homedir, ".gnome2", "gdm", NULL);
- cfg = gdm_common_config_load (cfgfile, NULL);
- g_free (cfgfile);
-
- if (cfg != NULL) {
- gdm_common_config_get_string (cfg, "face/picture=", &picfile, NULL);
- g_key_file_free (cfg);
- }
-
- /* must exist and be absolute (note that this check
- * catches empty strings)*/
- /* Note that these days we just set ~/.face */
- if G_UNLIKELY (picfile != NULL &&
- (picfile[0] != '/' ||
- /* this catches readability by user */
- g_access (picfile, R_OK) != 0)) {
- g_free (picfile);
- picfile = NULL;
- }
-
- if (picfile != NULL) {
- char buf[PATH_MAX];
- if (realpath (picfile, buf) == NULL) {
- g_free (picfile);
- picfile = NULL;
- } else {
- g_free (picfile);
- picfile = g_strdup (buf);
- }
- }
-
- if G_UNLIKELY (picfile != NULL) {
- if (! is_in_trusted_pic_dir (picfile)) {
- /* if not in trusted dir, check it out */
-
- /* Note that strict permissions checking is done
- * on this file. Even if it may not even be owned by the
- * user. This setting should ONLY point to pics in trusted
- * dirs. */
- if (! check_user_file (picfile, uid)) {
- g_free (picfile);
- picfile = NULL;
- }
- }
- }
- }
- g_free (cfgdir);
-
- return picfile;
-}
-
-static GHashTable *fstype_hash = NULL;
-extern char *filesystem_type (char *path, char *relpath, struct stat *statp);
-
-static gboolean
-path_is_local (const char *path)
-{
- gpointer local = NULL;
-
- if (path == NULL)
- return FALSE;
-
- if (fstype_hash == NULL)
- fstype_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- else
- local = g_hash_table_lookup (fstype_hash, path);
-
- if (local == NULL) {
- struct stat statbuf;
-
- if (g_stat (path, &statbuf) == 0) {
- char *type = filesystem_type ((char *)path, (char *)path, &statbuf);
- gboolean is_local = ((strcmp (ve_sure_string (type), "nfs") != 0) &&
- (strcmp (ve_sure_string (type), "afs") != 0) &&
- (strcmp (ve_sure_string (type), "autofs") != 0) &&
- (strcmp (ve_sure_string (type), "unknown") != 0) &&
- (strcmp (ve_sure_string (type), "ncpfs") != 0));
- local = GINT_TO_POINTER (is_local ? 1 : -1);
- g_hash_table_insert (fstype_hash, g_strdup (path), local);
- }
- }
-
- return GPOINTER_TO_INT (local) > 0;
-}
-
-gchar *
-gdm_daemon_config_get_facefile_from_home (const char *homedir,
- guint uid)
-{
- char *picfile = NULL;
- char *path;
- gboolean is_local;
-
- /* special case: look at parent of home to detect autofs
- this is so we don't try to trigger an automount */
- path = g_path_get_dirname (homedir);
- is_local = path_is_local (path);
- g_free (path);
-
- /* now check that home dir itself is local */
- if (is_local) {
- is_local = path_is_local (homedir);
- }
-
- /* Only look at local home directories so we don't try to
- read from remote (e.g. NFS) volumes */
- if (! is_local)
- return NULL;
-
- picfile = g_build_filename (homedir, ".face", NULL);
-
- if (check_user_file (picfile, uid))
- return picfile;
- else {
- g_free (picfile);
- picfile = NULL;
- }
-
- picfile = g_build_filename (homedir, ".face.icon", NULL);
-
- if (check_user_file (picfile, uid))
- return picfile;
- else {
- g_free (picfile);
- picfile = NULL;
- }
-
- picfile = get_facefile_from_gnome2_dir_config (homedir, uid);
- if (check_user_file (picfile, uid))
- return picfile;
- else {
- g_free (picfile);
- picfile = NULL;
- }
-
- /* Nothing found yet, try the old locations */
-
- picfile = g_build_filename (homedir, ".gnome2", "photo", NULL);
- if (check_user_file (picfile, uid))
- return picfile;
- else {
- g_free (picfile);
- picfile = NULL;
- }
-
- picfile = g_build_filename (homedir, ".gnome", "photo", NULL);
- if (check_user_file (picfile, uid))
- return picfile;
- else {
- g_free (picfile);
- picfile = NULL;
- }
-
- return NULL;
-}
-
-gchar *
-gdm_daemon_config_get_facefile_from_global (const char *username,
- guint uid)
-{
- char *picfile = NULL;
- const char *facedir;
-
- facedir = gdm_daemon_config_get_value_string (GDM_KEY_GLOBAL_FACE_DIR);
-
- /* Try the global face directory */
-
- picfile = g_build_filename (facedir, username, NULL);
-
- if (check_global_file (picfile, uid))
- return picfile;
-
- g_free (picfile);
- picfile = gdm_make_filename (facedir, username, ".png");
-
- if (check_global_file (picfile, uid))
- return picfile;
-
- g_free (picfile);
- return NULL;
-}
-
-static gboolean
-is_prog_in_path (const char *prog)
-{
- char *f;
- gboolean ret;
-
- f = g_find_program_in_path (prog);
- ret = (f != NULL);
- g_free (f);
- return ret;
-}
-
-/**
- * gdm_daemon_config_get_session_exec
- *
- * This function accesses the GDM session desktop file and returns
- * the execution command for starting the session.
- *
- * Must be called with the PATH set correctly to find session exec.
- */
-char *
-gdm_daemon_config_get_session_exec (const char *session_name,
- gboolean check_try_exec)
-{
- char *session_filename;
- const char *path_str;
- char **search_dirs;
- GKeyFile *cfg;
- static char *exec;
- static char *cached = NULL;
- gboolean hidden;
- char *ret;
-
- cfg = NULL;
-
- /* clear cache */
- if (session_name == NULL) {
- g_free (exec);
- exec = NULL;
- g_free (cached);
- cached = NULL;
- return NULL;
- }
-
- if (cached != NULL && strcmp (ve_sure_string (session_name), ve_sure_string (cached)) == 0)
- return g_strdup (exec);
-
- g_free (exec);
- exec = NULL;
- g_free (cached);
- cached = g_strdup (session_name);
-
- /* Some ugly special casing for legacy "Default.desktop", oh well,
- * we changed to "default.desktop" */
- if (g_ascii_strcasecmp (session_name, "default") == 0 ||
- g_ascii_strcasecmp (session_name, "default.desktop") == 0) {
- session_filename = g_strdup ("default.desktop");
- } else {
- session_filename = gdm_ensure_extension (session_name, ".desktop");
- }
-
- path_str = gdm_daemon_config_get_value_string (GDM_KEY_SESSION_DESKTOP_DIR);
- if (path_str == NULL) {
- gdm_error ("No session desktop directories defined");
- goto out;
- }
-
- search_dirs = g_strsplit (path_str, ":", -1);
-
- cfg = gdm_common_config_load_from_dirs (session_filename,
- (const char **)search_dirs,
- NULL);
- g_strfreev (search_dirs);
-
- if (cfg == NULL) {
- if (gdm_is_session_magic (session_name)) {
- exec = g_strdup (session_name);
- } else {
- g_free (exec);
- exec = NULL;
- }
- goto out;
- }
-
- hidden = FALSE;
- gdm_common_config_get_boolean (cfg, "Desktop Entry/Hidden=false", &hidden, NULL);
- if (hidden) {
- g_free (exec);
- exec = NULL;
- goto out;
- }
-
- if (check_try_exec) {
- char *tryexec;
-
- tryexec = NULL;
- gdm_common_config_get_string (cfg, "Desktop Entry/TryExec", &tryexec, NULL);
-
- if (tryexec != NULL &&
- tryexec[0] != '\0' &&
- ! is_prog_in_path (tryexec)) {
- g_free (tryexec);
- g_free (exec);
- exec = NULL;
- goto out;
- }
- g_free (tryexec);
- }
-
- exec = NULL;
- gdm_common_config_get_string (cfg, "Desktop Entry/Exec", &exec, NULL);
-
- out:
-
- ret = g_strdup (exec);
-
- g_key_file_free (cfg);
-
- return ret;
-}
-
-/**
- * gdm_daemon_config_get_session_xserver_args
- *
- * This function accesses the GDM session desktop file and returns
- * additional Xserver arguments to be used with this session
- */
-char *
-gdm_daemon_config_get_session_xserver_args (const char *session_name)
-{
- char *session_filename;
- const char *path_str;
- char **search_dirs;
- GKeyFile *cfg;
- static char *xserver_args;
- static char *cached = NULL;
- gboolean hidden;
- char *ret;
-
- cfg = NULL;
-
- /* clear cache */
- if (session_name == NULL) {
- g_free (xserver_args);
- xserver_args = NULL;
- g_free (cached);
- cached = NULL;
- return NULL;
- }
-
- if (cached != NULL && strcmp (ve_sure_string (session_name), ve_sure_string (cached)) == 0)
- return g_strdup (xserver_args);
-
- g_free (xserver_args);
- xserver_args = NULL;
- g_free (cached);
- cached = g_strdup (session_name);
-
- /* Some ugly special casing for legacy "Default.desktop", oh well,
- * we changed to "default.desktop" */
- if (g_ascii_strcasecmp (session_name, "default") == 0 ||
- g_ascii_strcasecmp (session_name, "default.desktop") == 0) {
- session_filename = g_strdup ("default.desktop");
- } else {
- session_filename = gdm_ensure_extension (session_name, ".desktop");
- }
-
- path_str = gdm_daemon_config_get_value_string (GDM_KEY_SESSION_DESKTOP_DIR);
- if (path_str == NULL) {
- gdm_error ("No session desktop directories defined");
- goto out;
- }
-
- search_dirs = g_strsplit (path_str, ":", -1);
-
- cfg = gdm_common_config_load_from_dirs (session_filename,
- (const char **)search_dirs,
- NULL);
- g_strfreev (search_dirs);
-
- xserver_args = NULL;
- gdm_common_config_get_string (cfg, "Desktop Entry/X-Gdm-XserverArgs", &xserver_args, NULL);
-
- out:
-
- ret = g_strdup (xserver_args);
-
- g_key_file_free (cfg);
-
- return ret;
-}
-
-/**
- * gdm_daemon_config_get_user_session_lang
- *
- * These functions get and set the user's language and setting in their
- * $HOME/.dmrc file.
- */
-void
-gdm_daemon_config_set_user_session_lang (gboolean savesess,
- gboolean savelang,
- const char *home_dir,
- const char *save_session,
- const char *save_language)
-{
- GKeyFile *dmrc;
- gchar *cfgstr;
-
- cfgstr = g_build_filename (home_dir, ".dmrc", NULL);
-
- dmrc = gdm_common_config_load (cfgstr, NULL);
- if (dmrc == NULL) {
- return;
- }
-
- if (savesess) {
- g_key_file_set_string (dmrc, "Desktop", "Session", ve_sure_string (save_session));
- }
-
- if (savelang) {
- if (ve_string_empty (save_language)) {
- /* we chose the system default language so wipe the
- * lang key */
- g_key_file_remove_key (dmrc, "Desktop", "Language", NULL);
- } else {
- g_key_file_set_string (dmrc, "Desktop", "Language", save_language);
- }
- }
-
- if (dmrc != NULL) {
- mode_t oldmode;
- oldmode = umask (077);
- gdm_common_config_save (dmrc, cfgstr, NULL);
- umask (oldmode);
- }
-
- g_free (cfgstr);
- g_key_file_free (dmrc);
-}
-
-void
-gdm_daemon_config_get_user_session_lang (char **usrsess,
- char **usrlang,
- const char *home_dir,
- gboolean *savesess)
-{
- char *p;
- char *cfgfile;
- GKeyFile *cfg;
- char *session;
- char *lang;
- gboolean save;
-
- cfgfile = g_build_filename (home_dir, ".dmrc", NULL);
- cfg = gdm_common_config_load (cfgfile, NULL);
- g_free (cfgfile);
-
- save = FALSE;
- session = NULL;
-
- gdm_common_config_get_string (cfg, "Desktop/Session", &session, NULL);
- if (session == NULL) {
- session = g_strdup ("");
- }
-
- /* this is just being truly anal about what users give us, and in case
- * it looks like they may have included a path whack it. */
- p = strrchr (session, '/');
- if (p != NULL) {
- char *tmp = g_strdup (p + 1);
- g_free (session);
- session = tmp;
- }
-
- /* ugly workaround for migration */
- if (strcmp (session, "Default") == 0 ||
- strcmp (session, "Default.desktop") == 0) {
- g_free (session);
- session = g_strdup ("default");
- save = TRUE;
- }
-
- gdm_common_config_get_string (cfg, "Desktop/Language", &lang, NULL);
- if (lang == NULL) {
- lang = g_strdup ("");
- }
-
- if (usrsess != NULL) {
- *usrsess = g_strdup (session);
- }
- g_free (session);
-
- if (savesess != NULL) {
- *savesess = save;
- }
-
- if (usrlang != NULL) {
- *usrlang = g_strdup (lang);
- }
- g_free (lang);
-
- g_key_file_free (cfg);
-}
diff --git a/daemon/gdm-daemon-config.h b/daemon/gdm-daemon-config.h
deleted file mode 100644
index 7c4f3767..00000000
--- a/daemon/gdm-daemon-config.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- * Copyright (C) 2005 Brian Cameron <brian.cameron@sun.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _GDM_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 char *id);
-char * 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 */
-char * gdm_daemon_config_get_display_custom_config_file (const char *display);
-char * gdm_daemon_config_get_custom_config_file (void);
-
-
-const char * gdm_daemon_config_get_value_string (const char *key);
-const char ** gdm_daemon_config_get_value_string_array (const char *key);
-gboolean gdm_daemon_config_get_value_bool (const char *key);
-gint gdm_daemon_config_get_value_int (const char *key);
-char * gdm_daemon_config_get_value_string_per_display (const char *key,
- const char *display);
-gboolean gdm_daemon_config_get_value_bool_per_display (const char *key,
- const char *display);
-gint gdm_daemon_config_get_value_int_per_display (const char *key,
- const char *display);
-
-void gdm_daemon_config_set_value_string (const char *key,
- const char *value);
-void gdm_daemon_config_set_value_bool (const char *key,
- gboolean value);
-void gdm_daemon_config_set_value_int (const char *key,
- gint value);
-
-
-gboolean gdm_daemon_config_key_to_string_per_display (const char *display,
- const char *key,
- char **retval);
-gboolean gdm_daemon_config_key_to_string (const char *file,
- const char *key,
- char **retval);
-gboolean gdm_daemon_config_to_string (const char *key,
- const char *display,
- char **retval);
-gboolean gdm_daemon_config_update_key (const char *key);
-
-
-int gdm_daemon_config_compare_displays (gconstpointer a,
- gconstpointer b);
-gboolean gdm_daemon_config_is_valid_key (const char *key);
-gboolean gdm_daemon_config_signal_terminthup_was_notified (void);
-
-char * gdm_daemon_config_get_facefile_from_home (const char *homedir,
- guint uid);
-char * gdm_daemon_config_get_facefile_from_global (const char *username,
- guint uid);
-void gdm_daemon_config_get_user_session_lang (char **usrsess,
- char **usrlang,
- const char *homedir,
- gboolean *savesess);
-void gdm_daemon_config_set_user_session_lang (gboolean savesess,
- gboolean savelang,
- const char *home_dir,
- const char *save_session,
- const char *save_language);
-char * gdm_daemon_config_get_session_exec (const char *session_name,
- gboolean check_try_exec);
-char * gdm_daemon_config_get_session_xserver_args (const char *session_name);
-
-
-G_END_DECLS
-
-#endif /* _GDM_DAEMON_CONFIG_H */
diff --git a/daemon/gdm-net.c b/daemon/gdm-net.c
deleted file mode 100644
index 93a48dbe..00000000
--- a/daemon/gdm-net.c
+++ /dev/null
@@ -1,682 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "config.h"
-
-#include <strings.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/un.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include <glib/gi18n.h>
-
-#include "gdm.h"
-#include "misc.h"
-#include "gdm-net.h"
-
-#include "gdm-common.h"
-#include "gdm-log.h"
-#include "gdm-daemon-config.h"
-
-/*
- * Kind of a weird setup, new connections whack old connections.
- *
- * We may want to allow tuning of the max connections, since
- * this number means that only a certain number of slaves can
- * talk to the daemon at once. Note that since new connections
- * whack old connections, this tends to cause traffic problems
- * if the daemon is really being hammered.
- *
- * This is because the slaves retry a failed connection 5 times,
- * though they are at least smart enough to sleep 1 second
- * between retries if the connection failed on the connect()
- * call. But, this means that throwing off a connection causes
- * that slave to come back in another second and try to
- * connect again. So if the daemon is really being hammered,
- * this just causes more traffic problems. It's really faster
- * to let each connection finish.
- *
- * This may cause problems for some setups (perhaps terminal
- * servers) where lots of connections may hit the server at once
- * and 15 connections may not be enough (especially since the
- * console login screen may also be using one of them). Perhaps
- * this number should be in configuration file so it can be
- * tuned by the end user?
- *
- * If, when you turn on debug, you notice messages like this
- * in the log, "Closing connection, x subconnections reached"
- * and some slaves are not working properly, then bumping this
- * number up is probably a reasonable fix if you can't simply
- * reduce the socket load the daemon must handle.
- */
-#define MAX_CONNECTIONS 15
-
-struct _GdmConnection {
- int fd;
- guint source;
- gboolean writable;
-
- GString *buffer;
-
- int message_count;
-
- gboolean nonblock;
-
- int close_level; /* 0 - normal
- 1 - no close, when called raise to 2
- 2 - close was requested */
-
- char *filename; /* unix socket or fifo filename */
-
- guint32 user_flags;
-
- GdmConnectionHandler handler;
- gpointer data;
- GDestroyNotify destroy_notify;
-
- gpointer close_data;
- GDestroyNotify close_notify;
-
- GdmConnection *parent;
-
- GList *subconnections;
- int n_subconnections;
-
- GdmDisplay *disp;
-};
-
-int
-gdm_connection_is_server_busy (GdmConnection *conn) {
- int max_connections = MAX_CONNECTIONS;
-
- if (conn->n_subconnections >= (max_connections / 2)) {
- gdm_debug ("Connections is %d, max is %d, busy TRUE",
- conn->n_subconnections, max_connections);
- return TRUE;
- } else {
- gdm_debug ("Connections is %d, max is %d, busy FALSE",
- conn->n_subconnections, max_connections);
- return FALSE;
- }
-}
-
-static gboolean
-close_if_needed (GdmConnection *conn, GIOCondition cond, gboolean error)
-{
- /* non-subconnections are never closed */
- if (conn->parent == NULL)
- return TRUE;
-
- if (cond & G_IO_ERR ||
- cond & G_IO_HUP || error) {
- if (cond & G_IO_ERR)
- gdm_debug ("close_if_needed: Got G_IO_ERR on %d", conn->fd);
- if (cond & G_IO_HUP)
- gdm_debug ("close_if_needed: Got G_IO_HUP on %d", conn->fd);
- if (error)
- gdm_debug ("close_if_needed: Got error on %d", conn->fd);
- conn->source = 0;
- gdm_connection_close (conn);
- return FALSE;
- }
- return TRUE;
-}
-
-static gboolean
-gdm_connection_handler (GIOChannel *source,
- GIOCondition cond,
- gpointer data)
-{
- GdmConnection *conn = data;
- char buf[PIPE_SIZE];
- char *p;
- size_t len;
-
- if ( ! (cond & G_IO_IN))
- return close_if_needed (conn, cond, FALSE);
-
- VE_IGNORE_EINTR (len = read (conn->fd, buf, sizeof (buf) -1));
- if (len <= 0)
- return close_if_needed (conn, cond, TRUE);
-
- buf[len] = '\0';
-
- if (conn->buffer == NULL)
- conn->buffer = g_string_new (NULL);
-
- for (p = buf; *p != '\0'; p++) {
- if (*p == '\r' ||
- (*p == '\n' &&
- ve_string_empty (conn->buffer->str)))
- /*ignore \r or empty lines*/
- continue;
- if (*p == '\n' ||
- /* cut lines short at 4096 to prevent DoS attacks */
- conn->buffer->len > 4096) {
- conn->close_level = 1;
- conn->message_count++;
- conn->handler (conn, conn->buffer->str,
- conn->data);
- if (conn->close_level == 2) {
- conn->close_level = 0;
- conn->source = 0;
- gdm_connection_close (conn);
- return FALSE;
- }
- conn->close_level = 0;
- g_string_truncate (conn->buffer, 0);
- } else {
- g_string_append_c (conn->buffer, *p);
- }
- }
-
- return close_if_needed (conn, cond, FALSE);
-}
-
-gboolean
-gdm_connection_is_writable (GdmConnection *conn)
-{
- g_return_val_if_fail (conn != NULL, FALSE);
-
- return conn->writable;
-}
-
-gboolean
-gdm_connection_write (GdmConnection *conn, const char *str)
-{
- int ret;
- int save_errno;
- int flags = 0;
-#ifndef MSG_NOSIGNAL
- void (*old_handler)(int);
-#endif
-
- g_return_val_if_fail (conn != NULL, FALSE);
- g_return_val_if_fail (str != NULL, FALSE);
-
- if G_UNLIKELY ( ! conn->writable)
- return FALSE;
-
-#ifdef MSG_DONTWAIT
- if (conn->nonblock)
- flags |= MSG_DONTWAIT;
-#endif
-
-#ifdef MSG_NOSIGNAL
- VE_IGNORE_EINTR (ret = send (conn->fd, str, strlen (str), MSG_NOSIGNAL | flags));
- save_errno = errno;
-#else
- old_handler = signal (SIGPIPE, SIG_IGN);
- VE_IGNORE_EINTR (ret = send (conn->fd, str, strlen (str), flags));
- save_errno = errno;
- signal (SIGPIPE, old_handler);
-#endif
-
- /* just so that 'signal' doesn't whack it */
- errno = save_errno;
-
- if G_UNLIKELY (ret < 0)
- return FALSE;
- else
- return TRUE;
-}
-
-static gboolean
-gdm_socket_handler (GIOChannel *source,
- GIOCondition cond,
- gpointer data)
-{
- GIOChannel *unixchan;
- GdmConnection *conn = data;
- GdmConnection *newconn;
- struct sockaddr_un addr;
- socklen_t addr_size = sizeof (addr);
- int fd;
- int max_connections;
-
- if ( ! (cond & G_IO_IN))
- return TRUE;
-
- VE_IGNORE_EINTR (fd = accept (conn->fd,
- (struct sockaddr *)&addr,
- &addr_size));
- if G_UNLIKELY (fd < 0) {
- gdm_debug ("gdm_socket_handler: Rejecting connection");
- return TRUE;
- }
-
- gdm_debug ("gdm_socket_handler: Accepting new connection fd %d", fd);
-
- newconn = g_new0 (GdmConnection, 1);
- newconn->disp = NULL;
- newconn->message_count = 0;
- newconn->nonblock = conn->nonblock;
- newconn->close_level = 0;
- newconn->fd = fd;
- newconn->writable = TRUE;
- newconn->filename = NULL;
- newconn->user_flags = 0;
- newconn->buffer = NULL;
- newconn->parent = conn;
- newconn->subconnections = NULL;
- newconn->n_subconnections = 0;
- newconn->handler = conn->handler;
- newconn->data = conn->data;
- newconn->destroy_notify = NULL; /* the data belongs to
- parent connection */
-
- conn->subconnections = g_list_append (conn->subconnections, newconn);
- conn->n_subconnections++;
-
- /*
- * When dynamix servers is turned on, the daemon can be flooded with
- * requests and closing a subconnection will typically make the client
- * just try and connect again, and worsen the flooding problem. When
- * using dynamic servers, allow more clients to connect at once.
- */
- max_connections = MAX_CONNECTIONS;
-
- if (conn->n_subconnections > max_connections) {
- GdmConnection *old;
- gdm_debug ("Closing connection, %d subconnections reached",
- max_connections);
- old = conn->subconnections->data;
- conn->subconnections =
- g_list_remove (conn->subconnections, old);
- gdm_connection_close (old);
- }
-
- unixchan = g_io_channel_unix_new (newconn->fd);
- g_io_channel_set_encoding (unixchan, NULL, NULL);
- g_io_channel_set_buffered (unixchan, FALSE);
-
- newconn->source = g_io_add_watch_full
- (unixchan, G_PRIORITY_DEFAULT,
- G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
- gdm_connection_handler, newconn, NULL);
- g_io_channel_unref (unixchan);
-
- return TRUE;
-}
-
-GdmConnection *
-gdm_connection_open_unix (const char *sockname, mode_t mode)
-{
- GIOChannel *unixchan;
- GdmConnection *conn;
- struct sockaddr_un addr;
- int fd;
- int try_again_attempts = 1000;
-
- fd = socket (AF_UNIX, SOCK_STREAM, 0);
- if G_UNLIKELY (fd < 0) {
- gdm_error (_("%s: Could not make socket"),
- "gdm_connection_open_unix");
- return NULL;
- }
-
-try_again:
- /* this is all for creating sockets in /tmp/ safely */
- VE_IGNORE_EINTR (g_unlink (sockname));
- if G_UNLIKELY (errno == EISDIR ||
- errno == EPERM) {
- /* likely a directory, someone's playing tricks on us */
- char *newname = NULL;
- do {
- g_free (newname);
- newname = g_strdup_printf ("%s-renamed-%u",
- sockname,
- (guint)g_random_int ());
- } while (g_access (newname, F_OK) == 0);
- VE_IGNORE_EINTR (g_rename (sockname, newname));
- if G_UNLIKELY (errno != 0)
- try_again_attempts = 0;
- g_free (newname);
- } else if G_UNLIKELY (errno != 0) {
- try_again_attempts = 0;
- }
-
- memset (&addr, 0, sizeof (addr));
- strcpy (addr.sun_path, sockname);
- addr.sun_family = AF_UNIX;
- if G_UNLIKELY (bind (fd,
- (struct sockaddr *) &addr, sizeof (addr)) < 0) {
- gdm_error (_("%s: Could not bind socket"),
- "gdm_connection_open_unix");
- try_again_attempts --;
- /* someone is being evil on us */
- if (errno == EADDRINUSE && try_again_attempts >= 0)
- goto try_again;
- VE_IGNORE_EINTR (close (fd));
- return NULL;
- }
-
- VE_IGNORE_EINTR (g_chmod (sockname, mode));
-
- conn = g_new0 (GdmConnection, 1);
- conn->disp = NULL;
- conn->message_count = 0;
- conn->nonblock = FALSE;
- conn->close_level = 0;
- conn->fd = fd;
- conn->writable = FALSE;
- conn->buffer = NULL;
- conn->filename = g_strdup (sockname);
- conn->user_flags = 0;
- conn->parent = NULL;
- conn->subconnections = NULL;
- conn->n_subconnections = 0;
-
- unixchan = g_io_channel_unix_new (conn->fd);
- g_io_channel_set_encoding (unixchan, NULL, NULL);
- g_io_channel_set_buffered (unixchan, FALSE);
-
- conn->source = g_io_add_watch_full
- (unixchan, G_PRIORITY_DEFAULT,
- G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
- gdm_socket_handler, conn, NULL);
- g_io_channel_unref (unixchan);
-
- listen (fd, 5);
-
- return conn;
-}
-
-GdmConnection *
-gdm_connection_open_fd (int fd)
-{
- GIOChannel *unixchan;
- GdmConnection *conn;
-
- g_return_val_if_fail (fd >= 0, NULL);
-
- conn = g_new0 (GdmConnection, 1);
- conn->disp = NULL;
- conn->message_count = 0;
- conn->nonblock = FALSE;
- conn->close_level = 0;
- conn->fd = fd;
- conn->writable = FALSE;
- conn->buffer = NULL;
- conn->filename = NULL;
- conn->user_flags = 0;
- conn->parent = NULL;
- conn->subconnections = NULL;
- conn->n_subconnections = 0;
-
- unixchan = g_io_channel_unix_new (conn->fd);
- g_io_channel_set_encoding (unixchan, NULL, NULL);
- g_io_channel_set_buffered (unixchan, FALSE);
-
- conn->source = g_io_add_watch_full
- (unixchan, G_PRIORITY_DEFAULT,
- G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
- gdm_connection_handler, conn, NULL);
- g_io_channel_unref (unixchan);
-
- return conn;
-}
-
-GdmConnection *
-gdm_connection_open_fifo (const char *fifo, mode_t mode)
-{
- GIOChannel *fifochan;
- GdmConnection *conn;
- int fd;
-
- VE_IGNORE_EINTR (g_unlink (fifo));
-
- if G_UNLIKELY (mkfifo (fifo, 0660) < 0) {
- gdm_error (_("%s: Could not make FIFO"),
- "gdm_connection_open_fifo");
- return NULL;
- }
-
- fd = open (fifo, O_RDWR); /* Open with write to avoid EOF */
-
- if G_UNLIKELY (fd < 0) {
- gdm_error (_("%s: Could not open FIFO"),
- "gdm_connection_open_fifo");
- return NULL;
- }
-
- VE_IGNORE_EINTR (g_chmod (fifo, mode));
-
- conn = g_new0 (GdmConnection, 1);
- conn->disp = NULL;
- conn->message_count = 0;
- conn->nonblock = FALSE;
- conn->close_level = 0;
- conn->fd = fd;
- conn->writable = FALSE;
- conn->buffer = NULL;
- conn->filename = g_strdup (fifo);
- conn->user_flags = 0;
- conn->parent = NULL;
- conn->subconnections = NULL;
- conn->n_subconnections = 0;
-
- fifochan = g_io_channel_unix_new (conn->fd);
- g_io_channel_set_encoding (fifochan, NULL, NULL);
- g_io_channel_set_buffered (fifochan, FALSE);
-
- conn->source = g_io_add_watch_full
- (fifochan, G_PRIORITY_DEFAULT,
- G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
- gdm_connection_handler, conn, NULL);
- g_io_channel_unref (fifochan);
-
- return conn;
-}
-
-void
-gdm_connection_set_handler (GdmConnection *conn,
- GdmConnectionHandler handler,
- gpointer data,
- GDestroyNotify destroy_notify)
-{
- g_return_if_fail (conn != NULL);
-
- if (conn->destroy_notify != NULL)
- conn->destroy_notify (conn->data);
-
- conn->handler = handler;
- conn->data = data;
- conn->destroy_notify = destroy_notify;
-}
-
-guint32
-gdm_connection_get_user_flags (GdmConnection *conn)
-{
- g_return_val_if_fail (conn != NULL, 0);
-
- return conn->user_flags;
-}
-
-void
-gdm_connection_set_user_flags (GdmConnection *conn,
- guint32 flags)
-{
- g_return_if_fail (conn != NULL);
-
- conn->user_flags = flags;
-}
-
-void
-gdm_connection_close (GdmConnection *conn)
-{
- GList *list;
-
- g_return_if_fail (conn != NULL);
-
- if (conn->close_level > 0) {
- /* flag that close was requested */
- conn->close_level = 2;
- return;
- }
-
- if (conn->close_notify != NULL) {
- conn->close_notify (conn->close_data);
- conn->close_notify = NULL;
- }
- conn->close_data = NULL;
-
- if (conn->buffer != NULL) {
- g_string_free (conn->buffer, TRUE);
- conn->buffer = NULL;
- }
-
- if (conn->parent != NULL) {
- conn->parent->subconnections =
- g_list_remove (conn->parent->subconnections, conn);
- /* This is evil a bit, but safe, whereas -- would not be */
- conn->parent->n_subconnections =
- g_list_length (conn->parent->subconnections);
- conn->parent = NULL;
- }
-
- list = conn->subconnections;
- conn->subconnections = NULL;
- g_list_foreach (list, (GFunc) gdm_connection_close, NULL);
- g_list_free (list);
-
- if (conn->destroy_notify != NULL) {
- conn->destroy_notify (conn->data);
- conn->destroy_notify = NULL;
- }
- conn->data = NULL;
-
- if (conn->source > 0) {
- g_source_remove (conn->source);
- conn->source = 0;
- }
-
- if (conn->fd > 0) {
- VE_IGNORE_EINTR (close (conn->fd));
- conn->fd = -1;
- }
-
- g_free (conn->filename);
- conn->filename = NULL;
-
- g_free (conn);
-}
-
-void
-gdm_connection_set_close_notify (GdmConnection *conn,
- gpointer close_data,
- GDestroyNotify close_notify)
-{
- g_return_if_fail (conn != NULL);
-
- if (conn->close_notify != NULL)
- conn->close_notify (conn->close_data);
-
- conn->close_data = close_data;
- conn->close_notify = close_notify;
-}
-
-gboolean
-gdm_connection_printf (GdmConnection *conn, const gchar *format, ...)
-{
- va_list args;
- gboolean ret;
- gchar *s;
-
- va_start (args, format);
- s = g_strdup_vprintf (format, args);
- va_end (args);
-
- ret = gdm_connection_write (conn, s);
-
- g_free (s);
-
- return ret;
-}
-
-int
-gdm_connection_get_message_count (GdmConnection *conn)
-{
- g_return_val_if_fail (conn != NULL, -1);
- return conn->message_count;
-}
-
-gboolean
-gdm_connection_get_nonblock (GdmConnection *conn)
-{
- g_return_val_if_fail (conn != NULL, FALSE);
- return conn->nonblock;
-}
-
-void
-gdm_connection_set_nonblock (GdmConnection *conn,
- gboolean nonblock)
-{
- g_return_if_fail (conn != NULL);
- conn->nonblock = nonblock;
-}
-
-GdmDisplay *
-gdm_connection_get_display (GdmConnection *conn)
-{
- g_return_val_if_fail (conn != NULL, NULL);
- return conn->disp;
-}
-
-void
-gdm_connection_set_display (GdmConnection *conn,
- GdmDisplay *disp)
-{
- g_return_if_fail (conn != NULL);
- conn->disp = disp;
-}
-
-void
-gdm_kill_subconnections_with_display (GdmConnection *conn,
- GdmDisplay *disp)
-{
- GList *subs;
-
- g_return_if_fail (conn != NULL);
- g_return_if_fail (disp != NULL);
-
- subs = conn->subconnections;
- while (subs != NULL) {
- GdmConnection *subcon = subs->data;
- if (subcon->disp == disp) {
- subcon->disp = NULL;
- conn->subconnections =
- g_list_remove (conn->subconnections, subcon);
- gdm_connection_close (subcon);
- subs = conn->subconnections;
- } else {
- subs = subs->next;
- }
- }
-}
-
-/* EOF */
diff --git a/daemon/gdm-net.h b/daemon/gdm-net.h
deleted file mode 100644
index 901c9762..00000000
--- a/daemon/gdm-net.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef GDM_NET_H
-#define GDM_NET_H
-
-#include <glib.h>
-
-typedef struct _GdmConnection GdmConnection;
-
-#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,
- const char *str,
- gpointer data);
-
-gboolean gdm_connection_is_writable (GdmConnection *conn);
-gboolean gdm_connection_write (GdmConnection *conn,
- const char *str);
-gboolean gdm_connection_printf (GdmConnection *conn,
- const gchar *format, ...)
- G_GNUC_PRINTF (2, 3);
-
-GdmConnection * gdm_connection_open_unix (const char *sockname,
- mode_t mode);
-GdmConnection * gdm_connection_open_fd (int fd);
-GdmConnection * gdm_connection_open_fifo (const char *fifo,
- mode_t mode);
-
-void gdm_connection_set_close_notify (GdmConnection *conn,
- gpointer close_data,
- GDestroyNotify close_notify);
-
-void gdm_connection_set_handler (GdmConnection *conn,
- GdmConnectionHandler handler,
- gpointer data,
- GDestroyNotify destroy_notify);
-
-gboolean gdm_connection_get_nonblock (GdmConnection *conn);
-void gdm_connection_set_nonblock (GdmConnection *conn,
- gboolean nonblock);
-
-guint32 gdm_connection_get_user_flags (GdmConnection *conn);
-void gdm_connection_set_user_flags (GdmConnection *conn,
- guint32 flags);
-#define GDM_CONNECTION_SET_USER_FLAG(conn,flag) { \
- guint32 _flags = gdm_connection_get_user_flags (conn); \
- _flags |= flag; \
- gdm_connection_set_user_flags (conn, _flags); \
- }
-#define GDM_CONNECTION_UNSET_USER_FLAG(conn,flag) { \
- guint32 _flags = gdm_connection_get_user_flags (conn); \
- _flags &= ~flag; \
- gdm_connection_set_user_flags (conn, _flags); \
- }
-
-GdmDisplay * gdm_connection_get_display (GdmConnection *conn);
-void gdm_connection_set_display (GdmConnection *conn,
- GdmDisplay *disp);
-int gdm_connection_is_server_busy (GdmConnection *conn);
-void gdm_kill_subconnections_with_display (GdmConnection *conn,
- GdmDisplay *disp);
-
-int gdm_connection_get_message_count (GdmConnection *conn);
-
-
-void gdm_connection_close (GdmConnection *conn);
-
-#endif /* GDM_NET_H */
-
-/* EOF */
diff --git a/daemon/gdm-socket-protocol.h b/daemon/gdm-socket-protocol.h
deleted file mode 100644
index e6cff546..00000000
--- a/daemon/gdm-socket-protocol.h
+++ /dev/null
@@ -1,247 +0,0 @@
-/* -*- 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
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _GDM_SOCKET_PROTOCOL_H
-#define _GDM_SOCKET_PROTOCOL_H
-
-#include <glib.h>
-
-#define STX 0x2 /* Start of txt */
-#define BEL 0x7 /* Bell, used to interrupt login for
- * say timed login or something similar */
-
-/*
- * 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 "/:"
-
-
-/*
- * 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 "/var/run/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.
- *
- * For a descriptions of the commands see:
- * http://www.gnome.org/projects/gdm/docs/2.18/controlling.htlm
- *
- */
-/* The user protocol, using /tmp/.gdm_socket */
-
-
-#define GDM_SUP_VERSION "VERSION"
-#define GDM_SUP_AUTH_LOCAL "AUTH_LOCAL"
-#define GDM_SUP_FLEXI_XSERVER "FLEXI_XSERVER"
-#define GDM_SUP_FLEXI_XSERVER_USER "FLEXI_XSERVER_USER"
-#define GDM_SUP_FLEXI_XNEST "FLEXI_XNEST"
-#define GDM_SUP_FLEXI_XNEST_USER "FLEXI_XNEST_USER"
-#define GDM_SUP_ADD_DYNAMIC_DISPLAY "ADD_DYNAMIC_DISPLAY"
-#define GDM_SUP_RELEASE_DYNAMIC_DISPLAYS "RELEASE_DYNAMIC_DISPLAYS"
-#define GDM_SUP_REMOVE_DYNAMIC_DISPLAY "REMOVE_DYNAMIC_DISPLAY"
-#define GDM_SUP_ATTACHED_SERVERS "ATTACHED_SERVERS"
-#define GDM_SUP_CONSOLE_SERVERS "CONSOLE_SERVERS"
-#define GDM_SUP_ALL_SERVERS "ALL_SERVERS"
-#define GDM_SUP_GET_SERVER_LIST "GET_SERVER_LIST"
-#define GDM_SUP_GET_SERVER_DETAILS "GET_SERVER_DETAILS"
-#define GDM_SUP_GET_CONFIG "GET_CONFIG"
-#define GDM_SUP_GET_CONFIG_FILE "GET_CONFIG_FILE"
-#define GDM_SUP_GET_CUSTOM_CONFIG_FILE "GET_CUSTOM_CONFIG_FILE"
-#define GDM_SUP_UPDATE_CONFIG "UPDATE_CONFIG"
-#define GDM_SUP_GREETERPIDS "GREETERPIDS"
-#define GDM_SUP_QUERY_LOGOUT_ACTION "QUERY_LOGOUT_ACTION"
-#define GDM_SUP_QUERY_CUSTOM_CMD_LABELS "QUERY_CUSTOM_CMD_LABELS"
-#define GDM_SUP_QUERY_CUSTOM_CMD_NO_RESTART_STATUS "QUERY_CUSTOM_CMD_NO_RESTART_STATUS"
-#define GDM_SUP_SET_LOGOUT_ACTION "SET_LOGOUT_ACTION"
-#define GDM_SUP_SET_SAFE_LOGOUT_ACTION "SET_SAFE_LOGOUT_ACTION"
-#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"
-#define GDM_SUP_SET_VT "SET_VT"
-#define GDM_SUP_SERVER_BUSY "SERVER_BUSY"
-#define GDM_SUP_GET_SERVER_DETAILS "GET_SERVER_DETAILS"
-#define GDM_SUP_CLOSE "CLOSE"
-
-/* 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 */
-};
-
-#endif /* _GDM_SOCKET_PROTOCOL_H */
diff --git a/daemon/gdm-xdmcp-manager.c b/daemon/gdm-xdmcp-manager.c
deleted file mode 100644
index ad377024..00000000
--- a/daemon/gdm-xdmcp-manager.c
+++ /dev/null
@@ -1,2932 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/utsname.h>
-
-#include <sys/socket.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif
-#include <sys/ioctl.h>
-
-#include <errno.h>
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <glib-object.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xmd.h>
-#include <X11/Xdmcp.h>
-
-#include "gdm-common.h"
-#include "gdm-xdmcp-manager.h"
-
-#include "misc.h"
-#include "auth.h"
-#include "cookie.h"
-#include "choose.h"
-#include "gdm-daemon-config.h"
-
-/*
- * On Sun, we need to define allow_severity and deny_severity to link
- * against libwrap.
- */
-#ifdef __sun
-#include <syslog.h>
-int allow_severity = LOG_INFO;
-int deny_severity = LOG_WARNING;
-#endif
-
-#define GDM_XDMCP_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_XDMCP_MANAGER, GdmXdmcpManagerPrivate))
-
-#define DEFAULT_PORT 177
-#define DEFAULT_USE_MULTICAST FALSE
-#define DEFAULT_MULTICAST_ADDRESS "ff02::1"
-#define DEFAULT_HONOR_INDIRECT TRUE
-#define DEFAULT_MAX_DISPLAYS_PER_HOST 2
-#define DEFAULT_MAX_DISPLAYS 16
-#define DEFAULT_MAX_PENDING_DISPLAYS 4
-#define DEFAULT_MAX_WAIT 15
-
-#define GDM_MAX_FORWARD_QUERIES 10
-#define GDM_FORWARD_QUERY_TIMEOUT 30
-#define MANAGED_FORWARD_INTERVAL 1500 /* 1.5 seconds */
-
-/* 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 */
-};
-
-/*
- * 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.
- */
-
-typedef struct _XdmAuth {
- ARRAY8 authentication;
- ARRAY8 authorization;
-} XdmAuthRec, *XdmAuthPtr;
-
-static XdmAuthRec serv_authlist = {
- { (CARD16) 0, (CARD8 *) 0 },
- { (CARD16) 0, (CARD8 *) 0 }
-};
-
-/* NOTE: Timeout and max are hardcoded */
-typedef struct _GdmForwardQuery {
- time_t acctime;
- struct sockaddr_storage *dsp_sa;
- struct sockaddr_storage *from_sa;
-} GdmForwardQuery;
-
-typedef struct {
- int times;
- guint handler;
- struct sockaddr_storage manager;
- struct sockaddr_storage origin;
- GdmXdmcpManager *xdmcp_manager;
-} ManagedForward;
-
-struct GdmXdmcpManagerPrivate
-{
- GSList *forward_queries;
- GSList *managed_forwards;
-
- int socket_fd;
- gint32 session_serial;
- guint socket_watch_id;
- XdmcpBuffer buf;
-
- guint num_sessions;
- guint num_pending_sessions;
-
- char *sysid;
- char *hostname;
- ARRAY8 servhost;
-
- /* configuration */
- guint port;
- gboolean use_multicast;
- char *multicast_address;
- gboolean honor_indirect;
- char *willing_script;
- guint max_displays_per_host;
- guint max_displays;
- guint max_pending_displays;
- guint max_wait;
-};
-
-enum {
- DISPLAY_ADDED,
- DISPLAY_REMOVED,
- LAST_SIGNAL
-};
-
-enum {
- PROP_0,
- PROP_PORT,
- PROP_USE_MULTICAST,
- PROP_MULTICAST_ADDRESS,
- PROP_HONOR_INDIRECT,
- PROP_WILLING_SCRIPT,
- PROP_MAX_DISPLAYS_PER_HOST,
- PROP_MAX_DISPLAYS,
- PROP_MAX_PENDING_DISPLAYS,
- PROP_MAX_WAIT,
-};
-
-static guint signals [LAST_SIGNAL] = { 0, };
-
-static void gdm_xdmcp_manager_class_init (GdmXdmcpManagerClass *klass);
-static void gdm_xdmcp_manager_init (GdmXdmcpManager *manager);
-static void gdm_xdmcp_manager_finalize (GObject *object);
-
-static gpointer xdmcp_manager_object = NULL;
-
-G_DEFINE_TYPE (GdmXdmcpManager, gdm_xdmcp_manager, G_TYPE_OBJECT)
-
-/* Theory of operation:
- *
- * Process idles waiting for UDP packets on port 177.
- * 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.
- *
- * If the manager accepts to service the display (i.e. loadavg is low)
- * it sends back an Accept containing a unique SessionID. The
- * SessionID is stored in an accept queue by the Manager. Should the
- * manager refuse to start a session a Decline is sent to the display.
- *
- * The display returns a Manage request containing the supplied
- * SessionID. The manager will then start a session on the display. In
- * case the SessionID is not on the accept queue the manager returns
- * Refuse. If the manager fails to open the display for connections
- * Failed is returned.
- *
- * During the session the display periodically sends KeepAlive packets
- * to the manager. The manager responds with Alive.
- *
- * Similarly the manager xpings the display once in a while and shuts
- * down the connection on failure.
- *
- */
-
-GQuark
-gdm_xdmcp_manager_error_quark (void)
-{
- static GQuark ret = 0;
- if (ret == 0) {
- ret = g_quark_from_static_string ("gdm_xdmcp_manager_error");
- }
-
- return ret;
-}
-
-static gint32
-get_next_session_serial (GdmXdmcpManager *manager)
-{
- gint32 serial;
-
- again:
- if (manager->priv->session_serial != G_MAXINT32) {
- serial = manager->priv->session_serial++;
- } else {
- serial = g_random_int ();
- }
-
- if (serial == 0) {
- goto again;
- }
-
- return serial;
-}
-
-/* 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
-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
-do_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 = create_socket (ai);
- if (sock >= 0) {
- if (hostaddr != NULL) {
- memcpy (hostaddr, ai->ai_addr, ai->ai_addrlen);
- }
- }
- }
- }
-
- freeaddrinfo (ai_list);
-
- return sock;
-}
-
-static void
-setup_multicast (GdmXdmcpManager *manager)
-{
-#ifdef ENABLE_IPV6
- /* Checking and Setting Multicast options */
- {
- /*
- * socktemp is a temporary socket for getting info about
- * available interfaces
- */
- int socktemp;
- int i;
- int num;
- char *buf;
- struct ipv6_mreq mreq;
-
- /* For interfaces' list */
- struct ifconf ifc;
- struct ifreq *ifr;
-
- socktemp = socket (AF_INET, SOCK_DGRAM, 0);
-#ifdef SIOCGIFNUM
- if (ioctl (socktemp, SIOCGIFNUM, &num) < 0) {
- num = 64;
- }
-#else
- num = 64;
-#endif /* SIOCGIFNUM */
- 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) {
- g_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;
- }
-
- mreq.ipv6mr_interface = ifindex;
- inet_pton (AF_INET6,
- manager->priv->multicast_address,
- &mreq.ipv6mr_multiaddr);
-
- setsockopt (manager->priv->socket_fd,
- IPPROTO_IPV6,
- IPV6_JOIN_GROUP,
- &mreq,
- sizeof (mreq));
- }
- }
- g_free (buf);
- close (socktemp);
- }
-#endif /* ENABLE_IPV6 */
-}
-
-static gboolean
-open_port (GdmXdmcpManager *manager)
-{
- struct sockaddr_storage serv_sa = { 0 };
-
- g_debug ("XDMCP: Start up on host %s, port %d",
- manager->priv->hostname,
- manager->priv->port);
-
- /* Open socket for communications */
-#ifdef ENABLE_IPV6
- manager->priv->socket_fd = do_bind (manager->priv->port, AF_INET6, &serv_sa);
- if (manager->priv->socket_fd < 0)
-#endif
- manager->priv->socket_fd = do_bind (manager->priv->port, AF_INET, &serv_sa);
-
- if G_UNLIKELY (manager->priv->socket_fd < 0) {
- g_warning (_("Could not create socket!"));
- return FALSE;
- }
-
- if (manager->priv->use_multicast) {
- setup_multicast (manager);
- }
-
- return TRUE;
-}
-
-static gboolean
-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;
- char *host;
-
- /* Find client hostname */
- client_he = gdm_gethostbyaddr (clnt_sa);
-
- if (client_he->not_found) {
- client = "unknown";
- } else {
- g_debug ("gdm_xdmcp_host_allow: client->hostname is %s\n",
- client_he->hostname);
- client = client_he->hostname;
- }
-
- /* 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);
-
- return ret;
-#else /* HAVE_TCPWRAPPERS */
- return (TRUE);
-#endif /* HAVE_TCPWRAPPERS */
-}
-
-static int
-gdm_xdmcp_num_displays_from_host (GdmXdmcpManager *manager,
- struct sockaddr_storage *addr)
-{
- 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)) {
- if (gdm_address_equal (&disp->addr, addr)) {
- count++;
- }
- }
- }
- return count;
-}
-
-static GdmDisplay *
-gdm_xdmcp_display_lookup_by_host (GdmXdmcpManager *manager,
- struct sockaddr_storage *addr,
- int dspnum)
-{
- 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)) {
-
- if (gdm_address_equal (&disp->addr, addr)
- && disp->xdmcp_dispnum == dspnum) {
- return disp;
- }
- }
- }
-
- return NULL;
-}
-
-static char *
-get_willing_output (GdmXdmcpManager *manager)
-{
- char *output;
- char **argv;
- FILE *fd;
- char buf[256];
-
- output = NULL;
- buf[0] = '\0';
-
- if (manager->priv->willing_script == NULL) {
- goto out;
- }
-
- argv = NULL;
- if (! g_shell_parse_argv (manager->priv->willing_script, NULL, &argv, NULL)) {
- goto out;
- }
-
- if (argv == NULL ||
- argv[0] == NULL ||
- g_access (argv[0], X_OK) != 0) {
- goto out;
- }
-
- fd = popen (manager->priv->willing_script, "r");
- if (fd == NULL) {
- goto out;
- }
-
- if (fgets (buf, sizeof (buf), fd) == NULL) {
- pclose (fd);
- goto out;
- }
-
- pclose (fd);
-
- output = g_strdup (buf);
-
- out:
- return output;
-}
-
-static void
-gdm_xdmcp_send_willing (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa)
-{
- ARRAY8 status;
- XdmcpHeader header;
- static char *last_status = NULL;
- static time_t last_willing = 0;
- char *host;
-
- gdm_address_get_info (clnt_sa, &host, NULL);
- g_debug ("XDMCP: Sending WILLING to %s", host);
- g_free (host);
-
- if (last_willing == 0 || time (NULL) - 3 > last_willing) {
- char *s;
-
- g_free (last_status);
-
- s = get_willing_output (manager);
- if (s != NULL) {
- g_free (last_status);
- last_status = s;
- } else {
- last_status = g_strdup (manager->priv->sysid);
- }
- }
-
- if (! gdm_address_is_local (clnt_sa) &&
- gdm_xdmcp_num_displays_from_host (manager, clnt_sa) >= manager->priv->max_displays_per_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 *) g_strdup_printf ("%s (Server is busy)",
- 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 += manager->priv->servhost.length + status.length;
- header.version = XDM_PROTOCOL_VERSION;
- XdmcpWriteHeader (&manager->priv->buf, &header);
-
- /* Hardcoded authentication */
- XdmcpWriteARRAY8 (&manager->priv->buf, &serv_authlist.authentication);
- XdmcpWriteARRAY8 (&manager->priv->buf, &manager->priv->servhost);
- XdmcpWriteARRAY8 (&manager->priv->buf, &status);
-
- XdmcpFlush (manager->priv->socket_fd,
- &manager->priv->buf,
- (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_storage));
-
- g_free (status.data);
-}
-
-static void
-gdm_xdmcp_send_unwilling (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- int type)
-{
- 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);
- g_debug ("XDMCP: Sending UNWILLING to %s", host);
- g_warning (_("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 + manager->priv->servhost.length + status.length;
- header.version = XDM_PROTOCOL_VERSION;
- XdmcpWriteHeader (&manager->priv->buf, &header);
-
- XdmcpWriteARRAY8 (&manager->priv->buf, &manager->priv->servhost);
- XdmcpWriteARRAY8 (&manager->priv->buf, &status);
- XdmcpFlush (manager->priv->socket_fd,
- &manager->priv->buf,
- (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_storage));
-
- last_time = time (NULL);
-}
-
-#define SIN(__s) ((struct sockaddr_in *) __s)
-#define SIN6(__s) ((struct sockaddr_in6 *) __s)
-
-static void
-set_port_for_request (struct sockaddr_storage *ss,
- ARRAY8 *port)
-{
- /* we depend on this being 2 elsewhere as well */
- 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;
- }
-}
-
-static void
-set_address_for_request (struct sockaddr_storage *ss,
- ARRAY8 *address)
-{
-
- 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;
- }
-
-}
-
-static void
-gdm_xdmcp_send_forward_query (GdmXdmcpManager *manager,
- GdmIndirectDisplay *id,
- struct sockaddr_storage *clnt_sa,
- struct sockaddr_storage *display_addr,
- ARRAYofARRAY8Ptr authlist)
-{
- struct sockaddr_storage *sa;
- XdmcpHeader header;
- int i;
- ARRAY8 address;
- ARRAY8 port;
- char *host;
- char *serv;
-
- g_assert (id != NULL);
- g_assert (id->chosen_host != NULL);
-
- gdm_address_get_info (id->chosen_host, &host, NULL);
- g_debug ("XDMCP: Sending forward query to %s",
- host);
- g_free (host);
-
- gdm_address_get_info (display_addr, &host, &serv);
- g_debug ("gdm_xdmcp_send_forward_query: Query contains %s:%s",
- host, serv);
- g_free (host);
- g_free (serv);
-
- set_port_for_request (clnt_sa, &port);
- set_address_for_request (display_addr, &address);
-
- sa = g_memdup (id->chosen_host, sizeof (id->chosen_host));
-
- header.version = XDM_PROTOCOL_VERSION;
- header.opcode = (CARD16) FORWARD_QUERY;
- header.length = 0;
- header.length += 2 + address.length;
- header.length += 2 + port.length;
- header.length += 1;
- for (i = 0; i < authlist->length; i++) {
- header.length += 2 + authlist->data[i].length;
- }
-
- XdmcpWriteHeader (&manager->priv->buf, &header);
- XdmcpWriteARRAY8 (&manager->priv->buf, &address);
- XdmcpWriteARRAY8 (&manager->priv->buf, &port);
- XdmcpWriteARRAYofARRAY8 (&manager->priv->buf, authlist);
-
- XdmcpFlush (manager->priv->socket_fd,
- &manager->priv->buf,
- (XdmcpNetaddr) sa,
- (int)sizeof (struct sockaddr_storage));
-
- g_free (port.data);
- g_free (address.data);
- g_free (sa);
-}
-
-static void
-handle_any_query (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- ARRAYofARRAY8Ptr authentication_names,
- int type)
-{
- gdm_xdmcp_send_willing (manager, clnt_sa);
-}
-
-static void
-handle_direct_query (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- int len,
- int type)
-{
- ARRAYofARRAY8 clnt_authlist;
- int expected_len;
- int i;
- int res;
-
- res = XdmcpReadARRAYofARRAY8 (&manager->priv->buf, &clnt_authlist);
- if G_UNLIKELY (! res) {
- g_warning (_("Could not extract authlist from packet"));
- return;
- }
-
- expected_len = 1;
-
- for (i = 0 ; i < clnt_authlist.length ; i++) {
- expected_len += 2 + clnt_authlist.data[i].length;
- }
-
- if (len == expected_len) {
- handle_any_query (manager, clnt_sa, &clnt_authlist, type);
- } else {
- g_warning (_("Error in checksum"));
- }
-
- XdmcpDisposeARRAYofARRAY8 (&clnt_authlist);
-}
-
-static void
-gdm_xdmcp_handle_broadcast_query (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- int len)
-{
- if (gdm_xdmcp_host_allow (clnt_sa)) {
- handle_direct_query (manager, clnt_sa, len, BROADCAST_QUERY);
- } else {
- /* just ignore it */
- }
-}
-
-static void
-gdm_xdmcp_handle_query (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- int len)
-{
- if (gdm_xdmcp_host_allow (clnt_sa)) {
- handle_direct_query (manager, clnt_sa, len, QUERY);
- } else {
- gdm_xdmcp_send_unwilling (manager, clnt_sa, QUERY);
- }
-}
-
-static void
-gdm_xdmcp_handle_indirect_query (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- int len)
-{
- ARRAYofARRAY8 clnt_authlist;
- int expected_len;
- int i;
- int res;
-
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
- /* ignore the request */
- return;
- }
-
- if (! manager->priv->honor_indirect) {
- /* ignore it */
- return;
- }
-
- res = XdmcpReadARRAYofARRAY8 (&manager->priv->buf, &clnt_authlist);
- if G_UNLIKELY (! res) {
- g_warning (_("Could not extract authlist from packet"));
- return;
- }
-
- expected_len = 1;
-
- for (i = 0 ; i < clnt_authlist.length ; i++) {
- expected_len += 2 + clnt_authlist.data[i].length;
- }
-
- /* 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 (len == expected_len) {
- GdmIndirectDisplay *id;
-
- id = gdm_choose_indirect_lookup (clnt_sa);
-
- 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 (manager, 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_storage *saddr = list->data;
-
- if (! gdm_address_is_loopback (saddr)) {
- /* forward query to * chosen host */
- gdm_xdmcp_send_forward_query (manager,
- id,
- clnt_sa,
- saddr,
- &clnt_authlist);
- }
-
- list = list->next;
- }
- } else {
- /* or send forward query to chosen host */
- gdm_xdmcp_send_forward_query (manager,
- id,
- clnt_sa,
- clnt_sa,
- &clnt_authlist);
- }
- } else if (id == NULL) {
- id = gdm_choose_indirect_alloc (clnt_sa);
- if (id != NULL) {
- gdm_xdmcp_send_willing (manager, clnt_sa);
- }
- } else {
- gdm_xdmcp_send_willing (manager, clnt_sa);
- }
-
- } else {
- g_warning (_("Error in checksum"));
- }
-
- XdmcpDisposeARRAYofARRAY8 (&clnt_authlist);
-}
-
-static void
-gdm_forward_query_dispose (GdmXdmcpManager *manager,
- GdmForwardQuery *q)
-{
- if (q == NULL) {
- return;
- }
-
- manager->priv->forward_queries = g_slist_remove (manager->priv->forward_queries, q);
-
- q->acctime = 0;
-
- {
- char *host;
-
- gdm_address_get_info (q->dsp_sa, &host, NULL);
- g_debug ("gdm_forward_query_dispose: Disposing %s", host);
- g_free (host);
- }
-
- g_free (q->dsp_sa);
- q->dsp_sa = NULL;
- g_free (q->from_sa);
- q->from_sa = NULL;
-
- g_free (q);
-}
-
-static gboolean
-remove_oldest_forward (GdmXdmcpManager *manager)
-{
- GSList *li;
- GdmForwardQuery *oldest = NULL;
-
- for (li = manager->priv->forward_queries; li != NULL; li = li->next) {
- GdmForwardQuery *query = li->data;
-
- if (oldest == NULL || query->acctime < oldest->acctime) {
- oldest = query;
- }
- }
-
- if (oldest != NULL) {
- gdm_forward_query_dispose (manager, oldest);
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-static GdmForwardQuery *
-gdm_forward_query_alloc (GdmXdmcpManager *manager,
- struct sockaddr_storage *mgr_sa,
- struct sockaddr_storage *dsp_sa)
-{
- GdmForwardQuery *q;
- int count;
-
- count = g_slist_length (manager->priv->forward_queries);
-
- while (count > GDM_MAX_FORWARD_QUERIES && remove_oldest_forward (manager)) {
- count--;
- }
-
- q = g_new0 (GdmForwardQuery, 1);
- q->dsp_sa = g_memdup (dsp_sa, sizeof (struct sockaddr_storage));
- q->from_sa = g_memdup (mgr_sa, sizeof (struct sockaddr_storage));
-
- manager->priv->forward_queries = g_slist_prepend (manager->priv->forward_queries, q);
-
- return q;
-}
-
-static GdmForwardQuery *
-gdm_forward_query_lookup (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa)
-{
- GSList *li;
- GSList *qlist;
- GdmForwardQuery *q;
- time_t curtime;
-
- curtime = time (NULL);
-
- qlist = g_slist_copy (manager->priv->forward_queries);
-
- for (li = qlist; li != NULL; li = li->next) {
- q = (GdmForwardQuery *) li->data;
-
- if (q == NULL)
- continue;
-
- if (gdm_address_equal (q->dsp_sa, clnt_sa)) {
- g_slist_free (qlist);
- return q;
- }
-
- if (q->acctime > 0 && curtime > q->acctime + GDM_FORWARD_QUERY_TIMEOUT) {
- char *host;
- char *serv;
-
- gdm_address_get_info (q->dsp_sa, &host, &serv);
-
- g_debug ("gdm_forward_query_lookup: Disposing stale forward query from %s:%s",
- host, serv);
- g_free (host);
- g_free (serv);
-
- gdm_forward_query_dispose (manager, q);
- continue;
- }
- }
-
- g_slist_free (qlist);
-
- {
- char *host;
-
- gdm_address_get_info (clnt_sa, &host, NULL);
- g_debug ("gdm_forward_query_lookup: Host %s not found",
- host);
- g_free (host);
- }
-
- return NULL;
-}
-
-static gboolean
-create_sa_from_request (ARRAY8 *req_addr,
- ARRAY8 *req_port,
- int family,
- struct sockaddr_storage **sap)
-{
- 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;
- }
-
- if (req_addr == NULL) {
- return FALSE;
- }
-
- serv = NULL;
- if (req_port != NULL) {
- /* port must always be length 2 */
- if (req_port->length != 2) {
- return FALSE;
- }
-
- 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) {
- g_warning (_("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;
- }
-
- /* just take the first one */
- ai = ai_list;
-
- found = FALSE;
- if (ai != NULL) {
- found = TRUE;
- if (sap != NULL) {
- *sap = g_memdup (ai->ai_addr, ai->ai_addrlen);
- }
- }
-
- freeaddrinfo (ai_list);
-
- return found;
-}
-
-static void
-gdm_xdmcp_whack_queued_managed_forwards (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- struct sockaddr_storage *origin)
-{
- GSList *li;
-
- for (li = manager->priv->managed_forwards; li != NULL; li = li->next) {
- ManagedForward *mf = li->data;
-
- if (gdm_address_equal (&mf->manager, clnt_sa) &&
- gdm_address_equal (&mf->origin, origin)) {
- manager->priv->managed_forwards = g_slist_remove_link (manager->priv->managed_forwards, li);
- g_slist_free_1 (li);
- g_source_remove (mf->handler);
- /* mf freed by glib */
- return;
- }
- }
-}
-
-static void
-gdm_xdmcp_handle_forward_query (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- int len)
-{
- ARRAY8 clnt_addr;
- ARRAY8 clnt_port;
- ARRAYofARRAY8 clnt_authlist;
- int i;
- int explen;
- struct sockaddr_storage *disp_sa;
- char *host;
- char *serv;
-
- disp_sa = NULL;
-
- /* Check with tcp_wrappers if client is allowed to access */
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
- char *host;
-
- gdm_address_get_info (clnt_sa, &host, NULL);
-
- g_warning ("%s: Got FORWARD_QUERY from banned host %s",
- "gdm_xdmcp_handle_forward query",
- host);
- g_free (host);
- return;
- }
-
- /* Read display address */
- if G_UNLIKELY (! XdmcpReadARRAY8 (&manager->priv->buf, &clnt_addr)) {
- g_warning (_("%s: Could not read display address"),
- "gdm_xdmcp_handle_forward_query");
- return;
- }
-
- /* Read display port */
- if G_UNLIKELY (! XdmcpReadARRAY8 (&manager->priv->buf, &clnt_port)) {
- XdmcpDisposeARRAY8 (&clnt_addr);
- g_warning (_("%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 (&manager->priv->buf, &clnt_authlist)) {
- XdmcpDisposeARRAY8 (&clnt_addr);
- XdmcpDisposeARRAY8 (&clnt_port);
- g_warning (_("%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++) {
- char *s = g_strndup ((char *) clnt_authlist.data[i].data,
- clnt_authlist.length);
- g_debug ("gdm_xdmcp_handle_forward_query: authlist: %s", s);
- g_free (s);
-
- explen += 2 + clnt_authlist.data[i].length;
- }
-
- if G_UNLIKELY (len != explen) {
- g_warning (_("%s: Error in checksum"),
- "gdm_xdmcp_handle_forward_query");
- goto out;
- }
-
- if (! create_sa_from_request (&clnt_addr, &clnt_port, clnt_sa->ss_family, &disp_sa)) {
- g_warning ("Unable to parse address for request");
- goto out;
- }
-
- gdm_xdmcp_whack_queued_managed_forwards (manager,
- clnt_sa,
- disp_sa);
-
- gdm_address_get_info (disp_sa, &host, &serv);
- g_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 (manager, disp_sa);
- if (q != NULL)
- gdm_forward_query_dispose (manager, q);
-
- gdm_forward_query_alloc (manager, clnt_sa, disp_sa);
-
- gdm_xdmcp_send_willing (manager, disp_sa);
- }
-
- out:
-
- g_free (disp_sa);
- XdmcpDisposeARRAYofARRAY8 (&clnt_authlist);
- XdmcpDisposeARRAY8 (&clnt_port);
- XdmcpDisposeARRAY8 (&clnt_addr);
-}
-
-static void
-gdm_xdmcp_really_send_managed_forward (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- struct sockaddr_storage *origin)
-{
- ARRAY8 address;
- XdmcpHeader header;
- char *host;
-
- gdm_address_get_info (clnt_sa, &host, NULL);
- g_debug ("XDMCP: Sending MANAGED_FORWARD to %s", host);
- g_free (host);
-
- set_address_for_request (origin, &address);
-
- header.opcode = (CARD16) GDM_XDMCP_MANAGED_FORWARD;
- header.length = 4 + address.length;
- header.version = GDM_XDMCP_PROTOCOL_VERSION;
- XdmcpWriteHeader (&manager->priv->buf, &header);
-
- XdmcpWriteARRAY8 (&manager->priv->buf, &address);
- XdmcpFlush (manager->priv->socket_fd,
- &manager->priv->buf,
- (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_storage));
-
- g_free (address.data);
-}
-
-static gboolean
-managed_forward_handler (ManagedForward *mf)
-{
- if (mf->xdmcp_manager->priv->socket_fd > 0) {
- gdm_xdmcp_really_send_managed_forward (mf->xdmcp_manager,
- &(mf->manager),
- &(mf->origin));
- }
-
- mf->times++;
- if (mf->xdmcp_manager->priv->socket_fd <= 0 || mf->times >= 2) {
- mf->xdmcp_manager->priv->managed_forwards = g_slist_remove (mf->xdmcp_manager->priv->managed_forwards, mf);
- mf->handler = 0;
- /* mf freed by glib */
- return FALSE;
- }
- return TRUE;
-}
-
-static void
-gdm_xdmcp_send_managed_forward (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- struct sockaddr_storage *origin)
-{
- ManagedForward *mf;
-
- gdm_xdmcp_really_send_managed_forward (manager, clnt_sa, origin);
-
- mf = g_new0 (ManagedForward, 1);
- mf->times = 0;
- mf->xdmcp_manager = manager;
-
- memcpy (&(mf->manager), clnt_sa, sizeof (struct sockaddr_storage));
- memcpy (&(mf->origin), origin, sizeof (struct sockaddr_storage));
-
- mf->handler = g_timeout_add_full (G_PRIORITY_DEFAULT,
- MANAGED_FORWARD_INTERVAL,
- (GSourceFunc)managed_forward_handler,
- mf,
- (GDestroyNotify) g_free);
- manager->priv->managed_forwards = g_slist_prepend (manager->priv->managed_forwards, mf);
-}
-
-static void
-gdm_xdmcp_send_got_managed_forward (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- struct sockaddr_storage *origin)
-{
- ARRAY8 address;
- XdmcpHeader header;
- char *host;
-
- gdm_address_get_info (clnt_sa, &host, NULL);
- g_debug ("XDMCP: Sending GOT_MANAGED_FORWARD to %s", host);
- g_free (host);
-
- set_address_for_request (origin, &address);
-
- header.opcode = (CARD16) GDM_XDMCP_GOT_MANAGED_FORWARD;
- header.length = 4 + address.length;
- header.version = GDM_XDMCP_PROTOCOL_VERSION;
- XdmcpWriteHeader (&manager->priv->buf, &header);
-
- XdmcpWriteARRAY8 (&manager->priv->buf, &address);
- XdmcpFlush (manager->priv->socket_fd,
- &manager->priv->buf,
- (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_storage));
-}
-
-static void
-gdm_xdmcp_recount_sessions (GdmXdmcpManager *manager)
-{
- GSList *li;
- GSList *displays;
-
- displays = gdm_daemon_config_get_display_list ();
-
- manager->priv->num_sessions = 0;
- manager->priv->num_pending_sessions = 0;
-
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *d = li->data;
- if (SERVER_IS_XDMCP (d)) {
- if (d->dispstat == XDMCP_MANAGED)
- manager->priv->num_sessions++;
- else if (d->dispstat == XDMCP_PENDING)
- manager->priv->num_pending_sessions++;
- }
- }
-}
-
-static void
-do_dispose (GdmXdmcpManager *manager,
- GdmDisplay *d)
-{
-
- gdm_display_dispose (d);
- gdm_xdmcp_recount_sessions (manager);
-}
-
-static void
-gdm_xdmcp_displays_purge (GdmXdmcpManager *manager)
-{
- GSList *dlist;
- time_t curtime = time (NULL);
- GSList *displays;
-
- displays = gdm_daemon_config_get_display_list ();
-
- dlist = displays;
- while (dlist != NULL) {
- GdmDisplay *d = dlist->data;
-
- if (d != NULL &&
- SERVER_IS_XDMCP (d) &&
- d->dispstat == XDMCP_PENDING &&
- curtime > d->acctime + manager->priv->max_wait) {
- g_debug ("gdm_xdmcp_displays_purge: Disposing session id %ld",
- (long)d->sessionid);
- do_dispose (manager, d);
-
- /* restart as the list is now broken */
- dlist = displays;
- } else {
- /* just go on */
- dlist = dlist->next;
- }
- }
-}
-
-static void
-gdm_xdmcp_display_dispose_check (GdmXdmcpManager *manager,
- const char *hostname,
- int dspnum)
-{
- GSList *dlist;
- GSList *displays;
-
- if (hostname == NULL) {
- return;
- }
-
- g_debug ("gdm_xdmcp_display_dispose_check (%s:%d)", hostname, dspnum);
-
- displays = gdm_daemon_config_get_display_list ();
-
- dlist = displays;
- while (dlist != NULL) {
- GdmDisplay *d = dlist->data;
-
- if (d != NULL &&
- SERVER_IS_XDMCP (d) &&
- d->xdmcp_dispnum == dspnum &&
- strcmp (d->hostname, hostname) == 0) {
-
- if (d->dispstat == XDMCP_MANAGED) {
- gdm_display_unmanage (d);
- } else {
- do_dispose (manager, d);
- }
-
- /* restart as the list is now broken */
- dlist = displays;
- } else {
- /* just go on */
- dlist = dlist->next;
- }
- }
-}
-
-static void
-gdm_xdmcp_send_decline (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- const char *reason)
-{
- XdmcpHeader header;
- ARRAY8 authentype;
- ARRAY8 authendata;
- ARRAY8 status;
- GdmForwardQuery *fq;
- char *host;
-
- gdm_address_get_info (clnt_sa, &host, NULL);
- g_debug ("XMDCP: Sending DECLINE to %s", host);
- g_free (host);
-
- 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 (&manager->priv->buf, &header);
- XdmcpWriteARRAY8 (&manager->priv->buf, &status);
- XdmcpWriteARRAY8 (&manager->priv->buf, &authentype);
- XdmcpWriteARRAY8 (&manager->priv->buf, &authendata);
-
- XdmcpFlush (manager->priv->socket_fd,
- &manager->priv->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 (manager, clnt_sa);
- if (fq != NULL) {
- gdm_xdmcp_send_managed_forward (manager, fq->from_sa, clnt_sa);
- gdm_forward_query_dispose (manager, fq);
- }
-}
-
-static GdmDisplay *
-gdm_xdmcp_display_alloc (GdmXdmcpManager *manager,
- struct sockaddr_storage *addr,
- GdmHostent *he /* eaten and freed */,
- int displaynum)
-{
- GdmDisplay *d = NULL;
- const char *proxycmd;
- gboolean use_proxy = FALSE;
-
- proxycmd = NULL;
- use_proxy = FALSE;
-#if 0
- proxycmd = gdm_daemon_config_get_value_string (GDM_KEY_XDMCP_PROXY_XSERVER);
- use_proxy = FALSE;
-#endif
- d = g_new0 (GdmDisplay, 1);
-
- if (use_proxy && proxycmd != NULL) {
- d->type = TYPE_XDMCP_PROXY;
- d->command = g_strdup (proxycmd);
- g_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 = get_next_session_serial (manager);
-
- 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)) {
- g_warning ("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);
-
- manager->priv->num_pending_sessions++;
-
- g_debug ("gdm_xdmcp_display_alloc: display=%s, session id=%ld, xdmcp_pending=%d",
- d->name, (long)d->sessionid, manager->priv->num_pending_sessions);
-
- return d;
-}
-
-static void
-gdm_xdmcp_send_accept (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- CARD32 session_id,
- ARRAY8Ptr authentication_name,
- ARRAY8Ptr authentication_data,
- ARRAY8Ptr authorization_name,
- ARRAY8Ptr authorization_data)
-{
- XdmcpHeader header;
- char *host;
-
- header.version = XDM_PROTOCOL_VERSION;
- header.opcode = (CARD16) ACCEPT;
- header.length = 4;
- header.length += 2 + authentication_name->length;
- header.length += 2 + authentication_data->length;
- header.length += 2 + authorization_name->length;
- header.length += 2 + authorization_data->length;
-
- XdmcpWriteHeader (&manager->priv->buf, &header);
- XdmcpWriteCARD32 (&manager->priv->buf, session_id);
- XdmcpWriteARRAY8 (&manager->priv->buf, authentication_name);
- XdmcpWriteARRAY8 (&manager->priv->buf, authentication_data);
- XdmcpWriteARRAY8 (&manager->priv->buf, authorization_name);
- XdmcpWriteARRAY8 (&manager->priv->buf, authorization_data);
-
- XdmcpFlush (manager->priv->socket_fd,
- &manager->priv->buf,
- (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_storage));
-
- gdm_address_get_info (clnt_sa, &host, NULL);
- g_debug ("XDMCP: Sending ACCEPT to %s with SessionID=%ld",
- host,
- (long)session_id);
- g_free (host);
-}
-
-static void
-gdm_xdmcp_handle_request (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- int len)
-{
- CARD16 clnt_dspnum;
- ARRAY16 clnt_conntyp;
- ARRAYofARRAY8 clnt_addr;
- ARRAY8 clnt_authname;
- ARRAY8 clnt_authdata;
- ARRAYofARRAY8 clnt_authorization;
- ARRAY8 clnt_manufacturer;
- int explen;
- int i;
- gboolean mitauth;
- gboolean entered;
- char *host;
-
- mitauth = FALSE;
- entered = FALSE;
-
- gdm_address_get_info (clnt_sa, &host, NULL);
- g_debug ("gdm_xdmcp_handle_request: Got REQUEST from %s", host);
-
- /* Check with tcp_wrappers if client is allowed to access */
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
- g_warning (_("%s: Got REQUEST from banned host %s"),
- "gdm_xdmcp_handle_request",
- host);
- g_free (host);
- return;
- }
- g_free (host);
-
- gdm_xdmcp_displays_purge (manager); /* Purge pending displays */
-
- /* Remote display number */
- if G_UNLIKELY (! XdmcpReadCARD16 (&manager->priv->buf, &clnt_dspnum)) {
- g_warning (_("%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 (&manager->priv->buf, &clnt_conntyp)) {
- g_warning (_("%s: Could not read Connection Type"),
- "gdm_xdmcp_handle_request");
- return;
- }
-
- /* This is TCP/IP - we don't care */
- if G_UNLIKELY (! XdmcpReadARRAYofARRAY8 (&manager->priv->buf, &clnt_addr)) {
- g_warning (_("%s: Could not read Client Address"),
- "gdm_xdmcp_handle_request");
- XdmcpDisposeARRAY16 (&clnt_conntyp);
- return;
- }
-
- /* Read authentication type */
- if G_UNLIKELY (! XdmcpReadARRAY8 (&manager->priv->buf, &clnt_authname)) {
- g_warning (_("%s: Could not read Authentication Names"),
- "gdm_xdmcp_handle_request");
- XdmcpDisposeARRAYofARRAY8 (&clnt_addr);
- XdmcpDisposeARRAY16 (&clnt_conntyp);
- return;
- }
-
- /* Read authentication data */
- if G_UNLIKELY (! XdmcpReadARRAY8 (&manager->priv->buf, &clnt_authdata)) {
- g_warning (_("%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 (&manager->priv->buf, &clnt_authorization)) {
- g_warning (_("%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 (&manager->priv->buf, &clnt_manufacturer)) {
- g_warning (_("%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);
- g_warning (_("%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;
- }
-
- {
- char *s = g_strndup ((char *) clnt_manufacturer.data, clnt_manufacturer.length);
- g_debug ("gdm_xdmcp_handle_request: xdmcp_pending=%d, MaxPending=%d, xdmcp_sessions=%d, MaxSessions=%d, ManufacturerID=%s",
- manager->priv->num_pending_sessions,
- manager->priv->max_pending_displays,
- manager->priv->num_sessions,
- manager->priv->max_displays,
- ve_sure_string (s));
- g_free (s);
- }
-
- /* Check if ok to manage display */
- if (mitauth &&
- manager->priv->num_sessions < manager->priv->max_displays &&
- (gdm_address_is_local (clnt_sa) ||
- gdm_xdmcp_num_displays_from_host (manager, clnt_sa) < manager->priv->max_displays_per_host)) {
- entered = TRUE;
- }
-
- if (entered) {
- GdmHostent *he;
- he = gdm_gethostbyaddr (clnt_sa);
-
- /* Check if we are already talking to this host */
- gdm_xdmcp_display_dispose_check (manager, he->hostname, clnt_dspnum);
-
- if (manager->priv->num_pending_sessions >= manager->priv->max_pending_displays) {
- g_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 (manager, clnt_sa, "Maximum pending servers");
- gdm_hostent_free (he);
- } else {
- GdmDisplay *d;
-
- d = gdm_xdmcp_display_alloc (manager,
- clnt_sa,
- he /* eaten and freed */,
- clnt_dspnum);
- if (d != NULL) {
- ARRAY8 authentication_name;
- ARRAY8 authentication_data;
- ARRAY8 authorization_name;
- ARRAY8 authorization_data;
-
- authentication_name.data = NULL;
- authentication_name.length = 0;
- authentication_data.data = NULL;
- authentication_data.length = 0;
-
- authorization_name.data = (CARD8 *) "MIT-MAGIC-COOKIE-1";
- authorization_name.length = strlen ((char *) authorization_name.data);
-
- authorization_data.data = (CARD8 *) d->bcookie;
- authorization_data.length = 16;
-
- /* the addrs are NOT copied */
- gdm_xdmcp_send_accept (manager,
- clnt_sa,
- d->sessionid,
- &authentication_name,
- &authentication_data,
- &authorization_name,
- &authorization_data);
- }
- }
- } 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 (manager,
- clnt_sa,
- "Only MIT-MAGIC-COOKIE-1 supported");
- } else if (manager->priv->num_sessions >= manager->priv->max_displays) {
- g_warning ("Maximum number of open XDMCP sessions reached");
- gdm_xdmcp_send_decline (manager,
- clnt_sa,
- "Maximum number of open sessions reached");
- } else {
- g_debug ("Maximum number of open XDMCP sessions from host %s reached",
- host);
- gdm_xdmcp_send_decline (manager,
- 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 GdmDisplay *
-gdm_xdmcp_display_lookup (GdmXdmcpManager *manager,
- CARD32 sessid)
-{
- GSList *l;
- GdmDisplay *d;
- GSList *displays;
-
- if (sessid == 0) {
- return (NULL);
- }
-
- displays = gdm_daemon_config_get_display_list ();
-
- l = displays;
- while (l != NULL) {
- d = (GdmDisplay *) l->data;
-
- if (d && d->sessionid == sessid) {
- return (d);
- }
-
- l = l->next;
- }
-
- return (NULL);
-}
-
-static void
-gdm_xdmcp_send_failed (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- CARD32 sessid)
-{
- XdmcpHeader header;
- ARRAY8 status;
-
- g_debug ("XDMCP: 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 (&manager->priv->buf, &header);
- XdmcpWriteCARD32 (&manager->priv->buf, sessid);
- XdmcpWriteARRAY8 (&manager->priv->buf, &status);
-
- XdmcpFlush (manager->priv->socket_fd,
- &manager->priv->buf,
- (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_storage));
-}
-
-static void
-gdm_xdmcp_send_refuse (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- CARD32 sessid)
-{
- XdmcpHeader header;
- GdmForwardQuery *fq;
-
- g_debug ("XDMCP: Sending REFUSE to %ld",
- (long)sessid);
-
- header.version = XDM_PROTOCOL_VERSION;
- header.opcode = (CARD16) REFUSE;
- header.length = 4;
-
- XdmcpWriteHeader (&manager->priv->buf, &header);
- XdmcpWriteCARD32 (&manager->priv->buf, sessid);
-
- XdmcpFlush (manager->priv->socket_fd,
- &manager->priv->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 (manager, clnt_sa);
- if (fq != NULL) {
- gdm_xdmcp_send_managed_forward (manager, fq->from_sa, clnt_sa);
- gdm_forward_query_dispose (manager, fq);
- }
-}
-
-static void
-gdm_xdmcp_handle_manage (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- int len)
-{
- CARD32 clnt_sessid;
- CARD16 clnt_dspnum;
- ARRAY8 clnt_dspclass;
- GdmDisplay *d;
- GdmIndirectDisplay *id;
- GdmForwardQuery *fq;
- char *host;
-
- gdm_address_get_info (clnt_sa, &host, NULL);
- g_debug ("gdm_xdmcp_handle_manage: Got MANAGE from %s", host);
-
- /* Check with tcp_wrappers if client is allowed to access */
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
- g_warning (_("%s: Got Manage from banned host %s"),
- "gdm_xdmcp_handle_manage",
- host);
- g_free (host);
- return;
- }
- g_free (host);
-
- /* SessionID */
- if G_UNLIKELY (! XdmcpReadCARD32 (&manager->priv->buf, &clnt_sessid)) {
- g_warning (_("%s: Could not read Session ID"),
- "gdm_xdmcp_handle_manage");
- return;
- }
-
- /* Remote display number */
- if G_UNLIKELY (! XdmcpReadCARD16 (&manager->priv->buf, &clnt_dspnum)) {
- g_warning (_("%s: Could not read Display Number"),
- "gdm_xdmcp_handle_manage");
- return;
- }
-
- /* Display Class */
- if G_UNLIKELY (! XdmcpReadARRAY8 (&manager->priv->buf, &clnt_dspclass)) {
- g_warning (_("%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_debug ("gdm_xdmcp-handle_manage: Got display=%d, SessionID=%ld Class=%s from %s",
- (int)clnt_dspnum, (long)clnt_sessid, ve_sure_string (s), host);
-
- g_free (s);
- }
-
- d = gdm_xdmcp_display_lookup (manager, clnt_sessid);
- if (d != NULL &&
- d->dispstat == XDMCP_PENDING) {
-
- g_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;
- }
-
- /* this was from a forwarded query quite apparently so
- * send MANAGED_FORWARD */
- fq = gdm_forward_query_lookup (manager, clnt_sa);
- if (fq != NULL) {
- gdm_xdmcp_send_managed_forward (manager, fq->from_sa, clnt_sa);
- gdm_forward_query_dispose (manager, fq);
- }
-
- d->dispstat = XDMCP_MANAGED;
- manager->priv->num_sessions++;
- manager->priv->num_pending_sessions--;
-
- /* Start greeter/session */
- if G_UNLIKELY (!gdm_display_manage (d)) {
- gdm_xdmcp_send_failed (manager, clnt_sa, clnt_sessid);
- XdmcpDisposeARRAY8 (&clnt_dspclass);
- return;
- }
- } else if G_UNLIKELY (d != NULL && d->dispstat == XDMCP_MANAGED) {
- g_debug ("gdm_xdmcp_handle_manage: Session id %ld already managed",
- (long)clnt_sessid);
- } else {
- g_warning ("gdm_xdmcp_handle_manage: Failed to look up session id %ld",
- (long)clnt_sessid);
- gdm_xdmcp_send_refuse (manager, clnt_sa, clnt_sessid);
- }
-
- XdmcpDisposeARRAY8 (&clnt_dspclass);
-}
-
-static void
-gdm_xdmcp_handle_managed_forward (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- int len)
-{
- ARRAY8 clnt_address;
- GdmIndirectDisplay *id;
- char *host;
- struct sockaddr_storage *disp_sa;
-
- gdm_address_get_info (clnt_sa, &host, NULL);
- g_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)) {
- g_warning ("%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 (&manager->priv->buf, &clnt_address)) {
- g_warning (_("%s: Could not read address"),
- "gdm_xdmcp_handle_managed_forward");
- return;
- }
-
- disp_sa = NULL;
- if (! create_sa_from_request (&clnt_address, NULL, clnt_sa->ss_family, &disp_sa)) {
- g_warning ("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 */
- gdm_xdmcp_send_got_managed_forward (manager, clnt_sa, disp_sa);
-
- XdmcpDisposeARRAY8 (&clnt_address);
-}
-
-static void
-gdm_xdmcp_handle_got_managed_forward (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- int len)
-{
- struct sockaddr_storage *disp_sa;
- ARRAY8 clnt_address;
- char *host;
-
- gdm_address_get_info (clnt_sa, &host, NULL);
- g_debug ("gdm_xdmcp_handle_got_managed_forward: Got MANAGED_FORWARD from %s",
- host);
-
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
- g_warning ("%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 (&manager->priv->buf, &clnt_address)) {
- g_warning (_("%s: Could not read address"),
- "gdm_xdmcp_handle_got_managed_forward");
- return;
- }
-
- if (! create_sa_from_request (&clnt_address, NULL, clnt_sa->ss_family, &disp_sa)) {
- g_warning (_("%s: Could not read address"),
- "gdm_xdmcp_handle_got_managed_forward");
- XdmcpDisposeARRAY8 (&clnt_address);
- return;
- }
-
- gdm_xdmcp_whack_queued_managed_forwards (manager, clnt_sa, disp_sa);
-
- XdmcpDisposeARRAY8 (&clnt_address);
-}
-
-static void
-gdm_xdmcp_send_alive (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- CARD16 dspnum,
- CARD32 sessid)
-{
- XdmcpHeader header;
- GdmDisplay *d;
- int send_running = 0;
- CARD32 send_sessid = 0;
-
- d = gdm_xdmcp_display_lookup (manager, sessid);
- if (d == NULL) {
- d = gdm_xdmcp_display_lookup_by_host (manager, clnt_sa, dspnum);
- }
-
- if (d != NULL) {
- send_sessid = d->sessionid;
- if (d->dispstat == XDMCP_MANAGED) {
- send_running = 1;
- }
- }
-
- g_debug ("XDMCP: 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 (&manager->priv->buf, &header);
- XdmcpWriteCARD8 (&manager->priv->buf, send_running);
- XdmcpWriteCARD32 (&manager->priv->buf, send_sessid);
-
- XdmcpFlush (manager->priv->socket_fd,
- &manager->priv->buf,
- (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_storage));
-}
-
-static void
-gdm_xdmcp_handle_keepalive (GdmXdmcpManager *manager,
- struct sockaddr_storage *clnt_sa,
- int len)
-{
- CARD16 clnt_dspnum;
- CARD32 clnt_sessid;
- char *host;
-
- gdm_address_get_info (clnt_sa, &host, NULL);
- g_debug ("XDMCP: Got KEEPALIVE from %s", host);
-
- /* Check with tcp_wrappers if client is allowed to access */
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
- g_warning (_("%s: Got KEEPALIVE from banned host %s"),
- "gdm_xdmcp_handle_keepalive",
- host);
- g_free (host);
- return;
- }
- g_free (host);
-
- /* Remote display number */
- if G_UNLIKELY (! XdmcpReadCARD16 (&manager->priv->buf, &clnt_dspnum)) {
- g_warning (_("%s: Could not read Display Number"),
- "gdm_xdmcp_handle_keepalive");
- return;
- }
-
- /* SessionID */
- if G_UNLIKELY (! XdmcpReadCARD32 (&manager->priv->buf, &clnt_sessid)) {
- g_warning (_("%s: Could not read Session ID"),
- "gdm_xdmcp_handle_keepalive");
- return;
- }
-
- gdm_xdmcp_send_alive (manager, clnt_sa, clnt_dspnum, clnt_sessid);
-}
-
-static const char *
-opcode_string (int opcode)
-{
- 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"
- };
-
-
- if (opcode < G_N_ELEMENTS (opcode_names)) {
- return opcode_names [opcode];
- } else if (opcode >= GDM_XDMCP_FIRST_OPCODE &&
- opcode < GDM_XDMCP_LAST_OPCODE) {
- return gdm_opcode_names [opcode - GDM_XDMCP_FIRST_OPCODE];
- } else {
- return "UNKNOWN";
- }
-}
-
-static gboolean
-decode_packet (GIOChannel *source,
- GIOCondition cond,
- GdmXdmcpManager *manager)
-{
- struct sockaddr_storage clnt_sa;
- gint sa_len;
- XdmcpHeader header;
- char *host;
- char *port;
- int res;
-
- sa_len = sizeof (clnt_sa);
-
- g_debug ("decode_packet: GIOCondition %d", (int)cond);
-
- if ( ! (cond & G_IO_IN)) {
- return TRUE;
- }
-
- res = XdmcpFill (manager->priv->socket_fd, &manager->priv->buf, (XdmcpNetaddr)&clnt_sa, &sa_len);
- if G_UNLIKELY (! res) {
- g_debug (_("XMCP: Could not create XDMCP buffer!"));
- return TRUE;
- }
-
- res = XdmcpReadHeader (&manager->priv->buf, &header);
- if G_UNLIKELY (! res) {
- g_warning (_("XDMCP: Could not read XDMCP header!"));
- return TRUE;
- }
-
- if G_UNLIKELY (header.version != XDM_PROTOCOL_VERSION &&
- header.version != GDM_XDMCP_PROTOCOL_VERSION) {
- g_warning (_("XMDCP: Incorrect XDMCP version!"));
- return TRUE;
- }
-
- gdm_address_get_info (&clnt_sa, &host, &port);
-
- g_debug ("XDMCP: Received opcode %s from client %s : %s",
- opcode_string (header.opcode),
- host,
- port);
-
- switch (header.opcode) {
- case BROADCAST_QUERY:
- gdm_xdmcp_handle_broadcast_query (manager, &clnt_sa, header.length);
- break;
-
- case QUERY:
- gdm_xdmcp_handle_query (manager, &clnt_sa, header.length);
- break;
-
- case INDIRECT_QUERY:
- gdm_xdmcp_handle_indirect_query (manager, &clnt_sa, header.length);
- break;
-
- case FORWARD_QUERY:
- gdm_xdmcp_handle_forward_query (manager, &clnt_sa, header.length);
- break;
-
- case REQUEST:
- gdm_xdmcp_handle_request (manager, &clnt_sa, header.length);
- break;
-
- case MANAGE:
- gdm_xdmcp_handle_manage (manager, &clnt_sa, header.length);
- break;
-
- case KEEPALIVE:
- gdm_xdmcp_handle_keepalive (manager, &clnt_sa, header.length);
- break;
-
- case GDM_XDMCP_MANAGED_FORWARD:
- gdm_xdmcp_handle_managed_forward (manager, &clnt_sa, header.length);
- break;
-
- case GDM_XDMCP_GOT_MANAGED_FORWARD:
- gdm_xdmcp_handle_got_managed_forward (manager, &clnt_sa, header.length);
- break;
-
- default:
- g_debug ("XDMCP: Unknown opcode from client %s : %s",
- host,
- port);
-
- break;
- }
-
- g_free (host);
- g_free (port);
-
- return TRUE;
-}
-
-gboolean
-gdm_xdmcp_manager_start (GdmXdmcpManager *manager,
- GError **error)
-{
- gboolean ret;
- GIOChannel *ioc;
-
- g_return_val_if_fail (GDM_IS_XDMCP_MANAGER (manager), FALSE);
- g_return_val_if_fail (manager->priv->socket_fd == -1, FALSE);
-
- ret = open_port (manager);
- if (! ret) {
- return ret;
- }
-
- g_debug ("XDMCP: Starting to listen on XDMCP port");
-
- ioc = g_io_channel_unix_new (manager->priv->socket_fd);
-
- g_io_channel_set_encoding (ioc, NULL, NULL);
- g_io_channel_set_buffered (ioc, FALSE);
-
- manager->priv->socket_watch_id = g_io_add_watch_full (ioc,
- G_PRIORITY_DEFAULT,
- G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- (GIOFunc)decode_packet,
- manager,
- NULL);
- g_io_channel_unref (ioc);
-
- return ret;
-}
-
-gboolean
-gdm_xdmcp_manager_stop (GdmXdmcpManager *manager,
- GError **error)
-{
- g_return_val_if_fail (GDM_IS_XDMCP_MANAGER (manager), FALSE);
- g_return_val_if_fail (manager->priv->socket_fd != -1, FALSE);
-
- if (manager->priv->socket_watch_id > 0) {
- g_source_remove (manager->priv->socket_watch_id);
- manager->priv->socket_watch_id = 0;
- }
-
- if (manager->priv->socket_fd > 0) {
- VE_IGNORE_EINTR (close (manager->priv->socket_fd));
- manager->priv->socket_fd = -1;
- }
-
- return TRUE;
-}
-
-void
-gdm_xdmcp_manager_set_port (GdmXdmcpManager *manager,
- guint port)
-{
- g_return_if_fail (GDM_IS_XDMCP_MANAGER (manager));
-
- manager->priv->port = port;
-}
-
-static void
-gdm_xdmcp_manager_set_use_multicast (GdmXdmcpManager *manager,
- gboolean use_multicast)
-{
- g_return_if_fail (GDM_IS_XDMCP_MANAGER (manager));
-
- manager->priv->use_multicast = use_multicast;
-}
-
-static void
-gdm_xdmcp_manager_set_multicast_address (GdmXdmcpManager *manager,
- const char *address)
-{
- g_return_if_fail (GDM_IS_XDMCP_MANAGER (manager));
-
- g_free (manager->priv->multicast_address);
- manager->priv->multicast_address = g_strdup (address);
-}
-
-static void
-gdm_xdmcp_manager_set_honor_indirect (GdmXdmcpManager *manager,
- gboolean honor_indirect)
-{
- g_return_if_fail (GDM_IS_XDMCP_MANAGER (manager));
-
- manager->priv->honor_indirect = honor_indirect;
-}
-
-static void
-gdm_xdmcp_manager_set_max_displays_per_host (GdmXdmcpManager *manager,
- guint num)
-{
- g_return_if_fail (GDM_IS_XDMCP_MANAGER (manager));
-
- manager->priv->max_displays_per_host = num;
-}
-
-static void
-gdm_xdmcp_manager_set_max_displays (GdmXdmcpManager *manager,
- guint num)
-{
- g_return_if_fail (GDM_IS_XDMCP_MANAGER (manager));
-
- manager->priv->max_displays = num;
-}
-
-static void
-gdm_xdmcp_manager_set_max_pending_displays (GdmXdmcpManager *manager,
- guint num)
-{
- g_return_if_fail (GDM_IS_XDMCP_MANAGER (manager));
-
- manager->priv->max_pending_displays = num;
-}
-
-static void
-gdm_xdmcp_manager_set_max_wait (GdmXdmcpManager *manager,
- guint num)
-{
- g_return_if_fail (GDM_IS_XDMCP_MANAGER (manager));
-
- manager->priv->max_wait = num;
-}
-
-static void
-gdm_xdmcp_manager_set_willing_script (GdmXdmcpManager *manager,
- const char *script)
-{
- g_return_if_fail (GDM_IS_XDMCP_MANAGER (manager));
-
- g_free (manager->priv->willing_script);
- manager->priv->willing_script = g_strdup (script);
-}
-
-static void
-gdm_xdmcp_manager_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GdmXdmcpManager *self;
-
- self = GDM_XDMCP_MANAGER (object);
-
- switch (prop_id) {
- case PROP_PORT:
- gdm_xdmcp_manager_set_port (self, g_value_get_uint (value));
- break;
- case PROP_USE_MULTICAST:
- gdm_xdmcp_manager_set_use_multicast (self, g_value_get_boolean (value));
- break;
- case PROP_MULTICAST_ADDRESS:
- gdm_xdmcp_manager_set_multicast_address (self, g_value_get_string (value));
- break;
- case PROP_HONOR_INDIRECT:
- gdm_xdmcp_manager_set_honor_indirect (self, g_value_get_boolean (value));
- break;
- case PROP_MAX_DISPLAYS_PER_HOST:
- gdm_xdmcp_manager_set_max_displays_per_host (self, g_value_get_uint (value));
- break;
- case PROP_MAX_DISPLAYS:
- gdm_xdmcp_manager_set_max_displays (self, g_value_get_uint (value));
- break;
- case PROP_MAX_PENDING_DISPLAYS:
- gdm_xdmcp_manager_set_max_pending_displays (self, g_value_get_uint (value));
- break;
- case PROP_MAX_WAIT:
- gdm_xdmcp_manager_set_max_wait (self, g_value_get_uint (value));
- break;
- case PROP_WILLING_SCRIPT:
- gdm_xdmcp_manager_set_willing_script (self, g_value_get_string (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gdm_xdmcp_manager_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GdmXdmcpManager *self;
-
- self = GDM_XDMCP_MANAGER (object);
-
- switch (prop_id) {
- case PROP_PORT:
- g_value_set_uint (value, self->priv->port);
- break;
- case PROP_USE_MULTICAST:
- g_value_set_boolean (value, self->priv->use_multicast);
- break;
- case PROP_MULTICAST_ADDRESS:
- g_value_set_string (value, self->priv->multicast_address);
- break;
- case PROP_HONOR_INDIRECT:
- g_value_set_boolean (value, self->priv->honor_indirect);
- break;
- case PROP_MAX_DISPLAYS_PER_HOST:
- g_value_set_uint (value, self->priv->max_displays_per_host);
- break;
- case PROP_MAX_DISPLAYS:
- g_value_set_uint (value, self->priv->max_displays);
- break;
- case PROP_MAX_PENDING_DISPLAYS:
- g_value_set_uint (value, self->priv->max_pending_displays);
- break;
- case PROP_MAX_WAIT:
- g_value_set_uint (value, self->priv->max_wait);
- break;
- case PROP_WILLING_SCRIPT:
- g_value_set_string (value, self->priv->willing_script);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gdm_xdmcp_manager_class_init (GdmXdmcpManagerClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->get_property = gdm_xdmcp_manager_get_property;
- object_class->set_property = gdm_xdmcp_manager_set_property;
- object_class->finalize = gdm_xdmcp_manager_finalize;
-
- g_object_class_install_property (object_class,
- PROP_PORT,
- g_param_spec_uint ("port",
- "UDP port",
- "UDP port",
- 0,
- G_MAXINT,
- DEFAULT_PORT,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
- g_object_class_install_property (object_class,
- PROP_USE_MULTICAST,
- g_param_spec_boolean ("use-multicast",
- NULL,
- NULL,
- DEFAULT_USE_MULTICAST,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
- g_object_class_install_property (object_class,
- PROP_MULTICAST_ADDRESS,
- g_param_spec_string ("multicast-address",
- "multicast-address",
- "multicast-address",
- DEFAULT_MULTICAST_ADDRESS,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
- g_object_class_install_property (object_class,
- PROP_HONOR_INDIRECT,
- g_param_spec_boolean ("honor-indirect",
- NULL,
- NULL,
- DEFAULT_HONOR_INDIRECT,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
- g_object_class_install_property (object_class,
- PROP_WILLING_SCRIPT,
- g_param_spec_string ("willing-script",
- "willing-script",
- "willing-script",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
- g_object_class_install_property (object_class,
- PROP_MAX_DISPLAYS_PER_HOST,
- g_param_spec_uint ("max-displays-per-host",
- "max-displays-per-host",
- "max-displays-per-host",
- 0,
- G_MAXINT,
- DEFAULT_MAX_DISPLAYS_PER_HOST,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
- g_object_class_install_property (object_class,
- PROP_MAX_DISPLAYS,
- g_param_spec_uint ("max-displays",
- "max-displays",
- "max-displays",
- 0,
- G_MAXINT,
- DEFAULT_MAX_DISPLAYS,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
- g_object_class_install_property (object_class,
- PROP_MAX_PENDING_DISPLAYS,
- g_param_spec_uint ("max-pending-displays",
- "max-pending-displays",
- "max-pending-displays",
- 0,
- G_MAXINT,
- DEFAULT_MAX_PENDING_DISPLAYS,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
- g_object_class_install_property (object_class,
- PROP_MAX_WAIT,
- g_param_spec_uint ("max-wait",
- "max-wait",
- "max-wait",
- 0,
- G_MAXINT,
- DEFAULT_MAX_WAIT,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_type_class_add_private (klass, sizeof (GdmXdmcpManagerPrivate));
-}
-
-static void
-gdm_xdmcp_manager_init (GdmXdmcpManager *manager)
-{
- char hostbuf[1024];
- struct utsname name;
-
- manager->priv = GDM_XDMCP_MANAGER_GET_PRIVATE (manager);
-
- manager->priv->socket_fd = -1;
-
- manager->priv->session_serial = g_random_int ();
-
- /* Fetch and store local hostname in XDMCP friendly format */
- hostbuf[1023] = '\0';
- if G_UNLIKELY (gethostname (hostbuf, 1023) != 0) {
- g_warning (_("Could not get server hostname: %s!"), g_strerror (errno));
- strcpy (hostbuf, "localhost.localdomain");
- }
-
- uname (&name);
- manager->priv->sysid = g_strconcat (name.sysname,
- " ",
- name.release,
- NULL);
-
- manager->priv->hostname = g_strdup (hostbuf);
-
- manager->priv->servhost.data = (CARD8 *) g_strdup (hostbuf);
- manager->priv->servhost.length = strlen ((char *) manager->priv->servhost.data);
-}
-
-static void
-gdm_xdmcp_manager_finalize (GObject *object)
-{
- GdmXdmcpManager *manager;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (GDM_IS_XDMCP_MANAGER (object));
-
- manager = GDM_XDMCP_MANAGER (object);
-
- g_return_if_fail (manager->priv != NULL);
-
- if (manager->priv->socket_watch_id > 0) {
- g_source_remove (manager->priv->socket_watch_id);
- }
-
- g_slist_free (manager->priv->forward_queries);
- g_slist_free (manager->priv->managed_forwards);
-
- g_free (manager->priv->sysid);
- g_free (manager->priv->hostname);
- g_free (manager->priv->multicast_address);
- g_free (manager->priv->willing_script);
-
- /* FIXME: Free servhost */
-
- G_OBJECT_CLASS (gdm_xdmcp_manager_parent_class)->finalize (object);
-}
-
-GdmXdmcpManager *
-gdm_xdmcp_manager_new (void)
-{
- if (xdmcp_manager_object != NULL) {
- g_object_ref (xdmcp_manager_object);
- } else {
- xdmcp_manager_object = g_object_new (GDM_TYPE_XDMCP_MANAGER, NULL);
- g_object_add_weak_pointer (xdmcp_manager_object,
- (gpointer *) &xdmcp_manager_object);
- }
-
- return GDM_XDMCP_MANAGER (xdmcp_manager_object);
-}
diff --git a/daemon/gdm-xdmcp-manager.h b/daemon/gdm-xdmcp-manager.h
deleted file mode 100644
index fe12ddc5..00000000
--- a/daemon/gdm-xdmcp-manager.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2006 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.
- *
- */
-
-
-#ifndef __GDM_XDMCP_MANAGER_H
-#define __GDM_XDMCP_MANAGER_H
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GDM_TYPE_XDMCP_MANAGER (gdm_xdmcp_manager_get_type ())
-#define GDM_XDMCP_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_XDMCP_MANAGER, GdmXdmcpManager))
-#define GDM_XDMCP_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_XDMCP_MANAGER, GdmXdmcpManagerClass))
-#define GDM_IS_XDMCP_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_XDMCP_MANAGER))
-#define GDM_IS_XDMCP_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_XDMCP_MANAGER))
-#define GDM_XDMCP_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_XDMCP_MANAGER, GdmXdmcpManagerClass))
-
-typedef struct GdmXdmcpManagerPrivate GdmXdmcpManagerPrivate;
-
-typedef struct
-{
- GObject parent;
- GdmXdmcpManagerPrivate *priv;
-} GdmXdmcpManager;
-
-typedef struct
-{
- GObjectClass parent_class;
-} GdmXdmcpManagerClass;
-
-typedef enum
-{
- GDM_XDMCP_MANAGER_ERROR_GENERAL
-} GdmXdmcpManagerError;
-
-#define GDM_XDMCP_MANAGER_ERROR gdm_xdmcp_manager_error_quark ()
-
-GQuark gdm_xdmcp_manager_error_quark (void);
-GType gdm_xdmcp_manager_get_type (void);
-
-GdmXdmcpManager * gdm_xdmcp_manager_new (void);
-
-void gdm_xdmcp_manager_set_port (GdmXdmcpManager *manager,
- guint port);
-gboolean gdm_xdmcp_manager_start (GdmXdmcpManager *manager,
- GError **error);
-gboolean gdm_xdmcp_manager_stop (GdmXdmcpManager *manager,
- GError **error);
-
-G_END_DECLS
-
-#endif /* __GDM_XDMCP_MANAGER_H */
diff --git a/daemon/gdm.c b/daemon/gdm.c
deleted file mode 100644
index f15f1b92..00000000
--- a/daemon/gdm.c
+++ /dev/null
@@ -1,4340 +0,0 @@
-/* -*- 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
- * 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
- */
-
-#include "config.h"
-
-#include <signal.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <unistd.h>
-#if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD)
-#include <sched.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <sys/resource.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <pwd.h>
-#include <grp.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <locale.h>
-#include <dirent.h>
-
-#ifdef HAVE_CHKAUTHATTR
-#include <auth_attr.h>
-#include <secdb.h>
-#endif
-
-/* This should be moved to auth.c I suppose */
-
-#include <X11/Xauth.h>
-#include <glib/gi18n.h>
-#include <glib-object.h>
-
-#include <gtk/gtk.h>
-
-/* Needed for signal handling */
-#include "gdm-common.h"
-
-#include "gdm.h"
-#include "misc.h"
-#include "slave.h"
-#include "server.h"
-#include "verify.h"
-#include "display.h"
-#include "choose.h"
-#include "getvt.h"
-#include "gdm-net.h"
-#include "cookie.h"
-#include "filecheck.h"
-#include "errorgui.h"
-
-#include "gdm-socket-protocol.h"
-#include "gdm-daemon-config.h"
-#include "gdm-log.h"
-
-#include "xdmcp.h"
-
-#define DYNAMIC_ADD 0
-#define DYNAMIC_RELEASE 1
-#define DYNAMIC_REMOVE 2
-
-#ifdef HAVE_LOGINDEVPERM
-#include <libdevinfo.h>
-#endif /* HAVE_LOGINDEVPERM */
-
-/* Local functions */
-static void gdm_handle_message (GdmConnection *conn,
- const gchar *msg,
- gpointer data);
-static void gdm_handle_user_message (GdmConnection *conn,
- const gchar *msg,
- gpointer data);
-static void gdm_daemonify (void);
-static void gdm_safe_restart (void);
-static void gdm_try_logout_action (GdmDisplay *disp);
-static void gdm_restart_now (void);
-static void 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_auth_file,
- const gchar *xnest_cookie,
- const gchar *username);
-static void custom_cmd_restart (long cmd_id);
-static void custom_cmd_no_restart (long cmd_id);
-
-/* Global vars */
-
-gint flexi_servers = 0; /* Number of flexi servers */
-static pid_t extra_process = 0; /* An extra process. Used for quickie
- processes, so that they also get whacked */
-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 */
-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 */
-
-GdmConnection *fifoconn = NULL; /* Fifo connection */
-GdmConnection *pipeconn = NULL; /* slavepipe (handled just like Fifo for
- compatibility) connection */
-GdmConnection *unixconn = NULL; /* UNIX Socket connection */
-int slave_fifo_pipe_fd = -1; /* The slavepipe connection */
-
-unsigned char *gdm_global_cookie = NULL;
-unsigned char *gdm_global_bcookie = NULL;
-char *gdm_system_locale = NULL;
-
-gboolean gdm_first_login = TRUE;
-
-static GdmLogoutAction safe_logout_action = GDM_LOGOUT_ACTION_NONE;
-
-/* set in the main function */
-gchar **stored_argv = NULL;
-int stored_argc = 0;
-
-static GMainLoop *main_loop = NULL;
-static gchar *config_file = NULL;
-static gboolean gdm_restart_mode = FALSE;
-static gboolean monte_carlo_sqrt2 = FALSE;
-
-/*
- * Lookup display number if the display number is
- * exists then clear the remove flag and return TRUE
- * otherwise return FALSE.
- */
-static gboolean
-mark_display_exists (int num)
-{
- GSList *li;
- GSList *displays;
-
- displays = gdm_daemon_config_get_display_list ();
-
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *disp = li->data;
- if (disp->dispnum == num) {
- disp->removeconf = FALSE;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/**
- * gdm_daemonify:
- *
- * Detach gdm daemon from the controlling terminal
- */
-static void
-gdm_daemonify (void)
-{
- FILE *pf;
- pid_t pid;
-
- pid = fork ();
- if (pid > 0) {
- const char *pidfile = GDM_PID_FILE;
-
- errno = 0;
- if ((pf = gdm_safe_fopen_w (pidfile, 0644)) != NULL) {
- errno = 0;
- VE_IGNORE_EINTR (fprintf (pf, "%d\n", (int)pid));
- VE_IGNORE_EINTR (fclose (pf));
- if G_UNLIKELY (errno != 0) {
- /* FIXME: how to handle this? */
- gdm_fdprintf (2, _("Cannot write PID file %s: possibly out of diskspace. Error: %s\n"),
- pidfile, strerror (errno));
- gdm_error (_("Cannot write PID file %s: possibly out of diskspace. Error: %s"),
- pidfile, strerror (errno));
-
- }
- } else if G_UNLIKELY (errno != 0) {
- /* FIXME: how to handle this? */
- gdm_fdprintf (2, _("Cannot write PID file %s: possibly out of diskspace. Error: %s\n"),
- pidfile, strerror (errno));
- gdm_error (_("Cannot write PID file %s: possibly out of diskspace. Error: %s"),
- pidfile, strerror (errno));
-
- }
-
- exit (EXIT_SUCCESS);
- }
-
- if G_UNLIKELY (pid < 0)
- gdm_fail (_("%s: fork () failed!"), "gdm_daemonify");
-
- if G_UNLIKELY (setsid () < 0)
- gdm_fail (_("%s: setsid () failed: %s!"), "gdm_daemonify",
- strerror (errno));
-
- VE_IGNORE_EINTR (g_chdir (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)));
- umask (022);
-
- VE_IGNORE_EINTR (close (0));
- VE_IGNORE_EINTR (close (1));
- VE_IGNORE_EINTR (close (2));
-
- gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
- gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
- gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
-}
-
-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 ();
-
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *d = li->data;
-
- if (d != NULL &&
- d->type == TYPE_STATIC &&
- d->dispstat == DISPLAY_UNBORN) {
- GdmXserver *svr;
- g_debug ("gdm_start_first_unborn_local: "
- "Starting %s", d->name);
-
- /* well sleep at least 'delay' seconds
- * before starting */
- d->sleep_before_run = delay;
-
- /* only the first static display has
- * timed login going on */
- if (gdm_first_login)
- d->timed_login_ok = TRUE;
-
- svr = gdm_server_resolve (d);
-
- if ( ! gdm_display_manage (d)) {
- gdm_display_unmanage (d);
- /* only the first static display where
- we actually log in gets
- autologged in */
- if (svr != NULL &&
- svr->handled &&
- ! svr->chooser)
- gdm_first_login = FALSE;
- } else {
- /* only the first static display where
- we actually log in gets
- autologged in */
- if (svr != NULL &&
- svr->handled &&
- ! svr->chooser)
- gdm_first_login = FALSE;
- break;
- }
- }
- }
-}
-
-void
-gdm_final_cleanup (void)
-{
- GSList *list, *li;
- const char *pidfile;
- gboolean first;
- GSList *displays;
-
- displays = gdm_daemon_config_get_display_list ();
-
- g_debug ("gdm_final_cleanup");
-
- if (extra_process > 1) {
- /* we sigterm extra processes, and we
- * don't wait */
- kill (-(extra_process), SIGTERM);
- extra_process = 0;
- }
-
- /* First off whack all XDMCP and FLEXI_XNEST
- slaves, we'll wait for them later */
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *d = li->data;
- if (SERVER_IS_XDMCP (d) ||
- SERVER_IS_PROXY (d)) {
- /* set to DEAD so that we won't kill it again */
- d->dispstat = DISPLAY_DEAD;
- if (d->slavepid > 1)
- kill (d->slavepid, SIGTERM);
- }
- }
-
- /* Now completely unmanage the static servers */
- first = TRUE;
- list = g_slist_copy (displays);
- /* somewhat of a hack to kill last server
- * started first. This mostly makes things end up on
- * the right vt */
- list = g_slist_reverse (list);
- for (li = list; li != NULL; li = li->next) {
- GdmDisplay *d = li->data;
- if (SERVER_IS_XDMCP (d) ||
- SERVER_IS_PROXY (d))
- continue;
- /* HACK! Wait 2 seconds between killing of static servers
- * because X is stupid and full of races and will otherwise
- * hang my keyboard */
- if ( ! first) {
- /* there could be signals happening
- here */
- gdm_sleep_no_signal (2);
- }
- first = FALSE;
- gdm_display_unmanage (d);
- }
- g_slist_free (list);
-
- /* and now kill and wait for the XDMCP and FLEXI_XNEST
- slaves. unmanage will not kill slaves we have already
- killed unless a SIGTERM was sent in the meantime */
-
- list = g_slist_copy (displays);
- for (li = list; li != NULL; li = li->next) {
- GdmDisplay *d = li->data;
- if (SERVER_IS_XDMCP (d) ||
- SERVER_IS_PROXY (d))
- gdm_display_unmanage (d);
- }
- g_slist_free (list);
-
- /* Close stuff */
-
- if (gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP))
- gdm_xdmcp_close ();
-
- if (fifoconn != NULL) {
- char *path;
- gdm_connection_close (fifoconn);
- path = g_build_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), ".gdmfifo", NULL);
- VE_IGNORE_EINTR (g_unlink (path));
- g_free (path);
- fifoconn = NULL;
- }
-
- if (pipeconn != NULL) {
- gdm_connection_close (pipeconn);
- pipeconn = NULL;
- }
-
- if (slave_fifo_pipe_fd >= 0) {
- VE_IGNORE_EINTR (close (slave_fifo_pipe_fd));
- slave_fifo_pipe_fd = -1;
- }
-
- if (unixconn != NULL) {
- gdm_connection_close (unixconn);
- VE_IGNORE_EINTR (g_unlink (GDM_SUP_SOCKET));
- unixconn = NULL;
- }
-
- pidfile = GDM_PID_FILE;
- if (pidfile != NULL) {
- VE_IGNORE_EINTR (g_unlink (pidfile));
- }
-
-#ifdef HAVE_LOGINDEVPERM
- (void) di_devperm_logout ("/dev/console");
-#endif /* HAVE_LOGINDEVPERM */
-}
-
-#ifdef __sun
-void
-gdm_rmdir (char *thedir)
-{
- DIR *odir;
- struct stat buf;
- struct dirent *dp;
- char thefile[FILENAME_MAX];
-
- if ((stat(thedir, &buf) == -1) || ! S_ISDIR(buf.st_mode))
- return ;
-
- if ((rmdir (thedir) == -1) && (errno == EEXIST))
- {
- odir = opendir (thedir);
- do {
- errno = 0;
- if ((dp = readdir (odir)) != NULL)
- {
- if (strcmp (dp->d_name, ".") == 0 ||
- strcmp (dp->d_name, "..") == 0)
- continue ;
- snprintf (thefile, FILENAME_MAX, "%s/%s", thedir, dp->d_name);
- if (stat (thefile, &buf) == -1)
- continue ;
- if (S_ISDIR(buf.st_mode))
- gdm_rmdir (thefile);
- else
- g_unlink (thefile);
- }
- } while (dp != NULL);
- closedir (odir);
- rmdir (thedir);
- }
-}
-#endif
-
-static gboolean
-deal_with_x_crashes (GdmDisplay *d)
-{
- gboolean just_abort = FALSE;
- const char *failsafe = gdm_daemon_config_get_value_string (GDM_KEY_FAILSAFE_XSERVER);
- const char *keepscrashing = gdm_daemon_config_get_value_string (GDM_KEY_X_KEEPS_CRASHING);
-
- if ( ! d->failsafe_xserver &&
- ! ve_string_empty (failsafe)) {
- char *bin = ve_first_word (failsafe);
- /* Yay we have a failsafe */
- if ( ! ve_string_empty (bin) &&
- g_access (bin, X_OK) == 0) {
- gdm_info (_("%s: Trying failsafe X "
- "server %s"),
- "deal_with_x_crashes",
- failsafe);
- g_free (bin);
- g_free (d->command);
- d->command = g_strdup (failsafe);
- d->failsafe_xserver = TRUE;
- return TRUE;
- }
- g_free (bin);
- }
-
- /* Eeek X keeps crashing, let's try the XKeepsCrashing script */
- if ( ! ve_string_empty (keepscrashing) &&
- g_access (keepscrashing, X_OK|R_OK) == 0) {
- pid_t pid;
-
- gdm_info (_("%s: Running the "
- "XKeepsCrashing script"),
- "deal_with_x_crashes");
-
- extra_process = pid = fork ();
- if (pid < 0)
- extra_process = 0;
-
- if (pid == 0) {
- char *argv[2];
- char *xlog = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_LOG_DIR), d->name, ".log");
-
- gdm_unset_signals ();
-
- /* Also make a new process group so that we may use
- * kill -(extra_process) to kill extra process and all its
- * possible children */
- setsid ();
-
- if (gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP))
- gdm_xdmcp_close ();
-
- gdm_close_all_descriptors (0 /* from */, -1 /* except */, -1 /* except2 */);
-
- /* No error checking here - if it's messed the best response
- * is to ignore & try to continue */
- gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
- gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
- gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
-
- argv[0] = (char *)gdm_daemon_config_get_value_string (GDM_KEY_X_KEEPS_CRASHING);
- argv[1] = NULL;
-
- gdm_restoreenv ();
-
- /* unset DISPLAY and XAUTHORITY if they exist
- * so that gdialog (if used) doesn't get confused */
- g_unsetenv ("DISPLAY");
- g_unsetenv ("XAUTHORITY");
-
- /* some promised variables */
- g_setenv ("XLOG", xlog, TRUE);
- g_setenv ("BINDIR", BINDIR, TRUE);
- g_setenv ("SBINDIR", SBINDIR, TRUE);
- g_setenv ("LIBEXECDIR", LIBEXECDIR, TRUE);
- g_setenv ("SYSCONFDIR", GDMCONFDIR, TRUE);
-
- /* To enable gettext stuff in the script */
- g_setenv ("TEXTDOMAIN", GETTEXT_PACKAGE, TRUE);
- g_setenv ("TEXTDOMAINDIR", GNOMELOCALEDIR, TRUE);
-
- if ( ! gdm_ok_console_language ()) {
- g_unsetenv ("LANG");
- g_unsetenv ("LC_ALL");
- g_unsetenv ("LC_MESSAGES");
- g_setenv ("LANG", "C", TRUE);
- g_setenv ("UNSAFE_TO_TRANSLATE", "yes", TRUE);
- }
-
- VE_IGNORE_EINTR (execv (argv[0], argv));
-
- /* yaikes! */
- _exit (32);
- } else if (pid > 0) {
- int status;
-
- if (extra_process > 1) {
- int ret;
- int killsignal = SIGTERM;
- int storeerrno;
- errno = 0;
- ret = waitpid (extra_process, &status, WNOHANG);
- do {
- /* wait for some signal, yes this is a race */
- if (ret <= 0)
- sleep (10);
- errno = 0;
- ret = waitpid (extra_process, &status, WNOHANG);
- storeerrno = errno;
- if ((ret <= 0) && gdm_daemon_config_signal_terminthup_was_notified ()) {
- kill (-(extra_process), killsignal);
- killsignal = SIGKILL;
- }
- } while (ret == 0 || (ret < 0 && storeerrno == EINTR));
- }
- extra_process = 0;
-
- if (WIFEXITED (status) &&
- WEXITSTATUS (status) == 0) {
- /* Yay, the user wants to try again, so
- * here we go */
- return TRUE;
- } else if (WIFEXITED (status) &&
- WEXITSTATUS (status) == 32) {
- /* We couldn't run the script, just drop through */
- ;
- } else {
- /* Things went wrong. */
- just_abort = TRUE;
- }
- }
-
- /* if we failed to fork, or something else has happened,
- * we fall through to the other options below */
- }
-
- /* if we have "open" we can talk to the user, not as user
- * friendly as the above script, but getting there */
- if ( ! just_abort &&
- g_access (LIBEXECDIR "/gdmopen", X_OK) == 0) {
- /* Shit if we knew what the program was to tell the user,
- * the above script would have been defined and we'd run
- * it for them */
- const char *error =
- C_(N_("The X server (your graphical interface) "
- "cannot be started. It is likely that it is not "
- "set up correctly. You will need to log in on a "
- "console and rerun the X configuration "
- "application, then restart GDM."));
- gdm_text_message_dialog (error);
- } /* else {
- * At this point .... screw the user, we don't know how to
- * talk to him. He's on some 'l33t system anyway, so syslog
- * reading will do him good
- * } */
-
- gdm_error (_("Failed to start X server several times in a short time period; disabling display %s"), d->name);
-
- return FALSE;
-}
-
-static gboolean
-try_command (const char *command,
- int *statusp)
-{
- GError *error;
- gboolean res;
- int status;
-
- g_debug ("Running %s", command);
-
- error = NULL;
- res = g_spawn_command_line_sync (command, NULL, NULL, &status, &error);
- if (error != NULL) {
- g_warning ("Command failed %s: %s", command, error->message);
- g_error_free (error);
- }
-
- *statusp = 0;
-
- if (WIFEXITED (status)) {
- *statusp = WEXITSTATUS (status);
- }
-
- return res;
-}
-
-static gboolean
-try_commands (const char **array)
-{
- int i;
- int status;
- gboolean ret;
-
- ret = FALSE;
-
- /* the idea here is to try the first available command and return if it succeeded */
-
- for (i = 0; array[i] != NULL; i++) {
- if (try_command (array[i], &status)) {
- ret = (status == 0);
-
- if (! ret) {
- gdm_error (_("command failed %s: %d"), array[i], status);
- }
-
- break;
- }
- }
-
- return ret;
-}
-
-static void
-suspend_machine (void)
-{
- const gchar **suspend;
-
- suspend = gdm_daemon_config_get_value_string_array (GDM_KEY_SUSPEND);
-
- gdm_info (_("Master suspending..."));
-
- if (suspend == NULL) {
- return;
- }
-
- try_commands (suspend);
-}
-
-#ifdef __linux__
-static void
-change_to_first_and_clear (gboolean restart)
-{
- gdm_change_vt (1);
- VE_IGNORE_EINTR (close (0));
- VE_IGNORE_EINTR (close (1));
- VE_IGNORE_EINTR (close (2));
- VE_IGNORE_EINTR (open ("/dev/tty1", O_WRONLY));
- VE_IGNORE_EINTR (open ("/dev/tty1", O_WRONLY));
- VE_IGNORE_EINTR (open ("/dev/tty1", O_WRONLY));
-
- g_setenv ("TERM", "linux", TRUE);
-
- /* evil hack that will get the fonts right */
- if (g_access ("/bin/bash", X_OK) == 0)
- system ("/bin/bash -l -c /bin/true");
-
- /* clear screen and set to red */
- printf ("\033[H\033[J\n\n\033[1m---\n\033[1;31m ");
-
- if (restart)
- printf (_("System is restarting, please wait ..."));
- else
- printf (_("System is shutting down, please wait ..."));
- /* set to black */
- printf ("\033[0m\n\033[1m---\033[0m\n\n");
-}
-#endif /* __linux__ */
-
-static void
-halt_machine (void)
-{
- const char **s;
-
- g_debug (_("Master halting..."));
-
- s = gdm_daemon_config_get_value_string_array (GDM_KEY_HALT);
-
- if (try_commands (s)) {
- /* maybe these don't run but oh well - there isn't
- really a good way to know a priori if the command
- will succeed. */
- gdm_final_cleanup ();
- VE_IGNORE_EINTR (g_chdir ("/"));
-#ifdef __linux__
- change_to_first_and_clear (FALSE);
-#endif /* __linux */
-
- }
-}
-
-static void
-restart_machine (void)
-{
- const char **s;
-
- g_debug (_("Restarting computer..."));
-
- s = gdm_daemon_config_get_value_string_array (GDM_KEY_REBOOT);
-
- if (try_commands (s)) {
- gdm_final_cleanup ();
- VE_IGNORE_EINTR (g_chdir ("/"));
-
-#ifdef __linux__
- change_to_first_and_clear (TRUE);
-#endif /* __linux */
-
- }
-}
-
-static void
-custom_cmd (long cmd_id)
-{
- gchar * key_string;
-
- if (cmd_id < 0 || cmd_id >= GDM_CUSTOM_COMMAND_MAX) {
- /* We are just feeling very paranoid */
- gdm_error (_("custom_cmd: Custom command index %ld outside permitted range [0,%d)"),
- cmd_id, GDM_CUSTOM_COMMAND_MAX);
- return;
- }
-
- key_string = g_strdup_printf ("%s%ld=", GDM_KEY_CUSTOM_CMD_NO_RESTART_TEMPLATE, cmd_id);
- if (gdm_daemon_config_get_value_bool (key_string))
- custom_cmd_no_restart (cmd_id);
- else
- custom_cmd_restart (cmd_id);
-
- g_free(key_string);
-}
-
-static void
-custom_cmd_restart (long cmd_id)
-{
- gchar * key_string;
- char **argv;
- const char *s;
-
- g_debug (_("Executing custom command %ld with restart option..."), cmd_id);
-
- gdm_final_cleanup ();
- VE_IGNORE_EINTR (g_chdir ("/"));
-
-#ifdef __linux__
- change_to_first_and_clear (TRUE);
-#endif /* __linux */
-
- key_string = g_strdup_printf ("%s%ld=", GDM_KEY_CUSTOM_CMD_TEMPLATE, cmd_id);
-
- argv = NULL;
- s = gdm_daemon_config_get_value_string (key_string);
- g_free (key_string);
- if (s != NULL) {
- g_shell_parse_argv (s, NULL, &argv, NULL);
- }
-
- if (argv != NULL && argv[0] != NULL)
- VE_IGNORE_EINTR (execv (argv[0], argv));
-
- g_strfreev (argv);
-
- gdm_error (_("%s: Execution of custom command failed: %s"),
- "gdm_child_action", strerror (errno));
-}
-
-static void
-custom_cmd_no_restart (long cmd_id)
-{
- pid_t pid;
-
- g_debug (_("Executing custom command %ld with no restart option ..."), cmd_id);
-
- pid = fork ();
-
- if (pid < 0) {
- /*failed fork*/
- gdm_error (_("custom_cmd: forking process for custom command %ld failed"), cmd_id);
- return;
- }
- else if (pid == 0) {
- /* child */
- char **argv;
- const char *s;
- gchar *key_string;
-
- key_string = g_strdup_printf ("%s%ld=", GDM_KEY_CUSTOM_CMD_TEMPLATE, cmd_id);
-
- argv = NULL;
- s = gdm_daemon_config_get_value_string (key_string);
- g_free (key_string);
- if (s != NULL) {
- g_shell_parse_argv (s, NULL, &argv, NULL);
- }
-
- if (argv != NULL && argv[0] != NULL)
- VE_IGNORE_EINTR (execv (argv[0], argv));
-
- g_strfreev (argv);
-
- gdm_error (_("%s: Execution of custom command failed: %s"),
- "gdm_child_action", strerror (errno));
- _exit (0);
- }
- else {
- /* parent */
- gint exitstatus = 0, status;
- pid_t p_stat = waitpid (1, &exitstatus, WNOHANG);
- if (p_stat > 0) {
- if G_LIKELY (WIFEXITED (exitstatus)){
- status = WEXITSTATUS (exitstatus);
- g_debug (_("custom_cmd: child %d returned %d"), p_stat, status);
- }
- return;
- }
- }
-}
-
-static gboolean
-gdm_cleanup_children (void)
-{
- pid_t pid;
- gint exitstatus = 0, status;
- GdmDisplay *d = NULL;
- gboolean crashed;
- gboolean sysmenu;
-
- /* Pid and exit status of slave that died */
- pid = waitpid (-1, &exitstatus, WNOHANG);
-
- if (pid <= 0)
- return FALSE;
-
- if G_LIKELY (WIFEXITED (exitstatus)) {
- status = WEXITSTATUS (exitstatus);
- crashed = FALSE;
- g_debug ("gdm_cleanup_children: child %d returned %d", pid, status);
- } else {
- status = EXIT_SUCCESS;
- crashed = TRUE;
- if (WIFSIGNALED (exitstatus)) {
- if (WTERMSIG (exitstatus) == SIGTERM ||
- WTERMSIG (exitstatus) == SIGINT) {
- /* we send these signals, sometimes children don't handle them */
- g_debug ("gdm_cleanup_children: child %d died of signal %d (TERM/INT)", pid,
- (int)WTERMSIG (exitstatus));
- } else {
- gdm_error ("gdm_cleanup_children: child %d crashed of signal %d", pid,
- (int)WTERMSIG (exitstatus));
- }
- } else {
- gdm_error ("gdm_cleanup_children: child %d crashed", pid);
- }
- }
-
- if (pid == extra_process) {
- /* an extra process died, yay! */
- extra_process = 0;
- extra_status = exitstatus;
- return TRUE;
- }
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (pid);
-
- if (d == NULL)
- return TRUE;
-
- /* whack connections about this display */
- if (unixconn != NULL)
- gdm_kill_subconnections_with_display (unixconn, d);
-
- if G_UNLIKELY (crashed) {
- gdm_error ("gdm_cleanup_children: Slave crashed, killing its "
- "children");
-
- if (d->sesspid > 1)
- kill (-(d->sesspid), SIGTERM);
- d->sesspid = 0;
- if (d->greetpid > 1)
- kill (-(d->greetpid), SIGTERM);
- d->greetpid = 0;
- if (d->chooserpid > 1)
- kill (-(d->chooserpid), SIGTERM);
- d->chooserpid = 0;
- if (d->servpid > 1)
- kill (d->servpid, SIGTERM);
- d->servpid = 0;
-
- if (gdm_daemon_config_get_value_bool (GDM_KEY_DYNAMIC_XSERVERS)) {
- /* XXX - This needs to be handled better */
- gdm_server_whack_lockfile (d);
- }
-
- /* race avoider */
- gdm_sleep_no_signal (1);
- }
-
- /* null all these, they are not valid most definately */
- d->servpid = 0;
- d->sesspid = 0;
- d->greetpid = 0;
- d->chooserpid = 0;
-
- /* definately not logged in now */
- d->logged_in = FALSE;
- g_free (d->login);
- d->login = NULL;
-
- /* Declare the display dead */
- d->slavepid = 0;
- d->dispstat = DISPLAY_DEAD;
-
- sysmenu = gdm_daemon_config_get_value_bool_per_display (GDM_KEY_SYSTEM_MENU, d->name);
-
- if ( ! sysmenu &&
- (status == DISPLAY_RESTARTGDM ||
- status == DISPLAY_REBOOT ||
- status == DISPLAY_SUSPEND ||
- status == DISPLAY_HALT)) {
- gdm_info (_("Restart GDM, Restart machine, Suspend, or Halt request when there is no system menu from display %s"), d->name);
- status = DISPLAY_REMANAGE;
- }
-
- if ( ! d->attached &&
- (status == DISPLAY_RESTARTGDM ||
- status == DISPLAY_REBOOT ||
- status == DISPLAY_SUSPEND ||
- status == DISPLAY_HALT)) {
- gdm_info (_("Restart GDM, Restart machine, Suspend or Halt request from a non-static display %s"), d->name);
- status = DISPLAY_REMANAGE;
- }
-
- if (status == DISPLAY_RUN_CHOOSER) {
- /* use the chooser on the next run (but only if allowed) */
- if (sysmenu &&
- gdm_daemon_config_get_value_bool_per_display (GDM_KEY_CHOOSER_BUTTON, d->name))
- d->use_chooser = TRUE;
- status = DISPLAY_REMANAGE;
- /* go around the display loop detection, these are short
- * sessions, so this decreases the chances of the loop
- * detection being hit */
- d->last_loop_start_time = 0;
- }
-
- if (status == DISPLAY_CHOSEN) {
- /* forget about this indirect id, since this
- * display will be dead very soon, and we don't want it
- * to take the indirect display with it */
- d->indirect_id = 0;
- status = DISPLAY_REMANAGE;
- }
-
- if (status == DISPLAY_GREETERFAILED) {
- if (d->managetime + 10 >= time (NULL)) {
- d->try_different_greeter = TRUE;
- } else {
- d->try_different_greeter = FALSE;
- }
- /* now just remanage */
- status = DISPLAY_REMANAGE;
- } else {
- d->try_different_greeter = FALSE;
- }
-
- /* checkout if we can actually do stuff */
- switch (status) {
- case DISPLAY_REBOOT:
- if (gdm_daemon_config_get_value_string_array (GDM_KEY_REBOOT) == NULL)
- status = DISPLAY_REMANAGE;
- break;
- case DISPLAY_HALT:
- if (gdm_daemon_config_get_value_string_array (GDM_KEY_HALT) == NULL)
- status = DISPLAY_REMANAGE;
- break;
- case DISPLAY_SUSPEND:
- if (gdm_daemon_config_get_value_string_array (GDM_KEY_SUSPEND) == NULL)
- status = DISPLAY_REMANAGE;
- break;
- default:
- break;
- }
-
- /* if we crashed clear the theme */
- if (crashed) {
- g_free (d->theme_name);
- d->theme_name = NULL;
- }
-
- start_autopsy:
-
- /* Autopsy */
- switch (status) {
-
- case DISPLAY_ABORT: /* Bury this display for good */
- gdm_info (_("%s: Aborting display %s"),
- "gdm_child_action", d->name);
-
- gdm_try_logout_action (d);
- gdm_safe_restart ();
-
- gdm_display_unmanage (d);
-
- /* If there are some pending statics, start them now */
- gdm_start_first_unborn_local (3 /* delay */);
- break;
-
- case DISPLAY_REBOOT: /* Restart machine */
- restart_machine ();
-
- status = DISPLAY_REMANAGE;
- goto start_autopsy;
- break;
-
- case DISPLAY_HALT: /* Halt machine */
- halt_machine ();
-
- status = DISPLAY_REMANAGE;
- goto start_autopsy;
- break;
-
- case DISPLAY_SUSPEND: /* Suspend machine */
- /* XXX: this is ugly, why should there be a suspend like this,
- * see GDM_SOP_SUSPEND_MACHINE */
- suspend_machine ();
-
- status = DISPLAY_REMANAGE;
- goto start_autopsy;
- break;
-
- case DISPLAY_RESTARTGDM:
- gdm_restart_now ();
- break;
-
- case DISPLAY_XFAILED: /* X sucks */
- g_debug ("X failed!");
- /* inform about error if needed */
- if (d->socket_conn != NULL) {
- GdmConnection *conn = d->socket_conn;
- d->socket_conn = NULL;
- gdm_connection_set_close_notify (conn, NULL, NULL);
- gdm_connection_write (conn, "ERROR 3 X failed\n");
- }
-
- gdm_try_logout_action (d);
- gdm_safe_restart ();
-
- /* in remote/flexi case just drop to _REMANAGE */
- if (d->type == TYPE_STATIC) {
- time_t now = time (NULL);
- d->x_faileds++;
- /* This really is likely the first time if it's been,
- some time, say 5 minutes */
- if (now - d->last_x_failed > (5*60)) {
- /* reset */
- d->x_faileds = 1;
- d->last_x_failed = now;
- /* well sleep at least 3 seconds before starting */
- d->sleep_before_run = 3;
- } else if (d->x_faileds >= 3) {
- g_debug ("gdm_child_action: dealing with X crashes");
- if ( ! deal_with_x_crashes (d)) {
- g_debug ("gdm_child_action: Aborting display");
- /* an original way to deal with these things:
- * "Screw you guys, I'm going home!" */
- gdm_display_unmanage (d);
-
- /* If there are some pending statics,
- * start them now */
- gdm_start_first_unborn_local (3 /* delay */);
- break;
- }
- g_debug ("gdm_child_action: Trying again");
-
- /* reset */
- d->x_faileds = 0;
- d->last_x_failed = 0;
- } else {
- /* well sleep at least 3 seconds before starting */
- d->sleep_before_run = 3;
- }
- /* go around the display loop detection, we're doing
- * our own here */
- d->last_loop_start_time = 0;
- }
- /* fall through */
-
- case DISPLAY_REMANAGE: /* Remanage display */
- default:
- g_debug ("gdm_child_action: In remanage");
-
- /* if we did REMANAGE, that means that we're no longer failing */
- if (status == DISPLAY_REMANAGE) {
- /* reset */
- d->x_faileds = 0;
- d->last_x_failed = 0;
- }
-
- /* inform about error if needed */
- if (d->socket_conn != NULL) {
- GdmConnection *conn = d->socket_conn;
- d->socket_conn = NULL;
- gdm_connection_set_close_notify (conn, NULL, NULL);
- gdm_connection_write (conn, "ERROR 2 Startup errors\n");
- }
-
- gdm_try_logout_action (d);
- gdm_safe_restart ();
-
- /* This is a static server so we start a new slave */
- if (d->type == TYPE_STATIC) {
- if ( ! gdm_display_manage (d)) {
- gdm_display_unmanage (d);
- /* If there are some pending statics,
- * start them now */
- gdm_start_first_unborn_local (3 /* delay */);
- }
- } else if (d->type == TYPE_FLEXI || d->type == TYPE_FLEXI_XNEST) {
- /* if this was a chooser session and we have chosen a host,
- then we don't want to unmanage, we want to manage and
- choose that host */
- if (d->chosen_hostname != NULL || d->use_chooser) {
- if ( ! gdm_display_manage (d)) {
- gdm_display_unmanage (d);
- }
- } else {
- /* else, this is a one time thing */
- gdm_display_unmanage (d);
- }
- /* Remote displays will send a request to be managed */
- } else /* TYPE_XDMCP */ {
- gdm_display_unmanage (d);
- }
-
- break;
- }
-
- gdm_try_logout_action (d);
- gdm_safe_restart ();
-
- return TRUE;
-}
-
-static void
-gdm_restart_now (void)
-{
- gdm_info (_("GDM restarting ..."));
- gdm_final_cleanup ();
- gdm_restoreenv ();
- VE_IGNORE_EINTR (execvp (stored_argv[0], stored_argv));
- gdm_error (_("Failed to restart self"));
- _exit (1);
-}
-
-static void
-gdm_safe_restart (void)
-{
- GSList *li;
- GSList *displays;
-
- displays = gdm_daemon_config_get_display_list ();
-
- if ( ! gdm_restart_mode)
- return;
-
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *d = li->data;
-
- if (d->logged_in)
- return;
- }
-
- gdm_restart_now ();
-}
-
-static void
-gdm_do_logout_action (GdmLogoutAction logout_action)
-{
- switch (logout_action) {
- case GDM_LOGOUT_ACTION_HALT:
- halt_machine ();
- break;
-
- case GDM_LOGOUT_ACTION_REBOOT:
- restart_machine ();
- break;
-
- case GDM_LOGOUT_ACTION_SUSPEND:
- suspend_machine ();
- break;
-
- default:
- /* This is a bit ugly but its the only place we can
- check for the range of values */
- if (logout_action >= GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST &&
- logout_action <= GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST)
- custom_cmd (logout_action - GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST);
- break;
- }
-}
-
-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 &&
- ! disp->logged_in) {
- gdm_do_logout_action (disp->logout_action);
- disp->logout_action = GDM_LOGOUT_ACTION_NONE;
- return;
- }
-
- if (safe_logout_action == GDM_LOGOUT_ACTION_NONE)
- return;
-
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *d = li->data;
-
- if (d->logged_in)
- return;
- }
-
- gdm_do_logout_action (safe_logout_action);
- safe_logout_action = GDM_LOGOUT_ACTION_NONE;
-}
-
-static void
-main_daemon_abrt (int sig)
-{
- /* FIXME: note that this could mean out of memory */
- gdm_error (_("main daemon: Got SIGABRT. Something went very wrong. Going down!"));
- gdm_final_cleanup ();
- exit (EXIT_FAILURE);
-}
-
-static gboolean
-mainloop_sig_callback (int sig, gpointer data)
-{
- /* signals are at somewhat random times aren't they? */
- gdm_random_tick ();
-
- g_debug ("mainloop_sig_callback: Got signal %d", (int)sig);
- switch (sig)
- {
- case SIGCHLD:
- while (gdm_cleanup_children ())
- ;
- break;
-
- case SIGINT:
- case SIGTERM:
- g_debug ("mainloop_sig_callback: Got TERM/INT. Going down!");
- gdm_final_cleanup ();
- exit (EXIT_SUCCESS);
- break;
-
-#ifdef SIGXFSZ
- case SIGXFSZ:
- gdm_error ("main daemon: Hit file size rlimit, restarting!");
- gdm_restart_now ();
- break;
-#endif
-
-#ifdef SIGXCPU
- case SIGXCPU:
- gdm_error ("main daemon: Hit CPU rlimit, restarting!");
- gdm_restart_now ();
- break;
-#endif
-
- case SIGHUP:
- gdm_restart_now ();
- break;
-
- case SIGUSR1:
- gdm_restart_mode = TRUE;
- gdm_safe_restart ();
- break;
-
- default:
- break;
- }
-
- return TRUE;
-}
-
-/*
- * main: The main daemon control
- */
-
-static void
-store_argv (int argc, char *argv[])
-{
- int i;
-
- 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;
-}
-
-static void
-close_notify (gpointer data)
-{
- GdmConnection **conn = data;
- * conn = NULL;
-}
-
-static void
-create_connections (void)
-{
- int p[2];
- gchar *path;
-
- path = g_build_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), ".gdmfifo", NULL);
- fifoconn = gdm_connection_open_fifo (path, 0660);
- g_free (path);
-
- if G_LIKELY (fifoconn != NULL) {
- gdm_connection_set_handler (fifoconn,
- gdm_handle_message,
- NULL /* data */,
- NULL /* destroy_notify */);
- gdm_connection_set_close_notify (fifoconn,
- &fifoconn,
- close_notify);
- }
-
- if G_UNLIKELY (pipe (p) < 0) {
- slave_fifo_pipe_fd = -1;
- pipeconn = NULL;
- } else {
- slave_fifo_pipe_fd = p[1];
- pipeconn = gdm_connection_open_fd (p[0]);
- }
-
- if G_LIKELY (pipeconn != NULL) {
- gdm_connection_set_handler (pipeconn,
- gdm_handle_message,
- NULL /* data */,
- NULL /* destroy_notify */);
- gdm_connection_set_close_notify (pipeconn,
- &pipeconn,
- close_notify);
- } else {
- VE_IGNORE_EINTR (close (p[0]));
- VE_IGNORE_EINTR (close (p[1]));
- slave_fifo_pipe_fd = -1;
- }
-
- unixconn = gdm_connection_open_unix (GDM_SUP_SOCKET, 0666);
-
- if G_LIKELY (unixconn != NULL) {
- gdm_connection_set_handler (unixconn,
- gdm_handle_user_message,
- NULL /* data */,
- NULL /* destroy_notify */);
- gdm_connection_set_nonblock (unixconn, TRUE);
- gdm_connection_set_close_notify (unixconn,
- &unixconn,
- close_notify);
- }
-}
-
-static void
-calc_sqrt2 (void)
-{
- unsigned long n = 0, h = 0;
- double x;
- printf ("\n");
- for (;;) {
- x = g_random_double_range (1.0, 2.0);
- if (x*x <= 2.0)
- h++;
- n++;
- if ( ! (n & 0xfff)) {
- double sqrttwo = 1.0 + ((double)h)/(double)n;
- printf ("sqrt(2) ~~ %1.10f\t(1 + %lu/%lu) "
- "iteration: %lu \r",
- sqrttwo, h, n, n);
- }
- }
-}
-
-GOptionEntry options [] = {
- { "nodaemon", '\0', 0, G_OPTION_ARG_NONE,
- &no_daemon, N_("Do not fork into the background"), NULL },
- { "no-console", '\0', 0, G_OPTION_ARG_NONE,
- &no_console, N_("No console (static) servers to be run"), NULL },
- { "config", '\0', 0, G_OPTION_ARG_STRING,
- &config_file, N_("Alternative GDM System Defaults configuration file"), N_("CONFIGFILE") },
- { "preserve-ld-vars", '\0', 0, G_OPTION_ARG_NONE,
- &preserve_ld_vars, N_("Preserve LD_* variables"), NULL },
- { "version", '\0', 0, G_OPTION_ARG_NONE,
- &print_version, N_("Print GDM version"), NULL },
- { "wait-for-go", '\0', 0, G_OPTION_ARG_NONE,
- &gdm_wait_for_go, N_("Start the first X server but then halt until we get a GO in the fifo"), NULL },
- { "monte-carlo-sqrt2", 0, 0, G_OPTION_ARG_NONE,
- &monte_carlo_sqrt2, NULL, NULL },
- { NULL }
-};
-
-static gboolean
-linux_only_is_running (pid_t pid)
-{
- char resolved_self[PATH_MAX];
- char resolved_running[PATH_MAX];
-
- char *running = g_strdup_printf ("/proc/%lu/exe", (gulong)pid);
-
- if (realpath ("/proc/self/exe", resolved_self) == NULL) {
- g_free (running);
- /* probably not a linux system */
- return TRUE;
- }
-
- if (realpath (running, resolved_running) == NULL) {
- g_free (running);
- /* probably not a linux system */
- return TRUE;
- }
-
- g_free (running);
-
- if (strcmp (resolved_running, resolved_self) == 0)
- return TRUE;
- return FALSE;
-}
-
-static void
-ensure_desc_012 (void)
-{
- int fd;
- /* We here ensure descriptors 0, 1 and 2
- * we of course count on the fact that open
- * opens the lowest available descriptor */
- for (;;) {
- fd = gdm_open_dev_null (O_RDWR);
- /* Once we are up to 3, we're beyond stdin,
- * stdout and stderr */
- if (fd >= 3) {
- VE_IGNORE_EINTR (close (fd));
- break;
- }
- }
-}
-
-/* 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
-initial_term_int (int signal)
-{
- if (extra_process > 1)
- kill (-(extra_process), SIGTERM);
- _exit (EXIT_FAILURE);
-}
-
-static void
-gdm_make_global_cookie (void)
-{
- FILE *fp;
- char *file;
-
- gdm_cookie_generate ((char **)&gdm_global_cookie, (char **)&gdm_global_bcookie);
-
- file = g_build_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), ".cookie", NULL);
- VE_IGNORE_EINTR (g_unlink (file));
-
- fp = gdm_safe_fopen_w (file, 0600);
- if G_UNLIKELY (fp == NULL) {
- gdm_error (_("Can't open %s for writing"), file);
- g_free (file);
- return;
- }
-
- VE_IGNORE_EINTR (fprintf (fp, "%s\n", gdm_global_cookie));
-
- /* FIXME: What about out of disk space errors? */
- errno = 0;
- VE_IGNORE_EINTR (fclose (fp));
- if G_UNLIKELY (errno != 0) {
- gdm_error (_("Can't write to %s: %s"), file,
- strerror (errno));
- }
-
- g_free (file);
-}
-
-int
-main (int argc, char *argv[])
-{
- FILE *pf;
- sigset_t mask;
- struct sigaction sig, child, abrt;
- GOptionContext *ctx;
- const char *pidfile;
- int i;
-
- /* semi init pseudorandomness */
- gdm_random_tick ();
-
- /* We here ensure descriptors 0, 1 and 2 */
- ensure_desc_012 ();
-
- /* store all initial stuff, args, env, rlimits, runlevel */
- store_argv (argc, argv);
- gdm_saveenv ();
- gdm_get_initial_limits ();
-
- bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
- textdomain (GETTEXT_PACKAGE);
-
- setlocale (LC_ALL, "");
-
- /* Initialize runtime environment */
- umask (022);
-
- g_type_init ();
-
- ctx = g_option_context_new (_("- The GNOME login manager"));
- g_option_context_add_main_entries (ctx, options, _("main options"));
-
- /* preprocess the arguments to support the xdm style -nodaemon
- * option
- */
- for (i = 0; i < argc; i++) {
- if (strcmp (argv[i], "-nodaemon") == 0)
- argv[i] = (char *) "--nodaemon";
- }
-
- g_option_context_parse (ctx, &argc, &argv, NULL);
- g_option_context_free (ctx);
-
- if (monte_carlo_sqrt2) {
- calc_sqrt2 ();
- return 0;
- }
-
- if (print_version) {
- printf ("GDM %s\n", VERSION);
- fflush (stdout);
- 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 */
- gdm_error (_("Only root wants to run GDM\n"));
- exit (-1);
- }
-
- main_loop = g_main_loop_new (NULL, FALSE);
-
- 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);
-
- /*
- * Do not call gdm_fail before calling gdm_config_parse ()
- * since the gdm_fail function uses config data
- */
- if G_UNLIKELY (sigaction (SIGTERM, &sig, NULL) < 0)
- gdm_fail (_("%s: Error setting up %s signal handler: %s"),
- "main", "TERM", strerror (errno));
-
- if G_UNLIKELY (sigaction (SIGINT, &sig, NULL) < 0)
- gdm_fail (_("%s: Error setting up %s signal handler: %s"),
- "main", "INT", strerror (errno));
-
- /* get the name of the root user */
- gdm_root_user ();
-
- pidfile = GDM_PID_FILE;
-
- /* Check if another gdm process is already running */
- if (g_access (pidfile, R_OK) == 0) {
-
- /* Check if the existing process is still alive. */
- gint pidv;
-
- pf = fopen (pidfile, "r");
-
- if (pf != NULL &&
- fscanf (pf, "%d", &pidv) == 1 &&
- kill (pidv, 0) == 0 &&
- linux_only_is_running (pidv)) {
- /* make sure the pid file doesn't get wiped */
- VE_IGNORE_EINTR (fclose (pf));
- gdm_fail (_("GDM already running. Aborting!"));
- }
-
- if (pf != NULL)
- VE_IGNORE_EINTR (fclose (pf));
- }
-
- /* Become daemon unless started in -nodaemon mode or child of init */
- if (no_daemon || getppid () == 1) {
-
- /* Write pid to pidfile */
- errno = 0;
- if ((pf = gdm_safe_fopen_w (pidfile, 0644)) != NULL) {
- errno = 0;
- VE_IGNORE_EINTR (fprintf (pf, "%d\n", (int)getpid ()));
- VE_IGNORE_EINTR (fclose (pf));
- if (errno != 0) {
- /* FIXME: how to handle this? */
- gdm_fdprintf (2, _("Cannot write PID file %s: possibly out of diskspace. Error: %s\n"),
- pidfile, strerror (errno));
- gdm_error (_("Cannot write PID file %s: possibly out of diskspace. Error: %s"),
- pidfile, strerror (errno));
-
- }
- } else if (errno != 0) {
- /* FIXME: how to handle this? */
- gdm_fdprintf (2, _("Cannot write PID file %s: possibly out of diskspace. Error: %s\n"),
- pidfile, strerror (errno));
- gdm_error (_("Cannot write PID file %s: possibly out of diskspace. Error: %s"),
- pidfile, strerror (errno));
-
- }
-
- VE_IGNORE_EINTR (g_chdir (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)));
- umask (022);
- }
- else
- gdm_daemonify ();
-
-#ifdef __sun
- g_unlink (SDTLOGIN_DIR);
- g_mkdir (SDTLOGIN_DIR, 0700);
-#endif
-
- /* Signal handling */
- ve_signal_add (SIGCHLD, mainloop_sig_callback, NULL);
- ve_signal_add (SIGTERM, mainloop_sig_callback, NULL);
- ve_signal_add (SIGINT, mainloop_sig_callback, NULL);
- ve_signal_add (SIGHUP, mainloop_sig_callback, NULL);
- ve_signal_add (SIGUSR1, mainloop_sig_callback, NULL);
-
- sig.sa_handler = ve_signal_notify;
- sig.sa_flags = SA_RESTART;
- sigemptyset (&sig.sa_mask);
-
- if G_UNLIKELY (sigaction (SIGTERM, &sig, NULL) < 0)
- gdm_fail (_("%s: Error setting up %s signal handler: %s"),
- "main", "TERM", strerror (errno));
-
- if G_UNLIKELY (sigaction (SIGINT, &sig, NULL) < 0)
- gdm_fail (_("%s: Error setting up %s signal handler: %s"),
- "main", "INT", strerror (errno));
-
- if G_UNLIKELY (sigaction (SIGHUP, &sig, NULL) < 0)
- gdm_fail (_("%s: Error setting up %s signal handler: %s"),
- "main", "HUP", strerror (errno));
-
- if G_UNLIKELY (sigaction (SIGUSR1, &sig, NULL) < 0)
- gdm_fail (_("%s: Error setting up %s signal handler: %s"),
- "main", "USR1", strerror (errno));
-
- /* some process limit signals we catch and restart on,
- note that we don't catch these in the slave, but then
- we catch those in the main daemon as slave crashing
- (terminated by signal), and we clean up appropriately */
-#ifdef SIGXCPU
- ve_signal_add (SIGXCPU, mainloop_sig_callback, NULL);
- if G_UNLIKELY (sigaction (SIGXCPU, &sig, NULL) < 0)
- gdm_fail (_("%s: Error setting up %s signal handler: %s"),
- "main", "XCPU", strerror (errno));
-#endif
-#ifdef SIGXFSZ
- ve_signal_add (SIGXFSZ, mainloop_sig_callback, NULL);
- if G_UNLIKELY (sigaction (SIGXFSZ, &sig, NULL) < 0)
- gdm_fail (_("%s: Error setting up %s signal handler: %s"),
- "main", "XFSZ", strerror (errno));
-#endif
-
- /* cannot use mainloop for SIGABRT, the handler can never
- return */
- abrt.sa_handler = main_daemon_abrt;
- abrt.sa_flags = SA_RESTART;
- sigemptyset (&abrt.sa_mask);
-
- if G_UNLIKELY (sigaction (SIGABRT, &abrt, NULL) < 0)
- gdm_fail (_("%s: Error setting up %s signal handler: %s"),
- "main", "ABRT", strerror (errno));
-
- child.sa_handler = ve_signal_notify;
- child.sa_flags = SA_RESTART|SA_NOCLDSTOP;
- sigemptyset (&child.sa_mask);
- sigaddset (&child.sa_mask, SIGCHLD);
-
- if G_UNLIKELY (sigaction (SIGCHLD, &child, NULL) < 0)
- gdm_fail (_("%s: Error setting up CHLD signal handler"), "gdm_main");
-
- sigemptyset (&mask);
- sigaddset (&mask, SIGINT);
- sigaddset (&mask, SIGTERM);
- sigaddset (&mask, SIGCHLD);
- sigaddset (&mask, SIGHUP);
- sigaddset (&mask, SIGUSR1);
- sigaddset (&mask, SIGABRT);
-#ifdef SIGXCPU
- sigaddset (&mask, SIGXCPU);
-#endif
-#ifdef SIGXFSZ
- sigaddset (&mask, SIGXFSZ);
-#endif
- sigprocmask (SIG_UNBLOCK, &mask, NULL);
-
- gdm_signal_ignore (SIGUSR2);
- gdm_signal_ignore (SIGPIPE);
-
- /* ignore power failures, up to user processes to
- * handle things correctly */
-#ifdef SIGPWR
- gdm_signal_ignore (SIGPWR);
-#endif
- /* can we ever even get this one? */
-#ifdef SIGLOST
- gdm_signal_ignore (SIGLOST);
-#endif
-
- g_debug ("gdm_main: Here we go...");
-
-#ifdef HAVE_LOGINDEVPERM
- di_devperm_login ("/dev/console", gdm_daemon_config_get_gdmuid (), gdm_daemon_config_get_gdmgid (), NULL);
-#endif /* HAVE_LOGINDEVPERM */
-
- /* Init XDMCP if applicable */
- if (gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP) && ! gdm_wait_for_go) {
- gdm_xdmcp_init ();
- }
-
- create_connections ();
-
- /* make sure things (currently /tmp/.ICE-unix and /tmp/.X11-unix)
- * are sane */
- gdm_ensure_sanity () ;
-
- /* Make us a unique global cookie to authenticate */
- gdm_make_global_cookie ();
-
- /* Start static X servers */
- gdm_start_first_unborn_local (0 /* delay */);
-
- /* Accept remote connections */
- if (gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP) && ! gdm_wait_for_go) {
- g_debug ("Accepting XDMCP connections...");
- gdm_xdmcp_run ();
- }
-
- /* We always exit via exit (), and sadly we need to g_main_quit ()
- * at times not knowing if it's this main or a recursive one we're
- * quitting.
- */
- while (1)
- {
- g_main_loop_run (main_loop);
- g_debug ("main: Exited main loop");
- }
-
- return EXIT_SUCCESS; /* Not reached */
-}
-
-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)
- return TRUE;
- }
- return FALSE;
-}
-
-static int
-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) {
- if (li->data == d)
- break;
- }
- /* next make sure it's unique */
- while (order_exists (order))
- order++;
- return order;
-}
-
-static void
-write_x_servers (GdmDisplay *d)
-{
- FILE *fp;
- char *file = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR), d->name, ".Xservers");
- int i;
- int bogusname;
-
- if (d->x_servers_order < 0)
- d->x_servers_order = get_new_order (d);
-
- fp = gdm_safe_fopen_w (file, 0644);
- if G_UNLIKELY (fp == NULL) {
- gdm_error (_("Can't open %s for writing"), file);
- g_free (file);
- return;
- }
-
- for (bogusname = 0, i = 0; i < d->x_servers_order; bogusname++, i++) {
- char buf[32];
- g_snprintf (buf, sizeof (buf), ":%d", bogusname);
- if (strcmp (buf, d->name) == 0)
- g_snprintf (buf, sizeof (buf), ":%d", ++bogusname);
- VE_IGNORE_EINTR (fprintf (fp, "%s local /usr/X11R6/bin/Xbogus\n", buf));
- }
-
- if (SERVER_IS_LOCAL (d)) {
- char **argv;
- char *command;
- int argc;
- argc = 0;
- argv = NULL;
- gdm_server_resolve_command_line (d,
- FALSE, /* resolve_flags */
- NULL, /* vtarg */
- &argc,
- &argv);
- command = g_strjoinv (" ", argv);
- g_strfreev (argv);
- VE_IGNORE_EINTR (fprintf (fp, "%s local %s\n", d->name, command));
- g_free (command);
- } else {
- VE_IGNORE_EINTR (fprintf (fp, "%s foreign\n", d->name));
- }
-
- /* FIXME: What about out of disk space errors? */
- errno = 0;
- VE_IGNORE_EINTR (fclose (fp));
- if G_UNLIKELY (errno != 0) {
- gdm_error (_("Can't write to %s: %s"), file,
- strerror (errno));
- }
-
- g_free (file);
-}
-
-static void
-send_slave_ack_dialog_int (GdmDisplay *d, int type, int response)
-{
- if (d->master_notify_fd >= 0) {
- char *not;
-
- not = g_strdup_printf ("%c%c%d\n", GDM_SLAVE_NOTIFY_RESPONSE, type, response);
- VE_IGNORE_EINTR (write (d->master_notify_fd, not, strlen (not)));
-
- g_free (not);
- }
- if (d->slavepid > 1) {
- /* now yield the CPU as the other process has more
- useful work to do then we do */
-#if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD)
- sched_yield ();
-#endif
- }
-}
-
-static void
-send_slave_ack_dialog_char (GdmDisplay *d, int type, const char *resp)
-{
- if (d->master_notify_fd >= 0) {
- if (resp == NULL) {
- char not[3];
-
- not[0] = GDM_SLAVE_NOTIFY_RESPONSE;
- not[1] = type;
- not[2] = '\n';
- VE_IGNORE_EINTR (write (d->master_notify_fd, not, 3));
- } else {
- char *not = g_strdup_printf ("%c%c%s\n",
- GDM_SLAVE_NOTIFY_RESPONSE,
- type,
- resp);
- VE_IGNORE_EINTR (write (d->master_notify_fd, not, strlen (not)));
- g_free (not);
- }
- }
- if (d->slavepid > 1) {
- /* now yield the CPU as the other process has more
- useful work to do then we do */
-#if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD)
- sched_yield ();
-#endif
- }
-}
-
-static void
-send_slave_ack (GdmDisplay *d, const char *resp)
-{
- if (d->master_notify_fd >= 0) {
- if (resp == NULL) {
- char not[2];
- not[0] = GDM_SLAVE_NOTIFY_ACK;
- not[1] = '\n';
- VE_IGNORE_EINTR (write (d->master_notify_fd, not, 2));
- } else {
- char *not = g_strdup_printf ("%c%s\n",
- GDM_SLAVE_NOTIFY_ACK,
- resp);
- VE_IGNORE_EINTR (write (d->master_notify_fd, not, strlen (not)));
- g_free (not);
- }
- }
- if (d->slavepid > 1) {
- kill (d->slavepid, SIGUSR2);
- /* now yield the CPU as the other process has more
- useful work to do then we do */
-#if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD)
- sched_yield ();
-#endif
- }
-}
-
-static void
-send_slave_command (GdmDisplay *d, const char *command)
-{
- if (d->master_notify_fd >= 0) {
- char *cmd = g_strdup_printf ("%c%s\n",
- GDM_SLAVE_NOTIFY_COMMAND,
- command);
- VE_IGNORE_EINTR (write (d->master_notify_fd, cmd, strlen (cmd)));
- g_free (cmd);
- }
- if (d->slavepid > 1) {
- kill (d->slavepid, SIGUSR2);
- /* now yield the CPU as the other process has more
- useful work to do then we do */
-#if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD)
- sched_yield ();
-#endif
- }
-}
-
-static void
-gdm_handle_message (GdmConnection *conn, const char *msg, gpointer data)
-{
- /* Evil!, all this for debugging? */
- if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG)) {
- if (strncmp (msg, GDM_SOP_COOKIE " ",
- strlen (GDM_SOP_COOKIE " ")) == 0) {
- char *s = g_strndup
- (msg, strlen (GDM_SOP_COOKIE " XXXX XX"));
- /* cut off most of the cookie for "security" */
- g_debug ("Handling message: '%s...'", s);
- g_free (s);
- } else if (strncmp (msg, GDM_SOP_SYSLOG " ",
- strlen (GDM_SOP_SYSLOG " ")) != 0) {
- /* Don't print out the syslog message as it will
- * be printed out anyway as that's the whole point
- * of the message. */
- g_debug ("Handling message: '%s'", msg);
- }
- }
-
- if (strncmp (msg, GDM_SOP_CHOSEN " ",
- strlen (GDM_SOP_CHOSEN " ")) == 0) {
- gdm_choose_data (msg);
- } else if (strncmp (msg, GDM_SOP_CHOSEN_LOCAL " ",
- strlen (GDM_SOP_CHOSEN_LOCAL " ")) == 0) {
- GdmDisplay *d;
- long slave_pid;
- char *p;
-
- if (sscanf (msg, GDM_SOP_CHOSEN_LOCAL " %ld", &slave_pid)
- != 1)
- return;
- p = strchr (msg, ' ');
- if (p != NULL)
- p = strchr (p+1, ' ');
- if (p == NULL)
- return;
- p++;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- g_free (d->chosen_hostname);
- d->chosen_hostname = g_strdup (p);
- g_debug ("Got CHOSEN_LOCAL == %s", p);
- /* send ack */
- send_slave_ack (d, NULL);
- }
- } else if (strncmp (msg, GDM_SOP_XPID " ",
- strlen (GDM_SOP_XPID " ")) == 0) {
- GdmDisplay *d;
- long slave_pid, pid;
-
- if (sscanf (msg, GDM_SOP_XPID " %ld %ld", &slave_pid, &pid)
- != 2)
- return;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- d->servpid = pid;
- g_debug ("Got XPID == %ld", (long)pid);
- /* send ack */
- send_slave_ack (d, NULL);
- }
- } else if (strncmp (msg, GDM_SOP_SESSPID " ",
- strlen (GDM_SOP_SESSPID " ")) == 0) {
- GdmDisplay *d;
- long slave_pid, pid;
-
- if (sscanf (msg, GDM_SOP_SESSPID " %ld %ld", &slave_pid, &pid)
- != 2)
- return;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- d->sesspid = pid;
- g_debug ("Got SESSPID == %ld", (long)pid);
- /* send ack */
- send_slave_ack (d, NULL);
- }
- } else if (strncmp (msg, GDM_SOP_GREETPID " ",
- strlen (GDM_SOP_GREETPID " ")) == 0) {
- GdmDisplay *d;
- long slave_pid, pid;
-
- if (sscanf (msg, GDM_SOP_GREETPID " %ld %ld", &slave_pid, &pid)
- != 2)
- return;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- d->greetpid = pid;
- g_debug ("Got GREETPID == %ld", (long)pid);
- /* send ack */
- send_slave_ack (d, NULL);
- }
- } else if (strncmp (msg, GDM_SOP_CHOOSERPID " ",
- strlen (GDM_SOP_CHOOSERPID " ")) == 0) {
- GdmDisplay *d;
- long slave_pid, pid;
-
- if (sscanf (msg, GDM_SOP_CHOOSERPID " %ld %ld",
- &slave_pid, &pid) != 2)
- return;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- d->chooserpid = pid;
- g_debug ("Got CHOOSERPID == %ld", (long)pid);
- /* send ack */
- send_slave_ack (d, NULL);
- }
- } else if (strncmp (msg, GDM_SOP_LOGGED_IN " ",
- strlen (GDM_SOP_LOGGED_IN " ")) == 0) {
- GdmDisplay *d;
- long slave_pid;
- int logged_in;
- if (sscanf (msg, GDM_SOP_LOGGED_IN " %ld %d", &slave_pid,
- &logged_in) != 2)
- return;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- d->logged_in = logged_in ? TRUE : FALSE;
- g_debug ("Got logged in == %s",
- d->logged_in ? "TRUE" : "FALSE");
-
- /* whack connections about this display if a user
- * just logged out since we don't want such
- * connections persisting to be authenticated */
- if ( ! logged_in && unixconn != NULL)
- gdm_kill_subconnections_with_display (unixconn, d);
-
- /* if the user just logged out,
- * let's see if it's safe to restart */
- if ( ! d->logged_in) {
- gdm_try_logout_action (d);
- gdm_safe_restart ();
- }
-
- /* send ack */
- send_slave_ack (d, NULL);
- }
- } else if (strncmp (msg, GDM_SOP_DISP_NUM " ",
- strlen (GDM_SOP_DISP_NUM " ")) == 0) {
- GdmDisplay *d;
- long slave_pid;
- int disp_num;
-
- if (sscanf (msg, GDM_SOP_DISP_NUM " %ld %d",
- &slave_pid, &disp_num) != 2)
- return;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- g_free (d->name);
- d->name = g_strdup_printf (":%d", disp_num);
- d->dispnum = disp_num;
- g_debug ("Got DISP_NUM == %d", disp_num);
- /* send ack */
- send_slave_ack (d, NULL);
- }
- } else if (strncmp (msg, GDM_SOP_VT_NUM " ",
- strlen (GDM_SOP_VT_NUM " ")) == 0) {
- GdmDisplay *d;
- long slave_pid;
- int vt_num;
-
- if (sscanf (msg, GDM_SOP_VT_NUM " %ld %d",
- &slave_pid, &vt_num) != 2)
- return;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- d->vt = vt_num;
- g_debug ("Got VT_NUM == %d", vt_num);
- /* send ack */
- send_slave_ack (d, NULL);
- }
- } else if (strncmp (msg, GDM_SOP_LOGIN " ",
- strlen (GDM_SOP_LOGIN " ")) == 0) {
- GdmDisplay *d;
- long slave_pid;
- char *p;
-
- if (sscanf (msg, GDM_SOP_LOGIN " %ld",
- &slave_pid) != 1)
- return;
- p = strchr (msg, ' ');
- if (p != NULL)
- p = strchr (p+1, ' ');
- if (p == NULL)
- return;
-
- p++;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- g_free (d->login);
- d->login = g_strdup (p);
- g_debug ("Got LOGIN == %s", p);
- /* send ack */
- send_slave_ack (d, NULL);
- }
- } else if (strncmp (msg, GDM_SOP_QUERYLOGIN " ",
- strlen (GDM_SOP_QUERYLOGIN " ")) == 0) {
- GdmDisplay *d;
- long slave_pid;
- char *p;
-
- if (sscanf (msg, GDM_SOP_QUERYLOGIN " %ld",
- &slave_pid) != 1)
- return;
- p = strchr (msg, ' ');
- if (p != NULL)
- p = strchr (p+1, ' ');
- if (p == NULL)
- return;
-
- p++;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- GString *resp = NULL;
- GSList *li;
- GSList *displays;
-
- displays = gdm_daemon_config_get_display_list ();
- g_debug ("Got QUERYLOGIN %s", p);
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *di = li->data;
- if (di->logged_in &&
- di->login != NULL &&
- strcmp (di->login, p) == 0) {
- gboolean migratable = FALSE;
-
- if (resp == NULL)
- resp = g_string_new (NULL);
- else
- resp = g_string_append_c (resp, ',');
-
- g_string_append (resp, di->name);
- g_string_append_c (resp, ',');
-
- if (d->attached && di->attached && di->vt > 0)
- migratable = TRUE;
- else if (gdm_daemon_config_get_value_string (GDM_KEY_XDMCP_PROXY_RECONNECT) != NULL &&
- d->type == TYPE_XDMCP_PROXY && di->type == TYPE_XDMCP_PROXY)
- migratable = TRUE;
-
- g_string_append_c (resp, migratable ? '1' : '0');
- }
- }
-
- /* send ack */
- if (resp != NULL) {
- send_slave_ack (d, resp->str);
- g_string_free (resp, TRUE);
- } else {
- send_slave_ack (d, NULL);
- }
- }
- } else if (strncmp (msg, GDM_SOP_MIGRATE " ",
- strlen (GDM_SOP_MIGRATE " ")) == 0) {
- GdmDisplay *d;
- 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;
- p = strchr (msg, ' ');
- if (p != NULL)
- p = strchr (p+1, ' ');
- if (p == NULL)
- return;
-
- p++;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
- if (d == NULL)
- return;
-
- g_debug ("Got MIGRATE %s", p);
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *di = li->data;
- if (di->logged_in && strcmp (di->name, p) == 0) {
- if (d->attached && di->vt > 0)
- gdm_change_vt (di->vt);
- else if (d->type == TYPE_XDMCP_PROXY && di->type == TYPE_XDMCP_PROXY)
- gdm_xdmcp_migrate (d, di);
- }
- }
- send_slave_ack (d, NULL);
- } else if (strncmp (msg, GDM_SOP_COOKIE " ",
- strlen (GDM_SOP_COOKIE " ")) == 0) {
- GdmDisplay *d;
- long slave_pid;
- char *p;
-
- if (sscanf (msg, GDM_SOP_COOKIE " %ld",
- &slave_pid) != 1)
- return;
- p = strchr (msg, ' ');
- if (p != NULL)
- p = strchr (p+1, ' ');
- if (p == NULL)
- return;
-
- p++;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- g_free (d->cookie);
- d->cookie = g_strdup (p);
- g_debug ("Got COOKIE == <secret>");
- /* send ack */
- send_slave_ack (d, NULL);
- }
- } else if (strncmp (msg, GDM_SOP_AUTHFILE " ",
- strlen (GDM_SOP_AUTHFILE " ")) == 0) {
- GdmDisplay *d;
- long slave_pid;
- char *p;
-
- if (sscanf (msg, GDM_SOP_AUTHFILE " %ld",
- &slave_pid) != 1)
- return;
- p = strchr (msg, ' ');
- if (p != NULL)
- p = strchr (p+1, ' ');
- if (p == NULL)
- return;
-
- p++;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- g_free (d->authfile);
- d->authfile = g_strdup (p);
- g_debug ("Got AUTHFILE == %s", d->authfile);
- /* send ack */
- send_slave_ack (d, NULL);
- }
- } else if (strncmp (msg, GDM_SOP_FLEXI_ERR " ",
- strlen (GDM_SOP_FLEXI_ERR " ")) == 0) {
- GdmDisplay *d;
- long slave_pid;
- int err;
-
- if (sscanf (msg, GDM_SOP_FLEXI_ERR " %ld %d",
- &slave_pid, &err) != 2)
- return;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- char *error = NULL;
- GdmConnection *conn = d->socket_conn;
- d->socket_conn = NULL;
-
- if (conn != NULL)
- gdm_connection_set_close_notify (conn,
- NULL, NULL);
-
- if (err == 3)
- error = "ERROR 3 X failed\n";
- else if (err == 4)
- error = "ERROR 4 X too busy\n";
- else if (err == 5)
- error = "ERROR 5 Nested display can't connect\n";
- else
- error = "ERROR 999 Unknown error\n";
- if (conn != NULL)
- gdm_connection_write (conn, error);
-
- g_debug ("Got FLEXI_ERR == %d", err);
- /* send ack */
- send_slave_ack (d, NULL);
- }
- } else if (strncmp (msg, GDM_SOP_FLEXI_OK " ",
- strlen (GDM_SOP_FLEXI_OK " ")) == 0) {
- GdmDisplay *d;
- long slave_pid;
-
- if (sscanf (msg, GDM_SOP_FLEXI_OK " %ld",
- &slave_pid) != 1)
- return;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- GdmConnection *conn = d->socket_conn;
- d->socket_conn = NULL;
-
- if (conn != NULL) {
- gdm_connection_set_close_notify (conn,
- NULL, NULL);
- if ( ! gdm_connection_printf (conn, "OK %s\n", d->name))
- gdm_display_unmanage (d);
- }
-
- g_debug ("Got FLEXI_OK");
- /* send ack */
- send_slave_ack (d, NULL);
- }
- } else if (strcmp (msg, GDM_SOP_SOFT_RESTART) == 0) {
- gdm_restart_mode = TRUE;
- 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);
- }
- } else if (strncmp (msg, GDM_SOP_SYSLOG " ",
- strlen (GDM_SOP_SYSLOG " ")) == 0) {
- char *p;
- long pid;
- int type;
- p = strchr (msg, ' ');
- if (p == NULL)
- return;
- p++;
- if (sscanf (p, "%ld", &pid) != 1)
- return;
- p = strchr (p, ' ');
- if (p == NULL)
- return;
- p++;
- if (sscanf (p, "%d", &type) != 1)
- return;
-
- p = strchr (p, ' ');
- if (p == NULL)
- return;
- 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)
- kill (d->greetpid, SIGHUP);
- else if (d->chooserpid > 1)
- kill (d->chooserpid, SIGHUP);
- }
- } 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;
- send_slave_command (d, GDM_NOTIFY_GO);
- }
- /* Init XDMCP if applicable */
- if (old_wait && gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP)) {
- if (gdm_xdmcp_init ()) {
- g_debug ("Accepting XDMCP connections...");
- gdm_xdmcp_run ();
- }
- }
- } else if (strncmp (msg, GDM_SOP_WRITE_X_SERVERS " ",
- strlen (GDM_SOP_WRITE_X_SERVERS " ")) == 0) {
- GdmDisplay *d;
- long slave_pid;
-
- if (sscanf (msg, GDM_SOP_WRITE_X_SERVERS " %ld",
- &slave_pid) != 1)
- return;
-
- /* Find out who this slave belongs to */
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- write_x_servers (d);
-
- /* send ack */
- send_slave_ack (d, NULL);
- }
- } else if (strncmp (msg, GDM_SOP_SUSPEND_MACHINE " ",
- strlen (GDM_SOP_SUSPEND_MACHINE " ")) == 0) {
- GdmDisplay *d;
- long slave_pid;
- gboolean sysmenu;
-
- if (sscanf (msg, GDM_SOP_SUSPEND_MACHINE " %ld", &slave_pid) != 1)
- return;
- d = gdm_display_lookup (slave_pid);
-
- gdm_info (_("Master suspending..."));
-
- sysmenu = gdm_daemon_config_get_value_bool_per_display (GDM_KEY_SYSTEM_MENU, d->name);
- if (sysmenu && gdm_daemon_config_get_value_string (GDM_KEY_SUSPEND) != NULL) {
- suspend_machine ();
- }
- } else if (strncmp (msg, GDM_SOP_CHOSEN_THEME " ",
- strlen (GDM_SOP_CHOSEN_THEME " ")) == 0) {
- GdmDisplay *d;
- long slave_pid;
- const char *p;
-
- if (sscanf (msg, GDM_SOP_CHOSEN_THEME " %ld", &slave_pid) != 1)
- return;
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- g_free (d->theme_name);
- d->theme_name = NULL;
-
- /* Syntax errors are partially OK here, if there
- was no theme argument we just wanted to clear the
- theme field */
- p = strchr (msg, ' ');
- if (p != NULL) {
- p = strchr (p+1, ' ');
- if (p != NULL) {
- while (*p == ' ')
- p++;
- if ( ! ve_string_empty (p))
- d->theme_name = g_strdup (p);
- }
- }
-
- send_slave_ack (d, NULL);
- }
- } else if (strncmp (msg, GDM_SOP_CUSTOM_CMD " ",
- strlen (GDM_SOP_CUSTOM_CMD " ")) == 0) {
- GdmDisplay *d;
- long slave_pid;
- long cmd_id;
-
- if (sscanf (msg, GDM_SOP_CUSTOM_CMD " %ld %ld", &slave_pid, &cmd_id) != 2)
- return;
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- custom_cmd (cmd_id);
- send_slave_ack (d, NULL);
- }
- } else if (strcmp (msg, GDM_SOP_FLEXI_XSERVER) == 0) {
- handle_flexi_server (NULL, TYPE_FLEXI, gdm_daemon_config_get_value_string (GDM_KEY_STANDARD_XSERVER),
- TRUE /* handled */,
- FALSE /* chooser */,
- NULL, 0, NULL, NULL, NULL);
- } else if (strncmp (msg, "opcode="GDM_SOP_SHOW_ERROR_DIALOG,
- strlen ("opcode="GDM_SOP_SHOW_ERROR_DIALOG)) == 0) {
- GdmDisplay *d;
- GtkMessageType type;
- char **list;
- char *ptr;
- char *error;
- char *details_label;
- char *details_file;
- long slave_pid;
- int uid, gid;
-
- list = g_strsplit (msg, "$$", -1);
-
- ptr = strchr (list[1], '=');
- slave_pid = atol (ptr + 1);
-
- ptr = strchr (list[2], '=');
- type = atoi (ptr + 1);
-
- ptr = strchr (list[3], '=');
- error = g_malloc0 (strlen (ptr));
- strcpy (error, ptr + 1);
-
- ptr = strchr (list[4], '=');
- details_label = g_malloc0 (strlen (ptr));
- strcpy (details_label, ptr + 1);
-
- ptr = strchr (list[5], '=');
- details_file = g_malloc0 (strlen (ptr));
- strcpy (details_file, ptr + 1);
-
- ptr = strchr (list[6], '=');
- uid = atoi (ptr + 1);
-
- ptr = strchr (list[7], '=');
- gid = atoi (ptr + 1);
-
- d = gdm_display_lookup (slave_pid);
-
- if (d != NULL) {
- if (GDM_AUTHFILE (d)) {
- VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0644));
- }
-
- /* 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));
- }
-
- send_slave_ack_dialog_char (d, GDM_SLAVE_NOTIFY_ERROR_RESPONSE, NULL);
- }
-
- g_free (error);
- g_free (details_label);
- g_free (details_file);
- g_strfreev (list);
- } else if (strncmp (msg, "opcode="GDM_SOP_SHOW_YESNO_DIALOG,
- strlen ("opcode="GDM_SOP_SHOW_YESNO_DIALOG)) == 0) {
- GdmDisplay *d;
- char **list;
- char *ptr;
- char *yesno_msg;
- long slave_pid;
- gboolean response_yesno;
-
- list = g_strsplit (msg, "$$", -1);
-
- ptr = strchr (list [1], '=');
- slave_pid = atol (ptr + 1);
-
- ptr = strchr (list [2], '=');
- yesno_msg = g_malloc0 (strlen (ptr));
- strcpy (yesno_msg, ptr + 1);
-
- d = gdm_display_lookup (slave_pid);
- if (d != NULL) {
- if (GDM_AUTHFILE (d)) {
- VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0644));
- }
-
- response_yesno = gdm_errorgui_failsafe_yesno (d, yesno_msg);
-
- send_slave_ack_dialog_int (d, GDM_SLAVE_NOTIFY_YESNO_RESPONSE, response_yesno);
-
- if (GDM_AUTHFILE (d)) {
- VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0640));
- }
- }
-
- g_free (yesno_msg);
- g_strfreev (list);
- } else if (strncmp (msg, "opcode="GDM_SOP_SHOW_QUESTION_DIALOG,
- strlen ("opcode="GDM_SOP_SHOW_QUESTION_DIALOG)) == 0) {
- GdmDisplay *d;
- char **list;
- char *ptr;
- char *question_msg;
- char *response_question;
- long slave_pid;
- gboolean echo;
-
- list = g_strsplit (msg, "$$", -1);
-
- ptr = strchr (list [1], '=');
- slave_pid = atol (ptr + 1);
-
- ptr = strchr (list [2], '=');
- question_msg = g_malloc0 (strlen (ptr));
- strcpy (question_msg, ptr + 1);
-
- ptr = strchr (list [3], '=');
- echo = atoi (ptr + 1);
-
- d = gdm_display_lookup (slave_pid);
- if (d != NULL) {
- if (GDM_AUTHFILE (d)) {
- VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0644));
- }
-
- response_question = gdm_errorgui_failsafe_question (d, question_msg, echo);
-
- send_slave_ack_dialog_char (d, GDM_SLAVE_NOTIFY_QUESTION_RESPONSE, response_question);
-
- if (GDM_AUTHFILE (d)) {
- VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0640));
- }
- }
-
- g_free (question_msg);
- g_strfreev (list);
- } else if (strncmp (msg, "opcode="GDM_SOP_SHOW_ASKBUTTONS_DIALOG,
- strlen ("opcode="GDM_SOP_SHOW_ASKBUTTONS_DIALOG)) == 0) {
- GdmDisplay *d;
- char *askbuttons_msg;
- char **list;
- char *ptr;
- char *options[4];
- long slave_pid;
- int i;
- int response_askbuttons;
-
- list = g_strsplit (msg, "$$", -1);
-
- ptr = strchr (list [1], '=');
- slave_pid = atol (ptr + 1);
-
- ptr = strchr (list [2], '=');
- askbuttons_msg = g_malloc0 (strlen (ptr));
- strcpy (askbuttons_msg, ptr + 1);
-
- ptr = strchr (list [3], '=');
- options[0] = g_malloc0 (strlen (ptr));
- strcpy (options[0], ptr + 1);
-
- ptr = strchr (list [4], '=');
- options[1] = g_malloc0 (strlen (ptr));
- strcpy (options[1], ptr + 1);
-
- ptr = strchr (list [5], '=');
- options[2] = g_malloc0 (strlen (ptr));
- strcpy (options[2], ptr + 1);
-
- ptr = strchr (list [6], '=');
- options[3] = g_malloc0 (strlen (ptr));
- strcpy (options[3], ptr + 1);
-
- d = gdm_display_lookup (slave_pid);
- if (d != NULL) {
- if (GDM_AUTHFILE (d)) {
- VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0644));
- }
-
- 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)) {
- VE_IGNORE_EINTR (chmod (GDM_AUTHFILE (d), 0640));
- }
- }
-
- g_free (askbuttons_msg);
-
- for (i = 0; i < 3; i ++)
- g_free (options[i]);
- g_strfreev (list);
- }
-}
-
-/* extract second word and the rest of the string */
-static void
-extract_dispname_uid_xauthfile_cookie (const char *msg,
- char **dispname,
- uid_t *uid,
- char **xauthfile,
- char **cookie)
-{
- const char *p;
- int i;
- char *pp;
-
- *dispname = NULL;
- *xauthfile = NULL;
- *cookie = NULL;
-
- /* Get dispname */
- p = strchr (msg, ' ');
- if (p == NULL)
- return;
-
- while (*p == ' ')
- p++;
-
- *dispname = g_strdup (p);
- pp = strchr (*dispname, ' ');
- if (pp != NULL)
- *pp = '\0';
-
- /* Get uid */
- p = strchr (p, ' ');
- if (p == NULL) {
- *dispname = NULL;
- g_free (*dispname);
- return;
- }
- while (*p == ' ')
- p++;
-
- if (sscanf (p, "%d", &i) != 1) {
- *dispname = NULL;
- g_free (*dispname);
- return;
- }
- *uid = i;
-
- /* Get cookie */
- p = strchr (p, ' ');
- if (p == NULL) {
- *dispname = NULL;
- g_free (*dispname);
- return;
- }
- while (*p == ' ')
- p++;
-
- *cookie = g_strdup (p);
- pp = strchr (*cookie, ' ');
- if (pp != NULL)
- *pp = '\0';
-
- /* Get xauthfile */
- p = strchr (p, ' ');
- if (p == NULL) {
- *cookie = NULL;
- g_free (*cookie);
- *dispname = NULL;
- g_free (*dispname);
- return;
- }
-
- while (*p == ' ')
- p++;
-
- *xauthfile = g_strstrip (g_strdup (p));
-
-}
-
-static void
-close_conn (gpointer data)
-{
- GdmDisplay *disp = data;
-
- /* We still weren't finished, so we want to whack this display */
- if (disp->socket_conn != NULL) {
- disp->socket_conn = NULL;
- gdm_display_unmanage (disp);
- }
-}
-
-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;
- if (disp->name != NULL &&
- strcmp (disp->name, name) == 0)
- return disp;
- }
- return NULL;
-}
-
-static char *
-extract_dispnum (const char *addy)
-{
- int num;
- char *p;
-
- gdm_assert (addy != NULL);
-
- p = strchr (addy, ':');
- if (p == NULL)
- return NULL;
-
- /* Whee! handles DECnet even if we don't do that */
- while (*p == ':')
- p++;
-
- if (sscanf (p, "%d", &num) != 1)
- return NULL;
-
- return g_strdup_printf ("%d", num);
-}
-
-static char *
-dehex_cookie (const char *cookie, int *len)
-{
- /* it should be +1 really, but I'm paranoid */
- char *bcookie = g_new0 (char, (strlen (cookie) / 2) + 2);
- int i;
- const char *p;
-
- *len = 0;
-
- for (i = 0, p = cookie;
- *p != '\0' && *(p+1) != '\0';
- i++, p += 2) {
- unsigned int num;
- if (sscanf (p, "%02x", &num) != 1) {
- g_free (bcookie);
- return NULL;
- }
- bcookie[i] = num;
- }
- *len = i;
- return bcookie;
-}
-
-/* This runs as the user who owns the file */
-static gboolean
-check_cookie (const gchar *file, const gchar *disp, const gchar *cookie)
-{
- Xauth *xa;
- gchar *number;
- gchar *bcookie;
- int cookielen;
- gboolean ret = FALSE;
- int cnt = 0;
-
- FILE *fp = fopen (file, "r");
- if (fp == NULL)
- return FALSE;
-
- number = extract_dispnum (disp);
- if (number == NULL)
- return FALSE;
- bcookie = dehex_cookie (cookie, &cookielen);
- if (bcookie == NULL) {
- g_free (number);
- return FALSE;
- }
-
- while ((xa = XauReadAuth (fp)) != NULL) {
- if (xa->number_length == strlen (number) &&
- strncmp (xa->number, number, xa->number_length) == 0 &&
- xa->name_length == strlen ("MIT-MAGIC-COOKIE-1") &&
- strncmp (xa->name, "MIT-MAGIC-COOKIE-1",
- xa->name_length) == 0 &&
- xa->data_length == cookielen &&
- memcmp (xa->data, bcookie, cookielen) == 0) {
- XauDisposeAuth (xa);
- ret = TRUE;
- break;
- }
- XauDisposeAuth (xa);
-
- /* just being ultra anal */
- cnt++;
- if (cnt > 500)
- break;
- }
-
- g_free (number);
- g_free (bcookie);
-
- VE_IGNORE_EINTR (fclose (fp));
-
- return ret;
-}
-
-static void
-handle_flexi_server (GdmConnection *conn,
- int type,
- const char *server,
- gboolean handled,
- gboolean chooser,
- const char *xnest_disp,
- uid_t xnest_uid,
- const char *xnest_auth_file,
- const char *xnest_cookie,
- const char *username)
-{
- GdmDisplay *display;
- gchar *bin;
- uid_t server_uid = 0;
-
- g_debug ("flexi server: '%s'", server);
-
- if (gdm_wait_for_go) {
- if (conn != NULL)
- gdm_connection_write (conn,
- "ERROR 1 No more flexi servers\n");
- return;
- }
-
- if (type == TYPE_FLEXI_XNEST) {
- gboolean authorized = TRUE;
- struct passwd *pw;
- gid_t oldgid = getegid ();
-
- pw = getpwuid (xnest_uid);
- if (pw == NULL) {
- if (conn != NULL)
- gdm_connection_write (conn,
- "ERROR 100 Not authenticated\n");
- return;
- }
-
- /* paranoia */
- NEVER_FAILS_seteuid (0);
-
- if (setegid (pw->pw_gid) < 0)
- NEVER_FAILS_setegid (gdm_daemon_config_get_gdmgid ());
-
- if (seteuid (xnest_uid) < 0) {
- if (conn != NULL)
- gdm_connection_write (conn,
- "ERROR 100 Not authenticated\n");
- return;
- }
-
- gdm_assert (xnest_auth_file != NULL);
- gdm_assert (xnest_disp != NULL);
- gdm_assert (xnest_cookie != NULL);
-
- if (authorized &&
- ! gdm_auth_file_check ("handle_flexi_server", xnest_uid, xnest_auth_file, FALSE /* absentok */, NULL))
- authorized = FALSE;
-
- if (authorized &&
- ! check_cookie (xnest_auth_file,
- xnest_disp,
- xnest_cookie)) {
- authorized = FALSE;
- }
-
- /* this must always work, thus the asserts */
- NEVER_FAILS_root_set_euid_egid (0, oldgid);
-
- if (! authorized) {
- /* Sorry dude, you're not doing something
- * right */
- if (conn != NULL)
- gdm_connection_write (conn,
- "ERROR 100 Not authenticated\n");
- return;
- }
-
- server_uid = xnest_uid;
- }
-
- if (flexi_servers >= gdm_daemon_config_get_value_int (GDM_KEY_FLEXIBLE_XSERVERS)) {
- if (conn != NULL)
- gdm_connection_write (conn,
- "ERROR 1 No more flexi servers\n");
- return;
- }
-
- bin = ve_first_word (server);
- if (ve_string_empty (server) ||
- g_access (bin, X_OK) != 0) {
- g_free (bin);
- if (conn != NULL)
- gdm_connection_write (conn,
- "ERROR 6 No server binary\n");
- return;
- }
- g_free (bin);
-
- display = gdm_display_alloc (-1, server);
- if G_UNLIKELY (display == NULL) {
- if (conn != NULL)
- gdm_connection_write (conn,
- "ERROR 2 Startup errors\n");
- return;
- }
-
- /* It is kind of ugly that we don't use
- the standard resolution for this, but
- oh well, this makes other things simpler */
- display->handled = handled;
- display->use_chooser = chooser;
-
- if (type == TYPE_FLEXI_XNEST) {
- GdmDisplay *parent;
- gchar *disp, *p;
- gdm_assert (xnest_disp != NULL);
-
- disp = g_strdup (xnest_disp);
- /* whack the screen info */
- p = strchr (disp, ':');
- if (p != NULL)
- p = strchr (p+1, '.');
- if (p != NULL)
- *p = '\0';
- /* if it's on one of the attached displays we started,
- * it's on the console, else it's not (it could be but
- * we aren't sure and we don't want to be fooled) */
- parent = find_display (disp);
- if (/* paranoia */xnest_disp[0] == ':' &&
- parent != NULL &&
- parent->attached)
- display->attached = TRUE;
- else
- display->attached = FALSE;
- g_free (disp);
-
- display->server_uid = server_uid;
- }
-
- flexi_servers++;
-
- display->preset_user = g_strdup (username);
- display->type = type;
- display->socket_conn = conn;
- display->parent_disp = g_strdup (xnest_disp);
- display->parent_auth_file = g_strdup (xnest_auth_file);
- if (conn != NULL)
- gdm_connection_set_close_notify (conn, display, close_conn);
- gdm_daemon_config_display_list_append (display);
-
- if ( ! gdm_display_manage (display)) {
- gdm_display_unmanage (display);
- if (conn != NULL)
- gdm_connection_write (conn,
- "ERROR 2 Startup errors\n");
- return;
- }
- /* Now we wait for the server to start up (or not) */
-}
-
-static void
-handle_dynamic_server (GdmConnection *conn, int type, gchar *key)
-{
- GdmDisplay *disp;
- int disp_num;
- gchar *msg;
- gchar *full;
- gchar *val;
-
- if (!(gdm_daemon_config_get_value_bool (GDM_KEY_DYNAMIC_XSERVERS))) {
- gdm_connection_write (conn, "ERROR 200 Dynamic Displays not allowed\n");
- return;
- }
-
- if ( ! GDM_CONN_AUTH_GLOBAL(conn)) {
- gdm_info (_("DYNAMIC request denied: " "Not authenticated"));
- gdm_connection_write (conn, "ERROR 100 Not authenticated\n");
- return;
- }
-
- if (key == NULL) {
- gdm_connection_write (conn, "ERROR 1 Bad display number <NULL>\n");
- return;
- } else if ( !(isdigit (*key))) {
- msg = g_strdup_printf ("ERROR 1 Bad display number <%s>\n", key);
- gdm_connection_write (conn, msg);
- g_free (msg);
- return;
- }
- disp_num = atoi (key);
-
- if (type == DYNAMIC_ADD) {
- /* prime an X server for launching */
-
- if (mark_display_exists (disp_num)) {
- /* need to skip starting this one again */
- gdm_connection_write (conn, "ERROR 2 Existing display\n");
- return;
- }
-
- full = strchr (key, '=');
- if (full == NULL || *(full + 1) == 0) {
- gdm_connection_write (conn, "ERROR 3 No server string\n");
- return;
- }
-
- val = full + 1;
- disp = gdm_display_alloc (disp_num, val);
-
- if (disp == NULL) {
- gdm_connection_write (conn, "ERROR 4 Display startup failure\n");
- return;
- }
-
- gdm_daemon_config_display_list_insert (disp);
-
- disp->dispstat = DISPLAY_CONFIG;
- disp->removeconf = FALSE;
-
- if (disp_num > gdm_daemon_config_get_high_display_num ())
- gdm_daemon_config_set_high_display_num (disp_num);
-
- gdm_connection_write (conn, "OK\n");
- return;
- }
-
- 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) {
- disp = li->data;
- nli = li->next;
- if (disp->dispnum == disp_num) {
- disp->removeconf = TRUE;
- gdm_display_unmanage (disp);
- gdm_connection_write (conn, "OK\n");
- return;
- }
- }
-
- msg = g_strdup_printf ("ERROR 1 Bad display number <%d>\n", disp_num);
- gdm_connection_write (conn, msg);
- return;
- }
-
- if (type == DYNAMIC_RELEASE) {
- /* cause the newly configured X servers to actually run */
- 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;
- nli = li->next;
- if ((disp->dispnum == disp_num) &&
- (disp->dispstat == DISPLAY_CONFIG)) {
- disp->dispstat = DISPLAY_UNBORN;
-
- if ( ! gdm_display_manage (disp)) {
- gdm_display_unmanage (disp);
- }
- found = TRUE;
- }
- }
-
- if (found)
- gdm_connection_write (conn, "OK\n");
- else {
- msg = g_strdup_printf ("ERROR 1 Bad display number <%d>\n", disp_num);
- gdm_connection_write (conn, msg);
- }
-
- /* Now we wait for the server to start up (or not) */
- return;
- }
-}
-
-static void
-sup_handle_auth_local (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
- GSList *li;
- char *cookie;
- GSList *displays;
-
- cookie = g_strdup (&msg[strlen (GDM_SUP_AUTH_LOCAL " ")]);
-
- 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 */
- gdm_connection_write (conn,
- "ERROR 100 Not authenticated\n");
- gdm_connection_close (conn);
- g_free (cookie);
- return;
- }
- /* check if cookie matches one of the attached displays */
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *disp = li->data;
- if (disp->attached &&
- disp->cookie != NULL &&
- g_ascii_strcasecmp (disp->cookie, cookie) == 0) {
- g_free (cookie);
- GDM_CONNECTION_SET_USER_FLAG
- (conn, GDM_SUP_FLAG_AUTHENTICATED);
- gdm_connection_set_display (conn, disp);
- gdm_connection_write (conn, "OK\n");
- return;
- }
- }
-
- if (gdm_global_cookie != NULL &&
- g_ascii_strcasecmp ((gchar *) gdm_global_cookie, cookie) == 0) {
- g_free (cookie);
- GDM_CONNECTION_SET_USER_FLAG
- (conn, GDM_SUP_FLAG_AUTH_GLOBAL);
- gdm_connection_write (conn, "OK\n");
- return;
- }
-
- /* Hmmm, perhaps this is better defined behaviour */
- GDM_CONNECTION_UNSET_USER_FLAG
- (conn, GDM_SUP_FLAG_AUTHENTICATED);
- GDM_CONNECTION_UNSET_USER_FLAG
- (conn, GDM_SUP_FLAG_AUTH_GLOBAL);
- gdm_connection_set_display (conn, NULL);
- gdm_connection_write (conn, "ERROR 100 Not authenticated\n");
- g_free (cookie);
-}
-
-static void
-sup_handle_attached_servers (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
- GString *retMsg;
- GSList *li;
- 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)
- msgLen = strlen (GDM_SUP_ATTACHED_SERVERS);
- else if (strncmp (msg, GDM_SUP_CONSOLE_SERVERS,
- strlen (GDM_SUP_CONSOLE_SERVERS)) == 0)
- msgLen = strlen (GDM_SUP_CONSOLE_SERVERS);
-
- key = g_strdup (&msg[msgLen]);
- g_strstrip (key);
-
- retMsg = g_string_new ("OK");
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *disp = li->data;
-
- if ( ! disp->attached)
- continue;
- if (!(strlen (key)) || (g_pattern_match_simple (key, disp->command))) {
- g_string_append_printf (retMsg, "%s%s,%s,", sep,
- ve_sure_string (disp->name),
- ve_sure_string (disp->login));
- sep = ";";
- if (disp->type == TYPE_FLEXI_XNEST) {
- g_string_append (retMsg, ve_sure_string (disp->parent_disp));
- } else {
- g_string_append_printf (retMsg, "%d", disp->vt);
- }
- }
- }
-
- g_string_append (retMsg, "\n");
- gdm_connection_write (conn, retMsg->str);
- g_free (key);
- g_string_free (retMsg, TRUE);
-}
-
-static void
-sup_handle_get_server_details (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
-
- const gchar *server = &msg[strlen (GDM_SUP_GET_SERVER_DETAILS " ")];
- gchar **splitstr = g_strsplit (server, " ", 2);
- GdmXserver *svr = gdm_daemon_config_find_xserver ((gchar *)splitstr[0]);
-
- if (svr != NULL) {
- if (g_strcasecmp (splitstr[1], "ID") == 0)
- gdm_connection_printf (conn, "OK %s\n", svr->id);
- else if (g_strcasecmp (splitstr[1], "NAME") == 0)
- gdm_connection_printf (conn, "OK %s\n", svr->name);
- else if (g_strcasecmp (splitstr[1], "COMMAND") == 0)
- gdm_connection_printf (conn, "OK %s\n", svr->command);
- else if (g_strcasecmp (splitstr[1], "PRIORITY") == 0)
- gdm_connection_printf (conn, "OK %d\n", svr->priority);
- else if (g_strcasecmp (splitstr[1], "FLEXIBLE") == 0 &&
- svr->flexible)
- gdm_connection_printf (conn, "OK true\n");
- else if (g_strcasecmp (splitstr[1], "FLEXIBLE") == 0 &&
- !svr->flexible)
- gdm_connection_printf (conn, "OK false\n");
- else if (g_strcasecmp (splitstr[1], "CHOOSABLE") == 0 &&
- svr->choosable)
- gdm_connection_printf (conn, "OK true\n");
- else if (g_strcasecmp (splitstr[1], "CHOOSABLE") == 0 &&
- !svr->choosable)
- gdm_connection_printf (conn, "OK false\n");
- else if (g_strcasecmp (splitstr[1], "HANDLED") == 0 &&
- svr->handled)
- gdm_connection_printf (conn, "OK true\n");
- else if (g_strcasecmp (splitstr[1], "HANDLED") == 0 &&
- !svr->handled)
- gdm_connection_printf (conn, "OK false\n");
- else if (g_strcasecmp (splitstr[1], "CHOOSER") == 0 &&
- svr->chooser)
- gdm_connection_printf (conn, "OK true\n");
- else if (g_strcasecmp (splitstr[1], "CHOOSER") == 0 &&
- !svr->chooser)
- gdm_connection_printf (conn, "OK false\n");
- else
- gdm_connection_printf (conn, "ERROR 2 Key not valid\n");
-
- g_strfreev (splitstr);
- } else {
- gdm_connection_printf (conn, "ERROR 1 Server not found\n");
- }
-}
-
-static void
-sup_handle_flexi_xserver (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
- char *name;
- const char *command = NULL;
- GdmXserver *svr;
- const char *rest;
- char *username;
- char *end;
- gboolean has_user;
-
- has_user = strncmp (msg, GDM_SUP_FLEXI_XSERVER_USER " ", strlen (GDM_SUP_FLEXI_XSERVER_USER " ")) == 0;
-
- g_debug ("Handling flexi request has-user:%d", has_user);
-
- /* Only allow locally authenticated connections */
- if ( ! GDM_CONN_AUTHENTICATED (conn)) {
- gdm_info (_("%s request denied: "
- "Not authenticated"), "FLEXI_XSERVER");
- gdm_connection_write (conn,
- "ERROR 100 Not authenticated\n");
- return;
- }
-
- if (has_user) {
- rest = msg + strlen (GDM_SUP_FLEXI_XSERVER_USER " ");
- end = strchr (rest, ' ');
- if (end) {
- username = g_strndup (rest, end - rest);
- rest = end + 1;
- } else {
- username = g_strdup (rest);
- rest = rest + strlen (rest);
- }
- } else {
- rest = msg + strlen (GDM_SUP_FLEXI_XSERVER " ");
- username = NULL;
- }
-
- name = g_strdup (rest);
- g_strstrip (name);
- if (ve_string_empty (name)) {
- g_free (name);
- name = g_strdup (GDM_STANDARD);
- }
-
- svr = gdm_daemon_config_find_xserver (name);
-
- if G_UNLIKELY (svr == NULL) {
- /* Don't print the name to syslog as it might be
- * long and dangerous */
- gdm_error (_("Unknown server type requested; using "
- "standard server."));
- command = gdm_daemon_config_get_value_string (GDM_KEY_STANDARD_XSERVER);
- } else if G_UNLIKELY ( ! svr->flexible) {
- gdm_error (_("Requested server %s not allowed to be "
- "used for flexible servers; using "
- "standard server."), name);
- command = gdm_daemon_config_get_value_string (GDM_KEY_STANDARD_XSERVER);
- } else {
- command = svr->command;
- }
- g_free (name);
-
- handle_flexi_server (conn,
- TYPE_FLEXI,
- command,
- /* It is kind of ugly that we don't use
- the standard resolution for this, but
- oh well, this makes other things simpler */
- svr->handled,
- svr->chooser,
- NULL,
- 0,
- NULL,
- NULL,
- username);
- g_free (username);
-}
-
-static void
-sup_handle_flexi_xnest (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
- char *dispname = NULL;
- char *xauthfile = NULL;
- char *cookie = NULL;
- uid_t uid;
- const char *rest;
- char *username;
- char *end;
- gboolean has_user;
-
- has_user = strncmp (msg, GDM_SUP_FLEXI_XNEST_USER " ", strlen (GDM_SUP_FLEXI_XNEST_USER " ")) == 0;
-
- g_debug ("Handling flexi xnest request has-user:%d", has_user);
-
- if (has_user) {
- rest = msg + strlen (GDM_SUP_FLEXI_XNEST_USER " ");
- end = strchr (rest, ' ');
- username = g_strndup (rest, end - rest);
- } else {
- rest = msg;
- username = NULL;
- }
-
- extract_dispname_uid_xauthfile_cookie (rest,
- &dispname,
- &uid,
- &xauthfile,
- &cookie);
-
- if (dispname == NULL) {
- /* Something bogus is going on, so just whack the
- * connection */
- g_free (xauthfile);
- gdm_connection_close (conn);
- g_warning ("Unable to get display name from request");
- return;
- }
-
- /* This is probably a pre-2.2.4.2 client */
- if (xauthfile == NULL || cookie == NULL) {
- /* evil, just whack the connection in this case */
- gdm_connection_write (conn,
- "ERROR 100 Not authenticated\n");
- gdm_connection_close (conn);
- g_free (cookie);
- return;
- }
-
- handle_flexi_server (conn,
- TYPE_FLEXI_XNEST,
- gdm_daemon_config_get_value_string (GDM_KEY_XNEST),
- TRUE /* handled */,
- FALSE /* chooser */,
- dispname,
- uid,
- xauthfile,
- cookie,
- username);
-
- g_free (dispname);
- g_free (xauthfile);
- g_free (username);
-}
-
-static void
-sup_handle_get_config (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
- const char *parms;
- char **splitstr;
- char *retval;
- static gboolean done_prefetch = FALSE;
-
- retval = NULL;
-
- parms = &msg[strlen (GDM_SUP_GET_CONFIG " ")];
-
- splitstr = g_strsplit (parms, " ", 2);
-
- if (splitstr == NULL || splitstr[0] == NULL) {
- goto out;
- }
-
- /*
- * It is not meaningful to manage this in a per-display
- * fashion since the prefetch program is only run once the
- * for the first display that requests the key. So process
- * this first and return "Unsupported key" for requests
- * after the first request.
- */
- if (strcmp (splitstr[0], GDM_KEY_PRE_FETCH_PROGRAM) == 0) {
- if (done_prefetch) {
- gdm_connection_printf (conn, "OK \n");
- } else {
- gdm_connection_printf (conn, "ERROR 50 Unsupported key <%s>\n", splitstr[0]);
- done_prefetch = TRUE;
- }
- goto out;
- }
-
- if (splitstr[0] != NULL) {
- gboolean res;
-
- /*
- * Note passing in the display is backwards compatible
- * since if it is NULL, it won't try to load the display
- * value at all.
- */
-
- g_debug ("Handling GET_CONFIG: %s for display %s", splitstr[0],
- splitstr[1] ? splitstr[1] : "(null)");
-
- res = gdm_daemon_config_to_string (splitstr[0], splitstr[1], &retval);
-
- if (res) {
- gdm_connection_printf (conn, "OK %s\n", retval);
- g_free (retval);
- } else {
- if (gdm_daemon_config_is_valid_key ((gchar *)splitstr[0]))
- gdm_connection_printf (conn, "OK \n");
- else
- gdm_connection_printf (conn,
- "ERROR 50 Unsupported key <%s>\n",
- splitstr[0]);
- }
- }
- out:
- g_strfreev (splitstr);
-}
-
-static gboolean
-is_action_available (GdmDisplay *disp, gchar *action)
-{
- const gchar **allowsyscmd;
- const gchar **rbackeys;
- gboolean sysmenu;
- gboolean ret = FALSE;
- int i;
-
- allowsyscmd = gdm_daemon_config_get_value_string_array (GDM_KEY_ALLOW_LOGOUT_ACTIONS);
- rbackeys = gdm_daemon_config_get_value_string_array (GDM_KEY_RBAC_SYSTEM_COMMAND_KEYS);
- sysmenu = gdm_daemon_config_get_value_bool_per_display (GDM_KEY_SYSTEM_MENU, disp->name);
-
- if (!disp->attached || !sysmenu) {
- return FALSE;
- }
-
- for (i = 0; allowsyscmd[i] != NULL; i++) {
- if (strcmp (allowsyscmd[i], action) == 0) {
- ret = TRUE;
- break;
- }
- }
-
-#ifdef HAVE_CHKAUTHATTR
- if (ret == TRUE && rbackeys) {
- for (i = 0; rbackeys[i] != NULL; i++) {
- gchar **rbackey = g_strsplit (rbackeys[i], ":", 2);
-
- if (! ve_string_empty (rbackey[0]) &&
- ! ve_string_empty (rbackey[1]) &&
- strcmp (rbackey[0], action) == 0) {
-
- if (!chkauthattr (rbackey[1], disp->login)) {
- g_strfreev (rbackey);
- ret = FALSE;
- break;
- }
-
- }
- g_strfreev (rbackey);
- }
- }
-#endif
-
- return ret;
-}
-
-static void
-sup_handle_query_logout_action (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
- GdmLogoutAction logout_action;
- GdmDisplay *disp;
- GString *reply;
- const gchar *sep = " ";
- int i;
- gchar *key_string = NULL;
-
- disp = gdm_connection_get_display (conn);
-
- /* Only allow locally authenticated connections */
- if (! GDM_CONN_AUTHENTICATED (conn) || disp == NULL) {
- gdm_info (_("%s request denied: "
- "Not authenticated"), "QUERY_LOGOUT_ACTION");
- gdm_connection_write (conn,
- "ERROR 100 Not authenticated\n");
- return;
- }
-
- reply = g_string_new ("OK");
-
- logout_action = disp->logout_action;
- if (logout_action == GDM_LOGOUT_ACTION_NONE)
- logout_action = safe_logout_action;
-
- if (gdm_daemon_config_get_value_string_array (GDM_KEY_HALT) &&
- is_action_available (disp, GDM_SUP_LOGOUT_ACTION_HALT)) {
- g_string_append_printf (reply, "%s%s", sep,
- GDM_SUP_LOGOUT_ACTION_HALT);
- if (logout_action == GDM_LOGOUT_ACTION_HALT)
- g_string_append (reply, "!");
- sep = ";";
- }
- if (gdm_daemon_config_get_value_string_array (GDM_KEY_REBOOT) &&
- is_action_available (disp, GDM_SUP_LOGOUT_ACTION_REBOOT)) {
- g_string_append_printf (reply, "%s%s", sep,
- GDM_SUP_LOGOUT_ACTION_REBOOT);
- if (logout_action == GDM_LOGOUT_ACTION_REBOOT)
- g_string_append (reply, "!");
- sep = ";";
- }
- if (gdm_daemon_config_get_value_string_array (GDM_KEY_SUSPEND) &&
- is_action_available (disp, GDM_SUP_LOGOUT_ACTION_SUSPEND)) {
- g_string_append_printf (reply, "%s%s", sep,
- GDM_SUP_LOGOUT_ACTION_SUSPEND);
- if (logout_action == GDM_LOGOUT_ACTION_SUSPEND)
- g_string_append (reply, "!");
- sep = ";";
- }
-
- if (is_action_available (disp, GDM_SUP_LOGOUT_ACTION_CUSTOM_CMD_TEMPLATE)) {
- for (i = 0; i < GDM_CUSTOM_COMMAND_MAX; i++) {
- key_string = g_strdup_printf ("%s%d=", GDM_KEY_CUSTOM_CMD_TEMPLATE, i);
-
- if (! ve_string_empty (gdm_daemon_config_get_value_string (key_string))) {
-
- g_free (key_string);
- key_string = g_strdup_printf("%s%d=",
- GDM_KEY_CUSTOM_CMD_IS_PERSISTENT_TEMPLATE, i);
-
- if (gdm_daemon_config_get_value_bool (key_string)) {
- g_string_append_printf (reply, "%s%s%d", sep,
- GDM_SUP_LOGOUT_ACTION_CUSTOM_CMD_TEMPLATE, i);
- if (logout_action == (GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST + i))
- g_string_append (reply, "!");
- sep = ";";
- }
- }
- g_free(key_string);
- }
- }
-
- g_string_append (reply, "\n");
- gdm_connection_write (conn, reply->str);
- g_string_free (reply, TRUE);
-}
-
-static void
-sup_handle_query_custom_cmd_labels (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
-
- GdmDisplay *disp;
- GString *reply;
- const gchar *sep = " ";
- gboolean sysmenu;
- int i;
- gchar *key_string = NULL;
-
- disp = gdm_connection_get_display (conn);
- sysmenu = gdm_daemon_config_get_value_bool_per_display (GDM_KEY_SYSTEM_MENU, disp->name);
-
- /* Only allow locally authenticated connections */
- if ( ! GDM_CONN_AUTHENTICATED (conn) ||
- disp == NULL) {
- gdm_info (_("%s request denied: "
- "Not authenticated"), "QUERY_CUSTOM_CMD_LABELS");
- gdm_connection_write (conn,
- "ERROR 100 Not authenticated\n");
- return;
- }
-
- reply = g_string_new ("OK");
-
- for (i = 0; i < GDM_CUSTOM_COMMAND_MAX; i++) {
- key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_TEMPLATE, i);
- if (sysmenu && disp->attached &&
- ! ve_string_empty (gdm_daemon_config_get_value_string (key_string))) {
- g_free (key_string);
- key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_IS_PERSISTENT_TEMPLATE, i);
- if (gdm_daemon_config_get_value_bool (key_string)) {
- g_free (key_string);
- key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_LABEL_TEMPLATE, i);
- g_string_append_printf (reply, "%s%s", sep, gdm_daemon_config_get_value_string (key_string));
- sep = ";";
- }
- }
- g_free(key_string);
- }
-
- g_string_append (reply, "\n");
- gdm_connection_write (conn, reply->str);
- g_string_free (reply, TRUE);
-}
-
-static void
-sup_handle_all_servers (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
- GString *reply;
- GSList *li;
- const gchar *sep = " ";
- GSList *displays;
-
- displays = gdm_daemon_config_get_display_list ();
-
- reply = g_string_new ("OK");
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *disp = li->data;
- g_string_append_printf (reply, "%s%s,%s", sep,
- ve_sure_string (disp->name),
- ve_sure_string (disp->login));
- sep = ";";
- }
- g_string_append (reply, "\n");
- gdm_connection_write (conn, reply->str);
- g_string_free (reply, TRUE);
-}
-
-static void
-sup_handle_get_server_list (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
- gchar *retval = gdm_daemon_config_get_xservers ();
-
- if (retval != NULL) {
- gdm_connection_printf (conn, "OK %s\n", retval);
- g_free (retval);
- } else {
- gdm_connection_printf (conn, "ERROR 1 No servers found\n");
- }
-}
-
-static void
-sup_handle_get_custom_config_file (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
- gchar *ret;
-
- ret = gdm_daemon_config_get_custom_config_file ();
- if (ret)
- gdm_connection_printf (conn, "OK %s\n", ret);
- else
- gdm_connection_write (conn,
- "ERROR 1 File not found\n");
-}
-
-static void
-sup_handle_greeterpids (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
- GString *reply;
- GSList *li;
- const gchar *sep = " ";
- GSList *displays;
-
- displays = gdm_daemon_config_get_display_list ();
-
- reply = g_string_new ("OK");
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *disp = li->data;
- if (disp->greetpid > 0) {
- g_string_append_printf (reply, "%s%ld",
- sep, (long)disp->greetpid);
- sep = ";";
- }
- }
- g_string_append (reply, "\n");
- gdm_connection_write (conn, reply->str);
- g_string_free (reply, TRUE);
-}
-
-static void
-sup_handle_query_custom_cmd_no_restart_status (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
-
- GdmDisplay *disp;
- GString *reply;
- gboolean sysmenu;
- unsigned long no_restart_status_flag = 0; /* we can store up-to 32 commands this way */
- int i;
- gchar *key_string = NULL;
-
- disp = gdm_connection_get_display (conn);
- sysmenu = gdm_daemon_config_get_value_bool_per_display (GDM_KEY_SYSTEM_MENU, disp->name);
-
- /* Only allow locally authenticated connections */
- if ( ! GDM_CONN_AUTHENTICATED (conn) ||
- disp == NULL) {
- gdm_info (_("%s request denied: "
- "Not authenticated"), "QUERY_CUSTOM_CMD_NO_RESTART_STATUS");
- gdm_connection_write (conn,
- "ERROR 100 Not authenticated\n");
- return;
- }
-
- reply = g_string_new ("OK ");
-
- for (i = 0; i < GDM_CUSTOM_COMMAND_MAX; i++) {
- key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_TEMPLATE, i);
- if (sysmenu && disp->attached &&
- ! ve_string_empty (gdm_daemon_config_get_value_string (key_string))) {
- g_free (key_string);
- key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_IS_PERSISTENT_TEMPLATE, i);
- if (gdm_daemon_config_get_value_bool (key_string)) {
- g_free (key_string);
- key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_NO_RESTART_TEMPLATE, i);
- if(gdm_daemon_config_get_value_bool (key_string))
- no_restart_status_flag |= (1 << i);
- }
- }
- g_free(key_string);
- }
-
- g_string_append_printf (reply, "%ld\n", no_restart_status_flag);
- gdm_connection_write (conn, reply->str);
- g_string_free (reply, TRUE);
-}
-
-static void
-sup_handle_set_logout_action (GdmConnection *conn,
- const char *msg,
- gpointer data)
-
-{
- GdmDisplay *disp;
- const gchar *action;
- gboolean was_ok = FALSE;
-
- action = &msg[strlen (GDM_SUP_SET_LOGOUT_ACTION " ")];
- disp = gdm_connection_get_display (conn);
-
- /* Only allow locally authenticated connections */
- if ( ! GDM_CONN_AUTHENTICATED (conn) ||
- disp == NULL ||
- ! disp->logged_in) {
- gdm_info (_("%s request denied: "
- "Not authenticated"), "SET_LOGOUT_ACTION");
- gdm_connection_write (conn,
- "ERROR 100 Not authenticated\n");
- return;
- }
-
- if (strcmp (action, GDM_SUP_LOGOUT_ACTION_NONE) == 0) {
- disp->logout_action = GDM_LOGOUT_ACTION_NONE;
- was_ok = TRUE;
- } else if (strcmp (action, GDM_SUP_LOGOUT_ACTION_HALT) == 0 &&
- gdm_daemon_config_get_value_string_array (GDM_KEY_HALT) &&
- is_action_available (disp, GDM_SUP_LOGOUT_ACTION_HALT)) {
- disp->logout_action = GDM_LOGOUT_ACTION_HALT;
- was_ok = TRUE;
- } else if (strcmp (action, GDM_SUP_LOGOUT_ACTION_REBOOT) == 0 &&
- gdm_daemon_config_get_value_string_array (GDM_KEY_REBOOT) &&
- is_action_available (disp, GDM_SUP_LOGOUT_ACTION_REBOOT)) {
- disp->logout_action = GDM_LOGOUT_ACTION_REBOOT;
- was_ok = TRUE;
- } else if (strcmp (action, GDM_SUP_LOGOUT_ACTION_SUSPEND) == 0 &&
- gdm_daemon_config_get_value_string_array (GDM_KEY_SUSPEND) &&
- is_action_available (disp, GDM_SUP_LOGOUT_ACTION_SUSPEND)) {
- disp->logout_action = GDM_LOGOUT_ACTION_SUSPEND;
- was_ok = TRUE;
- }
- else if (strncmp (action, GDM_SUP_LOGOUT_ACTION_CUSTOM_CMD_TEMPLATE,
- strlen (GDM_SUP_LOGOUT_ACTION_CUSTOM_CMD_TEMPLATE)) == 0 &&
- is_action_available (disp, GDM_SUP_LOGOUT_ACTION_CUSTOM_CMD_TEMPLATE)) {
-
- int cmd_index;
- if (sscanf (action, GDM_SUP_LOGOUT_ACTION_CUSTOM_CMD_TEMPLATE "%d", &cmd_index) == 1) {
- gchar *key_string = NULL;
- key_string = g_strdup_printf ("%s%d=", GDM_KEY_CUSTOM_CMD_TEMPLATE, cmd_index);
- if (! ve_string_empty (gdm_daemon_config_get_value_string (key_string))) {
- disp->logout_action =
- GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST + cmd_index;
- was_ok = TRUE;
- }
- g_free(key_string);
- }
- }
-
- if (was_ok) {
- gdm_connection_write (conn, "OK\n");
- gdm_try_logout_action (disp);
- } else {
- gdm_connection_write (conn, "ERROR 7 Unknown logout action, or not available\n");
- }
-}
-
-static void
-sup_handle_set_safe_logout_action (GdmConnection *conn,
- const char *msg,
- gpointer data)
-
-{
- GdmDisplay *disp;
- const gchar *action;
- gboolean was_ok = FALSE;
-
- action = &msg[strlen (GDM_SUP_SET_SAFE_LOGOUT_ACTION " ")];
- disp = gdm_connection_get_display (conn);
-
- /* Only allow locally authenticated connections */
- if ( ! GDM_CONN_AUTHENTICATED (conn) ||
- disp == NULL ||
- ! disp->logged_in) {
- gdm_info (_("%s request denied: "
- "Not authenticated"), "SET_LOGOUT_ACTION");
- gdm_connection_write (conn,
- "ERROR 100 Not authenticated\n");
- return;
- }
-
- if (strcmp (action, GDM_SUP_LOGOUT_ACTION_NONE) == 0) {
- safe_logout_action = GDM_LOGOUT_ACTION_NONE;
- was_ok = TRUE;
- } else if (strcmp (action, GDM_SUP_LOGOUT_ACTION_HALT) == 0 &&
- gdm_daemon_config_get_value_string_array (GDM_KEY_HALT) &&
- is_action_available (disp, GDM_SUP_LOGOUT_ACTION_HALT)) {
- safe_logout_action = GDM_LOGOUT_ACTION_HALT;
- was_ok = TRUE;
- } else if (strcmp (action, GDM_SUP_LOGOUT_ACTION_REBOOT) == 0 &&
- gdm_daemon_config_get_value_string_array (GDM_KEY_REBOOT) &&
- is_action_available (disp, GDM_SUP_LOGOUT_ACTION_REBOOT)) {
- safe_logout_action = GDM_LOGOUT_ACTION_REBOOT;
- was_ok = TRUE;
- } else if (strcmp (action, GDM_SUP_LOGOUT_ACTION_SUSPEND) == 0 &&
- gdm_daemon_config_get_value_string_array (GDM_KEY_SUSPEND) &&
- is_action_available (disp, GDM_SUP_LOGOUT_ACTION_SUSPEND)) {
- safe_logout_action = GDM_LOGOUT_ACTION_SUSPEND;
- was_ok = TRUE;
- }
- else if (strncmp (action, GDM_SUP_LOGOUT_ACTION_CUSTOM_CMD_TEMPLATE,
- strlen (GDM_SUP_LOGOUT_ACTION_CUSTOM_CMD_TEMPLATE)) == 0 &&
- is_action_available (disp, GDM_SUP_LOGOUT_ACTION_CUSTOM_CMD_TEMPLATE)) {
-
- int cmd_index;
- if (sscanf (action, GDM_SUP_LOGOUT_ACTION_CUSTOM_CMD_TEMPLATE "%d", &cmd_index) == 1) {
-
- gchar *key_string = NULL;
- key_string = g_strdup_printf ("%s%d=", GDM_KEY_CUSTOM_CMD_TEMPLATE, cmd_index);
-
- if (! ve_string_empty (gdm_daemon_config_get_value_string (key_string))) {
- safe_logout_action =
- GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST + cmd_index;
- was_ok = TRUE;
- }
- g_free(key_string);
- }
- }
-
- if (was_ok) {
- gdm_connection_write (conn, "OK\n");
- gdm_try_logout_action (disp);
- } else {
- gdm_connection_write (conn, "ERROR 7 Unknown logout action, or not available\n");
- }
-}
-
-static void
-sup_handle_query_vt (GdmConnection *conn,
- const char *msg,
- gpointer data)
-
-{
-
- /* Only allow locally authenticated connections */
- if ( ! GDM_CONN_AUTHENTICATED (conn)) {
- gdm_info (_("%s request denied: "
- "Not authenticated"), "QUERY_VT");
- gdm_connection_write (conn,
- "ERROR 100 Not authenticated\n");
- return;
- }
-
-#if defined (__linux__) || defined (__FreeBSD__) || defined (__DragonFly__)
- gdm_connection_printf (conn, "OK %d\n", gdm_get_cur_vt ());
-#else
- gdm_connection_write (conn, "ERROR 8 Virtual terminals not supported\n");
-#endif
-}
-
-static void
-sup_handle_set_vt (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
- 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) {
- gdm_connection_write (conn,
- "ERROR 9 Invalid virtual terminal number\n");
- return;
- }
-
- /* Only allow locally authenticated connections */
- if ( ! GDM_CONN_AUTHENTICATED (conn)) {
- gdm_info (_("%s request denied: "
- "Not authenticated"), "QUERY_VT");
- gdm_connection_write (conn,
- "ERROR 100 Not authenticated\n");
- return;
- }
-
-#if defined (__linux__) || defined (__FreeBSD__) || defined (__DragonFly__)
- gdm_change_vt (vt);
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *disp = li->data;
- if (disp->vt == vt) {
- send_slave_command (disp, GDM_NOTIFY_TWIDDLE_POINTER);
- break;
- }
- }
- gdm_connection_write (conn, "OK\n");
-#else
- gdm_connection_write (conn, "ERROR 8 Virtual terminals not supported\n");
-#endif
-}
-
-static void
-gdm_handle_user_message (GdmConnection *conn,
- const char *msg,
- gpointer data)
-{
-
- g_debug ("Handling user message: '%s'", msg);
-
- if (gdm_connection_get_message_count (conn) > GDM_SUP_MAX_MESSAGES) {
- g_debug ("Closing connection, %d messages reached", GDM_SUP_MAX_MESSAGES);
- gdm_connection_write (conn, "ERROR 200 Too many messages\n");
- gdm_connection_close (conn);
- return;
- }
-
- if (strncmp (msg, GDM_SUP_AUTH_LOCAL " ",
- strlen (GDM_SUP_AUTH_LOCAL " ")) == 0) {
-
- sup_handle_auth_local (conn, msg, data);
-
- } else if (strcmp (msg, GDM_SUP_FLEXI_XSERVER) == 0) {
- /* Only allow locally authenticated connections */
- if ( ! GDM_CONN_AUTHENTICATED (conn)) {
- gdm_info (_("%s request denied: "
- "Not authenticated"), "FLEXI_XSERVER");
- gdm_connection_write (conn,
- "ERROR 100 Not authenticated\n");
- return;
- }
-
- handle_flexi_server (conn,
- TYPE_FLEXI,
- gdm_daemon_config_get_value_string (GDM_KEY_STANDARD_XSERVER),
- TRUE /* handled */,
- FALSE /* chooser */,
- NULL,
- 0,
- NULL,
- NULL,
- NULL);
- } else if ((strncmp (msg, GDM_SUP_FLEXI_XSERVER_USER " ",
- strlen (GDM_SUP_FLEXI_XSERVER_USER " ")) == 0) ||
- (strncmp (msg, GDM_SUP_FLEXI_XSERVER " ",
- strlen (GDM_SUP_FLEXI_XSERVER " ")) == 0)) {
-
- sup_handle_flexi_xserver (conn, msg, data);
-
- } else if ((strncmp (msg, GDM_SUP_FLEXI_XNEST_USER " ",
- strlen (GDM_SUP_FLEXI_XNEST_USER " ")) == 0) ||
- (strncmp (msg, GDM_SUP_FLEXI_XNEST " ",
- strlen (GDM_SUP_FLEXI_XNEST " ")) == 0)) {
-
- sup_handle_flexi_xnest (conn, msg, data);
-
- } else if ((strncmp (msg, GDM_SUP_ATTACHED_SERVERS,
- strlen (GDM_SUP_ATTACHED_SERVERS)) == 0) ||
- (strncmp (msg, GDM_SUP_CONSOLE_SERVERS,
- strlen (GDM_SUP_CONSOLE_SERVERS)) == 0)) {
-
- sup_handle_attached_servers (conn, msg, data);
-
- } else if (strcmp (msg, GDM_SUP_ALL_SERVERS) == 0) {
-
- sup_handle_all_servers (conn, msg, data);
-
- } else if (strcmp (msg, GDM_SUP_GET_SERVER_LIST) == 0) {
-
- sup_handle_get_server_list (conn, msg, data);
-
- } else if (strncmp (msg, GDM_SUP_GET_SERVER_DETAILS " ",
- strlen (GDM_SUP_GET_SERVER_DETAILS " ")) == 0) {
-
- sup_handle_get_server_details (conn, msg, data);
-
- } else if (strcmp (msg, GDM_SUP_GREETERPIDS) == 0) {
-
- sup_handle_greeterpids (conn, msg, data);
-
- } else if (strncmp (msg, GDM_SUP_UPDATE_CONFIG " ",
- strlen (GDM_SUP_UPDATE_CONFIG " ")) == 0) {
- const char *key;
-
- key = &msg[strlen (GDM_SUP_UPDATE_CONFIG " ")];
-
- if (! gdm_daemon_config_update_key ((gchar *)key))
- gdm_connection_printf (conn, "ERROR 50 Unsupported key <%s>\n", key);
- else
- gdm_connection_write (conn, "OK\n");
- } else if (strncmp (msg, GDM_SUP_GET_CONFIG " ",
- strlen (GDM_SUP_GET_CONFIG " ")) == 0) {
-
- sup_handle_get_config (conn, msg, data);
-
- } else if (strcmp (msg, GDM_SUP_GET_CONFIG_FILE) == 0) {
- /*
- * Value is only non-null if passed in on command line.
- * Otherwise print compiled-in default file location.
- */
- if (config_file == NULL) {
- gdm_connection_printf (conn, "OK %s\n",
- GDM_DEFAULTS_CONF);
- } else {
- gdm_connection_printf (conn, "OK %s\n", config_file);
- }
- } else if (strcmp (msg, GDM_SUP_GET_CUSTOM_CONFIG_FILE) == 0) {
-
- sup_handle_get_custom_config_file (conn, msg, data);
-
- } else if (strcmp (msg, GDM_SUP_QUERY_LOGOUT_ACTION) == 0) {
-
- sup_handle_query_logout_action (conn, msg, data);
-
- } else if (strcmp (msg, GDM_SUP_QUERY_CUSTOM_CMD_LABELS) == 0) {
-
- sup_handle_query_custom_cmd_labels (conn, msg, data);
-
- } else if (strcmp (msg, GDM_SUP_QUERY_CUSTOM_CMD_NO_RESTART_STATUS) == 0) {
-
- sup_handle_query_custom_cmd_no_restart_status (conn, msg, data);
-
- } else if (strncmp (msg, GDM_SUP_SET_LOGOUT_ACTION " ",
- strlen (GDM_SUP_SET_LOGOUT_ACTION " ")) == 0) {
-
- sup_handle_set_logout_action (conn, msg, data);
-
- } else if (strncmp (msg, GDM_SUP_SET_SAFE_LOGOUT_ACTION " ",
- strlen (GDM_SUP_SET_SAFE_LOGOUT_ACTION " ")) == 0) {
-
- sup_handle_set_safe_logout_action (conn, msg, data);
-
- } else if (strcmp (msg, GDM_SUP_QUERY_VT) == 0) {
-
- sup_handle_query_vt (conn, msg, data);
-
- } else if (strncmp (msg, GDM_SUP_SET_VT " ",
- strlen (GDM_SUP_SET_VT " ")) == 0) {
-
- sup_handle_set_vt (conn, msg, data);
-
- } else if (strncmp (msg, GDM_SUP_ADD_DYNAMIC_DISPLAY " ",
- strlen (GDM_SUP_ADD_DYNAMIC_DISPLAY " ")) == 0) {
- gchar *key;
-
- key = g_strdup (&msg[strlen (GDM_SUP_ADD_DYNAMIC_DISPLAY " ")]);
- g_strstrip (key);
- handle_dynamic_server (conn, DYNAMIC_ADD, key);
- g_free (key);
-
- } else if (strncmp (msg, GDM_SUP_REMOVE_DYNAMIC_DISPLAY " ",
- strlen (GDM_SUP_REMOVE_DYNAMIC_DISPLAY " ")) == 0) {
- gchar *key;
-
- key = g_strdup (&msg[strlen (GDM_SUP_REMOVE_DYNAMIC_DISPLAY " ")]);
- g_strstrip (key);
- handle_dynamic_server (conn, DYNAMIC_REMOVE, key);
- g_free (key);
-
- } else if (strncmp (msg, GDM_SUP_RELEASE_DYNAMIC_DISPLAYS " ",
- strlen (GDM_SUP_RELEASE_DYNAMIC_DISPLAYS " ")) == 0) {
-
- gchar *key;
-
- key = g_strdup (&msg[strlen (GDM_SUP_RELEASE_DYNAMIC_DISPLAYS " ")]);
- g_strstrip (key);
- handle_dynamic_server (conn, DYNAMIC_RELEASE, key);
- g_free (key);
-
- } else if (strcmp (msg, GDM_SUP_VERSION) == 0) {
- gdm_connection_write (conn, "GDM " VERSION "\n");
- } else if (strcmp (msg, GDM_SUP_SERVER_BUSY) == 0) {
- if (gdm_connection_is_server_busy (unixconn))
- gdm_connection_write (conn, "OK true\n");
- else
- gdm_connection_write (conn, "OK false\n");
- } else if (strcmp (msg, GDM_SUP_CLOSE) == 0) {
- gdm_connection_close (conn);
- } else {
- gdm_connection_write (conn, "ERROR 0 Not implemented\n");
- gdm_connection_close (conn);
- }
-}
diff --git a/daemon/gdm.h b/daemon/gdm.h
deleted file mode 100644
index e13e4185..00000000
--- a/daemon/gdm.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* -*- 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
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef GDM_H
-#define GDM_H
-
-#define GDM_MAX_PASS 256 /* Define a value for password length. Glibc
- * leaves MAX_PASS undefined. */
-
-/* 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 */
-/* These are the exit codes */
-#define DISPLAY_REMANAGE 2 /* Restart display */
-#define DISPLAY_ABORT 4 /* Houston, we have a problem */
-#define DISPLAY_REBOOT 8 /* Rebewt */
-#define DISPLAY_HALT 16 /* Halt */
-#define DISPLAY_SUSPEND 17 /* Suspend (don't use, use the interrupt) */
-#define DISPLAY_CHOSEN 20 /* successful chooser session,
- restart display */
-#define DISPLAY_RUN_CHOOSER 30 /* Run chooser */
-#define DISPLAY_XFAILED 64 /* X failed */
-#define DISPLAY_GREETERFAILED 65 /* greeter failed (crashed) */
-#define DISPLAY_RESTARTGREETER 127 /* Restart greeter */
-#define DISPLAY_RESTARTGDM 128 /* Restart GDM */
-
-enum {
- DISPLAY_UNBORN /* Not yet started */,
- DISPLAY_ALIVE /* Yay! we're alive (non-XDMCP) */,
- XDMCP_PENDING /* Pending XDMCP display */,
- XDMCP_MANAGED /* Managed XDMCP display */,
- DISPLAY_DEAD /* Left for dead */,
- DISPLAY_CONFIG /* in process of being configured */
-};
-
-/* The dreaded miscellaneous category */
-#define PIPE_SIZE 4096
-
-/*
- * For backwards compatibility, do not set values for DEFAULT_WELCOME or
- * DEFAULT_REMOTEWELCOME. This will cause these values to always be
- * read from the config file, and will cause them to return FALSE if
- * no value is set in the config file. We want the value "FALSE" if
- * the values don't exist in the config file. The daemon will compare
- * the Welcome/RemoveWelcome value with the default string and
- * automatically translate the text if the string is the same as the
- * default string. We set the default values of GDM_KEY_WELCOME and
- * GDM_KEY_REMOTEWELCOME so that the default value is returned when
- * you run GET_CONFIG on these keys.
- */
-#define GDM_DEFAULT_WELCOME_MSG "Welcome"
-#define GDM_DEFAULT_REMOTE_WELCOME_MSG "Welcome to %n"
-
-#define GDM_SESSION_FAILSAFE_GNOME "GDM_Failsafe.GNOME"
-#define GDM_SESSION_FAILSAFE_XTERM "GDM_Failsafe.XTERM"
-
-/* FIXME: will support these builtin types later */
-#define GDM_SESSION_DEFAULT "default"
-#define GDM_SESSION_CUSTOM "custom"
-#define GDM_SESSION_FAILSAFE "failsafe"
-
-#define GDM_STANDARD "Standard"
-
-#define GDM_RESPONSE_CANCEL "GDM_RESPONSE_CANCEL"
-
-#define GDM_CUSTOM_COMMAND_MAX 10 /* maximum number of supported custom commands */
-
-#ifdef sun
-#define SDTLOGIN_DIR "/var/dt/sdtlogin"
-#endif
-
-/* If id == NULL, then get the first X server */
-void gdm_final_cleanup (void);
-
-#endif /* GDM_H */
-
-/* EOF */
diff --git a/daemon/gdm.in b/daemon/gdm.in
deleted file mode 100644
index adf9cf03..00000000
--- a/daemon/gdm.in
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-#
-# A script so that
-# 1) we read the standard system env vars
-# 2) syadmins/integrators can add their own private options etc...
-
-test -f /etc/profile && . /etc/profile
-
-# Try to set LC_MESSAGES to LANG if neither LC_MESSAGES or LC_ALL is set.
-# This ensures that gdm can display in a system's default language if only
-# LANG is set.
-
-# Make sure LANG is set
-#
-if [ -z "$LANG" ]
-then
- if [ -f /etc/sysconfig/language ]
- then
- LANG=`. /etc/sysconfig/language; echo $RC_LANG`
- export LANG
- fi
-fi
-
-if [ -z "$LC_MESSAGES" ]
-then
- if [ -z "$LC_ALL" ]
- then
- LC_MESSAGES=$LANG
- export LC_MESSAGES
- fi
-fi
-
-exec @sbindir@/gdm-binary "$@"
-
diff --git a/daemon/gdmconsolekit.c b/daemon/gdmconsolekit.c
deleted file mode 100644
index ce366ae7..00000000
--- a/daemon/gdmconsolekit.c
+++ /dev/null
@@ -1,538 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2006-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.
- *
- */
-
-#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 "gdm-log.h" /* for gdm_debug */
-#include "gdmconsolekit.h"
-
-
-#define CK_NAME "org.freedesktop.ConsoleKit"
-#define CK_PATH "/org/freedesktop/ConsoleKit"
-#define CK_INTERFACE "org.freedesktop.ConsoleKit"
-#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
-#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
-#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
-
-static DBusConnection *private_connection = NULL;
-
-static void
-add_param_int (DBusMessageIter *iter_struct,
- const char *key,
- int value)
-{
- DBusMessageIter iter_struct_entry;
- DBusMessageIter iter_var;
-
- dbus_message_iter_open_container (iter_struct,
- DBUS_TYPE_STRUCT,
- NULL,
- &iter_struct_entry);
-
- dbus_message_iter_append_basic (&iter_struct_entry,
- DBUS_TYPE_STRING,
- &key);
-
- dbus_message_iter_open_container (&iter_struct_entry,
- DBUS_TYPE_VARIANT,
- DBUS_TYPE_INT32_AS_STRING,
- &iter_var);
-
- dbus_message_iter_append_basic (&iter_var,
- DBUS_TYPE_INT32,
- &value);
-
- dbus_message_iter_close_container (&iter_struct_entry,
- &iter_var);
-
- dbus_message_iter_close_container (iter_struct, &iter_struct_entry);
-}
-
-static void
-add_param_boolean (DBusMessageIter *iter_struct,
- const char *key,
- gboolean value)
-{
- DBusMessageIter iter_struct_entry;
- DBusMessageIter iter_var;
-
- dbus_message_iter_open_container (iter_struct,
- DBUS_TYPE_STRUCT,
- NULL,
- &iter_struct_entry);
-
- dbus_message_iter_append_basic (&iter_struct_entry,
- DBUS_TYPE_STRING,
- &key);
-
- dbus_message_iter_open_container (&iter_struct_entry,
- DBUS_TYPE_VARIANT,
- DBUS_TYPE_BOOLEAN_AS_STRING,
- &iter_var);
-
- dbus_message_iter_append_basic (&iter_var,
- DBUS_TYPE_BOOLEAN,
- &value);
-
- dbus_message_iter_close_container (&iter_struct_entry,
- &iter_var);
-
- dbus_message_iter_close_container (iter_struct, &iter_struct_entry);
-}
-
-static void
-add_param_string (DBusMessageIter *iter_struct,
- const char *key,
- const char *value)
-{
- DBusMessageIter iter_struct_entry;
- DBusMessageIter iter_var;
-
- dbus_message_iter_open_container (iter_struct,
- DBUS_TYPE_STRUCT,
- NULL,
- &iter_struct_entry);
-
- dbus_message_iter_append_basic (&iter_struct_entry,
- DBUS_TYPE_STRING,
- &key);
-
- dbus_message_iter_open_container (&iter_struct_entry,
- DBUS_TYPE_VARIANT,
- DBUS_TYPE_STRING_AS_STRING,
- &iter_var);
-
- dbus_message_iter_append_basic (&iter_var,
- DBUS_TYPE_STRING,
- &value);
-
- dbus_message_iter_close_container (&iter_struct_entry,
- &iter_var);
-
- dbus_message_iter_close_container (iter_struct, &iter_struct_entry);
-}
-
-static gboolean
-session_get_x11_display (DBusConnection *connection,
- const char *ssid,
- char **str)
-{
- DBusError error;
- DBusMessage *message;
- DBusMessage *reply;
- DBusMessageIter iter;
- const char *value;
-
- if (str != NULL) {
- *str = NULL;
- }
-
- message = dbus_message_new_method_call (CK_NAME,
- ssid,
- CK_SESSION_INTERFACE,
- "GetX11Display");
- if (message == NULL) {
- gdm_debug ("ConsoleKit: Couldn't allocate the D-Bus message");
- return FALSE;
- }
-
- dbus_error_init (&error);
- reply = dbus_connection_send_with_reply_and_block (connection,
- message,
- -1, &error);
- if (dbus_error_is_set (&error)) {
- gdm_debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message);
- reply = NULL;
- }
-
- dbus_connection_flush (connection);
- dbus_message_unref (message);
-
- if (reply == NULL) {
- return FALSE;
- }
-
- dbus_message_iter_init (reply, &iter);
- dbus_message_iter_get_basic (&iter, &value);
- if (str != NULL) {
- *str = g_strdup (value);
- }
- dbus_message_unref (reply);
-
- return TRUE;
-}
-
-static gboolean
-session_unlock (DBusConnection *connection,
- const char *ssid)
-{
- DBusError error;
- DBusMessage *message;
- DBusMessage *reply;
-
- gdm_debug ("ConsoleKit: Unlocking session %s", ssid);
- message = dbus_message_new_method_call (CK_NAME,
- ssid,
- CK_SESSION_INTERFACE,
- "Unlock");
- if (message == NULL) {
- gdm_debug ("ConsoleKit: Couldn't allocate the D-Bus message");
- return FALSE;
- }
-
- dbus_error_init (&error);
- reply = dbus_connection_send_with_reply_and_block (connection,
- message,
- -1, &error);
- dbus_message_unref (message);
- dbus_message_unref (reply);
- dbus_connection_flush (connection);
-
- if (dbus_error_is_set (&error)) {
- gdm_debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* from libhal */
-static char **
-get_path_array_from_iter (DBusMessageIter *iter,
- int *num_elements)
-{
- int count;
- char **buffer;
-
- count = 0;
- buffer = (char **)malloc (sizeof (char *) * 8);
-
- if (buffer == NULL)
- goto oom;
-
- buffer[0] = NULL;
- while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_OBJECT_PATH) {
- const char *value;
- char *str;
-
- if ((count % 8) == 0 && count != 0) {
- buffer = realloc (buffer, sizeof (char *) * (count + 8));
- if (buffer == NULL)
- goto oom;
- }
-
- dbus_message_iter_get_basic (iter, &value);
- str = strdup (value);
- if (str == NULL)
- goto oom;
-
- buffer[count] = str;
-
- dbus_message_iter_next (iter);
- count++;
- }
-
- if ((count % 8) == 0) {
- buffer = realloc (buffer, sizeof (char *) * (count + 1));
- if (buffer == NULL)
- goto oom;
- }
-
- buffer[count] = NULL;
- if (num_elements != NULL)
- *num_elements = count;
- return buffer;
-
-oom:
- g_warning ("%s %d : error allocating memory\n", __FILE__, __LINE__);
- return NULL;
-
-}
-
-static char **
-get_sessions_for_user (DBusConnection *connection,
- const char *user,
- const char *x11_display)
-{
- DBusError error;
- DBusMessage *message;
- DBusMessage *reply;
- DBusMessageIter iter;
- DBusMessageIter iter_reply;
- DBusMessageIter iter_array;
- struct passwd *pwent;
- char **sessions;
-
- sessions = NULL;
- message = NULL;
- reply = NULL;
-
- pwent = getpwnam (user);
-
- dbus_error_init (&error);
- message = dbus_message_new_method_call (CK_NAME,
- CK_MANAGER_PATH,
- CK_MANAGER_INTERFACE,
- "GetSessionsForUser");
- if (message == NULL) {
- gdm_debug ("ConsoleKit: Couldn't allocate the D-Bus message");
- goto out;
- }
-
- dbus_message_iter_init_append (message, &iter);
- dbus_message_iter_append_basic (&iter,
- DBUS_TYPE_UINT32,
- &pwent->pw_uid);
-
- dbus_error_init (&error);
- reply = dbus_connection_send_with_reply_and_block (connection,
- message,
- -1, &error);
- dbus_connection_flush (connection);
-
- if (dbus_error_is_set (&error)) {
- gdm_debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message);
- goto out;
- }
-
- if (reply == NULL) {
- gdm_debug ("ConsoleKit: No reply for GetSessionsForUser");
- goto out;
- }
-
- dbus_message_iter_init (reply, &iter_reply);
- if (dbus_message_iter_get_arg_type (&iter_reply) != DBUS_TYPE_ARRAY) {
- gdm_debug ("ConsoleKit: Wrong reply for GetSessionsForUser - expecting an array.");
- goto out;
- }
-
- dbus_message_iter_recurse (&iter_reply, &iter_array);
- sessions = get_path_array_from_iter (&iter_array, NULL);
-
- out:
- if (message != NULL) {
- dbus_message_unref (message);
- }
- if (reply != NULL) {
- dbus_message_unref (reply);
- }
-
- return sessions;
-}
-
-void
-unlock_ck_session (const char *user,
- const char *x11_display)
-{
- DBusError error;
- DBusConnection *connection;
- char **sessions;
- int i;
-
- gdm_debug ("ConsoleKit: Unlocking session for %s on %s", user, x11_display);
-
- dbus_error_init (&error);
- connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
- if (connection == NULL) {
- gdm_debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message);
- dbus_error_free (&error);
- return;
- }
-
- sessions = get_sessions_for_user (connection, user, x11_display);
- if (sessions == NULL || sessions[0] == NULL) {
- gdm_debug ("ConsoleKit: no sessions found");
- return;
- }
-
- for (i = 0; sessions[i] != NULL; i++) {
- char *ssid;
- char *xdisplay;
-
- ssid = sessions[i];
- session_get_x11_display (connection, ssid, &xdisplay);
- gdm_debug ("ConsoleKit: session %s has DISPLAY %s", ssid, xdisplay);
-
- if (xdisplay != NULL
- && x11_display != NULL
- && strcmp (xdisplay, x11_display) == 0) {
- gboolean res;
-
- res = session_unlock (connection, ssid);
- if (! res) {
- gdm_error ("ConsoleKit: Unable to unlock %s", ssid);
- }
- }
-
- g_free (xdisplay);
- }
-
- g_strfreev (sessions);
-}
-
-char *
-open_ck_session (struct passwd *pwent,
- GdmDisplay *d,
- const char *session)
-{
- DBusConnection *connection;
- DBusError error;
- DBusMessage *message;
- DBusMessage *reply;
- DBusMessageIter iter;
- DBusMessageIter iter_struct;
- char *cookie;
-
- cookie = NULL;
-
- gdm_debug ("ConsoleKit: Opening session for %s", pwent->pw_name);
-
- dbus_error_init (&error);
- connection = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error);
- private_connection = connection;
-
- if (connection == NULL) {
- gdm_debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message);
- dbus_error_free (&error);
- return NULL;
- }
-
- dbus_connection_set_exit_on_disconnect (connection, FALSE);
- dbus_connection_setup_with_g_main (connection, NULL);
-
- dbus_error_init (&error);
- message = dbus_message_new_method_call (CK_NAME,
- CK_MANAGER_PATH,
- CK_MANAGER_INTERFACE,
- "OpenSessionWithParameters");
- if (message == NULL) {
- gdm_debug ("ConsoleKit: Couldn't allocate the D-Bus message");
- return NULL;
- }
-
- dbus_message_iter_init_append (message, &iter);
- dbus_message_iter_open_container (&iter,
- DBUS_TYPE_ARRAY,
- DBUS_STRUCT_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_STRUCT_END_CHAR_AS_STRING,
- &iter_struct);
-
- add_param_int (&iter_struct, "user", pwent->pw_uid);
- add_param_string (&iter_struct, "x11-display", d->name);
- add_param_boolean (&iter_struct, "is-local", d->attached);
- if (! d->attached) {
- add_param_string (&iter_struct, "remote-host-name", d->hostname);
- }
-
- if (d->vt > 0) {
- char *device;
-
- /* FIXME: how does xorg construct this */
- device = g_strdup_printf ("/dev/tty%d", d->vt);
- add_param_string (&iter_struct, "x11-display-device", device);
- g_free (device);
- }
-
- dbus_message_iter_close_container (&iter, &iter_struct);
-
- reply = dbus_connection_send_with_reply_and_block (connection,
- message,
- -1, &error);
- if (dbus_error_is_set (&error)) {
- gdm_debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message);
- reply = NULL;
- }
-
- dbus_connection_flush (connection);
-
- dbus_message_unref (message);
- dbus_error_free (&error);
-
- if (reply != NULL) {
- const char *value;
-
- dbus_message_iter_init (reply, &iter);
- dbus_message_iter_get_basic (&iter, &value);
- cookie = g_strdup (value);
- dbus_message_unref (reply);
- }
-
- return cookie;
-}
-
-void
-close_ck_session (const char *cookie)
-{
- DBusError error;
- DBusMessage *message;
- DBusMessage *reply;
- DBusMessageIter iter;
-
- if (cookie == NULL) {
- return;
- }
-
- if (private_connection == NULL) {
- return;
- }
-
- dbus_error_init (&error);
- message = dbus_message_new_method_call (CK_NAME,
- CK_MANAGER_PATH,
- CK_MANAGER_INTERFACE,
- "CloseSession");
- if (message == NULL) {
- gdm_debug ("ConsoleKit: Couldn't allocate the D-Bus message");
- return;
- }
-
- dbus_message_iter_init_append (message, &iter);
- dbus_message_iter_append_basic (&iter,
- DBUS_TYPE_STRING,
- &cookie);
-
- reply = dbus_connection_send_with_reply_and_block (private_connection,
- message,
- -1, &error);
- if (dbus_error_is_set (&error)) {
- gdm_debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message);
- reply = NULL;
- }
-
- dbus_connection_flush (private_connection);
-
- dbus_message_unref (message);
- dbus_error_free (&error);
-
- dbus_connection_close (private_connection);
- private_connection = NULL;
-}
diff --git a/daemon/gdmconsolekit.h b/daemon/gdmconsolekit.h
deleted file mode 100644
index 69f9ce39..00000000
--- a/daemon/gdmconsolekit.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2006 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.
- *
- */
-
-
-#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,
- GdmDisplay *display,
- const char *session);
-void close_ck_session (const char *cookie);
-void unlock_ck_session (const char *user,
- const char *x11_display);
-
-G_END_DECLS
-
-#endif /* __GDM_CONSOLE_KIT_H */
diff --git a/daemon/getvt.c b/daemon/getvt.c
deleted file mode 100644
index 941ab8b9..00000000
--- a/daemon/getvt.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "gdm.h"
-#include "misc.h"
-#include "getvt.h"
-
-#include "gdm-common.h"
-#include "gdm-daemon-config.h"
-
-/* Virtual terminals only supported on Linux, FreeBSD, or DragonFly */
-
-#if defined (__linux__) || defined (__FreeBSD__) || defined (__DragonFly__)
-
-#if defined (__linux__)
-#include <sys/vt.h>
-#elif defined (__FreeBSD__) || defined (__DragonFly__)
-#include <sys/consio.h>
-
-static const char*
-__itovty (int val)
-{
- static char str[8];
- char* next = str + sizeof (str) - 1;
-
- *next = '\0';
- do {
- *--next = "0123456789abcdefghigklmnopqrstuv"[val % 32];
- } while (val /= 32);
-
- return next;
-}
-#endif
-
-static int
-open_vt (int vtno)
-{
- char *vtname;
- int fd;
-
-#if defined (__linux__)
- vtname = g_strdup_printf ("/dev/tty%d", vtno);
-#elif defined (__FreeBSD__) || defined (__DragonFly__)
- vtname = g_strdup_printf ("/dev/ttyv%s", __itovty (vtno - 1));
-#endif
- do {
- errno = 0;
- fd = open (vtname, O_RDWR
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
- , 0);
- } while G_UNLIKELY (errno == EINTR);
- g_free (vtname);
- return fd;
-}
-
-#if defined (__linux__)
-
-static int
-get_free_vt_linux (int *vtfd)
-{
- int fd, fdv;
- int vtno;
- unsigned short vtmask;
- struct vt_stat vtstat;
-
- *vtfd = -1;
-
- do {
- errno = 0;
- fd = open ("/dev/console", O_WRONLY
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
- , 0);
- } while G_UNLIKELY (errno == EINTR);
- if (fd < 0)
- return -1;
-
- if (ioctl (fd, VT_GETSTATE, &vtstat) < 0) {
- VE_IGNORE_EINTR (close (fd));
- return -1;
- }
-
- for (vtno = gdm_daemon_config_get_value_int (GDM_KEY_FIRST_VT), vtmask = 1 << vtno;
- vtstat.v_state & vtmask; vtno++, vtmask <<= 1);
- if (!vtmask) {
- VE_IGNORE_EINTR (close (fd));
- return -1;
- }
-
- fdv = open_vt (vtno);
- if (fdv < 0) {
- VE_IGNORE_EINTR (close (fd));
- return -1;
- }
- *vtfd = fdv;
- return vtno;
-}
-
-#elif defined (__FreeBSD__) || defined (__DragonFly__)
-
-static int
-get_free_vt_freebsd_dragonfly (int *vtfd)
-{
- int fd, fdv;
- int vtno;
- GList *to_close_vts = NULL, *li;
-
- *vtfd = -1;
-
- do {
- errno = 0;
- fd = open ("/dev/console", O_WRONLY
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
- , 0);
- } while G_UNLIKELY (errno == EINTR);
- if (fd < 0)
- return -1;
-
- if ((ioctl (fd, VT_OPENQRY, &vtno) < 0) || (vtno == -1)) {
- VE_IGNORE_EINTR (close (fd));
- return -1;
- }
-
- fdv = open_vt (vtno);
- if (fdv < 0) {
- VE_IGNORE_EINTR (close (fd));
- return -1;
- }
-
- while (vtno < gdm_daemon_config_get_value_int (GDM_KEY_FIRST_VT)) {
- int oldvt = vtno;
- to_close_vts = g_list_prepend (to_close_vts,
- GINT_TO_POINTER (fdv));
-
- if (ioctl (fd, VT_OPENQRY, &vtno) == -1) {
- vtno = -1;
- goto cleanup;
- }
-
- if (oldvt == vtno) {
- vtno = -1;
- goto cleanup;
- }
-
- fdv = open_vt (vtno);
- if (fdv < 0) {
- vtno = -1;
- goto cleanup;
- }
- }
-
- *vtfd = fdv;
-
-cleanup:
- for (li = to_close_vts; li != NULL; li = li->next) {
- VE_IGNORE_EINTR (close (GPOINTER_TO_INT (li->data)));
- }
- return vtno;
-}
-
-#endif
-
-char *
-gdm_get_empty_vt_argument (int *fd, int *vt)
-{
- if ( ! gdm_daemon_config_get_value_bool (GDM_KEY_VT_ALLOCATION)) {
- *fd = -1;
- return NULL;
- }
-
-#if defined (__linux__)
- *vt = get_free_vt_linux (fd);
-#elif defined (__FreeBSD__) || defined (__DragonFly__)
- *vt = get_free_vt_freebsd_dragonfly (fd);
-#endif
-
- if (*vt < 0)
- return NULL;
- else
- return g_strdup_printf ("vt%d", *vt);
-}
-
-/* change to an existing vt */
-void
-gdm_change_vt (int vt)
-{
- int fd;
- if (vt < 0)
- return;
-
- do {
- errno = 0;
- fd = open ("/dev/console", O_WRONLY
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
- , 0);
- } while G_UNLIKELY (errno == EINTR);
- if (fd < 0)
- return;
-
- ioctl (fd, VT_ACTIVATE, vt);
- ioctl (fd, VT_WAITACTIVE, vt);
-
- VE_IGNORE_EINTR (close (fd));
-}
-
-int
-gdm_get_cur_vt (void)
-{
-#if defined (__linux__)
- struct vt_stat s;
-#elif defined (__FreeBSD__) || defined (__DragonFly__)
- int vtno;
-#endif
- int fd;
-
- do {
- errno = 0;
- fd = open ("/dev/console", O_WRONLY
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
- , 0);
- } while G_UNLIKELY (errno == EINTR);
- if (fd < 0)
- return -1;
-#if defined (__linux__)
- ioctl (fd, VT_GETSTATE, &s);
-
- VE_IGNORE_EINTR (close (fd));
-
- /* debug */
- /*
- printf ("current_Active %d\n", (int)s.v_active);
- */
-
- return s.v_active;
-#elif defined (__FreeBSD__) || defined (__DragonFly__)
- if (ioctl (fd, VT_GETACTIVE, &vtno) == -1) {
- VE_IGNORE_EINTR (close (fd));
- return -1;
- }
-
- VE_IGNORE_EINTR (close (fd));
-
- /* debug */
- /*
- printf ("current_Active %d\n", vtno);
- */
-
- return vtno;
-#endif
-}
-
-#else /* here this is just a stub, we don't know how to do this outside
- of linux really */
-
-char *
-gdm_get_empty_vt_argument (int *fd, int *vt)
-{
- *fd = -1;
- *vt = -1;
- return NULL;
-}
-
-void
-gdm_change_vt (int vt)
-{
- return;
-}
-
-int
-gdm_get_cur_vt (void)
-{
- return -1;
-}
-
-#endif
diff --git a/daemon/getvt.h b/daemon/getvt.h
deleted file mode 100644
index fdb1c02d..00000000
--- a/daemon/getvt.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 2002 Queen of England
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef GETVT_H
-#define GETVT_H
-
-/* gets an argument we should pass to the X server, on
- * linux for example we get the first empty vt (higher than
- * or equal to GDM_KEY_FIRST_VT) and then return vt<number>
- * (e.g. "vt7") as a newly allocated string.
- * Can return NULL if we can't figure out what to do
- * or if GDM_KEY_VT_ALLOCATION is false. */
-/* fd is opened so that we are saying we have opened this
- * vt. This should be closed after the server has started.
- * This is to avoid race with other stuff openning this vt.
- * It can be set to -1 if nothing could be opened. */
-char * gdm_get_empty_vt_argument (int *fd,
- int *vt);
-
-/* Change to the specified virtual terminal */
-void gdm_change_vt (int vt);
-
-/* Get the current virtual terminal number or -1 if we can't */
-int gdm_get_cur_vt (void);
-
-#endif /* GETVT_H */
diff --git a/daemon/md5.c b/daemon/md5.c
deleted file mode 100644
index 3faf29a0..00000000
--- a/daemon/md5.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest. This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * GdmMD5Context structure, pass it to gdm_md5_init, call
- * gdm_md5_update as needed on buffers full of bytes, and then call
- * gdm_md5_final, which will fill a supplied 16-byte array with the
- * digest.
- *
- * Changed all names to avoid glibc namespace pollution -- mkp
- *
- */
-
-#include "config.h"
-#include <string.h> /* for memcpy () */
-#include <glib.h>
-
-#ifdef __LINUX__
-#include <endian.h>
-#endif
-
-#include "md5.h"
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define byteReverse(buf, len) /* Nothing */
-#else
-
-/*
- * Note: this code is harmless on little-endian machines.
- */
-static void
-byteReverse(unsigned char *buf, unsigned longs)
-{
- guint32 t;
- do {
- t = (guint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
- ((unsigned) buf[1] << 8 | buf[0]);
- *(guint32 *) buf = t;
- buf += 4;
- } while (--longs);
-}
-
-#endif
-
-/*
- * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
-void
-gdm_md5_init (struct GdmMD5Context *ctx)
-{
- ctx->buf[0] = 0x67452301;
- ctx->buf[1] = 0xefcdab89;
- ctx->buf[2] = 0x98badcfe;
- ctx->buf[3] = 0x10325476;
-
- ctx->bits[0] = 0;
- ctx->bits[1] = 0;
-}
-
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-void
-gdm_md5_update (struct GdmMD5Context *ctx, unsigned char const *buf, unsigned len)
-{
- guint32 t;
-
- /* Update bitcount */
-
- t = ctx->bits[0];
- if ((ctx->bits[0] = t + ((guint32) len << 3)) < t)
- ctx->bits[1]++; /* Carry from low to high */
- ctx->bits[1] += len >> 29;
-
- t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
-
- /* Handle any leading odd-sized chunks */
-
- if (t) {
- unsigned char *p = (unsigned char *) ctx->in + t;
-
- t = 64 - t;
- if (len < t) {
- memcpy (p, buf, len);
- return;
- }
- memcpy (p, buf, t);
- byteReverse(ctx->in, 16);
- gdm_md5_transform (ctx->buf, (guint32 *) ctx->in);
- buf += t;
- len -= t;
- }
-
- /* Process data in 64-byte chunks */
-
- while (len >= 64) {
- memcpy (ctx->in, buf, 64);
- byteReverse(ctx->in, 16);
- gdm_md5_transform (ctx->buf, (guint32 *) ctx->in);
- buf += 64;
- len -= 64;
- }
-
- /* Handle any remaining bytes of data. */
-
- memcpy (ctx->in, buf, len);
-}
-
-/*
- * Final wrapup - pad to 64-byte boundary with the bit pattern
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-void
-gdm_md5_final (unsigned char digest[16], struct GdmMD5Context *ctx)
-{
- unsigned count;
- unsigned char *p;
-
- /* Compute number of bytes mod 64 */
- count = (ctx->bits[0] >> 3) & 0x3F;
-
- /* Set the first char of padding to 0x80. This is safe since there is
- always at least one byte free */
- p = ctx->in + count;
- *p++ = 0x80;
-
- /* Bytes of padding needed to make 64 bytes */
- count = 64 - 1 - count;
-
- /* Pad out to 56 mod 64 */
- if (count < 8) {
- /* Two lots of padding: Pad the first block to 64 bytes */
- memset (p, 0, count);
- byteReverse(ctx->in, 16);
- gdm_md5_transform (ctx->buf, (guint32 *) ctx->in);
-
- /* Now fill the next block with 56 bytes */
- memset (ctx->in, 0, 56);
- } else {
- /* Pad block to 56 bytes */
- memset (p, 0, count - 8);
- }
- byteReverse(ctx->in, 14);
-
- /* Append length in bits and transform */
- ((guint32 *) ctx->in)[14] = ctx->bits[0];
- ((guint32 *) ctx->in)[15] = ctx->bits[1];
-
- gdm_md5_transform (ctx->buf, (guint32 *) ctx->in);
- byteReverse((unsigned char *) ctx->buf, 4);
- memcpy (digest, ctx->buf, 16);
- memset (ctx, 0, sizeof (ctx)); /* In case it's sensitive */
-}
-
-
-/* The four core functions - F1 is optimized somewhat */
-
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1 (z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define gdm_md5_step(f, w, x, y, z, data, s) \
- ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data. GdmMD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-void
-gdm_md5_transform (guint32 buf[4], guint32 const in[16])
-{
- register guint32 a, b, c, d;
-
- a = buf[0];
- b = buf[1];
- c = buf[2];
- d = buf[3];
-
- gdm_md5_step(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
- gdm_md5_step(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
- gdm_md5_step(F1, c, d, a, b, in[2] + 0x242070db, 17);
- gdm_md5_step(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
- gdm_md5_step(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
- gdm_md5_step(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
- gdm_md5_step(F1, c, d, a, b, in[6] + 0xa8304613, 17);
- gdm_md5_step(F1, b, c, d, a, in[7] + 0xfd469501, 22);
- gdm_md5_step(F1, a, b, c, d, in[8] + 0x698098d8, 7);
- gdm_md5_step(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
- gdm_md5_step(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
- gdm_md5_step(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
- gdm_md5_step(F1, a, b, c, d, in[12] + 0x6b901122, 7);
- gdm_md5_step(F1, d, a, b, c, in[13] + 0xfd987193, 12);
- gdm_md5_step(F1, c, d, a, b, in[14] + 0xa679438e, 17);
- gdm_md5_step(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
- gdm_md5_step(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
- gdm_md5_step(F2, d, a, b, c, in[6] + 0xc040b340, 9);
- gdm_md5_step(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
- gdm_md5_step(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
- gdm_md5_step(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
- gdm_md5_step(F2, d, a, b, c, in[10] + 0x02441453, 9);
- gdm_md5_step(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
- gdm_md5_step(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
- gdm_md5_step(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
- gdm_md5_step(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
- gdm_md5_step(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
- gdm_md5_step(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
- gdm_md5_step(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
- gdm_md5_step(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
- gdm_md5_step(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
- gdm_md5_step(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
- gdm_md5_step(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
- gdm_md5_step(F3, d, a, b, c, in[8] + 0x8771f681, 11);
- gdm_md5_step(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
- gdm_md5_step(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
- gdm_md5_step(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
- gdm_md5_step(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
- gdm_md5_step(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
- gdm_md5_step(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
- gdm_md5_step(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
- gdm_md5_step(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
- gdm_md5_step(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
- gdm_md5_step(F3, b, c, d, a, in[6] + 0x04881d05, 23);
- gdm_md5_step(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
- gdm_md5_step(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
- gdm_md5_step(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
- gdm_md5_step(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
- gdm_md5_step(F4, a, b, c, d, in[0] + 0xf4292244, 6);
- gdm_md5_step(F4, d, a, b, c, in[7] + 0x432aff97, 10);
- gdm_md5_step(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
- gdm_md5_step(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
- gdm_md5_step(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
- gdm_md5_step(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
- gdm_md5_step(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
- gdm_md5_step(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
- gdm_md5_step(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
- gdm_md5_step(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
- gdm_md5_step(F4, c, d, a, b, in[6] + 0xa3014314, 15);
- gdm_md5_step(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
- gdm_md5_step(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
- gdm_md5_step(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
- gdm_md5_step(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
- gdm_md5_step(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-
- buf[0] += a;
- buf[1] += b;
- buf[2] += c;
- buf[3] += d;
-}
-
-
-
diff --git a/daemon/md5.h b/daemon/md5.h
deleted file mode 100644
index 38b992b0..00000000
--- a/daemon/md5.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef GdmMD5_H
-#define GdmMD5_H
-
-#include <glib.h>
-
-struct GdmMD5Context {
- guint32 buf[4];
- guint32 bits[2];
- unsigned char in[64];
-};
-
-void gdm_md5_init (struct GdmMD5Context *context);
-void gdm_md5_update (struct GdmMD5Context *context, unsigned char const *buf,
- unsigned len);
-void gdm_md5_final (unsigned char digest[16], struct GdmMD5Context *context);
-void gdm_md5_transform (guint32 buf[4], guint32 const in[16]);
-
-/*
- * This is needed to make RSAREF happy on some MS-DOS compilers.
- */
-/* typedef struct gdm_md5_Context gdm_md5__CTX; */
-
-#endif /* !GdmMD5_H */
diff --git a/daemon/misc.c b/daemon/misc.c
deleted file mode 100644
index 76e6887e..00000000
--- a/daemon/misc.c
+++ /dev/null
@@ -1,2171 +0,0 @@
-/* -*- 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
- * 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
- */
-
-#include "config.h"
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <signal.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <net/if.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <errno.h>
-#include <grp.h>
-#include <pwd.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif
-#ifdef HAVE_DEFOPEN
-#include <deflt.h>
-#endif
-
-#include <X11/Xlib.h>
-
-#include <glib/gi18n.h>
-
-#include "gdm.h"
-#include "misc.h"
-#include "xdmcp.h"
-#include "slave.h"
-
-#include "gdm-common.h"
-#include "gdm-log.h"
-#include "gdm-daemon-config.h"
-
-extern char **environ;
-
-#ifdef ENABLE_IPV6
-
-#ifdef __sun
-static gboolean
-have_ipv6_solaris (void)
-{
- int s, i;
- int ret;
- struct lifnum ln;
- struct lifconf ifc;
- struct lifreq *ifr;
- char *ifreqs;
-
- /* First, try the <AB>classic<BB> way */
- s = socket (AF_INET6, SOCK_DGRAM, 0);
- if (s < 0) return FALSE;
- close (s);
-
- s = socket (AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
-
- /*
- * Ok, the system is able to create IPv6 sockets, so
- * lets check if IPv6 is configured in the machine
- */
- ln.lifn_family=AF_UNSPEC;
- ln.lifn_flags=ln.lifn_count=0;
-
- ret = ioctl (s, SIOCGLIFNUM, &ln);
- if (ret == -1) {
- perror ("ioctl SIOCGLIFNUM");
- return FALSE;
- }
-
- /* Alloc the memory and get the configuration */
- ifc.lifc_flags = 0;
- ifc.lifc_family = AF_UNSPEC;
- ifc.lifc_len = ln.lifn_count * sizeof (struct lifreq);
-
- ifreqs = (char *) malloc (ifc.lifc_len);
- ifc.lifc_buf = ifreqs;
-
- if (ioctl (s, SIOCGLIFCONF, &ifc) < 0) {
- perror ("ioctl SIOCGLIFCONF");
- return FALSE;
- }
-
- /* Check each interface */
- ifr = ifc.lifc_req;
- ret = FALSE;
-
- for (i = ifc.lifc_len/sizeof (struct lifreq); --i >= 0; ifr++) {
- struct sockaddr_in *sin;
-
- /* Check the address */
- if (ioctl (s, SIOCGLIFFLAGS, ifr) < 0) {
- /* perror ("ioctl SIOCGLIFADDR"); */
- continue;
- }
-
- sin = (struct sockaddr_in *)&ifr->lifr_addr;
-
- if (sin->sin_family == AF_INET6) {
- ret = TRUE;
- break;
- }
-
- /* Check the interface flags */
- if (ioctl (s, SIOCGLIFFLAGS, (char *) ifr) < 0) {
- /* perror ("ioctl SIOCGLIFFLAGS"); */
- continue;
- }
-
- if (ifr->lifr_flags & IFF_IPV6) {
- ret = TRUE;
- break;
- }
- }
-
- /* Clean up */
- free (ifreqs);
- close (s);
-
- return ret;
-}
-#endif
-
-static gboolean
-have_ipv6 (void)
-{
- int s;
- static gboolean has_ipv6 = -1;
-
-#ifdef __sun
- has_ipv6 = have_ipv6_solaris ();
-#else
- if (has_ipv6 != -1) return has_ipv6;
-
- s = socket (AF_INET6, SOCK_STREAM, 0);
- if (s < 0) {
- has_ipv6 = FALSE;
- return FALSE;
- }
-
- VE_IGNORE_EINTR (close (s));
-#endif
- return has_ipv6;
-}
-#endif
-
-void
-gdm_fdprintf (int fd, const gchar *format, ...)
-{
- va_list args;
- gchar *s;
- int written, len;
-
- va_start (args, format);
- s = g_strdup_vprintf (format, args);
- va_end (args);
-
- len = strlen (s);
-
- if (len == 0) {
- g_free (s);
- return;
- }
-
- written = 0;
- while (written < len) {
- int w;
- VE_IGNORE_EINTR (w = write (fd, &s[written], len - written));
- if (w < 0)
- /* evil! */
- break;
- written += w;
- }
-
- g_free (s);
-}
-
-/*
- * Clear environment, but keep the i18n ones,
- * note that this leaks memory so only use before exec
- */
-void
-gdm_clearenv_no_lang (void)
-{
- int i;
- GList *li, *envs = NULL;
-
- for (i = 0; environ[i] != NULL; i++) {
- 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));
- }
- }
-
- ve_clearenv ();
-
- for (li = envs; li != NULL; li = li->next) {
- putenv (li->data);
- }
-
- g_list_free (envs);
-}
-
-static GList *stored_env = NULL;
-
-void
-gdm_saveenv (void)
-{
- int i;
-
- g_list_foreach (stored_env, (GFunc)g_free, NULL);
- g_list_free (stored_env);
- stored_env = NULL;
-
- for (i = 0; environ[i] != NULL; i++) {
- char *env = environ[i];
- stored_env = g_list_prepend (stored_env, g_strdup (env));
- }
-}
-
-const char *
-gdm_saved_getenv (const char *var)
-{
- int len;
- GList *li;
-
- len = strlen (var);
-
- for (li = stored_env; li != NULL; li = li->next) {
- const char *e = li->data;
- if (strncmp (var, e, len) == 0 &&
- e[len] == '=') {
- return &(e[len+1]);
- }
- }
- return NULL;
-}
-
-/* leaks */
-void
-gdm_restoreenv (void)
-{
- GList *li;
-
- ve_clearenv ();
-
- for (li = stored_env; li != NULL; li = li->next) {
- putenv (g_strdup (li->data));
- }
-}
-
-/* Evil function to figure out which display number is free */
-int
-gdm_get_free_display (int start, uid_t server_uid)
-{
- int sock;
- int i;
- struct sockaddr_in serv_addr = { 0 };
-
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-
- /*
- * Cap this at 3000, I'm not sure we can ever seriously
- * go that far
- */
- for (i = start; i < 3000; i++) {
- GSList *li;
- struct stat s;
- 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;
- if (SERVER_IS_LOCAL (dsp) &&
- dsp->dispnum == i)
- break;
- }
- if (li != NULL) {
- /* found one */
- continue;
- }
-
-#ifdef ENABLE_IPV6
- if (have_ipv6 ()) {
- struct sockaddr_in6 serv6_addr = { 0 };
-
- sock = socket (AF_INET6, SOCK_STREAM,0);
-
- serv6_addr.sin6_family = AF_INET6;
- serv6_addr.sin6_addr = in6addr_loopback;
- serv6_addr.sin6_port = htons (6000 + i);
- errno = 0;
- VE_IGNORE_EINTR (connect (sock,
- (struct sockaddr *)&serv6_addr,
- sizeof (serv6_addr)));
- }
- else
-#endif
- {
- sock = socket (AF_INET, SOCK_STREAM, 0);
-
- serv_addr.sin_port = htons (6000 + i);
-
- errno = 0;
- VE_IGNORE_EINTR (connect (sock,
- (struct sockaddr *)&serv_addr,
- sizeof (serv_addr)));
- }
- if (errno != 0 && errno != ECONNREFUSED) {
- VE_IGNORE_EINTR (close (sock));
- continue;
- }
- VE_IGNORE_EINTR (close (sock));
-
- /* if lock file exists and the process exists */
- g_snprintf (buf, sizeof (buf), "/tmp/.X%d-lock", i);
- VE_IGNORE_EINTR (r = g_stat (buf, &s));
- if (r == 0 &&
- ! S_ISREG (s.st_mode)) {
- /*
- * Eeeek! not a regular file? Perhaps someone
- * is trying to play tricks on us
- */
- continue;
- }
- VE_IGNORE_EINTR (fp = fopen (buf, "r"));
- if (fp != NULL) {
- char buf2[100];
- char *getsret;
- VE_IGNORE_EINTR (getsret = fgets (buf2, sizeof (buf2), fp));
- if (getsret != NULL) {
- gulong pid;
- if (sscanf (buf2, "%lu", &pid) == 1 &&
- kill (pid, 0) == 0) {
- VE_IGNORE_EINTR (fclose (fp));
- continue;
- }
-
- }
- VE_IGNORE_EINTR (fclose (fp));
-
- /* whack the file, it's a stale lock file */
- VE_IGNORE_EINTR (g_unlink (buf));
- }
-
- /* If starting as root, we'll be able to overwrite any
- * stale sockets or lock files, but a user may not be
- * able to */
- if (server_uid > 0) {
- g_snprintf (buf, sizeof (buf),
- "/tmp/.X11-unix/X%d", i);
- VE_IGNORE_EINTR (r = g_stat (buf, &s));
- if (r == 0 &&
- s.st_uid != server_uid) {
- continue;
- }
-
- g_snprintf (buf, sizeof (buf),
- "/tmp/.X%d-lock", i);
- VE_IGNORE_EINTR (r = g_stat (buf, &s));
- if (r == 0 &&
- s.st_uid != server_uid) {
- continue;
- }
- }
-
- return i;
- }
-
- return -1;
-}
-
-gboolean
-gdm_text_message_dialog (const char *msg)
-{
- char *dialog; /* do we have dialog? */
- char *msg_quoted;
-
- if ( ! gdm_daemon_config_get_value_bool (GDM_KEY_CONSOLE_NOTIFY))
- return FALSE;
-
- if (g_access (LIBEXECDIR "/gdmopen", X_OK) != 0)
- return FALSE;
-
- if (msg[0] == '-') {
- char *tmp = g_strconcat (" ", msg, NULL);
- msg_quoted = g_shell_quote (tmp);
- g_free (tmp);
- } else {
- msg_quoted = g_shell_quote (msg);
- }
-
- dialog = g_find_program_in_path ("dialog");
- if (dialog == NULL)
- dialog = g_find_program_in_path ("whiptail");
- if (dialog != NULL) {
- char *argv[6];
-
- if ( ! gdm_ok_console_language ()) {
- g_unsetenv ("LANG");
- g_unsetenv ("LC_ALL");
- g_unsetenv ("LC_MESSAGES");
- g_setenv ("LANG", "C", TRUE);
- g_setenv ("UNSAFE_TO_TRANSLATE", "yes", TRUE);
- }
-
- argv[0] = LIBEXECDIR "/gdmopen";
- argv[1] = "-l";
- argv[2] = "/bin/sh";
- argv[3] = "-c";
- argv[4] = g_strdup_printf ("%s --msgbox %s 16 70",
- dialog, msg_quoted);
- argv[5] = NULL;
-
- /* Make sure gdialog wouldn't get confused */
- if (gdm_exec_wait (argv, TRUE /* no display */,
- TRUE /* de_setuid */) < 0) {
- g_free (dialog);
- g_free (msg_quoted);
- g_free (argv[4]);
- return FALSE;
- }
-
- g_free (dialog);
- g_free (argv[4]);
- } else {
- char *argv[6];
-
- argv[0] = LIBEXECDIR "/gdmopen";
- argv[1] = "-l";
- argv[2] = "/bin/sh";
- argv[3] = "-c";
- argv[4] = g_strdup_printf
- ("clear ; "
- "echo %s ; read ; clear",
- msg_quoted);
- argv[5] = NULL;
-
- if (gdm_exec_wait (argv, TRUE /* no display */,
- TRUE /* de_setuid */) < 0) {
- g_free (argv[4]);
- g_free (msg_quoted);
- return FALSE;
- }
- g_free (argv[4]);
- }
- g_free (msg_quoted);
- return TRUE;
-}
-
-gboolean
-gdm_text_yesno_dialog (const char *msg, gboolean *ret)
-{
- char *dialog; /* do we have dialog? */
- char *msg_quoted;
-
- if ( ! gdm_daemon_config_get_value_bool (GDM_KEY_CONSOLE_NOTIFY))
- return FALSE;
-
- if (g_access (LIBEXECDIR "/gdmopen", X_OK) != 0)
- return FALSE;
-
- if (ret != NULL)
- *ret = FALSE;
-
- if (msg[0] == '-') {
- char *tmp = g_strconcat (" ", msg, NULL);
- msg_quoted = g_shell_quote (tmp);
- g_free (tmp);
- } else {
- msg_quoted = g_shell_quote (msg);
- }
-
- dialog = g_find_program_in_path ("dialog");
- if (dialog == NULL)
- dialog = g_find_program_in_path ("whiptail");
- if (dialog != NULL) {
- char *argv[6];
- int retint;
-
- if ( ! gdm_ok_console_language ()) {
- g_unsetenv ("LANG");
- g_unsetenv ("LC_ALL");
- g_unsetenv ("LC_MESSAGES");
- g_setenv ("LANG", "C", TRUE);
- g_setenv ("UNSAFE_TO_TRANSLATE", "yes", TRUE);
- }
-
- argv[0] = LIBEXECDIR "/gdmopen";
- argv[1] = "-l";
- argv[2] = "/bin/sh";
- argv[3] = "-c";
- argv[4] = g_strdup_printf ("%s --yesno %s 16 70",
- dialog, msg_quoted);
- argv[5] = NULL;
-
- /*
- * Will unset DISPLAY and XAUTHORITY if they exist
- * so that gdialog (if used) doesn't get confused
- */
- retint = gdm_exec_wait (argv, TRUE /* no display */,
- TRUE /* de_setuid */);
- if (retint < 0) {
- g_free (argv[4]);
- g_free (dialog);
- g_free (msg_quoted);
- return FALSE;
- }
-
- if (ret != NULL)
- *ret = (retint == 0) ? TRUE : FALSE;
-
- g_free (dialog);
- g_free (msg_quoted);
- g_free (argv[4]);
-
- return TRUE;
- } else {
- char tempname[] = "/tmp/gdm-yesno-XXXXXX";
- int tempfd;
- FILE *fp;
- char buf[256];
- char *argv[6];
-
- tempfd = g_mkstemp (tempname);
- if (tempfd < 0) {
- g_free (msg_quoted);
- return FALSE;
- }
-
- VE_IGNORE_EINTR (close (tempfd));
-
- argv[0] = LIBEXECDIR "/gdmopen";
- argv[1] = "-l";
- argv[2] = "/bin/sh";
- argv[3] = "-c";
- argv[4] = g_strdup_printf
- ("clear ; "
- "echo %s ; echo ; echo \"%s\" ; "
- "read RETURN ; echo $RETURN > %s ; clear'",
- msg_quoted,
- /* Translators, don't translate the 'y' and 'n' */
- _("y = Yes or n = No? >"),
- tempname);
- argv[5] = NULL;
-
- if (gdm_exec_wait (argv, TRUE /* no display */,
- TRUE /* de_setuid */) < 0) {
- g_free (argv[4]);
- g_free (msg_quoted);
- return FALSE;
- }
- g_free (argv[4]);
-
- if (ret != NULL) {
- VE_IGNORE_EINTR (fp = fopen (tempname, "r"));
- if (fp != NULL) {
- if (fgets (buf, sizeof (buf), fp) != NULL &&
- (buf[0] == 'y' || buf[0] == 'Y'))
- *ret = TRUE;
- VE_IGNORE_EINTR (fclose (fp));
- } else {
- g_free (msg_quoted);
- return FALSE;
- }
- }
-
- VE_IGNORE_EINTR (g_unlink (tempname));
-
- g_free (msg_quoted);
- return TRUE;
- }
-}
-
-int
-gdm_exec_wait (char * const *argv,
- gboolean no_display,
- gboolean de_setuid)
-{
- int status;
- pid_t pid;
-
- if (argv == NULL ||
- argv[0] == NULL ||
- g_access (argv[0], X_OK) != 0)
- return -1;
-
- g_debug ("Forking extra process: %s", argv[0]);
-
- pid = gdm_fork_extra ();
- if (pid == 0) {
- gdm_log_shutdown ();
-
- gdm_close_all_descriptors (0 /* from */, -1 /* except */, -1 /* except2 */);
-
- /*
- * No error checking here - if it's messed the best response
- * is to ignore & try to continue
- */
- gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
- gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
- gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
-
- if (de_setuid) {
- gdm_desetuid ();
- }
-
- gdm_log_init ();
-
- if (no_display) {
- g_unsetenv ("DISPLAY");
- g_unsetenv ("XAUTHORITY");
- }
-
- VE_IGNORE_EINTR (execv (argv[0], argv));
-
- _exit (-1);
- }
-
- if (pid < 0)
- return -1;
-
- gdm_wait_for_extra (pid, &status);
-
- if (WIFEXITED (status))
- return WEXITSTATUS (status);
- else
- return -1;
-}
-
-static int sigchld_blocked = 0;
-static sigset_t sigchldblock_mask, sigchldblock_oldmask;
-
-static int sigterm_blocked = 0;
-static sigset_t sigtermblock_mask, sigtermblock_oldmask;
-
-static int sigusr2_blocked = 0;
-static sigset_t sigusr2block_mask, sigusr2block_oldmask;
-
-void
-gdm_sigchld_block_push (void)
-{
- sigchld_blocked++;
-
- if (sigchld_blocked == 1) {
- /* Set signal mask */
- sigemptyset (&sigchldblock_mask);
- sigaddset (&sigchldblock_mask, SIGCHLD);
- sigprocmask (SIG_BLOCK, &sigchldblock_mask, &sigchldblock_oldmask);
- }
-}
-
-void
-gdm_sigchld_block_pop (void)
-{
- sigchld_blocked --;
-
- if (sigchld_blocked == 0) {
- /* Reset signal mask back */
- sigprocmask (SIG_SETMASK, &sigchldblock_oldmask, NULL);
- }
-}
-
-void
-gdm_sigterm_block_push (void)
-{
- sigterm_blocked++;
-
- if (sigterm_blocked == 1) {
- /* Set signal mask */
- sigemptyset (&sigtermblock_mask);
- sigaddset (&sigtermblock_mask, SIGTERM);
- sigaddset (&sigtermblock_mask, SIGINT);
- sigaddset (&sigtermblock_mask, SIGHUP);
- sigprocmask (SIG_BLOCK, &sigtermblock_mask, &sigtermblock_oldmask);
- }
-}
-
-void
-gdm_sigterm_block_pop (void)
-{
- sigterm_blocked --;
-
- if (sigterm_blocked == 0) {
- /* Reset signal mask back */
- sigprocmask (SIG_SETMASK, &sigtermblock_oldmask, NULL);
- }
-}
-
-void
-gdm_sigusr2_block_push (void)
-{
- sigset_t oldmask;
-
- if (sigusr2_blocked == 0) {
- /* Set signal mask */
- sigemptyset (&sigusr2block_mask);
- sigaddset (&sigusr2block_mask, SIGUSR2);
- sigprocmask (SIG_BLOCK, &sigusr2block_mask, &oldmask);
- }
-
- sigusr2_blocked++;
-
- sigusr2block_oldmask = oldmask;
-}
-
-void
-gdm_sigusr2_block_pop (void)
-{
- sigset_t oldmask;
-
- oldmask = sigusr2block_oldmask;
-
- sigusr2_blocked--;
-
- if (sigusr2_blocked == 0) {
- /* Reset signal mask back */
- sigprocmask (SIG_SETMASK, &sigusr2block_oldmask, NULL);
- }
-}
-
-pid_t
-gdm_fork_extra (void)
-{
- pid_t pid;
-
- gdm_sigchld_block_push ();
- gdm_sigterm_block_push ();
-
- pid = fork ();
- if (pid < 0)
- return 0;
- else if (pid == 0)
- /*
- * Unset signals here, and yet again
- * later as the block_pop will whack
- * our signal mask
- */
- gdm_unset_signals ();
-
- gdm_sigterm_block_pop ();
- gdm_sigchld_block_pop ();
-
- if (pid == 0) {
- /*
- * In the child setup empty mask and set all signals to
- * default values
- */
- gdm_unset_signals ();
-
- /*
- * Also make a new process group so that we may use
- * kill -(extra_process) to kill extra process and all it's
- * possible children
- */
- setsid ();
-
- /* Harmless in children, but in case we'd run
- extra processes from main daemon would fix
- problems ... */
- if (gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP))
- gdm_xdmcp_close ();
- }
-
- return pid;
-}
-
-void
-gdm_wait_for_extra (pid_t pid,
- int *statusp)
-{
- int status;
-
- gdm_sigchld_block_push ();
-
- if (pid > 1) {
- ve_waitpid_no_signal (pid, &status, 0);
- }
-
- if (statusp != NULL)
- *statusp = status;
-
- gdm_sigchld_block_pop ();
-}
-
-static void
-ensure_tmp_socket_dir (const char *dir)
-{
- mode_t old_umask;
-
- /*
- * The /tmp/.ICE-unix / .X11-unix check, note that we do
- * ignore errors, since it's not deadly to run
- * if we can't perform this task :)
- */
- old_umask = umask (0);
-
- if G_UNLIKELY (g_mkdir (dir, 01777) != 0) {
- /*
- * If we can't create it, perhaps it
- * already exists, in which case ensure the
- * correct permissions
- */
- struct stat s;
- int r;
- VE_IGNORE_EINTR (r = g_lstat (dir, &s));
- if G_LIKELY (r == 0 && S_ISDIR (s.st_mode)) {
- /* Make sure it is root and sticky */
- VE_IGNORE_EINTR (chown (dir, 0, 0));
- VE_IGNORE_EINTR (g_chmod (dir, 01777));
- } else {
- /*
- * There is a file/link/whatever of the same name?
- * whack and try mkdir
- */
- VE_IGNORE_EINTR (g_unlink (dir));
- g_mkdir (dir, 01777);
- }
- }
-
- umask (old_umask);
-}
-
-/*
- * Done on startup and when running display_manage
- * This can do some sanity ensuring, one of the things it does now is make
- * sure /tmp/.ICE-unix and /tmp/.X11-unix exist and have the correct
- * permissions
- */
-void
-gdm_ensure_sanity (void)
-{
- uid_t old_euid;
- gid_t old_egid;
-
- old_euid = geteuid ();
- old_egid = getegid ();
-
- NEVER_FAILS_root_set_euid_egid (0, 0);
-
- ensure_tmp_socket_dir ("/tmp/.ICE-unix");
- ensure_tmp_socket_dir ("/tmp/.X11-unix");
-
- NEVER_FAILS_root_set_euid_egid (old_euid, old_egid);
-}
-
-const GList *
-gdm_address_peek_local_list (void)
-{
- static GList *the_list = NULL;
- static time_t last_time = 0;
- char hostbuf[BUFSIZ];
- struct addrinfo hints;
- struct addrinfo *result;
- struct addrinfo *res;
-
- /* Don't check more then every 5 seconds */
- 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);
-
- hostbuf[BUFSIZ-1] = '\0';
- if (gethostname (hostbuf, BUFSIZ-1) != 0) {
- 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");
-
- return NULL;
- }
-
- 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) {
- freeaddrinfo (result);
- result = NULL;
- }
-
- return the_list;
-}
-
-
-gboolean
-gdm_address_is_local (struct sockaddr_storage *sa)
-{
- const GList *list;
-
- if (gdm_address_is_loopback (sa)) {
- return TRUE;
- }
-
- list = gdm_address_peek_local_list ();
-
- while (list != NULL) {
- struct sockaddr_storage *addr = list->data;
-
- if (gdm_address_equal (sa, addr)) {
- return TRUE;
- }
-
- list = list->next;
- }
-
- return FALSE;
-}
-
-gboolean
-gdm_setup_gids (const char *login, gid_t gid)
-{
- /*
- * FIXME: perhaps for *BSD there should be setusercontext
- * stuff here
- */
- if G_UNLIKELY (setgid (gid) < 0) {
- gdm_error (_("Could not setgid %d. Aborting."), (int)gid);
- return FALSE;
- }
-
- if G_UNLIKELY (initgroups (login, gid) < 0) {
- gdm_error (_("initgroups () failed for %s. Aborting."), login);
- return FALSE;
- }
-
- return TRUE;
-}
-
-void
-gdm_desetuid (void)
-{
- uid_t uid = getuid ();
- gid_t gid = getgid ();
-
-#ifdef HAVE_SETRESUID
- {
- int setresuid (uid_t ruid, uid_t euid, uid_t suid);
- int setresgid (gid_t rgid, gid_t egid, gid_t sgid);
- setresgid (gid, gid, gid);
- setresuid (uid, uid, uid);
- }
-#else
- setegid (getgid ());
- seteuid (getuid ());
-#endif
-}
-
-gboolean
-gdm_test_opt (const char *cmd, const char *help, const char *option)
-{
- char *q;
- char *full;
- char buf[1024];
- FILE *fp;
- static GString *cache = NULL;
- static char *cached_cmd = NULL;
- gboolean got_it;
-
- if (cached_cmd != NULL &&
- strcmp (cached_cmd, cmd) == 0) {
- char *p = strstr (ve_sure_string (cache->str), option);
- char end;
- if (p == NULL)
- return FALSE;
- /* Must be a full word */
- end = *(p + strlen (option));
- if ((end >= 'a' && end <= 'z') ||
- (end >= 'A' && end <= 'Z') ||
- (end >= '0' && end <= '9') ||
- end == '_')
- return FALSE;
- return TRUE;
- }
-
- g_free (cached_cmd);
- cached_cmd = g_strdup (cmd);
- if (cache != NULL)
- g_string_assign (cache, "");
- else
- cache = g_string_new (NULL);
-
- q = g_shell_quote (cmd);
-
- full = g_strdup_printf ("%s %s 2>&1", q, help);
- g_free (q);
-
- fp = popen (full, "r");
- g_free (full);
-
- if (fp == NULL)
- return FALSE;
-
- got_it = FALSE;
-
- while (fgets (buf, sizeof (buf), fp) != NULL) {
- char *p;
- char end;
-
- g_string_append (cache, buf);
-
- if (got_it)
- continue;
-
- p = strstr (buf, option);
- if (p == NULL)
- continue;
- /* Must be a full word */
- end = *(p + strlen (option));
- if ((end >= 'a' && end <= 'z') ||
- (end >= 'A' && end <= 'Z') ||
- (end >= '0' && end <= '9') ||
- end == '_')
- continue;
-
- got_it = TRUE;
- }
- VE_IGNORE_EINTR (fclose (fp));
- return got_it;
-}
-
-int
-gdm_fdgetc (int fd)
-{
- unsigned char buf[1];
- int bytes;
-
- /*
- * Must used an unsigned char buffer here because the GUI sends
- * username/password data as utf8 and the daemon will interpret
- * any character sent with its high bit set as EOF unless we
- * used unsigned here.
- */
- VE_IGNORE_EINTR (bytes = read (fd, buf, 1));
- if (bytes != 1)
- return EOF;
- else
- return (int)buf[0];
-}
-
-char *
-gdm_fdgets (int fd)
-{
- int c;
- int bytes = 0;
- GString *gs = g_string_new (NULL);
- for (;;) {
- c = gdm_fdgetc (fd);
- if (c == '\n')
- return g_string_free (gs, FALSE);
- /* on EOF */
- if (c < 0) {
- if (bytes == 0) {
- g_string_free (gs, TRUE);
- return NULL;
- } else {
- return g_string_free (gs, FALSE);
- }
- } else {
- bytes++;
- g_string_append_c (gs, c);
- }
- }
-}
-
-void
-gdm_close_all_descriptors (int from, int except, int except2)
-{
- DIR *dir;
- struct dirent *ent;
- GSList *openfds = NULL;
-
- /*
- * Evil, but less evil then going to _SC_OPEN_MAX
- * which can be very VERY large
- */
- dir = opendir ("/proc/self/fd/"); /* This is the Linux dir */
- if (dir == NULL)
- dir = opendir ("/dev/fd/"); /* This is the FreeBSD dir */
- if G_LIKELY (dir != NULL) {
- GSList *li;
- while ((ent = readdir (dir)) != NULL) {
- int fd;
- if (ent->d_name[0] == '.')
- continue;
- fd = atoi (ent->d_name);
- if (fd >= from && fd != except && fd != except2)
- openfds = g_slist_prepend (openfds, GINT_TO_POINTER (fd));
- }
- closedir (dir);
- for (li = openfds; li != NULL; li = li->next) {
- int fd = GPOINTER_TO_INT (li->data);
- VE_IGNORE_EINTR (close (fd));
- }
- g_slist_free (openfds);
- } else {
- int i;
- int max = sysconf (_SC_OPEN_MAX);
- /*
- * Don't go higher then this. This is
- * a safety measure to not hang on crazy
- * systems
- */
- if G_UNLIKELY (max > 4096) {
- /* FIXME: warn about this perhaps */
- /*
- * Try an open, in case we're really
- * leaking fds somewhere badly, this
- * should be very high
- */
- i = gdm_open_dev_null (O_RDONLY);
- max = MAX (i+1, 4096);
- }
- for (i = from; i < max; i++) {
- if G_LIKELY (i != except && i != except2)
- VE_IGNORE_EINTR (close (i));
- }
- }
-}
-
-int
-gdm_open_dev_null (mode_t mode)
-{
- int ret;
- VE_IGNORE_EINTR (ret = open ("/dev/null", mode));
- if G_UNLIKELY (ret < 0) {
- /*
- * Never output anything, we're likely in some
- * strange state right now
- */
- gdm_signal_ignore (SIGPIPE);
- VE_IGNORE_EINTR (close (2));
- gdm_fail ("Cannot open /dev/null, system on crack!");
- }
-
- return ret;
-}
-
-void
-gdm_unset_signals (void)
-{
- sigset_t mask;
-
- sigemptyset (&mask);
- sigprocmask (SIG_SETMASK, &mask, NULL);
-
- gdm_signal_default (SIGUSR1);
- gdm_signal_default (SIGUSR2);
- gdm_signal_default (SIGCHLD);
- gdm_signal_default (SIGTERM);
- gdm_signal_default (SIGINT);
- gdm_signal_default (SIGPIPE);
- gdm_signal_default (SIGALRM);
- gdm_signal_default (SIGHUP);
- gdm_signal_default (SIGABRT);
-#ifdef SIGXFSZ
- gdm_signal_default (SIGXFSZ);
-#endif
-#ifdef SIGXCPU
- gdm_signal_default (SIGXCPU);
-#endif
-}
-
-void
-gdm_signal_ignore (int signal)
-{
- struct sigaction ign_signal;
-
- ign_signal.sa_handler = SIG_IGN;
- ign_signal.sa_flags = SA_RESTART;
- sigemptyset (&ign_signal.sa_mask);
-
- if G_UNLIKELY (sigaction (signal, &ign_signal, NULL) < 0)
- gdm_error (_("%s: Error setting signal %d to %s"),
- "gdm_signal_ignore", signal, "SIG_IGN");
-}
-
-void
-gdm_signal_default (int signal)
-{
- struct sigaction def_signal;
-
- def_signal.sa_handler = SIG_DFL;
- def_signal.sa_flags = SA_RESTART;
- sigemptyset (&def_signal.sa_mask);
-
- if G_UNLIKELY (sigaction (signal, &def_signal, NULL) < 0)
- gdm_error (_("%s: Error setting signal %d to %s"),
- "gdm_signal_ignore", signal, "SIG_DFL");
-}
-
-static GdmHostent *
-fillout_addrinfo (struct addrinfo *res,
- struct sockaddr *ia,
- const char *name)
-{
- GdmHostent *he;
- gint i;
- gint addr_count = 0;
- struct addrinfo *tempaddrinfo;
-
- he = g_new0 (GdmHostent, 1);
-
- he->addrs = NULL;
- he->addr_count = 0;
-
- if (res != NULL && res->ai_canonname != NULL) {
- he->hostname = g_strdup (res->ai_canonname);
- he->not_found = FALSE;
- } else {
- he->not_found = TRUE;
- if (name != NULL)
- he->hostname = g_strdup (name);
- else {
- 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)) {
- new = inet_ntop (AF_INET, &(((struct sockaddr_in6 *)ia)->sin6_addr.s6_addr[12]), buffer, sizeof (buffer));
- } else {
- new = inet_ntop (AF_INET6, &((struct sockaddr_in6 *)ia)->sin6_addr, buffer6, sizeof (buffer6));
- }
- } else if (ia->sa_family == AF_INET) {
- new = inet_ntop (AF_INET, &((struct sockaddr_in *)ia)->sin_addr, buffer, sizeof (buffer));
- }
-
- if (new != NULL) {
- he->hostname = g_strdup (new);
- } else {
- he->hostname = NULL;
- }
- }
- }
-
- tempaddrinfo = res;
-
- while (res != NULL) {
- addr_count++;
- res = res->ai_next;
- }
-
- he->addrs = g_new0 (struct sockaddr_storage, addr_count);
- he->addr_count = addr_count;
- res = tempaddrinfo;
- for (i = 0; ; i++) {
- if (res == NULL)
- break;
-
- if ((res->ai_family == AF_INET) || (res->ai_family == AF_INET6)) {
- (he->addrs)[i] = *(struct sockaddr_storage *)(res->ai_addr);
- }
-
- res = res->ai_next;
- }
-
- /* We don't want the ::ffff: that could arise here */
- if (he->hostname != NULL &&
- strncmp (he->hostname, "::ffff:", 7) == 0) {
- strcpy (he->hostname, he->hostname + 7);
- }
-
- return he;
-}
-
-static gboolean do_jumpback = FALSE;
-static Jmp_buf signal_jumpback;
-static struct sigaction oldterm, oldint, oldhup;
-
-static void
-jumpback_sighandler (int signal)
-{
- /*
- * This avoids a race see Note below.
- * We want to jump back only on the first
- * signal invocation, even if the signal
- * handler didn't return.
- */
- gboolean old_do_jumpback = do_jumpback;
- do_jumpback = FALSE;
-
- if (signal == SIGINT)
- oldint.sa_handler (signal);
- else if (signal == SIGTERM)
- oldint.sa_handler (signal);
- else if (signal == SIGHUP)
- oldint.sa_handler (signal);
- /* No others should be set up */
-
- /* Note that we may not get here since
- 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);
- }
-}
-
-/*
- * This sets up interruptes to be proxied and the
- * gethostbyname/addr to be whacked using longjmp,
- * in case INT/TERM/HUP was gotten in which case
- * we no longer care for the result of the
- * resolution.
- */
-#define SETUP_INTERRUPTS_FOR_TERM_DECLS \
- struct sigaction term;
-
-#define SETUP_INTERRUPTS_FOR_TERM_SETUP \
- do_jumpback = FALSE; \
- \
- term.sa_handler = jumpback_sighandler; \
- term.sa_flags = SA_RESTART; \
- sigemptyset (&term.sa_mask); \
- \
- if G_UNLIKELY (sigaction (SIGTERM, &term, &oldterm) < 0) \
- gdm_fail (_("%s: Error setting up %s signal handler: %s"), \
- "SETUP_INTERRUPTS_FOR_TERM", "TERM", strerror (errno)); \
- \
- if G_UNLIKELY (sigaction (SIGINT, &term, &oldint) < 0) \
- gdm_fail (_("%s: Error setting up %s signal handler: %s"), \
- "SETUP_INTERRUPTS_FOR_TERM", "INT", strerror (errno)); \
- \
- if G_UNLIKELY (sigaction (SIGHUP, &term, &oldhup) < 0) \
- gdm_fail (_("%s: Error setting up %s signal handler: %s"), \
- "SETUP_INTERRUPTS_FOR_TERM", "HUP", strerror (errno)); \
-
-#define SETUP_INTERRUPTS_FOR_TERM_TEARDOWN \
- do_jumpback = FALSE; \
- \
- if G_UNLIKELY (sigaction (SIGTERM, &oldterm, NULL) < 0) \
- gdm_fail (_("%s: Error setting up %s signal handler: %s"), \
- "SETUP_INTERRUPTS_FOR_TERM", "TERM", strerror (errno)); \
- \
- if G_UNLIKELY (sigaction (SIGINT, &oldint, NULL) < 0) \
- gdm_fail (_("%s: Error setting up %s signal handler: %s"), \
- "SETUP_INTERRUPTS_FOR_TERM", "INT", strerror (errno)); \
- \
- if G_UNLIKELY (sigaction (SIGHUP, &oldhup, NULL) < 0) \
- gdm_fail (_("%s: Error setting up %s signal handler: %s"), \
- "SETUP_INTERRUPTS_FOR_TERM", "HUP", strerror (errno));
-
-GdmHostent *
-gdm_gethostbyname (const char *name)
-{
- struct addrinfo hints;
- /* static because of Setjmp */
- static struct addrinfo *result;
-
- SETUP_INTERRUPTS_FOR_TERM_DECLS
-
- /* The cached address */
- static GdmHostent *he = NULL;
- static time_t last_time = 0;
- static char *cached_hostname = NULL;
-
- if (cached_hostname != NULL &&
- strcmp (cached_hostname, name) == 0) {
- /* Don't check more then every 60 seconds */
- if (last_time + 60 > time (NULL))
- return gdm_hostent_copy (he);
- }
-
- SETUP_INTERRUPTS_FOR_TERM_SETUP
-
- if (Setjmp (signal_jumpback) == 0) {
- do_jumpback = TRUE;
-
- /* Find client hostname */
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_flags = AI_CANONNAME;
-
- if (result) {
- freeaddrinfo (result);
- result = NULL;
- }
-
- getaddrinfo (name, NULL, &hints, &result);
- do_jumpback = FALSE;
- } else {
- /* Here we got interrupted */
- result = NULL;
- }
-
- SETUP_INTERRUPTS_FOR_TERM_TEARDOWN
-
- g_free (cached_hostname);
- cached_hostname = g_strdup (name);
-
- gdm_hostent_free (he);
-
- he = fillout_addrinfo (result, NULL, name);
-
- last_time = time (NULL);
- return gdm_hostent_copy (he);
-}
-
-GdmHostent *
-gdm_gethostbyaddr (struct sockaddr_storage *ia)
-{
- 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;
-
- SETUP_INTERRUPTS_FOR_TERM_DECLS
-
- /* The cached address */
- static GdmHostent *he = NULL;
- static time_t last_time = 0;
- static struct in_addr cached_addr;
-
- if (last_time != 0) {
- 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) {
- 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))
- return gdm_hostent_copy (he);
- }
- }
- }
-
- SETUP_INTERRUPTS_FOR_TERM_SETUP
-
- if (Setjmp (signal_jumpback) == 0) {
- do_jumpback = TRUE;
-
- /* Find client hostname */
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_flags = AI_CANONNAME;
-
- if (result) {
- freeaddrinfo (result);
- result = NULL;
- }
-
- if (ia->ss_family == AF_INET6) {
- char buffer6[INET6_ADDRSTRLEN];
-
- inet_ntop (AF_INET6, &((struct sockaddr_in6 *)ia)->sin6_addr, buffer6, sizeof (buffer6));
-
- /*
- * In the case of IPv6 mapped address strip the
- * ::ffff: and lookup as an IPv4 address
- */
- if (strncmp (buffer6, "::ffff:", 7) == 0) {
- char *temp= (buffer6 + 7);
- strcpy (buffer6, temp);
- }
- getaddrinfo (buffer6, NULL, &hints, &result);
-
- } else if (ia->ss_family == AF_INET) {
- char buffer[INET_ADDRSTRLEN];
-
- inet_ntop (AF_INET, &((struct sockaddr_in *)ia)->sin_addr, buffer, sizeof (buffer));
-
- getaddrinfo (buffer, NULL, &hints, &result);
- }
-
- do_jumpback = FALSE;
- } else {
- /* Here we got interrupted */
- result = NULL;
- }
-
- SETUP_INTERRUPTS_FOR_TERM_TEARDOWN
-
- 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));
- memcpy (sin6.sin6_addr.s6_addr, cached_addr6.s6_addr, sizeof (struct in6_addr));
- sin6.sin6_family = AF_INET6;
- he = fillout_addrinfo (result, (struct sockaddr *)&sin6, NULL);
- }
- else if (ia->ss_family == AF_INET) {
- memcpy (&(cached_addr.s_addr), &(((struct sockaddr_in *)ia)->sin_addr.s_addr), sizeof (struct in_addr));
- memset (&sin, 0, sizeof (sin));
- memcpy (&sin.sin_addr, &cached_addr, sizeof (struct in_addr));
- sin.sin_family = AF_INET;
- he = fillout_addrinfo (result, (struct sockaddr *)&sin, NULL);
- }
-
- last_time = time (NULL);
- return gdm_hostent_copy (he);
-}
-
-GdmHostent *
-gdm_hostent_copy (GdmHostent *he)
-{
- GdmHostent *cpy;
-
- if (he == NULL)
- return NULL;
-
- cpy = g_new0 (GdmHostent, 1);
- cpy->not_found = he->not_found;
- cpy->hostname = g_strdup (he->hostname);
- if (he->addr_count == 0) {
- cpy->addr_count = 0;
- cpy->addrs = NULL;
- } else {
- cpy->addr_count = he->addr_count;
- cpy->addrs = g_new0 (struct sockaddr_storage, he->addr_count);
- memcpy (cpy->addrs, he->addrs, sizeof (struct sockaddr_storage) * he->addr_count);
- }
- return cpy;
-}
-
-void
-gdm_hostent_free (GdmHostent *he)
-{
- if (he == NULL)
- return;
- g_free (he->hostname);
- he->hostname = NULL;
-
- g_free (he->addrs);
- he->addrs = NULL;
- he->addr_count = 0;
-
- g_free (he);
-}
-
-/* Like fopen with "w" */
-FILE *
-gdm_safe_fopen_w (const char *file, mode_t perm)
-{
- int fd;
- FILE *ret;
- VE_IGNORE_EINTR (g_unlink (file));
- do {
- errno = 0;
- fd = open (file, O_EXCL|O_CREAT|O_TRUNC|O_WRONLY
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
-#ifdef O_NOFOLLOW
- |O_NOFOLLOW
-#endif
- , perm);
- } while G_UNLIKELY (errno == EINTR);
- if (fd < 0)
- return NULL;
- VE_IGNORE_EINTR (ret = fdopen (fd, "w"));
- return ret;
-}
-
-/* Like fopen with "a+" */
-FILE *
-gdm_safe_fopen_ap (const char *file, mode_t perm)
-{
- int fd;
- FILE *ret;
-
- if (g_access (file, F_OK) == 0) {
- do {
- errno = 0;
- fd = open (file, O_APPEND|O_RDWR
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
-#ifdef O_NOFOLLOW
- |O_NOFOLLOW
-#endif
- );
- } while G_UNLIKELY (errno == EINTR);
- } else {
- /* Doesn't exist, open with O_EXCL */
- do {
- errno = 0;
- fd = open (file, O_EXCL|O_CREAT|O_RDWR
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
-#ifdef O_NOFOLLOW
- |O_NOFOLLOW
-#endif
- , perm);
- } while G_UNLIKELY (errno == EINTR);
- }
- if (fd < 0)
- return NULL;
- VE_IGNORE_EINTR (ret = fdopen (fd, "a+"));
- return ret;
-}
-
-#ifdef RLIM_NLIMITS
-#define NUM_OF_LIMITS RLIM_NLIMITS
-#else /* ! RLIM_NLIMITS */
-#ifdef RLIMIT_NLIMITS
-#define NUM_OF_LIMITS RLIMIT_NLIMITS
-#endif /* RLIMIT_NLIMITS */
-#endif /* RLIM_NLIMITS */
-
-/* If we can count limits then the reset code is simple */
-#ifdef NUM_OF_LIMITS
-
-static struct rlimit limits[NUM_OF_LIMITS];
-
-void
-gdm_get_initial_limits (void)
-{
- int i;
-
- for (i = 0; i < NUM_OF_LIMITS; i++) {
- /* Some sane defaults */
- limits[i].rlim_cur = RLIM_INFINITY;
- limits[i].rlim_max = RLIM_INFINITY;
- /* Get the limits */
- getrlimit (i, &(limits[i]));
- }
-}
-
-void
-gdm_reset_limits (void)
-{
- int i;
-
- for (i = 0; i < NUM_OF_LIMITS; i++) {
- /* Get the limits */
- setrlimit (i, &(limits[i]));
- }
-}
-
-#define CHECK_LC(value, category) \
- (g_str_has_prefix (line->str, value "=")) \
- { \
- character = g_utf8_get_char (line->str + strlen (value "=")); \
-\
- if ((character == '\'') || (character == '\"')) \
- { \
- q = g_utf8_find_prev_char (line->str, line->str + line->len); \
-\
- if ((q == NULL) || (g_utf8_get_char (q) != character)) \
- { \
- g_string_set_size (line, 0); \
- continue; \
- } \
-\
- g_string_set_size (line, line->len - 1); \
- g_setenv (value, line->str + strlen (value "=") + 1, TRUE); \
- if (category) \
- setlocale ((category), line->str + strlen (value "=") + 1); \
- } \
- else \
- { \
- g_setenv (value, line->str + strlen (value "="), TRUE); \
- if (category) \
- setlocale ((category), line->str + strlen (value "=")); \
- } \
-\
- g_string_set_size (line, 0); \
- continue; \
- }
-
-void
-gdm_reset_locale (void)
-{
- char *i18n_file_contents;
- gsize i18n_file_length, i;
- GString *line;
- const gchar *p, *q;
- const gchar *gdmlang = g_getenv ("GDM_LANG");
-
- if (gdmlang)
- {
- g_setenv ("LANG", gdmlang, TRUE);
- g_unsetenv ("LC_ALL");
- g_unsetenv ("LC_MESSAGES");
- setlocale (LC_ALL, "");
- setlocale (LC_MESSAGES, "");
- return;
- }
-
- i18n_file_contents = NULL;
- line = NULL;
- p = NULL;
- if (!g_file_get_contents (LANG_CONFIG_FILE, &i18n_file_contents,
- &i18n_file_length, NULL))
- goto out;
-
- if (!g_utf8_validate (i18n_file_contents, i18n_file_length, NULL))
- goto out;
-
- line = g_string_new ("");
- p = i18n_file_contents;
- for (i = 0; i < i18n_file_length;
- p = g_utf8_next_char (p), i = p - i18n_file_contents)
- {
- gunichar character;
- character = g_utf8_get_char (p);
-
- if ((character != '\n') && (character != '\0'))
- {
- g_string_append_unichar (line, character);
- continue;
- }
-
- if CHECK_LC("LC_ALL", LC_ALL)
- else if CHECK_LC("LC_COLLATE", LC_COLLATE)
- else if CHECK_LC("LC_MESSAGES", LC_MESSAGES)
- else if CHECK_LC("LC_MONETARY", LC_MONETARY)
- else if CHECK_LC("LC_NUMERIC", LC_NUMERIC)
- else if CHECK_LC("LC_TIME", LC_TIME)
- else if CHECK_LC("LANG", 0)
-
- g_string_set_size (line, 0);
- }
-
- g_string_free (line, TRUE);
-
- setlocale (LC_ALL, "");
-
- out:
- g_free (i18n_file_contents);
-}
-
-#undef CHECK_LC
-
-#else /* ! NUM_OF_LIMITS */
-/* We have to go one by one here */
-
-#ifdef RLIMIT_CPU
-static struct rlimit limit_cpu = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-#ifdef RLIMIT_DATA
-static struct rlimit limit_data = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-#ifdef RLIMIT_FSIZE
-static struct rlimit limit_fsize = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-#ifdef RLIMIT_LOCKS
-static struct rlimit limit_locks = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-#ifdef RLIMIT_MEMLOCK
-static struct rlimit limit_memlock = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-#ifdef RLIMIT_NOFILE
-static struct rlimit limit_nofile = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-#ifdef RLIMIT_OFILE
-static struct rlimit limit_ofile = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-#ifdef RLIMIT_NPROC
-static struct rlimit limit_nproc = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-#ifdef RLIMIT_RSS
-static struct rlimit limit_rss = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-#ifdef RLIMIT_STACK
-static struct rlimit limit_stack = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-#ifdef RLIMIT_CORE
-static struct rlimit limit_core = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-#ifdef RLIMIT_AS
-static struct rlimit limit_as = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-#ifdef RLIMIT_VMEM
-static struct rlimit limit_vmem = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-#ifdef RLIMIT_PTHREAD
-static struct rlimit limit_pthread = { RLIM_INFINITY, RLIM_INFINITY };
-#endif
-
-void
-gdm_get_initial_limits (void)
-{
- /* Note: I don't really know which ones are really very standard
- and which ones are not, so I just test for them all one by one */
-
-#ifdef RLIMIT_CPU
- getrlimit (RLIMIT_CPU, &limit_cpu);
-#endif
-#ifdef RLIMIT_DATA
- getrlimit (RLIMIT_DATA, &limit_data);
-#endif
-#ifdef RLIMIT_FSIZE
- getrlimit (RLIMIT_FSIZE, &limit_fsize);
-#endif
-#ifdef RLIMIT_LOCKS
- getrlimit (RLIMIT_LOCKS, &limit_locks);
-#endif
-#ifdef RLIMIT_MEMLOCK
- getrlimit (RLIMIT_MEMLOCK, &limit_memlock);
-#endif
-#ifdef RLIMIT_NOFILE
- getrlimit (RLIMIT_NOFILE, &limit_nofile);
-#endif
-#ifdef RLIMIT_OFILE
- getrlimit (RLIMIT_OFILE, &limit_ofile);
-#endif
-#ifdef RLIMIT_NPROC
- getrlimit (RLIMIT_NPROC, &limit_nproc);
-#endif
-#ifdef RLIMIT_RSS
- getrlimit (RLIMIT_RSS, &limit_rss);
-#endif
-#ifdef RLIMIT_STACK
- getrlimit (RLIMIT_STACK, &limit_stack);
-#endif
-#ifdef RLIMIT_CORE
- getrlimit (RLIMIT_CORE, &limit_core);
-#endif
-#ifdef RLIMIT_AS
- getrlimit (RLIMIT_AS, &limit_as);
-#endif
-#ifdef RLIMIT_VMEM
- getrlimit (RLIMIT_VMEM, &limit_vmem);
-#endif
-#ifdef RLIMIT_PTHREAD
- getrlimit (RLIMIT_PTHREAD, &limit_pthread);
-#endif
-}
-
-void
-gdm_reset_limits (void)
-{
- /* Note: I don't really know which ones are really very standard
- and which ones are not, so I just test for them all one by one */
-
-#ifdef RLIMIT_CPU
- setrlimit (RLIMIT_CPU, &limit_cpu);
-#endif
-#ifdef RLIMIT_DATA
- setrlimit (RLIMIT_DATA, &limit_data);
-#endif
-#ifdef RLIMIT_FSIZE
- setrlimit (RLIMIT_FSIZE, &limit_fsize);
-#endif
-#ifdef RLIMIT_LOCKS
- setrlimit (RLIMIT_LOCKS, &limit_locks);
-#endif
-#ifdef RLIMIT_MEMLOCK
- setrlimit (RLIMIT_MEMLOCK, &limit_memlock);
-#endif
-#ifdef RLIMIT_NOFILE
- setrlimit (RLIMIT_NOFILE, &limit_nofile);
-#endif
-#ifdef RLIMIT_OFILE
- setrlimit (RLIMIT_OFILE, &limit_ofile);
-#endif
-#ifdef RLIMIT_NPROC
- setrlimit (RLIMIT_NPROC, &limit_nproc);
-#endif
-#ifdef RLIMIT_RSS
- setrlimit (RLIMIT_RSS, &limit_rss);
-#endif
-#ifdef RLIMIT_STACK
- setrlimit (RLIMIT_STACK, &limit_stack);
-#endif
-#ifdef RLIMIT_CORE
- setrlimit (RLIMIT_CORE, &limit_core);
-#endif
-#ifdef RLIMIT_AS
- setrlimit (RLIMIT_AS, &limit_as);
-#endif
-#ifdef RLIMIT_VMEM
- setrlimit (RLIMIT_VMEM, &limit_vmem);
-#endif
-#ifdef RLIMIT_PTHREAD
- setrlimit (RLIMIT_PTHREAD, &limit_pthread);
-#endif
-}
-
-#endif /* NUM_OF_LIMITS */
-
-const char *
-gdm_root_user (void)
-{
- static char *root_user = NULL;
- struct passwd *pwent;
-
- if (root_user != NULL)
- return root_user;
-
- pwent = getpwuid (0);
- if (pwent == NULL) /* huh? */
- root_user = g_strdup ("root");
- else
- root_user = g_strdup (pwent->pw_name);
- return root_user;
-}
-
-void
-gdm_sleep_no_signal (int secs)
-{
- time_t endtime = time (NULL)+secs;
-
- while (secs > 0) {
- struct timeval tv;
- tv.tv_sec = secs;
- tv.tv_usec = 0;
- select (0, NULL, NULL, NULL, &tv);
- /* Don't want to use sleep since we're using alarm
- for pinging */
- secs = endtime - time (NULL);
- }
-}
-
-char *
-gdm_make_filename (const char *dir, const char *name, const char *extension)
-{
- char *base = g_strconcat (name, extension, NULL);
- char *full = g_build_filename (dir, base, NULL);
- g_free (base);
- return full;
-}
-
-char *
-gdm_ensure_extension (const char *name, const char *extension)
-{
- const char *p;
-
- if (ve_string_empty (name))
- return g_strdup (name);
-
- p = strrchr (name, '.');
- if (p != NULL &&
- strcmp (p, extension) == 0) {
- return g_strdup (name);
- } else {
- return g_strconcat (name, extension, NULL);
- }
-}
-
-char *
-gdm_strip_extension (const char *name, const char *extension)
-{
- const char *p = strrchr (name, '.');
- if (p != NULL &&
- strcmp (p, extension) == 0) {
- char *r = g_strdup (name);
- char *rp = strrchr (r, '.');
- *rp = '\0';
- return r;
- } else {
- return g_strdup (name);
- }
-}
-
-void
-gdm_twiddle_pointer (GdmDisplay *disp)
-{
- if (disp == NULL ||
- disp->dsp == NULL)
- return;
-
- XWarpPointer (disp->dsp,
- None /* src_w */,
- None /* dest_w */,
- 0 /* src_x */,
- 0 /* src_y */,
- 0 /* src_width */,
- 0 /* src_height */,
- 1 /* dest_x */,
- 1 /* dest_y */);
- XSync (disp->dsp, False);
- XWarpPointer (disp->dsp,
- None /* src_w */,
- None /* dest_w */,
- 0 /* src_x */,
- 0 /* src_y */,
- 0 /* src_width */,
- 0 /* src_height */,
- -1 /* dest_x */,
- -1 /* dest_y */);
- XSync (disp->dsp, False);
-}
-
-static char *
-compress_string (const char *s)
-{
- GString *gs = g_string_new (NULL);
- const char *p;
- gboolean in_whitespace = TRUE;
-
- for (p = s; *p != '\0'; p++) {
- if (*p == ' ' || *p == '\t') {
- if ( ! in_whitespace)
- g_string_append_c (gs, *p);
- in_whitespace = TRUE;
- } else {
- g_string_append_c (gs, *p);
- in_whitespace = FALSE;
- }
- }
-
- return g_string_free (gs, FALSE);
-}
-
-
-char *
-gdm_get_last_info (const char *username)
-{
- char *info = NULL;
- const char *cmd = NULL;
-
- if G_LIKELY (g_access ("/usr/bin/last", X_OK) == 0)
- cmd = "/usr/bin/last";
- else if (g_access ("/bin/last", X_OK) == 0)
- cmd = "/bin/last";
-
- if G_LIKELY (cmd != NULL) {
- char *user_quoted = g_shell_quote (username);
- char *newcmd;
- FILE *fp;
-
- newcmd = g_strdup_printf ("%s %s", cmd, user_quoted);
-
- VE_IGNORE_EINTR (fp = popen (newcmd, "r"));
-
- g_free (user_quoted);
- g_free (newcmd);
-
- if G_LIKELY (fp != NULL) {
- char buf[256];
- char *r;
- VE_IGNORE_EINTR (r = fgets (buf, sizeof (buf), fp));
- if G_LIKELY (r != NULL) {
- char *s = compress_string (buf);
- if ( ! ve_string_empty (s))
- info = g_strdup_printf (_("Last login:\n%s"), s);
- g_free (s);
- }
- VE_IGNORE_EINTR (pclose (fp));
- }
- }
-
- return info;
-}
-
-gboolean
-gdm_ok_console_language (void)
-{
- int i;
- char **v;
- static gboolean cached = FALSE;
- static gboolean is_ok;
- const char *loc;
- const char *consolecannothandle = gdm_daemon_config_get_value_string (GDM_KEY_CONSOLE_CANNOT_HANDLE);
-
- if (cached)
- return is_ok;
-
- /* So far we should be paranoid, we're not set yet */
- if (consolecannothandle == NULL)
- return FALSE;
-
- cached = TRUE;
-
- loc = setlocale (LC_MESSAGES, NULL);
- if (loc == NULL) {
- is_ok = TRUE;
- return TRUE;
- }
-
- is_ok = TRUE;
-
- v = g_strsplit (consolecannothandle, ",", -1);
- for (i = 0; v != NULL && v[i] != NULL; i++) {
- if ( ! ve_string_empty (v[i]) &&
- strncmp (v[i], loc, strlen (v[i])) == 0) {
- is_ok = FALSE;
- break;
- }
- }
- if (v != NULL)
- g_strfreev (v);
-
- return is_ok;
-}
-
-const char *
-gdm_console_translate (const char *str)
-{
- if (gdm_ok_console_language ())
- return _(str);
- else
- return str;
-}
-
-/*
- * gdm_read_default
- *
- * 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)
-{
-#ifdef HAVE_DEFOPEN
- gchar *retval = NULL;
-
- if (defopen ("/etc/default/login") == 0) {
- int flags = defcntl (DC_GETFLAGS, 0);
-
- TURNOFF (flags, DC_CASE);
- (void) defcntl (DC_SETFLAGS, flags); /* ignore case */
- retval = g_strdup (defread (key));
- (void) defopen ((char *)NULL);
- }
- return retval;
-#else
- return NULL;
-#endif
-}
-
-/* EOF */
diff --git a/daemon/misc.h b/daemon/misc.h
deleted file mode 100644
index 56a83217..00000000
--- a/daemon/misc.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef GDM_MISC_H
-#define GDM_MISC_H
-
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "gdm.h"
-#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);
-
-/* 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);
-
-int gdm_get_free_display (int start, uid_t server_uid);
-
-gboolean gdm_text_message_dialog (const char *msg);
-gboolean gdm_text_yesno_dialog (const char *msg, gboolean *ret);
-int gdm_exec_wait (char * const *argv, gboolean no_display,
- gboolean de_setuid);
-
-/* done before each login. This can do so sanity ensuring,
- * one of the things it does now is make sure /tmp/.ICE-unix
- * exists and has the correct permissions */
-void gdm_ensure_sanity (void);
-
-/* This is for race free forks */
-void gdm_sigchld_block_push (void);
-void gdm_sigchld_block_pop (void);
-void gdm_sigterm_block_push (void);
-void gdm_sigterm_block_pop (void);
-void gdm_sigusr2_block_push (void);
-void gdm_sigusr2_block_pop (void);
-
-pid_t gdm_fork_extra (void);
-void gdm_wait_for_extra (pid_t pid, int *status);
-
-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,
- as gethostbyaddr/name failed */
- char *hostname; /* never a bogus dot, if
- invalid/unknown, then set to the
- ip address in string form */
-
- struct sockaddr_storage *addrs;
- int addr_count;
-} GdmHostent;
-
-GdmHostent * gdm_gethostbyname (const char *name);
-
-GdmHostent *gdm_gethostbyaddr (struct sockaddr_storage *ia);
-GdmHostent * gdm_hostent_copy (GdmHostent *he);
-void gdm_hostent_free (GdmHostent *he);
-
-gboolean gdm_setup_gids (const char *login, gid_t gid);
-
-void gdm_desetuid (void);
-
-gboolean gdm_test_opt (const char *cmd, const char *help, const char *option);
-
-void gdm_close_all_descriptors (int from, int except, int except2);
-
-int gdm_open_dev_null (mode_t mode);
-
-void gdm_unset_signals (void);
-
-void gdm_saveenv (void);
-const char * gdm_saved_getenv (const char *var);
-/* leaks */
-void gdm_restoreenv (void);
-
-/* like fopen with "w" but unlinks and uses O_EXCL */
-FILE * gdm_safe_fopen_w (const char *file, mode_t perm);
-/* like fopen with "a+" and uses O_EXCL and O_NOFOLLOW */
-FILE * gdm_safe_fopen_ap (const char *file, mode_t perm);
-
-/* first must get initial limits before attempting to ever reset those
- limits */
-void gdm_get_initial_limits (void);
-void gdm_reset_limits (void);
-void gdm_reset_locale (void);
-
-const char *gdm_root_user (void);
-
-#include <setjmp.h>
-
-/* stolen from xdm sources */
-#if defined(X_NOT_POSIX) || defined(__EMX__) || defined(__NetBSD__) && defined(__sparc__)
-#define Setjmp(e) setjmp(e)
-#define Longjmp(e,v) longjmp(e,v)
-#define Jmp_buf jmp_buf
-#else
-#define Setjmp(e) sigsetjmp(e,1)
-#define Longjmp(e,v) siglongjmp(e,v)
-#define Jmp_buf sigjmp_buf
-#endif
-
-void gdm_signal_ignore (int signal);
-void gdm_signal_default (int signal);
-
-void gdm_sleep_no_signal (int secs);
-
-/* somewhat like g_build_filename, but does somet hing like
- * <dir> "/" <name> <extension>
- */
-char * gdm_make_filename (const char *dir, const char *name, const char *extension);
-char * gdm_ensure_extension (const char *name, const char *extension);
-char * gdm_strip_extension (const char *name, const char *extension);
-
-void gdm_twiddle_pointer (GdmDisplay *disp);
-
-char * gdm_get_last_info (const char *username);
-
-gboolean gdm_ok_console_language (void);
-const char * gdm_console_translate (const char *str);
-/* Use with C_(N_("foo")) to make gettext work it out right */
-#define C_(x) (gdm_console_translate(x))
-
-gchar * gdm_read_default (gchar *key);
-
-#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__, \
- G_GNUC_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__, \
- G_GNUC_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_MISC_H */
diff --git a/daemon/server.c b/daemon/server.c
deleted file mode 100644
index 0cf0f818..00000000
--- a/daemon/server.c
+++ /dev/null
@@ -1,1594 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * GDM - The GNOME Display Manager
- * Copyright (C) 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* This file contains functions for controlling local X servers */
-
-#include "config.h"
-
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <grp.h>
-#include <sys/types.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/resource.h>
-#include <strings.h>
-#include <string.h>
-#include <signal.h>
-#include <errno.h>
-#include <time.h>
-#include <ctype.h>
-#include <X11/Xlib.h>
-
-#include "gdm.h"
-#include "server.h"
-#include "misc.h"
-#include "xdmcp.h"
-#include "display.h"
-#include "auth.h"
-#include "slave.h"
-#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);
-
-/* Global vars */
-static int server_signal_pipe[2];
-static GdmDisplay *d = NULL;
-static gboolean server_signal_notified = FALSE;
-static int gdm_in_signal = 0;
-
-static void do_server_wait (GdmDisplay *d);
-static gboolean setup_server_wait (GdmDisplay *d);
-
-void
-gdm_server_whack_lockfile (GdmDisplay *disp)
-{
- char buf[256];
-
- /* X seems to be sometimes broken with its lock files and
- doesn't seem to remove them always, and if you manage
- to get into the weird state where the old pid now
- corresponds to some new pid, X will just die with
- a stupid error. */
-
- /* Yes there could be a race here if another X server starts
- at this exact instant. Oh well such is life. Very unlikely
- to happen though as we should really be the only ones
- trying to start X servers, and we aren't starting an
- X server on this display yet. */
-
- /* if lock file exists and it is our process, whack it! */
- g_snprintf (buf, sizeof (buf), "/tmp/.X%d-lock", disp->dispnum);
- VE_IGNORE_EINTR (g_unlink (buf));
-
- /* whack the unix socket as well */
- g_snprintf (buf, sizeof (buf),
- "/tmp/.X11-unix/X%d", disp->dispnum);
- VE_IGNORE_EINTR (g_unlink (buf));
-}
-
-
-/* Wipe cookie files */
-void
-gdm_server_wipe_cookies (GdmDisplay *disp)
-{
- if ( ! ve_string_empty (disp->authfile)) {
- VE_IGNORE_EINTR (g_unlink (disp->authfile));
- }
- g_free (disp->authfile);
- disp->authfile = NULL;
- if ( ! ve_string_empty (disp->authfile_gdm)) {
- VE_IGNORE_EINTR (g_unlink (disp->authfile_gdm));
- }
- g_free (disp->authfile_gdm);
- disp->authfile_gdm = NULL;
-}
-
-static Jmp_buf reinitjmp;
-
-/* ignore handlers */
-static int
-ignore_xerror_handler (Display *disp, XErrorEvent *evt)
-{
- return 0;
-}
-
-static int
-jumpback_xioerror_handler (Display *disp)
-{
- Longjmp (reinitjmp, 1);
-}
-
-#ifdef HAVE_FBCONSOLE
-#define FBCONSOLE "/usr/openwin/bin/fbconsole"
-
-static void
-gdm_exec_fbconsole (GdmDisplay *disp)
-{
- pid_t pid;
- char *argv[6];
-
- argv[0] = FBCONSOLE;
- argv[1] = "-d";
- 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 */)
-;
- VE_IGNORE_EINTR (execv (argv[0], argv));
- }
- if (pid == -1) {
- gdm_error (_("Can not start fallback console"));
- }
-}
-#endif
-
-/**
- * gdm_server_reinit:
- * @disp: Pointer to a GdmDisplay structure
- *
- * Reinit the display, basically sends a HUP signal
- * but only if the display exists
- */
-
-gboolean
-gdm_server_reinit (GdmDisplay *disp)
-{
- if (disp == NULL)
- return FALSE;
-
- if (disp->servpid <= 0) {
- /* Kill our connection if one existed, likely to result
- * in some bizzaro error right now */
- if (disp->dsp != NULL) {
- XCloseDisplay (disp->dsp);
- disp->dsp = NULL;
- }
- return FALSE;
- }
-
- gdm_debug ("gdm_server_reinit: Server for %s is about to be reinitialized!", disp->name);
-
- if ( ! setup_server_wait (disp))
- return FALSE;
-
- d->servstat = SERVER_PENDING;
-
- if (disp->dsp != NULL) {
- /* static because of the Setjmp */
- static int (*old_xerror_handler)(Display *, XErrorEvent *) = NULL;
- static int (*old_xioerror_handler)(Display *) = NULL;
-
- old_xerror_handler = NULL;
- old_xioerror_handler = NULL;
-
- /* Do note the interaction of this Setjmp and the signal
- handlers and the Setjmp in slave.c */
-
- /* Long live Setjmp, DIE DIE DIE XSetIOErrorHandler */
-
- if (Setjmp (reinitjmp) == 0) {
- /* come here and we'll whack the server and wait to get
- an xio error */
- old_xerror_handler = XSetErrorHandler (ignore_xerror_handler);
- old_xioerror_handler = XSetIOErrorHandler (jumpback_xioerror_handler);
-
- /* Now whack the server with a SIGHUP */
- gdm_sigchld_block_push ();
- if (disp->servpid > 1)
- kill (disp->servpid, SIGHUP);
- else
- d->servstat = SERVER_DEAD;
- gdm_sigchld_block_pop ();
-
- /* the server is dead, weird */
- if (disp->dsp != NULL) {
- XCloseDisplay (disp->dsp);
- disp->dsp = NULL;
- }
- }
- /* no more display */
- disp->dsp = NULL;
- XSetErrorHandler (old_xerror_handler);
- XSetIOErrorHandler (old_xioerror_handler);
- } else {
- /* Now whack the server with a SIGHUP */
- gdm_sigchld_block_push ();
- if (disp->servpid > 1)
- kill (disp->servpid, SIGHUP);
- else
- d->servstat = SERVER_DEAD;
- gdm_sigchld_block_pop ();
- }
-
- /* Wait for the SIGUSR1 */
- do_server_wait (d);
-
- if (d->servstat == SERVER_RUNNING) {
-#ifdef HAVE_FBCONSOLE
- gdm_exec_fbconsole (d);
-#endif
- return TRUE;
- } else {
- /* if something really REALLY screwed up, then whack the
- lockfiles for safety */
- gdm_server_whack_lockfile (d);
- return FALSE;
- }
-}
-
-/**
- * gdm_server_stop:
- * @disp: Pointer to a GdmDisplay structure
- *
- * Stops a local X server, but only if it exists
- */
-
-void
-gdm_server_stop (GdmDisplay *disp)
-{
- static gboolean waiting_for_server = FALSE;
- int old_servstat;
-
- if (disp == NULL)
- return;
-
- /* Kill our connection if one existed */
- if (disp->dsp != NULL) {
- /* on XDMCP servers first kill everything in sight */
- if (disp->type == TYPE_XDMCP)
- gdm_server_whack_clients (disp->dsp);
- XCloseDisplay (disp->dsp);
- disp->dsp = NULL;
- }
-
- /* Kill our parent connection if one existed */
- if (disp->parent_dsp != NULL) {
- /* on XDMCP servers first kill everything in sight */
- if (disp->type == TYPE_XDMCP_PROXY)
- gdm_server_whack_clients (disp->parent_dsp);
- XCloseDisplay (disp->parent_dsp);
- disp->parent_dsp = NULL;
- }
-
- if (disp->servpid <= 0)
- return;
-
- gdm_debug ("gdm_server_stop: Server for %s going down!", disp->name);
-
- old_servstat = disp->servstat;
- disp->servstat = SERVER_DEAD;
-
- if (disp->servpid > 0) {
- pid_t servpid;
-
- gdm_debug ("gdm_server_stop: Killing server pid %d",
- (int)disp->servpid);
-
- /* avoid SIGCHLD race */
- gdm_sigchld_block_push ();
- servpid = disp->servpid;
-
- if (waiting_for_server) {
- gdm_error ("gdm_server_stop: Some problem killing server, whacking with SIGKILL");
- if (disp->servpid > 1)
- kill (disp->servpid, SIGKILL);
-
- } else {
- if (disp->servpid > 1 &&
- kill (disp->servpid, SIGTERM) == 0) {
- waiting_for_server = TRUE;
- ve_waitpid_no_signal (disp->servpid, NULL, 0);
- waiting_for_server = FALSE;
- }
- }
- disp->servpid = 0;
-
- gdm_sigchld_block_pop ();
-
- if (old_servstat == SERVER_RUNNING)
- gdm_server_whack_lockfile (disp);
-
- gdm_debug ("gdm_server_stop: Server pid %d dead", (int)servpid);
-
- /* 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;
- }
-
- gdm_server_wipe_cookies (disp);
-
- gdm_slave_whack_temp_auth_file ();
-}
-
-static gboolean
-busy_ask_user (GdmDisplay *disp)
-{
- /* if we have "open" we can talk to the user */
- if (g_access (LIBEXECDIR "/gdmopen", X_OK) == 0) {
- char *error = g_strdup_printf
- (C_(N_("There already appears to be an X server "
- "running on display %s. Should another "
- "display number by tried? Answering no will "
- "cause GDM to attempt starting the server "
- "on %s again.%s")),
- disp->name,
- disp->name,
-#ifdef __linux__
- C_(N_(" (You can change consoles by pressing Ctrl-Alt "
- "plus a function key, such as Ctrl-Alt-F7 to go "
- "to console 7. X servers usually run on consoles "
- "7 and higher.)"))
-#else /* ! __linux__ */
- /* no info for non linux users */
- ""
-#endif /* __linux__ */
- );
- gboolean ret = TRUE;
- /* default ret to TRUE */
- if ( ! gdm_text_yesno_dialog (error, &ret))
- ret = TRUE;
- g_free (error);
- return ret;
- } else {
- /* Well we'll just try another display number */
- return TRUE;
- }
-}
-
-/* Checks only output, no XFree86 v4 logfile */
-static gboolean
-display_parent_no_connect (GdmDisplay *disp)
-{
- char *logname = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_LOG_DIR), d->name, ".log");
- FILE *fp;
- char buf[256];
- char *getsret;
-
- VE_IGNORE_EINTR (fp = fopen (logname, "r"));
- g_free (logname);
-
- if (fp == NULL)
- return FALSE;
-
- for (;;) {
- VE_IGNORE_EINTR (getsret = fgets (buf, sizeof (buf), fp));
- if (getsret == NULL) {
- VE_IGNORE_EINTR (fclose (fp));
- return FALSE;
- }
- /* Note: this is probably XFree86 specific, and perhaps even
- * version 3 specific (I don't have xfree v4 to test this),
- * of course additions are welcome to make this more robust */
- if (strstr (buf, "Unable to open display \"") == buf) {
- gdm_error (_("Display '%s' cannot be opened by nested display"),
- ve_sure_string (disp->parent_disp));
- VE_IGNORE_EINTR (fclose (fp));
- return TRUE;
- }
- }
-}
-
-static gboolean
-display_busy (GdmDisplay *disp)
-{
- char *logname = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_LOG_DIR), d->name, ".log");
- FILE *fp;
- char buf[256];
- char *getsret;
-
- VE_IGNORE_EINTR (fp = fopen (logname, "r"));
- g_free (logname);
-
- if (fp == NULL)
- return FALSE;
-
- for (;;) {
- VE_IGNORE_EINTR (getsret = fgets (buf, sizeof (buf), fp));
- if (getsret == NULL) {
- VE_IGNORE_EINTR (fclose (fp));
- return FALSE;
- }
- /* Note: this is probably XFree86 specific */
- if (strstr (buf, "Server is already active for display")
- == buf) {
- gdm_error (_("Display %s is busy. There is another "
- "X server running already."),
- disp->name);
- VE_IGNORE_EINTR (fclose (fp));
- return TRUE;
- }
- }
-}
-
-/* if we find 'Log file: "foo"' switch fp to foo and
- return TRUE */
-/* Note: assumes buf is of size 256 and is writable */
-static gboolean
-open_another_logfile (char buf[256], FILE **fp)
-{
- if (strncmp (&buf[5], "Log file: \"", strlen ("Log file: \"")) == 0) {
- FILE *ffp;
- char *fname = &buf[5+strlen ("Log file: \"")];
- char *p = strchr (fname, '"');
- if (p == NULL)
- return FALSE;
- *p = '\0';
- VE_IGNORE_EINTR (ffp = fopen (fname, "r"));
- if (ffp == NULL)
- return FALSE;
- VE_IGNORE_EINTR (fclose (*fp));
- *fp = ffp;
- return TRUE;
- }
- return FALSE;
-}
-
-static int
-display_vt (GdmDisplay *disp)
-{
- char *logname = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_LOG_DIR), d->name, ".log");
- FILE *fp;
- char buf[256];
- gboolean switched = FALSE;
- char *getsret;
-
- VE_IGNORE_EINTR (fp = fopen (logname, "r"));
- g_free (logname);
-
- if (fp == NULL)
- return FALSE;
-
- for (;;) {
- int vt;
- char *p;
-
- VE_IGNORE_EINTR (getsret = fgets (buf, sizeof (buf), fp));
- if (getsret == NULL) {
- VE_IGNORE_EINTR (fclose (fp));
- return -1;
- }
-
- if ( ! switched &&
- /* this is XFree v4 specific */
- open_another_logfile (buf, &fp)) {
- switched = TRUE;
- continue;
- }
- /* Note: this is probably XFree86 specific (works with
- * both v3 and v4 though */
- p = strstr (buf, "using VT number ");
- if (p != NULL &&
- sscanf (p, "using VT number %d", &vt) == 1) {
- VE_IGNORE_EINTR (fclose (fp));
- return vt;
- }
- }
-}
-
-static struct sigaction old_svr_wait_chld;
-static sigset_t old_svr_wait_mask;
-
-static gboolean
-setup_server_wait (GdmDisplay *d)
-{
- struct sigaction usr1, chld;
- sigset_t mask;
-
- if (pipe (server_signal_pipe) != 0) {
- gdm_error (_("%s: Error opening a pipe: %s"),
- "setup_server_wait", strerror (errno));
- return FALSE;
- }
- server_signal_notified = FALSE;
-
- /* Catch USR1 from X server */
- usr1.sa_handler = gdm_server_usr1_handler;
- usr1.sa_flags = SA_RESTART;
- sigemptyset (&usr1.sa_mask);
-
- if (sigaction (SIGUSR1, &usr1, NULL) < 0) {
- gdm_error (_("%s: Error setting up %s signal handler: %s"),
- "gdm_server_start", "USR1", strerror (errno));
- VE_IGNORE_EINTR (close (server_signal_pipe[0]));
- VE_IGNORE_EINTR (close (server_signal_pipe[1]));
- return FALSE;
- }
-
- /* Catch CHLD from X server */
- chld.sa_handler = gdm_server_child_handler;
- chld.sa_flags = SA_RESTART|SA_NOCLDSTOP;
- sigemptyset (&chld.sa_mask);
-
- if (sigaction (SIGCHLD, &chld, &old_svr_wait_chld) < 0) {
- gdm_error (_("%s: Error setting up %s signal handler: %s"),
- "gdm_server_start", "CHLD", strerror (errno));
- gdm_signal_ignore (SIGUSR1);
- VE_IGNORE_EINTR (close (server_signal_pipe[0]));
- VE_IGNORE_EINTR (close (server_signal_pipe[1]));
- return FALSE;
- }
-
- /* Set signal mask */
- sigemptyset (&mask);
- sigaddset (&mask, SIGUSR1);
- sigaddset (&mask, SIGCHLD);
- sigprocmask (SIG_UNBLOCK, &mask, &old_svr_wait_mask);
-
- return TRUE;
-}
-
-static void
-do_server_wait (GdmDisplay *d)
-{
- /* Wait for X server to send ready signal */
- if (d->servstat == SERVER_PENDING) {
- if (d->server_uid != 0 && ! d->handled && ! d->chosen_hostname) {
- /* FIXME: If not handled, we just don't know, so
- * just wait a few seconds and hope things just work,
- * fortunately there is no such case yet and probably
- * never will, but just for code anality's sake */
- gdm_sleep_no_signal (gdm_daemon_config_get_value_int(GDM_KEY_XSERVER_TIMEOUT));
- } else if (d->server_uid != 0) {
- int i;
-
- /* FIXME: This is not likely to work in reinit,
- but we never reinit Nested servers nowdays,
- so that's fine */
-
- /* if we're running the server as a non-root, we can't
- * use USR1 of course, so try openning the display
- * as a test, but the */
-
- /* just in case it's set */
- g_unsetenv ("XAUTHORITY");
-
- gdm_auth_set_local_auth (d);
-
- for (i = 0;
- d->dsp == NULL &&
- d->servstat == SERVER_PENDING &&
- i < gdm_daemon_config_get_value_int(GDM_KEY_XSERVER_TIMEOUT);
- i++) {
- d->dsp = XOpenDisplay (d->name);
- if (d->dsp == NULL)
- gdm_sleep_no_signal (1);
- else
- d->servstat = SERVER_RUNNING;
- }
- if (d->dsp == NULL &&
- /* Note: we could have still gotten a SIGCHLD */
- d->servstat == SERVER_PENDING) {
- d->servstat = SERVER_TIMEOUT;
- }
- } else {
- time_t t = time (NULL);
-
- gdm_debug ("do_server_wait: Before mainloop waiting for server");
-
- do {
- fd_set rfds;
- struct timeval tv;
-
- /* Wait up to GDM_KEY_XSERVER_TIMEOUT seconds. */
- tv.tv_sec = MAX (1, gdm_daemon_config_get_value_int(GDM_KEY_XSERVER_TIMEOUT)
- - (time (NULL) - t));
- tv.tv_usec = 0;
-
- FD_ZERO (&rfds);
- FD_SET (server_signal_pipe[0], &rfds);
-
- if (select (server_signal_pipe[0]+1, &rfds, NULL, NULL, &tv) > 0) {
- char buf[4];
- /* read the Yay! */
- VE_IGNORE_EINTR (read (server_signal_pipe[0], buf, 4));
- }
- if ( ! server_signal_notified &&
- t + gdm_daemon_config_get_value_int(GDM_KEY_XSERVER_TIMEOUT) < time (NULL)) {
- gdm_debug ("do_server_wait: Server timeout");
- d->servstat = SERVER_TIMEOUT;
- server_signal_notified = TRUE;
- }
- if (d->servpid <= 1) {
- d->servstat = SERVER_ABORT;
- server_signal_notified = TRUE;
- }
- } while ( ! server_signal_notified);
-
- gdm_debug ("gdm_server_start: After mainloop waiting for server");
- }
- }
-
- /* restore default handlers */
- gdm_signal_ignore (SIGUSR1);
- sigaction (SIGCHLD, &old_svr_wait_chld, NULL);
- sigprocmask (SIG_SETMASK, &old_svr_wait_mask, NULL);
-
- VE_IGNORE_EINTR (close (server_signal_pipe[0]));
- VE_IGNORE_EINTR (close (server_signal_pipe[1]));
-
- if (d->servpid <= 1) {
- d->servstat = SERVER_ABORT;
- }
-
- if (d->servstat != SERVER_RUNNING) {
- /* bad things are happening */
- if (d->servpid > 0) {
- pid_t pid;
-
- d->dsp = NULL;
-
- gdm_sigchld_block_push ();
- pid = d->servpid;
- d->servpid = 0;
- if (pid > 1 &&
- kill (pid, SIGTERM) == 0)
- ve_waitpid_no_signal (pid, NULL, 0);
- gdm_sigchld_block_pop ();
- }
-
- /* We will rebake cookies anyway, so wipe these */
- gdm_server_wipe_cookies (d);
- }
-}
-
-/* We keep a connection (parent_dsp) open with the parent X server
- * before running a proxy on it to prevent the X server resetting
- * as we open and close other connections.
- * Note that XDMCP servers, by default, reset when the seed X
- * connection closes whereas usually the X server only quits when
- * all X connections have closed.
- */
-static gboolean
-connect_to_parent (GdmDisplay *d)
-{
- int maxtries;
- int openretries;
-
- gdm_debug ("gdm_server_start: Connecting to parent display \'%s\'",
- d->parent_disp);
-
- d->parent_dsp = NULL;
-
- maxtries = SERVER_IS_XDMCP (d) ? 10 : 2;
-
- openretries = 0;
- while (openretries < maxtries &&
- d->parent_dsp == NULL) {
- d->parent_dsp = XOpenDisplay (d->parent_disp);
-
- if G_UNLIKELY (d->parent_dsp == NULL) {
- gdm_debug ("gdm_server_start: Sleeping %d on a retry", 1+openretries*2);
- gdm_sleep_no_signal (1+openretries*2);
- openretries++;
- }
- }
-
- if (d->parent_dsp == NULL)
- gdm_error (_("%s: failed to connect to parent display \'%s\'"),
- "gdm_server_start", d->parent_disp);
-
- return d->parent_dsp != NULL;
-}
-
-/**
- * gdm_server_start:
- * @disp: Pointer to a GdmDisplay structure
- *
- * Starts a local X server. Handles retries and fatal errors properly.
- */
-
-gboolean
-gdm_server_start (GdmDisplay *disp,
- gboolean try_again_if_busy /* only affects non-flexi servers */,
- gboolean treat_as_flexi,
- int min_flexi_disp,
- int flexi_retries)
-{
- int flexi_disp = 20;
- char *vtarg = NULL;
- int vtfd = -1, vt = -1;
-
- if (disp == NULL)
- return FALSE;
-
- d = disp;
-
- /* if an X server exists, wipe it */
- gdm_server_stop (d);
-
- /* First clear the VT number */
- if (d->type == TYPE_STATIC ||
- d->type == TYPE_FLEXI) {
- d->vt = -1;
- gdm_slave_send_num (GDM_SOP_VT_NUM, -1);
- }
-
- if (SERVER_IS_FLEXI (d) ||
- treat_as_flexi) {
- flexi_disp = gdm_get_free_display
- (MAX (gdm_daemon_config_get_high_display_num () + 1, min_flexi_disp) /* start */,
- d->server_uid /* server uid */);
-
- g_free (d->name);
- d->name = g_strdup_printf (":%d", flexi_disp);
- d->dispnum = flexi_disp;
-
- gdm_slave_send_num (GDM_SOP_DISP_NUM, flexi_disp);
- }
-
- if (d->type == TYPE_XDMCP_PROXY &&
- ! connect_to_parent (d))
- return FALSE;
-
- gdm_debug ("gdm_server_start: %s", d->name);
-
- /* Create new cookie */
- if ( ! gdm_auth_secure_display (d))
- return FALSE;
- gdm_slave_send_string (GDM_SOP_COOKIE, d->cookie);
- gdm_slave_send_string (GDM_SOP_AUTHFILE, d->authfile);
- g_setenv ("DISPLAY", d->name, TRUE);
-
- if ( ! setup_server_wait (d))
- return FALSE;
-
- d->servstat = SERVER_DEAD;
-
- if (d->type == TYPE_STATIC ||
- d->type == TYPE_FLEXI) {
- vtarg = gdm_get_empty_vt_argument (&vtfd, &vt);
- }
-
- /* fork X server process */
- gdm_server_spawn (d, vtarg);
-
- /* we can now use d->handled since that's set up above */
- do_server_wait (d);
-
- /* If we were holding a vt open for the server, close it now as it has
- * already taken the bait. */
- if (vtfd > 0) {
- VE_IGNORE_EINTR (close (vtfd));
- }
-
- switch (d->servstat) {
-
- case SERVER_TIMEOUT:
- gdm_debug ("gdm_server_start: Temporary server failure (%s)", d->name);
- break;
-
- case SERVER_ABORT:
- gdm_debug ("gdm_server_start: Server %s died during startup!", d->name);
- break;
-
- case SERVER_RUNNING:
- gdm_debug ("gdm_server_start: Completed %s!", d->name);
-
- if (SERVER_IS_FLEXI (d))
- gdm_slave_send_num (GDM_SOP_FLEXI_OK, 0 /* bogus */);
- if (d->type == TYPE_STATIC ||
- d->type == TYPE_FLEXI) {
- if (vt >= 0)
- d->vt = vt;
-
- if (d->vt < 0)
- d->vt = display_vt (d);
- if (d->vt >= 0)
- gdm_slave_send_num (GDM_SOP_VT_NUM, d->vt);
- }
-
-#ifdef HAVE_FBCONSOLE
- gdm_exec_fbconsole (d);
-#endif
-
- return TRUE;
- default:
- break;
- }
-
- if (SERVER_IS_PROXY (disp) &&
- display_parent_no_connect (disp)) {
- gdm_slave_send_num (GDM_SOP_FLEXI_ERR,
- 5 /* proxy can't connect */);
- _exit (DISPLAY_REMANAGE);
- }
-
- /* if this was a busy fail, that is, there is already
- * a server on that display, we'll display an error and after
- * this we'll exit with DISPLAY_REMANAGE to try again if the
- * user wants to, or abort this display */
- if (display_busy (disp)) {
- if (SERVER_IS_FLEXI (disp) ||
- treat_as_flexi) {
- /* for flexi displays, try again a few times with different
- * display numbers */
- if (flexi_retries <= 0) {
- /* Send X too busy */
- gdm_error (_("%s: Cannot find a free "
- "display number"),
- "gdm_server_start");
- if (SERVER_IS_FLEXI (disp)) {
- gdm_slave_send_num (GDM_SOP_FLEXI_ERR,
- 4 /* X too busy */);
- }
- /* eki eki */
- _exit (DISPLAY_REMANAGE);
- }
- return gdm_server_start (d, FALSE /*try_again_if_busy */,
- treat_as_flexi,
- flexi_disp + 1,
- flexi_retries - 1);
- } else {
- if (try_again_if_busy) {
- gdm_debug ("%s: Display %s busy. Trying once again "
- "(after 2 sec delay)",
- "gdm_server_start", d->name);
- gdm_sleep_no_signal (2);
- return gdm_server_start (d,
- FALSE /* try_again_if_busy */,
- treat_as_flexi,
- flexi_disp,
- flexi_retries);
- }
- if (busy_ask_user (disp)) {
- gdm_error (_("%s: Display %s busy. Trying "
- "another display number."),
- "gdm_server_start",
- d->name);
- d->busy_display = TRUE;
- return gdm_server_start (d,
- FALSE /*try_again_if_busy */,
- TRUE /* treat as flexi */,
- gdm_daemon_config_get_high_display_num () + 1,
- flexi_retries - 1);
- }
- _exit (DISPLAY_REMANAGE);
- }
- }
-
- _exit (DISPLAY_XFAILED);
-
- return FALSE;
-}
-
-/* Do things that require checking the log,
- * we really do need to get called a bit later, after all init is done
- * as things aren't written to disk before that */
-void
-gdm_server_checklog (GdmDisplay *disp)
-{
- if (d->vt < 0 &&
- (d->type == TYPE_STATIC ||
- d->type == TYPE_FLEXI)) {
- d->vt = display_vt (d);
- if (d->vt >= 0)
- gdm_slave_send_num (GDM_SOP_VT_NUM, d->vt);
- }
-}
-
-/* somewhat safer rename (safer if the log dir is unsafe), may in fact
- lose the file though, it guarantees that a is gone, but not that
- b exists */
-static void
-safer_rename (const char *a, const char *b)
-{
- errno = 0;
- if (link (a, b) < 0) {
- if (errno == EEXIST) {
- VE_IGNORE_EINTR (g_unlink (a));
- return;
- }
- VE_IGNORE_EINTR (g_unlink (b));
- /* likely this system doesn't support hard links */
- g_rename (a, b);
- VE_IGNORE_EINTR (g_unlink (a));
- return;
- }
- VE_IGNORE_EINTR (g_unlink (a));
-}
-
-static void
-rotate_logs (const char *dname)
-{
- const gchar *logdir = gdm_daemon_config_get_value_string (GDM_KEY_LOG_DIR);
-
- /* I'm too lazy to write a loop */
- char *fname4 = gdm_make_filename (logdir, dname, ".log.4");
- char *fname3 = gdm_make_filename (logdir, dname, ".log.3");
- char *fname2 = gdm_make_filename (logdir, dname, ".log.2");
- char *fname1 = gdm_make_filename (logdir, dname, ".log.1");
- char *fname = gdm_make_filename (logdir, dname, ".log");
-
- /* Rotate the logs (keep 4 last) */
- VE_IGNORE_EINTR (g_unlink (fname4));
- safer_rename (fname3, fname4);
- safer_rename (fname2, fname3);
- safer_rename (fname1, fname2);
- safer_rename (fname, fname1);
-
- g_free (fname4);
- g_free (fname3);
- g_free (fname2);
- g_free (fname1);
- g_free (fname);
-}
-
-static int
-vector_len (char * const *v)
-{
- int i;
- if (v == NULL)
- return 0;
- for (i = 0; v[i] != NULL; i++)
- ;
- return i;
-}
-
-static void
-gdm_server_add_xserver_args (GdmDisplay *d, char **argv)
-{
- int count;
- char **args;
- int len;
- int i;
-
- len = vector_len (argv);
- g_shell_parse_argv (d->xserver_session_args, &count, &args, NULL);
- argv = g_renew (char *, argv, len + count + 1);
-
- for (i=0; i < count;i++) {
- argv[len++] = g_strdup(args[i]);
- }
-
- argv[len] = NULL;
- g_strfreev (args);
-}
-
-GdmXserver *
-gdm_server_resolve (GdmDisplay *disp)
-{
- char *bin;
- GdmXserver *svr = NULL;
-
- bin = ve_first_word (disp->command);
- if (bin != NULL && bin[0] != '/') {
- svr = gdm_daemon_config_find_xserver (bin);
- }
- g_free (bin);
- return svr;
-}
-
-
-static char **
-vector_merge (char * const *v1,
- int len1,
- char * const *v2,
- int len2)
-{
- int argc, i;
- char **argv;
-
- if (v1 == NULL && v2 == NULL)
- return NULL;
-
- argc = len1 + len2;
-
- argv = g_new (char *, argc + 1);
- for (i = 0; i < len1; i++)
- argv[i] = g_strdup (v1[i]);
- for (; i < argc; i++)
- argv[i] = g_strdup (v2[i - len1]);
- argv[i] = NULL;
-
- return argv;
-}
-
-gboolean
-gdm_server_resolve_command_line (GdmDisplay *disp,
- gboolean resolve_flags,
- const char *vtarg,
- int *argcp,
- char ***argvp)
-{
- char *bin;
- int argc;
- char **argv;
- int len;
- int i;
- gboolean gotvtarg = FALSE;
- gboolean query_in_arglist = FALSE;
-
- argv = NULL;
-
- bin = ve_first_word (disp->command);
- if (bin == NULL) {
- const char *str;
-
- gdm_error (_("Invalid server command '%s'"), disp->command);
- str = gdm_daemon_config_get_value_string (GDM_KEY_STANDARD_XSERVER);
- g_shell_parse_argv (str, &argc, &argv, NULL);
- } else if (bin[0] != '/') {
- GdmXserver *svr = gdm_daemon_config_find_xserver (bin);
- if (svr == NULL) {
- const char *str;
-
- gdm_error (_("Server name '%s' not found; "
- "using standard server"), bin);
- str = gdm_daemon_config_get_value_string (GDM_KEY_STANDARD_XSERVER);
- g_shell_parse_argv (str, &argc, &argv, NULL);
-
- } else {
- char **svr_command;
- const char *str;
- int svr_argc;
-
- str = ve_sure_string (svr->command);
- svr_command = NULL;
- g_shell_parse_argv (str, &svr_argc, &svr_command, NULL);
-
- g_shell_parse_argv (disp->command, &argc, &argv, NULL);
-
- if (argv[0] == NULL || argv[1] == NULL) {
- g_strfreev (argv);
- argv = svr_command;
- argc = svr_argc;
- } else {
- char **old_argv = argv;
- argv = vector_merge (svr_command,
- svr_argc,
- &old_argv[1],
- argc);
- g_strfreev (svr_command);
- g_strfreev (old_argv);
-
- argc += svr_argc;
- }
-
- if (resolve_flags) {
- /* Setup the handled function */
- disp->handled = svr->handled;
- /* never make use_chooser FALSE,
- it may have been set temporarily for
- us by the master */
- if (svr->chooser)
- disp->use_chooser = TRUE;
- disp->priority = svr->priority;
- }
- }
- } else {
- g_shell_parse_argv (disp->command, &argc, &argv, NULL);
- }
-
- for (len = 0; argv != NULL && argv[len] != NULL; len++) {
- char *arg = argv[len];
- /* HACK! Not to add vt argument to servers that already force
- * allocation. Mostly for backwards compat only */
- if (strncmp (arg, "vt", 2) == 0 &&
- isdigit (arg[2]) &&
- (arg[3] == '\0' ||
- (isdigit (arg[3]) && arg[4] == '\0')))
- gotvtarg = TRUE;
- if (strcmp (arg, "-query") == 0 ||
- strcmp (arg, "-indirect") == 0)
- query_in_arglist = TRUE;
- }
-
- argv = g_renew (char *, argv, len + 10);
- /* shift args down one */
- for (i = len - 1; i >= 1; i--) {
- argv[i+1] = argv[i];
- }
- /* server number is the FIRST argument, before any others */
- argv[1] = g_strdup (disp->name);
- len++;
-
- if (disp->authfile != NULL) {
- argv[len++] = g_strdup ("-auth");
- argv[len++] = g_strdup (disp->authfile);
- }
-
- if (resolve_flags && disp->chosen_hostname) {
- /* this display is NOT handled */
- disp->handled = FALSE;
- /* never ever ever use chooser here */
- disp->use_chooser = FALSE;
- disp->priority = 0;
- /* run just one session */
- argv[len++] = g_strdup ("-terminate");
- argv[len++] = g_strdup ("-query");
- argv[len++] = g_strdup (disp->chosen_hostname);
- query_in_arglist = TRUE;
- }
-
- if (resolve_flags && gdm_daemon_config_get_value_bool (GDM_KEY_DISALLOW_TCP) && ! query_in_arglist) {
- argv[len++] = g_strdup ("-nolisten");
- argv[len++] = g_strdup ("tcp");
- d->tcp_disallowed = TRUE;
- }
-
- if (vtarg != NULL &&
- ! gotvtarg) {
- argv[len++] = g_strdup (vtarg);
- }
-
- argv[len++] = NULL;
-
- *argvp = argv;
- *argcp = len;
-
- g_free (bin);
-
- return TRUE;
-}
-
-/**
- * gdm_server_spawn:
- * @disp: Pointer to a GdmDisplay structure
- *
- * forks an actual X server process
- *
- * Note that we can only use d->handled once we call this function
- * since otherwise the server might not yet be looked up yet.
- */
-
-static void
-gdm_server_spawn (GdmDisplay *d, const char *vtarg)
-{
- struct sigaction ign_signal;
- sigset_t mask;
- int argc;
- gchar **argv = NULL;
- char *logfile;
- int logfd;
- char *command;
- pid_t pid;
-
- if (d == NULL ||
- ve_string_empty (d->command)) {
- return;
- }
-
- d->servstat = SERVER_PENDING;
-
- gdm_sigchld_block_push ();
-
- /* eek, some previous copy, just wipe it */
- if (d->servpid > 0) {
- pid_t pid = d->servpid;
- d->servpid = 0;
- if (pid > 1 &&
- kill (pid, SIGTERM) == 0)
- ve_waitpid_no_signal (pid, NULL, 0);
- }
-
- /* Figure out the server command */
- argv = NULL;
- argc = 0;
- gdm_server_resolve_command_line (d,
- TRUE /* resolve flags */,
- vtarg,
- &argc,
- &argv);
-
- /* Do not support additional session arguments with Xnest. */
- if (d->type != TYPE_FLEXI_XNEST) {
- if (d->xserver_session_args)
- gdm_server_add_xserver_args (d, argv);
- }
-
- command = g_strjoinv (" ", argv);
-
- /* 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)
- gdm_unset_signals ();
- gdm_sigterm_block_pop ();
- gdm_sigchld_block_pop ();
-
- switch (pid) {
-
- case 0:
- /* the pops whacked mask again */
- gdm_unset_signals ();
-
- gdm_log_shutdown ();
-
- /* close things */
- gdm_close_all_descriptors (0 /* from */, -1 /* except */, -1 /* except2 */);
-
- /* No error checking here - if it's messed the best response
- * is to ignore & try to continue */
- gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
- gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
- gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
-
- gdm_log_init ();
-
- /* Rotate the X server logs */
- rotate_logs (d->name);
-
- /* Log all output from spawned programs to a file */
- logfile = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_LOG_DIR), d->name, ".log");
- VE_IGNORE_EINTR (g_unlink (logfile));
- VE_IGNORE_EINTR (logfd = open (logfile, O_CREAT|O_TRUNC|O_WRONLY|O_EXCL, 0644));
-
- if (logfd != -1) {
- VE_IGNORE_EINTR (dup2 (logfd, 1));
- VE_IGNORE_EINTR (dup2 (logfd, 2));
- close (logfd);
- } else {
- gdm_error (_("%s: Could not open logfile for display %s!"),
- "gdm_server_spawn", d->name);
- }
-
- /* The X server expects USR1/TTIN/TTOU to be SIG_IGN */
- ign_signal.sa_handler = SIG_IGN;
- ign_signal.sa_flags = SA_RESTART;
- sigemptyset (&ign_signal.sa_mask);
-
- if (d->server_uid == 0) {
- /* only set this if we can actually listen */
- if (sigaction (SIGUSR1, &ign_signal, NULL) < 0) {
- gdm_error (_("%s: Error setting %s to %s"),
- "gdm_server_spawn", "USR1", "SIG_IGN");
- _exit (SERVER_ABORT);
- }
- }
- if (sigaction (SIGTTIN, &ign_signal, NULL) < 0) {
- gdm_error (_("%s: Error setting %s to %s"),
- "gdm_server_spawn", "TTIN", "SIG_IGN");
- _exit (SERVER_ABORT);
- }
- if (sigaction (SIGTTOU, &ign_signal, NULL) < 0) {
- gdm_error (_("%s: Error setting %s to %s"),
- "gdm_server_spawn", "TTOU", "SIG_IGN");
- _exit (SERVER_ABORT);
- }
-
- /* And HUP and TERM are at SIG_DFL from gdm_unset_signals,
- we also have an empty mask and all that fun stuff */
-
- /* unblock signals (especially HUP/TERM/USR1) so that we
- * can control the X server */
- sigemptyset (&mask);
- sigprocmask (SIG_SETMASK, &mask, NULL);
-
- if (SERVER_IS_PROXY (d)) {
- gboolean add_display = TRUE;
-
- g_unsetenv ("DISPLAY");
- if (d->parent_auth_file != NULL)
- g_setenv ("XAUTHORITY", d->parent_auth_file, TRUE);
- else
- g_unsetenv ("XAUTHORITY");
-
- if (d->type == TYPE_FLEXI_XNEST) {
- char *font_path = NULL;
- /* Add -fp with the current font path, but only if not
- * already among the arguments */
- if (strstr (command, "-fp") == NULL)
- font_path = get_font_path (d->parent_disp);
- if (font_path != NULL) {
- argv = g_renew (char *, argv, argc + 2);
- argv[argc++] = "-fp";
- argv[argc++] = font_path;
- command = g_strconcat (command, " -fp ",
- font_path, NULL);
- }
- add_display = FALSE;
- }
-
- /*
- * Set the DISPLAY environment variable when calling
- * nested server since some Xnest commands like Xephyr
- * do not support the -display argument.
- */
- if (add_display == TRUE) {
- argv = g_renew (char *, argv, argc + 3);
- argv[argc++] = "-display";
- argv[argc++] = d->parent_disp;
- argv[argc++] = NULL;
- command = g_strconcat (command, " -display ",
- d->parent_disp, NULL);
- } else {
- argv = g_renew (char *, argv, argc + 1);
- argv[argc++] = NULL;
- g_setenv ("DISPLAY", d->parent_disp, TRUE);
- }
- }
-
- if (argv[0] == NULL) {
- gdm_error (_("%s: Empty server command for display %s"),
- "gdm_server_spawn",
- d->name);
- _exit (SERVER_ABORT);
- }
-
- gdm_debug ("gdm_server_spawn: '%s'", command);
-
- if (d->priority != 0) {
- if (setpriority (PRIO_PROCESS, 0, d->priority)) {
- gdm_error (_("%s: Server priority couldn't be set to %d: %s"),
- "gdm_server_spawn", d->priority,
- strerror (errno));
- }
- }
-
- setpgid (0, 0);
-
- if (d->server_uid != 0) {
- struct passwd *pwent;
- pwent = getpwuid (d->server_uid);
- if (pwent == NULL) {
- gdm_error (_("%s: Server was to be spawned by uid %d but "
- "that user doesn't exist"),
- "gdm_server_spawn",
- (int)d->server_uid);
- _exit (SERVER_ABORT);
- }
- 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", "/", TRUE); /* Hack */
- g_setenv ("SHELL", pwent->pw_shell, TRUE);
- g_unsetenv ("MAIL");
-
- if (setgid (pwent->pw_gid) < 0) {
- gdm_error (_("%s: Couldn't set groupid to %d"),
- "gdm_server_spawn", (int)pwent->pw_gid);
- _exit (SERVER_ABORT);
- }
-
- if (initgroups (pwent->pw_name, pwent->pw_gid) < 0) {
- gdm_error (_("%s: initgroups () failed for %s"),
- "gdm_server_spawn", pwent->pw_name);
- _exit (SERVER_ABORT);
- }
-
- if (setuid (d->server_uid) < 0) {
- gdm_error (_("%s: Couldn't set userid to %d"),
- "gdm_server_spawn", (int)d->server_uid);
- _exit (SERVER_ABORT);
- }
- } else {
- gid_t groups[1] = { 0 };
- if (setgid (0) < 0) {
- gdm_error (_("%s: Couldn't set groupid to 0"),
- "gdm_server_spawn");
- /* Don't error out, it's not fatal, if it fails we'll
- * just still be */
- }
- /* this will get rid of any suplementary groups etc... */
- setgroups (1, groups);
- }
-
-#if sun
- {
- /* Remove old communication pipe, if present */
- char old_pipe[MAXPATHLEN];
-
- sprintf (old_pipe, "%s/%d", SDTLOGIN_DIR, d->name);
- g_unlink (old_pipe);
- }
-#endif
-
- VE_IGNORE_EINTR (execv (argv[0], argv));
-
- gdm_fdprintf (2, "GDM: Xserver not found: %s\n"
- "Error: Command could not be executed!\n"
- "Please install the X server or correct "
- "GDM configuration and restart GDM.",
- command);
-
- gdm_error (_("%s: Xserver not found: %s"),
- "gdm_server_spawn", command);
-
- _exit (SERVER_ABORT);
-
- case -1:
- g_strfreev (argv);
- g_free (command);
- gdm_error (_("%s: Can't fork Xserver process!"),
- "gdm_server_spawn");
- d->servpid = 0;
- d->servstat = SERVER_DEAD;
-
- break;
-
- default:
- g_strfreev (argv);
- g_free (command);
- gdm_debug ("%s: Forked server on pid %d",
- "gdm_server_spawn", (int)pid);
- break;
- }
-}
-
-/**
- * gdm_server_usr1_handler:
- * @sig: Signal value
- *
- * Received when the server is ready to accept connections
- */
-
-static void
-gdm_server_usr1_handler (gint sig)
-{
- gdm_in_signal++;
-
- d->servstat = SERVER_RUNNING; /* Server ready to accept connections */
- d->starttime = time (NULL);
-
- server_signal_notified = TRUE;
- /* this will quit the select */
- VE_IGNORE_EINTR (write (server_signal_pipe[1], "Yay!", 4));
-
- gdm_in_signal--;
-}
-
-
-/**
- * gdm_server_child_handler:
- * @sig: Signal value
- *
- * Received when server died during startup
- */
-
-static void
-gdm_server_child_handler (int signal)
-{
- gdm_in_signal++;
-
- /* go to the main child handler */
- gdm_slave_child_handler (signal);
-
- /* this will quit the select */
- VE_IGNORE_EINTR (write (server_signal_pipe[1], "Yay!", 4));
-
- gdm_in_signal--;
-}
-
-
-void
-gdm_server_whack_clients (Display *dsp)
-{
- int i, screen_count;
- int (* old_xerror_handler) (Display *, XErrorEvent *);
-
- if (dsp == NULL)
- return;
-
- old_xerror_handler = XSetErrorHandler (ignore_xerror_handler);
-
- XGrabServer (dsp);
-
- screen_count = ScreenCount (dsp);
-
- for (i = 0; i < screen_count; i++) {
- Window root_ret, parent_ret;
- Window *childs = NULL;
- unsigned int childs_count = 0;
- Window root = RootWindow (dsp, i);
-
- while (XQueryTree (dsp, root, &root_ret, &parent_ret,
- &childs, &childs_count) &&
- childs_count > 0) {
- int ii;
-
- for (ii = 0; ii < childs_count; ii++) {
- XKillClient (dsp, childs[ii]);
- }
-
- XFree (childs);
- }
- }
-
- XUngrabServer (dsp);
-
- XSync (dsp, False);
- XSetErrorHandler (old_xerror_handler);
-}
-
-static char *
-get_font_path (const char *display)
-{
- Display *disp;
- char **font_path;
- int n_fonts;
- int i;
- GString *gs;
-
- disp = XOpenDisplay (display);
- if (disp == NULL)
- return NULL;
-
- font_path = XGetFontPath (disp, &n_fonts);
- if (font_path == NULL) {
- XCloseDisplay (disp);
- return NULL;
- }
-
- gs = g_string_new (NULL);
- for (i = 0; i < n_fonts; i++) {
- if (i != 0)
- g_string_append_c (gs, ',');
-
- if (gdm_daemon_config_get_value_bool (GDM_KEY_XNEST_UNSCALED_FONT_PATH) == TRUE)
- g_string_append (gs, font_path[i]);
- else {
- gchar *unscaled_ptr = NULL;
-
- /*
- * When using Xsun Xnest, it doesn't support the
- * ":unscaled" suffix in fontpath entries, so strip it.
- */
- unscaled_ptr = g_strrstr (font_path[i], ":unscaled");
- if (unscaled_ptr != NULL) {
- gchar *temp_string;
-
- temp_string = g_strndup (font_path[i],
- strlen (font_path[i]) -
- strlen (":unscaled"));
-
-gdm_debug ("font_path[i] is %s, temp_string is %s", font_path[i], temp_string);
- g_string_append (gs, temp_string);
- g_free (temp_string);
- } else {
-gdm_debug ("font_path[i] is %s", font_path[i]);
- g_string_append (gs, font_path[i]);
- }
- }
- }
-
- XFreeFontPath (font_path);
-
- XCloseDisplay (disp);
-
- return g_string_free (gs, FALSE);
-}
-
-/* EOF */
diff --git a/daemon/server.h b/daemon/server.h
deleted file mode 100644
index 2bcc9c15..00000000
--- a/daemon/server.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- 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
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef GDM_SERVER_H
-#define GDM_SERVER_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);
-
-/* Wipe X server's butt */
-void gdm_server_whack_lockfile (GdmDisplay *disp);
-
-gboolean gdm_server_start (GdmDisplay *d,
- gboolean try_again_if_busy,
- gboolean treat_as_flexi,
- int min_flexi_disp,
- int flexi_retries);
-void gdm_server_stop (GdmDisplay *d);
-gboolean gdm_server_reinit (GdmDisplay *d);
-void gdm_server_whack_clients (Display *dsp);
-void gdm_server_checklog (GdmDisplay *disp);
-
-gboolean gdm_server_resolve_command_line (GdmDisplay *disp,
- gboolean resolve_flags,
- const char *vtarg,
- int *argc,
- char ***argv);
-GdmXserver * gdm_server_resolve (GdmDisplay *disp);
-
-
-
-#endif /* GDM_SERVER_H */
-
-/* EOF */
diff --git a/daemon/slave.c b/daemon/slave.c
deleted file mode 100644
index f13c18bf..00000000
--- a/daemon/slave.c
+++ /dev/null
@@ -1,5877 +0,0 @@
-/* -*- 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
- * 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
- */
-
-/* This is the gdm slave process. gdmslave runs the chooser, greeter
- * and the user's session scripts. */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <utime.h>
-#if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD)
-#include <sched.h>
-#endif
-#ifdef HAVE_LOGINCAP
-#include <login_cap.h>
-#endif
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <strings.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <string.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#ifdef HAVE_XFREE_XINERAMA
-#include <X11/extensions/Xinerama.h>
-#elif HAVE_SOLARIS_XINERAMA
-#include <X11/extensions/xinerama.h>
-#endif
-
-#if defined (CAN_USE_SETPENV) && defined (HAVE_USERSEC_H)
-#include <usersec.h>
-#endif
-
-#include <signal.h>
-#include <pwd.h>
-#include <grp.h>
-#include <errno.h>
-#include <time.h>
-
-#ifdef HAVE_TSOL
-#include <user_attr.h>
-#endif
-
-#ifdef HAVE_SELINUX
-#include <selinux/selinux.h>
-#include <selinux/get_context_list.h>
-#endif /* HAVE_SELINUX */
-
-#include <glib/gi18n.h>
-#include <gdk/gdkx.h>
-#include <gtk/gtk.h>
-
-#include "gdm.h"
-#include "slave.h"
-#include "misc.h"
-#include "verify.h"
-#include "filecheck.h"
-#include "auth.h"
-#include "server.h"
-#include "choose.h"
-#include "getvt.h"
-#include "errorgui.h"
-#include "cookie.h"
-#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
-
-/* Per-slave globals */
-
-static GdmDisplay *d = 0;
-static gchar *login = NULL;
-static gboolean greet = FALSE;
-static gboolean configurator = FALSE;
-static gboolean remanage_asap = FALSE;
-static gboolean got_xfsz_signal = FALSE;
-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
- username entry & unselect
- face browser (if present) */
-static gboolean do_restart_greeter = FALSE; /* If this is true, whack the
- greeter and try again */
-static gboolean restart_greeter_now = FALSE; /* Restart_greeter_when the
- SIGCHLD hits */
-static gboolean always_restart_greeter = FALSE; /* Always restart greeter when
- the user accepts restarts. */
-static gboolean gdm_wait_for_ack = TRUE; /* Wait for ack on all messages
- to the daemon */
-static int in_session_stop = 0;
-static int in_usr2_signal = 0;
-static gboolean need_to_quit_after_session_stop = FALSE;
-static int exit_code_to_use = DISPLAY_REMANAGE;
-static gboolean session_started = FALSE;
-static gboolean greeter_disabled = FALSE;
-static gboolean greeter_no_focus = FALSE;
-
-static uid_t logged_in_uid = -1;
-static gid_t logged_in_gid = -1;
-static int greeter_fd_out = -1;
-static int greeter_fd_in = -1;
-
-static gboolean interrupted = FALSE;
-static gchar *ParsedAutomaticLogin = NULL;
-static gchar *ParsedTimedLogin = NULL;
-
-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
-
-static int slave_waitpid_r = -1;
-static int slave_waitpid_w = -1;
-static GSList *slave_waitpids = NULL;
-
-extern gboolean gdm_first_login;
-
-/* The slavepipe (like fifo) connection, this is the write end */
-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;
-
-typedef struct {
- pid_t pid;
-} GdmWaitPid;
-
-/* Local prototypes */
-static gint gdm_slave_xerror_handler (Display *disp, XErrorEvent *evt);
-static gint gdm_slave_xioerror_handler (Display *disp);
-static void gdm_slave_run (GdmDisplay *display);
-static void gdm_slave_wait_for_login (void);
-static void gdm_slave_greeter (void);
-static void gdm_slave_chooser (void);
-static void gdm_slave_session_start (void);
-static void gdm_slave_session_stop (gboolean run_post_session,
- gboolean no_shutdown_check);
-static void gdm_slave_alrm_handler (int sig);
-static void gdm_slave_term_handler (int sig);
-static void gdm_slave_usr2_handler (int sig);
-static void gdm_slave_quick_exit (gint status);
-static void gdm_slave_exit (gint status, const gchar *format, ...) G_GNUC_PRINTF (2, 3);
-static void gdm_child_exit (gint status, const gchar *format, ...) G_GNUC_PRINTF (2, 3);
-static gint gdm_slave_exec_script (GdmDisplay *d, const gchar *dir,
- const char *login, struct passwd *pwent,
- gboolean pass_stdout);
-static gchar *gdm_parse_enriched_login (const gchar *s, GdmDisplay *display);
-static void gdm_slave_handle_usr2_message (void);
-static void gdm_slave_handle_notify (const char *msg);
-static void create_temp_auth_file (void);
-static void set_xnest_parent_stuff (void);
-static void check_notifies_now (void);
-static void restart_the_greeter (void);
-
-#ifdef HAVE_TSOL
-static gboolean gdm_can_i_assume_root_role (struct passwd *pwent);
-#endif
-
-gboolean gdm_is_user_valid (const char *username);
-
-/* Yay thread unsafety */
-static gboolean x_error_occurred = FALSE;
-static gboolean gdm_got_ack = FALSE;
-static char * gdm_ack_response = NULL;
-char * gdm_ack_question_response = NULL;
-static GList *unhandled_notifies = NULL;
-
-/* for signals that want to exit */
-static Jmp_buf slave_start_jmp;
-static gboolean return_to_slave_start_jmp = FALSE;
-static gboolean already_in_slave_start_jmp = FALSE;
-static char *slave_start_jmp_error_to_print = NULL;
-enum {
- JMP_FIRST_RUN = 0,
- JMP_SESSION_STOP_AND_QUIT = 1,
- JMP_JUST_QUIT_QUICKLY = 2
-};
-#define DEFAULT_LANGUAGE "Default"
-#define SIGNAL_EXIT_WITH_JMP(d,how) \
- { \
- if ((d)->slavepid == getpid () && return_to_slave_start_jmp) { \
- already_in_slave_start_jmp = TRUE; \
- Longjmp (slave_start_jmp, how); \
- } else { \
- /* evil! how this this happen */ \
- if (slave_start_jmp_error_to_print != NULL) \
- gdm_error (slave_start_jmp_error_to_print); \
- gdm_error ("Bad (very very VERY bad!) things happening in signal"); \
- _exit (DISPLAY_REMANAGE); \
- } \
- }
-
-/* Notify all waitpids, make waitpids check notifies */
-static void
-slave_waitpid_notify (void)
-{
- /* we're in no slave waitpids */
- if (slave_waitpids == NULL)
- return;
-
- gdm_sigchld_block_push ();
-
- if (slave_waitpid_w >= 0)
- VE_IGNORE_EINTR (write (slave_waitpid_w, "N", 1));
-
- gdm_sigchld_block_pop ();
-}
-
-/* Make sure to wrap this call with sigchld blocks */
-static GdmWaitPid *
-slave_waitpid_setpid (pid_t pid)
-{
- int p[2];
- GdmWaitPid *wp;
-
- if G_UNLIKELY (pid <= 1)
- return NULL;
-
- wp = g_new0 (GdmWaitPid, 1);
- wp->pid = pid;
-
- if (slave_waitpid_r < 0) {
- if G_UNLIKELY (pipe (p) < 0) {
- gdm_error ("slave_waitpid_setpid: cannot create pipe, trying to wing it");
- } else {
- slave_waitpid_r = p[0];
- slave_waitpid_w = p[1];
- }
- }
-
- slave_waitpids = g_slist_prepend (slave_waitpids, wp);
- return wp;
-}
-
-static void
-run_session_output (gboolean read_until_eof)
-{
- char buf[256];
- int r, written;
- uid_t old;
- gid_t oldg;
-
- old = geteuid ();
- oldg = getegid ();
-
- /* make sure we can set the gid */
- NEVER_FAILS_seteuid (0);
-
- /* make sure we are the user when we do this,
- for purposes of file limits and all that kind of
- stuff */
- if G_LIKELY (logged_in_gid >= 0) {
- if G_UNLIKELY (setegid (logged_in_gid) != 0) {
- gdm_error (_("Can't set EGID to user GID"));
- NEVER_FAILS_root_set_euid_egid (old, oldg);
- return;
- }
- }
-
- if G_LIKELY (logged_in_uid >= 0) {
- if G_UNLIKELY (seteuid (logged_in_uid) != 0) {
- gdm_error (_("Can't set EUID to user UID"));
- NEVER_FAILS_root_set_euid_egid (old, oldg);
- return;
- }
- }
-
- /* the fd is non-blocking */
- for (;;) {
- VE_IGNORE_EINTR (r = read (d->session_output_fd, buf, sizeof (buf)));
-
- /* EOF */
- if G_UNLIKELY (r == 0) {
- VE_IGNORE_EINTR (close (d->session_output_fd));
- d->session_output_fd = -1;
- VE_IGNORE_EINTR (close (d->xsession_errors_fd));
- d->xsession_errors_fd = -1;
- break;
- }
-
- /* Nothing to read */
- if (r < 0 && errno == EAGAIN)
- break;
-
- /* some evil error */
- if G_UNLIKELY (r < 0) {
- gdm_error ("error reading from session output, closing the pipe");
- VE_IGNORE_EINTR (close (d->session_output_fd));
- d->session_output_fd = -1;
- VE_IGNORE_EINTR (close (d->xsession_errors_fd));
- d->xsession_errors_fd = -1;
- break;
- }
-
- if G_UNLIKELY (d->xsession_errors_bytes >= MAX_XSESSION_ERRORS_BYTES ||
- got_xfsz_signal)
- continue;
-
- /* write until we succeed in writing something */
- VE_IGNORE_EINTR (written = write (d->xsession_errors_fd, buf, r));
- if G_UNLIKELY (written < 0 || got_xfsz_signal) {
- /* evil! */
- break;
- }
-
- /* write until we succeed in writing everything */
- while G_UNLIKELY (written < r) {
- int n;
- VE_IGNORE_EINTR (n = write (d->xsession_errors_fd, &buf[written], r-written));
- if G_UNLIKELY (n < 0 || got_xfsz_signal) {
- /* evil! */
- break;
- }
- written += n;
- }
-
- d->xsession_errors_bytes += r;
-
- 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")));
- }
-
- /* there wasn't more then buf available, so no need to try reading
- * again, unless we really want to */
- if (r < sizeof (buf) && ! read_until_eof)
- break;
- }
-
- NEVER_FAILS_root_set_euid_egid (old, oldg);
-}
-
-static void
-run_chooser_output (void)
-{
- char *bf;
-
- if G_UNLIKELY (d->chooser_output_fd < 0)
- return;
-
- /* the fd is non-blocking */
- do {
- bf = gdm_fdgets (d->chooser_output_fd);
- if (bf != NULL) {
- g_free (d->chooser_last_line);
- d->chooser_last_line = bf;
- }
- } while (bf != NULL);
-}
-
-#define TIME_UNSET_P(tv) ((tv)->tv_sec == 0 && (tv)->tv_usec == 0)
-
-/* Try to touch an authfb auth file every 12 hours. That way if it's
- * in /tmp it doesn't get whacked by tmpwatch */
-#define TRY_TO_TOUCH_TIME (60*60*12)
-
-static struct timeval *
-min_time_to_wait (struct timeval *tv)
-{
- if (d->authfb) {
- time_t ct = time (NULL);
- time_t sec_to_wait;
-
- if (d->last_auth_touch + TRY_TO_TOUCH_TIME + 5 <= ct)
- sec_to_wait = 5;
- else
- sec_to_wait = (d->last_auth_touch + TRY_TO_TOUCH_TIME) - ct;
-
- if (TIME_UNSET_P (tv) ||
- sec_to_wait < tv->tv_sec)
- tv->tv_sec = sec_to_wait;
- }
- if (TIME_UNSET_P (tv))
- return NULL;
- else
- return tv;
-}
-
-static void
-try_to_touch_fb_userauth (void)
-{
- if (d->authfb && d->userauth != NULL && logged_in_uid >= 0) {
- time_t ct = time (NULL);
-
- if (d->last_auth_touch + TRY_TO_TOUCH_TIME <= ct) {
- uid_t old;
- gid_t oldg;
-
- old = geteuid ();
- oldg = getegid ();
-
- NEVER_FAILS_seteuid (0);
-
- /* make sure we are the user when we do this,
- for purposes of file limits and all that kind of
- stuff */
- if G_LIKELY (logged_in_gid >= 0) {
- if G_UNLIKELY (setegid (logged_in_gid) != 0) {
- gdm_error ("Can't set GID to user GID");
- NEVER_FAILS_root_set_euid_egid (old, oldg);
- return;
- }
- }
-
- if G_LIKELY (logged_in_uid >= 0) {
- if G_UNLIKELY (seteuid (logged_in_uid) != 0) {
- gdm_error ("Can't set UID to user UID");
- NEVER_FAILS_root_set_euid_egid (old, oldg);
- return;
- }
- }
-
- /* This will "touch" the file */
- utime (d->userauth, NULL);
-
- NEVER_FAILS_root_set_euid_egid (old, oldg);
-
- d->last_auth_touch = ct;
- }
- }
-}
-
-/* must call slave_waitpid_setpid before calling this */
-static void
-slave_waitpid (GdmWaitPid *wp)
-{
- if G_UNLIKELY (wp == NULL)
- return;
-
- gdm_debug ("slave_waitpid: waiting on %d", (int)wp->pid);
-
- if G_UNLIKELY (slave_waitpid_r < 0) {
- gdm_error ("slave_waitpid: no pipe, trying to wing it");
-
- /* This is a real stupid fallback for a real stupid case */
- while (wp->pid > 1) {
- struct timeval tv;
- /* Wait 5 seconds. */
- tv.tv_sec = 5;
- tv.tv_usec = 0;
- select (0, NULL, NULL, NULL, min_time_to_wait (&tv));
- /* don't want to use sleep since we're using alarm
- for pinging */
-
- /* try to touch an fb auth file */
- try_to_touch_fb_userauth ();
-
- if (d->session_output_fd >= 0)
- run_session_output (FALSE /* read_until_eof */);
- if (d->chooser_output_fd >= 0)
- run_chooser_output ();
- check_notifies_now ();
- }
- check_notifies_now ();
- } else {
- gboolean read_session_output = TRUE;
-
- do {
- char buf[1];
- fd_set rfds;
- int ret;
- struct timeval tv;
- int maxfd;
-
- FD_ZERO (&rfds);
- FD_SET (slave_waitpid_r, &rfds);
- if (read_session_output &&
- d->session_output_fd >= 0)
- FD_SET (d->session_output_fd, &rfds);
- if (d->chooser_output_fd >= 0)
- FD_SET (d->chooser_output_fd, &rfds);
-
- /* unset time */
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- maxfd = MAX (slave_waitpid_r, d->session_output_fd);
- maxfd = MAX (maxfd, d->chooser_output_fd);
-
- ret = select (maxfd + 1, &rfds, NULL, NULL, min_time_to_wait (&tv));
-
- /* try to touch an fb auth file */
- try_to_touch_fb_userauth ();
-
- if (ret > 0) {
- if (FD_ISSET (slave_waitpid_r, &rfds)) {
- VE_IGNORE_EINTR (read (slave_waitpid_r, buf, 1));
- }
- if (d->session_output_fd >= 0 &&
- FD_ISSET (d->session_output_fd, &rfds)) {
- run_session_output (FALSE /* read_until_eof */);
- }
- if (d->chooser_output_fd >= 0 &&
- FD_ISSET (d->chooser_output_fd, &rfds)) {
- run_chooser_output ();
- }
- } else if (errno == EBADF) {
- read_session_output = FALSE;
- }
- check_notifies_now ();
- } while (wp->pid > 1);
- check_notifies_now ();
- }
-
- gdm_sigchld_block_push ();
-
- wp->pid = -1;
-
- slave_waitpids = g_slist_remove (slave_waitpids, wp);
- g_free (wp);
-
- gdm_sigchld_block_pop ();
-
- gdm_debug ("slave_waitpid: done_waiting");
-}
-
-static void
-check_notifies_now (void)
-{
- GList *list, *li;
-
- if (restart_greeter_now &&
- do_restart_greeter) {
- do_restart_greeter = FALSE;
- restart_the_greeter ();
- }
-
- while (unhandled_notifies != NULL) {
- gdm_sigusr2_block_push ();
- list = unhandled_notifies;
- unhandled_notifies = NULL;
- gdm_sigusr2_block_pop ();
-
- for (li = list; li != NULL; li = li->next) {
- char *s = li->data;
- li->data = NULL;
-
- gdm_slave_handle_notify (s);
-
- g_free (s);
- }
- g_list_free (list);
- }
-
- if (restart_greeter_now &&
- do_restart_greeter) {
- do_restart_greeter = FALSE;
- restart_the_greeter ();
- }
-}
-
-static void
-gdm_slave_desensitize_config (void)
-{
- if (configurator &&
- d->dsp != NULL) {
- gulong foo = 1;
- Atom atom = XInternAtom (d->dsp,
- "_GDM_SETUP_INSENSITIVE",
- False);
- XChangeProperty (d->dsp,
- DefaultRootWindow (d->dsp),
- atom,
- XA_CARDINAL, 32, PropModeReplace,
- (unsigned char *) &foo, 1);
- XSync (d->dsp, False);
- }
-
-}
-
-static void
-gdm_slave_sensitize_config (void)
-{
- if (d->dsp != NULL) {
- XDeleteProperty (d->dsp,
- DefaultRootWindow (d->dsp),
- XInternAtom (d->dsp,
- "_GDM_SETUP_INSENSITIVE",
- False));
- XSync (d->dsp, False);
- }
-}
-
-/* ignore handlers */
-static int
-ignore_xerror_handler (Display *disp, XErrorEvent *evt)
-{
- x_error_occurred = TRUE;
- return 0;
-}
-
-static void
-whack_greeter_fds (void)
-{
- if (greeter_fd_out > 0)
- VE_IGNORE_EINTR (close (greeter_fd_out));
- greeter_fd_out = -1;
- if (greeter_fd_in > 0)
- VE_IGNORE_EINTR (close (greeter_fd_in));
- greeter_fd_in = -1;
-}
-
-static void
-term_session_stop_and_quit (void)
-{
- gdm_in_signal = 0;
- already_in_slave_start_jmp = TRUE;
- gdm_wait_for_ack = FALSE;
- need_to_quit_after_session_stop = TRUE;
-
- if (slave_start_jmp_error_to_print != NULL)
- gdm_error (slave_start_jmp_error_to_print);
- slave_start_jmp_error_to_print = NULL;
-
- /* only if we're not hanging in session stop and getting a
- TERM signal again */
- if (in_session_stop == 0 && session_started)
- gdm_slave_session_stop (d->logged_in && login != NULL,
- TRUE /* no_shutdown_check */);
-
- gdm_debug ("term_session_stop_and_quit: Final cleanup");
-
- /* Well now we're just going to kill
- * everything including the X server,
- * so no need doing XCloseDisplay which
- * may just get us an XIOError */
- d->dsp = NULL;
-
- gdm_slave_quick_exit (exit_code_to_use);
-}
-
-static void
-term_quit (void)
-{
- gdm_in_signal = 0;
- already_in_slave_start_jmp = TRUE;
- gdm_wait_for_ack = FALSE;
- need_to_quit_after_session_stop = TRUE;
-
- if (slave_start_jmp_error_to_print != NULL)
- gdm_error (slave_start_jmp_error_to_print);
- slave_start_jmp_error_to_print = NULL;
-
- gdm_debug ("term_quit: Final cleanup");
-
- /* Well now we're just going to kill
- * everything including the X server,
- * so no need doing XCloseDisplay which
- * may just get us an XIOError */
- d->dsp = NULL;
-
- gdm_slave_quick_exit (exit_code_to_use);
-}
-
-static gboolean
-parent_exists (void)
-{
- pid_t ppid = getppid ();
- static gboolean parent_dead = FALSE; /* once dead, always dead */
-
- if G_UNLIKELY (parent_dead ||
- ppid <= 1 ||
- kill (ppid, 0) < 0) {
- parent_dead = TRUE;
- return FALSE;
- }
- return TRUE;
-}
-
-#ifdef SIGXFSZ
-static void
-gdm_slave_xfsz_handler (int signal)
-{
- gdm_in_signal++;
-
- /* in places where we care we can check
- * and stop writing */
- got_xfsz_signal = TRUE;
-
- /* whack self ASAP */
- remanage_asap = TRUE;
-
- gdm_in_signal--;
-}
-#endif /* SIGXFSZ */
-
-
-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;
-#ifdef SIGXFSZ
- struct sigaction xfsz;
-#endif /* SIGXFSZ */
- sigset_t mask;
- int pinginterval = gdm_daemon_config_get_value_int (GDM_KEY_PING_INTERVAL);
-
- /*
- * Set d global to display before setting signal handlers,
- * since the signal handlers use the d value. Avoids a
- * race condition. It is also set again in gdm_slave_run
- * since it is called in a loop.
- */
- d = display;
-
- gdm_normal_runlevel = get_runlevel ();
-
- /* Ignore SIGUSR1/SIGPIPE, and especially ignore it
- before the Setjmp */
- gdm_signal_ignore (SIGUSR1);
- gdm_signal_ignore (SIGPIPE);
-
- /* ignore power failures, up to user processes to
- * handle things correctly */
-#ifdef SIGPWR
- gdm_signal_ignore (SIGPWR);
-#endif
-
- /* The signals we wish to listen to */
- sigemptyset (&mask);
- sigaddset (&mask, SIGINT);
- sigaddset (&mask, SIGTERM);
- sigaddset (&mask, SIGCHLD);
- sigaddset (&mask, SIGUSR2);
- sigaddset (&mask, SIGUSR1); /* normally we ignore USR1 */
- if ( ! SERVER_IS_LOCAL (display) && pinginterval > 0) {
- sigaddset (&mask, SIGALRM);
- }
- /* must set signal mask before the Setjmp as it will be
- restored, and we're only interested in catching the above signals */
- sigprocmask (SIG_UNBLOCK, &mask, NULL);
-
-
- if G_UNLIKELY (display == NULL) {
- /* saaay ... what? */
- _exit (DISPLAY_REMANAGE);
- }
-
- gdm_debug ("gdm_slave_start: Starting slave process for %s", display->name);
-
- switch (Setjmp (slave_start_jmp)) {
- case JMP_FIRST_RUN:
- return_to_slave_start_jmp = TRUE;
- break;
- case JMP_SESSION_STOP_AND_QUIT:
- term_session_stop_and_quit ();
- /* huh? should never get here */
- _exit (DISPLAY_REMANAGE);
- default:
- case JMP_JUST_QUIT_QUICKLY:
- term_quit ();
- /* huh? should never get here */
- _exit (DISPLAY_REMANAGE);
- }
-
- if ( ! SERVER_IS_LOCAL (display) && pinginterval > 0) {
- /* Handle a ALRM signals from our ping alarms */
- alrm.sa_handler = gdm_slave_alrm_handler;
- alrm.sa_flags = SA_RESTART | SA_NODEFER;
- sigemptyset (&alrm.sa_mask);
- sigaddset (&alrm.sa_mask, SIGALRM);
-
- if G_UNLIKELY (sigaction (SIGALRM, &alrm, NULL) < 0)
- gdm_slave_exit (DISPLAY_ABORT,
- _("%s: Error setting up %s signal handler: %s"),
- "gdm_slave_start", "ALRM", strerror (errno));
- }
-
- /* Handle a INT/TERM signals from gdm master */
- term.sa_handler = gdm_slave_term_handler;
- term.sa_flags = SA_RESTART;
- sigemptyset (&term.sa_mask);
- sigaddset (&term.sa_mask, SIGTERM);
- sigaddset (&term.sa_mask, SIGINT);
-
- if G_UNLIKELY ((sigaction (SIGTERM, &term, NULL) < 0) ||
- (sigaction (SIGINT, &term, NULL) < 0))
- gdm_slave_exit (DISPLAY_ABORT,
- _("%s: Error setting up %s signal handler: %s"),
- "gdm_slave_start", "TERM/INT", strerror (errno));
-
- /* Child handler. Keeps an eye on greeter/session */
- child.sa_handler = gdm_slave_child_handler;
- child.sa_flags = SA_RESTART|SA_NOCLDSTOP;
- sigemptyset (&child.sa_mask);
- sigaddset (&child.sa_mask, SIGCHLD);
-
- 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));
-
- /* Handle a USR2 which is ack from master that it received a message */
- usr2.sa_handler = gdm_slave_usr2_handler;
- usr2.sa_flags = SA_RESTART;
- sigemptyset (&usr2.sa_mask);
- sigaddset (&usr2.sa_mask, SIGUSR2);
-
- if G_UNLIKELY (sigaction (SIGUSR2, &usr2, NULL) < 0)
- gdm_slave_exit (DISPLAY_ABORT, _("%s: Error setting up %s signal handler: %s"),
- "gdm_slave_start", "USR2", strerror (errno));
-
-#ifdef SIGXFSZ
- /* handle the filesize signal */
- xfsz.sa_handler = gdm_slave_xfsz_handler;
- xfsz.sa_flags = SA_RESTART;
- sigemptyset (&xfsz.sa_mask);
- sigaddset (&xfsz.sa_mask, SIGXFSZ);
-
- if G_UNLIKELY (sigaction (SIGXFSZ, &xfsz, NULL) < 0)
- gdm_slave_exit (DISPLAY_ABORT,
- _("%s: Error setting up %s signal handler: %s"),
- "gdm_slave_start", "XFSZ", strerror (errno));
-#endif /* SIGXFSZ */
-
- first_time = time (NULL);
- death_count = 0;
-
- for (;;) {
- time_t the_time;
-
- check_notifies_now ();
-
- gdm_debug ("gdm_slave_start: Loop Thingie");
- gdm_slave_run (display);
-
- /* remote and flexi only run once */
- if (display->type != TYPE_STATIC ||
- ! parent_exists ()) {
- gdm_server_stop (display);
- gdm_slave_send_num (GDM_SOP_XPID, 0);
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- }
-
- the_time = time (NULL);
-
- death_count++;
-
- if ((the_time - first_time) <= 0 ||
- (the_time - first_time) > 60) {
- first_time = the_time;
- death_count = 0;
- } else if G_UNLIKELY (death_count > 6) {
- gdm_slave_quick_exit (DISPLAY_ABORT);
- }
-
- gdm_debug ("gdm_slave_start: Reinitializing things");
-
- /* Whack the server because we want to restart it next
- * time we run gdm_slave_run */
- gdm_server_stop (display);
- gdm_slave_send_num (GDM_SOP_XPID, 0);
- }
- /* very very very evil, should never break, we can't return from
- here sanely */
- _exit (DISPLAY_ABORT);
-}
-
-static gboolean
-setup_automatic_session (GdmDisplay *display, const char *name)
-{
- char *new_login;
- g_free (login);
- login = g_strdup (name);
-
- greet = FALSE;
- gdm_debug ("setup_automatic_session: Automatic login: %s", login);
-
- /* Run the init script. gdmslave suspends until script
- * has terminated */
- gdm_slave_exec_script (display, gdm_daemon_config_get_value_string (GDM_KEY_DISPLAY_INIT_DIR),
- NULL, NULL, FALSE /* pass_stdout */);
-
- gdm_debug ("setup_automatic_session: DisplayInit script finished");
-
- new_login = NULL;
- if ( ! gdm_verify_setup_user (display, login,
- display->name, &new_login))
- return FALSE;
-
- if (new_login != NULL) {
- g_free (login);
- login = g_strdup (new_login);
- }
-
- gdm_debug ("setup_automatic_session: Automatic login successful");
-
- return TRUE;
-}
-
-#ifdef HAVE_TSOL
-static void
-gdm_tsol_init (GdmDisplay *display)
-{
-
- int opcode;
- int firstevent;
- int firsterror;
-
- have_suntsol_extension = XQueryExtension (display->dsp,
- "SUN_TSOL",
- &opcode,
- &firstevent,
- &firsterror);
-}
-#endif
-
-static void
-gdm_screen_init (GdmDisplay *display)
-{
-#ifdef HAVE_XFREE_XINERAMA
- int (* old_xerror_handler) (Display *, XErrorEvent *);
- gboolean have_xinerama = FALSE;
-
- x_error_occurred = FALSE;
- old_xerror_handler = XSetErrorHandler (ignore_xerror_handler);
-
- have_xinerama = XineramaIsActive (display->dsp);
-
- XSync (display->dsp, False);
- XSetErrorHandler (old_xerror_handler);
-
- if (x_error_occurred)
- have_xinerama = FALSE;
-
- if (have_xinerama) {
- int screen_num;
- int xineramascreen;
- XineramaScreenInfo *xscreens =
- XineramaQueryScreens (display->dsp,
- &screen_num);
-
-
- if G_UNLIKELY (screen_num <= 0)
- gdm_fail ("Xinerama active, but <= 0 screens?");
-
- if (screen_num <= gdm_daemon_config_get_value_int (GDM_KEY_XINERAMA_SCREEN))
- gdm_daemon_config_set_value_int (GDM_KEY_XINERAMA_SCREEN, 0);
-
- xineramascreen = gdm_daemon_config_get_value_int (GDM_KEY_XINERAMA_SCREEN);
-
- display->screenx = xscreens[xineramascreen].x_org;
- display->screeny = xscreens[xineramascreen].y_org;
- display->screenwidth = xscreens[xineramascreen].width;
- display->screenheight = xscreens[xineramascreen].height;
-
- display->lrh_offsetx =
- DisplayWidth (display->dsp,
- DefaultScreen (display->dsp))
- - (display->screenx + display->screenwidth);
- display->lrh_offsety =
- DisplayHeight (display->dsp,
- DefaultScreen (display->dsp))
- - (display->screeny + display->screenheight);
-
- XFree (xscreens);
- } else
-#elif HAVE_SOLARIS_XINERAMA
- /* 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);
-
- 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
- * returns the num of monitor
- */
- if G_UNLIKELY (result <= 0)
- gdm_fail ("Xinerama active, but <= 0 screens?");
-
- if (n_monitors <= gdm_daemon_config_get_value_int (GDM_KEY_XINERAMA_SCREEN))
- gdm_daemon_config_set_value_int (GDM_KEY_XINERAMA_SCREEN, 0);
-
- xineramascreen = gdm_daemon_config_get_value_int (GDM_KEY_XINERAMA_SCREEN);
- display->screenx = monitors[xineramascreen].x;
- display->screeny = monitors[xineramascreen].y;
- display->screenwidth = monitors[xineramascreen].width;
- display->screenheight = monitors[xineramascreen].height;
-
- display->lrh_offsetx =
- DisplayWidth (display->dsp,
- DefaultScreen (display->dsp))
- - (display->screenx + display->screenwidth);
- display->lrh_offsety =
- DisplayHeight (display->dsp,
- DefaultScreen (display->dsp))
- - (display->screeny + display->screenheight);
-
- } 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;
- }
-}
-
-static void
-gdm_slave_whack_greeter (void)
-{
- GdmWaitPid *wp;
-
- gdm_sigchld_block_push ();
-
- /* do what you do when you quit, this will hang until the
- * greeter decides to print an STX\n and die, meaning it can do some
- * last minute cleanup */
- gdm_slave_greeter_ctl_no_ret (GDM_QUIT, "");
-
- greet = FALSE;
-
- wp = slave_waitpid_setpid (d->greetpid);
- gdm_sigchld_block_pop ();
-
- slave_waitpid (wp);
-
- d->greetpid = 0;
-
- whack_greeter_fds ();
-
- gdm_slave_send_num (GDM_SOP_GREETPID, 0);
-
- gdm_slave_whack_temp_auth_file ();
-}
-
-static void
-wait_for_display_to_die (Display *display,
- const char *display_name)
-{
- fd_set rfds;
- int fd;
-
- gdm_debug ("wait_for_display_to_die: waiting for display '%s' to die",
- display_name);
-
- fd = ConnectionNumber (display);
-
- FD_ZERO (&rfds);
- FD_SET (fd, &rfds);
-
- while (1) {
- char buf[256];
- struct timeval tv;
- int n;
-
- tv.tv_sec = 5;
- tv.tv_usec = 0;
-
- n = select (fd + 1, &rfds, NULL, NULL, &tv);
- if (G_LIKELY (n == 0)) {
- XSync (display, True);
- } else if (n > 0) {
- VE_IGNORE_EINTR (n = read (fd, buf, sizeof (buf)));
- if (n <= 0)
- break;
- } else if (errno != EINTR) {
- break;
- }
-
- FD_CLR (fd, &rfds);
- }
-
- gdm_debug ("wait_for_display_to_die: '%s' dead", display_name);
-}
-
-static int
-ask_migrate (const char *migrate_to)
-{
- int r;
- char *msg;
- char *but[4];
- char *askbuttons_msg;
-
- /*
- * If migratable and ALWAYS_LOGIN_CURRENT_SESSION is true, then avoid
- * the dialog.
- */
- if (migrate_to != NULL &&
- gdm_daemon_config_get_value_bool (GDM_KEY_ALWAYS_LOGIN_CURRENT_SESSION)) {
- return 1;
- }
-
- /*
- * Avoid dialog if DOUBLE_LOGIN_WARNING is false. In this case
- * ALWAYS_LOGIN_CURRENT_SESSION is false, so assume new session.
- */
- if (!gdm_daemon_config_get_value_bool (GDM_KEY_DOUBLE_LOGIN_WARNING)) {
- return 0;
- }
-
- but[0] = _("Log in anyway");
- if (migrate_to != NULL) {
- msg = _("You are already logged in. "
- "You can log in anyway, return to your "
- "previous login session, or abort this "
- "login");
- but[1] = _("Return to previous login");
- but[2] = _("Abort login");
- but[3] = "NIL";
- } else {
- msg = _("You are already logged in. "
- "You can log in anyway or abort this "
- "login");
- but[1] = _("Abort login");
- but[2] = "NIL";
- but[3] = "NIL";
- }
-
- if (greet)
- gdm_slave_greeter_ctl_no_ret (GDM_DISABLE, "");
-
- 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);
-
- g_free (askbuttons_msg);
- g_free (gdm_ack_response);
- gdm_ack_response = NULL;
-
- if (greet)
- gdm_slave_greeter_ctl_no_ret (GDM_ENABLE, "");
-
- return r;
-}
-
-gboolean
-gdm_slave_check_user_wants_to_log_in (const char *user)
-{
- gboolean loggedin = FALSE;
- int i;
- char **vec;
- char *migrate_to = NULL;
-
- /* always ignore root here, this is mostly a special case
- * since a root login may not be a real login, such as the
- * config stuff, and people shouldn't log in as root anyway
- */
- if (strcmp (user, gdm_root_user ()) == 0)
- return TRUE;
-
- gdm_slave_send_string (GDM_SOP_QUERYLOGIN, user);
- if G_LIKELY (ve_string_empty (gdm_ack_response))
- return TRUE;
- vec = g_strsplit (gdm_ack_response, ",", -1);
- if (vec == NULL)
- return TRUE;
-
- gdm_debug ("QUERYLOGIN response: %s\n", gdm_ack_response);
-
- for (i = 0; vec[i] != NULL && vec[i+1] != NULL; i += 2) {
- int ii;
- loggedin = TRUE;
- if (sscanf (vec[i+1], "%d", &ii) == 1 && ii == 1) {
- migrate_to = g_strdup (vec[i]);
- break;
- }
- }
-
- g_strfreev (vec);
-
- if ( ! loggedin)
- return TRUE;
-
- if (d->type != TYPE_XDMCP_PROXY) {
- int r;
-
- r = ask_migrate (migrate_to);
-
- if (r <= 0) {
- g_free (migrate_to);
- return TRUE;
- }
-
- /*
- * migrate_to should never be NULL here, since
- * ask_migrate will always return 0 or 1 if migrate_to
- * is NULL.
- */
- if (migrate_to == NULL ||
- (migrate_to != NULL && r == 2)) {
- g_free (migrate_to);
- return FALSE;
- }
-
- /* Must be that r == 1, that is return to previous login */
-
- if (d->type == TYPE_FLEXI) {
- gdm_slave_whack_greeter ();
- gdm_server_stop (d);
- gdm_slave_send_num (GDM_SOP_XPID, 0);
-
- /* wait for a few seconds to avoid any vt changing race
- */
- gdm_sleep_no_signal (1);
-
-#ifdef WITH_CONSOLE_KIT
- unlock_ck_session (user, migrate_to);
-#endif
-
- gdm_slave_send_string (GDM_SOP_MIGRATE, migrate_to);
- g_free (migrate_to);
-
- /* we are no longer needed so just die.
- REMANAGE == ABORT here really */
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- }
-
- gdm_slave_send_string (GDM_SOP_MIGRATE, migrate_to);
- g_free (migrate_to);
- } else {
- Display *parent_dsp;
-
- if (migrate_to == NULL)
- return TRUE;
-
- gdm_slave_send_string (GDM_SOP_MIGRATE, migrate_to);
- g_free (migrate_to);
-
- /*
- * We must stay running and hold open our connection to the
- * parent display because with XDMCP the Xserver resets when
- * the initial X client closes its connection (rather than
- * when *all* X clients have closed their connection)
- */
-
- gdm_slave_whack_greeter ();
-
- parent_dsp = d->parent_dsp;
- d->parent_dsp = NULL;
- gdm_server_stop (d);
-
- gdm_slave_send_num (GDM_SOP_XPID, 0);
-
- gdm_debug ("Slave not exiting in order to hold open the connection to the parent display");
-
- wait_for_display_to_die (d->parent_dsp, d->parent_disp);
-
- gdm_slave_quick_exit (DISPLAY_ABORT);
- }
-
- /* abort this login attempt */
- return FALSE;
-}
-
-static gboolean do_xfailed_on_xio_error = FALSE;
-
-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,
- 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);
-
-#ifdef HAVE_TSOL
- /* Check out Solaris Trusted Xserver extension */
- if (d->handled)
- 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);
-}
-
-/* A hack really, this will wait around until the first mapped window
- * with this class and focus it */
-static void
-focus_first_x_window (const char *class_res_name)
-{
- pid_t pid;
- Display *disp;
- int p[2];
- XWindowAttributes attribs = { 0, };
-
- if G_UNLIKELY (pipe (p) < 0) {
- p[0] = -1;
- p[1] = -1;
- }
-
- g_debug ("Forking process to focus first X11 window");
-
- pid = fork ();
- if G_UNLIKELY (pid < 0) {
- if (p[0] != -1)
- VE_IGNORE_EINTR (close (p[0]));
- if (p[1] != -1)
- VE_IGNORE_EINTR (close (p[1]));
- gdm_error (_("%s: cannot fork"), "focus_first_x_window");
- return;
- }
- /* parent */
- if (pid > 0) {
- /* Wait for this subprocess to start-up */
- if (p[0] >= 0) {
- fd_set rfds;
- struct timeval tv;
-
- VE_IGNORE_EINTR (close (p[1]));
-
- FD_ZERO(&rfds);
- FD_SET(p[0], &rfds);
-
- /* Wait up to 2 seconds. */
- tv.tv_sec = 2;
- tv.tv_usec = 0;
-
- select (p[0]+1, &rfds, NULL, NULL, &tv);
-
- VE_IGNORE_EINTR (close (p[0]));
- }
- return;
- }
-
- gdm_unset_signals ();
-
- gdm_log_shutdown ();
-
- gdm_close_all_descriptors (0 /* from */, p[1] /* except */, -1 /* except2 */);
-
- /* No error checking here - if it's messed the best response
- * is to ignore & try to continue */
- gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
- gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
- gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
-
- gdm_log_init ();
-
- /* just in case it's set */
- g_unsetenv ("XAUTHORITY");
-
- gdm_auth_set_local_auth (d);
-
- gdm_sigchld_block_push ();
- disp = XOpenDisplay (d->name);
- gdm_sigchld_block_pop ();
- if G_UNLIKELY (disp == NULL) {
- gdm_error (_("%s: cannot open display %s"),
- "focus_first_x_window",
- d->name);
- _exit (0);
- }
-
- XSetInputFocus (disp, PointerRoot, RevertToPointerRoot, CurrentTime);
-
- /* set event mask for events on root window */
- XGetWindowAttributes (disp,
- DefaultRootWindow (disp),
- &attribs);
- XSelectInput (disp,
- DefaultRootWindow (disp),
- attribs.your_event_mask |
- SubstructureNotifyMask);
-
- if G_LIKELY (p[1] >= 0) {
- VE_IGNORE_EINTR (write (p[1], "!", 1));
- VE_IGNORE_EINTR (close (p[1]));
- }
-
- for (;;) {
- XEvent event = { 0, };
- XClassHint hint = { NULL, NULL };
-
- XNextEvent (disp, &event);
-
- if (event.type == MapNotify &&
- XGetClassHint (disp,
- event.xmap.window,
- &hint) &&
- hint.res_name != NULL &&
- strcmp (hint.res_name, class_res_name) == 0) {
- Window root_return;
- int x_return, y_return;
- unsigned int width_return = 0, height_return = 0;
- unsigned int border_width_return;
- unsigned int depth_return;
-
- XGetGeometry (disp, event.xmap.window,
- &root_return, &x_return,
- &y_return, &width_return,
- &height_return, &border_width_return,
- &depth_return);
- XWarpPointer (disp, None, event.xmap.window,
- 0, 0, 0, 0,
- width_return / 2,
- height_return / 2);
- XSync (disp, False);
- XCloseDisplay (disp);
-
- _exit (0);
- }
- }
-}
-
-static void
-run_config (GdmDisplay *display, struct passwd *pwent)
-{
- pid_t pid;
-
- /* 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_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);
- XDefineCursor (d->dsp,
- DefaultRootWindow (d->dsp),
- xcursor);
- XFreeCursor (d->dsp, xcursor);
- XSync (d->dsp, False);
- }
-
- g_debug ("Forking GDM configuration 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 ();
-
- if G_UNLIKELY (pid < 0) {
- /* Return left pointer */
- Cursor xcursor;
-
- /* Can't fork */
- display->sesspid = 0;
-
- xcursor = XCreateFontCursor (d->dsp, GDK_LEFT_PTR);
- XDefineCursor (d->dsp,
- DefaultRootWindow (d->dsp),
- xcursor);
- XFreeCursor (d->dsp, xcursor);
- XSync (d->dsp, False);
-
- return;
- }
-
- if (pid == 0) {
- char **argv = NULL;
- const char *s;
-
- /* child */
-
- setsid ();
-
- gdm_unset_signals ();
-
- setuid (0);
- setgid (0);
- gdm_desetuid ();
-
- /* setup environment */
- gdm_restoreenv ();
- gdm_reset_locale ();
-
- /* root here */
- g_setenv ("XAUTHORITY", GDM_AUTHFILE (display), TRUE);
- g_setenv ("DISPLAY", display->name, TRUE);
- g_setenv ("LOGNAME", pwent->pw_name, TRUE);
- g_setenv ("USER", pwent->pw_name, TRUE);
- g_setenv ("USERNAME", pwent->pw_name, TRUE);
- g_setenv ("HOME", pwent->pw_dir, TRUE);
- g_setenv ("SHELL", pwent->pw_shell, 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 (display->theme_name))
- g_setenv ("GDM_GTK_THEME", display->theme_name, TRUE);
-
- gdm_log_shutdown ();
-
- gdm_close_all_descriptors (0 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */);
-
- /* No error checking here - if it's messed the best response
- * is to ignore & try to continue */
- gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
- gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
- gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
-
- gdm_log_init ();
-
- VE_IGNORE_EINTR (g_chdir (pwent->pw_dir));
- if G_UNLIKELY (errno != 0)
- VE_IGNORE_EINTR (g_chdir ("/"));
-
- /* exec the configurator */
- s = gdm_daemon_config_get_value_string (GDM_KEY_CONFIGURATOR);
- if (s != NULL) {
- g_shell_parse_argv (s, NULL, &argv, NULL);
- }
-
- if G_LIKELY (argv != NULL &&
- argv[0] != NULL &&
- g_access (argv[0], X_OK) == 0) {
- VE_IGNORE_EINTR (execv (argv[0], argv));
- }
-
- g_strfreev (argv);
-
- 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);
-
- if (g_access (argv[0], X_OK) == 0) {
- VE_IGNORE_EINTR (execv (argv[0], argv));
- }
-
- g_strfreev (argv);
-
- 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 ();
- wp = slave_waitpid_setpid (display->sesspid);
- gdm_sigchld_block_pop ();
-
- slave_waitpid (wp);
-
- display->sesspid = 0;
- configurator = FALSE;
-
- /* this will clean up the sensitivity property */
- gdm_slave_sensitize_config ();
- }
-}
-
-static void
-restart_the_greeter (void)
-{
- do_restart_greeter = FALSE;
-
- gdm_slave_desensitize_config ();
-
- /* no login */
- g_free (login);
- login = NULL;
-
- /* Now restart it */
- if (greet) {
- GdmWaitPid *wp;
-
- gdm_sigchld_block_push ();
-
- gdm_slave_greeter_ctl_no_ret (GDM_SAVEDIE, "");
-
- greet = FALSE;
-
- wp = slave_waitpid_setpid (d->greetpid);
-
- gdm_sigchld_block_pop ();
-
- slave_waitpid (wp);
-
- d->greetpid = 0;
-
- whack_greeter_fds ();
-
- gdm_slave_send_num (GDM_SOP_GREETPID, 0);
- }
- gdm_slave_greeter ();
-
- if (greeter_disabled)
- gdm_slave_greeter_ctl_no_ret (GDM_DISABLE, "");
-
- if (greeter_no_focus)
- gdm_slave_greeter_ctl_no_ret (GDM_NOFOCUS, "");
-
- gdm_slave_sensitize_config ();
-}
-
-static gboolean
-play_login_sound (const char *sound_file)
-{
- const char *soundprogram = gdm_daemon_config_get_value_string (GDM_KEY_SOUND_PROGRAM);
- pid_t pid;
-
- if (ve_string_empty (soundprogram) ||
- ve_string_empty (sound_file) ||
- g_access (soundprogram, X_OK) != 0 ||
- g_access (sound_file, F_OK) != 0)
- return FALSE;
-
- gdm_sigchld_block_push ();
- gdm_sigterm_block_push ();
-
- g_debug ("Forking sound program: %s", soundprogram);
-
- pid = fork ();
- if (pid == 0)
- gdm_unset_signals ();
-
- gdm_sigterm_block_pop ();
- gdm_sigchld_block_pop ();
-
- if (pid == 0) {
- setsid ();
- seteuid (0);
- setegid (0);
- execl (soundprogram,
- soundprogram,
- sound_file,
- NULL);
- _exit (0);
- }
-
- return TRUE;
-}
-
-static void
-gdm_slave_wait_for_login (void)
-{
- const char *successsound;
- char *username;
- g_free (login);
- login = NULL;
-
- /* Chat with greeter */
- while (login == NULL) {
- /* init to a sane value */
- do_timed_login = FALSE;
- do_configurator = FALSE;
- do_cancel = FALSE;
-
- if G_UNLIKELY (do_restart_greeter) {
- do_restart_greeter = FALSE;
- restart_the_greeter ();
- }
-
- /* We are NOT interrupted yet */
- interrupted = FALSE;
-
- check_notifies_now ();
-
- /* just for paranoia's sake */
- NEVER_FAILS_root_set_euid_egid (0, 0);
-
- gdm_debug ("gdm_slave_wait_for_login: In loop");
- username = d->preset_user;
- d->preset_user = NULL;
- login = gdm_verify_user (d /* the display */,
- username /* username */,
- d->name /* display name */,
- d->attached /* display attached? */,
- TRUE /* allow retry */);
- g_free (username);
-
- gdm_debug ("gdm_slave_wait_for_login: end verify for '%s'",
- ve_sure_string (login));
-
- /* Complex, make sure to always handle the do_configurator
- * do_timed_login and do_restart_greeter after any call
- * to gdm_verify_user */
-
- if G_UNLIKELY (do_restart_greeter) {
- g_free (login);
- login = NULL;
- do_restart_greeter = FALSE;
- restart_the_greeter ();
- continue;
- }
-
- check_notifies_now ();
-
- if G_UNLIKELY (do_configurator) {
- struct passwd *pwent;
- gboolean oldAllowRoot;
-
- do_configurator = FALSE;
- g_free (login);
- login = NULL;
- /* clear any error */
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX, "");
- gdm_slave_greeter_ctl_no_ret
- (GDM_MSG,
- _("You must authenticate as root to run configuration."));
-
- /* we always allow root for this */
- oldAllowRoot = gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_ROOT);
- gdm_daemon_config_set_value_bool (GDM_KEY_ALLOW_ROOT, TRUE);
-
- pwent = getpwuid (0);
- if G_UNLIKELY (pwent == NULL) {
- /* what? no "root" ?? */
- gdm_slave_greeter_ctl_no_ret (GDM_RESET, "");
- continue;
- }
-
- gdm_slave_greeter_ctl_no_ret (GDM_SETLOGIN, pwent->pw_name);
- login = gdm_verify_user (d,
- pwent->pw_name,
- d->name,
- d->attached,
- FALSE);
- gdm_daemon_config_set_value_bool (GDM_KEY_ALLOW_ROOT, oldAllowRoot);
-
- /* Clear message */
- gdm_slave_greeter_ctl_no_ret (GDM_MSG, "");
-
- if G_UNLIKELY (do_restart_greeter) {
- g_free (login);
- login = NULL;
- do_restart_greeter = FALSE;
- restart_the_greeter ();
- continue;
- }
-
- check_notifies_now ();
-
- /* The user can't remember his password */
- if (login == NULL) {
- gdm_debug ("gdm_slave_wait_for_login: No login/Bad login");
- gdm_slave_greeter_ctl_no_ret (GDM_RESET, "");
- continue;
- }
-
- /* Wipe the login */
- g_free (login);
- login = NULL;
-
- /* Note that this can still fall through to
- * the timed login if the user doesn't type in the
- * password fast enough and there is timed login
- * enabled */
- if (do_timed_login) {
- break;
- }
-
- if G_UNLIKELY (do_configurator) {
- do_configurator = FALSE;
- gdm_slave_greeter_ctl_no_ret (GDM_RESET, "");
- continue;
- }
-
- /* Now running as root */
-
- /* Get the root pwent */
- pwent = getpwuid (0);
-
- if G_UNLIKELY (pwent == NULL) {
- /* What? No "root" ?? This is not possible
- * since we logged in, but I'm paranoid */
- gdm_slave_greeter_ctl_no_ret (GDM_RESET, "");
- continue;
- }
-
- d->logged_in = TRUE;
- logged_in_uid = 0;
- logged_in_gid = 0;
- gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE);
- /* Note: nobody really logged in */
- gdm_slave_send_string (GDM_SOP_LOGIN, "");
-
- /* Disable the login screen, we don't want people to
- * log in in the meantime */
- gdm_slave_greeter_ctl_no_ret (GDM_DISABLE, "");
- greeter_disabled = TRUE;
-
- /* Make the login screen not focusable */
- gdm_slave_greeter_ctl_no_ret (GDM_NOFOCUS, "");
- greeter_no_focus = TRUE;
-
- check_notifies_now ();
- restart_greeter_now = TRUE;
-
- gdm_debug ("gdm_slave_wait_for_login: Running GDM Configurator ...");
- run_config (d, pwent);
- gdm_debug ("gdm_slave_wait_for_login: GDM Configurator finished ...");
-
- restart_greeter_now = FALSE;
-
- gdm_verify_cleanup (d);
-
- gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE);
- d->logged_in = FALSE;
- logged_in_uid = -1;
- logged_in_gid = -1;
-
- if (remanage_asap) {
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- }
-
- 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, "");
- continue;
- }
-
- /* The user timed out into a timed login during the
- * conversation */
- if (do_timed_login) {
- break;
- }
-
- if (login == NULL) {
- const char *failuresound = gdm_daemon_config_get_value_string (GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE);
-
- gdm_debug ("gdm_slave_wait_for_login: No login/Bad login");
- gdm_slave_greeter_ctl_no_ret (GDM_RESET, "");
-
- /* Play sounds if specified for a failed login */
- if (d->attached && failuresound &&
- gdm_daemon_config_get_value_bool (GDM_KEY_SOUND_ON_LOGIN_FAILURE) &&
- ! play_login_sound (failuresound)) {
- gdm_error (_("Login sound requested on non-local display or the play "
- "software cannot be run or the sound does not exist."));
- }
- }
- }
-
- /* The user timed out into a timed login during the conversation */
- if (do_timed_login) {
- g_free (login);
- login = NULL;
- /* timed login is automatic, thus no need for greeter,
- * we'll take default values */
- gdm_slave_whack_greeter ();
-
- gdm_debug ("gdm_slave_wait_for_login: Timed Login");
- }
-
- successsound = gdm_daemon_config_get_value_string (GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE);
- /* Play sounds if specified for a successful login */
- if (login != NULL && successsound &&
- gdm_daemon_config_get_value_bool (GDM_KEY_SOUND_ON_LOGIN_SUCCESS) &&
- d->attached &&
- ! play_login_sound (successsound)) {
- gdm_error (_("Login sound requested on non-local display or the play software "
- "cannot be run or the sound does not exist."));
- }
-
- gdm_debug ("gdm_slave_wait_for_login: got_login for '%s'",
- ve_sure_string (login));
-
-
-}
-
-/* This is VERY evil! */
-static void
-run_pictures (void)
-{
- char *response;
- int max_write;
- char buf[1024];
- size_t bytes;
- struct passwd *pwent;
- char *picfile;
- FILE *fp;
-
- response = NULL;
- for (;;) {
- struct stat s;
- char *tmp, *ret;
- int i, r;
-
- g_free (response);
- response = gdm_slave_greeter_ctl (GDM_NEEDPIC, "");
- if (ve_string_empty (response)) {
- g_free (response);
- return;
- }
-
- pwent = getpwnam (response);
- if G_UNLIKELY (pwent == NULL) {
- gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
- continue;
- }
-
- picfile = NULL;
-
- NEVER_FAILS_seteuid (0);
- if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
- seteuid (pwent->pw_uid) != 0) {
- NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
- gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
- continue;
- }
-
- picfile = gdm_daemon_config_get_facefile_from_home (pwent->pw_dir, pwent->pw_uid);
-
- if (! picfile)
- picfile = gdm_daemon_config_get_facefile_from_global (pwent->pw_name, pwent->pw_uid);
-
- if (! picfile) {
- NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
- gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
- continue;
- }
-
- VE_IGNORE_EINTR (r = g_stat (picfile, &s));
- if G_UNLIKELY (r < 0 || s.st_size > gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE)) {
- NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
-
- gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
- continue;
- }
-
- VE_IGNORE_EINTR (fp = fopen (picfile, "r"));
- g_free (picfile);
- if G_UNLIKELY (fp == NULL) {
- NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
-
- gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "");
- continue;
- }
-
- tmp = g_strdup_printf ("buffer:%d", (int)s.st_size);
- ret = gdm_slave_greeter_ctl (GDM_READPIC, tmp);
- g_free (tmp);
-
- if G_UNLIKELY (ret == NULL || strcmp (ret, "OK") != 0) {
- VE_IGNORE_EINTR (fclose (fp));
- g_free (ret);
-
- NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
-
- continue;
- }
- g_free (ret);
-
- gdm_fdprintf (greeter_fd_out, "%c", STX);
-
-#ifdef PIPE_BUF
- max_write = MIN (PIPE_BUF, sizeof (buf));
-#else
- /* apparently Hurd doesn't have PIPE_BUF */
- max_write = fpathconf (greeter_fd_out, _PC_PIPE_BUF);
- /* could return -1 if no limit */
- if (max_write > 0)
- max_write = MIN (max_write, sizeof (buf));
- else
- max_write = sizeof (buf);
-#endif
-
- i = 0;
- while (i < s.st_size) {
- int written;
-
- VE_IGNORE_EINTR (bytes = fread (buf, sizeof (char),
- max_write, fp));
-
- if (bytes <= 0)
- break;
-
- if G_UNLIKELY (i + bytes > s.st_size)
- bytes = s.st_size - i;
-
- /* write until we succeed in writing something */
- VE_IGNORE_EINTR (written = write (greeter_fd_out, buf, bytes));
- if G_UNLIKELY (written < 0 &&
- (errno == EPIPE || errno == EBADF)) {
- /* something very, very bad has happened */
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- }
-
- if G_UNLIKELY (written < 0)
- written = 0;
-
- /* write until we succeed in writing everything */
- while (written < bytes) {
- int n;
- VE_IGNORE_EINTR (n = write (greeter_fd_out, &buf[written], bytes-written));
- if G_UNLIKELY (n < 0 &&
- (errno == EPIPE || errno == EBADF)) {
- /* something very, very bad has happened */
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- } else if G_LIKELY (n > 0) {
- written += n;
- }
- }
-
- /* we have written bytes bytes if it likes it or not */
- i += bytes;
- }
-
- VE_IGNORE_EINTR (fclose (fp));
-
- /* eek, this "could" happen, so just send some garbage */
- while G_UNLIKELY (i < s.st_size) {
- bytes = MIN (sizeof (buf), s.st_size - i);
- errno = 0;
- bytes = write (greeter_fd_out, buf, bytes);
- if G_UNLIKELY (bytes < 0 && (errno == EPIPE || errno == EBADF)) {
- /* something very, very bad has happened */
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- }
- 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 ());
- }
- g_free (response); /* not reached */
-}
-
-/* hakish, copy file (owned by fromuid) to a temp file owned by touid */
-static char *
-copy_auth_file (uid_t fromuid, uid_t touid, const char *file)
-{
- uid_t old = geteuid ();
- gid_t oldg = getegid ();
- char *name;
- int authfd;
- int fromfd;
- int bytes;
- char buf[2048];
- int cnt;
-
- NEVER_FAILS_seteuid (0);
- NEVER_FAILS_setegid (gdm_daemon_config_get_gdmgid ());
-
- if G_UNLIKELY (seteuid (fromuid) != 0) {
- NEVER_FAILS_root_set_euid_egid (old, oldg);
- return NULL;
- }
-
- if ( ! gdm_auth_file_check ("copy_auth_file", fromuid,
- file, FALSE /* absentok */, NULL)) {
- NEVER_FAILS_root_set_euid_egid (old, oldg);
- return NULL;
- }
-
- do {
- errno = 0;
- fromfd = open (file, O_RDONLY
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
-#ifdef O_NOFOLLOW
- |O_NOFOLLOW
-#endif
- );
- } while G_UNLIKELY (errno == EINTR);
-
- if G_UNLIKELY (fromfd < 0) {
- NEVER_FAILS_root_set_euid_egid (old, oldg);
- return NULL;
- }
-
- 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");
-
- VE_IGNORE_EINTR (g_unlink (name));
- VE_IGNORE_EINTR (authfd = open (name, O_EXCL|O_TRUNC|O_WRONLY|O_CREAT, 0600));
-
- if G_UNLIKELY (authfd < 0) {
- VE_IGNORE_EINTR (close (fromfd));
- NEVER_FAILS_root_set_euid_egid (old, oldg);
- g_free (name);
- return NULL;
- }
-
- VE_IGNORE_EINTR (fchown (authfd, touid, -1));
-
- cnt = 0;
- for (;;) {
- int written, n;
- VE_IGNORE_EINTR (bytes = read (fromfd, buf, sizeof (buf)));
-
- /* EOF */
- if (bytes == 0)
- break;
-
- if G_UNLIKELY (bytes < 0) {
- /* Error reading */
- gdm_error ("Error reading %s: %s", file, strerror (errno));
- VE_IGNORE_EINTR (close (fromfd));
- VE_IGNORE_EINTR (close (authfd));
- NEVER_FAILS_root_set_euid_egid (old, oldg);
- g_free (name);
- return NULL;
- }
-
- written = 0;
- do {
- VE_IGNORE_EINTR (n = write (authfd, &buf[written], bytes-written));
- if G_UNLIKELY (n < 0) {
- /* Error writing */
- gdm_error ("Error writing %s: %s", name, strerror (errno));
- VE_IGNORE_EINTR (close (fromfd));
- VE_IGNORE_EINTR (close (authfd));
- NEVER_FAILS_root_set_euid_egid (old, oldg);
- g_free (name);
- return NULL;
- }
- written += n;
- } while (written < bytes);
-
- cnt = cnt + written;
- /* this should never occur (we check above)
- but we're paranoid) */
- if G_UNLIKELY (cnt > gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE))
- return NULL;
- }
-
- VE_IGNORE_EINTR (close (fromfd));
- VE_IGNORE_EINTR (close (authfd));
-
- NEVER_FAILS_root_set_euid_egid (old, oldg);
-
- return name;
-}
-
-static void
-exec_command (const char *command, const char *extra_arg)
-{
- char **argv;
- int argc;
-
- if (! g_shell_parse_argv (command, &argc, &argv, NULL)) {
- return;
- }
-
- if (argv == NULL ||
- ve_string_empty (argv[0]))
- return;
-
- if (g_access (argv[0], X_OK) != 0)
- return;
-
- if (extra_arg != NULL) {
-
- argv = g_renew (char *, argv, argc + 2);
- argv[argc] = g_strdup (extra_arg);
- argv[argc + 1] = NULL;
- }
-
- VE_IGNORE_EINTR (execv (argv[0], argv));
- g_strfreev (argv);
-}
-
-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 ();
-
- 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);
-
- g_debug ("Forking greeter process: %s", command);
-
- /* 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 ();
-
- gdm_unset_signals ();
-
- /* Plumbing */
- VE_IGNORE_EINTR (close (pipe1[1]));
- VE_IGNORE_EINTR (close (pipe2[0]));
-
- VE_IGNORE_EINTR (dup2 (pipe1[0], STDIN_FILENO));
- VE_IGNORE_EINTR (dup2 (pipe2[1], STDOUT_FILENO));
-
- gdm_log_shutdown ();
-
- gdm_close_all_descriptors (2 /* from */, slave_fifo_pipe_fd/* except */, d->slave_notify_fd/* except2 */);
-
- gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
-
- gdm_log_init ();
-
- 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);
-
- 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);
- }
-
- 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");
- }
-
- /* 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);
-
- gdm_error (_("%s: Cannot start greeter trying default: %s"),
- "gdm_slave_greeter",
- LIBEXECDIR "/gdmlogin");
-
- g_setenv ("GDM_WHACKED_GREETER_CONFIG", "true", TRUE);
-
- exec_command (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"));
-
- /* 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]));
-
- whack_greeter_fds ();
-
- greeter_fd_out = pipe1[1];
- greeter_fd_in = pipe2[0];
-
- gdm_debug ("gdm_slave_greeter: Greeter on pid %d", (int)pid);
-
- gdm_slave_send_num (GDM_SOP_GREETPID, d->greetpid);
- run_pictures (); /* Append pictures to greeter if browsing is on */
-
- 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);
-
-
- check_notifies_now ();
- break;
- }
-}
-
-/* This should not call anything that could cause a syslog in case we
- * are in a signal */
-void
-gdm_slave_send (const char *str, gboolean wait_for_ack)
-{
- int fd;
- char *fifopath;
- int i;
- uid_t old;
-
- if ( ! gdm_wait_for_ack)
- wait_for_ack = FALSE;
-
- if (wait_for_ack) {
- gdm_got_ack = FALSE;
- g_free (gdm_ack_response);
- gdm_ack_response = NULL;
- }
-
- /* ensure this is sent from the actual slave with the pipe always, this is anal I know */
- if (G_LIKELY (d->slavepid == getppid ()) || G_LIKELY (d->slavepid == getpid ())) {
- fd = slave_fifo_pipe_fd;
- } else {
- fd = -1;
- }
-
- if G_UNLIKELY (fd < 0) {
- /* FIXME: This is not likely to ever be used, remove
- at some point. Other then slaves shouldn't be using
- these functions. And if the pipe creation failed
- 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);
- old = geteuid ();
- if (old != 0)
- seteuid (0);
-#ifdef O_NOFOLLOW
- VE_IGNORE_EINTR (fd = open (fifopath, O_WRONLY|O_NOFOLLOW));
-#else
- VE_IGNORE_EINTR (fd = open (fifopath, O_WRONLY));
-#endif
- if (old != 0)
- seteuid (old);
- g_free (fifopath);
- }
-
- /* eek */
- if G_UNLIKELY (fd < 0) {
- if (gdm_in_signal == 0)
- gdm_error (_("%s: Can't open fifo!"), "gdm_slave_send");
- return;
- }
-
- gdm_fdprintf (fd, "\n%s\n", str);
-
- if G_UNLIKELY (fd != slave_fifo_pipe_fd) {
- VE_IGNORE_EINTR (close (fd));
- }
-
-#if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD)
- if (wait_for_ack && ! gdm_got_ack) {
- /* let the other process do its stuff */
- sched_yield ();
- }
-#endif
-
- /* Wait till you get a response from the daemon */
- if (strncmp (str, "opcode="GDM_SOP_SHOW_ERROR_DIALOG,
- strlen ("opcode="GDM_SOP_SHOW_ERROR_DIALOG)) == 0 ||
- strncmp (str, "opcode="GDM_SOP_SHOW_YESNO_DIALOG,
- strlen ("opcode="GDM_SOP_SHOW_YESNO_DIALOG)) == 0 ||
- strncmp (str, "opcode="GDM_SOP_SHOW_QUESTION_DIALOG,
- strlen ("opcode="GDM_SOP_SHOW_QUESTION_DIALOG)) == 0 ||
- strncmp (str, "opcode="GDM_SOP_SHOW_ASKBUTTONS_DIALOG,
- strlen ("opcode="GDM_SOP_SHOW_ASKBUTTONS_DIALOG)) == 0) {
-
- for (; wait_for_ack && !gdm_got_ack ; ) {
- fd_set rfds;
-
- FD_ZERO (&rfds);
- FD_SET (d->slave_notify_fd, &rfds);
-
- if (select (d->slave_notify_fd+1, &rfds, NULL, NULL, NULL) > 0) {
- gdm_slave_handle_usr2_message ();
- }
- }
- } else {
- for (i = 0;
- wait_for_ack &&
- ! gdm_got_ack &&
- parent_exists () &&
- i < 10;
- i++) {
- if (in_usr2_signal > 0) {
- fd_set rfds;
- struct timeval tv;
-
- FD_ZERO (&rfds);
- FD_SET (d->slave_notify_fd, &rfds);
-
- /* Wait up to 1 second. */
- tv.tv_sec = 1;
- tv.tv_usec = 0;
-
- if (select (d->slave_notify_fd+1, &rfds, NULL, NULL, &tv) > 0) {
- gdm_slave_handle_usr2_message ();
- }
- } else {
- 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 */
- }
- }
- }
-
- if G_UNLIKELY (wait_for_ack &&
- ! gdm_got_ack &&
- gdm_in_signal == 0) {
- if (strncmp (str, GDM_SOP_COOKIE " ",
- strlen (GDM_SOP_COOKIE " ")) == 0) {
- char *s = g_strndup
- (str, strlen (GDM_SOP_COOKIE " XXXX XX"));
- /* cut off most of the cookie for "security" */
- gdm_debug ("Timeout occurred for sending message %s...", s);
- g_free (s);
- } else {
- gdm_debug ("Timeout occurred for sending message %s", str);
- }
- }
-}
-
-void
-gdm_slave_send_num (const char *opcode, long num)
-{
- char *msg;
-
- if (gdm_in_signal == 0)
- gdm_debug ("Sending %s == %ld for slave %ld",
- opcode,
- (long)num,
- (long)getpid ());
-
- msg = g_strdup_printf ("%s %ld %ld", opcode,
- (long)getpid (), (long)num);
-
- gdm_slave_send (msg, TRUE);
-
- g_free (msg);
-}
-
-void
-gdm_slave_send_string (const char *opcode, const char *str)
-{
- char *msg;
-
- if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG) && gdm_in_signal == 0) {
- gdm_debug ("Sending %s == <secret> for slave %ld",
- opcode,
- (long)getpid ());
- }
-
- if (strcmp (opcode, GDM_SOP_SHOW_ERROR_DIALOG) == 0 ||
- strcmp (opcode, GDM_SOP_SHOW_YESNO_DIALOG) == 0 ||
- strcmp (opcode, GDM_SOP_SHOW_QUESTION_DIALOG) == 0 ||
- strcmp (opcode, GDM_SOP_SHOW_ASKBUTTONS_DIALOG) == 0) {
- msg = g_strdup_printf ("opcode=%s$$pid=%ld$$%s", opcode,
- (long)d->slavepid, ve_sure_string (str));
- } else {
- msg = g_strdup_printf ("%s %ld %s", opcode,
- (long)getpid (), ve_sure_string (str));
- }
-
- gdm_slave_send (msg, TRUE);
-
- g_free (msg);
-}
-
-static void
-send_chosen_host (GdmDisplay *disp,
- const char *hostname)
-{
- GdmHostent *hostent;
- struct sockaddr_storage ss;
- char *str = NULL;
- char *host;
-
- hostent = gdm_gethostbyname (hostname);
-
- if G_UNLIKELY (hostent->addrs == NULL) {
- gdm_error ("Cannot get address of host '%s'", hostname);
- gdm_hostent_free (hostent);
- return;
- }
-
- /* take first address */
- memcpy (&ss, &hostent->addrs[0], sizeof (struct sockaddr_storage));
-
- gdm_address_get_info (&ss, &host, NULL);
- gdm_hostent_free (hostent);
-
- 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);
-}
-
-
-static void
-gdm_slave_chooser (void)
-{
- gint p[2];
- struct passwd *pwent;
- pid_t pid;
- GdmWaitPid *wp;
- const char *defaultpath;
- const char *gdmuser;
- const char *moduleslist;
-
- gdm_debug ("gdm_slave_chooser: Running chooser on %s", d->name);
-
- /* Open a pipe for chooser communications */
- if G_UNLIKELY (pipe (p) < 0)
- gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't init pipe to gdmchooser"), "gdm_slave_chooser");
-
- /* 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 */);
-
- 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 ();
- pid = d->chooserpid = fork ();
- if (pid == 0)
- gdm_unset_signals ();
- gdm_sigterm_block_pop ();
- gdm_sigchld_block_pop ();
-
- switch (pid) {
-
- case 0:
- setsid ();
-
- gdm_unset_signals ();
-
- /* Plumbing */
- VE_IGNORE_EINTR (close (p[0]));
-
- if (p[1] != STDOUT_FILENO)
- VE_IGNORE_EINTR (dup2 (p[1], STDOUT_FILENO));
-
- gdm_log_shutdown ();
-
- VE_IGNORE_EINTR (close (0));
- gdm_close_all_descriptors (2 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */);
-
- gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
- gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
-
- gdm_log_init ();
-
- 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 ());
-
- 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_chooser", 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_chooser", gdm_daemon_config_get_gdmuid ());
-
- gdm_restoreenv ();
- gdm_reset_locale ();
-
- g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
- g_setenv ("DISPLAY", d->name, TRUE);
-
- g_setenv ("LOGNAME", gdmuser, TRUE);
- g_setenv ("USER", gdmuser, TRUE);
- g_setenv ("USERNAME", gdmuser, TRUE);
-
- g_setenv ("GDM_VERSION", VERSION, TRUE);
-
- pwent = getpwnam (gdmuser);
- if G_LIKELY (pwent != NULL) {
- /* Note that usually this doesn't exist */
- if (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);
- }
-
- 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);
-
- 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)) {
- char *modules = g_strdup_printf ("--gtk-module=%s", moduleslist);
- exec_command (gdm_daemon_config_get_value_string (GDM_KEY_CHOOSER), modules);
- }
-
- exec_command (gdm_daemon_config_get_value_string (GDM_KEY_CHOOSER), NULL);
-
- gdm_errorgui_error_box (d,
- GTK_MESSAGE_ERROR,
- _("Cannot start the chooser application. "
- "You will probably not be able to log in. "
- "Please contact the system administrator."));
-
- gdm_child_exit (DISPLAY_REMANAGE, _("%s: Error starting chooser on display %s"), "gdm_slave_chooser", d->name);
-
- case -1:
- gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't fork gdmchooser process"), "gdm_slave_chooser");
-
- default:
- gdm_debug ("gdm_slave_chooser: Chooser on pid %d", d->chooserpid);
- gdm_slave_send_num (GDM_SOP_CHOOSERPID, d->chooserpid);
-
- VE_IGNORE_EINTR (close (p[1]));
-
- g_free (d->chooser_last_line);
- d->chooser_last_line = NULL;
- d->chooser_output_fd = p[0];
- /* make the output read fd non-blocking */
- fcntl (d->chooser_output_fd, F_SETFL, O_NONBLOCK);
-
- /* wait for the chooser to die */
-
- gdm_sigchld_block_push ();
- wp = slave_waitpid_setpid (d->chooserpid);
- gdm_sigchld_block_pop ();
-
- slave_waitpid (wp);
-
- d->chooserpid = 0;
- gdm_slave_send_num (GDM_SOP_CHOOSERPID, 0);
-
- /* Note: Nothing affecting the chooser needs update
- * from notifies, plus we are exitting right now */
-
- run_chooser_output ();
- VE_IGNORE_EINTR (close (d->chooser_output_fd));
- d->chooser_output_fd = -1;
-
- if (d->chooser_last_line != NULL) {
- char *host = d->chooser_last_line;
- d->chooser_last_line = NULL;
-
- if (SERVER_IS_XDMCP (d)) {
- send_chosen_host (d, host);
- gdm_slave_quick_exit (DISPLAY_CHOSEN);
- } else {
- gdm_debug ("Sending locally chosen host %s", host);
- gdm_slave_send_string (GDM_SOP_CHOSEN_LOCAL, host);
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- }
- }
-
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- break;
- }
-}
-
-gboolean
-gdm_is_session_magic (const char *session_name)
-{
- return (strcmp (session_name, GDM_SESSION_DEFAULT) == 0 ||
- strcmp (session_name, GDM_SESSION_CUSTOM) == 0 ||
- strcmp (session_name, GDM_SESSION_FAILSAFE) == 0);
-}
-
-/* Note that this does check TryExec! while normally we don't check
- * it */
-static gboolean
-is_session_ok (const char *session_name)
-{
- char *exec;
- gboolean ret = TRUE;
-
- /* these are always OK */
- if (strcmp (session_name, GDM_SESSION_FAILSAFE_GNOME) == 0 ||
- strcmp (session_name, GDM_SESSION_FAILSAFE_XTERM) == 0)
- return TRUE;
-
- if (ve_string_empty (gdm_daemon_config_get_value_string (GDM_KEY_SESSION_DESKTOP_DIR)))
- return gdm_is_session_magic (session_name);
-
- exec = gdm_daemon_config_get_session_exec (session_name, TRUE /* check_try_exec */);
- if (exec == NULL)
- ret = FALSE;
- g_free (exec);
- return ret;
-}
-
-static char *
-find_a_session (void)
-{
- char *try[] = {
- "Default",
- "default",
- "Gnome",
- "gnome",
- "GNOME",
- "Custom",
- "custom",
- "kde",
- "KDE",
- "failsafe",
- "Failsafe",
- NULL
- };
- int i;
- char *session;
- const char *defaultsession = gdm_daemon_config_get_value_string (GDM_KEY_DEFAULT_SESSION);
-
- if (!ve_string_empty (defaultsession) &&
- is_session_ok (defaultsession))
- session = g_strdup (defaultsession);
- else
- session = NULL;
-
- for (i = 0; try[i] != NULL && session == NULL; i++) {
- if (is_session_ok (try[i]))
- session = g_strdup (try[i]);
- }
- return session;
-}
-
-static char *
-find_prog (const char *name)
-{
- char *path;
- int i;
- char *try[] = {
- "/usr/bin/X11/",
- "/usr/X11R6/bin/",
- "/opt/X11R6/bin/",
- "/usr/bin/",
- "/usr/openwin/bin/",
- "/usr/local/bin/",
- "/opt/gnome/bin/",
- BINDIR "/",
- NULL
- };
-
- path = g_find_program_in_path (name);
- if (path != NULL &&
- g_access (path, X_OK) == 0) {
- return path;
- }
- g_free (path);
- for (i = 0; try[i] != NULL; i++) {
- path = g_strconcat (try[i], name, NULL);
- if (g_access (path, X_OK) == 0) {
- return path;
- }
- g_free (path);
- }
- return NULL;
-}
-
-static gboolean
-wipe_xsession_errors (struct passwd *pwent,
- const char *home_dir,
- gboolean home_dir_ok)
-{
- gboolean wiped_something = FALSE;
- DIR *dir;
- struct dirent *ent;
- uid_t old = geteuid ();
- uid_t oldg = getegid ();
-
- seteuid (0);
- if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
- seteuid (pwent->pw_uid) != 0) {
- NEVER_FAILS_root_set_euid_egid (old, oldg);
- return FALSE;
- }
-
- if G_LIKELY (home_dir_ok) {
- char *filename = g_build_filename (home_dir,
- ".xsession-errors",
- NULL);
- if (g_access (filename, F_OK) == 0) {
- wiped_something = TRUE;
- VE_IGNORE_EINTR (g_unlink (filename));
- }
- g_free (filename);
- }
-
- VE_IGNORE_EINTR (dir = opendir ("/tmp"));
- if G_LIKELY (dir != NULL) {
- char *prefix = g_strdup_printf ("xses-%s.", pwent->pw_name);
- int prefixlen = strlen (prefix);
- VE_IGNORE_EINTR (ent = readdir (dir));
- while (ent != NULL) {
- if (strncmp (ent->d_name, prefix, prefixlen) == 0) {
- char *filename = g_strdup_printf ("/tmp/%s",
- ent->d_name);
- wiped_something = TRUE;
- VE_IGNORE_EINTR (g_unlink (filename));
- g_free (filename);
- }
- VE_IGNORE_EINTR (ent = readdir (dir));
- }
- VE_IGNORE_EINTR (closedir (dir));
- g_free (prefix);
- }
-
- NEVER_FAILS_root_set_euid_egid (old, oldg);
-
- return wiped_something;
-}
-
-static int
-open_xsession_errors (struct passwd *pwent,
- gboolean failsafe,
- const char *home_dir,
- gboolean home_dir_ok)
-{
- int logfd = -1;
-
- g_free (d->xsession_errors_filename);
- d->xsession_errors_filename = NULL;
-
- /* Log all output from session programs to a file,
- * unless in failsafe mode which needs to work when there is
- * no diskspace as well */
- if G_LIKELY ( ! failsafe && home_dir_ok) {
- char *filename = g_build_filename (home_dir,
- ".xsession-errors",
- NULL);
- uid_t old = geteuid ();
- uid_t oldg = getegid ();
-
- seteuid (0);
- if G_LIKELY (setegid (pwent->pw_gid) == 0 &&
- seteuid (pwent->pw_uid) == 0) {
- /* unlink to be anal */
- VE_IGNORE_EINTR (g_unlink (filename));
- VE_IGNORE_EINTR (logfd = open (filename, O_EXCL|O_CREAT|O_TRUNC|O_WRONLY, 0644));
- }
- NEVER_FAILS_root_set_euid_egid (old, oldg);
-
- if G_UNLIKELY (logfd < 0) {
- gdm_error (_("%s: Could not open ~/.xsession-errors"),
- "run_session_child");
- g_free (filename);
- } else {
- d->xsession_errors_filename = filename;
- }
- }
-
- /* let's try an alternative */
- if G_UNLIKELY (logfd < 0) {
- mode_t oldmode;
-
- char *filename = g_strdup_printf ("/tmp/xses-%s.XXXXXX",
- pwent->pw_name);
- uid_t old = geteuid ();
- uid_t oldg = getegid ();
-
- seteuid (0);
- if G_LIKELY (setegid (pwent->pw_gid) == 0 &&
- seteuid (pwent->pw_uid) == 0) {
- oldmode = umask (077);
- logfd = mkstemp (filename);
- umask (oldmode);
- }
-
- NEVER_FAILS_root_set_euid_egid (old, oldg);
-
- if G_LIKELY (logfd >= 0) {
- d->xsession_errors_filename = filename;
- } else {
- g_free (filename);
- }
- }
-
- return logfd;
-}
-
-#ifdef HAVE_SELINUX
-/* This should be run just before we exec the user session */
-static gboolean
-gdm_selinux_setup (const char *login)
-{
- security_context_t scontext;
- 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;
-
- if (getseuserbyname(login, &seuser, &level) == 0)
- ret=get_default_context_with_level(seuser, level, 0, &scontext);
-
- if (ret < 0) {
- gdm_error ("SELinux gdm login: unable to obtain default security context for %s.", login);
- /* note that this will be run when the .xsession-errors
- is already being logged, so we can use stderr */
- gdm_fdprintf (2, "SELinux gdm login: unable to obtain default security context for %s.", login);
- return (security_getenforce()==0);
- }
-
- gdm_assert (scontext != NULL);
-
- if (setexeccon (scontext) != 0) {
- gdm_error ("SELinux gdm login: unable to set executable context %s.",
- (char *)scontext);
- gdm_fdprintf (2, "SELinux gdm login: unable to set executable context %s.",
- (char *)scontext);
- freecon (scontext);
- return (security_getenforce()==0);
- }
-
- freecon (scontext);
-
- return TRUE;
-}
-#endif /* HAVE_SELINUX */
-
-static void
-session_child_run (struct passwd *pwent,
- int logfd,
- gboolean failsafe,
- const char *home_dir,
- gboolean home_dir_ok,
-#ifdef WITH_CONSOLE_KIT
- const char *ck_session_cookie,
-#endif
- const char *session,
- const char *save_session,
- const char *language,
- const char *gnome_session,
- gboolean usrcfgok,
- gboolean savesess,
- gboolean savelang)
-{
- char *sessionexec = NULL;
- GString *fullexec = NULL;
- const char *shell = NULL;
- const char *greeter;
- gint result;
- gchar **argv = NULL;
-
-#ifdef CAN_USE_SETPENV
- extern char **newenv;
- int i;
-#endif
-
- gdm_unset_signals ();
- if G_UNLIKELY (setsid () < 0)
- /* should never happen */
- gdm_error (_("%s: setsid () failed: %s!"),
- "session_child_run", strerror (errno));
-
- g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
-
- /* Here we setup our 0,1,2 descriptors, we do it here
- * nowdays rather then later on so that we get errors even
- * from the PreSession script */
- if G_LIKELY (logfd >= 0) {
- VE_IGNORE_EINTR (dup2 (logfd, 1));
- VE_IGNORE_EINTR (dup2 (logfd, 2));
- VE_IGNORE_EINTR (close (logfd));
- } else {
- VE_IGNORE_EINTR (close (1));
- VE_IGNORE_EINTR (close (2));
- gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
- gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
- }
-
- VE_IGNORE_EINTR (close (0));
- gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
-
- /* Set this for the PreSession script */
- /* compatibility */
- g_setenv ("GDMSESSION", session, TRUE);
-
- g_setenv ("DESKTOP_SESSION", session, TRUE);
-
- /* Determine default greeter type so the PreSession */
- /* script can set the appropriate background color. */
- 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);
- }
-
- if (strstr (greeter, "gdmlogin") != NULL) {
- g_setenv ("GDM_GREETER_TYPE", "PLAIN", TRUE);
- } else if (strstr (greeter, "gdmgreeter") != NULL) {
- g_setenv ("GDM_GREETER_TYPE", "THEMED", TRUE);
- } else {
- /* huh? */
- g_setenv ("GDM_GREETER_TYPE", "unknown", TRUE);
- }
-
- /* Run the PreSession script */
- if G_UNLIKELY (gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_PRESESSION),
- pwent->pw_name, pwent,
- TRUE /* pass_stdout */) != EXIT_SUCCESS &&
- /* ignore errors in failsafe modes */
- ! 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");
-
- ve_clearenv ();
-
- /* Prepare user session */
- g_setenv ("XAUTHORITY", d->userauth, TRUE);
- g_setenv ("DISPLAY", d->name, TRUE);
- g_setenv ("LOGNAME", pwent->pw_name, TRUE);
- g_setenv ("USER", pwent->pw_name, TRUE);
- g_setenv ("USERNAME", pwent->pw_name, TRUE);
- g_setenv ("HOME", home_dir, TRUE);
-#ifdef WITH_CONSOLE_KIT
- if (ck_session_cookie != NULL) {
- g_setenv ("XDG_SESSION_COOKIE", ck_session_cookie, TRUE);
- }
-#endif
- g_setenv ("PWD", home_dir, TRUE);
- g_setenv ("GDMSESSION", session, TRUE);
- g_setenv ("DESKTOP_SESSION", session, TRUE);
- g_setenv ("SHELL", pwent->pw_shell, TRUE);
-
- if (d->type == TYPE_STATIC) {
- g_setenv ("GDM_XSERVER_LOCATION", "local", TRUE);
- } else if (d->type == TYPE_XDMCP) {
- g_setenv ("GDM_XSERVER_LOCATION", "xdmcp", TRUE);
- } else if (d->type == TYPE_FLEXI) {
- g_setenv ("GDM_XSERVER_LOCATION", "flexi", TRUE);
- } else if (d->type == TYPE_FLEXI_XNEST) {
- g_setenv ("GDM_XSERVER_LOCATION", "flexi-xnest", TRUE);
- } else if (d->type == TYPE_XDMCP_PROXY) {
- g_setenv ("GDM_XSERVER_LOCATION", "xdmcp-proxy", TRUE);
- } else {
- /* huh? */
- g_setenv ("GDM_XSERVER_LOCATION", "unknown", TRUE);
- }
-
- if (gnome_session != NULL)
- g_setenv ("GDM_GNOME_SESSION", gnome_session, TRUE);
-
- /* Special PATH for root */
- if (pwent->pw_uid == 0)
- g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_ROOT_PATH), TRUE);
- else
- g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_PATH), TRUE);
-
- /*
- * Install GDM desktop files to a non-default desktop file
- * location (/usr/share/gdm/applications) and GDM appends
- * this directory to the end of the XDG_DATA_DIR environment
- * variable. This way, GDM menu choices never appear if
- * using a different display manager.
- */
- {
- const char *old_system_data_dirs;
- char *new_system_data_dirs;
-
- old_system_data_dirs = g_getenv ("XDG_DATA_DIRS") ?
- g_getenv ("XDG_DATA_DIRS") :
- "/usr/local/share/:/usr/share/";
-
- new_system_data_dirs = g_build_path (":",
- old_system_data_dirs, DATADIR "/gdm/", NULL);
-
- g_setenv ("XDG_DATA_DIRS", new_system_data_dirs, TRUE);
-
- g_free (new_system_data_dirs);
- }
-
- /* Eeeeek, this no lookie as a correct language code,
- * just use the system default */
- if G_UNLIKELY ( ! ve_string_empty (language) &&
- ! ve_locale_exists (language)) {
- char *msg = g_strdup_printf (_("Language %s does not exist; using %s"),
- language, _("System default"));
- gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, msg);
- language = NULL;
- g_free (msg);
- }
-
- /* Now still as root make the system authfile not readable by others,
- and therefore not by the gdm user */
- 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,
- _("%s: Could not setup environment for %s. "
- "Aborting."),
- "session_child_run", login);
-
- /* setup euid/egid to the correct user,
- * not to leave the egid around. It's
- * ok to gdm_fail here */
- NEVER_FAILS_root_set_euid_egid (pwent->pw_uid, pwent->pw_gid);
-
- VE_IGNORE_EINTR (result = g_chdir (home_dir));
- if G_UNLIKELY (result != 0) {
- VE_IGNORE_EINTR (g_chdir ("/"));
- NEVER_FAILS_root_set_euid_egid (0, 0);
- } else if (pwent->pw_uid != 0) {
- /* sanitize .ICEauthority to be of the correct
- * permissions, if it exists */
- struct stat s0, s1, s2;
- gint s0_ret, s1_ret, s2_ret;
- gint iceauth_fd;
-
- 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 &&
- s1_ret == 0 &&
- s2_ret == 0 &&
- S_ISREG (s1.st_mode) &&
- s1.st_ino == s2.st_ino &&
- s1.st_dev == s2.st_dev &&
- s1.st_uid == s2.st_uid &&
- s1.st_gid == s2.st_gid &&
- s1.st_mode == s2.st_mode &&
- (s1.st_uid != pwent->pw_uid ||
- s1.st_gid != pwent->pw_gid ||
- (s1.st_mode & (S_IRWXG|S_IRWXO)) ||
- !(s1.st_mode & S_IRWXU))) {
- /* This may not work on NFS, but oh well, there
- * this is beyond our help, but it's unlikely
- * that it got screwed up when NFS was used
- * in the first place */
-
- /* only if we own the current directory */
- fchown (iceauth_fd,
- pwent->pw_uid,
- pwent->pw_gid);
- fchmod (iceauth_fd, S_IRUSR | S_IWUSR);
- }
-
- if (iceauth_fd >= 0)
- close (iceauth_fd);
- }
-
- NEVER_FAILS_setegid (pwent->pw_gid);
-#ifdef HAVE_LOGINCAP
- if (setusercontext (NULL, pwent, pwent->pw_uid,
- LOGIN_SETLOGIN | LOGIN_SETPATH |
- LOGIN_SETPRIORITY | LOGIN_SETRESOURCES |
- LOGIN_SETUMASK | LOGIN_SETUSER |
- LOGIN_SETENV) < 0)
- gdm_child_exit (DISPLAY_REMANAGE,
- _("%s: setusercontext () failed for %s. "
- "Aborting."), "session_child_run",
- login);
-#else
- if G_UNLIKELY (setuid (pwent->pw_uid) < 0)
- gdm_child_exit (DISPLAY_REMANAGE,
- _("%s: Could not become %s. Aborting."), "session_child_run", login);
-#endif
-
- /* Only force GDM_LANG to something if there is other then
- * system default selected. Else let the session do whatever it
- * does since we're using sys default */
- if ( ! ve_string_empty (language)) {
- g_setenv ("LANG", language, TRUE);
- g_setenv ("GDM_LANG", language, TRUE);
- }
-
- /* 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);
-
- gdm_log_shutdown ();
-
- gdm_close_all_descriptors (3 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */);
-
- gdm_log_init ();
-
- sessionexec = NULL;
- if (strcmp (session, GDM_SESSION_FAILSAFE_XTERM) != 0 &&
- strcmp (session, GDM_SESSION_FAILSAFE_GNOME) != 0) {
-
- sessionexec = gdm_daemon_config_get_session_exec (session,
- FALSE /* check_try_exec */);
-
- if G_UNLIKELY (sessionexec == NULL) {
- gchar *msg = g_strdup_printf (
- _("No Exec line in the session file: %s. Running the GNOME failsafe session instead"),
- session);
-
- gdm_error (_("%s: %s"), "session_child_run", msg);
- gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR, msg);
- g_free (msg);
-
- session = GDM_SESSION_FAILSAFE_GNOME;
- } else {
- /* HACK!, if failsafe, we really wish to run the
- internal one */
- if (strcmp (sessionexec, "failsafe") == 0) {
- session = GDM_SESSION_FAILSAFE_XTERM;
- sessionexec = NULL;
- }
- }
- }
-
- fullexec = g_string_new (NULL);
-
-#ifdef HAVE_CTRUN
- g_string_append (fullexec, "/usr/bin/ctrun -l child -i none ");
-#endif
-
- if (sessionexec != NULL) {
- const char *basexsession = gdm_daemon_config_get_value_string (GDM_KEY_BASE_XSESSION);
-
- /* cannot be possibly failsafe */
- if G_UNLIKELY (g_access (basexsession, X_OK) != 0) {
- gdm_error (_("%s: Cannot find or run the base Xsession script. Running the GNOME failsafe session instead."),
- "session_child_run");
- session = GDM_SESSION_FAILSAFE_GNOME;
- sessionexec = NULL;
- gdm_errorgui_error_box
- (d, GTK_MESSAGE_ERROR,
- _("Cannot find or run the base session script. Running the GNOME failsafe session instead."));
- } else {
- /*
- * This is where the session is OK, and note that
- * we really DON'T care about leaks, we are going to
- * exec in just a bit
- */
- g_string_append (fullexec, basexsession);
- g_string_append (fullexec, " ");
-
-#ifdef HAVE_TSOL
- if (have_suntsol_extension)
- g_string_append (fullexec, "/usr/bin/tsoljdslabel ");
-#endif
- g_string_append (fullexec, sessionexec);
- }
- }
-
- if (strcmp (session, GDM_SESSION_FAILSAFE_GNOME) == 0) {
- gchar *test_exec = NULL;
-
-#ifdef HAVE_TSOL
- /*
- * Trusted Path will be preserved as long as the sys admin
- * doesn't put anything stupid in gdm.conf
- */
- if (have_suntsol_extension == TRUE)
- g_string_append (fullexec, "/usr/bin/tsoljdslabel ");
-#endif
-
- test_exec = find_prog ("gnome-session");
- if G_UNLIKELY (test_exec == 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, "
- "will try running the \"Failsafe xterm\" "
- "session."));
- } else {
- g_string_append (fullexec, test_exec);
- g_string_append (fullexec, " --failsafe");
- 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."));
- }
- failsafe = TRUE;
- }
-
- /* This is an if and not an else, we could have done a fall-through
- * to here in the above code if we can't find gnome-session */
- if (strcmp (session, GDM_SESSION_FAILSAFE_XTERM) == 0) {
- gchar *test_exec;
- gchar *geometry = g_strdup_printf (" -geometry 80x24-%d-%d",
- d->lrh_offsetx,
- d->lrh_offsety);
- test_exec = find_prog ("xterm");
- if (test_exec == NULL) {
- gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR,
- _("Cannot find \"xterm\" to start "
- "a failsafe session."));
- /* nyah nyah nyah nyah nyah */
- /* 66 means no "session crashed" examine .xsession-errors dialog */
- _exit (66);
- } else {
- gchar *failsafe_msg = NULL;
- g_string_append (fullexec, test_exec);
- g_string_append (fullexec, geometry);
-
- failsafe_msg = _("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.");
-#ifdef HAVE_TSOL
- if (have_suntsol_extension) {
- /*
- * In a Solaris Trusted Extensions environment, failsafe
- * xterms should be restricted to the root user, or
- * users who have the root role. This is necessary to
- * prevent normal users and evil terrorists bypassing
- * their assigned clearance and getting direct access
- * to the global zone.
- */
- if (pwent->pw_uid != 0 &&
- gdm_can_i_assume_root_role (pwent) == TRUE) {
- g_string_append (fullexec, " -C -e su");
- failsafe_msg = _("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.");
- } else {
- /* Normal user without root role - get lost */
- 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"));
- _exit (66);
- }
- }
-#endif /* HAVE_TSOL */
-
- gdm_errorgui_error_box (d, GTK_MESSAGE_INFO, failsafe_msg);
- focus_first_x_window ("xterm");
- }
- g_free (geometry);
- failsafe = TRUE;
- }
-
- gdm_debug ("Running %s for %s on %s", fullexec->str, login, d->name);
-
- if ( ! ve_string_empty (pwent->pw_shell)) {
- shell = pwent->pw_shell;
- } else {
- shell = "/bin/sh";
- }
-
- /* just a stupid test */
- if (strcmp (shell, "/sbin/nologin") == 0 ||
- strcmp (shell, "/bin/false") == 0 ||
- strcmp (shell, "/bin/true") == 0) {
- gdm_error (_("%s: User not allowed to log in"),
- "session_child_run");
- gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR,
- _("The system administrator has "
- "disabled your account."));
- /* ends as if nothing bad happened */
- /* 66 means no "session crashed" examine .xsession-errors
- dialog */
- _exit (66);
- }
-
-#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]);
- char *p = strchr (env_str, '=');
- if (p != NULL) {
- /* Add a NULL byte to terminate the variable name */
- p[0] = '\0';
- /* Add the variable to the env */
- g_setenv (env_str, &p[1], TRUE);
- }
- g_free (env_str);
- }
-#endif
-
-#ifdef HAVE_SELINUX
- if ( ! gdm_selinux_setup (pwent->pw_name)) {
- /* 66 means no "session crashed" examine .xsession-errors
- dialog */
- gdm_errorgui_error_box (d, GTK_MESSAGE_ERROR,
- _("Error! Unable to set executable context."));
- _exit (66);
- }
-#endif
-
- g_shell_parse_argv (fullexec->str, NULL, &argv, NULL);
- VE_IGNORE_EINTR (execv (argv[0], argv));
- g_strfreev (argv);
-
- /* will go to .xsession-errors */
- fprintf (stderr, _("%s: Could not exec %s"),
- "session_child_run", fullexec->str);
- gdm_error ( _("%s: Could not exec %s"),
- "session_child_run", fullexec->str);
- g_string_free (fullexec, TRUE);
-
- /* if we can't read and exec the session, then make a nice
- * error dialog */
- 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);
-}
-
-static void
-finish_session_output (gboolean do_read)
-{
- if G_LIKELY (d->session_output_fd >= 0) {
- if (do_read)
- run_session_output (TRUE /* read_until_eof */);
- if (d->session_output_fd >= 0) {
- VE_IGNORE_EINTR (close (d->session_output_fd));
- d->session_output_fd = -1;
- }
- if (d->xsession_errors_fd >= 0) {
- VE_IGNORE_EINTR (close (d->xsession_errors_fd));
- d->xsession_errors_fd = -1;
- }
- }
-}
-
-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;
-#ifdef WITH_CONSOLE_KIT
- 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
- */
- 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);
-
- /*
- * If the desktop file specifies that there are special Xserver
- * arguments to use, then restart the Xserver with them.
- */
- d->xserver_session_args = gdm_daemon_config_get_session_xserver_args (session);
- if (d->xserver_session_args) {
- gdm_server_stop (d);
- gdm_slave_send_num (GDM_SOP_XPID, 0);
- gdm_server_start (d, TRUE, FALSE, 20, 5);
- gdm_slave_send_num (GDM_SOP_XPID, d->servpid);
- g_free (d->xserver_session_args);
- d->xserver_session_args = NULL;
- }
-
- /* 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);
-#endif
-
- 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 *lang;
- gboolean has_language;
-
- has_language = (language != NULL) && (language[0] != '\0');
-
- 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,
-#endif
- session,
- save_session,
- lang,
- gnome_session,
- usrcfgok,
- savesess,
- savelang);
- g_assert_not_reached ();
- }
-
- default:
- always_restart_greeter = FALSE;
- if (!savelang && language && strcmp (usrlang, language)) {
- 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);
- }
- 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 "
- "some installation problem or that you may "
- "be out of diskspace. Try logging in with "
- "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);
-
- gdm_slave_send_string (GDM_SOP_SHOW_ERROR_DIALOG, 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);
- }
-#endif
-
- 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)");
-}
-
-
-/* Stop any in progress sessions */
-static void
-gdm_slave_session_stop (gboolean run_post_session,
- gboolean no_shutdown_check)
-{
- struct passwd *pwent;
- char *x_servers_file;
- char *local_login;
-
- in_session_stop++;
-
- session_started = FALSE;
-
- 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);
-
- 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));
- }
-
- 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 ();
-
- finish_session_output (run_post_session /* do_read */);
-
- 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");
-
- /* 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);
-
- 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);
- }
-
- /* 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;
-
- /* things are going to be killed, so ignore errors */
- XSetErrorHandler (ignore_xerror_handler);
-
- gdm_verify_cleanup (d);
-
- in_session_stop --;
-
- if (need_to_quit_after_session_stop) {
- gdm_debug ("gdm_slave_session_stop: Final cleanup");
-
- 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) {
- 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__ */
-}
-
-static void
-gdm_slave_term_handler (int sig)
-{
- static gboolean got_term_before = FALSE;
-
- gdm_in_signal++;
- gdm_wait_for_ack = FALSE;
-
- exit_code_to_use = DISPLAY_ABORT;
- need_to_quit_after_session_stop = TRUE;
-
- if (already_in_slave_start_jmp ||
- (got_term_before && in_session_stop > 0)) {
- gdm_sigchld_block_push ();
- /* be very very very nasty to the extra process if the user is really
- trying to get rid of us */
- if (extra_process > 1)
- kill (-(extra_process), SIGKILL);
- /* also be very nasty to the X server at this stage */
- if (d->servpid > 1)
- kill (d->servpid, SIGKILL);
- gdm_sigchld_block_pop ();
- gdm_in_signal--;
- got_term_before = TRUE;
- /* we're already quitting, just a matter of killing all the processes */
- return;
- }
- got_term_before = TRUE;
-
- /* just in case this was set to something else, like during
- * server reinit */
- XSetIOErrorHandler (gdm_slave_xioerror_handler);
-
- if (in_session_stop > 0) {
- /* the need_to_quit_after_session_stop is now set so things will
- work out right */
- gdm_in_signal--;
- return;
- }
-
- if (session_started) {
- SIGNAL_EXIT_WITH_JMP (d, JMP_SESSION_STOP_AND_QUIT);
- } else {
- SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
- }
-
- /* never reached */
- gdm_in_signal--;
-}
-
-/* called on alarms to ping */
-static void
-gdm_slave_alrm_handler (int sig)
-{
- static gboolean in_ping = FALSE;
-
- if G_UNLIKELY (already_in_slave_start_jmp)
- return;
-
- gdm_in_signal++;
-
- if G_UNLIKELY (d->dsp == NULL) {
- gdm_in_signal --;
- /* huh? */
- return;
- }
-
- if G_UNLIKELY (in_ping) {
- need_to_quit_after_session_stop = TRUE;
- exit_code_to_use = DISPLAY_REMANAGE;
-
- if (session_started) {
- SIGNAL_EXIT_WITH_JMP (d, JMP_SESSION_STOP_AND_QUIT);
- } else {
- SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
- }
- }
-
- in_ping = TRUE;
-
- /* schedule next alarm */
- alarm (gdm_daemon_config_get_value_int (GDM_KEY_PING_INTERVAL));
-
- XSync (d->dsp, True);
-
- in_ping = FALSE;
-
- gdm_in_signal --;
-}
-
-/* Called on every SIGCHLD */
-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));
- }
- }
- }
-
- 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);
-
- do_restart_greeter = TRUE;
- if (restart_greeter_now) {
- slave_waitpid_notify ();
- } else {
- interrupted = TRUE;
- }
- continue;
- }
-
- 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;
- 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 ();
-
- 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);
- }
-
- /* 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);
-
- gdm_in_signal--;
-}
-
-static void
-gdm_slave_handle_usr2_message (void)
-{
- char buf[256];
- ssize_t count;
- char **vec;
- int i;
-
- VE_IGNORE_EINTR (count = read (d->slave_notify_fd, buf, sizeof (buf) -1));
- if (count <= 0) {
- return;
- }
-
- buf[count] = '\0';
-
- vec = g_strsplit (buf, "\n", -1);
- if (vec == NULL) {
- return;
- }
-
- for (i = 0; vec[i] != NULL; i++) {
- char *s = vec[i];
- if (s[0] == GDM_SLAVE_NOTIFY_ACK) {
- gdm_got_ack = TRUE;
- g_free (gdm_ack_response);
- if (s[1] != '\0')
- gdm_ack_response = g_strdup (&s[1]);
- else
- gdm_ack_response = NULL;
- } else if (s[0] == GDM_SLAVE_NOTIFY_KEY) {
- slave_waitpid_notify ();
- unhandled_notifies =
- g_list_append (unhandled_notifies,
- g_strdup (&s[1]));
- } else if (s[0] == GDM_SLAVE_NOTIFY_COMMAND) {
- if (strcmp (&s[1], GDM_NOTIFY_DIRTY_SERVERS) == 0) {
- /* never restart flexi servers
- * they whack themselves */
- if (!SERVER_IS_FLEXI (d))
- remanage_asap = TRUE;
- } else if (strcmp (&s[1], GDM_NOTIFY_SOFT_RESTART_SERVERS) == 0) {
- /* never restart flexi servers,
- * they whack themselves */
- /* FIXME: here we should handle actual
- * restarts of flexi servers, but it probably
- * doesn't matter */
- if (!SERVER_IS_FLEXI (d)) {
- if ( ! d->logged_in) {
- if (gdm_in_signal > 0) {
- exit_code_to_use = DISPLAY_REMANAGE;
- SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
- } else {
- /* FIXME: are we ever not in signal here? */
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- }
- } else {
- remanage_asap = TRUE;
- }
- }
- } else if (strcmp (&s[1], GDM_NOTIFY_GO) == 0) {
- gdm_wait_for_go = FALSE;
- } else if (strcmp (&s[1], GDM_NOTIFY_TWIDDLE_POINTER) == 0) {
- gdm_twiddle_pointer (d);
- }
- } else if (s[0] == GDM_SLAVE_NOTIFY_RESPONSE) {
- gdm_got_ack = TRUE;
- if (gdm_ack_response)
- g_free (gdm_ack_response);
-
- if (s[1] == GDM_SLAVE_NOTIFY_YESNO_RESPONSE) {
- if (s[2] == '0') {
- gdm_ack_response = g_strdup ("no");
- } else {
- gdm_ack_response = g_strdup ("yes");
- }
- } else if (s[1] == GDM_SLAVE_NOTIFY_ASKBUTTONS_RESPONSE) {
- gdm_ack_response = g_strdup (&s[2]);
- } else if (s[1] == GDM_SLAVE_NOTIFY_QUESTION_RESPONSE) {
- gdm_ack_question_response = g_strdup (&s[2]);
- } else if (s[1] == GDM_SLAVE_NOTIFY_ERROR_RESPONSE) {
- if (s[2] != '\0') {
- gdm_ack_response = g_strdup (&s[2]);
- } else {
- gdm_ack_response = NULL;
- }
- }
- }
- }
-
- g_strfreev (vec);
-}
-
-static void
-gdm_slave_usr2_handler (int sig)
-{
- gdm_in_signal++;
- in_usr2_signal++;
-
- gdm_slave_handle_usr2_message ();
-
- in_usr2_signal--;
- gdm_in_signal--;
-}
-
-/* Minor X faults */
-static gint
-gdm_slave_xerror_handler (Display *disp, XErrorEvent *evt)
-{
- gdm_debug ("gdm_slave_xerror_handler: X error - display doesn't respond");
- return (0);
-}
-
-/* We usually respond to fatal errors by restarting the display */
-static gint
-gdm_slave_xioerror_handler (Display *disp)
-{
- if (already_in_slave_start_jmp) {
- /* eki eki eki, this is not good,
- should only happen if we get some io error after
- we have gotten a SIGTERM */
- SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
- }
-
- gdm_in_signal++;
-
- /* Display is all gone */
- d->dsp = NULL;
-
- if ((d->type == TYPE_STATIC ||
- d->type == TYPE_FLEXI) &&
- (do_xfailed_on_xio_error ||
- d->starttime + 5 >= time (NULL))) {
- exit_code_to_use = DISPLAY_XFAILED;
- } else {
- exit_code_to_use = DISPLAY_REMANAGE;
- }
-
- slave_start_jmp_error_to_print =
- g_strdup_printf (_("%s: Fatal X error - Restarting %s"),
- "gdm_slave_xioerror_handler", d->name);
-
- need_to_quit_after_session_stop = TRUE;
-
- if (session_started) {
- SIGNAL_EXIT_WITH_JMP (d, JMP_SESSION_STOP_AND_QUIT);
- } else {
- SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
- }
-
- /* never reached */
- gdm_in_signal--;
-
- return 0;
-}
-
-/* return true for "there was an interruption received",
- and interrupted will be TRUE if we are actually interrupted from doing what
- we want. If FALSE is returned, just continue on as we would normally */
-static gboolean
-check_for_interruption (const char *msg)
-{
- /* Hell yeah we were interrupted, the greeter died */
- if (msg == NULL) {
- interrupted = TRUE;
- return TRUE;
- }
-
- if (msg[0] == BEL) {
- /* Different interruptions come here */
- /* Note that we don't want to actually do anything. We want
- * to just set some flag and go on and schedule it after we
- * dump out of the login in the main login checking loop */
- switch (msg[1]) {
- case GDM_INTERRUPT_TIMED_LOGIN:
- /* only allow timed login if display is local,
- * 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))
- && d->timed_login_ok &&
- ! ve_string_empty (ParsedTimedLogin) &&
- strcmp (ParsedTimedLogin, gdm_root_user ()) != 0 &&
- gdm_daemon_config_get_value_int (GDM_KEY_TIMED_LOGIN_DELAY) > 0) {
- do_timed_login = TRUE;
- }
- break;
- case GDM_INTERRUPT_CONFIGURE:
- if (d->attached &&
- gdm_daemon_config_get_value_bool_per_display (GDM_KEY_CONFIG_AVAILABLE, d->name) &&
- gdm_daemon_config_get_value_bool_per_display (GDM_KEY_SYSTEM_MENU, d->name) &&
- ! ve_string_empty (gdm_daemon_config_get_value_string (GDM_KEY_CONFIGURATOR))) {
- do_configurator = TRUE;
- }
- break;
- case GDM_INTERRUPT_SUSPEND:
- if (d->attached &&
- gdm_daemon_config_get_value_bool_per_display (GDM_KEY_SYSTEM_MENU, d->name) &&
- ! 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_slave_send (msg, FALSE /* wait_for_ack */);
- g_free (msg);
- }
- /* Not interrupted, continue reading input,
- * just proxy this to the master server */
- return TRUE;
- case GDM_INTERRUPT_LOGIN_SOUND:
- if (d->attached &&
- ! play_login_sound (gdm_daemon_config_get_value_string (GDM_KEY_SOUND_ON_LOGIN_FILE))) {
- gdm_error (_("Login sound requested on non-local display or the play software "
- "cannot be run or the sound does not exist"));
- }
- return TRUE;
- case GDM_INTERRUPT_SELECT_USER:
- gdm_verify_select_user (&msg[2]);
- break;
- case GDM_INTERRUPT_CANCEL:
- do_cancel = TRUE;
- break;
- case GDM_INTERRUPT_CUSTOM_CMD:
- 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_slave_send (message, TRUE);
- g_free (message);
- }
- return TRUE;
- case GDM_INTERRUPT_THEME:
- g_free (d->theme_name);
- d->theme_name = NULL;
- if ( ! ve_string_empty (&msg[2]))
- d->theme_name = g_strdup (&msg[2]);
- gdm_slave_send_string (GDM_SOP_CHOSEN_THEME, &msg[2]);
- return TRUE;
- case GDM_INTERRUPT_SELECT_LANG:
- if (msg + 2) {
- 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));
- 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");
- g_unsetenv ("LC_MESSAGES");
- setlocale (LC_ALL, "");
- setlocale (LC_MESSAGES, "");
- gdm_saveenv ();
-
- do_restart_greeter = TRUE;
- }
- break;
- default:
- break;
- }
-
- /* this was an interruption, if it wasn't
- * handled then the user will just get an error as if he
- * entered an invalid login or passward. Seriously BEL
- * cannot be part of a login/password really */
- interrupted = TRUE;
- return TRUE;
- }
- return FALSE;
-}
-
-
-char *
-gdm_slave_greeter_ctl (char cmd, const char *str)
-{
- char *buf = NULL;
- int c;
-
- /* There is no spoon^H^H^H^H^Hgreeter */
- if G_UNLIKELY ( ! greet)
- return NULL;
-
- 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 defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_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;
- }
-}
-
-void
-gdm_slave_greeter_ctl_no_ret (char cmd, const char *str)
-{
- g_free (gdm_slave_greeter_ctl (cmd, str));
-}
-
-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);
-
- 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;
-
- /* No need to send the PIDS to the daemon
- * since we'll just exit cleanly */
-
- /* Push and never pop */
- gdm_sigchld_block_push ();
-
- /* 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->sesspid > 1)
- kill (-(d->sesspid), SIGTERM);
- d->sesspid = 0;
-
- if (extra_process > 1)
- kill (-(extra_process), SIGTERM);
- extra_process = 0;
-
- gdm_verify_cleanup (d);
- gdm_server_stop (d);
-
- if (d->servpid > 1)
- kill (d->servpid, SIGTERM);
- d->servpid = 0;
-
- gdm_debug ("gdm_slave_quick_exit: Killed everything from the display");
- }
-
- _exit (status);
-}
-
-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);
-}
-
-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);
-
- g_error ("%s", s);
-
- g_free (s);
-
- _exit (status);
-}
-
-void
-gdm_slave_whack_temp_auth_file (void)
-{
- uid_t old;
-
- old = geteuid ();
- if (old != 0)
- seteuid (0);
- if (d->parent_temp_auth_file != NULL) {
- VE_IGNORE_EINTR (g_unlink (d->parent_temp_auth_file));
- }
- g_free (d->parent_temp_auth_file);
- d->parent_temp_auth_file = NULL;
- if (old != 0)
- seteuid (old);
-}
-
-static void
-create_temp_auth_file (void)
-{
- if (d->type == TYPE_FLEXI_XNEST &&
- d->parent_auth_file != NULL) {
- if (d->parent_temp_auth_file != NULL) {
- VE_IGNORE_EINTR (g_unlink (d->parent_temp_auth_file));
- }
- g_free (d->parent_temp_auth_file);
- d->parent_temp_auth_file =
- copy_auth_file (d->server_uid,
- gdm_daemon_config_get_gdmuid (),
- d->parent_auth_file);
- }
-}
-
-static void
-set_xnest_parent_stuff (void)
-{
- if (d->type == TYPE_FLEXI_XNEST) {
- 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);
- g_free (d->parent_temp_auth_file);
- d->parent_temp_auth_file = NULL;
- }
- }
-}
-
-static gint
-gdm_slave_exec_script (GdmDisplay *d,
- const gchar *dir,
- const char *login,
- struct passwd *pwent,
- gboolean pass_stdout)
-{
- pid_t pid;
- char *script;
- char *ctrun;
- gchar **argv = NULL;
- 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 ();
-
- g_debug ("Forking extra process: %s", script);
-
- 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 {
- 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);
- }
-
- 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);
-
- /* 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);
-
-#ifdef HAVE_CTRUN
- ctrun = g_strdup_printf (
- "/bin/sh -c \"/usr/bin/ctrun -l child -i none %s\"",
- script);
- g_shell_parse_argv (ctrun, NULL, &argv, NULL);
- g_free (ctrun);
-#else
- g_shell_parse_argv (script, NULL, &argv, NULL);
-#endif
-
- VE_IGNORE_EINTR (execv (argv[0], argv));
- g_strfreev (argv);
- g_error (_("%s: Failed starting: %s"),
- "gdm_slave_exec_script",
- script);
- _exit (EXIT_SUCCESS);
-
- 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;
-
- default:
- gdm_wait_for_extra (extra_process, &status);
-
- gdm_slave_whack_temp_auth_file ();
-
- g_free (script);
-
- if (WIFEXITED (status))
- return WEXITSTATUS (status);
- else
- return EXIT_SUCCESS;
- }
-}
-
-gboolean
-gdm_slave_greeter_check_interruption (void)
-{
- if (interrupted) {
- /* no longer interrupted */
- interrupted = FALSE;
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-gboolean
-gdm_slave_action_pending (void)
-{
- if (do_timed_login ||
- do_configurator ||
- do_restart_greeter ||
- do_cancel)
- return FALSE;
- return TRUE;
-}
-
-/* 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 = NULL;
- pid_t pid;
-
- if (s == NULL)
- return (NULL);
-
- str = g_string_new (NULL);
-
- while (s[0] != '\0') {
-
- if (s[0] == '%' && s[1] != 0) {
- cmd = s[1];
- s++;
-
- switch (cmd) {
-
- case 'h':
- g_string_append (str, display->hostname);
- break;
-
- case 'd':
- g_string_append (str, display->name);
- break;
-
- case '%':
- g_string_append_c (str, '%');
- break;
-
- 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 {
- g_debug ("Forking extra process: %s", str->str);
-
- extra_process = 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));
- }
-
- 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_shell_parse_argv (str->str, NULL, &argv, NULL);
-
- VE_IGNORE_EINTR (execv (argv[0], argv));
- g_strfreev (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
-gdm_slave_handle_notify (const char *msg)
-{
- int val;
-
- gdm_debug ("Handling slave notify: '%s'", msg);
-
- if (sscanf (msg, GDM_NOTIFY_ALLOW_ROOT " %d", &val) == 1) {
- gdm_daemon_config_set_value_bool (GDM_KEY_ALLOW_ROOT, val);
- } else if (sscanf (msg, GDM_NOTIFY_ALLOW_REMOTE_ROOT " %d", &val) == 1) {
- gdm_daemon_config_set_value_bool (GDM_KEY_ALLOW_REMOTE_ROOT, val);
- } else if (sscanf (msg, GDM_NOTIFY_ALLOW_REMOTE_AUTOLOGIN " %d", &val) == 1) {
- gdm_daemon_config_set_value_bool (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN, val);
- } else if (sscanf (msg, GDM_NOTIFY_SYSTEM_MENU " %d", &val) == 1) {
- gdm_daemon_config_set_value_bool (GDM_KEY_SYSTEM_MENU, val);
- if (d->greetpid > 1)
- kill (d->greetpid, SIGHUP);
- } else if (sscanf (msg, GDM_NOTIFY_CONFIG_AVAILABLE " %d", &val) == 1) {
- gdm_daemon_config_set_value_bool (GDM_KEY_CONFIG_AVAILABLE, val);
- if (d->greetpid > 1)
- kill (d->greetpid, SIGHUP);
- } else if (sscanf (msg, GDM_NOTIFY_CHOOSER_BUTTON " %d", &val) == 1) {
- gdm_daemon_config_set_value_bool (GDM_KEY_CHOOSER_BUTTON, val);
- if (d->greetpid > 1)
- kill (d->greetpid, SIGHUP);
- } else if (sscanf (msg, GDM_NOTIFY_RETRY_DELAY " %d", &val) == 1) {
- gdm_daemon_config_set_value_int (GDM_KEY_RETRY_DELAY, val);
- } else if (sscanf (msg, GDM_NOTIFY_DISALLOW_TCP " %d", &val) == 1) {
- gdm_daemon_config_set_value_bool (GDM_KEY_DISALLOW_TCP, val);
- remanage_asap = TRUE;
- } else if (strncmp (msg, GDM_NOTIFY_GREETER " ",
- strlen (GDM_NOTIFY_GREETER) + 1) == 0) {
- gdm_daemon_config_set_value_string (GDM_KEY_GREETER, ((gchar *)&msg[strlen (GDM_NOTIFY_GREETER) + 1]));
-
- if (d->attached) {
- do_restart_greeter = TRUE;
- if (restart_greeter_now) {
- ; /* will get restarted later */
- } else if (d->type == TYPE_STATIC) {
- /* FIXME: can't handle flexi servers like this
- * without going all cranky */
- if ( ! d->logged_in) {
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- } else {
- remanage_asap = TRUE;
- }
- }
- }
- } else if (strncmp (msg, GDM_NOTIFY_CUSTOM_CMD_TEMPLATE,
- 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
- 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);
-
- if (d->attached) {
- do_restart_greeter = TRUE;
- if (restart_greeter_now) {
- ; /* will get restarted later */
- } else if (d->type == TYPE_STATIC) {
- /* FIXME: can't handle flexi servers like this
- * without going all cranky */
- if ( ! d->logged_in) {
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- } else {
- remanage_asap = TRUE;
- }
- }
- }
- }
- } 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]));
- if ( ! d->attached) {
- do_restart_greeter = TRUE;
- if (restart_greeter_now) {
- ; /* will get restarted later */
- } else if (d->type == TYPE_XDMCP) {
- /* FIXME: can't handle flexi servers like this
- * without going all cranky */
- if ( ! d->logged_in) {
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- } else {
- remanage_asap = TRUE;
- }
- }
- }
- } else if ((strncmp (msg, GDM_NOTIFY_TIMED_LOGIN " ",
- strlen (GDM_NOTIFY_TIMED_LOGIN) + 1) == 0) ||
- (strncmp (msg, GDM_NOTIFY_TIMED_LOGIN_DELAY " ",
- strlen (GDM_NOTIFY_TIMED_LOGIN_DELAY) + 1) == 0) ||
- (strncmp (msg, GDM_NOTIFY_TIMED_LOGIN_ENABLE " ",
- strlen (GDM_NOTIFY_TIMED_LOGIN_ENABLE) + 1) == 0)) {
- do_restart_greeter = TRUE;
- /* FIXME: this is fairly nasty, we should handle this nicer */
- /* FIXME: can't handle flexi servers without going all cranky */
- if (d->type == TYPE_STATIC || d->type == TYPE_XDMCP) {
- if ( ! d->logged_in) {
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- } else {
- remanage_asap = TRUE;
- }
- }
- } 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]));
- 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]));
- 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]));
- 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]));
-
- if (gdm_daemon_config_get_value_bool (GDM_KEY_ADD_GTK_MODULES)) {
- do_restart_greeter = TRUE;
- if (restart_greeter_now) {
- ; /* will get restarted later */
- } else if (d->type == TYPE_STATIC) {
- /* FIXME: can't handle flexi servers like this
- * without going all cranky */
- if ( ! d->logged_in) {
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- } else {
- remanage_asap = TRUE;
- }
- }
- }
- } else if (sscanf (msg, GDM_NOTIFY_ADD_GTK_MODULES " %d", &val) == 1) {
- gdm_daemon_config_set_value_bool (GDM_KEY_ADD_GTK_MODULES, val);
-
- do_restart_greeter = TRUE;
- if (restart_greeter_now) {
- ; /* will get restarted later */
- } else if (d->type == TYPE_STATIC) {
- /* FIXME: can't handle flexi servers like this
- * without going all cranky */
- if ( ! d->logged_in) {
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
- } else {
- remanage_asap = TRUE;
- }
- }
- }
-}
-
-/* do cleanup but only if we are a slave, if we're not a slave, just
- * return FALSE */
-gboolean
-gdm_slave_final_cleanup (void)
-{
- if (getpid () != d->slavepid)
- return FALSE;
- gdm_debug ("slave killing self");
- gdm_slave_term_handler (SIGTERM);
- return TRUE;
-}
-
-#ifdef HAVE_TSOL
-static gboolean
-gdm_can_i_assume_root_role (struct passwd *pwent)
-{
- userattr_t *uattr = NULL;
- char *freeroles = NULL;
- char *roles = NULL;
- char *role = NULL;
-
- uattr = getuseruid (pwent->pw_uid);
- if G_UNLIKELY (uattr == NULL)
- return FALSE;
-
- freeroles = roles = g_strdup (kva_match (uattr->attr, USERATTR_ROLES_KW));
- if (roles == NULL) {
- return FALSE;
- }
-
- while ((role = strtok (roles, ",")) != NULL) {
- roles = NULL;
- if (!strncmp (role, "root", 4)) {
- g_free (freeroles);
- g_free (role);
- return TRUE;
- }
- }
- g_free (freeroles);
- g_free (role);
- return FALSE;
-}
-#endif /* HAVE_TSOL */
-
-
-/* gdm_is_user_valid() mostly copied from gui/gdmuser.c */
-gboolean
-gdm_is_user_valid (const char *username)
-{
- return (NULL != getpwnam (username));
-}
diff --git a/daemon/slave.h b/daemon/slave.h
deleted file mode 100644
index 1f1599e0..00000000
--- a/daemon/slave.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef GDM_SLAVE_H
-#define GDM_SLAVE_H
-
-#include <glib.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);
-char *gdm_slave_greeter_ctl (char cmd, const char *str);
-gboolean gdm_slave_greeter_check_interruption (void);
-gboolean gdm_slave_action_pending (void);
-
-void gdm_slave_send (const char *str, gboolean wait_for_ack);
-void gdm_slave_send_num (const char *opcode, long num);
-void gdm_slave_send_string (const char *opcode, const char *str);
-gboolean gdm_slave_final_cleanup (void);
-
-void gdm_slave_whack_temp_auth_file (void);
-
-gboolean gdm_slave_check_user_wants_to_log_in (const char *user);
-gboolean gdm_is_session_magic (const char *session_name);
-
-/* This is the slave child handler so that we can chain to it from elsewhere */
-void gdm_slave_child_handler (int sig);
-
-#endif /* GDM_SLAVE_H */
-
-/* EOF */
-
diff --git a/daemon/verify-crypt.c b/daemon/verify-crypt.c
deleted file mode 100644
index baf9fc56..00000000
--- a/daemon/verify-crypt.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * GDM - The GNOME Display Manager
- * Copyright (C) 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "config.h"
-
-#include <glib/gi18n.h>
-#include <pwd.h>
-#include <grp.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <string.h>
-
-#if defined (CAN_CLEAR_ADMCHG) && defined (HAVE_USERSEC_H)
-# include <usersec.h>
-#endif /* CAN_CLEAR_ADMCHG && HAVE_USERSEC_H */
-
-#ifdef HAVE_CRYPT
-# include <crypt.h>
-#endif /* HAVE_CRYPT */
-
-#include "gdm.h"
-#include "misc.h"
-#include "slave.h"
-#include "verify.h"
-#include "errorgui.h"
-#include "gdm-common.h"
-#include "gdm-daemon-config.h"
-#include "gdm-socket-protocol.h"
-
-static char *selected_user = NULL;
-
-void
-gdm_verify_select_user (const char *user)
-{
- g_free (selected_user);
- if (ve_string_empty (user))
- selected_user = NULL;
- else
- selected_user = g_strdup (user);
-}
-
-static void
-print_cant_auth_errbox (void)
-{
- gboolean is_capslock = FALSE;
- const char *basemsg;
- char *msg;
- char *ret;
-
- ret = gdm_slave_greeter_ctl (GDM_QUERY_CAPSLOCK, "");
- if ( ! ve_string_empty (ret))
- is_capslock = TRUE;
- g_free (ret);
-
- basemsg = _("\nIncorrect username or password. "
- "Letters must be typed in the correct "
- "case.");
- if (is_capslock) {
- msg = g_strconcat (basemsg, " ",
- _("Caps Lock is on."),
- NULL);
- } else {
- msg = g_strdup (basemsg);
- }
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX, msg);
- g_free (msg);
-}
-
-/**
- * gdm_verify_user:
- * @username: Name of user or NULL if we should ask
- * @display: Name of display to register with the authentication system
- * @local: boolean if local
- * @allow_retry: boolean. Not used by verify-crypt. If this code
- * allowed the user to retry, this boolean would specify
- * whether to enable this feature. We only want this
- * feature to work for normal login, not for asking for
- * root password to call the configurator.
- *
- * Provides a communication layer between the operating system's
- * authentication functions and the gdmgreeter.
- *
- * Returns the user's login on success and NULL on failure.
- */
-
-gchar *
-gdm_verify_user (GdmDisplay *d,
- const char *username,
- const gchar *display,
- gboolean local,
- gboolean allow_retry)
-{
- gchar *login, *passwd, *ppasswd;
- struct passwd *pwent;
-#if defined (HAVE_PASSWDEXPIRED) && defined (HAVE_CHPASS) \
- || defined (HAVE_LOGINRESTRICTIONS)
- gchar *message = NULL;
-#endif
-#if defined (HAVE_PASSWDEXPIRED) && defined (HAVE_CHPASS)
- gchar *info_msg = NULL, *response = NULL;
- gint reEnter, ret;
-#endif
-
- if (local && d->timed_login_ok)
- gdm_slave_greeter_ctl_no_ret (GDM_STARTTIMER, "");
-
- if (username == NULL) {
- authenticate_again:
- /* Ask for the user's login */
- gdm_verify_select_user (NULL);
- gdm_slave_greeter_ctl_no_ret (GDM_MSG, _("Please enter your username"));
- login = gdm_slave_greeter_ctl (GDM_PROMPT, _("Username:"));
- if (login == NULL ||
- gdm_slave_greeter_check_interruption ()) {
- if ( ! ve_string_empty (selected_user)) {
- /* user selected */
- g_free (login);
- login = selected_user;
- selected_user = NULL;
- } else {
- /* some other interruption */
- if (local)
- gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
- g_free (login);
- return NULL;
- }
- }
- gdm_slave_greeter_ctl_no_ret (GDM_MSG, "");
-
- if (gdm_daemon_config_get_value_bool (GDM_KEY_DISPLAY_LAST_LOGIN)) {
- char *info = gdm_get_last_info (login);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX, info);
- g_free (info);
- }
- } else {
- login = g_strdup (username);
- }
- gdm_slave_greeter_ctl_no_ret (GDM_SETLOGIN, login);
-
- pwent = getpwnam (login);
-
- ppasswd = (pwent == NULL) ? NULL : g_strdup (pwent->pw_passwd);
-
- /* Request the user's password */
- if (pwent != NULL &&
- ve_string_empty (ppasswd)) {
- /* eeek a passwordless account */
- passwd = g_strdup ("");
- } else {
- passwd = gdm_slave_greeter_ctl (GDM_NOECHO, _("Password:"));
- if (passwd == NULL)
- passwd = g_strdup ("");
- if (gdm_slave_greeter_check_interruption ()) {
- if (local)
- gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
- g_free (login);
- g_free (passwd);
- g_free (ppasswd);
- return NULL;
- }
- }
-
- if (local)
- gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
-
- if (pwent == NULL) {
- gdm_sleep_no_signal (gdm_daemon_config_get_value_int (GDM_KEY_RETRY_DELAY));
- g_warning (_("Couldn't authenticate user \"%s\""), login);
-
- print_cant_auth_errbox ();
-
- g_free (login);
- g_free (passwd);
- g_free (ppasswd);
- return NULL;
- }
-
- /* Check whether password is valid */
- if (ppasswd == NULL || (ppasswd[0] != '\0' &&
- strcmp (crypt (passwd, ppasswd), ppasswd) != 0)) {
- gdm_sleep_no_signal (gdm_daemon_config_get_value_int (GDM_KEY_RETRY_DELAY));
- g_warning (_("Couldn't authenticate user \"%s\""), login);
-
- print_cant_auth_errbox ();
-
- g_free (login);
- g_free (passwd);
- g_free (ppasswd);
- return NULL;
- }
-
- if ( ( ! gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_ROOT)||
- ( ! gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_REMOTE_ROOT) && ! local) ) &&
- pwent->pw_uid == 0) {
- g_warning (_("Root login disallowed on display '%s'"), display);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("The system administrator "
- "is not allowed to login "
- "from this screen"));
- /*gdm_slave_greeter_ctl_no_ret (GDM_ERRDLG,
- _("Root login disallowed"));*/
- g_free (login);
- g_free (passwd);
- g_free (ppasswd);
- return NULL;
- }
-
-#ifdef HAVE_LOGINRESTRICTIONS
-
- /* Check with the 'loginrestrictions' function
- if the user has been disallowed */
- if (loginrestrictions (login, 0, NULL, &message) != 0) {
- g_warning (_("User %s not allowed to log in"), login);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("\nThe system administrator "
- "has disabled your "
- "account."));
- g_free (login);
- g_free (passwd);
- g_free (ppasswd);
- if (message != NULL)
- free (message);
- return NULL;
- }
-
- if (message != NULL)
- free (message);
- message = NULL;
-
-#else /* ! HAVE_LOGINRESTRICTIONS */
-
- /* check for the standard method of disallowing users */
- if (pwent->pw_shell != NULL &&
- (strcmp (pwent->pw_shell, "/sbin/nologin") == 0 ||
- strcmp (pwent->pw_shell, "/bin/true") == 0 ||
- strcmp (pwent->pw_shell, "/bin/false") == 0)) {
- g_warning (_("User %s not allowed to log in"), login);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("\nThe system administrator "
- "has disabled your "
- "account."));
- /*gdm_slave_greeter_ctl_no_ret (GDM_ERRDLG,
- _("Login disabled"));*/
- g_free (login);
- g_free (passwd);
- g_free (ppasswd);
- return NULL;
- }
-
-#endif /* HAVE_LOGINRESTRICTIONS */
-
- g_free (passwd);
- g_free (ppasswd);
-
- if ( ! gdm_slave_check_user_wants_to_log_in (login)) {
- g_free (login);
- login = NULL;
- goto authenticate_again;
- }
-
- if ( ! gdm_setup_gids (login, pwent->pw_gid)) {
- g_warning (_("Cannot set user group for %s"), login);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("\nCannot set your user group; "
- "you will not be able to log in. "
- "Please contact your system administrator."));
- g_free (login);
- return NULL;
- }
-
-#if defined (HAVE_PASSWDEXPIRED) && defined (HAVE_CHPASS)
-
- switch (passwdexpired (login, &info_msg)) {
- case 1 :
- g_warning (_("Password of %s has expired"), login);
- 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);
-
- do {
- ret = chpass (login, response, &reEnter, &message);
- g_free (response);
-
- if (ret != 1) {
- if (ret != 0) {
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("\nCannot change your password; "
- "you will not be able to log in. "
- "Please try again later or contact "
- "your system administrator."));
- } else if ((reEnter != 0) && (message)) {
- response = gdm_slave_greeter_ctl (GDM_NOECHO, message);
- if (response == NULL)
- response = g_strdup ("");
- }
- }
-
- g_free (message);
- message = NULL;
-
- } while ( ((reEnter != 0) && (ret == 0))
- || (ret ==1) );
-
- g_free (response);
- g_free (message);
-
- if ((ret != 0) || (reEnter != 0)) {
- return NULL;
- }
-
-#if defined (CAN_CLEAR_ADMCHG)
- /* The password is changed by root, clear the ADM_CHG
- flag in the passwd file */
- ret = setpwdb (S_READ | S_WRITE);
- if (!ret) {
- upwd = getuserpw (login);
- if (upwd == NULL) {
- ret = -1;
- } else {
- upwd->upw_flags &= ~PW_ADMCHG;
- ret = putuserpw (upwd);
- if (!ret) {
- ret = endpwdb ();
- }
- }
- }
-
- if (ret) {
- 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."));
- }
-
-#else /* !CAN_CLEAR_ADMCHG */
- 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."));
-
-#endif /* CAN_CLEAR_ADMCHG */
-
- break;
-
- case 2 :
- g_warning (_("Password of %s has expired"), login);
- 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);
- return NULL;
- break;
-
- case -1 :
- g_warning (_("Internal error on passwdexpired"));
- 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);
- return NULL;
- break;
-
- default :
- g_free (info_msg);
- break;
- }
-
-#endif /* HAVE_PASSWDEXPIRED && HAVE_CHPASS */
-
- return login;
-}
-
-/**
- * gdm_verify_setup_user:
- * @login: The name of the user
- * @display: The name of the display
- *
- * This is used for auto loging in. This just sets up the login
- * session for this user
- */
-
-gboolean
-gdm_verify_setup_user (GdmDisplay *d,
- const gchar *login, const gchar *display,
- char **new_login)
-{
- struct passwd *pwent;
-
- *new_login = NULL;
-
- pwent = getpwnam (login);
- if (pwent == NULL) {
- g_warning (_("Cannot get passwd structure for %s"), login);
- return FALSE;
- }
-
- if ( ! gdm_setup_gids (login, pwent->pw_gid)) {
- g_warning (_("Cannot set user group for %s"), login);
- gdm_errorgui_error_box (d,
- GTK_MESSAGE_ERROR,
- _("\nCannot set your user group; "
- "you will not be able to log in. "
- "Please contact your system administrator."));
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * gdm_verify_cleanup:
- *
- * Unregister the user's session
- */
-
-void
-gdm_verify_cleanup (GdmDisplay *d)
-{
- gid_t groups[1] = { 0 };
-
- /* Clear the group setup */
- setgid (0);
- /* this will get rid of any suplementary groups etc... */
- setgroups (1, groups);
-}
-
-/* used in pam */
-gboolean
-gdm_verify_setup_env (GdmDisplay *d)
-{
- return TRUE;
-}
diff --git a/daemon/verify-pam.c b/daemon/verify-pam.c
deleted file mode 100644
index 4331e751..00000000
--- a/daemon/verify-pam.c
+++ /dev/null
@@ -1,1673 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * GDM - The GNOME Display Manager
- * Copyright (C) 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "config.h"
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <grp.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <syslog.h>
-#include <security/pam_appl.h>
-#include <pwd.h>
-#ifdef __sun
-#include <fcntl.h>
-#endif
-
-#include <glib/gi18n.h>
-
-#include "gdm.h"
-#include "misc.h"
-#include "slave.h"
-#include "verify.h"
-#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 */
-#ifdef HAVE_ADT
-#include <bsm/adt.h>
-#include <bsm/adt_event.h>
-#endif /* HAVE_ADT */
-
-#define AU_FAILED 0
-#define AU_SUCCESS 1
-#ifdef HAVE_LIBAUDIT
-#include <libaudit.h>
-#else
-#define log_to_audit_system(l,h,d,s) do { ; } while (0)
-#endif
-
-/* Evil, but this way these things are passed to the child session */
-static pam_handle_t *pamh = NULL;
-
-static GdmDisplay *cur_gdm_disp = NULL;
-
-/* Hack. Used so user does not need to select username in face
- * browser again if pw was wrong. Not used if username was typed
- * manually */
-static char* prev_user;
-static unsigned auth_retries;
-
-/* this is another hack */
-static gboolean did_we_ask_for_password = FALSE;
-
-static char *selected_user = NULL;
-
-static gboolean opened_session = FALSE;
-static gboolean did_setcred = FALSE;
-
-extern char *gdm_ack_question_response;
-
-#ifdef HAVE_ADT
-#define PW_FALSE 1 /* no password change */
-#define PW_TRUE 2 /* successful password change */
-#define PW_FAILED 3 /* failed password change */
-
-static adt_session_data_t *adt_ah = NULL; /* audit session handle */
-
-/*
- * audit_success_login - audit successful login
- *
- * Entry process audit context established -- i.e., pam_setcred ()
- * called.
- * pw_change == PW_TRUE, if successful password change audit
- * required.
- * pwent = authenticated user's passwd entry.
- *
- * Exit ADT_login (ADT_SUCCESS) audit record written
- * pw_change == PW_TRUE, ADT_passwd (ADT_SUCCESS) audit
- * record written.
- * adt_ah = audit session established for audit_logout ();
- *
- */
-static void
-audit_success_login (int pw_change, struct passwd *pwent)
-{
- adt_event_data_t *event; /* event to generate */
-
- if (adt_start_session (&adt_ah, NULL, ADT_USE_PROC_DATA) != 0) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_start_session (ADT_login): %m");
- return;
- }
-
- if (adt_set_user (adt_ah, pwent->pw_uid, pwent->pw_gid,
- pwent->pw_uid, pwent->pw_gid, NULL, ADT_USER) != 0) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_set_user (ADT_login, %s): %m", pwent->pw_name);
- }
- if ((event = adt_alloc_event (adt_ah, ADT_login)) == NULL) {
-
- syslog (LOG_AUTH | LOG_ALERT, "adt_alloc_event (ADT_login): %m");
- } else if (adt_put_event (event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_put_event (ADT_login, ADT_SUCCESS): %m");
- }
-
- if (pw_change == PW_TRUE) {
-
- /* Also audit password change */
- adt_free_event (event);
- if ((event = adt_alloc_event (adt_ah, ADT_passwd)) == NULL) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_alloc_event (ADT_passwd): %m");
- } else if (adt_put_event (event, ADT_SUCCESS,
- ADT_SUCCESS) != 0) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_put_event (ADT_passwd, ADT_SUCCESS): %m");
- }
- }
- adt_free_event (event);
-}
-
-/*
- * audit_fail_login - audit failed login
- *
- * Entry did_setcred == FALSE, process audit context is not established.
- * TRUE, process audit context established.
- * d = display structure, d->attached non 0 if local,
- * d->hostname used if remote.
- * pw_change == PW_FALSE, if no password change requested.
- * PW_TRUE, if successful password change audit
- * required.
- * PW_FAILED, if failed password change audit
- * required.
- * pwent = NULL, or password entry to use.
- * pamerr = PAM error code; reason for failure.
- *
- * Exit ADT_login (ADT_FAILURE) audit record written
- * pw_change == PW_TRUE, ADT_passwd (ADT_FAILURE) audit
- * record written.
- *
- */
-static void
-audit_fail_login (GdmDisplay *d, int pw_change, struct passwd *pwent,
- int pamerr)
-{
- adt_session_data_t *ah; /* audit session handle */
- adt_event_data_t *event; /* event to generate */
- adt_termid_t *tid; /* terminal ID for failures */
-
- if (did_setcred == TRUE) {
- if (adt_start_session (&ah, NULL, ADT_USE_PROC_DATA) != 0) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_start_session (ADT_login, ADT_FAILURE): %m");
- return;
- }
- } else {
- if (adt_start_session (&ah, NULL, 0) != 0) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_start_session (ADT_login, ADT_FAILURE): %m");
- return;
- }
- if (d->attached) {
- /* login from the local host */
- if (adt_load_ttyname ("/dev/console", &tid) != 0) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_loadhostname (localhost): %m");
- }
- } else {
- /* login from a remote host */
- if (adt_load_hostname (d->hostname, &tid) != 0) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_loadhostname (%s): %m", d->hostname);
- }
- }
- if (adt_set_user (ah,
- pwent ? pwent->pw_uid : ADT_NO_ATTRIB,
- pwent ? pwent->pw_gid : ADT_NO_ATTRIB,
- pwent ? pwent->pw_uid : ADT_NO_ATTRIB,
- pwent ? pwent->pw_gid : ADT_NO_ATTRIB,
- tid, ADT_NEW) != 0) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_set_user (%s): %m",
- pwent ? pwent->pw_name : "ADT_NO_ATTRIB");
- }
- }
- if ((event = adt_alloc_event (ah, ADT_login)) == NULL) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_alloc_event (ADT_login, ADT_FAILURE): %m");
- goto done;
- } else if (adt_put_event (event, ADT_FAILURE,
- ADT_FAIL_PAM + pamerr) != 0) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_put_event (ADT_login (ADT_FAIL, %s): %m",
- pam_strerror (pamh, pamerr));
- }
- if (pw_change != PW_FALSE) {
-
- /* Also audit password change */
- adt_free_event (event);
- if ((event = adt_alloc_event (ah, ADT_passwd)) == NULL) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_alloc_event (ADT_passwd): %m");
- goto done;
- }
- if (pw_change == PW_TRUE) {
- if (adt_put_event (event, ADT_SUCCESS,
- ADT_SUCCESS) != 0) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_put_event (ADT_passwd, ADT_SUCCESS): "
- "%m");
- }
- } else if (pw_change == PW_FAILED) {
- if (adt_put_event (event, ADT_FAILURE,
- ADT_FAIL_PAM + pamerr) != 0) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_put_event (ADT_passwd, ADT_FAILURE): "
- "%m");
- }
- }
- }
- adt_free_event (event);
-
- done:
- /* reset process audit state. this process is being reused.*/
-
- if ((adt_set_user (ah, ADT_NO_AUDIT, ADT_NO_AUDIT, ADT_NO_AUDIT,
- ADT_NO_AUDIT, NULL, ADT_NEW) != 0) ||
- (adt_set_proc (ah) != 0)) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_put_event (ADT_login (ADT_FAILURE reset, %m)");
- }
- (void) adt_end_session (ah);
-}
-
-/*
- * audit_logout - audit user logout
- *
- * Entry adt_ah = audit session handle established by
- * audit_success_login ().
- *
- * Exit ADT_logout (ADT_SUCCESS) audit record written
- * process audit state reset. (this process is reused for
- * the next login.)
- * audit session adt_ah ended.
- */
-static void
-audit_logout (void)
-{
- adt_event_data_t *event; /* event to generate */
-
- if ((event = adt_alloc_event (adt_ah, ADT_logout)) == NULL) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_alloc_event (ADT_logout): %m");
- } else if (adt_put_event (event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_put_event (ADT_logout, ADT_SUCCESS): %m");
- }
- adt_free_event (event);
-
- /* reset process audit state. this process is being reused.*/
-
- if ((adt_set_user (adt_ah, ADT_NO_AUDIT, ADT_NO_AUDIT, ADT_NO_AUDIT,
- ADT_NO_AUDIT, NULL, ADT_NEW) != 0) ||
- (adt_set_proc (adt_ah) != 0)) {
-
- syslog (LOG_AUTH | LOG_ALERT,
- "adt_set_proc (ADT_logout reset): %m");
- }
- (void) adt_end_session (adt_ah);
-}
-#endif /* HAVE_ADT */
-
-#ifdef __sun
-void
-solaris_xserver_cred (char *login, GdmDisplay *d, struct passwd *pwent)
-{
- struct stat statbuf;
- struct group *gr;
- gid_t groups[NGROUPS_UMAX];
- char *home, *disp, *tmp, pipe[MAXPATHLEN], info[MAXPATHLEN];
- int displayNumber = 0;
- int retval, fd, i, nb;
- int ngroups;
-
- if (!d->attached)
- return;
-
- if (g_access (pwent->pw_dir, F_OK) != 0) {
- gdm_debug ("solaris_xserver_cred: no HOME dir access\n");
- return;
- }
-
- /*
- * Handshake with server. Make sure it created a pipe.
- * Open and write.
- */
- if ((tmp = strstr (d->name, ":")) != NULL) {
- tmp++;
- displayNumber = atoi (tmp);
- }
-
- sprintf (pipe, "%s/%d", SDTLOGIN_DIR, displayNumber);
-
- if (g_stat (SDTLOGIN_DIR, &statbuf) == 0) {
- if (! statbuf.st_mode & S_IFDIR) {
- gdm_debug ("solaris_xserver_cred: %s is not a directory\n",
- SDTLOGIN_DIR);
- return;
- }
- }
- else {
- gdm_debug ("solaris_xserver_cred: %s does not exist\n", SDTLOGIN_DIR);
- return;
- }
-
- fd = open (pipe, O_RDWR);
- g_unlink (pipe);
-
- if (fd < 0) {
- gdm_debug ("solaris_xserver_cred: could not open %s\n", pipe);
- return;
- }
- if (fstat (fd, &statbuf) == 0 ) {
- if ( ! statbuf.st_mode & S_IFIFO) {
- close (fd);
- gdm_debug ("solaris_xserver_cred: %s is not a pipe\n", pipe);
- return;
- }
- } else {
- close (fd);
- gdm_debug ("solaris_xserver_cred: %s does not exist\n", pipe);
- return;
- }
-
- sprintf (info, "GID=\"%d\"; ", pwent->pw_gid);
- nb = write (fd, info, strlen (info));
- gdm_debug ("solaris_xserver_cred: %s\n", info);
-
- if (initgroups (login, pwent->pw_gid) == -1) {
- ngroups = 0;
- } else {
- ngroups = getgroups (NGROUPS_UMAX, groups);
- }
-
- for (i=0; i < ngroups; i++) {
- sprintf (info, "G_LIST_ID=\"%u\" ", groups[i]);
- nb = write (fd, info, strlen (info));
- gdm_debug ("solaris_xserver_cred: %s\n", info);
- }
-
- if (ngroups > 0) {
- sprintf (info, ";");
- write (fd, info, strlen (info));
- }
-
- sprintf (info, " HOME=\"%s\" ", pwent->pw_dir);
- nb = write (fd, info, strlen (info));
- gdm_debug ("solaris_xserver_cred: %s\n", info);
-
- sprintf (info, " UID=\"%d\" EOF=\"\";", pwent->pw_uid);
- nb = write (fd, info, strlen (info));
- gdm_debug ("solaris_xserver_cred: %s\n", info);
-
- /*
- * Handshake with server. Make sure it read the pipe.
- *
- * Close file descriptor.
- */
- close (fd);
-
- return;
-}
-#endif
-
-void
-gdm_verify_select_user (const char *user)
-{
- g_free (selected_user);
- if (ve_string_empty (user))
- selected_user = NULL;
- else
- selected_user = g_strdup (user);
-}
-
-static const char *
-perhaps_translate_message (const char *msg)
-{
- char *s;
- const char *ret;
- static GHashTable *hash = NULL;
- static char *locale = NULL;
-
- /* if locale changes out from under us then rebuild hash table
- */
- if ((locale != NULL) &&
- (strcmp (locale, setlocale (LC_ALL, NULL)) != 0)) {
- g_assert (hash != NULL);
- g_hash_table_destroy (hash);
- hash = NULL;
- }
-
- if (hash == NULL) {
- g_free (locale);
- locale = g_strdup (setlocale (LC_ALL, NULL));
-
- /* Here we come with some fairly standard messages so that
- we have as much as possible translated. Should really be
- translated in pam I suppose. This way we can "change"
- some of these messages to be more sane. */
- hash = g_hash_table_new (g_str_hash, g_str_equal);
- /* login: is whacked always translate to Username: */
- g_hash_table_insert (hash, "login:", _("Username:"));
- g_hash_table_insert (hash, "Username:", _("Username:"));
- g_hash_table_insert (hash, "username:", _("Username:"));
- g_hash_table_insert (hash, "Password:", _("Password:"));
- g_hash_table_insert (hash, "password:", _("Password:"));
- g_hash_table_insert (hash, "You are required to change your password immediately (password aged)", _("You are required to change your password immediately (password aged)"));
- g_hash_table_insert (hash, "You are required to change your password immediately (root enforced)", _("You are required to change your password immediately (root enforced)"));
- g_hash_table_insert (hash, "Your account has expired; please contact your system administrator", _("Your account has expired; please contact your system administrator"));
- g_hash_table_insert (hash, "No password supplied", _("No password supplied"));
- g_hash_table_insert (hash, "Password unchanged", _("Password unchanged"));
- g_hash_table_insert (hash, "Can not get username", _("Can not get username"));
- g_hash_table_insert (hash, "Retype new UNIX password:", _("Retype new UNIX password:"));
- g_hash_table_insert (hash, "Enter new UNIX password:", _("Enter new UNIX password:"));
- g_hash_table_insert (hash, "(current) UNIX password:", _("(current) UNIX password:"));
- g_hash_table_insert (hash, "Error while changing NIS password.", _("Error while changing NIS password."));
- g_hash_table_insert (hash, "You must choose a longer password", _("You must choose a longer password"));
- g_hash_table_insert (hash, "Password has been already used. Choose another.", _("Password has been already used. Choose another."));
- g_hash_table_insert (hash, "You must wait longer to change your password", _("You must wait longer to change your password"));
- g_hash_table_insert (hash, "Sorry, passwords do not match", _("Sorry, passwords do not match"));
- /* FIXME: what about messages which have some variables in them, perhaps try to do those as well */
- }
- s = g_strstrip (g_strdup (msg));
- ret = g_hash_table_lookup (hash, s);
- g_free (s);
- if (ret != NULL)
- return ret;
- else
- return msg;
-}
-
-/* Internal PAM conversation function. Interfaces between the PAM
- * authentication system and the actual greeter program */
-
-static int
-gdm_verify_pam_conv (int num_msg, struct pam_message **msg,
- struct pam_response **resp,
- void *appdata_ptr)
-{
- int replies = 0;
- int i;
- char *s = NULL;
- struct pam_response *reply = NULL;
- const void *p;
- const char *login;
-
- if (pamh == NULL)
- return PAM_CONV_ERR;
-
- /* Should never happen unless PAM is on crack and keeps asking questions
- after we told it to go away. So tell it to go away again and
- maybe it will listen */
- /* well, it actually happens if there are multiple pam modules
- * with conversations */
- if ( ! gdm_slave_action_pending () || selected_user)
- return PAM_CONV_ERR;
-
- reply = malloc (sizeof (struct pam_response) * num_msg);
-
- if (reply == NULL)
- return PAM_CONV_ERR;
-
- memset (reply, 0, sizeof (struct pam_response) * num_msg);
-
- /* Here we set the login if it wasn't already set,
- * this is kind of anal, but this way we guarantee that
- * the greeter always is up to date on the login */
- if (pam_get_item (pamh, PAM_USER, (void **)&p) == PAM_SUCCESS) {
- login = (const char *)p;
- gdm_slave_greeter_ctl_no_ret (GDM_SETLOGIN, login);
- }
-
- /* Workaround to avoid gdm messages being logged as PAM_pwdb */
- gdm_log_shutdown ();
- gdm_log_init ();
-
- for (replies = 0; replies < num_msg; replies++) {
- const char *m = (*msg)[replies].msg;
- m = perhaps_translate_message (m);
-
- switch ((*msg)[replies].msg_style) {
-
- /* PAM requested textual input with echo on */
- case PAM_PROMPT_ECHO_ON:
- if (strcmp (m, _("Username:")) == 0) {
- if ( ve_string_empty (selected_user)) {
- /* this is an evil hack, but really there is no way we'll
- know this is a username prompt. However we SHOULD NOT
- rely on this working. The pam modules can set their
- prompt to whatever they wish to */
- gdm_slave_greeter_ctl_no_ret
- (GDM_MSG, _("Please enter your username"));
- s = gdm_slave_greeter_ctl (GDM_PROMPT, m);
- /* this will clear the message */
- gdm_slave_greeter_ctl_no_ret (GDM_MSG, "");
- }
- } else {
- s = gdm_slave_greeter_ctl (GDM_PROMPT, m);
- }
-
- if (gdm_slave_greeter_check_interruption ()) {
- g_free (s);
- for (i = 0; i < replies; i++)
- if (reply[replies].resp != NULL)
- free (reply[replies].resp);
- free (reply);
- return PAM_CONV_ERR;
- }
-
- reply[replies].resp_retcode = PAM_SUCCESS;
- reply[replies].resp = strdup (ve_sure_string (s));
- g_free (s);
- break;
-
- case PAM_PROMPT_ECHO_OFF:
- if (strcmp (m, _("Password:")) == 0)
- did_we_ask_for_password = TRUE;
- /* PAM requested textual input with echo off */
- s = gdm_slave_greeter_ctl (GDM_NOECHO, m);
- if (gdm_slave_greeter_check_interruption ()) {
- g_free (s);
- for (i = 0; i < replies; i++)
- if (reply[replies].resp != NULL)
- free (reply[replies].resp);
- free (reply);
- return PAM_CONV_ERR;
- }
- reply[replies].resp_retcode = PAM_SUCCESS;
- reply[replies].resp = strdup (ve_sure_string (s));
- g_free (s);
- break;
-
- case PAM_ERROR_MSG:
- /* PAM sent a message that should displayed to the user */
- gdm_slave_greeter_ctl_no_ret (GDM_ERRDLG, m);
- reply[replies].resp_retcode = PAM_SUCCESS;
- reply[replies].resp = NULL;
- break;
- case PAM_TEXT_INFO:
- /* PAM sent a message that should displayed to the user */
- gdm_slave_greeter_ctl_no_ret (GDM_MSG, m);
- reply[replies].resp_retcode = PAM_SUCCESS;
- reply[replies].resp = NULL;
- break;
-
- default:
- /* PAM has been smoking serious crack */
- for (i = 0; i < replies; i++)
- if (reply[replies].resp != NULL)
- free (reply[replies].resp);
- free (reply);
- return PAM_CONV_ERR;
- }
-
- }
-
- *resp = reply;
- return PAM_SUCCESS;
-}
-
-static struct pam_conv pamc = {
- &gdm_verify_pam_conv,
- NULL
-};
-
-/* Extra message to give on queries */
-static char *extra_standalone_message = NULL;
-
-static int
-gdm_verify_standalone_pam_conv (int num_msg, struct pam_message **msg,
- struct pam_response **resp,
- void *appdata_ptr)
-{
- int replies = 0;
- int i;
- char *text;
- char *question_msg;
- struct pam_response *reply = NULL;
-
- if (pamh == NULL)
- return PAM_CONV_ERR;
-
- reply = malloc (sizeof (struct pam_response) * num_msg);
-
- if (reply == NULL)
- return PAM_CONV_ERR;
-
- memset (reply, 0, sizeof (struct pam_response) * num_msg);
-
- for (replies = 0; replies < num_msg; replies++) {
- const char *m = (*msg)[replies].msg;
- m = perhaps_translate_message (m);
- switch ((*msg)[replies].msg_style) {
-
- case PAM_PROMPT_ECHO_ON:
- if (extra_standalone_message != NULL)
- text = g_strdup_printf
- ("%s%s", extra_standalone_message,
- m);
- else
- text = g_strdup (m);
-
- /* PAM requested textual input with echo on */
- question_msg = g_strdup_printf ("question_msg=%s$$echo=%d", text, TRUE);
-
- gdm_slave_send_string (GDM_SOP_SHOW_QUESTION_DIALOG, question_msg);
-
- g_free (question_msg);
- g_free (text);
-
- reply[replies].resp_retcode = PAM_SUCCESS;
- if (gdm_ack_question_response) {
- reply[replies].resp = strdup (ve_sure_string (gdm_ack_question_response));
- g_free (gdm_ack_question_response);
- gdm_ack_question_response = NULL;
- } else
- reply[replies].resp = NULL;
-
- break;
-
- case PAM_PROMPT_ECHO_OFF:
- if (extra_standalone_message != NULL)
- text = g_strdup_printf
- ("%s%s", extra_standalone_message,
- m);
- else
- text = g_strdup (m);
-
- /* PAM requested textual input with echo off */
- question_msg = g_strdup_printf ("question_msg=%s$$echo=%d", text, TRUE);
-
- gdm_slave_send_string (GDM_SOP_SHOW_QUESTION_DIALOG, question_msg);
-
- g_free (question_msg);
- g_free (text);
-
- reply[replies].resp_retcode = PAM_SUCCESS;
- if (gdm_ack_question_response) {
- reply[replies].resp = strdup (ve_sure_string (gdm_ack_question_response));
- g_free (gdm_ack_question_response);
- gdm_ack_question_response = NULL;
- } else
- reply[replies].resp = NULL;
-
- break;
-
- case PAM_ERROR_MSG:
- /* PAM sent a message that should displayed to the user */
- gdm_errorgui_error_box (cur_gdm_disp,
- GTK_MESSAGE_ERROR,
- m);
- reply[replies].resp_retcode = PAM_SUCCESS;
- reply[replies].resp = NULL;
- break;
-
- case PAM_TEXT_INFO:
- /* PAM sent a message that should displayed to the user */
- gdm_errorgui_error_box (cur_gdm_disp,
- GTK_MESSAGE_INFO,
- m);
- reply[replies].resp_retcode = PAM_SUCCESS;
- reply[replies].resp = NULL;
- break;
-
- default:
- /* PAM has been smoking serious crack */
- for (i = 0; i < replies; i++)
- if (reply[replies].resp != NULL)
- free (reply[replies].resp);
- free (reply);
- return PAM_CONV_ERR;
- }
-
- }
-
- *resp = reply;
- return PAM_SUCCESS;
-}
-
-static struct pam_conv standalone_pamc = {
- &gdm_verify_standalone_pam_conv,
- NULL
-};
-
-/* Creates a pam handle for the auto login */
-static gboolean
-create_pamh (GdmDisplay *d,
- const char *service,
- const char *login,
- struct pam_conv *conv,
- const char *display,
- int *pamerr)
-{
- if (display == NULL) {
- gdm_error (_("Cannot setup pam handle with null display"));
- return FALSE;
- }
-
- if (pamh != NULL) {
- gdm_error ("create_pamh: Stale pamh around, cleaning up");
- pam_end (pamh, PAM_SUCCESS);
- }
- /* init things */
- pamh = NULL;
- opened_session = FALSE;
- did_setcred = FALSE;
-
- /* Initialize a PAM session for the user */
- if ((*pamerr = pam_start (service, login, conv, &pamh)) != PAM_SUCCESS) {
- pamh = NULL; /* be anal */
- if (gdm_slave_action_pending ())
- gdm_error (_("Unable to establish service %s: %s\n"),
- service, pam_strerror (NULL, *pamerr));
- return FALSE;
- }
-
- /* Inform PAM of the user's tty */
-#ifdef __sun
- if (d->attached)
- (void) pam_set_item (pamh, PAM_TTY, "/dev/console");
- else
-#endif /* sun */
- if ((*pamerr = pam_set_item (pamh, PAM_TTY, display)) != PAM_SUCCESS) {
- if (gdm_slave_action_pending ())
- gdm_error (_("Can't set PAM_TTY=%s"), display);
- return FALSE;
- }
-
- if ( ! d->attached) {
- /* Only set RHOST if host is remote */
- /* From the host of the display */
- if ((*pamerr = pam_set_item (pamh, PAM_RHOST,
- d->hostname)) != PAM_SUCCESS) {
- if (gdm_slave_action_pending ())
- gdm_error (_("Can't set PAM_RHOST=%s"),
- d->hostname);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-/**
- * log_to_audit_system:
- * @login: Name of user
- * @hostname: Name of host machine
- * @tty: Name of display
- * @success: 1 for success, 0 for failure
- *
- * Logs the success or failure of the login attempt with the linux kernel
- * audit system. The intent is to capture failed events where the user
- * fails authentication or otherwise is not permitted to login. There are
- * many other places where pam could potentially fail and cause login to
- * fail, but these are system failures rather than the signs of an account
- * being hacked.
- *
- * Returns nothing.
- */
-
-#ifdef HAVE_LIBAUDIT
-static void
-log_to_audit_system(const char *login,
- const char *hostname,
- const char *tty,
- gboolean success)
-{
- struct passwd *pw;
- char buf[64];
- int audit_fd;
-
- audit_fd = audit_open();
- if (login)
- pw = getpwnam(login);
- else {
- login = "unknown";
- pw = NULL;
- }
- if (pw) {
- snprintf(buf, sizeof(buf), "uid=%d", pw->pw_uid);
- audit_log_user_message(audit_fd, AUDIT_USER_LOGIN,
- buf, hostname, NULL, tty, (int)success);
- } else {
- snprintf(buf, sizeof(buf), "acct=%s", login);
- audit_log_user_message(audit_fd, AUDIT_USER_LOGIN,
- buf, hostname, NULL, tty, (int)success);
- }
- close(audit_fd);
-}
-#endif
-
-/**
- * gdm_verify_user:
- * @username: Name of user or NULL if we should ask
- * @display: Name of display to register with the authentication system
- * @local: boolean if local
- * @allow_retry: boolean if we should allow retry logic to be enabled.
- * We only want this to work for normal login, not for
- * asking for the root password to cal the configurator.
- *
- * Provides a communication layer between the operating system's
- * authentication functions and the gdmgreeter.
- *
- * Returns the user's login on success and NULL on failure.
- */
-
-gchar *
-gdm_verify_user (GdmDisplay *d,
- const char *username,
- const gchar *display,
- gboolean local,
- gboolean allow_retry)
-{
- gint pamerr = 0;
- struct passwd *pwent = NULL;
- const void *p;
- char *login, *passreq, *consoleonly;
- char *pam_stack = NULL;
- int null_tok = 0;
- gboolean credentials_set = FALSE;
- gboolean error_msg_given = FALSE;
- gboolean started_timer = FALSE;
-
-#ifdef HAVE_ADT
- int pw_change = PW_FALSE; /* if got to trying to change password */
-#endif /* HAVE_ADT */
-
- verify_user_again:
-
- pamerr = 0;
- login = NULL;
- error_msg_given = FALSE;
- credentials_set = FALSE;
- started_timer = FALSE;
- null_tok = 0;
-
- /* Don't start a timed login if we've already entered a username */
- if (username != NULL) {
- login = g_strdup (username);
- gdm_slave_greeter_ctl_no_ret (GDM_SETLOGIN, login);
- } else {
- /* start the timer for timed logins */
- if ( ! ve_string_empty (gdm_daemon_config_get_value_string (GDM_KEY_TIMED_LOGIN)) &&
- d->timed_login_ok &&
- (local || gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN))) {
- gdm_slave_greeter_ctl_no_ret (GDM_STARTTIMER, "");
- started_timer = TRUE;
- }
- }
-
- cur_gdm_disp = d;
-
- authenticate_again:
-
- if (prev_user && !login) {
- login = g_strdup(prev_user);
- } else if (login && !prev_user) {
- prev_user = g_strdup(login);
- auth_retries = 0;
- } else if (login && prev_user && strcmp (login, prev_user)) {
- g_free (prev_user);
- prev_user = g_strdup (login);
- auth_retries = 0;
- }
-
- /*
- * Initialize a PAM session for the user...
- * Get value per-display so different displays can use different
- * PAM Stacks, in case one display should use a different
- * authentication mechanism than another display.
- */
- pam_stack = gdm_daemon_config_get_value_string_per_display (GDM_KEY_PAM_STACK, (char *)display);
-
- if ( ! create_pamh (d, pam_stack, login, &pamc, display, &pamerr)) {
- if (started_timer)
- gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
- g_free (pam_stack);
- goto pamerr;
- }
-
- g_free (pam_stack);
-
- /*
- * have to unset login otherwise there is no chance to ever enter
- * a different user
- */
- g_free (login);
- login = NULL;
-
- pam_set_item (pamh, PAM_USER_PROMPT, _("Username:"));
-
-#if 0
- /* FIXME: this makes things wait at the wrong places! such as
- when running the configurator. We wish to ourselves cancel logins
- without a delay, so ... evil */
-#ifdef PAM_FAIL_DELAY
- pam_fail_delay (pamh, gdm_daemon_config_get_value_int (GDM_KEY_RETRY_DELAY) * 1000000);
-#endif /* PAM_FAIL_DELAY */
-#endif
-
- passreq = gdm_read_default ("PASSREQ=");
- if ((passreq != NULL) &&
- g_ascii_strcasecmp (passreq, "YES") == 0)
- gdm_daemon_config_set_value_bool (GDM_KEY_PASSWORD_REQUIRED, TRUE);
-
- if (gdm_daemon_config_get_value_bool (GDM_KEY_PASSWORD_REQUIRED))
- null_tok |= PAM_DISALLOW_NULL_AUTHTOK;
-
- gdm_verify_select_user (NULL);
-
- /* Start authentication session */
- did_we_ask_for_password = FALSE;
- if ((pamerr = pam_authenticate (pamh, null_tok)) != PAM_SUCCESS) {
- /* Log the failed login attempt */
- log_to_audit_system(login, d->hostname, display, AU_FAILED);
- if ( ! ve_string_empty (selected_user)) {
- pam_handle_t *tmp_pamh;
-
- /* Face browser was used to select a user,
- just completely rewhack everything since it
- seems various PAM implementations are
- having goats with just setting PAM_USER
- and trying to pam_authenticate again */
-
- g_free (login);
- login = selected_user;
- selected_user = NULL;
-
- gdm_sigterm_block_push ();
- gdm_sigchld_block_push ();
- tmp_pamh = pamh;
- pamh = NULL;
- gdm_sigchld_block_pop ();
- gdm_sigterm_block_pop ();
-
- /* FIXME: what about errors */
- /* really this has been a sucess, not a failure */
- pam_end (tmp_pamh, pamerr);
-
- g_free (prev_user);
- prev_user = NULL;
- auth_retries = 0;
-
- gdm_slave_greeter_ctl_no_ret (GDM_SETLOGIN, login);
-
- goto authenticate_again;
- }
-
- if (started_timer)
- gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
-
- if (gdm_slave_action_pending ()) {
- /* FIXME: see note above about PAM_FAIL_DELAY */
- /* #ifndef PAM_FAIL_DELAY */
- gdm_sleep_no_signal (gdm_daemon_config_get_value_int (GDM_KEY_RETRY_DELAY));
- /* wait up to 100ms randomly */
- usleep (g_random_int_range (0, 100000));
- /* #endif */ /* PAM_FAIL_DELAY */
- gdm_error (_("Couldn't authenticate user"));
-
- if (prev_user) {
-
- unsigned max_auth_retries = 3;
- char *val = gdm_read_default ("LOGIN_RETRIES=");
-
- if (val) {
- max_auth_retries = atoi (val);
- g_free (val);
- }
-
- if (allow_retry == FALSE || pamerr == PAM_MAXTRIES ||
- ++auth_retries >= max_auth_retries) {
-
- g_free (prev_user);
- prev_user = NULL;
- auth_retries = 0;
- }
- }
- } else {
- /* cancel, configurator etc pressed */
- g_free (prev_user);
- prev_user = NULL;
- auth_retries = 0;
- }
-
- goto pamerr;
- }
-
- /* stop the timer for timed logins */
- if (started_timer)
- gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
-
- g_free (login);
- login = NULL;
- g_free (prev_user);
- prev_user = NULL;
-
- if ((pamerr = pam_get_item (pamh, PAM_USER, (void **)&p)) != PAM_SUCCESS) {
- login = NULL;
- /* is not really an auth problem, but it will
- pretty much look as such, it shouldn't really
- happen */
- if (gdm_slave_action_pending ())
- gdm_error (_("Couldn't authenticate user"));
- goto pamerr;
- }
-
- login = g_strdup ((const char *)p);
- /* kind of anal, the greeter likely already knows, but it could have
- been changed */
- gdm_slave_greeter_ctl_no_ret (GDM_SETLOGIN, login);
-
- if ( ! gdm_slave_check_user_wants_to_log_in (login)) {
- /* cleanup stuff */
- gdm_slave_greeter_ctl_no_ret (GDM_SETLOGIN, "");
- g_free (login);
- login = NULL;
- gdm_slave_greeter_ctl_no_ret (GDM_RESETOK, "");
-
- gdm_verify_cleanup (d);
-
- goto verify_user_again;
- }
-
- /* Check if user is root and is allowed to log in */
- consoleonly = gdm_read_default ("CONSOLE=");
- if ((consoleonly != NULL) &&
- g_ascii_strcasecmp (consoleonly, "/dev/console") == 0)
- gdm_daemon_config_set_value_bool (GDM_KEY_ALLOW_REMOTE_ROOT, FALSE);
-
- pwent = getpwnam (login);
- if ( ( ! gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_ROOT) ||
- ( ! gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_REMOTE_ROOT) && ! local) ) &&
- pwent != NULL &&
- pwent->pw_uid == 0) {
- /* Log the failed login attempt */
- log_to_audit_system(login, d->hostname, display, AU_FAILED);
- gdm_error (_("Root login disallowed on display '%s'"),
- display);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("\nThe system administrator "
- "is not allowed to login "
- "from this screen"));
- /*gdm_slave_greeter_ctl_no_ret (GDM_ERRDLG,
- _("Root login disallowed"));*/
- error_msg_given = TRUE;
-
-#ifdef HAVE_ADT
- /*
- * map console login not allowed as a pam_acct_mgmt () failure
- * indeed that's where these checks should be made.
- */
- pamerr = PAM_PERM_DENIED;
-#endif /* HAVE_ADT */
- goto pamerr;
- }
-
- if (gdm_daemon_config_get_value_bool (GDM_KEY_DISPLAY_LAST_LOGIN)) {
- char *info = gdm_get_last_info (login);
- gdm_slave_greeter_ctl_no_ret (GDM_MSG, info);
- g_free (info);
- }
-
- /* Check if the user's account is healthy. */
- pamerr = pam_acct_mgmt (pamh, null_tok);
- switch (pamerr) {
- case PAM_SUCCESS :
- break;
- case PAM_NEW_AUTHTOK_REQD :
- if ((pamerr = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK)) != PAM_SUCCESS) {
- /* Log the failed login attempt */
- log_to_audit_system(login, d->hostname, display, AU_FAILED);
- gdm_error (_("Authentication token change failed for user %s"), login);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("\nThe change of the authentication token failed. "
- "Please try again later or contact the system administrator."));
- error_msg_given = TRUE;
-#ifdef HAVE_ADT
- /* Password change failed */
- pw_change = PW_FAILED;
-#endif /* HAVE_ADT */
- goto pamerr;
- }
-#ifdef HAVE_ADT
- /* Password changed */
- pw_change = PW_TRUE;
-#endif /* HAVE_ADT */
- break;
- case PAM_ACCT_EXPIRED :
- /* Log the failed login attempt */
- log_to_audit_system(login, d->hostname, display, AU_FAILED);
- gdm_error (_("User %s no longer permitted to access the system"), login);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("\nThe system administrator has disabled your account."));
- error_msg_given = TRUE;
- goto pamerr;
- case PAM_PERM_DENIED :
- /* Log the failed login attempt */
- log_to_audit_system(login, d->hostname, display, AU_FAILED);
- gdm_error (_("User %s not permitted to gain access at this time"), login);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("\nThe system administrator has disabled access to the system temporarily."));
- error_msg_given = TRUE;
- goto pamerr;
- default :
- /* Log the failed login attempt */
- log_to_audit_system(login, d->hostname, display, AU_FAILED);
- if (gdm_slave_action_pending ())
- gdm_error (_("Couldn't set acct. mgmt for %s"), login);
- goto pamerr;
- }
-
- pwent = getpwnam (login);
- if (/* paranoia */ pwent == NULL ||
- ! gdm_setup_gids (login, pwent->pw_gid)) {
- gdm_error (_("Cannot set user group for %s"), login);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("\nCannot set your user group; "
- "you will not be able to log in. "
- "Please contact your system administrator."));
-#ifdef HAVE_ADT
- /*
- * map group setup error as a pam_setcred () failure
- * indeed that's where this should be done.
- */
- pamerr = PAM_SYSTEM_ERR;
-#endif /* HAVE_ADT */
- goto pamerr;
- }
-
- did_setcred = TRUE;
-
-#ifdef __sun
- solaris_xserver_cred (login, d, pwent);
-#endif
-
- /* Set credentials */
- pamerr = pam_setcred (pamh, PAM_ESTABLISH_CRED);
- if (pamerr != PAM_SUCCESS) {
- did_setcred = FALSE;
- if (gdm_slave_action_pending ())
- gdm_error (_("Couldn't set credentials for %s"), login);
- goto pamerr;
- }
-
- credentials_set = TRUE;
- opened_session = TRUE;
-
- /* Register the session */
- pamerr = pam_open_session (pamh, 0);
- if (pamerr != PAM_SUCCESS) {
- opened_session = FALSE;
- /* we handle this above */
- did_setcred = FALSE;
- if (gdm_slave_action_pending ())
- gdm_error (_("Couldn't open session for %s"), login);
- goto pamerr;
- }
- /* Login succeeded */
- log_to_audit_system(login, d->hostname, display, AU_SUCCESS);
-
- /* Workaround to avoid gdm messages being logged as PAM_pwdb */
- gdm_log_shutdown ();
- gdm_log_init ();
-
- cur_gdm_disp = NULL;
-
-#ifdef HAVE_LOGINDEVPERM
- if (d->attached)
- (void) di_devperm_login ("/dev/console", pwent->pw_uid,
- pwent->pw_gid, NULL);
-#endif /* HAVE_LOGINDEVPERM */
-#ifdef HAVE_ADT
- audit_success_login (pw_change, pwent);
-#endif /* HAVE_ADT */
-
- return login;
-
- pamerr:
-#ifdef HAVE_ADT
- audit_fail_login (d, pw_change, pwent, pamerr);
-#endif /* HAVE_ADT */
-
- /* The verbose authentication is turned on, output the error
- * message from the PAM subsystem */
- if ( ! error_msg_given &&
- gdm_slave_action_pending ()) {
- /*
- * I'm not sure yet if I should display this message for any
- * other issues - heeten
- * Adding AUTHINFO_UNAVAIL to the list - its what an unknown
- * user is.
- */
- if (pamerr == PAM_AUTH_ERR ||
- pamerr == PAM_USER_UNKNOWN ||
- pamerr == PAM_AUTHINFO_UNAVAIL) {
- gboolean is_capslock = FALSE;
- const char *basemsg;
- char *msg;
- char *ret;
-
- ret = gdm_slave_greeter_ctl (GDM_QUERY_CAPSLOCK, "");
- if ( ! ve_string_empty (ret))
- is_capslock = TRUE;
- g_free (ret);
-
- /* Only give this message if we actually asked for
- password, otherwise it would be silly to say that
- the password may have been wrong */
- if (did_we_ask_for_password) {
- basemsg = _("\nIncorrect username or password. "
- "Letters must be typed in the correct "
- "case.");
- } else {
- basemsg = _("\nAuthentication failed. "
- "Letters must be typed in the correct "
- "case.");
- }
- if (is_capslock) {
- msg = g_strconcat (basemsg, " ",
- _("Caps Lock is on."),
- NULL);
- } else {
- msg = g_strdup (basemsg);
- }
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX, msg);
- g_free (msg);
- } else {
- gdm_slave_greeter_ctl_no_ret (GDM_ERRDLG, _("Authentication failed"));
- }
- }
-
- did_setcred = FALSE;
- opened_session = FALSE;
-
- if (pamh != NULL) {
- pam_handle_t *tmp_pamh;
- gdm_sigterm_block_push ();
- gdm_sigchld_block_push ();
- tmp_pamh = pamh;
- pamh = NULL;
- gdm_sigchld_block_pop ();
- gdm_sigterm_block_pop ();
-
- /* Throw away the credentials */
- if (credentials_set)
- pam_setcred (tmp_pamh, PAM_DELETE_CRED);
- pam_end (tmp_pamh, pamerr);
- }
- pamh = NULL;
-
- /* Workaround to avoid gdm messages being logged as PAM_pwdb */
- gdm_log_shutdown ();
- gdm_log_init ();
-
- g_free (login);
-
- cur_gdm_disp = NULL;
-
- return NULL;
-}
-
-/**
- * gdm_verify_setup_user:
- * @login: The name of the user
- * @display: The name of the display
- *
- * This is used for auto loging in. This just sets up the login
- * session for this user
- */
-
-gboolean
-gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display,
- char **new_login)
-{
- gint pamerr = 0;
- struct passwd *pwent = NULL;
- const void *p;
- char *passreq;
- char *pam_stack = NULL;
- char *pam_service_name = NULL;
- int null_tok = 0;
- gboolean credentials_set;
- const char *after_login;
-
- credentials_set = FALSE;
-
-#ifdef HAVE_ADT
- int pw_change = PW_FALSE; /* if got to trying to change password */
-#endif /* HAVE_ADT */
-
- *new_login = NULL;
-
- if (login == NULL)
- return FALSE;
-
- cur_gdm_disp = d;
-
- g_free (extra_standalone_message);
- extra_standalone_message = g_strdup_printf ("%s (%s)",
- _("Automatic login"),
- login);
-
- /*
- * Initialize a PAM session for the user...
- * Get value per-display so different displays can use different
- * PAM Stacks, in case one display should use a different
- * authentication mechanism than another display.
- */
- pam_stack = gdm_daemon_config_get_value_string_per_display (GDM_KEY_PAM_STACK, (char *)display);
- pam_service_name = g_strdup_printf ("%s-autologin", pam_stack);
-
- if ( ! create_pamh (d, pam_service_name, login, &standalone_pamc,
- display, &pamerr)) {
- g_free (pam_stack);
- g_free (pam_service_name);
- goto setup_pamerr;
- }
- g_free (pam_stack);
- g_free (pam_service_name);
-
- passreq = gdm_read_default ("PASSREQ=");
- if ((passreq != NULL) &&
- g_ascii_strcasecmp (passreq, "YES") == 0)
- gdm_daemon_config_set_value_bool (GDM_KEY_PASSWORD_REQUIRED, TRUE);
-
- if (gdm_daemon_config_get_value_bool (GDM_KEY_PASSWORD_REQUIRED))
- null_tok |= PAM_DISALLOW_NULL_AUTHTOK;
-
- /* Start authentication session */
- did_we_ask_for_password = FALSE;
- if ((pamerr = pam_authenticate (pamh, null_tok)) != PAM_SUCCESS) {
- if (gdm_slave_action_pending ()) {
- gdm_error (_("Couldn't authenticate user"));
- gdm_errorgui_error_box (cur_gdm_disp,
- GTK_MESSAGE_ERROR,
- _("Authentication failed"));
- }
- goto setup_pamerr;
- }
-
- if ((pamerr = pam_get_item (pamh, PAM_USER, (void **)&p)) != PAM_SUCCESS) {
- /* is not really an auth problem, but it will
- pretty much look as such, it shouldn't really
- happen */
- gdm_error (_("Couldn't authenticate user"));
- gdm_errorgui_error_box (cur_gdm_disp,
- GTK_MESSAGE_ERROR,
- _("Authentication failed"));
- goto setup_pamerr;
- }
- after_login = (const char *)p;
-
- if (after_login != NULL /* should never be */ &&
- strcmp (after_login, login) != 0) {
- *new_login = g_strdup (after_login);
- }
-
-#ifdef HAVE_ADT
- /* to set up for same auditing calls as in gdm_verify_user */
- pwent = getpwnam (login);
-#endif /* HAVE_ADT */
-
- /* Check if the user's account is healthy. */
- pamerr = pam_acct_mgmt (pamh, null_tok);
- switch (pamerr) {
- case PAM_SUCCESS :
- break;
- case PAM_NEW_AUTHTOK_REQD :
- /* XXX: this is for automatic and timed logins,
- * we shouldn't be asking for new pw since we never
- * authenticated the user. I suppose just ignoring
- * this would be OK */
-#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_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."));
-#ifdef HAVE_ADT
- pw_change = PW_FAILED;
-#endif /* HAVE_ADT */
- goto setup_pamerr;
- }
-#ifdef HAVE_ADT
- pw_change = PW_TRUE;
-#endif /* HAVE_ADT */
-#endif /* 0 */
- break;
- case PAM_ACCT_EXPIRED :
- gdm_error (_("User %s no longer permitted to access the system"), login);
- 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_errorgui_error_box (cur_gdm_disp,
- GTK_MESSAGE_ERROR,
- _("The system administrator has disabled your access to the system temporarily."));
- goto setup_pamerr;
- default :
- if (gdm_slave_action_pending ())
- gdm_error (_("Couldn't set acct. mgmt for %s"), login);
- goto setup_pamerr;
- }
-
- pwent = getpwnam (login);
- if (/* paranoia */ pwent == NULL ||
- ! gdm_setup_gids (login, pwent->pw_gid)) {
- gdm_error (_("Cannot set user group for %s"), login);
- gdm_errorgui_error_box (cur_gdm_disp,
- GTK_MESSAGE_ERROR,
- _("Cannot set your user group; "
- "you will not be able to log in. "
- "Please contact your system administrator."));
-#ifdef HAVE_ADT
- /*
- * map group setup error as a pam_setcred () failure
- * indeed that's where this should be done.
- */
- pamerr = PAM_SYSTEM_ERR;
-#endif /* HAVE_ADT */
- goto setup_pamerr;
- }
-
- did_setcred = TRUE;
-
-#ifdef __sun
- solaris_xserver_cred ((char *)login, d, pwent);
-#endif
-
- /* Set credentials */
- pamerr = pam_setcred (pamh, PAM_ESTABLISH_CRED);
- if (pamerr != PAM_SUCCESS) {
- did_setcred = FALSE;
- if (gdm_slave_action_pending ())
- gdm_error (_("Couldn't set credentials for %s"), login);
- goto setup_pamerr;
- }
-
- credentials_set = TRUE;
- opened_session = TRUE;
-
- /* Register the session */
- pamerr = pam_open_session (pamh, 0);
- if (pamerr != PAM_SUCCESS) {
- did_setcred = FALSE;
- opened_session = FALSE;
- /* Throw away the credentials */
- pam_setcred (pamh, PAM_DELETE_CRED);
-
- if (gdm_slave_action_pending ())
- gdm_error (_("Couldn't open session for %s"), login);
- goto setup_pamerr;
- }
-
- /* Workaround to avoid gdm messages being logged as PAM_pwdb */
- gdm_log_shutdown ();
- gdm_log_init ();
-
- cur_gdm_disp = NULL;
-
- g_free (extra_standalone_message);
- extra_standalone_message = NULL;
-
-#ifdef HAVE_LOGINDEVPERM
- if (d->attached)
- (void) di_devperm_login ("/dev/console", pwent->pw_uid,
- pwent->pw_gid, NULL);
-#endif /* HAVE_LOGINDEVPERM */
-#ifdef HAVE_ADT
- audit_success_login (pw_change, pwent);
-#endif /* HAVE_ADT */
-
- return TRUE;
-
- setup_pamerr:
-
-#ifdef HAVE_ADT
- audit_fail_login (d, pw_change, pwent, pamerr);
-#endif /* HAVE_ADT */
-
- did_setcred = FALSE;
- opened_session = FALSE;
- if (pamh != NULL) {
- pam_handle_t *tmp_pamh;
-
- gdm_sigterm_block_push ();
- gdm_sigchld_block_push ();
- tmp_pamh = pamh;
- pamh = NULL;
- gdm_sigchld_block_pop ();
- gdm_sigterm_block_pop ();
-
- /* Throw away the credentials */
- if (credentials_set)
- pam_setcred (tmp_pamh, PAM_DELETE_CRED);
- pam_end (tmp_pamh, pamerr);
- }
- pamh = NULL;
-
- /* Workaround to avoid gdm messages being logged as PAM_pwdb */
- gdm_log_shutdown ();
- gdm_log_init ();
-
- cur_gdm_disp = NULL;
-
- g_free (extra_standalone_message);
- extra_standalone_message = NULL;
-
- return FALSE;
-}
-
-/**
- * gdm_verify_cleanup:
- *
- * Unregister the user's session
- */
-
-void
-gdm_verify_cleanup (GdmDisplay *d)
-{
- gid_t groups[1] = { 0 };
- cur_gdm_disp = d;
-
- if (pamh != NULL) {
- gint pamerr;
- pam_handle_t *tmp_pamh;
- gboolean old_opened_session;
- gboolean old_did_setcred;
-
- gdm_debug ("Running gdm_verify_cleanup and pamh != NULL");
-
- gdm_sigterm_block_push ();
- gdm_sigchld_block_push ();
- tmp_pamh = pamh;
- pamh = NULL;
- old_opened_session = opened_session;
- opened_session = FALSE;
- old_did_setcred = did_setcred;
- did_setcred = FALSE;
- gdm_sigchld_block_pop ();
- gdm_sigterm_block_pop ();
-
- pamerr = PAM_SUCCESS;
-
-#ifdef HAVE_ADT
- /*
- * User exiting.
- * If logged in, audit logout before cleaning up
- */
- if (old_opened_session && old_did_setcred) {
- audit_logout ();
- }
-#endif /* HAVE_ADT */
- /* Close the users session */
- if (old_opened_session) {
- gdm_debug ("Running pam_close_session");
- pamerr = pam_close_session (tmp_pamh, 0);
- }
-
- /* Throw away the credentials */
- if (old_did_setcred) {
- gdm_debug ("Running pam_setcred with PAM_DELETE_CRED");
- pamerr = pam_setcred (tmp_pamh, PAM_DELETE_CRED);
- }
-
- pam_end (tmp_pamh, pamerr);
-
-#ifdef HAVE_LOGINDEVPERM
- if (old_opened_session && old_did_setcred && d->attached) {
- (void) di_devperm_logout ("/dev/console");
- /* give it back to gdm user */
- (void) di_devperm_login ("/dev/console",
- gdm_daemon_config_get_gdmuid (),
- gdm_daemon_config_get_gdmgid (), NULL);
- }
-#endif /* HAVE_LOGINDEVPERM */
-
- /* Workaround to avoid gdm messages being logged as PAM_pwdb */
- gdm_log_shutdown ();
- gdm_log_init ();
- }
-
- /* Clear the group setup */
- setgid (0);
- /* this will get rid of any suplementary groups etc... */
- setgroups (1, groups);
-
- cur_gdm_disp = NULL;
-
- /* reset limits */
- gdm_reset_limits ();
-}
-
-/* used in pam */
-gboolean
-gdm_verify_setup_env (GdmDisplay *d)
-{
- gchar **pamenv;
-
- if (pamh == NULL)
- return FALSE;
-
- /* Migrate any PAM env. variables to the user's environment */
- /* This leaks, oh well */
- if ((pamenv = pam_getenvlist (pamh))) {
- gint i;
-
- for (i = 0 ; pamenv[i] ; i++) {
- putenv (g_strdup (pamenv[i]));
- }
- }
-
- return TRUE;
-}
diff --git a/daemon/verify-shadow.c b/daemon/verify-shadow.c
deleted file mode 100644
index 1f3a0e20..00000000
--- a/daemon/verify-shadow.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * GDM - The GNOME Display Manager
- * Copyright (C) 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "config.h"
-
-#include <glib/gi18n.h>
-#include <pwd.h>
-#include <shadow.h>
-#include <grp.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <string.h>
-
-#if defined (CAN_CLEAR_ADMCHG) && defined (HAVE_USERSEC_H)
-# include <usersec.h>
-#endif /* CAN_CLEAR_ADMCHG && HAVE_USERSEC_H */
-
-#ifdef HAVE_CRYPT
-# include <crypt.h>
-#endif /* HAVE_CRYPT */
-
-#include "gdm.h"
-#include "misc.h"
-#include "slave.h"
-#include "verify.h"
-#include "errorgui.h"
-#include "gdm-common.h"
-#include "gdm-daemon-config.h"
-#include "gdm-socket-protocol.h"
-
-static char *selected_user = NULL;
-
-void
-gdm_verify_select_user (const char *user)
-{
- g_free (selected_user);
- if (ve_string_empty (user))
- selected_user = NULL;
- else
- selected_user = g_strdup (user);
-}
-
-static void
-print_cant_auth_errbox (void)
-{
- gboolean is_capslock = FALSE;
- const char *basemsg;
- char *msg;
- char *ret;
-
- ret = gdm_slave_greeter_ctl (GDM_QUERY_CAPSLOCK, "");
- if ( ! ve_string_empty (ret))
- is_capslock = TRUE;
- g_free (ret);
-
- basemsg = _("\nIncorrect username or password. "
- "Letters must be typed in the correct "
- "case.");
- if (is_capslock) {
- msg = g_strconcat (basemsg, " ",
- _("Caps Lock is on."),
- NULL);
- } else {
- msg = g_strdup (basemsg);
- }
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX, msg);
- g_free (msg);
-}
-
-/**
- * gdm_verify_user:
- * @username: Name of user or NULL if we should ask
- * @display: Name of display to register with the authentication system
- * @local: boolean if local
- * @allow_retry: boolean. Not used by verify-crypt. If this code
- * allowed the user to retry, this boolean would specify
- * whether to enable this feature. We only want this
- * feature to work for normal login, not for asking for
- * root password to call the configurator.
- *
- * Provides a communication layer between the operating system's
- * authentication functions and the gdmgreeter.
- *
- * Returns the user's login on success and NULL on failure.
- */
-
-gchar *
-gdm_verify_user (GdmDisplay *d,
- const char *username,
- const gchar *display,
- gboolean local,
- gboolean allow_retry)
-{
- gchar *login, *passwd, *ppasswd;
- struct passwd *pwent;
- struct spwd *sp;
-#if defined (HAVE_PASSWDEXPIRED) && defined (HAVE_CHPASS) \
- || defined (HAVE_LOGINRESTRICTIONS)
- gchar *message = NULL;
-#endif
-#if defined (HAVE_PASSWDEXPIRED) && defined (HAVE_CHPASS)
- gchar *info_msg = NULL, *response = NULL;
- gint reEnter, ret;
-#endif
-
- if (local && d->timed_login_ok)
- gdm_slave_greeter_ctl_no_ret (GDM_STARTTIMER, "");
-
- if (username == NULL) {
- authenticate_again:
- /* Ask for the user's login */
- gdm_verify_select_user (NULL);
- gdm_slave_greeter_ctl_no_ret (GDM_MSG, _("Please enter your username"));
- login = gdm_slave_greeter_ctl (GDM_PROMPT, _("Username:"));
- if (login == NULL ||
- gdm_slave_greeter_check_interruption ()) {
- if ( ! ve_string_empty (selected_user)) {
- /* user selected */
- g_free (login);
- login = selected_user;
- selected_user = NULL;
- } else {
- /* some other interruption */
- if (local)
- gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
- g_free (login);
- return NULL;
- }
- }
- gdm_slave_greeter_ctl_no_ret (GDM_MSG, "");
-
- if (gdm_daemon_config_get_value_bool (GDM_KEY_DISPLAY_LAST_LOGIN)) {
- char *info = gdm_get_last_info (login);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX, info);
- g_free (info);
- }
- } else {
- login = g_strdup (username);
- }
- gdm_slave_greeter_ctl_no_ret (GDM_SETLOGIN, login);
-
- pwent = getpwnam (login);
-
- setspent ();
-
- /* Lookup shadow password */
- sp = getspnam (login);
-
- /* Use shadow password when available */
- if (sp != NULL) {
- ppasswd = g_strdup (sp->sp_pwdp);
- } else {
- /* In case shadow password cannot be retrieved (when using NIS
- authentication for example), use standard passwd */
- if (pwent != NULL &&
- pwent->pw_passwd != NULL)
- ppasswd = g_strdup (pwent->pw_passwd);
- else
- /* If no password can be retrieved, set it to NULL */
- ppasswd = NULL;
- }
-
- endspent ();
-
- /* Request the user's password */
- if (pwent != NULL &&
- ve_string_empty (ppasswd)) {
- /* eeek a passwordless account */
- passwd = g_strdup ("");
- } else {
- passwd = gdm_slave_greeter_ctl (GDM_NOECHO, _("Password:"));
- if (passwd == NULL)
- passwd = g_strdup ("");
- if (gdm_slave_greeter_check_interruption ()) {
- if (local)
- gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
- g_free (login);
- g_free (passwd);
- g_free (ppasswd);
- return NULL;
- }
- }
-
- if (local)
- gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
-
- if (pwent == NULL) {
- gdm_sleep_no_signal (gdm_daemon_config_get_value_int (GDM_KEY_RETRY_DELAY));
- g_warning (_("Couldn't authenticate user \"%s\""), login);
-
- print_cant_auth_errbox ();
-
- g_free (login);
- g_free (passwd);
- g_free (ppasswd);
- return NULL;
- }
-
- /* Check whether password is valid */
- if (ppasswd == NULL || (ppasswd[0] != '\0' &&
- strcmp (crypt (passwd, ppasswd), ppasswd) != 0)) {
- gdm_sleep_no_signal (gdm_daemon_config_get_value_int (GDM_KEY_RETRY_DELAY));
- g_warning (_("Couldn't authenticate user \"%s\""), login);
-
- print_cant_auth_errbox ();
-
- g_free (login);
- g_free (passwd);
- g_free (ppasswd);
- return NULL;
- }
-
- if ( ( ! gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_ROOT)||
- ( ! gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_REMOTE_ROOT) && ! local) ) &&
- pwent->pw_uid == 0) {
- g_warning (_("Root login disallowed on display '%s'"), display);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("The system administrator "
- "is not allowed to login "
- "from this screen"));
- /*gdm_slave_greeter_ctl_no_ret (GDM_ERRDLG,
- _("Root login disallowed"));*/
- g_free (login);
- g_free (passwd);
- g_free (ppasswd);
- return NULL;
- }
-
-#ifdef HAVE_LOGINRESTRICTIONS
-
- /* Check with the 'loginrestrictions' function
- if the user has been disallowed */
- if (loginrestrictions (login, 0, NULL, &message) != 0) {
- g_warning (_("User %s not allowed to log in"), login);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("\nThe system administrator "
- "has disabled your "
- "account."));
- g_free (login);
- g_free (passwd);
- g_free (ppasswd);
- if (message != NULL)
- free (message);
- return NULL;
- }
-
- if (message != NULL)
- free (message);
- message = NULL;
-
-#else /* ! HAVE_LOGINRESTRICTIONS */
-
- /* check for the standard method of disallowing users */
- if (pwent->pw_shell != NULL &&
- (strcmp (pwent->pw_shell, "/sbin/nologin") == 0 ||
- strcmp (pwent->pw_shell, "/bin/true") == 0 ||
- strcmp (pwent->pw_shell, "/bin/false") == 0)) {
- g_warning (_("User %s not allowed to log in"), login);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("\nThe system administrator "
- "has disabled your "
- "account."));
- /*gdm_slave_greeter_ctl_no_ret (GDM_ERRDLG,
- _("Login disabled"));*/
- g_free (login);
- g_free (passwd);
- g_free (ppasswd);
- return NULL;
- }
-
-#endif /* HAVE_LOGINRESTRICTIONS */
-
- g_free (passwd);
- g_free (ppasswd);
-
- if ( ! gdm_slave_check_user_wants_to_log_in (login)) {
- g_free (login);
- login = NULL;
- goto authenticate_again;
- }
-
- if ( ! gdm_setup_gids (login, pwent->pw_gid)) {
- g_warning (_("Cannot set user group for %s"), login);
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("\nCannot set your user group; "
- "you will not be able to log in. "
- "Please contact your system administrator."));
- g_free (login);
- return NULL;
- }
-
-#if defined (HAVE_PASSWDEXPIRED) && defined (HAVE_CHPASS)
-
- switch (passwdexpired (login, &info_msg)) {
- case 1 :
- g_warning (_("Password of %s has expired"), login);
- 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);
-
- do {
- ret = chpass (login, response, &reEnter, &message);
- g_free (response);
-
- if (ret != 1) {
- if (ret != 0) {
- gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
- _("\nCannot change your password; "
- "you will not be able to log in. "
- "Please try again later or contact "
- "your system administrator."));
- } else if ((reEnter != 0) && (message)) {
- response = gdm_slave_greeter_ctl (GDM_NOECHO, message);
- if (response == NULL)
- response = g_strdup ("");
- }
- }
-
- g_free (message);
- message = NULL;
-
- } while ( ((reEnter != 0) && (ret == 0))
- || (ret ==1) );
-
- g_free (response);
- g_free (message);
-
- if ((ret != 0) || (reEnter != 0)) {
- return NULL;
- }
-
-#if defined (CAN_CLEAR_ADMCHG)
- /* The password is changed by root, clear the ADM_CHG
- flag in the passwd file */
- ret = setpwdb (S_READ | S_WRITE);
- if (!ret) {
- upwd = getuserpw (login);
- if (upwd == NULL) {
- ret = -1;
- }
- else {
- upwd->upw_flags &= ~PW_ADMCHG;
- ret = putuserpw (upwd);
- if (!ret) {
- ret = endpwdb ();
- }
- }
- }
-
- if (ret) {
- 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."));
- }
-
-#else /* !CAN_CLEAR_ADMCHG */
- 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."));
-
-#endif /* CAN_CLEAR_ADMCHG */
-
- break;
-
- case 2 :
- g_warning (_("Password of %s has expired"), login);
- 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);
- return NULL;
- break;
-
- case -1 :
- g_warning (_("Internal error on passwdexpired"));
- 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);
- return NULL;
- break;
-
- default :
- g_free (info_msg);
- break;
- }
-
-#endif /* HAVE_PASSWDEXPIRED && HAVE_CHPASS */
-
- return login;
-}
-
-/**
- * gdm_verify_setup_user:
- * @login: The name of the user
- * @display: The name of the display
- *
- * This is used for auto loging in. This just sets up the login
- * session for this user
- */
-
-gboolean
-gdm_verify_setup_user (GdmDisplay *d,
- const gchar *login,
- const gchar *display,
- char **new_login)
-{
- struct passwd *pwent;
-
- *new_login = NULL;
-
- pwent = getpwnam (login);
- if (pwent == NULL) {
- g_warning (_("Cannot get passwd structure for %s"), login);
- return FALSE;
- }
-
- if ( ! gdm_setup_gids (login, pwent->pw_gid)) {
- g_warning (_("Cannot set user group for %s"), login);
- gdm_errorgui_error_box (d,
- GTK_MESSAGE_ERROR,
- _("\nCannot set your user group; "
- "you will not be able to log in. "
- "Please contact your system administrator."));
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * gdm_verify_cleanup:
- *
- * Unregister the user's session */
-
-void
-gdm_verify_cleanup (GdmDisplay *d)
-{
- gid_t groups[1] = { 0 };
-
- /* Clear the group setup */
- setgid (0);
- /* this will get rid of any suplementary groups etc... */
- setgroups (1, groups);
-}
-
-/* used in pam */
-gboolean
-gdm_verify_setup_env (GdmDisplay *d)
-{
- return TRUE;
-}
-
-/* EOF */
diff --git a/daemon/verify.h b/daemon/verify.h
deleted file mode 100644
index a861c6e4..00000000
--- a/daemon/verify.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef GDM_VERIFY_H
-#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 */
-gchar *gdm_verify_user (GdmDisplay *d,
- const char *username,
- const gchar *display,
- gboolean local,
- gboolean allow_retry);
-void gdm_verify_cleanup (GdmDisplay *d);
-void gdm_verify_check (void);
-void gdm_verify_select_user (const char *user);
-/* used in pam */
-gboolean gdm_verify_setup_env (GdmDisplay *d);
-gboolean gdm_verify_setup_user (GdmDisplay *d,
- const gchar *login,
- const gchar *display,
- char **new_login);
-
-#endif /* GDM_VERIFY_H */
-
-/* EOF */
diff --git a/daemon/xdmcp.c b/daemon/xdmcp.c
deleted file mode 100644
index 2a07efe7..00000000
--- a/daemon/xdmcp.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/* -*- 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
- * 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
- */
-
-
-#include "config.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-
-#include "display.h"
-#include "gdm-daemon-config.h"
-#include "gdm-log.h"
-
-#include "gdm-xdmcp-manager.h"
-#include "xdmcp.h"
-
-#ifdef HAVE_LIBXDMCP
-
-static GdmXdmcpManager *xdmcp_manager = NULL;
-
-gboolean
-gdm_xdmcp_init (void)
-{
- xdmcp_manager = gdm_xdmcp_manager_new ();
- return TRUE;
-}
-
-void
-gdm_xdmcp_run (void)
-{
- if (xdmcp_manager != NULL) {
- gdm_xdmcp_manager_start (xdmcp_manager, NULL);
- }
-}
-
-void
-gdm_xdmcp_close (void)
-{
- g_object_unref (xdmcp_manager);
-}
-
-static void
-reconnect_to_parent (GdmDisplay *to)
-{
- GError *error;
- gchar *command_argv[10];
- const gchar *proxyreconnect = gdm_daemon_config_get_value_string (GDM_KEY_XDMCP_PROXY_RECONNECT);
-
- command_argv[0] = (char *)proxyreconnect;
- command_argv[1] = "--display";
- command_argv[2] = to->parent_disp;
- command_argv[3] = "--display-authfile";
- command_argv[4] = to->parent_auth_file;
- command_argv[5] = "--to";
- command_argv[6] = to->name;
- command_argv[7] = "--to-authfile";
- command_argv[8] = to->authfile;
- command_argv[9] = NULL;
-
- gdm_debug ("XDMCP: migrating display by running "
- "'%s --display %s --display-authfile %s --to %s --to-authfile %s'",
- proxyreconnect,
- to->parent_disp, to->parent_auth_file,
- to->name, to->authfile);
-
- error = NULL;
- if (!g_spawn_async (NULL, command_argv, NULL, 0, NULL, NULL, NULL, &error)) {
- gdm_error (_("%s: Failed to run "
- "'%s --display %s --display-authfile %s --to %s --to-authfile %s': %s"),
- "gdm_xdmcp_migrate",
- proxyreconnect,
- to->parent_disp, to->parent_auth_file,
- to->name, to->authfile,
- error->message);
- g_error_free (error);
- }
-}
-
-void
-gdm_xdmcp_migrate (GdmDisplay *from, GdmDisplay *to)
-{
- if (from->type != TYPE_XDMCP_PROXY ||
- to->type != TYPE_XDMCP_PROXY)
- return;
- g_free (to->parent_disp);
- to->parent_disp = from->parent_disp;
- from->parent_disp = NULL;
-
- g_free (to->parent_auth_file);
- to->parent_auth_file = from->parent_auth_file;
- from->parent_auth_file = NULL;
-
- reconnect_to_parent (to);
-}
-
-#else /* HAVE_LIBXDMCP */
-
-/* Here come some empty stubs for no XDMCP support */
-int
-gdm_xdmcp_init (void)
-{
- gdm_error (_("%s: No XDMCP support"), "gdm_xdmcp_init");
- return FALSE;
-}
-
-void
-gdm_xdmcp_run (void)
-{
- gdm_error (_("%s: No XDMCP support"), "gdm_xdmcp_run");
-}
-
-void
-gdm_xdmcp_close (void)
-{
- gdm_error (_("%s: No XDMCP support"), "gdm_xdmcp_close");
-}
-
-void
-gdm_xdmcp_migrate (GdmDisplay *from, GdmDisplay *to)
-{
- gdm_error (_("%s: No XDMCP support"), "gdm_xdmcp_migrate");
-}
-
-#endif /* HAVE_LIBXDMCP */
diff --git a/daemon/xdmcp.h b/daemon/xdmcp.h
deleted file mode 100644
index d9870ffd..00000000
--- a/daemon/xdmcp.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- 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
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef GDM_XDMCP_H
-#define GDM_XDMCP_H
-
-/* 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_migrate (GdmDisplay *from, GdmDisplay *to);
-
-#endif /* GDM_XDMCP_H */