Perl installations with functioning Net::LDAP and Authen::SASL modules should call Perl's bind method using its sasl argument to bind to UW directories requiring client authentication.

This example script establishes a connection to the configured LDAP server, issues the StartTLS extended operation, binds using the SASL EXTERNAL (TLS client certificate authentication) mechanism, and performs a simple search using the defined searchbase and filter.

The newest Person Directory servers now use an InCommon server cert. Your application will need to include the Comodo root cert in your CACert file (identified as "/path/to/uwca.crt" below) to connect. See: Person Directory - Combined UWCA InCommon Root Certs. During initial testing in 2016 several apps took advantage of a certificate bundle and didn't require changes.

#!/usr/local/bin/perl

use Net::LDAP;
use Authen::SASL;

# UW Person Directory Service config
$host = "eds.u.washington.edu";
$base = "dc=personregistry,dc=washington,dc=edu";
$filter = "uwnetid=donn";

# UW Groups Directory Service config
# $host = 'groups.u.washington.edu';
# $base = 'dc=washington,dc=edu';
# $filter = 'cn=u:cac:teg-smw';

# SASL EXTERNAL authentication config
$tls_cacert = '/path/to/uwca.crt';
$tls_cert = '/path/to/my.crt';
$tls_key  = '/path/to/my.key';

$ldap = Net::LDAP->new($host) or die "$@";

$mesg = $ldap->start_tls(
        verify => 'require'
        , clientcert => $tls_cert
        , clientkey => $tls_key
        , cafile => $tls_cacert
        );

$mesg->code && die $mesg->error;

$sasl = Authen::SASL->new(
          mechanism => 'EXTERNAL'
        , callback => { user => '' }
        ) or die "$@";

$mesg = $ldap->bind(sasl => $sasl);
$mesg->code && die $mesg->error;
$result = $ldap->search(
          base => $base
        , filter => $filter
        );

$result->code && warn "failed to find entry: ", $result->error;
foreach $entry ($result->entries) {
                $entry->dump;
        }
$mesg = $ldap->unbind;