New hint about starting and stopping sessionpart of dbus using KDM.

Stef Bon stef at bononline.nl
Wed Jan 18 13:49:37 PST 2006


Hello,


a promised here my new hint about starting and stopping the dbus daemon per 
user.

Later I will add more hints about:

- mounting cifs shares at begin of a session and unmounting them again at 
reset.

- starting fusesmb at begin of a session and stopping them again at reset

- syncing directories and files at begin and backagain at reset


Stef
-------------- next part --------------
AUTHOR: Stef Bon <stef at bononline dot nl>

DATE: 2006-01-16

LICENSE: GNU Free Documentation License Version 1.2

SYNOPSIS: Starting and stopping DBUS at a KDE-session using KDM.

DESCRIPTION: 
This hint is about starting the sessionpart of the dbusdaemon. This 
is based on my hint 
"Execute scripts at begin and end of a KDE-session using KDM and PAM".

In this hint is described in general how scripts and commands are 
started at the begin and end of a KDE session using KDM, and for password 
sensitive commands support from PAM.

DBUS does not need anything of PAM, so here you'll find how you can start
and stop the session dbus daemon with KDM.

ATTACHMENT:

PREREQUISITES:
This hint requires sufficient knowledge of LINUX in general, and scripts in particular.
Futher sudo should be installed, and you should start KDE via KDM.

HINT:

Content:

1. Starting the sessiondaemon of dbus and make environmentvariables available.
1.1 About the startupfiles of Bash.
1.2 Starting the sessionbus part of dbus
1.3 Stopping the sessionbus part of dbus
1.4 Installation of Sudo 1.6.8p7
1.5 One user is more than one time logged in


1. Starting the sessiondaemon of dbus and make the environmentvariables available
---------------------------------------------------------------------------------

The dbus package is split up in two parts: one systemwide part and one for (each) session/user.
The systemwide part (a daemon) is started at boottime, with special privileges of a dedicated user.
The sessionwide part (also a daemon) has to started when a session for a user begins, 
and stopped when the session ends.

The construction with kdm I'm using here is ideal for this. One script in the startup directory to
start the sessiondaemon for a user, running with the privileges of that user, and one in the reset directory an other script has to stop that daemon.

But is not so simple as that. Some variables (DBUS_SESSION_BUS_ADDRESS and DBUS_SESSION_BUS_PID) have to 
be available in the environment to every application which works with dbus. 
IMHO the setting of these variables should go in the bash-startupscripts.
Then whatever script or application you're running, these variables are set
to the right value. 



1.1 About the startupfiles of Bash
----------------------------------

The sessiondaemon of dbus creates a file which contains the environmentvariables. As stated above this
file should be read (sourced) by bash when it starts for this user.

When bash is started by "login" as an interactive login shell, it reads /etc/profile and ~/.bash_profile.
Bash is also started by "kdm", and the files /etc/profile and ~/.bash_profile are sourced.

How should the dbus environmentvariables should be made available, or where should the file containing
the dbusvariables be sourced? Let's call this file dbus-bash.sh.

The dbus-bash.sh can't go in the /etc/profile.d directory and the /etc/profile file, because it differs for every user.
It should go in the ~/.bash_profile file, by appending or something simular. That is not only 
complicated at startup, but also at reset. Then it has to be removed again.

There is no other place in BLFS/LFS at this moment to put this file.
That's why I suggest the creating of a new directory (~/.profile.d) containing files which are 
sourced when a BASH session is starts for that user.
These files are exactly equivalent to those in /etc/profile.d, but contain variables that are not the same 
for every user.


                     global             user
		 ------------------------------

		 /etc/bashrc          ~/.bashrc
		 /etc/profile         ~/.bash_profile
		 /etc/profile.d       ~/.profile.d


By adding the following code to the $HOME/.bash_profile at the end of it any script with the .sh extension
will be sourced for this user only:

-- snip --

for script in $HOME/.profile.d/*.sh ; do
        if [ -x $script ]; then
                . $script
        fi
done

-- snip --

Now create as a user in his/her homedirectory:

mkdir $HOME/.profile.d



1.2  Starting the sessionbus part of dbus
-----------------------------------------


I assume that dbus is installed, and that it is started at boottime.
Compiling and installing it is described in the latest versions of BLFS 
(beginning 200510..). 

Create a script in the /etc/session.d/kdm/startup directory dbus-kdm.sh:

cd /etc/session.d/kdm/startup

cat >> dbus-kdm.sh << "EOF"
#!/bin/bash

retcode=0;

userid=$1
userproperties=$(getent passwd | grep -E "^$userid")
homedir=$(echo $userproperties | cut -d ":" -f 6);
gidnr=$(echo $userproperties | cut -d ":" -f 4);
uidnr=$(echo $userproperties | cut -d ":" -f 3);


if [ -d $homedir/.profile.d ]; then
	
	if [ $(id -u) -eq 0 ]; then
 	    sudo -u $userid -H /bin/sh -c "dbus-launch --auto-syntax > $homedir/.profile.d/dbus-bash.sh"
	    retcode=$?
	    chown $uidnr:$gidnr $homedir/.profile.d/dbus-bash.sh
	    chmod u+x $homedir/.profile.d/dbus-bash.sh
	elif [ $(id -u) -eq $uidnr ]; then 
    	    dbus-launch --auto-syntax > $homedir/.profile.d/dbus-bash.sh
	    retcode=$?
	    chmod u+x $homedir/.profile.d/dbus-bash.sh
	fi

fi;

if [ $retcode -ne 0 ]; then
    echo "An error with dbus ($retcode)."
fi;

exit $retcode
EOF

This script, executed by KDM at startup will start the dbus session daemon for this user, 
and will create a dbus-bash.sh script in the .profile.d directory of this user containing 
all the dbusvariables.

Now when bash starts at login, it reads (sources) this file.

As you can see, I've split the start of dbus up into two parts:
- dbus-kdm.sh, started when a (kdm)session starts, should be run once
- dbus-bash.sh, sourced when a (bash)session starts, could be sourced multiple times

Futher, I use the --auto-syntax parameter, where I assume Bash is used. So I could
use here --sh-syntax, but it works.

And Sudo is needed to run dbus-launcher as the user who's logging in, and the script is 
run as root. This is the case with KDM, the Xstartup file is run as root.
Installation of Sudo in chapter 1.4.




1.3  Stopping the sessionbus part of dbus
-----------------------------------------


Creating the dbus.sh script in the reset directory:


cd /etc/session.d/kdm/reset

cat >> dbus-kdm.sh << "EOF"
#!/bin/bash

retcode=0;

userid=$1
userproperties=$(getent passwd | grep -E "^$userid")
homedir=$(echo $userproperties | cut -d ":" -f 6);
gidnr=$(echo $userproperties | cut -d ":" -f 4);
uidnr=$(echo $userproperties | cut -d ":" -f 3);
	
if [ -f $homedir/.profile.d/dbus-bash.sh ]; then
	
	. $homedir/.profile.d/dbus-bash.sh
	
	if [ -n "$DBUS_SESSION_BUS_PID" ]; then
		if [ $(id -u) -eq 0 ]; then
		    sudo -u $userid -H /bin/sh -c "kill $DBUS_SESSION_BUS_PID"
		    retcode=$?
		    rm $homedir/.profile.d/dbus-bash.sh
		elif [ $(id -u) -eq $uidnr ]; then
		    kill $DBUS_SESSION_BUS_PID
		    retcode=$?
		    rm $homedir/.profile.d/dbus-bash.sh
		fi
	
	fi
fi;


if [ $retcode -ne 0 ]; then
    echo "An error with dbus ($retcode)."
fi;

exit $retcode
EOF

This script stops the session part of the dbus-daemon.




1.4 Installation of Sudo 1.6.8p7
--------------------------------

With sudo it's possible to execute a script or command as a normal user,
being root. I use version 1.6.8p7. You can get a recent version from:

http://www.sudo.ws/sudo

Unpack and change to the source:

tar -xvzf sudo-1.6.8p7.tar.gz
cd sudo-1.6.8p7

./configure --prefix=/usr --libexecdir=/usr/sbin --mandir=/usr/share/man --sysconfdir=/etc
make
make install

Notes:

- documentation you'll find only in the basedirectory of the source:
README, README.LDAP, PORTING, RUNSON, BUGS, INSTALL, CHANGES and so on.
If you want you can copy this to the usual directory in:

/usr/share/doc/sudo-1.6.8p7

- Authentication can be done via PAM. This is not needed here, because the default
behaviour of sudo allows root to run any script and command.

- for other purposes, like mount.cifs, you just need root privileges. Here you use 
sudo again, but then the other way around.




1.5 One user is more than one time logged in
--------------------------------------------

For most of the situations this construction is good enough. Most users 
have one session at a time. Now what happens when a user has more than 
one sessions at the same time? Is it nessacary to start the sessionpart
of dbus for every session, or is one instance sufficient? 
At this moment I don't have the answer for that question. 
Any has, please let me know.

I'll go check out the Internet about it.

ACKNOWLEDGEMENTS:


CHANGELOG:
[2006-01-18]
  * Initial hint.


More information about the hints mailing list