########################################################################## # package QueryLDAP.pm # This module contains functions which asks hosts questions # V Who When What # --------------------------------------------------------------------------- # 1.0.5 skendric 2008-07-30 Bail if all LDAP servers are down # 1.0.4 skendric 2008-07-03 Stylistic mods # 1.0.3 skendric 2008-06-16 Stylistic mods # 1.0.2 skendric 2007-03-12 Stylistic mods # 1.0.1 skendric 2006-07-14 Enhanced debugging output # 1.0.0 skendric 2005-07-25 First version # # # # Authors: Stuart Kendrick # # Source: http://www.skendric.com/device/soma # # This software is available under the GNU GENERAL PUBLIC LICENSE, see # http://www.fsf.org/licenses/gpl.html # package FHCRC::VDOPS::QueryLDAP; #### Load modules #### use strict; use warnings; use threads; use threads::shared; use Carp qw(carp cluck croak confess); use Data::Dumper; use Exporter; use Net::LDAP::Express; use Perl6::Say; use lib '/home/soma/lib'; use FHCRC::VDOPS::LDAPTools; use FHCRC::VDOPS::SomaData; use FHCRC::VDOPS::Utilities; #### Set-up export stuff #### our @ISA = qw(Exporter); our @EXPORT = qw( gather_ou ); # Declare package local variables ##### Only subroutines below here #### ######################################################################## # Given reference to a hash of nodenames keyed by some unique ID, # look-up the OU associated with that nodename in an LDAP server # and return a reference to a hash of OUs keyed by the unique ID. # Restrict searches to objectClass=Computer and parse the string # returned from a query to 'objectName' in order to discover the OU ######################################################################## sub gather_ou { my @entry; # List of 'entries' from LDAP object my $filter; # Net::LDAP::Express filter my $nodenames = shift; # Reference to hash of nodenames my $ldap; # Net::LDAP::Express object my $mesg; # Net::LDAP::Express->search object my @search; # Net::LDAP::Express attribute search list my $server; # LDAP server which we queried my $objectName; # The objectName associated with $cn # from a query to $cn's objectName my $ou; # The Organizational Unity which we have extracted my %ou; # Hash of OUs keyed by whatever keys $nodenames # Debug trace trace_location('begin') if $debug > 2; # Sanity check confess 'No parameters' unless defined $nodenames; # Define local variables @search = qw/objectName/; # Acquire Net::LDAP::Express object ($ldap, $server) = connect_ldap(\@ldapServer, \@search); unless (defined $ldap and defined $server) { say "All LDAP servers are down, bailing"; return undef; } # Walk through nodenames say "Walking nodenames and querying OU" if $debug; NODE: for my $mac (keys %$nodenames) { my $node = $nodenames->{$mac}; # Query $node's entry for objectName $filter = "(&(cn=$node)(objectClass=computer))"; eval { $mesg = $ldap->search ( filter => $filter, searchattrs => \@search ) }; if ($@) { log_it("Problem searching $server for objectName on $node: $@"); next NODE; } # Extract objectName @entry = $mesg->entries; log_it("More than one LDAP entry for $node") if @entry > 1; for my $entry (@entry) { $objectName = $entry->{'asn'}->{'objectName'}; } # Grab last OU if (defined $objectName) { ($ou) = ($objectName =~ /,OU=([a-zA-Z0-9\-]*?),$ldapBase/i); } # Sanity check if (defined $ou) { undef $ou if ($ou eq $EMPTY_STR or $ou eq $SPACE); } # Populate $nodenames with ou $ou{$mac} = $ou if defined $ou; # Debug info say "Found $ou for $mac" if (defined $ou and $debug == 8); undef $filter; undef @entry; undef $objectName; undef $ou; } # Clean-up say "Disconnecting from ldap server" if $debug; eval { $ldap->disconnect() }; log_it("Cannot disconnect from ldap server $server: $@") if $@; # Debug info if ($debug == 7) { for my $mac (keys %ou) { say "$mac = $ou{$mac}" if defined $ou{$mac}; } } # Debug trace trace_location('end') if $debug > 2; return \%ou; }