diff --git a/modules/lemonldap-ng-common/lemonldap-ng.ini b/modules/lemonldap-ng-common/lemonldap-ng.ini index f387de802..3767f4392 100644 --- a/modules/lemonldap-ng-common/lemonldap-ng.ini +++ b/modules/lemonldap-ng-common/lemonldap-ng.ini @@ -186,6 +186,7 @@ status = 0 ;useRedirectOnForbidden = 1 # Hide LemonLDAP::NG Handler in Apache Server Signature ;hideSignature = 1 +useRedirectOnError = 1 # Zimbra Handler parameters ;zimbraPreAuthKey = XXXX @@ -212,6 +213,11 @@ status = 0 # Use the following to modify error output: ;hideLogLevels = debug|info +[sessionsExplorer] +# Sessions explorer inherits from manager section. You can override here +# some parameters like 'protection' +;protection = authenticate + [apply] # URL used to reload configuration diff --git a/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/AuthBasic.pm b/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/AuthBasic.pm index c58afc67c..f45765096 100644 --- a/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/AuthBasic.pm +++ b/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/AuthBasic.pm @@ -82,12 +82,8 @@ sub run ($$) { # Catch SOAP errors if ( $r->fault ) { - $class->lmLog( - "SOAP request to the portal failed: " - . $r->fault->{faultstring}, - 'error' - ); - return SERVER_ERROR; + return $class->abort( "SOAP request to the portal failed: " + . $r->fault->{faultstring} ); } else { my $res = $r->result(); diff --git a/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/SharedConf.pm b/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/SharedConf.pm index 9e676eb80..01540c192 100644 --- a/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/SharedConf.pm +++ b/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/SharedConf.pm @@ -86,7 +86,7 @@ sub defaultValuesInit { # @return boolean sub localInit { my ( $class, $args ) = splice @_; - $class->abort( + die( "$class : unable to build configuration : $Lemonldap::NG::Common::Conf::msg" ) unless ( $lmConf = @@ -122,10 +122,8 @@ sub localInit { sub run($$) { my ( $class, $r ) = splice @_; if ( time() - $lastReload > $reloadTime ) { - unless ( my $tmp = $class->testConf(1) == OK ) { - $class->lmLog( "$class: No configuration found", 'error' ); - return SERVER_ERROR; - } + die( "$class: No configuration found" ) + unless ( $class->testConf(1) == OK ); } return $class->SUPER::run($r); } diff --git a/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Simple.pm b/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Simple.pm index 6ed97e0f6..636e9a0f1 100644 --- a/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Simple.pm +++ b/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Simple.pm @@ -47,6 +47,7 @@ our ( $customFunctions, $transform, $cda, $childInitDone, $httpOnly, $cookieExpiration, $timeoutActivity, $datasUpdate, $useRedirectOnForbidden, + $useRedirectOnError, ); ########################################## @@ -74,7 +75,8 @@ BEGIN { ], traces => [qw( $whatToTrace $statusPipe $statusOut)], apache => [ - qw( MP OK REDIRECT FORBIDDEN DONE DECLINED SERVER_ERROR useRedirectOnForbidden ) + qw( MP OK REDIRECT FORBIDDEN DONE DECLINED SERVER_ERROR + $useRedirectOnForbidden $useRedirectOnError ) ], post => [qw($transform)], cda => ['$cda'], @@ -140,6 +142,7 @@ BEGIN { threads::shared::share($statusOut); threads::shared::share($timeoutActivity); threads::shared::share($useRedirectOnForbidden); + threads::shared::share($useRedirectOnError); }; } elsif ( MP() == 1 ) { @@ -187,20 +190,34 @@ sub logout_mp2 : method { shift->unlog(@_); } +## @rmethod int abort(string mess) +# Logs message and exit or redirect to the portal if "useRedirectOnError" is +# set to true. +# @param $mess Message to log +# @return Apache2::Const::REDIRECT or Apache2::Const::SERVER_ERROR sub abort { my ( $class, $mess ) = splice @_; + + # If abort is called without a valid request, fall to die + eval { my $args = $apacheRequest->args; my $uri = $apacheRequest->uri . ( $args ? "?$args" : "" ); + + # Set error 500 in logs even if "useRedirectOnError" is set $apacheRequest->push_handlers( PerlLogHandler => sub { $_[0]->status(SERVER_ERROR); DECLINED; } ); $class->lmLog( $mess, 'error' ); - if ($useRedirectOnForbidden) { + + # Redirect or die + if ($useRedirectOnError) { $class->lmLog( "Use redirect for error", 'debug' ); return $class->goToPortal( $uri, 'lmError=500' ); } else { return SERVER_ERROR; } + }; + die $mess if ($@); } ## @rmethod void lmLog(string mess, string level) @@ -209,7 +226,7 @@ sub abort { # @param $level string (debug, info, warning or error) sub lmLog { my ( $class, $mess, $level ) = splice @_; - $class->abort("Level is required") unless ($level); + die("Level is required") unless ($level); my $call; unless ( $level eq 'debug' ) { my @tmp = caller(); @@ -485,7 +502,7 @@ sub childInit { sub purgeCache { my $class = shift; eval "use $localStorage;"; - $class->abort("Unable to load $localStorage: $@") if ($@); + die("Unable to load $localStorage: $@") if ($@); # At each Apache (re)start, we've to clear the cache to avoid living # with old datas @@ -665,6 +682,10 @@ sub defaultValuesInit { $httpOnly = defined($httpOnly) ? $httpOnly : $args->{httpOnly}; $cookieExpiration = $args->{cookieExpiration} || $cookieExpiration; $timeoutActivity = $args->{timeoutActivity} || $timeoutActivity || 0; + $useRedirectOnError = + defined($useRedirectOnError) + ? $useRedirectOnError + : $args->{useRedirectOnError}; $useRedirectOnForbidden = defined($useRedirectOnForbidden) ? $useRedirectOnForbidden @@ -677,7 +698,7 @@ sub defaultValuesInit { # @param $args reference to the configuration hash sub portalInit { my ( $class, $args ) = splice @_; - $class->abort("portal parameter required") unless ( $args->{portal} ); + die("portal parameter required") unless ( $args->{portal} ); if ( $args->{portal} =~ /[\$\(&\|"']/ ) { my $portal = $class->conditionSub( $args->{portal} ); eval "sub portal {return &\$portal}"; @@ -685,7 +706,7 @@ sub portalInit { else { eval "sub portal {return '$args->{portal}'}"; } - $class->abort("Unable to read portal parameter ($@)") if ($@); + die("Unable to read portal parameter ($@)") if ($@); 1; } @@ -695,9 +716,9 @@ sub portalInit { sub globalStorageInit { my ( $class, $args ) = splice @_; $globalStorage = $args->{globalStorage} - or $class->abort("globalStorage required"); + or die("globalStorage required"); eval "use $globalStorage;"; - $class->abort($@) if ($@); + die($@) if ($@); $globalStorageOptions = $args->{globalStorageOptions}; } @@ -1274,10 +1295,8 @@ sub redirectFilter { sub status($$) { my ( $class, $r ) = splice @_; $class->lmLog( "$class: request for status", 'debug' ); - unless ( $statusPipe and $statusOut ) { - $class->lmLog( "$class: status page can not be displayed", 'error' ); - return SERVER_ERROR; - } + return $class->abort("$class: status page can not be displayed") + unless ( $statusPipe and $statusOut ); $r->handler("perl-script"); print $statusPipe "STATUS" . ( $r->args ? " " . $r->args : '' ) . "\n"; my $buf; diff --git a/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/SympaAutoLogin.pm b/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/SympaAutoLogin.pm index 041f41227..09cabc9cd 100644 --- a/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/SympaAutoLogin.pm +++ b/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/SympaAutoLogin.pm @@ -29,7 +29,7 @@ sub defaultValuesInit { # If not, try to read it from /etc/lemonldap-ng/sympa.secret if ( !$sympaSecret and -r '/etc/lemonldap-ng/sympa.secret' ) { open S, '/etc/lemonldap-ng/sympa.secret' - or $class->abort("Unable to open /etc/lemonldap-ng/sympa.secret"); + or die("Unable to open /etc/lemonldap-ng/sympa.secret"); $sympaSecret = join( '', ); close S; $sympaSecret =~ s/[\r\n]//g; @@ -63,10 +63,8 @@ sub run { return $ret unless ( $ret == OK ); # Fail if no sympaSecret - unless ($sympaSecret) { - $class->lmLog( "No Sympa secret configured", 'error' ); - return SERVER_ERROR; - } + return $class->abort("No Sympa secret configured") + unless ($sympaSecret); # Mail value my $mail = $datas->{$sympaMailKey}; diff --git a/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/ZimbraPreAuth.pm b/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/ZimbraPreAuth.pm index 1fc936645..714a7dd3f 100644 --- a/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/ZimbraPreAuth.pm +++ b/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/ZimbraPreAuth.pm @@ -75,10 +75,8 @@ sub run { return OK unless ( $uri =~ $zimbraSsoUrl ); # Check mandatory parameters - unless ($zimbraPreAuthKey) { - $class->lmLog( "No Zimbra preauth key configured", 'error' ); - return SERVER_ERROR; - } + return $class->abort("No Zimbra preauth key configured"); + unless ($zimbraPreAuthKey); # Build URL my $zimbra_url = $class->_buildZimbraPreAuthUrl( diff --git a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_Struct.pm b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_Struct.pm index 1f1c51dcf..c5815410d 100644 --- a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_Struct.pm +++ b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_Struct.pm @@ -730,10 +730,13 @@ sub struct { }, redirection => { - _nodes => [qw(https port useRedirectOnForbidden)], + _nodes => [ + qw(https port useRedirectOnForbidden useRedirectOnError) + ], https => 'bool:/https', port => 'int:/port', useRedirectOnForbidden => 'bool:/useRedirectOnForbidden', + useRedirectOnError => 'bool:/useRedirectOnError', }, specialHandlers => { @@ -1390,6 +1393,7 @@ sub testStruct { test => qr/^[a-zA-Z][\w\:]*$/, msgFail => 'Bad module name', }, + useRedirectOnError => $boolean, useRedirectOnForbidden => $boolean, useXForwardedForIP => $boolean, variables => $testNotDefined, @@ -1696,6 +1700,7 @@ sub defaultConf { userControl => '^[\w\.\-@]+$', userDB => 'LDAP', passwordDB => 'LDAP', + useRedirectOnError => '1', useRedirectOnForbidden => '0', useXForwardedForIP => '0', vhostPort => '-1', diff --git a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_i18n.pm b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_i18n.pm index da9d4aa46..459326638 100644 --- a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_i18n.pm +++ b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_i18n.pm @@ -290,6 +290,7 @@ sub en { userDB => 'Users module', userControl => 'Username control', userPivot => 'Login field name in user table', + useRedirectOnError => 'Redirect on handler error', useRedirectOnForbidden => 'Redirect on forbidden', useXForwardedForIP => "Use X-Forwarded-For header address", variables => "Variables", @@ -671,6 +672,7 @@ sub fr { userDB => "Module d'utilisateurs", userControl => "Contrôle du nom d'utilisateur", userPivot => 'Champ identifiant dans la table des utilisateurs', + useRedirectOnError => 'Redirection pour les erreurs d\'agent', useRedirectOnForbidden => 'Redirection pour les accès interdits', useXForwardedForIP => "Utiliser l'adresse IP de l'en-tête X-Forwarded-For",