diff --git a/build/lemonldap-ng/Makefile b/build/lemonldap-ng/Makefile index d6f4c37f4..7cb2cad6f 100644 --- a/build/lemonldap-ng/Makefile +++ b/build/lemonldap-ng/Makefile @@ -55,7 +55,8 @@ CONFDIR=$(LMPREFIX)/etc RCONFDIR=$(DESTDIR)/$(CONFDIR) CRONDIR=$(LMPREFIX)/etc/cron.d RCRONDIR=$(DESTDIR)/$(CRONDIR) -STORAGECONFFILE=$(CONFDIR)/storage.conf +CONFFILENAME=lemonldap-ng.ini +STORAGECONFFILE=$(CONFDIR)/$(CONFFILENAME) # Lemonldap-ng configuration storage dir FILECONFIGDIR=$(DATADIR)/conf @@ -366,9 +367,8 @@ install_conf_dir: install_sessions_dir # Configuration files install @install -v -d $(RCONFDIR) $(RFILECONFIGDIR) $(RTOOLSDIR) @if [ "$(ERASECONFIG)" -eq "1" ]; then \ - cp --remove-destination $(SRCCOMMONDIR)/storage.conf $(RCONFDIR); \ - perl -i -pe 's#^dirName = .*#dirName = $(FILECONFIGDIR)#g' $(RCONFDIR)/storage.conf; \ - cp --remove-destination $(SRCCOMMONDIR)/localconf.ini $(RCONFDIR); \ + cp --remove-destination $(SRCCOMMONDIR)/$(CONFFILENAME) $(RCONFDIR); \ + perl -i -pe 's#^dirName\s*=\s*.*#dirName = $(FILECONFIGDIR)#g' $(RCONFDIR)/$(CONFFILENAME); \ fi @cp _example/conf/lmConf-1 $(RFILECONFIGDIR) @perl -000 -i -pe "s#^(globalStorageOptions\\n\\s+)'[^\\n]*?'\$$#\$${1}\'\\\$$data1 = {&39;Directory&39; => &39;$(APACHESESSIONFILEDIR)&39;,&39;LockDirectory&39; => &39;$(APACHESESSIONFILELOCKDIR)&39;};'#m" $(RFILECONFIGDIR)/lmConf-1 diff --git a/modules/lemonldap-ng-common/MANIFEST b/modules/lemonldap-ng-common/MANIFEST index 547300f60..5196f8c52 100644 --- a/modules/lemonldap-ng-common/MANIFEST +++ b/modules/lemonldap-ng-common/MANIFEST @@ -22,7 +22,7 @@ META.yml Module meta-data (added by MakeMaker) README scripts/lmConfig_File2LDIF scripts/lmConfig_File2MySQL -storage.conf +lemonldap-ng.ini t/01-Common-Conf.t t/02-Common-Conf-File.t t/03-Common-Conf-DBI.t diff --git a/modules/lemonldap-ng-common/META.yml b/modules/lemonldap-ng-common/META.yml index ff977d493..c77b7a405 100644 --- a/modules/lemonldap-ng-common/META.yml +++ b/modules/lemonldap-ng-common/META.yml @@ -20,7 +20,6 @@ requires: Regexp::Assemble: 0 SOAP::Lite: 0 Storable: 0 - File::Basename: 0 Config::IniFiles: 0 no_index: directory: diff --git a/modules/lemonldap-ng-common/Makefile.PL b/modules/lemonldap-ng-common/Makefile.PL index 8d0fce5b1..fa15cd881 100644 --- a/modules/lemonldap-ng-common/Makefile.PL +++ b/modules/lemonldap-ng-common/Makefile.PL @@ -12,7 +12,7 @@ sub MY::top_targets { $r .= <<"EOT"; my_target: - perl -i -pe 's/^(use constant DEFAULTCONFFILE =>).*\$\$/\$\$1 "$cf";/' blib/lib/Lemonldap/NG/Common/Conf.pm + perl -i -pe 's/^(use constant DEFAULTCONFFILE\\s*=>).*\$\$/\$\$1 "$cf";/' blib/lib/Lemonldap/NG/Common/Conf/Constants.pm EOT } return $r; @@ -32,6 +32,7 @@ WriteMakefile( 'SOAP::Lite' => 0, 'Crypt::Rijndael' => 0, 'HTTP::Headers' => 0, + 'Config::IniFiles' => 0, }, # e.g., Module::Name => 1.1 #EXE_FILES => [ 'scripts/lmConfig_File2MySQL', ], ( diff --git a/modules/lemonldap-ng-common/localconf.ini b/modules/lemonldap-ng-common/lemonldap-ng.ini similarity index 56% rename from modules/lemonldap-ng-common/localconf.ini rename to modules/lemonldap-ng-common/lemonldap-ng.ini index c992104ed..53b2ee15d 100644 --- a/modules/lemonldap-ng-common/localconf.ini +++ b/modules/lemonldap-ng-common/lemonldap-ng.ini @@ -6,11 +6,21 @@ # local LemonLDAP::NG elements # # Parameters of section "all" are always read +# Section "configuration" is used to load global configuration and set cache # Other section are only read by the specific LemonLDAP::NG component #============================================================================== -[all] -#cda = 1 +[all] +;cda = 1 + +[configuration] +# Global configuration access type (File, SOAP, DBI, LDAP) +type = File +dirName = /var/lib/lemonldap-ng/conf + +# Configuration cache +localStorage = Cache::FileCache +localStorageOptions = { 'namespace' => 'MyNamespace', 'default_expires_in' => 600, 'directory_umask' => '007', 'cache_root' => '/tmp', 'cache_depth' => 5, } [portal] portalDisplayResetPassword = 0 @@ -20,5 +30,5 @@ https = 0 [manager] dhtmlXTreeImageLocation = /imgs/ -#protection = authenticate +;protection = authenticate diff --git a/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf.pm b/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf.pm index 17e8e0b8a..8a05e4e32 100644 --- a/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf.pm +++ b/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf.pm @@ -12,7 +12,6 @@ no strict 'refs'; use Lemonldap::NG::Common::Conf::Constants; #inherits use Lemonldap::NG::Common::Crypto; #link protected cipher Object "cypher" in configuration hash use Regexp::Assemble; -use File::Basename; use Config::IniFiles; #inherits Lemonldap::NG::Common::Conf::File @@ -20,15 +19,9 @@ use Config::IniFiles; #inherits Lemonldap::NG::Common::Conf::SOAP #inherits Lemonldap::NG::Common::Conf::LDAP -use constant DEFAULTCONFFILE => "/usr/local/lemonldap-ng/etc/storage.conf"; -use constant LOCALCONFFILENAME => "localconf.ini"; -use constant DEFAULTINISECTION => "all"; - our $VERSION = 0.70; our $msg; -our %_confFiles; - ## @cmethod Lemonldap::NG::Common::Conf new(hashRef arg) # Constructor. # Succeed if it has found a way to access to Lemonldap::NG configuration with @@ -53,12 +46,18 @@ sub new { %$self = %{ $_[0] }; } else { - if (defined @_ and ($#_>0) ) { + if ( defined @_ && $#_%2 == 1 ) { %$self = @_; } } unless ( $self->{mdone} ) { - $self->_readConfFile( $self->{confFile} ) unless ( $self->{type} ); + unless ( $self->{type} ) { + # Use local conf to get configStorage and localStorage + my $localconf = $self->getLocalConf( CONFSECTION, $self->{confFile}, 0 ); + if ( defined $localconf ) { + %$self = ( %$self, %$localconf ); + } + } unless ( $self->{type} ) { $msg .= 'Error: configStorage: type is not defined'; return 0; @@ -90,39 +89,6 @@ sub new { return $self; } -## @method private boolean _readConfFile(string file) -# Read $file to know how to access to Lemonldap::NG configuration. -# @param $file Optional file name (default: /etc/lemonldap-ng/storage.conf) -# @return True if the file was successfuly read -sub _readConfFile { - my $self = shift; - my $file = shift || DEFAULTCONFFILE; - unless ( $_confFiles{$file} ) { - unless ( open F, $file ) { - $msg = "Warning $file: $!. "; - return 0; - } - while () { - next if ( /^\s*$/ or /^\s*#/ ); - chomp; - s/\r//g; - /^\s*([\w]+)(?:\s*[:=]\s*|\s+)(["']?)([\S].*[\S])\2\s*$/ or next; - my $k = $1; - $_confFiles{$file}->{$k} = $3; - if ( $_confFiles{$file}->{$k} =~ /^[{\[].*[}\]]$/ ) { - eval "\$_confFiles{'$file'}->{'$k'} = $_confFiles{$file}->{$k}"; - if ($@) { - $msg = "Warning: error in file $file : $@. "; - return 0; - } - } - } - close F; - } - %$self = ( %$self, %{ $_confFiles{$file} } ); - return 1; -} - ## @method int saveConf(hashRef conf) # Serialize $conf and call store(). # @param $conf Lemonldap::NG configuration hashRef @@ -195,26 +161,29 @@ sub getConf { } } -## @method hashRef getLocalConf(string section, string file) +## @method hashRef getLocalConf(string section, string file, int loaddefault) # Get configuration from local file # -# @param $section Optional section name (default DEFAULTINISECTION) -# @param $file Optional file name (default dirname DEFAULTCONFFILE . LOCALCONFFILENAME) +# @param $section Optional section name (default DEFAULTSECTION) +# @param $file Optional file name (default DEFAULTCONFFILE) +# @param $loaddefault Optional load default section parameters (default 1) # @return Lemonldap::NG configuration sub getLocalConf { - my ( $self, $section, $file ) = @_; + my ( $self, $section, $file, $loaddefault ) = @_; my $r; - $section ||= DEFAULTINISECTION; + $section ||= DEFAULTSECTION; + $file ||= DEFAULTCONFFILE; + $loaddefault = 1 unless ( defined $loaddefault ); - unless ( $file ) { - # Get storage.conf path - my( $filename, $directories ) = fileparse DEFAULTCONFFILE; - $file = $directories . LOCALCONFFILENAME; - } - - # If local configuration file does not exists, exit silently. + # If default configuration cannot be read + # - Error if configuration section is requested + # - Silent exit for other section requests unless ( -r $file ) { + if ( $section eq CONFSECTION) { + $msg = "Cannot read $file to get configuration access parameters"; + return 0; + } return $r; } @@ -224,18 +193,39 @@ sub getLocalConf { -allowempty => 1, ); - unless (defined $cfg) { + unless ( defined $cfg ) { $msg = "Local config error: ".@Config::IniFiles::errors; return 0; } + # Check if default section exists + unless ( $cfg->SectionExists( DEFAULTSECTION ) ) { + $msg = "Default section (".DEFAULTSECTION.") is missing"; + return 0; + } + + # Check if configuration section exists + if ( $section eq CONFSECTION and !$cfg->SectionExists( CONFSECTION ) ) { + $msg = "Configuration section (".CONFSECTION.") is missing"; + return 0; + } + # First load all default section parameters - foreach ($cfg->Parameters( DEFAULTINISECTION )) { - $r->{$_} = $cfg->val( DEFAULTINISECTION, $_ ); + if ( $loaddefault ) { + foreach ($cfg->Parameters( DEFAULTSECTION )) { + $r->{$_} = $cfg->val( DEFAULTSECTION, $_ ); + if ( $r->{$_} =~ /^[{\[].*[}\]]$/ ) { + eval "\$r->{$_} = $r->{$_}"; + if ($@) { + $msg = "Warning: error in file $file: $@. "; + return 0; + } + } + } } # Stop if the requested section is the default section - return $r if ( $section eq DEFAULTINISECTION ); + return $r if ( $section eq DEFAULTSECTION ); # Check if requested section exists return 0 unless $cfg->SectionExists( $section ); @@ -243,6 +233,13 @@ sub getLocalConf { # Load section parameters foreach ($cfg->Parameters( $section )) { $r->{$_} = $cfg->val( $section, $_ ); + if ( $r->{$_} =~ /^[{\[].*[}\]]$/ ) { + eval "\$r->{$_} = $r->{$_}"; + if ($@) { + $msg = "Warning: error in file $file: $@. "; + return 0; + } + } } return $r; diff --git a/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/Constants.pm b/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/Constants.pm index 6fa735f00..7108266f2 100644 --- a/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/Constants.pm +++ b/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/Constants.pm @@ -4,7 +4,7 @@ use strict; use Exporter 'import'; use base qw(Exporter); -our $VERSION = '0.1'; +our $VERSION = '0.20'; # CONSTANTS @@ -13,6 +13,12 @@ use constant UNKNOWN_ERROR => -2; use constant DATABASE_LOCKED => -3; use constant UPLOAD_DENIED => -4; use constant SYNTAX_ERROR => -5; +use constant DEFAULTCONFFILE => "/usr/local/lemonldap-ng/etc/lemonldap-ng.ini"; +use constant DEFAULTSECTION => "all"; +use constant CONFSECTION => "configuration"; +use constant PORTALSECTION => "portal"; +use constant HANDLERSECTION => "handler"; +use constant MANAGERSECTION => "manager"; our %EXPORT_TAGS = ( 'all' => [ qw( CONFIG_WAS_CHANGED @@ -20,6 +26,12 @@ our %EXPORT_TAGS = ( 'all' => [ qw( DATABASE_LOCKED UPLOAD_DENIED SYNTAX_ERROR + DEFAULTCONFFILE + DEFAULTSECTION + CONFSECTION + PORTALSECTION + HANDLERSECTION + MANAGERSECTION ) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); diff --git a/modules/lemonldap-ng-common/storage.conf b/modules/lemonldap-ng-common/storage.conf deleted file mode 100644 index 771be4ffd..000000000 --- a/modules/lemonldap-ng-common/storage.conf +++ /dev/null @@ -1,52 +0,0 @@ -# -# This file contains parameters used by Lemonldap::NG to find its configuration -# -# -# 1 - Type -# -# You can use one of the following: -# * File: you have to set 'dirName' parameter. Example: -# -# type = File -# dirName = /var/lib/lemonldap-ng/conf -# -# * DBI : you have to set 'dbiChain' (required) and 'dbiUser' and 'dbiPassword' -# if needed. Example: -# -# type = DBI -# dbiChain = DBI:mysql:database=lemonldap-ng;host=1.2.3.4 -# dbiUser = lemonldap -# dbiPassword = password -# -# * SOAP: SOAP configuration access is a sort of proxy: the portal is -# configured to use the real session storage type (DBI or File for -# example). -# You have to set 'proxy' parameter. Example: -# -# type = SOAP -# proxy = https://auth.example.com/index.pl/config -# proxyOptions = { timeout => 5 } -# User = lemonldap -# Password = mypassword -# -# * LDAP: you have to set ldapServer, ldapConfBranch, ldapBindDN and ldapBindPassword. -# -# type = LDAP -# ldapServer = ldap://localhost -# ldapConfBase = ou=conf,ou=applications,dc=example,dc=com -# ldapBindDN = cn=manager,dc=example,dc=com -# ldapBindPassword = secret -# -# -# 2 - LocalStorage -# -# To increase performances, use a local cache for the configuration. You have -# to choose a Cache::Cache module and set it's parameters (1 line). Example: -# -# localStorage = Cache::FileCache -# localStorageOptions = { 'namespace' => 'MyNamespace', 'default_expires_in' => 600, 'directory_umask' => '007', 'cache_root' => '/tmp', 'cache_depth' => 5, } - -type = File -dirName = /var/lib/lemonldap-ng/conf -localStorage = Cache::FileCache -localStorageOptions = { 'namespace' => 'MyNamespace', 'default_expires_in' => 600, 'directory_umask' => '007', 'cache_root' => '/tmp', 'cache_depth' => 5, } diff --git a/modules/lemonldap-ng-common/t/01-Common-Conf.t b/modules/lemonldap-ng-common/t/01-Common-Conf.t index de6763b00..c140d1a6d 100644 --- a/modules/lemonldap-ng-common/t/01-Common-Conf.t +++ b/modules/lemonldap-ng-common/t/01-Common-Conf.t @@ -14,6 +14,8 @@ BEGIN { use_ok('Lemonldap::NG::Common::Conf') } # its man page ( perldoc Test::More ) for help writing this test script. my $h; +my $inifile = "lemonldap-ng.ini"; +my $confsection = "configuration"; ok( ( @@ -26,5 +28,11 @@ ok( $h = bless {}, 'Lemonldap::NG::Common::Conf'; -ok( $h->_readConfFile('storage.conf'), 'Read storage.conf' ); +ok( + ( + %$h = (%$h , %{ $h->getLocalConf( $confsection, $inifile, 0) }) + and exists $h->{localStorage} + ), + "Read $inifile" +); 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 4f2a369d9..502b72f57 100644 --- a/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/SharedConf.pm +++ b/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/SharedConf.pm @@ -20,6 +20,7 @@ use strict; use Lemonldap::NG::Handler::Simple qw(:all); use Lemonldap::NG::Handler::Vhost; use Lemonldap::NG::Common::Conf; #link protected lmConf +use Lemonldap::NG::Common::Conf::Constants; #inherits use Cache::Cache qw($EXPIRES_NEVER); use base qw(Lemonldap::NG::Handler::Vhost Lemonldap::NG::Handler::Simple); @@ -90,7 +91,7 @@ sub localInit { Lemonldap::NG::Common::Conf->new( $args->{configStorage} ) ); # Get local configuration parameters - my $localconf = $lmConf->getLocalConf("handler"); + my $localconf = $lmConf->getLocalConf( HANDLERSECTION ); $args->{$_} ||= $localconf->{$_} foreach ( keys %$localconf ); # Store in localConfig global variable diff --git a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager.pm b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager.pm index 0810cd54e..460ae4859 100644 --- a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager.pm +++ b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager.pm @@ -59,11 +59,12 @@ sub msafe { sub new { my ( $class, $args ) = @_; my $self = $class->SUPER::new(); + %$self = ( %$self, %$args ); # TODO load global configuration parameters ? - + # Try to load local configuration parameters to get 'protection' - my $localconf = $self->config->getLocalConf("manager"); + my $localconf = $self->config->getLocalConf( MANAGERSECTION ); $args->{protection} ||= $localconf->{protection}; if ( $args->{protection} ) { @@ -73,7 +74,6 @@ sub new { } # Now push all local configuration parameters - %$self = ( %$self, %$args ); $self->{$_} = $args->{$_} || $localconf->{$_} foreach ( keys %$localconf ); foreach (qw(dhtmlXTreeImageLocation)) { diff --git a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/SharedConf.pm b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/SharedConf.pm index 0badfcb8e..b0442f93d 100644 --- a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/SharedConf.pm +++ b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/SharedConf.pm @@ -8,6 +8,7 @@ package Lemonldap::NG::Portal::SharedConf; use strict; use Lemonldap::NG::Portal::Simple qw(:all); use Lemonldap::NG::Common::Conf; #link protected lmConf Configuration +use Lemonldap::NG::Common::Conf::Constants; #inherits *EXPORT_OK = *Lemonldap::NG::Portal::Simple::EXPORT_OK; *EXPORT_TAGS = *Lemonldap::NG::Portal::Simple::EXPORT_TAGS; @@ -87,7 +88,7 @@ sub _getLocalLmConf { } # Get local configuration parameters for portal - return $self->{lmConf}->getLocalConf("portal"); + return $self->{lmConf}->getLocalConf( PORTALSECTION ); } 1;