Searching LDAP using Perl and Net::LDAPS over SSL/TLS
*Thanks to Aron Roberts of IST-WSS and Lewis Burgess of IST-SDA for providing this code sample
#!/usr/local/bin/perl## Search the CalNet Directory Service using a 'uid' attribute# and return selected attributes of the UC Berkeley-affiliated# person, if any, that matches that 'uid'## Prerequisite: Graham Barr's Perl-LDAP, whose home page is located at:## http://perl-ldap.sourceforge.net/## For additional Perl-LDAP documentation and usage examples, see:## http://www.perlmonth.com/features/ldap/ldap.html?issue=11# http://theoryx5.uwinnipeg.ca/CPAN/data/perl-ldap/Net/LDAP/Examples.html## Some significant limitations of the code sample below include:## - It is a simple, procedural script. You'd likely want to break out# several of its functions into individual subroutines.## - It performs only primitive error handling. (It just dies and displays# an error message when an error occurs.)## - It doesn't automatically try any alternate directory servers# if the primary server is unavailable.## - It performs an "anonymous" bind to the directory.## In some cases, your application might need to bind (authenticate)# to the CalNet directory as a specific user, rather than anonymously.# You'd need to do so, for instance, to access non-public attributes of# campus people, such as their CalNet IDs or student IDs.## (Note: to access such non public-attributes, you'll first need to# obtain the appropriate permissions from the CalNet System's# administrators and often also from the campus department[s] which# own that data.)## Here is an example of how you would bind to the directory as a specific# user, from Mark Wilcox's article on www.pearlmonth.com (above):## my $mesg = $ldap->bind('uid=myuid,ou=people,dc=berkeley,dc=edu',# password => 'password');## In addition, when binding as a specific user, your application's# connection to the directory should be made using SSL. This way,# your directory user password and the non-public data you are# receiving will be encrypted when being sent over the network.## For more information about how to use Perl-LDAP to connect to the# directory using SSL encryption, see the documentation for the# Net::LDAPS module, which is included with the Perl-LDAP distribution:## http://perl-ldap.sourceforge.net/doc/Net/LDAPS.html## The additional prerequisites for using Perl-LDAP with SSL appear to be:## OpenSSL: http://www.openssl.org/# Net::SSLeay: http://www.bacus.pt/Net_SSLeay/index.htmluse Net::LDAPS;# ---------------------------------------------------------------# Accept a single command line parameter, the 'uid' attribute that# uniquely identifies 'people' entries in the CalNet Directory Service#$uid = $ARGV[0] || 3877;# Convenience placeholder if we want to repeatedly test with a specific uid# $uid = "3877"; // Replace this uid with the one you would like to test$uid = '95088';# Define variables# ----------------# LDAP directory to contact$directoryURL = "ldap.berkeley.edu";#$directoryURL = "ldap-test.berkeley.edu";$LDAPBIND = 'uid=YourAppBind,ou=applications,dc=berkeley,dc=edu';$LDAPPWD = 'YourAppPassword';# Portion of the directory we'll be searching$searchBase = "ou=people,dc=berkeley,dc=edu";# The attributes (and their associated values) that we wish to# search for in the directory.## In this instance, we're searching for the directory entry# which matches a specific 'uid'## If we were searching for entries by name, for instance,# we could instead search on the common name (cn) attribute,# such as "(cn=John*Doe)", or the surname (sn) attribute,# such as "(sn=Doe)" $searchFilter = "(uid=$uid)";# The attributes we'd like to have returned for each entry## (Doing this is entirely optional; it simply reduces the# volume of data returned by excluding attributes that we're# not interested in receiving.)$attributesToReturn = ['displayname','mail','telephoneNumber','berkeleyEduPrimaryDeptUnit','berkeleyEduUnitCalNetDeptName'];# Connect to the directory# ------------------------print "Connecting to LDAP server \"$directoryURL\" ...\n";# Open a connection to the directory$ldaps = Net::LDAPS->new($directoryURL,verify => 'require',capath => '/path/to/certs/pem/calnet-certs-complete/certs',) # as structor die "$@";#$ldaps = Net::LDAPS->new($directoryURL) # as struct# or die "$@";# Make an anonyous bind to the directory# (See the comments above if you wish to bind to the# directory as a specific user.)#$ldaps->bind;$ldaps->bind("$LDAPBIND", password => "$LDAPPWD");print "Looking up directory data for uid \"$uid\" ...\n";# Perform a search# ----------------$searchResultsObject = $ldaps->search(# Search the 'people' portion of the directory,# as defined abovebase => $searchBase, # Note the comma here# Search on the uid attributefilter => $searchFilter, # and here# Return only a limited set of attributes from# the search, *if* we've defined such a set aboveattrs => $attributesToReturn);# If there is a result code (indicating an error),# display an error messageif ($searchResultsObject->code) {print "An error occurred during the LDAP search attempt:\n";die $searchResultsObject->error;}# Disconnect from the directory# -----------------------------$ldaps->unbind;# Work with the data returned from the search# -------------------------------------------my $countOfEntriesReturned = $searchResultsObject->count;print "Search returned $countOfEntriesReturned entries ...\n\n";# Cycle through each of the directory entries returned from the# search, and extract and print the values of selected attributes# of each entryfor ( my $index = 0 ; $index < $countOfEntriesReturned; $index++){# Look at each of the 'entry' objects returned from the searchmy $entry = $searchResultsObject->entry($index);# Initialize each variable each time through the loop$displayName = "";$eMailAddress = "";$phoneNumber = "";$dept1Name = "";$dept1 = "";# Extract the values from selected attributes$displayName = $entry->get_value('displayname');$eMailAddress = $entry->get_value('mail');$phoneNumber = $entry->get_value('telephoneNumber');$dept1Name = $entry->get_value('berkeleyEduUnitCalNetDeptName');$dept1 = $entry->get_value('berkeleyEduPrimaryDeptUnit');if ($dept1Name){ $departmentName = $dept1Name; }else{ $departmentName = $dept1; }print " Name: $displayName\n";print " Dept: $departmentName\n";print "E-mail: $eMailAddress\n";print " Phone: $phoneNumber\n";print "\n";} |