Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re: LDAP Search Script runs slow

by atcroft (Abbot)
on Dec 06, 2003 at 17:59 UTC ( [id://312788]=note: print w/replies, xml ) Need Help??


in reply to LDAP Search Script runs slow

One thing you may wish to do is look at using a callback routine with your search. If I am reading your code correctly, you are not doing so yet. That being the case, the search waits for all the results to be returned (which can be quite some time, if there are a large number of records in the LDAP data store you are querying), whereas if a callback routine is used, each record is processed as found.

The code below is part of a test routine I used a while back (edited appropriately, with appologies for any errors that may have been edited in), which might give you an idea on using a callback routine. (The LDAP modules' documentation were quite helpful for me when I had to do something with it.)

#!/usr/bin/perl -w use Net::LDAP qw(:all); use Net::LDAP::Entry; use Net::LDAP::LDIF; use Net::LDAP::Util qw(ldap_error_text); use strict; $| = 1; my $ldap_server = "your.ldap.server.here"; my $basedn = "your.base.dn.here"; my $binddn = "your.bind.dn.here"; my $password = "your.ldap.password.here"; my $ldap = Net::LDAP->new($ldap_server) or die ( $@ . "\n" ); my $msg = $ldap->bind( $binddn, password => $password ); my $scope = "base"; my $filter = "(objectClass=*)"; my $searchobj = $ldap->search( base => $basedn, filter => $filter, callback => \&process ); die ( "Bad search: " . ldap_error_text( $searchobj->code() ) ) if ( $searchobj->code() ); sub process { my $mesg = shift; my $obj = shift; if ( !$obj ) { # Search complete } else { my $dn = $obj->dn(); { my @parts = (); print( 'dn: ', $dn, "\n" ); foreach my $attr ( sort( { lc($a) cmp lc($b) } $obj->attributes ) ) { print( join ( ': ', $attr, $obj->get_value($attr) ), "\n" ); } print( "\n" ); } $mesg->pop_entry(); } }

Replies are listed 'Best First'.
Re: Re: LDAP Search Script runs slow
by bionicle32 (Novice) on Dec 07, 2003 at 00:23 UTC
    Atcroft, I noticed that you are using LDIF which is for writting to a textfile. Can this be used to store the information in a variable like the way I did it in mine? I am trying to write a web application so I am not really sure if I would know how to modify your script to return the results back to the browser at one time. Can you advise? Thanks Bionicle32

      Here was an attempt at blending some of the aspects of your script with the code I offered above. Untested, but at least it may give you the ideas you need. I did leave out some of the functions from your original code, so you would have to integrate them in.

      I wasn't actually using the LDIF format in my test script, so I appologize for any confusion that may have caused.

      #!/usr/bin/perl -w use CGI qw(:standard); use CGI::Carp qw(fatalsToBrowser); use Net::LDAP qw(:all); use Net::LDAP::Entry; use Net::LDAP::Util qw(ldap_error_text); use strict; use vars qw($attributes $returnedcount); $| = 1; { my $attributelist = qw(cn uid l departmentnumber title mail); $attributes = join('|', @attributelist); } $returnedcount = 0; my $cgi = new CGI; print $cgi->header(); print <<HTML_HEADER; <html> <head> HTML_HEADER my $flag = $cgi->param('looking'); if (!flag) { lookUp(); } else { print <<HEADER; <title>LDAP Results</title> </head> <body> <div align="center"> <table> HEADER my $ldap_server = "your.ldap.server.here"; my $basedn = "your.base.dn.here"; my $binddn = "your.bind.dn.here"; my $password = "your.ldap.password.here"; my $ldap = Net::LDAP->new($ldap_server) or die ( $@ . "\n" ); my $result = $ldap->bind( $binddn, password => $password ) or die($result->error()); my $scope = "sub"; my $count = 0; my $searchstory = ''; { my %searchparams = ( 'first' => 'givenname', 'last' => 'sn', 'dept' => 'departmentnumber' ); foreach my $p (keys(%searchparams)) if (defined($cgi->param($p))) { $count++; $searchstory .= '(' . $p . '=*' . $cgi->param($searchparams{$p}) . '*)'; } } $searchstory = '(&' . $searchstory . ')' if ($count > 1); } # UNTESTED # - Supposed to send something to the browser periodically - $SIG{ALRM} = sub { print ' '; alarm(5); } # UNTESTED my $searchobj = $ldap->search( base => $basedn, filter => $searchstory, callback => \&process ); print( '<tr>', '<td colspan="2">Bad search</td>', '<td>', ldap_error_text( $searchobj->code() ), '</td>', "</tr>\n" ) if ( $searchobj->code() ); print( '<tr>', '<td colspan="2">Returned entries: ', $returnedcount, '</td>', "</tr>\n" ); } $ldap->unbind(); } print <<HTML_FOOTER; </table> </div> </body> </html> HTML_FOOTER sub process { local $SIG{ALRM} = 'IGNORE'; my $mesg = shift; my $obj = shift; if ( !$obj ) { # Search complete } else { my $dn = $obj->dn(); { my @parts = (); my $resultstring = '|'; print( '<tr><td>dn: ', $dn, "</td>\n" ); foreach my $attr ( sort( { lc($a) cmp lc($b) } $obj->attributes ) ) { next unless ($attr =~ m/^($attributes)$/); $resultstring .= join ( ': ', $attr, $obj->get_value($attr) ), "|" ); } print( "<td>$resultstring</td></tr>\n" ); $returnedcount++; } $mesg->pop_entry(); } }

      Updated: 06 Dec 2003 - Added *untested* SIGALRM to try to send something to the browser periodically.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://312788]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2024-03-29 10:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found