Merge branch 'master' into 2.7.2/master

This commit is contained in:
Philippe Caseiro 2021-03-03 17:05:07 +01:00
commit da3c97d534
16 changed files with 280 additions and 61 deletions

View File

@ -9,6 +9,7 @@
<file filelist='lemonldap-nginx' name='/etc/lemonldap-ng/manager-nginx.conf' mkdir='True' rm='True'/>
<file filelist='lemonldap-nginx' name='/etc/lemonldap-ng/handler-nginx.conf' mkdir='True' rm='True'/>
<file filelist='lemonldap-nginx' name='/etc/lemonldap-ng/portal-nginx.conf' mkdir='True' rm='True'/>
<file filelist='lemonldap-nginx' name='/etc/lemonldap-ng/nginx-lmlog.conf' mkdir='True' rm='True'/>
<file filelist='lemonldap-apache' name='/etc/lemonldap-ng/manager-apache2.X.conf' mkdir='True' rm='True'/>
<file filelist='lemonldap-apache' name='/etc/lemonldap-ng/handler-apache2.X.conf' mkdir='True' rm='True'/>
@ -27,6 +28,14 @@
</files>
<variables>
<family name='eole-sso'>
<variable name='eolesso_cas_folder' redefine="True" exists='True'>
<value>/cas</value>
</variable>
<variable name='eolesso_port' redefine="True" exists='True'>
<value>443</value>
</variable>
</family>
<family name='Services'>
<variable name='activerLemon' type='oui/non' description="Activer LemonLDAP::NG">
<value>non</value>
@ -39,6 +48,10 @@
<variable name='authWebName' type='string' description="Nom DNS du service d'authentification LemonLDAP-NG"/>
<variable name='reloadWebName' type='string' description="Nom DNS du service Reload de LemonLDAP-NG" mode="expert"/>
<variable name='lemon_user_db' type='string' description="Backend pour les comptes utilisateurs" mode="expert">
<value>LDAP</value>
</variable>
<variable name='ldapScheme' type='string' description="Protocole LDAP à utiliser" mandatory='True'/>
<variable name='ldapServer' type='string' description="Adresse du Serveur LDAP utilisé par LemonLDAP::NG" mandatory="True"/>
<variable name='ldapServerPort' type='number' description="Port d'écoute du LDAP utilisé par LemonLDAP::NG" mandatory='True'/>
@ -46,11 +59,18 @@
<variable name='ldapBindUserDN' type='string' description="Utilisateur de connection à l'annuaire" mandatory="True"/>
<variable name='ldapBindUserPassword' type='password' description="Mot de passe de l'utilisateur de connection à l'annuaire" mandatory="True"/>
<variable name="samlOrganizationName" type='string' description="Nom de l'organisation SAML" mode='expert'/>
<variable name='lmldapverify' type='oui/non' description="Vérifier les certificats SSL du serveur LDAP">
<value>oui</value>
</variable>
<variable name="lemonproc" type='number' description="Nombre de processus dédié à Lemon (équivalent au nombre de processeurs)" mandatory="True">
<value>4</value>
</variable>
<variable name="lm_loglevel" type='string' description="Verbosité des journaux" mode='expert'>
<value>info</value>
</variable>
<variable name="lemonAdmin" type='string' description="LemonLDAP Administrator username" mode='expert'>
<value>admin</value>
</variable>
@ -73,7 +93,19 @@
<variable name='llCheckLogins' type='oui/non' description="Permettre aux utilisateurs d'afficher l'historique de connection">
<value>non</value>
</variable>
<variable name='llResetPassword' type='oui/non' description="Permettre aux utilisateurs de réinitialiser leurs mots de passe">
<variable name='llResetPassword' type='oui/non' description="Permettre aux utilisateurs de réinitialiser leurs mots de passe par mail">
<value>oui</value>
</variable>
<variable name='llChangePassword' type='oui/non' description="Permettre aux utilisateurs de changer leurs mots de passe depuis LemonLDAP">
<value>oui</value>
</variable>
<variable name='llADPasswordMaxAge' type='number' description="Durée de vie des mots de passe (en secondes)" mode='expert'>
<value>5184000</value>
</variable>
<variable name='llADPasswordExpireWarn' type='number' description="Délai avant affichage d'un message d'alerte sur l'expiration du mot de passe (en secondes)">
<value>3456000</value>
</variable>
<variable name='llResetExpiredPassword' type='oui/non' description="Autoriser le renouvellement des mots de passe expirés">
<value>oui</value>
</variable>
<variable name='llResetUrl' type='string' description="Adresse de l'application pour réinitialiser leurs mots de passe" />
@ -117,13 +149,28 @@
<param>['ldaps','ldap']</param>
</check>
<check name="valid_enum" target="llRegisterDB">
<param>['LDAP','Demo','Custom']</param>
<check name="valid_enum" target="lemon_user_db">
<param>['LDAP','AD']</param>
</check>
<check name='valid_enum' target="lm_loglevel">
<param>['info','notice','warn','error','debug']</param>
</check>
<check name="valid_enum" target="llRegisterDB">
<param>['LDAP','AD','Demo','Custom']</param>
</check>
<group master="casAttribute">
<slave>casLDAPAttribute</slave>
</group>
<condition name='disabled_if_not_in' source='lemon_user_db'>
<param>AD</param>
<target type='variable'>llADPasswordMaxAge</target>
<target type='variable'>llADPasswordExpireWarn</target>
</condition>
<condition name='disabled_if_in' source='activerLemon'>
<param>non</param>
<target type='filelist'>lemonldap</target>
@ -157,6 +204,7 @@
<condition name='disabled_if_in' source='llResetPassword'>
<param>non</param>
<target type='variable'>llResetUrl</target>
<target type='variable'>llResetExpiredPassword</target>
</condition>
<check name='valid_enum' target='llSkin'>
<param>['bootstrap','dark','impact','pastel']</param>

View File

@ -6,19 +6,12 @@
<variables>
<family name='eole sso'>
<variable name='eolesso_adresse' description="Nom de domaine du serveur d'authentification SSO" redefine="True" exists='True' />
<variable name='eolesso_cas_folder' redefine="True" exists='True'>
<value>cas</value>
</variable>
<variable name='eolesso_port' redefine="True" exists='True'>
<value>443</value>
</variable>
<variable name='eolesso_adresse' description="Nom de domaine du serveur d'authentification SSO" redefine="True" exists='True' />
</family>
</variables>
<constraints>
<fill name='calc_multi_condition' target='activer_sso'>
<param>oui</param>
<param type='eole' name='condition_1'>activerLemon</param>
@ -31,12 +24,6 @@
<target type='variable'>activer_sso</target>
</condition>
<auto name='calc_multi_condition' target='ldapScheme'>
<param>oui</param>
<param type='eole' name='condition_1'>ldap_tls</param>
<param name='match'>ldaps</param>
<param name='default_mismatch'>ldap</param>
</auto>
<fill name='calc_val_first_value' target='eolesso_adresse'>
<param type='eole' optional='True' hidden='False'>authWebName</param>
@ -49,6 +36,13 @@
<target type='variable'>eolesso_adresse</target>
</condition>
<auto name='calc_multi_condition' target='ldapScheme'>
<param>oui</param>
<param type='eole' name='condition_1'>ldap_tls</param>
<param name='match'>ldaps</param>
<param name='default_mismatch'>ldap</param>
</auto>
<auto name='calc_val' target='ldapServer'>
<param type='eole'>adresse_ip_ldap</param>
</auto>
@ -57,16 +51,22 @@
<param type='eole'>ldap_port</param>
</auto>
<auto name='calc_val' target='lemon_user_db'>
<param>LDAP</param>
</auto>
<auto name='calc_val' target='llRegisterDB'>
<param>LDAP</param>
</auto>
<auto name='calc_val' target='ldapUserBaseDN'>
<param type='eole'>ldap_base_dn</param>
</auto>
<auto name='calc_val' target='ldapBindUserDN'>
<param type='eole'>ldap_reader</param>
</auto>
<auto name='calc_val' target='ldapBindUserPassword'>
<param type='eole'>ldap_reader_passfile</param>
<param type='eole'>ldap_reader_passfile</param>
</auto>
<auto name='calc_val' target='casFolder'>

2
eole-lemonldap-ng.mk Normal file
View File

@ -0,0 +1,2 @@
creolefuncs_DATA_DIR := $(DESTDIR)/usr/share/creole/funcs
lemonldap-ng_DATA_DIR := $(eole_DIR)/lemonldap-ng

View File

@ -1 +0,0 @@
creolefuncs_DATA_DIR := $(DESTDIR)/usr/share/creole/funcs

102
lemonldap-ng/LDAP.pm Normal file
View File

@ -0,0 +1,102 @@
package Lemonldap::NG::Portal::UserDB::LDAP;
use strict;
use Mouse;
use utf8;
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK);
extends 'Lemonldap::NG::Portal::Lib::LDAP';
our $VERSION = '2.0.6';
has ldapGroupAttributeNameSearch => (
is => 'rw',
lazy => 1,
builder => sub {
my $attributes = [];
@$attributes =
split( /\s+/, $_[0]->{conf}->{ldapGroupAttributeNameSearch} )
if $_[0]->{conf}->{ldapGroupAttributeNameSearch};
push( @$attributes, $_[0]->{conf}->{ldapGroupAttributeNameGroup} )
if ( $_[0]->{conf}->{ldapGroupRecursive}
and $_[0]->{conf}->{ldapGroupAttributeNameGroup} ne "dn" );
return $attributes;
}
);
# RUNNING METHODS
#
# getUser is provided by Portal::Lib::LDAP
# Load all parameters included in exportedVars parameter.
# Multi-value parameters are loaded in a single string with
# a separator (param multiValuesSeparator)
# @return Lemonldap::NG::Portal constant
sub setSessionInfo {
my ( $self, $req ) = @_;
$req->{sessionInfo}->{_dn} = $req->data->{dn};
my %vars = ( %{ $self->conf->{exportedVars} },
%{ $self->conf->{ldapExportedVars} } );
while ( my ( $k, $v ) = each %vars ) {
# getLdapValue returns an empty string for missing attribute
# but we really want to return undef so they don't get stored in session
$req->sessionInfo->{$k} =
$self->ldap->getLdapValue( $req->data->{ldapentry}, $v ) || undef;
}
PE_OK;
}
# Load all groups in $groups.
# @return Lemonldap::NG::Portal constant
sub setGroups {
my ( $self, $req ) = @_;
my $groups = $req->{sessionInfo}->{groups};
my $hGroups = $req->{sessionInfo}->{hGroups};
if ( $self->conf->{ldapGroupBase} ) {
# Get value for group search
my $group_value = $self->ldap->getLdapValue( $req->data->{ldapentry},
$self->conf->{ldapGroupAttributeNameUser} );
if ( $self->conf->{ldapGroupDecodeSearchedValue} ) {
utf8::decode($group_value);
}
$self->logger->debug( "Searching LDAP groups in "
. $self->conf->{ldapGroupBase}
. " for $group_value" );
# Call searchGroups
my $ldapGroups = $self->ldap->searchGroups(
$self->conf->{ldapGroupBase},
$self->conf->{ldapGroupAttributeName},
$group_value,
$self->ldapGroupAttributeNameSearch,
$req->{ldapGroupDuplicateCheck}
);
foreach ( keys %$ldapGroups ) {
my $groupName = $_;
$hGroups->{$groupName} = $ldapGroups->{$groupName};
my $groupValues = [];
foreach ( @{ $self->ldapGroupAttributeNameSearch } ) {
next if $_ =~ /^name$/;
my $firstValue = $ldapGroups->{$groupName}->{$_}->[0];
push @$groupValues, $firstValue;
}
$groups .= $self->conf->{multiValuesSeparator} if $groups;
$groups .= join( '|', @$groupValues );
}
}
$req->{sessionInfo}->{groups} = $groups;
$req->{sessionInfo}->{hGroups} = $hGroups;
PE_OK;
}
1;

View File

@ -0,0 +1,20 @@
--- /usr/share/perl5/Lemonldap/NG/Portal/UserDB/LDAP.pm.old 2019-12-11 12:05:54.000000000 +0100
+++ /usr/share/perl5/Lemonldap/NG/Portal/UserDB/LDAP.pm 2021-01-05 10:54:19.188732119 +0100
@@ -40,10 +40,15 @@
%{ $self->conf->{ldapExportedVars} } );
while ( my ( $k, $v ) = each %vars ) {
+ my $value = $self->ldap->getLdapValue( $req->data->{ldapentry}, $v );
+
# getLdapValue returns an empty string for missing attribute
# but we really want to return undef so they don't get stored in session
- $req->sessionInfo->{$k} =
- $self->ldap->getLdapValue( $req->data->{ldapentry}, $v ) || undef;
+ # This has to be a string comparison because "0" is a valid attribute
+ # value. See #2403
+ $value = undef if ( $value eq "" );
+
+ $req->sessionInfo->{$k} = $value;
}
PE_OK;

12
posttemplate/70-lemonldap-patch Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
# vérifie si le patch est déjà appliqué
grep -q 2403 /usr/share/perl5/Lemonldap/NG/Portal/UserDB/LDAP.pm && exit 0
# copie de sauvegarde
cp -a /usr/share/perl5/Lemonldap/NG/Portal/UserDB/LDAP.pm /usr/share/eole/lemonldap-ng/
# application du patch
patch -d / -p 0 < /usr/share/eole/lemonldap-ng/LDAP.pm.patch
exit 0

View File

@ -29,6 +29,17 @@ ErrorDocument 503 https://%%authWebName/lmerror/503
<VirtualHost %%adresse_ip_eth0:443>
ServerName %%reloadWebName
SSLEngine on
SSLCertificateFile %%server_cert
SSLCertificateKeyFile %%server_key
SSLCertificateChainFile /etc/ssl/certs/ca_local.crt
SSLProtocol all -SSLv3 -SSLv2
SSLProxyEngine on
LogLevel %%lm_loglevel
ErrorLog /var/log/apache2/handler_error.log
CustomLog /var/log/apache2/handler_access.log common
# Configuration reload mechanism (only 1 per physical server is
# needed): choose your URL to avoid restarting Apache when
# configuration change

View File

@ -23,8 +23,7 @@ server {
}
server {
listen 443;
ssl on;
listen 443 ssl;
%if %%cert_type == "letsencrypt"
ssl_certificate %%le_config_dir/live/%%managerWebName/cert.pem;
ssl_certificate_key %%le_config_dir/live/%%managerWebName/privkey.pem;
@ -62,7 +61,7 @@ server {
deny all;
# Uncomment this if you use https only
#add_header Strict-Transport-Security "max-age=15768000";
add_header Strict-Transport-Security "max-age=15768000";
}
}

View File

@ -36,7 +36,7 @@
;
; 1 - Defined logging level
; Set here one of error, warn, notice, info or debug
logLevel = debug
logLevel = %%lm_loglevel
; Note that this has no effect for Apache2 logging: Apache LogLevel is used
; instead
;
@ -65,9 +65,9 @@ logLevel = debug
; 2.1 - Using Syslog
;
; For Syslog logging, you can also overwrite facilities. Default values:
;logger = Lemonldap::NG::Common::Logger::Syslog
;syslogFacility = daemon
;userSyslogFacility = auth
logger = Lemonldap::NG::Common::Logger::Syslog
syslogFacility = daemon
userSyslogFacility = auth
;
; 2.2 - Using Log4perl
;
@ -197,11 +197,11 @@ portalSkin = %%llSkin
; Modules displayed
;portalDisplayLogout = 1
portalDisplayResetPassword = %%boolean[%%llResetPassword]
;portalDisplayChangePassword = 1
portalDisplayChangePassword = %%boolean[%%llChangePassword]
;portalDisplayAppslist = 1
;portalDisplayLoginHistory = 1
; Require the old password when changing password
;portalRequireOldPassword = 1
portalRequireOldPassword = %%boolean[%%llChangePassword]
; Attribute displayed as connected user
;portalUserAttr = mail
; Old menu HTML code

View File

@ -1,20 +1,30 @@
%set %%boolean = {'oui': 1, 'non': 0}
%set %%ssoFilters = %%getSSOFilters
%set %%ldapAttributes = {"uid": "uid", "mail": "mail", "cn":"cn"}
%set %%exported_vars = ['"UA": "HTTP_USER_AGENT"']
%set %%cas_attributes = []
%set %%ldap_attributes = {}
%for %%attr in %%casAttribute
%silent %%exported_vars.append('"' + %%attr + '": "' + %%attr + '.casLDAPAttribute"')
%silent %%cas_attributes.append('"' + %%attr + '": "' + %%attr + '.casLDAPAttribute"')
%silent %%exported_vars.append('"' + %%attr + '": "' + %%attr.casLDAPAttribute + '"')
%silent %%cas_attributes.append('"' + %%attr + '": "' + %%attr.casLDAPAttribute + '"')
%set %%ldap_attributes[%%attr.casLDAPAttribute] = %%attr.casLDAPAttribute
%end for
%for %%key, %%value in %%ssoFilters
%silent %%exported_vars.append('"' + %%key + '": "' + %%value + '"')
%silent %%cas_attributes.append('"' + %%key + '": "' + %%value + '"')
%set %%ldap_attributes[%%value] = %%value
%end for
%silent %%exported_vars.sort()
%silent %%cas_attributes.sort()
%set %%ldapAttr = []
%for %%k, %%v in %%ldap_attributes.items()
%silent %%ldapAttr.append('"' + %%k + '": "' + %%v + '"')
%end for
{
"ADPwdExpireWarning": 0,
"ADPwdMaxAge": 0,
%if %%lemon_user_db == "AD"
"ADPwdExpireWarning": %%llADPasswordExpireWarn,
"ADPwdMaxAge": %%llADPasswordMaxAge,
%end if
"CAS_authnLevel": 1,
"CAS_pgtFile": "/tmp/pgt.txt",
"CAS_proxiedServices": {},
@ -85,7 +95,7 @@
},
"authChoiceModules": {},
"authChoiceParam": "lmAuth",
"authentication": "LDAP",
"authentication": "%%lemon_user_db",
"browserIdAuthnLevel": 1,
"captchaStorage": "Apache::Session::File",
"captchaStorageOptions": {
@ -152,14 +162,26 @@
"issuerDBSAMLRule": 1,
"jsRedirect": 0,
"key": "e\"bTCt3*eU9^\\V%b",
%if %%llResetPassword == "oui"
%if %%llResetExpiredPassword == "oui"
%if %%lemon_user_db == "AD"
"ldapPpolicyControl": 0,
%else
"ldapPpolicyControl": 1,
%end if
"ldapAllowResetExpiredPassword": 1,
"ldapChangePasswordAsUser": 1,
%else
"ldapPpolicyControl": 0,
"ldapAllowResetExpiredPassword": 0,
"ldapChangePasswordAsUser": 1,
%end if
%end if
"ldapAuthnLevel": 2,
"ldapSearchDeref": "find",
"ldapBase": "%%ldapUserBaseDN",
"ldapChangePasswordAsUser": 0,
"ldapExportedVars": {
"cn": "cn",
"mail": "mail",
"uid": "uid"
%%custom_join(%%ldapAttr, ',\n ')
},
"ldapGroupAttributeName": "memberUid",
"ldapGroupAttributeNameGroup": "dn",
@ -170,9 +192,15 @@
"ldapPasswordResetAttribute": "pwdReset",
"ldapPasswordResetAttributeValue": "TRUE",
"ldapPort": "%%ldapServerPort",
"ldapPpolicyControl": 0,
"ldapPwdEnc": "utf-8",
"ldapServer": "%%ldapScheme://%%ldapServer",
%if %%ldapScheme == "ldaps"
%if %%lmldapverify == "oui"
"ldapVerify": "Require",
%else
"ldapVerify": "None",
%end if
%end if
"ldapSetPassword": 0,
"ldapTimeout": 120,
"ldapUsePasswordResetAttribute": 1,
@ -212,7 +240,7 @@
"mailTimeout": 0,
%if %%llResetPassword == "oui"
%if %%is_empty(%%llResetUrl)
"mailUrl": "https://%%authWebName/mail.pl",
"mailUrl": "https://%%authWebName/resetpwd",
%else
"mailUrl": "%%llResetUrl",
%end if
@ -251,7 +279,7 @@
"openIdSreg_fullname": "cn",
"openIdSreg_nickname": "uid",
"openIdSreg_timezone": "_timezone",
"passwordDB": "LDAP",
"passwordDB": "%%lemon_user_db",
"persistentStorage": "Apache::Session::File",
"persistentStorageOptions": {
"Directory": "/var/lib/lemonldap-ng/psessions",
@ -261,7 +289,7 @@
"portalAntiFrame": 1,
"portalCheckLogins": %%boolean[%%llCheckLogins],
"portalDisplayAppslist": 1,
"portalDisplayChangePassword": "$_auth =~ /^(LDAP|DBI|Demo)$/",
"portalDisplayChangePassword": "$_auth =~ /^(AD|LDAP|DBI|Demo)$/",
"portalDisplayLoginHistory": 1,
"portalDisplayLogout": 1,
"portalDisplayRegister": %%boolean[%%llRegisterAccount],
@ -371,7 +399,7 @@
"useRedirectOnForbidden": 0,
"useSafeJail": 1,
"userControl": "^[\\w\\.\\-@]+$",
"userDB": "LDAP",
"userDB": "%%lemon_user_db",
"vhostOptions": {
"%%managerWebName": {
"vhostHttps": "1"

View File

@ -13,13 +13,13 @@
<VirtualHost %%adresse_ip_eth0:443>
ServerName %%managerWebName
SSLEngine on
SSLCertificateFile /etc/ssl/certs/eole.crt
SSLCertificateKeyFile /etc/ssl/private/eole.key
SSLCertificateFile %%server_cert
SSLCertificateKeyFile %%server_key
SSLCertificateChainFile /etc/ssl/certs/ca_local.crt
SSLProtocol all -SSLv3 -SSLv2
SSLProxyEngine on
LogLevel info
LogLevel %%lm_loglevel
ErrorLog /var/log/apache2/manager_error.log
CustomLog /var/log/apache2/manager_access.log common

View File

@ -5,8 +5,7 @@ server {
}
server {
listen 443;
ssl on;
listen 443 ssl;
%if %%cert_type == "letsencrypt"
ssl_certificate %%le_config_dir/live/%%managerWebName/cert.pem;
ssl_certificate_key %%le_config_dir/live/%%managerWebName/privkey.pem;
@ -70,8 +69,8 @@ server {
# DEBIAN
# If install was made with USEDEBIANLIBS (official releases), uncomment this
#location /javascript/ {
# alias /usr/share/javascript/;
#}
location /javascript/ {
alias /usr/share/javascript/;
}
}

View File

@ -1,3 +1,3 @@
log_format lm_combined '$remote_addr - $lmremote_user [$time_local] '
log_format lm_app '$remote_addr - $upstream_http_lm_remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
'"$http_referer" "$http_user_agent" $upstream_http_lm_remote_custom';

View File

@ -13,13 +13,13 @@
<VirtualHost %%adresse_ip_eth0:443>
ServerName %%authWebName
SSLEngine on
SSLCertificateFile /etc/ssl/certs/eole.crt
SSLCertificateKeyFile /etc/ssl/private/eole.key
SSLCertificateFile %%server_cert
SSLCertificateKeyFile %%server_key
SSLCertificateChainFile /etc/ssl/certs/ca_local.crt
SSLProtocol all -SSLv3 -SSLv2
SSLProxyEngine on
LogLevel info
LogLevel %%lm_loglevel
ErrorLog /var/log/apache2/portal_error.log
CustomLog /var/log/apache2/portal_access.log common

View File

@ -15,8 +15,7 @@ server {
}
server {
listen 443;
ssl on;
listen 443 ssl;
%if %%cert_type == "letsencrypt"
ssl_certificate %%le_config_dir/live/%%authWebName/cert.pem;
ssl_certificate_key %%le_config_dir/live/%%authWebName/privkey.pem;
@ -83,7 +82,7 @@ server {
# DEBIAN
# If install was made with USEDEBIANLIBS (official releases), uncomment this
#location /javascript/ {
# alias /usr/share/javascript/;
#}
location /javascript/ {
alias /usr/share/javascript/;
}
}