move export info to the modules themselves
[freeside.git] / FS / FS / part_export / ldap.pm
index 6ff9abe..823d99d 100644 (file)
@@ -1,11 +1,52 @@
 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 {
@@ -23,10 +64,9 @@ 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 $username_attrib;
   my %attrib = map    { /^\s*(\w+)\s+(.*\S)\s*$/;
                         $username_attrib = $1 if $2 eq '$username';
@@ -201,17 +241,24 @@ sub ldap_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( $username_attrib, %attrib ) = @_;
-  $dn = "$username_attrib=$attrib{$username_attrib}, $dn" if $username_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;
 }
@@ -238,8 +285,10 @@ sub ldap_connect {
 
   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;
+