summaryrefslogtreecommitdiff
path: root/community/lxdm
diff options
context:
space:
mode:
authorNicolás Reynolds <fauno@endefensadelsl.org>2013-12-27 23:55:53 +0000
committerNicolás Reynolds <fauno@endefensadelsl.org>2013-12-27 23:55:53 +0000
commit65eeff79fff8a1bfdf67ca51d147384f46f4d5c0 (patch)
treefbfdff322b28d9a3c37e6e31c94caf1d8e48dac1 /community/lxdm
parentd53c44f055929b18d7d1b25f8367ee5836c435fc (diff)
Fri Dec 27 23:54:04 UTC 2013
Diffstat (limited to 'community/lxdm')
-rw-r--r--community/lxdm/PKGBUILD30
-rwxr-xr-xcommunity/lxdm/Xsession64
-rw-r--r--community/lxdm/default-config.patch63
-rw-r--r--community/lxdm/git-fixes.patch721
-rw-r--r--community/lxdm/lxdm.pam7
5 files changed, 637 insertions, 248 deletions
diff --git a/community/lxdm/PKGBUILD b/community/lxdm/PKGBUILD
index 4ccae3d07..5b5edba39 100644
--- a/community/lxdm/PKGBUILD
+++ b/community/lxdm/PKGBUILD
@@ -1,18 +1,18 @@
-# $Id: PKGBUILD 97132 2013-09-13 13:17:58Z bgyorgy $
+# $Id: PKGBUILD 101508 2013-11-26 19:15:27Z bgyorgy $
# Maintainer: Bartłomiej Piotrowski <nospam@bpiotrowski.pl>
# Contributor: AndyRTR <andyrtr@archlinux.org>
# Contributor: kiefer <jorgelmadrid@gmail.com>
pkgname=lxdm
pkgver=0.4.1
-pkgrel=27
+pkgrel=29
pkgdesc='Lightweight X11 Display Manager'
arch=('i686' 'x86_64')
url="http://sourceforge.net/projects/lxdm/"
license=('GPL')
groups=('lxde')
-depends=('gtk2' 'xorg-server' 'iso-codes')
-makedepends=('intltool')
+depends=('gtk2' 'xorg-server')
+makedepends=('intltool' 'iso-codes')
optdepends=('gtk-engines: default GTK+ theme'
'librsvg: display the default background')
install=$pkgname.install
@@ -21,10 +21,14 @@ backup=('etc/lxdm/lxdm.conf' 'etc/pam.d/lxdm' 'etc/lxdm/Xsession'
'etc/lxdm/PostLogout' 'etc/lxdm/PreReboot' 'etc/lxdm/PreShutdown')
source=(http://downloads.sourceforge.net/lxde/$pkgname-$pkgver.tar.gz
git-fixes.patch
- default-config.patch)
+ default-config.patch
+ lxdm.pam
+ Xsession)
md5sums=('8da1cfc2be6dc9217c85a7cf51e1e821'
- '03d0779fbac1a9964776c82e69fbc53e'
- 'c61ec8ffd3fe8bd2a6a9178393622f4c')
+ 'e9367cec197fa2919531f5c623ecec47'
+ '2ba18992efef43f84061717f0550e4b6'
+ 'c941ef896248bc7c03901b513490425c'
+ 'd9c8f8c9e6de52dbc389696454c8f572')
prepare(){
cd "$srcdir/$pkgname-$pkgver"
@@ -35,8 +39,12 @@ prepare(){
# Adjust Arch-specific settings
patch -Np1 -i ../default-config.patch
- # Fix version number
- sed -i 's/3.6.0/3.8/' gnome-shell/LXDM_User_Switch@dgod/metadata.json
+ # Use our custom pam and Xsession files
+ cp ../lxdm.pam pam/lxdm
+ cp ../Xsession data/Xsession
+
+ # Fix for pulseaudio
+ echo 'test -x /usr/bin/pax11publish && /usr/bin/pax11publish -r' >>data/PostLogout.in
}
build() {
@@ -56,8 +64,4 @@ package() {
install -dm 755 "$pkgdir/var/lib/lxdm"
echo 'GDK_CORE_DEVICE_EVENTS=true' > "$pkgdir"/var/lib/lxdm/.pam_environment
chown -R 121:121 "$pkgdir/var/lib/lxdm"
-
- # GNOME Shell extension
- mkdir -p "$pkgdir/usr/share/gnome-shell/extensions"
- cp -r gnome-shell/LXDM_User_Switch@dgod "$pkgdir/usr/share/gnome-shell/extensions"
}
diff --git a/community/lxdm/Xsession b/community/lxdm/Xsession
new file mode 100755
index 000000000..c34de14eb
--- /dev/null
+++ b/community/lxdm/Xsession
@@ -0,0 +1,64 @@
+#!/bin/sh
+#
+# LXDM wrapper to run around X sessions.
+
+echo "Running X session wrapper"
+
+if [ $# -eq 1 -a -n "$1" ]; then
+ LXSESSION=$1
+else
+# default session
+ LXSESSION=/usr/bin/startlxde
+fi
+
+# Load profile
+for file in "/etc/profile" "$HOME/.profile" "/etc/xprofile" "$HOME/.xprofile"; do
+ if [ -f "$file" ]; then
+ echo "Loading profile from $file";
+ . "$file"
+ fi
+done
+
+# Load resources
+for file in "/etc/X11/Xresources" "$HOME/.Xresources"; do
+ if [ -f "$file" ]; then
+ echo "Loading resource: $file"
+ xrdb -nocpp -merge "$file"
+ fi
+done
+
+# Load keymaps
+for file in "/etc/X11/Xkbmap" "$HOME/.Xkbmap"; do
+ if [ -f "$file" ]; then
+ echo "Loading keymap: $file"
+ setxkbmap `cat "$file"`
+ XKB_IN_USE=yes
+ fi
+done
+
+# Load xmodmap if not using XKB
+if [ -z "$XKB_IN_USE" ]; then
+ for file in "/etc/X11/Xmodmap" "$HOME/.Xmodmap"; do
+ if [ -f "$file" ]; then
+ echo "Loading modmap: $file"
+ xmodmap "$file"
+ fi
+ done
+fi
+
+unset XKB_IN_USE
+
+# Run all system xinitrc shell scripts.
+xinitdir="/etc/X11/xinit/xinitrc.d"
+if [ -d "$xinitdir" ]; then
+ for script in $xinitdir/*; do
+ echo "Loading xinit script $script"
+ if [ -x "$script" -a ! -d "$script" ]; then
+ . "$script"
+ fi
+ done
+fi
+
+echo "X session wrapper complete, running session $LXSESSION"
+
+exec $LXSESSION
diff --git a/community/lxdm/default-config.patch b/community/lxdm/default-config.patch
index 78c9bc00b..67435f94b 100644
--- a/community/lxdm/default-config.patch
+++ b/community/lxdm/default-config.patch
@@ -10,7 +10,7 @@ diff -Naur lxdm.orig/data/lxdm.conf.in lxdm/data/lxdm.conf.in
# uncomment this if you really want xserver listen to tcp
# tcp_listen=1
# uncoment this if you want reset the xserver after logou
-@@ -34,7 +34,7 @@
+@@ -34,13 +34,13 @@
gtk_theme=Clearlooks
## background of the greeter
@@ -19,61 +19,10 @@ diff -Naur lxdm.orig/data/lxdm.conf.in lxdm/data/lxdm.conf.in
## if show bottom pane
bottom_pane=1
-diff -Naur lxdm.orig/data/lxdm.in lxdm/data/lxdm.in
---- lxdm.orig/data/lxdm.in 2013-08-30 17:56:16.097006000 +0200
-+++ lxdm/data/lxdm.in 2013-09-04 01:57:56.950799946 +0200
-@@ -1,21 +1,13 @@
- #!/bin/sh
--[ -f /etc/sysconfig/i18n ] && . /etc/sysconfig/i18n
--
--if [ -z "$LANG" -a -e /etc/sysconfig/language ]; then
-- . /etc/sysconfig/language
-- if [ -n "$RC_LANG"]; then
-- LANG=$RC_LANG
-- fi
-+if [ -r /etc/profile.d/locale.sh ]; then
-+ . /etc/profile.d/locale.sh
- fi
+ ## if show language select control
+-lang=1
++lang=0
- if [ -n "$LANG" ]; then
- export LANG
- fi
-
--[ -f /etc/sysconfig/desktop ] && . /etc/sysconfig/desktop
--[ -f /etc/sysconfig/windowmanager ] && . /etc/sysconfig/windowmanager
--
- if [ -n "$DEFAULT_WM" ]; then
- PREFERRED=$DEFAULT_WM
- fi
-diff -Naur lxdm.orig/data/Xsession lxdm/data/Xsession
---- lxdm.orig/data/Xsession 2013-08-30 17:56:16.097006000 +0200
-+++ lxdm/data/Xsession 2013-09-04 01:58:19.941348762 +0200
-@@ -9,6 +9,8 @@
- LXSESSION=/usr/bin/startlxde
- fi
-
-+[ -f /etc/profile ] && . /etc/profile
-+[ -f ~/.profile ] && . ~/.profile
- [ -f /etc/xprofile ] && . /etc/xprofile
- [ -f ~/.xprofile ] && . ~/.xprofile
-
-diff -Naur lxdm.orig/pam/lxdm lxdm/pam/lxdm
---- lxdm.orig/pam/lxdm 2013-08-30 17:56:16.100339000 +0200
-+++ lxdm/pam/lxdm 2013-08-30 17:58:35.543771605 +0200
-@@ -1,9 +1,7 @@
- #%PAM-1.0
--auth substack system-auth
--auth optional pam_gnome_keyring.so
--account include system-auth
--session optional pam_keyinit.so force revoke
--session include system-auth
--session optional pam_console.so
--session optional pam_gnome_keyring.so auto_start
--session optional pam_selinux.so
-+auth include system-login
-+-auth optional pam_gnome_keyring.so
-+account include system-login
-+password include system-login
-+session include system-login
-+-session optional pam_gnome_keyring.so auto_start
+ ## if show keyboard layout select control
+ keyboard=0
diff --git a/community/lxdm/git-fixes.patch b/community/lxdm/git-fixes.patch
index 6a331cf0b..fed4800ee 100644
--- a/community/lxdm/git-fixes.patch
+++ b/community/lxdm/git-fixes.patch
@@ -20,7 +20,7 @@ index bfac56b..6f997b8 100644
rpmbuild -bb \
--define "_sourcedir `pwd`" \
diff --git a/configure.ac b/configure.ac
-index e952473..8958c9c 100644
+index e952473..22d2e17 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,8 +2,8 @@
@@ -30,7 +30,7 @@ index e952473..8958c9c 100644
-AC_INIT([lxdm], [0.4.1], [http://lxde.org/])
-AM_INIT_AUTOMAKE([-Wall -Werror foreign])
+AC_INIT([lxdm], [0.5.0], [http://lxde.org/])
-+AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
++AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects no-dist-gzip dist-xz])
AC_CONFIG_SRCDIR([src/lxdm.c])
AC_CONFIG_HEADERS([config.h])
@@ -690,7 +690,7 @@ index 51ffda4..41c95f4 100644
session optional pam_gnome_keyring.so auto_start
+session optional pam_selinux.so
diff --git a/src/Makefile.am b/src/Makefile.am
-index 7fdfd99..4f9a11c 100644
+index 7fdfd99..8b27291 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,6 +8,7 @@ lxdm_binary_CFLAGS = \
@@ -706,7 +706,7 @@ index 7fdfd99..4f9a11c 100644
lxdm_binary_SOURCES = \
- lxdm.c lxdm.h ui.c lxcom.c lxcom.h xconn.c xconn.h \
-+ lxdm.c lxdm.h ui.c lxcom.c lxcom.h xconn.c xconn.h auth.c lxcommon.h \
++ lxdm.c lxdm.h ui.c lxcom.c lxcom.h xconn.c xconn.h auth.c auth.h lxcommon.h \
$(NULL)
-libexec_PROGRAMS = lxdm-greeter-gdk lxdm-numlock lxdm-greeter-gtk
@@ -748,10 +748,10 @@ index 7fdfd99..4f9a11c 100644
+
diff --git a/src/auth.c b/src/auth.c
new file mode 100644
-index 0000000..10c047c
+index 0000000..7651fbb
--- /dev/null
+++ b/src/auth.c
-@@ -0,0 +1,632 @@
+@@ -0,0 +1,638 @@
+/*
+ * lxdm.c - main entry of lxdm
+ *
@@ -851,8 +851,8 @@ index 0000000..10c047c
+{
+ struct passwd *pw;
+ struct spwd *sp;
-+ char *real;
-+ char *enc;
++ char *real;
++ char *enc;
+ if(!user || !user[0])
+ {
+ g_debug("user==NULL\n");
@@ -866,45 +866,45 @@ index 0000000..10c047c
+ return AUTH_BAD_USER;
+ }
+ if(strstr(pw->pw_shell, "nologin"))
-+ {
-+ g_debug("user %s have nologin shell\n",user);
-+ return AUTH_PRIV;
-+ }
-+ if(type==AUTH_TYPE_AUTO_LOGIN && !pass)
-+ {
++ {
++ g_debug("user %s have nologin shell\n",user);
++ return AUTH_PRIV;
++ }
++ if(type==AUTH_TYPE_AUTO_LOGIN && !pass)
++ {
+ goto out;
+ }
-+ sp = getspnam(user);
-+ if( !sp )
-+ {
++ sp = getspnam(user);
++ if( !sp )
++ {
++ return AUTH_FAIL;
++ }
++ endspent();
++ real = sp->sp_pwdp;
++ if( !real || !real[0] )
++ {
++ if( !pass || !pass[0] )
++ {
++ *ppw = pw;
++ g_debug("user %s auth with no password ok\n",user);
++ return AUTH_SUCCESS;
++ }
++ else
++ {
++ g_debug("user %s password not match\n",user);
++ return AUTH_FAIL;
++ }
++ }
++ enc = crypt(pass, real);
++ if( strcmp(real, enc) )
++ {
++ g_debug("user %s password not match\n",user);
+ return AUTH_FAIL;
+ }
-+ endspent();
-+ real = sp->sp_pwdp;
-+ if( !real || !real[0] )
-+ {
-+ if( !pass || !pass[0] )
-+ {
-+ *ppw = pw;
-+ g_debug("user %s auth with no password ok\n",user);
-+ return AUTH_SUCCESS;
-+ }
-+ else
-+ {
-+ g_debug("user %s password not match\n",user);
-+ return AUTH_FAIL;
-+ }
-+ }
-+ enc = crypt(pass, real);
-+ if( strcmp(real, enc) )
-+ {
-+ g_debug("user %s password not match\n",user);
-+ return AUTH_FAIL;
-+ }
+out:
-+ g_debug("user %s auth ok\n",pw->pw_name);
++ g_debug("user %s auth ok\n",pw->pw_name);
+ passwd_copy(&a->pw,pw);
-+ return AUTH_SUCCESS;
++ return AUTH_SUCCESS;
+}
+
+int lxdm_auth_session_begin(LXDM_AUTH *a,int tty,int display,char mcookie[16])
@@ -1004,10 +1004,10 @@ index 0000000..10c047c
+ return AUTH_BAD_USER;
+ }
+ if(strstr(pw->pw_shell, "nologin"))
-+ {
-+ g_debug("user %s have nologin shell\n",user);
-+ return AUTH_PRIV;
-+ }
++ {
++ g_debug("user %s have nologin shell\n",user);
++ return AUTH_PRIV;
++ }
+ if(a->handle) pam_end(a->handle,0);
+ if(PAM_SUCCESS != pam_start("lxdm", pw->pw_name, &conv, (pam_handle_t**)&a->handle))
+ {
@@ -1046,15 +1046,15 @@ index 0000000..10c047c
+ char x[256];
+
+ if(!a->handle)
-+ {
-+ g_message("begin session without auth\n");
-+ return -1;
-+ }
++ {
++ g_message("begin session without auth\n");
++ return -1;
++ }
+ sprintf(x, "tty%d", tty);
-+ pam_set_item(a->handle, PAM_TTY, x);
++ pam_set_item(a->handle, PAM_TTY, x);
+#ifdef PAM_XDISPLAY
+ sprintf(x,":%d",display);
-+ pam_set_item(a->handle, PAM_XDISPLAY, x);
++ pam_set_item(a->handle, PAM_XDISPLAY, x);
+#endif
+#if !defined(DISABLE_XAUTH) && defined(PAM_XAUTHDATA)
+ struct pam_xauth_data value;
@@ -1064,28 +1064,34 @@ index 0000000..10c047c
+ value.datalen=16;
+ pam_set_item (a->handle, PAM_XAUTHDATA, &value);
+#endif
-+ if(name && name[0])
-+ {
-+ char *env;
-+ env = g_strdup_printf ("DESKTOP_SESSION=%s", name);
-+ pam_putenv (a->handle, env);
-+ g_free (env);
-+ }
++ if(name && name[0])
++ {
++ char *env;
++ env = g_strdup_printf ("DESKTOP_SESSION=%s", name);
++ pam_putenv (a->handle, env);
++ g_free (env);
++ }
+ err = pam_open_session(a->handle, 0); /* FIXME pam session failed */
-+ if( err != PAM_SUCCESS )
-+ g_warning( "pam open session error \"%s\"\n", pam_strerror(a->handle, err));
++ if( err != PAM_SUCCESS )
++ g_warning( "pam open session error \"%s\"\n", pam_strerror(a->handle, err));
++ else
++ a->in_session=1;
+ return 0;
+}
+
+int lxdm_auth_session_end(LXDM_AUTH *a)
+{
+ int err;
-+ if(!a->handle)
++ if(!a->handle)
+ return 0;
-+ err = pam_close_session(a->handle, 0);
-+ pam_end(a->handle, err);
-+ a->handle = NULL;
-+ passwd_clean(&a->pw);
++ if(a->in_session)
++ {
++ err = pam_close_session(a->handle, 0);
++ a->in_session=0;
++ }
++ pam_end(a->handle, err);
++ a->handle = NULL;
++ passwd_clean(&a->pw);
+ return 0;
+}
+
@@ -1268,7 +1274,7 @@ index 0000000..10c047c
+#include <assert.h>
+int lxdm_auth_session_begin(LXDM_AUTH *a,const char *name,int tty,int display,char mcookie[16])
+{
-+ char temp[32];
++ char temp[256];
+ char res[8];
+ gchar *b64;
+ int ret;
@@ -1386,10 +1392,10 @@ index 0000000..10c047c
+
diff --git a/src/auth.h b/src/auth.h
new file mode 100644
-index 0000000..84d2267
+index 0000000..5db944e
--- /dev/null
+++ b/src/auth.h
-@@ -0,0 +1,44 @@
+@@ -0,0 +1,45 @@
+/*
+ * lxdm.c - main entry of lxdm
+ *
@@ -1418,6 +1424,7 @@ index 0000000..84d2267
+ struct passwd pw;
+ int pipe[2];
+ int child;
++ int in_session;
+}LXDM_AUTH;
+
+enum{
@@ -2158,10 +2165,74 @@ index 095227b..2c6e5be 100644
g_free(str);
return TRUE;
diff --git a/src/lxcom.c b/src/lxcom.c
-index 02763eb..eef3d1b 100644
+index 02763eb..9491cb2 100644
--- a/src/lxcom.c
+++ b/src/lxcom.c
-@@ -89,7 +89,7 @@ static gboolean lxcom_prepare (GSource *source,gint *timeout)
+@@ -12,37 +12,56 @@
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ #include <sys/stat.h>
++
++#if defined(__sun)
++#include <ucred.h>
++#include <sys/filio.h>
++#elif !defined(linux) && !defined(__NetBSD__)
++#include <sys/ucred.h>
++#endif
++
+ #include <sys/socket.h>
+ #include <sys/un.h>
+ #include <sys/ioctl.h>
+-#if !defined(linux) && !defined(__NetBSD__)
+-#include <sys/ucred.h>
+-#endif
+
+ #ifndef SCM_CREDS
+-#define SCM_CREDS SCM_CREDENTIALS
++ #if defined(SCM_CREDENTIALS)
++ #define SCM_CREDS SCM_CREDENTIALS
++ #elif defined(SCM_UCRED)
++ #define SCM_CREDS SCM_UCRED
++ #else
++ #error not support unix socket creds
++ #endif
+ #endif
+
+ #ifndef linux
+-# ifndef __NetBSD__
++# if defined(__sun)
++# define LXDM_PEER_UID(c) ucred_geteuid(c)
++# define LXDM_PEER_GID(c) ucred_getegid(c)
++# define LXDM_PEER_PID(c) ucred_getpid(c)
++# elif !defined(__NetBSD__)
+ # define LXDM_PEER_UID(c) ((c)->cr_uid)
+ # define LXDM_PEER_GID(c) ((c)->cr_groups[0])
++# define LXDM_PEER_PID -1
+ # else
+ # define LXDM_PEER_UID(c) ((c)->sc_uid)
+ # define LXDM_PEER_GID(c) ((c)->sc_gid)
++# define LXDM_PEER_PID -1
+ # endif
+-# define LXDM_PEER_PID -1
+ #else
+ # define LXDM_PEER_UID(c) ((c)->uid)
+ # define LXDM_PEER_GID(c) ((c)->gid)
+ # define LXDM_PEER_PID(c) ((c)->pid)
+ #endif
+
+-#ifdef __NetBSD__
++#if defined(__NetBSD__)
+ typedef struct sockcred LXDM_CRED;
++#elif defined(__sun)
++typedef ucred_t LXDM_CRED;
+ #else
+ typedef struct ucred LXDM_CRED;
+ #endif
++
+ #include <glib.h>
+ #include "lxcom.h"
+
+@@ -89,13 +108,13 @@ static gboolean lxcom_prepare (GSource *source,gint *timeout)
static gboolean lxcom_check(GSource *source)
{
@@ -2170,7 +2241,51 @@ index 02763eb..eef3d1b 100644
}
static gboolean lxcom_dispatch (GSource *source,GSourceFunc callback,gpointer user_data)
-@@ -272,6 +272,7 @@ void lxcom_init(const char *sock)
+ {
+ char buf[4096];
+- char ctrl[CMSG_SPACE(sizeof(struct ucred))];
++ char ctrl[/*CMSG_SPACE(sizeof(LXDM_CRED))*/1024];
+ struct sockaddr_un peer;
+ struct iovec v={buf,sizeof(buf)};
+ struct msghdr h={&peer,sizeof(peer),&v,1,ctrl,sizeof(ctrl),0};
+@@ -118,16 +137,18 @@ static gboolean lxcom_dispatch (GSource *source,GSourceFunc callback,gpointer us
+ char **argv;
+ GString *res;
+
+- #ifndef __NetBSD__
+- size = sizeof(LXDM_CRED);
+- #else
++ #if defined(__sun)
++ size = ucred_size();
++ #elif defined(__NetBSD__)
+ if (cmptr->cmsg_len < SOCKCREDSIZE(0)) break;
+ size = SOCKCREDSIZE(((cred *)CMSG_DATA(cmptr))->sc_ngroups);
++ #else
++ size = sizeof(LXDM_CRED);
+ #endif
+ if (cmptr->cmsg_len != CMSG_LEN(size)) break;
+- if (cmptr->cmsg_level != SOL_SOCKET) break;
+- if (cmptr->cmsg_type != SCM_CREDS) break;
+- c=(LXDM_CRED*)CMSG_DATA(cmptr);
++ if (cmptr->cmsg_level != SOL_SOCKET) break;
++ if (cmptr->cmsg_type != SCM_CREDS) break;
++ c=(LXDM_CRED*)CMSG_DATA(cmptr);
+ if(g_shell_parse_argv(buf,&argc,&argv,NULL))
+ {
+ res=((LXComFunc)callback)(user_data,LXDM_PEER_UID(c),LXDM_PEER_PID(c),argc,argv);
+@@ -259,7 +280,11 @@ void lxcom_init(const char *sock)
+ strcpy(su.sun_path,sock);
+ self_server_fd=socket(AF_UNIX,SOCK_DGRAM,0);
+ assert(self_server_fd!=-1);
++#if defined(__sun)
++ ret=setsockopt(self_server_fd,SOL_SOCKET,SO_RECVUCRED,&on,sizeof(on));
++#else
+ ret=setsockopt(self_server_fd,SOL_SOCKET,SO_PASSCRED,&on,sizeof(on));
++#endif
+ assert(ret==0);
+ fcntl(self_server_fd,F_SETFL,O_NONBLOCK|fcntl(self_server_fd,F_GETFL));
+ ret=bind(self_server_fd,(struct sockaddr*)&su,sizeof(su));
+@@ -272,6 +297,7 @@ void lxcom_init(const char *sock)
s->poll.fd=self_server_fd;
s->poll.events=G_IO_IN;
@@ -2178,6 +2293,55 @@ index 02763eb..eef3d1b 100644
g_source_add_poll((GSource*)s,&s->poll);
self_source_id=g_source_attach((GSource*)s,NULL);
+@@ -289,22 +315,28 @@ void lxcom_init(const char *sock)
+ static ssize_t lxcom_write(int s,const void *buf,size_t count)
+ {
+ struct iovec iov[1] ={{(void*)buf,count,}};
+- struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0 };
++ struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0 };
+ #if !defined(linux) && !defined(__NetBSD__)
+- char ctrl[CMSG_SPACE(sizeof(LXDM_CRED))];
+- struct cmsghdr *cmptr;
++
++#if defined(__sun)
++ int size = ucred_size();
++#else
++ int size = sizeof(LXDM_CRED);
++#endif
++ char ctrl[CMSG_SPACE(size)];
++ struct cmsghdr *cmptr;
+ char *p;
+ int i;
+
+- msg.msg_control = ctrl;
+- msg.msg_controllen = sizeof(ctrl);
++ msg.msg_control = ctrl;
++ msg.msg_controllen = sizeof(ctrl);
+
+- cmptr = CMSG_FIRSTHDR(&msg);
+- cmptr->cmsg_len = CMSG_LEN(sizeof(LXDM_CRED));
+- cmptr->cmsg_level = SOL_SOCKET;
+- cmptr->cmsg_type = SCM_CREDS;
++ cmptr = CMSG_FIRSTHDR(&msg);
++ cmptr->cmsg_len = CMSG_LEN(size);
++ cmptr->cmsg_level = SOL_SOCKET;
++ cmptr->cmsg_type = SCM_CREDS;
+ p=(char*)CMSG_DATA(cmptr);
+- for(i=0;i<sizeof(LXDM_CRED);i++)
++ for(i=0;i<size;i++)
+ p[i]=0;
+ #endif
+ return sendmsg(s,&msg,0);
+@@ -332,9 +364,6 @@ gboolean lxcom_send(const char *sock,const char *buf,char **res)
+ su.sun_family=AF_UNIX;
+ s=socket(AF_UNIX,SOCK_DGRAM,0);
+ assert(s!=-1);
+- fcntl(s,F_SETFL,O_NONBLOCK|fcntl(self_server_fd,F_GETFL));
+- s=socket(AF_UNIX,SOCK_DGRAM,0);
+- assert(s!=-1);
+ fcntl(s,F_SETFL,O_NONBLOCK|fcntl(self_client_fd,F_GETFL));
+ strcpy(su.sun_path,sock);
+ ret=connect(s,(struct sockaddr*)&su,sizeof(su));
diff --git a/src/lxcommon.h b/src/lxcommon.h
new file mode 100644
index 0000000..24a6c38
@@ -2192,7 +2356,7 @@ index 0000000..24a6c38
+#endif /*_LXCOMMON_H_*/
+
diff --git a/src/lxdm.c b/src/lxdm.c
-index 5c279af..8ac8478 100644
+index 5c279af..638c30f 100644
--- a/src/lxdm.c
+++ b/src/lxdm.c
@@ -24,9 +24,6 @@
@@ -2398,7 +2562,7 @@ index 5c279af..8ac8478 100644
if(plymouth)
{
nr_tty=1;
-@@ -550,13 +559,13 @@ void lxdm_quit_self(int code)
+@@ -550,20 +559,20 @@ void lxdm_quit_self(int code)
static void log_init(void)
{
int fd_log;
@@ -2413,27 +2577,39 @@ index 5c279af..8ac8478 100644
}
static void log_ignore(const gchar *log_domain, GLogLevelFlags log_level,
-@@ -647,6 +656,19 @@ static void replace_env(char** env, const char* name, const char* new_val)
- *(penv + 1) = NULL;
+ const gchar *message, gpointer user_data)
+ {
}
+-
++#if 0
+ GSList *do_scan_xsessions(void)
+ {
+ GSList *xsessions = NULL;
+@@ -630,22 +639,7 @@ void free_xsessions(GSList *l)
+ }
+ g_slist_free(l);
+ }
+-
+-static void replace_env(char** env, const char* name, const char* new_val)
+-{
+- register char** penv;
+- for(penv = env; *penv; ++penv)
+- {
+- if(g_str_has_prefix(*penv, name))
+- {
+- g_free(*penv);
+- *penv = g_strconcat(name, new_val, NULL);
+- return;
+- }
+- }
+- *penv = g_strconcat(name, new_val, NULL);
+- *(penv + 1) = NULL;
+-}
++#endif
-+static const char *get_env(char **env, const char *name)
-+{
-+ register char** penv;
-+ for(penv = env; *penv; ++penv)
-+ {
-+ if(g_str_has_prefix(*penv, name))
-+ {
-+ return *penv+strlen(name);
-+ }
-+ }
-+ return NULL;
-+}
-+
#ifndef DISABLE_XAUTH
- static inline void xauth_write_uint16(int fd,uint16_t data)
-@@ -665,15 +687,20 @@ static inline void xauth_write_string(int fd,const char *s)
+@@ -665,15 +659,20 @@ static inline void xauth_write_string(int fd,const char *s)
write(fd,s,len);
}
@@ -2458,7 +2634,7 @@ index 5c279af..8ac8478 100644
xauth_write_string(fd,"MIT-MAGIC-COOKIE-1");
xauth_write_uint16(fd,16);
write(fd,data,16);
-@@ -695,139 +722,55 @@ static void create_server_auth(LXSession *s)
+@@ -695,139 +694,57 @@ static void create_server_auth(LXSession *s)
authfile = g_strdup_printf("/var/run/lxdm/lxdm-:%d.auth",s->display);
@@ -2471,7 +2647,7 @@ index 5c279af..8ac8478 100644
}
-static void create_client_auth(char *home,char **env)
-+static void create_client_auth(struct passwd *pw,char **env)
++static char ** create_client_auth(struct passwd *pw,char **env)
{
LXSession *s;
char *authfile;
@@ -2479,19 +2655,21 @@ index 5c279af..8ac8478 100644
- char *path;
- if((user=getuid())== 0 ) /* root don't need it */
+- return;
+ if(pw->pw_uid==0) /* root don't need it */
- return;
++ return env;
- s=lxsession_find_user(user);
+ s=lxsession_find_user(pw->pw_uid);
if(!s)
- return;
+- return;
-
- path=g_key_file_get_string(config,"base","xauth_path",NULL);
- if(path)
++ return env;
+
+ /* pam_mktemp may provide XAUTHORITY to DM, just use it */
-+ if((authfile=(char*)get_env(env,"XAUTHORITY="))!=NULL)
++ if((authfile=(char*)g_environ_getenv(env,"XAUTHORITY"))!=NULL)
{
- authfile = g_strdup_printf("%s/.Xauth%d", path,getuid());
- g_free(path);
@@ -2514,10 +2692,13 @@ index 5c279af..8ac8478 100644
}
remove(authfile);
- xauth_write_file(authfile,s->mcookie);
+- replace_env(env,"XAUTHORITY=",authfile);
+ xauth_write_file(authfile,s->display,s->mcookie);
- replace_env(env,"XAUTHORITY=",authfile);
++ env=g_environ_setenv(env,"XAUTHORITY",authfile,TRUE);
+ chown(authfile,pw->pw_uid,pw->pw_gid);
g_free(authfile);
++
++ return env;
}
#endif
@@ -2525,8 +2706,7 @@ index 5c279af..8ac8478 100644
-static char *user_pass[2];
-
-static int do_conv(int num, const struct pam_message **msg,struct pam_response **resp, void *arg)
-+int lxdm_auth_user(int type,char *user, char *pass, struct passwd **ppw)
- {
+-{
- int result = PAM_SUCCESS;
- int i;
- *resp = (struct pam_response *) calloc(num, sizeof(struct pam_response));
@@ -2555,7 +2735,8 @@ index 5c279af..8ac8478 100644
-#endif
-
-int lxdm_auth_user(char *user, char *pass, struct passwd **ppw)
--{
++int lxdm_auth_user(int type,char *user, char *pass, struct passwd **ppw)
+ {
- struct passwd *pw;
-#if !HAVE_LIBPAM
- struct spwd *sp;
@@ -2622,7 +2803,7 @@ index 5c279af..8ac8478 100644
s=lxsession_find_greeter();
if(!s) s=lxsession_find_idle();
if(!s) s=lxsession_add();
-@@ -836,97 +779,12 @@ int lxdm_auth_user(char *user, char *pass, struct passwd **ppw)
+@@ -836,97 +753,12 @@ int lxdm_auth_user(char *user, char *pass, struct passwd **ppw)
g_critical("lxsession_add fail\n");
exit(0);
}
@@ -2724,7 +2905,7 @@ index 5c279af..8ac8478 100644
static void close_left_fds(void)
{
struct dirent **list;
-@@ -945,9 +803,15 @@ static void close_left_fds(void)
+@@ -945,32 +777,35 @@ static void close_left_fds(void)
close(fd);
}
free(list);
@@ -2739,19 +2920,137 @@ index 5c279af..8ac8478 100644
-void switch_user(struct passwd *pw, char *run, char **env)
+void switch_user(struct passwd *pw, const char *run, char **env)
{
- int fd;
+- int fd;
++ int fd;
-@@ -968,9 +832,6 @@ void switch_user(struct passwd *pw, char *run, char **env)
- dup2(fd,STDERR_FILENO);
- close(fd);
- }
+- setenv("USER",pw->pw_name,1);
+- setenv("LOGNAME",pw->pw_name,1);
+- setenv("SHELL",pw->pw_shell,1);
+- setenv("HOME",pw->pw_dir,1);
+-
+- g_spawn_command_line_sync ("/etc/lxdm/PreLogin",NULL,NULL,NULL,NULL);
+-
+- if( !pw || initgroups(pw->pw_name, pw->pw_gid) ||
+- setgid(pw->pw_gid) || setuid(pw->pw_uid) || setsid() == -1 )
+- exit(EXIT_FAILURE);
+- chdir(pw->pw_dir);
+- fd=open(".xsession-errors",O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
+- if(fd!=-1)
+- {
+- dup2(fd,STDERR_FILENO);
+- close(fd);
+- }
-#ifndef DISABLE_XAUTH
- create_client_auth(pw->pw_dir,env);
-#endif
++ setenv("USER",pw->pw_name,1);
++ setenv("LOGNAME",pw->pw_name,1);
++ setenv("SHELL",pw->pw_shell,1);
++ setenv("HOME",pw->pw_dir,1);
++
++ g_spawn_command_line_sync ("/etc/lxdm/PreLogin",NULL,NULL,NULL,NULL);
++
++ if( !pw || initgroups(pw->pw_name, pw->pw_gid) ||
++ setgid(pw->pw_gid) || setuid(pw->pw_uid) || setsid() == -1 )
++ exit(EXIT_FAILURE);
++ chdir(pw->pw_dir);
++ fd=open(".xsession-errors",O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
++ if(fd!=-1)
++ {
++ dup2(fd,STDERR_FILENO);
++ close(fd);
++ }
/* reset signal */
signal(SIGCHLD, SIG_DFL);
-@@ -1114,7 +975,7 @@ void lxdm_startx(LXSession *s)
+@@ -987,45 +822,45 @@ void switch_user(struct passwd *pw, char *run, char **env)
+
+ static void get_lock(void)
+ {
+- FILE *fp;
+- char *lockfile;
++ FILE *fp;
++ char *lockfile;
+
+- lockfile = g_key_file_get_string(config, "base", "lock", 0);
+- if( !lockfile ) lockfile = g_strdup("/var/run/lxdm.pid");
++ lockfile = g_key_file_get_string(config, "base", "lock", 0);
++ if( !lockfile ) lockfile = g_strdup("/var/run/lxdm.pid");
+
+- fp = fopen(lockfile, "r");
+- if( fp )
+- {
+- int pid;
+- int ret;
+- ret = fscanf(fp, "%d", &pid);
+- fclose(fp);
+- if(ret == 1 && pid!=getpid())
++ fp = fopen(lockfile, "r");
++ if( fp )
++ {
++ int pid;
++ int ret;
++ ret = fscanf(fp, "%d", &pid);
++ fclose(fp);
++ if(ret == 1 && pid!=getpid())
+ {
+- if(kill(pid, 0) == 0 || (ret == -1 && errno == EPERM))
+- {
+- /* we should only quit if the pid running is lxdm */
++ if(kill(pid, 0) == 0 || (ret == -1 && errno == EPERM))
++ {
++ /* we should only quit if the pid running is lxdm */
+ #ifdef __linux__
+- char path[64],buf[128];
+- sprintf(path,"/proc/%d/exe",pid);
+- ret=readlink(path,buf,128);
+- if(ret<128 && ret>0 && strstr(buf,"lxdm-binary"))
+- lxdm_quit_self(1);
+-#else
++ char path[64],buf[128];
++ sprintf(path,"/proc/%d/exe",pid);
++ ret=readlink(path,buf,128);
++ if(ret<128 && ret>0 && strstr(buf,"lxdm-binary"))
+ lxdm_quit_self(1);
++#else
++ lxdm_quit_self(1);
+ #endif
+- }
++ }
+ }
+- }
+- fp = fopen(lockfile, "w");
+- if( !fp )
+- {
+- g_critical("open lock file %s fail\n",lockfile);
+- lxdm_quit_self(0);
+- }
+- fprintf( fp, "%d", getpid() );
+- fclose(fp);
+- g_free(lockfile);
++ }
++ fp = fopen(lockfile, "w");
++ if( !fp )
++ {
++ g_critical("open lock file %s fail\n",lockfile);
++ lxdm_quit_self(0);
++ }
++ fprintf( fp, "%d", getpid() );
++ fclose(fp);
++ g_free(lockfile);
+ }
+
+ static void put_lock(void)
+@@ -1083,6 +918,8 @@ void lxdm_startx(LXSession *s)
+ int i;
+ char display[16];
+
++ lxsession_set_active(s);
++
+ sprintf(display,":%d",s->display);
+ setenv("DISPLAY",display,1);
+
+@@ -1114,7 +951,7 @@ void lxdm_startx(LXSession *s)
g_strfreev(args);
lxcom_add_child_watch(s->server, on_xserver_stop, s);
@@ -2760,7 +3059,7 @@ index 5c279af..8ac8478 100644
for( i = 0; i < 100; i++ )
{
if(lxcom_last_sig==SIGINT || lxcom_last_sig==SIGTERM)
-@@ -1124,6 +985,7 @@ void lxdm_startx(LXSession *s)
+@@ -1124,6 +961,7 @@ void lxdm_startx(LXSession *s)
g_usleep(50 * 1000);
//g_message("retry %d\n",i);
}
@@ -2768,7 +3067,7 @@ index 5c279af..8ac8478 100644
if(s->dpy==NULL)
exit(EXIT_FAILURE);
-@@ -1200,6 +1062,11 @@ static void on_session_stop(void *data,int pid, int status)
+@@ -1200,6 +1038,11 @@ static void on_session_stop(void *data,int pid, int status)
{
lxsession_free(s);
}
@@ -2780,7 +3079,7 @@ index 5c279af..8ac8478 100644
gchar *argv[] = { "/etc/lxdm/PostLogout", NULL };
g_spawn_async(NULL, argv, s->env, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL);
}
-@@ -1212,7 +1079,7 @@ gboolean lxdm_get_session_info(char *session,char **pname,char **pexec)
+@@ -1212,7 +1055,7 @@ gboolean lxdm_get_session_info(char *session,char **pname,char **pexec)
name=g_key_file_get_string(config, "base", "session", 0);
if(!name && getenv("PREFERRED"))
name = g_strdup(getenv("PREFERRED"));
@@ -2789,7 +3088,7 @@ index 5c279af..8ac8478 100644
name = g_strdup(getenv("DESKTOP"));
if(!name) name=g_strdup("LXDE");
}
-@@ -1291,7 +1158,7 @@ static void lxdm_save_login(char *session,char *lang)
+@@ -1291,7 +1134,7 @@ static void lxdm_save_login(char *session,char *lang)
lang="";
var=g_key_file_new();
g_key_file_set_list_separator(var, ' ');
@@ -2798,7 +3097,7 @@ index 5c279af..8ac8478 100644
old=g_key_file_get_string(var,"base","last_session",0);
if(0!=g_strcmp0(old,session))
{
-@@ -1343,7 +1210,7 @@ static void lxdm_save_login(char *session,char *lang)
+@@ -1343,7 +1186,7 @@ static void lxdm_save_login(char *session,char *lang)
char* data = g_key_file_to_data(var, &len, NULL);
mkdir("/var/lib/lxdm",0755);
chmod("/var/lib/lxdm",0755);
@@ -2807,7 +3106,7 @@ index 5c279af..8ac8478 100644
g_free(data);
}
g_key_file_free(var);
-@@ -1357,6 +1224,8 @@ void lxdm_do_login(struct passwd *pw, char *session, char *lang, char *option)
+@@ -1357,6 +1200,8 @@ void lxdm_do_login(struct passwd *pw, char *session, char *lang, char *option)
LXSession *s,*prev;
lxdm_save_login(session,lang);
@@ -2816,7 +3115,16 @@ index 5c279af..8ac8478 100644
if(!session ||!session[0] || !lang || !lang[0])
{
-@@ -1423,12 +1292,10 @@ void lxdm_do_login(struct passwd *pw, char *session, char *lang, char *option)
+@@ -1398,7 +1243,7 @@ void lxdm_do_login(struct passwd *pw, char *session, char *lang, char *option)
+ }
+ prev=lxsession_find_user(pw->pw_uid);
+ s=lxsession_find_greeter();
+- if(prev)
++ if(prev && prev->child>0)
+ {
+ if(s) lxsession_free(s);
+ lxsession_set_active(prev);
+@@ -1423,12 +1268,10 @@ void lxdm_do_login(struct passwd *pw, char *session, char *lang, char *option)
s->ckc=NULL;
}
#endif
@@ -2831,7 +3139,7 @@ index 5c279af..8ac8478 100644
#else
if(!s->ckc)
#endif
-@@ -1451,9 +1318,20 @@ void lxdm_do_login(struct passwd *pw, char *session, char *lang, char *option)
+@@ -1451,49 +1294,58 @@ void lxdm_do_login(struct passwd *pw, char *session, char *lang, char *option)
"x11-display", &n,
"is-local",&is_local,
NULL))
@@ -2849,18 +3157,51 @@ index 5c279af..8ac8478 100644
+ g_message("create ConsoleKit connector fail\n");
}
#endif
-+
- char** env, *path;
- int n_env,i;
- n_env = g_strv_length(environ);
-@@ -1483,17 +1361,22 @@ void lxdm_do_login(struct passwd *pw, char *session, char *lang, char *option)
- replace_env(env, "LANGUAGE=", lang);
+- char** env, *path;
+- int n_env,i;
+- n_env = g_strv_length(environ);
+- /* copy all environment variables and override some of them */
+- env = g_new(char*, n_env + 1 + 13);
+- for( i = 0; i < n_env; ++i )
+- env[i] = g_strdup(environ[i]);
+- env[i] = NULL;
+-
+- replace_env(env, "HOME=", pw->pw_dir);
+- replace_env(env, "SHELL=", pw->pw_shell);
+- replace_env(env, "USER=", pw->pw_name);
+- replace_env(env, "LOGNAME=", pw->pw_name);
++ char **env, *path;
++ env=g_get_environ();
++
++ env=g_environ_setenv(env, "HOME", pw->pw_dir, TRUE);
++ env=g_environ_setenv(env, "SHELL", pw->pw_shell, TRUE);
++ env=g_environ_setenv(env, "USER", pw->pw_name, TRUE);
++ env=g_environ_setenv(env, "LOGNAME", pw->pw_name, TRUE);
+
+ /* override $PATH if needed */
+ path = g_key_file_get_string(config, "base", "path", 0);
+ if( G_UNLIKELY(path) && path[0] ) /* if PATH is specified in config file */
+- replace_env(env, "PATH=", path); /* override current $PATH with config value */
++ env=g_environ_setenv(env, "PATH", path, TRUE); /* override current $PATH with config value */
+ else /* don't use the global env, they are bad for user */
+- replace_env(env, "PATH=", "/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin"); /* set proper default */
++ env=g_environ_setenv(env, "PATH", "/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin", TRUE); /* set proper default */
+ g_free(path);
+ /* optionally override $LANG, $LC_MESSAGES, and $LANGUAGE */
+ if( lang && lang[0] )
+ {
+- replace_env(env, "LANG=", lang);
+- replace_env(env, "LC_MESSAGES=", lang);
+- replace_env(env, "LANGUAGE=", lang);
++ env=g_environ_setenv(env, "LANG", lang, TRUE);
++ env=g_environ_setenv(env, "LC_MESSAGES", lang, TRUE);
++ env=g_environ_setenv(env, "LANGUAGE", lang, TRUE);
}
- s->env = env;
+
+#ifndef DISABLE_XAUTH
-+ create_client_auth(pw,env);
++ env=create_client_auth(pw,env);
+#endif
+ s->env = env;
- s->child = pid = fork();
+ /*s->child = pid = fork();
@@ -2882,7 +3223,7 @@ index 5c279af..8ac8478 100644
g_free(session_name);
g_free(session_exec);
if(alloc_session)
-@@ -1519,7 +1402,7 @@ void lxdm_do_shutdown(void)
+@@ -1519,7 +1371,7 @@ void lxdm_do_shutdown(void)
char *cmd;
cmd = g_key_file_get_string(config, "cmd", "shutdown", 0);
if( !cmd ) cmd = g_strdup("shutdown -h now");
@@ -2891,7 +3232,7 @@ index 5c279af..8ac8478 100644
g_spawn_command_line_async(cmd,0);
g_free(cmd);
lxdm_quit_self(0);
-@@ -1548,10 +1431,30 @@ int lxdm_do_auto_login(void)
+@@ -1548,10 +1400,30 @@ int lxdm_do_auto_login(void)
if(count==1)
pass = g_key_file_get_string(config, "base", "password", 0);
#endif
@@ -2922,7 +3263,7 @@ index 5c279af..8ac8478 100644
if(p[0]=='@')
{
option=p+1;
-@@ -1559,11 +1462,16 @@ int lxdm_do_auto_login(void)
+@@ -1559,11 +1431,16 @@ int lxdm_do_auto_login(void)
session=g_key_file_get_string(config,option,"session",0);
lang=g_key_file_get_string(config,option,"lang",0);
}
@@ -2940,7 +3281,7 @@ index 5c279af..8ac8478 100644
if(ret==AUTH_SUCCESS)
{
lxdm_do_login(pw,session,lang,option);
-@@ -1571,9 +1479,11 @@ int lxdm_do_auto_login(void)
+@@ -1571,9 +1448,11 @@ int lxdm_do_auto_login(void)
}
g_free(user);g_free(session);g_free(lang);
}
@@ -2953,7 +3294,7 @@ index 5c279af..8ac8478 100644
}
static void log_sigsegv(void)
-@@ -1677,8 +1587,23 @@ GKeyFile *lxdm_user_list(void)
+@@ -1677,8 +1556,23 @@ GKeyFile *lxdm_user_list(void)
g_key_file_set_comment(kf,NULL,NULL,"lxdm user list",NULL);
while((pw=getpwent())!=NULL)
{
@@ -2977,7 +3318,7 @@ index 5c279af..8ac8478 100644
if(strncmp(pw->pw_dir,"/home/",6))
{
if(!strv_find(white,pw->pw_name))
-@@ -1780,21 +1705,21 @@ int main(int arc, char *arg[])
+@@ -1780,21 +1674,21 @@ int main(int arc, char *arg[])
return res?0:-1;
}
}
@@ -3003,7 +3344,7 @@ index 5c279af..8ac8478 100644
g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG, log_ignore, NULL);
}
-@@ -1832,3 +1757,4 @@ int main(int arc, char *arg[])
+@@ -1832,3 +1726,4 @@ int main(int arc, char *arg[])
return 0;
}
@@ -3028,10 +3369,10 @@ index 4c79ca3..568573f 100644
{
diff --git a/src/pam.c b/src/pam.c
new file mode 100644
-index 0000000..810e44f
+index 0000000..7277a50
--- /dev/null
+++ b/src/pam.c
-@@ -0,0 +1,578 @@
+@@ -0,0 +1,586 @@
+/*
+ * lxdm.c - main entry of lxdm
+ *
@@ -3075,6 +3416,7 @@ index 0000000..810e44f
+#include <dirent.h>
+#include <errno.h>
+#include <poll.h>
++#include <sys/stat.h>
+
+#include <pwd.h>
+#include <grp.h>
@@ -3123,8 +3465,8 @@ index 0000000..810e44f
+{
+ struct passwd *pw;
+ struct spwd *sp;
-+ char *real;
-+ char *enc;
++ char *real;
++ char *enc;
+ if(!user || !user[0])
+ {
+ g_debug("user==NULL\n");
@@ -3138,44 +3480,44 @@ index 0000000..810e44f
+ return AUTH_BAD_USER;
+ }
+ if(strstr(pw->pw_shell, "nologin"))
-+ {
-+ g_debug("user %s have nologin shell\n",user);
-+ return AUTH_PRIV;
-+ }
-+ if(type==AUTH_TYPE_AUTO_LOGIN && !pass)
-+ {
++ {
++ g_debug("user %s have nologin shell\n",user);
++ return AUTH_PRIV;
++ }
++ if(type==AUTH_TYPE_AUTO_LOGIN && !pass)
++ {
+ goto out;
+ }
-+ sp = getspnam(user);
-+ if( !sp )
-+ {
++ sp = getspnam(user);
++ if( !sp )
++ {
+ return AUTH_FAIL;
+ }
-+ endspent();
-+ real = sp->sp_pwdp;
-+ if( !real || !real[0] )
-+ {
-+ if( !pass || !pass[0] )
-+ {
-+ *ppw = pw;
-+ g_debug("user %s auth with no password ok\n",user);
-+ return AUTH_SUCCESS;
-+ }
-+ else
-+ {
-+ g_debug("user %s password not match\n",user);
-+ return AUTH_FAIL;
-+ }
-+ }
-+ enc = crypt(pass, real);
-+ if( strcmp(real, enc) )
-+ {
-+ g_debug("user %s password not match\n",user);
-+ return AUTH_FAIL;
-+ }
-+ g_debug("user %s auth ok\n",pw->pw_name);
++ endspent();
++ real = sp->sp_pwdp;
++ if( !real || !real[0] )
++ {
++ if( !pass || !pass[0] )
++ {
++ *ppw = pw;
++ g_debug("user %s auth with no password ok\n",user);
++ return AUTH_SUCCESS;
++ }
++ else
++ {
++ g_debug("user %s password not match\n",user);
++ return AUTH_FAIL;
++ }
++ }
++ enc = crypt(pass, real);
++ if( strcmp(real, enc) )
++ {
++ g_debug("user %s password not match\n",user);
++ return AUTH_FAIL;
++ }
++ g_debug("user %s auth ok\n",pw->pw_name);
+ passwd_copy(&a->pw,pw);
-+ return AUTH_SUCCESS;
++ return AUTH_SUCCESS;
+}
+
+int lxdm_auth_session_begin(LXDM_AUTH *a,int tty,int display,char mcookie[16])
@@ -3329,6 +3671,8 @@ index 0000000..810e44f
+ err = pam_open_session(a->handle, 0); /* FIXME pam session failed */
+ if( err != PAM_SUCCESS )
+ g_warning( "pam open session error \"%s\"\n", pam_strerror(a->handle, err));
++ else
++ a->in_session=1;
+ return 0;
+}
+
@@ -3337,9 +3681,13 @@ index 0000000..810e44f
+ int err;
+ if(!a->handle)
+ return 0;
-+ err = pam_close_session(a->handle, 0);
++ if(a->in_session)
++ {
++ err = pam_close_session(a->handle, 0);
++ a->in_session=0;
++ }
+ pam_end(a->handle, err);
-+ a->handle = NULL;
++ a->handle = NULL;
+ passwd_clean(&a->pw);
+ return 0;
+}
@@ -3413,7 +3761,7 @@ index 0000000..810e44f
+void switch_user(struct passwd *pw, const char *run, char **env)
+{
+ int fd;
-+
++
+ setenv("USER",pw->pw_name,1);
+ setenv("LOGNAME",pw->pw_name,1);
+ setenv("SHELL",pw->pw_shell,1);
@@ -3424,13 +3772,13 @@ index 0000000..810e44f
+ if( !pw || initgroups(pw->pw_name, pw->pw_gid) ||
+ setgid(pw->pw_gid) || setuid(pw->pw_uid)/* || setsid() == -1 */)
+ exit(EXIT_FAILURE);
-+ chdir(pw->pw_dir);
-+ fd=open(".xsession-errors",O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
-+ if(fd!=-1)
-+ {
-+ dup2(fd,STDERR_FILENO);
-+ close(fd);
-+ }
++ chdir(pw->pw_dir);
++ fd=open(".xsession-errors",O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
++ if(fd!=-1)
++ {
++ dup2(fd,STDERR_FILENO);
++ close(fd);
++ }
+
+ /* reset signal */
+ signal(SIGCHLD, SIG_DFL);
@@ -3441,7 +3789,7 @@ index 0000000..810e44f
+ close_left_fds();
+
+ g_spawn_command_line_async ("/etc/lxdm/PostLogin",NULL);
-+ execle("/etc/lxdm/Xsession", "/etc/lxdm/Xsession", run, NULL, environ);
++ execl("/etc/lxdm/Xsession","/etc/lxdm/Xsession",run,NULL);
+ perror("execle");
+ exit(EXIT_FAILURE);
+}
@@ -3606,6 +3954,7 @@ index 0000000..810e44f
+ }
+ //fprintf(stderr,"end\n");
+ }
++ lxdm_auth_session_end(&a);
+ lxdm_auth_cleanup(&a);
+ return 0;
+}
@@ -3666,6 +4015,22 @@ index 2691a03..f233589 100644
if( AUTH_SUCCESS == ret && pw != NULL )
{
ui_drop();
+diff --git a/src/xconn.c b/src/xconn.c
+index f0bdbf2..5c62d4b 100644
+--- a/src/xconn.c
++++ b/src/xconn.c
+@@ -55,9 +55,9 @@ void xconn_clean(xconn_t c)
+ unsigned int nchildren;
+ unsigned int i;
+ Window Root;
+-
++
+ if(!c) return;
+-
++
+ XSetErrorHandler(CatchErrors);
+ XSetIOErrorHandler(CatchIOErrors);
+
diff --git a/systemd/Makefile.am b/systemd/Makefile.am
new file mode 100644
index 0000000..b568c5a
diff --git a/community/lxdm/lxdm.pam b/community/lxdm/lxdm.pam
new file mode 100644
index 000000000..76b8869a2
--- /dev/null
+++ b/community/lxdm/lxdm.pam
@@ -0,0 +1,7 @@
+#%PAM-1.0
+auth include system-login
+-auth optional pam_gnome_keyring.so
+account include system-login
+password include system-login
+session include system-login
+-session optional pam_gnome_keyring.so auto_start