Imported Debian patch 1.5-10.1
This commit is contained in:
parent
6236f92ec8
commit
642d4c9ea8
7
Makefile
7
Makefile
|
@ -1,6 +1,9 @@
|
|||
CFLAGS=-fomit-frame-pointer -m486 -O2 -s
|
||||
CFLAGS=-fomit-frame-pointer -O2 -s -g -Wall
|
||||
timeoutd: timeoutd.c Makefile
|
||||
$(CC) $(CFLAGS) -o timeoutd timeoutd.c
|
||||
#$(CC) $(CFLAGS) -o timeoutd timeoutd.c
|
||||
$(CC) $(CFLAGS) -o timeoutd.o -c timeoutd.c -DTIMEOUTDX11
|
||||
$(CC) $(CFLAGS) -o timeoutd -L/usr/X11R6/lib timeoutd.o -lXss -lXext
|
||||
|
||||
|
||||
install:
|
||||
install -o root -g system -m 2111 timeoutd /usr/etc/timeoutd
|
||||
|
|
4
README
4
README
|
@ -1,4 +1,4 @@
|
|||
TIMEOUTD 1.4 by Shane Alderton
|
||||
TIMEOUTD 1.5 by Shane Alderton
|
||||
|
||||
Timeoutd is a programme which allows you to control the following
|
||||
characteristics on a user by user and/or group by group basis for
|
||||
|
@ -41,4 +41,4 @@ line in /etc/profile near the top of the file:
|
|||
|
||||
|
||||
Please sends bugs, comments, suggestions to:
|
||||
shane@ion.apana.org.au (Shane Alderton)
|
||||
shanea@bigpond.net.au (Shane Alderton)
|
||||
|
|
122
debian/changelog
vendored
Normal file
122
debian/changelog
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
timeoutd (1.5-10.1) unstable; urgency=low
|
||||
|
||||
* Non-maintainer upload.
|
||||
* Added LSB formatted dependency info in init.d script (closes: #468919)
|
||||
* Removed redundant debian/init.d file
|
||||
|
||||
-- Peter Eisentraut <petere@debian.org> Wed, 02 Apr 2008 02:15:25 +0200
|
||||
|
||||
timeoutd (1.5-10) unstable; urgency=low
|
||||
|
||||
* Updating build depencies due to xlibs-dev: Closes: #346924
|
||||
* Thanks Mark Hindley for patches: Closes: #347780
|
||||
o Don't crash when X server is not contactable
|
||||
o Recognise remote X sessions
|
||||
o XCloseDisplay to free resources
|
||||
o Rename shutdown() to prevent conflict with netdb.h
|
||||
|
||||
-- Dennis Stampfer <seppy@debian.org> Fri, 20 Jan 2006 20:39:25 +0100
|
||||
|
||||
timeoutd (1.5-9) unstable; urgency=low
|
||||
|
||||
* Removed "-m486" because it breaks builds on other archs.
|
||||
Closes: #231522
|
||||
|
||||
-- Dennis Stampfer <seppy@debian.org> Mon, 1 Mar 2004 20:56:13 +0100
|
||||
|
||||
timeoutd (1.5-8) unstable; urgency=low
|
||||
|
||||
* timeoutd now complains in logs when segfaulting
|
||||
* Improofed SSH-Handling
|
||||
- Wait a few secs to read message before logging out
|
||||
* No more warnings when compiling
|
||||
* Now depends on xlibs
|
||||
- timeoutd is able to querry X for idle time. Closes: #222287
|
||||
* Improofed description
|
||||
* Corrected debian/copyright
|
||||
* Conforms to Standards version 3.6.1
|
||||
|
||||
-- Dennis Stampfer <seppy@debian.org> Fri, 2 Jan 2004 00:11:09 +0100
|
||||
|
||||
timeoutd (1.5-7) unstable; urgency=low
|
||||
|
||||
* Upstream author's adress outdated. Changed address.
|
||||
* Restrictions are now possible for users running X.
|
||||
* telnet sessions are handled like tty. Closes: #194917
|
||||
* ssh restrictions are possible from now on.
|
||||
* Conforms to Standards version 3.6.0
|
||||
|
||||
-- Dennis Stampfer <seppy@debian.org> Sun, 01 Jun 2003 16:27:00 +0200
|
||||
|
||||
timeoutd (1.5-6) unstable; urgency=low
|
||||
|
||||
* timeoutd runs now also when a X-Session is running. Closes: #191575
|
||||
* Conforms to Standards version 3.5.9.0
|
||||
|
||||
-- Dennis Stampfer <seppy@debian.org> Sat, 10 May 2003 15:28:35 +0200
|
||||
|
||||
timeoutd (1.5-5) unstable; urgency=low
|
||||
|
||||
* New Maintainer. Closes: #158333
|
||||
* Conforms to Standards version 3.5.8.0
|
||||
* Improved description.
|
||||
|
||||
-- Dennis Stampfer <synrg-sponsoring-seppy@gluck.debian.org> Wed, 4 Dec 2002 18:32:37 +0100
|
||||
|
||||
timeoutd (1.5-4) unstable; urgency=low
|
||||
|
||||
* QA upload.
|
||||
* Package is orphaned (see #158333); set maintainer to Debian QA Group.
|
||||
* timeoutd.c:
|
||||
- Determine utmp field sizes with sizeof instead of using traditional
|
||||
values. Closes: #52456.
|
||||
- Open terminal device with O_NONBLOCK. Closes: #30980.
|
||||
- Do `chdir("/dev")' to avoid `device busy' errors when the filesystem
|
||||
from which we were started is unmounted.
|
||||
- Fix some more warnings.
|
||||
* timeouts: Add format summary. Closes: #126543.
|
||||
* Drop dump_wtmp -- last(1) is so much better. Closes: #22775.
|
||||
* Why was timeoutd setgid root? It must be run as root anyway to kill
|
||||
other users' processes...
|
||||
* Add build dependencies. Closes: #95039.
|
||||
* Switch from debstd to debhelper.
|
||||
* debian/copyright:
|
||||
- Note that the upstream URL is outdated and that the author's e-mail
|
||||
bounces. Closes: #131085.
|
||||
- Refer to /usr/share/common-licenses/GPL.
|
||||
* debian/init.d: Update from current /etc/init.d/skeleton. Uses a delay
|
||||
between starting and stopping. Closes: #30979.
|
||||
* debian/README.debian: Everything already said in copyright; remove.
|
||||
* debian/changelog: Remove obsolete Emacs local variables.
|
||||
* Conforms to Standards version 3.5.6.
|
||||
|
||||
-- Matej Vela <vela@debian.org> Thu, 29 Aug 2002 04:26:45 +0200
|
||||
|
||||
timeoutd (1.5-3) unstable; urgency=low
|
||||
|
||||
* Non-Maintainer upload
|
||||
* rebuild to move /usr/doc to /usr/share/doc (Closes: #91677)
|
||||
* indented Description
|
||||
* updated FSF address in copyright
|
||||
* marked init.d script as conffile
|
||||
* added isp flags to dpkg-gencontrol to create Section: and Priority:
|
||||
fields
|
||||
* tweaked init.d script to provide a force-reload
|
||||
* upped standards version
|
||||
|
||||
-- Stephen Stafford <bagpuss@debian.org> Sat, 21 Apr 2001 22:26:37 +0100
|
||||
|
||||
timeoutd (1.5-2) unstable; urgency=low
|
||||
|
||||
* recompiled for libc6
|
||||
* now includes dump_wtmp binary
|
||||
* cleaned up some compiler warnings
|
||||
* added reload and restart args to /etc/init.d/timeoutd
|
||||
|
||||
-- Craig Sanders <cas@taz.net.au> Sat, 8 Nov 1997 13:18:47 +1100
|
||||
|
||||
timeoutd (1.5-1) unstable; urgency=low
|
||||
|
||||
* Initial Release.
|
||||
|
||||
-- Craig Sanders <cas@taz.net.au> Sat, 22 Feb 1997 15:20:11 +1100
|
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
4
|
25
debian/control
vendored
Normal file
25
debian/control
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
Source: timeoutd
|
||||
Section: admin
|
||||
Priority: extra
|
||||
Maintainer: Dennis Stampfer <seppy@debian.org>
|
||||
Standards-Version: 3.6.2
|
||||
Build-Depends: debhelper (>= 4), libx11-dev, libxss-dev
|
||||
|
||||
Package: timeoutd
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}
|
||||
Conflicts: suidmanager (<< 0.50)
|
||||
Description: Flexible user timeout daemon with X11 support
|
||||
timeoutd enforces the time restrictions specified for each or all users.
|
||||
.
|
||||
timeoutd scans /var/run/utmp every minute and checks /etc/timeouts for
|
||||
an entry which matches a restricted user, based on:
|
||||
.
|
||||
- The current day and time
|
||||
- The tty that the user is currently logged in on
|
||||
- The user's login ID
|
||||
- Any primary or secondary groups the user is in
|
||||
timeoutd can restrict local users, X11-users and users via telnet/SSH
|
||||
for a maximum of their session, max. day, idle or no login at all.
|
||||
.
|
||||
timeoutd is also able to restrict users running X.
|
36
debian/copyright
vendored
Normal file
36
debian/copyright
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
This package was debianized by Craig Sanders <cas@taz.net.au> on
|
||||
Sat, 22 Feb 1997 15:20:11 +1100.
|
||||
|
||||
It is maintained by Dennis Stampfer <seppy@debian.org> since
|
||||
Wed, 4 Dec 2002 18:32:37 +0100
|
||||
|
||||
It was downloaded from ion.apana.org.au. Unfortunately, this address is
|
||||
outdated. It is not developed upstream anymore.
|
||||
|
||||
Author: Shane Alderton <shanea@bigpond.net.au>
|
||||
|
||||
Copyright 1997 Shane Alderton
|
||||
|
||||
Maintainers worked on timeoutd for Debian:
|
||||
1997 Craig Sanders
|
||||
2001 Stephen Stafford
|
||||
2002 Matej Vela
|
||||
2002-2006 Dennis Stampfer
|
||||
|
||||
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 2 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
On Debian systems, the complete text of the GNU General Public License
|
||||
can be found in /usr/share/common-licenses/GPL.
|
||||
|
64
debian/rules
vendored
Executable file
64
debian/rules
vendored
Executable file
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/make -f
|
||||
# Sample debian/rules that uses debhelper.
|
||||
# This file is public domain software, originally written by Joey Hess.
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
build:
|
||||
$(MAKE) timeoutd
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
|
||||
# Add here commands to clean up after the build process.
|
||||
rm -f timeoutd timeoutd.o
|
||||
|
||||
dh_clean
|
||||
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_clean -k
|
||||
dh_installdirs
|
||||
|
||||
# Add here commands to install the package into debian/<packagename>
|
||||
dh_install
|
||||
|
||||
# Build architecture-independent files here.
|
||||
binary-indep: build install
|
||||
# We have nothing to do by default.
|
||||
|
||||
# Build architecture-dependent files here.
|
||||
binary-arch: build install
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_installchangelogs
|
||||
dh_installdocs
|
||||
# dh_installexamples
|
||||
# dh_installmenu
|
||||
# dh_installdebconf
|
||||
# dh_installlogrotate
|
||||
# dh_installemacsen
|
||||
# dh_installpam
|
||||
# dh_installmime
|
||||
dh_installinit
|
||||
# dh_installcron
|
||||
# dh_installinfo
|
||||
# dh_undocumented
|
||||
dh_installman
|
||||
# dh_link
|
||||
dh_strip
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
# dh_makeshlibs
|
||||
dh_installdeb
|
||||
# dh_perl
|
||||
dh_shlibdeps
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install
|
1
debian/timeoutd.docs
vendored
Normal file
1
debian/timeoutd.docs
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
README
|
51
debian/timeoutd.init.d
vendored
Normal file
51
debian/timeoutd.init.d
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
#! /bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: timeoutd
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: start and stop the user timeout daemon
|
||||
### END INIT INFO
|
||||
#
|
||||
# Based on skeleton 1.9.1 by Miquel van Smoorenburg <miquels@cistron.nl>.
|
||||
|
||||
DAEMON=/usr/sbin/timeoutd
|
||||
NAME=timeoutd
|
||||
DESC="user timeout daemon"
|
||||
|
||||
test -x $DAEMON || exit 0
|
||||
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Starting $DESC: $NAME"
|
||||
start-stop-daemon --start --oknodo --quiet --exec $DAEMON
|
||||
echo "."
|
||||
;;
|
||||
stop)
|
||||
echo -n "Stopping $DESC: $NAME"
|
||||
start-stop-daemon --stop --oknodo --quiet --exec $DAEMON
|
||||
echo "."
|
||||
;;
|
||||
reload|force-reload)
|
||||
echo -n "Reloading $DESC configuration..."
|
||||
start-stop-daemon --stop --signal 1 --quiet --exec $DAEMON
|
||||
echo "done."
|
||||
;;
|
||||
restart)
|
||||
echo -n "Restarting $DESC: $NAME"
|
||||
start-stop-daemon --stop --oknodo --quiet --exec $DAEMON
|
||||
sleep 1
|
||||
start-stop-daemon --start --quiet --exec $DAEMON
|
||||
echo "."
|
||||
;;
|
||||
*)
|
||||
N=/etc/init.d/$NAME
|
||||
echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
2
debian/timeoutd.install
vendored
Normal file
2
debian/timeoutd.install
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
timeoutd usr/sbin
|
||||
timeouts etc
|
1
debian/timeoutd.manpages
vendored
Normal file
1
debian/timeoutd.manpages
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
timeoutd.8 timeouts.5
|
45
timeoutd.8
45
timeoutd.8
|
@ -2,11 +2,13 @@
|
|||
.SH NAME
|
||||
timeoutd \- Enforce idle and session time restrictions
|
||||
.SH SYNOPSIS
|
||||
.B /usr/etc/timeoutd [ user tty ]
|
||||
.B /usr/sbin/timeoutd [ user tty ]
|
||||
.SH DESCRIPTION
|
||||
.I timeoutd enforces the time restrictions specified in /usr/etc/timeouts.
|
||||
.B timeoutd
|
||||
enforces the time restrictions specified in
|
||||
.IR /etc/timeouts .
|
||||
When invoked in daemon mode (without any parameters) timeoutd backgrounds
|
||||
itself, then scans \fB/etc/utmp\fR every minute and checks /usr/etc/timeouts
|
||||
itself, then scans \fB/var/run/utmp\fR every minute and checks \fB/etc/timeouts\fR
|
||||
for an entry which matches that user, based on:
|
||||
.IP "\- The current day and time"
|
||||
.IP "\- The tty that the user is currently logged in on"
|
||||
|
@ -14,12 +16,19 @@ for an entry which matches that user, based on:
|
|||
.IP "\- Any primary or secondary groups the user is in"
|
||||
.PP
|
||||
If a match is found, the limits specified for that entry are enforced by
|
||||
sending a SIGHUP (Hangup signal) to the user's login process, followed
|
||||
after 5 seconds by a SIGKILL (Sure kill signal) to ensure the user is
|
||||
sending a
|
||||
.B SIGHUP
|
||||
(Hangup signal) to the user's login process, followed
|
||||
after 5 seconds by a
|
||||
.B SIGKILL
|
||||
(Sure kill signal) to ensure the user is
|
||||
logged out.
|
||||
.PP
|
||||
Where possible, timeoutd will send a warning to the user
|
||||
every minute for 5 minutes (or other time specified in /usr/etc/timeouts)
|
||||
Where possible,
|
||||
.B timeoutd
|
||||
will send a warning to the user
|
||||
every minute for 5 minutes (or other time specified in
|
||||
.IR /etc/timeouts )
|
||||
before logging them out. Warnings are not sent for exceeded idle limits,
|
||||
as this would count as activity on the terminal.
|
||||
.PP
|
||||
|
@ -28,19 +37,24 @@ of time logged in per session and per day.
|
|||
.PP
|
||||
When calculating idle time, any activity on the terminal, either incoming
|
||||
(such as typing) or outgoing (such as information displayed on the screen)
|
||||
is counted as activity. This is to prevent logoffs during file transfers.
|
||||
is counted as activity. This is to prevent log-offs during file transfers.
|
||||
.PP
|
||||
Under Linux, timeoutd detects when a serial line is in SLIP mode and disables
|
||||
Under Linux,
|
||||
.B timeoutd
|
||||
detects when a serial line is in SLIP mode and disables
|
||||
idle time limit checking (as the last read/write times for the tty are
|
||||
not updated).
|
||||
.PP
|
||||
Debug information, error messages and notification of users who have been
|
||||
timed out are all recorded via syslog (facility=DAEMON).
|
||||
.PP
|
||||
Timeoutd can also be invoked by login to check whether a user is allowed
|
||||
.B timeoutd
|
||||
can also be invoked by login to check whether a user is allowed
|
||||
to login at that time, or whether they have exceeded their daily time limit.
|
||||
When invoked in this way, by passing a username and tty (without the leading
|
||||
/dev) on the command line, timeoutd returns one of the following exit codes:
|
||||
/dev) on the command line,
|
||||
.B timeoutd
|
||||
returns one of the following exit codes:
|
||||
.IP "0 User is allowed to login
|
||||
.IP "1 Fatal error
|
||||
.IP "5 Incorrect command line format
|
||||
|
@ -48,9 +62,9 @@ When invoked in this way, by passing a username and tty (without the leading
|
|||
.IP "20 User not permitted to login at this time on this tty
|
||||
.IP "30 Internal error checking user name (probably invalid user name)
|
||||
.SH FILES
|
||||
.IP "/usr/etc/timeouts \- lists valid login times and idle/session time restrictions
|
||||
.IP "/etc/utmp \- current login sessions
|
||||
.IP "/usr/adm/wtmp \- for calculating total logged in time for current day
|
||||
.IP "/etc/timeouts \- lists valid login times and idle/session time restrictions
|
||||
.IP "/var/run/utmp \- current login sessions
|
||||
.IP "/var/log/wtmp \- for calculating total logged in time for current day
|
||||
.SH BUGS
|
||||
Sessions which end in the current day but started before midnight
|
||||
will not be considered when calculating total daily logged in time for a
|
||||
|
@ -61,4 +75,5 @@ by one extra session if they log on just before midnight.
|
|||
.SH "SEE ALSO"
|
||||
.BR timeouts "(5)
|
||||
.SH "WRITTEN BY"
|
||||
Shane Alderton <shane@ion.apana.org.au>
|
||||
Orginally written by Shane Alderton <shanea@bigpond.net.au>, updated by
|
||||
Dennis Stampfer <seppy@debian.org>.
|
||||
|
|
562
timeoutd.c
562
timeoutd.c
|
@ -22,11 +22,16 @@
|
|||
programme upon which this programme was based.
|
||||
|
||||
*/
|
||||
/* #define DEBUG _DEBUG_ */
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <utmp.h>
|
||||
#include <pwd.h>
|
||||
|
@ -36,6 +41,17 @@
|
|||
#include <ctype.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#ifdef TIMEOUTDX11
|
||||
#include <netdb.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/scrnsaver.h>
|
||||
|
||||
#define TIMEOUTD_XSESSION_NONE 0
|
||||
#define TIMEOUTD_XSESSION_LOCAL 1
|
||||
#define TIMEOUTD_XSESSION_REMOTE 2
|
||||
#endif
|
||||
|
||||
#define OPENLOG_FLAGS LOG_CONS|LOG_PID
|
||||
#define SYSLOG_DEBUG LOG_DEBUG
|
||||
|
@ -93,7 +109,7 @@ struct utmp *getutent() /* returns next utmp file entry */
|
|||
#endif
|
||||
|
||||
#ifndef CONFIG
|
||||
#define CONFIG "/usr/etc/timeouts"
|
||||
#define CONFIG "/etc/timeouts"
|
||||
#endif
|
||||
|
||||
#define MAXLINES 512
|
||||
|
@ -104,6 +120,7 @@ struct utmp *getutent() /* returns next utmp file entry */
|
|||
#define SESSMAX 3
|
||||
#define DAYMAX 4
|
||||
#define NOLOGIN 5
|
||||
/*#define XSESSION 6*/
|
||||
#define IDLEMSG 0
|
||||
#define SESSMSG 1
|
||||
#define DAYMSG 2
|
||||
|
@ -119,14 +136,31 @@ char daynums[] = { 1 , 2 , 4 , 8 , 16 , 32 , 64 , 62 , 127, 0};
|
|||
struct utmp *utmpp; /* pointer to utmp file entry */
|
||||
char *ctime(); /* returns pointer to time string */
|
||||
struct utmp *getutent(); /* returns next utmp file entry */
|
||||
void shutdown();
|
||||
void shut_down();
|
||||
void read_config();
|
||||
void reread_config();
|
||||
void reapchild();
|
||||
void free_wtmp();
|
||||
void check_idle();
|
||||
void read_wtmp();
|
||||
void bailout();
|
||||
char chk_timeout();
|
||||
void logoff_msg();
|
||||
void killit();
|
||||
int getdisc();
|
||||
int chk_xsession(); /* seppy: is it a X-Session? */
|
||||
void killit_xsession(); /* seppy: kill the X-Session*/
|
||||
int chk_ssh(pid_t pid); /* seppy: check if user is logged in via ssh (we have to
|
||||
handle that different... ;( */
|
||||
char *getusr(pid_t pid); /*seppy: get the owner of a running process */
|
||||
void segfault(); /* seppy: catch segfault and log them */
|
||||
int chk_xterm(); /* seppy: is it a xterm? */
|
||||
pid_t getcpid(); /* seppy: get the child's pid. Needed for ssh */
|
||||
|
||||
#ifdef TIMEOUTDX11
|
||||
Time get_xidle(); /* seppy: how long is user idle? (user,display)*/
|
||||
#endif
|
||||
|
||||
|
||||
struct ut_list {
|
||||
struct utmp elem;
|
||||
|
@ -157,8 +191,8 @@ struct config_ent {
|
|||
|
||||
struct config_ent *config[MAXLINES + 1];
|
||||
char errmsg[256];
|
||||
char dev[24];
|
||||
char limit_type;
|
||||
char dev[sizeof(utmpp->ut_line)];
|
||||
unsigned char limit_type;
|
||||
int configline = 0;
|
||||
int pending_reread = 0;
|
||||
int allow_reread = 0;
|
||||
|
@ -166,6 +200,9 @@ time_t time_now;
|
|||
struct tm now;
|
||||
int now_hhmm;
|
||||
int daytime = 0; /* Amount of time a user has been on in current day */
|
||||
char path[255]; /*seppy*/
|
||||
FILE *proc_file;/*seppy*/
|
||||
char comm[16]; /*seppy; to save the command of a pid*/
|
||||
|
||||
#ifdef NEED_STRCASECMP
|
||||
int strcasecmp(char *s1, char *s2)
|
||||
|
@ -216,15 +253,16 @@ char *delim;
|
|||
}
|
||||
#endif
|
||||
|
||||
main(argc, argv)
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
signal(SIGTERM, shutdown);
|
||||
signal(SIGTERM, shut_down);
|
||||
signal(SIGHUP, reread_config);
|
||||
signal(SIGCHLD, reapchild);
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGQUIT, SIG_IGN);
|
||||
signal(SIGSEGV, segfault);
|
||||
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
|
||||
|
@ -240,15 +278,29 @@ char *argv[];
|
|||
/* read config file into memory */
|
||||
read_config();
|
||||
|
||||
/* Change into the root filesystem to avoid "device busy" errors when the
|
||||
* filesystem from which we were started is unmounted. /dev is convenient as
|
||||
* ut_line fields are relative to it.
|
||||
*/
|
||||
if (chdir("/dev"))
|
||||
{
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_ERR, "Could not change working directory to /dev!");
|
||||
closelog();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Handle the "timeoutd user tty" invocation */
|
||||
/* This is a bit of a shameless hack, but, well, it works. */
|
||||
if (argc == 3)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "Running in user check mode. Checking user %s on %s.", argv[1], argv[2]);
|
||||
closelog();
|
||||
strcpy(dev, "/dev/");
|
||||
strcat(dev, argv[2]);
|
||||
#endif
|
||||
strncpy(dev, argv[2], sizeof(dev) - 1);
|
||||
dev[sizeof(dev) - 1] = '\0';
|
||||
time_now = time((time_t *)0); /* get current time */
|
||||
now = *(localtime(&time_now)); /* Break it into bits */
|
||||
now_hhmm = now.tm_hour * 100 + now.tm_min;
|
||||
|
@ -280,10 +332,12 @@ char *argv[];
|
|||
logoff_msg(1);
|
||||
exit(20);
|
||||
case ACTIVE:
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "User %s on %s passed login check.", argv[1], argv[2]);
|
||||
free_wtmp();
|
||||
closelog();
|
||||
#endif
|
||||
free_wtmp();
|
||||
exit(0);
|
||||
default:
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
|
@ -317,18 +371,22 @@ char *argv[];
|
|||
allow_reread = 0;
|
||||
read_wtmp(); /* Read in today's wtmp entries */
|
||||
setutent();
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "Time to check utmp for exceeded limits.");
|
||||
closelog();
|
||||
#endif
|
||||
while ((utmpp = getutent()) != (struct utmp *) NULL)
|
||||
check_idle();
|
||||
free_wtmp(); /* Free up memory used by today's wtmp entries */
|
||||
allow_reread = 1;
|
||||
if (pending_reread)
|
||||
reread_config(SIGHUP);
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "Finished checking utmp... sleeping for 1 minute.");
|
||||
closelog();
|
||||
#endif
|
||||
sleep(60);
|
||||
}
|
||||
}
|
||||
|
@ -340,18 +398,21 @@ void read_wtmp()
|
|||
FILE *fp;
|
||||
struct utmp ut;
|
||||
struct tm *tm;
|
||||
char user[9];
|
||||
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "Reading today's wtmp entries.");
|
||||
closelog();
|
||||
#endif
|
||||
|
||||
if ((fp = fopen(WTMP_FILE, "r")) == NULL)
|
||||
bailout("Could not open wtmp file!", 1);
|
||||
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "Seek to end of wtmp");
|
||||
closelog();
|
||||
#endif
|
||||
/* Go to end of file minus one structure */
|
||||
fseek(fp, -1L * sizeof(struct utmp), SEEK_END);
|
||||
|
||||
|
@ -381,18 +442,22 @@ void read_wtmp()
|
|||
if (fseek(fp, -2 * sizeof(struct utmp), SEEK_CUR) < 0) break;
|
||||
}
|
||||
fclose(fp);
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "Finished reading today's wtmp entries.");
|
||||
closelog();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Free up memory used by today's wtmp entries */
|
||||
|
||||
void free_wtmp()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "Freeing list of today's wtmp entries.");
|
||||
closelog();
|
||||
#endif
|
||||
|
||||
while (wtmplist)
|
||||
{
|
||||
|
@ -413,9 +478,11 @@ void free_wtmp()
|
|||
wtmplist = wtmplist->next;
|
||||
free(ut_list_p);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "Finished freeing list of today's wtmp entries.");
|
||||
closelog();
|
||||
#endif
|
||||
}
|
||||
|
||||
void store_times(t, time_str)
|
||||
|
@ -488,7 +555,7 @@ char *time_str;
|
|||
}
|
||||
te->starttime = atoi(p);
|
||||
te->endtime = atoi(p+5);
|
||||
if (te->starttime == 0 && strncmp(p, "0000-", 5) || te->endtime == 0 && strcmp(p+5, "0000"))
|
||||
if ((te->starttime == 0 && strncmp(p, "0000-", 5)) || (te->endtime == 0 && strcmp(p+5, "0000")))
|
||||
{
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_ERR, "Invalid range (%s) in time field of config file (%s). Entry ignored.", p, CONFIG);
|
||||
|
@ -517,13 +584,15 @@ char *b;
|
|||
else strcpy(*a, b);
|
||||
}
|
||||
|
||||
read_config()
|
||||
void read_config()
|
||||
{
|
||||
FILE *config_file;
|
||||
char *p;
|
||||
char *lstart;
|
||||
int i = 0;
|
||||
#ifdef DEBUG
|
||||
int j = 0;
|
||||
#endif
|
||||
char line[256];
|
||||
char *tok;
|
||||
int linenum = 0;
|
||||
|
@ -578,17 +647,17 @@ read_config()
|
|||
if (tok != NULL)
|
||||
{
|
||||
config[i]->idlemax = atoi(tok);
|
||||
if (p = strchr(tok, ';')) alloc_cp(&config[i]->messages[IDLEMSG], p+1);
|
||||
if ((p = strchr(tok, ';')) != NULL) alloc_cp(&config[i]->messages[IDLEMSG], p+1);
|
||||
}
|
||||
if ((tok = strsep(&lstart, ":")) != NULL)
|
||||
{
|
||||
config[i]->sessmax = atoi(tok);
|
||||
if (p = strchr(tok, ';')) alloc_cp(&config[i]->messages[SESSMSG], p+1);
|
||||
if ((p = strchr(tok, ';')) != NULL) alloc_cp(&config[i]->messages[SESSMSG], p+1);
|
||||
}
|
||||
if ((tok = strsep(&lstart, ":")) != NULL)
|
||||
{
|
||||
config[i]->daymax = atoi(tok);
|
||||
if (p = strchr(tok, ';')) alloc_cp(&config[i]->messages[DAYMSG], p+1);
|
||||
if ((p = strchr(tok, ';')) != NULL) alloc_cp(&config[i]->messages[DAYMSG], p+1);
|
||||
}
|
||||
if ((tok = strsep(&lstart, ":")) != NULL)
|
||||
{
|
||||
|
@ -646,13 +715,13 @@ struct time_ent *te;
|
|||
while (te->days)
|
||||
{
|
||||
if (daynums[now.tm_wday] & te->days && /* Date within range */
|
||||
(te->starttime <= te->endtime && /* Time within range */
|
||||
((te->starttime <= te->endtime && /* Time within range */
|
||||
now_hhmm >= te->starttime &&
|
||||
now_hhmm <= te->endtime
|
||||
||
|
||||
te->starttime > te->endtime &&
|
||||
(now_hhmm >= te->starttime ||
|
||||
now_hhmm <= te->endtime)
|
||||
||
|
||||
(te->starttime > te->endtime &&
|
||||
(now_hhmm >= te->starttime ||
|
||||
now_hhmm <= te->endtime))
|
||||
)
|
||||
)
|
||||
return 1;
|
||||
|
@ -666,7 +735,6 @@ char *element;
|
|||
char *in_set;
|
||||
{
|
||||
char *t;
|
||||
char *q;
|
||||
char *set = (char *) malloc(strlen(in_set) + 1);
|
||||
|
||||
if (set == NULL) bailout("Out of memory", 1);
|
||||
|
@ -771,18 +839,43 @@ fprintf(stderr, "%s has been logged in for %d minutes today.\n", user, daytime);
|
|||
return;
|
||||
}
|
||||
|
||||
void warnpending(tty, time_remaining)
|
||||
void warnpending(tty, time_remaining, user, host)
|
||||
char *tty;
|
||||
int time_remaining;
|
||||
char *user;
|
||||
char *host;
|
||||
{
|
||||
int fd;
|
||||
FILE *ttyf;
|
||||
FILE *msgfile = NULL;
|
||||
char cmdbuf[1024];
|
||||
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "Warning user on %s of pending logoff in %d minutes.",
|
||||
tty, time_remaining);
|
||||
syslog(SYSLOG_DEBUG, "Warning %s@%s on %s of pending logoff in %d minutes.",
|
||||
user, host, tty, time_remaining);
|
||||
closelog();
|
||||
if ((ttyf = fopen(tty, "w")) == NULL)
|
||||
#endif
|
||||
|
||||
if(chk_xsession(tty, host)) {
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "Warning %s running X on %s for pending logout! (%d min%s left)", user, tty, time_remaining, time_remaining==1?"":"s");
|
||||
closelog();
|
||||
|
||||
/* then send the message using xmessage */
|
||||
/* well, this is not really clean: */
|
||||
sprintf(cmdbuf, "su %s -c \"xmessage -display %s -center 'WARNING: You will be logged out in %d minute%s when your %s limit expires.'&\"", user, tty, time_remaining, time_remaining==1?"":"s", limit_names[limit_type]);
|
||||
system(cmdbuf);
|
||||
/*#ifdef DEBUG*/
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_DEBUG, "cmdbuf=%s", cmdbuf);
|
||||
closelog();
|
||||
/*#endif*/
|
||||
sleep(KWAIT); /* and give the user some time to read the message ;) */
|
||||
return;
|
||||
}
|
||||
|
||||
if ((fd = open(tty, O_WRONLY|O_NOCTTY|O_NONBLOCK)) < 0 ||
|
||||
(ttyf = fdopen(fd, "w")) == NULL)
|
||||
{
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_ERR, "Could not open %s to warn of impending logoff.\n",tty);
|
||||
|
@ -808,7 +901,7 @@ int session;
|
|||
char ttymatch = 0;
|
||||
char usermatch = 0;
|
||||
char groupmatch = 0;
|
||||
char *tty = dev + 5; /* Skip over the /dev/ */
|
||||
char *tty = dev;
|
||||
char **p;
|
||||
int disc;
|
||||
|
||||
|
@ -830,9 +923,11 @@ int session;
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "Checking user %s group %s tty %s.", user, gr->gr_name, tty);
|
||||
closelog();
|
||||
#endif
|
||||
|
||||
/* Check to see if current user matches any entry based on tty/user/group */
|
||||
while (config[configline])
|
||||
|
@ -866,11 +961,13 @@ printf("Group %s member %s\n", secgr->gr_name, *p);
|
|||
if (timematch && ttymatch && usermatch && groupmatch)
|
||||
{
|
||||
get_day_time(user);
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "Matched entry %d", configline);
|
||||
syslog(SYSLOG_DEBUG, "Idle=%d (max=%d) Sess=%d (max=%d) Daily=%d (max=%d) warntime=%d", idle, config[configline]->idlemax, session, config[configline]->sessmax, daytime, config[configline]->daymax, config[configline]->warntime);
|
||||
closelog();
|
||||
disc = getdisc(dev);
|
||||
#endif
|
||||
disc = getdisc(dev, host);
|
||||
|
||||
limit_type = NOLOGINMSG;
|
||||
if (!config[configline]->login_allowed)
|
||||
|
@ -891,12 +988,12 @@ printf("Group %s member %s\n", secgr->gr_name, *p);
|
|||
/* If none of those have been exceeded, then warn users of upcoming logouts */
|
||||
limit_type = DAYMSG;
|
||||
if (config[configline]->daymax > 0 && daytime >= config[configline]->daymax - config[configline]->warntime)
|
||||
warnpending(dev, config[configline]->daymax - daytime);
|
||||
warnpending(dev, config[configline]->daymax - daytime, user, host);
|
||||
else
|
||||
{
|
||||
limit_type = SESSMSG;
|
||||
if (config[configline]->sessmax > 0 && session >= config[configline]->sessmax - config[configline]->warntime)
|
||||
warnpending(dev, config[configline]->sessmax - session);
|
||||
warnpending(dev, config[configline]->sessmax - session, user, host);
|
||||
}
|
||||
|
||||
/* Otherwise, leave the poor net addict alone */
|
||||
|
@ -909,35 +1006,71 @@ printf("Group %s member %s\n", secgr->gr_name, *p);
|
|||
return ACTIVE;
|
||||
}
|
||||
|
||||
check_idle() /* Check for exceeded time limits & logoff exceeders */
|
||||
void check_idle() /* Check for exceeded time limits & logoff exceeders */
|
||||
{
|
||||
char user[12];
|
||||
char host[17];
|
||||
char user[sizeof(utmpp->ut_user)];
|
||||
char host[sizeof(utmpp->ut_host)];
|
||||
struct stat status, *pstat;
|
||||
time_t idle, start, sesstime, time();
|
||||
time_t idle, sesstime, time();
|
||||
short aktconfigline = -1; /* -1 if user is in config; >0 if he's not in config, * is handled in an other way */
|
||||
|
||||
pstat = &status; /* point to status structure */
|
||||
#ifndef SUNOS
|
||||
if (utmpp->ut_type != USER_PROCESS || !utmpp->ut_user[0]) /* if not user process */
|
||||
return(0); /* skip the utmp entry */
|
||||
return; /* skip the utmp entry */
|
||||
#endif
|
||||
strncpy(user, utmpp->ut_user, 8); /* get user name */
|
||||
user[8] = '\0'; /* null terminate user name string */
|
||||
strncpy(host, utmpp->ut_host, 16); /* get host name */
|
||||
host[16] = '\0';
|
||||
strcpy(dev, "/dev/"); /* add "/dev/" directory prefix */
|
||||
strcat(dev, utmpp->ut_line); /* append basename of port */
|
||||
if (stat(dev, pstat)) /* if can't get status for port */
|
||||
strncpy(user, utmpp->ut_user, sizeof(user) - 1); /* get user name */
|
||||
user[sizeof(user) - 1] = '\0'; /* null terminate user name string */
|
||||
|
||||
|
||||
/* Only check user if he is mentioned in the config */
|
||||
|
||||
if(!config[0])
|
||||
return; /* no entries in config */
|
||||
while(config[++aktconfigline] && aktconfigline >= 0)
|
||||
if(strcmp(config[aktconfigline]->users, user) == 0 || config[aktconfigline]->users[0] == '*') {
|
||||
aktconfigline = -2; /* we found user or * in config, so he/they has/have restrictions */
|
||||
break;
|
||||
}
|
||||
|
||||
if(aktconfigline > 0) { /* > 0 if user is in config */
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "User %s or * not in config -> No restrictions. Not checking %s on %s", user, user, dev);
|
||||
closelog();
|
||||
#endif
|
||||
return; /* now, we return because the user beeing checked is not in config, so he has no restrictions */
|
||||
}
|
||||
|
||||
|
||||
strncpy(host, utmpp->ut_host, sizeof(host) - 1); /* get host name */
|
||||
host[sizeof(host) - 1] = '\0';
|
||||
strncpy(dev, utmpp->ut_line, sizeof(dev) - 1); /* get device name */
|
||||
dev[sizeof(dev) - 1] = '\0';
|
||||
if (stat(dev, pstat) && !chk_xsession(dev, host) == TIMEOUTD_XSESSION_LOCAL) /* if can't get status for
|
||||
port && if it's not a local Xsession*/
|
||||
{
|
||||
sprintf(errmsg, "Can't get status of user %s's terminal (%s)\n",
|
||||
user, dev);
|
||||
bailout(errmsg, 1);
|
||||
/* bailout(errmsg, 1); MOH: is there a reason to exit here? */
|
||||
return;
|
||||
}
|
||||
/* idle time is the lesser of:
|
||||
* current time less last access time OR
|
||||
* current time less last modified time
|
||||
*/
|
||||
#ifdef TIMEOUTDX11
|
||||
if(chk_xsession(dev, host) && !chk_xterm(dev, host)) { /* check idle for Xsession, but not for xterm */
|
||||
idle = get_xidle(user, dev) / 1000 / 60; /* get_xidle returns millisecs, we need mins */
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "get_xidle(%s,%s) returned %dmins idle for %s.", dev, host, (int)idle, user);
|
||||
closelog();
|
||||
}
|
||||
else if (chk_xterm(dev, host)) return;
|
||||
else
|
||||
#endif
|
||||
idle = (time_now - max(pstat->st_atime, pstat->st_mtime)) / 60;
|
||||
|
||||
sesstime = (time_now - utmpp->ut_time) / 60;
|
||||
switch(chk_timeout(user, dev, host, idle, sesstime))
|
||||
{
|
||||
|
@ -951,18 +1084,18 @@ check_idle() /* Check for exceeded time limits & logoff exceeders */
|
|||
case IDLEMAX:
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_NOTICE,
|
||||
"User %s exceeded idle limit (idle for %d minutes, max=%d).\n",
|
||||
"User %s exceeded idle limit (idle for %ld minutes, max=%d).\n",
|
||||
user, idle, config[configline]->idlemax);
|
||||
closelog();
|
||||
killit(utmpp->ut_pid, user, dev);
|
||||
killit(utmpp->ut_pid, user, dev, host);
|
||||
break;
|
||||
case SESSMAX:
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_NOTICE,
|
||||
"User %s exceeded maximum session limit (on for %d minutes, max=%d).\n",
|
||||
user, sesstime, config[configline]->sessmax);
|
||||
"User %s exceeded maximum session limit at %s (on for %ld minutes, max=%d).\n",
|
||||
user, dev, sesstime, config[configline]->sessmax);
|
||||
closelog();
|
||||
killit(utmpp->ut_pid, user, dev);
|
||||
killit(utmpp->ut_pid, user, dev, host);
|
||||
break;
|
||||
case DAYMAX:
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
|
@ -970,22 +1103,26 @@ check_idle() /* Check for exceeded time limits & logoff exceeders */
|
|||
"User %s exceeded maximum daily limit (on for %d minutes, max=%d).\n",
|
||||
user, daytime, config[configline]->daymax);
|
||||
closelog();
|
||||
killit(utmpp->ut_pid, user, dev);
|
||||
killit(utmpp->ut_pid, user, dev, host);
|
||||
break;
|
||||
case NOLOGIN:
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_NOTICE, "NOLOGIN period reached for user %s.", user);
|
||||
#ifdef DEBUG
|
||||
syslog(LOG_NOTICE, "NOLOGIN period reached for user %s@%s. (pid %d)", user, host, utmpp->ut_pid);
|
||||
#else
|
||||
syslog(LOG_NOTICE, "NOLOGIN period reached for user %s %s", user, host);
|
||||
#endif
|
||||
closelog();
|
||||
killit(utmpp->ut_pid, user, dev);
|
||||
killit(utmpp->ut_pid, user, dev, host);
|
||||
break;
|
||||
default:
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_ERR, "Internal error - unexpected return from chk_timeout", "");
|
||||
syslog(LOG_ERR, "Internal error - unexpected return from chk_timeout");
|
||||
closelog();
|
||||
}
|
||||
}
|
||||
|
||||
bailout(message, status) /* display error message and exit */
|
||||
void bailout(message, status) /* display error message and exit */
|
||||
int status; /* exit status */
|
||||
char *message; /* pointer to the error message */
|
||||
{
|
||||
|
@ -995,7 +1132,7 @@ char *message; /* pointer to the error message */
|
|||
exit(status);
|
||||
}
|
||||
|
||||
void shutdown(signum)
|
||||
void shut_down(signum)
|
||||
int signum;
|
||||
{
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
|
@ -1004,6 +1141,15 @@ int signum;
|
|||
exit(0);
|
||||
}
|
||||
|
||||
void segfault(signum)
|
||||
int signum;
|
||||
{
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_NOTICE, "Received SIGSEGV.. Something went wrong! Exiting!");
|
||||
closelog();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void logoff_msg(tty)
|
||||
int tty;
|
||||
{
|
||||
|
@ -1031,16 +1177,22 @@ int tty;
|
|||
}
|
||||
|
||||
/* terminate process using SIGHUP, then SIGKILL */
|
||||
killit(pid, user, dev)
|
||||
void killit(pid, user, dev, host)
|
||||
int pid;
|
||||
char *user;
|
||||
char *dev;
|
||||
char *host;
|
||||
{
|
||||
int tty;
|
||||
pid_t cpid;
|
||||
#ifdef SUNOS
|
||||
struct passwd *pw;
|
||||
#endif
|
||||
|
||||
if(chk_xsession(dev, host) && !chk_xterm(dev, host)) {
|
||||
killit_xsession(utmpp->ut_pid, user, dev);
|
||||
return;
|
||||
}
|
||||
/* Tell user which limit they have exceeded and that they will be logged off */
|
||||
if ((tty = open(dev, O_WRONLY|O_NOCTTY|O_NONBLOCK)) < 0)
|
||||
{
|
||||
|
@ -1050,14 +1202,28 @@ char *dev;
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
if (!strcmp(limit_name, s_nologin))
|
||||
fprintf(tty, "\r\n\r\nLogins not allowed at this time. Please try again later.\r\n");
|
||||
else
|
||||
fprintf(tty, "\r\n\r\nYou have exceeded your %s time limit. Logging you off now.\r\n\r\n",
|
||||
limit_name);
|
||||
*/
|
||||
|
||||
/* check if the pid is sshd. If so, get PID of the child process (another ssh, owned by the user).
|
||||
Test reverse if this child process is also ssh and owned by the user we want to log out.
|
||||
(because we don't want to slay another user ;) */
|
||||
cpid = getcpid(pid);
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_NOTICE, "I am at killit() pid=%d user=%s child=%d line %d", pid, user, cpid, __LINE__);
|
||||
closelog();
|
||||
#endif
|
||||
|
||||
if(chk_ssh(pid) && chk_ssh(cpid) && !strcmp(getusr(cpid), user)) {
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_NOTICE, "User %s (pid:%d, cpid:%d) logged in via ssh from %s.", user, pid, cpid, host);
|
||||
closelog();
|
||||
#endif
|
||||
pid = cpid;
|
||||
}
|
||||
|
||||
logoff_msg(tty);
|
||||
sleep (KWAIT); /*make sure msg does not get lost, again (esp. ssh)*/
|
||||
close(tty);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -1145,19 +1311,23 @@ int signum;
|
|||
signal(SIGCHLD, reapchild);
|
||||
}
|
||||
|
||||
int getdisc(d)
|
||||
int getdisc(d, host)
|
||||
char *d;
|
||||
char *host;
|
||||
{
|
||||
int fd;
|
||||
int disc;
|
||||
|
||||
#ifdef linux
|
||||
if(chk_xsession(d, host) || chk_xterm(d, host))
|
||||
return N_TTY;
|
||||
|
||||
if ((fd = open(d, O_RDONLY|O_NONBLOCK|O_NOCTTY)) < 0)
|
||||
{
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_WARNING, "Could not open %s for checking line discipline - idle limits will be enforced.", d);
|
||||
closelog();
|
||||
return;
|
||||
return N_TTY;
|
||||
}
|
||||
|
||||
if (ioctl(fd, TIOCGETD, &disc) < 0)
|
||||
|
@ -1166,14 +1336,16 @@ char *d;
|
|||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_WARNING, "Could not get line discipline for %s - idle limits will be enforced.", d);
|
||||
closelog();
|
||||
return;
|
||||
return N_TTY;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(SYSLOG_DEBUG, "TTY %s: Discipline=%s.",d,disc==N_SLIP?"SLIP":disc==N_TTY?"TTY":disc==N_PPP?"PPP":disc==N_MOUSE?"MOUSE":"UNKNOWN");
|
||||
closelog();
|
||||
#endif
|
||||
|
||||
return disc;
|
||||
#else
|
||||
|
@ -1181,3 +1353,263 @@ char *d;
|
|||
#endif
|
||||
}
|
||||
|
||||
int chk_xsession(dev, host) /* returns TIMEOUTD_XSESSION_{REMOTE,LOCAL,NONE} when dev and host seem to be a xSession. */
|
||||
char *dev,*host;
|
||||
{
|
||||
if(strncmp(dev, ":0", 1) == 0 && strlen(host) == 0 /*||
|
||||
(strncmp(dev, "pts/0", 3) == 0 && strncmp(host, ":0", 1) == 0 )*/) { /* if strings are the same, str[n]cmp returns 0 */
|
||||
/* Look here, how we check if it's a Xsession but no telnet or whatever.
|
||||
* The problem is that a xterm running on :0 has the device pts/?. But if we ignore
|
||||
* all pts/?, ssh users won't be restricted.
|
||||
* So, if (tty="pts/?" OR tty=":*") AND host = ":*", we have a Xsession:
|
||||
*
|
||||
* seppy@schleptop:~$ w
|
||||
* 20:06:33 up 18 min, 6 users, load average: 0.14, 0.16, 0.12
|
||||
* USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
|
||||
* dennis :0 - 19:48 ?xdm? 0.00s ? -
|
||||
* dennis pts/1 :0.0 20:00 4:12 0.03s 0.03s bash
|
||||
* dennis pts/2 :0.0 20:01 0.00s 0.18s 0.16s ssh localhost
|
||||
* dennis pts/3 localhost 20:01 0.00s 0.01s 0.00s w
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_DEBUG, "LOCAL Xsession detected. device=%s host=%s", dev, host);
|
||||
closelog();
|
||||
#endif
|
||||
return TIMEOUTD_XSESSION_LOCAL;
|
||||
}
|
||||
else if (strstr(dev, ":") && strlen(host) > 1 && gethostbyname(host)) {
|
||||
/* What about remote XDMCP sessions?
|
||||
* USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
|
||||
* mark pts/3 mercury Sat11 0.00s 10.99s 0.04s w
|
||||
* rebecca ap:10 ap 10:32 0.00s 0.00s 1.28s x-session-manager
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_DEBUG, "REMOTE Xsession detected. device=%s host=%s", dev, host);
|
||||
closelog();
|
||||
#endif
|
||||
return TIMEOUTD_XSESSION_REMOTE;
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_DEBUG, "NO xsession detected. device=%s host=%s", dev, host);
|
||||
closelog();
|
||||
#endif
|
||||
return TIMEOUTD_XSESSION_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/* We have to handle Xterms(pts/?) and Xsessions (:0) different:
|
||||
- Check Xsession for idle, but not a XTERM
|
||||
- Send message for pending logoff to X, but not to XTERM
|
||||
-> Don't check XTERM at all
|
||||
- but: check ssh (pts/?) but no XTERM (again)
|
||||
*/
|
||||
int chk_xterm(dev, host) /* returns 1 when dev and host seem to be a xTERM. */
|
||||
char *dev,*host;
|
||||
{
|
||||
if(strncmp(dev, "pts/0", 3) == 0 && strncmp(host, ":0", 1) == 0 ) {
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_DEBUG, "XTERM detected. device=%s host=%s Ignoring.", dev, host);
|
||||
closelog();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
} /* chk_xterm(dev,host) */
|
||||
|
||||
|
||||
void killit_xsession(pid, user, dev) /* returns 1 when dev and host seem to be a xSession. */
|
||||
int pid;
|
||||
char *dev, *user;
|
||||
{
|
||||
char msgbuf[1024], cmdbuf[1024];
|
||||
/* first, get the message into msgbuf */
|
||||
if (limit_type == NOLOGINMSG) {
|
||||
sprintf(msgbuf, "Logins not allowed at this time. Please try again later.");
|
||||
} else {
|
||||
sprintf(msgbuf, "You have exceeded your %s time limit. Logging you off now.", limit_names[limit_type]);
|
||||
}
|
||||
|
||||
/* then send the message using xmessage */
|
||||
/* well, this is not really clean: */
|
||||
sprintf(cmdbuf, "su %s -c \"xmessage -display %s -center '%s'&\"", user, dev, msgbuf);
|
||||
system(cmdbuf);
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_DEBUG, "cmdbuf=%s", cmdbuf);
|
||||
closelog();
|
||||
#endif
|
||||
sleep(KWAIT); /* and give the user some time to read the message ;) */
|
||||
|
||||
|
||||
#ifndef DEBUG
|
||||
/* kill pid here */
|
||||
kill(pid, SIGTERM); /* otherwise, X crashes */
|
||||
sleep(KWAIT);
|
||||
if (!kill(pid, 0)) { /* SIGHUP might be ignored */
|
||||
kill(pid, SIGKILL); /* then send sure "kill" signal */
|
||||
sleep(KWAIT);
|
||||
if (!kill(pid, 0))
|
||||
{
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_ERR, "Could not log user %s off line %s. (running X)", user, dev);
|
||||
closelog();
|
||||
}
|
||||
}
|
||||
#else
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_ERR, "Would normally logoff user %s running X (kill PID %d)", user, pid);
|
||||
closelog();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
int chk_ssh(pid)/* seppy; returns true if pid is sshd, otherwise it returns false */
|
||||
pid_t pid;
|
||||
{
|
||||
sprintf(path, "/proc/%d/stat", pid);
|
||||
proc_file = fopen(path, "r");
|
||||
if(!proc_file) {
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_WARNING, "chk_ssh(): PID %d does not exist. Something went wrong. Ignoring.", pid);
|
||||
closelog();
|
||||
return 0;
|
||||
}
|
||||
|
||||
fscanf (proc_file, "%*d (%[^)]", comm);
|
||||
fclose(proc_file);
|
||||
|
||||
if(!strcmp(comm, "sshd"))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *getusr(pid) /*seppy; returns the name of the user owning process with the Process ID pid */
|
||||
pid_t pid;
|
||||
{
|
||||
char uid[99];
|
||||
sprintf(path, "/proc/%d/status", pid);
|
||||
proc_file = fopen(path, "r");
|
||||
if(!proc_file) {
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_NOTICE, "getusr(): PID %d does not exist. Ignoring.", pid);
|
||||
closelog();
|
||||
return "unknown";
|
||||
}
|
||||
while(!fscanf(proc_file, "Uid: %s", uid))
|
||||
fgets(uid, 98, proc_file);
|
||||
fclose(proc_file);
|
||||
return getpwuid(atoi(uid))->pw_name;
|
||||
}
|
||||
|
||||
#ifdef TIMEOUTDX11
|
||||
Time get_xidle(user, display) /*seppy; returns millicecs since last input event */
|
||||
char *user;
|
||||
char *display;
|
||||
{
|
||||
Display* dpy;
|
||||
static XScreenSaverInfo* mitInfo = 0;
|
||||
struct passwd *pwEntry;
|
||||
char homedir[50]; /*50 should be enough*/
|
||||
char oldhomedir[50];
|
||||
uid_t oldeuid;
|
||||
Time retval = 0;
|
||||
|
||||
pwEntry = getpwnam(user);
|
||||
if(!pwEntry) {
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_ERR, "Could not get passwd-entry for user %s", user);
|
||||
closelog();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_DEBUG, "su-ing to %s(%d) and connecting to X", user, pwEntry->pw_uid);
|
||||
closelog();
|
||||
#endif
|
||||
|
||||
/*change into the user running x. we need that to connect to X*/
|
||||
/*setregid(1000, 1000); We don't need this*/
|
||||
|
||||
/*save old, to come back*/
|
||||
oldeuid = geteuid();
|
||||
sprintf(oldhomedir, "HOME=%s", getenv("HOME"));
|
||||
|
||||
/*become user*/
|
||||
if(seteuid(pwEntry->pw_uid) == -1) {
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_ERR, "Could not seteuid(%d).", pwEntry->pw_uid);
|
||||
closelog();
|
||||
}
|
||||
|
||||
sprintf(homedir, "HOME=%s", pwEntry->pw_dir);
|
||||
putenv(homedir);
|
||||
|
||||
/* First, check if there is a xserver.. */
|
||||
if ((dpy = XOpenDisplay (display)) == NULL) { /* = intended */
|
||||
openlog("timeoutd", OPENLOG_FLAGS, LOG_DAEMON);
|
||||
syslog(LOG_NOTICE, "Could not connect to %s to query idle-time for %s. Ignoring.", display, user);
|
||||
closelog();
|
||||
} else {
|
||||
if (!mitInfo)
|
||||
mitInfo = XScreenSaverAllocInfo ();
|
||||
XScreenSaverQueryInfo (dpy, DefaultRootWindow (dpy), mitInfo);
|
||||
retval = mitInfo->idle;
|
||||
XCloseDisplay(dpy);
|
||||
}
|
||||
/*go back again*/
|
||||
putenv(oldhomedir);
|
||||
setuid(oldeuid);
|
||||
|
||||
return retval;
|
||||
} /* get_xidle(user) */
|
||||
#endif
|
||||
|
||||
|
||||
/* seppy; getchild()
|
||||
returns the pid of the first child-process found.
|
||||
- 1 if a error occured,
|
||||
- 0 if none found
|
||||
|
||||
We need this because utmp returns a process owned by
|
||||
root when a user is connected via ssh. If we kill its
|
||||
child (owned by the user) he/she gets logged off */
|
||||
pid_t getcpid(ppid)
|
||||
pid_t ppid;
|
||||
{
|
||||
DIR *proc;
|
||||
FILE *proc_file;
|
||||
struct dirent *cont;
|
||||
char akt_pid[99];
|
||||
char path[256];
|
||||
|
||||
proc = opendir("/proc/");
|
||||
if(proc == NULL) {
|
||||
printf("error opening directory\n");
|
||||
return -1; /* error */
|
||||
}
|
||||
|
||||
while((cont = readdir(proc)) != NULL)
|
||||
if(cont->d_type == 4 && isdigit(cont->d_name[0])) { /* check only PIDs */
|
||||
sprintf(path, "/proc/%s/status", cont->d_name);
|
||||
proc_file = fopen(path, "r");
|
||||
if(!proc_file)
|
||||
printf("error opening proc status file %s\n", path);
|
||||
|
||||
while(!fscanf(proc_file, "PPid: %s", akt_pid))
|
||||
fgets(akt_pid, 10, proc_file);
|
||||
|
||||
if(atoi(akt_pid) == ppid)
|
||||
return (pid_t)atoi(cont->d_name); /* return pid of child */
|
||||
} /* if(cont->d_type == 4) */
|
||||
|
||||
return 0; /* no child found */
|
||||
} /* getchild(ppid) */
|
||||
|
|
20
timeouts
20
timeouts
|
@ -1 +1,19 @@
|
|||
Al:*:shane:*:NOLOGIN
|
||||
# /etc/timeouts: user login/idle/session time limits. See timeouts(5).
|
||||
#
|
||||
# Format: TIMES:TTYS:USERS:GROUPS:MAXIDLE:MAXSESS:MAXDAY:WARN
|
||||
# or: TIMES:TTYS:USERS:GROUPS:LOGINSTATUS
|
||||
#
|
||||
# Some examples:
|
||||
#
|
||||
# dopey is not allowed to login
|
||||
#Al:*:dopey:*:NOLOGIN
|
||||
#
|
||||
# cas gets unlimited use
|
||||
#Al:*:cas:*:0:0:0:0
|
||||
#
|
||||
# fred is allowed 20 minutes idle, 240 mins per session, and 480 mins per day
|
||||
# on ttyS3
|
||||
#Al:ttyS3:fred:*:20:240:480:10
|
||||
#
|
||||
# everyone else is allowed only 120min/session, 240/day
|
||||
#Al:ttyS3:*:*:20:120:240:5
|
||||
|
|
|
@ -89,10 +89,10 @@ and 60 minutes on ttyS4.
|
|||
Would match all dialled in users (if all ttyS lines were modems) and
|
||||
prevent them logging in before 7am or after 8pm on weekdays.
|
||||
.SH FILES
|
||||
/usr/etc/timeouts
|
||||
/etc/timeouts
|
||||
.SH BUGS
|
||||
See timeoutd(8)
|
||||
.SH "SEE ALSO"
|
||||
.BR timeoutd "(8)
|
||||
.SH "WRITTEN BY"
|
||||
Shane Alderton <shane@ion.apana.org.au>
|
||||
Shane Alderton <shanea@bigpond.net.au>
|
||||
|
|
Loading…
Reference in a new issue