Merge branch 'v2.0' into findUser
This commit is contained in:
commit
cd37ccc35c
|
@ -28,6 +28,21 @@
|
||||||
auth_request_set $headervalue14 $upstream_http_headervalue14;
|
auth_request_set $headervalue14 $upstream_http_headervalue14;
|
||||||
auth_request_set $headername15 $upstream_http_headername15;
|
auth_request_set $headername15 $upstream_http_headername15;
|
||||||
auth_request_set $headervalue15 $upstream_http_headervalue15;
|
auth_request_set $headervalue15 $upstream_http_headervalue15;
|
||||||
|
auth_request_set $deleteheader1 $upstream_http_deleteheader1;
|
||||||
|
auth_request_set $deleteheader2 $upstream_http_deleteheader2;
|
||||||
|
auth_request_set $deleteheader3 $upstream_http_deleteheader3;
|
||||||
|
auth_request_set $deleteheader4 $upstream_http_deleteheader4;
|
||||||
|
auth_request_set $deleteheader5 $upstream_http_deleteheader5;
|
||||||
|
auth_request_set $deleteheader6 $upstream_http_deleteheader6;
|
||||||
|
auth_request_set $deleteheader7 $upstream_http_deleteheader7;
|
||||||
|
auth_request_set $deleteheader8 $upstream_http_deleteheader8;
|
||||||
|
auth_request_set $deleteheader9 $upstream_http_deleteheader9;
|
||||||
|
auth_request_set $deleteheader10 $upstream_http_deleteheader10;
|
||||||
|
auth_request_set $deleteheader11 $upstream_http_deleteheader11;
|
||||||
|
auth_request_set $deleteheader12 $upstream_http_deleteheader12;
|
||||||
|
auth_request_set $deleteheader13 $upstream_http_deleteheader13;
|
||||||
|
auth_request_set $deleteheader14 $upstream_http_deleteheader14;
|
||||||
|
auth_request_set $deleteheader15 $upstream_http_deleteheader15;
|
||||||
auth_request_set $lmcookie $upstream_http_cookie;
|
auth_request_set $lmcookie $upstream_http_cookie;
|
||||||
access_by_lua '
|
access_by_lua '
|
||||||
local i = 1
|
local i = 1
|
||||||
|
@ -38,7 +53,16 @@
|
||||||
else
|
else
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
i = i +1
|
i = i + 1
|
||||||
|
end
|
||||||
|
i = 1
|
||||||
|
while true do
|
||||||
|
if ngx.var["deleteheader"..i] ~= nil then
|
||||||
|
ngx.req.clear_header(ngx.var["deleteheader"..i])
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
end
|
end
|
||||||
';
|
';
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,11 @@ Password
|
||||||
reset (default: TRUE).
|
reset (default: TRUE).
|
||||||
- **Allow a user to reset his expired password**: if activated, the
|
- **Allow a user to reset his expired password**: if activated, the
|
||||||
user will be prompted to change password if his password is expired
|
user will be prompted to change password if his password is expired
|
||||||
(default: 0)
|
(default: disabled)
|
||||||
|
- **Search for user before password change**: this option forces the password
|
||||||
|
change module to search for the user again, refreshing its DN. This feature
|
||||||
|
is only useful in rare cases when you use LDAP as the password module, but
|
||||||
|
not as the UserDB module. (default: enabled)
|
||||||
- **IBM Tivoli DS support**: enable this option if you use ITDS. LL::NG
|
- **IBM Tivoli DS support**: enable this option if you use ITDS. LL::NG
|
||||||
will then scan error message to return a more precise error to the
|
will then scan error message to return a more precise error to the
|
||||||
user.
|
user.
|
||||||
|
|
|
@ -192,6 +192,33 @@ In this example we have:
|
||||||
'exportedHeaders/test.example.com' 'Auth-User' '$uid' \
|
'exportedHeaders/test.example.com' 'Auth-User' '$uid' \
|
||||||
'exportedHeaders/test.example.com' 'Auth-Mail' '$mail'
|
'exportedHeaders/test.example.com' 'Auth-Mail' '$mail'
|
||||||
|
|
||||||
|
Configure form replay
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
To add form replay on a host, you need to set the catched URI and
|
||||||
|
the variables to post.
|
||||||
|
|
||||||
|
In this example we have:
|
||||||
|
|
||||||
|
- Host: test.example.com
|
||||||
|
- Catched URI: /login.php
|
||||||
|
- jQuery URL: default
|
||||||
|
|
||||||
|
- Variables:
|
||||||
|
- login: $uid
|
||||||
|
- password: $_password
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 -sep , \
|
||||||
|
addKey \
|
||||||
|
post,test.example.com,'/login.php' jqueryUrl default
|
||||||
|
|
||||||
|
/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 -sep , \
|
||||||
|
addPostVars \
|
||||||
|
post,test.example.com,'/login.php' login '$uid' \
|
||||||
|
post,test.example.com,'/login.php' password '$_password'
|
||||||
|
|
||||||
Configure LDAP authentication backend
|
Configure LDAP authentication backend
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,13 @@ backups and a rollback plan ready!
|
||||||
2.0.10
|
2.0.10
|
||||||
------
|
------
|
||||||
|
|
||||||
|
A vulnerability affecting LemonLDAP::NG installations has been found out when ALL following criteria apply:
|
||||||
|
|
||||||
|
* Your handler server uses Nginx
|
||||||
|
* Your virtual host configuration contains per-URL 'skip' or 'unprotect' access rule
|
||||||
|
|
||||||
|
In this situation, you have to update your LUA configuration file like ``/etc/nginx/nginx-lua-headers.conf``
|
||||||
|
|
||||||
- New dependency: IO::Socket::Timeout
|
- New dependency: IO::Socket::Timeout
|
||||||
- TOTP check tolerates forward AND backward clock drift (totp2fRange)
|
- TOTP check tolerates forward AND backward clock drift (totp2fRange)
|
||||||
- Avoid assignment in expressions option is disabled by default
|
- Avoid assignment in expressions option is disabled by default
|
||||||
|
|
|
@ -30,7 +30,7 @@ use constant DEFAULTCONFBACKENDOPTIONS => (
|
||||||
dirName => '/usr/local/lemonldap-ng/data/conf',
|
dirName => '/usr/local/lemonldap-ng/data/conf',
|
||||||
);
|
);
|
||||||
our $hashParameters = qr/^(?:(?:l(?:o(?:ca(?:lSessionStorageOption|tionRule)|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|(?:(?:d(?:emo|bi)|webID)ExportedVa|exported(?:Heade|Va)|issuerDBGetParamete)r|f(?:indUser(?:Exclud|Search)ingAttribute|acebookExportedVar)|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|macro)s|o(?:idc(?:S(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|RPMetaData(?:(?:Option(?:sExtraClaim)?|ExportedVar|Macro)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node))|penIdExportedVars)|c(?:as(?:A(?:ppMetaData(?:(?:ExportedVar|Option|Macro)s|Node)|ttributes)|S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions))|(?:ustom(?:Plugins|Add)Param|heckUserHiddenHeader|ombModule)s)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option|Macro)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars|fExtra)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
|
our $hashParameters = qr/^(?:(?:l(?:o(?:ca(?:lSessionStorageOption|tionRule)|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|(?:(?:d(?:emo|bi)|webID)ExportedVa|exported(?:Heade|Va)|issuerDBGetParamete)r|f(?:indUser(?:Exclud|Search)ingAttribute|acebookExportedVar)|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|macro)s|o(?:idc(?:S(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|RPMetaData(?:(?:Option(?:sExtraClaim)?|ExportedVar|Macro)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node))|penIdExportedVars)|c(?:as(?:A(?:ppMetaData(?:(?:ExportedVar|Option|Macro)s|Node)|ttributes)|S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions))|(?:ustom(?:Plugins|Add)Param|heckUserHiddenHeader|ombModule)s)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option|Macro)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars|fExtra)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
|
||||||
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|f(?:RemovedUseNotif|OnlyUpgrade)|kip(?:Upgrade|Renew)Confirmation|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Allow(?:PasswordGrant|Offline)|Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:Display(?:Re(?:freshMyRights|setPassword|gister)|CertificateResetByMail|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|ForceAuthn|AntiFrame)|roxyUseSoap)|c(?:o(?:ntextSwitching(?:Allowed2fModifications|StopWithLogout)|mpactConf|rsEnabled)|a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:State|User|XSS)|da)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?|sExplorer)?|y(?:Deleted|Other))|AjaxHook)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|re(?:st(?:(?:Password|Session|Config|Auth)Server|ExportSecretKeys)|freshSessions)|br(?:uteForceProtection(?:IncrementalTempo)?|owsersDontStorePassword)|d(?:is(?:ablePersistentStorage|playSessionId)|biDynamicHashEnabled)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|g(?:roupsBeforeMacros|lobalLogoutTimer)|a(?:voidAssignment|ctiveTimer)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|krb(?:RemoveDomain|ByJs)|(?:wsdlServ|findUs)er)$/;
|
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|f(?:RemovedUseNotif|OnlyUpgrade)|kip(?:Upgrade|Renew)Confirmation|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Allow(?:PasswordGrant|Offline)|Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:Display(?:Re(?:freshMyRights|setPassword|gister)|CertificateResetByMail|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|ForceAuthn|AntiFrame)|roxyUseSoap)|l(?:dap(?:(?:G(?:roup(?:DecodeSearchedValu|Recursiv)|etUserBeforePasswordChang)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|c(?:o(?:ntextSwitching(?:Allowed2fModifications|StopWithLogout)|mpactConf|rsEnabled)|a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:State|User|XSS)|da)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?|sExplorer)?|y(?:Deleted|Other))|AjaxHook)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|re(?:st(?:(?:Password|Session|Config|Auth)Server|ExportSecretKeys)|freshSessions)|br(?:uteForceProtection(?:IncrementalTempo)?|owsersDontStorePassword)|d(?:is(?:ablePersistentStorage|playSessionId)|biDynamicHashEnabled)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|g(?:roupsBeforeMacros|lobalLogoutTimer)|a(?:voidAssignment|ctiveTimer)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|krb(?:RemoveDomain|ByJs)|(?:wsdlServ|findUs)er)$/;
|
||||||
|
|
||||||
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );
|
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ our $authParameters = {
|
||||||
githubParams => [qw(githubAuthnLevel githubClientID githubClientSecret githubUserField githubScope)],
|
githubParams => [qw(githubAuthnLevel githubClientID githubClientSecret githubUserField githubScope)],
|
||||||
gpgParams => [qw(gpgAuthnLevel gpgDb)],
|
gpgParams => [qw(gpgAuthnLevel gpgDb)],
|
||||||
kerberosParams => [qw(krbAuthnLevel krbKeytab krbByJs krbRemoveDomain krbAllowedDomains)],
|
kerberosParams => [qw(krbAuthnLevel krbKeytab krbByJs krbRemoveDomain krbAllowedDomains)],
|
||||||
ldapParams => [qw(ldapAuthnLevel ldapExportedVars ldapServer ldapPort ldapVerify ldapBase managerDn managerPassword ldapTimeout ldapIOTimeout ldapVersion ldapRaw ldapCAFile ldapCAPath LDAPFilter AuthLDAPFilter mailLDAPFilter ldapSearchDeref ldapGroupBase ldapGroupObjectClass ldapGroupAttributeName ldapGroupAttributeNameUser ldapGroupAttributeNameSearch ldapGroupDecodeSearchedValue ldapGroupRecursive ldapGroupAttributeNameGroup ldapPpolicyControl ldapSetPassword ldapChangePasswordAsUser ldapPwdEnc ldapUsePasswordResetAttribute ldapPasswordResetAttribute ldapPasswordResetAttributeValue ldapAllowResetExpiredPassword ldapITDS)],
|
ldapParams => [qw(ldapAuthnLevel ldapExportedVars ldapServer ldapPort ldapVerify ldapBase managerDn managerPassword ldapTimeout ldapIOTimeout ldapVersion ldapRaw ldapCAFile ldapCAPath LDAPFilter AuthLDAPFilter mailLDAPFilter ldapSearchDeref ldapGroupBase ldapGroupObjectClass ldapGroupAttributeName ldapGroupAttributeNameUser ldapGroupAttributeNameSearch ldapGroupDecodeSearchedValue ldapGroupRecursive ldapGroupAttributeNameGroup ldapPpolicyControl ldapSetPassword ldapChangePasswordAsUser ldapPwdEnc ldapUsePasswordResetAttribute ldapPasswordResetAttribute ldapPasswordResetAttributeValue ldapAllowResetExpiredPassword ldapGetUserBeforePasswordChange ldapITDS)],
|
||||||
linkedinParams => [qw(linkedInAuthnLevel linkedInClientID linkedInClientSecret linkedInFields linkedInUserField linkedInScope)],
|
linkedinParams => [qw(linkedInAuthnLevel linkedInClientID linkedInClientSecret linkedInFields linkedInUserField linkedInScope)],
|
||||||
nullParams => [qw(nullAuthnLevel)],
|
nullParams => [qw(nullAuthnLevel)],
|
||||||
oidcParams => [qw(oidcAuthnLevel oidcRPCallbackGetParam oidcRPStateTimeout)],
|
oidcParams => [qw(oidcAuthnLevel oidcRPCallbackGetParam oidcRPStateTimeout)],
|
||||||
|
|
|
@ -22,7 +22,10 @@ for ( my $i = 0 ; $i < @ARGV ; $i++ ) {
|
||||||
|
|
||||||
$action ||= "help";
|
$action ||= "help";
|
||||||
|
|
||||||
if ( $action =~ /^(?:[gs]et|del|(?:add|del)Key|save|restore|rollback)$/ ) {
|
if ( $action =~
|
||||||
|
/^(?:[gs]et|del|(?:add|del)Key|(?:add|del)PostVars|save|restore|rollback)$/
|
||||||
|
)
|
||||||
|
{
|
||||||
eval { require Lemonldap::NG::Manager::Cli; };
|
eval { require Lemonldap::NG::Manager::Cli; };
|
||||||
die "Manager libraries not available, aborting ($@)" if ($@);
|
die "Manager libraries not available, aborting ($@)" if ($@);
|
||||||
Lemonldap::NG::Manager::Cli->run(@ARGV);
|
Lemonldap::NG::Manager::Cli->run(@ARGV);
|
||||||
|
@ -40,19 +43,21 @@ sub help {
|
||||||
print STDERR qq{Usage: $0 <options> action <parameters>
|
print STDERR qq{Usage: $0 <options> action <parameters>
|
||||||
|
|
||||||
Available actions:
|
Available actions:
|
||||||
- help : print this
|
- help : print this
|
||||||
- info : get currentconfiguration info
|
- info : get currentconfiguration info
|
||||||
- update-cache : force configuration cache to be updated
|
- update-cache : force configuration cache to be updated
|
||||||
- test-email <destination> : send a test email
|
- test-email <destination> : send a test email
|
||||||
- get <keys> : get values of parameters
|
- get <key> : get values of parameters
|
||||||
- set <key> <value> : set parameter(s) value(s)
|
- set <key> <value> : set parameter(s) value(s)
|
||||||
- del <keys> : delete parameters
|
- del <key> : delete parameters
|
||||||
- addKey <key> <subkey> <value> : add or set a subkey in a parameter
|
- addKey <key> <subkey> <value> : add or set a subkey in a parameter
|
||||||
- delKey <key> <subkey> : delete subkey of a parameter
|
- delKey <key> <subkey> : delete subkey of a parameter
|
||||||
- save : export configuration to STDOUT
|
- addPostVars <host> <uri> <key> <value> : add post vars for form replay
|
||||||
- restore - : import configuration from STDIN
|
- delPostVars <host> <uri> <key> : delete post vars for form replay
|
||||||
- restore <file> : import configuration from file
|
- save : export configuration to STDOUT
|
||||||
- rollback : restore previous configuration
|
- restore - : import configuration from STDIN
|
||||||
|
- restore <file> : import configuration from file
|
||||||
|
- rollback : restore previous configuration
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
- yes <0|1> : accept confirmation prompt automatically
|
- yes <0|1> : accept confirmation prompt automatically
|
||||||
|
|
|
@ -228,6 +228,10 @@ sub run {
|
||||||
elsif ( $protection == $class->MAYSKIP
|
elsif ( $protection == $class->MAYSKIP
|
||||||
and $class->grant( $req, $session, $uri, $cond ) eq '999_SKIP' )
|
and $class->grant( $req, $session, $uri, $cond ) eq '999_SKIP' )
|
||||||
{
|
{
|
||||||
|
$class->logger->debug("Access control skipped");
|
||||||
|
$class->updateStatus( $req, 'SKIP' );
|
||||||
|
$class->hideCookie($req);
|
||||||
|
$class->cleanHeaders($req);
|
||||||
return $class->OK;
|
return $class->OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,6 +768,7 @@ sub cleanHeaders {
|
||||||
my ( $class, $req ) = @_;
|
my ( $class, $req ) = @_;
|
||||||
my $vhost = $class->resolveAlias($req);
|
my $vhost = $class->resolveAlias($req);
|
||||||
if ( defined( $class->tsv->{headerList}->{$vhost} ) ) {
|
if ( defined( $class->tsv->{headerList}->{$vhost} ) ) {
|
||||||
|
$class->logger->debug("Remove headers relative to $vhost");
|
||||||
$class->unset_header_in( $req,
|
$class->unset_header_in( $req,
|
||||||
@{ $class->tsv->{headerList}->{$vhost} } );
|
@{ $class->tsv->{headerList}->{$vhost} } );
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ package Lemonldap::NG::Handler::Server::Main;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
|
|
||||||
our $VERSION = '2.0.6';
|
our $VERSION = '2.0.10';
|
||||||
|
|
||||||
use base 'Lemonldap::NG::Handler::PSGI::Main';
|
use base 'Lemonldap::NG::Handler::PSGI::Main';
|
||||||
|
|
||||||
|
@ -25,13 +25,27 @@ sub set_header_in {
|
||||||
push @{ $req->{respHeaders} }, %headers;
|
push @{ $req->{respHeaders} }, %headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
## @method void unset_header_in(array headers)
|
||||||
|
# deletes request headers and push headers that will be removed by LUA
|
||||||
|
# @param headers array containing header names
|
||||||
sub unset_header_in {
|
sub unset_header_in {
|
||||||
my ( $class, $req, $header ) = @_;
|
my ( $class, $req, @headers ) = @_;
|
||||||
$req->{respHeaders} = [ grep { $_ ne $header and $_ ne cgiName($header) }
|
$req->data->{deleteIndex} //= 1;
|
||||||
@{ $req->{respHeaders} } ];
|
my $i = $req->data->{deleteIndex};
|
||||||
delete $req->{env}->{ cgiName($header) };
|
foreach my $header (@headers) {
|
||||||
$header =~ s/-/_/g;
|
$class->logger->debug("Delete header $header");
|
||||||
delete $req->{env}->{$header};
|
$req->{respHeaders} =
|
||||||
|
[ grep { $_ ne $header and $_ ne cgiName($header) }
|
||||||
|
@{ $req->{respHeaders} } ];
|
||||||
|
delete $req->{env}->{ cgiName($header) };
|
||||||
|
push @{ $req->{respHeaders} }, "Deleteheader$i", $header;
|
||||||
|
$i++;
|
||||||
|
push @{ $req->{respHeaders} }, "Deleteheader$i", cgiName($header);
|
||||||
|
$header =~ s/-/_/g;
|
||||||
|
delete $req->{env}->{$header};
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
$req->data->{deleteIndex} = $i;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Inheritence is broken in this case with Debian >= jessie
|
# Inheritence is broken in this case with Debian >= jessie
|
||||||
|
|
|
@ -70,7 +70,7 @@ sub handler {
|
||||||
( 'Content-Length' => 0, Cookie => ( $req->env->{HTTP_COOKIE} // '' ) );
|
( 'Content-Length' => 0, Cookie => ( $req->env->{HTTP_COOKIE} // '' ) );
|
||||||
my $i = 0;
|
my $i = 0;
|
||||||
while ( my ( $k, $v ) = splice( @{ $req->{respHeaders} }, 0, 2 ) ) {
|
while ( my ( $k, $v ) = splice( @{ $req->{respHeaders} }, 0, 2 ) ) {
|
||||||
if ( $k =~ /^(?:Lm-Remote-(?:User|Custom)|Cookie)$/ ) {
|
if ( $k =~ /^(?:Deleteheader\d+|Lm-Remote-(?:User|Custom)|Cookie)$/ ) {
|
||||||
push @convertedHdrs, $k, $v;
|
push @convertedHdrs, $k, $v;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -204,11 +204,7 @@ count(3);
|
||||||
ok( $res = $client->_get( '/skipif/za', undef, 'test1.example.com' ),
|
ok( $res = $client->_get( '/skipif/za', undef, 'test1.example.com' ),
|
||||||
'Test skip() rule 1' );
|
'Test skip() rule 1' );
|
||||||
ok( $res->[0] == 302, ' Code is 302' ) or explain( $res, 302 );
|
ok( $res->[0] == 302, ' Code is 302' ) or explain( $res, 302 );
|
||||||
$SKIPUSER = 1;
|
count(2);
|
||||||
ok( $res = $client->_get( '/skipif/zz', undef, 'test1.example.com' ),
|
|
||||||
'Test skip() rule 2' );
|
|
||||||
ok( $res->[0] == 200, ' Code is 200' ) or explain( $res, 200 );
|
|
||||||
count(4);
|
|
||||||
|
|
||||||
# Wildcards
|
# Wildcards
|
||||||
ok(
|
ok(
|
||||||
|
@ -219,6 +215,20 @@ ok(
|
||||||
ok( $res->[0] == 200, ' Code is 200' ) or explain( $res, 200 );
|
ok( $res->[0] == 200, ' Code is 200' ) or explain( $res, 200 );
|
||||||
count(2);
|
count(2);
|
||||||
|
|
||||||
|
# SKIP TESTS
|
||||||
|
$SKIPUSER = 1;
|
||||||
|
|
||||||
|
ok( $res = $client->_get( '/skipif/zz', undef, 'test1.example.com' ),
|
||||||
|
'Test skip() rule 2' );
|
||||||
|
ok( $res->[0] == 200, ' Code is 200' ) or explain( $res, 200 );
|
||||||
|
count(2);
|
||||||
|
|
||||||
|
# Forged headers
|
||||||
|
ok( $res = $client->_get( '/skipif/zz', undef, 'test1.example.com', undef, HTTP_AUTH_USER => 'rtyler' ),
|
||||||
|
'Test skip() with forged header' );
|
||||||
|
ok( $res->[0] == 200, ' Code is 200' ) or explain( $res, 200 );
|
||||||
|
count(2);
|
||||||
|
|
||||||
ok(
|
ok(
|
||||||
$res =
|
$res =
|
||||||
$client->_get( '/', undef, 'foo.example.fr', "lemonldap=$sessionId" ),
|
$client->_get( '/', undef, 'foo.example.fr', "lemonldap=$sessionId" ),
|
||||||
|
@ -295,10 +305,14 @@ clean();
|
||||||
|
|
||||||
sub Lemonldap::NG::Handler::PSGI::handler {
|
sub Lemonldap::NG::Handler::PSGI::handler {
|
||||||
my ( $self, $req ) = @_;
|
my ( $self, $req ) = @_;
|
||||||
unless ($SKIPUSER) {
|
if ($SKIPUSER) {
|
||||||
|
ok( !$req->env->{HTTP_AUTH_USER}, 'No HTTP_AUTH_USER' )
|
||||||
|
or explain( $req->env->{HTTP_AUTH_USER}, '<empty>' );
|
||||||
|
}
|
||||||
|
else {
|
||||||
ok( $req->env->{HTTP_AUTH_USER} eq 'dwho', 'Header is given to app' )
|
ok( $req->env->{HTTP_AUTH_USER} eq 'dwho', 'Header is given to app' )
|
||||||
or explain( $req->env->{HTTP_AUTH_USER}, 'dwho' );
|
or explain( $req->env->{HTTP_AUTH_USER}, 'dwho' );
|
||||||
count(1);
|
|
||||||
}
|
}
|
||||||
|
count(1);
|
||||||
return [ 200, [ 'Content-Type', 'text/plain' ], ['Hello'] ];
|
return [ 200, [ 'Content-Type', 'text/plain' ], ['Hello'] ];
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,6 +191,28 @@ ok(
|
||||||
);
|
);
|
||||||
count(3);
|
count(3);
|
||||||
|
|
||||||
|
# Clean headers
|
||||||
|
ok(
|
||||||
|
$res = $client->_get(
|
||||||
|
'/skipif/zz', undef, 'test1.example.com', undef,
|
||||||
|
HTTP_AUTH_USER => 'rtyler'
|
||||||
|
),
|
||||||
|
'Test skip() with forged header'
|
||||||
|
);
|
||||||
|
ok( $res->[0] == 200, 'Code is 200' ) or explain( $res, 200 );
|
||||||
|
count(2);
|
||||||
|
%h = @{ $res->[1] };
|
||||||
|
my %delete;
|
||||||
|
foreach ( keys %h ) {
|
||||||
|
/^Deleteheader\d$/ and $delete{ $h{$_} }++;
|
||||||
|
}
|
||||||
|
foreach (qw(Cookie HTTP_COOKIE Auth-User HTTP_AUTH_USER)) {
|
||||||
|
ok( $delete{$_}, "Delete command for $_" )
|
||||||
|
or explain( \%h, 'Delete* headers' );
|
||||||
|
ok( !$h{$_}, "$_ is deleted" ) or explain( \%h, 'Delete* headers' );
|
||||||
|
count(2);
|
||||||
|
}
|
||||||
|
|
||||||
done_testing( count() );
|
done_testing( count() );
|
||||||
|
|
||||||
clean();
|
clean();
|
||||||
|
|
|
@ -5,7 +5,6 @@ sub accessToTrace {
|
||||||
my $custom = $hash->{custom};
|
my $custom = $hash->{custom};
|
||||||
my $req = $hash->{req};
|
my $req = $hash->{req};
|
||||||
my $vhost = $hash->{vhost};
|
my $vhost = $hash->{vhost};
|
||||||
my $custom = $hash->{custom};
|
|
||||||
my $params = $hash->{params};
|
my $params = $hash->{params};
|
||||||
my $session = $hash->{session};
|
my $session = $hash->{session};
|
||||||
|
|
||||||
|
|
|
@ -166,6 +166,16 @@ sub updateOidcRp {
|
||||||
return $self->sendError( $req, "Invalid input: " . $req->error, 400 )
|
return $self->sendError( $req, "Invalid input: " . $req->error, 400 )
|
||||||
unless ($update);
|
unless ($update);
|
||||||
|
|
||||||
|
if ( $update->{redirectUris} ) {
|
||||||
|
if ( ref( $update->{redirectUris} ) eq "ARRAY" ) {
|
||||||
|
$update->{options}->{redirectUris} = $update->{redirectUris};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return $self->sendError( $req,
|
||||||
|
'Invalid input: redirectUris must be an array', 400 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$self->logger->debug(
|
$self->logger->debug(
|
||||||
"[API] OIDC RP $confKey configuration update requested");
|
"[API] OIDC RP $confKey configuration update requested");
|
||||||
|
|
||||||
|
@ -294,7 +304,11 @@ sub _getOidcRpByConfKey {
|
||||||
my $macros = $conf->{oidcRPMetaDataMacros}->{$confKey} || {};
|
my $macros = $conf->{oidcRPMetaDataMacros}->{$confKey} || {};
|
||||||
|
|
||||||
# Redirect URIs, filled later
|
# Redirect URIs, filled later
|
||||||
my $redirectUris;
|
my $redirectUris = $self->_translateValueConfToApi(
|
||||||
|
'oidcRPMetaDataOptionsRedirectUris',
|
||||||
|
$conf->{oidcRPMetaDataOptions}->{$confKey}
|
||||||
|
->{oidcRPMetaDataOptionsRedirectUris}
|
||||||
|
);
|
||||||
|
|
||||||
# Get options
|
# Get options
|
||||||
my $options = {};
|
my $options = {};
|
||||||
|
|
|
@ -1685,6 +1685,10 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
|
||||||
'LDAPFilter' => {
|
'LDAPFilter' => {
|
||||||
'type' => 'text'
|
'type' => 'text'
|
||||||
},
|
},
|
||||||
|
'ldapGetUserBeforePasswordChange' => {
|
||||||
|
'default' => 0,
|
||||||
|
'type' => 'bool'
|
||||||
|
},
|
||||||
'ldapGroupAttributeName' => {
|
'ldapGroupAttributeName' => {
|
||||||
'default' => 'member',
|
'default' => 'member',
|
||||||
'type' => 'text'
|
'type' => 'text'
|
||||||
|
|
|
@ -3324,6 +3324,10 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
|
||||||
default => 0,
|
default => 0,
|
||||||
type => 'bool',
|
type => 'bool',
|
||||||
},
|
},
|
||||||
|
ldapGetUserBeforePasswordChange => {
|
||||||
|
default => 0,
|
||||||
|
type => 'bool',
|
||||||
|
},
|
||||||
ldapSearchDeref => {
|
ldapSearchDeref => {
|
||||||
type => 'select',
|
type => 'select',
|
||||||
select => [
|
select => [
|
||||||
|
|
|
@ -302,6 +302,7 @@ sub tree {
|
||||||
'ldapPasswordResetAttribute',
|
'ldapPasswordResetAttribute',
|
||||||
'ldapPasswordResetAttributeValue',
|
'ldapPasswordResetAttributeValue',
|
||||||
'ldapAllowResetExpiredPassword',
|
'ldapAllowResetExpiredPassword',
|
||||||
|
'ldapGetUserBeforePasswordChange',
|
||||||
'ldapITDS'
|
'ldapITDS'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,7 +7,7 @@ use Data::Dumper;
|
||||||
use JSON;
|
use JSON;
|
||||||
use Lemonldap::NG::Common::Conf::ReConstants;
|
use Lemonldap::NG::Common::Conf::ReConstants;
|
||||||
|
|
||||||
our $VERSION = '2.0.9';
|
our $VERSION = '2.0.10';
|
||||||
$Data::Dumper::Useperl = 1;
|
$Data::Dumper::Useperl = 1;
|
||||||
|
|
||||||
extends('Lemonldap::NG::Manager::Cli::Lib');
|
extends('Lemonldap::NG::Manager::Cli::Lib');
|
||||||
|
@ -43,6 +43,23 @@ sub get {
|
||||||
print "$key has the following keys:\n";
|
print "$key has the following keys:\n";
|
||||||
print " $_\n" foreach ( sort keys %$value );
|
print " $_\n" foreach ( sort keys %$value );
|
||||||
}
|
}
|
||||||
|
elsif ( ref $value eq 'ARRAY' ) {
|
||||||
|
print "$key is an array with values:\n";
|
||||||
|
foreach my $avalue (@$value) {
|
||||||
|
if ( ref $avalue eq 'HASH' ) {
|
||||||
|
print "\tHash with following keys:\n";
|
||||||
|
print "\t\t$_\n" foreach ( sort keys %$avalue );
|
||||||
|
}
|
||||||
|
elsif ( ref $value eq 'ARRAY' ) {
|
||||||
|
print "\tArray with following keys:\n";
|
||||||
|
print "\t\t$_\n" foreach (@$avalue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$avalue //= '';
|
||||||
|
print "\tValue = $avalue\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
$value //= '';
|
$value //= '';
|
||||||
print "$key = $value\n";
|
print "$key = $value\n";
|
||||||
|
@ -230,6 +247,68 @@ sub delKey {
|
||||||
return $self->_save($new);
|
return $self->_save($new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub addPostVars {
|
||||||
|
my $self = shift;
|
||||||
|
unless ( @_ % 4 == 0 ) {
|
||||||
|
die 'usage: "addPostVars (?:vhost uri key value)+';
|
||||||
|
}
|
||||||
|
my @list;
|
||||||
|
while (@_) {
|
||||||
|
my $vhost = shift;
|
||||||
|
my $uri = shift;
|
||||||
|
my $key = shift;
|
||||||
|
my $value = shift;
|
||||||
|
$self->logger->info(
|
||||||
|
"CLI: Append post vars $key $value to URI $uri for vhost $vhost");
|
||||||
|
push @list, [ $vhost, $uri, $key, $value ];
|
||||||
|
}
|
||||||
|
require Clone;
|
||||||
|
my $new = Clone::clone( $self->mgr->hLoadedPlugins->{conf}->currentConf );
|
||||||
|
foreach my $el (@list) {
|
||||||
|
$new->{post}->{ $el->[0] }->{ $el->[1] }->{vars} = []
|
||||||
|
unless ( defined $new->{post}->{ $el->[0] }->{ $el->[1] }->{vars} );
|
||||||
|
push(
|
||||||
|
@{ $new->{post}->{ $el->[0] }->{ $el->[1] }->{vars} },
|
||||||
|
[ $el->[2], $el->[3] ]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return $self->_save($new);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub delPostVars {
|
||||||
|
my $self = shift;
|
||||||
|
unless ( @_ % 3 == 0 ) {
|
||||||
|
die 'usage: "delPostVars (?:vhost uri key)+';
|
||||||
|
}
|
||||||
|
my @list;
|
||||||
|
while (@_) {
|
||||||
|
my $vhost = shift;
|
||||||
|
my $uri = shift;
|
||||||
|
my $key = shift;
|
||||||
|
$self->logger->info(
|
||||||
|
"CLI: Delete post vars $key from URI $uri for vhost $vhost");
|
||||||
|
push @list, [ $vhost, $uri, $key ];
|
||||||
|
}
|
||||||
|
require Clone;
|
||||||
|
my $new = Clone::clone( $self->mgr->hLoadedPlugins->{conf}->currentConf );
|
||||||
|
foreach my $el (@list) {
|
||||||
|
$new->{post}->{ $el->[0] }->{ $el->[1] }->{vars} = []
|
||||||
|
unless ( defined $new->{post}->{ $el->[0] }->{ $el->[1] }->{vars} );
|
||||||
|
for (
|
||||||
|
my $i = 0 ;
|
||||||
|
$i <= $#{ $new->{post}->{ $el->[0] }->{ $el->[1] }->{vars} } ;
|
||||||
|
$i++
|
||||||
|
)
|
||||||
|
{
|
||||||
|
delete( $new->{post}->{ $el->[0] }->{ $el->[1] }->{vars}->[$i] )
|
||||||
|
if (
|
||||||
|
$new->{post}->{ $el->[0] }->{ $el->[1] }->{vars}->[$i]->[0] eq
|
||||||
|
$el->[2] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $self->_save($new);
|
||||||
|
}
|
||||||
|
|
||||||
sub lastCfg {
|
sub lastCfg {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
$self->logger->info("CLI: Retrieve last conf.");
|
$self->logger->info("CLI: Retrieve last conf.");
|
||||||
|
@ -337,7 +416,8 @@ sub _setKey {
|
||||||
sub _save {
|
sub _save {
|
||||||
my ( $self, $new ) = @_;
|
my ( $self, $new ) = @_;
|
||||||
require Lemonldap::NG::Manager::Conf::Parser;
|
require Lemonldap::NG::Manager::Conf::Parser;
|
||||||
my $parser = Lemonldap::NG::Manager::Conf::Parser->new( {
|
my $parser = Lemonldap::NG::Manager::Conf::Parser->new(
|
||||||
|
{
|
||||||
newConf => $new,
|
newConf => $new,
|
||||||
refConf => $self->mgr->hLoadedPlugins->{conf}->currentConf,
|
refConf => $self->mgr->hLoadedPlugins->{conf}->currentConf,
|
||||||
req => $self->req
|
req => $self->req
|
||||||
|
@ -432,11 +512,12 @@ sub run {
|
||||||
die 'nothing to do, aborting';
|
die 'nothing to do, aborting';
|
||||||
}
|
}
|
||||||
my $action = shift;
|
my $action = shift;
|
||||||
unless (
|
unless ( $action =~
|
||||||
$action =~ /^(?:get|set|del|addKey|delKey|save|restore|rollback)$/ )
|
/^(?:get|set|del|addKey|delKey|addPostVars|delPostVars|save|restore|rollback)$/
|
||||||
|
)
|
||||||
{
|
{
|
||||||
die
|
die
|
||||||
"Unknown action $action. Only get, set, del, addKey, delKey, save, restore, rollback allowed";
|
"Unknown action $action. Only get, set, del, addKey, delKey, addPostVars, delPostVars, save, restore, rollback allowed";
|
||||||
}
|
}
|
||||||
|
|
||||||
unless ( $action eq "restore" ) {
|
unless ( $action eq "restore" ) {
|
||||||
|
|
|
@ -443,6 +443,7 @@
|
||||||
"ldapFilters":"فلتر",
|
"ldapFilters":"فلتر",
|
||||||
"LDAPFilter":"فلتر الاعْتيادي",
|
"LDAPFilter":"فلتر الاعْتيادي",
|
||||||
"ldapGroupAttributeName":"السمات المستهدف",
|
"ldapGroupAttributeName":"السمات المستهدف",
|
||||||
|
"ldapGetUserBeforePasswordChange":"Search for user before password change",
|
||||||
"ldapGroupAttributeNameGroup":"سمات مصدر المجموعة",
|
"ldapGroupAttributeNameGroup":"سمات مصدر المجموعة",
|
||||||
"ldapGroupAttributeNameSearch":"السمات التي تم البحث عنها",
|
"ldapGroupAttributeNameSearch":"السمات التي تم البحث عنها",
|
||||||
"ldapGroupAttributeNameUser":"سمة مصدر المستخدم",
|
"ldapGroupAttributeNameUser":"سمة مصدر المستخدم",
|
||||||
|
|
|
@ -442,6 +442,7 @@
|
||||||
"ldapExportedVars":"Exported variables",
|
"ldapExportedVars":"Exported variables",
|
||||||
"ldapFilters":"Filters",
|
"ldapFilters":"Filters",
|
||||||
"LDAPFilter":"Default filter",
|
"LDAPFilter":"Default filter",
|
||||||
|
"ldapGetUserBeforePasswordChange":"Search for user before password change",
|
||||||
"ldapGroupAttributeName":"Target attribute",
|
"ldapGroupAttributeName":"Target attribute",
|
||||||
"ldapGroupAttributeNameGroup":"Group source attribute",
|
"ldapGroupAttributeNameGroup":"Group source attribute",
|
||||||
"ldapGroupAttributeNameSearch":"Searched attributes",
|
"ldapGroupAttributeNameSearch":"Searched attributes",
|
||||||
|
|
|
@ -442,6 +442,7 @@
|
||||||
"ldapExportedVars":"Exported variables",
|
"ldapExportedVars":"Exported variables",
|
||||||
"ldapFilters":"Filters",
|
"ldapFilters":"Filters",
|
||||||
"LDAPFilter":"Default filter",
|
"LDAPFilter":"Default filter",
|
||||||
|
"ldapGetUserBeforePasswordChange":"Search for user before password change",
|
||||||
"ldapGroupAttributeName":"Target attribute",
|
"ldapGroupAttributeName":"Target attribute",
|
||||||
"ldapGroupAttributeNameGroup":"Group source attribute",
|
"ldapGroupAttributeNameGroup":"Group source attribute",
|
||||||
"ldapGroupAttributeNameSearch":"Searched attributes",
|
"ldapGroupAttributeNameSearch":"Searched attributes",
|
||||||
|
|
|
@ -442,6 +442,7 @@
|
||||||
"ldapExportedVars":"Variables exportadas",
|
"ldapExportedVars":"Variables exportadas",
|
||||||
"ldapFilters":"Filtros",
|
"ldapFilters":"Filtros",
|
||||||
"LDAPFilter":"Filtro por defecto",
|
"LDAPFilter":"Filtro por defecto",
|
||||||
|
"ldapGetUserBeforePasswordChange":"Search for user before password change",
|
||||||
"ldapGroupAttributeName":"Atributo objetivo",
|
"ldapGroupAttributeName":"Atributo objetivo",
|
||||||
"ldapGroupAttributeNameGroup":"Group source attribute",
|
"ldapGroupAttributeNameGroup":"Group source attribute",
|
||||||
"ldapGroupAttributeNameSearch":"Atributos buscados",
|
"ldapGroupAttributeNameSearch":"Atributos buscados",
|
||||||
|
|
|
@ -442,6 +442,7 @@
|
||||||
"ldapExportedVars":"Variables exportées",
|
"ldapExportedVars":"Variables exportées",
|
||||||
"ldapFilters":"Filtres",
|
"ldapFilters":"Filtres",
|
||||||
"LDAPFilter":"Filtre par défaut",
|
"LDAPFilter":"Filtre par défaut",
|
||||||
|
"ldapGetUserBeforePasswordChange":"Rechercher l'utilisateur avant le changement de mot de passe",
|
||||||
"ldapGroupAttributeName":"Attribut cible",
|
"ldapGroupAttributeName":"Attribut cible",
|
||||||
"ldapGroupAttributeNameGroup":"Attribut source groupe",
|
"ldapGroupAttributeNameGroup":"Attribut source groupe",
|
||||||
"ldapGroupAttributeNameSearch":"Attributs recherchés",
|
"ldapGroupAttributeNameSearch":"Attributs recherchés",
|
||||||
|
|
|
@ -442,6 +442,7 @@
|
||||||
"ldapExportedVars":"Variabili esportate",
|
"ldapExportedVars":"Variabili esportate",
|
||||||
"ldapFilters":"Filtri",
|
"ldapFilters":"Filtri",
|
||||||
"LDAPFilter":"Filtro predefinito",
|
"LDAPFilter":"Filtro predefinito",
|
||||||
|
"ldapGetUserBeforePasswordChange":"Search for user before password change",
|
||||||
"ldapGroupAttributeName":"Attributo target",
|
"ldapGroupAttributeName":"Attributo target",
|
||||||
"ldapGroupAttributeNameGroup":"Attributo del gruppo sorgente",
|
"ldapGroupAttributeNameGroup":"Attributo del gruppo sorgente",
|
||||||
"ldapGroupAttributeNameSearch":"Attributi ricercati",
|
"ldapGroupAttributeNameSearch":"Attributi ricercati",
|
||||||
|
|
|
@ -442,6 +442,7 @@
|
||||||
"ldapExportedVars":"Wyeksportowane zmienne",
|
"ldapExportedVars":"Wyeksportowane zmienne",
|
||||||
"ldapFilters":"Filtry",
|
"ldapFilters":"Filtry",
|
||||||
"LDAPFilter":"Domyślny filtr",
|
"LDAPFilter":"Domyślny filtr",
|
||||||
|
"ldapGetUserBeforePasswordChange":"Search for user before password change",
|
||||||
"ldapGroupAttributeName":"Atrybut docelowy",
|
"ldapGroupAttributeName":"Atrybut docelowy",
|
||||||
"ldapGroupAttributeNameGroup":"Atrybut źródła grupy",
|
"ldapGroupAttributeNameGroup":"Atrybut źródła grupy",
|
||||||
"ldapGroupAttributeNameSearch":"Szukane atrybuty",
|
"ldapGroupAttributeNameSearch":"Szukane atrybuty",
|
||||||
|
|
|
@ -442,6 +442,7 @@
|
||||||
"ldapExportedVars":"Dışa aktarılan değişkenler",
|
"ldapExportedVars":"Dışa aktarılan değişkenler",
|
||||||
"ldapFilters":"Filtreler",
|
"ldapFilters":"Filtreler",
|
||||||
"LDAPFilter":"Varsayılan filtre",
|
"LDAPFilter":"Varsayılan filtre",
|
||||||
|
"ldapGetUserBeforePasswordChange":"Search for user before password change",
|
||||||
"ldapGroupAttributeName":"Hedef nitelik",
|
"ldapGroupAttributeName":"Hedef nitelik",
|
||||||
"ldapGroupAttributeNameGroup":"Grup kaynağı niteliği",
|
"ldapGroupAttributeNameGroup":"Grup kaynağı niteliği",
|
||||||
"ldapGroupAttributeNameSearch":"Aranan nitelikler",
|
"ldapGroupAttributeNameSearch":"Aranan nitelikler",
|
||||||
|
|
|
@ -442,6 +442,7 @@
|
||||||
"ldapExportedVars":"Biến đã được xuất",
|
"ldapExportedVars":"Biến đã được xuất",
|
||||||
"ldapFilters":"Bộ lọc",
|
"ldapFilters":"Bộ lọc",
|
||||||
"LDAPFilter":"Bộ lọc mặc định",
|
"LDAPFilter":"Bộ lọc mặc định",
|
||||||
|
"ldapGetUserBeforePasswordChange":"Search for user before password change",
|
||||||
"ldapGroupAttributeName":"Thuộc tính đích",
|
"ldapGroupAttributeName":"Thuộc tính đích",
|
||||||
"ldapGroupAttributeNameGroup":"Thuộc tính nguồn nhóm",
|
"ldapGroupAttributeNameGroup":"Thuộc tính nguồn nhóm",
|
||||||
"ldapGroupAttributeNameSearch":"Thuộc tính đã tìm kiếm",
|
"ldapGroupAttributeNameSearch":"Thuộc tính đã tìm kiếm",
|
||||||
|
|
|
@ -442,6 +442,7 @@
|
||||||
"ldapExportedVars":"Exported variables",
|
"ldapExportedVars":"Exported variables",
|
||||||
"ldapFilters":"Filters",
|
"ldapFilters":"Filters",
|
||||||
"LDAPFilter":"Default filter",
|
"LDAPFilter":"Default filter",
|
||||||
|
"ldapGetUserBeforePasswordChange":"Search for user before password change",
|
||||||
"ldapGroupAttributeName":"Target attribute",
|
"ldapGroupAttributeName":"Target attribute",
|
||||||
"ldapGroupAttributeNameGroup":"Group source attribute",
|
"ldapGroupAttributeNameGroup":"Group source attribute",
|
||||||
"ldapGroupAttributeNameSearch":"Searched attributes",
|
"ldapGroupAttributeNameSearch":"Searched attributes",
|
||||||
|
|
|
@ -442,6 +442,7 @@
|
||||||
"ldapExportedVars":"已匯出的變數",
|
"ldapExportedVars":"已匯出的變數",
|
||||||
"ldapFilters":"過濾器",
|
"ldapFilters":"過濾器",
|
||||||
"LDAPFilter":"預設過濾器",
|
"LDAPFilter":"預設過濾器",
|
||||||
|
"ldapGetUserBeforePasswordChange":"Search for user before password change",
|
||||||
"ldapGroupAttributeName":"目標屬性",
|
"ldapGroupAttributeName":"目標屬性",
|
||||||
"ldapGroupAttributeNameGroup":"群組來源屬性",
|
"ldapGroupAttributeNameGroup":"群組來源屬性",
|
||||||
"ldapGroupAttributeNameSearch":"已搜尋的屬性",
|
"ldapGroupAttributeNameSearch":"已搜尋的屬性",
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -21,7 +21,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
||||||
PE_UNAUTHORIZEDPARTNER
|
PE_UNAUTHORIZEDPARTNER
|
||||||
);
|
);
|
||||||
|
|
||||||
our $VERSION = '2.0.9';
|
our $VERSION = '2.0.10';
|
||||||
|
|
||||||
extends 'Lemonldap::NG::Portal::Main::Issuer',
|
extends 'Lemonldap::NG::Portal::Main::Issuer',
|
||||||
'Lemonldap::NG::Portal::Lib::SAML';
|
'Lemonldap::NG::Portal::Lib::SAML';
|
||||||
|
@ -680,20 +680,20 @@ sub run {
|
||||||
unless ( defined $value ) {
|
unless ( defined $value ) {
|
||||||
if ($mandatory) {
|
if ($mandatory) {
|
||||||
$self->logger->error(
|
$self->logger->error(
|
||||||
"Session key $_ is required to set SAML $name attribute"
|
"Session key $_ is required to set SAML $name attribute ($sp)"
|
||||||
);
|
);
|
||||||
return PE_ISSUERMISSINGREQATTR;
|
return PE_ISSUERMISSINGREQATTR;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$self->logger->debug(
|
$self->logger->debug(
|
||||||
"SAML2 attribute $name has no value but is not mandatory, skip it"
|
"SAML2 attribute $name has no value but is not mandatory ($sp), skip it"
|
||||||
);
|
);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->logger->debug(
|
$self->logger->debug(
|
||||||
"SAML2 attribute $name will be set with $_ session key");
|
"SAML2 attribute $name will be set with $_ session key ($sp)");
|
||||||
|
|
||||||
# SAML2 attribute
|
# SAML2 attribute
|
||||||
my $attribute =
|
my $attribute =
|
||||||
|
|
|
@ -30,6 +30,12 @@ sub confirm {
|
||||||
|
|
||||||
sub modifyPassword {
|
sub modifyPassword {
|
||||||
my ( $self, $req, $pwd, $useMail ) = @_;
|
my ( $self, $req, $pwd, $useMail ) = @_;
|
||||||
|
|
||||||
|
# If the password change is done in a different backend,
|
||||||
|
# we need to reload the correct DN
|
||||||
|
$self->getUser( $req, useMail => $useMail )
|
||||||
|
if $self->conf->{ldapGetUserBeforePasswordChange};
|
||||||
|
|
||||||
my $dn = $req->data->{dn} || $req->sessionInfo->{_dn};
|
my $dn = $req->data->{dn} || $req->sessionInfo->{_dn};
|
||||||
unless ($dn) {
|
unless ($dn) {
|
||||||
$self->logger->error('"dn" is not set, abort password modification');
|
$self->logger->error('"dn" is not set, abort password modification');
|
||||||
|
|
|
@ -37,7 +37,7 @@ sub init {
|
||||||
$tmp =
|
$tmp =
|
||||||
$self->loadModule( "::Password::$mod->{type}", $mod->{over} );
|
$self->loadModule( "::Password::$mod->{type}", $mod->{over} );
|
||||||
unless ($tmp) {
|
unless ($tmp) {
|
||||||
$self->notice("Unable to load Password::$mod->{type}");
|
$self->logger->notice("Unable to load Password::$mod->{type}");
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,11 @@ sub modifyPassword {
|
||||||
my $dn;
|
my $dn;
|
||||||
my $requireOldPassword;
|
my $requireOldPassword;
|
||||||
|
|
||||||
|
# If the password change is done in a different backend,
|
||||||
|
# we need to reload the correct DN
|
||||||
|
$self->getUser( $req, useMail => $useMail )
|
||||||
|
if $self->conf->{ldapGetUserBeforePasswordChange};
|
||||||
|
|
||||||
if ( $req->data->{dn} ) {
|
if ( $req->data->{dn} ) {
|
||||||
$dn = $req->data->{dn};
|
$dn = $req->data->{dn};
|
||||||
$requireOldPassword = $self->requireOldPwdRule->( $req, $req->userData );
|
$requireOldPassword = $self->requireOldPwdRule->( $req, $req->userData );
|
||||||
|
|
Loading…
Reference in New Issue
Block a user