From 5aba8d1655a44551c051d3654fd40a2fcfd1a005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 12 Jun 2015 16:42:03 +0200 Subject: [PATCH] Possibility to configure objectClass and attributes for LDAP backend (references #8) --- lib/Apache/Session/Browseable/LDAP.pm | 48 +++++++---- lib/Apache/Session/Browseable/Store/LDAP.pm | 89 +++++++++++++++------ 2 files changed, 96 insertions(+), 41 deletions(-) diff --git a/lib/Apache/Session/Browseable/LDAP.pm b/lib/Apache/Session/Browseable/LDAP.pm index 7412691..12b0e18 100644 --- a/lib/Apache/Session/Browseable/LDAP.pm +++ b/lib/Apache/Session/Browseable/LDAP.pm @@ -64,17 +64,23 @@ sub searchOnExpr { sub _query { my ( $class, $args, $selectField, $value, @fields ) = @_; + $args->{ldapObjectClass} ||= 'applicationProcess'; + $args->{ldapAttributeId} ||= 'cn'; + $args->{ldapAttributeContent} ||= 'description'; + $args->{ldapAttributeIndex} ||= 'ou'; my %res = (); my $ldap = Apache::Session::Browseable::Store::LDAP::ldap( { args => $args } ); my $msg = $ldap->search( - base => $args->{ldapConfBase}, - filter => - "(&(objectClass=applicationProcess)(ou=${selectField}_$value))", + base => $args->{ldapConfBase}, + filter => "(&(objectClass=" + . $args->{ldapObjectClass} . ")(" + . $args->{ldapAttributeIndex} + . "=${selectField}_$value))", #scope => 'base', - attrs => [ 'description', 'cn' ], + attrs => [ $args->{ldapAttributeContent}, $args->{ldapAttributeId} ], ); $ldap->unbind(); @@ -84,8 +90,8 @@ sub _query { } else { foreach my $entry ( $msg->entries ) { - my $id = $entry->get_value('cn') or die; - my $tmp = $entry->get_value('description'); + my $id = $entry->get_value( $args->{ldapAttributeId} ) or die; + my $tmp = $entry->get_value( $args->{ldapAttributeContent} ); next unless ($tmp); eval { $tmp = unserialize($tmp); }; next if ($@); @@ -104,6 +110,11 @@ sub get_key_from_all_sessions { my $class = shift; my $args = shift; my $data = shift; + $args->{ldapObjectClass} ||= 'applicationProcess'; + $args->{ldapAttributeId} ||= 'cn'; + $args->{ldapAttributeContent} ||= 'description'; + $args->{ldapAttributeIndex} ||= 'ou'; + my %res; my $ldap = @@ -113,8 +124,11 @@ sub get_key_from_all_sessions { # VERY STRANGE BUG ! With this filter, description isn't base64 encoded !!! #filter => '(objectClass=applicationProcess)', - filter => '(&(objectClass=applicationProcess)(ou=*))', - attrs => [ 'cn', 'description' ], + + filter => '(&(objectClass=' + . $args->{ldapObjectClass} . ')(' + . $args->{ldapAttributeIndex} . '=*))', + attrs => [ $args->{ldapAttributeId}, $args->{ldapAttributeContent} ], ); $ldap->unbind(); @@ -124,8 +138,8 @@ sub get_key_from_all_sessions { } else { foreach my $entry ( $msg->entries ) { - my $id = $entry->get_value('cn') or die; - my $tmp = $entry->get_value('description'); + my $id = $entry->get_value( $args->{ldapAttributeId} ) or die; + my $tmp = $entry->get_value( $args->{ldapAttributeContent} ); next unless ($tmp); eval { $tmp = unserialize($tmp); }; next if ($@); @@ -157,11 +171,15 @@ Apache::Session::Browseable::LDAP - An implementation of Apache::Session::LDAP use Apache::Session::Browseable::LDAP; tie %hash, 'Apache::Session::Browseable::LDAP', $id, { - ldapServer => 'ldap://localhost:389', - ldapConfBase => 'dmdName=applications,dc=example,dc=com', - ldapBindDN => 'cn=admin,dc=example,dc=com', - ldapBindPassword => 'pass', - Index => 'uid ipAddr', + ldapServer => 'ldap://localhost:389', + ldapConfBase => 'dmdName=applications,dc=example,dc=com', + ldapBindDN => 'cn=admin,dc=example,dc=com', + ldapBindPassword => 'pass', + Index => 'uid ipAddr', + ldapObjectClass => 'applicationProcess', + ldapAttributeId => 'cn', + ldapAttributeContent => 'description', + ldapAttributeIndex => 'ou', }; =head1 DESCRIPTION diff --git a/lib/Apache/Session/Browseable/Store/LDAP.pm b/lib/Apache/Session/Browseable/Store/LDAP.pm index a27c780..e434363 100644 --- a/lib/Apache/Session/Browseable/Store/LDAP.pm +++ b/lib/Apache/Session/Browseable/Store/LDAP.pm @@ -14,27 +14,36 @@ sub insert { my $self = shift; my $session = shift; $self->{args} = $session->{args}; + $self->{args}->{ldapObjectClass} ||= 'applicationProcess'; + $self->{args}->{ldapAttributeId} ||= 'cn'; + $self->{args}->{ldapAttributeContent} ||= 'description'; + $self->{args}->{ldapAttributeIndex} ||= 'ou'; + my $index = ref( $session->{args}->{Index} ) ? $session->{args}->{Index} : [ split /\s+/, $session->{args}->{Index} ]; my $id = $session->{data}->{_session_id}; - my $ou; + my $attrIndex; foreach my $i (@$index) { my $t; next unless ( $t = $session->{data}->{$i} ); - push @$ou, "${i}_$t"; + push @$attrIndex, "${i}_$t"; } my $attrs = [ - objectClass => [ 'top', 'applicationProcess' ], - cn => $session->{data}->{_session_id}, - description => $session->{serialized}, + objectClass => $self->{args}->{ldapObjectClass}, + $self->{args}->{ldapAttributeId} => $session->{data}->{_session_id}, + $self->{args}->{ldapAttributeContent} => $session->{serialized}, ]; - push @$attrs, ( ou => $ou ) if ($ou); + push @$attrs, ( $self->{args}->{ldapAttributeIndex} => $attrIndex ) + if ($attrIndex); - my $msg = $self->ldap->add( "cn=$id," . $self->{args}->{ldapConfBase}, - attrs => $attrs, ); + my $msg = $self->ldap->add( + $self->{args}->{ldapAttributeId} . "=$id," + . $self->{args}->{ldapConfBase}, + attrs => $attrs, + ); $self->ldap->unbind() && delete $self->{ldap}; $self->logError($msg) if ( $msg->code ); @@ -44,24 +53,35 @@ sub update { my $self = shift; my $session = shift; $self->{args} = $session->{args}; + $self->{args}->{ldapObjectClass} ||= 'applicationProcess'; + $self->{args}->{ldapAttributeId} ||= 'cn'; + $self->{args}->{ldapAttributeContent} ||= 'description'; + $self->{args}->{ldapAttributeIndex} ||= 'ou'; + my $index = ref( $session->{args}->{Index} ) ? $session->{args}->{Index} : [ split /\s+/, $session->{args}->{Index} ]; my $id = $session->{data}->{_session_id}; - my $ou; + my $attrIndex; foreach my $i (@$index) { my $t; next unless ( $t = $session->{data}->{$i} ); - push @$ou, "${i}_$t"; + push @$attrIndex, "${i}_$t"; } - my $attrs = { description => $session->{serialized} }; - $attrs->{ou} = $ou if ($ou); + + my $attrs = + { $self->{args}->{ldapAttributeContent} => $session->{serialized} }; + $attrs->{ $self->{args}->{ldapAttributeIndex} } = $attrIndex + if ($attrIndex); my $msg = $self->ldap->modify( - "cn=$session->{data}->{_session_id}," . $self->{args}->{ldapConfBase}, - replace => $attrs, ); + $self->{args}->{ldapAttributeId} . "=" + . $session->{data}->{_session_id} . "," + . $self->{args}->{ldapConfBase}, + replace => $attrs, + ); $self->ldap->unbind() && delete $self->{ldap}; $self->logError($msg) if ( $msg->code ); @@ -71,20 +91,26 @@ sub materialize { my $self = shift; my $session = shift; $self->{args} = $session->{args}; + $self->{args}->{ldapObjectClass} ||= 'applicationProcess'; + $self->{args}->{ldapAttributeId} ||= 'cn'; + $self->{args}->{ldapAttributeContent} ||= 'description'; + $self->{args}->{ldapAttributeIndex} ||= 'ou'; my $msg = $self->ldap->search( - base => "cn=$session->{data}->{_session_id}," + base => $self->{args}->{ldapAttributeId} . "=" + . $session->{data}->{_session_id} . "," . $self->{args}->{ldapConfBase}, - filter => '(objectClass=applicationProcess)', + filter => '(objectClass=' . $self->{args}->{ldapObjectClass} . ')', scope => 'base', - attrs => ['description'], + attrs => [ $self->{args}->{ldapAttributeContent} ], ); $self->ldap->unbind() && delete $self->{ldap}; $self->logError($msg) if ( $msg->code ); eval { - $session->{serialized} = $msg->shift_entry()->get_value('description'); + $session->{serialized} = $msg->shift_entry() + ->get_value( $self->{args}->{ldapAttributeContent} ); }; if ( !defined $session->{serialized} ) { @@ -96,9 +122,14 @@ sub remove { my $self = shift; my $session = shift; $self->{args} = $session->{args}; + $self->{args}->{ldapObjectClass} ||= 'applicationProcess'; + $self->{args}->{ldapAttributeId} ||= 'cn'; + $self->{args}->{ldapAttributeContent} ||= 'description'; + $self->{args}->{ldapAttributeIndex} ||= 'ou'; - $self->ldap->delete( - "cn=$session->{data}->{_session_id}," . $self->{args}->{ldapConfBase} ); + $self->ldap->delete( $self->{args}->{ldapAttributeId} . "=" + . $session->{data}->{_session_id} . "," + . $self->{args}->{ldapConfBase} ); $self->ldap->unbind() && delete $self->{ldap}; } @@ -192,15 +223,21 @@ objects are stored in an LDAP directory file using the Net::LDAP Perl module. This module requires one argument in the usual Apache::Session style. The keys ldapServer, ldapBase, ldapBindDN, ldapBindPassword are required. The key -ldapPort is optional. Example: +ldapPort, ldapObjectClass, ldapAttributeId, ldapAttributeContent, ldapAttributeIndex +are optional. +Example: tie %s, 'Apache::Session::Browseable::LDAP', undef, { - ldapServer => 'localhost', - ldapBase => 'dc=example,dc=com', - ldapBindDN => 'cn=admin,dc=example,dc=com', - ldapBindPassword => 'pass', - Index => 'uid ipAddr', + ldapServer => 'localhost', + ldapBase => 'dc=example,dc=com', + ldapBindDN => 'cn=admin,dc=example,dc=com', + ldapBindPassword => 'pass', + Index => 'uid ipAddr', + ldapObjectClass => 'applicationProcess', + ldapAttributeId => 'cn', + ldapAttributeContent => 'description', + ldapAttributeIndex => 'ou', }; =head1 AUTHOR