Changeset 1015

Show
Ignore:
Timestamp:
01/16/06 23:27:54 (3 years ago)
Author:
tushar
Message:

Update Hint: execute-session-scripts-using-kdm-and-pam

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/execute-session-scripts-using-kdm-and-pam.txt

    r994 r1015  
    11AUTHOR: Stef Bon <stef at bononline dot nl> 
    22 
    3 DATE: 2005-10-21 
     3DATE: 2006-01-15 
    44 
    55LICENSE: GNU Free Documentation License Version 1.2 
    66 
    7 SYNOPSIS: Execute scripts at begin and end of a usersession using PAM with some examples like dbus
     7SYNOPSIS: Execute scripts at begin and end of a KDE-session using KDM and PAM
    88 
    99DESCRIPTION: 
    10 This hint is about the ability to execute scripts when a session for a user starts,  
    11 and when it ends.  
    12  
    13 I started to when I was looking for a sollution to store my kde settings on a central  
    14 computer. Later I discovered that scripts for other purposes are possible. 
    15  
    16 It works via pam. I know this can be done via  
    17 the scripts in the profile.d directory which are executed when a shell starts,  
    18 but pam is in my opinion the best place to this.  
    19  
    20 The original hint is at http://linux.bononline.nl. You can download all the scripts there too. 
     10 
     11This hint is about the ability to execute scripts when a KDE session starts  
     12and when it stops.  
     13 
     14Earlier I wrote a hint about this using PAM, with the help of the module pam_script.  
     15I discovered that PAM is not the best place to do so. PAM is not the place to start  
     16scripts, KDM is. KDM provides a very easy way via the Xstartup and Xreset files to  
     17execute scripts. PAM has the abilty to do something with the credentials provided  
     18at login, with the help of a module called pam_script.  
     19 
     20I'm trying to combine those two. 
     21 
     22 
     23warning: 
     24 
     25I use PAM and a module called pam_script to store the credentials provided at 
     26login (the username and the password!!) for authentication against SMB servers, when  
     27mounting shares. 
     28This looks a little bit like Single Sign On, but it isn't!! The credentials are stored in  
     29a subdirectory of the homedir (~/.cifs/mount.cifs.conf), with enough security at runtime. 
     30But somebody can still find them being root, or with a LiveCD. The credentials are stored 
     31plaintext, no encryption!! 
     32 
     33So, this should never be used in an environment where you can't trust your users! 
     34 
    2135 
    2236ATTACHMENTS: 
     
    2438 
    2539PREREQUISITES: 
    26 This hint requires that you have sufficient knowledge of LINUX in general, and  
    27 PAM in particular. 
    28 shadow-4.0.3 or shadow-4.0.11.1 or 4.0.12 (at this moment the latest).  
    29 For the option runas=root to work, you'll need these.  
    30 Other versions of shadow (4.0.4.1 and 4.0.7) are causing problems. In the  
    31 code of login of these versions, root privileges are dropped too early  
    32 (before the pam_close_session call). 
    33  
     40This hint requires sufficient knowledge of LINUX in general, and scripts in particular. 
    3441 
    3542HINT: 
    3643 
    37 1. Use scripts at begin and end of a session: introduction 
    38 ----------------------------------------------------------------------------- 
    39  
    40 When using modern Linux systems, you can use your account on more  
    41 systems to login. This is possible with LDAP, nss-ldap and pam-ldap. 
    42 But every machine has it's own settings for kde for example, so you can't  
    43 take your settings with you, just like "roamingprofiles". 
    44  
    45 I started to look for a sollution to solve this, and with PAM and a module pam_script, 
    46 this was possible. 
    47  
    48 When looking at PAM for Linux, it has the ability to use a loadable plugin, which will  
    49 take care for retrieving settings from a central network host when a session opens,  
    50 and storing the same settings to the same host when a sessions closes. 
    51  
    52 This is not possible for a standard PAM installation. There is no standard pam module 
    53 which will execute scripts in general.  But there is a module, developed seperately,  
    54 pam_script, which will do this. 
    55  
    56 Later I discovered that I could use this construction for more purposes: 
    57 - browsing the network using FUSE, fusesmb using the credentials provided at login;  
    58 - start dbus-launcher per session/user and make environmentvariables available; 
    59  
    60  
    61  
    62 2. Installing the software 
    63 -------------------------- 
    64  
    65  
    66 2.1 pam_script 
    67 -------------- 
    68  
     44Content: 
     451. KDM: the files 
     462. PAM: the files 
     472.1 Installation of pam_script 
     482.2 Adjusting pam configuration 
     492.3 Creating the onauth script 
     50 
     51 
     521. KDM: the files 
     53----------------- 
     54 
     55KDM uses some files to start and stop: 
     56 
     57. Xstartup  
     58run as root, after a user succesfully logs in.  
     59 
     60. Xsession 
     61runs with permissions of the authorized user, to start the desired session (KDE). 
     62 
     63. Xreset 
     64run as root, after the user session has ended. 
     65 
     66Where Xstartup is the place to start things up, Xreset is the place to undo these commands. 
     67 
     68For more information about these files look at the handbook of KDM. 
     69 
     70By adding the following code to the Xstartup file: 
     71 
     72 
     73-- snip -- 
     74 
     75for script in /etc/session.d/kdm/startup/*.sh; do 
     76 
     77        if [ -x $script ]; then 
     78         
     79                eval $script $USER 
     80 
     81        fi; 
     82 
     83done; 
     84 
     85 
     86and the code to the Xreset file: 
     87 
     88 
     89-- snip -- 
     90 
     91for script in /etc/session.d/kdm/reset/*.sh; do 
     92 
     93        if [ -x $script ]; then 
     94         
     95                eval $script $USER 
     96 
     97        fi; 
     98 
     99done; 
     100 
     101 
     102Create the directories where the scripts go: 
     103 
     104install -m755 -d /etc/session.d/kdm/startup 
     105install -m755 -d /etc/session.d/kdm/reset 
     106 
     107The files in these directories must be accessible for every ordinary user:  
     108therefore the permissions are 755.  
     109Al scripts in these directories should have the same permissions: 755. 
     110 
     111Every user should be able to execute the script, but only root is able to modify  
     112them. 
     113 
     114 
     1152. PAM: the files 
     116----------------- 
     117 
     118My version of PAM is 0.80.  
     119I using pam-script to make credentials provided at login available for password 
     120sensitive programs like mount.cifs and fusesmb. If this is not what you want, skip  
     121this section.  
     122Also be aware of the "danger" of this construction, as already stated in the  
     123DESCRIPTION. 
     124 
     125 
     1262.1 installation of pam_script 
     127------------------------------ 
    69128 
    70129Get the module pam_script from http://freshmeat.net/projects/pam_script.  
    71 I'm using version 0.1.5
     130I'm using version 0.1.6
    72131 
    73132unpack: 
     
    92151 
    93152 
    94 -- snip -- 
    95  
    96 session         optional        pam_mail.so dir=/var/mail noenv close empty 
    97 session         optional        pam_motd.so 
    98 session         required        pam_unix.so shadow md5 
    99 session         required        pam_script.so runas=root 
    100 session         required        pam_ldap.so 
    101  
    102  
    103153Pam_script has the ability (from version 0.1.5) to get the password provided at login,  
    104154and make this available via an environmentvariable PAM_AUTHTOK to scripts.  
    105155Insert it in the authpart: 
    106156 
    107  
    108157-- snip -- 
    109158 
    110159auth            required        pam_shells.so 
    111 auth            sufficient      pam_unix.so shadow md5 
    112160auth            required        pam_script.so expose=1 
     161auth            sufficient      pam_unix.so use_first_apss 
    113162auth            required        pam_ldap.so use_first_pass 
    114163 
    115  
    116 Note that if the module pam_unix.so succees, pam_script.so is skipped. This no problem for me. On my 
    117 desktop I only want pam_script and the scripts for my normal users, which are in the LDAP database. 
    118 I had to do this, because version 0.1.5 does not ask for a password: another module has to do that.  
    119 That other module is pam_ldap.so or pam_unix.so. 
    120164 
    121165When using other ways for users to login than the standard, like a X-based login as kdm, 
     
    125169cd /etc/pam.d 
    126170 
    127 ls -al 
    128  
    129 drwxr-xr-x   2 root root  392 2005-07-11 13:59 . 
    130 drwxr-xr-x  36 root root 3152 2005-07-19 14:09 .. 
    131 -rw-r--r--   1 root root  253 2004-05-12 16:06 chage 
    132 -rw-r--r--   1 root root   69 2005-01-12 00:20 cups 
    133 -rw-r--r--   1 root root  330 2005-01-19 10:00 fcron 
    134 -rw-r--r--   1 root root  506 2004-12-22 23:04 fcrontab 
    135171lrwxrwxrwx   1 root root    5 2005-07-11 13:59 kde -> login 
    136172lrwxrwxrwx   1 root root    5 2005-07-11 13:59 kde-np -> login 
    137173-rw-r--r--   1 root root  931 2005-07-19 13:20 login 
    138 -rw-r--r--   1 root root  305 2005-07-16 22:46 other 
    139 -rw-r--r--   1 root root  282 2003-08-13 18:22 passwd 
    140 -rw-r--r--   1 root root  411 2003-08-12 17:53 shadow 
    141 -rw-r--r--   1 root root  448 2005-07-18 10:18 su 
    142 -rw-r--r--   1 root root  666 2005-02-28 12:59 sudo 
    143 -rw-r--r--   1 root root  257 2004-05-12 16:05 useradd 
    144 -rw-r--r--   1 root root  200 2005-04-25 09:05 xscreensaver 
    145  
    146174 
    147175 
     
    150178- the pam_script.so uses some parameters. All of them are described in the README in the 
    151179source directory. 
    152 I use expose=1 in the autpart because I want the password to be used by fusesmb. 
    153 And in the sessionpart I use runas=root because some actions (like umount) have to be run as root. 
    154 - when logging out using the normal console, the service is 'login'. Login did not call 
    155 all the modules. I had to add a new parameter to the /etc/login.defs : 
    156  
    157 CLOSE_SESSIONS        yes 
    158  
    159 This option is there already in the shadow package since 2002-10-14, according to the ChangeLog, 
    160 but does not appear in the login.defs, but is important for closing a session when the service is  
    161 login. 
    162 In the newest shadow package (4.0.12) this option is removed completely: the session is always  
    163 closed. 
    164  
    165  
    166  
    167 2.3 Creating the session scripts 
    168 -------------------------------- 
     180I use expose=1 in the autpart because I want the password to be used by fusesmb and mount.cifs. 
     181 
     182 
     1832.3 Creating the onauth script 
     184------------------------------ 
    169185 
    170186 
    171187The pam_script works with two standard scripts, onsessionopen and onsessionclose in the 
    172188/etc/security directory.  
    173          
    174 cat >> /etc/security/onsessionopen << "EOF" 
     189 
     190 
     191cat >> /etc/security/onauth << "EOF" 
    175192#!/bin/bash 
    176193 
     
    181198if [ -z "$userproperties" ]; then 
    182199 
    183         # 
    184         # userproperties not found: something wrong 
    185         # 
    186  
    187         echo "User not found." 
    188         exit 
    189  
    190 fi; 
    191  
    192 nrusers=$(w -h  $userid | wc -l ); 
    193  
    194 firstsession=0; 
    195  
    196 case "$service" in 
    197     login) 
    198         if [ $nrusers -eq 0 ]; then 
    199  
    200             firstsession=1; 
    201  
    202         fi; 
    203         ;; 
    204     kde) 
    205         if [ $nrusers -eq 0 ]; then 
    206  
    207             firstsession=1; 
    208         fi; 
    209         ;; 
    210 esac; 
    211  
    212  
    213  
    214 if [ $firstsession -eq 1 ]; then 
    215  
    216     # There are no other pending sessions for this user 
    217  
    218     if [ -d /var/lib/pam/scripts/onsessionopen ]; then 
    219  
    220         for script in /var/lib/pam/scripts/onsessionopen/*.sh; do 
    221             if [ -x $script ] ; then 
    222                 eval $script $userid 
    223             fi; 
    224         done; 
    225          
    226     fi;  
    227  
    228 fi; 
    229  
    230 EOF 
    231  
    232  
    233  
    234 cat >> /etc/security/onsessionclose << "EOF" 
    235 #!/bin/bash 
    236  
    237 userid=$1 
    238 service=$2 
    239  
    240 userproperties=$(getent passwd | grep -E "^$userid"); 
    241  
    242 if [ -z "$userproperties" ]; then 
    243  
    244         # 
    245         # userproperties not found: something wrong 
    246         # 
    247  
    248         echo "User not found." 
    249         exit 
    250  
    251 fi; 
    252  
    253 nrusers=$(w -h $userid | wc -l ); 
    254  
    255 lastsession=0; 
    256  
    257 case "$service" in 
    258         login) 
    259                 if [ $nrusers -eq 1 ]; then 
    260  
    261                         lastsession=1; 
    262  
    263                 fi; 
    264                 ;; 
    265         kde) 
    266                 if [ $nrusers -eq 0 ]; then 
    267  
    268                         lastsession=1; 
    269                 fi; 
    270                 ;; 
    271 esac; 
    272  
    273  
    274 if [ $lastsession -eq 1 ]; then 
    275  
    276     # This is the last session for this user 
    277  
    278     if [ -d /var/lib/pam/scripts/onsessionclose ]; then 
    279  
    280         for script in /var/lib/pam/scripts/onsessionclose/*.sh ; do 
    281             if [ -x $script ] ; then 
    282                 eval $script $userid 
    283             fi; 
    284         done; 
    285          
    286     fi;  
    287  
    288 fi; 
    289  
    290 EOF 
    291  
    292 cat >> /etc/security/onauth << "EOF" 
    293 #!/bin/bash 
    294  
    295 userid=$1 
    296 service=$2 
    297 userproperties=$(getent passwd | grep -E "^$userid") 
    298  
    299 if [ -z "$userproperties" ]; then 
    300  
    301200    # 
    302201    # userproperties not found: something wrong 
    303202    # 
    304      
     203 
    305204    echo "User not found." 
    306205    exit 
    307      
     206 
    308207fi; 
    309  
    310208 
    311209homedir=$(echo $userproperties | cut -d ":" -f 6); 
     
    315213nrusers=$(w -h $userid | wc -l); 
    316214 
    317 firstsession=0; 
    318  
    319 case "$service" in 
    320  
    321     login) 
    322          
    323         if [ $nrusers -eq 0 ]; then 
    324              
    325             firstsession=1; 
    326              
    327         fi; 
    328         ;; 
    329  
    330     kde) 
    331          
    332         if [ $nrusers -eq 0 ]; then 
    333              
    334             firstsession=1; 
    335              
    336         fi; 
    337         ;; 
    338 esac;        
    339  
    340  
    341 if [ $firstsession -eq 1 ]; then 
    342          
    343     if [ -d /var/lib/pam/scripts ]; then 
    344              
    345         for script in /var/lib/pam/scripts/onauth/*.sh; do 
     215if [ $nrusers -eq 0 ]; then 
     216 
     217    if [ -d /etc/session.d/pam ]; then 
     218 
     219        for script in /etc/session.d/pam/onauth/*.sh; do 
    346220         
    347221            if [ -x $script ]; then 
    348                  
     222 
    349223                eval $script $userid $service $PAM_AUTHTOK 
    350                  
     224 
    351225            fi; 
    352226        done; 
     
    357231 
    358232exit 0 
     233 
    359234EOF 
    360235 
    361  
    362 chown root:root /etc/security/onsession* 
    363 chmod 755 /etc/security/onsession* 
    364236chown root:root /etc/security/onauth 
    365237chmod 755 /etc/security/onauth 
     
    368240Create the following directories: 
    369241 
    370 mkdir -p /var/lib/pam/scripts/onsessionopen 
    371 mkdir -p /var/lib/pam/scripts/onsessionclose 
    372 mkdir -p /var/lib/pam/scripts/onauth 
     242mkdir -p /etc/session.d/pam/onauth 
    373243 
    374244Here is where the scripts will go. 
     
    389259in, please let me know. 
    390260 
    391 - Sudo in needed. 
    392 in the examples 'sudo' is used. This is not difficult. Sudo does not have to support PAM. 
    393 That's not neccasary. It's only needed to execute a command as normal user when the id is root. 
    394  
    395 - Some remarks about the behaviour of the command "w" 
    396 The number of sessions is zero when logging in: the user is still not logged in. This  
    397 happens with all the services I'm using: login and kdm. 
    398 When logging out, something strange happens: it's one when logging out when the service  
    399 is 'login', zero when service is "kde" (and this user is not logged in on any other way). 
    400 I've just discovered what's causing this. The program "login" is responsible. It stores a 
    401 record in the utmp-database with the pid of the login-proces (the parent), not the pid of the  
    402 shell (the child). When the session is closed, the proces with the pid stored in the  
    403 utmp database isn't closed at all. That's the login program itself, which is still running. 
    404 So, when using "w" to check the users logged in, it finds that the proces with the pid in the  
    405 utmp database for this user is still running, it concludes this user must still be logged in, which is not 
    406 the case.<br> 
    407 I've posted a message about this issue on the maillinglist op shadow.  
    408 (http://lists.pld.org.pl/mailman/pipermail/shadow/2005-October/thread.html) 
    409  
    410 - I choose to execute the scripts only when it's the first time a user logs in, or the 
    411 last time he/she logs out. It's also possible to leave that to the scripts (in /var/lib/pam/scripts). 
    412  
    413  
    414  
    415  
    416 3. Examples 
    417  
    418  
    419 3.1 Scripts for storing and retrieving my kde-settings on a central server 
    420 -------------------------------------------------------------------------- 
    421  
    422  
    423 When using modern Linux systems, you can use your account on more  
    424 systems to login. This is possible with LDAP, nss-ldap and pam-ldap. 
    425 But every machine has it's own settings for kde for example, so you can't  
    426 take your settings with you, just like "roamingprofiles". 
    427  
    428 I started to look for a sollution to solve this, and with PAM and a module pam_script, 
    429 this was possible. 
    430  
    431 First the script to get the settings from the central rsync server: 
    432  
    433  
    434 cd /var/lib/pam/scripts/onsessionopen 
    435  
    436 cat >> kde.sh << "EOF" 
    437 #!/bin/bash 
    438  
    439 retcode=0; 
    440  
    441 userid=$1 
    442 userproperties=$(getent passwd | grep -E "^$userid") 
    443 homedir=$(echo $userproperties | cut -d ":" -f 6); 
    444 gidnr=$(echo $userproperties | cut -d ":" -f 4); 
    445 uidnr=$(echo $userproperties | cut -d ":" -f 3); 
    446  
    447  
    448 if [ -d $homedir ]; then 
    449  
    450         usershareavailable=$(rsync 192.168.0.3::4users | grep -w $userid ); 
    451  
    452         retcode=$? 
    453  
    454         if [ $retcode -eq 0 ]; then 
    455  
    456                 # 
    457                 # no error 
    458                 # 
    459  
    460                 if [ -z "$usershareavailable" ]; then 
    461  
    462                         # 
    463                         # directory for this user does not exist 
    464                         # 
    465                         # maybe a default? 
    466                         # 
    467  
    468                         echo "No directory on rsyncserver available for this user." 
    469  
    470                 else 
    471  
    472                         thereisarchive=$(rsync 192.168.0.3::4users/$userid/.kde | grep -w ".kde"); 
    473  
    474                         retcode=$? 
    475  
    476                         if [ $retcode -eq 0 ]; then 
    477  
    478                                 if [ -n "$thereisarchive" ]; then 
    479  
    480                                         # 
    481                                         # no error & archive found 
    482                                         # 
    483  
    484                                         rsync -rptgozu 192.168.0.3::4users/$userid/.kde/ $homedir/.kde 
    485  
    486                                         chown -R $uidnr:$gidnr $homedir/.kde 
    487  
    488                                 else 
    489  
    490                                         echo "No kde-settings for this user available on rsyncserver." 
    491                                 fi; 
    492  
    493                         fi; 
    494                 fi; 
    495         fi; 
    496 fi; 
    497  
    498 if [ $retcode -ne 0 ]; then 
    499         echo "An error with the rsynccommando for kde ($retcode)." 
    500 fi; 
    501  
    502 exit $retcode 
    503  
    504 EOF 
    505  
    506 And the logout script: 
    507  
    508 cd ../onsessionclose 
    509  
    510 cat >> kde.sh << "EOF" 
    511 #!/bin/bash 
    512  
    513 retcode=0; 
    514  
    515 userid=$1 
    516 userproperties=$(getent passwd | grep -E "^$userid") 
    517 homedir=$(echo $userproperties | cut -d ":" -f 6); 
    518 gidnr=$(echo $userproperties | cut -d ":" -f 4); 
    519 uidnr=$(echo $userproperties | cut -d ":" -f 3); 
    520  
    521 if [ -d $homedir/.kde ]; then 
    522          
    523         # 
    524         # there is something to sync 
    525         # 
    526  
    527         usershareavailable=$(rsync 192.168.0.3::4users | grep -w $userid ); 
    528  
    529         retcode=$? 
    530  
    531         if [ $retcode -eq 0 ]; then 
    532  
    533                 # 
    534                 # no error 
    535                 # 
    536  
    537                 if [ -z "$usershareavailable" ]; then 
    538  
    539                         # 
    540                         # directory for this user does not exist yet 
    541                         # 
    542                         # a trick to create a directory on the rsyncserver 
    543  
    544                         mkdir /tmp/$userid 
    545  
    546                         rsync -dptgoz /tmp/$userid 192.168.0.3::4users 
    547  
    548                         rmdir /tmp/$userid 
    549  
    550                 fi; 
    551  
    552                 if [ $retcode -eq 0 ]; then 
    553  
    554                         # 
    555                         # no error found 
    556                         # 
    557  
    558                         rsync -rptgoz --delete $homedir/.kde 192.168.0.3::4users/$userid 
    559  
    560                         retcode=$? 
    561  
    562                 fi; 
    563         fi; 
    564 fi; 
    565  
    566 if [ $retcode -ne 0 ]; then 
    567         echo "An error with the rsynccommando for kde ($retcode)." 
    568 fi 
    569  
    570 exit $retcode 
    571  
    572 EOF 
    573  
    574 Notes: 
    575  
    576 - see the difference between the rsync commando for login and logout.  
    577 First the -u flag at login and not logout. 
    578 I don't want newer files get overwritten on login. When due to some reason  
    579 the settings are not saved properly, the most recent settings are still on the 
    580 workstation and not on the server. You don't want them to be overwritten. That's 
    581 reason for the -u flag at login. Not at logout. Why? Good question.  
    582 Now the --delete flag at logout. 
    583 Obvious, you don't want that there are still files on the server, which are not  
    584 there (anymore?) on the workstation. 
    585  
    586 - Storing settings on a central server can become very complicated when one user is  
    587 logged on more than one machine at the same time. There is now way to  
    588 'merge' the settings. The setting saved at the last logout are the ones which  
    589 will remain on the server. Windows uses the same strategy. 
    590  
    591 - These scripts are for the settings of kde. But this is just an example. 
    592 You can put any script ( with the .sh extension ) 
    593 in this directory. The bookmarks of Firefox for example. 
    594  
    595 The rsyncserver is hosted at 192.168.0.3, with a share [4users]. This share 
    596 can be accessed without credentials: public access. Making it work with  
    597 user-based access is not so simple. The rsyncdaemon does not support pam yet.  
    598 This could work when shell for transport is ssh. Work to be done. 
    599  
    600 As you can see I use the rsync algoritm, but you can use also a 
    601 ftp server with write-access. The big advantage of rsync however  
    602 is the efficient way it handles (non)changes. 
    603  
    604 This way it looks at the way Windows workstations handle settings:  
    605 when there is a [profiles] share, the server supports "roamingprofiles". 
    606 I think the way the saving en getting the "profile" at these  
    607 Windows machines looks a lot like rsync for Linux. 
    608  
    609  
    610  
    611 3.2 Browsing the network using FUSE, fusesmb and pam_storepw 
    612 ------------------------------------------------------------ 
    613  
    614 Very new is FUSE. At this moment the FUSE package contains a kernelmodule, a library and utilities. 
    615 Soon the module will be standard in the kernel. For more information see the website of course.<br> 
    616 Pam_script has the ability (from version 0.1.5) to get the password provided at login, and provide 
    617 this via an evironmentvariable PAM_AUTHTOK to scripts. A script for fusesmb can write this value to 
    618 a configurationfile (~/.smb/fusesmb.conf) to browse the network with the credentials provided at login. 
    619  
    620 Get it from the projectsite: 
    621  
    622 http://fuse.sourceforge.net 
    623  
    624 Installing FUSE: 
    625  
    626 cd fuse-2.3.0 
    627 ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-kernel-module --enable-lib --enable-util 
    628 make 
    629 make install 
    630  
    631 A module is installed, fuse. 
    632 To load it: 
    633  
    634 modprobe fuse 
    635  
    636 and add it to /etc/sysconfig/modules. 
    637  
    638 Configuration of fuse goes via the fuse.conf file in the /etc directory: 
    639  
    640 cat >> /etc/fuse.conf << "EOF" 
    641  
    642 mount_max = 999 
    643  
    644 user_allow_other 
    645 EOF 
    646  
    647 Get fusesmb: 
    648  
    649 Look for a link at the site of FUSE. 
    650  
    651 Installing fusesmb: 
    652  
    653 cd fusesmb-0.8.1 
    654 ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var 
    655 make 
    656 make install 
    657  
    658 It requires samba-3.0.*. 
    659 With samba-3.0.14a it works fine. Not with samba-3.0.20 at this moment. Check the website for more info. 
    660  
    661  
    662 Now the actual scripts: 
    663  
    664 cd /var/lib/pam/onsessionopen 
    665  
    666 cat >> fusesmb.sh << "EOF" 
    667 #!/bin/bash 
    668  
    669 retcode=0; 
    670  
    671 userid=$1 
    672 userproperties=$(getent passwd | grep -E "^$userid") 
    673 homedir=$(echo $userproperties | cut -d ":" -f 6); 
    674 gidnr=$(echo $userproperties | cut -d ":" -f 4); 
    675 uidnr=$(echo $userproperties | cut -d ":" -f 3); 
    676  
    677 if [ -d $homedir ]; then 
    678  
    679     if [ ! -d $homedir/network ]; then 
    680         mkdir -p $homedir/network 
    681         chown $uidnr:$gidnr $homedir/network 
    682     fi 
    683  
    684     if [ $(id -u) -eq 0 ]; then 
    685         sudo -H -u $userid /bin/sh -c "fusesmb $homedir/network -o fsname=fusesmb,default_permissions,allow_other" 
    686         retcode=$? 
    687     elif [ $(id -u) -eq $uidnr ]; then  
    688         fusesmb $homedir/network -o fsname=fusesmb,default_permissions,allow_other 
    689         retcode=$? 
    690     fi   
    691      
    692 fi; 
    693  
    694  
    695 if [ $retcode -ne 0 ]; then 
    696     echo "An error with fusesmb ($retcode)." 
    697 fi; 
    698  
    699 exit $retcode 
    700 EOF 
    701  
    702 And the logout script: 
    703  
    704 cd ../onsessionclose 
    705  
    706 cat >> fusesmb.sh << "EOF" 
    707 #!/bin/bash 
    708  
    709 retcode=0; 
    710  
    711 userid=$1 
    712 userproperties=$(getent passwd | grep -E "^$userid") 
    713 homedir=$(echo $userproperties | cut -d ":" -f 6); 
    714 gidnr=$(echo $userproperties | cut -d ":" -f 4); 
    715 uidnr=$(echo $userproperties | cut -d ":" -f 3); 
    716  
    717 if [ -d $homedir ]; then 
    718  
    719     if [ -n "$(mount | grep $homedir/network)" ]; then 
    720  
    721         fusermount -u $homedir/network 
    722  
    723     fi; 
    724      
    725     if [ -e $homedir/.smb/fusesmb.conf ]; then 
    726      
    727         rm -f $homedir/.smb/fusesmb.conf 
    728      
    729     fi; 
    730  
    731 fi; 
    732  
    733  
    734 if [ $retcode -ne 0 ]; then 
    735     echo "An error with fusesmb ($retcode)." 
    736 fi; 
    737  
    738 exit $retcode 
    739 EOF 
    740  
    741  
    742 And the onauth script: 
    743  
    744 cat >> /var/pam/scripts/onauth/fusesmb.sh << "EOF" 
    745 #!/bin/bash 
    746  
    747 retcode=0; 
    748  
    749 userid=$1 
    750 service=$2 
    751 authtok=$3 
    752  
    753 userproperties=$(getent passwd | grep -E "^$userid") 
    754 homedir=$(echo $userproperties | cut -d ":" -f 6); 
    755 gidnr=$(echo $userproperties | cut -d ":" -f 4); 
    756 uidnr=$(echo $userproperties | cut -d ":" -f 3); 
    757  
    758 if [ -d $homedir ]; then 
    759  
    760  
    761         if [ ! -d $homedir/.smb ]; then 
    762  
    763             mkdir -p $homedir/.smb 
    764             chown $uidnr:$gidnr $homedir/.smb 
    765             chmod 755 $homedir/.smb 
    766  
    767         fi 
    768  
    769         if [ -n "$authtok" ]; then 
    770  
    771             rm -f $homedir/.smb/fusesmb.conf 
    772  
    773             touch $homedir/.smb/fusesmb.conf 
    774             chown $uidnr:$gidnr $homedir/.smb/fusesmb.conf 
    775             chmod 600 $homedir/.smb/fusesmb.conf 
    776  
    777             echo "[global]" > $homedir/.smb/fusesmb.conf 
    778             echo "username = $userid" >> $homedir/.smb/fusesmb.conf 
    779             echo "password = $authtok" >> $homedir/.smb/fusesmb.conf 
    780      
    781         fi; 
    782  
    783 fi; 
    784  
    785  
    786 if [ $retcode -ne 0 ]; then 
    787     echo "An error with fusesmb ($retcode)." 
    788 fi; 
    789  
    790 exit $retcode 
    791 EOF 
    792  
    793  
    794 Notes: 
    795  
    796 - The fusesmb script in the onauth directory overwrites any existing fusesmb.conf in the ~/.smb  
    797 directory. I do not have any simple sollution to do otherwise. One way to do that is the use of  
    798 a template. In this template the variables username and password get inserted with 'sed'. 
    799  
    800  
    801  
    802 3.3 Starting the sessiondaemon of dbus and make the environmentvariables available 
    803 ---------------------------------------------------------------------------------- 
    804  
    805 The dbus package is split up in two parts: one systemwide part and one for (each) session/user. 
    806 The systemwide part (a daemon) is started at boottime, with special privileges of a dedicated user. 
    807 The sessionwide part (also a daemon) has to started when a session for a user begins,  
    808 and stopped when the session ends. 
    809  
    810 The construction with pam I'm using here is ideal for this. Create a script in the login directory to 
    811 start the sessiondaemon for a user, running with the privileges of that user. In the logout directory an  
    812 other script has to stop that daemon. 
    813 But is not so simple as that. Some variables (DBUS_SESSION_BUS_ADDRESS and DBUS_SESSION_BUS_PID) have to  
    814 be available in the environment to every application which works with dbus.  
    815 IMHO the setting of these variables should go in the bash-startupscripts. 
    816 Then whatever script or application you're running, these variables are set 
    817 to the right value.  
    818  
    819 Bash Shell startupfiles 
    820 ----------------------- 
    821  
    822  
    823                      global             user 
    824                  ------------------------------ 
    825                       
    826                  /etc/bashrc          ~/.bashrc 
    827                  /etc/profile         ~/.bash_profile 
    828                  /etc/profile.d       no equivalent 
    829                   
    830 When bash is started by "login" as an interactive login shell, it reads /etc/profile and ~/.bash_profile. 
    831 Bash is also started by "kdm", and the files /etc/profile and ~/.bash_profile are sourced. 
    832  
    833 The sessionwide environmentvariables can't go in the /etc/profile.d directory, because it differs for every user.  
    834 There is no equivalent in de homedirectory in startup of BASH in BLFS at this moment. My idea 
    835 is to create a .profile.d directory in the homedirectory of a user, containing scripts which has 
    836 to be executed when a BASH session is started for that user. 
    837  
    838 By adding the following code to the $HOME/.bash_profile at the end of it any script with the .sh extension 
    839 will be executed for this user only: 
    840  
    841 -- snip -- 
    842  
    843 for script in $HOME/.profile.d/*.sh ; do 
    844         if [ -x $script ]; then 
    845                 . $script 
    846         fi 
    847 done 
    848  
    849 -- snip -- 
    850  
    851 Now create as a user in his/her homedirectory: 
    852  
    853 mkdir $HOME/.profile.d 
    854  
    855  
    856 Compiling and installing it is described in the latest versions of BLFS  
    857 (beginning 200510..).  
    858  
    859 I assume that dbus is installed, and that it is started at boottime. 
    860  
    861 Create a script in the onsessionopen directory dbus.sh: 
    862  
    863 cd /var/lib/pam/onsessionopen 
    864  
    865 cat >> dbus.sh << "EOF" 
    866 #!/bin/bash 
    867  
    868 retcode=0; 
    869  
    870 userid=$1 
    871 userproperties=$(getent passwd | grep -E "^$userid") 
    872 homedir=$(echo $userproperties | cut -d ":" -f 6); 
    873 gidnr=$(echo $userproperties | cut -d ":" -f 4); 
    874 uidnr=$(echo $userproperties | cut -d ":" -f 3); 
    875  
    876 if [ -d $homedir ]; then 
    877  
    878     if [ -d $homedir/.profile.d ]; then 
    879          
    880         if [ $(id -u) -eq 0 ]; then 
    881             sudo -u $userid /bin/sh -c "dbus-launch --auto-syntax > $homedir/.profile.d/dbus.sh" 
    882             retcode=$? 
    883             chown $uidnr:$gidnr $homedir/.profile.d/dbus.sh 
    884             chmod u+x $homedir/.profile.d/dbus.sh 
    885         elif [ $(id -u) -eq $uidnr ]; then  
    886             dbus-launch --auto-syntax > $homedir/.profile.d/dbus.sh 
    887             retcode=$? 
    888             chmod u+x $homedir/.profile.d/dbus.sh 
    889         fi 
    890         retcode=$? 
    891  
    892     fi 
    893  
    894 fi; 
    895  
    896  
    897 if [ $retcode -ne 0 ]; then 
    898     echo "An error with dbus ($retcode)." 
    899 fi; 
    900  
    901 exit $retcode 
    902 EOF 
    903  
    904 This script will start the dbus session daemon for this user, and will create a dbus.sh script in the .profile.d 
    905 directory of this user.  
    906  
    907 Creating the dbus.sh script in the logout directory: 
    908  
    909 cd ../onsessionclose 
    910  
    911 cat >> dbus.sh << "EOF" 
    912 #!/bin/bash 
    913  
    914 retcode=0; 
    915  
    916 userid=$1 
    917 userproperties=$(getent passwd | grep -E "^$userid") 
    918 homedir=$(echo $userproperties | cut -d ":" -f 6); 
    919 gidnr=$(echo $userproperties | cut -d ":" -f 4); 
    920 uidnr=$(echo $userproperties | cut -d ":" -f 3); 
    921  
    922 if [ -d $homedir ]; then 
    923  
    924     if [ -d $homedir/.profile.d ]; then 
    925          
    926         if [ -f $homedir/.profile.d/dbus.sh ]; then 
    927             . $homedir/.profile.d/dbus.sh 
    928             if [ -n "$DBUS_SESSION_BUS_PID" ]; then 
    929                 if [ $(id -u) -eq 0 ]; then 
    930                     sudo -H -u $userid /bin/sh -c "kill $DBUS_SESSION_BUS_PID" 
    931                     retcode=$? 
    932                     rm $homedir/.profile.d/dbus.sh 
    933                 elif [ $(id -u) -eq $uidnr ]; then 
    934                     kill $DBUS_SESSION_BUS_PID 
    935                     retcode=$? 
    936                     rm $homedir/.profile.d/dbus.sh 
    937                 fi         
    938             fi 
    939         fi 
    940     fi 
    941  
    942 fi; 
    943  
    944  
    945 if [ $retcode -ne 0 ]; then 
    946     echo "An error with dbus ($retcode)." 
    947 fi; 
    948  
    949 exit $retcode 
    950 EOF 
    951  
    952 Now when bash is started, the dbus.sh script in the $HOME/.profile.d is found and executed 
    953 by $HOME/.bash_profile.  
     261- I choose to execute the script only when it's the first time a user logs in. 
     262It's also possible to leave that to the scripts (in /etc/session.d/pam/). 
     263 
     264- pam_script is able to execute scripts when a sessions starts, and when is ends  
     265(pam_script calls it onsessionopen and onsessionclose).  
     266I've used this, but not anymore. These scripts I now put in /etc/session.d/kdm/startup and  
     267/etc/session.d/kdm/reset. 
     268 
    954269 
    955270 
    956271ACKNOWLEDGEMENTS: 
    957 Thanks to the author of pam_script, Izak Burger. 
     272  * Thanks to the author of pam_script, Izak Burger, for his module and  
     273    some usefull hints. 
    958274 
    959275CHANGELOG: 
    960 [2005-07-18
     276[2006-01-15
    961277  * Initial hint. 
    962 [2005-07-20] 
    963   * Some text changes: things could be explained better 
    964   * remove the -f parameter in the 'last' command. It works now with the standard 
    965     /var/log/wtmp file. The /var/run/utmp file was not so reliable after all. 
    966   * added the --delete flag to the rsync commando at logout.  
    967   * added the -u flag when getting the settings at login.  
    968   * added more comment on saving and restoring settings in a mutiuser/multihost (wow!) 
    969     environment. 
    970 [2005-07-27] 
    971   * Use the command 'w' to determine how many times a user is logged in on the 
    972     system in stead of 'last'. 
    973   * Correction of some phrases: incorrect English.  
    974 [2005-08-10] 
    975   * added some comment about the version of shadow to use. Some versions caused 
    976     problems. 
    977   * corrected some typos. 
    978   * added some comment about the option runas=root which can be very insecure      
    979 [2005-08-23] 
    980   * moved the scriptdirectory to a central place (/var/lib/sync4settings) in stead of 
    981     the homedirectory. This was very insecure. 
    982     The scripts have to handle a general $userid. 
    983     Created a central map on the resyncserver [4users] where the settings are stored 
    984     Added a check what the service is at logout: kdm or login. The command 'w' gives  
    985     different output.  
    986     Added comment about the removal of the option "CLOSE_SESSIONS" in version 4.0.12  
    987     of the shadow package. 
    988 [2005-09-27] 
    989   * moved the scriptdirectory to /var/lib/pam/scripts in stead of 
    990     /var/lib/sync4settings. 
    991   * to execute a script use the command "eval". 
    992   * more comment. 
    993 [2005-09-29] 
    994   * Changed the name of the hint: Execute scripts at begin and end of a usersession using PAM  
    995   * added two examples: fusesmb and dbus. 
    996 [2005-10-21] 
    997   * Use sudo in stead of su to execute scripts as a normal user 
    998   * Use pam_script-0.1.5. The important change in this version is the ability to make the  
    999     authtentification tokens available to the scripts. This means that I do not have to use 
    1000     the module pam_storepw anymore. 
    1001     Added the onauth script in /etc and the /var/lib/pam/scripts/onauth directory.  
    1002   * 
    1003  
    1004  
    1005 TODO: 
    1006  
    1007   * look for some way to show information about progres and/or errors when executing 
    1008     the scripts when using a graphical login. xconsole? 
    1009   * add another example like mounting shares with mount.cifs. 
    1010   * what to do when system crashes at the next reboot? 
    1011   * 'shutdown' does close the shellsessions properly. Why? 
    1012  
    1013 DONE: 
    1014   * find out why runas=root does not work with pam_script at logout for me: 
    1015     all the credits should go to the maintainer of pam_script.