Wie greift man richtig über SSL auf einen Openldap-Server zu?

Hallo, im Wiki (http://wiki.otrs.org/index.php?title=LDAP_mit_TLS_bzw._SSL) steht dass man das Modul Kernel::System::Auth::LDAP nach Kernel::System::Auth::LDAPS kopieren soll. Ist doch so gemeint oder? cp LDAP.pm LDAPS.pm Dann steht:Im Perl Modul LDAP durch LDAPS ersetzen Ist doch so gemeint oder? # -- # Kernel/System/Auth/LDAPS.pm - provides the LDAPS authentication # Copyright (C) 2001-2010 OTRS AG, http://otrs.org/ # -- # $Id: LDAPS.pm,v 1.58 2010/03/25 14:42:45 martin Exp $ # -- # This software comes with ABSOLUTELY NO WARRANTY. For details, see # the enclosed file COPYING for license information (AGPL). If you # did not receive this file, see http://www.gnu.org/licenses/agpl.txt. # -- package Kernel::System::Auth::LDAPS; use strict; use warnings; use Net::LDAPS; use vars qw($VERSION); $VERSION = qw($Revision: 1.58 $) [1]; sub new { my ( $Type, %Param ) = @_; # allocate new hash for object my $Self = {}; bless( $Self, $Type ); # check needed objects for (qw(LogObject ConfigObject DBObject UserObject GroupObject EncodeObject)) { $Self->{$_} = $Param{$_} || die "No $_!"; } # Debug 0=off 1=on $Self->{Debug} = 0; # get LDAPS preferences $Self->{Count} = $Param{Count} || ''; $Self->{Die} = $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::Die' . $Param{Count} ); if ( $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::Host' . $Param{Count} ) ) { $Self->{Host} = $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::Host' . $Param{Count} ); } else { $Self->{LogObject}->Log( Priority => 'error', Message => "Need AuthModule::LDAPS::Host$Param{Count} in Kernel/Config.pm", ); return; } if ( defined( $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::BaseDN' . $Param{Count} ) ) ) { $Self->{BaseDN} = $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::BaseDN' . $Param{Count} ); } else { $Self->{LogObject}->Log( Priority => 'error', Message => "Need AuthModule::LDAPS::BaseDN$Param{Count} in Kernel/Config.pm", ); return; } if ( $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::UID' . $Param{Count} ) ) { $Self->{UID} = $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::UID' . $Param{Count} ); } else { $Self->{LogObject}->Log( Priority => 'error', Message => "Need AuthModule::LDAPS::UID$Param{Count} in Kernel/Config.pm", ); return; } $Self->{SearchUserDN} = $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::SearchUserDN' . $Param{Count} ) || ''; $Self->{SearchUserPw} = $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::SearchUserPw' . $Param{Count} ) || ''; $Self->{GroupDN} = $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::GroupDN' . $Param{Count} ) || ''; $Self->{AccessAttr} = $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::AccessAttr' . $Param{Count} ) || 'memberUid'; $Self->{UserAttr} = $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::UserAttr' . $Param{Count} ) || 'DN'; $Self->{UserSuffix} = $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::UserSuffix' . $Param{Count} ) || ''; $Self->{UserLowerCase} = $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::UserLowerCase' . $Param{Count} ) || 0; $Self->{DestCharset} = $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::Charset' . $Param{Count} ) || 'utf-8'; # LDAPS filter always used $Self->{AlwaysFilter} = $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::AlwaysFilter' . $Param{Count} ) || ''; # Net::LDAPS new params if ( $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::Params' . $Param{Count} ) ) { $Self->{Params} = $Self->{ConfigObject}->Get( 'AuthModule::LDAPS::Params' . $Param{Count} ); } else { $Self->{Params} = {}; } return $Self; } sub GetOption { my ( $Self, %Param ) = @_; # check needed stuff if ( !$Param{What} ) { $Self->{LogObject}->Log( Priority => 'error', Message => "Need What!" ); return; } # module options my %Option = ( PreAuth => 0, ); # return option return $Option{ $Param{What} }; } sub Auth { my ( $Self, %Param ) = @_; # check needed stuff for (qw(User Pw)) { if ( !$Param{$_} ) { $Self->{LogObject}->Log( Priority => 'error', Message => "Need $_!" ); return; } } $Param{User} = $Self->_ConvertTo( $Param{User}, $Self->{ConfigObject}->Get('DefaultCharset') ); $Param{Pw} = $Self->_ConvertTo( $Param{Pw}, $Self->{ConfigObject}->Get('DefaultCharset') ); # get params my $RemoteAddr = $ENV{REMOTE_ADDR} || 'Got no REMOTE_ADDR env!'; # remove leading and trailing spaces $Param{User} =~ s/^\s+//; $Param{User} =~ s/\s+$//; # Convert username to lower case letters if ( $Self->{UserLowerCase} ) { $Param{User} = lc $Param{User}; } # add user suffix if ( $Self->{UserSuffix} ) { $Param{User} .= $Self->{UserSuffix}; # just in case for debug if ( $Self->{Debug} > 0 ) { $Self->{LogObject}->Log( Priority => 'notice', Message => "User: ($Param{User}) added $Self->{UserSuffix} to username!", ); } } # just in case for debug! if ( $Self->{Debug} > 0 ) { $Self->{LogObject}->Log( Priority => 'notice', Message => "User: '$Param{User}' tried to authenticate with Pw: '$Param{Pw}' " . "(REMOTE_ADDR: $RemoteAddr)", ); } # LDAPS connect and bind (maybe with SearchUserDN and SearchUserPw) my $LDAPS = Net::LDAPS->new( $Self->{Host}, %{ $Self->{Params} } ); if ( !$LDAPS ) { if ( $Self->{Die} ) { die "Can't connect to $Self->{Host}: $@"; } else { $Self->{LogObject}->Log( Priority => 'error', Message => "Can't connect to $Self->{Host}: $@", ); return; } } my $Result = ''; if ( $Self->{SearchUserDN} && $Self->{SearchUserPw} ) { $Result = $LDAPS->bind( dn => $Self->{SearchUserDN}, password => $Self->{SearchUserPw} ); } else { $Result = $LDAPS->bind(); } if ( $Result->code ) { $Self->{LogObject}->Log( Priority => 'error', Message => 'First bind failed! ' . $Result->error(), ); $LDAPS->disconnect; return; } # user quote my $UserQuote = $Param{User}; $UserQuote =~ s/\\/\\\\/g; $UserQuote =~ s/\(/\\(/g; $UserQuote =~ s/\)/\\)/g; # build filter my $Filter = "($Self->{UID}=$UserQuote)"; # prepare filter if ( $Self->{AlwaysFilter} ) { $Filter = "(&$Filter$Self->{AlwaysFilter})"; } # perform user search $Result = $LDAPS->search( base => $Self->{BaseDN}, filter => $Filter, ); if ( $Result->code ) { $Self->{LogObject}->Log( Priority => 'error', Message => 'Search failed! ' . $Result->error, ); $LDAPS->unbind; $LDAPS->disconnect; return; } # get whole user dn my $UserDN = ''; for my $Entry ( $Result->all_entries ) { $UserDN = $Entry->dn(); } # log if there is no LDAPS user entry if ( !$UserDN ) { # failed login note $Self->{LogObject}->Log( Priority => 'notice', Message => "User: $Param{User} authentication failed, no LDAPS entry found!" . "BaseDN='$Self->{BaseDN}', Filter='$Filter', (REMOTE_ADDR: $RemoteAddr).", ); # take down session $LDAPS->unbind; $LDAPS->disconnect; return; } # DN quote my $UserDNQuote = $UserDN; $UserDNQuote =~ s/\\/\\\\/g; $UserDNQuote =~ s/\(/\\(/g; $UserDNQuote =~ s/\)/\\)/g; # check if user need to be in a group! if ( $Self->{AccessAttr} && $Self->{GroupDN} ) { # just in case for debug if ( $Self->{Debug} > 0 ) { $Self->{LogObject}->Log( Priority => 'notice', Message => 'check for groupdn!', ); } # search if we're allowed to my $Filter2 = ''; if ( $Self->{UserAttr} eq 'DN' ) { $Filter2 = "($Self->{AccessAttr}=$UserDNQuote)"; } else { $Filter2 = "($Self->{AccessAttr}=$UserQuote)"; } my $Result2 = $LDAPS->search( base => $Self->{GroupDN}, filter => $Filter2, ); if ( $Result2->code ) { $Self->{LogObject}->Log( Priority => 'error', Message => "Search failed! base='$Self->{GroupDN}', filter='$Filter2', " . $Result->error, ); # take down session $LDAPS->unbind; $LDAPS->disconnect; return; } # extract it my $GroupDN = ''; for my $Entry ( $Result2->all_entries ) { $GroupDN = $Entry->dn(); } # log if there is no LDAPS entry if ( !$GroupDN ) { # failed login note $Self->{LogObject}->Log( Priority => 'notice', Message => "User: $Param{User} authentication failed, no LDAPS group entry found" . "GroupDN='$Self->{GroupDN}', Filter='$Filter2'! (REMOTE_ADDR: $RemoteAddr).", ); # take down session $LDAPS->unbind; $LDAPS->disconnect; return; } } # bind with user data -> real user auth. $Result = $LDAPS->bind( dn => $UserDN, password => $Param{Pw} ); if ( $Result->code ) { # failed login note $Self->{LogObject}->Log( Priority => 'notice', Message => "User: $Param{User} ($UserDN) authentication failed: '" . $Result->error() . "' (REMOTE_ADDR: $RemoteAddr).", ); # take down session $LDAPS->unbind; $LDAPS->disconnect; return; } # maybe check if pw is expired # if () { # $Self->{LogObject}->Log( # Priority => 'info', # Message => "Password is expired!", # ); # return; # } # login note $Self->{LogObject}->Log( Priority => 'notice', Message => "User: $Param{User} ($UserDN) authentication ok (REMOTE_ADDR: $RemoteAddr).", ); # take down session $LDAPS->unbind; $LDAPS->disconnect; return $Param{User}; } sub _ConvertTo { my ( $Self, $Text, $Charset ) = @_; return if !defined $Text; if ( !$Charset || !$Self->{DestCharset} ) { $Self->{EncodeObject}->EncodeInput( \$Text ); return $Text; } # convert from input charset ($Charset) to directory charset ($Self->{DestCharset}) return $Self->{EncodeObject}->Convert( Text => $Text, From => $Charset, To => $Self->{DestCharset}, ); } sub _ConvertFrom { my ( $Self, $Text, $Charset ) = @_; return if !defined $Text; if ( !$Charset || !$Self->{DestCharset} ) { $Self->{EncodeObject}->EncodeInput( \$Text ); return $Text; } # convert from directory charset ($Self->{DestCharset}) to input charset ($Charset) return $Self->{EncodeObject}->Convert( Text => $Text, From => $Self->{DestCharset}, To => $Charset, ); } 1; Dann soll man ind der Config.pm die Anbindung an LDAP so vornehmen: Beispiel 11.7. Agentenauthentifizierung gegen ein LDAP Backend # This is an example configuration for an LDAP auth. backend. # (Make sure Net::LDAPS is installed!) $Self->{'AuthModule'} = 'Kernel::System::Auth::LDAPS'; $Self->{'AuthModule::LDAPS::Host'} = 'xxx.xxx.xxx.xxx'; $Self->{'AuthModule::LDAPS::BaseDN'} = 'o=xx xx,c=DE'; $Self->{'AuthModule::LDAPS::UID'} = 'uid'; # Check if the user is allowed to auth in a posixGroup # (e. g. user needs to be in a group xyz to use otrs) $Self->{'AuthModule::LDAPS::GroupDN'} = 'cn=otrsagenten,ou=groups,o=Universitaet,c=DE'; $Self->{'AuthModule::LDAPS::AccessAttr'} = 'memberUid'; # for ldap posixGroups objectclass (just uid) # $Self->{'AuthModule::LDAPS::UserAttr'} = 'UID'; # for non ldap posixGroups objectclass (with full user dn) # $Self->{'AuthModule::LDAPS::UserAttr'} = 'DN'; # The following is valid but would only be necessary if the # anonymous user do NOT have permission to read from the LDAP tree $Self->{'AuthModule::LDAPS::SearchUserDN'} = 'cn=searchuser,ou=xxx,o=Universitaet,c=DE'; $Self->{'AuthModule::LDAPS::SearchUserPw'} = 'xxx'; # in case you want to add always one filter to each ldap query, use # this option. e. g. AlwaysFilter => '(mail=*)' or AlwaysFilter => '(objectclass=user)' $Self->{'AuthModule::LDAPS::AlwaysFilter'} = ''; # in case you want to add a suffix to each login name, then # you can use this option. e. g. user just want to use user but # in your ldap directory exists user@domain. # $Self->{'AuthModule::LDAPS::UserSuffix'} = '@domain.com'; # Net::LDAP new params (if needed - for more info see perldoc Net::LDAPS) $Self->{'AuthModule::LDAPS::Params'} = { port => 63651, timeout => 120, async => 0, version => 3, }; Leider funkioniert das so nicht: Can't locate Net/LDAPS.pm in @INC (@INC contains: ../../ /opt/otrs/bin/cgi-bin/../../Kernel/cpan-lib /opt/otrs/bin/cgi-bin/../.. /usr/lib/perl5/5.10.0/x86_64-linux-thread-multi /usr/lib/perl5/5.10.0 /usr/lib/perl5/site_perl/5.10.0/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.10.0 /usr/lib/perl5/vendor_perl/5.10.0/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.10.0 /usr/lib/perl5/vendor_perl . /opt/otrs/bin/cgi-bin/../.. /opt/otrs/bin/cgi-bin/../../Kernel/cpan-lib) at ../..//Kernel/System/Auth/LDAPS.pm line 16. BEGIN failed--compilation aborted at ../..//Kernel/System/Auth/LDAPS.pm line 16. Irgendwie kann er mit LDAPS noch nicht anfangen. Es gibt ja auch kein perl-ldaps Welche Module müssen installiert sein? Hat jemand eine Schritt für Schritt-Anleitung um eine LDAPS-Anbindung einzurichten. Hoffe auf Tipps und Tricks!! DANKE schon mal.

Hallo, mir ist nicht ganz klar warum man das Modul kopieren sollte ... Naja, ich würde es mal mit ldaps:// als Referer versuchen, hat denn nicht geklappt? Cheers, Nils On 21.02.2011, at 14:38, Ukohfink wrote:
im Wiki (http://wiki.otrs.org/index.php?title=LDAP_mit_TLS_bzw._SSL) steht dass man das Modul Kernel::System::Auth::LDAP nach Kernel::System::Auth::LDAPS kopieren soll. Ist doch so gemeint oder? cp LDAP.pm LDAPS.pm
— Nils Leideck Senior Consultant http://webint.cryptonode.de / a Fractal project
participants (2)
-
Nils Leideck
-
Ukohfink