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

bind() is hardcoded to perform simple binds #25

Open phillipod opened 9 years ago

phillipod commented 9 years ago

See #6 for full background. Note that bind_s does not have this limitation.

quanah commented 9 years ago

bind and bind_s are both deprecated functions:

LDAP_F( int ) ldap_bind LDAP_P(( /* deprecated, use ldap_sasl_bind / LDAP ld, LDAP_CONST char who, LDAP_CONST char passwd, int authmethod ));

LDAP_F( int ) ldap_bind_s LDAP_P(( /* deprecated, use ldap_sasl_bind_s / LDAP ld, LDAP_CONST char who, LDAP_CONST char cred, int authmethod ));

quanah commented 9 years ago

Historically, I believe this was done for backwards compat with previous net::ldapapi versions (just to note)

phillipod commented 9 years ago

Okay. I've been able to implement a call to ldap_sasl_interactive_bind(), and it works.

But I'm reluctant to add it to a 3.0.x release.

  1. The current return convention for asynchronous functions being the message id or undef means it is necessary to modify errorize() to record 'status' as a 'lastrc' attribute. This is so the LDAP_SASL_BIND_IN_PROGRESS result codes can be acted upon - while the message results contain errcode LDAP_SASL_BIND_IN_PROGRESS during a GSSAPI exchange, a successful GSSAPI bind then has an errcode of LDAP_SUCCESS - but the ldap_sasl_interactive_bind() return is still LDAP_SASL_BIND_IN_PROGRESS.
  2. There doesn't seem to be an equivalent asynchronous method in the Mozilla LDAP SDK. For anyone who is using mozldap, changing the nature of the function to synchronous could be problematic. And having a fairly hefty chunk of #ifdef'd OpenLDAP / mozldap code, when 3.1 is around the corner and will drop mozldap (#34), seems pointless potential for bugs.

To me, it seems best to maintain status quo for 3.0.x and bump this to 3.1, where we have the chance to make the API seem more natural.

Here's the code of the test program, I'll branch off the code for support ldap_sasl_interactive_bind() so you can have a look as well and let me know what you think. Note that I haven't bothered exporting the SASL specific symbols for LDAP_OPTS etc, so am using fixed numbers in the test program.

#!/usr/bin/perl

use Net::LDAPapi;
use Data::Dumper;
use Devel::Hexdump 'xd';

$Data::Dumper::Terse = 1;

#my $ld = Net::LDAPapi->new(-url => "ldapi:///") || die "$!";
#$ld->sasl_parms(-mech => "EXTERNAL");

my $ld = Net::LDAPapi->new("localhost") || die "$!";
$ld->sasl_parms(-mech=>"GSSAPI", -realm=>"EXAMPLE.COM");

my $ssf = undef;
$ld->get_option(0x6104, \$ssf);
print "SSF: $ssf\n";

print "===== BIND\n";

my $msgid;
my $message = undef;
my $rmech = undef;

my $bindrc;
my $done = 0;
my %result = ();

do {
  $msgid = $ld->bind(-type => LDAP_AUTH_SASL, -message => $message, -rmech => \$rmech);
  my $bindrc = $ld->{'lastrc'};

  $ld->get_option(0x6104, \$ssf);

  {
    if (!$msgid) { $done++; last; }

    ldap_msgfree($message);
    $message = undef;

    $message = $ld->result($msgid, 1, 1);
    %result = $ld->parse_result($message);

    if ($bindrc != 14) { $done++; }
  }
} while ($done == 0);

if ($result{'errcode'} != LDAP_SUCCESS) {
  $ld->perror();
}

$ssf = undef;
$ld->get_option(0x6104, \$ssf);
print "SSF: $ssf\n";

my $authzid = undef;

my $id = $ld->whoami_s(\$authzid);

if ($id != LDAP_SUCCESS) {
  $ld->perror();
}

print "$authzid\n";

OpenLDAP default EXTERNAL output:

SSF: 0
===== BIND
SSF: 0
dn:gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth

GSSAPI output:

SSF: 0
===== BIND
SSF: 56
dn:uid=test user,ou=users,dc=example,dc=com
phillipod commented 9 years ago

Here's the comparison: https://github.com/quanah/net-ldapapi/compare/master...phillipod:ldap_sasl_interactive_bind

quanah commented 9 years ago

I think punting this until 3.1.x seems fine.