From a731fbf66cfc9eb8894549e0dc65507c003e5c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Oudot?= Date: Fri, 27 Sep 2013 22:22:27 +0000 Subject: [PATCH] Manage reset at next logon message from AD (#513, #LEMONLDAP-409) --- .../lib/Lemonldap/NG/Portal/AuthAD.pm | 31 ++++++++++- .../lib/Lemonldap/NG/Portal/_LDAP.pm | 53 ++++++++++++------- 2 files changed, 64 insertions(+), 20 deletions(-) diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/AuthAD.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/AuthAD.pm index 0e90e075e..bd03077b4 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/AuthAD.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/AuthAD.pm @@ -8,10 +8,23 @@ package Lemonldap::NG::Portal::AuthAD; use strict; our $VERSION = '1.3.0'; +use Lemonldap::NG::Portal::Simple; use base qw(Lemonldap::NG::Portal::AuthLDAP); *_formateFilter = *Lemonldap::NG::Portal::UserDBAD::formateFilter; +## @apmethod int authInit() +# Add specific attributes for search +# @return Lemonldap::NG::Portal constant +sub authInit { + my $self = shift; + + $self->{exportedVars}->{_AD_pwdLastSet} = 'pwdLastSet'; + $self->{exportedVars}->{_AD_userAccountControl} = 'userAccountControl'; + + return $self->SUPER::authInit(); +} + ## @apmethod int authenticate() # Authenticate user by LDAP mechanism. # Check AD specific attribute to get password state. @@ -21,8 +34,22 @@ sub authenticate { my $res = $self->SUPER::authenticate; - # Check specific AD attributes - # TODO + unless ( $res == PE_OK ) { + + # Check specific AD attributes + my $pls = $self->{entry}->get_value('pwdLastSet'); + + # Password must be changed if pwdLastSet 0 + if ( $pls == 0 ) { + $self->lmLog( "[AD] User must change its password", 'debug' ); + return PE_PP_CHANGE_AFTER_RESET; + } + + } + + # Remember password if password reset needed + $self->{oldpassword} = $self->{password} + if ( $res == PE_PP_CHANGE_AFTER_RESET ); return $res; } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_LDAP.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_LDAP.pm index 5ba2b9799..ed46e506d 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_LDAP.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_LDAP.pm @@ -248,12 +248,13 @@ sub userModifyPassword { if ($ad) { $ppolicyControl = 0; $setPassword = 0; - $asUser = 0; $passwordAttribute = "unicodePwd"; # Encode password for AD $newpassword = utf8( chr(34) . $newpassword . chr(34) )->utf16le(); - + if ($oldpassword) { + $oldpassword = utf8( chr(34) . $oldpassword . chr(34) )->utf16le(); + } $self->{portal}->lmLog( "Active Directory mode enabled", 'debug' ); } @@ -294,27 +295,41 @@ sub userModifyPassword { } } else { - if ($requireOldPassword) { - return PE_MUST_SUPPLY_OLD_PASSWORD if ( !$oldpassword ); + # AD specific + # Change password as user with a delete/add modification + if ( $ad and $oldpassword ) { - # Check old password with a bind - $mesg = $self->bind( $dn, password => $oldpassword ); - if ( $mesg->code != 0 ) { - $self->{portal}->lmLog( "Bad old password", 'debug' ); - return PE_BADOLDPASSWORD; - } + $mesg = $self->modify( + $dn, + delete => { $passwordAttribute => $oldpassword }, + add => { $passwordAttribute => $newpassword } + ); - # Rebind as Manager only if user is not granted to change its password - $self->bind() unless $asUser; } - # Use standard modification - $mesg = - $self->modify( $dn, - replace => { $passwordAttribute => $newpassword } ); - } + else { + if ($requireOldPassword) { + return PE_MUST_SUPPLY_OLD_PASSWORD if ( !$oldpassword ); + + # Check old password with a bind + $mesg = $self->bind( $dn, password => $oldpassword ); + if ( $mesg->code != 0 ) { + $self->{portal}->lmLog( "Bad old password", 'debug' ); + return PE_BADOLDPASSWORD; + } + + # Rebind as Manager only if user is not granted to change its password + $self->bind() unless $asUser; + } + + # Use standard modification + $mesg = + $self->modify( $dn, + replace => { $passwordAttribute => $newpassword } ); + } + } $self->{portal} ->lmLog( "Modification return code: " . $mesg->code, 'debug' ); return PE_WRONGMANAGERACCOUNT @@ -444,7 +459,9 @@ sub ldap { $self->lmLog( "LDAP error: " . $mesg->error, 'error' ); } else { - if ( $self->{ldapPpolicyControl} and not $self->{ldap}->loadPP() ) { + if ( $self->{ldapPpolicyControl} + and not $self->{ldap}->loadPP() ) + { $self->lmLog( "LDAP password policy error", 'error' ); } else {