ad name to dn conversion

WARNING: Please update your bookmarks! The content of this site has been moved to http://dille.name where it will be updated as needed. This page will remain unchanged.

This note demonstrates some exciting Perl magic. It presents several ways to convert a directory-like name of an object in Active Directory to a X.500 Distonguished name. The script is interrupted by useful comments explaining the following chunk.
#!/usr/bin/perl

use strict;
use warnings;
use locale;
use English;

my $user = 'userName@sub.domain.de/ou 1/ou2';
The following code chunk demonstrates how to perform the conversion in two lines. Unfortunately, this is rather hard to read.
print "\n";
{
    print 'line ' . __LINE__ . ': ' . $user . "\n";
    my ($userName, $dnsDomain, $ou)
        = ($user =~ m!^([^@]+)@([^/]+)/(.+)$!);
    my $ldap = 'cn=' . $userName
             . ',ou=' . join(',ou=', reverse split('/', $ou))
             . ',dc=' . join(',dc=', split('\.', $dnsDomain));
    print 'line ' . __LINE__ . ': ' . $ldap . "\n";
}
This three-liner makes the conversion rather easy to understand after several months.
print "\n";
{
    print 'line ' . __LINE__ . ': ' . $user . "\n";
    my ($userName, $dnsDomain, @ou) = split(m![@/]!, $user);
    $dnsDomain =~ s!\.!,dc=!g;
    my $ldap = 'cn=' . $userName
             . ',ou=' . join(',ou=', reverse @ou)
             . ',dc=' . $dnsDomain;
    print 'line ' . __LINE__ . ': ' . $ldap . "\n";
}
Although the following chunk consist of several lines, it contains a single regular expression performing the conversion. To run it using strict, you need to declare $ldap.
print "\n";
{
    my $ldap;
    print 'line ' . __LINE__ . ': ' . $user . "\n";
    $user =~ m!
        ([^@]+)@                          # matches the common name
        (\.?                              # matches individual
            ([^\./]+)                     # domain components
            (?{$ldap.=',dc='.$^N})        # and appends them
        )+
        (/                                # matches individual
            ([^/]+)                       # ou components
            (?{$ldap=',ou='.$^N.$ldap})   # and prepends them
        )*
        (?{$ldap='cn='.$1.$ldap})         # prepends the common name
    !x;
    print 'line ' . __LINE__ . ': ' . $ldap . "\n";
}