Solved

Last User Login Script

Posted on 1998-05-27
7
191 Views
Last Modified: 2006-11-17
I am trying to write a script that will tell when a user on a network of 90 computers last logged in. Each Computer has its own wtmp file that holds last login information. The password file for the network is stored on a central computer and all the computers use NIS and NFS for file sharing. I want the script to go to each computer on the network (I have a list of computers it will read from called computer.list) and have it go in and tell me when the user last logged in on the network.
0
Comment
Question by:Enslaver
7 Comments
 
LVL 5

Expert Comment

by:b2pi
ID: 1206417
You could certainly do this, but it would be wrong, from both efficiency and security standpoints.  Instead, let me suggest that you have each user run a perl script upon login (via the global login files, depending on shell).

That script will connect with a server running on some designated machine (make sure to set the name of the machine in an environment variable so that it can be easily changed later), and hand off the name of the user and the name of the machine being logged into to the server.

The server script, also, of course, written in perl, will simply store the current time, username and machine name.  You'll probably want to use a berkeley db file for this.

You'll  find an example server and client in the camel.

0
 

Author Comment

by:Enslaver
ID: 1206418
With a network of 1000+ users that would be too tough. And I am not concerned about security. I have already thought this through and found my way to be the best way to do it.
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 1206419
can you finger your user at all hosts from computer.list?
Then it could be done.
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:Enslaver
ID: 1206420
Nope, fingerd only accepts requests from localhost.
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 1206421
Would be a hard job then ;-|

If fingerd is somehow secure, I assume that wtmp is not accesable from network too.

So you either must export your wtmp to a public (network-) accessable directory -not very clever-, or use a solution as b2pi suggested -you rejected-, or you do it similar as b2pi as follows:

each login writes to a public accessable file a notification line
a program reads this file at each login to get requiered information (you don't need a client/server solution for this)
0
 

Author Comment

by:Enslaver
ID: 1206422
Ok well my goal is to find out who to date hasnt logged in in 3 months. Not find out 3 months from now, and all wtmp's are accessable through nfs because we have each of the computers mounted on /net/computername
0
 
LVL 1

Accepted Solution

by:
leendert earned 200 total points
ID: 1206423
Hi there,

Ok here is what I did. I wrote two perl programs. A client which
must be installed on the target computer and a "querylu" (Query
Last User) script that sits on your computer.

What you need to do is to install the client script on the target
computer and to create an entry in the /etc/services and
/etc/inetd files.

Here are two examples of such entries :

/etc/services file :
lastuser         5610/tcp

/etc/inetd.conf file :
lastuser    stream  tcp nowait  root /usr/lenny/bin/script/lastuser lastuser

Note : the above line must be on one line. it wrapped while I
typed it in. Modify the path to the script to suit your needs.

After you modified these files you will have to "kill -1" the
inetd process. So do a "ps -ef/-aux | grep inetd" and kill it
with a -1 (HUP) signal. This will force inetd to reload it's
config.


The source of the lastuser script (client side) :

#!/usr/local/bin/perl

open (PWFile, "/etc/passwd");
@PWLines = <PWFile>;
close (PWFile);

foreach $PWLine (@PWLines) {
    chop ($PWLine);
    # Check for known user shells to identify valid users
    if ( ($PWLine =~ /ksh/) || ($PWLine =~ /tcsh/) ||
           ($PWLine =~ /csh/) || ($PWLine =~ /zsh/) ) {
        # This means we have a valid user.
        @Tok = split (/:/, $PWLine);
        $UserName = $Tok[0];
        $LastLine = `last | grep $UserName | head -1`;
        if ($LastLine ne "") {
            push (@LastLines, $LastLine);
        }
    }
}


while ($Input = <STDIN>) {
    chop($Input);
    if ($Input eq "all") {
        print @LastLines;
        exit;
    }
    else {
        foreach $Line (@LastLines) {
            if ($Line =~ /$Input/) {
                print $Line;
                `echo $Line > /tmp/dump`;
            }
        }
        exit;
    }
}


The source of the querylu (query last user ) script:

#!/usr/local/bin/perl

use Socket;


if ($#ARGV == -1) {
    printf ("Usage : querylu (all/<username>)\n");
    exit;
}
   
$UserName = $ARGV[0];
       
$QueryPort=5610;
       
open (CompFile, "computer.list") || die "Could not open computer.list file";
@CompLines=<CompFile>;
close (CompFile);
         
foreach $Computer (@CompLines) {
    chop ($Computer);

    $IAddr = inet_aton($Computer);
    $PAddr = sockaddr_in($QueryPort, $IAddr);
   
    $ProtoCol = getprotobyname('tcp');
    socket (SOCK, PF_INET, SOCK_STREAM, $ProtoCol) or die "Socket error : $!";
    connect (SOCK, $PAddr) or die "Connect error : $!";
     
    select(SOCK);
    $| = 1;
    select(STDOUT);
               
    print SOCK "$UserName\n";
             
    while ( $Line  = <SOCK> ) {
        printf ("[$Computer]$Line");
    }
    close (SOCK);
}


Notes :
You can modify the script to read the passwd file from your
central storage.

The query script will read the "computer.list"
file and query the specified users on the machines in the
list.

If you decide to use a different port in the services file,
please modify it in the querylu script as well.

I use these scripts with Perl v 5.004_04 on freeBSD 2.2.6

Usage :

After these scripts are installed, you can query all the users
by typing : "querylu all"

or you can specify a username on the command line.

I hope this will help you. If you have more problems concerning
this, please let me know.

Leendert.
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
On Microsoft Windows, if  when you click or type the name of a .pl file, you get an error "is not recognized as an internal or external command, operable program or batch file", then this means you do not have the .pl file extension associated with …
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now