From 531c4d067653e153eb06b6b1002132af5917e129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Mon, 22 Jul 2024 19:59:15 +0200 Subject: [PATCH] Add functions to manage lock status and unlock date --- src/Ltb/Date.php | 5 +- src/Ltb/Directory.php | 21 ++++- src/Ltb/Directory/ActiveDirectory.php | 67 +++++++++++++-- src/Ltb/Directory/OpenLDAP.php | 113 +++++++++++++++++++++----- 4 files changed, 174 insertions(+), 32 deletions(-) diff --git a/src/Ltb/Date.php b/src/Ltb/Date.php index 69c107f..b559d94 100644 --- a/src/Ltb/Date.php +++ b/src/Ltb/Date.php @@ -1,4 +1,5 @@ 1.1.1970 difference in seconds - return date(DateTime::RFC822, $unixTimestamp); + $date = new DateTime(); + $date->setTimestamp($unixTimestamp); + return $date; } } diff --git a/src/Ltb/Directory.php b/src/Ltb/Directory.php index 87a63c1..ca09bbc 100644 --- a/src/Ltb/Directory.php +++ b/src/Ltb/Directory.php @@ -1,8 +1,27 @@ getUnlockDate($ldap, $dn, $config); + + if ($lockoutTime > 0 and !$unlockDate) { + return true; + } + + if ($unlockDate and time() <= $unlockDate->getTimestamp()) { + return true; + } + + return false; + } + + public function getUnlockDate($ldap, $dn, $config) : ?DateTime { + + $unlockDate = NULL; # Get entry - $search = ldap_read($ldap, $dn, "(objectClass=*)", array('useraccountcontrol')); + $search = ldap_read($ldap, $dn, "(objectClass=*)", array('lockouttime')); $errno = ldap_errno($ldap); if ( $errno ) { error_log("LDAP - Search error $errno (".ldap_error($ldap).")"); - return $isLocked; + return $unlockDate; } else { $entry = ldap_get_entries($ldap, $search); } - # Check userAccountControl - $userAccountControl = $entry[0]['useraccountcontrol'][0]; + # Get lockoutTime + $lockoutTime = $entry[0]['lockouttime'][0]; + + if ( !$lockoutTime or $lockoutTime == 0) { + return $unlockDate; + } - if ($userAccountControl & 2) { $isLocked = true; } + # Get lockoutDuration + $lockoutDuration = $config["lockoutDuration"]; + + # Compute unlock date + if ($lockoutDuration) { + $adUnlockDate = $lockoutTime + ($lockoutDuration * 10000000); + $unlockDate = \Ltb\Date::adDate2phpDate($adUnlockDate); + } + + return $unlockDate; + } + + public function getLockoutDuration($ldap, $dn, $config) : ?int { + return $config['lockoutDuration']; + } - return $isLocked; + public function canLockAccount($ldap, $dn, $config) : bool { + return true; } } diff --git a/src/Ltb/Directory/OpenLDAP.php b/src/Ltb/Directory/OpenLDAP.php index 3631141..da7ddf3 100644 --- a/src/Ltb/Directory/OpenLDAP.php +++ b/src/Ltb/Directory/OpenLDAP.php @@ -1,12 +1,11 @@ getUnlockDate($ldap, $dn, $config); + + if ( $unlockDate and time() <= $unlockDate->getTimestamp() ) { + return true; + } + + return false; + } + + public function getUnlockDate($ldap, $dn, $config) : ?DateTime { + + $unlockDate = NULL; + # Get entry + $search = ldap_read($ldap, $dn, "(objectClass=*)", array('pwdaccountlockedtime')); + $errno = ldap_errno($ldap); + + if ( $errno ) { + error_log("LDAP - Search error $errno (".ldap_error($ldap).")"); + return $unlockDate; + } else { + $entry = ldap_get_entries($ldap, $search); + } + + # Get pwdAccountLockedTime + $pwdAccountLockedTime = $entry[0]['pwdaccountlockedtime'][0]; + + if (!$pwdAccountLockedTime) { + return $unlockDate; + } + + # Get lockoutDuration + $lockoutDuration = $config["LockoutDuration"]; + + if ( $pwdAccountLockedTime === "000001010000Z" ) { + return $unlockDate; + } else if (isset($pwdLockoutDuration) and ($pwdLockoutDuration > 0)) { + $lockDate = \Ltb\Date::ldapDate2phpDate($pwdAccountLockedTime); + $unlockDate = date_add( $lockDate, new DateInterval('PT'.$pwdLockoutDuration.'S')); + } + + return $unlockDate; + } + + public function getLockoutDuration($ldap, $dn, $config) : ?int { + + $lockoutDuration = 0; + + # If lockoutDuration is forced in config + if (isset($config['lockoutDuration'])) { + return $config['lockoutDuration']; + } + + # Else get password policy configuration $ppolicy_search = ldap_read($ldap, $config['pwdPolicy'], "(objectClass=*)", array('pwdlockout', 'pwdlockoutduration')); $errno = ldap_errno($ldap); if ( $errno ) { error_log("LDAP - Search error $errno (".ldap_error($ldap).")"); - return $isLocked; + return $lockoutDuration; } else { $ppolicy_entry = ldap_get_entries($ldap, $ppolicy_search); } $pwdLockout = strtolower($ppolicy_entry[0]['pwdlockout'][0]) == "true" ? true : false; $pwdLockoutDuration = $ppolicy_entry[0]['pwdlockoutduration'][0]; - $pwdAccountLockedTime = $entry[0]['pwdaccountlockedtime'][0]; - if ( $pwdAccountLockedTime === "000001010000Z" ) { - $isLocked = true; - } else if (isset($pwdAccountLockedTime)) { - if (isset($pwdLockoutDuration) and ($pwdLockoutDuration > 0)) { - $lockDate = \Ltb\Date::ldapDate2phpDate($pwdAccountLockedTime); - $unlockDate = date_add( $lockDate, new DateInterval('PT'.$pwdLockoutDuration.'S')); - if ( time() <= $unlockDate->getTimestamp() ) { - $isLocked = true; - } - } else { - $isLocked = true; - } - } - - return $isLocked; + if ($pwdLockout) { + $lockoutDuration = $pwdLockoutDuration; + } + + return $lockoutDuration; + } + + public function canLockAccount($ldap, $dn, $config) : bool { + + # Search password policy + $ppolicy_search = ldap_read($ldap, $config['pwdPolicy'], "(objectClass=*)", array('pwdlockout')); + $errno = ldap_errno($ldap); + + if ( $errno ) { + error_log("LDAP - Search error $errno (".ldap_error($ldap).")"); + return false; + } else { + $ppolicy_entry = ldap_get_entries($ldap, $ppolicy_search); + } + + $pwdLockout = strtolower($ppolicy_entry[0]['pwdlockout'][0]) == "true" ? true : false; + + return $pwdLockout; } }