#!/usr/bin/perl use strict; use warnings; use IO::Socket; use Digest::MD5 qw(md5 md5_hex md5_base64); use Net::LDAP; #use threads; #use threads::shared; # unix socket file my $socketfile ="/var/run/ldapcached.sock"; my $pidfile="/var/run/ldapcached.pid"; # program name my $prog="ldapcached"; $0=$prog; # ignore unix socket $SIG{PIPE} = sub { my $continue = 0 }; no warnings 'uninitialized'; ################### Auth Modules start ################### sub mod_AuthLDAP { # ldap module my $AdminDN = "CN=MyNtUser,CN=Users,DC=myproject,DC=com"; my $AdminPass = "MyNtUser_Pass"; my $SearchBase = "DC=myproject,DC=com"; my $LDAPServer = "192.168.0.10:389"; ######### my ($userName, $userPass ) = (@_); my $ldap = Net::LDAP->new($LDAPServer, verify=>'none') or die "$@"; my $mesg = $ldap->bind ($AdminDN, password=>$AdminPass); #print "\nLine2=".$mesg->code; $mesg->code && return('FAIL'); $mesg = $ldap->search(base=>$SearchBase, filter=>"sAMAccountName=$userName" ); $mesg->code && return('FAIL'); my $entry = $mesg->shift_entry; #while (my ($key,$value) = each(%{$mesg})) { print "\n\t$key,$value";} if ($entry) { my $userDN = $entry->dn; my $Result = $ldap->bind ($userDN, password=>"$userPass"); #print "\nLine6=".$Result->code. " - ".$entry->dump; if ($Result->code) { return('FAIL');} else { return('PASS');} } else { return('FAIL');} $ldap->unbind; } ################### Auth Modules end ##################### ################################# if ( $ARGV[0] =~ m/-?daemon/ ) { if ( -f $pidfile) { print " $prog pidfile exist!"; chomp(my $pid=`cat $pidfile`); chomp (my $tmp=`ps ax -o pid | egrep "$pid|$prog" | grep -v grep`); print "\n $prog running - $tmp\n"; exit 1; } my %cache; ########### Server Code ########### unlink $socketfile; my $data; my $server = IO::Socket::UNIX->new( Local => $socketfile, Type => SOCK_STREAM, Listen => 500 ) or die $!; # sock file ownership chmod 0644, $socketfile; chown scalar getpwnam('prod'), 0, $socketfile; $server->autoflush(1); while ( my $connection = $server->accept()) { my $data= <$connection>; ##print $data, $/; chomp $data; ############################ my $auth_status="DONT"; my ($key,$value)=split(/\s=!=\s/,$data); my $md5_value = md5_hex($value); if (exists $cache{$key}){ #while (my ($key1,$value1)= each(%cache)) { print "\n $key1 => $value1"; } if ($md5_value eq $cache{$key}) { #print "\nPassword matched from Cache\n"; $auth_status="Pass"; } else { ##print "\nGo to LDAP - No password match\n"; my $result = mod_AuthLDAP($key,$value); if ($result eq "PASS") {$auth_status="Pass";$cache{$key}=$md5_value;} else {$auth_status="Failed";} } } else { ##print "\nGo to LDAP"; my $result = mod_AuthLDAP($key,$value); if ($result eq "PASS") {$auth_status="Pass"; $cache{$key}=$md5_value;} else {$auth_status="Failed";} } ## send data to client print $connection "$auth_status\n"; } ## end of while loop ########### Server Code end ####### } else { print " * Usage: $0 < --daemon >";} #end print "\n";