#!@l_prefix@/bin/perl
##
##  ypanything.passwd.pl: LDAP passwd provider
##

use IO::File;
use MIME::Base64;

#   configuration
my $host         = "localhost";
my $port         = "389";
my $bindDN       = "CN=Directory Manager";
my $bindPassword = "secret";
my $base         = "O=example.com";
my $searchType   = "sub";
my $ldapsearch   = "@l_prefix@/bin/ldapsearch";
	
#   query directory via LDAP
my $ldap = new IO::File
    "$ldapsearch -x -LLL -h '$host' -p '$port'" .
    " -D '$bindDN' -w '$bindPassword' -b '$base' -s '$searchType'" .
    " objectClass=posixAccount" .
    " uid userpassword uidnumber gidnumber gecos homedirectory loginshell |"
    or die "$!";
my @pw = ();
my $pw = {};
while (<$ldap>) {
    if (m/^\s*$/) {
        if (defined($pw)) {
            push(@pw, $pw);
            $pw = {};
        }
    }
    elsif (m/^([^:]+)::\s*(.*?)\s*$/) {
        $pw->{$1} .= (defined($pw->{$1}) ? $pw->{$1} . "," : "") . MIME::Base64::decode($2);
    }
    elsif (m/^([^:]+):\s*(.*?)\s*$/) {
        $pw->{$1} = (defined($pw->{$1}) ? $pw->{$1} . "," : "") . $2;
    }
}
$ldap->close();

#   post-processing and output generation
my $O = "";
foreach my $pw (@pw) {
    $pw->{"userpassword"} ||= "*";
    $pw->{"userpassword"} =~ s/\{crypt\}//ig;
    $O .= sprintf("%s:%s:%s:%s:%s:%s:%s\n",
        $pw->{uid}, $pw->{userpassword}, $pw->{uidnumber}, $pw->{gidnumber},
        $pw->{gecos}, $pw->{homedirectory}, $pw->{loginshell}
    );
}

#   provide output
print STDOUT $O;
exit(0);

