Code

16c8c1695c990dd561b8d04d5ea32fa99f46d2b3
[gosa.git] / gosa-si / modules / ArpHandler.pm
1 package ArpHandler;
3 use Exporter;
4 @ISA = ("Exporter");
6 use strict;
7 use warnings;
8 use GOSA::GosaSupportDaemon;
9 use Getopt::Long;
10 use Config::IniFiles;
11 use POSIX;
12 use Fcntl;
13 use Net::LDAP;
14 use Net::LDAP::LDIF;
15 use Net::LDAP::Entry;
16 use Net::DNS;
17 use Switch;
18 use Data::Dumper;
19 use POE qw(Component::Pcap Component::ArpWatch);
21 BEGIN{}
22 END{}
24 my ($verbose, $cfg_file, $log_file, $pid_file, $foreground); 
25 my ($timeout, $mailto, $mailfrom, $user, $group);
26 my ($procid, $pid, $loglevel);
27 my ($fifo_path, $max_process_timeout, $max_process );
28 my %daemon_children;
29 my ($ldap, $bind_phrase, $password, $ldap_base) ;
30 my $hosts_database={};
31 my $resolver=Net::DNS::Resolver->new;
33 $procid = -1 ;
34 $foreground = 0 ;
35 $verbose = 0 ;
36 $max_process = 2 ;
37 $max_process_timeout = 1 ;
38 $ldap_base = "dc=gonicus,dc=de" ;
39 #$ldap_path = "/var/run/gosa-support-daemon.socket";
40 #$log_path = "/var/log/gosa-support-daemon.log";
41 #$pid_path = "/var/run/gosa-support-daemon/gosa-support-daemon.pid";
43 #---------------------------------------------------------------------------
44 #  parse commandline options
45 #---------------------------------------------------------------------------
46 #Getopt::Long::Configure( "bundling" );
47 #GetOptions( "v|verbose+" => \$verbose,
48 #        "c|config=s" => \$cfg_file,
49 #        "h|help" => \&usage,
50 #        "l|logfile=s" => \$log_file,
51 #        "p|pid=s" => \$pid_file,
52 #        "f|foreground" => \$foreground);
53 #
54 #---------------------------------------------------------------------------
55 #  read and set config parameters
56 #---------------------------------------------------------------------------
57 #my %cfg_defaults =
58 #("Allgemein" =>
59 # {"timeout"  => [ \$timeout, 1000 ],
60 # "mailto"   => [ \$mailto, 'root@localhost' ],
61 # "mailfrom" => [ \$mailfrom, 'sps-daemon@localhost' ],
62 # "user"     => [ \$user, "nobody" ],
63 # "group"    => [ \$group, "nogroup" ],
64 # "fifo_path" => [ \$fifo_path, "/home/rettenbe/gonicus/gosa-support/tmp/fifo" ],
65 # "log_file"  => [ \$log_file, "/home/rettenbe/gonicus/gosa-support/tmp/gosa-support.log" ],
66 # "pid_file"  => [ \$pid_file, "/home/rettenbe/gonicus/gosa-support/tmp/gosa-support.pid" ],
67 # "loglevel"     => [ \$loglevel, 1]
68 # },
69 #"LDAP"  =>
70 #    {"bind" => [ \$bind_phrase, "cn=ldapadmin,dc=gonicus,dc=de" ],
71 #     "password" => [ \$password, "tester" ],
72 #    }
73 # );
74 #&read_configfile;
76 sub get_module_info {
77         my @info = (undef,
78                 undef,
79                 undef,
80                 undef,
81                 "socket",
82         );
84         my $device = 'eth0';
85         $ldap = Net::LDAP->new("ldap.intranet.gonicus.de") or die "$@";
87         POE::Session->create( 
88                 inline_states => {
89                         _start => \&start,
90                         _stop => sub {
91                                 $_[KERNEL]->post( arp_watch => 'shutdown' )
92                         },
93                         got_packet => \&got_packet,
94                 },
95         );
97     return \@info;
98 }
100 sub process_incoming_msg {
101         return 0;
104 sub start {
105         POE::Component::ArpWatch->spawn( 
106                 Alias => 'arp_watch',
107                 Device => 'eth0', 
108                 Dispatch => 'got_packet',
109                 Session => $_[SESSION],
110         );
112         $_[KERNEL]->post( arp_watch => 'run' );
115 sub got_packet {
116         my $packet = $_[ARG0];
118         if($packet->{source_haddr} eq "00:00:00:00:00:00" || 
119                 $packet->{source_haddr} eq "ff:ff:ff:ff:ff:ff" || 
120                 $packet->{source_ipaddr} eq "0.0.0.0") {
121                 return;
122         }
124         if(!exists($hosts_database->{$packet->{source_haddr}})) {
125                 my $ldap_result=&get_host_from_ldap($packet->{source_haddr});
126                 if(exists($ldap_result->{dn})) {
127                         $hosts_database->{$packet->{source_haddr}}=$ldap_result;
128                         $hosts_database->{$packet->{source_haddr}}->{dnsname}=($resolver->search($packet->{source_ipaddr}))->{answer}[0]->{ptrdname};
129                         print STDERR "Host was found in LDAP as ".$ldap_result->{dn}."\n";
130                 } else {
131                         $hosts_database->{$packet->{source_haddr}}={
132                                 macAddress => $packet->{source_haddr},
133                                 ipHostNumber => $packet->{source_ipaddr},
134                                 dnsname => ($resolver->search($packet->{source_ipaddr}))->{answer}[0]->{ptrdname},
135                         };
136                         print STDERR "Host was not found in LDAP (".($hosts_database->{$packet->{source_haddr}}->{dnsname}).")\n";
137                 }
138         } else {
139                 print STDERR "Host already in cache (".($hosts_database->{$packet->{source_haddr}}->{dnsname}).")\n";
140         }
141
143 sub get_host_from_ldap {
144         my $mac=shift;
145         my $result={};
146                 
147         my $ldap_result= search_ldap_entry(
148                 $ldap,
149                 $ldap_base,
150                 "(|(macAddress=$mac)(dhcpHWAddress=ethernet $mac))"
151         );
153         if($ldap_result->count==1) {
154                 if(exists($ldap_result->{entries}[0]) && 
155                         exists($ldap_result->{entries}[0]->{asn}->{objectName}) && 
156                         exists($ldap_result->{entries}[0]->{asn}->{attributes})) {
158                         for my $attribute(@{$ldap_result->{entries}[0]->{asn}->{attributes}}) {
159                                 if($attribute->{type} eq 'cn') {
160                                         $result->{cn} = $attribute->{vals}[0];
161                                 }
162                                 if($attribute->{type} eq 'macAddress') {
163                                         $result->{macAddress} = $attribute->{vals}[0];
164                                 }
165                                 if($attribute->{type} eq 'dhcpHWAddress') {
166                                         $result->{dhcpHWAddress} = $attribute->{vals}[0];
167                                 }
168                                 if($attribute->{type} eq 'ipHostNumber') {
169                                         $result->{ipHostNumber} = $attribute->{vals}[0];
170                                 }
171                         }
172                 }
173                 $result->{dn} = $ldap_result->{entries}[0]->{asn}->{objectName};
174         }
176         return $result;
180 #===  FUNCTION  ================================================================
181 #         NAME:  add_ldap_entry
182 #      PURPOSE:  adds an element to ldap-tree
183 #   PARAMETERS:  
184 #      RETURNS:  none
185 #  DESCRIPTION:  ????
186 #       THROWS:  no exceptions
187 #     COMMENTS:  none
188 #     SEE ALSO:  n/a
189 #===============================================================================
190 #sub add_ldap_entry {
191 #    my ($ldap_tree, $ldap_base, $mac, $gotoSysStatus, $ip, $interface, $desc) = @_;
192 #    my $dn = "cn=$mac,ou=incoming,$ldap_base";
193 #    my $s_res = &search_ldap_entry($ldap_tree, $ldap_base, "(|(macAddress=$mac)(dhcpHWAddress=ethernet $mac))");
194 #    my $c_res = $s_res->count;
195 #    if($c_res == 1) {
196 #        daemon_log("WARNING: macAddress $mac already in LDAP", 1);
197 #        return;
198 #    } elsif($c_res > 0) {
199 #        daemon_log("ERROR: macAddress $mac exists $c_res times in LDAP", 1);
200 #        return;
201 #    }
203 #    # create LDAP entry 
204 #    my $entry = Net::LDAP::Entry->new( $dn );
205 #    $entry->dn($dn);
206 #    $entry->add("objectClass" => "goHard");
207 #    $entry->add("cn" => $mac);
208 #    $entry->add("macAddress" => $mac);
209 #    if(defined $gotoSysStatus) {$entry->add("gotoSysStatus" => $gotoSysStatus)}
210 #    if(defined $ip) {$entry->add("ipHostNumber" => $ip) }
211 #    #if(defined $interface) { }
212 #    if(defined $desc) {$entry->add("description" => $desc) }
213 #    
214 #    # submit entry to LDAP
215 #    my $result = $entry->update ($ldap_tree); 
216 #        
217 #    # for $result->code constants please look at Net::LDAP::Constant
218 #    my $log_time = localtime( time );
219 #    if($result->code == 68) {   # entry already exists 
220 #        daemon_log("WARNING: $log_time: $dn ".$result->error, 3);
221 #    } elsif($result->code == 0) {   # everything went fine
222 #        daemon_log("$log_time: add entry $dn to ldap", 1);
223 #    } else {  # if any other error occur
224 #        daemon_log("ERROR: $log_time: $dn, ".$result->code.", ".$result->error, 1);
225 #    }
226 #    return;
227 #}
230 #===  FUNCTION  ================================================================
231 #         NAME:  change_ldap_entry
232 #      PURPOSE:  ????
233 #   PARAMETERS:  ????
234 #      RETURNS:  ????
235 #  DESCRIPTION:  ????
236 #       THROWS:  no exceptions
237 #     COMMENTS:  none
238 #     SEE ALSO:  n/a
239 #===============================================================================
240 #sub change_ldap_entry {
241 #    my ($ldap_tree, $ldap_base, $mac, $gotoSysStatus ) = @_;
242 #    
243 #    # check if ldap_entry exists or not
244 #    my $s_res = &search_ldap_entry($ldap_tree, $ldap_base, "(|(macAddress=$mac)(dhcpHWAddress=ethernet $mac))");
245 #    my $c_res = $s_res->count;
246 #    if($c_res == 0) {
247 #        daemon_log("WARNING: macAddress $mac not in LDAP", 1);
248 #        return;
249 #    } elsif($c_res > 1) {
250 #        daemon_log("ERROR: macAddress $mac exists $c_res times in LDAP", 1);
251 #        return;
252 #    }
254 #    my $s_res_entry = $s_res->pop_entry();
255 #    my $dn = $s_res_entry->dn();
256 #    my $result = $ldap->modify( $dn, replace => {'gotoSysStatus' => $gotoSysStatus } );
258 #    # for $result->code constants please look at Net::LDAP::Constant
259 #    my $log_time = localtime( time );
260 #    if($result->code == 32) {   # entry doesnt exists 
261 #        &add_ldap_entry($mac, $gotoSysStatus);
262 #    } elsif($result->code == 0) {   # everything went fine
263 #        daemon_log("$log_time: entry $dn changed successful", 1);
264 #    } else {  # if any other error occur
265 #        daemon_log("ERROR: $log_time: $dn, ".$result->code.", ".$result->error, 1);
266 #    }
268 #    return;
269 #}
271 #===  FUNCTION  ================================================================
272 #         NAME:  search_ldap_entry
273 #      PURPOSE:  ????
274 #   PARAMETERS:  [Net::LDAP] $ldap_tree - object of an ldap-tree
275 #                string $sub_tree - dn of the subtree the search is performed
276 #                string $search_string - either a string or a Net::LDAP::Filter object
277 #      RETURNS:  [Net::LDAP::Search] $msg - result object of the performed search
278 #  DESCRIPTION:  ????
279 #       THROWS:  no exceptions
280 #     COMMENTS:  none
281 #     SEE ALSO:  n/a
282 #===============================================================================
283 sub search_ldap_entry {
284     my ($ldap_tree, $sub_tree, $search_string) = @_;
285     my $msg = $ldap_tree->search( # perform a search
286                         base   => $sub_tree,
287                         filter => $search_string,
288                       ) or daemon_log("cannot perform search at ldap: $@", 1);
289 #    if(defined $msg) {
290 #        print $sub_tree."\t".$search_string."\t";
291 #        print $msg->count."\n";
292 #        foreach my $entry ($msg->entries) { $entry->dump; };
293 #    }
295     return $msg;
300 #========= MAIN = main ========================================================
301 #daemon_log( "####### START DAEMON ######\n", 1 );
302 #&check_cmdline_param ;
303 #&check_pid;
304 #&open_fifo($fifo_path);
306 ## Just fork, if we"re not in foreground mode
307 #if( ! $foreground ) { $pid = fork(); }
308 #else { $pid = $$; }
310 ## Do something useful - put our PID into the pid_file
311 #if( 0 != $pid ) {
312 #    open( LOCK_FILE, ">$pid_file" );
313 #    print LOCK_FILE "$pid\n";
314 #    close( LOCK_FILE );
315 #    if( !$foreground ) { exit( 0 ) };
316 #}
319 #if( not -p $fifo_path ) { die "fifo file disappeared\n" }
320 #if($c_res == 1) {
321 #        daemon_log("WARNING: macAddress $mac already in LDAP", 1);
322 #        return;
323 #    } elsif($c_res > 0) {
324 #        daemon_log("ERROR: macAddress $mac exists $c_res times in LDAP", 1);
325 #        return;
326 #    }
328 #    # create LDAP entry 
329 #    my $entry = Net::LDAP::Entry->new( $dn );
330 #    $entry->dn($dn);
331 #    $entry->add("objectClass" => "goHard");
332 #    $entry->add("cn" => $mac);
333 #    $entry->add("macAddress" => $mac);
334 #    if(defined $gotoSysStatus) {$entry->add("gotoSysStatus" => $gotoSysStatus)}
335 #    if(defined $ip) {$entry->add("ipHostNumber" => $ip) }
336 #    #if(defined $interface) { }
337 #    if(defined $desc) {$entry->add("description" => $desc) }
338 #    
339 #    # submit entry to LDAP
340 #    my $result = $entry->update ($ldap_tree); 
341 #        
342 #    # for $result->code constants please look at Net::LDAP::Constant
343 #    my $log_time = localtime( time );
344 #    if($result->code == 68) {   # entry already exists 
345 #        daemon_log("WARNING: $log_time: $dn ".$result->error, 3);
346 #    } elsif($result->code == 0) {   # everything went fine
347 #        daemon_log("$log_time: add entry $dn to ldap", 1);
348 #    } else {  # if any other error occur
349 #        daemon_log("ERROR: $log_time: $dn, ".$result->code.", ".$result->error, 1);
350 #    }
351 #    return;
352 #}
355 #===  FUNCTION  ================================================================
356 #         NAME:  change_ldap_entry
357 #      PURPOSE:  ????
358 #   PARAMETERS:  ????
359 #      RETURNS:  ????
360 #  DESCRIPTION:  ????
361 #       THROWS:  no exceptions
362 #     COMMENTS:  none
363 #     SEE ALSO:  n/a
364 #===============================================================================
365 #sub change_ldap_entry {
366 #    my ($ldap_tree, $ldap_base, $mac, $gotoSysStatus ) = @_;
367 #    
368 #    # check if ldap_entry exists or not
369 #    my $s_res = &search_ldap_entry($ldap_tree, $ldap_base, "(|(macAddress=$mac)(dhcpHWAddress=ethernet $mac))");
370 #    my $c_res = $s_res->count;
371 #    if($c_res == 0) {
372 #        daemon_log("WARNING: macAddress $mac not in LDAP", 1);
373 #        return;
374 #    } elsif($c_res > 1) {
375 #        daemon_log("ERROR: macAddress $mac exists $c_res times in LDAP", 1);
376 #        return;
377 #    }
379 #    my $s_res_entry = $s_res->pop_entry();
380 #    my $dn = $s_res_entry->dn();
381 #    my $result = $ldap->modify( $dn, replace => {'gotoSysStatus' => $gotoSysStatus } );
383 #    # for $result->code constants please look at Net::LDAP::Constant
384 #    my $log_time = localtime( time );
385 #    if($result->code == 32) {   # entry doesnt exists 
386 #        &add_ldap_entry($mac, $gotoSysStatus);
387 #    } elsif($result->code == 0) {   # everything went fine
388 #        daemon_log("$log_time: entry $dn changed successful", 1);
389 #    } else {  # if any other error occur
390 #        daemon_log("ERROR: $log_time: $dn, ".$result->code.", ".$result->error, 1);
391 #    }
393 #    return;
394 #}
396 #===  FUNCTION  ================================================================
397 #         NAME:  search_ldap_entry
398 #      PURPOSE:  ????
399 #   PARAMETERS:  [Net::LDAP] $ldap_tree - object of an ldap-tree
400 #                string $sub_tree - dn of the subtree the search is performed
401 #                string $search_string - either a string or a Net::LDAP::Filter object
402 #      RETURNS:  [Net::LDAP::Search] $msg - result object of the performed search
403 #  DESCRIPTION:  ????
404 #       THROWS:  no exceptions
405 #     COMMENTS:  none
406 #     SEE ALSO:  n/a
407 #===============================================================================
408 #sub search_ldap_entry {
409 #    my ($ldap_tree, $sub_tree, $search_string) = @_;
410 #    my $msg = $ldap_tree->search( # perform a search
411 #                        base   => $sub_tree,
412 #                        filter => $search_string,
413 #                      ) or daemon_log("cannot perform search at ldap: $@", 1);
414 ##    if(defined $msg) {
415 ##        print $sub_tree."\t".$search_string."\t";
416 ##        print $msg->count."\n";
417 ##        foreach my $entry ($msg->entries) { $entry->dump; };
418 ##    }
420 #    return $msg;
421 #}
425 #========= MAIN = main ========================================================
426 #daemon_log( "####### START DAEMON ######\n", 1 );
427 #&check_cmdline_param ;
428 #&check_pid;
429 #&open_fifo($fifo_path);
431 ## Just fork, if we"re not in foreground mode
432 #if( ! $foreground ) { $pid = fork(); }
433 #else { $pid = $$; }
435 ## Do something useful - put our PID into the pid_file
436 #if( 0 != $pid ) {
437 #    open( LOCK_FILE, ">$pid_file" );
438 #    print LOCK_FILE "$pid\n";
439 #    close( LOCK_FILE );
440 #    if( !$foreground ) { exit( 0 ) };
441 #}
444 #if( not -p $fifo_path ) { die "fifo file disappeared\n" }
445 #sysopen(FIFO, $fifo_path, O_RDONLY) or die "can't read from $fifo_path: $!" ;
447 #while( 1 ) {
448 #    # checke alle prozesse im hash daemon_children ob sie noch aktiv sind, wenn
449 #    # nicht, dann entferne prozess aus hash
450 #    while( (my $key, my $val) = each( %daemon_children) ) {
451 #        my $status = waitpid( $key, &WNOHANG) ;
452 #        if( $status == -1 ) { 
453 #            delete $daemon_children{$key} ; 
454 #            daemon_log("childprocess finished: $key", 3) ;
455 #        }
456 #    }
458 #    # ist die max_process anzahl von prozesskindern erreicht, dann warte und 
459 #    # prüfe erneut, ob in der zwischenzeit prozesse fertig geworden sind
460 #    if( keys( %daemon_children ) >= $max_process ) { 
461 #        sleep($max_process_timeout) ;
462 #        next ;
463 #    }
465 #    my $msg = <FIFO>;
466 #    if( not defined( $msg )) { next ; }
467 #    
468 #    chomp( $msg );
469 #    if( length( $msg ) == 0 ) { next ; }
471 #    my $forked_pid = fork();
472 ##=== PARENT = parent ==========================================================
473 #    if ( $forked_pid != 0 ) { 
474 #        daemon_log("childprocess forked: $forked_pid", 3) ;
475 #        $daemon_children{$forked_pid} = 0 ;
476 #    }
477 ##=== CHILD = child ============================================================
478 #    else {
479 #        # parse the incoming message from arp, split the message and return 
480 #        # the values in an array. not defined values are set to "none" 
481 #        #my ($mac, $ip, $interface, $arp_sig, $desc) = &parse_input( $msg ) ;
482 #        daemon_log( "childprocess read from arp: $fifo_path\nline: $msg", 3);
483 #        my ($mac, $ip, $interface, $arp_sig, $desc) = split('\s', $msg, 5);
485 #        # create connection to LDAP
486 #        $#sysopen(FIFO, $fifo_path, O_RDONLY) or die "can't read from $fifo_path: $!" ;
488 #while( 1 ) {
489 #    # checke alle prozesse im hash daemon_children ob sie noch aktiv sind, wenn
490 #    # nicht, dann entferne prozess aus hash
491 #    while( (my $key, my $val) = each( %daemon_children) ) {
492 #        my $status = waitpid( $key, &WNOHANG) ;
493 #        if( $status == -1 ) { 
494 #            delete $daemon_children{$key} ; 
495 #            daemon_log("childprocess finished: $key", 3) ;
496 #        }
497 #    }
499 #    # ist die max_process anzahl von prozesskindern erreicht, dann warte und 
500 #    # prüfe erneut, ob in der zwischenzeit prozesse fertig geworden sind
501 #    if( keys( %daemon_children ) >= $max_process ) { 
502 #        sleep($max_process_timeout) ;
503 #        next ;
504 #    }
506 #    my $msg = <FIFO>;
507 #    if( not defined( $msg )) { next ; }
508 #    
509 #    chomp( $msg );
510 #    if( length( $msg ) == 0 ) { next ; }
512 #    my $forked_pid = fork();
513 ##=== PARENT = parent ==========================================================
514 #    if ( $forked_pid != 0 ) { 
515 #        daemon_log("childprocess forked: $forked_pid", 3) ;
516 #        $daemon_children{$forked_pid} = 0 ;
517 #    }
518 ##=== CHILD = child ============================================================
519 #    else {
520 #        # parse the incoming message from arp, split the message and return 
521 #        # the values in an array. not defined values are set to "none" 
522 #        #my ($mac, $ip, $interface, $arp_sig, $desc) = &parse_input( $msg ) ;
523 #        daemon_log( "childprocess read from arp: $fifo_path\nline: $msg", 3);
524 #        my ($mac, $ip, $interface, $arp_sig, $desc) = split('\s', $msg, 5);
526 #        # create connection to LDAP
527 #        $ldap = Net::LDAP->new( "localhost" ) or die "$@";
528 #        $ldap->bind($bind_phrase,
529 #                    password => $password,
530 #                    ) ;
531 #        
532 #        switch($arp_sig) {
533 #            case 0 {&change_ldap_entry($ldap, $ldap_base, 
534 #                                      $mac, "ip-changed",
535 #                                      )} 
536 #            case 1 {&change_ldap_entry($ldap, $ldap_base, 
537 #                                      $mac, "mac-not-whitelisted",
538 #                                      )}
539 #            case 2 {&change_ldap_entry($ldap, $ldap_base, 
540 #                                      $mac, "mac-in-blacklist",
541 #                                      )}
542 #            case 3 {&add_ldap_entry($ldap, $ldap_base, 
543 #                                   $mac, "new-mac-address", $ip, 
544 #                                   $interface, $desc, 
545 #                                   )}
546 #            case 4 {&change_ldap_entry($ldap, $ldap_base, 
547 #                                      $mac, "unauthorized-arp-request",
548 #                                      )}
549 #            case 5 {&change_ldap_entry($ldap, $ldap_base, 
550 #                                      $mac, "abusive-number-of-arp-requests",
551 #                                      )}
552 #            case 6 {&change_ldap_entry($ldap, $ldap_base, 
553 #                                      $mac, "ether-and-arp-mac-differs",
554 #                                      )}
555 #            case 7 {&change_ldap_entry($ldap, $ldap_base, 
556 #                                      $mac, "flood-detected",
557 #                                      )}
558 #            case 8 {&add_ldap_entry($ldap, $ldap_base, 
559 #                                   $mac, $ip, "new-system",
560 #                                   )}
561 #            case 9 {&change_ldap_entry($ldap, $ldap_base, 
562 #                                      $mac, "mac-changed",
563 #                                      )}
564 #        }
567         # ldap search
568 #        my $base_phrase = "dc=gonicus,dc=de";
569 #        my $filter_phrase = "cn=keinesorge";
570 #        my $attrs_phrase = "cn macAdress";
571 #        my $msg_search = $ldap->search( base   => $base_phrase,
572 #                                        filter => $filter_phrase,
573 #                                        attrs => $attrs_phrase,
574 #                                        );
575 #        $msg_search->code && die $msg_search->error;
576 #        
577 #        my @entries = $msg_search->entries;
578 #        my $max = $msg_search->count;
579 #        print "anzahl der entries: $max\n";
580 #        my $i;
581 #        for ( $i = 0 ; $i < $max ; $i++ ) {
582 #            my $entry = $msg_search->entry ( $i );
583 #            foreach my $attr ( $entry->attributes ) {
584 #                if( not $attr eq "cn") {
585 #                    next;
586 #                }
587 #                print join( "\n ", $attr, $entry->get_value( $attr ) ), "\n\n";
588 #            }
589 #        }
590                 #
591                 #        # ldap add
592                 #       
593                 #        
594                 #        $ldap->unbind;
595                 #        exit;
596                 #    }
597                 #
598                 #}
600 1;