2007-05-01 16:53:26 +02:00
|
|
|
#!/usr/bin/perl
|
2010-04-09 17:43:21 +02:00
|
|
|
#=============================================================================
|
|
|
|
# Cleaner for LemonLDAP::NG: removes old sessions from Apache::Session
|
2007-05-01 16:53:26 +02:00
|
|
|
#
|
|
|
|
# This module is written to be used by cron to clean old sessions from
|
2010-04-09 17:43:21 +02:00
|
|
|
# Apache::Session. It does not works with Apache::Session::Memcached
|
|
|
|
#
|
|
|
|
# This is part of LemonLDAP::NG product, released under GPL
|
|
|
|
#=============================================================================
|
2007-05-01 16:53:26 +02:00
|
|
|
|
2008-11-17 17:59:56 +01:00
|
|
|
use Lemonldap::NG::Common::Conf;
|
|
|
|
use Lemonldap::NG::Common::Conf::Constants;
|
2008-12-01 18:21:34 +01:00
|
|
|
use Lemonldap::NG::Common::Apache::Session;
|
2014-04-25 10:20:00 +02:00
|
|
|
use Lemonldap::NG::Common::Session;
|
2007-05-01 16:53:26 +02:00
|
|
|
use strict;
|
2012-10-30 15:21:02 +01:00
|
|
|
use Getopt::Std;
|
2007-05-01 16:53:26 +02:00
|
|
|
|
2012-10-30 16:22:36 +01:00
|
|
|
# Options
|
|
|
|
# -d: debug mode
|
|
|
|
# -f: force delete of corrupted sessions
|
2012-10-30 15:21:02 +01:00
|
|
|
our $opt_d;
|
2012-10-30 16:22:36 +01:00
|
|
|
our $opt_f;
|
|
|
|
getopts('df');
|
2012-10-30 15:21:02 +01:00
|
|
|
|
|
|
|
my $debug = $opt_d;
|
2012-10-30 16:22:36 +01:00
|
|
|
my $force = $opt_f;
|
2010-04-09 17:43:21 +02:00
|
|
|
my $nb_purged = 0;
|
2012-10-30 16:22:36 +01:00
|
|
|
my $nb_error = 0;
|
2007-05-01 16:53:26 +02:00
|
|
|
|
2010-04-09 17:43:21 +02:00
|
|
|
#=============================================================================
|
|
|
|
# Load configuration
|
|
|
|
#=============================================================================
|
2010-10-08 21:19:59 +02:00
|
|
|
my $lmconf = Lemonldap::NG::Common::Conf->new()
|
|
|
|
or die $Lemonldap::NG::Common::Conf::msg;
|
2007-05-01 16:53:26 +02:00
|
|
|
my $conf = $lmconf->getConf or die "Unable to get configuration ($!)";
|
2010-04-09 17:43:21 +02:00
|
|
|
my $localconf = $lmconf->getLocalConf(PORTALSECTION)
|
|
|
|
or die "Unable to get local configuration ($!)";
|
2007-05-01 16:53:26 +02:00
|
|
|
|
2010-04-09 17:43:21 +02:00
|
|
|
if ($localconf) {
|
|
|
|
$conf->{$_} = $localconf->{$_} foreach ( keys %$localconf );
|
|
|
|
}
|
2007-05-01 16:53:26 +02:00
|
|
|
|
2010-04-09 17:43:21 +02:00
|
|
|
print "Configuration loaded\n" if $debug;
|
2007-05-01 16:53:26 +02:00
|
|
|
|
2010-04-09 17:43:21 +02:00
|
|
|
#=============================================================================
|
|
|
|
# Timeout
|
|
|
|
#=============================================================================
|
2011-06-09 16:26:51 +02:00
|
|
|
print "Timeout value: " . $conf->{timeout} . "\n" if $debug;
|
2010-04-09 17:43:21 +02:00
|
|
|
|
|
|
|
#=============================================================================
|
|
|
|
# Apache::Session backends
|
|
|
|
#=============================================================================
|
|
|
|
my @backends;
|
|
|
|
my $module;
|
|
|
|
|
|
|
|
# Sessions
|
2012-09-03 20:56:39 +02:00
|
|
|
if ( defined $conf->{globalStorage} ) {
|
2010-04-09 17:43:21 +02:00
|
|
|
|
|
|
|
# Load module
|
|
|
|
$module = $conf->{globalStorage};
|
|
|
|
eval "use $module";
|
|
|
|
die $@ if ($@);
|
2010-11-01 10:15:59 +01:00
|
|
|
$conf->{globalStorageOptions}->{backend} = $module;
|
2010-04-09 17:43:21 +02:00
|
|
|
|
|
|
|
# Add module in managed backends
|
2012-09-03 20:56:39 +02:00
|
|
|
push @backends, $conf->{globalStorageOptions};
|
2010-04-09 17:43:21 +02:00
|
|
|
|
|
|
|
print "Session backend $module will be used\n" if $debug;
|
|
|
|
}
|
|
|
|
|
|
|
|
# SAML
|
2012-10-30 15:21:02 +01:00
|
|
|
if ( defined $conf->{samlStorage}
|
2012-09-03 20:56:39 +02:00
|
|
|
or keys %{ $conf->{samlStorageOptions} } )
|
2010-04-09 17:43:21 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
# Load module
|
2012-09-03 20:56:39 +02:00
|
|
|
$module = $conf->{samlStorage} || $conf->{globalStorage};
|
2010-04-09 17:43:21 +02:00
|
|
|
eval "use $module";
|
|
|
|
die $@ if ($@);
|
2010-11-01 10:15:59 +01:00
|
|
|
$conf->{samlStorageOptions}->{backend} = $module;
|
2010-04-09 17:43:21 +02:00
|
|
|
|
|
|
|
# Add module in managed backends
|
2012-09-03 20:56:39 +02:00
|
|
|
push @backends, $conf->{samlStorageOptions};
|
2010-04-09 17:43:21 +02:00
|
|
|
|
|
|
|
print "SAML backend $module will be used\n" if $debug;
|
|
|
|
}
|
|
|
|
|
2014-04-25 10:20:00 +02:00
|
|
|
# CAS
|
|
|
|
if ( defined $conf->{casStorage}
|
|
|
|
or keys %{ $conf->{casStorageOptions} } )
|
|
|
|
{
|
|
|
|
|
|
|
|
# Load module
|
|
|
|
$module = $conf->{casStorage} || $conf->{globalStorage};
|
|
|
|
eval "use $module";
|
|
|
|
die $@ if ($@);
|
|
|
|
$conf->{casStorageOptions}->{backend} = $module;
|
|
|
|
|
|
|
|
# Add module in managed backends
|
|
|
|
push @backends, $conf->{casStorageOptions};
|
|
|
|
|
|
|
|
print "CAS backend $module will be used\n" if $debug;
|
|
|
|
}
|
|
|
|
|
2014-06-11 12:22:34 +02:00
|
|
|
# Captcha
|
|
|
|
if ( defined $conf->{captchaStorage}
|
|
|
|
or keys %{ $conf->{captchaStorageOptions} } )
|
|
|
|
{
|
|
|
|
|
|
|
|
# Load module
|
|
|
|
$module = $conf->{captchaStorage} || $conf->{globalStorage};
|
|
|
|
eval "use $module";
|
|
|
|
die $@ if ($@);
|
|
|
|
$conf->{captchaStorageOptions}->{backend} = $module;
|
|
|
|
|
|
|
|
# Add module in managed backends
|
|
|
|
push @backends, $conf->{captchaStorageOptions};
|
|
|
|
|
|
|
|
print "Captcha backend $module will be used\n" if $debug;
|
|
|
|
}
|
|
|
|
|
2015-03-11 12:39:20 +01:00
|
|
|
# OpenIDConnect
|
|
|
|
if ( defined $conf->{oidcStorage}
|
|
|
|
or keys %{ $conf->{oidcStorageOptions} } )
|
|
|
|
{
|
|
|
|
|
|
|
|
# Load module
|
|
|
|
$module = $conf->{oidcStorage} || $conf->{globalStorage};
|
|
|
|
eval "use $module";
|
|
|
|
die $@ if ($@);
|
|
|
|
$conf->{oidcStorageOptions}->{backend} = $module;
|
|
|
|
|
|
|
|
# Add module in managed backends
|
|
|
|
push @backends, $conf->{oidcStorageOptions};
|
|
|
|
|
|
|
|
print "OIDC backend $module will be used\n" if $debug;
|
|
|
|
}
|
|
|
|
|
2010-04-09 17:43:21 +02:00
|
|
|
#=============================================================================
|
|
|
|
# Load and purge sessions
|
|
|
|
#=============================================================================
|
2012-09-03 20:56:39 +02:00
|
|
|
for my $options (@backends) {
|
2010-04-09 17:43:21 +02:00
|
|
|
|
2012-09-03 20:56:39 +02:00
|
|
|
next if ( $options->{backend} eq "Apache::Session::Memcached" );
|
2010-04-09 17:43:21 +02:00
|
|
|
my @t;
|
2017-04-03 07:02:25 +02:00
|
|
|
if ( $options->{backend}->can('deleteIfLowerThan') ) {
|
|
|
|
next
|
|
|
|
if $options->{backend}->deleteIfLowerThan(
|
|
|
|
$options,
|
|
|
|
{
|
|
|
|
not => { '_session_kind' => 'Persistent' },
|
|
|
|
or => {
|
|
|
|
_utime => time - $conf->{timeout},
|
|
|
|
(
|
|
|
|
$conf->{timeoutActivity}
|
|
|
|
? ( _lastSeen => time - $conf->{timeoutActivity} )
|
|
|
|
: ()
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
2010-04-09 17:43:21 +02:00
|
|
|
|
|
|
|
# Get all expired sessions
|
2012-09-03 20:56:39 +02:00
|
|
|
Lemonldap::NG::Common::Apache::Session->get_key_from_all_sessions(
|
2010-04-09 17:43:21 +02:00
|
|
|
$options,
|
2011-06-09 16:26:51 +02:00
|
|
|
sub {
|
|
|
|
my $entry = shift;
|
|
|
|
my $id = shift;
|
|
|
|
my $time = time;
|
|
|
|
|
2012-10-30 15:21:02 +01:00
|
|
|
print "Check session $id\n" if $debug;
|
|
|
|
|
2012-10-30 16:22:36 +01:00
|
|
|
# Empty session need to be removed
|
|
|
|
unless ($entry) {
|
|
|
|
push @t, $id;
|
|
|
|
print "Session $id is empty (corrupted?), delete forced\n"
|
|
|
|
if $debug;
|
|
|
|
}
|
|
|
|
|
2011-06-09 16:26:51 +02:00
|
|
|
# Do net check sessions without _utime
|
|
|
|
return undef unless $entry->{_utime};
|
|
|
|
|
2016-01-20 10:33:28 +01:00
|
|
|
# Do not expire persistent sessions
|
|
|
|
return undef if ( $entry->{_session_kind} eq "Persistent" );
|
|
|
|
|
2010-05-07 12:00:55 +02:00
|
|
|
# Session expired
|
|
|
|
if ( $time - $entry->{_utime} > $conf->{timeout} ) {
|
|
|
|
push @t, $id;
|
2011-06-29 11:47:11 +02:00
|
|
|
print "Session $id expired\n" if $debug;
|
2010-05-07 12:00:55 +02:00
|
|
|
}
|
2011-06-09 16:26:51 +02:00
|
|
|
|
2010-05-07 12:00:55 +02:00
|
|
|
# User has no activity, so considere the session has expired
|
2011-06-09 16:26:51 +02:00
|
|
|
elsif ( $conf->{timeoutActivity}
|
|
|
|
and $entry->{_lastSeen}
|
2010-05-07 12:00:55 +02:00
|
|
|
and $time - $entry->{_lastSeen} > $conf->{timeoutActivity} )
|
|
|
|
{
|
2011-06-09 16:26:51 +02:00
|
|
|
push @t, $id;
|
2011-06-29 11:47:11 +02:00
|
|
|
print "Session $id inactive\n" if $debug;
|
2010-05-07 12:00:55 +02:00
|
|
|
}
|
2011-06-09 16:26:51 +02:00
|
|
|
undef;
|
|
|
|
}
|
2010-04-09 17:43:21 +02:00
|
|
|
);
|
2007-05-01 16:53:26 +02:00
|
|
|
|
2010-04-09 17:43:21 +02:00
|
|
|
# Delete sessions
|
2012-10-30 16:22:36 +01:00
|
|
|
my @errors;
|
2010-04-09 17:43:21 +02:00
|
|
|
for my $id (@t) {
|
2014-04-25 10:20:00 +02:00
|
|
|
|
|
|
|
my $session = Lemonldap::NG::Common::Session->new(
|
|
|
|
storageModule => $options->{backend},
|
|
|
|
storageModuleOptions => $options,
|
|
|
|
cacheModule => $conf->{localSessionStorage},
|
|
|
|
cacheModuleOptions => $conf->{localSessionStorageOptions},
|
|
|
|
id => $id,
|
|
|
|
);
|
|
|
|
|
|
|
|
unless ( $session->data ) {
|
|
|
|
print "Error while opening session $id\n" if $debug;
|
2012-10-30 16:22:36 +01:00
|
|
|
print STDERR "Error on session $id\n";
|
|
|
|
$nb_error++;
|
|
|
|
push @errors, $id;
|
2011-06-29 11:47:11 +02:00
|
|
|
next;
|
|
|
|
}
|
2014-04-25 10:20:00 +02:00
|
|
|
|
|
|
|
unless ( $session->remove ) {
|
|
|
|
print "Error while deleting session $id\n" if $debug;
|
2012-10-30 16:22:36 +01:00
|
|
|
print STDERR "Error on session $id\n";
|
|
|
|
$nb_error++;
|
|
|
|
push @errors, $id;
|
2011-06-09 16:26:51 +02:00
|
|
|
next;
|
|
|
|
}
|
2010-04-09 17:43:21 +02:00
|
|
|
print "Session $id has been purged\n" if $debug;
|
2011-06-09 16:26:51 +02:00
|
|
|
$nb_purged++;
|
2010-04-09 17:43:21 +02:00
|
|
|
}
|
2007-05-01 16:53:26 +02:00
|
|
|
|
2010-04-09 17:43:21 +02:00
|
|
|
# Remove lock files for File backend
|
2010-11-01 10:15:59 +01:00
|
|
|
if ( $options->{backend} =~ /^Apache::Session::(?:Browseable::)?File$/i ) {
|
2011-06-09 16:26:51 +02:00
|
|
|
require Apache::Session::Lock::File;
|
|
|
|
my $l = new Apache::Session::Lock::File;
|
|
|
|
my $lock_directory = $options->{LockDirectory} || $options->{Directory};
|
2010-04-09 17:43:21 +02:00
|
|
|
$l->clean( $lock_directory, $conf->{timeout} );
|
|
|
|
}
|
2012-10-30 16:22:36 +01:00
|
|
|
|
|
|
|
# Force deletion of corrupted sessions for File backend
|
|
|
|
if ( $options->{backend} =~ /^Apache::Session::(?:Browseable::)?File$/i
|
|
|
|
and $force )
|
|
|
|
{
|
|
|
|
foreach (@errors) {
|
|
|
|
my $id = $_;
|
|
|
|
eval { unlink $options->{Directory} . "/$id"; };
|
|
|
|
if ($@) {
|
|
|
|
print STDERR "Unable to remove session $id\n";
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
print STDERR "Session $id removed with force\n";
|
|
|
|
$nb_error--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-10-30 18:27:36 +01:00
|
|
|
}
|
|
|
|
|
2010-04-09 17:43:21 +02:00
|
|
|
#=============================================================================
|
2012-10-30 16:22:36 +01:00
|
|
|
# Exit
|
2010-04-09 17:43:21 +02:00
|
|
|
#=============================================================================
|
|
|
|
print "$nb_purged sessions have been purged\n" if $debug;
|
2012-10-30 16:22:36 +01:00
|
|
|
print STDERR
|
|
|
|
"$nb_error sessions remaining, try to purge them with force (option -f)\n"
|
|
|
|
if $nb_error;
|
|
|
|
|
|
|
|
my $exit = $nb_error ? 1 : 0;
|
|
|
|
exit $exit;
|