quanah / net-ldapapi

The Net::LDAPapi Perl Module uses the OpenLDAP and Mozilla C api's to directly access and manipulate an LDAP v2 or LDAP v3 server.
8 stars 6 forks source link

search_s() clobbers ATTRS parameter #8

Closed phillipod closed 9 years ago

phillipod commented 9 years ago

The following code:

print "===== SEARCH\n";

my $search_msg = $ld->search(
  -basedn => "o=Test Data,c=NZ",
  -scope => LDAP_SCOPE_SUBTREE,
  -filter => "(sn=Last)",
  -attrs => \@{['cn']},
  -attrsonly => 0);

my $search_result = $ld->parse_result($ld->result($search_msg));

if ($search_result->{'errcode'} != LDAP_SUCCESS) {
  print "- Fail\n";
}

for (my $entry = $ld->first_entry(); $entry; $entry = $ld->next_entry) {
  print "dn: " . $ld->get_dn() . "\n";

  for (my $attribute = $ld->first_attribute; $attribute; $attribute = $ld->next_attribute) {
    foreach my $value ($ld->get_values($attribute)) {
      print $attribute . ": " . $value . "\n";
    }
  }
}

print "===== SEARCH_S\n";

my $search_s_result = $ld->search_s(
  -basedn => "o=Test Data,c=NZ",
  -scope => LDAP_SCOPE_SUBTREE,
  -filter => "(sn=Last)",
  -attrs => \@{['cn']},
  -attrsonly => 0);

if ($search_s_result != LDAP_SUCCESS) {
  print "- Fail\n";
}

for (my $entry = $ld->first_entry(); $entry; $entry = $ld->next_entry) {
  print "dn: " . $ld->get_dn() . "\n";

  for (my $attribute = $ld->first_attribute; $attribute; $attribute = $ld->next_attribute) {
    foreach my $value ($ld->get_values($attribute)) {
      print $attribute . ": " . $value . "\n";
    }
  }
}

produces the following output:

===== SEARCH
dn: cn=Full,ou=Users,o=Test Data,c=nz
cn: Full
===== SEARCH_S
dn: cn=Full,ou=Users,o=Test Data,c=nz
cn: Full
sn: Last
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
givenName: First

search() looks like the following:

sub search
{
...;
    if( !defined($attrs) ) {
        my @null_array = ();
        $attrs = \@null_array;
    }
...
}

search_s() looks like the following:

sub search_s
{
...;
    if( !defined($attrs) == undef ) {
        my @null_array = ();
        $attrs = \@null_array;
    }
...;
}

I think the conditional in search_s() is being parsed as:

if (!(defined($attrs) == undef)) {
}

In effect, if $attrs isn't passed at all, it's essentially a NOP - $attrs = undef and defined(undef) == undef. But if $attrs is passed, defined($attrs) != undef - so the negation proceeds into the conditional block.

I'll submit a pull request for this shortly. :)