aboutsummaryrefslogtreecommitdiffstats
path: root/src/logging
blob: 65b31041aabe728e805c59676ce1853e0f7f49ca (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/bin/sh

# cerberus-logging – Log-in logging extension for cerberus
# 
# Copyright © 2014  Mattias Andrée (maandree@member.fsf.org)
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


# Login username, client hostname if non-local, ttyname, cerberus-hook and PID
username=
hostname=
ttyname="$(tty <&2 | cut -d / -f 1,2 --complement)"
hook="${1}"
pid=$PPID
if [ ! "${LOGIN_PID}" = "" ]; then
    pid="${LOGIN_PID}"
fi
# Remove the hookname from $@
shift 1

# Parse the command line, excluding the hookname
# This is the arguments cerberus was spawned with
hostname_on_next=0
dash=0
for arg in "$@"; do
    if [ "${arg}" = "" ]; then
	true
    elif [ "${arg::1}" = "-" ] && [ ${dash} = 0 ]; then
	arg="${arg:1}"
	while [ ! "${arg}" = "" ]; do
	    c="${arg::1}"
	    arg="${arg:1}"
	    if [ "${c}" = "h" ]; then # hostname
		if [ ! "${arg}" = "" ]; then
		    hostname="${arg}"
		else
		    hostname_on_next=1
		fi
		break
	    elif [ "${c}" = "f" ]; then # force
		if [ ! "${arg}" = "" ]; then
		    username="${arg}"
		fi
		break
	    elif [ "${c}" = "-" ]; then # username
		dash=1
		break
	    fi
	done
    elif [ ${hostname_on_next} = 1 ]; then
	hostname="${arg}"
	hostname_on_next=0
    else
	username="${arg}"
    fi
done
user="${username}"

# Execute a program only if it exists
try ()
{
    if hash "${1}" 2>/dev/null; then
	"$@"
    fi
}
# Call logging programs (those that exists) for a successful login action
log_login ()
{
    # This is useful if you want to print the last logging.
    # log-login-lastlog updates the entry in lastlog so it is helpful
    # to be able to print the log entry before the is updated. Its lets
    # you add a script named .prelogin in your home directory that
    # contains the following code, to print the last login information:
    #    echo 'Last login:' ; lastlog --user $USER | tail -n 1
    script="$(getent passwd | grep "^${user}:" | cut -d : -f 6)/.prelogin"
    if [ -x "${script}" ]; then
	su -c "${script}" -- "${user}"
    fi
    
    try log-login-utmp "$@"
    try log-login-audit "$@"
    try log-login-lastlog "$@"
    try log-login-syslog "$@"
}
# Call logging programs (those that exists) for a logout action
log_logout ()
{
    true
}
# Call logging programs (those that exists) for a failed login action
log_denied ()
{
    try log-login-btmp "$@"
    try log-login-audit "$@"
    try log-login-syslog "$@"
}

# Figure out the actionname
action="${hook}"
if [ "${hook}" = denied ]; then
    action=failed
fi

# Preprend options to values
action=--action="${action}"
username=--username="${username}"
ttyname=--ttyname="${ttyname}"
pid=--pid="${pid}"

# Call the logging programs
if [ "${hook}" = login ] || [ "${hook}" = logout ] || [ "${hook}" = denied ]; then
    if [ "${hostname}" = "" ]; then
	"log_${hook}" "${action}" "${username}" "${ttyname}" "${pid}"
    else
	"log_${hook}" "${action}" "${username}" "${ttyname}" "${pid}" --hostname="${hostname}"
    fi
fi