package FS::part_export::ldap;
-use vars qw(@ISA);
+use vars qw(@ISA %info @saltset);
+use Tie::IxHash;
use FS::Record qw( dbh );
use FS::part_export;
@ISA = qw(FS::part_export);
+tie my %options, 'Tie::IxHash',
+ 'dn' => { label=>'Root DN' },
+ 'password' => { label=>'Root DN password' },
+ 'userdn' => { label=>'User DN' },
+ 'attributes' => { label=>'Attributes',
+ type=>'textarea',
+ default=>join("\n",
+ 'uid $username',
+ 'mail $username\@$domain',
+ 'uidno $uid',
+ 'gidno $gid',
+ 'cn $first',
+ 'sn $last',
+ 'mailquota $quota',
+ 'vmail',
+ 'location',
+ 'mailtag',
+ 'mailhost',
+ 'mailmessagestore $dir',
+ 'userpassword $crypt_password',
+ 'hint',
+ 'answer $sec_phrase',
+ 'objectclass top,person,inetOrgPerson',
+ ),
+ },
+ 'radius' => { label=>'Export RADIUS attributes', type=>'checkbox', },
+;
+
+%info = (
+ 'svc' => 'svc_acct',
+ 'desc' => 'Real-time export to LDAP',
+ 'options' => \%options,
+ 'notes' => <<'END'
+Real-time export to arbitrary LDAP attributes. Requires installation of
+<a href="http://search.cpan.org/dist/Net-LDAP">Net::LDAP</a> from CPAN.
+END
+);
+
+@saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' );
+
sub rebless { shift; }
sub _export_insert {
}
}
$crypt_password = ''; #surpress "used only once" warnings
- $crypt_password = crypt( $svc_acct->_password,
+ $crypt_password = '{crypt}'. crypt( $svc_acct->_password,
$saltset[int(rand(64))].$saltset[int(rand(64))] );
-
- my %attrib = map { /^\s*(\w+)\s+(.*\S)\s*$/; ( $1 => eval(qq("$2")) ); }
+ my $username_attrib;
+ my %attrib = map { /^\s*(\w+)\s+(.*\S)\s*$/;
+ $username_attrib = $1 if $2 eq '$username';
+ ( $1 => eval(qq("$2")) ); }
grep { /^\s*(\w+)\s+(.*\S)\s*$/ }
split("\n", $self->option('attributes'));
my $err_or_queue = $self->ldap_queue( $svc_acct->svcnum, 'insert',
#$svc_acct->username,
+ $username_attrib,
%attrib );
return $err_or_queue unless ref($err_or_queue);
$self->machine,
$self->option('dn'),
$self->option('password'),
+ $self->option('userdn'),
@_,
) or $queue;
}
sub ldap_insert { #subroutine, not method
- my $ldap = ldap_connect(shift, (my $dn = shift), shift);
- my %attrib = @_;
+ my $ldap = ldap_connect(shift, shift, shift);
+ my( $userdn, $username_attrib, %attrib ) = @_;
+
+ $userdn = "$username_attrib=$attrib{$username_attrib}, $userdn"
+ if $username_attrib;
+ #icky hack, but should be unsurprising to the LDAPers
+ foreach my $key ( grep { $attrib{$_} =~ /,/ } keys %attrib ) {
+ $attrib{$key} = [ split(/,/, $attrib{$key}) ];
+ }
- my $status = $ldap->add( $dn, attrs => [ %attrib ] );
- die $status->error if $status->is_error;
+ my $status = $ldap->add( $userdn, attrs => [ %attrib ] );
+ die 'LDAP error: '. $status->error. "\n" if $status->is_error;
$ldap->unbind;
}
my $ldap = Net::LDAP->new($machine) or die $@;
my $status = $ldap->bind( $dn, %bind_options );
- die $status->error if $status->is_error;
+ die 'LDAP error: '. $status->error. "\n" if $status->is_error;
$ldap;
}
+1;
+