#################### main pod documentation begin ################### =head1 NAME Zymonic::Decryptor::Message - Zymonic Decryptor base module. =head1 SYNOPSIS This is a module for communicating with LDAP servers. =head1 DESCRIPTION This is a Message class to allow the decryptor to handle communication with LDAP servers throughout the user's session i.e. by tokenising their password. =head1 USAGE The module expects a hashref of the following form: { host => 'LDAP SERVER', new_options => { ... all options valid for Net::LDAP::new }, bind_dn => 'cn=me,ou=myorg', bind_options => { ... all options valid for Net::LDAP::bind }, start_tls => { ... all options valid for Net::LDAP::start_tls }, add|modify|moddn|delete|schema_dn => 'uid=newdn,...', add|modify|moddn|delete|schema_options => { ... all options valid for Net::LDAP::add/modify/moddn/delete} search_options => { ... all options valid for Net::LDAP::search } get_schema => 'true', } When the message is called it will: 1) Create a connection. 2) Start TLS (if specified) 3) Bind (if specified) 4) add/modify/moddn/delete (any/all of which are specified) 5) Search and return a hashref of entries keyed on DN (if specified) 6) Return the result of each action. =head1 BUGS None we're aware of... =head1 SUPPORT As in the license, Zymonic is provided without warranty or support unless purchased separately, however... If you email zymonic-support@zednax.com your issue will be noted and may receive a response. For security issues, please contact zymonic-security@zednax.com and someone will respond within 8 working hours. =head1 AUTHOR Alex Masidlover et al. CPAN ID: MODAUTHOR Zednax Limited alex.masidlover@zednax.com http://www.zednax.com =head1 COPYRIGHT This program is free software licensed under the... Zymonic Public License 1.0 The full text of the license can be found in the LICENSE file included with this module. Other licenses may be acceptable if including parts of Zymonic in larger projects, please contact Zednax for details. =head1 SEE ALSO perl(1). =cut #################### main pod documentation end ################### package Zymonic::Decryptor::Message; use strict; use warnings; BEGIN { use Exporter (); use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); $VERSION = '0.01'; @ISA = qw(Exporter); #Give a hoot don't pollute, do not export more than needed by default @EXPORT = qw(); @EXPORT_OK = qw(); %EXPORT_TAGS = (); } use base 'Zymonic::Base'; use Zymonic::Utils qw(debug rethrow_exception); use Net::LDAP; use Net::LDAP::Schema; #################### subroutine header begin #################### =head2 respond Usage : my $response = $mh->repsond($in) Purpose : This is the response handler method for decryptor messages. Returns : a response hashref Argument : a message hashref Throws : nothing Comment : The 'base' response is just a ping... See Also : =cut #################### subroutine header end #################### sub respond { my $self = shift; my $in = shift; $self->{decryptor_server}->connection_log( 'Creating an LDAP connection to ' . $in->{host} ); my $result = {}; eval { # Attempt Connection Zymonic::Exception::Decryptor::Message::LDAP->throw( error => 'Host must be specified', log_id => $self->{decryptor_server}->{log_id} ) unless $in->{host}; my $ldap = Net::LDAP->new( $in->{host}, %{ $in->{new_options} } ) || Zymonic::Exception::Decryptor::Message::LDAP->throw( error => 'Connection to ' . $in->{host} . ' failed!', log_id => $self->{decryptor_server}->{log_id} ); # Start TLS $ldap->start_tls( %{ $in->{start_tls} } ) if defined $in->{start_tls}; # Bind my $res = undef; $res = $ldap->bind( $in->{bind_dn}, %{ $in->{bind_options} } ) if defined $in->{bind_dn}; Zymonic::Exception::Decryptor::Message::LDAP->throw( error => 'Error doing LDAP bind ' . $res->error_text(), log_id => $self->{decryptor_server}->{log_id} ) if defined $res and $res->is_error(); # Add $res = undef; $res = $ldap->add( $in->{add_dn}, %{ $in->{add_options} } ) if defined $in->{add_dn}; Zymonic::Exception::Decryptor::Message::LDAP->throw( error => 'Error doing LDAP add ' . $res->error_text(), log_id => $self->{decryptor_server}->{log_id} ) if defined $res and $res->is_error(); # Modify $res = undef; $res = $ldap->modify( $in->{modify_dn}, %{ $in->{modify_options} } ) if defined $in->{modify_dn}; Zymonic::Exception::Decryptor::Message::LDAP->throw( error => 'Error doing LDAP modify ' . $res->error_text(), log_id => $self->{decryptor_server}->{log_id} ) if defined $res and $res->is_error(); # Moddn $res = undef; $res = $ldap->moddn( $in->{moddn_dn}, %{ $in->{moddn_options} } ) if defined $in->{moddn_dn}; Zymonic::Exception::Decryptor::Message::LDAP->throw( error => 'Error doing LDAP moddn ' . $res->error_text(), log_id => $self->{decryptor_server}->{log_id} ) if defined $res and $res->is_error(); # Delete $res = undef; $res = $ldap->delete( $in->{delete_dn}, %{ $in->{delete_options} } ) if defined $in->{delete_dn}; Zymonic::Exception::Decryptor::Message::LDAP->throw( error => 'Error doing LDAP delete ' . $res->error_text(), log_id => $self->{decryptor_server}->{log_id} ) if defined $res and $res->is_error(); # Search $res = undef; if ( defined $in->{search_options} ) { # TODO substitute filter params into the filter $res = $ldap->search( %{ $in->{search_options} } ); Zymonic::Exception::Decryptor::Message::LDAP->throw( error => 'Error doing LDAP search ' . $res->error_text(), log_id => $self->{decryptor_server}->{log_id} ) if defined $res and $res->is_error(); $result->{search_result} = $res->as_struct(); } # Schema if ( defined $in->{get_schema} ) { my $schema = $ldap->schema(); foreach my $oc ( @{ $in->{ObjectClasses} } ) { $result->{attributes}->{$oc}->{may} = $schema->may($oc); $result->{attributes}->{$oc}->{must} = $schema->must($oc); } } $ldap->unbind(); $ldap->disconnect(); $result->{complete} = 1; } or do { my $exception = $@; if ( ref($exception) && $exception->isa('Zymonic::Exception::Decryptor::Message::LDAP') ) { $result->{error} = $exception->{error}; } else { rethrow_exception($exception); } }; return $result; }