From 7a04829a08c49e2fbba87f3e91532dd1b61b47ea Mon Sep 17 00:00:00 2001 From: Xavier Guimard Date: Wed, 21 Oct 2009 12:43:13 +0000 Subject: [PATCH] New portal parameters : singleIP and singleSession --- modules/lemonldap-ng-common/MANIFEST | 1 + .../lib/Lemonldap/NG/Common/Apache/Session.pm | 18 +++ .../lib/Lemonldap/NG/Common/Conf/CDBI.pm | 131 ++++++++++++++++++ .../lib/Lemonldap/NG/Common/Conf/DBI.pm | 1 - .../lib/Lemonldap/NG/Manager/Sessions.pm | 2 +- .../lib/Lemonldap/NG/Portal/Simple.pm | 19 ++- 6 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/CDBI.pm diff --git a/modules/lemonldap-ng-common/MANIFEST b/modules/lemonldap-ng-common/MANIFEST index 09c952b18..547300f60 100644 --- a/modules/lemonldap-ng-common/MANIFEST +++ b/modules/lemonldap-ng-common/MANIFEST @@ -8,6 +8,7 @@ lib/Lemonldap/NG/Common/CGI/SOAPServer.pm lib/Lemonldap/NG/Common/CGI/SOAPService.pm lib/Lemonldap/NG/Common/Conf.pm lib/Lemonldap/NG/Common/Conf/Constants.pm +lib/Lemonldap/NG/Common/Conf/CDBI.pm lib/Lemonldap/NG/Common/Conf/DBI.pm lib/Lemonldap/NG/Common/Conf/File.pm lib/Lemonldap/NG/Common/Conf/LDAP.pm diff --git a/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Apache/Session.pm b/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Apache/Session.pm index 46ec13d96..d62960f5f 100644 --- a/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Apache/Session.pm +++ b/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Apache/Session.pm @@ -14,6 +14,24 @@ our $VERSION = 0.21; BEGIN { + sub Apache::Session::searchOn { + my ( $class, $args, $selectField, $value, @fields ) = @_; + my %res = (); + $class->get_key_from_all_sessions($args,sub{ + my $entry = shift; + my $id = shift; + return undef unless($entry->{selectField}eq $value); + if (@fields) { + $res{ $id }->{$_} = $entry->{$_} foreach (@fields); + } + else { + $res{ $id } = $entry; + } + undef; + }); + return \%res; + } + sub Apache::Session::get_key_from_all_sessions { return 0; } diff --git a/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/CDBI.pm b/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/CDBI.pm new file mode 100644 index 000000000..1e271d2dc --- /dev/null +++ b/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/CDBI.pm @@ -0,0 +1,131 @@ +package Lemonldap::NG::Common::Conf::CDBI; + +use strict; +use DBI; +require Storable; +use Lemonldap::NG::Common::Conf::Constants; #inherits + +our $VERSION = 0.1; + +BEGIN { + *Lemonldap::NG::Common::Conf::_dbh = \&_dbh; +} + +sub prereq { + my $self = shift; + unless ( $self->{dbiChain} ) { + $Lemonldap::NG::Common::Conf::msg = + '"dbiChain" is required in DBI configuration type'; + return 0; + } + print STDERR __PACKAGE__ . 'Warning: "dbiUser" parameter is not set' + unless ( $self->{dbiUser} ); + $self->{dbiTable} ||= "lmConfig"; + 1; +} + +sub available { + my $self = shift; + my $sth = $self->_dbh->prepare( + "SELECT cfgNum from " . $self->{dbiTable} . " order by cfgNum" ); + $sth->execute(); + my @conf; + while ( my @row = $sth->fetchrow_array ) { + push @conf, $row[0]; + } + return @conf; +} + +sub lastCfg { + my $self = shift; + my @row = $self->_dbh->selectrow_array( + "SELECT max(cfgNum) from " . $self->{dbiTable} ); + return $row[0]; +} + +sub _dbh { + my $self = shift; + $self->{dbiTable} ||= "lmConfig"; + return $self->{_dbh} if ( $self->{_dbh} and $self->{_dbh}->ping ); + return DBI->connect_cached( + $self->{dbiChain}, $self->{dbiUser}, + $self->{dbiPassword}, { RaiseError => 1 } + ); +} + +sub lock { + my $self = shift; + my $sth = $self->_dbh->prepare_cached( q{SELECT GET_LOCK(?, 5)}, {}, 1 ); + $sth->execute('lmconf'); + my @row = $sth->fetchrow_array; + return $row[0] || 0; +} + +sub isLocked { + my $self = shift; + my $sth = $self->_dbh->prepare_cached( q{SELECT IS_FREE_LOCK(?)}, {}, 1 ); + $sth->execute('lmconf'); + my @row = $sth->fetchrow_array; + return $row[0] ? 0 : 1; +} + +sub unlock { + my $self = shift; + my $sth = $self->_dbh->prepare_cached( q{SELECT RELEASE_LOCK(?)}, {}, 1 ); + $sth->execute('lmconf'); + my @row = $sth->fetchrow_array; + return $row[0] || 0; +} + +sub store { + my ( $self, $fields ) = @_; + my $c = $fields->{cfgNum}; + $fields = Storable::nfreeze($fields); + $fields =~ s/'/''/gs; + my $tmp = + $self->_dbh->do( "insert into " + . $self->{dbiTable} . " (cfgNum,data) values ($cfgNum,'$fields')"); + unless ($tmp) { + $self->logError; + return UNKNOWN_ERROR; + } + unless ( $self->unlock ) { + $self->logError; + return UNKNOWN_ERROR; + } + eval { $self->_dbh->do("COMMIT"); }; + return $c; +} + +sub load { + my ( $self, $cfgNum, $fields ) = @_; + $fields = $fields ? join( ",", @$fields ) : '*'; + my $row = $self->_dbh->selectrow_arrayref( + "SELECT data from " . $self->{dbiTable} . " WHERE cfgNum=$cfgNum" ); + unless ($row) { + $self->logError; + return 0; + } + my $r; + eval { $r = Storable::thaw($row->[1]); } ; + if ($@) { + $Lemonldap::NG::Common::Conf::msg = "Bad stored data in conf database: $@"; + return 0; + } + return $r; +} + +sub delete { + my ( $self, $cfgNum ) = @_; + $self->_dbh->do( + "DELETE from " . $self->{dbiTable} . " WHERE cfgNum=$cfgNum" ); +} + +sub logError { + my $self = shift; + $Lemonldap::NG::Common::Conf::msg = + "Database error: " . $self->_dbh->errstr . "\n"; +} + +1; +__END__ diff --git a/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/DBI.pm b/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/DBI.pm index 3452b25e4..0ac6872ca 100644 --- a/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/DBI.pm +++ b/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/DBI.pm @@ -2,7 +2,6 @@ package Lemonldap::NG::Common::Conf::DBI; use strict; use DBI; -use MIME::Base64; use Lemonldap::NG::Common::Conf::Constants; #inherits use Lemonldap::NG::Common::Conf::Serializer; diff --git a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Sessions.pm b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Sessions.pm index 191b832d1..9779374b6 100755 --- a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Sessions.pm +++ b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Sessions.pm @@ -115,7 +115,7 @@ sub process { my $entry = shift; my $id = shift; next if ( $entry->{_httpSessionType} ); - if ( $entry->{$ipField} =~ /^$reip$/ ) { + if ( $entry->{$ipField} eq $reip ) { push @{ $byUid->{ $entry->{$ipField} } ->{ $entry->{$whatToTrace} } }, { id => $id, _utime => $entry->{_utime} }; diff --git a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Simple.pm b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Simple.pm index fd1e8b7d9..1c79844d6 100644 --- a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Simple.pm +++ b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Simple.pm @@ -17,6 +17,7 @@ use CGI::Cookie; require POSIX; use Lemonldap::NG::Portal::_i18n; #inherits use Lemonldap::NG::Common::Safelib; #link protected safe Safe object +use Lemonldap::NG::Common::Apache::Session; #link protected session Apache::Session object use Safe; # Special comments for doxygen @@ -559,7 +560,8 @@ sub process { SAMLForUnAuthUser authInit extractFormInfo userDBInit getUser setAuthSessionInfo passwordDBInit modifyPassword setSessionInfo resetPasswordByMail setMacros setLocalGroups setGroups authenticate - store buildCookie checkNotification SAMLForAuthUser autoRedirect) + removeOther store buildCookie checkNotification SAMLForAuthUser + autoRedirect) ); $self->updateStatus; return ( ( $self->{error} > 0 ) ? 0 : 1 ); @@ -798,6 +800,21 @@ sub authenticate { PE_OK; } +sub removeOther { + my $self = shift; + if($self->{singleSession} or $self->{singleIP}) { + my $sessions = $self->{globalStorage}->searchOn($self->{globalStorageOptions},$self->{whatToTrace},$self->{sessionInfo}->{$self->{whatToTrace}}); + foreach my $id ( keys %$sessions ) { + my $h = $self->getApacheSession($id); + unless($self->{singleIP} and $self->{sessionInfo}->{ipAddr} eq $h->{ipAddr}) { + tied(%$h)->delete(); + $self->lmLog("Deleting session $id",'debug'); + } + } + } + PE_OK; +} + ##@apmethod int store() # 13) Store user's datas in sessions database. # Now, the user is known, authenticated and session variable are evaluated.