Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37763931
en ru br
ALT Linux repos
S:1.0.8-alt2

Group :: Graphical desktop/Other
RPM: mint-display-manager

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: mint-display-manager-1.0.8-alt2.patch
Download


 config/Init.in                        |   2 +-
 config/PostSession.in                 |   5 +-
 config/Xsession.in                    | 226 +---------------------------------
 config/locale.alias                   |  12 +-
 config/mdm                            |  14 +--
 config/mdm-autologin                  |  13 +-
 config/mdm.conf-custom.in             |  19 +++
 config/mdm.conf.in                    |   2 +-
 configure.ac                          |   4 +-
 daemon/mdm-daemon-config-keys.h       |   1 +
 daemon/mdm-socket-protocol.h          |   4 +
 daemon/mdm.c                          |   8 ++
 daemon/slave.c                        |  59 +++++++--
 daemon/verify-crypt.c                 |   1 -
 daemon/verify-pam.c                   |   6 -
 daemon/verify-shadow.c                |   1 -
 gui/Makefile.am                       |   3 +
 gui/greeter/Makefile.am               |   1 +
 gui/greeter/greeter.c                 |  27 ++--
 gui/greeter/greeter_item_pam.c        |  44 ++++++-
 gui/mdmlogin.c                        |  32 ++++-
 gui/mdmsetup.desktop.in.in            |   4 +-
 gui/modules/AccessDwellMouseEvents.in |  14 +--
 gui/modules/AccessKeyMouseEvents.in   |   8 +-
 gui/modules/dwellmouselistener.c      |  22 ++++
 gui/modules/keymouselistener.c        |  27 +++-
 utils/mdmsetup-pam                    |  10 +-
 27 files changed, 265 insertions(+), 304 deletions(-)
diff --git a/config/Init.in b/config/Init.in
index d8d06ec..d1cfbc0 100644
--- a/config/Init.in
+++ b/config/Init.in
@@ -48,7 +48,7 @@ if [ "x$XMODMAP" != "x" ] ; then
   UNAME=`mdmwhich uname`
   PROCESSOR=`$UNAME -p`
   if [ "x$PROCESSOR" = "xsparc" ]; then
-    if $XMODMAP | /usr/bin/grep mod4 | /usr/bin/grep Alt > /dev/null 2>/dev/null
+    if $XMODMAP | /bin/grep mod4 | /bin/grep Alt > /dev/null 2>/dev/null
     then
       $XMODMAP -e "clear Mod1" \
                -e "clear Mod4" \
diff --git a/config/PostSession.in b/config/PostSession.in
index ea74ff7..2308c83 100755
--- a/config/PostSession.in
+++ b/config/PostSession.in
@@ -2,6 +2,7 @@
 
 PATH="@X_PATH@:$PATH:/bin:/usr/bin"
 OLD_IFS=$IFS
+XRESET=/etc/X11/Xreset
 
 mdmwhich () {
   COMMAND="$1"
@@ -20,8 +21,8 @@ mdmwhich () {
 }
 
 # Use common Xreset framework if it exist
-if [ -x /etc/X11/Xreset ] ; then
-  /etc/X11/Xreset
+if [ -x "$XRESET" ] ; then
+  $XRESET
 fi
 
 exit 0
diff --git a/config/Xsession.in b/config/Xsession.in
index 1387ad6..45918d6 100755
--- a/config/Xsession.in
+++ b/config/Xsession.in
@@ -1,235 +1,13 @@
 #!@XSESSION_SHELL@
-#
-# This is SORT OF LIKE an X session, but not quite.  You get a command as the
-# first argument (it could be multiple words, so run it with "eval").  As a
-# special case, the command can be:
-#  default - Run the appropriate Xclients startup (see the code below)
-#  custom - Run ~/.xsession and if that's not available run 'default'
-#
-# (Note that other arguments could also follow, but only the command one is
-# right now relevant and supported)
-#
-# The output is ALREADY redirected to .xsession-errors in MDM.  This way
-# .xsession-errors actually gets more output such as if the PreSession script
-# is failing.  This also prevents DoS attacks if some app in the users session
-# can be prodded to dump lots of stuff on the stdout/stderr.  We wish to be
-# robust don't we?  In case you wish to use an existing script for other DM's,
-# you can just not redirect when MDMSESSION is set.  MDMSESSION will always
-# be set from mdm.
-#
-# Also note that this is not run as a login shell, this is just executed.
-# This is why we source the profile files below.
-#
-# based on:
-# $XConsortium: Xsession /main/10 1995/12/18 18:21:28 gildea $
 
 command="$@"
 
-# this will go into the .xsession-errors along with all other echo's
-# good for debugging where things went wrong
-echo "$0: Beginning session setup..."
-
-# First read /etc/profile and .profile
-test -f /etc/profile && . /etc/profile
-test -f "$HOME/.profile" && . "$HOME/.profile"
-# Second read /etc/xprofile and .xprofile for X specific setup
-test -f /etc/xprofile && . /etc/xprofile
-test -f "$HOME/.xprofile" && . "$HOME/.xprofile"
-
-# Translation stuff
-if [ -x "@libexecdir@/mdmtranslate" ] ; then
-  mdmtranslate="@libexecdir@/mdmtranslate"
-else
-  mdmtranslate=
-fi
-
-# Note that this should only go to zenity dialogs which always expect utf8
-gettextfunc () {
-  if [ "x$mdmtranslate" != "x" ] ; then
-    "$mdmtranslate" --utf8 "$1"
-  else
-    echo "$1"
-  fi
-}
-
-OLD_IFS=$IFS
-
-mdmwhich () {
-  COMMAND="$1"
-  OUTPUT=
-  IFS=:
-  for dir in $PATH
-  do
-    if test -x "$dir/$COMMAND" ; then
-      if test "x$OUTPUT" = "x" ; then
-        OUTPUT="$dir/$COMMAND"
-      fi
-    fi
-  done
-  IFS=$OLD_IFS 
-  echo "$OUTPUT"
-}
-
-zenity=`mdmwhich zenity`
-
-# Note: ~/.xsession-errors is now done in the daemon so that it
-# works for ALL sessions (except ones named 'Failsafe')
-
-# clean up after xbanner
-freetemp=`mdmwhich freetemp`
-if [ -n "$freetemp" ] ; then
-	"$freetemp"
+if [ -z "$command" ] ; then
+   command=failsafe
 fi
 
-userresources="$HOME/.Xresources"
-usermodmap="$HOME/.Xmodmap"
-userxkbmap="$HOME/.Xkbmap"
-
-sysresources=/etc/X11/Xresources 
-sysmodmap=/etc/X11/Xmodmap 
-sysxkbmap=/etc/X11/Xkbmap
-
-rh6sysresources=/etc/X11/xinit/Xresources 
-rh6sysmodmap=/etc/X11/xinit/Xmodmap 
-
-# merge in defaults
-if [ -f "$rh6sysresources" ]; then
-    xrdb -merge "$rh6sysresources"
-fi
-
-if [ -f "$sysresources" ]; then
-    xrdb -merge "$sysresources"
-fi
-
-if [ -f "$userresources" ]; then
-    xrdb -merge "$userresources"
-fi
-
-# merge in keymaps
-if [ -f "$sysxkbmap" ]; then
-    setxkbmap `cat "$sysxkbmap"`
-    XKB_IN_USE=yes
-fi
-
-if [ -f "$userxkbmap" ]; then
-    setxkbmap `cat "$userxkbmap"`
-    XKB_IN_USE=yes
-fi
-
-#
-# Eeek, this seems like too much magic here
-#
-if [ -z "$XKB_IN_USE" -a ! -L /etc/X11/X ]; then
-    if grep '^exec.*/Xsun' /etc/X11/X > /dev/null 2>&1 && [ -f /etc/X11/XF86Config ]; then
-       xkbsymbols=`sed -n -e 's/^[     ]*XkbSymbols[   ]*"\(.*\)".*$/\1/p' /etc/X11/XF86Config`
-       if [ -n "$xkbsymbols" ]; then
-           setxkbmap -symbols "$xkbsymbols"
-           XKB_IN_USE=yes
-       fi
-    fi
-fi
-
-# xkb and xmodmap don't play nice together
-if [ -z "$XKB_IN_USE" ]; then
-    if [ -f "$rh6sysmodmap" ]; then
-       xmodmap "$rh6sysmodmap"
-    fi
-
-    if [ -f "$sysmodmap" ]; then
-       xmodmap "$sysmodmap"
-    fi
-
-    if [ -f "$usermodmap" ]; then
-       xmodmap "$usermodmap"
-    fi
-fi
-
-unset XKB_IN_USE
-
-# Normalize languages, some places/distros screw us up in /etc/profile,
-# so in case the user did select a language
-if [ -n "$MDM_LANG" ]; then
-  LANG="$MDM_LANG"
-  export LANG
-
-  if [ -n "$LC_ALL" ]; then
-    if [ "$LC_ALL" != "$LANG" ]; then
-      LC_ALL="$LANG"
-    fi
-  else
-    unset LC_ALL
-  fi
-
-  if [ -n "$LANGUAGE" ]; then
-    if [ "$LANGUAGE" != "$LANG" ]; then
-      LANGUAGE="$LANG"
-    fi
-  else
-    unset LANGUAGE
-  fi
-
-  if [ -n "$LINGUAS" ]; then
-    if [ "$LINGUAS" != "$LANG" ]; then
-      LINGUAS="$LANG"
-    fi
-  else
-    unset LINGUAS
-  fi
-fi
-
-# 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
-
-if [ "x$command" = "xcustom" ] ; then
-  if [ -x "$HOME/.xsession" ]; then
-    command="$HOME/.xsession"
-  else
-    echo "$0: Cannot find ~/.xsession will try the default session"
-    command="default"
-  fi
-fi
-
-if [ "x$command" = "xdefault" ] ; then
-  if [ -x "$HOME/.Xclients" ]; then
-    command="$HOME/.Xclients"
-  elif [ -x /etc/X11/xinit/Xclients ]; then
-    command="/etc/X11/xinit/Xclients"
-  elif [ -x /etc/X11/Xclients ]; then
-    command="/etc/X11/Xclients"
-  else
-    if [ -n "$zenity" ] ; then
-	disptext=`gettextfunc "System has no Xclients file, so starting a failsafe xterm session.  Windows will have focus only if the mouse pointer is above them.  To get out of this mode type 'exit' in the window."`
-      "$zenity" --info --text "$disptext"
-    else
-      echo "$0: Cannot find Xclients"
-    fi
-    exec xterm -geometry 80x24+0+0
-  fi
-fi
-
-# add ssh-agent if found
-sshagent="`mdmwhich ssh-agent`"
-if [ -n "$sshagent" ] && [ -x "$sshagent" ] && [ -z "$SSH_AUTH_SOCK" ]; then
-    command="$sshagent -- $command"
-elif [ -z "$sshagent" ] ; then
-    echo "$0: ssh-agent not found!"
-fi
-
-echo "$0: Setup done, will execute: $command"
-
 eval exec $command
 
 echo "$0: Executing $command failed, will run xterm"
 
-if [ -n "$zenity" ] ; then
-	disptext=`gettextfunc "Failed to start the session, so starting a failsafe xterm session.  Windows will have focus only if the mouse pointer is above them.  To get out of this mode type 'exit' in the window."`
-	"$zenity" --info --text "$disptext"
-fi
-
 exec xterm -geometry 80x24+0+0
diff --git a/config/locale.alias b/config/locale.alias
index 475218a..44599a2 100644
--- a/config/locale.alias
+++ b/config/locale.alias
@@ -25,8 +25,8 @@ Armenian		hy_AM.UTF-8,hy_AM
 Azerbaijani		az_AZ.UTF-8,az_AZ
 Azerbaijani(Iran)	az_IR.UTF-8,az_IR
 Basque			eu_ES.UTF-8,eu_ES
-Belarusian		be_BY.UTF-8,be_BY
-Belarusian(Latin)	be_BY.UTF-8@latin,be_BY@latin
+Belarusian(UTF-8)	be_BY.UTF-8,be_BY
+Belarusian(CP1251)	be_BY.CP1251,be_BY
 Bengali			bn_BD.UTF-8,bn_BD
 Bengali(India)		bn_IN.UTF-8,bn_IN
 Bosnian			bs_BA.UTF-8,bs_BA
@@ -103,7 +103,9 @@ Portuguese(Brazilian)	pt_BR.UTF-8,pt_BR
 Portuguese		pt_PT.UTF-8,pt_PT
 Punjabi			pa_IN.UTF-8,pa_IN
 Romanian		ro_RO.UTF-8,ro_RO
-Russian			ru_RU.UTF-8,ru_RU
+Russian(UTF-8)		ru_RU.UTF-8,ru_RU
+Russian(KOI8-R)		ru_RU.KOI8-R,ru_RU
+Russian(CP1251)		ru_RU.CP1251,ru_RU
 Serbian			sr_CS.UTF-8,sr_CS,sr_YU@cyrillic,sr_YU
 Serbian(Montenegro)	sr_ME.UTF-8
 Serbian(Serbia)		sr_RS.UTF-8
@@ -136,7 +138,9 @@ Tamil			ta_IN.UTF-8,ta_IN
 Telugu			te_IN.UTF-8,te_IN
 Thai			th_TH.UTF-8,th_TH
 Turkish			tr_TR.UTF-8,tr_TR
-Ukrainian		uk_UA.UTF-8,uk_UA
+Ukrainian(UTF-8)	uk_UA.UTF-8,uk_UA
+Ukrainian(KOI8-U)	uk_UA.KOI8-U,uk_UA
+Ukrainian(CP1251)	uk_UA.CP1251,uk_UA
 Uzbek			uz_UZ.UTF-8,uz_UZ
 Uzbek(Latin)		uz_UZ.UTF-8@Latn,uz_UZ@Latn
 Vietnamese		vi_VN.UTF-8,vi_VN
diff --git a/config/mdm b/config/mdm
index 4b2bbae..b83f5f4 100644
--- a/config/mdm
+++ b/config/mdm
@@ -1,8 +1,8 @@
 #%PAM-1.0
-auth       required	pam_env.so
-auth       required	pam_stack.so service=system-auth
-auth       required	pam_nologin.so
-account    required	pam_stack.so service=system-auth
-password   required	pam_stack.so service=system-auth
-session    required	pam_stack.so service=system-auth
-session    optional     pam_console.so
+auth		required	pam_shells.so
+auth		required	pam_succeed_if.so quiet uid ne 0
+auth		include		common-login
+account		include		common-login
+password	include		common-login
+session		substack	common-login
+session		optional	pam_console.so
diff --git a/config/mdm-autologin b/config/mdm-autologin
index 7f819da..8e84472 100644
--- a/config/mdm-autologin
+++ b/config/mdm-autologin
@@ -1,8 +1,7 @@
 #%PAM-1.0
-auth       required	pam_env.so
-auth       required	pam_nologin.so
-auth       required	pam_permit.so
-account    required	pam_stack.so service=system-auth
-password   required	pam_stack.so service=system-auth
-session    required	pam_stack.so service=system-auth
-session    optional     pam_console.so
+auth		required	pam_nologin.so
+auth		required	pam_permit.so
+account		include		common-login
+password	include		common-login
+session		substack	common-login
+session		optional	pam_console.so
diff --git a/config/mdm.conf-custom.in b/config/mdm.conf-custom.in
index 068d450..891b0fd 100644
--- a/config/mdm.conf-custom.in
+++ b/config/mdm.conf-custom.in
@@ -53,14 +53,33 @@
 # Have fun!
 
 [daemon]
+LogDir=/var/log/mdm
+SessionDesktopDir=/etc/X11/sessions/
+Greeter=/usr/lib/mdm/mdmgreeter
+RemoteGreeter=/usr/lib/mdm/mdmgreeter
 
 [security]
+AllowRoot=false
 
 [xdmcp]
+Enable=false
 
 [gui]
 
 [greeter]
+TitleBar=false
+GlobalFaceDir=/usr/share/design-current/faces/
+DefaultFace=/usr/share/design-current/faces/default.png
+Logo=/usr/share/design/desktop/icons/large/altlinux.png
+MinimalUID=500
+LockPosition=true
+BackgroundColor=#666699
+ShowGnomeFailsafeSession=false
+ShowXtermFailsafeSession=false
+Use24Clock=true
+GraphicalTheme=happygnome-list
+GraphicalThemes=happygnome-list
+IncludeAll=true
 
 [chooser]
 
diff --git a/config/mdm.conf.in b/config/mdm.conf.in
index 3eeaa59..b1dd147 100644
--- a/config/mdm.conf.in
+++ b/config/mdm.conf.in
@@ -412,7 +412,7 @@ IncludeAll=true
 # File which contains the locale we show to the user.  Likely you want to use
 # the one shipped with MDM and edit it.  It is not a standard locale.alias
 # file, although MDM will be able to read a standard locale.alias file as well.
-LocaleFile=/etc/mdm/locale.conf
+#LocaleFile=/etc/X11/mdm/locale.alias
 # Logo shown in the standard greeter.
 Logo=@pixmapdir@/mdmLogo.xpm
 # Logo shown on file chooser button in mdmsetup (do not modify this value).
diff --git a/configure.ac b/configure.ac
index 2b9443e..5a1c34c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1090,8 +1090,8 @@ case "$host" in
 	;;
 *)
 	HOST_MDM_USER_PATH="/bin:/usr/bin"
-	HOST_HALT_COMMAND="/usr/bin/poweroff;/sbin/poweroff;/sbin/shutdown -h now;/usr/sbin/shutdown -h now"
-	HOST_REBOOT_COMMAND="/usr/bin/reboot;/sbin/reboot;/sbin/shutdown -r now;/usr/sbin/shutdown -r now"
+	HOST_HALT_COMMAND="/usr/sbin/gdm-termok-command /sbin/poweroff;/usr/sbin/gdm-termok-command /sbin/shutdown -h now;/sbin/poweroff;/sbin/shutdown -h now"
+	HOST_REBOOT_COMMAND="/usr/sbin/gdm-termok-command /sbin/reboot;/usr/sbin/gdm-termok-command /sbin/shutdown -r now;/sbin/reboot;/sbin/shutdown -r now"
 	HOST_SUSPEND_COMMAND=""
 	HOST_XSESSION_SHELL=/bin/sh
 	HOST_SOUND_PROGRAM=/usr/bin/play
diff --git a/daemon/mdm-daemon-config-keys.h b/daemon/mdm-daemon-config-keys.h
index 1713e08..9b93415 100644
--- a/daemon/mdm-daemon-config-keys.h
+++ b/daemon/mdm-daemon-config-keys.h
@@ -245,6 +245,7 @@ G_BEGIN_DECLS
 #define MDM_NOTIFY_SOFT_RESTART_SERVERS "SOFT_RESTART_SERVERS"
 #define MDM_NOTIFY_GO "GO"
 #define MDM_NOTIFY_TWIDDLE_POINTER "TWIDDLE_POINTER"
+#define MDM_NOTIFY_RESET "RESET"
 
 G_END_DECLS
 
diff --git a/daemon/mdm-socket-protocol.h b/daemon/mdm-socket-protocol.h
index 9b4231a..28b4cf5 100644
--- a/daemon/mdm-socket-protocol.h
+++ b/daemon/mdm-socket-protocol.h
@@ -41,6 +41,7 @@
 #define MDM_PROMPT     'N'
 #define MDM_SESS       'G'
 #define MDM_LANG       '&'
+#define MDM_A11Y       'Z'
 #define MDM_SSESS      'C'
 #define MDM_SLANG      'R'
 #define MDM_SETLANG    'L'
@@ -155,6 +156,9 @@
 #define MDM_SOP_SHOW_QUESTION_DIALOG "SHOW_QUESTION_DIALOG"  /* show the question dialog from daemon */
 #define MDM_SOP_SHOW_ASKBUTTONS_DIALOG "SHOW_ASKBUTTON_DIALOG"  /* show the askbutton dialog from daemon */
 
+/* Reset any in progress authentication conversations */
+#define MDM_SOP_CANCEL_LOGIN_REQUESTS "CANCEL_LOGIN_REQUESTS" /* no arguments */
+
 
 /* Ack for a slave message */
 /* Note that an extra response can follow an 'ack' */
diff --git a/daemon/mdm.c b/daemon/mdm.c
index c3893be..8dae607 100644
--- a/daemon/mdm.c
+++ b/daemon/mdm.c
@@ -2610,6 +2610,14 @@ mdm_handle_message (MdmConnection *conn, const char *msg, gpointer data)
 				     TRUE /* handled */,
 				     FALSE /* chooser */,
 				     NULL, 0, NULL, NULL, NULL);
+} else if (strcmp (msg, MDM_SOP_CANCEL_LOGIN_REQUESTS) == 0) {
+		GSList *li, *displays = mdm_daemon_config_get_display_list ();
+		for (li = displays; li != NULL; li = li->next) {
+			MdmDisplay *d = li->data;
+			if (!d->logged_in) {
+				send_slave_command (d, MDM_NOTIFY_RESET);
+			}
+		}
 	} else if (strncmp (msg, "opcode="MDM_SOP_SHOW_ERROR_DIALOG,
 			    strlen ("opcode="MDM_SOP_SHOW_ERROR_DIALOG)) == 0) {
 		char **list;
diff --git a/daemon/slave.c b/daemon/slave.c
index 964f5f3..fc26703 100644
--- a/daemon/slave.c
+++ b/daemon/slave.c
@@ -182,6 +182,12 @@ static int mdm_normal_runlevel         = -1;
 static pid_t extra_process             = 0;
 static int extra_status                = 0;
 
+/* a dup of the other side of greeter_fd_in so that
+ * the slave can talk to itself from its sig handler
+ * using the greeter ipc mechanism
+ */
+static int slave_fd_out = -1;
+
 #ifdef HAVE_TSOL
 static gboolean have_suntsol_extension = FALSE;
 #endif
@@ -659,7 +665,7 @@ ignore_xerror_handler (Display *disp, XErrorEvent *evt)
 }
 
 static void
-whack_greeter_fds (void)
+whack_greeter_and_slave_fds (void)
 {
 	if (greeter_fd_out > 0)
 		VE_IGNORE_EINTR (close (greeter_fd_out));
@@ -667,6 +673,9 @@ whack_greeter_fds (void)
 	if (greeter_fd_in > 0)
 		VE_IGNORE_EINTR (close (greeter_fd_in));
 	greeter_fd_in = -1;
+	if (slave_fd_out > 0)
+		VE_IGNORE_EINTR (close (slave_fd_out));
+	slave_fd_out = -1;
 }
 
 static void
@@ -1152,7 +1161,7 @@ mdm_slave_whack_greeter (void)
 
 	d->greetpid = 0;
 
-	whack_greeter_fds ();
+	whack_greeter_and_slave_fds ();
 
 	mdm_slave_send_num (MDM_SOP_GREETPID, 0);
 
@@ -2076,7 +2085,7 @@ restart_the_greeter (void)
 
 		d->greetpid = 0;
 
-		whack_greeter_fds ();
+		whack_greeter_and_slave_fds ();
 
 		mdm_slave_send_num (MDM_SOP_GREETPID, 0);
 	}
@@ -2313,6 +2322,12 @@ mdm_slave_wait_for_login (void)
 			break;
 		}
 
+		if (do_cancel) {
+			mdm_debug ("canceling...");
+			mdm_slave_greeter_ctl_no_ret (MDM_RESETOK, "");
+			continue;
+		}
+
 		if (login_user == NULL) {
 			const char *failuresound = mdm_daemon_config_get_value_string (MDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE);
 
@@ -2946,10 +2961,10 @@ mdm_slave_greeter (void)
 
 	default:
 		VE_IGNORE_EINTR (close (pipe1[0]));
-		VE_IGNORE_EINTR (close (pipe2[1]));
 
-		whack_greeter_fds ();
+		whack_greeter_and_slave_fds ();
 
+		slave_fd_out = pipe2[1];
 		greeter_fd_out = pipe1[1];
 		greeter_fd_in = pipe2[0];
 
@@ -3651,6 +3666,7 @@ session_child_run (struct passwd *pwent,
 		   const char *session,
 		   const char *save_session,
 		   const char *language,
+		   const char *a11y_ats,
 		   const char *gnome_session,
 		   gboolean usrcfgok,
 		   gboolean savesess,
@@ -3749,6 +3765,9 @@ session_child_run (struct passwd *pwent,
 	}
 #endif
 	g_setenv ("PWD", home_dir, TRUE);
+	if (a11y_ats != NULL) {
+		g_setenv ("MDM_ATS", a11y_ats, TRUE);
+	}
 	g_setenv ("MDMSESSION", session, TRUE);
 	g_setenv ("DESKTOP_SESSION", session, TRUE);
 	g_setenv ("SHELL", pwent->pw_shell, TRUE);
@@ -4542,6 +4561,7 @@ mdm_slave_session_start (void)
 	struct passwd *pwent;
 	const char *home_dir = NULL;
 	char *save_session = NULL, *session = NULL, *language = NULL, *usrsess, *usrlang;
+	char *a11y_ats = NULL;
 	char *gnome_session = NULL;
 #ifdef WITH_CONSOLE_KIT
 	char *ck_session_cookie;
@@ -4710,9 +4730,19 @@ mdm_slave_session_start (void)
 			g_free (usrlang);
 			return;
 		}
+
+		a11y_ats = mdm_slave_greeter_ctl (MDM_A11Y, NULL);
+		if (a11y_ats != NULL &&
+		    strcmp (a11y_ats, MDM_RESPONSE_CANCEL) == 0) {
+			mdm_debug ("User canceled login");
+			mdm_verify_cleanup (d);
+			session_started = FALSE;
+			return;
+		}
 	} else {
 		session = g_strdup (usrsess);
 		language = g_strdup (usrlang);
+		a11y_ats = NULL;
 	}
 
 	tmp = mdm_strip_extension (session, ".desktop");
@@ -4733,10 +4763,15 @@ mdm_slave_session_start (void)
 		language = NULL;
 	}
 
+	if G_LIKELY (ve_string_empty (a11y_ats)) {
+		g_free (a11y_ats);
+		a11y_ats = NULL;
+	}
+
 	g_free (usrsess);
 
-	mdm_debug ("Initial setting: session: '%s' language: '%s'\n",
-		   session, ve_sure_string (language));
+	mdm_debug ("Initial setting: session: '%s' language: '%s'i ATs enabled in mdm: '%s'\n",
+		   session, ve_sure_string (language), ve_sure_string (a11y_ats));
 
 	/* save this session as the users session */
 	save_session = g_strdup (session);
@@ -4928,6 +4963,7 @@ mdm_slave_session_start (void)
 					   session,
 					   save_session,
 					   lang,
+					   a11y_ats,
 					   gnome_session,
 					   usrcfgok,
 					   savesess,
@@ -5320,7 +5356,7 @@ mdm_slave_child_handler (int sig)
 
 				greet = FALSE;
 				d->greetpid = 0;
-				whack_greeter_fds ();
+				whack_greeter_and_slave_fds ();
 				mdm_slave_send_num (MDM_SOP_GREETPID, 0);
 
 				do_restart_greeter = TRUE;
@@ -5332,7 +5368,7 @@ mdm_slave_child_handler (int sig)
 				continue;
 			}
 
-			whack_greeter_fds ();
+			whack_greeter_and_slave_fds ();
 
 			/* if greet is TRUE, then the greeter died outside of our
 			 * control really, so clean up and die, something is wrong
@@ -5475,6 +5511,11 @@ mdm_slave_handle_usr2_message (void)
 				mdm_wait_for_go = FALSE;
 			} else if (strcmp (&s[1], MDM_NOTIFY_TWIDDLE_POINTER) == 0) {
 				mdm_twiddle_pointer (d);
+			} else if (strcmp (&s[1], MDM_NOTIFY_RESET) == 0) {
+				if (!d->logged_in) {
+					mdm_fdprintf (slave_fd_out, "%c%c%c\n",
+						      STX, BEL, MDM_INTERRUPT_CANCEL);
+				}
 			}
 		} else if (s[0] == MDM_SLAVE_NOTIFY_RESPONSE) {
 			mdm_got_ack = TRUE;
diff --git a/daemon/verify-crypt.c b/daemon/verify-crypt.c
index cff8e1f..68d533c 100644
--- a/daemon/verify-crypt.c
+++ b/daemon/verify-crypt.c
@@ -122,7 +122,6 @@ mdm_verify_user (MdmDisplay *d,
 	authenticate_again:
 		/* Ask for the user's login */
 		mdm_verify_select_user (NULL);
-		mdm_slave_greeter_ctl_no_ret (MDM_MSG, _("Please enter your username"));
 		login = mdm_slave_greeter_ctl (MDM_PROMPT, _("Username:"));
 		if (login == NULL ||
 		    mdm_slave_greeter_check_interruption ()) {
diff --git a/daemon/verify-pam.c b/daemon/verify-pam.c
index a95fee8..dc1a262 100644
--- a/daemon/verify-pam.c
+++ b/daemon/verify-pam.c
@@ -556,12 +556,6 @@ mdm_verify_pam_conv (int num_msg,
 		case PAM_PROMPT_ECHO_ON:
 			if (strcmp (m, _("Username:")) == 0) {
 				if (ve_string_empty (selected_user)) {
-					/* this is an evil hack, but really there is no way we'll
-					   know this is a username prompt.  However we SHOULD NOT
-					   rely on this working.  The pam modules can set their
-					   prompt to whatever they wish to */
-					mdm_slave_greeter_ctl_no_ret
-						(MDM_MSG, _("Please enter your username"));
 					s = mdm_slave_greeter_ctl (MDM_PROMPT, m);
 					/* this will clear the message */
 					mdm_slave_greeter_ctl_no_ret (MDM_MSG, "");
diff --git a/daemon/verify-shadow.c b/daemon/verify-shadow.c
index d93e998..ac81f80 100644
--- a/daemon/verify-shadow.c
+++ b/daemon/verify-shadow.c
@@ -124,7 +124,6 @@ mdm_verify_user (MdmDisplay *d,
 	authenticate_again:
 		/* Ask for the user's login */
 		mdm_verify_select_user (NULL);
-		mdm_slave_greeter_ctl_no_ret (MDM_MSG, _("Please enter your username"));
 		login = mdm_slave_greeter_ctl (MDM_PROMPT, _("Username:"));
 		if (login == NULL ||
 		    mdm_slave_greeter_check_interruption ()) {
diff --git a/gui/Makefile.am b/gui/Makefile.am
index 1c72b3d..b8c7b2e 100644
--- a/gui/Makefile.am
+++ b/gui/Makefile.am
@@ -123,6 +123,7 @@ mdmchooser_LDADD = \
 	$(XINERAMA_LIBS)	\
 	$(X_LIBS)		\
 	$(XDMCP_LIBS)		\
+	-lXau			\
 	-lX11			\
 	$(NULL)
 
@@ -142,6 +143,7 @@ mdmlogin_LDADD = \
 	$(X_EXTRA_LIBS)		\
 	$(XINERAMA_LIBS)	\
 	$(X_LIBS)		\
+	-lXau			\
 	-lX11			\
 	$(NULL)
 
@@ -180,6 +182,7 @@ mdmphotosetup_LDADD = \
 	$(INTLLIBS)		\
 	$(EXTRA_SOCKET_LIB)	\
 	$(EXTRA_NSL_LIB)	\
+	-lXau			\
 	-lX11			\
 	$(top_builddir)/common/libmdmcommon.a \
 	$(NULL)
diff --git a/gui/greeter/Makefile.am b/gui/greeter/Makefile.am
index ec33bc3..f2db4ae 100644
--- a/gui/greeter/Makefile.am
+++ b/gui/greeter/Makefile.am
@@ -91,6 +91,7 @@ mdmgreeter_LDADD = \
 	$(X_EXTRA_LIBS)		\
 	$(XINERAMA_LIBS)	\
 	$(X_LIBS)		\
+	-lXau			\
 	-lX11			
 
 EXTRA_DIST = \
diff --git a/gui/greeter/greeter.c b/gui/greeter/greeter.c
index e0aeda1..065d202 100644
--- a/gui/greeter/greeter.c
+++ b/gui/greeter/greeter.c
@@ -224,7 +224,6 @@ process_operation (guchar       op_code,
     GtkWidget *dlg;
     char *tmp;
     char *session;
-    GreeterItemInfo *conversation_info;
     static GnomeCanvasItem *disabled_cover = NULL;
     gint lookup_status = SESSION_LOOKUP_SUCCESS;
     gchar *firstmsg = NULL;
@@ -391,6 +390,19 @@ process_operation (guchar       op_code,
 	g_free (session);
 	break;
 
+    case MDM_A11Y:
+    {
+	const char *ats_launched;
+	/* print out the assistive technologies that we've started for the user */
+	ats_launched = g_getenv ("MDM_ATS");
+	if (ats_launched != NULL)
+		printf ("%c%s\n", STX, ats_launched);
+	else
+		printf ("%c\n", STX);
+	fflush (stdout);
+	break;
+    }
+
     case MDM_LANG:
 	mdm_lang_op_lang (args);
 	break;
@@ -428,16 +440,9 @@ process_operation (guchar       op_code,
 
 	first_prompt = TRUE;
 
-	conversation_info = greeter_lookup_id ("pam-conversation");
-	
-	if (conversation_info)
-	  {
-	    tmp = ve_locale_to_utf8 (args);
-	    g_object_set (G_OBJECT (conversation_info->item),
-			  "text", tmp,
-			  NULL);
-	    g_free (tmp);
-	  }
+        greeter_item_ulist_unset_selected_user ();
+        greeter_item_pam_prompt ("", PW_ENTRY_SIZE, TRUE);
+        greeter_item_pam_message ("");
 
 	printf ("%c\n", STX);
 	fflush (stdout);
diff --git a/gui/greeter/greeter_item_pam.c b/gui/greeter/greeter_item_pam.c
index fce9589..9e52c87 100644
--- a/gui/greeter/greeter_item_pam.c
+++ b/gui/greeter/greeter_item_pam.c
@@ -47,6 +47,7 @@ gchar *greeter_current_user = NULL;
 gboolean require_quarter = FALSE;
 
 extern gboolean greeter_probably_login_prompt;
+static gboolean using_fallback_message = FALSE;
 extern GtkButton *gtk_ok_button;
 extern GtkButton *gtk_start_again_button;
 
@@ -252,13 +253,35 @@ greeter_item_pam_prompt (const char *message,
 			 int         entry_len,
 			 gboolean    entry_visible)
 {
+  GreeterItemInfo *message_info;
   GreeterItemInfo *conversation_info;
   GreeterItemInfo *entry_info;
   GtkWidget *entry;
 
+  message_info = greeter_lookup_id ("pam-message");
   conversation_info = greeter_lookup_id ("pam-prompt");
   entry_info = greeter_lookup_id ("user-pw-entry");
 
+  if (strcmp (message, _("Username:")) == 0 && message_info)
+    {
+      gchar *text;
+      text = NULL;
+      g_object_get (G_OBJECT (message_info->item),
+                    "text", &text,
+                    NULL);
+      if (ve_string_empty (text))
+        {
+          set_text (message_info, _("Please enter your username"));
+          using_fallback_message = TRUE;
+        }
+      g_free (text);
+    }
+  else if (using_fallback_message)
+    {
+      set_text (message_info, "");
+      using_fallback_message = FALSE;
+    }
+
   if (conversation_info)
     {
       set_text (conversation_info, message);
@@ -294,11 +317,20 @@ greeter_item_pam_prompt (const char *message,
     {
       entry = GNOME_CANVAS_WIDGET (entry_info->item)->widget;
       
-      gtk_entry_set_visibility (GTK_ENTRY (entry), entry_visible);
-      gtk_widget_set_sensitive (GTK_WIDGET (entry), TRUE);
-      gtk_entry_set_max_length (GTK_ENTRY (entry), entry_len);
-      gtk_entry_set_text (GTK_ENTRY (entry), "");
-      gtk_widget_grab_focus (entry);
+      if (message != NULL && strcmp (message, "") != 0)
+        {
+          gtk_entry_set_visibility (GTK_ENTRY (entry), entry_visible);
+          gtk_widget_set_sensitive (GTK_WIDGET (entry), TRUE);
+          gtk_entry_set_max_length (GTK_ENTRY (entry), entry_len);
+          gtk_entry_set_text (GTK_ENTRY (entry), "");
+          gtk_widget_grab_focus (entry);
+        }
+      else
+        {
+          gtk_entry_set_visibility (GTK_ENTRY (entry), entry_visible);
+          gtk_entry_set_text (GTK_ENTRY (entry), "...");
+          gtk_widget_set_sensitive (GTK_WIDGET (entry), FALSE);
+        }
     }
 
   messages_to_give = FALSE;
@@ -323,6 +355,7 @@ greeter_item_pam_message (const char *message)
        * we try to collect them until the next prompt or reset or
        * whatnot */
       if ( ! replace_msg &&
+	   ! using_fallback_message &&
 	   /* empty message is for clearing */
 	   ! ve_string_empty (message))
 	{
@@ -342,6 +375,7 @@ greeter_item_pam_message (const char *message)
         set_text (message_info, message);
     }
   replace_msg = FALSE;
+  using_fallback_message = FALSE;
 }
 
 
diff --git a/gui/mdmlogin.c b/gui/mdmlogin.c
index 33bad34..fb5c341 100644
--- a/gui/mdmlogin.c
+++ b/gui/mdmlogin.c
@@ -164,6 +164,7 @@ extern gchar *default_session;
 extern const gchar *current_session;
 extern gboolean session_dir_whacked_out;
 extern gint mdm_timed_delay;
+static gboolean using_fallback_message = FALSE;
 
 static gboolean first_prompt = TRUE;
 
@@ -1351,9 +1352,20 @@ process_operation (guchar       op_code,
 					mdm_config_get_string (MDM_KEY_SOUND_ON_LOGIN_FILE),
 					mdm_config_get_bool   (MDM_KEY_SOUND_ON_LOGIN));
 		gtk_label_set_text_with_mnemonic (GTK_LABEL (label), _("_Username:"));
+                if (ve_string_empty (gtk_label_get_text (GTK_LABEL (msg)))) {
+                        gtk_label_set_text (GTK_LABEL (msg),
+                                            _("Please enter your username"));
+                        using_fallback_message = TRUE;
+                }
+
 	} else {
 		if (tmp != NULL)
 			gtk_label_set_text (GTK_LABEL (label), tmp);
+                if (using_fallback_message) {
+                        gtk_label_set_text (GTK_LABEL (msg), "");
+                        using_fallback_message = FALSE;
+                }
+
 	}
 	g_free (tmp);
 
@@ -1441,6 +1453,7 @@ process_operation (guchar       op_code,
 		g_free (tmp);
 	}
 	replace_msg = FALSE;
+	using_fallback_message = FALSE;
 
 	gtk_widget_show (GTK_WIDGET (msg));
 	printf ("%c\n", STX);
@@ -1557,6 +1570,19 @@ process_operation (guchar       op_code,
 	fflush (stdout);
 	break;
 
+    case MDM_A11Y:
+    {
+	const char *ats_launched;
+	/* print out the assistive technologies that we've started for the user */
+	ats_launched = g_getenv ("MDM_ATS");
+	if (ats_launched != NULL)
+		printf ("%c%s\n", STX, ats_launched);
+	else
+		printf ("%c\n", STX);
+	fflush (stdout);
+	break;
+    }
+
     case MDM_LANG:
 	mdm_lang_op_lang (args);
 	break;
@@ -1612,16 +1638,14 @@ process_operation (guchar       op_code,
 
 	first_prompt = TRUE;
 
-	gtk_widget_set_sensitive (entry, TRUE);
+	gtk_widget_set_sensitive (entry, FALSE);
 	gtk_widget_set_sensitive (ok_button, FALSE);
 	gtk_widget_set_sensitive (start_again_button, FALSE);
 
 	if (browser_ok && mdm_config_get_bool (MDM_KEY_BROWSER))
 	    gtk_widget_set_sensitive (GTK_WIDGET (browser), TRUE);
 
-	tmp = ve_locale_to_utf8 (args);
-	gtk_label_set_text (GTK_LABEL (msg), tmp);
-	g_free (tmp);
+	gtk_label_set_text (GTK_LABEL (msg), "");
 	gtk_widget_show (GTK_WIDGET (msg));
 
 	printf ("%c\n", STX);
diff --git a/gui/mdmsetup.desktop.in.in b/gui/mdmsetup.desktop.in.in
index ae253a4..0129294 100644
--- a/gui/mdmsetup.desktop.in.in
+++ b/gui/mdmsetup.desktop.in.in
@@ -2,8 +2,8 @@
 Encoding=UTF-8
 _Name=Login Window
 _Comment=Configure MDM login window appearance and behavior
-TryExec=@sbindir@/mdmsetup
-Exec=gksu @sbindir@/mdmsetup
+TryExec=/usr/bin/mdmsetup
+Exec=gksu /usr/bin/mdmsetup
 Icon=mdmsetup
 StartupNotify=true
 Terminal=false
diff --git a/gui/modules/AccessDwellMouseEvents.in b/gui/modules/AccessDwellMouseEvents.in
index cb19a6e..2f2167f 100644
--- a/gui/modules/AccessDwellMouseEvents.in
+++ b/gui/modules/AccessDwellMouseEvents.in
@@ -38,10 +38,10 @@
 # Support several different options for different user needs.  Note these
 # gestures all start by moving the mouse into the top window border.
 #
-TBLR I 10000    @AT_BINDIR@/gok --login --access-method=dwellselection
-TLBR I 10000    @AT_BINDIR@/gok --login --access-method=automaticscanning --scan-action=switch1 --select-action=switch1
-TRBL I 10000    @AT_BINDIR@/gok --login --access-method=inversescanning --scan-action=switch1 --select-action=switch2
-TBRL I 10000    @AT_BINDIR@/gok --login  --access-method=automaticscanning --scan-action=switch3 --select-action=switch3
+TBLR I 10000    @AT_BINDIR@/gok --login --access-method=dwellselection #AT_TYPE=onscreenkeyboard
+TLBR I 10000    @AT_BINDIR@/gok --login --access-method=automaticscanning --scan-action=switch1 --select-action=switch1 #AT_TYPE=onscreenkeyboard
+TRBL I 10000    @AT_BINDIR@/gok --login --access-method=inversescanning --scan-action=switch1 --select-action=switch2 #AT_TYPE=onscreenkeyboard
+TBRL I 10000    @AT_BINDIR@/gok --login  --access-method=automaticscanning --scan-action=switch3 --select-action=switch3 #AT_TYPE=onscreenkeyboard
 
 # AT Program - ORCA
 #
@@ -50,13 +50,13 @@ TBRL I 10000    @AT_BINDIR@/gok --login  --access-method=automaticscanning --sca
 #
 # Speech
 #
-BTRL I 10000    @AT_BINDIR@/orca -n -d main-window
+BTRL I 10000    @AT_BINDIR@/orca -n -d main-window #AT_TYPE=screenreader
 
 # Magnifier
 #
-BTLR I 10000    @AT_BINDIR@/orca -n -d main-window -d speech -e magnifier
+BTLR I 10000    @AT_BINDIR@/orca -n -d main-window -d speech -e magnifier #AT_TYPE=magnifier
 
 # Speech and Magnifier
 #
-BRTL I 10000    @AT_BINDIR@/orca -n -d main-window -e magnifier
+BRTL I 10000    @AT_BINDIR@/orca -n -d main-window -e magnifier #AT_TYPE=screenreader magnifier
 
diff --git a/gui/modules/AccessKeyMouseEvents.in b/gui/modules/AccessKeyMouseEvents.in
index a70be06..e6f0d61 100644
--- a/gui/modules/AccessKeyMouseEvents.in
+++ b/gui/modules/AccessKeyMouseEvents.in
@@ -78,14 +78,14 @@
 #
 # press ctrl-s for 1 second to launch orca in speech mode
 #
-<Control>s  1 1000 10000  @AT_BINDIR@/orca -n -d main-window
+<Control>s  1 1000 10000  @AT_BINDIR@/orca -n -d main-window #AT_TYPE=screenreader
 
 # press ctrl-m for 1 second to launch orca in mag mode
 #
-<Control>m  1 1000 10000  @AT_BINDIR@/orca -n -d main-window -d speech -e magnifier
+<Control>m  1 1000 10000  @AT_BINDIR@/orca -n -d main-window -d speech -e magnifier #AT_TYPE=magnifier
 
 # press ctrl-o or ctrl-g for 1 second to launch orca in speech and mag mode
 #
-<Control>o  1 1000 10000  @AT_BINDIR@/orca -n -d main-window -e magnifier
-<Control>g  1 1000 10000  @AT_BINDIR@/orca -n -d main-window -e magnifier
+<Control>o  1 1000 10000  @AT_BINDIR@/orca -n -d main-window -e magnifier #AT_TYPE=screenreader magnifier
+<Control>g  1 1000 10000  @AT_BINDIR@/orca -n -d main-window -e magnifier #AT_TYPE=screenreader magnifier
 
diff --git a/gui/modules/dwellmouselistener.c b/gui/modules/dwellmouselistener.c
index 84e2b84..7f53854 100644
--- a/gui/modules/dwellmouselistener.c
+++ b/gui/modules/dwellmouselistener.c
@@ -585,11 +585,33 @@ leave_enter_emission_hook (GSignalInvocationHint        *ihint,
 					G_CALLBACK (gtk_widget_destroy), NULL);
 				gtk_widget_show (dialog);
 			} else {
+				const char *at_name;
+				const char *ats_launched;
 				GdkCursor *cursor = gdk_cursor_new (GDK_WATCH);
 				gdk_window_set_cursor (gdk_get_default_root_window (),
 					cursor);
 				gdk_cursor_unref (cursor);
 				g_timeout_add (2000, change_cursor_back, NULL);
+
+				at_name = strstr (action, "#AT_TYPE=");
+				if (at_name != NULL) {
+					int i;
+					char **v;
+					at_name += 9;
+					v = g_strsplit (at_name, " ", 0);
+					for (i = 0; v[i] != NULL; i++) {
+						ats_launched = g_getenv ("MDM_ATS");
+						if (ats_launched == NULL) {
+							g_setenv ("MDM_ATS", v[i], TRUE);
+						} else if (strstr (ats_launched, v[i]) == NULL) {
+							char *s;
+							s = g_strdup_printf ("%s %s", ats_launched, v[i]);
+							g_setenv ("MDM_ATS", s, TRUE);
+							g_free (s);
+						}
+					}
+					g_strfreev (v);
+				}
 			}
 		}
 	}
diff --git a/gui/modules/keymouselistener.c b/gui/modules/keymouselistener.c
index edde8b9..05d7342 100644
--- a/gui/modules/keymouselistener.c
+++ b/gui/modules/keymouselistener.c
@@ -158,13 +158,16 @@ init_xinput (GdkDisplay *display, GdkWindow *root)
 {
 #ifdef HAVE_XINPUT
 	XEventClass  event_list[40];
-	int          i, j, number = 0, num_devices; 
+	int          i, j, number = 0, num_devices = 0;
 	XDeviceInfo  *devices = NULL;
 	XDevice      *device = NULL;
 
 	devices = XListInputDevices (GDK_DISPLAY_XDISPLAY (display),
 		&num_devices);
 
+        if (devices == NULL)
+            return;
+
 	if (debug_gestures)
 	    syslog (LOG_WARNING, "checking %d input devices...", num_devices);
 
@@ -964,6 +967,8 @@ gestures_filter (GdkXEvent *gdk_xevent,
 						NULL);
 					gtk_widget_show (dialog);
 				} else {
+					char *at_name;
+					const char *ats_launched;
 					GdkCursor *cursor = gdk_cursor_new (GDK_WATCH);
 					gdk_window_set_cursor (gdk_get_default_root_window (),
 						cursor);
@@ -971,6 +976,26 @@ gestures_filter (GdkXEvent *gdk_xevent,
 					g_timeout_add (2000,
 						       change_cursor_back,
 						       NULL);
+
+					at_name = strstr (action, "#AT_TYPE=");
+					if (at_name != NULL) {
+						int i;
+						char **v;
+						at_name += 9;
+						v = g_strsplit (at_name, " ", 0);
+						for (i = 0; v[i] != NULL; i++) {
+							ats_launched = g_getenv ("MDM_ATS");
+							if (ats_launched == NULL) {
+								g_setenv ("MDM_ATS", v[i], TRUE);
+							} else if (strstr (ats_launched, v[i]) == NULL) {
+								char *s;
+								s = g_strdup_printf ("%s %s", ats_launched, v[i]);
+								g_setenv ("MDM_ATS", s, TRUE);
+								g_free (s);
+							}
+						}
+						g_strfreev (v);
+					}
 				}
 			}
    			return GDK_FILTER_CONTINUE;
diff --git a/utils/mdmsetup-pam b/utils/mdmsetup-pam
index ecb8494..990ab08 100644
--- a/utils/mdmsetup-pam
+++ b/utils/mdmsetup-pam
@@ -1,6 +1,6 @@
 #%PAM-1.0
-auth       sufficient   pam_rootok.so
-auth       required     pam_stack.so service=system-auth
-session    required     pam_permit.so
-session    optional     pam_xauth.so
-account    required     pam_permit.so
+auth	sufficient	pam_rootok.so
+auth	include		system-auth
+account	required	pam_permit.so
+session	required	pam_permit.so
+session	optional	pam_xauth.so
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin