Minor spacing changes
[linux_from_scratch_hints.git] / starting-and-stopping-dbus-with-kdm.txt
blobffbf608c3822c5137002165b58e29c15b0aed3ac
1 AUTHOR: Stef Bon <stef at bononline dot nl>
3 DATE: 2006-09-09
5 LICENSE: GNU Free Documentation License Version 1.2
7 SYNOPSIS: Starting and stopping DBUS at a KDE-session using KDM.
9 DESCRIPTION: 
10 This hint is about starting the sessionpart of the dbusdaemon. This 
11 is based on my hint 
12 "Execute scripts at begin and end of a KDE-session using KDM".
14 In this hint is described in general how scripts and commands are 
15 started at the begin and end of a KDE session using KDM.
17 It's very possible to use this construction with oher loginmanagers as well.
20 ATTACHMENT:
22 PREREQUISITES:
23 This hint requires sufficient knowledge of LINUX in general, and scripts in particular.
24 Futher sudo should be installed, and you should start KDE via KDM.
26 HINT:
28 Content:
30 1. Starting the sessiondaemon of dbus and make environmentvariables available.
31 1.1 About the startupfiles of Bash.
32 1.2 Starting the sessionbus part of dbus
33 1.3 Stopping the sessionbus part of dbus
34 1.4 Installation of Sudo 1.6.8p12
35 1.5 One user is more than one time logged in
38 1. Starting the sessiondaemon of dbus and make the environmentvariables available
39 ---------------------------------------------------------------------------------
41 The dbus package is split up in two parts: one systemwide part and one 
42 for (each) session/user. The systemwide part (a daemon) is started at boottime, 
43 with special privileges of a dedicated user. The sessionwide part (also a daemon) 
44 has to started when a session for a user begins, and stopped when the session ends.
46 The construction with kdm I'm using here is ideal for this. One script in the 
47 startup directory to start the sessiondaemon for a user, running with the privileges 
48 of that user, and one in the reset directory an other script has to stop that daemon.
50 But is not so simple as that. Some variables (DBUS_SESSION_BUS_ADDRESS and 
51 DBUS_SESSION_BUS_PID) have to be available in the environment to every application 
52 which works with dbus. IMHO the setting of these variables should go in the 
53 bash-startupscripts. Then whatever script or application you're running, these 
54 variables are set to the right value. 
58 1.1 About the startupfiles of Bash
59 ----------------------------------
61 The sessiondaemon of dbus creates a file which contains the environmentvariables. 
62 As stated above this file should be read (sourced) by bash when it starts for this user.
64 When bash is started by "login" as an interactive login shell, it reads /etc/profile 
65 and ~/.bash_profile. Bash is also started by "kdm", and the files /etc/profile 
66 and ~/.bash_profile are sourced.
68 My idea is to store the output of the command
70 dbus-launch --auto-syntax 
72 in the file
74 $HOME/.dbus-session
76 This file is "sourced" when bash start. This happens not automatically, but you 
77 will have to add the following script to /etc/profile.d :
79 cat >> dbus-session.sh << "EOF"
81 if [ -f $HOME/.dbus-session ]; then
83         . $HOME/.dbus-session
85 fi;
86 EOF
88 This way, the environment variables are made available when Bash starts.
91 1.2  Starting the sessionbus part of dbus
92 -----------------------------------------
95 I assume that dbus is installed, and that it is started at boottime.
96 Compiling and installing it is described in the latest versions of BLFS 
97 (beginning 200510..). 
99 Create a script in the /etc/session.d/kdm/startup directory dbus-session-start.sh:
101 cd /etc/session.d/kdm/startup
103 cat >> dbus-session-start.sh << "EOF"
104 #!/bin/bash
106 retcode=0;
108 userid=$1
109 userproperties=$(getent passwd | grep -m 1 -E "^$userid")
110 homedir=$(echo $userproperties | cut -d ":" -f 6);
111 gidnr=$(echo $userproperties | cut -d ":" -f 4);
112 uidnr=$(echo $userproperties | cut -d ":" -f 3);
115 if [ -d $homedir ]; then
117     #
118     # do a check whether dbus-daemon is already running
119     # dbus-daemon needs to be started by the user (uidnr) logging in
120     #
121     
122     if [ -f $homedir/.dbus-session ]; then
124         # do a check the dbus-daemon for this user is running with the pid
125         # in the .dbus-session file
127         # pid according to the ps command
128         ps_dbus_session_pid=$(ps aux | grep -m 1 -E "^$userid.*dbus-daemon.*session.*" \
129         | grep -v "grep" | sed 's@[[:space:]][[:space:]]*@ @g' | cut -d " " -f 2)
130         
131         # read the pid from the .dbus-session file
132         . $homedir/.dbus-session
135         # check they are the same       
136         if [ -z "$ps_dbus_session_pid" ]; then
137         
138             # dbus for this user not running
139             rm $homedir/.dbus-session
140             
141         elif [ $DBUS_SESSION_BUS_PID -ne $ps_dbus_session_pid ]; then
142         
143             # there is something wrong: stop dbus-daemon for this user 
144             # and remove .dbus-session file
145             if [ $(id -u) -eq 0 ]; then
146                 sudo -H -u $userid sh -c "kill $ps_dbus_session_pid"
148             elif [ $(id -u) -eq $uidnr ]; then
149                 kill -SIGTERM $ps_dbus_session_pid;
150             fi
152             rm $homedir/.dbus-session
153             
154         fi
155     
156     fi  
158     if [ ! -f $homedir/.dbus-session ]; then
160         # only start a dbus session if .dbus-session file it not found
161         # in users homedirectory 
162   
163         if [ $(id -u) -eq 0 ]; then
164             sudo -u $userid -H /bin/sh -c "dbus-launch --auto-syntax > $homedir/.dbus-session"
165             retcode=$?
166             chown $uidnr:$gidnr $homedir/.dbus-session
167         elif [ $(id -u) -eq $uidnr ]; then 
168             dbus-launch --auto-syntax > $homedir/.dbus-session
169             retcode=$?
170         fi
172     fi
176 if [ $retcode -ne 0 ]; then
177     echo "An error with dbus ($retcode)."
180 exit $retcode
183 chmod 755 /etc/session.d/kdm/startup/dbus-session-start.sh
185 This script, executed by KDM at startup will start the dbus session daemon for this user, 
186 and will create the .dbus-session file in the homedirectory of this user, containing
187 all the dbusvariables.
188 It will only do this when dbus is not already running for this user.
190 Now when bash starts at login, it reads (sources) this file.
192 As you can see, I've split the start of dbus up into two parts:
193 - dbus-kdm.sh, started when a (kdm)session starts, should be run once
194 - .dbus-session, sourced when a (bash)session starts, could be sourced multiple times
196 Futher, I use the --auto-syntax parameter, where I assume Bash is used. So I could
197 use here --sh-syntax, but it works.
199 And Sudo is needed to run dbus-launcher as the user who's logging in, and the script is 
200 run as root. This is the case with KDM, the Xstartup file is run as root.
201 Installation of Sudo in chapter 1.4.
206 1.3  Stopping the sessionbus part of dbus
207 -----------------------------------------
210 Creating the dbus-session-stop.sh script in the reset directory:
213 cd /etc/session.d/kdm/reset
215 cat >> dbus-session-stop.sh << "EOF"
216 #!/bin/bash
218 retcode=0;
220 userid=$1
221 userproperties=$(getent passwd | grep -m 1 -E "^$userid")
222 homedir=$(echo $userproperties | cut -d ":" -f 6);
223 gidnr=$(echo $userproperties | cut -d ":" -f 4);
224 uidnr=$(echo $userproperties | cut -d ":" -f 3);
225         
226 if [ -f $homedir/.dbus-session ]; then
227         
228         . $homedir/.dbus-session
229         
230         if [ -n "$DBUS_SESSION_BUS_PID" ]; then
231                 if [ $(id -u) -eq 0 ]; then
232                     sudo -u $userid -H /bin/sh -c "kill $DBUS_SESSION_BUS_PID"
233                     retcode=$?
234                     rm $homedir/.dbus-session
235                 elif [ $(id -u) -eq $uidnr ]; then
236                     kill $DBUS_SESSION_BUS_PID
237                     retcode=$?
238                     rm $homedir/.dbus-session
239                 fi
240         
241         fi
245 if [ $retcode -ne 0 ]; then
246     echo "An error with dbus ($retcode)."
249 exit $retcode
252 chmod 755 /etc/session.d/kdm/reset/dbus-session-stop.sh
254 This script stops the session part of the dbus-daemon.
259 1.4 Installation of Sudo 1.6.8p12
260 ---------------------------------
262 With sudo it's possible to execute a script or command as a normal user,
263 being root. 
265 Since some time now sudo is in the BLFS book. Install it as described there.
266 Notes:
268 - documentation you'll find only in the basedirectory of the source:
269 README, README.LDAP, PORTING, RUNSON, BUGS, INSTALL, CHANGES and so on.
270 If you want you can copy this to the usual directory in:
272 /usr/share/doc/sudo-1.6.8p12
274 - Authentication can be done via PAM. This is not needed here, because the default
275 behaviour of sudo allows root to run any script and command.
277 - for other purposes, like mount.cifs, you just need root privileges. Here you use 
278 sudo again, but then the other way around.
283 1.5 One user is more than one time logged in
284 --------------------------------------------
286 For most of the situations this construction is good enough. Most users 
287 have one session at a time. Now what happens when a user has more than 
288 one sessions at the same time? Is it nessacary to start the sessionpart
289 of dbus for every session, or is one instance sufficient? 
291 This construction does not allow more than one dbus-daemon per user. 
292 I think that should be good enough. 
295 ACKNOWLEDGEMENTS:
298 CHANGELOG:
299 [2006-01-18]
300   * Initial hint.
301 [2006-07-18]
302   * Changed the bash scripts
303   * changed from sudo-1.6.8p7 to sudo-1.6.8p12
304 [2006-09-09]
305   * add check to see dbus-daemon is already running for this user
306     and the information found in .dbus-session is right