# ** *********************************************************************
# ** -- $Id: //Tools/Odds-Ends/LDAP/find_user.pl#3 $
# ** -- $Change: 104214 $
# ** -- $DateTime: 2008/07/31 10:21:59 $
# ** -- $Author: paul.m.thompson $
# ** *********************************************************************
# ---------------------------------------------------------------------------
# Special blocks
# BEGIN {}
# CHECK {}
# INIT {}
# END {}
# ---------------------------------------------------------------------------
# pragmas
use strict ;
use diagnostics ;
use warnings ;
# ---------------------------------------------------------------------------
# modules used
use Getopt::Long qw( :config bundling ignore_case_always ) ;
use Net::LDAP ;
# ---------------------------------------------------------------------------
# prototypes of local functions.
sub Usage(;$) ;
sub Build_Filter($$$) ;
# ---------------------------------------------------------------------------
# Constants
# use constant DEFAULT_X => 'X' ;
# ---------------------------------------------------------------------------
# globals
our $PERL_ID = sprintf "Perl v%vd for '$^O'", $^V ;
our $PVCS_REVISION = sprintf("%d.%02d", q$Revision 0.0$ =~ /(\d+)\.(\d+)/);
# Command line options
our %g_Options ;
# As per Hardik Sancheti, 25-sep-2005
# There is a replication between two servers in the same environment but
# not between different environments.
# Production
# ldapwb.okla.seagate.com - load-balanced server for clients wanting to write to CDS.
# ldaprb.okla.seagate.com - load-balanced server for clients wanting to read from CDS.
# Staging
# stag-ldapwb.okla.seagate.com
# stag-ldaprb.okla.seagate.com
# Development
# dev-ldapwb.okla.seagate.com
# dev-ldaprb.okla.seagate.com
$g_Options{LdapServer} = 'ldaprb.okla.seagate.com' ;
$g_Options{LdapBase} = 'ou=people,o=seagate.com,o=SDS' ;
$g_Options{LdapAttribs} = 'cn sAMAccountName employeenumber mail mailmessagestore telephoneNumber l physicalDeliveryOfficeName manager' ;
$g_Options{LdapSearchOn} = '' ;
# <none> option does not take an argument
# =s :s option takes a mandatory (=) or optional (:) string argument
# =i :i option takes a mandatory (=) or optional (:) integer argument
# =f :f option takes a mandatory (=) or optional (:) real number argument
# >new option is a synonym for option `new'
GetOptions
(
\%g_Options ,
'Help|h|?' ,
'Verbose|v' ,
'All' ,
'Exact' ,
'LdapServer:s' ,
'LdapBase:s' ,
'LdapAttribs:s' ,
'LdapSearchOn:s'
);
# Print all options if VERBOSE mode
if ($g_Options{Verbose})
{
print "Options:\n" ;
print " $_ == '$g_Options{$_}'\n" foreach sort(keys %g_Options) ;
print "Args : ",join(';',@ARGV),"\n";
}
# Print usage & quit if HELP mode
Usage if $g_Options{Help} ;
my $o_ldap = Net::LDAP->new($g_Options{LdapServer}) or die "Can't create LDAP object to '$g_Options{LdapServer} : $@";
my $msg = $o_ldap->bind() or die "Can't bind to '$g_Options{LdapServer} : $@" ;
my $ldap_wildcard = $g_Options{Exact} ? '' : '*' ;
foreach my $Arg (@ARGV)
{
my ($filter,$attribs,$search_on) ;
# If param is numeric or "phone-numberish", treat it like a GID or phone number
# Otherwise treat it like a name, phone number, Lotus Notes "short" name, or email address
if ($Arg =~ /[-.\(\)\d]+/)
{
$filter = Build_Filter($Arg , $g_Options{LdapSearchOn} ? $g_Options{LdapSearchOn} : "uid,telephoneNumber",$ldap_wildcard) ;
}
else
{
$filter = Build_Filter($Arg , $g_Options{LdapSearchOn} ? $g_Options{LdapSearchOn} : "cn,mail,mailmessagestore",$ldap_wildcard) ;
}
$attribs = $g_Options{All} ? [] : [ split(/[,;\s]+/,$g_Options{LdapAttribs}) ] ;
print "Try to find: '$Arg'\n" , "Attributes: $attribs\n" , "filter: '$filter'\n" if $g_Options{Verbose} ;
$msg = $o_ldap->search(base => $g_Options{LdapBase} , attrs => $attribs , filter => $filter) ;
$msg->code && die $msg->error ;
foreach my $entry ($msg->entries)
{
$entry->dump ;
}
}
$o_ldap->unbind() or die "Can't unbind to '$g_Options{LdapServer} : $@" ;
# ---------------------------------------------------------------------------
# Return an LDAP filter composed of param1 matched with the various components of param2.
# An LDAP "x OR y OR x" filter (where x,y,z are comparison operations) looks like:
# (|(x)(y)(z))
sub Build_Filter($$$)
{
my $arg = shift() ;
my $csv = shift() ;
my $wildcard = shift() ;
my $filter ;
$filter .= "($_=${wildcard}${arg}${wildcard})" foreach split(/\s*[,;]\s*/,$csv) ;
return "(|$filter)" ;
}
# ---------------------------------------------------------------------------
# Optional param will print "special" messages first.
sub Usage(;$)
{
print "\n",shift(),"\n" if $#_ >= 0 ;
print "\n$0 : $PVCS_REVISION ($PERL_ID) \n" ;
print "\n" ,
"This program will look up users in Seagate LDAP by name, phone, \n" ,
" Lotus Notes 'short' name, or GID and report their info. You can use\n" ,
" partial parameters -- they are enclosed in LDAP wildcard chars ('*').\n" ,
" If you specify a numeric param, the search is limited to GID or phone\n" ,
"The following command line flags are recognized.\n" ,
" --LdapServer=s : Specify the LDAP server.\n" ,
" Default = $g_Options{LdapServer}\n" ,
" --LdapBase=s : Specify the LDAP base OU.\n" ,
" Default = $g_Options{LdapBase}\n" ,
" --LdapSearchOn=s: LDAP field(s) to search in COMMA or SEMICOLON delimited list.\n" ,
" Default = 'uid,telephoneNumber' for numeric params or\n" ,
" 'cn,mail,mailmessagestore' for all others\n" ,
" --LdapAttribs=s : Specify the LDAP attributes to print.\n" ,
" Default = $g_Options{LdapAttribs}\n" ,
"\n" ,
"These params allow you to change some behaviorial settings:\n" ,
" --All : Print all attributes instead of select set.\n" ,
" --Exact : Exact match. Don't enclose param in wildcard chars ('*').\n" ,
"\n" ,
" --Verbose : Print more info.\n" ,
" --Version : Print program version info and quit.\n" ,
"\n"
;
exit ;
}
# ---------------------------------------------------------------------------
# End of script
# ---------------------------------------------------------------------------
# Data
# ---------------------------------------------------------------------------
__DATA__
__END__