Xref: utzoo unix-pc.sources:412 comp.sys.att:7880 Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ukma!rayssd!icus!lenny From: lenny@icus.islp.ny.us (Lenny Tropiano) Newsgroups: unix-pc.sources,comp.sys.att Subject: Impose a system time limit on user logins ... Keywords: time limit, user logins, keep modem usage down Message-ID: <995@icus.islp.ny.us> Date: 25 Oct 89 00:40:44 GMT Organization: ICUS Software Systems, Islip, New York Lines: 309 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 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@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 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@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 X#include X#include X#include X#include X#include 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.h <<'END_OF_limit.h' X/* X** Configuration setup for limit.c X** by Lenny Tropiano (ICUS Software Systems) (c)1989 X** email: lenny@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