HOWTO execute scripts at begin and end of a usersession using PAM with examples. |
||
|---|---|---|
| Prev | Chapter Building, installing and configuration of pam_script |
Next |
tar -xzf pam-script-*.tar.gz cd pam-script-* make mv pam_script.so /lib/security chown root:root /lib/security/pam_script.so chmod 755 /lib/security/pam_script.so |
The module is stacked in the sessionpart:
cat /etc/pam.d/login -- snip -- session optional pam_mail.so dir=/var/mail noenv close empty session optional pam_motd.so session required pam_script.so runas=root session required pam_unix.so shadow md5 session required pam_ldap.so |
Pam_script has the ability (from version 0.1.5) to get the password provided at login, and make
this via an evironmentvariable PAM_AUTHTOK available to scripts.
Insert it in the authpart:
cat /etc/pam.d/login -- snip -- auth required pam_shells.so auth sufficient pam_unix.so shadow md5 auth required pam_script.so expose=1 auth required pam_ldap.so use_first_pass |
Note that if the module pam_unix.so succees, pam_script.so is skipped. This no problem for me. On my
desktop I only want pam_script and the scripts for my normal users, which are in the LDAP database.
I had to do this, because version 0.1.5 does not ask for a password: another module has to do that.
That other module is pam_ldap.so or pam_unix.so.
When using other ways for users to login than the standard, like a X-based login as kdm,
adjust them the same way. On my machine I login frequently with kdm, and that uses the
kde-service, which is a symlink to the login-service:
cd /etc/pam.d
ls -al
drwxr-xr-x 2 root root 392 2005-07-11 13:59 .
drwxr-xr-x 36 root root 3152 2005-07-19 14:09 ..
-rw-r--r-- 1 root root 253 2004-05-12 16:06 chage
-rw-r--r-- 1 root root 69 2005-01-12 00:20 cups
-rw-r--r-- 1 root root 330 2005-01-19 10:00 fcron
-rw-r--r-- 1 root root 506 2004-12-22 23:04 fcrontab
lrwxrwxrwx 1 root root 5 2005-07-11 13:59 kde -> login
lrwxrwxrwx 1 root root 5 2005-07-11 13:59 kde-np -> login
-rw-r--r-- 1 root root 931 2005-07-19 13:20 login
-rw-r--r-- 1 root root 305 2005-07-16 22:46 other
-rw-r--r-- 1 root root 282 2003-08-13 18:22 passwd
-rw-r--r-- 1 root root 411 2003-08-12 17:53 shadow
-rw-r--r-- 1 root root 448 2005-07-18 10:18 su
-rw-r--r-- 1 root root 666 2005-02-28 12:59 sudo
-rw-r--r-- 1 root root 257 2004-05-12 16:05 useradd
-rw-r--r-- 1 root root 200 2005-04-25 09:05 xscreensaver
|
- the pam_script.so uses some parameters. All of them are described in the README in the
source directory.
I use expose=1 in the authpart because I want the password to be used by fusesmb.
And in the sessionpart I use runas=root because some actions (like umount) have to be run as root.
- to make use of the module I had to reorder the auth-part. The module pam_script has to become
after pam_unix or pam_ldap, but before pam_ldap.
Pam_script.so works with three scripts, standard onsessionopen, onsessionclose and onauth in the
/etc/security directory.
The onsessionopen script looks like:
cat >> /etc/security/onsessionopen << "EOF"
#!/bin/bash
userid=$1
service=$2
userproperties=$(getent passwd | grep -E "^$userid");
if [ -z "$userproperties" ]; then
#
# userproperties not found: something wrong
#
echo "User not found."
exit
fi;
nrusers=$(w -h $userid | wc -l );
firstsession=0;
case "$service" in
login)
if [ $nrusers -eq 0 ]; then
firstsession=1;
fi;
;;
kde)
if [ $nrusers -eq 0 ]; then
firstsession=1;
fi;
;;
esac;
if [ $firstsession -eq 1 ]; then
# There are no other sessions for this user: this is the first
if [ -d /var/lib/pam/scripts/onsessionopen ]; then
for script in /var/lib/pam/scripts/onsessionopen/*.sh ; do
if [ -x $script ] ; then
eval $script $userid $
fi;
done;
fi;
fi;
EOF
|
The onsessionclose script:
cat >> /etc/security/onsessionclose << "EOF"
#!/bin/bash
userid=$1
service=$2
userproperties=$(getent passwd | grep -E "^$userid");
if [ -z "$userproperties" ]; then
#
# userproperties not found: something wrong
#
echo "User not found."
exit
fi;
nrusers=$(w -h $userid | wc -l );
lastsession=0;
case "$service" in
login)
if [ $nrusers -eq 1 ]; then
lastsession=1;
fi;
;;
kde)
if [ $nrusers -eq 0 ]; then
lastsession=1;
fi;
;;
esac;
if [ $lastsession -eq 1 ]; then
# This is the last session for this user
if [ -d /var/lib/pam/scripts/onsessionclose ]; then
for script in /var/lib/pam/scripts/onsessionclose/*.sh ; do
if [ -x $script ] ; then
eval $script $userid
fi;
done;
fi;
fi;
EOF
|
The onauth script:
cat >> /etc/security/onauth << "EOF"
#!/bin/bash
userid=$1
service=$2
userproperties=$(getent passwd | grep -E "^$userid")
if [ -z "$userproperties" ]; then
#
# userproperties not found: something wrong
#
echo "User not found."
exit
fi;
homedir=$(echo $userproperties | cut -d ":" -f 6);
gidnr=$(echo $userproperties | cut -d ":" -f 4);
uidnr=$(echo $userproperties | cut -d ":" -f 3);
nrusers=$(w -h $userid | wc -l);
firstsession=0;
case "$service" in
login)
if [ $nrusers -eq 0 ]; then
firstsession=1;
fi;
;;
kde)
if [ $nrusers -eq 0 ]; then
firstsession=1;
fi;
;;
esac;
if [ $firstsession -eq 1 ]; then
if [ -d /var/lib/pam/scripts ]; then
for script in /var/lib/pam/scripts/onauth/*.sh; do
if [ -x $script ]; then
eval $script $userid $service $PAM_AUTHTOK
fi;
done;
fi;
fi;
exit 0
|
Set permissions and rwx bits right:
chown root:root /etc/security/onsession* chmod 755 /etc/security/onsession* chown root:root /etc/security/onauth chmod 755 /etc/security/onauth |
These scripts can also be downloaded from:
Create the directories where the scripts will go:
mkdir -p /var/lib/pam/scripts/onsessionopen mkdir -p /var/lib/pam/scripts/onsessionclose mkdir -p /var/lib/pam/scripts/onauth |
The construction is now ready to execute sessionscripts at login and logout. But this still does nothing: there are no
scripts in the open and the close directory. There are some examples of scripts I'm using on my system.
- as you can see I use the command "w" to determine the users logged in.
Other utilities as who, users and last gave not reliable information. It
looks as if the utmp file is not always presenting the right values.
Utilities as who,users and last show information from utmp without any check, so
they inherit the faults. 'w' does some extra checking, which makes it more
usable.
Other pammodules, like pam_mount, have other
ways to keep track of the amount of logins per user. With pam_mount, a seperate file (/var/run/pam_mount/$userid)
is created for this purpose.
Anyone knowing a better way to determine how many times a user is logged
in, please let me know.
- in the examples 'sudo' is used. This is not included in the BLFS 6.1 book, so you have to install it yourself.
Sources available at the homepage of sudo.
This is not difficult. Sudo does not have to support PAM. That's not neccasary.
It's only needed to execute a command as normal user when the id is root.
The number of sessions is zero
when logging in: the user is still not logged in. This happens with all the services I'm using: login
and kde.
When logging out, something strange happens: it's one when logging out when the service is 'login',
zero when service is "kde" (and this user is not logged in on any other way).
I've just discovered what's causing this. The program "login" is responsible. It stores a
record in the utmp-database with the pid of the login-proces (the parent), not the pid of the
shell (the child). When the session is closed, the proces with the pid stored in the
utmp database isn't closed at all. That's the login program itself, which is still running.
So, when using "w" to check the users logged in, it finds that the proces with the pid in the
utmp database for this user is still running, it concludes this user must still be logged in, which is not
the case.
I've posted a message about this issue on the maillinglist op shadow.
| Prev | Up | Next |