Impose a system time limit on user logins ...

Lenny Tropiano lenny at icus.islp.ny.us
Wed Oct 25 10:40:44 AEST 1989


Here's a small program that I have been using here for a while, I figured
it would be useful for the net...  It basically imposes a time limit on
user logins.  (Default 30 minutes a session, 60 minutes a day...)  All
changes can be adjusted in the "limit.h" file.

See program comments for more details...  I wrote this on a UNIX pc, but
it should be easily used on any SYS V machine.

--- cut here --- --- cut here --- --- cut here --- --- cut here ---
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  Makefile limit.c limit.h
# Wrapped by lenny at icus on Tue Oct 24 20:35:23 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(503 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X#
X# Makefile to compile limit.c  (Limit a regular user on your system...)
X# By Lenny Tropiano
X# (c)1989 ICUS Software Systems UUCP:  ...icus!lenny -or- lenny at icus.islp.ny.us
X#
XLDFLAGS=-s
XLIBS=/lib/crt0s.o /lib/shlib.ifile
XCFLAGS=-v -O
XDEST=/usr/lbin
X#
Xlimit:  limit.o
X	@echo "Loading ..."
X	$(LD) $(LDFLAGS) -o limit limit.o $(LIBS) 
X#
Xlimit.o: limit.c limit.h
X#
Xinstall: limit
X	mv limit $(DEST)/
X	chown root $(DEST)/limit
X	chgrp bin  $(DEST)/limit
X	chmod 4511 $(DEST)/limit
Xclean:
X	rm -f limit *.o core
END_OF_Makefile
if test 503 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f limit.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"limit.c\"
else
echo shar: Extracting \"limit.c\" \(5586 characters\)
sed "s/^X//" >limit.c <<'END_OF_limit.c'
X/************************************************************************\
X**                                                                      **
X** Program name:    limit.c (Limit time regular users on your system)   **
X** Programmer:      Lenny Tropiano                                      **
X** E-Mail address:  ...!icus!lenny -or- lenny at icus.islp.ny.us           **
X** Organization:    ICUS Software Systems     (c)1989                   **
X** Date:            October 24, 1989                                    **
X**                                                                      **
X**************************************************************************
X**                                                                      **
X** Program use:  Make this program the default shell in the /etc/passwd **
X**               file of a user, it will limit the time of a user login **
X**               The user will be warned one minute before he or she is **
X**               "rudely" terminated.  Then if they don't logout, the   **
X**               login process is killed.  It also prevents them from   **
X**               logging into the system more than (predefined) time    **
X**               each day.  The default settings in the limit.h file    **
X**               is 30 minutes a session, 60 minutes a day.             **
X**                                                                      **
X**               NOTE:   The restrict.log file must be cleared out by   **
X**                       a cron, with:                                  **
X**			 0 0 * * * cp /dev/null /usr/adm/restrict.log   **
X**                       or whatever you call that file. If the LOGFILE **
X**                       isn't cleared out, the user will get the       **
X**                       message that they exceeded the time for the    **
X**                       day.                                           **
X**                                                                      **
X**************************************************************************
X**                                                                      **
X** Disclaimer:   This program must run, setuid to root to be able to    **
X**               kill the process.  I hope the security problems        **
X**               inherent with setuid-root programs don't exist here,   **
X**               but I give no warranties to that fact.                 **
X**                                                                      **
X**************************************************************************
X** Permission is granted to distribute this program by any means as     **
X** long as credit is given for my work.     I would also like to see    **
X** any modifications or enhancements to this program.                   **
X\************************************************************************/
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <time.h>
X#include <fcntl.h>
X#include <signal.h>
X#include <pwd.h>
X
X#include "limit.h"
X
Xstruct	USERLIMIT	limit;
Xtime_t	login;
Xint	pid, uid;
X
Xmain(argc,argv,envp)
Xint  argc;
Xchar *argv[];
Xchar *envp[];
X{
X	int    fd;
X	void   terminate(), warn();
X	struct passwd *pswd;
X
X	if (access(RLOG, 0) == -1) {
X		if ((fd = creat(RLOG,0644)) == -1) {
X			fprintf(stderr,"Cannot create file %s: ", RLOG);
X			perror("creat()");
X			exit(1);
X		}
X	} else {
X		if ((fd = open(RLOG,O_RDWR)) == -1) {
X			fprintf(stderr,"Cannot open file %s: ", RLOG);
X			perror("open()");
X			exit(1);
X		}
X	}
X
X	if (lseek(fd, (long)(getuid()*sizeof(struct USERLIMIT)), 0) == -1) {
X		fprintf(stderr,"Cannot position file %s: ", RLOG);
X		perror("lseek()");
X		exit(1);
X	}
X
X	if (read(fd, (char *) &limit, sizeof limit) == sizeof limit) {
X		if (limit.usage >= MAXUSAG) {
X			printf("Your usage for today has *EXCEEDED*\n");
X			printf("Please call back tomorrow.\n");
X			sleep(2);
X			exit(0);
X		}
X	} else { 
X		limit.usage = 
X		limit.totusage = 0;
X	}
X	close(fd);
X
X	signal(SIGHUP, terminate);
X	signal(SIGCLD, terminate);
X	signal(SIGTERM, terminate);
X	signal(SIGALRM, warn);
X
X	time(&login);
X
X	if ((MAXUSAG - limit.usage) < (MAXTIME - WARN)) 
X		alarm(1);		/* five seconds before warning! */
X	else 
X		alarm(MAXTIME - WARN);
X
X	if ((pid = fork()) == 0) {
X		setpwent();
X		if ((pswd = (struct passwd *)getpwuid(getuid())) == NULL) {
X		   	fprintf(stderr,
X				"Password entry missing in /etc/passwd.\n");
X		   	exit(1);
X		}
X		setuid(pswd->pw_uid);		/* set us up as right person */
X		setgid(pswd->pw_gid);
X		endpwent();
X
X		putenv("IFS=\" \n\t\"");	/* prevent any security probs */
X		execl(SHELL_PATH,SHELL_NAME,0);
X		perror("exec() failed for shell");
X		exit(1);
X	} else {
X		signal(SIGINT,SIG_IGN);
X		signal(SIGQUIT,SIG_IGN);
X		uid = getuid();
X		setuid(0);
X		setgid(0);
X		setpgrp();
X		wait((int *)0);
X	}
X	exit(0);
X}
X
Xvoid terminate()
X{
X	int	fd;
X	time_t	logout;
X
X	time(&logout);
X	limit.usage += (logout - login);
X
X	if ((fd = open(RLOG,O_RDWR)) == -1) {
X		fprintf(stderr,"Cannot open file %s: ", RLOG);
X		perror("open()");
X		exit(1);
X	}
X	lseek(fd, (long)(uid*sizeof(struct USERLIMIT)), 0);
X	write(fd, (char *) &limit, sizeof limit);
X	close(fd);
X
X	exit(0);
X}
X
Xvoid warn()
X{
X	void	bye();
X
X	printf("\n\007\007** You have ONE more minute left in this session **\n");
X	signal(SIGALRM, bye);
X	alarm(WARN);
X	wait((int *)0);
X}
X
Xvoid bye()
X{
X	printf("\nYour time limit has *EXCEEDED*.\n");
X	printf("Automatic system LOGOFF commencing now.\007\007\n\n");
X
X	kill(pid, SIGTERM);
X	sleep(2);
X	kill(pid, SIGKILL);
X	signal(SIGHUP, SIG_IGN);
X	signal(SIGCLD, SIG_IGN);
X	signal(SIGTERM, SIG_IGN);
X	terminate();
X}
END_OF_limit.c
if test 5586 -ne `wc -c <limit.c`; then
    echo shar: \"limit.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f limit.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"limit.h\"
else
echo shar: Extracting \"limit.h\" \(984 characters\)
sed "s/^X//" >limit.h <<'END_OF_limit.h'
X/*
X** Configuration setup for limit.c
X**     by  Lenny Tropiano  (ICUS Software Systems) (c)1989
X** email:  lenny at icus.islp.ny.us
X**
X*/
X
X/* restriction log file, but be cleared daily */
X
X#ifndef RLOG
X# define RLOG		"/usr/adm/restrict.log" 
X#endif
X
X/* shell to call after exec'ing */
X
X#ifndef SHELL
X# define SHELL_PATH	"/bin/ksh" 
X#endif
X
X#ifndef SHELL_NAME
X# define SHELL_NAME	"-ksh" 
X#endif
X
X/* per-login time limit */
X
X#ifndef TIME_LIMIT
X# define TIME_LIMIT	30L				/* 30 minutes	*/
X#endif
X
X/* 
X** maximum time limit per day (or period of time from which the restrict
X** log file was created and cleared
X** (this could be a weekly value if restrict.log isn't cleared DAILY, but
X** done weekly).
X*/
X
X#ifndef MAX_LIMIT
X# define MAX_LIMIT	60L				/* 60 minutes	*/
X#endif
X
X/* don't change anything below this ... */
X
X#define	MAXTIME		(60L * TIME_LIMIT)
X#define	MAXUSAG		(60L * MAX_LIMIT)
X#define	WARN		(60L * 1L)			/* 1 minute   */
X
Xstruct	USERLIMIT {
X	time_t	usage;
X	time_t	totusage;
X};
END_OF_limit.h
if test 984 -ne `wc -c <limit.h`; then
    echo shar: \"limit.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
-- 
| Lenny Tropiano            ICUS Software Systems      [w] +1 (516) 589-7930 |
| lenny at icus.islp.ny.us     Telex; 154232428 ICUS      [h] +1 (516) 968-8576 |
| {ames,pacbell,decuac,hombre,sbcs,attctc}!icus!lenny     attmail!icus!lenny |
+------- ICUS Software Systems -- PO Box 1;  Islip Terrace, NY  11752 -------+



More information about the Comp.sys.att mailing list