#!/usr/bin/perl -w
##################################################################################
# checkpassads.pl #
# #
# Gaurang K. Pandya [gaubrig at yahoo.com] #
# #
# This script is build on Larry M. Smith's checkpassword.pl script. #
# So credit definitely goes to him too. Thanks Larry for this wonderful job. #
# I have just changed the core part of this script that checks for password, #
# to authenticate against Microsoft Active Directory Services, by just #
# binding and unbinding to ADS. It does need local users too for rest of #
# parameters like $HOME, $UID, $GID, $SHELL etc., so adding users to *nix #
# box is mandatory. #
# #
# I have written another script for fetching users from ADS and adding #
# them to *nix box. Which can be found at #
# #
# http://www.geocities.com/gaurangpandya/scripts/adduser.htm #
# #
# the latest version of this script can be found at #
# #
# http://www.geocities.com/gaurangpandya/scripts/checkpassads.pl.htm #
# #
# #
# Let me know if you change this or any comments/suggesions about this. #
# #
##################################################################################
# ::NOTE:: #
# #
# In order to use this script local user should have their SHELL set as #
# Windows 2000 Domain name i.e., if your W2k Domain is domain.company.com #
# then $SHELL for users should be "/domain". I have done this to prevent users #
# with same name but different domain being misunderstood as autherized user. #
# #
# This script can be used for all the trusted domains. #
##################################################################################
# ::DISCLAIMER:: #
# #
# This script has been provided "AS IS" and for free. Use it at your own risk. #
# Works well for me, your's *MAY* be different case!!!. You are expected to #
# test it before using it. #
# #
#I have included comments from Larry too as given below. #
##################################################################################
##################################################################################
# Larry M. Smith [chains-ads at FahQ2.com] #
# #
# #
# #
# Expects tcpserver environmental variables $TCPLOCALPORT and $TCPREMOTEIP. #
# See http://cr.yp.to/ucspi-tcp/environment.html #
# #
# Provided AS IS and free... It works on my system, your's *MAY* be #
# different!!! YOU as sysadmin, are expected to TEST everything that #
# you bring online!!! Also, you may not like the way I log failed #
# passwords. #
# #
# If you see something that could/should be done differently please let me #
# know. #
# #
##################################################################################
##################################################################################
# You will need these modules installed on your system. #
# Please read the respective man pages for more info. #
##################################################################################
use strict qw( vars );
use User::pwent;
use Unix::Syslog qw(:macros);
use Unix::Syslog qw(:subs);
use Net::LDAP qw(:all);
##################################################################################
# Change these to match your system/site polices. #
##################################################################################
my $MINUID = 500; # We don't want brute force attacks against root, etc.
my $EGID = "100 100"; # Don't pass extra groups like wheel, etc.
my $RGID = 100;
my $server = 'ads-server';
$|=1;
my $ipaddr = $ENV{'TCPREMOTEIP'};
my $port = $ENV{'TCPLOCALPORT'};
my $BCODE = 49;
my($len,$buf);
open (USER, "<&=3") or exit (-3);
$len = read(USER, $buf, 512);
close USER;
exit(-3) if $len < 4;
my($user, $pass) = split /\x00/, $buf;
$user = lc $user;
$buf = "\x00" x $len;
my $pw = getpwnam($user) || err_unknown();
my $uid = $pw->uid;
my $phash = $pw->passwd;
my $home = $pw->dir;
my $shell = $pw->shell;
my @spl = split(/\//,$shell);
my $dom = lc $spl[1];
my $sla = "\\";
my $fulluser = $dom.$sla.$user;
if ($uid < $MINUID) {
err_minuid();
}
check_ads();
if ($BCODE eq 0 )
{
$ENV{USER}=$user;
$ENV{UID}=$uid+0;
$ENV{HOME}=$home;
$ENV{SHELL}=$shell;
exit(-4) unless $ENV{UID};
chdir $ENV{HOME};
$) = $EGID;
$( = $RGID;
$> = $ENV{UID};
$< = $ENV{UID};
log_pop3();
exec @ARGV;
}
else
{
err_badpass();
}
sub err_unknown {
openlog("checkpassads.pl: ", LOG_PID, LOG_MAIL);
syslog(LOG_INFO, "Attempt to login port %d with unknown user (%s) from [%s]",
$port, $fulluser, $ipaddr);
closelog;
exit(-3);
}
sub err_minuid{
openlog("checkpassads.pl: ", LOG_PID, LOG_MAIL);
syslog(LOG_INFO, "Attempt to login port %d with UID lt %d (%s) from [%s]",$port,
$MINUID, $fulluser, $ipaddr);
closelog;
exit(-3);
}
sub err_badpass{
openlog("checkpassads.pl: ", LOG_PID, LOG_MAIL);
syslog(LOG_INFO, "Attempt to login port %d failed for UID %d (%s - %s) from
[%s]",$port, $uid, $fulluser, $pass, $ipaddr);
closelog();
exit(-3);
}
sub log_pop3{
openlog("checkpassads.pl: ", LOG_PID, LOG_MAIL);
syslog(LOG_INFO, "port %d login successful UID %d (%s) from [%s]",$port, $uid,
$fulluser, $ipaddr);
closelog();
}
sub check_ads{
my $ldap = Net::LDAP->new($server);
my $bind = $ldap->bind($fulluser, password=>$pass, version=>3);
$BCODE = $bind->code;
}
sleep(10);
exit(-4);