--- lib/A3C/LDAP/Server.pm 2008/06/27 19:09:13 228 +++ lib/A3C/LDAP/Server.pm 2008/06/27 19:31:49 229 @@ -11,10 +11,15 @@ ); use Net::LDAP::Server; use Net::LDAP::Filter; -use base 'Net::LDAP::Server'; +use base qw(Net::LDAP::Server); use fields qw(upstream); use A3C::LDAP; +use A3C::Cache; + +#use A3C::Cache; +use URI::Escape; # uri_escape + use Data::Dump qw/dump/; =head1 NAME @@ -27,8 +32,91 @@ Provide LDAP server functionality for L somewhat similar to C +=head1 METHODS + +=head2 run + + my $pid = A3C::LDAP::Server->run({ port => 1389, fork => 0 }); + =cut +our $pids; +our $cache; + +sub cache { + return $cache if $cache; + $cache = new A3C::Cache->new({ instance => '', dir => 'ldap' }); +} + +sub run { + my $self = shift; + + my $args = shift; + # default LDAP port + my $port = $args->{port} ||= 1389; + + if ( $args->{fork} ) { + defined(my $pid = fork()) or die "Can't fork: $!"; + if ( $pid ) { + $pids->{ $port } = $pid; + warn "# pids = ",dump( $pids ); + sleep 1; + return $pid; + } + } + + my $sock = IO::Socket::INET->new( + Listen => 5, + Proto => 'tcp', + Reuse => 1, + LocalPort => $port, + ) or die "can't listen on port $port: $!\n"; + + warn "LDAP server listening on port $port\n"; + + my $sel = IO::Select->new($sock) or die "can't select socket: $!\n"; + my %Handlers; + while (my @ready = $sel->can_read) { + foreach my $fh (@ready) { + if ($fh == $sock) { + # let's create a new socket + my $psock = $sock->accept; + $sel->add($psock); + $Handlers{*$psock} = A3C::LDAP::Server->new($psock); + } else { + my $result = $Handlers{*$fh}->handle; + if ($result) { + # we have finished with the socket + $sel->remove($fh); + $fh->close; + delete $Handlers{*$fh}; + } + } + } + } +} + +=head2 stop + + my $stopped_pids = A3C::LDAP::Server->stop; + +=cut + +sub stop { + warn "## stop pids = ",dump( $pids ); + return unless $pids; + my $stopped = 0; + foreach my $port ( keys %$pids ) { + my $pid = delete($pids->{$port}) or die "no pid?"; + warn "# Shutdown LDAP server at port $port pid $pid\n"; + kill(9,$pid) or die "can't kill $pid: $!"; + waitpid($pid,0) or die "waitpid $pid: $!"; + $stopped++; + } + warn "## stopped $stopped processes\n"; + return $stopped; +} + use constant RESULT_OK => { 'matchedDN' => '', 'errorMessage' => '', @@ -75,7 +163,7 @@ password => $req->{authentication}->{simple} ); - warn "# bind msg = ",dump( $msg ); + #warn "# bind msg = ",dump( $msg ); if ( $msg->code != LDAP_SUCCESS ) { warn "ERROR: ", $msg->code, ": ", $msg->server_error, "\n"; return { @@ -151,6 +239,9 @@ } warn "## entries = ",dump( @entries ); + + $self->cache->write_cache( \@entries, uri_escape( $filter )); + return RESULT_OK, @entries; }