RT 5.x TLS on LDAPImport.pm

We’ve been moving to use TLS for all of our LDAP interactions here, in preparation for Microsoft to eventually decide to switch off unsecure LDAP to ActiveDirectory servers (which they’ve postponed a couple of times). RT seems to understand the tls flag for one half of its LDAP support, but not for the LDAP import. This has been mentioned several times in the past on the forum for 4.x versions of RT, but I thought’d I’d give a heads up that this is still the case in RT5.x.

To help folk out if you want to turn on LDAP’s TLS option for imports, here’s a simple local overlay you can pop into /opt/rt5/local/lib/RT/LDAPImport_Local.pm:

package RT::LDAPImport;

use warnings;
use strict;
use base qw(Class::Accessor);
__PACKAGE__->mk_accessors(qw(_ldap _group _users));
use Carp;
use Net::LDAP;
use Net::LDAP::Util qw(escape_filter_value);
use Net::LDAP::Control::Paged;
use Net::LDAP::Constant qw(LDAP_CONTROL_PAGED);
use Net::LDAP::Constant qw(LDAP_EXTENSION_START_TLS);
use Authen::SASL;
use Data::Dumper;
no warnings qw(redefine);

sub connect_ldap {
    my $self = shift;

    $RT::LDAPOptions = [] unless $RT::LDAPOptions;
    my $ldap = Net::LDAP->new($RT::LDAPHost, @$RT::LDAPOptions);

    $RT::Logger->debug("connecting to $RT::LDAPHost");
    unless ($ldap) {
        $RT::Logger->error("Can't connect to $RT::LDAPHost $@");
        return;
    }

    if($RT::LDAPTLS) {
	unless ($ldap->root_dse->supported_extension( LDAP_EXTENSION_START_TLS )) {
	    $RT::Logger->error("START_TLS Extension Required");
	    return;
	}

	my $mesg = $ldap->start_tls($RT::LDAPTLSOptions);

	if( $mesg->is_error() ) {
	    $RT::Logger->error("Failed to start_tls ( " . 
			       $mesg->code() . " - " . 
			       $mesg->error() . " )\n");
	    return;
        }
	    $RT::Logger->debug("TLS turned on - about to try binding");
    }
    my $msg;
    if ($RT::LDAPUser) {
        $RT::Logger->debug("binding as $RT::LDAPUser");
        $msg = $ldap->bind($RT::LDAPUser, password => $RT::LDAPPassword);
    } else {
        $RT::Logger->debug("binding anonymously");
        $msg = $ldap->bind;
    }

    if ($msg->code) {
        $RT::Logger->error("LDAP bind failed " . $msg->error);
        return;
    }

    $self->_ldap($ldap);
    return $ldap;

}

1;

This just overlays the LDAP connection subroutine and uses two new RT_SiteConfig.pm options:

  • LDAPTLS which is a boolean to turn on the LDAP TLS support
  • LDAPTLSOptions which is a hash of options to pass to the Net::LDAP start_tls method.

For example:

Set($LDAPTLS, 1);
Set($LDAPTLSOptions, {
    verify => 'require',
    sslversion => 'tlsv1_2',
    cafile => '/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem'
    });

Is it worth popping a copy over to the RT bug tracker to see if this sort of thing can finally get slipped into the RT 5.x code base for 5.0.2 or beyond? Or are there some technical/ideological reasons why previous TLS patches for LDAPImport.pm didn’t make it into the main code?

1 Like