# ** ********************************************************************* # ** -- $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} = '' ; # 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__