perlsearchfilterradixnetldap

LDAP Search -- Bad Filter


So I am trying to search LDAP to populate a CSV file. The User IDs are obtained by parsing a text file. I want to search the LDAP for the user ID (mailNickname), FName (givenName), LName (sn), "OU", pwdLastSet. How do I use the filter aspect of search because I keep getting the "bad filter" error.

Thanks for your help.

    #!/usr/bin/perl
use xSV;
use Net::LDAP;
use Term::ReadKey;
# use strict;

$debug_on = 1;  # This will enable some debugging messages.

if (defined($ARGV[0])) {
    $input = $ARGV[0];
} else {
    print "No input file specified!  Assuming MKSGroupsoutput.txt...\n";
    $input = "MKSGroupsoutput.txt";
}

if (defined($ARGV[1])) { 
    $output = $ARGV[1];
} else {
    $output = $input . ".csv";
}

open GROUPS, "< $input" or die "ERROR: Can't open input file: '$input'\n";

print "INPUT: $input\nOUTPUT: $output\n";

sub debug {
    if ($debug_on == 1) {
        print "@_";
    }
}

my $csv = Text::xSV->new(
    filename => $output,
    header   => [
    "AccountName", 
    "LastName", 
    "FirstName", 
    "EEID", 
    "SYSGenericAcct", 
    "Notes", 
    "AccessLevel", 
    "AccessCapability", 
    "Owner/Manager",
    "Description", 
    "Created", 
    "Status", 
    "LastStatusChange", 
    "LastPwdChange", 
    "DataSource"
    ],
  );
$csv->print_header();

my ($inputname, $fname, $lname, @name, $uname, $pwordinput, $pword, $domain, $line, $ldap, $bindstring, $root, $pword, $base_dn);
#User driven input to connect to LDAP.  ReadMode 2 keeps password hidden, the reset back to 0.
print "Please enter your Full Name: ";
$inputname = <STDIN>;
print "Please enter your password: ";
ReadMode 2;
$pwordinput = <STDIN>;
ReadMode 0;

#Builds the LDAP CN value from user input. Trims \n off user input values
$inputname = substr($inputname,0,-1);
@name = split(' ', $inputname);
$fname = ucfirst(@name[0]);
$lname = ucfirst(@name[1]);
$pword = substr($pwordinput,0,-1);
$uname = $lname ."\\, " . $fname;
$bindstring = "CN=" . $uname . ",OU=User,DC=hq,DC=name,DC=com";

#LDAP Connection parameters
$base_dn = "OU=User,DC=hq,DC=name,DC=com";
$ldap = Net::LDAP->new('ldap://local', onerror =>'die');
$ldap->bind($bindstring, password => $pword); #Sometimes the BIND fails (1 out of 10 times)
$root = $ldap->root_dse;

#Parses text file
while ($line = <GROUPS>) {
    chomp($line);
    if ($line =~ m/^  user  .*/) {
        $line =~ s/^  user.\s//;
        my ($searchoutput, $user, @entries, $entry, $href, $strDomain, $strUsername, $strDN, $arrSplitResponse, $strLName, $strFName, $strUserType);
        $user = $line;
        $user = "mailNickname: " . $user;
        $searchoutput = $ldap->search(filter=>$user,base=>$base_dn); # ERROR HERE
        @entries = $searchoutput->entries;
        foreach $entry ( @entries ) {
            print "DN: ", $entry->dn, "\n"; #NEVER ENTERS THIS LOOP
        }

Solution

  • Why did you remove use strict;? It should ALWAYS be there. Same with use warnings;. That might help point out some of your issues.

    I see you've set onerror which can be okay once you've solved your problems, but I recommend that you don't do that until you've solved all of your problems. Instead, capture the output of your LDAP methods:

    my $ldap_message = $ldap->bind($bindstring, password => $pword);
    die qq(LDAP Error Code: ) . $ldap_message->code if $ldap_message->code;
    

    This might help you debug.


    Okay, enough berating you. Let's get down to your error:

    If I remember my Net::LDAP, the search is:

    my $search_obj = ldap->search(base => $base, filter => $filter);
    

    where $base is a valid LDAP base, and $filter is a valid query in LDAP syntax.

    Looking at your code:

    my $user = "mailNickname: " . $user;
    my $searchoutput = $ldap->search(filter=>$user, base=>$base_dn); # ERROR HERE
    

    It looks like your search query is mailNickName: david if $user is david. That's not a valid LDAP search. It should be

    my $user = "(mailNickname=$user)"; #Equal sign. Parentheses might be unnecessary
    my $searchoutput = $ldap->search(filter=>$user, base=>$base_dn);
    

    Notice I can put variable names inside of quotes. It's one of the things I like in Perl. Makes the code easier to read. That might do the trick. Again, capture the output of all of your LDAP methods, and use the code method to find out what's causing your error.