autolog-0.40/autolog100755 1300 146 117225 7102305520 13103 0ustar cjstudentELF0484 (444{`{`|`||4Za /lib/ld-linux.so.2GNU%+'  # !)$ *"(&%  #!L-(  1\(8">,9Fu"ML`"T܉Q"Z<9"c :"l<rE"y܈(;"l&o"l"̊,"/"Ä- |  (\`܊!&&5 G̉!NP"Wv"m"r|__gmon_start__libc.so.6strcpyprintfgetgrgidfscanffgetstolowersystemmallocsleepgetutentre_matchpopencallocfprintfkillctimere_compile_pattern__deregister_frame_infostrstrstrncmpstrncpyreallocstrtokforktimestrcmpgetpwuidgetpwnamsprintffclosestderrexitfopenatoi_IO_stdin_used__libc_start_mainstrlensetutent__register_frame_infofree__xstatGLIBC_2.1GLIBC_2.0ii zii ` (  $ ( ,04*8<@DH&L PT'X \%`d hlptx!|#)"US[shtfwjE]5%%h%h% h%h%h %h(%h0% h8p%$h@`%(hHP%,hP@%0hX0%4h` %8hh%<hp%@hx%Dh%Hh%Lh%Ph%Th%Xh%\h%`hp%dh`%hhP%lh@%ph0%th %xh%|h%h%h%h%h%h%h %h(%h01^PTRhHh|QVhU=u8PС8ult h]Ð&U]É'U帼thdh]ÐU]ÐUWVSEvE;E| EE :-7EE BPB+`vEEE fEEE FEEE Rc&EEE R3&EEE :y1҈‰&EEE :y1҈‰&EEE :y1҈‰_t&'EEE :y1҈‰/t&'EE Rh`P{ .v'EE Rh`PK Eht&J#hh*:G=utj'@Pj<J =t,h;h= hX h*=t h;=u'Չ'=tR EE;~ &EEU)JRuk=t hsEEU)J Mu+] MJ<u EH=tV;~I=t h9 X =tPh`=t&PhDPh 1=u;| v'P=u;| v't&' hO7e[^_]Ít&U,SDžPRh@P& PhEP Dž&'h,EPu9Ѝ &'h1EPu9Ѝ &'h6EP^u)Ѝ Qh:EPu,=tEPPh`_ hjE}ut&Ct&'ЍЍ<~B~9);})v'EP=uP=hLh?h2Dž;| ut&ЍRЍRЍRЍRЍRЍRЍRЍRЍRЍRh ,&'h;JPhL=th`i&hR[^]Í&U(SEEPE܋EP‰UE܉EEEEPEPfPEP7 u>jjE PAPE PEPnËE P 9uEEPU؉]ԉ]É'UVSE!EVhP*E PhP hPh@PhQPjhQPjhTPj P}Ex$Džwh0EPOujh2s1'Ex t'EPhMP. P/ExhWPhPEPE PhPEPRhP h@PohQP[jQhQP=j3hTPt&'hWPh PEPE Ph`PEPRhP hPh PhQPtjjhQPVjLhTP8PExOE Ph`P4 h0PPu jh1*v'ExtghPEPE PhPEPRh@Pk hePWyhP;EPE PhPEPRh@P hPh@PPM}DžeExE PhP h0Pu jh1v'hP;PPE PhPhPEPhP PS}DžExE Ph@P h0Pujh1E PhkPG PPE PhPEPhP PsEx(t=EPEPEPE PPhPP!1 v']ÍU|EEPPthPSE}u rhPRhEPK EPPEEPEPhEPEP^1 t&']ÍUdEPhhEPEP]U}~E;}E]UxDžhJP詾ujhmt&PhPľ vPhP蜾 uhP˿hj贿PMPhP蚿 PPXtoDž=tj PJPPPh P1Pf&'=t)PPPPhe`UPJP謾P)JR!u v'븐&uW=tj P PPPh?PP()JBPuuR=tj P脽PPPh]PkP0&P萼]ÐUS[#UE PRj}]]ÐUS=tЃ;u]]É'U]ÐUS[ç"]/etc/autolog.conf/var/log/autolog.log/tmp/autolog.dataautologout: illegal switch: %s autologout: illegal parameter: %s ps auxStarting Service Aus der Datei eingelesen: ========================= knock out. check for dead processes. next check for processes after %10d. daemons maximum sleeptime %7d seconds, today. daemon is falling asleep for%5d seconds, now. Stopped service@@@@@@@@@@@@@@@@@@@@@P@@@Ќ@@p@ @@/proc/%d/dev/%sDead process: Non-user process:%s N:%-8s P:%5d Login:%sCan't get status of user's terminalChecking: %-11s on %-12s I:%4d T:%d Login: %s found: %2d Username UserID Terminal idle Starttime BanningEnd WarningEnd --> %-10s %4d %-10s %5d %10d %10d %10d w+Can't create data-file.%d %-10s %4d %-10s %5d %10d %10d %10d r%d %s %d %s %d %d %d %dCan't find file: %s ps=name=group=line=idle=grace=ban=nohardclearmailwarnloglostkillUnknown token in file: %s: %s Config File: name group line idle grace mail warn log hard ban ---------------------------------------------------------- %-8s %-8s %-6s %3d %5d %4d %4d %3d %4d %4d [%s] Lost processes will be killed. Lost processes stay alive. user: %-10s %-10s %-d now: %d = %s Checking: %-11s on %-12s I:%-4d Can't find group entry for user: %s Can't find password entry for user: %s User exempt No match for process .user has logged out. %4d <> %4d user has changed -> do not disturb. Subject to logout Idle time: %4d (%2d allowed) User temporary banned. Banning should end: %10d idle-state: %3d / %d: sess-state: %3d / %d: time left: %4d sec. Subject to logout Total time: %4d (%2d allowed) Killing user, now. idle-punish I am angry, user returned... Warning user:%s Line:%s Sleep %d sec Can't use ps programDead process: %-8s -> %5s %5d %5d -> ok, Name = %s => kill. |-> %5d get PIDs for %s ** IDLE-PUNISH **wCan't open user's terminalclear >%s .--------------------------------------------. | %10s, you have been idle too long. | | Punishment: Log out for %3d seconds! | `--------------------------------------------'   ** ANGRY **.--------------------------------------------------. | %10s, you have just been kicked off. | | Make off, don't try it again, today. | `--------------------------------------------------' ** NOTIFIED **| %10s: You've been on for %3d min. | | You'll be logged off in %3d sec. so finish up. | .----------------------------------------------. | %10s: You've been idle for %3d min. | | You'll be logged off in %3d sec | | unless you hit a key. | `----------------------------------------------' /bin/mail -s "++WARNING - LOG-OFF ++" %sCan't use /bin/mail programYour session-limit will be reached soon. %s: You've been on for %3d min. You'll be logged off in %3d sec. So finish up, please. Your have been idle for quite a long time. %s: You've idle for %3d min. Please: Type something into a terminal or you'll be kicked off. ** LOGOFF **/bin/mail -s "Logged off, you were idle" %sSubject: Excess Idle Time Logged off - %s - %s - excess idle time - on tty = %s ** LOGOFF FAILED **/bin/mail -s "Couldn't log out [%s] " rootSubject: Can't logoff %s Can't Log off - %s %s tty = %s %-20s %-8s %-5s idle:%3d sess:%3da%s%s - %s ** ERROR **%-20s %s %-5s idle:%3d sess:%3dDead , killed: %-10s %5d : %5dLost, killed: %-10s %5d : %5dLeft, killed: %-10s %5d : %5d .+xˆ҈"2BRbr‰҉"2BRbrŠҊ" | H( p z 8D4ooogdTdT.<=l/{=b|8bv'au' L0g(; f$B?'  $!<"R#i%&12345 6/ 8H 9b ; = > ? @ A B C/ DH E_ Fx G H I N Q R8 SP Ti V Y o r u {4 |Q n  7 Q F   *"i F3;BE/mRY ](ekOsgx' #$%& "dT'dMd.<=l/{=b|8bv'au'(;Tj%?'Q F {G%*08 =$C:KPRf Q+[t :m$*&):) D*D+D,N@)[@)$&dinit.c/usr/src/packages/BUILD/glibc-2.1/csu/gcc2_compiled.int:t(0,1)=r(0,1);0020000000000;0017777777777;char:t(0,2)=r(0,2);0;127;long int:t(0,3)=r(0,1);0020000000000;0017777777777;unsigned int:t(0,4)=r(0,1);0000000000000;0037777777777;long unsigned int:t(0,5)=r(0,1);0000000000000;0037777777777;long long int:t(0,6)=r(0,1);01000000000000000000000;0777777777777777777777;long long unsigned int:t(0,7)=r(0,1);0000000000000;01777777777777777777777;short int:t(0,8)=r(0,8);-32768;32767;short unsigned int:t(0,9)=r(0,9);0;65535;signed char:t(0,10)=r(0,10);-128;127;unsigned char:t(0,11)=r(0,11);0;255;float:t(0,12)=r(0,1);4;0;double:t(0,13)=r(0,1);8;0;long double:t(0,14)=r(0,1);12;0;complex int:t(0,15)=s8real:(0,1),0,32;imag:(0,1),32,32;;complex float:t(0,16)=r(0,16);4;0;complex double:t(0,17)=r(0,17);8;0;complex long double:t(0,18)=r(0,18);12;0;void:t(0,19)=(0,19)../include/libc-symbols.h/usr/src/packages/BUILD/glibc-2.1/cc/config.h../include/libintl.h../intl/libintl.h../include/features.h../include/sys/cdefs.h../misc/sys/cdefs.h/usr/lib/gcc-lib/i486-linux/egcs-2.91.66/include/stddef.h../include/locale.h../locale/locale.hlconv:T(10,1)=s48decimal_point:(10,2)=*(0,2),0,32;thousands_sep:(10,2),32,32;\grouping:(10,2),64,32;int_curr_symbol:(10,2),96,32;\currency_symbol:(10,2),128,32;mon_decimal_point:(10,2),160,32;\mon_thousands_sep:(10,2),192,32;mon_grouping:(10,2),224,32;\positive_sign:(10,2),256,32;negative_sign:(10,2),288,32;\int_frac_digits:(0,2),320,8;frac_digits:(0,2),328,8;\p_cs_precedes:(0,2),336,8;p_sep_by_space:(0,2),344,8;\n_cs_precedes:(0,2),352,8;n_sep_by_space:(0,2),360,8;\p_sign_posn:(0,2),368,8;n_sign_posn:(0,2),376,8;;../include/xlocale.h../locale/xlocale.h__locale_struct:T(13,1)=s36__locales:(13,2)=ar(0,1);0;5;(13,3)=*(13,4)=xslocale_data:,0,192;\__ctype_b:(13,5)=*(0,9),192,32;__ctype_tolower:(13,6)=*(0,1),224,32;\__ctype_toupper:(13,6),256,32;;__locale_t:t(13,7)=(13,8)=*(13,1)../sysdeps/unix/sysv/linux/_G_config.h../sysdeps/unix/sysv/linux/bits/types.hsize_t:t(16,1)=(0,4)__u_char:t(15,1)=(0,11)__u_short:t(15,2)=(0,9)__u_int:t(15,3)=(0,4)__u_long:t(15,4)=(0,5)__u_quad_t:t(15,5)=(0,7)__quad_t:t(15,6)=(0,6)__int8_t:t(15,7)=(0,10)__uint8_t:t(15,8)=(0,11)__int16_t:t(15,9)=(0,8)__uint16_t:t(15,10)=(0,9)__int32_t:t(15,11)=(0,1)__uint32_t:t(15,12)=(0,4)__int64_t:t(15,13)=(0,6)__uint64_t:t(15,14)=(0,7)__qaddr_t:t(15,15)=(15,16)=*(15,6)__dev_t:t(15,17)=(15,5)__uid_t:t(15,18)=(15,3)__gid_t:t(15,19)=(15,3)__ino_t:t(15,20)=(15,4)__mode_t:t(15,21)=(15,3)__nlink_t:t(15,22)=(15,3)__off_t:t(15,23)=(0,3)__loff_t:t(15,24)=(15,6)__pid_t:t(15,25)=(0,1)__ssize_t:t(15,26)=(0,1)__rlim_t:t(15,27)=(0,3)__rlim64_t:t(15,28)=(15,6)__id_t:t(15,29)=(15,3)__fsid_t:t(15,30)=(15,31)=s8__val:(15,32)=ar(0,1);0;1;(0,1),0,64;;__daddr_t:t(15,33)=(0,1)__caddr_t:t(15,34)=(10,2)__time_t:t(15,35)=(0,3)__swblk_t:t(15,36)=(0,3)__clock_t:t(15,37)=(0,3)__fd_mask:t(15,38)=(0,5)__fd_set:t(15,39)=(15,40)=s128fds_bits:(15,41)=ar(0,1);0;31;(15,38),0,1024;;__key_t:t(15,42)=(0,1)__ipc_pid_t:t(15,43)=(0,9)__blkcnt_t:t(15,44)=(0,3)__blkcnt64_t:t(15,45)=(15,6)__fsblkcnt_t:t(15,46)=(15,4)__fsblkcnt64_t:t(15,47)=(15,5)__fsfilcnt_t:t(15,48)=(15,4)__fsfilcnt64_t:t(15,49)=(15,5)__ino64_t:t(15,50)=(15,4)__off64_t:t(15,51)=(15,24)__t_scalar_t:t(15,52)=(0,1)__t_uscalar_t:t(15,53)=(0,4)__intptr_t:t(15,54)=(0,1)../linuxthreads/sysdeps/pthread/bits/pthreadtypes.h../sysdeps/unix/sysv/linux/bits/sched.h__sched_param:T(18,1)=s4sched_priority:(0,1),0,32;;_pthread_fastlock:T(17,1)=s8__status:(0,3),0,32;__spinlock:(0,1),32,32;;_pthread_descr:t(17,2)=(17,3)=*(17,4)=xs_pthread_descr_struct:pthread_attr_t:t(17,5)=(17,6)=s36__detachstate:(0,1),0,32;\__schedpolicy:(0,1),32,32;__schedparam:(18,1),64,32;\__inheritsched:(0,1),96,32;__scope:(0,1),128,32;\__guardsize:(16,1),160,32;__stackaddr_set:(0,1),192,32;\__stackaddr:(17,7)=*(0,19),224,32;__stacksize:(16,1),256,32;;pthread_cond_t:t(17,8)=(17,9)=s12__c_lock:(17,1),0,64;\__c_waiting:(17,2),64,32;;pthread_condattr_t:t(17,10)=(17,11)=s4__dummy:(0,1),0,32;;pthread_key_t:t(17,12)=(0,4)pthread_mutex_t:t(17,13)=(17,14)=s24__m_reserved:(0,1),0,32;\__m_count:(0,1),32,32;__m_owner:(17,2),64,32;\__m_kind:(0,1),96,32;__m_lock:(17,1),128,64;;pthread_mutexattr_t:t(17,15)=(17,16)=s4__mutexkind:(0,1),0,32;;pthread_once_t:t(17,17)=(0,1)pthread_rwlock_t:t(17,18)=(17,19)=s32__rw_lock:(17,1),0,64;\__rw_readers:(0,1),64,32;__rw_writer:(17,2),96,32;\__rw_read_waiting:(17,2),128,32;__rw_write_waiting:(17,2),160,32;\__rw_kind:(0,1),192,32;__rw_pshared:(0,1),224,32;;pthread_rwlockattr_t:t(17,20)=(17,21)=s8__lockkind:(0,1),0,32;\__pshared:(0,1),32,32;;pthread_t:t(17,22)=(0,5)wchar_t:t(19,1)=(0,3)wint_t:t(19,2)=(0,4)_G_int16_t:t(14,1)=(0,8)_G_int32_t:t(14,2)=(0,1)_G_uint16_t:t(14,3)=(0,9)_G_uint32_t:t(14,4)=(0,4)_IO_stdin_used:G(0,1)/usr/src/packages/BUILD/glibc-2.1/io/stat.c../include/sys/stat.h../io/sys/stat.h../include/time.h../time/time.htime_t:t(21,1)=(16,35)dev_t:t(15,1)=(16,17)gid_t:t(15,2)=(16,19)ino_t:t(15,3)=(16,20)mode_t:t(15,4)=(16,21)nlink_t:t(15,5)=(16,22)off_t:t(15,6)=(16,23)uid_t:t(15,7)=(16,18)pid_t:t(15,8)=(16,25)../sysdeps/unix/sysv/linux/bits/stat.hstat:T(22,1)=s88st_dev:(16,17),0,64;__pad1:(0,9),64,16;\st_ino:(16,20),96,32;st_mode:(16,21),128,32;st_nlink:(16,22),160,32;\st_uid:(16,18),192,32;st_gid:(16,19),224,32;st_rdev:(16,17),256,64;\__pad2:(0,9),320,16;st_size:(16,23),352,32;st_blksize:(0,5),384,32;\st_blocks:(16,44),416,32;st_atime:(16,35),448,32;\__unused1:(0,5),480,32;st_mtime:(16,35),512,32;\__unused2:(0,5),544,32;st_ctime:(16,35),576,32;\__unused3:(0,5),608,32;__unused4:(0,5),640,32;\__unused5:(0,5),672,32;;stat64:T(22,2)=s96st_dev:(16,17),0,64;__pad1:(0,9),64,16;\st_ino:(16,50),96,32;st_mode:(16,21),128,32;st_nlink:(16,22),160,32;\__pad2:(0,9),320,16;st_size:(16,51),352,64;st_blksize:(0,5),416,32;\st_blocks:(16,45),448,64;st_atime:(16,35),512,32;\__unused1:(0,5),544,32;st_mtime:(16,35),576,32;\__unused2:(0,5),608,32;st_ctime:(16,35),640,32;\__unused3:(0,5),672,32;__unused4:(0,5),704,32;\__unused5:(0,5),736,32;;__stat:F(0,1)file:p(0,20)=*(0,2)buf:p(0,21)=*(22,1)file:r(0,20)buf:r(0,21)GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)01.0101.0101.0101.0101.0101.0101.01.symtab.strtab.shstrtab.interp.note.ABI-tag.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.got.rel.bss.rel.plt.init.plt.text.fini.rodata.data.eh_frame.ctors.dtors.got.dynamic.bss.stab.stabstr.comment.note# 1((H7 pp?  GoVTo0c 44l <<u DD8 ~||/00 CHHNN ||`h````a``bPX `bL  mgJP ; 8](p 4< D |  0 H|` T " ` -1?K` at d  "   @  H    y $04 -` 7@GHNv"ö-܈(/"& pp  P  P     0  'u"9,9L| R<cjL`"|\(l"`| A0 ""3o"QXj̉!|܉Q"XJP"Jp D  :"  : CL,"_<9"s{| L-H\l& |  & E".&" 3D:P"`JekJr{̊  ܊;" ( D |pc J' 3< K#initfini.cgcc2_compiled.init.ccrtstuff.cp.2__DTOR_LIST__completed.3__do_global_dtors_aux__EH_FRAME_BEGIN__fini_dummyobject.8frame_dummyinit_dummyforce_to_data__CTOR_LIST____do_global_ctors_aux__CTOR_END____DTOR_END____FRAME_END__autolog.cstat.ccheck_utmputmpplostkillkill_Reskill_PIDs_DYNAMICg_mail_etext__register_frame_info@@GLIBC_2.0strcmp@@GLIBC_2.0_fp_hwfprintf@@GLIBC_2.0fork@@GLIBC_2.0usermaxc_idx__statsave_usersgetpwuid@@GLIBC_2.0lower_sleepdebuglog_msggetgrgid@@GLIBC_2.0bailoutkill_HUPdatfnamesystem@@GLIBC_2.0tolower@@GLIBC_2.0_initpopen@@GLIBC_2.1delimsmalloc@@GLIBC_2.0fscanf@@GLIBC_2.0sleep_max__deregister_frame_info@@GLIBC_2.0pres_timestderr@@GLIBC_2.0anystrg__xstat@@GLIBC_2.0do_biteids_filllistalltime@@GLIBC_2.0_startfgets@@GLIBC_2.0re_compile_pattern@@GLIBC_2.0g_warnstrstr@@GLIBC_2.0strlen@@GLIBC_2.0sleep@@GLIBC_2.0c_arrids_lststrncmp@@GLIBC_2.0setutent@@GLIBC_2.0sleeptimeuserlstmesg__bss_startmainre_match@@GLIBC_2.0g_idleg_graceresistconfname__libc_start_main@@GLIBC_2.0get_PIDsuserfillrealloc@@GLIBC_2.0getutent@@GLIBC_2.0g_cleardata_startprintf@@GLIBC_2.0_finifclose@@GLIBC_2.1ctime@@GLIBC_2.0pat_matchg_hardgetpwnam@@GLIBC_2.0exit@@GLIBC_2.0load_usersatoi@@GLIBC_2.0check_idlecalloc@@GLIBC_2.0stat_edata_GLOBAL_OFFSET_TABLE_free@@GLIBC_2.0_endg_logps_cmdchck_pidstrncpy@@GLIBC_2.0set_defskill_KILLfopen@@GLIBC_2.1_IO_stdin_usedstrtok@@GLIBC_2.0kill@@GLIBC_2.0sprintf@@GLIBC_2.0show_results__data_startkill_lost_PIDsids_maxeat_confilelogfname__gmon_start__strcpy@@GLIBC_2.0autolog-0.40/autolog-0.40.spec100744 1300 146 3625 7102305520 14347 0ustar cjstudentSummary: Auto logout daemon - chase sleeping users Name: autolog Version: 0.40 Release: 1 Copyright: GPL URL: http://www.cip-bau.uni-hannover.de/~juerges Group: Daemons Source: autolog-0.40.tar.gz Vendor: this was free Packager: Carsten Juerges %description - This program wakes up from time to time and looks around for users doing nothing. If they seem to be idle for too much time long, they get a warning message. They get some time to type something into a terminal, otherwise they get kicked off. This programs automatically logs out "forgotten" logins. - It is also possible to set a maximum session time for a special user, group, etc. If a users exceeds that he will be banned for a certain amount of time. - This programm is also looking for lost processes and kills them from time to time. if (500 (autolog <0.40) Carsten Juerges (autolog 0.40) %changelog (Details see CHANGES) * Wed Apr 28 2000 autolog - Version 0.40 released. First public release. The whole thing renamed to the old name, to show this is an upgraded version of autolog an not an entiryly new thing. Many things to complete, but this should already work. * Wed Apr 12 2000 autologd - Version 0.10 released. First release for discussion purpose with the other author(s). So someone else could check, whether it works. Many things to complete, but this should already work %prep %setup %build make autolog %install make install %files %config /etc/autolog.conf /sbin/init.d/autolog /usr/sbin/autolog /var/log/autolog.log /tmp/autolog.data %doc README CHANGES %doc /usr/man/man5/autolog.conf.5.gz %doc /usr/man/man8/autolog.8.gz autolog-0.40/autolog.8.gz100644 1300 146 2301 7102305520 13611 0ustar cjstudent 9autolog.8Vo6~_qK3l})Q,YبmJHDhgh>X:u 4bO(5ic? /:JuJvɸO-%⩷pV{ m66zN3C Δw 6thsWP2i=J1agSX9m ASmFౣ }Dama) TXeWsC vsoe߲32o3d[q)FOux|#eJ6%CFL}"pG~3!t,a(LBt17U1`7Ӎ=^ ,kF\%퇃և#aHox)gD6F*gxC%_ {Kʣdl-K$sbx 3M=?Xچ{#5~:Uy`XXqZLa):dkWXapkLLSY+Mp?#l[ /ПKV|ڮ {@$@;AWt9x0cbu`r$ԲQn<4X7;sc#d#u$'u y'(,A8 7! B+^OBj5J|ONѲra Y`+2E$^rвF<;NM9>|IȘ6~?y3wt|{(oDi $ǁK?_ħuwOJyQ #include #include #include #include #include #include #include #include #include #include #define D_IDLE 30 /* maximum idle time (minutes) */ #define D_GRACE 120 /* grace time (sec) for user reply */ #define D_HARD 0 /* consider connect time only */ #define D_MAIL 1 /* notify user by mail */ #define D_CLEAR 0 /* clear user terminal before warning */ #define D_WARN 1 /* warn user before killing */ #define D_LOG 1 /* log activity in logfile */ #define WARNING 1 /* a warning message */ #define LOGOFF 2 /* a log-off message */ #define NOLOGOFF 3 /* a log-off failure message */ #define ANGRY 4 /* a log-off user returned message */ #define IDLEPUNISH 5 /* punish idling-users message */ #define HUP_WAIT 20 /* time to wait after SIGHUP (in sec.) */ #define KILLWAIT 3 /* time to wait after SIGKILL (in sec.) */ #define Max_Sleep 1800 /* max. sleeping time for this daemon ;-) */ #define ChckSleep 90 /* check whether user logged in again */ #define Idle_Ban 120 /* punishment-time for idle users */ //#define HUP_WAIT 2 /* (demo / debug) */ //#define KILLWAIT 1 /* (demo / debug) */ //#define Max_Sleep 10 /* (demo / debug) */ //#define ChckSleep 10 /* (demo / debug) */ #define STRLEN 64 #define LINELEN 256 #define MAXCONF 512 /* maximum lines in config file */ typedef struct{ char Name[20]; /* Name of user. */ char Device[20]; /* Outputdevice with the minimum idle-time */ /* "." serves as flag that user logged out, */ /* when chasing lost processes. */ uid_t UserID; /* to check whether user has changed */ int IdleTime; /* Minimum-time the user is idle */ int SessStrt; /* Starttime of the users session */ int Ban_Ends; /* Endtime of banning user this user */ int WarnEnds; /* End of grace-time (after warning). */ } userdata; /* e.g. 30 Mins after hardkick. */ struct utmp *utmpp; /* pointer to utmp file entry */ char delims[] = "\n\t "; /* valid delimiters in config file */ char anystrg[] = ".+"; /* matches anything */ int debug = 0; int resist = 1; /* 0=> ordin. program 1=> behave as daemon. */ int do_bite = 1; int listall = 0; char *confname = "/etc/autolog.conf"; char *logfname = "/var/log/autolog.log"; char *datfname = "/tmp/autolog.data"; int g_idle = D_IDLE; int g_grace = D_GRACE; int g_hard = D_HARD; int g_mail = D_MAIL; int g_clear = D_CLEAR; int g_warn = D_WARN; int g_log = D_LOG; typedef struct conf { char *name; /* user name */ char *group; /* group name */ char *line; /* tty line */ int idle; /* minutes of idle time */ int grace; /* minutes of grace time */ int ban; /* ban user for ... minutes */ int hard; /* consider connect time only */ int mail; /* notify by mail */ int clear; /* clear screen before warn */ int warn; /* warn before kill */ int log; /* log actions to logfile */ } conf_el; conf_el c_arr[MAXCONF]; int sleeptime = Max_Sleep; /* maximum amount of time */ int sleep_max = Max_Sleep; /* to sleep for daemon. */ int c_idx = 0; int userfill=0; /* different users found. */ int usermax =0; /* current size of List. */ userdata* userlst; /* Store user-Data here. */ int ids_fill; int ids_max; int *ids_lst; time_t time(); /* they are used so often */ time_t pres_time; /* current time. */ time_t chck_pid=0; /* don't check pids before ... */ int lostkill=1; /* 1 => kill lost processes. */ char *ps_cmd; main(int argc, char *argv[]) { int i; for (i = 1; i < argc; i++){ if (argv[i][0] == '-'){ switch(tolower(argv[i][1])) { case 'r': resist = 1; break; /* debug */ case 'o': resist = 0; break; case 'a': listall = 1; break; case 'b': do_bite = 0;/* I got used to */ break; case 'd': debug = 1; break; case 'h': g_hard = 1; break; case 'n': do_bite = 0; break; case 'l': logfname = argv[++i]; break; case 'f': confname = argv[++i]; break; case 't': g_idle = atoi(argv[++i]); break; case 'g': g_grace = atoi(argv[++i]); break; case 'm': g_mail = (argv[++i][0] == 'y'); break; case 'c': g_clear = (argv[++i][0] == 'y'); break; case 'w': g_warn = (argv[++i][0] == 'y'); break; case 'L': g_log = (argv[++i][0] == 'y'); break; default: fprintf(stderr,"autologout: illegal switch: %s\n", argv[i]); } } else fprintf(stderr,"autologout: illegal parameter: %s\n", argv[i]); } /* for */ ps_cmd="ps aux"; time(&pres_time); /* get current time for log-file */ log_msg("Starting Service"); eat_confile(); /* read config file */ if (!debug) /* if not in debug mode, */ if (fork()) exit(0); /* the parent process exits here. */ // if (!debug && resist) /* if not in debug mode, */ // if (fork()) exit(0); /* the parent process exits here. */ userfill = 0; usermax = 8; userlst = (userdata*)calloc(sizeof(userdata),1+usermax); load_users(); if (debug){ printf("\n"); printf("Aus der Datei eingelesen:\n"); printf("=========================\n"); show_results(); } /* now sit in an infinite loop and work */ do { time(&pres_time); /* get current time */ sleeptime = sleep_max; /* assume max. sleeptime. */ setutent(); if (debug) printf("\n"); while ((utmpp = getutent()) != (struct utmp *) NULL) check_utmp(); if (debug) show_results(); for (i=1; i<=userfill; i++){ if (check_idle(&userlst[i])==2){ if (debug) printf("knock out.\n"); userlst[i] = userlst[userfill]; userfill--; } } /*.. check for lost processes, from time to time. ...........................*/ if (lostkill && pres_time>chck_pid){ if (debug) printf("check for dead processes.\n"); kill_lost_PIDs(); chck_pid = pres_time+10*60; if (debug) printf("next check for processes after %10d.\n",chck_pid); } if (debug) { //show_results(); printf("daemons maximum sleeptime %7d seconds, today.\n",sleep_max); printf("daemon is falling asleep for%5d seconds, now.\n",sleeptime); } if (resist || (sleeptime < sleep_max) ) sleep(sleeptime); } while (resist || /* Stay when in daemon-mode */ (sleeptime < sleep_max) ); /* or users are to be kicked off */ save_users(); log_msg("Stopped service"); } /*************************************************************** * This function makes sure we will find in our table: * * - shortest idle-time and device of this. * * - earliest start-time of all logins. * ***************************************************************/ check_utmp(){ /* select utmp entries needing killing */ char dev[STRLEN], name[STRLEN], prname[STRLEN]; char *msg; struct stat status; time_t idle, atime; int userpos=0; /* position of user found, 0 => not found */ sprintf(prname,"/proc/%d",utmpp->ut_pid); /* append /proc/ to proclist */ sprintf(dev, "/dev/%s" ,utmpp->ut_line); /* append /dev/ to base name */ msg=""; /*.. Get information about the current process. .............................*/ if (stat(prname, &status)) msg="Dead process: "; if (utmpp->ut_type != USER_PROCESS) msg="Non-user process:"; if (strlen(msg)){ if (listall) printf("%s N:%-8s P:%5d Login:%s", msg,utmpp->ut_user,utmpp->ut_pid,ctime(&utmpp->ut_time)); return(0); } if (stat(dev, &status)){ /* if can't get status for port */ bailout("Can't get status of user's terminal", 1); return(0); } /*.. Find out everything about current time, sleep time and session time. ...*/ if (utmpp->ut_time > status.st_atime) /* get last access time */ atime = utmpp->ut_time; /* proc - starttime */ else atime = status.st_atime; /* proc - accesstime */ idle = (pres_time - atime ) / 60; /* total idle minutes */ /*.. Find out username and groupname of this login. .........................*/ strncpy(name, utmpp->ut_user, UT_NAMESIZE); /* get user name */ name[UT_NAMESIZE] = '\0'; /* null terminate user name string */ if (listall) printf("Checking: %-11s on %-12s I:%4d T:%d Login: %s", name,dev,idle,utmpp->ut_type,ctime(&utmpp->ut_time)); strcpy(userlst[0].Name, name); strcpy(userlst[0].Device,utmpp->ut_line); userlst[0].IdleTime =idle; /*.. Get Position of user in userlst. .......................................*/ userpos=userfill; while ( strcmp(userlst[userpos].Name,name) ) userpos--; /*.. if not found -> add user to userlst. ...................................*/ if ( userpos ==0 ) { userfill++; if (userfill>usermax){ usermax = 2*usermax; userlst = (userdata*) realloc(userlst,sizeof(userdata) * (1+usermax)); } strcpy(userlst[userfill].Name, name); strcpy(userlst[userfill].Device,utmpp->ut_line); userlst[userfill].IdleTime = idle; userlst[userfill].UserID = status.st_uid; userlst[userfill].SessStrt = utmpp->ut_time; userlst[userfill].WarnEnds = 0; } else{ if (userlst[userpos].IdleTime > idle){ /* less idle-time found. ....*/ userlst[userpos].IdleTime = idle; strcpy(userlst[userpos].Device,utmpp->ut_line); } if (userlst[userpos].SessStrt > utmpp->ut_time){ /* earlier start. */ userlst[userpos].SessStrt = utmpp->ut_time; } } } show_results(){ int userpos=0; /* position of user found, 0 => not found */ printf("\nfound: %2d\n\n",userfill); printf(" Username UserID Terminal idle Starttime BanningEnd WarningEnd\n"); for (userpos=1; userpos<=userfill; userpos++){ printf(" --> %-10s %4d %-10s %5d %10d %10d %10d\n", userlst[userpos].Name, userlst[userpos].UserID, userlst[userpos].Device, userlst[userpos].IdleTime,userlst[userpos].SessStrt, userlst[userpos].Ban_Ends,userlst[userpos].WarnEnds); } } save_users(){ int userpos=0; /* position of user found, 0 => not found */ FILE* f; if (!(f=fopen(datfname,"w+"))) { bailout("Can't create data-file.", 6); return; } fprintf(f,"%d\n",userfill); for (userpos=1; userpos<=userfill; userpos++){ fprintf(f," %-10s %4d %-10s %5d %10d %10d %10d\n", userlst[userpos].Name, userlst[userpos].UserID, userlst[userpos].Device, userlst[userpos].IdleTime,userlst[userpos].SessStrt, userlst[userpos].Ban_Ends,userlst[userpos].WarnEnds); } fclose(f); } load_users(){ int userpos=0; /* position of user found, 0 => not found */ FILE* f; /*.. if no table exists, no problem, just return. ...........................*/ if (!(f=fopen(datfname,"r"))) { return; } /*.. check, how many lines with data will follow. ...........................*/ fscanf(f,"%d",&userfill); /*.. if necessary extend list. ..............................................*/ if (userfill>usermax){ usermax = 2*userfill; userlst = (userdata*) realloc(userlst,sizeof(userdata) * (1+usermax)); } /*.. read all the data-lines. ...............................................*/ for (userpos=1; userpos<=userfill; userpos++){ fscanf(f," %s %d %s %d %d %d %d", &userlst[userpos].Name, &userlst[userpos].UserID, &userlst[userpos].Device, &userlst[userpos].IdleTime, &userlst[userpos].SessStrt, &userlst[userpos].Ban_Ends, &userlst[userpos].WarnEnds); } fclose(f); } /*---------------------------------------------------------------------------*/ /*=== The following functions cope with the config-file. ===*/ /*---------------------------------------------------------------------------*/ set_defs(int i){ c_arr[i].name = anystrg; c_arr[i].group = anystrg; c_arr[i].line = anystrg; c_arr[i].idle = g_idle; c_arr[i].ban = 0; c_arr[i].grace = g_grace; c_arr[i].hard = g_hard; c_arr[i].mail = g_mail; c_arr[i].clear = g_clear; c_arr[i].warn = g_warn; c_arr[i].log = g_log; } eat_confile() { FILE *f; char *s, iline[LINELEN]; int i, lev; int idle; if (!(f=fopen(confname, "r")) ){ if (debug) printf("Can't find file: %s\n", confname); } else { while (fgets(iline, LINELEN, f)){ if (*iline == '#' || strlen(iline) <= 1) continue; /*.. check for ps=command in config-file, extract command. ...............*/ s=strstr(iline,"ps="); if (s){ ps_cmd = strcpy((char *)malloc(strlen(s)+1),s+3); continue; } set_defs(c_idx); s=strtok(iline,delims); do{ lev = 1; if (!strncmp(s,"name=",5) && *(s+=5)) c_arr[c_idx].name=strcpy((char *)malloc(strlen(s)+1),s); else if (!strncmp(s,"group=",6) && *(s+=6)) c_arr[c_idx].group=strcpy((char *)malloc(strlen(s)+1),s); else if (!strncmp(s,"line=", 5) && *(s+=5)) c_arr[c_idx].line=strcpy((char *)malloc(strlen(s)+1),s); else if (!strncmp(s,"idle=", 5) && *(s+=5)) c_arr[c_idx].idle=atoi(s); else if (!strncmp(s,"grace=",6) && *(s+=6)) c_arr[c_idx].grace=atoi(s); else if (!strncmp(s,"ban=", 4) && *(s+=4)) c_arr[c_idx].ban =atoi(s); else { if (!strncmp(s,"no",2)){ lev=0; s+=2; } if (!strcmp(s,"hard")) c_arr[c_idx].hard=lev; else if (!strcmp(s,"clear")) c_arr[c_idx].clear=lev; else if (!strcmp(s,"mail")) c_arr[c_idx].mail=lev; else if (!strcmp(s,"warn")) c_arr[c_idx].warn=lev; else if (!strcmp(s,"log")) c_arr[c_idx].log=lev; else if (!strcmp(s,"lostkill")) lostkill=lev; else if (debug) printf("Unknown token in file: %s: %s\n",confname,s); } } while(s=strtok(0,delims)); idle=c_arr[c_idx].idle; /*.. Maybe it is necessary to reduce the max. sleeptime to shortest session. */ if (0< c_arr[c_idx].hard && 0Name ); strcpy(dev, akt_usr->Device); idle = akt_usr->IdleTime; stime = pres_time - akt_usr->SessStrt; akt_usr->IdleTime = 30000; /* 20 days will "clear" the idletime */ if (debug) printf("\nuser: %-10s %-10s %-d\n",name,dev,idle); sprintf(ddev,"/dev/%s",dev); /* append /dev/ to base name */ /*.. If user has logged out, check his Session time and so. .................*/ if (debug) printf("now: %d = %s",pres_time,ctime(&pres_time)); if (listall) printf("\nChecking: %-11s on %-12s I:%-4d\n",name,dev,idle); /* now try to find the group of this person */ /* if usernames in utmp are limited to 8 chars, we will may fail on */ /* names that are longer than this, so we'll try to find it by uid */ if (!(passwd_entry = getpwnam(name))) /* If can't find by name */ passwd_entry = getpwuid(akt_usr->UserID); /* try by uid */ if (passwd_entry){ strcpy(name,passwd_entry->pw_name); if(group_entry = getgrgid( passwd_entry->pw_gid )) gn = group_entry->gr_name; else if (debug) printf("Can't find group entry for user: %s\n",name); } else if (debug) printf("Can't find password entry for user: %s\n",name); for(i = 0; i < c_idx; i++){ if (pat_match(c_arr[i].name, name) && pat_match(c_arr[i].group,gn) && pat_match(c_arr[i].line, dev)){ // if (debug) // printf("Match #%2d: U:%-12s Grp:%-8s Line:%-9s Pid:%-6d Sess:%3d:%02d\n", // i+1,name,gn,utmpp->ut_line,utmpp->ut_pid,stime/60,stime%60); if (c_arr[i].idle<0){ /* if user exempt (idle<0) */ if (debug) printf("User exempt\n"); return(0); /* then don't kill him */ } ce = &c_arr[i]; /* get address of matched record */ break; } } if (i >= c_idx) { if (debug) printf("No match for process\n"); return(0); } /* device empty or new user => check whether banning is over. ...............*/ if (stat(ddev, &status) || status.st_uid != akt_usr->UserID){ if (pres_time>akt_usr->Ban_Ends){ /* End of banning-time */ akt_usr->SessStrt = pres_time; /* allow new session. */ akt_usr->Ban_Ends = 0; /* (just for debugging). */ akt_usr->WarnEnds = 0; /* user may return, now. */ return(2); /* 0 => user done. */ } else lower_sleep(ChckSleep); /* user might come back */ strcpy(akt_usr->Device, "."); /* "Flag": user logged out. */ if (debug){ if (stat(ddev, &status)) printf("user has logged out.\n"); else if (status.st_uid != akt_usr->UserID){ printf("%4d <> %4d\n",status.st_uid,akt_usr->UserID); printf("user has changed -> do not disturb.\n"); } } return(0); } /* Check whether to knock out this user. ....................................*/ if (!c_arr[i].hard) { /* if considering idle time */ if ( akt_usr->Ban_Endsidle){ /* if user was recently active */ akt_usr->WarnEnds = 0; /* set to not warned. */ return(0); } if (debug) printf("Subject to logout Idle time: %4d (%2d allowed)\n", idle,ce->idle); } else if (debug) printf("User temporary banned.\n"); } else { int time_left; /*.. In case, he leaves now, his ban will end after his banning-time. .......*/ /*.. This will also increase his banning-time in case he returnes to early. .*/ /*.. Set end of banning to current time + time to ban user. ................*/ akt_usr->Ban_Ends = pres_time + 60*ce->ban; if (debug) printf("Banning should end: %10d\n", akt_usr->Ban_Ends ); /*.. Make sure, daemon doesn't sleep too long from now. .....................*/ if (debug) printf("idle-state: %3d / %d:\n",idle, ce->idle ); if (debug) printf("sess-state: %3d / %d:\n",stime/60,ce->idle ); time_left=60*ce->idle - stime; if (debug) printf("time left: %4d sec.\n", time_left); if (0grace); /* process is to be killed */ if (debug) printf("Subject to logout Total time: %4d (%2d allowed)\n", stime/60,ce->idle); } if (stat(ddev, &status)){ bailout("Can't get status of user's terminal", 2); return(0); } /*.. action either warning or killing. */ // if (akt_usr->WarnEndsed && (pres_time > akt_usr->Ban_Ends) ) { if (0WarnEnds && (pres_time > akt_usr->WarnEnds) ) { if (debug) printf("Killing user, now.\n"); if (kill_PIDs(name)==1) /* try to kill users' processes */ mesg(LOGOFF, name, ddev, stime/60, idle, ce); /* mail to user */ else mesg(NOLOGOFF,name, ddev, stime/60, idle, ce); /* couldn't kill */ if (ce->hard) akt_usr->WarnEnds =-1; /* if user returnes at ones -> angry */ else{ akt_usr->WarnEnds =-2; akt_usr->Ban_Ends = pres_time /* give other users a chance */ + Idle_Ban; /* to catch this computer. */ lower_sleep(ChckSleep); } } else if (akt_usr->WarnEnds==-2){ /* punish being idle for too long. */ mesg(IDLEPUNISH, name, ddev, stime/60, idle, ce); akt_usr->WarnEnds = pres_time+5; /* give some time to read message */ lower_sleep(5); if (debug) printf("idle-punish\n"); } else if (akt_usr->WarnEnds==-1){ mesg(ANGRY, name, ddev, stime/60, idle, ce); /* angry about user. */ if (debug) printf("I am angry, user returned...\n"); if (kill_PIDs(name)==1) /* try to kill user, at once */ mesg(LOGOFF, name, ddev, stime/60, idle, ce); /* mail to user */ else mesg(NOLOGOFF,name, ddev, stime/60, idle, ce); /* couldn't kill */ } else { if (akt_usr->WarnEnds==0){ mesg(WARNING, name, ddev, stime/60, idle, ce); /* try to warn user. */ akt_usr->WarnEnds = pres_time+ce->grace; /* wait until grace ends */ if (debug) printf("Warning user:%s Line:%s Sleep %d sec\n",name,dev,ce->grace); } lower_sleep(ce->grace); } return(0); } /*---------------------------------------------------------------------------*/ /*=== This function finds out the PIDs of the current user. ===*/ /*---------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ void get_PIDs /* find processes of a given user. */ /*----------------------------------------------------------------------------*/ (char *u_name) /* name of the user. */ /*----------------------------------------------------------------------------*/ /* this version assumes that ps -au returns one header-line and then */ /* lines with usernames, pids and some other stuff */ { char prname[LINELEN], iline[LINELEN]; char *s; char *ps_name, *ps_pid; struct stat status; FILE *ps; int i, pid, uid; if (!(ps = popen(ps_cmd, "r")) ){ bailout("Can't use ps program", 6); return; } fgets(iline, LINELEN, ps); /* get header-line */ ids_fill = 0; while (fgets(iline, LINELEN, ps)){ ps_name= strtok(iline,delims); /* manual: Never use this function. */ ps_pid = strtok(0,delims); pid = atoi(ps_pid); sprintf(prname,"/proc/%d",pid); /* append /proc/ to proclist */ if (stat(prname, &status)) printf("Dead process: \n"); uid = status.st_uid; if (debug) printf("%-8s -> %5s %5d %5d\n", ps_name, ps_pid, pid,uid); if ( strcmp(u_name,ps_name)==0 ){ if (debug) printf(" -> ok, Name = %s => kill.\n",u_name); ids_fill++; if (ids_fill > ids_max) { ids_max = 2*(ids_max); ids_lst = (int*) realloc(ids_lst,sizeof(int)* (1+(ids_max))); } ids_lst[ids_fill]=pid; } } fclose(ps); if (debug) { printf (" |-> "); for (i=1; i<=ids_fill; i++) printf (" %5d",ids_lst[i]); printf ("\n"); } } /*---------------------------------------------------------------------------*/ /*=== The following functions have a murder job. ===*/ /*---------------------------------------------------------------------------*/ int kill_PIDs(char *u_name){ int i,ok=1; ids_max = 50; ids_lst = (int*)calloc(sizeof(int),1+(int)(ids_max)); if (debug) printf("\nget PIDs for %s\n",u_name); /*.. Tell processes to hang up. .............................................*/ // ids_fill = 0; get_PIDs(u_name); if (do_bite) for (i=1; i<=ids_fill; i++) kill_HUP(ids_lst[i]); sleep(HUP_WAIT); /*.. Check for processes that still survived and now kill them. .............*/ /*.. This will also kill a user that returns at once. Without warning. :) ...*/ ids_fill = 0; get_PIDs(u_name); if (do_bite) for (i=1; i<=ids_fill; i++) kill_KILL(ids_lst[i]); sleep(KILLWAIT); /*.. Check for processes that survived killing. .............................*/ if (do_bite) for (i=1; i<=ids_fill; i++) { if (kill_Res(ids_lst[i])) ok=0; } free (ids_lst); return(ok); } kill_HUP(int pid){ /* terminate process using SIGHUP, first. */ kill(pid, SIGHUP); /* first send "hangup" signal */ } kill_KILL(int pid){ /* terminate process using SIGKILL, later.*/ kill(pid, SIGKILL); /* then send sure "kill" signal. */ } int kill_Res(int pid){ /* Check for processes that refused to die.*/ if (!kill(pid, 0)) return(1); /* failure--refuses to die! */ else return(0); /* successful kill with SIGKILL */ } /*---------------------------------------------------------------------------*/ /*=== The following functions spread the messages to everywhere. ===*/ /*---------------------------------------------------------------------------*/ mesg(int flag, char *name, char *dev, int stime, int idle, conf_el *ce) { char mbuf[LINELEN]; /* message buffer */ char *hint; time_t tvec; FILE *fp, *mprog; time(&tvec); /* tvec = current time. .....*/ if (flag == IDLEPUNISH && ce->warn) { /* process warning message. */ hint="** IDLE-PUNISH **"; if (!(fp = fopen(dev, "w")) ){ bailout("Can't open user's terminal", 5); return(0); } if (ce->clear){ sprintf (mbuf,"clear >%s",dev); system (mbuf); } fprintf(fp,"\n\n\r"); /* \r is sometimes needed...*/ fprintf(fp,".--------------------------------------------.\n\r"); fprintf(fp,"| %10s, you have been idle too long. |\n\r",name); fprintf(fp,"| Punishment: Log out for %3d seconds! |\n\r",Idle_Ban); fprintf(fp,"`--------------------------------------------'\n\r"); fprintf(fp,"\07\n"); sleep(1); fprintf(fp,"\07\n"); sleep(1); fprintf(fp,"\07\n\r"); sleep(10); /* just some time to read this message */ fclose(fp); } if (flag == ANGRY && ce->warn) { /* process warning message. */ hint=" ** ANGRY **"; if (!(fp = fopen(dev, "w")) ){ bailout("Can't open user's terminal", 5); return(0); } if (ce->clear){ sprintf (mbuf,"clear >%s",dev); system (mbuf); } if (ce->hard){ fprintf(fp,"\n\n\r"); /* \r is sometimes needed...*/ fprintf(fp,".--------------------------------------------------.\n\r"); fprintf(fp,"| %10s, you have just been kicked off. |\n\r", name); fprintf(fp,"| Make off, don't try it again, today. |\n\r"); fprintf(fp,"`--------------------------------------------------'\n\r"); fprintf(fp,"\07\n"); sleep(1); fprintf(fp,"\07\n"); sleep(1); fprintf(fp,"\07\n\r"); sleep(10); /* just some time to read this message */ } fclose(fp); } if (flag == WARNING && ce->warn) { /* process warning message. */ hint="** NOTIFIED **"; if (!(fp = fopen(dev, "w")) ){ bailout("Can't open user's terminal", 5); return(0); } if (ce->clear){ sprintf (mbuf,"clear >%s",dev); system (mbuf); } if (ce->hard){ fprintf(fp,"\n\n\r"); /* \r is sometimes needed...*/ fprintf(fp,".--------------------------------------------------.\n\r"); fprintf(fp,"| %10s: You've been on for %3d min. |\n\r", name, stime); fprintf(fp,"| You'll be logged off in %3d sec. so finish up. |\n\r", ce->grace); fprintf(fp,"`--------------------------------------------------'\n\r"); fprintf(fp,"\07\n"); sleep(1); fprintf(fp,"\07\n"); sleep(1); fprintf(fp,"\07\n\r"); } else { fprintf(fp,"\n\n\r"); /* \r is sometimes needed...*/ fprintf(fp,".----------------------------------------------.\n\r"); fprintf(fp,"| %10s: You've been idle for %3d min. |\n\r", name, idle); fprintf(fp,"| You'll be logged off in %3d sec |\n\r", ce->grace); fprintf(fp,"| unless you hit a key. |\n\r"); fprintf(fp,"`----------------------------------------------'\n\r"); /*.. Try to wake up sleeping user by beeping 3 times. . .....................*/ fprintf(fp,"\07\n"); sleep(1); fprintf(fp,"\07\n"); sleep(1); fprintf(fp,"\07\n\r"); } fclose(fp); if (ce->mail){ sprintf(mbuf, "/bin/mail -s \"++WARNING - LOG-OFF ++\" %s", name); /* open pipe to mail program for writing */ if (!(mprog = popen(mbuf, "w")) ){ bailout("Can't use /bin/mail program", 6); return(0); } if (ce->hard){ fprintf(mprog, "Your session-limit will be reached soon.\n"); fprintf(mprog, " %s: You've been on for %3d min.\n", name, stime); fprintf(mprog, " You'll be logged off in %3d sec.\n",ce->grace); fprintf(mprog, " So finish up, please.\n"); } else{ fprintf(mprog, "Your have been idle for quite a long time.\n"); fprintf(mprog, " %s: You've idle for %3d min.\n", name, stime); fprintf(mprog, " You'll be logged off in %3d sec.\n",ce->grace); fprintf(mprog, " Please: Type something into a terminal \n"); fprintf(mprog, " or you'll be kicked off.\n"); } fclose(mprog); } } if (flag == LOGOFF){ hint="** LOGOFF **"; if (ce->mail){ sprintf(mbuf, "/bin/mail -s \"Logged off, you were idle\" %s", name); /* open pipe to mail program for writing */ if (!(mprog = popen(mbuf, "w")) ){ bailout("Can't use /bin/mail program", 6); return(0); } fprintf(mprog, "Subject: Excess Idle Time\n\n"); fprintf(mprog, " Logged off - %s - %s\n",name, ctime(&tvec)); fprintf(mprog, " - excess idle time - \n"); fprintf(mprog, " on tty = %s\n",dev+5); fclose(mprog); } } if (flag == NOLOGOFF){ hint="** LOGOFF FAILED **"; if (ce->mail){ sprintf(mbuf, "/bin/mail -s \"Couldn't log out [%s] \" root",name); if ((mprog = popen(mbuf, "w")) == (FILE *) NULL){ bailout("Can't use /bin/mail program", 7); return(0); } fprintf(mprog, "Subject: Can't logoff %s\n", name); fprintf(mprog, "Can't Log off - %s %s\n", name, ctime(&tvec)); fprintf(mprog, "tty = %s\n", dev+5); fclose(mprog); } } if (ce->log){ /* Generate logfile message */ char msg[100]; sprintf(msg, "%-20s %-8s %-5s idle:%3d sess:%3d", hint,name, dev+5, idle, stime); log_msg(msg); } return(0); } log_msg(char *message) { /* This function adds something to a logfile. ......*/ FILE *log = 0; struct stat status; char str_time[30]; if (stat(logfname, &status) >= 0){ /* if logfile exists */ log = fopen(logfname, "a"); /* open to append */ if (log==NULL) return(1); /* fopen failed. */ sprintf(str_time,"%s",ctime(&pres_time)+3); str_time[strlen(str_time)-1]=0; fprintf(log, "%s - %s\n",str_time,message); fclose(log); return(0); } } bailout(char *message, int status){ /* Handle error message. */ char msg[100]; /* Try to log the message. */ sprintf(msg, "%-20s %s %-5s idle:%3d sess:%3d", "** ERROR **" , message); log_msg(msg); } /*.. reduce time to sleep for the next time the daemon falls asleep. ........*/ lower_sleep(int sleep_left){ if ( 0 not found */ /*.. have ps tell us all current users, uids and pids. ......................*/ if (!(ps = popen(ps_cmd, "r")) ){ bailout("Can't use ps program", 6); return; } fgets(iline, LINELEN, ps); /* get header-line */ ids_fill = 0; while (fgets(iline, LINELEN, ps)){ ps_name= strtok(iline,delims); /* manual: Never use this function. */ ps_pid = strtok(0,delims); pid = atoi(ps_pid); sprintf(prname,"/proc/%d",pid); /* append /proc/ to proclist */ if (stat(prname, &status)){ userpos=-1; /* => process will be killed. */ if (do_bite) kill(pid, SIGKILL); /* send the "kill" signal */ sprintf(mbuf,"Dead , killed: %-10s %5d : %5d",ps_name,uid,pid); log_msg(mbuf); } else{ uid = status.st_uid; if (debug) printf("%-8s -> %5s %5d %5d\n", ps_name, ps_pid, pid,uid); if (500 <= uid && uid <= 60000){ /* neither root nor nobody */ /*.. Get Position of user in userlst. .......................................*/ strcpy(userlst[0].Name, ps_name); userpos=userfill; while ( strcmp(userlst[userpos].Name,ps_name) ) userpos--; if (userpos ==0 ){ /* user not found => not active */ if (do_bite) kill(pid, SIGKILL); /* send the "kill" signal */ sprintf(mbuf,"Lost, killed: %-10s %5d : %5d",ps_name,uid,pid); log_msg(mbuf); } else if(strlen(userlst[userpos].Device)==1){ /* "." */ if (do_bite) kill(pid, SIGKILL); /* send the "kill" signal */ sprintf(mbuf,"Left, killed: %-10s %5d : %5d",ps_name,uid,pid); log_msg(mbuf); } } } } fclose(ps); } autolog-0.40/autolog.conf100644 1300 146 3154 7102305520 13757 0ustar cjstudent# Enter a regular expression for the username, group and tty line. # All three expressions must be matched before the rest of the line will # be applied to any process. # If the process has been idle (or connected) more than "idle" minutes, # autolog will attempt to kill the process. # If idle<0, the process is exempt. # If idle=0, the users must not be idle for to long :) -> debugging # If "nowarn" is asserted, the user will # not be warned that it is about to be killed. # After "grace" seconds, autolog will attempt to kill the process. # If "mail" is asserted, mail will be sent to the user # telling how his process met its end. # If "hard is asserted, the process will be killed # after "idle" minutes of total session time (rather than idle time). # ban=xx: A user extending his session-limit will be banned for xx minutes. name=ppp-.* idle=-1 line=ttyS2 line=pty.* idle=30 grace=30 nomail nolog group=games idle=10 grace=60 group=lynx.* idle=10 grace=60 clear # protected users name=root idle=-1 # idle - limits group=student idle=15 grace=180 # session - limits group=users idle=60 grace=120 hard ban=20 clear name=guest idle=60 grace=60 hard ban=5 clear # This makes it possible to change the options... # make sure, ps with its options returns one heading-line # and lines beginning with: USERNAME PID # e.g.: cj 2568 # or : cj 2568 0.0 0.0 1944 0 pts/2 ..... [telnet] # No spaces or tabs before this option, please. # ps=ps -ef # ps=ps aux # ps=ps ax o user o pid # To stop autolog from killing lost processes, umcomment the next line. nolostkillautolog-0.40/autolog.conf.5.gz100644 1300 146 3370 7102305520 14541 0ustar cjstudentP 9autolog.conf.5W]sܶ}ǯ/-Ό'DձZJ۴IZm}ν)m}}Sڻ+\n :Y/7qEM+uEo[R7 u5iZ(lj? 5W./߿S8S?ǣhc[>{L<#?,.`&*Mu&F)NL8SJ `B։76S0ѹl7 ǂl~qq8jkhm-%M`q)bN aOP{ln4q{GC>9g""(P BD]lRQb>DR;}ø\Ռi\ނEvGZj/24 9nHo "\>-ȨeDu@#+i,Z%XU_3'\)*?Fo7JIhÙ#wuB l*@I{jt&y,HHlu?ї[Gr]ocPзQ|6(R|/rRUZp>0d8gDx8 > vkaJFŻ|T^J%_szUs2r3MD 5+}&9 |`sW4)0CbSΑ8Lgfz=`BkeAXryTs#~r `xM[mJ*7 #@PzL/ ],^׽ ^ʼnV?[b 2 h gy8;L؊Ntvw -;C``\BKr }1\{ZR0ha\ZtGDG9V%1"4ރG8EY $CAӨAMsqdLwubC5+wx/]BsEP i)b"+pmy[>`zI,O'ypCv r_11 (Kg/;? kFԥ8^qouizP}ٔ+ `\(H '-&iW`Z91?pӑh)h,H=|P0m,6!j uP8ټÇAFJMke3MEl/Z+ &4$Xƛ|czl!f+K$^K化QmI6*mnzNg[g?z{I2\wks|e$<۠^BC̊g<]W_e';L debugging # If "nowarn" is asserted, the user will # not be warned that it is about to be killed. # After "grace" seconds, autolog will attempt to kill the process. # If "mail" is asserted, mail will be sent to the user # telling how his process met its end. # If "hard is asserted, the process will be killed # after "idle" minutes of total session time (rather than idle time). # ban=xx: A user extending his session-limit will be banned for xx minutes. name=ppp-.* idle=-1 line=ttyS2 line=pty.* idle=30 grace=30 nomail nolog group=games idle=10 grace=60 group=lynx.* idle=10 grace=60 clear # protected users name=root idle=-1 # idle - limits group=student idle=15 grace=180 # session - limits group=users idle=0 grace=02 hard ban=1 clear name=guest idle=60 grace=60 hard ban=5 clear # This makes it possible to change the options... # make sure, ps with its options returns one heading-line # and lines beginning with: USERNAME PID # e.g.: cj 2568 # or : cj 2568 0.0 0.0 1944 0 pts/2 ..... [telnet] # No spaces or tabs before this option, please. # ps=ps -ef # ps=ps -aux # ps=ps ax o user o pid # To stop autolog from killing lost processes, umcomment the next line. # nolostkill autolog-0.40/autolog.dump100644 1300 146 6024 7102305520 13776 0ustar cjstudent/*****************************************************************************/ /* */ /* Programm: autolog.dump C-Programm to log out sleeping users */ /* */ /* Autor: Carsten Juerges Erster Versuch: 06.04.2000 */ /* Kurze Wanne 1 Letztes Update: 10.04.2000 */ /* 30926 Seelze */ /* juerges@cip-bau.uni-hannover.de */ /* */ /* Rechner: AMD K6-2 SuSE Linux 6.3 */ /* */ /* Meldung: This version seems to worke quite good. */ /* */ /* This files stores the old functions which have been rewritten. */ /* */ /*****************************************************************************/ /*===========================================================================*/ /* get_PIDs ===*/ /* - found, that some (old) ps-versions do not support my options ===*/ /*---------------------------------------------------------------------------*/ get_PIDs(char *u_name){ char mbuf[LINELEN]; /* message buffer */ FILE *ps; int i; int pid; sprintf(mbuf, "ps -U %s --no-heading o pid",u_name); //## if (!(ps = popen(mbuf, "r")) ) bailout("Can't use ps program", 6); while (!feof(ps)) { pid=0; fscanf(ps,"%d", &pid); //## if (pid>1){ /* otherwise feof or pid=0. can't kill pid=1 anyway. */ ids_fill++; if (ids_fill > ids_max) { ids_max = 2*(ids_max); ids_lst = (int*) realloc(ids_lst,sizeof(int)* (1+(ids_max))); } ids_lst[ids_fill]=pid; } } fclose(ps); if (debug) { printf (" |-> "); for (i=1; i<=ids_fill; i++) printf (" %5d",ids_lst[i]); printf ("\n"); } } /*---------------------------------------------------------------------------*/ kill_lost_PIDs(){ char mbuf[LINELEN]; /* message buffer */ FILE *ps; char u_name[20]; int pid, uid; int userpos=0; /* position of user found, 0 => not found */ /*.. have ps tell us all current users, uids and pids. ......................*/ sprintf(mbuf, "ps ax --no-heading o user o uid o pid"); //## if (debug) printf("\n"); if (!(ps = popen(mbuf, "r")) ) bailout("Can't use ps program", 6); while (!feof(ps)) { pid=0; fscanf(ps,"%s", u_name); //## fscanf(ps,"%d", &uid); //## fscanf(ps,"%d", &pid); //## if (pid>1){ /* otherwise feof or pid=0. can't kill pid=1 anyway. */ if (100 < uid && uid < 65534){ /* neither root nor nobody */ /*.. Get Position of user in userlst. .......................................*/ strcpy(userlst[0].Name, u_name); userpos=userfill; while ( strcmp(userlst[userpos].Name,u_name) ) userpos--; if (userpos ==0 ){ /* could not find this user => not active */ if (do_bite) kill(pid, SIGKILL); /* send the "kill" signal */ if (debug){ printf("kill: %-10s %5d : %5d\n",u_name,uid,pid); } } } } } fclose(ps); } /*===========================================================================*/ autolog-0.40/autolog.init100744 1300 146 1626 7102305520 14000 0ustar cjstudent#! /bin/sh # Copyright (c) 2000 Carsten Juerges, Hannover, Germany. All rights reserved. # # Author: Carsten Juerges , 2000 # # /sbin/init.d/autolog # . /etc/rc.config base=${0##*/} link=${base#*[SK][0-9][0-9]} test $link = $base && START_AUTOLOG=yes test "$START_AUTOLOG" = yes || exit 0 export PATH=/bin:/usr/bin:/sbin:/usr/sbin export HOME=/ return=$rc_done case "$1" in start) echo -n "Starting autolog daemon" startproc /usr/sbin/autolog || return=$rc_failed echo -e "$return" ;; stop) echo -n "Shutting down autolog daemon" killproc -TERM /usr/sbin/autolog || return=$rc_failed echo -e "$return" ;; restart) $0 stop && $0 start || return=$rc_failed ;; status) checkproc /usr/sbin/autolog && echo "autolog up" || echo "No autolog" ;; *) echo "Usage: $0 {start|stop|status|restart}" exit 1 esac test "$return" = "$rc_done" || exit 1 exit 0 autolog-0.40/autolog.log100644 1300 146 51 7102305520 13544 0ustar cjstudent Apr 9 19:55:29 2000 - Starting Service autolog-0.40/CHANGES100644 1300 146 3700 7102305520 12426 0ustar cjstudentCHANGES(autolog): ================ - 0.2: Added 'hard' logout feature. Several bug fixes. - 0.21: Added 'pre-clear' option. - 0.30: Rewrote the configuration file parser. Added group matching and the "nowarn" option. Rewrote/cleaned up almost the whole program. - 0.31: Fixed bug with searching for group. If the group could not be found from the username, the program would segmentation fault. Hopefully fixed. - 0.32: re_exec seems to have a bug that dumps core in some cases. I rewrote the pat_match routine to not use it. Both versions of pat_match are included with an #ifdef. - 0.33: Nov 1996 Kyle Bateman Fixed bug in logging routine. When writing to log file, the program could crash. Also more careful check for non-existent processes. - 0.34: Dec 1996 Kyle Bateman Added man pages (thanks to Christoph Lameter). Some login processes didn't twiddle the "last access" time when a user first logged in. Checked to see if last access was older than login time to rule out such problems. - 0.35: Oct 1998 Kyle Bateman fixed segfault error (Thanks to Thomas Gray). fclose(log) was being called even when the logfile hadn't been opened. - 0.40: April 2000 Carsten Juerges Rewritten parts of the code to chase users and to make sure, they get the information about their approaching end. April 14, 2000 Detected some old(?) ps-commands which do not support the parameters, I used. rewritten this part and enabled a feature to pass any strange ps-command via config-file. April 28, 2000 Checked README-file and the manual-entries to make sure one will find information about all the new features. Added a little feature "nolostkill" to stop this program from killing lost processes. Only lost processes with uid (user-id) between 500 and 60000 will be killed, others usually belong to system processes. autolog-0.40/Makefile100644 1300 146 1417 7102305520 13076 0ustar cjstudent# ********************************************************* # Change this section as needed # The -g flag is to include debugging information. It gets # stripped back out in the install command anyway. CC = gcc CFLAGS = -g MANDIR = /usr/man BINDIR = /usr/sbin/ LOGDIR = /var/log/ INIDIR = /sbin/init.d/ # ********************************************************* autolog: autolog.c $(CC) $(CFLAGS) -o autolog autolog.c install: autolog install -m744 -o 0 -g 0 autolog $(BINDIR) install -m744 -o 0 -g 0 autolog.init $(INIDIR)/autolog install -m644 -o 0 -g 0 autolog.conf /etc install -m644 -o 0 -g 0 autolog.log $(LOGDIR) install -m644 autolog.conf.5.gz $(MANDIR)/man5 install -m644 autolog.8.gz $(MANDIR)/man8 clean: rm autolog autolog-0.40/README100644 1300 146 34060 7102305520 12336 0ustar cjstudentAutolog 0.40 Autolog is a new version of autolog by Kyle Bateman (kyle@actarg.com), modified by me (Carsten Juerges, juerges@cip-bau.uni-hannover.de) to get the logout-warning on that terminal I worked in, last time. Before the warning was written on the login-screen, where I started X (startx), so it was difficult to get or to react on this warning. Now it is checked, which is the terminal with the shortest idle-time and the message is displayed there. So I can react on it, there. I put the old readme-text below the (=====)-line and added my changes (of details) into that text. They can be found by searching for "##". Here I just want to report about a few changes, I added to the program. - first of all: This program can run in daemon-mode or as "ordinary program". As ordinary program it writes "/tmp/autolog.data" when starting. So it is not necessary to keep the program in memory to chase sleeping users. As this file is read, when the program starts. If this file doesn't exist, no problem. It will be generated next time. See the options. If running as daemon, make sure, you don't start it several times e.g. by crontab. If running as ordinary program, it will stay at least as long in memory until all necessary kickouts are done. And some more time to make sure, user doesn't return 2 minutes later. (Until als bans are over.) - if a user logs out, before his session-limit is reached, his limit will be reset. It was also possible to log in again, after being kicked out. -> fixed this. added a ban-time. (##-1) the session-limit will be reset when the banning has passed or a bit later, depends on when the daemon wakes up from sleeping. -> added little feature that kills forgotten processes. they do appear (e.g. netscape) when a user does not terminate netscape correctly. -> daemon tries to wake up a sleeping user by beeping. the user also gets an email, his beeping might not work. Email might not work on a network, don't know, could only test this on one network, there it worked. -> being idle for too long is punished with 2 Mins ban. Users should not be punished for being idle they might be thinking about the current problem. They deserve a little break. These two minutes should only stop those user who log in again and again to block the computer. -> if the user tries to login before his ban-time ends, he will be kicked out without any warning. He will be banned for the originial ban-period, again :) -> changed the "exempt-code" to idle=-1, so idle=0 will be usefull for demonstration-purpose. -> the information about crontab (down in the text) has expired, if running this program as daemon. left it, because i find the hints about crontabs quite usefull. Maybe it is usefull to restart the program from time to time as it might have halted due to any errors. (via cron) The program should only run once on a machine. Otherwise the resulting user-information about being kicked out it might be confusing. -> Make sure to reduce the size of the log-file from time to time, as it is always growing when adding messages. The logile or at least a part of it might be usefull to find misconfiguration or even bugs in the program. ======================================================================= Autolog 0.35 Autolog is a version of autologout (idleout-mcm) modified by me to allow a more detailed configuration file, and to accept command line parameters. According to David Dickson, the code originally came from the "Wizard's Grabbag" from the May 1990 Unix World. He ported the code essentially unchanged. Mike Mitchell added some code to read a file "/etc/autologout.exempt" listing those users which should not be subject to auto logout. My system required a little more complex approach. I wanted some users to be logged off more aggressively than others. I wanted my own sessions to remain on line only if they existed on certain ports. I also wanted users coming in over the net to be subject to a little different idle time than other users. After doing version 0.20, several people wrote with various additions and patches. The problem was that the original syntax of the autolog.conf file was a bit limiting and it was hard to work in too many additional features without making a big fat mess. With the new, improved format of the configuration file, I should be able to accomodate many more future features. The configuration file consists of multiple lines, each of which describes a class of processes subject (or not subject) to a certain auto logout procedure. A line consists of any number of switches. Value switches are of the form: "name=value". Boolean switches are of the form: "name" or "noname". Here are some example lines: name=root line=tty[1-7] idle=0 name=guest idle=5 grace=60 nomail hard warn group=lynx-.* idle=10 grace=60 clear idle=60 grace=30 Using these switches, you can define a username, a group, and a tty line. These descriptions can contain wildcard characters (regular expressions). You can also define an idle time, a grace period and a few other options. When reading the configuration file, the program creates a record for each configuration line. A value is assigned to each variable in the record regardless of whether or not you specify one explicitly. Values for missing variables are provided by defaults which are compiled in and can be modified from the command line. If no configuration file is found, the program will create a single entry which has all values set from the defaults. This entry will match any process on any port (name=.+ line=.+ group=.+). Therefore, the default action is to kill all processes. The values which can be set for each entry are as follows: name= A regular expression specifying which username(s) to match. group= A regular expression specifying which group(s) to match. line= A regular expression specifying which tty line(s) to match. Omit the "/dev/" part of the special name. idle= An integer specifying the number of --minutes-- of idle (or connect) time to allow before beginning automatic logoff. An idle time of 0 exempts the process from automatic logoff. (##) changed this to "-1" => exempts idle-time. this allows short idle-time "0" for demonstrating. grace= An integer specifying the number of --seconds-- from the initial warning to killing the process. ban= An integer specifying the number of --minutes--, the user should stay away after exceeding his session-limit. (##-1) hard A boolean value indicating total connect time will be considered rather than idle time. mail A boolean value indicating that mail will be sent to the user explaining that he was killed. clear A boolean value indicating that the screen will be cleared before a warning message is sent. (##) -> will only be cleared, if user is still on that screen. warn A boolean value indicating that a warning message will be sent at the beginning of the "grace" period. log A boolean value indicating that activities will be logged to the logfile (if it exists). Additionally I added a feature for exotic ps-versions: ps=ps -ef a ps-command, which results in one heading line and lines starting with username and pid e.g. "ps=ps aux" on SuSE Linux. lostkill A boolean value indicatin whether this program should kill lost processes or not. So place "nolostkill" in the config-file doesn't touch them. If enabled(default), this program will only kill lost processes with uid between 500 and 60000. Other uids (at least in some Linux dialects) belong to system processes which should not be killed. Once configured, the program reads the utmp file, entry by entry. The username for each 'user process' is compared to the entries in the configuration file. The first entry to match both the name, the group, and the tty line of the process will be used to conduct the automatic logout. If no entries are found matching a given process, that process will be spared from an untimely demise. Therefore, it is a good idea to always have a "cleanup" line at the end of the configuration file to catch anything that might have been missed by the more explicit definitions. Since the default name, group, and line are all ".+", a simple line like: idle=30 will do. Actually, any one switch can be specified on the line and all the others will get the default values. See the sample file autolog.conf for an example configuration. Installation Instructions: 1. If desired, edit the defaults in autolog.c such as D_IDLE, D_GRACE, D_MAIL, etc. (This is generally not necessary). If you want the binary to land somewhere besides /usr/sbin, edit the Makefile accordingly. 2. Type 'make install'. 3. Copy autolog.conf to /etc and then edit it to make the changes needed by your system. (See the instructions above.) 4. Wait until the system has a bunch of idle processes. Run "autolog -d -n |less" and examine the output to see that the desired processes are going to "get the axe." If it looks good, try running "autolog -d" to make sure. When you're happy with your configuration file, setup cron. 5. In your Crontab file place a line that invokes autolog about every few minutes, such as: 0,10,20,30,40,50 * * * * /usr/sbin/autolog On my system cron only runs the process at night. This way, users sessions stay on uninterrupted during the workday. I use the lines: 0 20 * * * /usr/sbin/autolog 0 22 * * * /usr/sbin/autolog 0 1 * * * /usr/sbin/autolog COMMAND LINE PARAMETERS: -a (all processes) Print information on ALL utmp entries--not just user processes. -d (debug mode) This is helpful in setting up your configuration file. The program runs in foreground rather than forking and it prints out verbose messages about what it is doing. -n (nokill) Use this to prevent autolog from actually "killing" anyone. Use -d and -n together when setting up a new configuration file. -o (ordinary) Use this to start the program as ordinary program. Otherwise it will stay as daemon in memory. Good idea if you are low on memory. -f config_file_name Use this to override the default: "/etc/autolog.conf" -l log_file_name Use this to override the default: "/var/log/autolog.log" Note that if this file doesn't exist, no logging will happen. Create the file (with touch) to enable logging. -t idle_time Use this to override the internal default idle time (minutes) -g grace_period Use this to override the internal default grace period (seconds) -m yes/no Use this to override the internal mailing switch. If "yes" the program will send mail to the users right after killing them. -c yes/no Use this to override the internal "pre-clear" switch. If "yes" the program will clear the terminal screen before warning the user. -w yes/no If set to "no" no warning message will be printed to processes about to be killed. -h yes/no Do timeouts based on total session time--not idle time. (hard) -L yes/no If set to "yes" activities will be written to the logfile if present. Bugs/Caveats: - The utmp file seems to only hold 8 characters worth of login name. If your login name is shorter than this, note that autolog may only see the first 8 characters. This is screwing up the group search function too. This shouldn't be too hard to fix. I'll just have to derive the real login name from the pid or something... - There is a feature that would be very helpful that autolog doesn't have yet. The ppp program generally creates a login process which is seen by autolog. The problem is that network activity does not change the idle time on the tty controlled by ppp. So there is no way (with the existing code) for autolog to know if the network link has gone idle for a period of time (it appears idle all the time--no matter what happens. So your choices are this: You can leave ppp out of your "autolog strategy" in which case it will look like an idle shell and will get killed. Or, you can put it in the configuration file with an exemption (idle=0) in which case it will never get killed no matter what. If someone knows where I can snoop in the OS (in a portable way) to find out how long its been since a ppp login passed any network traffic, I would add a ppp switch to be used for this purpose. - When this program get to another system, it sometime needs to be recompiled. I compiled it in SuSE 6.3 and running under SuSE 6.0 it gave a "segmentation fault" without recompiling. Ideas: - One might find out, how the "you have new mail"-message gets to the user and try to use this way for letting the user know about his coming end. - One might think about a pop-up box when running a session without any terminals. At the moment this program tries to send an email to the user. If one selects enough idle-time, this should be ok. - Maybe it is possible when this deamon starts sleeping, it actually terminates and gets started again after some time. This might save some memory when sleeping or sleeping for more than 5 Minutes. I assume, other deamons behave like this, too, but I don't know how... Have fun knocking off those 'delinquent' users! And don't let the power go to your head... Kyle Bateman kyle@actarg.com Be carefull when playing with a daemon. Devils like playing, but only they know all rules of their games! A game, plaid with a devil becomes the devil's game. Users should be informed about such a program running. Especially users, which are kicked off without warning might get very angry when loosing several hours of work. Keep in mind, some are running jobs over several hours. Carsten Juerges juerges@cip-bau.uni-hannover.de p.s. quoting a part of "man strtok" > BUGS Never use this function. This function modifies ...