egray@fthood (07/20/85)
The following program will kick users off of the system if their idle time exceeds a specified number of minutes. The program checks for "silent" processes, so as to not terminate a connection just because no I/O to the terminal had taken place. Our system is set up with customer user ID's and group ID's starting at 100. This way, certain users can be made exempt from the idledaemon. Another site specific item in the program is the location of the dialup lines, since console and hardwire ports are exempt. ihnp4!uiucuxc!fthood!egray ----------------------------------------------------------------------------- /* * Idledaemon E. Gray 12 Apr 85 * Kicks a user off the system if his idle time has exceeded * a specified number of minutes. Only applies to dialup * lines, and certain users are exempt. */ #include <stdio.h> #include <signal.h> #include <pwd.h> #include <sys/types.h> #include <sys/stat.h> main(argc, argv) int argc; char *argv[]; { FILE *fp, *sp, *popen(); int uid, pid, gid, maxidle, tty, line, min; struct stat buff; struct passwd *pwline, *getpwuid(); long last, diff, now; char ttyname[20], pipe[20], buf[BUFSIZ]; if (argc <= 1) { fprintf(stderr,"Idledaemon : requires a time argument\n"); exit(1); } min = atoi(argv[1]); maxidle = min * 60; nice(10); /* turn off interrrupts */ signal(SIGINT, SIG_IGN); signal(SIGHUP, SIG_IGN); /* put it in the background */ if (fork()) exit(0); while(1) { sleep(60); /* dialups are tty8 -> tty11 */ for (tty=8; tty<=11; tty++) { sprintf(ttyname, "/dev/tty%d", tty); if (stat(ttyname, &buff) < 0) { fprintf(stderr, "Idledaemon: stat failed\n"); continue; } time(&now); /* Is the time of last I/O */ /* but NOT process inactivity */ last = buff.st_atime; diff = now - last; if (diff < 0) diff = 0; uid = buff.st_uid; gid = buff.st_gid; /* exclude non-humans */ if (uid < 100) continue; /* exclude special groups */ if (gid < 100) continue; if (diff < maxidle) continue; sprintf(pipe, "ps -ot%d", tty); /* lazy man's way to get pid */ if ((sp = popen(pipe, "r")) == NULL) { fprintf(stderr, "Idledaemon : Can't open ps\n"); continue; } /* strip off the header line */ fgets(buf, BUFSIZ, sp); line = 0; while (fgets(buf, BUFSIZ, sp) != NULL) { line++; sscanf(buf, "%d", &pid); } pclose(sp); /* has silent process ? */ if (line > 1) continue; if (!(fp = fopen(ttyname, "w"))) { fprintf(stderr,"Idledaemon : can't open %s\n", ttyname); continue; } fprintf(fp, "\n\n******************************************************************************\n"); fprintf(fp, "Message from Idledaemon at %s", ctime(&now)); fprintf(fp, "Your connection is being dropped due to inactivity in excess of %d minutes\n", min); fprintf(fp, "******************************************************************************\n"); fprintf(fp, "\n\007\007\007"); fclose(fp); /* send SIGKILL to tty */ kill(pid, 9); /* find login name */ pwline = getpwuid(uid); /* mail him a nasty note */ sprintf(pipe, "mail %s", pwline->pw_name); if ((sp = popen(pipe, "w")) == NULL) { fprintf(stderr, "Idledaemon : can't open mail\n"); continue; } fprintf(sp, "\nSubject : Inactive terminal\n\n"); fprintf(sp, "Your terminal was found to be inactive in excess of %d minutes at the\n", min); fprintf(sp, "above date and time.\n\n"); fprintf(sp, "Please use your ADP resources wisely and consistent with security\n"); fprintf(sp, "regulations.\n\n"); fprintf(sp, "Thank you\n"); fprintf(sp, "Emmet P Gray\n"); pclose(sp); } } }