23245293 Move gdm to Userland and update to 3.18.2
authorAlan Coopersmith <Alan.Coopersmith@Oracle.COM>
Mon, 31 Oct 2016 18:25:15 -0700
changeset 7201 bcc18175756d
parent 7200 bc003d56ef5a
child 7202 f6004455ce0a
23245293 Move gdm to Userland and update to 3.18.2 PSARC/2016/448 GNOME Display Manager (GDM) v3.18 23245463 Move desktop-startup 0.38.0 to Userland 16882229 Desktop packages should remove restart_fmri=svc:/system/rbac:default 21020801 Add "RO" to res1 field of auth_attr.d files in gdm 21020166 html help files in gdm for RBAC profiles and authorizations must go 22134482 svc:/application/graphical-login/gdm goes into maintenance when gdm coredumps
components/gnome/gdm/Makefile
components/gnome/gdm/desktop-startup.p5m
components/gnome/gdm/files/0011.env
components/gnome/gdm/files/0020.pre-localization
components/gnome/gdm/files/dtstart
components/gnome/gdm/files/dtstartup.copyright
components/gnome/gdm/files/gdm-launch-environment.pam
components/gnome/gdm/files/gdm.8
components/gnome/gdm/files/gdm.auth_attr
components/gnome/gdm/files/gdm.prof_attr
components/gnome/gdm/files/gdm.user_attr
components/gnome/gdm/files/gdm.xml
components/gnome/gdm/files/org.gnome.login-screen.gschema.override
components/gnome/gdm/files/svc-gdm
components/gnome/gdm/files/xterm.desktop
components/gnome/gdm/gdm.license
components/gnome/gdm/gdm.p5m
components/gnome/gdm/patches/0001-fix-shutdown-crash.patch
components/gnome/gdm/patches/0002-disable-systemd.patch
components/gnome/gdm/patches/0003-solaris-pam.patch
components/gnome/gdm/patches/0004-sdtlogin.patch
components/gnome/gdm/patches/0005-smf-contracts.patch
components/gnome/gdm/patches/0006-etc-default-login.patch
components/gnome/gdm/patches/0007-solaris-notty.patch
components/gnome/gdm/patches/0008-audio-settings-restore.patch
components/gnome/gdm/patches/0009-xauth-directory.patch
components/gnome/gdm/patches/0010-logindevperm.patch
components/gnome/gdm/patches/0011-vtswitch-on-exit.patch
components/gnome/gdm/patches/0012-restart-limit.patch
components/gnome/gdm/patches/0013-bind_textdomain_codeset.patch
components/gnome/gdm/patches/0014-logout-wtmpx.patch
components/gnome/gdm/patches/0015-display-etc-issue-file.patch
components/gnome/gdm/patches/0016-solaris-xserver-path.patch
components/gnome/gdm/patches/0017-libwrap-library-path.patch
components/gnome/gdm/patches/0018-service-log.patch
components/gnome/gdm/patches/0019-no-wayland.patch
components/gnome/gdm/test/results-64.master
components/meta-packages/incorporation-cache
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/Makefile	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,121 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+#
+BUILD_BITS= 		64
+# All components using gobject-introspection must be built with gcc as
+# gobject-introspection does not produce correct results when using Studio.
+COMPILER= 		gcc
+include ../../../make-rules/shared-macros.mk
+
+COMPONENT_NAME=		gdm
+COMPONENT_VERSION=	3.18.2
+COMPONENT_PROJECT_URL=  https://wiki.gnome.org/Projects/GDM
+COMPONENT_ARCHIVE_HASH= \
+	sha256:549235247611d74f0d5d5a4aa01ba9350a4d3468e44ac013b40791c6a986f822
+COMPONENT_BUGDB=        gnome/gdm
+
+TPNO=			25845
+
+# Needs accountsservice, not available on S11.
+include $(WS_MAKE_RULES)/no-evaluation.mk
+
+include $(WS_MAKE_RULES)/gnome-component.mk
+
+# Regenerate configure after patches modify configure.ac
+COMPONENT_PREP_ACTION += ( cd $(@D); autoreconf -fiv);
+
+# Make sure we haven't broken the SMF manifest formatting
+COMPONENT_PREP_ACTION += \
+    ( /usr/sbin/svccfg validate $(COMPONENT_DIR)/files/gdm.xml );
+
+# Assumes GNU msgfmt in PATH.
+COMPONENT_BUILD_ENV += PATH="$(GNUBIN):$(PATH)"
+CONFIGURE_ENV += PATH="$(GNUBIN):$(PATH)"
+
+# uuid detection fails due to Solaris bug 15586738.
+CONFIGURE_OPTIONS += ac_cv_search_uuid_to_string=generic
+CONFIGURE_ENV += UUID_CFLAGS="-I$(USRINCDIR)/uuid"
+CONFIGURE_ENV.32 += UUID_LIBS="-luuid"
+CONFIGURE_ENV.64 += UUID_LIBS="-L$(USRLIBDIR64) -luuid"
+
+# intltool may or may not be run depending on previous state of build dir
+COMPONENT_TEST_TRANSFORMS += "-e '/\/usr\/bin\/intltool-update/d'"
+
+CONFIGURE_OPTIONS += --enable-debug
+CONFIGURE_OPTIONS += --enable-authentication-scheme=pam
+CONFIGURE_OPTIONS += --enable-gdm-xsession
+CONFIGURE_OPTIONS += --enable-ipv6
+CONFIGURE_OPTIONS += --enable-rbac-shutdown=solaris.system.shutdown
+CONFIGURE_OPTIONS += --enable-shared
+CONFIGURE_OPTIONS += --disable-static
+CONFIGURE_OPTIONS += --disable-systemd-journal
+CONFIGURE_OPTIONS += --disable-wayland-support
+CONFIGURE_OPTIONS += --with-console-kit
+CONFIGURE_OPTIONS += --with-pic
+CONFIGURE_OPTIONS += --without-plymouth
+CONFIGURE_OPTIONS += --without-systemd
+CONFIGURE_OPTIONS += --without-systemdsystemunitdir
+CONFIGURE_OPTIONS += --with-user=gdm --with-group=gdm
+CONFIGURE_OPTIONS += --with-default-path='$(USRBINDIR):$(USRSBINDIR)'
+CONFIGURE_OPTIONS += --with-xauth-dir=/tmp
+CONFIGURE_OPTIONS += --with-initial-vt=7
+CONFIGURE_OPTIONS += --libexecdir="$(USRLIBDIR)/gdm"
+
+REQUIRED_PACKAGES += data/iso-codes
+REQUIRED_PACKAGES += developer/documentation-tool/itstool
+REQUIRED_PACKAGES += file/gnu-coreutils
+REQUIRED_PACKAGES += gnome/accessibility/orca
+REQUIRED_PACKAGES += gnome/gnome-session
+REQUIRED_PACKAGES += gnome/gnome-shell
+REQUIRED_PACKAGES += gnome/gsettings-desktop-schemas
+REQUIRED_PACKAGES += gnome/zenity
+REQUIRED_PACKAGES += library/desktop/gdk-pixbuf
+REQUIRED_PACKAGES += library/desktop/gtk3
+REQUIRED_PACKAGES += library/desktop/xdg/libcanberra
+REQUIRED_PACKAGES += library/glib2
+REQUIRED_PACKAGES += library/gnome/dconf
+REQUIRED_PACKAGES += library/gnome/yelp-tools
+REQUIRED_PACKAGES += library/xdg/consolekit
+REQUIRED_PACKAGES += system/core-os
+REQUIRED_PACKAGES += system/input-method/imf-startup
+REQUIRED_PACKAGES += system/io/audio
+REQUIRED_PACKAGES += system/library/accountsservice
+REQUIRED_PACKAGES += system/library/dbus
+REQUIRED_PACKAGES += system/library/fontconfig
+REQUIRED_PACKAGES += terminal/xterm
+REQUIRED_PACKAGES += x11/keyboard/xkb-utilities
+REQUIRED_PACKAGES += x11/library/libx11
+REQUIRED_PACKAGES += x11/library/libxau
+REQUIRED_PACKAGES += x11/library/libxdmcp
+REQUIRED_PACKAGES += x11/library/libxft
+REQUIRED_PACKAGES += x11/library/libxi
+REQUIRED_PACKAGES += x11/library/libxinerama
+REQUIRED_PACKAGES += x11/server/xephyr
+REQUIRED_PACKAGES += x11/server/xserver-common
+REQUIRED_PACKAGES += x11/session/xinit
+REQUIRED_PACKAGES += x11/x11-server-utilities
+
+# Required for testing, not building or running:
+REQUIRED_PACKAGES += developer/test/check
+REQUIRED_PACKAGES += library/libxml2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/desktop-startup.p5m	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,44 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+#
+
+<transform file path=etc/X11/xinit/xinitrc.d/.+ -> set mode 0555>
+<transform file path=.*/(.*) -> set action.hash files/%<1>>
+set name=pkg.fmri \
+    value=pkg:/system/display-manager/[email protected],$(BUILD_VERSION)
+set name=pkg.summary value="Desktop startup scripts in xinitrc.d"
+set name=info.classification \
+    value="org.opensolaris.category.2008:Desktop (GNOME)/Scripts"
+set name=org.opensolaris.arc-caseid value=PSARC/2016/448
+set name=org.opensolaris.consolidation value=$(CONSOLIDATION)
+#
+file path=etc/X11/xinit/xinitrc.d/0011.env
+file path=etc/X11/xinit/xinitrc.d/0020.pre-localization
+file path=usr/bin/dtstart
+license files/dtstartup.copyright license=Oracle
+
+# Programs run by various scripts in this package
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/gnome-session
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/xmodmap
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/xrdb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/files/0011.env	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,56 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+#
+
+
+DESKTOP_SESSION=${DESKTOP_SESSION:-"xdm"}
+MAIL=${MAIL-"/var/mail/$USER"}
+SHELL=${SHELL-"/bin/sh"}
+DISPLAY=${DISPLAY-":0"}
+TERM=${TERM-"xterm"}
+
+case "$DESKTOP_SESSION" in
+gnome|GNOME|JDS)
+    EDITOR=${EDITOR:-"gedit"}
+    ;;
+kde|KDE)
+    EDITOR=${EDITOR:-"kedit"}
+    ;;
+*)
+    EDITOR=${EDITOR:-"vi"}
+    ;;
+esac
+
+export EDITOR MAIL TERM SHELL DISPLAY
+
+if /usr/bin/xmodmap | /usr/bin/grep mod4 | /usr/bin/grep Alt > /dev/null 2>/dev/null
+then
+    /usr/bin/xmodmap \
+	-e "clear Mod1" \
+        -e "clear Mod4" \
+        -e "add Mod1 = Alt_L" \
+        -e "add Mod1 = Alt_R" \
+        -e "add Mod4 = Meta_L" \
+        -e "add Mod4 = Meta_R"
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/files/0020.pre-localization	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,67 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+#
+
+# To determine the character set used for filenames with
+# glib's g_filename_to/from_utf8() functions, we set the
+# environment variables G_FILENAME_ENCODING and G_BROKEN_FILENAMES.
+#
+# G_BROKEN_FILENAMES, when set, lets the functions take the
+# character set for the current locale for filename's encoding.
+#
+# G_FILENAME_ENCODING, which is introduced to glib 2.3.x and later, may be
+# set to a comma-separated list of character set names.
+# The special token "@locale" is taken to mean the character set
+# for the current locale. The first character set from the list is taken
+# as the filename encoding.
+#
+# If G_FILENAME_ENCODING is not set, but G_BROKEN_FILENAMES is, the
+# character set of the current locale is taken as the filename encoding.
+
+export G_BROKEN_FILENAMES=yes
+export G_FILENAME_ENCODING=@locale,UTF-8
+
+# Fixes Sun Bug 6583891 / Oracle Bug 15411677
+case $LANG in
+    ja*) export VTE_CJK_WIDTH=1;;
+    ko*) export VTE_CJK_WIDTH=1;;
+    zh*) export VTE_CJK_WIDTH=1;;
+    *) ;;
+esac
+
+# Fixes Sun Bug 6555226 / Oracle Bug 15395640
+if [[ "$LANG" == "zh" ]] ; then
+    export LANGUAGE=zh:zh_CN.EUC
+fi
+
+# Locale specific .desktop files
+if [[ -d /usr/share/locale/$LANG/xdg ]] ; then
+    XDG_DATA_DIRS=${XDG_DATA_DIRS:-"/usr/share"}
+    XDG_DATA_DIRS=${XDG_DATA_DIRS}:/usr/share/locale/$LANG/xdg
+    export XDG_DATA_DIRS
+fi
+
+if [[ -x /usr/bin/xdg-user-dirs-update ]]; then
+    /usr/bin/xdg-user-dirs-update
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/files/dtstart	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,82 @@
+#!/bin/bash
+#
+# Script for starting a desktop session
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+#
+
+MYNAME=$(basename $0)
+
+usage() {
+    echo "Usage: $0 session_name"
+    echo "    This script loads scripts in /etc/X11/xinit/xinitrc.d"
+    echo "    and runs a session manager."
+    echo "    session_name is gnome, twm or xdm"
+}
+
+if [ $# -ne 1 ]; then
+    usage
+    exit 1
+fi
+
+case "$1" in
+    -h|--help|-\?)
+        usage
+        exit 0
+    ;;
+esac
+
+SESSION_NAME="$1"
+shift
+
+case "$SESSION_NAME" in
+gdm|GDM|gnome|GNOME|jds|JDS) SESSION_MANAGER=/usr/bin/gnome-session ;;
+twm|TWM) SESSION_MANAGER=/usr/bin/twm ;;
+xdm|XDM) SESSION_MANAGER=/usr/lib/X11/xdm/Xsession ;;
+console) exit 0 ;;
+*)
+    if [ "x$SESSION_NAME" != x ] ; then
+        SESSION_MANAGER=$SESSION_NAME
+    fi
+    if [ ! -x $SESSION_NAME ] ; then
+        echo "Could not find session startup for $SESSION_NAME"
+        SESSION_MANAGER=/usr/bin/twm
+    fi
+
+esac
+
+# GDM session worker sets DESKTOP_SESSION environment from .desktop file.
+export DESKTOP_SESSION=$SESSION_NAME
+
+# run all system xinitrc shell scripts.
+if [ -d /etc/X11/xinit/xinitrc.d ]; then
+    for i in /etc/X11/xinit/xinitrc.d/* ; do
+        if [ -x "$i" ]; then
+            . "$i"
+        fi
+    done
+fi
+
+exec $SESSION_MANAGER $@
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/files/dtstartup.copyright	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,1 @@
+Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/files/gdm-launch-environment.pam	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,9 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+#
+# PAM configuration for gdm environment to display login screen
+# (explicit because of pam_allow).
+#
+gdm-launch-environment	auth	required	pam_unix_cred.so.1
+gdm-launch-environment	auth	sufficient	pam_allow.so.1
+gdm-launch-environment	account	sufficient	pam_allow.so.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/files/gdm.8	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,1080 @@
+.TH gdm 8 "28 Dec 2015"
+.SH "NAME"
+gdm \- GDM (GNOME Display Manager)
+.SH "SYNOPSIS"
+.PP
+\fB/usr/sbin/gdm\fR [\fB--help\fR] [\fB--fatal-warnings\fR] [\fB--timed-exit\fR] [\fB--version\fR]
+.SH "DESCRIPTION"
+.PP
+GDM is the GNOME Display Manager, a program used for login session management\&.
+GDM supports managing the console display, other attached displays, XDMCP
+displays, and flexible (or on-demand) displays\&.  Flexible displays make use
+of the Virtual Terminals (VT) interfaces to allow user switching, so that
+multiple users can run simultaneous sessions sharing the same console\&.
+GDM uses ConsoleKit to manage what sessions are active on the system\&.
+GDM supports a number of configuration interfaces which are described in
+later sections of this manpage\&.
+.PP
+For each display that GDM is configured to manage, the
+\fBgdm\fR program will launch a slave daemon which does the
+work to actually manage the display\&.  The slave daemon will start the login
+greeter GUI program, the program that the user interacts with\&.  Refer to the
+"Login Greeter GUI" section below for more information about how the
+user interface works\&.
+.PP
+If Virtual Terminals are supported on your system, you can start a flexible
+display via the "User Switcher" panel applet\&.  You may need to add
+this applet to your panel to make use of it\&.  You can also use the 
+\fBgdmflexiserver\fR(1)
+command to start flexible displays from the command line\&.
+.PP
+On Solaris, the GDM service is managed by the 
+\fBsmf\fR(7)
+service management facility under the service identifier
+\fIsvc:/application/graphical-login/gdm\fR\&.
+On Solaris, it is recommended that you use the
+\fBsvcadm\fR(8) utility to enable and disable the
+"gdm" service instead of killing the daemon with a SIGTERM signal.
+.PP
+GDM supports libaudit and Solaris auditing\&.  Refer to the 
+"System Administration Guide: Security Services" and the
+\fBaudit\fR(8) manpage for more information\&.
+On Solaris, GDM also uses
+\fBlogindevperm\fR(5)
+to ensure that device permissions are set properly for the user on login\&.
+.SH "OPTIONS"
+.PP
+The following options are supported by \fBgdm\fR:
+.TP 30
+.B --fatal-warnings
+Make all warnings fatal\&.  Useful for debugging\&.
+.TP 30
+.B --help
+Display detailed usage message\&.
+.TP 30
+.B --timed-exit
+Exit after 30 seconds\&.  Useful for debugging\&.
+.TP 30
+.B --version
+Display the GDM version\&.
+.SH "ENVIRONMENT VARIABLES"
+.PP
+See
+\fBenviron\fR(5)
+for descriptions of environment variables\&.
+.PP
+When the following description refers to "scripts", these are
+referring to the GDM \fBInit\fR, \fBPostLogin\fR,
+\fBPreSession\fR, and \fBPostSession\fR scripts\&.
+.TP 30
+.B DESKTOP_SESSION
+For any user session started by GDM, this environment variable is set to the
+session name the user has chosen in the login GUI, such as "gnome" to
+indicate that the \fB/usr/share/xsession/gnome\&.desktop\fR
+session file was used to launch the session\&. 
+.TP 30
+.B DISPLAY
+When running scripts and for any user session started by GDM, this environment
+variable is set to the Xserver display value associated with the session\&.
+.TP 30
+.B DESKTOP_SESSION
+For any user session started by GDM, this environment variable is set to the
+keyboard layout that the user has chosen in the login GUI\&.
+.TP 30
+.B HOME
+When running scripts and for any user session started by GDM, this environment
+variable is set to the home directory associated with the user\&.
+.TP 30
+.B LANG
+For any user session started by GDM, this environment variable is set to the
+langauge choice selected when the user logged in\&.
+.TP 30
+.B REMOTE_HOST
+When running scripts, this environment variable is set to the hostname if the
+session is non-local (e\&.g\&. XDMCP)\&.
+.TP 30
+.B RUNNING_UNDER_GDM
+When running scripts, this environment variable is set to "true", so
+that they can identify when they are executed by the GDM process\&.
+.TP 30
+.B SHELL
+When running scripts and for any user session started by GDM, this environment
+variable is set to the shell associated with the session\&.
+.TP 30
+.B USER
+When running scripts and for any user session started by GDM, this environment
+variable is set to the username associated with the session\&.
+.TP 30
+.B USERNAME
+When running scripts and for any user session started by GDM, this environment
+variable is set to the username associated with the session\&.
+.TP 30
+.B XAUTHORITY
+When running scripts and for any user session started by GDM, this environment
+variable is set to the Xserver Xauthority file being used by the session\&.
+.TP 30
+.B XDG_SESSION_COOKIE
+This environment variable is provided by ConsoleKit, and this value is set
+for any user session started by GDM so that ConsoleKit can properly identify
+the session\&.
+.SH "EXTENDED DESCRIPTION"
+.SS "Login Greeter GUI"
+.PP
+The login greeter GUI allows the user to specify how their user session should
+be started and ensures that the user authenticates before gaining access to
+their user session\&.  Authentication can be disabled if desired\&.
+.PP
+GDM makes use of
+\fBpam\fR(3PAM)
+to manage how the user authenticates (for example, by entering a username and
+password, via a SmartCard, fingerprint reader, etc\&.)\&.  If authentication is
+not desired, then GDM provides two configuration options which can be used
+to bypass it: "Automatic Login" and "Timed Login"\&.  These
+are not enabled by default, but can be turned on if desired\&.
+.PP
+The Automatic Login feature will cause GDM to bypass the login greeter GUI
+entirely and immediately start a session for the user specified in the GDM
+configuration\&.  The Timed Login feature will display the login greeter GUI for
+a number of seconds specified in the GDM configuration\&.  If no user logs in
+before the timeout, then GDM will automatically start the user session for the
+user specified in the GDM configuration\&.  Timed Login is useful if you wish to
+have the opportunity to login as a different user on some occasions\&.  Obviously
+neither Automatic Login or Timed Login are secure, and they should only be used
+on systems where the security provided by authentication is not needed\&.
+.PP
+GDM normally uses a PAM stack named "gdm"\&.  When Automatic Login or
+Timed Login is enabled, then GDM instead uses a PAM stack named
+"gdm-autologin"\&.  Note that Automatic Login and Timed Login will not
+work properly if the "gdm-autologin" PAM stack is not defined in your
+PAM configuration\&.
+.PP
+The login greeter GUI provides two mechanisms for specifying which user is
+logging into the system\&.  Either the "Face Browser" can be used,
+or GDM can prompt the user with the requests specified by the system PAM
+configuration\&.  By default, this means entering both the username and password
+by hand\&.
+.PP
+The Face Browser is designed to work when PAM is configured to allow users to
+select their username, so it is not useful with certain PAM configurations
+(such as when the username is identified via a SmartCard or fingerprint)\&.  The
+Face Browser obviously exposes usernames to anyone with access to the machine,
+so users may wish to disable it if this is considered a security issue\&.
+.PP
+When the Face Browser is enabled, a list of users will appear in the login
+greeter GUI\&.  An icon for each user is shown, and users can specify what icon
+is associated with their user\&.  If the user has an image file named
+\fB~/\&.face\fR, then GDM will associate this image with the user\&.
+If the user does not have such an image file, a default icon is displayed\&.
+Image files must be no larger than 64K in size, or they are ignored by GDM\&.
+.PP
+The login greeter GUI can be configured to provide "Shutdown",
+"Restart", and "Suspend" buttons which allow the user to
+shutdown, restart, or suspend the system if desired\&.  On Solaris, the buttons
+will only be available if the "solaris\&.system\&.shutdown" authorization name is
+specified for the "gdm" user in the
+\fB/etc/user_attr\fR file\&.  For example, the
+\fB/etc/user_attr\fR file should include the following line to
+make these buttons available from the GDM login GUI screen\&.
+.PP
+.nf
+gdm::::type=normal;auths=solaris\&.system\&.shutdown
+.fi
+.PP
+While the login greeter GUI is displayed, a panel is provided at the bottom
+of the screen which provides useful information, interfaces that allow the
+user to specify how their session should be started, and interfaces to help
+the user navigate the login screen\&.  These include:
+.sp
+.in +2
+\(bu
+.mk
+.in +3
+.rt
+A clock, showing the date and time\&.
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+What type of session to run\&.
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+An alternative language to use\&.
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+An alternative keyboard layout (if supported)\&.
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+The ability to launch assistive technology programs if desired\&.
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+The ability to monitor the system battery (if using a system with a battery)\&.
+.sp
+.in -3
+.in -2
+.PP
+The login greeter GUI also allows the user to take a screenshot\&.  If the
+user presses the keybindng associated with printing the screen, then the
+\fBgdm-screenshot\fR is run to take the screenshot\&.
+.SS "Accessibility"
+.PP
+GDM supports accessibility\&.  Users can click on the accessibility icon on
+the panel to specify which assistive programs should be launched with the
+login GUI programs\&.  It is also possible to configure a system so that 
+needed assistive programs should always be launched\&.
+.SS "Security"
+.PP
+The GDM login GUI programs are run with a dedicated user id and group id\&.
+By default "gdm" is used for both the user id and group id, but these
+values are configurable\&.  The reason for using this special user and group is
+to make sure that the GDM user interfaces run as a user without unnecessary
+privileges, so that in the unlikely case that someone finds a weakness in the
+GUI, they will not gain access to a privileged account on the machine\&.
+.PP
+Note that the GDM user and group do have some privileges beyond what a normal
+user has\&.  This user and group has access to the Xserver authorization
+directory which contains all of the Xserver authorization files and other
+private information\&.  This means that someone who gains the GDM user/group
+privileges can then connect to any running Xserver session\&.  Do not, under any
+circumstances, make the GDM user/group a user/group that might be easy to get
+access to, such as the user "\fBnobody\fR"\&.
+.PP
+File permissions are set on the authorization files so that only the user
+has read and write access to ensure that users are unable to access the 
+authorization files belonging to other users\&.
+.SS "XDMCP"
+.PP
+XDMCP (X Display Manager Control Protocol) displays the login screen
+and resulting session on a remote machine over the network interface\&.
+By default, XDMCP is disabled in GDM\&.  However, GDM can be configured
+to enable XDMCP so that users can log into the system from remote hosts\&.
+By default, GDM listens to UDP port 177, although this can be configured\&.
+GDM responds to QUERY and BROADCAST_QUERY requests by sending a WILLING
+packet to the originator\&.
+.PP
+GDM provides configuration options that make GDM more resistant to
+denial-of-service attacks on the XDMCP service\&.  The default values should
+work for most systems, but several protocol parameters, handshaking timeouts,
+and so on can be fine-tuned to make it more secure\&.  It is not recommended
+that you modify the XDMCP configuration unless you know what you are doing\&.
+.PP
+GDM grants access to the hosts specified in the GDM service section of your
+TCP Wrappers configuration file\&.  Refer to the \fBlibwrap\fR(3)
+manpage for more information\&.  GDM does not support remote display access
+control on systems without TCP Wrapper support\&.
+.PP
+GDM can also be configured to honor INDIRECT queries and present a host
+chooser to the remote display\&. GDM remembers the user\&'s choice and forwards
+subsequent requests to the chosen manager\&. GDM also supports an extension
+to the protocol which makes GDM forget the redirection once the user\&'s
+connection succeeds\&.  This extension is only supported if both daemons are
+GDM\&. This extension is transparent and is ignored by XDM or other daemons
+that implement XDMCP\&.
+.PP
+GDM only supports the MIT-MAGIC-COOKIE-1 authentication system\&. Because of
+this, the cookies are transmitted as clear text\&. Therefore, you should be
+careful about the network where you use this\&. That is, be careful about
+where your XDMCP connection is going\&. Note that if snooping is possible, an
+attacker could snoop your password as you log in, so a better XDMCP
+authentication would not help you much anyway\&. If snooping is possible and
+undesirable, you should use \fBssh\fR(1) for tunneling an X connection, rather
+then using GDM\&'s XDMCP\&. Think of XDMCP as a sort of graphical telnet,
+with the same security issues\&.
+.SS "GDM Configuration"
+.PP
+ConsoleKit interfaces are used to configure how GDM should manage displays
+in a multiseat environment, so to configure multiseat please refer to the
+\fBconsole-kit-daemon\fR(8)
+manpage\&.
+.PP
+GDM also provides a number of configuration interfaces which allow the user to
+specify how GDM should operate\&.  The configuration available for the GDM
+daemon and the GDM login greeter GUI are described below\&.  GDM also provides
+scripting interfaces and other interfaces to configure how sessions are started
+which are described in the "GDM Login Scripts and Session Files"
+section of this manpage\&.
+.PP
+The default system configuration for the GDM daemon is stored in the file
+\fB/etc/gdm/gdm\&.schemas\fR, and accessed by GDM via GConf\&.
+Users are not recommended to modify this file since it may be overwritten on
+upgrade\&.  Instead users should override these settings by specifying values
+in the \fB/etc/gdm/custom\&.conf\fR file, which is in standard INI format\&.
+.PP
+The settings below are in "group/key=\fIdefault_value\fR \fItype\fR" format\&.
+The type can be \fIstring\fR, \fIinteger\fR, or \fIboolean\fR\&.  To override
+the "xdmcp/Enable" value, you would modify the
+\fB/etc/gdm/custom\&.conf\fR so it contains these lines:
+.PP
+.nf
+[xdmcp]
+Enable=true
+.fi
+.PP
+ 
+The following keys are supported for configuring the GDM daemon:
+.sp
+.ne 2
+.mk
+\fBchooser/Multicast=false (boolean)\fR
+If true and IPv6 is enabled, the chooser will send a multicast query to the
+local network and collect responses from the hosts who have joined multicast
+group\&. 
+
+.sp
+.ne 2
+.mk
+\fBchooser/MulticastAddr=ff02::1 (string)\fR
+This is the Link-local Multicast address\&.
+
+.sp
+.ne 2
+.mk
+\fBdaemon/TimedLoginEnable=false (boolean)\fR
+If the user given in TimedLogin should be logged in after a number of seconds
+(set with TimedLoginDelay) of inactivity on the login screen\&. This is useful
+for public access terminals or perhaps even home use\&. If the user uses the
+keyboard or browses the menus, the timeout will be reset to TimedLoginDelay or
+30 seconds, whichever is higher\&. If the user does not enter a username but just
+hits the ENTER key while the login program is requesting the username, then GDM
+will assume the user wants to login immediately as the timed user\&. Note that no
+password will be asked for this user so you should be careful, although if
+using PAM it can be configured to require password entry before allowing login\&.
+
+.sp
+.ne 2
+.mk
+\fBdaemon/TimedLogin= (string)\fR
+This is the user that should be logged in after a specified number of seconds
+of inactivity\&.  If the value ends with a vertical bar | (the pipe symbol), then
+GDM will execute the program specified and use whatever value is returned on
+standard out from the program as the user\&. The program is run with the DISPLAY
+environment variable set so that it is possible to specify the user in a
+per-display fashion\&. For example if the value is
+"/usr/bin/getloginuser|", then the program
+\fB/usr/bin/getloginuser\fR will be run to get the user value\&. 
+
+.sp
+.ne 2
+.mk
+\fBdaemon/TimedLoginDelay=30 (integer)\fR
+Delay in seconds before the TimedLogin  user will be logged in\&.
+
+.sp
+.ne 2
+.mk
+\fBdaemon/AutomaticLoginEnable=false (boolean)\fR
+If true, the user given in AutomaticLogin  should be logged in immediately\&.
+This feature is like timed login with a delay of 0 seconds\&.
+
+.sp
+.ne 2
+.mk
+\fBdaemon/AutomaticLogin= (string)\fR
+This is the user that should be logged in immediately if AutomaticLoginEnable
+is true\&.  If the value ends with a vertical bar | (the pipe symbol), then GDM
+will execute the program specified and use whatever value is returned on
+standard out from the program as the user\&. The program is run with the DISPLAY
+environment variable set so that it is possible to specify the user in a
+per-display fashion\&. For example if the value is
+"/usr/bin/getloginuser|", then the program
+\fB/usr/bin/getloginuser\fR will be run to get the user value\&. 
+
+.sp
+.ne 2
+.mk
+\fBdaemon/User=gdm (string)\fR
+The username under which the greeter and other GUI programs are run\&.
+
+.sp
+.ne 2
+.mk
+\fBdaemon/Group=gdm (string)\fR
+The group id used to run the login GUI programs
+
+.sp
+.ne 2
+.mk
+\fBdebug/Enable=false (boolean)\fR
+If true, then GDM will provide debug output in the system log, which is
+either \fB/var/log/messages\fR or
+\fB/var/adm/messages\fR depending on your system\&.
+
+.sp
+.ne 2
+.mk
+\fBgreeter/IncludeAll=false (boolean)\fR
+If true, then the face browser will show all users on the local machine\&. If
+false, the face browser will only show users who have recently logged in\&.
+.sp
+When this key is true, GDM will call fgetpwent() to get a list of local users
+on the system\&.  Anyusers with a user id less than 500 (or 100 if running on
+Solaris) are filtered out\&.  The Face Browser also will display any users that
+have previously logged in on the system (for example NIS/LDAP users)\&. It gets
+this list via calling the
+\fBck-history\fR(1)
+ConsoleKit interface\&. It will also filter out any users which do not have a
+valid shell (valid shells are any shell that getusershell() returns -
+\fB/sbin/nologin\fR or \fB/bin/false\fR are
+considered invalid shells even if getusershell() returns them)\&.
+.sp
+If false, then GDM more simply only displays users that have previously logged
+in on the system (local or NIS/LDAP users) by calling the
+\fBck-history\fR(1)
+ConsoleKit interface\&.
+
+.sp
+.ne 2
+.mk
+\fBgreeter/Include= (string)\fR
+Set to a list of users to always include in the Face Browser\&.  This value
+is set to a list of users separated by commas\&.  By default, the value is
+empty\&.
+
+.sp
+.ne 2
+.mk
+\fBgreeter/Exclude=bin,root,daemon,adm,lp,sync,shutdown,halt,mail,news,uucp,operator,nobody,nobody4,noaccess,postgres,pvm,rpm,nfsnobody,pcap (string)\fR
+Set to a list of users to always exclude in the Face Browser\&.  This value
+is set to a list of users separated by commas\&.  Note that the setting in the
+\fBcustom\&.conf\fR overrides the default value, so if you wish
+to add additional users to the list, then you need to set the value to the
+default value with additional users appended to the list\&.
+
+.sp
+.ne 2
+.mk
+\fBgreeter/ShowLast=false (boolean)\fR
+If true, then the session, language and layout dialogs in the login greeter GUI
+will show the option "Last" by default\&.  The users default settings
+in their \fB~/\&.dmrc\fR file will be used\&.  If no settings exist
+in this file, then the system defaults will be used\&.  Note that GDM normally
+caches the user\&'s \fB~/\&.dmrc\fR in the
+\fB/var/cache/gdm\fR directory\&.  Turning on this feature causes
+GDM to avoid using the cache, and instead accesses the user\&'s configuration
+settings from their \fB~/\&.dmrc\fR file after
+\fBpam_setcred\fR(3PAM) is called\&.
+This feature is useful in situations where users might log into multiple
+servers and the system administrator wants to avoid situations where the
+user\&'s cached settings might become inconsistent across different servers\&.
+
+.sp
+.ne 2
+.mk
+\fBsecurity/DisallowTCP=false (boolean)\fR
+If true, then always append "-\fBnolisten\fR tcp" to the
+Xserver command line when starting attached Xservers, thus disallowing TCP
+connection\&.  This is a more secure configuration if you are not using remote
+connections\&.  Note that on Solaris, the
+\fBoptions/tcp_listen\fR property of the 
+\fBx11-server\fR service also controls whether this option is
+appended to the Xserver command line\&.  The GDM configuration value is set to
+"false" by default on Solaris to defer control of this feature to
+this \fBx11-server\fR property\&.  Refer to the
+\fBXserver\fR(1)
+manpage for more information\&.
+
+.sp
+.ne 2
+.mk
+\fBxdmcp/DisplaysPerHost=1 (integer)\fR
+To prevent attackers from filling up the pending queue, GDM will only allow
+one connection for each remote computer\&. If you want to provide display
+services to computers with more than one seat, you should increase this
+value\&.  Note that the number of attached DISPLAYS allowed is not limited\&.
+Only remote connections via XDMCP are limited by this configuration option\&. 
+
+.sp
+.ne 2
+.mk
+\fBxdmcp/Enable=false (boolean)\fR
+Setting this to true enables XDMCP support allowing remote displays/X terminals
+to be managed by GDM\&.  If GDM is compiled to support it, access from remote
+displays can be controlled using the TCP Wrappers library\&.
+
+.sp
+.ne 2
+.mk
+\fBxdmcp/HonorIndirect=true (boolean)\fR
+Enables XDMCP INDIRECT choosing for X-terminals which do not supply their own
+display browser\&. 
+
+.sp
+.ne 2
+.mk
+\fBxdmcp/MaxPending=4 (integer)\fR
+To avoid denial of service attacks, GDM has fixed size queue of pending
+connections\&. Only MaxPending displays can start at the same time\&.  Please
+note that this parameter does not limit the number of remote displays which
+can be managed\&. It only limits the number of displays initiating a
+connection simultaneously\&. 
+
+.sp
+.ne 2
+.mk
+\fBxdmcp/MaxSessions=16 (integer)\fR
+Determines the maximum number of remote display connections which will be
+managed simultaneously\&. I\&.e\&. the total number of remote displays that
+can use your host\&. 
+
+.sp
+.ne 2
+.mk
+\fBxdmcp/MaxWait=30 (integer)\fR
+When GDM is ready to manage a display an ACCEPT packet is sent to it
+containing a unique session id which will be used in future XDMCP
+conversations\&.  GDM will then place the session id in the pending queue
+waiting for the display to respond with a MANAGE request\&.  If no response
+is received within MaxWait seconds, GDM will declare the display dead and
+erase it from the pending queue freeing up the slot for other displays\&. 
+
+.sp
+.ne 2
+.mk
+\fBxdmcp/MaxWaitIndirect=30 (integer)\fR
+The MaxWaitIndirect parameter determines the maximum number of seconds between
+the time where a user chooses a host and the subsequent indirect query where
+the user is connected to the host\&. When the timeout is exceeded, the
+information about the chosen host is forgotten and the indirect slot freed up
+for other displays\&. The information may be forgotten earlier if there are more
+hosts trying to send indirect queries then MaxPendingIndirect\&. 
+
+.sp
+.ne 2
+.mk
+\fBxdmcp/PingIntervalSeconds=15 (integer)\fR
+Interval in which to ping the Xserver in seconds\&. If the Xserver does not
+respond before the next time we ping it, the connection is stopped and the
+session ended\&. This is a combination of the XDM PingInterval and PingTimeout,
+but in seconds\&. 
+
+.sp
+.ne 2
+.mk
+\fBxdmcp/Port=177 (integer)\fR
+The UDP port number gdm should listen to for XDMCP requests\&.
+
+.sp
+.ne 2
+.mk
+\fBxdmcp/Willing=/etc/gdm/Willing (string)\fR
+When the machine sends a WILLING packet back after a QUERY it sends a string
+that gives the current status of this server\&. The default message is the
+system ID, but it is possible to create a script that displays customized
+message\&.  If this script does not exist or this key is empty the default
+message is sent\&.  If this script succeeds and produces some output, the
+first line of it\&'s output is sent (and only the first line)\&. It runs at
+most once every 3 seconds to prevent possible denial of service by flooding
+the machine with QUERY packets\&. 
+
+.PP
+The default system configuration for the GDM login greeter GUI is stored in
+the system GConf schemas directory in the file
+\fBgdm-simple-greeter\&.schemas\fR, and accessed by GDM via
+GConf\&.  Users are not recommended to modify this file file since it may be
+overwritten on upgrade\&.  Instead users should override these settings by
+modifying the GConf configuration for the GDM user (the user specified in the
+Daemon/User configuration key above), normally the "gdm" user\&.
+Users can use the 
+\fBgconftool-2\fR(1)
+or
+\fBgconf-editor\fR(1)
+programs to set these values, if desired\&.  Refer to the EXAMPLES section of
+this manpage for more information about how to use these tools to change
+common settings\&.
+.PP
+GDM will use the GCONF_DEFAULT_SOURCE_PATH environment variable to ensure that each display uses it\&'s own GConf configuration\&.  This way changes in GConf will only affect the greeter in a per-seat manner\&.
+.PP
+ 
+The following keys are supported for configuring the GDM login greeter GUI and
+are in
+"GConf key=\fIdefault_value\fR
+(\fIgconf_data_type\fR)"
+format:
+.sp
+.ne 2
+.mk
+\fB/apps/gdm/simple-greeter/banner_message_enable=false (boolean)\fR
+Controls whether the banner message text is displayed\&. 
+
+.sp
+.ne 2
+.mk
+\fB/apps/gdm/simple-greeter/banner_message_text=NULL (string)\fR
+Specifies the text banner message to show on the greeter window\&.
+
+.sp
+.ne 2
+.mk
+\fB/apps/gdm/simple-greeter/disable_restart_buttons=false (boolean)\fR
+Controls whether to show the restart buttons in the login window\&.
+
+.sp
+.ne 2
+.mk
+\fB/apps/gdm/simple-greeter/disable_user_list=true (boolean)\fR
+If true, then the face browser with known users is not shown in the login
+window\&. 
+
+.sp
+.ne 2
+.mk
+\fB/apps/gdm/simple-greeter/logo_icon_name=computer (string)\fR
+Set to the themed icon name to use for the greeter logo\&.
+
+.sp
+.ne 2
+.mk
+\fB/apps/gdm/simple-greeter/wm_use_compiz=false (boolean)\fR
+Controls whether compiz is used as the window manager instead of metacity\&.
+
+.sp
+.ne 2
+.mk
+\fB/desktop/gnome/interface/accessibility=true (boolean)\fR
+Controls whether the Accessibility infrastructure will be started with the GDM
+GUI\&. This is needed for many accessibility technology programs to work\&. 
+
+.sp
+.ne 2
+.mk
+\fB/desktop/gnome/applications/at/screen_magnifier_enabled=false (boolean)\fR
+If set, then the assistive tools linked to this GConf key will be started with
+the GDM GUI program\&. By default this is a screen magnifier application\&. 
+
+.sp
+.ne 2
+.mk
+\fB/desktop/gnome/applications/at/screen_keyboard_enabled=false (boolean)\fR
+If set, then the assistive tools linked to this GConf key will be started with
+the GDM GUI program\&. By default this is an on-screen keyboard application\&. 
+
+.sp
+.ne 2
+.mk
+\fB/desktop/gnome/applications/at/screen_reader_enabled=false (boolean)\fR
+If set, then the assistive tools linked to this GConf key will be started with
+the GDM GUI program\&. By default this is a screen reader application\&. 
+
+.PP
+On Solaris, GDM also supports the CONSOLE, PASSREQ, PATH, and SUPATH
+configuration options in \fB/etc/default/login\fR\&.  Refer to the
+\fBlogin\fR(1) manpage for details\&.
+.SS "Logging"
+.PP
+GDM logs error and debug information to the system syslog file\&.
+.PP
+Output from the Xservers started by GDM is stored in the GDM log directory,
+\fB/var/log/gdm\fR\&.  The Xserver output for each display is
+saved in a file \fB\fIdisplay\fR\&.log\fR,
+where \fIdisplay\fR is the DISPLAY value for the
+associated display\&.
+.PP
+Output from the GDM login greeter GUI is saved in a file
+\fB\fIdisplay\fR-greeter\&.log\fR and
+output from the GDM slave daemon is saved in a file
+\fB\fIdisplay\fR-slave\&.log\fR\&.  Again,
+the \fIdisplay\fR is the DISPLAY value for the
+associated display\&.
+.PP
+Four older versions of each file are also stored, by appending 1 through 4 to
+the filename\&. These files are rotated, as new sessions on that display are
+started\&.
+.PP
+The output from the user session is saved in a file
+\fB~/\&.xsession-errors\fR\&.  The user session output is 
+redirected before the \fBPreSession\fR script is started\&.
+.PP
+Note that if the session is a failsafe session, or if GDM cannot open this file
+for some reason, a fallback file is created named
+\fB/tmp/xses-\fIuser\fR\&.XXXXXX\fR,
+where XXXXXX are random characters\&.
+.PP
+If you run a system with quotas set, consider using the PostSession script to
+delete the \fB~/\&.xsession-errors\fR file, so that this log file
+is not stored unnecessarily\&.
+.SH "EXAMPLES"
+.PP
+Note that the user should change user to the "gdm" user before
+running the following
+\fBgconftool-2\fR(1) commands\&.  For example, the
+ \fBsu\fR(8)
+command could be used\&.  Configuration changes will only take effect if they
+apply to the "gdm" user\&.
+.PP
+\fBExample 1: To Enable Face Browser for all GDM login greeter GUI\fR
+.PP
+.PP
+.nf
+\fBexample% gconftool-2 --direct --config-source xml:readwrite:/var/lib/gdm/\&.gconf\&.mandatory -t bool -s /apps/gdm/simple-greeter/disable_user_list false\fR
+.fi
+.PP
+\fBExample 2: To Change the Background Image to \fBstream\&.jpg\fR for the GDM login greeter GUI\fR
+.PP
+.PP
+.nf
+\fBexample% gconftool-2 --direct --config-source xml:readwrite:/var/lib/gdm/\&.gconf\&.mandatory -t string -s /desktop/gnome/background/picture_filename /usr/share/pixmaps/backgrounds/opensolaris/stream\&.jpg\fR
+.fi
+.PP
+\fBExample 3: To Disable Face Browser for StaticSeat1 GDM login greeter GUI\fR
+.PP
+.PP
+.nf
+\fBexample% gconftool-2 --direct --config-source xml:readwrite:/var/lib/gdm/StaticSeat1/\&.gconf -t bool -s /apps/gdm/simple-greeter/disable_user_list true\fR
+.fi
+.SH "EXIT STATUS"
+.PP
+The following exit values are returned:
+.TP 8
+.B 0
+Application exited successfully
+.TP 8
+.B >0
+Application exited with failure
+.SH "FILES"
+.PP
+The following files are used by this application:
+.TP 30
+.B /usr/sbin/gdm
+Executable for GNOME Display Manager\&.
+
+.SS "GDM Login Scripts and Session Files"
+.PP
+The following GDM login integration interfaces are discussed below:
+.sp
+.in +2
+\(bu
+.mk
+.in +3
+.rt
+\fB/etc/gdm/Init/Default\fR
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+\fB/etc/gdm/Init/\fIdisplay\fR\fR
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+\fB/etc/gdm/PostLogin/Default\fR
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+\fB/etc/gdm/PostLogin/\fIdisplay\fR\fR
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+\fB/etc/gdm/PreSession/Default\fR
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+\fB/etc/gdm/PreSession/\fIdisplay\fR\fR
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+\fB/etc/gdm/Xsession\fR
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+\fB/etc/X11/xinit/xinitrc\&.d\fR
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+\fB/etc/profile\fR
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+\fB~/profile\fR
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+\fB/etc/X11/xinit/xinitrc\&.d\fR
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+\fB/etc/gdm/PostSession/Default\fR
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+\fB/etc/gdm/PostSession/\fIdisplay\fR\fR
+.in -3
+.in -2
+.PP
+The following session files are also discussed below:
+.sp
+.in +2
+\(bu
+.mk
+.in +3
+.rt
+\fB/usr/share/gdm/autostart/LoginWindow/*\&.desktop\fR
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+\fB/usr/share/xsessions/*\&.desktop\fR
+.in -3
+\(bu
+.mk
+.in +3
+.rt
+\fB~/\&.dmrc\fR(default user session)
+.in -3
+.in -2
+.PP
+The \fBInit\fR, \fBPostLogin\fR,
+\fBPreSession\fR, and \fBPostSession\fR scripts
+all work as described below\&. 
+.PP
+For each type of script, the default one which will be executed is called
+"Default" and is stored in a directory associated with the script
+type\&. So the default \fBInit\fR script is
+\fB/etc/gdm/Init/Default\fR\&.  A per-display script can be
+provided, and if it exists it will be run instead of the default script\&. Such
+scripts are stored in the same directory as the default script and have the
+same name as the Xserver DISPLAY value for that display\&. For example, if the
+/etc/gdm/Init/:0  script exists, it will be run for
+DISPLAY ":0"\&.
+.PP
+All of these scripts are run with root privilege and return 0 if run
+successfully, and a non-zero return code if there was any failure that should
+cause the login session to be aborted\&. Also note that GDM will block until the
+scripts finish, so if any of these scripts hang, this will cause the login
+process to also hang\&.
+.PP
+When the Xserver for the login GUI has been successfully started, but before
+the login GUI is actually displayed, GDM will run the \fBInit\fR
+script\&. This script is useful for starting programs that should be run while
+the login screen is showing, or for doing any special initialization if
+required\&.
+.PP
+After the user has been successfully authenticated GDM will run the
+\fBPostLogin\fR script\&. This is done before any session setup
+has been done, including before the 
+\fBpam_open_session\fR(3PAM)
+call\&. This script is useful for doing any session initialization that needs to
+happen before the session starts\&. For example, you might setup the user\&'s
+$HOME directory if needed\&.
+.PP
+After the user session has been initialized, GDM will run the
+\fBPreSession\fR script\&. This script is useful for doing any
+session initialization that needs to happen after the session has been
+initialized\&. It can be used for session management or accounting, for example\&.
+.PP
+When a user terminates their session, GDM will run the
+\fBPostSession\fR script\&. Note that the Xserver will have been
+stopped by the time this script is run, so it should not be accessed\&.
+.PP
+Note that the \fBPostSession\fR script will be run even when the
+display fails to respond due to an I/O error or similar\&. Thus, there is no
+guarantee that X applications will work during script execution\&.
+.PP
+All of the above scripts will set the RUNNING_UNDER_GDM environment variable
+to "yes"\&. If the scripts are also shared with other display managers,
+this allows you to identify when GDM is calling these scripts, so you can run
+specific code when GDM is used\&. 
+.PP
+The \fB/usr/share/gdm/autostart/LoginWindow\fR directory
+contains \fB\&.desktop\fR files\&.  Any
+\fB\&.desktop\fR files in this directory will cause the
+associated program to automatically start with the login GUI greeter\&. By
+default, GDM is shipped with files which will autostart the gdm-simple-greeter
+login GUI greeter itself, the \fBgnome-power-manager\fR
+application, the \fBgnome-settings-daemon\fR, and the
+\fBmetacity\fR window manager\&. These programs are needed for the
+greeter program to work\&. In addition, desktop files are provided for starting
+various AT programs if the associated accessibility configuration GConf keys
+are set\&.
+.PP
+The administrator can customize \&.desktop files\&. For example, an \fBxterm\&.desktop\fR file can be useful when debugging the GDM login greeter\&. A \&.desktop file to launch \fBxterm\fR(1) would look as follows: 
+.PP
+.nf
+[Desktop Entry] 
+Name=Xterm 
+Comment=Xterm 
+Exec=/usr/X11/bin/xterm 
+OnlyShowIn=GNOME; 
+Terminal=false 
+Type=Application 
+X-GNOME-Autostart-Phase=Applications 
+X-GNOME-AutoRestart=true 
+.fi
+.PP
+The user\&'s default session and language choices are stored in the
+\fB~/\&.dmrc\fR file\&. When a user logs in for the first time, this
+file is created with the user\&'s initial choices\&. The user can change these
+default values by simply changing to a different value when logging in\&. GDM
+will remember this change for subsequent logins\&. 
+.PP
+The session types which are available in the GDM login greeter GUI are
+specified by \fB\&.desktop\fR files\&.  These desktop files are in
+standard INI format and the executable that will be run to start the session
+is specified by the "Exec" key in the file\&.  Desktop files are
+normally stored in the \fB/usr/share/xsessions\fR directory\&.
+However, GDM will search for desktop files in the following directories in this
+order: \fB/etc/X11/sessions/\fR,
+\fB/etc/dm/Sessions\fR,
+\fB/usr/share/xsessions\fR, and
+\fB/usr/share/gdm/BuiltInSessions\fR\&.
+.PP
+The \fB/etc/gdm/Xsession\fR script is called between the
+\fBPreSession\fR and the \fBPostSession\fR
+scripts\&. This script does not support per-display like the other scripts\&. This
+script is used for actually starting the user session\&. This script is run as
+the user, and it will run whatever session was specified by the Desktop session
+file the user selected to start\&.  The \fB/etc/gdm/Xsession\fR
+script will source \fB/etc/profile\fR,
+\fB~/\&.profile\fR, and all scripts in the
+\fB/etc/X11/xinit/xinitrc\&.d\fR directory before starting the
+user session\&.  Refer to the
+\fBprofile\fR(4)
+manpage for more information\&.
+.SS "Configuration Files"
+.TP 30
+.B /etc/gdm/gdm\&.schemas\fR\fR
+GDM default daemon configuration\&.
+
+.TP 30
+.B /etc/gdm/custom\&.conf\fR\fR
+GDM daemon configuration customization\&.
+
+.TP 30
+.B /etc/gconf/schemas/gdm-simple-greeter\&.schemas\fR\fR
+GDM default login greeter GUI configuration\&.
+
+.TP 30
+.B /etc/default/login\fR\fR
+On Solaris, GDM supports the CONSOLE, PASSREQ, PATH, and SUPATH configuration
+options\&.  Refer to the
+\fBlogin\fR(1)
+manpage for details\&.
+
+.TP 30
+.B ~gdm/\&.gconf\&.mandatory\fR\fR
+The GDM user\&'s mandatory GConf settings\&.
+
+.TP 30
+.B ~gdm/\&.gconf\fR\fR
+The GDM user\&'s GConf settings\&.
+
+.TP 30
+.B ~gdm/\fIseat\fR/\&.gconf\fR\fR
+The per-seat GDM user\&'s GConf settings\&.
+
+.TP 30
+.B ~gdm/\&.gconf\&.path\fR\fR
+This file specifies the GDM user\&'s mandatory GConf settings directory\&.
+
+.SS "Logging"
+.TP 30
+.B /var/log/gdm/\fIdisplay\fR\&.log\fR\fR
+Xserver output for each \fIdisplay\fR\&.
+
+.TP 30
+.B /var/log/gdm/\fIdisplay\fR-greeter\&.log\fR\fR
+GDM login greeter GUI output for each \fIdisplay\fR\&.
+
+.TP 30
+.B /var/log/gdm/\fIdisplay\fR-slave\&.log\fR\fR
+GDM slave daemon output for each \fIdisplay\fR\&.
+
+.TP 30
+.B ~/\&.xsession-errors\fR\fR
+Output from the user session\&.
+
+.SS "GDM Xauthority files"
+.TP 30
+.B /var/run/gdm\fR\fR
+Stores the Xserver authentication files for each managed session\&.
+
+.SS "Face Browser"
+.TP 30
+.B /usr/share/pixmaps/faces\fR\fR
+Global directory for face images\&.
+
+.TP 30
+.B ~/\&.face\fR\fR
+User-defined icon to be used by GDM face browser\&.
+
+.SS "GDM user cache"
+.TP 30
+.B /var/cache/gdm\fR\fR
+GDM copies the user\&'s \fB~/\&.dmrc and
+\fB~/\&.face\fR files to
+\fB/var/cache/gdm/\fIusername\fR\fR, so
+that they can be accessed on subsequent logins without accessing the user\&'s
+$HOME directory before 
+\fBpam_setcred\fR(3PAM) is called\&.\fR
+
+.SH "SEE ALSO"
+.PP
+More information can be found at:
+.PP
+\fBhttp://library\&.gnome\&.org/admin/gdm\fR
+.PP
+Latest version of the \fIGNOME Desktop User Guide\fR for your
+platform\&.
+.PP
+\fBgdmflexiserver\fR(1),
+\fBgdm-screenshot\fR(1),
+\fBgconftool-2\fR(1),
+\fBgconf-editor\fR(1),
+\fBlogin\fR(1),
+\fBssh\fR(1),
+\fBXorg\fR(1),
+\fBXserver\fR(1),
+\fBaudit\fR(8),
+\fBconsole-kit-daemon\fR(8),
+\fBsvcadm\fR(8),
+\fBlibwrap\fR(3),
+\fBpam\fR(3PAM),
+\fBlogindevperm\fR(5),
+\fBpam\&.conf\fR(5),
+\fBprofile\fR(5),
+\fBuser_attr\fR(5),
+\fBattributes\fR(7),
+\fBenviron\fR(7),
+\fBsmf\fR(7)
+.SH "NOTES"
+.PP
+This man page written by Martin K\&. Petersen <mkp@mkp\&.net>, George Lebl
+<jirka@5z\&.com>, and Brian Cameron <brian\&.cameron@sun\&.com>\&.
+Copyright (c) 1998, 1999 by Martin K\&. Petersen\&.
+Copyright (c) 2001, 2003, 2004 by George Lebl\&.
+Copyright (c) 2003 by Red Hat, Inc\&.
+Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/files/gdm.auth_attr	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+#
+# authorization attributes. see auth_attr(5)
+#
+solaris.smf.manage.dt.:RO::Manage Desktop Service States::
+solaris.smf.manage.dt.login:RO::Manage Desktop Login Service States::
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/files/gdm.prof_attr	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+#
+# profiles attributes. see prof_attr(4)
+#
+Desktop Configuration:RO:::auths=solaris.smf.manage.dt.login
+Device Security:RO:::auths=solaris.smf.manage.dt.login
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/files/gdm.user_attr	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,6 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+#
+# Use special PAM policy for displaying the login screen as the gdm user
+#
+gdm::::pam_policy=/etc/gdm/gdm-launch-environment.pam
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/files/gdm.xml	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,130 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+  Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ -->
+
+<service_bundle type='manifest' name='system/display-manager/gdm'>
+
+<service
+    name='application/graphical-login/gdm'
+    type='service'
+    version='1'>
+
+	<dependency
+	    name='filesystem'
+	    grouping='require_all'
+	    restart_on='none'
+	    type='service'>
+		<service_fmri value='svc:/system/filesystem/local'/>
+	</dependency>
+
+	<dependency name='multi-user'
+	    grouping='require_all'
+	    restart_on='error'
+	    type='service'>
+		<service_fmri value='svc:/milestone/multi-user:default'/>
+	</dependency>
+
+	<dependency
+	    name='self-assembly-complete'
+	    grouping='require_all'
+	    restart_on='none'
+	    type='service'>
+		<service_fmri value='svc:/milestone/self-assembly-complete'/>
+	</dependency>
+
+	<dependency
+	    name='fc-cache'
+	    grouping='require_all'
+	    restart_on='none'
+	    type='service'>
+		<service_fmri value='svc:/application/font/fc-cache'/>
+	</dependency>
+
+	<dependency
+	    name='utmpx'
+	    grouping='require_all'
+	    restart_on='none'
+	    type='service'>
+		<service_fmri value='svc:/system/utmp'/>
+	</dependency>
+
+	<dependency
+	    name='hal'
+	    grouping='optional_all'
+	    restart_on='none'
+	    type='service'>
+		<service_fmri value='svc:/system/hal' />
+	</dependency>
+
+        <dependency
+            name='dbus'
+            type='service'
+            grouping='require_all'
+            restart_on='none'>
+                <service_fmri value='svc:/system/dbus' />
+        </dependency>
+
+	<dependency
+	    name='accountsservice'
+	    grouping='require_all'
+	    restart_on='none'
+	    type='service'>
+		<service_fmri value='svc:/system/accountsservice'/>
+	</dependency>
+
+	<dependency
+	    name='consolekit'
+	    grouping='require_all'
+	    restart_on='none'
+	    type='service'>
+		<service_fmri value='svc:/system/consolekit'/>
+	</dependency>
+
+	<method_context>
+	  <method_credential user='root' clearance='ADMIN_HIGH' />
+	</method_context>
+
+	<exec_method
+	    type='method'
+	    name='start'
+	    exec='/lib/svc/method/svc-gdm start'
+	    timeout_seconds='150' />
+
+	<exec_method
+	    type='method'
+	    name='stop'
+	    exec='/lib/svc/method/svc-gdm stop %{restarter/contract}'
+	    timeout_seconds='150' />
+
+	<!-- Authorization -->
+        <property_group name='general' type='framework'>
+                <!-- to start stop gdm -->
+                <propval name='action_authorization' type='astring'
+                        value='solaris.smf.manage.dt.login' />
+        </property_group>
+
+	<!-- these are passed to gdm in the method script -->
+        <property_group name='gdm' type='application'>
+                <propval name='args' type='astring' value='' />
+        </property_group>
+
+	<instance name='default' enabled='false' />
+
+	<stability value='Unstable' />
+
+	<template>
+		<common_name>
+			<loctext xml:lang='C'>
+				GNOME Display Manager
+			</loctext>
+		</common_name>
+		<documentation>
+			<manpage title='gdm' section='8'
+				manpath='/usr/share/man' />
+		</documentation>
+	</template>
+</service>
+
+</service_bundle>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/files/org.gnome.login-screen.gschema.override	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,3 @@
+[org.gnome.login-screen]
+logo='/usr/share/pixmaps/Oracle_Solaris_Logo.png'
+disable-user-list=true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/files/svc-gdm	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,61 @@
+#!/bin/sh
+#
+# Copyright 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+#
+# For modifying parameters passed to gdm, do not edit this script.
+# Instead use svccfg(1m) to modify the SMF repository.  For example:
+#
+# # svccfg
+# svc:> select application/graphical-login/gdm
+# svc:/application/graphical-login/gdm> setprop gdm/args = "--fatal-warnings"
+# svc:/application/graphical-login/gdm> exit
+
+. /lib/svc/share/smf_include.sh
+
+CK_FMRI='svc:/system/consolekit'
+sessions="$(eval "echo $(svcprop -p consolekit/sessions $CK_FMRI)")"
+
+case "$1" in
+'start')
+	FMRI=svc:/application/graphical-login/gdm
+
+	arg="$(eval "echo $(svcprop -p gdm/args $FMRI)")"
+
+	/usr/sbin/gdm $arg &
+
+	rc=$?
+	if [[ $rc != 0 ]]; then
+		echo "$0: gdm failed with $rc"
+		exit $SMF_EXIT_ERR_FATAL
+	fi
+
+	# If no static sessions started, start dynamic ones
+	if [[ -z "$sessions" && -x /usr/lib/ConsoleKit/dsession ]]; then
+                sleep 2
+  		/usr/lib/ConsoleKit/dsession --init
+  	fi
+	;;
+
+'stop')
+	if [[ -z "$sessions" && -x /usr/lib/ConsoleKit/dsession ]]; then
+  		/usr/lib/ConsoleKit/dsession --fini
+  	fi
+
+	PIDFILE='/var/run/gdm/gdm.pid'
+	if [[ ! -f $PIDFILE ]] ; then
+	        echo "$PIDFILE doesn't exist, perhaps GDM isn't running"
+	else
+		kill -TERM $(cat $PIDFILE) && sleep 5
+	fi
+	# kill any stragglers that gdm itself didn't kill off
+	smf_kill_contract $2 TERM 1 30
+	[[ $? -ne 0 ]] && exit 1
+	;;
+
+*)
+	echo "Usage: $0 { start | stop }"
+	exit $SMF_EXIT_ERR_FATAL
+	;;
+esac
+
+exit $SMF_EXIT_OK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/files/xterm.desktop	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=xterm
+Comment=Failsafe session with only xterm
+X-GDM-BypassXsession=true
+Exec=/usr/bin/xterm
+TryExec=/usr/bin/xterm
+Icon=
+Type=Application
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/gdm.license	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,899 @@
+		    GNU GENERAL PUBLIC LICENSE
+
+		       Version 2, June 1991
+
+
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+
+ of this license document, but changing it is not allowed.
+
+
+
+			    Preamble
+
+
+
+  The licenses for most software are designed to take away your
+
+freedom to share and change it.  By contrast, the GNU General Public
+
+License is intended to guarantee your freedom to share and change free
+
+software--to make sure the software is free for all its users.  This
+
+General Public License applies to most of the Free Software
+
+Foundation's software and to any other program whose authors commit to
+
+using it.  (Some other Free Software Foundation software is covered by
+
+the GNU Library General Public License instead.)  You can apply it to
+
+your programs, too.
+
+
+
+  When we speak of free software, we are referring to freedom, not
+
+price.  Our General Public Licenses are designed to make sure that you
+
+have the freedom to distribute copies of free software (and charge for
+
+this service if you wish), that you receive source code or can get it
+
+if you want it, that you can change the software or use pieces of it
+
+in new free programs; and that you know you can do these things.
+
+
+
+  To protect your rights, we need to make restrictions that forbid
+
+anyone to deny you these rights or to ask you to surrender the rights.
+
+These restrictions translate to certain responsibilities for you if you
+
+distribute copies of the software, or if you modify it.
+
+
+
+  For example, if you distribute copies of such a program, whether
+
+gratis or for a fee, you must give the recipients all the rights that
+
+you have.  You must make sure that they, too, receive or can get the
+
+source code.  And you must show them these terms so they know their
+
+rights.
+
+
+
+  We protect your rights with two steps: (1) copyright the software, and
+
+(2) offer you this license which gives you legal permission to copy,
+
+distribute and/or modify the software.
+
+
+
+  Also, for each author's protection and ours, we want to make certain
+
+that everyone understands that there is no warranty for this free
+
+software.  If the software is modified by someone else and passed on, we
+
+want its recipients to know that what they have is not the original, so
+
+that any problems introduced by others will not reflect on the original
+
+authors' reputations.
+
+
+
+  Finally, any free program is threatened constantly by software
+
+patents.  We wish to avoid the danger that redistributors of a free
+
+program will individually obtain patent licenses, in effect making the
+
+program proprietary.  To prevent this, we have made it clear that any
+
+patent must be licensed for everyone's free use or not licensed at all.
+
+
+
+  The precise terms and conditions for copying, distribution and
+
+modification follow.
+
+
+
+
+		    GNU GENERAL PUBLIC LICENSE
+
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+
+
+  0. This License applies to any program or other work which contains
+
+a notice placed by the copyright holder saying it may be distributed
+
+under the terms of this General Public License.  The "Program", below,
+
+refers to any such program or work, and a "work based on the Program"
+
+means either the Program or any derivative work under copyright law:
+
+that is to say, a work containing the Program or a portion of it,
+
+either verbatim or with modifications and/or translated into another
+
+language.  (Hereinafter, translation is included without limitation in
+
+the term "modification".)  Each licensee is addressed as "you".
+
+
+
+Activities other than copying, distribution and modification are not
+
+covered by this License; they are outside its scope.  The act of
+
+running the Program is not restricted, and the output from the Program
+
+is covered only if its contents constitute a work based on the
+
+Program (independent of having been made by running the Program).
+
+Whether that is true depends on what the Program does.
+
+
+
+  1. You may copy and distribute verbatim copies of the Program's
+
+source code as you receive it, in any medium, provided that you
+
+conspicuously and appropriately publish on each copy an appropriate
+
+copyright notice and disclaimer of warranty; keep intact all the
+
+notices that refer to this License and to the absence of any warranty;
+
+and give any other recipients of the Program a copy of this License
+
+along with the Program.
+
+
+
+You may charge a fee for the physical act of transferring a copy, and
+
+you may at your option offer warranty protection in exchange for a fee.
+
+
+
+  2. You may modify your copy or copies of the Program or any portion
+
+of it, thus forming a work based on the Program, and copy and
+
+distribute such modifications or work under the terms of Section 1
+
+above, provided that you also meet all of these conditions:
+
+
+
+    a) You must cause the modified files to carry prominent notices
+
+    stating that you changed the files and the date of any change.
+
+
+
+    b) You must cause any work that you distribute or publish, that in
+
+    whole or in part contains or is derived from the Program or any
+
+    part thereof, to be licensed as a whole at no charge to all third
+
+    parties under the terms of this License.
+
+
+
+    c) If the modified program normally reads commands interactively
+
+    when run, you must cause it, when started running for such
+
+    interactive use in the most ordinary way, to print or display an
+
+    announcement including an appropriate copyright notice and a
+
+    notice that there is no warranty (or else, saying that you provide
+
+    a warranty) and that users may redistribute the program under
+
+    these conditions, and telling the user how to view a copy of this
+
+    License.  (Exception: if the Program itself is interactive but
+
+    does not normally print such an announcement, your work based on
+
+    the Program is not required to print an announcement.)
+
+
+
+
+These requirements apply to the modified work as a whole.  If
+
+identifiable sections of that work are not derived from the Program,
+
+and can be reasonably considered independent and separate works in
+
+themselves, then this License, and its terms, do not apply to those
+
+sections when you distribute them as separate works.  But when you
+
+distribute the same sections as part of a whole which is a work based
+
+on the Program, the distribution of the whole must be on the terms of
+
+this License, whose permissions for other licensees extend to the
+
+entire whole, and thus to each and every part regardless of who wrote it.
+
+
+
+Thus, it is not the intent of this section to claim rights or contest
+
+your rights to work written entirely by you; rather, the intent is to
+
+exercise the right to control the distribution of derivative or
+
+collective works based on the Program.
+
+
+
+In addition, mere aggregation of another work not based on the Program
+
+with the Program (or with a work based on the Program) on a volume of
+
+a storage or distribution medium does not bring the other work under
+
+the scope of this License.
+
+
+
+  3. You may copy and distribute the Program (or a work based on it,
+
+under Section 2) in object code or executable form under the terms of
+
+Sections 1 and 2 above provided that you also do one of the following:
+
+
+
+    a) Accompany it with the complete corresponding machine-readable
+
+    source code, which must be distributed under the terms of Sections
+
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+
+
+    b) Accompany it with a written offer, valid for at least three
+
+    years, to give any third party, for a charge no more than your
+
+    cost of physically performing source distribution, a complete
+
+    machine-readable copy of the corresponding source code, to be
+
+    distributed under the terms of Sections 1 and 2 above on a medium
+
+    customarily used for software interchange; or,
+
+
+
+    c) Accompany it with the information you received as to the offer
+
+    to distribute corresponding source code.  (This alternative is
+
+    allowed only for noncommercial distribution and only if you
+
+    received the program in object code or executable form with such
+
+    an offer, in accord with Subsection b above.)
+
+
+
+The source code for a work means the preferred form of the work for
+
+making modifications to it.  For an executable work, complete source
+
+code means all the source code for all modules it contains, plus any
+
+associated interface definition files, plus the scripts used to
+
+control compilation and installation of the executable.  However, as a
+
+special exception, the source code distributed need not include
+
+anything that is normally distributed (in either source or binary
+
+form) with the major components (compiler, kernel, and so on) of the
+
+operating system on which the executable runs, unless that component
+
+itself accompanies the executable.
+
+
+
+If distribution of executable or object code is made by offering
+
+access to copy from a designated place, then offering equivalent
+
+access to copy the source code from the same place counts as
+
+distribution of the source code, even though third parties are not
+
+compelled to copy the source along with the object code.
+
+
+
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+
+except as expressly provided under this License.  Any attempt
+
+otherwise to copy, modify, sublicense or distribute the Program is
+
+void, and will automatically terminate your rights under this License.
+
+However, parties who have received copies, or rights, from you under
+
+this License will not have their licenses terminated so long as such
+
+parties remain in full compliance.
+
+
+
+  5. You are not required to accept this License, since you have not
+
+signed it.  However, nothing else grants you permission to modify or
+
+distribute the Program or its derivative works.  These actions are
+
+prohibited by law if you do not accept this License.  Therefore, by
+
+modifying or distributing the Program (or any work based on the
+
+Program), you indicate your acceptance of this License to do so, and
+
+all its terms and conditions for copying, distributing or modifying
+
+the Program or works based on it.
+
+
+
+  6. Each time you redistribute the Program (or any work based on the
+
+Program), the recipient automatically receives a license from the
+
+original licensor to copy, distribute or modify the Program subject to
+
+these terms and conditions.  You may not impose any further
+
+restrictions on the recipients' exercise of the rights granted herein.
+
+You are not responsible for enforcing compliance by third parties to
+
+this License.
+
+
+
+  7. If, as a consequence of a court judgment or allegation of patent
+
+infringement or for any other reason (not limited to patent issues),
+
+conditions are imposed on you (whether by court order, agreement or
+
+otherwise) that contradict the conditions of this License, they do not
+
+excuse you from the conditions of this License.  If you cannot
+
+distribute so as to satisfy simultaneously your obligations under this
+
+License and any other pertinent obligations, then as a consequence you
+
+may not distribute the Program at all.  For example, if a patent
+
+license would not permit royalty-free redistribution of the Program by
+
+all those who receive copies directly or indirectly through you, then
+
+the only way you could satisfy both it and this License would be to
+
+refrain entirely from distribution of the Program.
+
+
+
+If any portion of this section is held invalid or unenforceable under
+
+any particular circumstance, the balance of the section is intended to
+
+apply and the section as a whole is intended to apply in other
+
+circumstances.
+
+
+
+It is not the purpose of this section to induce you to infringe any
+
+patents or other property right claims or to contest validity of any
+
+such claims; this section has the sole purpose of protecting the
+
+integrity of the free software distribution system, which is
+
+implemented by public license practices.  Many people have made
+
+generous contributions to the wide range of software distributed
+
+through that system in reliance on consistent application of that
+
+system; it is up to the author/donor to decide if he or she is willing
+
+to distribute software through any other system and a licensee cannot
+
+impose that choice.
+
+
+
+This section is intended to make thoroughly clear what is believed to
+
+be a consequence of the rest of this License.
+
+
+
+
+  8. If the distribution and/or use of the Program is restricted in
+
+certain countries either by patents or by copyrighted interfaces, the
+
+original copyright holder who places the Program under this License
+
+may add an explicit geographical distribution limitation excluding
+
+those countries, so that distribution is permitted only in or among
+
+countries not thus excluded.  In such case, this License incorporates
+
+the limitation as if written in the body of this License.
+
+
+
+  9. The Free Software Foundation may publish revised and/or new versions
+
+of the General Public License from time to time.  Such new versions will
+
+be similar in spirit to the present version, but may differ in detail to
+
+address new problems or concerns.
+
+
+
+Each version is given a distinguishing version number.  If the Program
+
+specifies a version number of this License which applies to it and "any
+
+later version", you have the option of following the terms and conditions
+
+either of that version or of any later version published by the Free
+
+Software Foundation.  If the Program does not specify a version number of
+
+this License, you may choose any version ever published by the Free Software
+
+Foundation.
+
+
+
+  10. If you wish to incorporate parts of the Program into other free
+
+programs whose distribution conditions are different, write to the author
+
+to ask for permission.  For software which is copyrighted by the Free
+
+Software Foundation, write to the Free Software Foundation; we sometimes
+
+make exceptions for this.  Our decision will be guided by the two goals
+
+of preserving the free status of all derivatives of our free software and
+
+of promoting the sharing and reuse of software generally.
+
+
+
+			    NO WARRANTY
+
+
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+
+REPAIR OR CORRECTION.
+
+
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+
+POSSIBILITY OF SUCH DAMAGES.
+
+
+
+		     END OF TERMS AND CONDITIONS
+
+
+
+
+	    How to Apply These Terms to Your New Programs
+
+
+
+  If you develop a new program, and you want it to be of the greatest
+
+possible use to the public, the best way to achieve this is to make it
+
+free software which everyone can redistribute and change under these terms.
+
+
+
+  To do so, attach the following notices to the program.  It is safest
+
+to attach them to the start of each source file to most effectively
+
+convey the exclusion of warranty; and each file should have at least
+
+the "copyright" line and a pointer to where the full notice is found.
+
+
+
+    <one line to give the program's name and a brief idea of what it does.>
+
+    Copyright (C) <year>  <name of author>
+
+
+
+    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
+
+
+
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+
+
+If the program is interactive, make it output a short notice like this
+
+when it starts in an interactive mode:
+
+
+
+    Gnomovision version 69, Copyright (C) year  name of author
+
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+
+    This is free software, and you are welcome to redistribute it
+
+    under certain conditions; type `show c' for details.
+
+
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+
+parts of the General Public License.  Of course, the commands you use may
+
+be called something other than `show w' and `show c'; they could even be
+
+mouse-clicks or menu items--whatever suits your program.
+
+
+
+You should also get your employer (if you work as a programmer) or your
+
+school, if any, to sign a "copyright disclaimer" for the program, if
+
+necessary.  Here is a sample; alter the names:
+
+
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+
+
+  <signature of Ty Coon>, 1 April 1989
+
+  Ty Coon, President of Vice
+
+
+
+This General Public License does not permit incorporating your program into
+
+proprietary programs.  If your program is a subroutine library, you may
+
+consider it more useful to permit linking proprietary applications with the
+
+library.  If this is what you want to do, use the GNU Library General
+
+Public License instead of this License.
+
+
+
+---
+
+
+
+Some code is licensed under the LGPLv2 or later license:
+
+
+
+ Copyright (C) 1999, 2001-2002 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+
+
+   The GNU C 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.
+
+
+
+   The GNU C 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 the GNU C 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.
+
+
+
+---
+
+
+
+or with this LGPLv2.1 or later license:
+
+
+
+   The GNU C Library is free software; you can redistribute it and/or
+
+   modify it under the terms of the GNU Lesser General Public
+
+   License as published by the Free Software Foundation; either
+
+   version 2.1 of the License, or (at your option) any later version.
+
+
+
+   The GNU C 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
+
+   Lesser General Public License for more details.
+
+
+
+   You should have received a copy of the GNU Lesser General Public
+
+   License along with the GNU C Library; if not, write to the Free
+
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+
+   02111-1307 USA.
+
+
+
+
+
+---
+
+
+
+Some code uses this MIT license:
+
+
+
+ Copyright (c) 2007 David Zeuthen <[email protected]>
+
+ Copyright (c) 2007 William Jon McCann <[email protected]>
+
+
+
+ Permission is hereby granted, free of charge, to any person
+
+ obtaining a copy of this software and associated documentation
+
+ files (the "Software"), to deal in the Software without
+
+ restriction, including without limitation the rights to use,
+
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+
+ copies of the Software, and to permit persons to whom the
+
+ Software is furnished to do so, subject to the following
+
+ conditions:
+
+
+
+ The above copyright notice and this permission notice shall be
+
+ included in all copies or substantial portions of the Software.
+
+
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+
+ OTHER DEALINGS IN THE SOFTWARE.
+
+
+
+---
+
+
+
+The GDM MD5 code uses this zlib/libpng license:
+
+
+
+ gdm-md5.c md5 implementation (based on L Peter Deutsch implementation)
+
+
+
+ Copyright (C) 2003 Red Hat Inc.
+
+ Copyright (C) 1999, 2000 Aladdin Enterprises.  All rights reserved.
+
+
+
+ This software is provided 'as-is', without any express or implied
+
+ warranty.  In no event will the authors be held liable for any damages
+
+ arising from the use of this software.
+
+
+
+ Permission is granted to anyone to use this software for any purpose,
+
+ including commercial applications, and to alter it and redistribute it
+
+ freely, subject to the following restrictions:
+
+
+
+ 1. The origin of this software must not be misrepresented; you must not
+
+    claim that you wrote the original software. If you use this software
+
+    in a product, an acknowledgment in the product documentation would be
+
+    appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+
+    misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+
+
+
+ L. Peter Deutsch
+
+ [email protected]
+
+
+
+
+
+ Independent implementation of MD5 (RFC 1321).
+
+
+
+ This code implements the MD5 Algorithm defined in RFC 1321.
+
+ It is derived directly from the text of the RFC and not from the
+
+ reference implementation.
+
+
+ The original and principal author of md5.c is L. Peter Deutsch
+
+ <[email protected]>.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/gdm.p5m	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,308 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+#
+
+<transform file path=usr.*/man/.+ -> default mangler.man.stability volatile>
+<transform file preserve=(true|renamenew) -> default overlay allow>
+set name=pkg.fmri \
+    value=pkg:/system/display-manager/gdm@$(IPS_COMPONENT_VERSION),$(BUILD_VERSION)
+set name=pkg.summary value="GNOME Display Manager (GDM)"
+set name=pkg.description \
+    value="The GNOME Display Manager (GDM) is a program that manages graphical display servers and handles graphical user logins."
+set name=com.oracle.info.description value="GNOME Display Manager (GDM)"
+set name=com.oracle.info.tpno value=$(TPNO)
+set name=info.classification \
+    value="org.opensolaris.category.2008:Desktop (GNOME)/Sessions"
+set name=info.source-url value=$(COMPONENT_ARCHIVE_URL)
+set name=info.upstream-url value=$(COMPONENT_PROJECT_URL)
+# LSARC/2003/261 gdm2 - Gnome Display Manager
+# LSARC/2005/417 GDM2 as default Solaris Display Manager
+# PSARC/2008/662 GDM system user home directory
+# LSARC/2009/433 GNOME Display Manager (GDM) Rewrite
+# PSARC/2010/116 GDM Integration With audioctl
+set name=org.opensolaris.arc-caseid value=LSARC/2003/261 value=LSARC/2005/417 \
+    value=LSARC/2009/433 value=PSARC/2008/662 value=PSARC/2010/116 \
+    value=PSARC/2016/448
+set name=org.opensolaris.consolidation value=$(CONSOLIDATION)
+
+
+file path=etc/dbus-1/system.d/gdm.conf
+file path=etc/gdm/Init/Default mode=0555 preserve=true
+file path=etc/gdm/PostLogin/Default.sample mode=0555
+file path=etc/gdm/PostSession/Default mode=0555 preserve=true
+file path=etc/gdm/PreSession/Default mode=0555 preserve=true
+file path=etc/gdm/Xsession mode=0555 preserve=true
+file path=etc/gdm/custom.conf mode=0644 preserve=true
+file files/gdm-launch-environment.pam path=etc/gdm/gdm-launch-environment.pam \
+    preserve=renamenew
+file files/gdm.auth_attr \
+    path=etc/security/auth_attr.d/system:display-manager:gdm
+file files/gdm.prof_attr \
+    path=etc/security/prof_attr.d/system:display-manager:gdm
+file files/gdm.user_attr path=etc/user_attr.d/system:display-manager:gdm
+file files/gdm.xml path=lib/svc/manifest/application/graphical-login/gdm.xml
+file files/svc-gdm path=lib/svc/method/svc-gdm
+file path=usr/bin/gdm-screenshot
+file path=usr/bin/gdmflexiserver
+file path=usr/include/gdm/gdm-client-glue.h
+file path=usr/include/gdm/gdm-client.h
+file path=usr/include/gdm/gdm-sessions.h
+file path=usr/include/gdm/gdm-user-switching.h
+file path=usr/lib/$(MACH64)/girepository-1.0/Gdm-1.0.typelib
+link path=usr/lib/$(MACH64)/libgdm.so target=libgdm.so.1.0.0
+link path=usr/lib/$(MACH64)/libgdm.so.1 target=libgdm.so.1.0.0
+file path=usr/lib/$(MACH64)/libgdm.so.1.0.0
+file path=usr/lib/$(MACH64)/pkgconfig/gdm.pc
+link path=usr/lib/gdm/ck-get-x11-display-device \
+    target=../ck-get-x11-display-device
+file path=usr/lib/gdm/gdm-host-chooser mode=0555
+file path=usr/lib/gdm/gdm-session-worker mode=0555
+file path=usr/lib/gdm/gdm-simple-chooser mode=0555
+# No Wayland for Solaris yet
+# file path=usr/lib/gdm/gdm-wayland-session
+file path=usr/lib/gdm/gdm-x-session mode=0555
+file path=usr/sbin/gdm
+file path=usr/share/dconf/profile/gdm
+file path=usr/share/gdm/gdb-cmd
+file path=usr/share/gdm/gdm.schemas
+file path=usr/share/gdm/greeter-dconf-defaults
+# No Wayland for Solaris yet
+# file path=usr/share/gdm/greeter/applications/gnome-shell-wayland.desktop
+file path=usr/share/gdm/greeter/applications/gnome-shell.desktop
+file path=usr/share/gdm/greeter/applications/mime-dummy-handler.desktop
+file path=usr/share/gdm/greeter/applications/mimeapps.list
+file path=usr/share/gdm/greeter/autostart/orca-autostart.desktop
+file path=usr/share/gdm/locale.alias
+file path=usr/share/gir-1.0/Gdm-1.0.gir
+file files/org.gnome.login-screen.gschema.override \
+    path=usr/share/glib-2.0/schemas/org.gnome.login-screen.gschema.override
+file path=usr/share/glib-2.0/schemas/org.gnome.login-screen.gschema.xml
+file path=usr/share/help/C/gdm/index.docbook
+file path=usr/share/help/C/gdm/legal.xml
+file path=usr/share/help/ca/gdm/index.docbook
+file path=usr/share/help/ca/gdm/legal.xml
+file path=usr/share/help/cs/gdm/index.docbook
+file path=usr/share/help/cs/gdm/legal.xml
+file path=usr/share/help/de/gdm/index.docbook
+file path=usr/share/help/de/gdm/legal.xml
+file path=usr/share/help/el/gdm/index.docbook
+file path=usr/share/help/el/gdm/legal.xml
+file path=usr/share/help/en_GB/gdm/index.docbook
+file path=usr/share/help/en_GB/gdm/legal.xml
+file path=usr/share/help/es/gdm/index.docbook
+file path=usr/share/help/es/gdm/legal.xml
+file path=usr/share/help/fr/gdm/index.docbook
+file path=usr/share/help/fr/gdm/legal.xml
+file path=usr/share/help/gl/gdm/index.docbook
+file path=usr/share/help/gl/gdm/legal.xml
+file path=usr/share/help/hu/gdm/index.docbook
+file path=usr/share/help/hu/gdm/legal.xml
+file path=usr/share/help/id/gdm/index.docbook
+file path=usr/share/help/id/gdm/legal.xml
+file path=usr/share/help/it/gdm/index.docbook
+file path=usr/share/help/it/gdm/legal.xml
+file path=usr/share/help/ko/gdm/index.docbook
+file path=usr/share/help/ko/gdm/legal.xml
+file path=usr/share/help/oc/gdm/index.docbook
+file path=usr/share/help/oc/gdm/legal.xml
+file path=usr/share/help/pt_BR/gdm/index.docbook
+file path=usr/share/help/pt_BR/gdm/legal.xml
+file path=usr/share/help/ro/gdm/index.docbook
+file path=usr/share/help/ro/gdm/legal.xml
+file path=usr/share/help/ru/gdm/index.docbook
+file path=usr/share/help/ru/gdm/legal.xml
+file path=usr/share/help/sl/gdm/index.docbook
+file path=usr/share/help/sl/gdm/legal.xml
+file path=usr/share/help/sv/gdm/index.docbook
+file path=usr/share/help/sv/gdm/legal.xml
+file path=usr/share/help/te/gdm/index.docbook
+file path=usr/share/help/te/gdm/legal.xml
+file path=usr/share/help/uk/gdm/index.docbook
+file path=usr/share/help/uk/gdm/legal.xml
+file path=usr/share/help/zh_CN/gdm/index.docbook
+file path=usr/share/help/zh_CN/gdm/legal.xml
+file path=usr/share/icons/hicolor/16x16/apps/gdm-xnest.png
+file path=usr/share/icons/hicolor/32x32/apps/gdm-setup.png
+file path=usr/share/icons/hicolor/32x32/apps/gdm-xnest.png
+file path=usr/share/locale/af/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/am/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/an/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ar/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/as/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ast/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/az/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/be/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/be@latin/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/bg/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/bn/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/bn_IN/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/br/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/bs/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ca/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ca@valencia/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/crh/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/cs/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/csb/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/cy/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/da/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/de/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/dz/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/el/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/en@shaw/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/en_CA/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/en_GB/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/eo/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/es/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/et/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/eu/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/fa/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/fi/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/fr/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/fur/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/fy/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ga/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/gd/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/gl/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/gu/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/gv/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/he/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/hi/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/hr/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/hu/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/hy/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/id/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/is/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/it/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ja/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ka/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/kab/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/kk/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/km/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/kn/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ko/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ku/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ky/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/lt/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/lv/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/mai/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/mg/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/mi/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/mk/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ml/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/mn/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/mr/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ms/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/nb/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/nds/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ne/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/nl/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/nn/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/nso/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/oc/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/or/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/pa/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/pl/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ps/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/pt/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/pt_BR/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ro/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ru/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/rw/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/si/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/sk/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/sl/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/sq/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/sr/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/sr@latin/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/sv/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ta/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/te/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/tg/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/th/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/tr/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/ug/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/uk/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/uz/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/uz@cyrillic/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/vi/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/wa/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/xh/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/zh_CN/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/zh_HK/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/zh_TW/LC_MESSAGES/gdm.mo
+file path=usr/share/locale/zu/LC_MESSAGES/gdm.mo
+file files/gdm.8 path=usr/share/man/man8/gdm.8
+file path=usr/share/pixmaps/gdm-foot-logo.png
+file path=usr/share/pixmaps/gdm-setup.png
+file path=usr/share/pixmaps/gdm-xnest.png
+file path=usr/share/pixmaps/gdm.png
+file path=usr/share/pixmaps/nobody.png
+file path=usr/share/pixmaps/nohost.png
+file files/xterm.desktop path=usr/share/xsessions/xterm.desktop
+dir  path=var/cache/gdm group=gdm mode=0755
+dir  path=var/lib/gdm group=gdm mode=1770
+dir  path=var/lib/gdm/.local group=gdm mode=0770
+dir  path=var/lib/gdm/.local/share group=gdm mode=0770
+dir  path=var/lib/gdm/.local/share/applications group=gdm mode=0770
+dir  path=var/log/gdm group=gdm mode=1770
+
+
+group groupname=gdm gid=50
+user username=gdm gcos-field="GDM Reserved UID" group=gdm \
+    home-dir=/var/lib/gdm password=*LK* uid=50
+license gdm.license license="GPL v2, LGPL v2, MIT"
+
+
+depend type=require fmri=__TBD \
+    pkg.debug.depend.file=etc/X11/xinit/xinitrc.d/0011.env
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/Xserver
+
+# Programs run by various session scripts in /etc/gdm/*
+# or /usr/share/gdm/greeter/*/*.desktop
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/audioctl
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/awk
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/chmod
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/chown
+# Commented out temporarily to break dependency loop in initial GNOME 3 build
+# Uncomment once gnome-shell is installed on Userland build machines
+# depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/gnome-shell
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/hostname
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/mkdir
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/orca
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/setxkbmap
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/stat
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/su
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/uname
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/xhost
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/xmodmap
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/xrdb
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/xterm
+depend type=require fmri=__TBD pkg.debug.depend.file=usr/bin/zenity
+
+# gsettings schemas referenced in gdm code
+depend type=require fmri=__TBD \
+    pkg.tmp.gsettings-schema=org.gnome.desktop.a11y.applications
+# Commented out temporarily to break dependency loop in initial GNOME 3 build
+# Uncomment once gnome-shell is installed on Userland build machines
+# depend type=require fmri=__TBD pkg.tmp.gsettings-schema=org.gnome.login-screen
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0001-fix-shutdown-crash.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,70 @@
+From ad177152bc5e75dcf4b04d60931a3723f3fba4df Mon Sep 17 00:00:00 2001
+From: Ray Strode <[email protected]>
+Date: Wed, 22 Jun 2016 10:13:07 -0400
+Subject: [PATCH 01/19] fix shutdown crash
+
+Backport of upstream fix from
+https://git.gnome.org/browse/gdm/commit/?id=e980b9101bfb1387df3cab4bf0c5ebdb4c6badbb
+
+local-display-factory: disconnect signal handlers when factory is disposed
+
+There's the potential for a crash in the shutdown path after the
+factory is disposed, since we fail to disconnect signal handlers to
+the displays / display store at factory dispose time.
+
+This commit changes the g_signal_connect to g_signal_connect_object, to
+avoid any potential for crash.
+
+(this is a fix noticed when reading through the source.  It's tangentially
+related to a discussion on irc for a different bug)
+---
+ daemon/gdm-local-display-factory.c | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
+index c794313..de6ecdd 100644
+--- a/daemon/gdm-local-display-factory.c
++++ b/daemon/gdm-local-display-factory.c
+@@ -549,8 +549,10 @@ on_display_added (GdmDisplayStore        *display_store,
+         display = gdm_display_store_lookup (display_store, id);
+ 
+         if (display != NULL) {
+-                g_signal_connect (display, "notify::status",
+-                                  G_CALLBACK (on_display_status_changed), factory);
++                g_signal_connect_object (display, "notify::status",
++                                         G_CALLBACK (on_display_status_changed),
++                                         factory,
++                                         0);
+ 
+                 g_object_weak_ref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory);
+         }
+@@ -582,15 +584,17 @@ gdm_local_display_factory_start (GdmDisplayFactory *base_factory)
+ 
+         store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
+ 
+-        g_signal_connect (G_OBJECT (store),
+-                          "display-added",
+-                          G_CALLBACK (on_display_added),
+-                          factory);
+-
+-        g_signal_connect (G_OBJECT (store),
+-                          "display-removed",
+-                          G_CALLBACK (on_display_removed),
+-                          factory);
++        g_signal_connect_object (G_OBJECT (store),
++                                 "display-added",
++                                 G_CALLBACK (on_display_added),
++                                 factory,
++                                 0);
++
++        g_signal_connect_object (G_OBJECT (store),
++                                 "display-removed",
++                                 G_CALLBACK (on_display_removed),
++                                 factory,
++                                 0);
+ 
+         gdm_local_display_factory_start_monitor (factory);
+         return gdm_local_display_factory_sync_seats (factory);
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0002-disable-systemd.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,2768 @@
+From 32964af4bf85ba8668606c8895795ec2af762b2c Mon Sep 17 00:00:00 2001
+From: Niveditha Rau <[email protected]>
+Date: Tue, 29 Dec 2015 11:59:18 -0800
+Subject: [PATCH 02/19] disable systemd
+
+---
+ common/gdm-common.c                | 330 ++++++++++++++++++++++-
+ common/gdm-common.h                |   3 +
+ common/gdm-log.c                   |  21 ++
+ configure.ac                       |  80 +++---
+ daemon/Makefile.am                 |  10 +
+ daemon/gdm-launch-environment.c    |   5 +
+ daemon/gdm-local-display-factory.c |  60 ++++-
+ daemon/gdm-manager.c               | 531 ++++++++++++++++++++++++++++++++++---
+ daemon/gdm-server.c                |  75 +++++-
+ daemon/gdm-session-record.c        | 102 ++++++-
+ daemon/gdm-session-worker-job.c    |   3 +
+ daemon/gdm-session-worker.c        | 277 ++++++++++++++++++-
+ daemon/gdm-session-worker.xml      |   3 +
+ daemon/gdm-session.c               |  26 ++
+ daemon/gdm-session.h               |   2 +
+ libgdm/gdm-user-switching.c        | 351 +++++++++++++++++++++++-
+ 16 files changed, 1749 insertions(+), 130 deletions(-)
+
+diff --git a/common/gdm-common.c b/common/gdm-common.c
+index a96b30f..e06f0d9 100644
+--- a/common/gdm-common.c
++++ b/common/gdm-common.c
+@@ -39,12 +39,25 @@
+ #include "mkdtemp.h"
+ #endif
+ 
++#ifdef WITH_SYSTEMD
+ #include <systemd/sd-login.h>
++#endif
+ 
+ #define GDM_DBUS_NAME                            "org.gnome.DisplayManager"
+ #define GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH      "/org/gnome/DisplayManager/LocalDisplayFactory"
+ #define GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE "org.gnome.DisplayManager.LocalDisplayFactory"
+ 
++#ifdef WITH_CONSOLE_KIT
++#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_SEAT_INTERFACE    "org.freedesktop.ConsoleKit.Seat"
++#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
++#endif
++
+ G_DEFINE_QUARK (gdm-common-error, gdm_common_error);
+ 
+ const char *
+@@ -343,10 +356,300 @@ create_transient_display (GDBusConnection *connection,
+         return TRUE;
+ }
+ 
++#ifdef WITH_CONSOLE_KIT
++static gboolean
++get_current_session_id (GDBusConnection  *connection,
++                        char            **session_id)
++{
++        GError *local_error = NULL;
++        GVariant *reply;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             CK_NAME,
++                                             CK_MANAGER_PATH,
++                                             CK_MANAGER_INTERFACE,
++                                             "GetCurrentSession",
++                                             NULL, /* parameters */
++                                             G_VARIANT_TYPE ("(o)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL, &local_error);
++        if (reply == NULL) {
++                g_warning ("Unable to determine session: %s", local_error->message);
++                g_error_free (local_error);
++                return FALSE;
++        }
++
++        g_variant_get (reply, "(o)", session_id);
++        g_variant_unref (reply);
++
++        return TRUE;
++}
++
++static gboolean
++get_seat_id_for_session (GDBusConnection  *connection,
++                         const char       *session_id,
++                         char            **seat_id)
++{
++        GError *local_error = NULL;
++        GVariant *reply;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             CK_NAME,
++                                             session_id,
++                                             CK_SESSION_INTERFACE,
++                                             "GetSeatId",
++                                             NULL, /* parameters */
++                                             G_VARIANT_TYPE ("(o)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL, &local_error);
++        if (reply == NULL) {
++                g_warning ("Unable to determine seat: %s", local_error->message);
++                g_error_free (local_error);
++                return FALSE;
++        }
++
++        g_variant_get (reply, "(o)", seat_id);
++        g_variant_unref (reply);
++
++        return TRUE;
++}
++
++static char *
++get_current_seat_id (GDBusConnection *connection)
++{
++        gboolean res;
++        char    *session_id;
++        char    *seat_id;
++
++        session_id = NULL;
++        seat_id = NULL;
++
++        res = get_current_session_id (connection, &session_id);
++        if (res) {
++                res = get_seat_id_for_session (connection, session_id, &seat_id);
++        }
++        g_free (session_id);
++
++        return seat_id;
++}
++
++static gboolean
++activate_session_id_for_ck (GDBusConnection *connection,
++                            const char      *seat_id,
++                            const char      *session_id)
++{
++        GError *local_error = NULL;
++        GVariant *reply;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             CK_NAME,
++                                             seat_id,
++                                             CK_SEAT_INTERFACE,
++                                             "ActivateSession",
++                                             g_variant_new ("(o)", session_id),
++                                             NULL,
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL, &local_error);
++        if (reply == NULL) {
++                g_warning ("Unable to activate session: %s", local_error->message);
++                g_error_free (local_error);
++                return FALSE;
++        }
++
++        g_variant_unref (reply);
++
++        return TRUE;
++}
++
+ static gboolean
+-activate_session_id (GDBusConnection *connection,
+-                     const char      *seat_id,
+-                     const char      *session_id)
++session_is_login_window (GDBusConnection *connection,
++                         const char      *session_id)
++{
++        GError *local_error = NULL;
++        GVariant *reply;
++        const char *value;
++        gboolean ret;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             CK_NAME,
++                                             session_id,
++                                             CK_SESSION_INTERFACE,
++                                             "GetSessionType",
++                                             NULL,
++                                             G_VARIANT_TYPE ("(s)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL, &local_error);
++        if (reply == NULL) {
++                g_warning ("Unable to determine session type: %s", local_error->message);
++                g_error_free (local_error);
++                return FALSE;
++        }
++
++        g_variant_get (reply, "(&s)", &value);
++
++        if (value == NULL || value[0] == '\0' || strcmp (value, "LoginWindow") != 0) {
++                ret = FALSE;
++        } else {
++                ret = TRUE;
++        }
++
++        g_variant_unref (reply);
++
++        return ret;
++}
++
++static gboolean
++seat_can_activate_sessions (GDBusConnection *connection,
++                            const char      *seat_id)
++{
++        GError *local_error = NULL;
++        GVariant *reply;
++        gboolean ret;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             CK_NAME,
++                                             seat_id,
++                                             CK_SEAT_INTERFACE,
++                                             "CanActivateSessions",
++                                             NULL,
++                                             G_VARIANT_TYPE ("(b)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL, &local_error);
++        if (reply == NULL) {
++                g_warning ("Unable to determine if can activate sessions: %s", local_error->message);
++                g_error_free (local_error);
++                return FALSE;
++        }
++
++        g_variant_get (reply, "(b)", &ret);
++        g_variant_unref (reply);
++
++        return ret;
++}
++
++static const char **
++seat_get_sessions (GDBusConnection *connection,
++                   const char      *seat_id)
++{
++        GError *local_error = NULL;
++        GVariant *reply;
++        const char **value;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             CK_NAME,
++                                             seat_id,
++                                             CK_SEAT_INTERFACE,
++                                             "GetSessions",
++                                             NULL,
++                                             G_VARIANT_TYPE ("(ao)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL, &local_error);
++        if (reply == NULL) {
++                g_warning ("Unable to list sessions: %s", local_error->message);
++                g_error_free (local_error);
++                return FALSE;
++        }
++
++        g_variant_get (reply, "(^ao)", &value);
++        g_variant_unref (reply);
++
++        return value;
++}
++
++static gboolean
++get_login_window_session_id_for_ck (GDBusConnection  *connection,
++                                    const char       *seat_id,
++                                    char            **session_id)
++{
++        gboolean     can_activate_sessions;
++        const char **sessions;
++        int          i;
++
++        *session_id = NULL;
++        sessions = NULL;
++
++        g_debug ("checking if seat can activate sessions");
++
++        can_activate_sessions = seat_can_activate_sessions (connection, seat_id);
++        if (! can_activate_sessions) {
++                g_debug ("seat is unable to activate sessions");
++                return FALSE;
++        }
++
++        sessions = seat_get_sessions (connection, seat_id);
++        for (i = 0; sessions [i] != NULL; i++) {
++                const char *ssid;
++
++                ssid = sessions [i];
++
++                if (session_is_login_window (connection, ssid)) {
++                        *session_id = g_strdup (ssid);
++                        break;
++                }
++        }
++        g_free (sessions);
++
++        return TRUE;
++}
++
++static gboolean
++goto_login_session_for_ck (GDBusConnection  *connection,
++                           GError          **error)
++{
++        gboolean        ret;
++        gboolean        res;
++        char           *session_id;
++        char           *seat_id;
++
++        ret = FALSE;
++
++        /* First look for any existing LoginWindow sessions on the seat.
++           If none are found, create a new one. */
++
++        seat_id = get_current_seat_id (connection);
++        if (seat_id == NULL || seat_id[0] == '\0') {
++                g_debug ("seat id is not set; can't switch sessions");
++                g_set_error (error, GDM_COMMON_ERROR, 0, _("Could not identify the current session."));
++
++                return FALSE;
++        }
++
++        res = get_login_window_session_id_for_ck (connection, seat_id, &session_id);
++        if (! res) {
++                g_set_error (error, GDM_COMMON_ERROR, 1, _("User unable to switch sessions."));
++                return FALSE;
++        }
++
++        if (session_id != NULL) {
++                res = activate_session_id_for_ck (connection, seat_id, session_id);
++                if (res) {
++                        ret = TRUE;
++                }
++        }
++
++        if (! ret && g_strcmp0 (seat_id, "/org/freedesktop/ConsoleKit/Seat1") == 0) {
++                res = create_transient_display (connection, error);
++                if (res) {
++                        ret = TRUE;
++                }
++        }
++
++        return ret;
++}
++#endif
++
++#ifdef WITH_SYSTEMD
++
++static gboolean
++activate_session_id_for_systemd (GDBusConnection *connection,
++                                 const char      *seat_id,
++                                 const char      *session_id)
+ {
+         GError *local_error = NULL;
+         GVariant *reply;
+@@ -373,8 +676,8 @@ activate_session_id (GDBusConnection *connection,
+ }
+ 
+ static gboolean
+-get_login_window_session_id (const char  *seat_id,
+-                             char       **session_id)
++get_login_window_session_id_for_systemd (const char  *seat_id,
++					char       **session_id)
+ {
+         gboolean   ret;
+         int        res, i;
+@@ -442,7 +745,7 @@ out:
+ }
+ 
+ static gboolean
+-goto_login_session (GDBusConnection  *connection,
++goto_login_session_for_systemd (GDBusConnection  *connection,
+                     GError          **error)
+ {
+         gboolean        ret;
+@@ -497,7 +800,7 @@ goto_login_session (GDBusConnection  *connection,
+                 return FALSE;
+         }
+ 
+-        res = get_login_window_session_id (seat_id, &session_id);
++        res = get_login_window_session_id_for_systemd (seat_id, &session_id);
+         if (res && session_id != NULL) {
+                 res = activate_session_id (connection, seat_id, session_id);
+ 
+@@ -518,6 +821,7 @@ goto_login_session (GDBusConnection  *connection,
+ 
+         return ret;
+ }
++#endif
+ 
+ gboolean
+ gdm_goto_login_session (GError **error)
+@@ -533,7 +837,17 @@ gdm_goto_login_session (GError **error)
+                 return FALSE;
+         }
+ 
+-        return goto_login_session (connection, error);
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                return goto_login_session_for_systemd (connection, error);
++        }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++        return goto_login_session_for_ck (connection, error);
++#else
++        return FALSE;
++#endif
+ }
+ 
+ static void
+diff --git a/common/gdm-common.h b/common/gdm-common.h
+index d0812ed..19dbbbb 100644
+--- a/common/gdm-common.h
++++ b/common/gdm-common.h
+@@ -33,6 +33,9 @@
+ 
+ #define GDM_CUSTOM_SESSION  "custom"
+ 
++/* check if logind is running */
++#define LOGIND_RUNNING() (access("/run/systemd/seats/", F_OK) >= 0)
++
+ GQuark gdm_common_error_quark (void);
+ #define GDM_COMMON_ERROR gdm_common_error_quark()
+ 
+diff --git a/common/gdm-log.c b/common/gdm-log.c
+index 8a2d015..03b7bcc 100644
+--- a/common/gdm-log.c
++++ b/common/gdm-log.c
+@@ -30,7 +30,9 @@
+ #include <unistd.h>
+ 
+ #include <syslog.h>
++#ifdef WITH_SYSTEMD
+ #include <systemd/sd-daemon.h>
++#endif
+ 
+ #include <glib.h>
+ #include <glib/gstdio.h>
+@@ -132,8 +134,27 @@ gdm_log_init (void)
+                 return;
+ 
+         initialized = TRUE;
++#ifdef WITH_SYSTEMD
++        is_sd_booted = sd_booted () > 0;
++#endif
+ 
+         g_log_set_default_handler (gdm_log_default_handler, NULL);
++
++        /* Only set up syslog if !systemd, otherwise with systemd
++         * enabled, we keep the default GLib log handler which goes to
++         * stderr, which is routed to the appropriate place in the
++         * systemd service file.
++         */
++        if (!is_sd_booted) {
++                prg_name = g_get_prgname ();
++
++                options = LOG_PID;
++#ifdef LOG_PERROR
++                options |= LOG_PERROR;
++#endif
++
++                openlog (prg_name, options, LOG_DAEMON);
++        }
+ }
+ 
+ void
+diff --git a/configure.ac b/configure.ac
+index bedac99..0ada667 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -244,6 +244,15 @@ AC_ARG_WITH(tcp-wrappers,
+                            [Use TCP Wrappers @<:@default=auto@:>@]),,
+             with_tcp_wrappers=auto)
+ 
++AC_ARG_WITH(console-kit,
++            AS_HELP_STRING([--with-console-kit],
++                           [Add ConsoleKit support @<:@default=auto@:>@]),,
++            with_console_kit=no)
++
++AC_ARG_WITH(systemd,
++            AS_HELP_STRING([--with-systemd],
++                           [Add systemd support @<:@default=auto@:>@]),
++            [with_systemd=$withval], [with_systemd=auto])
+ 
+ AC_ARG_WITH([systemdsystemunitdir],
+             AS_HELP_STRING([--with-systemdsystemunitdir=DIR],
+@@ -614,14 +623,8 @@ dnl ---------------------------------------------------------------------------
+ dnl - Check for utmp stuff
+ dnl ---------------------------------------------------------------------------
+ 
+-AC_CHECK_HEADERS(utmp.h utmpx.h libutil.h sys/param.h)
+-AC_CHECK_FUNCS([getutxent updwtmpx updwtmp])
+-AC_CHECK_LIB(util, login, [
+-		   AC_DEFINE(HAVE_LOGIN, 1, [Define if have login])
+-		       EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -lutil" ])
+-AC_CHECK_LIB(util, logout, [
+-		   AC_DEFINE(HAVE_LOGOUT, 1, [Define if have logout])
+-		       EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -lutil" ])
++AC_CHECK_HEADERS(utmp.h utmpx.h util.h sys/param.h)
++AC_CHECK_FUNCS([getutxent getttyent updwtmpx updwtmp])
+ AC_CHECK_LIB(util, logwtmp, [
+ 	  	   AC_DEFINE(HAVE_LOGWTMP, 1, [Define if have logwtmp])
+ 		       EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -lutil" ])
+@@ -870,51 +873,16 @@ AC_SUBST(XINERAMA_LIBS)
+ CPPFLAGS="$xinerama_save_cppflags"
+ 
+ dnl ---------------------------------------------------------------------------
+-dnl - Check for systemd support
++dnl - Check for ConsoleKit support
+ dnl ---------------------------------------------------------------------------
+ 
+-PKG_CHECK_MODULES(SYSTEMD,
+-                  [libsystemd])
+-
+-AC_SUBST(SYSTEMD_CFLAGS)
+-AC_SUBST(SYSTEMD_LIBS)
+-
+-PKG_CHECK_MODULES(JOURNALD,
+-                  [libsystemd],
+-                  [have_journald=yes], [have_journald=no])
+-
+-if test "x$enable_systemd_journal" = "xauto" ; then
+-        if test x$have_journald = xno ; then
+-                use_journald=no
+-        else
+-                use_journald=yes
+-        fi
+-
+-else
+-        use_journald="$enable_systemd_journal"
+-fi
+-
+-if test "x$use_journald" != "xno" ; then
+-        if test "x$have_journald" = "xno"; then
+-                AC_MSG_ERROR([journald support explicitly required, but journald not found])
+-        fi
+-
+-        AC_DEFINE(ENABLE_SYSTEMD_JOURNAL, 1, [Define to enable systemd journal support])
+-fi
+-AC_SUBST(JOURNALD_CFLAGS)
+-AC_SUBST(JOURNALD_LIBS)
+-
+-if test "x$enable_wayland_support" != "xno" ; then
+-        AC_DEFINE(ENABLE_WAYLAND_SUPPORT, 1, [Define to enable wayland support])
+-fi
+-
+-AC_PATH_PROG(SYSTEMD_X_SERVER, systemd-multi-seat-x, [/lib/systemd/systemd-multi-seat-x], [/lib/systemd:/usr/lib/systemd:$PATH])
+-AC_SUBST(SYSTEMD_X_SERVER)
+-AC_DEFINE_UNQUOTED(SYSTEMD_X_SERVER,"$SYSTEMD_X_SERVER",[Path to systemd X server wrapper])
+-
+-if test "x$with_systemdsystemunitdir" != xno; then
+-        AC_SUBST(SYSTEMD_SYSTEM_UNIT_DIR, [$with_systemdsystemunitdir])
++use_console_kit=no
++if test "x$with_console_kit" != "xno" ; then
++       use_console_kit=yes
++       AC_DEFINE(WITH_CONSOLE_KIT, 1, [Define to enable ConsoleKit support])
+ fi
++AM_CONDITIONAL(WITH_CONSOLE_KIT, test x$use_console_kit = xyes)
++AC_SUBST(WITH_CONSOLE_KIT)
+ 
+ dnl ---------------------------------------------------------------------------
+ dnl - Check for plymouth support
+@@ -1068,6 +1036,15 @@ fi
+ AC_SUBST(GDM_CUSTOM_CONF)
+ AC_SUBST(GDM_OLD_CONF, '${gdmconfdir}/gdm.conf')
+ 
++AC_ARG_WITH(consolekit-directory,
++              [AC_HELP_STRING([--with-consolekit-directory],
++                              [Specify the directory of ck-get-x11-display-device @<:@default=libexecdir@:>@])],,
++                              [with_consolekit_directory="\${libexecdir}"])
++
++CONSOLEKIT_DIR=$with_consolekit_directory
++AC_SUBST(CONSOLEKIT_DIR)
++
++
+ AC_ARG_WITH(gnome-settings-daemon-directory,
+               [AC_HELP_STRING([--with-gnome-settings-daemon-directory],
+                               [Specify the directory of gnome-settings-daemon used by the chooser @<:@default=libexecdir@:>@])],,
+@@ -1549,6 +1526,7 @@ echo "
+         dmconfdir:                ${dmconfdir}
+         localstatedir:            ${localstatedir}
+         datadir:                  ${datadir}
++	consolekit location:      ${with_consolekit_directory}
+ 	gnome-settings-daemon location: ${with_gnome_settings_daemon_directory}
+ 	gnome-session-check-accel location: ${with_check_accelerated_directory}
+ 	source code location:	  ${srcdir}
+@@ -1578,6 +1556,8 @@ echo \
+ "        Xinerama support:         ${XINERAMA_SUPPORT}
+         XDMCP support:            ${XDMCP_SUPPORT}
+         SELinux support:          ${use_selinux}
++        ConsoleKit support:       ${use_console_kit}
++        systemd support:          ${use_systemd}
+         systemd unit dir:         ${with_systemdsystemunitdir}
+         plymouth support:         ${use_plymouth}
+         wayland support:          ${use_wayland}
+diff --git a/daemon/Makefile.am b/daemon/Makefile.am
+index ab5dda0..dece5db 100644
+--- a/daemon/Makefile.am
++++ b/daemon/Makefile.am
+@@ -20,6 +20,7 @@ AM_CPPFLAGS = \
+ 	-DGDM_SCREENSHOT_DIR=\"$(GDM_SCREENSHOT_DIR)\"		\
+ 	-DGDM_CACHE_DIR=\""$(localstatedir)/cache/gdm"\"	\
+ 	-DGDM_SESSION_DEFAULT_PATH=\"$(GDM_SESSION_DEFAULT_PATH)\" \
++	-DCONSOLEKIT_DIR=\"$(CONSOLEKIT_DIR)\" 		\
+ 	$(DISABLE_DEPRECATED_CFLAGS)			\
+ 	$(DAEMON_CFLAGS)				\
+ 	$(XLIB_CFLAGS)					\
+@@ -264,6 +265,11 @@ EXTRA_gdm_SOURCES = 	\
+ 	$(XDMCP_SOURCES)	\
+ 	$(NULL)
+ 
++CONSOLE_KIT_SOURCES =          \
++       $(NULL)
++
++EXTRA_gdm_SOURCES += $(CONSOLE_KIT_SOURCES)
++
+ gdm_LDADD = \
+ 	$(top_builddir)/common/libgdmcommon.la	\
+ 	$(XLIB_LIBS)				\
+@@ -275,6 +281,10 @@ gdm_LDADD = \
+ 	$(EXTRA_DAEMON_LIBS)			\
+ 	$(NULL)
+ 
++if WITH_CONSOLE_KIT
++gdm_SOURCES += $(CONSOLE_KIT_SOURCES)
++endif
++
+ CLEANFILES =					\
+ 	gdm-display-glue.c			\
+ 	gdm-local-display-factory-glue.c	\
+diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c
+index 1beceea..b176c63 100644
+--- a/daemon/gdm-launch-environment.c
++++ b/daemon/gdm-launch-environment.c
+@@ -176,6 +176,9 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment,
+                 char *seat_id;
+ 
+                 seat_id = launch_environment->priv->x11_display_seat_id;
++                if (g_str_has_prefix (seat_id, "/org/freedesktop/ConsoleKit/")) {
++                        seat_id += strlen ("/org/freedesktop/ConsoleKit/");
++                }
+ 
+                 g_hash_table_insert (hash, g_strdup ("GDM_SEAT_ID"), g_strdup (seat_id));
+         }
+@@ -204,6 +207,8 @@ on_session_setup_complete (GdmSession        *session,
+                 gdm_session_set_environment_variable (launch_environment->priv->session, key, value);
+         }
+         g_hash_table_destroy (hash);
++
++        gdm_session_select_session_type (launch_environment->priv->session, "LoginWindow");
+ }
+ 
+ static void
+diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
+index de6ecdd..5d58a89 100644
+--- a/daemon/gdm-local-display-factory.c
++++ b/daemon/gdm-local-display-factory.c
+@@ -42,6 +42,8 @@
+ 
+ #define GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_LOCAL_DISPLAY_FACTORY, GdmLocalDisplayFactoryPrivate))
+ 
++
++#define CK_SEAT1_PATH                       "/org/freedesktop/ConsoleKit/Seat1"
+ #define SYSTEMD_SEAT0_PATH                  "seat0"
+ 
+ #define GDM_DBUS_PATH                       "/org/gnome/DisplayManager"
+@@ -59,8 +61,10 @@ struct GdmLocalDisplayFactoryPrivate
+         /* FIXME: this needs to be per seat? */
+         guint            num_failures;
+ 
++#ifdef WITH_SYSTEMD
+         guint            seat_new_id;
+         guint            seat_removed_id;
++#endif
+ };
+ 
+ enum {
+@@ -190,8 +194,22 @@ store_display (GdmLocalDisplayFactory *factory,
+ static const char *
+ get_seat_of_transient_display (GdmLocalDisplayFactory *factory)
+ {
++
++        const char *seat_id = NULL;
++
+         /* FIXME: don't hardcode seat */
+-        return SYSTEMD_SEAT0_PATH;
++
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING() > 0) {
++                seat_id = SYSTEMD_SEAT0_PATH;
++        }
++#endif
++
++        if (seat_id == NULL) {
++                seat_id = CK_SEAT1_PATH;
++        }
++
++        return seat_id;
+ }
+ 
+ /*
+@@ -216,7 +234,19 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact
+ 
+         g_debug ("GdmLocalDisplayFactory: Creating transient display");
+ 
+-        display = gdm_local_display_new ();
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING() > 0) {
++                display = gdm_local_display_new ();
++        }
++#endif
++
++        if (display == NULL) {
++                guint32 num;
++
++                num = take_next_display_number (factory);
++
++                display = gdm_legacy_display_new (num);
++        }
+ 
+         seat_id = get_seat_of_transient_display (factory);
+         g_object_set (display,
+@@ -290,7 +320,7 @@ on_display_status_changed (GdmDisplay             *display,
+                         /* reset num failures */
+                         factory->priv->num_failures = 0;
+ 
+-                        gdm_local_display_factory_sync_seats (factory);
++                       create_display (factory, seat_id, session_type, is_initial);
+                 }
+                 break;
+         case GDM_DISPLAY_FAILED:
+@@ -371,13 +401,14 @@ create_display (GdmLocalDisplayFactory *factory,
+ 
+         g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id);
+ 
+-
++#ifdef WITH_SYSTEMD
+         if (g_strcmp0 (seat_id, "seat0") == 0) {
+                 display = gdm_local_display_new ();
+                 if (session_type != NULL) {
+                         g_object_set (G_OBJECT (display), "session-type", session_type, NULL);
+                 }
+         }
++#endif
+ 
+         if (display == NULL) {
+                 guint32 num;
+@@ -402,6 +433,7 @@ create_display (GdmLocalDisplayFactory *factory,
+         return display;
+ }
+ 
++#ifdef WITH_SYSTEMD
+ static void
+ delete_display (GdmLocalDisplayFactory *factory,
+                 const char             *seat_id) {
+@@ -538,6 +570,7 @@ gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory)
+                 factory->priv->seat_removed_id = 0;
+         }
+ }
++#endif
+ 
+ static void
+ on_display_added (GdmDisplayStore        *display_store,
+@@ -578,6 +611,7 @@ static gboolean
+ gdm_local_display_factory_start (GdmDisplayFactory *base_factory)
+ {
+         GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory);
++        GdmDisplay             *display;
+         GdmDisplayStore *store;
+ 
+         g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
+@@ -596,8 +630,18 @@ gdm_local_display_factory_start (GdmDisplayFactory *base_factory)
+                                  factory,
+                                  0);
+ 
+-        gdm_local_display_factory_start_monitor (factory);
+-        return gdm_local_display_factory_sync_seats (factory);
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                gdm_local_display_factory_start_monitor (factory);
++                return gdm_local_display_factory_sync_seats (factory);
++        }
++#endif
++
++
++        /* On ConsoleKit just create Seat1, and that's it. */
++        display = create_display (factory, CK_SEAT1_PATH, NULL, TRUE);
++
++        return display != NULL;
+ }
+ 
+ static gboolean
+@@ -608,7 +652,9 @@ gdm_local_display_factory_stop (GdmDisplayFactory *base_factory)
+ 
+         g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
+ 
++#ifdef WITH_SYSTEMD
+         gdm_local_display_factory_stop_monitor (factory);
++#endif
+ 
+         store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
+ 
+@@ -764,7 +810,9 @@ gdm_local_display_factory_finalize (GObject *object)
+ 
+         g_hash_table_destroy (factory->priv->used_display_numbers);
+ 
++#ifdef WITH_SYSTEMD
+         gdm_local_display_factory_stop_monitor (factory);
++#endif
+ 
+         G_OBJECT_CLASS (gdm_local_display_factory_parent_class)->finalize (object);
+ }
+diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
+index 7602e75..3d1d2eb 100644
+--- a/daemon/gdm-manager.c
++++ b/daemon/gdm-manager.c
+@@ -34,7 +34,9 @@
+ #include <glib/gstdio.h>
+ #include <glib-object.h>
+ 
++#ifdef WITH_SYSTEMD
+ #include <systemd/sd-login.h>
++#endif
+ 
+ #include "gdm-common.h"
+ 
+@@ -59,6 +61,15 @@
+ 
+ #define INITIAL_SETUP_USERNAME "gnome-initial-setup"
+ 
++#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_SEAT_INTERFACE    "org.freedesktop.ConsoleKit.Seat"
++#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
++
+ typedef struct
+ {
+         GdmManager *manager;
+@@ -202,9 +213,10 @@ plymouth_quit_without_transition (void)
+ }
+ #endif
+ 
++#ifdef WITH_SYSTEMD
+ static char *
+-get_session_id_for_pid (pid_t    pid,
+-                        GError **error)
++get_session_id_for_pid_systemd (pid_t    pid,
++                                GError **error)
+ {
+         char *session, *gsession;
+         int ret;
+@@ -229,11 +241,61 @@ get_session_id_for_pid (pid_t    pid,
+                 return NULL;
+         }
+ }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++static char *
++get_session_id_for_pid_consolekit (GDBusConnection  *connection,
++                                   pid_t             pid,
++                                   GError          **error)
++{
++        GVariant *reply;
++        char *retval;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             "org.freedesktop.ConsoleKit",
++                                             "/org/freedesktop/ConsoleKit/Manager",
++                                             "org.freedesktop.ConsoleKit.Manager",
++                                             "GetSessionForUnixProcess",
++                                             g_variant_new ("(u)", pid),
++                                             G_VARIANT_TYPE ("(o)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL, error);
++        if (reply == NULL) {
++                return NULL;
++        }
++
++        g_variant_get (reply, "(o)", &retval);
++        g_variant_unref (reply);
++
++        return retval;
++}
++#endif
+ 
++static char *
++get_session_id_for_pid (GDBusConnection  *connection,
++                        pid_t             pid,
++                        GError          **error)
++{
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                return get_session_id_for_pid_systemd (pid, error);
++        }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++        return get_session_id_for_pid_consolekit (connection, pid, error);
++#endif
++
++        return NULL;
++}
++
++#ifdef WITH_SYSTEMD
+ static gboolean
+-get_uid_for_session_id (const char  *session_id,
+-                        uid_t       *uid,
+-                        GError     **error)
++get_uid_for_systemd_session_id (const char  *session_id,
++                                uid_t       *uid,
++                                GError     **error)
+ {
+         int ret;
+ 
+@@ -250,6 +312,61 @@ get_uid_for_session_id (const char  *session_id,
+ 
+         return TRUE;
+ }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++static gboolean
++
++get_uid_for_consolekit_session_id (GDBusConnection  *connection,
++                                   const char       *session_id,
++                                   uid_t            *out_uid,
++                                   GError          **error)
++{
++        GVariant *reply;
++        guint32 uid;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             "org.freedesktop.ConsoleKit",
++                                             session_id,
++                                             "org.freedesktop.ConsoleKit.Session",
++                                             "GetUnixUser",
++                                             NULL,
++                                             G_VARIANT_TYPE ("(u)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL,
++                                             error);
++        if (reply == NULL) {
++                return FALSE;
++        }
++
++        g_variant_get (reply, "(u)", &uid);
++        g_variant_unref (reply);
++
++        *out_uid = (uid_t) uid;
++
++        return TRUE;
++}
++#endif
++
++static gboolean
++get_uid_for_session_id (GDBusConnection  *connection,
++                        const char       *session_id,
++                        uid_t            *uid,
++                        GError          **error)
++{
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                return get_uid_for_systemd_session_id (session_id, uid, error);
++        }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++        return get_uid_for_consolekit_session_id (connection, session_id, uid, error);
++#endif
++
++        return FALSE;
++}
+ 
+ static gboolean
+ lookup_by_session_id (const char *id,
+@@ -263,10 +380,50 @@ lookup_by_session_id (const char *id,
+         return g_strcmp0 (current, looking_for) == 0;
+ }
+ 
++#ifdef WITH_CONSOLE_KIT
+ static gboolean
+-is_login_session (GdmManager  *self,
+-                  const char  *session_id,
+-                  GError     **error)
++is_consolekit_login_session (GdmManager       *self,
++                             GDBusConnection  *connection,
++                             const char       *session_id,
++                             GError          **error)
++{
++        GVariant *reply;
++        char *session_type = NULL;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             "org.freedesktop.ConsoleKit",
++                                             session_id,
++                                             "org.freedesktop.ConsoleKit.Session",
++                                             "GetSessionType",
++                                             NULL,
++                                             G_VARIANT_TYPE ("(s)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL,
++                                             error);
++        if (reply == NULL) {
++                return FALSE;
++        }
++
++        g_variant_get (reply, "(s)", &session_type);
++        g_variant_unref (reply);
++
++        if (g_strcmp0 (session_type, "LoginWindow") != 0) {
++                g_free (session_type);
++
++                return FALSE;
++        }
++
++        g_free (session_type);
++        return TRUE;
++}
++#endif
++
++#ifdef WITH_SYSTEMD
++static gboolean
++is_systemd_login_session (GdmManager  *self,
++                          const char  *session_id,
++                          GError     **error)
+ {
+         char *session_class = NULL;
+         int ret;
+@@ -291,11 +448,32 @@ is_login_session (GdmManager  *self,
+         g_free (session_class);
+         return TRUE;
+ }
++#endif
+ 
+ static gboolean
+-activate_session_id (GdmManager *manager,
+-                     const char *seat_id,
+-                     const char *session_id)
++is_login_session (GdmManager       *self,
++                  GDBusConnection  *connection,
++                  const char       *session_id,
++                  GError          **error)
++{
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                return is_systemd_login_session (self, session_id, error);
++        }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++        return is_consolekit_login_session (self, connection, session_id, error);
++#endif
++
++        return FALSE;
++}
++
++#ifdef WITH_SYSTEMD
++static gboolean
++activate_session_id_for_systemd (GdmManager   *manager,
++                                 const char *seat_id,
++                                 const char *session_id)
+ {
+         GError *error = NULL;
+         GVariant *reply;
+@@ -322,15 +500,74 @@ activate_session_id (GdmManager *manager,
+ 
+         return TRUE;
+ }
++#endif
+ 
++#ifdef WITH_CONSOLE_KIT
+ static gboolean
+-session_unlock (GdmManager *manager,
+-                const char *ssid)
++activate_session_id_for_ck (GdmManager *manager,
++                            const char *seat_id,
++                            const char *session_id)
+ {
+         GError *error = NULL;
+         GVariant *reply;
+ 
+-        g_debug ("Unlocking session %s", ssid);
++        reply = g_dbus_connection_call_sync (manager->priv->connection,
++                                             CK_NAME,
++                                             seat_id,
++                                             "org.freedesktop.ConsoleKit.Seat",
++                                             "ActivateSession",
++                                             g_variant_new ("(o)", session_id),
++                                             NULL, /* expected reply */
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL,
++                                             &error);
++        if (reply == NULL) {
++                g_debug ("GdmManager: ConsoleKit %s raised:\n %s\n\n",
++                         g_dbus_error_get_remote_error (error), error->message);
++                g_error_free (error);
++
++                /* It is very likely that the "error" just reported is
++                 * that the session is already active.  Unfortunately,
++                 * ConsoleKit doesn't use proper error codes and it
++                 * translates the error message, so we have no real way
++                 * to detect this case...
++                 */
++                return TRUE;
++        }
++
++        g_variant_unref (reply);
++
++        return TRUE;
++}
++#endif
++
++static gboolean
++activate_session_id (GdmManager *manager,
++                     const char *seat_id,
++                     const char *session_id)
++{
++
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                return activate_session_id_for_systemd (manager, seat_id, session_id);
++        }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++        return activate_session_id_for_ck (manager, seat_id, session_id);
++#else
++        return FALSE;
++#endif
++}
++
++#ifdef WITH_SYSTEMD
++static gboolean
++session_unlock_for_systemd (GdmManager *manager,
++                            const char *ssid)
++{
++        GError *error = NULL;
++        GVariant *reply;
+ 
+         reply = g_dbus_connection_call_sync (manager->priv->connection,
+                                              "org.freedesktop.login1",
+@@ -354,6 +591,60 @@ session_unlock (GdmManager *manager,
+ 
+         return TRUE;
+ }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++static gboolean
++session_unlock_for_ck (GdmManager *manager,
++                       const char *ssid)
++{
++        GError *error = NULL;
++        GVariant *reply;
++
++        reply = g_dbus_connection_call_sync (manager->priv->connection,
++                                             CK_NAME,
++                                             ssid,
++                                             CK_SESSION_INTERFACE,
++                                             "Unlock",
++                                             NULL, /* parameters */
++                                             NULL, /* expected reply */
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL,
++                                             &error);
++        if (reply == NULL) {
++                g_debug ("GdmManager: ConsoleKit %s raised:\n %s\n\n",
++                         g_dbus_error_get_remote_error (error), error->message);
++                g_error_free (error);
++                return FALSE;
++        }
++
++        g_variant_unref (reply);
++
++        return TRUE;
++}
++#endif
++
++static gboolean
++session_unlock (GdmManager *manager,
++                const char *ssid)
++{
++
++        g_debug ("Unlocking session %s", ssid);
++
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                return session_unlock_for_systemd (manager, ssid);
++        }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++        return session_unlock_for_ck (manager, ssid);
++#else
++        return TRUE;
++#endif
++}
++
+ 
+ static GdmSession *
+ find_session_for_user_on_seat (GdmManager *manager,
+@@ -385,10 +676,43 @@ find_session_for_user_on_seat (GdmManager *manager,
+         return NULL;
+ }
+ 
++#ifdef WITH_CONSOLE_KIT
+ static gboolean
+-is_remote_session (GdmManager  *self,
+-                   const char  *session_id,
+-                   GError     **error)
++is_consolekit_remote_session (GdmManager       *self,
++                             GDBusConnection  *connection,
++                             const char       *session_id,
++                             GError          **error)
++{
++        GVariant *reply;
++        gboolean is_remote;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             "org.freedesktop.ConsoleKit",
++                                             session_id,
++                                             "org.freedesktop.ConsoleKit.Session",
++                                             "IsLocal",
++                                             NULL,
++                                             G_VARIANT_TYPE ("(b)"),
++                                            G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL,
++                                             error);
++        if (reply == NULL) {
++               return FALSE;
++        }
++
++        g_variant_get (reply, "(b)", &is_remote);
++        g_variant_unref (reply);
++
++        return is_remote;
++}
++#endif
++
++#ifdef WITH_SYSTEMD
++static gboolean
++is_systemd_remote_session (GdmManager  *self,
++                           const char  *session_id,
++                           GError     **error)
+ {
+         char *seat;
+         int ret;
+@@ -414,10 +738,31 @@ is_remote_session (GdmManager  *self,
+ 
+         return is_remote;
+ }
++#endif
++
++static gboolean
++is_remote_session (GdmManager       *self,
++                  GDBusConnection  *connection,
++                  const char       *session_id,
++                  GError          **error)
++{
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                return is_systemd_remote_session (self, session_id, error);
++        }
++#endif
+ 
++#ifdef WITH_CONSOLE_KIT
++        return is_consolekit_remote_session (self, connection, session_id, error);
++#endif
++
++        return FALSE;
++}
++
++#ifdef WITH_SYSTEMD
+ static char *
+-get_seat_id_for_session_id (const char  *session_id,
+-                            GError     **error)
++get_seat_id_for_systemd_session_id (const char  *session_id,
++                                    GError     **error)
+ {
+         int ret;
+         char *seat, *out_seat;
+@@ -442,10 +787,61 @@ get_seat_id_for_session_id (const char  *session_id,
+ 
+         return out_seat;
+ }
++#endif
+ 
++#ifdef WITH_CONSOLE_KIT
+ static char *
+-get_tty_for_session_id (const char  *session_id,
+-                        GError     **error)
++get_seat_id_for_consolekit_session_id (GDBusConnection  *connection,
++                                       const char       *session_id,
++                                       GError          **error)
++{
++        GVariant *reply;
++        char *retval;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             "org.freedesktop.ConsoleKit",
++                                             session_id,
++                                             "org.freedesktop.ConsoleKit.Session",
++                                             "GetSeatId",
++                                             NULL,
++                                             G_VARIANT_TYPE ("(o)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL,
++                                             error);
++        if (reply == NULL) {
++                return NULL;
++        }
++
++        g_variant_get (reply, "(o)", &retval);
++        g_variant_unref (reply);
++
++        return retval;
++}
++#endif
++
++static char *
++get_seat_id_for_session_id (GDBusConnection  *connection,
++                            const char       *session_id,
++                            GError          **error)
++{
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                return get_seat_id_for_systemd_session_id (session_id, error);
++        }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++        return get_seat_id_for_consolekit_session_id (connection, session_id, error);
++#endif
++
++        return NULL;
++}
++
++#ifdef WITH_SYSTEMD
++static char *
++get_tty_for_systemd_session_id (const char  *session_id,
++                                GError     **error)
+ {
+         int ret;
+         char *tty, *out_tty;
+@@ -469,6 +865,20 @@ get_tty_for_session_id (const char  *session_id,
+ 
+         return out_tty;
+ }
++#endif
++
++static char *
++get_tty_for_session_id (const char  *session_id,
++                        GError     **error)
++{
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                return get_tty_for_systemd_session_id (session_id, error);
++        }
++#endif
++
++        return NULL;
++}
+ 
+ static void
+ get_display_and_details_for_bus_sender (GdmManager       *self,
+@@ -512,7 +922,7 @@ get_display_and_details_for_bus_sender (GdmManager       *self,
+                 goto out;
+         }
+ 
+-        session_id = get_session_id_for_pid (pid, &error);
++        session_id = get_session_id_for_pid (connection, pid, &error);
+ 
+         if (session_id == NULL) {
+                 g_debug ("GdmManager: Error while retrieving session id for sender: %s",
+@@ -526,7 +936,7 @@ get_display_and_details_for_bus_sender (GdmManager       *self,
+         }
+ 
+         if (out_is_login_screen != NULL) {
+-                *out_is_login_screen = is_login_session (self, session_id, &error);
++                *out_is_login_screen = is_login_session (self, connection, session_id, &error);
+ 
+                 if (error != NULL) {
+                         g_debug ("GdmManager: Error while checking if sender is login screen: %s",
+@@ -536,7 +946,7 @@ get_display_and_details_for_bus_sender (GdmManager       *self,
+                 }
+         }
+ 
+-        if (!get_uid_for_session_id (session_id, &session_uid, &error)) {
++        if (!get_uid_for_session_id (connection, session_id, &session_uid, &error)) {
+                 g_debug ("GdmManager: Error while retrieving uid for session: %s",
+                          error->message);
+                 g_error_free (error);
+@@ -553,7 +963,7 @@ get_display_and_details_for_bus_sender (GdmManager       *self,
+         }
+ 
+         if (out_seat_id != NULL) {
+-                *out_seat_id = get_seat_id_for_session_id (session_id, &error);
++                *out_seat_id = get_seat_id_for_session_id (connection, session_id, &error);
+ 
+                 if (error != NULL) {
+                         g_debug ("GdmManager: Error while retrieving seat id for session: %s",
+@@ -563,7 +973,7 @@ get_display_and_details_for_bus_sender (GdmManager       *self,
+         }
+ 
+         if (out_is_remote != NULL) {
+-                *out_is_remote = is_remote_session (self, session_id, &error);
++                *out_is_remote = is_remote_session (self, connection, session_id, &error);
+ 
+                 if (error != NULL) {
+                         g_debug ("GdmManager: Error while retrieving remoteness for session: %s",
+@@ -927,7 +1337,7 @@ on_reauthentication_client_rejected (GdmSession              *session,
+                  * same audit session, ignore it since it doesn't "own" the
+                  * reauthentication session
+                  */
+-                client_session_id = get_session_id_for_pid (pid_of_client,
++		client_session_id = get_session_id_for_pid (self->priv->connection,pid_of_client,
+                                                             NULL);
+                 session_id = g_object_get_data (G_OBJECT (session), "caller-session-id");
+ 
+@@ -1139,16 +1549,19 @@ static gboolean
+ display_is_on_seat0 (GdmDisplay *display)
+ {
+         gboolean is_on_seat0 = TRUE;
+-        char *seat_id = NULL;
+ 
+-        g_object_get (G_OBJECT (display), "seat-id", &seat_id, NULL);
+-
+-        if (g_strcmp0 (seat_id, "seat0") != 0) {
+-            is_on_seat0 = FALSE;
+-        }
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                char *seat_id = NULL;
+ 
+-        g_free (seat_id);
++                g_object_get (G_OBJECT (display), "seat-id", &seat_id, NULL);
+ 
++                if (g_strcmp0 (seat_id, "seat0") != 0) {
++                        is_on_seat0 = FALSE;
++                }
++                g_free (seat_id);
++        }
++#endif
+         return is_on_seat0;
+ }
+ 
+@@ -1749,11 +2162,57 @@ on_user_session_died (GdmSession *session,
+ }
+ 
+ static char *
++query_ck_for_display_device (GdmManager *manager,
++                             GdmDisplay *display)
++{
++        char    *out;
++        char    *command;
++        char    *display_name = NULL;
++        int      status;
++        gboolean res;
++        GError  *error;
++
++        g_object_get (G_OBJECT (display),
++                      "x11-display-name", &display_name,
++                      NULL);
++
++        error = NULL;
++        command = g_strdup_printf (CONSOLEKIT_DIR "/ck-get-x11-display-device --display %s",
++                                   display_name);
++        g_free (display_name);
++
++        g_debug ("GdmManager: Running helper %s", command);
++        out = NULL;
++        res = g_spawn_command_line_sync (command,
++                                         &out,
++                                         NULL,
++                                         &status,
++                                         &error);
++        if (! res) {
++                g_warning ("GdmManager: Could not run helper %s: %s", command, error->message);
++                g_error_free (error);
++        } else {
++                out = g_strstrip (out);
++                g_debug ("GdmManager: Got tty: '%s'", out);
++        }
++
++        g_free (command);
++
++        return out;
++}
++
++static char *
+ get_display_device (GdmManager *manager,
+                     GdmDisplay *display)
+ {
+-        /* systemd finds the display device out on its own based on the display */
+-        return NULL;
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                /* systemd finds the display device out on its own based on the display */
++                return NULL;
++        }
++#endif
++
++        return query_ck_for_display_device (manager, display);
+ }
+ 
+ static void
+diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
+index eb7db0e..08f2354 100644
+--- a/daemon/gdm-server.c
++++ b/daemon/gdm-server.c
+@@ -43,7 +43,9 @@
+ #include <linux/vt.h>
+ #endif
+ 
++#ifdef WITH_SYSTEMD
+ #include <systemd/sd-daemon.h>
++#endif
+ 
+ #ifdef ENABLE_SYSTEMD_JOURNAL
+ #include <systemd/sd-journal.h>
+@@ -122,23 +124,66 @@ static void     gdm_server_finalize     (GObject        *object);
+ 
+ G_DEFINE_TYPE (GdmServer, gdm_server, G_TYPE_OBJECT)
+ 
++static char *
++_gdm_server_query_ck_for_display_device (GdmServer *server)
++{
++        char    *out;
++        char    *command;
++        int      status;
++        gboolean res;
++        GError  *error;
++
++        g_return_val_if_fail (GDM_IS_SERVER (server), NULL);
++
++
++        error = NULL;
++        command = g_strdup_printf (CONSOLEKIT_DIR "/ck-get-x11-display-device --display %s",
++                                   server->priv->display_name);
++        g_debug ("GdmServer: Running helper %s", command);
++        out = NULL;
++        res = g_spawn_command_line_sync (command,
++                                         &out,
++                                         NULL,
++                                         &status,
++                                         &error);
++        if (! res) {
++                g_warning ("Could not run helper: %s", error->message);
++                g_error_free (error);
++        } else {
++                out = g_strstrip (out);
++                g_debug ("GdmServer: Got tty: '%s'", out);
++        }
++
++        g_free (command);
++
++        return out;
++}
++
+ char *
+ gdm_server_get_display_device (GdmServer *server)
+ {
+-        /* systemd finds the display device out on its own based on the display */
+-        return NULL;
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                /* systemd finds the display device out on its own based on the display */
++                return NULL;
++        }
++#endif
++
++        if (server->priv->display_device == NULL) {
++                server->priv->display_device =
++                    _gdm_server_query_ck_for_display_device (server);
++
++                g_object_notify (G_OBJECT (server), "display-device");
++
++        }
++
++        return g_strdup (server->priv->display_device);
+ }
+ 
+ static void
+ gdm_server_ready (GdmServer *server)
+ {
+         g_debug ("GdmServer: Got USR1 from X server - emitting READY");
+-
+-        gdm_run_script (GDMCONFDIR "/Init", GDM_USERNAME,
+-                        server->priv->display_name,
+-                        NULL, /* hostname */
+-                        server->priv->auth_file);
+-
+         g_signal_emit (server, signals[READY], 0);
+ }
+ 
+@@ -159,7 +204,7 @@ got_sigusr1 (gpointer user_data)
+                 GdmServer *server = l->data;
+ 
+                 if (server->priv->pid == pid)
+-                        gdm_server_ready (server);
++                       gdm_server_ready (server);
+         }
+ 
+         return G_SOURCE_REMOVE;
+@@ -228,6 +273,8 @@ gdm_server_init_command (GdmServer *server)
+ 
+ #define X_SERVER_ARG_FORMAT " -background none -noreset -verbose %s%s"
+ 
++#ifdef WITH_SYSTEMD
++
+         /* This is a temporary hack to work around the fact that XOrg
+          * currently lacks support for multi-seat hotplugging for
+          * display devices. This bit should be removed as soon as XOrg
+@@ -242,6 +289,10 @@ gdm_server_init_command (GdmServer *server)
+          * wasn't booted using systemd, or b) the wrapper tool is
+          * missing, or c) we are running for the main seat 'seat0'. */
+ 
++        if (!LOGIND_RUNNING()) {
++                goto fallback;
++        }
++
+ #ifdef ENABLE_SYSTEMD_JOURNAL
+         /* For systemd, we don't have a log file but instead log to stdout,
+            so set it to the xserver's built-in default verbosity */
+@@ -264,6 +315,8 @@ gdm_server_init_command (GdmServer *server)
+         return;
+ 
+ fallback:
++#endif
++
+         server->priv->command = g_strdup_printf (X_SERVER X_SERVER_ARG_FORMAT, verbosity, debug_options);
+ 
+ }
+@@ -315,10 +368,12 @@ gdm_server_resolve_command_line (GdmServer  *server,
+                 argv[len++] = g_strdup (server->priv->auth_file);
+         }
+ 
+-        if (server->priv->display_seat_id != NULL) {
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING() && server->priv->display_seat_id != NULL) {
+                 argv[len++] = g_strdup ("-seat");
+                 argv[len++] = g_strdup (server->priv->display_seat_id);
+         }
++#endif
+ 
+         if (server->priv->disable_tcp && ! query_in_arglist) {
+                 argv[len++] = g_strdup ("-nolisten");
+diff --git a/daemon/gdm-session-record.c b/daemon/gdm-session-record.c
+index 32933ef..590a1e8 100644
+--- a/daemon/gdm-session-record.c
++++ b/daemon/gdm-session-record.c
+@@ -33,6 +33,16 @@
+ #include <utmp.h>
+ #endif
+ 
++#if defined(HAVE_UTIL_H)
++#include <util.h>
++#endif
++
++#if defined(HAVE_GETTTYENT)
++#include <fcntl.h> /* open(2) */
++#include <ttyent.h>
++static int fd = -1;
++#endif
++
+ #include <glib.h>
+ #include <glib/gi18n.h>
+ #include <glib/gstdio.h>
+@@ -43,6 +53,10 @@
+ #define GDM_BAD_SESSION_RECORDS_FILE "/var/log/btmp"
+ #endif
+ 
++static void write_utmp_login_manually (struct utmp *ut);
++static void write_utmp_logout_manually (char *);
++
++
+ #if !defined(GDM_NEW_SESSION_RECORDS_FILE)
+ #    if defined(WTMPX_FILE)
+ #        define GDM_NEW_SESSION_RECORDS_FILE WTMPX_FILE
+@@ -183,6 +197,85 @@ record_set_line (UTMP       *u,
+         g_debug ("using ut_line %.*s", (int) sizeof (u->ut_line), u->ut_line);
+ }
+ 
++static void
++write_utmp_login_manually (struct utmp *ut)
++{
++#if defined(HAVE_GETTTYENT) && defined(HAVE_UTMP_H)
++        UTMP ubuf;
++        int topslot = -1;
++
++        g_debug ("Adding new utmp record");
++
++        /*
++         * First, loop through /etc/ttys, if needed, to initialize the
++         * top of the tty slots, since gdm has no tty.
++         */
++        if (topslot < 0) {
++                topslot = 0;
++                while (getttyent () != (struct ttyent *) NULL)
++                        topslot++;
++        }
++        if ((topslot < 0) || ((fd < 0) &&
++            (fd = open (_PATH_UTMP, O_RDWR|O_CREAT, 0644)) < 0))
++                return;
++
++        /*
++         * Now find a slot that's not in use...
++         */
++        (void) lseek (fd, (off_t) (topslot * sizeof (struct utmp)), SEEK_SET);
++
++        while (1) {
++                if (read (fd, &ubuf, sizeof (struct utmp)) ==
++                    sizeof (struct utmp)) {
++                        if (!ubuf.ut_name[0]) {
++                                (void) lseek (fd, -(off_t) sizeof (struct utmp),
++                                    SEEK_CUR);
++                                break;
++                        }
++                        topslot++;
++                } else {
++                        (void) lseek (fd, (off_t) (topslot *
++                            sizeof (struct utmp)), SEEK_SET);
++                        break;
++                }
++        }
++
++        (void) write (fd, ut, sizeof (struct utmp));
++#endif
++}
++
++static void
++write_utmp_logout_manually (char *line)
++{
++#if defined(HAVE_GETTTYENT) && defined(HAVE_UTMP_H)
++        int rval = 1;
++        struct timeval tv;
++        UTMP ut;
++
++        g_debug ("Removing utmp record");
++
++
++        if (fd >= 0) {
++            (void) lseek (fd, 0, SEEK_SET);
++            while (read (fd, &ut, sizeof (struct utmp)) == sizeof (struct utmp)) {
++                    if (!ut.ut_name[0] ||
++                        strncmp (ut.ut_line, line, UT_LINESIZE))
++                            continue;
++                    bzero (ut.ut_name, UT_NAMESIZE);
++                    bzero (ut.ut_host, UT_HOSTSIZE);
++                    gettimeofday (&tv, NULL);
++                    ut.ut_time = tv.tv_sec;
++                    (void) lseek (fd, -(off_t) sizeof (struct utmp), SEEK_CUR);
++                    (void) write (fd, &ut, sizeof (struct utmp));
++                    rval = 0;
++            }
++        }
++
++        if (rval != 0)
++            g_debug ("Failed to remove utmp record");
++#endif
++}
++
+ void
+ gdm_session_record_login (GPid                  session_pid,
+                           const char           *user_name,
+@@ -227,8 +320,9 @@ gdm_session_record_login (GPid                  session_pid,
+ #if defined(HAVE_GETUTXENT)
+         g_debug ("Adding or updating utmp record for login");
+         pututxline (&session_record);
+-#elif defined(HAVE_LOGIN)
+-	login (&session_record);
++#else
++        if (strcmp (session_record.ut_name, "(unknown)") != 0)
++            write_utmp_login_manually (&session_record);
+ #endif
+ }
+ 
+@@ -270,8 +364,8 @@ gdm_session_record_logout (GPid                  session_pid,
+ #if defined(HAVE_GETUTXENT)
+         g_debug ("Adding or updating utmp record for logout");
+         pututxline (&session_record);
+-#elif defined(HAVE_LOGOUT)
+-        logout (session_record.ut_line);
++#else
++        write_utmp_logout_manually (session_record.ut_line);
+ #endif
+ }
+ 
+diff --git a/daemon/gdm-session-worker-job.c b/daemon/gdm-session-worker-job.c
+index 69dca2e..52a6e9f 100644
+--- a/daemon/gdm-session-worker-job.c
++++ b/daemon/gdm-session-worker-job.c
+@@ -36,7 +36,10 @@
+ #include <sys/prctl.h>
+ #endif
+ 
++#ifdef WITH_SYSTEMD
+ #include <systemd/sd-daemon.h>
++#endif
++
+ 
+ #ifdef ENABLE_SYSTEMD_JOURNAL
+ #include <systemd/sd-journal.h>
+diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
+index 5ae5b3f..3b10940 100644
+--- a/daemon/gdm-session-worker.c
++++ b/daemon/gdm-session-worker.c
+@@ -28,9 +28,11 @@
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
++#ifdef WITH_SYSTEMD
+ #include <sys/ioctl.h>
+ #include <sys/vt.h>
+ #include <sys/kd.h>
++#endif
+ #include <errno.h>
+ #include <grp.h>
+ #include <pwd.h>
+@@ -49,7 +51,9 @@
+ 
+ #include <X11/Xauth.h>
+ 
++#ifdef WITH_SYSTEMD
+ #include <systemd/sd-daemon.h>
++#endif
+ 
+ #ifdef ENABLE_SYSTEMD_JOURNAL
+ #include <systemd/sd-journal.h>
+@@ -130,6 +134,9 @@ struct GdmSessionWorkerPrivate
+         int               state;
+ 
+         int               exit_code;
++#ifdef WITH_CONSOLE_KIT
++        char             *session_cookie;
++#endif
+ 
+         pam_handle_t     *pam_handle;
+ 
+@@ -145,6 +152,7 @@ struct GdmSessionWorkerPrivate
+         char             *hostname;
+         char             *username;
+         char             *log_file;
++        char             *session_type;
+         char             *session_id;
+         uid_t             uid;
+         gid_t             gid;
+@@ -207,6 +215,207 @@ G_DEFINE_TYPE_WITH_CODE (GdmSessionWorker,
+                          G_IMPLEMENT_INTERFACE (GDM_DBUS_TYPE_WORKER,
+                                                 worker_interface_init))
+ 
++#ifdef WITH_CONSOLE_KIT
++static gboolean
++open_ck_session (GdmSessionWorker  *worker)
++{
++        GDBusConnection  *system_bus;
++        GVariantBuilder   builder;
++        GVariant         *parameters;
++        GVariant         *in_args;
++        struct passwd    *pwent;
++        GVariant         *reply;
++        GError           *error = NULL;
++        const char       *display_name;
++        const char       *display_device;
++        const char       *display_hostname;
++        const char       *session_type;
++        gint32            uid;
++
++        g_assert (worker->priv->session_cookie == NULL);
++
++        if (worker->priv->x11_display_name != NULL) {
++                display_name = worker->priv->x11_display_name;
++        } else {
++                display_name = "";
++        }
++        if (worker->priv->hostname != NULL) {
++                display_hostname = worker->priv->hostname;
++        } else {
++                display_hostname = "";
++        }
++        if (worker->priv->display_device != NULL) {
++                display_device = worker->priv->display_device;
++        } else {
++                display_device = "";
++        }
++
++        if (worker->priv->session_type != NULL) {
++                session_type = worker->priv->session_type;
++        } else {
++                session_type = "";
++        }
++
++        g_assert (worker->priv->username != NULL);
++
++
++        gdm_get_pwent_for_name (worker->priv->username, &pwent);
++        if (pwent == NULL) {
++                goto out;
++        }
++
++        uid = (gint32) pwent->pw_uid;
++
++        error = NULL;
++        system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
++
++        if (system_bus == NULL) {
++                g_warning ("Couldn't create connection to system bus: %s",
++                           error->message);
++
++                g_error_free (error);
++                goto out;
++        }
++
++        g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sv)"));
++        g_variant_builder_add_parsed (&builder, "('unix-user', <%i>)", uid);
++        g_variant_builder_add_parsed (&builder, "('x11-display-device', <%s>)", display_device);
++        g_variant_builder_add_parsed (&builder, "('x11-display', <%s>)", display_name);
++        g_variant_builder_add_parsed (&builder, "('remote-host-name', <%s>)", display_hostname);
++        g_variant_builder_add_parsed (&builder, "('is-local', <%b>)", worker->priv->display_is_local);
++        g_variant_builder_add_parsed (&builder, "('session-type', <%s>)", session_type);
++
++        parameters = g_variant_builder_end (&builder);
++        in_args = g_variant_new_tuple (&parameters, 1);
++
++        reply = g_dbus_connection_call_sync (system_bus,
++                                             "org.freedesktop.ConsoleKit",
++                                             "/org/freedesktop/ConsoleKit/Manager",
++                                             "org.freedesktop.ConsoleKit.Manager",
++                                             "OpenSessionWithParameters",
++                                             in_args,
++                                             G_VARIANT_TYPE ("(s)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL,
++                                             &error);
++
++        if (! reply) {
++                g_warning ("%s\n", error->message);
++                g_clear_error (&error);
++                goto out;
++        }
++
++        g_variant_get (reply, "(s)", &worker->priv->session_cookie);
++
++        g_variant_unref (reply);
++
++out:
++        return worker->priv->session_cookie != NULL;
++}
++
++static void
++close_ck_session (GdmSessionWorker *worker)
++{
++        GDBusConnection  *system_bus;
++        GVariant         *reply;
++        GError           *error = NULL;
++        gboolean          was_closed;
++
++        if (worker->priv->session_cookie == NULL) {
++                return;
++        }
++
++        error = NULL;
++        system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
++
++
++        if (system_bus == NULL) {
++                g_warning ("Couldn't create connection to system bus: %s",
++                           error->message);
++
++                g_error_free (error);
++                goto out;
++        }
++
++        reply = g_dbus_connection_call_sync (system_bus,
++                                             "org.freedesktop.ConsoleKit",
++                                             "/org/freedesktop/ConsoleKit/Manager",
++                                             "org.freedesktop.ConsoleKit.Manager",
++                                             "CloseSession",
++                                             g_variant_new ("(s)", worker->priv->session_cookie),
++                                             G_VARIANT_TYPE ("(b)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL,
++                                             &error);
++
++        if (! reply) {
++                g_warning ("%s", error->message);
++                g_clear_error (&error);
++                goto out;
++        }
++
++        g_variant_get (reply, "(b)", &was_closed);
++
++        if (!was_closed) {
++                g_warning ("Unable to close ConsoleKit session");
++        }
++
++        g_variant_unref (reply);
++
++out:
++        g_clear_pointer (&worker->priv->session_cookie,
++                         (GDestroyNotify) g_free);
++}
++
++static char *
++get_ck_session_id (GdmSessionWorker *worker)
++{
++        GDBusConnection  *system_bus;
++        GVariant         *reply;
++        GError           *error = NULL;
++        char             *session_id = NULL;
++
++        error = NULL;
++        system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
++
++        if (system_bus == NULL) {
++                g_warning ("Couldn't create connection to system bus: %s",
++                           error->message);
++
++                g_error_free (error);
++                goto out;
++        }
++
++        reply = g_dbus_connection_call_sync (system_bus,
++                                             "org.freedesktop.ConsoleKit",
++                                             "/org/freedesktop/ConsoleKit/Manager",
++                                             "org.freedesktop.ConsoleKit.Manager",
++                                             "GetSessionForCookie",
++                                             g_variant_new ("(s)", worker->priv->session_cookie),
++                                             G_VARIANT_TYPE ("(o)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL,
++                                             &error);
++
++        if (reply == NULL) {
++                g_warning ("%s", error->message);
++                g_clear_error (&error);
++                goto out;
++        }
++
++        g_variant_get (reply, "(o)", &session_id);
++
++        g_variant_unref (reply);
++
++out:
++        return session_id;
++}
++#endif
++
++
+ /* adapted from glib script_execute */
+ static void
+ script_execute (const gchar *file,
+@@ -754,6 +963,7 @@ gdm_session_worker_stop_auditor (GdmSessionWorker *worker)
+         worker->priv->auditor = NULL;
+ }
+ 
++#ifdef WITH_SYSTEMD
+ static void
+ on_release_display (int signal)
+ {
+@@ -879,6 +1089,7 @@ jump_to_vt (GdmSessionWorker  *worker,
+ 
+         close (active_vt_tty_fd);
+ }
++#endif
+ 
+ static void
+ gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker,
+@@ -909,9 +1120,11 @@ gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker,
+ 
+         gdm_session_worker_stop_auditor (worker);
+ 
++#ifdef WITH_SYSTEMD
+         if (worker->priv->login_vt != worker->priv->session_vt) {
+                 jump_to_vt (worker, worker->priv->login_vt);
+-        }
++	}
++#endif
+ 
+         worker->priv->login_vt = 0;
+         worker->priv->session_vt = 0;
+@@ -1036,10 +1249,12 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker,
+                 }
+         }
+ 
++#ifdef WITH_SYSTEMD
+         /* set seat ID */
+-        if (seat_id != NULL && seat_id[0] != '\0') {
++	if (seat_id != NULL && seat_id[0] != '\0' && LOGIND_RUNNING()) {
+                 gdm_session_worker_set_environment_variable (worker, "XDG_SEAT", seat_id);
+         }
++#endif
+ 
+         if (strcmp (service, "gdm-launch-environment") == 0) {
+                 gdm_session_worker_set_environment_variable (worker, "XDG_SESSION_CLASS", "greeter");
+@@ -1235,6 +1450,7 @@ gdm_session_worker_environment_variable_is_set (GdmSessionWorker *worker,
+         return pam_getenv (worker->priv->pam_handle, key) != NULL;
+ }
+ 
++
+ static gboolean
+ _change_user (GdmSessionWorker  *worker,
+               uid_t              uid,
+@@ -1595,6 +1811,27 @@ gdm_session_worker_get_environment (GdmSessionWorker *worker)
+         return (const char * const *) pam_getenvlist (worker->priv->pam_handle);
+ }
+ 
++#ifdef WITH_CONSOLE_KIT
++static void
++register_ck_session (GdmSessionWorker *worker)
++{
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                return;
++        }
++#endif
++
++        open_ck_session (worker);
++
++        if (worker->priv->session_cookie != NULL) {
++                gdm_session_worker_set_environment_variable (worker,
++                                                             "XDG_SESSION_COOKIE",
++                                                             worker->priv->session_cookie);
++        }
++}
++#endif
++
++
+ static gboolean
+ run_script (GdmSessionWorker *worker,
+             const char       *dir)
+@@ -1625,6 +1862,9 @@ session_worker_child_watch (GPid              pid,
+                  : WIFSIGNALED (status) ? WTERMSIG (status)
+                  : -1);
+ 
++#ifdef WITH_CONSOLE_KIT
++        close_ck_session (worker);
++#endif
+ 
+         gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS);
+ 
+@@ -1813,12 +2053,15 @@ gdm_session_worker_start_session (GdmSessionWorker  *worker,
+ 
+         error_code = PAM_SUCCESS;
+ 
++#ifdef WITH_SYSTEMD
++
+         /* If we're in new vt mode, jump to the new vt now. There's no need to jump for
+          * the other two modes: in the logind case, the session will activate itself when
+          * ready, and in the reuse server case, we're already on the correct VT. */
+         if (worker->priv->display_mode == GDM_SESSION_DISPLAY_MODE_NEW_VT) {
+                 jump_to_vt (worker, worker->priv->session_vt);
+         }
++#endif
+ 
+         session_pid = fork ();
+ 
+@@ -1865,6 +2108,7 @@ gdm_session_worker_start_session (GdmSessionWorker  *worker,
+                         _exit (2);
+                 }
+ 
++#ifdef WITH_SYSTEMD
+                 /* Take control of the tty
+                  */
+                 if (needs_controlling_terminal) {
+@@ -1872,6 +2116,7 @@ gdm_session_worker_start_session (GdmSessionWorker  *worker,
+                                 g_debug ("GdmSessionWorker: could not take control of tty: %m");
+                         }
+                 }
++#endif
+ 
+ #ifdef HAVE_LOGINCAP
+                 if (setusercontext (NULL, passwd_entry, passwd_entry->pw_uid, LOGIN_SETALL) < 0) {
+@@ -2016,6 +2261,7 @@ gdm_session_worker_start_session (GdmSessionWorker  *worker,
+         return TRUE;
+ }
+ 
++#ifdef WITH_SYSTEMD
+ static gboolean
+ set_up_for_new_vt (GdmSessionWorker *worker)
+ {
+@@ -2073,6 +2319,7 @@ fail:
+         close (fd);
+         return FALSE;
+ }
++#endif
+ 
+ static gboolean
+ set_up_for_current_vt (GdmSessionWorker  *worker,
+@@ -2161,6 +2408,7 @@ gdm_session_worker_open_session (GdmSessionWorker  *worker,
+                         return FALSE;
+                 }
+                 break;
++#ifdef WITH_SYSTEMD
+         case GDM_SESSION_DISPLAY_MODE_NEW_VT:
+         case GDM_SESSION_DISPLAY_MODE_LOGIND_MANAGED:
+                 if (!set_up_for_new_vt (worker)) {
+@@ -2171,6 +2419,7 @@ gdm_session_worker_open_session (GdmSessionWorker  *worker,
+                         return FALSE;
+                 }
+                 break;
++#endif
+         }
+ 
+         flags = 0;
+@@ -2200,7 +2449,9 @@ gdm_session_worker_open_session (GdmSessionWorker  *worker,
+         g_debug ("GdmSessionWorker: state SESSION_OPENED");
+         worker->priv->state = GDM_SESSION_WORKER_STATE_SESSION_OPENED;
+ 
++#ifdef WITH_SYSTEMD
+         session_id = gdm_session_worker_get_environment_variable (worker, "XDG_SESSION_ID");
++#endif
+ 
+         /* FIXME: should we do something here?
+          * Note that error return status from PreSession script should
+@@ -2210,6 +2461,14 @@ gdm_session_worker_open_session (GdmSessionWorker  *worker,
+          */
+         run_script (worker, GDMCONFDIR "/PreSession");
+ 
++#ifdef WITH_CONSOLE_KIT
++        register_ck_session (worker);
++
++        if (session_id == NULL) {
++                session_id = get_ck_session_id (worker);
++        }
++#endif
++
+         if (session_id != NULL) {
+                 g_free (worker->priv->session_id);
+                 worker->priv->session_id = session_id;
+@@ -2314,6 +2573,19 @@ gdm_session_worker_handle_set_session_name (GdmDBusWorker         *object,
+ }
+ 
+ static gboolean
++gdm_session_worker_handle_set_session_type (GdmDBusWorker         *object,
++                                            GDBusMethodInvocation *invocation,
++                                            const char            *session_type)
++{
++        GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
++        g_debug ("GdmSessionWorker: session type set to %s", session_type);
++        g_free (worker->priv->session_type);
++        worker->priv->session_type = g_strdup (session_type);
++        gdm_dbus_worker_complete_set_session_type (object, invocation);
++        return TRUE;
++}
++
++static gboolean
+ gdm_session_worker_handle_set_session_display_mode (GdmDBusWorker         *object,
+                                                     GDBusMethodInvocation *invocation,
+                                                     const char            *str)
+@@ -3121,6 +3393,7 @@ worker_interface_init (GdmDBusWorkerIface *interface)
+         interface->handle_open = gdm_session_worker_handle_open;
+         interface->handle_set_language_name = gdm_session_worker_handle_set_language_name;
+         interface->handle_set_session_name = gdm_session_worker_handle_set_session_name;
++	interface->handle_set_session_type = gdm_session_worker_handle_set_session_type;
+         interface->handle_set_session_display_mode = gdm_session_worker_handle_set_session_display_mode;
+         interface->handle_set_environment_variable = gdm_session_worker_handle_set_environment_variable;
+         interface->handle_start_program = gdm_session_worker_handle_start_program;
+diff --git a/daemon/gdm-session-worker.xml b/daemon/gdm-session-worker.xml
+index 9f6d8b3..853bc6a 100644
+--- a/daemon/gdm-session-worker.xml
++++ b/daemon/gdm-session-worker.xml
+@@ -13,6 +13,9 @@
+     <method name="SetSessionName">
+       <arg name="session_name" direction="in" type="s" />
+     </method>
++    <method name="SetSessionType">
++      <arg name="session_type" direction="in" type="s"/>
++    </method>
+     <method name="SetSessionDisplayMode">
+       <arg name="mode" direction="in" type="s"/>
+     </method>
+diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
+index 5707b15..49edb0c 100644
+--- a/daemon/gdm-session.c
++++ b/daemon/gdm-session.c
+@@ -3071,6 +3071,11 @@ gdm_session_get_display_mode (GdmSession *self)
+                  self->priv->is_program_session? "yes" : "no",
+                  self->priv->display_seat_id);
+ 
++        if (!LOGIND_RUNNING()) {
++                return GDM_SESSION_DISPLAY_MODE_REUSE_VT;
++        }
++
++
+ #ifdef ENABLE_WAYLAND_SUPPORT
+         /* Wayland sessions are for now assumed to run in a
+          * mutter-launch-like environment, so we allocate
+@@ -3112,6 +3117,27 @@ gdm_session_select_program (GdmSession *self,
+ }
+ 
+ void
++gdm_session_select_session_type (GdmSession *self,
++                                 const char *text)
++{
++        GHashTableIter iter;
++        gpointer key, value;
++
++        g_debug ("GdmSession: selecting session type '%s'", text);
++
++        g_hash_table_iter_init (&iter, self->priv->conversations);
++        while (g_hash_table_iter_next (&iter, &key, &value)) {
++                GdmSessionConversation *conversation;
++
++                conversation = (GdmSessionConversation *) value;
++
++                gdm_dbus_worker_call_set_session_type (conversation->worker_proxy,
++                                                       text,
++                                                       NULL, NULL, NULL);
++        }
++}
++
++void
+ gdm_session_select_session (GdmSession *self,
+                             const char *text)
+ {
+diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
+index 7cfaca1..6d13f11 100644
+--- a/daemon/gdm-session.h
++++ b/daemon/gdm-session.h
+@@ -176,6 +176,8 @@ void              gdm_session_answer_query                (GdmSession *session,
+                                                            const char *text);
+ void              gdm_session_select_program              (GdmSession *session,
+                                                            const char *command_line);
++void              gdm_session_select_session_type         (GdmSession *session,
++                                                           const char *session_type);
+ void              gdm_session_select_session              (GdmSession *session,
+                                                            const char *session_name);
+ void              gdm_session_select_user                 (GdmSession *session,
+diff --git a/libgdm/gdm-user-switching.c b/libgdm/gdm-user-switching.c
+index 3d4303e..b08d7a5 100644
+--- a/libgdm/gdm-user-switching.c
++++ b/libgdm/gdm-user-switching.c
+@@ -1,4 +1,4 @@
+-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -
+  *
+  * Copyright (C) 2012 Red Hat, Inc.
+  * Copyright (C) 2012 Giovanni Campagna <[email protected]>
+@@ -31,12 +31,26 @@
+ #include <glib-object.h>
+ #include <gio/gio.h>
+ 
++#ifdef WITH_SYSTEMD
+ #include <systemd/sd-login.h>
++#endif
+ 
+ #include "common/gdm-common.h"
+ #include "gdm-user-switching.h"
+ #include "gdm-client.h"
+ 
++#ifdef WITH_CONSOLE_KIT
++#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_SEAT_INTERFACE    "org.freedesktop.ConsoleKit.Seat"
++#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
++#endif
++
++
+ static gboolean
+ create_transient_display (GDBusConnection *connection,
+                           GCancellable    *cancellable,
+@@ -67,12 +81,305 @@ create_transient_display (GDBusConnection *connection,
+         return TRUE;
+ }
+ 
++#ifdef WITH_CONSOLE_KIT
++
++static gboolean
++get_current_session_id (GDBusConnection  *connection,
++                        char            **session_id)
++{
++        GError *local_error = NULL;
++
++        GVariant *reply;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             CK_NAME,
++                                             CK_MANAGER_PATH,
++                                             CK_MANAGER_INTERFACE,
++                                             "GetCurrentSession",
++                                             NULL, /* parameters */
++                                             G_VARIANT_TYPE ("(o)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL, &local_error);
++        if (reply == NULL) {
++                g_warning ("Unable to determine session: %s", local_error->message);
++                g_error_free (local_error);
++                return FALSE;
++        }
++
++        g_variant_get (reply, "(o)", session_id);
++        g_variant_unref (reply);
++
++        return TRUE;
++}
++
++static gboolean
++get_seat_id_for_session (GDBusConnection  *connection,
++                         const char       *session_id,
++                         char            **seat_id)
++{
++        GError *local_error = NULL;
++        GVariant *reply;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             CK_NAME,
++                                             session_id,
++                                             CK_SESSION_INTERFACE,
++                                             "GetSeatId",
++                                             NULL, /* parameters */
++                                             G_VARIANT_TYPE ("(o)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL, &local_error);
++        if (reply == NULL) {
++                g_warning ("Unable to determine seat: %s", local_error->message);
++                g_error_free (local_error);
++                return FALSE;
++        }
++
++        g_variant_get (reply, "(o)", seat_id);
++        g_variant_unref (reply);
++
++        return TRUE;
++}
++
++static char *
++get_current_seat_id (GDBusConnection *connection)
++{
++        gboolean res;
++        char    *session_id;
++        char    *seat_id;
++
++        session_id = NULL;
++        seat_id = NULL;
++
++        res = get_current_session_id (connection, &session_id);
++        if (res) {
++                res = get_seat_id_for_session (connection, session_id, &seat_id);
++        }
++        g_free (session_id);
++
++        return seat_id;
++}
++
++static gboolean
++activate_session_id_for_ck (GDBusConnection *connection,
++                            GCancellable    *cancellable,
++                            const char      *seat_id,
++                            const char      *session_id,
++                            GError         **error)
++{
++        GVariant *reply;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             CK_NAME,
++                                             seat_id,
++                                             CK_SEAT_INTERFACE,
++                                             "ActivateSession",
++                                             g_variant_new ("(o)", session_id),
++                                             NULL,
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL, error);
++        if (reply == NULL) {
++                g_prefix_error (error, _("Unable to activate session: "));
++                return FALSE;
++        }
++
++        g_variant_unref (reply);
++
++        return TRUE;
++}
++
++static gboolean
++session_is_login_window (GDBusConnection *connection,
++                         const char      *session_id)
++{
++        GError *local_error = NULL;
++        GVariant *reply;
++        const char *value;
++        gboolean ret;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             CK_NAME,
++                                             session_id,
++                                             CK_SESSION_INTERFACE,
++                                             "GetSessionType",
++                                             NULL,
++                                             G_VARIANT_TYPE ("(s)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL, &local_error);
++        if (reply == NULL) {
++                g_warning ("Unable to determine session type: %s", local_error->message);
++                g_error_free (local_error);
++                return FALSE;
++        }
++
++        g_variant_get (reply, "(&s)", &value);
++
++        if (value == NULL || value[0] == '\0' || strcmp (value, "LoginWindow") != 0) {
++                ret = FALSE;
++        } else {
++                ret = TRUE;
++        }
++
++        g_variant_unref (reply);
++
++        return ret;
++}
++
++static gboolean
++seat_can_activate_sessions (GDBusConnection *connection,
++                            const char      *seat_id)
++{
++        GError *local_error = NULL;
++        GVariant *reply;
++        gboolean ret;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             CK_NAME,
++                                             seat_id,
++                                             CK_SEAT_INTERFACE,
++                                             "CanActivateSessions",
++                                             NULL,
++                                             G_VARIANT_TYPE ("(b)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL, &local_error);
++        if (reply == NULL) {
++                g_warning ("Unable to determine if can activate sessions: %s", local_error->message);
++                g_error_free (local_error);
++                return FALSE;
++        }
++
++        g_variant_get (reply, "(b)", &ret);
++        g_variant_unref (reply);
++
++        return ret;
++}
++
++static const char **
++seat_get_sessions (GDBusConnection *connection,
++                   const char      *seat_id)
++{
++        GError *local_error = NULL;
++        GVariant *reply;
++        const char **value;
++
++        reply = g_dbus_connection_call_sync (connection,
++                                             CK_NAME,
++                                             seat_id,
++                                             CK_SEAT_INTERFACE,
++                                             "GetSessions",
++                                             NULL,
++                                             G_VARIANT_TYPE ("(ao)"),
++                                             G_DBUS_CALL_FLAGS_NONE,
++                                             -1,
++                                             NULL, &local_error);
++        if (reply == NULL) {
++                g_warning ("Unable to list sessions: %s", local_error->message);
++                g_error_free (local_error);
++                return FALSE;
++        }
++
++        g_variant_get (reply, "(^ao)", &value);
++        g_variant_unref (reply);
++
++        return value;
++}
++
++static gboolean
++get_login_window_session_id_for_ck (GDBusConnection  *connection,
++                                    const char       *seat_id,
++                                    char            **session_id)
++{
++        gboolean     can_activate_sessions;
++        const char **sessions;
++        int          i;
++
++        *session_id = NULL;
++        sessions = NULL;
++
++        g_debug ("checking if seat can activate sessions");
++
++        can_activate_sessions = seat_can_activate_sessions (connection, seat_id);
++        if (! can_activate_sessions) {
++                g_debug ("seat is unable to activate sessions");
++                return FALSE;
++        }
++
++        sessions = seat_get_sessions (connection, seat_id);
++        for (i = 0; sessions [i] != NULL; i++) {
++                const char *ssid;
++
++                ssid = sessions [i];
++
++                if (session_is_login_window (connection, ssid)) {
++                        *session_id = g_strdup (ssid);
++                        break;
++                }
++        }
++        g_free (sessions);
++
++        return TRUE;
++}
++
++static gboolean
++goto_login_session_for_ck (GDBusConnection  *connection,
++                           GCancellable     *cancellable,
++                           GError          **error)
++{
++        gboolean        ret;
++        gboolean        res;
++        char           *session_id;
++        char           *seat_id;
++
++        ret = FALSE;
++
++        /* First look for any existing LoginWindow sessions on the seat.
++           If none are found, create a new one. */
++
++        seat_id = get_current_seat_id (connection);
++        if (seat_id == NULL || seat_id[0] == '\0') {
++                g_debug ("seat id is not set; can't switch sessions");
++                g_set_error (error, GDM_CLIENT_ERROR, 0, _("Could not identify the current session."));
++
++                return FALSE;
++        }
++
++        res = get_login_window_session_id_for_ck (connection, seat_id, &session_id);
++        if (! res) {
++                g_set_error (error, GDM_CLIENT_ERROR, 0, _("User unable to switch sessions."));
++                return FALSE;
++        }
++
++        if (session_id != NULL) {
++                res = activate_session_id_for_ck (connection, cancellable, seat_id, session_id, error);
++                if (res) {
++                        ret = TRUE;
++                }
++        }
++
++        if (! ret && g_strcmp0 (seat_id, "/org/freedesktop/ConsoleKit/Seat1") == 0) {
++                res = create_transient_display (connection, cancellable, error);
++                if (res) {
++                        ret = TRUE;
++                }
++        }
++
++        return ret;
++}
++#endif
++
++#ifdef WITH_SYSTEMD
++
+ static gboolean
+-activate_session_id (GDBusConnection  *connection,
+-                     GCancellable     *cancellable,
+-                     const char       *seat_id,
+-                     const char       *session_id,
+-                     GError          **error)
++activate_session_id_for_systemd (GDBusConnection  *connection,
++                                 GCancellable     *cancellable,
++                                 const char       *seat_id,
++                                 const char       *session_id,
++                                 GError          **error)
+ {
+         GVariant *reply;
+ 
+@@ -97,8 +404,8 @@ activate_session_id (GDBusConnection  *connection,
+ }
+ 
+ static gboolean
+-get_login_window_session_id (const char  *seat_id,
+-                             char       **session_id)
++get_login_window_session_id_for_systemd (const char  *seat_id,
++                                         char       **session_id)
+ {
+         gboolean   ret;
+         int        res, i;
+@@ -182,9 +489,9 @@ out:
+ }
+ 
+ static gboolean
+-goto_login_session (GDBusConnection  *connection,
+-                    GCancellable     *cancellable,
+-                    GError          **error)
++goto_login_session_for_systemd (GDBusConnection  *connection,
++                                GCancellable     *cancellable,
++                                GError          **error)
+ {
+         gboolean        ret;
+         int             res;
+@@ -238,9 +545,9 @@ goto_login_session (GDBusConnection  *connection,
+                 return FALSE;
+         }
+ 
+-        res = get_login_window_session_id (seat_id, &session_id);
++	res = get_login_window_session_id_for_systemd (seat_id, &session_id);
+         if (res && session_id != NULL) {
+-                res = activate_session_id (connection, cancellable, seat_id, session_id, error);
++                res = activate_session_id_for_systemd (connection, cancellable, seat_id, session_id, error);
+ 
+                 if (res) {
+                         ret = TRUE;
+@@ -259,6 +566,7 @@ goto_login_session (GDBusConnection  *connection,
+ 
+         return ret;
+ }
++#endif
+ 
+ gboolean
+ gdm_goto_login_session_sync (GCancellable  *cancellable,
+@@ -271,8 +579,23 @@ gdm_goto_login_session_sync (GCancellable  *cancellable,
+         if (!connection)
+                 return FALSE;
+ 
+-        retval = goto_login_session (connection, cancellable, error);
++#ifdef WITH_SYSTEMD
++        if (LOGIND_RUNNING()) {
++                retval = goto_login_session_for_systemd (connection,
++                                                         cancellable,
++                                                         error);
++
++                g_object_unref (connection);
++                return retval;
++        }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++        retval = goto_login_session_for_ck (connection, cancellable, error);
+ 
+         g_object_unref (connection);
+         return retval;
++#else
++	return FALSE;
++#endif
+ }
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0003-solaris-pam.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,79 @@
+From 1ca93c6cf2f4710895caf1f13b38dcb2a46bf688 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Tue, 29 Dec 2015 12:26:03 -0800
+Subject: [PATCH 03/19] solaris pam
+
+Fix compiler complaints due to different types between Solaris & Linux PAM:
+
+daemon/gdm-session-worker.c: In function 'gdm_session_worker_get_username':
+daemon/gdm-session-worker.c:611:9: warning: passing argument 3 of
+  'pam_get_item' from incompatible pointer type [enabled by default]
+         if (pam_get_item (worker->priv->pam_handle, PAM_USER, &item) == PAM_SUCCESS) {
+         ^
+In file included from daemon/gdm-session-worker.c:40:0:
+/usr/include/security/pam_appl.h:167:1: note: expected 'void **' but
+  argument is of type 'const void **'
+ pam_get_item(
+ ^
+
+daemon/gdm-session-worker.c: In function 'gdm_session_worker_initialize_pam':
+daemon/gdm-session-worker.c:1200:31: warning: assignment from incompatible
+  pointer type [enabled by default]
+         pam_conversation.conv = (GdmSessionWorkerPamNewMessagesFunc) gdm_session_worker_pam_new_messages_handler;
+                               ^
+
+(split out of Desktop gate patch gdm-03-sdtlogin.diff since it's unrelated)
+---
+ daemon/gdm-session-worker.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
+index 3b10940..291caad 100644
+--- a/daemon/gdm-session-worker.c
++++ b/daemon/gdm-session-worker.c
+@@ -37,6 +37,12 @@
+ #include <grp.h>
+ #include <pwd.h>
+ 
++#if __sun
++#define GDM_PAM_QUAL
++#else
++#define GDM_PAM_QUAL const
++#endif
++
+ #include <security/pam_appl.h>
+ 
+ #ifdef HAVE_LOGINCAP
+@@ -205,7 +211,7 @@ static void     worker_interface_init           (GdmDBusWorkerIface *iface);
+ 
+ 
+ typedef int (* GdmSessionWorkerPamNewMessagesFunc) (int,
+-                                                    const struct pam_message **,
++                                                    GDM_PAM_QUAL struct pam_message **,
+                                                     struct pam_response **,
+                                                     gpointer);
+ 
+@@ -604,7 +610,11 @@ static gboolean
+ gdm_session_worker_get_username (GdmSessionWorker  *worker,
+                                  char             **username)
+ {
++#ifdef __sun
++        gpointer item;
++#else
+         gconstpointer item;
++#endif
+ 
+         g_assert (worker->priv->pam_handle != NULL);
+ 
+@@ -860,7 +870,7 @@ get_friendly_error_message (int error_code)
+ 
+ static int
+ gdm_session_worker_pam_new_messages_handler (int                        number_of_messages,
+-                                             const struct pam_message **messages,
++                                             GDM_PAM_QUAL struct pam_message **messages,
+                                              struct pam_response      **responses,
+                                              GdmSessionWorker          *worker)
+ {
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0004-sdtlogin.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,227 @@
+From f7978982d31f67867d8200f9f3102eb423312abc Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Tue, 29 Dec 2015 12:50:16 -0800
+Subject: [PATCH 04/19] sdtlogin
+
+Adds SDTLOGIN interface, which drops the Xserver to user
+perms rather than running as root, for added security on Solaris.
+Original date:2008-05-06 owner:yippi type:feature
+
+For the original definition, see Sun ASARC case 1995/390.
+For the current implementation in the X server, see sun-src/os/dtlogin.c
+and dtlogin-userinfo.patch in open-src/xserver/xorg in the X gate.
+---
+ common/gdm-common.h         |   5 ++
+ daemon/gdm-server.c         |  11 +++++
+ daemon/gdm-session-worker.c | 116 ++++++++++++++++++++++++++++++++++++++++++++
+ daemon/main.c               |  15 ++++++
+ 4 files changed, 147 insertions(+)
+
+diff --git a/common/gdm-common.h b/common/gdm-common.h
+index 19dbbbb..6ac61c0 100644
+--- a/common/gdm-common.h
++++ b/common/gdm-common.h
+@@ -42,6 +42,11 @@ GQuark gdm_common_error_quark (void);
+ typedef char * (*GdmExpandVarFunc) (const char *var,
+                                     gpointer user_data);
+ 
++#ifdef __sun
++#define GDM_DT_DIR "/var/dt"
++#define GDM_SDTLOGIN_DIR "/var/dt/sdtlogin"
++#endif
++
+ G_BEGIN_DECLS
+ 
+ int            gdm_wait_on_pid           (int pid);
+diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
+index 08f2354..2cec263 100644
+--- a/daemon/gdm-server.c
++++ b/daemon/gdm-server.c
+@@ -742,6 +742,17 @@ gdm_server_spawn (GdmServer    *server,
+                 goto out;
+         }
+ 
++#if __sun
++        /* Remove old communication pipe, if present */
++        char *display_num = strchr(server->priv->display_name, ':');
++        if (display_num != NULL && display_num[1] != '\0') {
++                char *old_pipe = g_strdup_printf ("%s/%s", GDM_SDTLOGIN_DIR,
++                                                  display_num + 1);
++                VE_IGNORE_EINTR (g_remove (old_pipe));
++                g_free (old_pipe);
++        }
++#endif
++
+         env = get_server_environment (server);
+ 
+         freeme = g_strjoinv (" ", argv);
+diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
+index 291caad..93c9e82 100644
+--- a/daemon/gdm-session-worker.c
++++ b/daemon/gdm-session-worker.c
+@@ -38,6 +38,7 @@
+ #include <pwd.h>
+ 
+ #if __sun
++#include <sys/param.h>
+ #define GDM_PAM_QUAL
+ #else
+ #define GDM_PAM_QUAL const
+@@ -2044,6 +2045,115 @@ out:
+         return fd;
+ }
+ 
++#ifdef __sun
++static void
++solaris_xserver_cred (const char *username, struct passwd *passwd_entry,
++                      const char *x11_display_name)
++{
++        FILE *fp;
++        struct stat statbuf;
++        gid_t  groups[NGROUPS_UMAX];
++        char *tmp, *p, pipe[MAXPATHLEN], info[MAXPATHLEN];
++        int display_number = 0;
++        int fd, i;
++        int ngroups;
++
++        if (g_access (passwd_entry->pw_dir, F_OK) != 0) {
++                g_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 (x11_display_name, ":")) != NULL) {
++                tmp++;
++                display_number = g_ascii_strtod (tmp, &p);
++
++                if (errno != 0) {
++                        g_debug ("solaris_xserver_cred: problem getting display number\n");
++                        return;
++                }
++        }
++
++        if (g_stat (GDM_SDTLOGIN_DIR, &statbuf) == 0) {
++                if (! S_ISDIR(statbuf.st_mode)) {
++                        g_debug ("solaris_xserver_cred: %s is not a directory\n",
++                                 GDM_SDTLOGIN_DIR);
++                        return;
++                }
++        } else {
++                g_debug ("solaris_xserver_cred: %s does not exist\n", GDM_SDTLOGIN_DIR);
++                return;
++        }
++
++        snprintf (pipe, sizeof(pipe), "%s/%d", GDM_SDTLOGIN_DIR, display_number);
++        fd = open (pipe, O_RDWR);
++        g_remove (pipe);
++
++        if (fd < 0) {
++                g_debug ("solaris_xserver_cred: could not open %s\n", pipe);
++                return;
++        }
++        if (fstat (fd, &statbuf) == 0 ) {
++                if (! S_ISFIFO(statbuf.st_mode)) {
++                        close (fd);
++                        g_debug ("solaris_xserver_cred: %s is not a pipe\n", pipe);
++                        return;
++                }
++        } else {
++                close (fd);
++                g_debug ("solaris_xserver_cred: %s does not exist\n", pipe);
++                return;
++        }
++        fp = fdopen (fd, "w");
++        if (fp == NULL) {
++                close (fd);
++                g_debug ("solaris_xserver_cred: could not fdopen %s\n", pipe);
++                return;
++        }
++
++        snprintf (info, sizeof(info), "GID=\"%d\"; ", passwd_entry->pw_gid);
++        fputs (info, fp);
++        g_debug ("solaris_xserver_cred: %s\n", info);
++
++        if (initgroups (username, passwd_entry->pw_gid) == -1) {
++                ngroups = 0;
++        } else {
++                ngroups = getgroups (NGROUPS_UMAX, groups);
++        }
++
++        for (i=0; i < ngroups; i++) {
++                snprintf (info, sizeof(info), "G_LIST_ID=\"%u\" ", groups[i]);
++                fputs (info, fp);
++                g_debug ("solaris_xserver_cred: %s\n", info);
++        }
++
++        if (ngroups > 0) {
++                fputc (';', fp);
++        }
++
++        snprintf (info, sizeof(info), " HOME=\"%s\" ", passwd_entry->pw_dir);
++        fputs (info, fp);
++        g_debug ("solaris_xserver_cred: %s\n", info);
++
++        snprintf (info, sizeof(info), " UID=\"%d\" EOF=\"\";", passwd_entry->pw_uid);
++        fputs (info, fp);
++        g_debug ("solaris_xserver_cred: %s\n", info);
++
++        /*
++         * Handshake with server. Make sure it read the pipe.
++         *
++         * Close file descriptor.
++         */
++        fflush (fp);
++        fclose (fp);
++
++        return;
++}
++#endif
++
+ static gboolean
+ gdm_session_worker_start_session (GdmSessionWorker  *worker,
+                                   GError           **error)
+@@ -2061,6 +2171,12 @@ gdm_session_worker_start_session (GdmSessionWorker  *worker,
+                          worker->priv->arguments[0]);
+         }
+ 
++#ifdef __sun
++        solaris_xserver_cred (worker->priv->username,
++                              passwd_entry,
++                              worker->priv->x11_display_name);
++#endif
++
+         error_code = PAM_SUCCESS;
+ 
+ #ifdef WITH_SYSTEMD
+diff --git a/daemon/main.c b/daemon/main.c
+index ca2dda3..50f6e94 100644
+--- a/daemon/main.c
++++ b/daemon/main.c
+@@ -324,6 +324,21 @@ main (int    argc,
+ 
+         block_sigusr1 ();
+ 
++#ifdef __sun
++        {
++                struct stat statbuf;
++                int r;
++
++                r = stat (GDM_DT_DIR, &statbuf);
++                if (r < 0) {
++                        g_mkdir (GDM_DT_DIR, 0755);
++                }
++
++                g_remove (GDM_SDTLOGIN_DIR);
++                g_mkdir (GDM_SDTLOGIN_DIR, 0700);
++        }
++#endif
++
+         bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+         textdomain (GETTEXT_PACKAGE);
+         setlocale (LC_ALL, "");
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0005-smf-contracts.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,233 @@
+From 1564b58074df543f4e90b2fee79199c5dd36afca Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Tue, 29 Dec 2015 13:35:20 -0800
+Subject: [PATCH 05/19] smf contracts
+
+Bug 15491359 - SUNBT6720967 gdm is insufficiently contract-aware
+Original date:2008-05-05 owner:yippi type:feature doo:14007
+---
+ acconfig.h                      |   1 +
+ configure.ac                    |   8 +++
+ daemon/gdm-session-worker-job.c | 151 ++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 160 insertions(+)
+
+diff --git a/acconfig.h b/acconfig.h
+index c8a1d96..a6bd4be 100644
+--- a/acconfig.h
++++ b/acconfig.h
+@@ -28,6 +28,7 @@
+ #undef HAVE_SETENV
+ #undef HAVE_SETRESUID
+ #undef HAVE_SHADOW
++#undef HAVE_SMF_CONTRACTS
+ #undef HAVE_SOLARIS_XINERAMA
+ #undef HAVE_STPCPY
+ #undef HAVE_SYS_SOCKIO_H
+diff --git a/configure.ac b/configure.ac
+index 0ada667..5e97a41 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -965,6 +965,14 @@ if test "x$enable_rbac_shutdown" != "xno"; then
+ fi
+ AC_SUBST(RBAC_LIBS)
+ 
++dnl ---------------------------------------------------------------------------
++dnl check for Solaris SMF contract support
++dnl ---------------------------------------------------------------------------
++
++AC_MSG_CHECKING(for Solaris SMF contract support)
++AC_CHECK_LIB(contract, ct_tmpl_activate, [
++			AC_DEFINE(HAVE_SMF_CONTRACTS)
++                            EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -lcontract" ])
+ 
+ dnl ---------------------------------------------------------------------------
+ dnl check for backtrace support
+diff --git a/daemon/gdm-session-worker-job.c b/daemon/gdm-session-worker-job.c
+index 52a6e9f..a1363e9 100644
+--- a/daemon/gdm-session-worker-job.c
++++ b/daemon/gdm-session-worker-job.c
+@@ -45,6 +45,13 @@
+ #include <systemd/sd-journal.h>
+ #endif
+ 
++#ifdef HAVE_SMF_CONTRACTS
++#include <sys/ctfs.h>
++#include <sys/contract.h>
++#include <sys/contract/process.h>
++#include <libcontract.h>
++#endif
++
+ #include <glib.h>
+ #include <glib/gi18n.h>
+ #include <glib-object.h>
+@@ -117,9 +124,145 @@ session_worker_job_setup_journal_fds (void)
+         return;
+ }
+ 
++#ifdef HAVE_SMF_CONTRACTS
++static int contracts_fd = -1;
++
++static void
++contracts_pre_fork (void)
++{
++        const char *errmsg = "opening process contract template";
++
++        /*
++         * On failure, just continue since it is better to start with
++         * children in the same contract than to not start them at all.
++         */
++        if (contracts_fd == -1) {
++                if ((contracts_fd = open64 (CTFS_ROOT "/process/template",
++                                            O_RDWR)) == -1)
++                        goto exit;
++
++                errmsg = "setting contract terms";
++                if ((errno = ct_pr_tmpl_set_param (contracts_fd, CT_PR_PGRPONLY)))
++                        goto exit;
++
++                if ((errno = ct_tmpl_set_informative (contracts_fd, CT_PR_EV_HWERR)))
++                        goto exit;
++
++                if ((errno = ct_pr_tmpl_set_fatal (contracts_fd, CT_PR_EV_HWERR)))
++                        goto exit;
++
++                if ((errno = ct_tmpl_set_critical (contracts_fd, 0)))
++                        goto exit;
++        }
++
++        errmsg = "setting active template";
++        if ((errno = ct_tmpl_activate (contracts_fd)))
++                goto exit;
++
++        g_debug ("Set active contract");
++        return;
++
++exit:
++        if (contracts_fd != -1)
++                (void) close (contracts_fd);
++
++        contracts_fd = -1;
++
++        if (errno) {
++                g_debug ("Error setting up active contract template: %s while %s",
++                         strerror (errno), errmsg);
++        }
++}
++
++static void
++contracts_post_fork_child (void)
++{
++        /* Clear active template so no new contracts are created on fork */
++        if (contracts_fd == -1)
++                return;
++
++        if ((errno = (ct_tmpl_clear (contracts_fd)))) {
++                g_debug (
++                        "Error clearing active contract template (child): %s",
++                        strerror (errno));
++        } else {
++                g_debug ("Cleared active contract template (child)");
++        }
++
++        (void) close (contracts_fd);
++
++        contracts_fd = -1;
++}
++
++static void
++contracts_post_fork_parent (int fork_succeeded)
++{
++        char path[PATH_MAX];
++        int cfd;
++        ct_stathdl_t status;
++        ctid_t latest;
++
++        /* Clear active template, abandon latest contract. */
++        if (contracts_fd == -1)
++                return;
++
++        if ((errno = ct_tmpl_clear (contracts_fd)))
++                g_debug ("Error while clearing active contract template: %s",
++                         strerror (errno));
++        else
++                g_debug ("Cleared active contract template (parent)");
++
++        if (!fork_succeeded)
++                return;
++
++        if ((cfd = open64 (CTFS_ROOT "/process/latest", O_RDONLY)) == -1) {
++                g_debug ("Error getting latest contract: %s",
++                         strerror(errno));
++                return;
++        }
++
++        if ((errno = ct_status_read (cfd, CTD_COMMON, &status)) != 0) {
++                g_debug ("Error getting latest contract ID: %s",
++                         strerror(errno));
++                (void) close (cfd);
++                return;
++        }
++
++        latest = ct_status_get_id (status);
++        ct_status_free (status);
++        (void) close (cfd);
++
++        if ((snprintf (path, PATH_MAX, CTFS_ROOT "/all/%ld/ctl",
++                       (long) latest)) >= PATH_MAX) {
++                g_debug ("Error opening the latest contract ctl file: %s",
++                         strerror (ENAMETOOLONG));
++                return;
++        }
++
++        cfd = open64 (path, O_WRONLY);
++        if (cfd == -1) {
++                g_debug ("Error opening the latest contract ctl file: %s",
++                         strerror (errno));
++                return;
++        }
++
++        if ((errno = ct_ctl_abandon (cfd)))
++                g_debug ("Error abandoning latest contract: %s",
++                         strerror (errno));
++        else
++                g_debug ("Abandoned latest contract");
++
++        (void) close (cfd);
++}
++#endif /* HAVE_SMF_CONTRACTS */
++
+ static void
+ session_worker_job_child_setup (GdmSessionWorkerJob *session_worker_job)
+ {
++#ifdef HAVE_SMF_CONTRACTS
++        contracts_post_fork_child ();
++#endif
++
+         session_worker_job_setup_journal_fds ();
+ 
+         /* Terminate the process when the parent dies */
+@@ -273,6 +416,10 @@ gdm_session_worker_job_spawn (GdmSessionWorkerJob *session_worker_job,
+         }
+         env = get_job_environment (session_worker_job);
+ 
++#ifdef HAVE_SMF_CONTRACTS
++        contracts_pre_fork ();
++#endif
++
+         error = NULL;
+         ret = g_spawn_async_with_pipes (NULL,
+                                         (char **) args->pdata,
+@@ -286,6 +433,10 @@ gdm_session_worker_job_spawn (GdmSessionWorkerJob *session_worker_job,
+                                         NULL,
+                                         &error);
+ 
++#ifdef HAVE_SMF_CONTRACTS
++        contracts_post_fork_parent ((session_worker_job->priv->pid > 0));
++#endif
++
+         g_ptr_array_foreach (args, (GFunc)g_free, NULL);
+         g_ptr_array_free (args, TRUE);
+ 
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0006-etc-default-login.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,141 @@
+From 0ccf6e6afa7eb6f5dc8b8c6689caa8bb190fef0d Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Tue, 29 Dec 2015 14:21:38 -0800
+Subject: [PATCH 06/19] /etc/default/login
+
+Add support for /etc/default/login configuration.
+Original date:2009-03-31 owner:yippi type:feature
+---
+ daemon/gdm-session-worker.c | 83 +++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 76 insertions(+), 7 deletions(-)
+
+diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
+index 93c9e82..5fc83d6 100644
+--- a/daemon/gdm-session-worker.c
++++ b/daemon/gdm-session-worker.c
+@@ -222,6 +222,33 @@ G_DEFINE_TYPE_WITH_CODE (GdmSessionWorker,
+                          G_IMPLEMENT_INTERFACE (GDM_DBUS_TYPE_WORKER,
+                                                 worker_interface_init))
+ 
++#if __sun
++#include <deflt.h>
++
++/*
++ * 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.
++ */
++static gchar *
++gdm_read_default (gchar *key)
++{
++    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;
++}
++#endif
++
+ #ifdef WITH_CONSOLE_KIT
+ static gboolean
+ open_ck_session (GdmSessionWorker  *worker)
+@@ -1351,6 +1378,28 @@ gdm_session_worker_authorize_user (GdmSessionWorker *worker,
+         g_debug ("GdmSessionWorker: determining if authenticated user (password required:%d) is authorized to session",
+                  password_is_required);
+ 
++#ifdef __sun
++        char *consoleonly = gdm_read_default ("CONSOLE=");
++
++        if ((consoleonly != NULL) &&
++            (strcmp (consoleonly, "/dev/console") == 0)) {
++
++                if (worker->priv->hostname != NULL &&
++                    worker->priv->hostname[0] != '\0') {
++                        struct passwd *passwd_entry;
++
++                        passwd_entry = getpwnam (worker->priv->username);
++                        if (passwd_entry->pw_uid == 0) {
++                                error_code = PAM_PERM_DENIED;
++
++                                g_debug ("The system administrator is not allowed to log in remotely");
++                                g_set_error (error, GDM_SESSION_WORKER_ERROR, GDM_SESSION_WORKER_ERROR_AUTHORIZING, "%s", pam_strerror (worker->priv->pam_handle, error_code));
++                                goto out;
++                        }
++                }
++        }
++#endif
++
+         authentication_flags = 0;
+ 
+         if (password_is_required) {
+@@ -1716,6 +1765,7 @@ gdm_session_worker_accredit_user (GdmSessionWorker  *worker,
+         gid_t    gid;
+         char    *shell;
+         char    *home;
++        char    *path_str;
+         int      error_code;
+ 
+         ret = FALSE;
+@@ -1756,18 +1806,26 @@ gdm_session_worker_accredit_user (GdmSessionWorker  *worker,
+                                                                 home,
+                                                                 shell);
+ 
+-        /* Let's give the user a default PATH if he doesn't already have one
+-         */
+-        if (!gdm_session_worker_environment_variable_is_set (worker, "PATH")) {
++        path_str = NULL;
++
++#ifdef __sun
++        if (uid == 0)
++                path_str = gdm_read_default ("SUPATH=");
++
++        if (path_str == NULL)
++                path_str = gdm_read_default ("PATH=");
++#endif
++
++        if (path_str == NULL)  {
+                 if (strcmp (BINDIR, "/usr/bin") == 0) {
+-                        gdm_session_worker_set_environment_variable (worker, "PATH",
+-                                                                     GDM_SESSION_DEFAULT_PATH);
++                        path_str = GDM_SESSION_DEFAULT_PATH;
+                 } else {
+-                        gdm_session_worker_set_environment_variable (worker, "PATH",
+-                                                                     BINDIR ":" GDM_SESSION_DEFAULT_PATH);
++                        path_str = BINDIR ":" GDM_SESSION_DEFAULT_PATH;
+                 }
+         }
+ 
++        gdm_session_worker_set_environment_variable (worker, "PATH", path_str);
++
+         if (! _change_user (worker, uid, gid)) {
+                 g_debug ("GdmSessionWorker: Unable to change to user");
+                 error_code = PAM_SYSTEM_ERR;
+@@ -2768,6 +2826,17 @@ do_setup (GdmSessionWorker *worker)
+         GError  *error;
+         gboolean res;
+ 
++#ifdef __sun
++        char    *passreq;
++
++        passreq = gdm_read_default ("PASSREQ=");
++
++        if ((passreq != NULL) && g_ascii_strcasecmp (passreq, "YES") == 0)
++                worker->priv->password_is_required = TRUE;
++        else
++                worker->priv->password_is_required = FALSE;
++#endif
++
+         error = NULL;
+         res = gdm_session_worker_initialize_pam (worker,
+                                                  worker->priv->service,
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0007-solaris-notty.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,151 @@
+From 05391989747e3c6044329002f0786c37f34a2f6c Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Tue, 29 Dec 2015 15:51:45 -0800
+Subject: [PATCH 07/19] solaris-notty
+
+Workaround the Solaris PAM & auditing subsystems requirements that
+every session cannot be attributed to a single device file, as if
+we all still logged in on serial terminals.
+
+Original date:2009-10-16 owner:yippi type:branding
+---
+ daemon/gdm-manager.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
+ daemon/gdm-server.c  | 37 +++++++++++++++++++++++++++++++++----
+ 2 files changed, 81 insertions(+), 4 deletions(-)
+
+diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
+index 3d1d2eb..46c07ca 100644
+--- a/daemon/gdm-manager.c
++++ b/daemon/gdm-manager.c
+@@ -29,6 +29,11 @@
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ 
++#ifdef __sun
++#include <utime.h>
++#include <sys/param.h>
++#endif
++
+ #include <glib.h>
+ #include <glib/gi18n.h>
+ #include <glib/gstdio.h>
+@@ -2467,6 +2472,46 @@ clean_embryonic_user_session (GdmSession *session)
+         g_object_unref (session);
+ }
+ 
++static void
++create_device (const char *dev)
++{
++#ifdef __sun
++        gchar buf[MAXPATHLEN + 1];
++        struct stat st;
++
++        if (dev == NULL || dev[0] == '\0')
++                return;
++
++        if (strcmp (dev, "/dev/dtlocal")  != 0 &&
++            strcmp (dev, "/dev/dtremote") != 0 )
++                return;
++
++        memset (buf, 0, sizeof (gchar) * (MAXPATHLEN + 1));
++
++        if (stat (dev, &st) != 0) {
++                g_debug ("Creating pseudo-device %s", dev);
++                symlink ("/dev/null", dev);
++        } else if (readlink (dev, buf, MAXPATHLEN) > 0) {
++                if (strcmp (buf, "/dev/null") == 0) {
++                        /* Touch symlink */
++                        struct utimbuf  timebuf;
++
++                        timebuf.modtime = time ((time_t *) 0);
++                        timebuf.actime  = timebuf.modtime;
++
++                        if ((utime (dev, &timebuf)) != 0)
++                                g_debug ("Problem updating access time of pseudo-device %s", dev);
++                        else
++                                g_debug ("Touching pseudo-device %s", dev);
++                } else {
++                        g_debug ("Device %s points to %s", dev, buf);
++                }
++        } else {
++                g_debug ("Device %s is not a symlink", dev);
++        }
++#endif
++}
++
+ static GdmSession *
+ create_embryonic_user_session_for_display (GdmManager *manager,
+                                            GdmDisplay *display,
+@@ -2490,6 +2535,9 @@ create_embryonic_user_session_for_display (GdmManager *manager,
+                       "seat-id", &display_seat_id,
+                       NULL);
+         display_device = get_display_device (manager, display);
++        if (!display_device && !display_is_local)
++                display_device = g_strdup ("/dev/dtremote");
++        create_device (display_device);
+ 
+         session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_LOGIN,
+                                    allowed_user,
+diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
+index 2cec263..77c18a8 100644
+--- a/daemon/gdm-server.c
++++ b/daemon/gdm-server.c
+@@ -96,6 +96,7 @@ struct GdmServerPrivate
+         guint    child_watch_id;
+ 
+         gboolean is_initial;
++        gboolean is_local;
+ };
+ 
+ enum {
+@@ -146,15 +147,43 @@ _gdm_server_query_ck_for_display_device (GdmServer *server)
+                                          NULL,
+                                          &status,
+                                          &error);
++        g_free (command);
++
+         if (! res) {
+                 g_warning ("Could not run helper: %s", error->message);
+                 g_error_free (error);
+-        } else {
+-                out = g_strstrip (out);
+-                g_debug ("GdmServer: Got tty: '%s'", out);
++                g_free (out);
++                return NULL;
+         }
+ 
+-        g_free (command);
++        out = g_strstrip (out);
++
++        /* There are several scenarios that the device will be "?"
++         * 1. Local sessions without VT support. If the display is ":0",
++         *    we set the device as "/dev/console" to gain device permissions.
++         *    This only happens on those systems do not has VT support such as
++         *    old Solaris. So far, Linux and OpenSolaris with VT support.
++         * 2. XDMCP sessions, we set device as "/dev/dtremote"
++         * 3. Local sessions like Sun Ray, Xvfb, Xvnc, we set device as
++         *    "/dev/dtlocal"
++         */
++        if (g_str_equal (out, "?")) {
++                if (!server->priv->is_local) {
++                        /* This is for XDMCP sessions. */
++                        out = g_strdup ("/dev/dtremote");
++                } else  {
++                        if (g_str_equal (server->priv->display_name, ":0")) {
++                                /* This is for local session run on console. */
++                                out = g_strdup ("/dev/console");
++                        } else {
++                                /* This is for local sessions like
++                                 * Sun Ray, Xvfb, Xvnc, etc. */
++                                out = g_strdup ("/dev/dtlocal");
++                        }
++                }
++        }
++
++        g_debug ("GdmServer: Got tty: '%s'", out);
+ 
+         return out;
+ }
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0008-audio-settings-restore.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,90 @@
+From 86af425cff12da4d1e53d9688e1130f7981648de Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Tue, 29 Dec 2015 16:13:34 -0800
+Subject: [PATCH 08/19] audio-settings-restore
+
+Bug 15424062/SUNBT6606096 volume control preferences don't remain after reboot
+Original date:2010-02-15 owner:yippi type:feature bugster:6606096
+
+Includes followup fix for:
+
+Bug 18899731 - GDM: permissions for .audioctl and audioctl device file are
+  not set as expected.
+Original date:2014-07-11 owner:abhijit type:bug bugdb:18899731
+---
+ data/PostSession.in | 26 ++++++++++++++++++++++++++
+ data/Xsession.in    | 24 ++++++++++++++++++++++++
+ 2 files changed, 50 insertions(+)
+
+diff --git a/data/PostSession.in b/data/PostSession.in
+index c52d3c2..83e23d1 100755
+--- a/data/PostSession.in
++++ b/data/PostSession.in
+@@ -1,3 +1,29 @@
+ #!/bin/sh
++PATH="@SCRIPT_PATH@"
++
++AUDIOCTL_SAVE_HOSTNAME=`/usr/bin/hostname`
++AUDIOCTL_SAVE_DIR="$HOME/.audioctl"
++AUDIOCTL_SAVE_DEVICE=""
++AUDIOCTL_DEVICE_OWNER=`/usr/bin/stat -L /dev/audio -c %U`
++
++# Only set audio settings if logindevperm has set the owner of the audio device
++# to this user.
++#
++if test "x$USER" = "x$AUDIOCTL_DEVICE_OWNER" ; then
++  if test -x "/usr/bin/audioctl" ; then
++    AUDIOCTL_SAVE_DEVICE=`/usr/bin/audioctl show-device | /usr/bin/awk '/^ *Name /{ print $3; }'`
++  fi
++
++  if test -n "$AUDIOCTL_SAVE_HOSTNAME" -a -n "$AUDIOCTL_SAVE_DEVICE"; then
++    if test ! -d "$AUDIOCTL_SAVE_DIR" ; then
++      /usr/bin/su "$USER" -c "/usr/bin/mkdir $AUDIOCTL_SAVE_DIR; /usr/bin/chmod 700 $AUDIOCTL_SAVE_DIR"
++    fi
++
++    if test -d "$AUDIOCTL_SAVE_DIR" ; then
++      AUDIOCTL_SAVE_FILE="$AUDIOCTL_SAVE_DIR/audioctl-$AUDIOCTL_SAVE_HOSTNAME-$AUDIOCTL_SAVE_DEVICE"
++      /usr/bin/su "$USER" -c "/usr/bin/audioctl save-controls -f $AUDIOCTL_SAVE_FILE; /usr/bin/chmod 600 $AUDIOCTL_SAVE_FILE"
++    fi
++  fi
++fi
+ 
+ exit 0
+diff --git a/data/Xsession.in b/data/Xsession.in
+index f253375..fda4b16 100755
+--- a/data/Xsession.in
++++ b/data/Xsession.in
+@@ -70,6 +70,30 @@ gdmwhich () {
+   echo "$OUTPUT"
+ }
+ 
++# Reload audio settings after sourcing the user's .profile to ensure that any
++# AUDIODEV settings defined by the user are honored.
++#
++AUDIOCTL_SAVE_HOSTNAME=`/usr/bin/hostname`
++AUDIOCTL_SAVE_DEVICE=""
++AUDIOCTL_SAVE_DIR="$HOME/.audioctl"
++AUDIOCTL_DEVICE_OWNER=`/usr/bin/stat -L /dev/audio -c %U`
++
++# Only set audio settings if logindevperm has set the owner of the audio
++# device to this user.
++#
++if test "x$USER" = "x$AUDIOCTL_DEVICE_OWNER" ; then
++  if test -x "/usr/bin/audioctl" ; then
++    AUDIOCTL_SAVE_DEVICE=`/usr/bin/audioctl show-device | /usr/bin/awk '/^ *Name /{ print $3; }'`
++  fi
++
++  if test -n "$AUDIOCTL_SAVE_HOSTNAME" -a -n "$AUDIOCTL_SAVE_DEVICE"; then
++    AUDIOCTL_SAVE_FILE="$AUDIOCTL_SAVE_DIR/audioctl-$AUDIOCTL_SAVE_HOSTNAME-$AUDIOCTL_SAVE_DEVICE"
++    if test -f "$AUDIOCTL_SAVE_FILE" ; then
++      /usr/bin/audioctl load-controls $AUDIOCTL_SAVE_FILE
++    fi
++  fi
++fi
++
+ zenity=`gdmwhich zenity`
+ 
+ # Note: ~/.xsession-errors is now done in the daemon so that it
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0009-xauth-directory.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,285 @@
+From 2ee31816ec447ad8aca5ed20e1793f248204d0ed Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Tue, 29 Dec 2015 17:22:36 -0800
+Subject: [PATCH 09/19] xauth-directory
+
+Bug 15620655/SUNBT6923733 gdm create user writable directories under /var/run
+Original date:2010-02-19 owner:yippi type:feature bugster:6923733
+---
+ daemon/gdm-display-access-file.c | 128 ++++++++++++++++++++++++++++++++++-----
+ daemon/gdm-display-access-file.h |   1 +
+ daemon/main.c                    |   3 +
+ data/Makefile.am                 |  12 ++--
+ 4 files changed, 124 insertions(+), 20 deletions(-)
+
+diff --git a/daemon/gdm-display-access-file.c b/daemon/gdm-display-access-file.c
+index 02ec0a0..90e4eed 100644
+--- a/daemon/gdm-display-access-file.c
++++ b/daemon/gdm-display-access-file.c
+@@ -41,6 +41,8 @@
+ #include "gdm-display-access-file.h"
+ #include "gdm-common.h"
+ 
++static const char *xauth_dir_name = NULL;
++
+ struct _GdmDisplayAccessFilePrivate
+ {
+         char *username;
+@@ -221,13 +223,24 @@ _get_uid_and_gid_for_user (const char *username,
+         return TRUE;
+ }
+ 
++void
++gdm_display_access_file_cleanup_xauth (void)
++{
++        /* Clean up any xauth_dir_name when shutting down */
++        if (strcmp (GDM_XAUTH_DIR, "/tmp") == 0 && xauth_dir_name != NULL) {
++                g_remove (xauth_dir_name);
++                g_debug ("GdmDisplayAccessFile: Unlinking xauth directory %s", xauth_dir_name);
++                xauth_dir_name = NULL;
++        }
++}
++
+ static void
+-clean_up_stale_auth_subdirs (void)
++clean_up_stale_auth_subdirs (const char * xauth_dir_name)
+ {
+         GDir *dir;
+         const char *filename;
+ 
+-        dir = g_dir_open (GDM_XAUTH_DIR, 0, NULL);
++        dir = g_dir_open (xauth_dir_name, 0, NULL);
+ 
+         if (dir == NULL) {
+                 return;
+@@ -236,7 +249,7 @@ clean_up_stale_auth_subdirs (void)
+         while ((filename = g_dir_read_name (dir)) != NULL) {
+                 char *path;
+ 
+-                path = g_build_filename (GDM_XAUTH_DIR, filename, NULL);
++                path = g_build_filename (xauth_dir_name, filename, NULL);
+ 
+                 /* Will only succeed if the directory is empty
+                  */
+@@ -251,10 +264,13 @@ _create_xauth_file_for_user (const char  *username,
+                              char       **filename,
+                              GError     **error)
+ {
++        struct stat statbuf;
++        gboolean dir_exists;
+         char   *template;
+         const char *dir_name;
+         char   *auth_filename;
+         int     fd;
++        int     xauth_dir_fp = -1;
+         FILE   *fp;
+         uid_t   uid;
+         gid_t   gid;
+@@ -268,10 +284,37 @@ _create_xauth_file_for_user (const char  *username,
+         fp = NULL;
+         fd = -1;
+ 
++        dir_exists = TRUE;
++
++        if (xauth_dir_name == NULL) {
++                if (strcmp (GDM_XAUTH_DIR, "/tmp") == 0) {
++                        dir_exists = FALSE;
++                        template = g_strdup_printf ("/tmp/gdm-auth-cookies-XXXXXX");
++                        xauth_dir_name = gdm_make_temp_dir (template);
++
++                        g_debug ("GdmDisplayAccessFile: Creating xauth directory %s", xauth_dir_name);
++                        g_chmod (xauth_dir_name, 0711);
++                        _get_uid_and_gid_for_user (GDM_USERNAME, &uid, &gid);
++                        if (chown (xauth_dir_name, 0, gid) != 0) {
++                                g_warning ("Unable to change owner of '%s'",
++                                           xauth_dir_name);
++                        }
++                } else {
++                        xauth_dir_name = GDM_XAUTH_DIR;
++                }
++        }
++
++        /*
++         * Note: if GDM_XAUTH_DIR is "/tmp", we never fall into the next if-case, since
++         * gdm_make_temp_dir calls mkdtemp() which creates the directory.
++         */
++
+         /* Create directory if not exist, then set permission 0711 and ownership root:gdm */
+-        if (g_file_test (GDM_XAUTH_DIR, G_FILE_TEST_IS_DIR) == FALSE) {
+-                g_remove (GDM_XAUTH_DIR);
+-                if (g_mkdir (GDM_XAUTH_DIR, 0711) != 0) {
++
++        if (g_file_test (xauth_dir_name, G_FILE_TEST_IS_DIR) == FALSE) {
++                dir_exists = FALSE;
++                g_remove (xauth_dir_name);
++                if (g_mkdir (xauth_dir_name, 0711) != 0) {
+                         g_set_error (error,
+                                      G_FILE_ERROR,
+                                      g_file_error_from_errno (errno),
+@@ -279,18 +322,70 @@ _create_xauth_file_for_user (const char  *username,
+                         goto out;
+                 }
+ 
+-                g_chmod (GDM_XAUTH_DIR, 0711);
++                g_chmod (xauth_dir_name, 0711);
+                 _get_uid_and_gid_for_user (GDM_USERNAME, &uid, &gid);
+-                if (chown (GDM_XAUTH_DIR, 0, gid) != 0) {
++                if (chown (xauth_dir_name, 0, gid) != 0) {
+                         g_warning ("Unable to change owner of '%s'",
+-                                   GDM_XAUTH_DIR);
++                                   xauth_dir_name);
++                }
++        }
++
++        /* Do sanity testing on the Xauth directory */
++        if ((xauth_dir_fp = open (xauth_dir_name, O_RDONLY | O_NOFOLLOW)) == -1) {
++                /* If it is a symlink, open fails with O_NOFOLLOW. */
++                g_set_error (error,
++                     GDM_DISPLAY_ACCESS_FILE_ERROR,
++                     GDM_DISPLAY_ACCESS_FILE_ERROR_FINDING_AUTH_ENTRY,
++                     _("GDM authorization directory %s cannot be opened."),
++                     xauth_dir_name);
++                goto out;
++        }
++
++        if (fstat (xauth_dir_fp, &statbuf) == 0) {
++                if (! S_ISDIR (statbuf.st_mode)) {
++                        g_set_error (error,
++                             GDM_DISPLAY_ACCESS_FILE_ERROR,
++                             GDM_DISPLAY_ACCESS_FILE_ERROR_FINDING_AUTH_ENTRY,
++                             _("GDM authorization directory %s is not a directory."),
++                             xauth_dir_name);
++                        goto out;
++                }
++
++                if (statbuf.st_uid != 0) {
++                        g_set_error (error,
++                             GDM_DISPLAY_ACCESS_FILE_ERROR,
++                             GDM_DISPLAY_ACCESS_FILE_ERROR_FINDING_AUTH_ENTRY,
++                             _("GDM authorization directory %s: uid is not root"),
++                             xauth_dir_name);
++                        goto out;
++                }
++
++                _get_uid_and_gid_for_user (GDM_USERNAME, &uid, &gid);
++                if (statbuf.st_gid != gid) {
++                        g_set_error (error,
++                             GDM_DISPLAY_ACCESS_FILE_ERROR,
++                             GDM_DISPLAY_ACCESS_FILE_ERROR_FINDING_AUTH_ENTRY,
++                             _("GDM authorization directory %s: gid is not the GDM user"),
++                             xauth_dir_name);
++                        goto out;
+                 }
+         } else {
+-                /* if it does exist make sure it has correct mode 0711 */
+-                g_chmod (GDM_XAUTH_DIR, 0711);
++                g_set_error (error,
++                     GDM_DISPLAY_ACCESS_FILE_ERROR,
++                     GDM_DISPLAY_ACCESS_FILE_ERROR_FINDING_AUTH_ENTRY,
++                     _("Cannot fstat() the GDM authorization directory %s"),
++                     xauth_dir_name);
++                goto out;
++        }
++
++        if (dir_exists == TRUE) {
++                /* If we did not create the directory, do some cleanup */
++
++                /* Make sure it has correct mode 0711 */
++                g_chmod (xauth_dir_name, 0711);
+ 
+                 /* and clean up any stale auth subdirs */
+-                clean_up_stale_auth_subdirs ();
++                clean_up_stale_auth_subdirs (xauth_dir_name);
+         }
+ 
+         if (!_get_uid_and_gid_for_user (username, &uid, &gid)) {
+@@ -303,9 +398,8 @@ _create_xauth_file_for_user (const char  *username,
+ 
+         }
+ 
+-        template = g_strdup_printf (GDM_XAUTH_DIR
+-                                    "/auth-for-%s-XXXXXX",
+-                                    username);
++        template = g_strdup_printf ("%s/auth-for-%s-XXXXXX",
++                                    xauth_dir_name, username);
+ 
+         g_debug ("GdmDisplayAccessFile: creating xauth directory %s", template);
+         /* Initially create with mode 01700 then later chmod after we create database */
+@@ -394,7 +488,9 @@ out:
+         if (fd != -1) {
+                 close (fd);
+         }
+-
++        if (xauth_dir_fp != -1) {
++		close (xauth_dir_fp);
++        }
+         return fp;
+ }
+ 
+diff --git a/daemon/gdm-display-access-file.h b/daemon/gdm-display-access-file.h
+index cc7de9e..091b31f 100644
+--- a/daemon/gdm-display-access-file.h
++++ b/daemon/gdm-display-access-file.h
+@@ -83,6 +83,7 @@ gboolean              gdm_display_access_file_remove_display          (GdmDispla
+ 
+ void                  gdm_display_access_file_close                   (GdmDisplayAccessFile  *file);
+ char                 *gdm_display_access_file_get_path                (GdmDisplayAccessFile  *file);
++void                  gdm_display_access_file_cleanup_xauth           (void);
+ 
+ G_END_DECLS
+ #endif /* __GDM_DISPLAY_ACCESS_FILE_H__ */
+diff --git a/daemon/main.c b/daemon/main.c
+index 50f6e94..65f34c8 100644
+--- a/daemon/main.c
++++ b/daemon/main.c
+@@ -47,6 +47,7 @@
+ #include "gdm-settings.h"
+ #include "gdm-settings-direct.h"
+ #include "gdm-settings-keys.h"
++#include "gdm-display-access-file.h"
+ 
+ #define GDM_DBUS_NAME "org.gnome.DisplayManager"
+ 
+@@ -426,6 +427,8 @@ main (int    argc,
+         gdm_settings_direct_shutdown ();
+         gdm_log_shutdown ();
+ 
++        gdm_display_access_file_cleanup_xauth ();
++
+         g_main_loop_unref (main_loop);
+ 
+         ret = 0;
+diff --git a/data/Makefile.am b/data/Makefile.am
+index 81cde22..a05fc14 100644
+--- a/data/Makefile.am
++++ b/data/Makefile.am
+@@ -212,8 +212,10 @@ uninstall-hook:
+ 	$(DESTDIR)$(sysconfdir)/dconf/profile/gdm \
+ 	-rf \
+ 	$(DESTDIR)$(screenshotdir) \
+-	$(DESTDIR)$(xauthdir) \
+ 	$(DESTDIR)$(PAM_PREFIX)/pam.d
++	if test "x$(xauthdir)" -ne "x/tmp"; then \
++		rm -rf $(DESTDIR)$(xauthdir) \
++	fi
+ 
+ 	if test -n "$(systemdsystemunit)"; then \
+ 		rm -f $(DESTDIR)$(SYSTEMD_SYSTEM_UNIT_DIR)/$(systemdsystemunit); \
+@@ -292,9 +294,11 @@ endif
+ 	fi
+ 
+ 	if test '!' -d $(DESTDIR)$(xauthdir); then \
+-		$(mkinstalldirs) $(DESTDIR)$(xauthdir); \
+-		chmod 0711 $(DESTDIR)$(xauthdir); \
+-		chown root:gdm $(DESTDIR)$(xauthdir) || : ; \
++		if test "x$(xauthdir)" -ne "x/tmp"; then \
++			$(mkinstalldirs) $(DESTDIR)$(xauthdir); \
++			chmod 0711 $(DESTDIR)$(xauthdir); \
++			chown root:gdm $(DESTDIR)$(xauthdir) || : ; \
++		fi \
+ 	fi
+ 
+ 	if test -n "$(systemdsystemunit)" -a '!' -d $(DESTDIR)$(SYSTEMD_SYSTEM_UNIT_DIR); then \
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0010-logindevperm.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,152 @@
+From ec1cbb0425a809bae65d76cec2440aeaac6a0970 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Tue, 29 Dec 2015 18:07:05 -0800
+Subject: [PATCH 10/19] logindevperm
+
+Support for Solaris /etc/logindevperm.  A previous version of this patch
+was upstream, but disappeared in code rewrites.  The desktop gate had a
+patch (gdm-28-logindevperm.diff) which also removed the old upstream code
+and replaced with a new version - it's unclear if it was ever sent upstream.
+
+This revision is based on that patch, but moves the calls from the
+launch-environment to the session-worker, where they can be run as
+root so that they actually work in gdm 3.18.
+
+Orig. date:2010-12-14 owner:yippi type:feature bugster:6998997 bugzilla:621581
+---
+ configure.ac                |  2 +-
+ daemon/gdm-session-worker.c | 77 +++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 78 insertions(+), 1 deletion(-)
+
+diff --git a/configure.ac b/configure.ac
+index 5e97a41..cc58fbb 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1152,7 +1152,7 @@ AC_SUBST(EXTRA_TEST_LIBS)
+ #
+ AC_CHECK_LIB(devinfo, di_devperm_login, [
+                         AC_DEFINE(HAVE_LOGINDEVPERM)
+-                            PAM_LIBS="$PAM_LIBS -ldevinfo" ])
++                            EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -ldevinfo" ])
+ 
+ dnl ---------------------------------------------------------------------------
+ dnl - Check for X Server location
+diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
+index 5fc83d6..f19a92f 100644
+--- a/daemon/gdm-session-worker.c
++++ b/daemon/gdm-session-worker.c
+@@ -46,6 +46,10 @@
+ 
+ #include <security/pam_appl.h>
+ 
++#ifdef HAVE_LOGINDEVPERM
++#include <libdevinfo.h>
++#endif
++
+ #ifdef HAVE_LOGINCAP
+ #include <login_cap.h>
+ #endif
+@@ -1917,6 +1921,10 @@ run_script (GdmSessionWorker *worker,
+                                worker->priv->x11_authority_file);
+ }
+ 
++#ifdef HAVE_LOGINDEVPERM
++static void gdm_session_worker_revoke_console_permissions (GdmSessionWorker *);
++#endif
++
+ static void
+ session_worker_child_watch (GPid              pid,
+                             int               status,
+@@ -1944,6 +1952,11 @@ session_worker_child_watch (GPid              pid,
+         worker->priv->child_pid = -1;
+         worker->priv->child_watch_id = 0;
+         run_script (worker, GDMCONFDIR "/PostSession");
++
++#ifdef HAVE_LOGINDEVPERM
++        gdm_session_worker_revoke_console_permissions (worker);
++#endif
++
+ }
+ 
+ static void
+@@ -2103,6 +2116,66 @@ out:
+         return fd;
+ }
+ 
++#ifdef HAVE_LOGINDEVPERM
++static void
++gdm_session_worker_grant_console_permissions (
++        GdmSessionWorker  *worker,
++        struct passwd *passwd_entry)
++{
++        const char *username =  worker->priv->username;
++        const char *display_device = worker->priv->display_device;
++
++        /*
++         * Only do logindevperm processing if /dev/console or
++         * a device associated with a VT
++         */
++        if (display_device != NULL &&
++            (strncmp (display_device, "/dev/vt/", strlen ("/dev/vt/")) == 0 ||
++             strcmp  (display_device, "/dev/console") == 0)) {
++                g_debug ("Logindevperm login for user %s, device %s",
++                         username, display_device);
++                if (di_devperm_login (display_device,
++                                      passwd_entry->pw_uid,
++                                      passwd_entry->pw_gid,
++                                      NULL) == -1) {
++                        g_debug("error processing /etc/logindevperm,"
++                                " see syslog for more details\n");
++                }
++        } else {
++                g_debug ("Not calling di_devperm_login login for user %s, device %s",
++                         username, display_device);
++        }
++}
++
++static void
++gdm_session_worker_revoke_console_permissions (
++        GdmSessionWorker  *worker)
++{
++        const char *username =  worker->priv->username;
++        const char *display_device = worker->priv->display_device;
++
++        /*
++         * Only do logindevperm processing if /dev/console or a device
++         * associated with a VT.  Do this after processing the PostSession
++         * script so that permissions for devices are not returned to root
++         * before running the script.
++         */
++        if (display_device != NULL &&
++            (strncmp (display_device, "/dev/vt/", strlen ("/dev/vt/")) == 0 ||
++             strcmp  (display_device, "/dev/console") == 0)) {
++                g_debug ("di_devperm_logout for user %s, device %s",
++                         username, display_device);
++                if (di_devperm_logout (display_device) == -1) {
++                        g_debug("error processing /etc/logindevperm,"
++                                " see syslog for more details\n");
++                }
++        } else {
++                g_debug ("Not calling di_devperm_logout logout for user %s, device %s",
++                         username, display_device);
++        }
++}
++#endif  /* HAVE_LOGINDEVPERM */
++
+ #ifdef __sun
+ static void
+ solaris_xserver_cred (const char *username, struct passwd *passwd_entry,
+@@ -2229,6 +2302,10 @@ gdm_session_worker_start_session (GdmSessionWorker  *worker,
+                          worker->priv->arguments[0]);
+         }
+ 
++#ifdef HAVE_LOGINDEVPERM
++        gdm_session_worker_grant_console_permissions (worker, passwd_entry);
++#endif
++
+ #ifdef __sun
+         solaris_xserver_cred (worker->priv->username,
+                               passwd_entry,
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0011-vtswitch-on-exit.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,99 @@
+From 07e3172702817a57ef5b9546575c3d0a6378c0f4 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Tue, 29 Dec 2015 18:35:41 -0800
+Subject: [PATCH 11/19] vtswitch on exit
+
+Bug 15737566/SUNBT7082840 Disabling the gdm SMF service no longer returns
+ to the text console
+Original date:2011-08-29 owner:yippi type:bug bugster:7082840
+---
+ daemon/main.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 60 insertions(+)
+
+diff --git a/daemon/main.c b/daemon/main.c
+index 65f34c8..f3329d0 100644
+--- a/daemon/main.c
++++ b/daemon/main.c
+@@ -33,6 +33,7 @@
+ #include <sys/wait.h>
+ #include <locale.h>
+ #include <signal.h>
++#include <sys/vt.h>
+ 
+ #include <glib.h>
+ #include <glib/gi18n.h>
+@@ -255,12 +256,71 @@ gdm_daemon_lookup_user (uid_t *uidp,
+ }
+ 
+ static gboolean
++ck_fd_is_a_console (int fd)
++{
++#ifdef __linux__
++        struct vt_stat vts;
++#elif defined(__FreeBSD__)
++        int vers;
++#endif
++        int  kb_ok;
++
++        errno = 0;
++#ifdef __linux__
++        kb_ok = (ioctl (fd, VT_GETSTATE, &vts) == 0);
++#elif defined(__FreeBSD__)
++        kb_ok = (ioctl (fd, CONS_GETVERS, &vers) == 0);
++#else
++        kb_ok = 1;
++#endif
++
++        return (isatty (fd) && kb_ok);
++}
++
++static int
++open_a_console (const char *fnam)
++{
++        int fd;
++
++        fd = open (fnam, O_RDONLY | O_NOCTTY);
++        if (fd < 0 && errno == EACCES)
++                fd = open (fnam, O_WRONLY | O_NOCTTY);
++
++        if (fd < 0)
++                return -1;
++
++        if (! ck_fd_is_a_console (fd)) {
++                close (fd);
++                fd = -1;
++        }
++
++        return fd;
++}
++
++static gboolean
+ on_shutdown_signal_cb (gpointer user_data)
+ {
+         GMainLoop *mainloop = user_data;
+ 
+         g_main_loop_quit (mainloop);
+ 
++        /* Switch to VT1 before going down. */
++        int fd = open_a_console ("/dev/vt/active");
++        if (fd < 0) {
++                fd = open_a_console ("/dev/vt/0");
++        }
++
++        if (fd >= 0) {
++                int res;
++
++                res = ioctl (fd, VT_ACTIVATE, 1);
++
++                if (res != 0) {
++                        if (errno == ENOTSUP) {
++                                g_debug ("VT_ACTIVATE not supported, cannot switch to VT1");
++                        }
++                }
++        }
+         return FALSE;
+ }
+ 
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0012-restart-limit.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,100 @@
+From 1d0cd85ec6ad9ae9886618816605261e8519b731 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Tue, 29 Dec 2015 18:50:08 -0800
+Subject: [PATCH 12/19] restart limit
+
+Bug 15745160/SUNBT7096672 GDM should stop restarting the Xserver on the console
+Original owner:yippi date:2011-11-07 type:bug bugster:7096672
+---
+ daemon/gdm-display.c | 33 ++++++++++++++++++++-------------
+ 1 file changed, 20 insertions(+), 13 deletions(-)
+
+diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
+index ab84ba4..ab7eba7 100644
+--- a/daemon/gdm-display.c
++++ b/daemon/gdm-display.c
+@@ -68,7 +68,8 @@ struct GdmDisplayPrivate
+         char                 *x11_display_name;
+         int                   status;
+         time_t                creation_time;
+-        GTimer               *server_timer;
++        int                   num_failures;
++        gint64                time_last_start;
+ 
+         char                 *x11_cookie;
+         gsize                 x11_cookie_size;
+@@ -613,6 +614,10 @@ gdm_display_manage (GdmDisplay *self)
+ 
+         g_debug ("GdmDisplay: Managing display: %s", self->priv->id);
+ 
++        if (self->priv->time_last_start == 0) {
++                self->priv->time_last_start = g_get_monotonic_time();
++        }
++
+         /* If not explicitly prepared, do it now */
+         if (self->priv->status == GDM_DISPLAY_UNMANAGED) {
+                 res = gdm_display_prepare (self);
+@@ -621,8 +626,6 @@ gdm_display_manage (GdmDisplay *self)
+                 }
+         }
+ 
+-        g_timer_start (self->priv->server_timer);
+-
+         if (g_strcmp0 (self->priv->session_class, "greeter") == 0) {
+                 if (GDM_DISPLAY_GET_CLASS (self)->manage != NULL) {
+                         GDM_DISPLAY_GET_CLASS (self)->manage (self);
+@@ -658,8 +661,6 @@ gdm_display_unmanage (GdmDisplay *self)
+ 
+         g_debug ("GdmDisplay: unmanage display");
+ 
+-        g_timer_stop (self->priv->server_timer);
+-
+         if (self->priv->user_access_file != NULL) {
+                 gdm_display_access_file_close (self->priv->user_access_file);
+                 g_object_unref (self->priv->user_access_file);
+@@ -672,9 +673,18 @@ gdm_display_unmanage (GdmDisplay *self)
+                 self->priv->access_file = NULL;
+         }
+ 
+-        elapsed = g_timer_elapsed (self->priv->server_timer, NULL);
+-        if (elapsed < 3) {
+-                g_warning ("GdmDisplay: display lasted %lf seconds", elapsed);
++        elapsed = (g_get_monotonic_time() - self->priv->time_last_start) / 1000000;
++        g_debug ("GdmDisplay: Elapsed time since last start: %lf", elapsed);
++        if (elapsed > 60) {
++                self->priv->num_failures = 0;
++                self->priv->time_last_start = g_get_monotonic_time();
++        } else {
++                self->priv->num_failures++;
++                g_debug ("GdmDisplay: Number of failures=%d", self->priv->num_failures);
++        }
++
++        if (self->priv->num_failures >= 5) {
++                g_warning ("GdmDisplay: Display %s failed 5 times in %lf seconds, no longer managing display", self->priv->id, elapsed);
+                 _gdm_display_set_status (self, GDM_DISPLAY_FAILED);
+         } else {
+                 _gdm_display_set_status (self, GDM_DISPLAY_UNMANAGED);
+@@ -1300,7 +1310,8 @@ gdm_display_init (GdmDisplay *self)
+         self->priv = GDM_DISPLAY_GET_PRIVATE (self);
+ 
+         self->priv->creation_time = time (NULL);
+-        self->priv->server_timer = g_timer_new ();
++        self->priv->time_last_start = 0;
++        self->priv->num_failures = 0;
+ }
+ 
+ static void
+@@ -1336,10 +1347,6 @@ gdm_display_finalize (GObject *object)
+                 g_object_unref (self->priv->user_access_file);
+         }
+ 
+-        if (self->priv->server_timer != NULL) {
+-                g_timer_destroy (self->priv->server_timer);
+-        }
+-
+         G_OBJECT_CLASS (gdm_display_parent_class)->finalize (object);
+ }
+ 
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0013-bind_textdomain_codeset.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,27 @@
+From db0314f3eae402e81b13fbb905bfc7d2b3fddb62 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Tue, 29 Dec 2015 18:59:56 -0800
+Subject: [PATCH 13/19] bind_textdomain_codeset
+
+Bug 15725357/SUNBT7060748 Some messages are not displayed correctly
+  in non-UTF-8 locale terminal environment
+Original date:2012-03-23 owner:pengwang type:bug bugster: 7060748
+---
+ daemon/main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/daemon/main.c b/daemon/main.c
+index f3329d0..924eb89 100644
+--- a/daemon/main.c
++++ b/daemon/main.c
+@@ -401,6 +401,7 @@ main (int    argc,
+ #endif
+ 
+         bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
++        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+         textdomain (GETTEXT_PACKAGE);
+         setlocale (LC_ALL, "");
+ 
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0014-logout-wtmpx.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,28 @@
+From dd025ea2459d84cfd30406a9a06c22a2ed0db266 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Tue, 29 Dec 2015 19:09:03 -0800
+Subject: [PATCH 14/19] logout wtmpx
+
+Bug 15814640/SUNBT7196841 When a user logout from GDM the username is
+  not logged
+Original date:2012-09-17 owner:abhijit type:bug bugster: 7196841
+---
+ daemon/gdm-session-record.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/daemon/gdm-session-record.c b/daemon/gdm-session-record.c
+index 590a1e8..349c36f 100644
+--- a/daemon/gdm-session-record.c
++++ b/daemon/gdm-session-record.c
+@@ -338,6 +338,8 @@ gdm_session_record_logout (GPid                  session_pid,
+         if (x11_display_name == NULL)
+                 x11_display_name = display_device;
+ 
++        record_set_username (&session_record, user_name);
++
+         g_debug ("Writing logout record");
+ 
+ #if defined(HAVE_UT_UT_TYPE)
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0015-display-etc-issue-file.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,29 @@
+From ce79e5360f1a7d4d9040d2ff098798269305917f Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Tue, 29 Dec 2015 19:16:58 -0800
+Subject: [PATCH 15/19] display /etc/issue file
+
+Bug 15774186/SUNBT7147307 gdm should be configured by default to display
+  /etc/issue
+Original date:2014-07-03 owner:abhijit type:bug bugdb: 15774186
+---
+ data/Init.in | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/data/Init.in b/data/Init.in
+index ec6fd39..8256edc 100644
+--- a/data/Init.in
++++ b/data/Init.in
+@@ -86,4 +86,9 @@ if [ "x$SETXKBMAP" != "x" ] ; then
+   fi
+ fi
+ 
++if [ -f /etc/issue ] ; then
++   /usr/bin/zenity --text-info --width=800 --height=300 \
++         --title="Security Message" --filename=/etc/issue
++fi
++
+ exit 0
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0016-solaris-xserver-path.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,31 @@
+From 202fe64993977f44f51b76264b2fbe4b2878ef7a Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Tue, 29 Dec 2015 21:08:59 -0800
+Subject: [PATCH 16/19] solaris xserver path
+
+On Solaris 11 & later, we just use /usr/bin, not /usr/X11/bin.
+Need to submit upstream.
+---
+ configure.ac | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/configure.ac b/configure.ac
+index cc58fbb..e819e5e 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1169,7 +1169,11 @@ dnl ---------------------------------------------------------------------------
+ # and /usr/X11 since they often symlink to each other, and configure
+ # should use the more stable location (the real directory) if possible.
+ #
+-if test -x /usr/X11/bin/Xserver; then
++if test -x /usr/bin/Xserver; then
++   X_PATH="/usr/bin"
++   X_SERVER_PATH="/usr/bin"
++   X_SERVER="/usr/bin/Xserver"
++elif test -x /usr/X11/bin/Xserver; then
+    X_PATH="/usr/X11/bin"
+    X_SERVER_PATH="/usr/X11/bin"
+    X_SERVER="/usr/X11/bin/Xserver"
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0017-libwrap-library-path.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,30 @@
+From abb394431714cb79959ca0b69cc9032c629d2bf0 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Wed, 30 Dec 2015 00:09:41 -0800
+Subject: [PATCH 17/19] libwrap library path
+
+Don't force use of -L/usr/sfw/lib -R/usr/sfw/lib when libwrap is found
+in the default path.  Need to send upstream.
+---
+ configure.ac | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/configure.ac b/configure.ac
+index e819e5e..d3bc4d0 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -725,7 +725,10 @@ else
+ 		echo "Not using TCP wrappers after all."
+ 		echo "*********************************************************"
+ 	else
+-		LIBWRAP_LIBS="-L/usr/sfw/lib -R/usr/sfw/lib -lwrap"
++		if test "x$LIBWRAP_PATH" = "x/usr/sfw/lib/libwrap.so" ; then
++			LIBWRAP_LIBS="-L/usr/sfw/lib -R/usr/sfw/lib"
++		fi
++		LIBWRAP_LIBS="$LIBWRAP_LIBS -lwrap"
+ 		AC_DEFINE(HAVE_TCPWRAPPERS, 1, [Define if have tcp wrappers])
+ 	fi
+   else
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0018-service-log.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,37 @@
+From c78c018393a9d32a97f38f99d5679d7ddef6c356 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Sun, 28 Aug 2016 14:57:46 -0700
+Subject: [PATCH 18/19] service log
+
+On Solaris, check for running under SMF control instead of for serviced
+to determine if we should log to syslog or stderr (for SMF to capture).
+---
+ common/gdm-log.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/common/gdm-log.c b/common/gdm-log.c
+index 03b7bcc..1303d5c 100644
+--- a/common/gdm-log.c
++++ b/common/gdm-log.c
+@@ -136,14 +136,16 @@ gdm_log_init (void)
+         initialized = TRUE;
+ #ifdef WITH_SYSTEMD
+         is_sd_booted = sd_booted () > 0;
++#elif defined(__sun)
++        is_sd_booted = (g_getenv("SMF_FMRI") != NULL);
+ #endif
+ 
+         g_log_set_default_handler (gdm_log_default_handler, NULL);
+ 
+-        /* Only set up syslog if !systemd, otherwise with systemd
++        /* Only set up syslog if !systemd/SMF, otherwise with systemd or SMF
+          * enabled, we keep the default GLib log handler which goes to
+          * stderr, which is routed to the appropriate place in the
+-         * systemd service file.
++         * systemd service file or SMF service log.
+          */
+         if (!is_sd_booted) {
+                 prg_name = g_get_prgname ();
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/patches/0019-no-wayland.patch	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,28 @@
+From da48e745aab98f0081bcc1ca7792b011cecfb237 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Sun, 28 Aug 2016 15:04:36 -0700
+Subject: [PATCH 19/19] no wayland
+
+Remove commented out entry in config file about enabling/disabling
+Wayland to avoid confusion, since we don't compile Wayland support
+into the binaries at all.
+---
+ data/gdm.conf-custom.in | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/data/gdm.conf-custom.in b/data/gdm.conf-custom.in
+index c9e2864..438d518 100644
+--- a/data/gdm.conf-custom.in
++++ b/data/gdm.conf-custom.in
+@@ -1,8 +1,6 @@
+ # GDM configuration storage
+ 
+ [daemon]
+-# Uncoment the line below to force the login screen to use Xorg
+-#WaylandEnable=false
+ 
+ [security]
+ 
+-- 
+2.7.4
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gnome/gdm/test/results-64.master	Mon Oct 31 18:25:15 2016 -0700
@@ -0,0 +1,155 @@
+make[1]: Entering directory '$(@D)'
+Making check in data
+make[2]: Entering directory '$(@D)/data'
+Making check in applications
+make[3]: Entering directory '$(@D)/data/applications'
+make[3]: Nothing to be done for 'check'.
+make[3]: Leaving directory '$(@D)/data/applications'
+Making check in autostart
+make[3]: Entering directory '$(@D)/data/autostart'
+make[3]: Nothing to be done for 'check'.
+make[3]: Leaving directory '$(@D)/data/autostart'
+Making check in pixmaps
+make[3]: Entering directory '$(@D)/data/pixmaps'
+Making check in 16x16
+make[4]: Entering directory '$(@D)/data/pixmaps/16x16'
+make[4]: Nothing to be done for 'check'.
+make[4]: Leaving directory '$(@D)/data/pixmaps/16x16'
+Making check in 32x32
+make[4]: Entering directory '$(@D)/data/pixmaps/32x32'
+make[4]: Nothing to be done for 'check'.
+make[4]: Leaving directory '$(@D)/data/pixmaps/32x32'
+Making check in 48x48
+make[4]: Entering directory '$(@D)/data/pixmaps/48x48'
+make[4]: Nothing to be done for 'check'.
+make[4]: Leaving directory '$(@D)/data/pixmaps/48x48'
+make[4]: Entering directory '$(@D)/data/pixmaps'
+make[4]: Nothing to be done for 'check-am'.
+make[4]: Leaving directory '$(@D)/data/pixmaps'
+make[3]: Leaving directory '$(@D)/data/pixmaps'
+make[3]: Entering directory '$(@D)/data'
+make[3]: Nothing to be done for 'check-am'.
+make[3]: Leaving directory '$(@D)/data'
+make[2]: Leaving directory '$(@D)/data'
+Making check in common
+make[2]: Entering directory '$(@D)/common'
+make[2]: Nothing to be done for 'check'.
+make[2]: Leaving directory '$(@D)/common'
+Making check in daemon
+make[2]: Entering directory '$(@D)/daemon'
+/usr/gnu/bin/make  check-am
+make[3]: Entering directory '$(@D)/daemon'
+make[3]: Nothing to be done for 'check-am'.
+make[3]: Leaving directory '$(@D)/daemon'
+make[2]: Leaving directory '$(@D)/daemon'
+Making check in libgdm
+make[2]: Entering directory '$(@D)/libgdm'
+/usr/gnu/bin/make  check-am
+make[3]: Entering directory '$(@D)/libgdm'
+make[3]: Nothing to be done for 'check-am'.
+make[3]: Leaving directory '$(@D)/libgdm'
+make[2]: Leaving directory '$(@D)/libgdm'
+Making check in gui
+make[2]: Entering directory '$(@D)/gui'
+Making check in simple-chooser
+make[3]: Entering directory '$(@D)/gui/simple-chooser'
+make[3]: Nothing to be done for 'check'.
+make[3]: Leaving directory '$(@D)/gui/simple-chooser'
+make[3]: Entering directory '$(@D)/gui'
+make[3]: Nothing to be done for 'check-am'.
+make[3]: Leaving directory '$(@D)/gui'
+make[2]: Leaving directory '$(@D)/gui'
+Making check in utils
+make[2]: Entering directory '$(@D)/utils'
+make[2]: Nothing to be done for 'check'.
+make[2]: Leaving directory '$(@D)/utils'
+Making check in po
+make[2]: Entering directory '$(@D)/po'
+rm -f missing notexist
+if [ -r missing -o -r notexist ]; then \
+  exit 1; \
+fi
+make[2]: Leaving directory '$(@D)/po'
+Making check in tests
+make[2]: Entering directory '$(@D)/tests'
+/usr/gnu/bin/make  check-TESTS
+make[3]: Entering directory '$(@D)/tests'
+make[4]: Entering directory '$(@D)/tests'
+PASS: m-common
+============================================================================
+Testsuite summary for gdm 3.18.2
+============================================================================
+# TOTAL: 1
+# PASS:  1
+# SKIP:  0
+# XFAIL: 0
+# FAIL:  0
+# XPASS: 0
+# ERROR: 0
+============================================================================
+make[4]: Leaving directory '$(@D)/tests'
+make[3]: Leaving directory '$(@D)/tests'
+make[2]: Leaving directory '$(@D)/tests'
+Making check in docs
+make[2]: Entering directory '$(@D)/docs'
+for lc in C ca cs de el en_GB es fr gl hu id it ko oc pt_BR ro ru sl sv te uk zh_CN; do \
+  if test -d "$lc"; \
+    then d=; \
+    xmlpath="$lc"; \
+  else \
+    d="$(SOURCE_DIR)/docs/"; \
+    xmlpath="$lc:$(SOURCE_DIR)/docs/$lc"; \
+  fi; \
+  for page in index.docbook legal.xml; do \
+    echo "xmllint --noout --noent --path $xmlpath --xinclude $d$lc/$page"; \
+    xmllint --noout --noent --path "$xmlpath" --xinclude "$d$lc/$page"; \
+  done; \
+done
+xmllint --noout --noent --path C:$(SOURCE_DIR)/docs/C --xinclude $(SOURCE_DIR)/docs/C/index.docbook
+xmllint --noout --noent --path C:$(SOURCE_DIR)/docs/C --xinclude $(SOURCE_DIR)/docs/C/legal.xml
+xmllint --noout --noent --path ca --xinclude ca/index.docbook
+xmllint --noout --noent --path ca --xinclude ca/legal.xml
+xmllint --noout --noent --path cs --xinclude cs/index.docbook
+xmllint --noout --noent --path cs --xinclude cs/legal.xml
+xmllint --noout --noent --path de --xinclude de/index.docbook
+xmllint --noout --noent --path de --xinclude de/legal.xml
+xmllint --noout --noent --path el --xinclude el/index.docbook
+xmllint --noout --noent --path el --xinclude el/legal.xml
+xmllint --noout --noent --path en_GB --xinclude en_GB/index.docbook
+xmllint --noout --noent --path en_GB --xinclude en_GB/legal.xml
+xmllint --noout --noent --path es --xinclude es/index.docbook
+xmllint --noout --noent --path es --xinclude es/legal.xml
+xmllint --noout --noent --path fr --xinclude fr/index.docbook
+xmllint --noout --noent --path fr --xinclude fr/legal.xml
+xmllint --noout --noent --path gl --xinclude gl/index.docbook
+xmllint --noout --noent --path gl --xinclude gl/legal.xml
+xmllint --noout --noent --path hu --xinclude hu/index.docbook
+xmllint --noout --noent --path hu --xinclude hu/legal.xml
+xmllint --noout --noent --path id --xinclude id/index.docbook
+xmllint --noout --noent --path id --xinclude id/legal.xml
+xmllint --noout --noent --path it --xinclude it/index.docbook
+xmllint --noout --noent --path it --xinclude it/legal.xml
+xmllint --noout --noent --path ko --xinclude ko/index.docbook
+xmllint --noout --noent --path ko --xinclude ko/legal.xml
+xmllint --noout --noent --path oc --xinclude oc/index.docbook
+xmllint --noout --noent --path oc --xinclude oc/legal.xml
+xmllint --noout --noent --path pt_BR --xinclude pt_BR/index.docbook
+xmllint --noout --noent --path pt_BR --xinclude pt_BR/legal.xml
+xmllint --noout --noent --path ro --xinclude ro/index.docbook
+xmllint --noout --noent --path ro --xinclude ro/legal.xml
+xmllint --noout --noent --path ru --xinclude ru/index.docbook
+xmllint --noout --noent --path ru --xinclude ru/legal.xml
+xmllint --noout --noent --path sl --xinclude sl/index.docbook
+xmllint --noout --noent --path sl --xinclude sl/legal.xml
+xmllint --noout --noent --path sv --xinclude sv/index.docbook
+xmllint --noout --noent --path sv --xinclude sv/legal.xml
+xmllint --noout --noent --path te --xinclude te/index.docbook
+xmllint --noout --noent --path te --xinclude te/legal.xml
+xmllint --noout --noent --path uk --xinclude uk/index.docbook
+xmllint --noout --noent --path uk --xinclude uk/legal.xml
+xmllint --noout --noent --path zh_CN --xinclude zh_CN/index.docbook
+xmllint --noout --noent --path zh_CN --xinclude zh_CN/legal.xml
+make[2]: Leaving directory '$(@D)/docs'
+make[2]: Entering directory '$(@D)'
+make[2]: Leaving directory '$(@D)'
+make[1]: Leaving directory '$(@D)'
--- a/components/meta-packages/incorporation-cache	Sat Sep 17 00:10:49 2016 -0700
+++ b/components/meta-packages/incorporation-cache	Mon Oct 31 18:25:15 2016 -0700
@@ -114,6 +114,4 @@
 consolidation/userland/userland-incorporation:library/speech/[email protected]
 consolidation/userland/userland-incorporation:library/xdg/[email protected]
 consolidation/userland/userland-incorporation:service/[email protected]
-consolidation/userland/userland-incorporation:system/display-manager/[email protected]
-consolidation/userland/userland-incorporation:system/display-manager/[email protected]
 consolidation/userland/userland-incorporation:terminal/[email protected]