From 66d7fbbb64cf883a21774577b6eb52e6779ecbce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 12 Jul 2024 11:09:01 +0200 Subject: [PATCH 01/35] Switch to LTB LDAP 0.2 --- composer.json | 2 +- composer.lock | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 39b7983e..bb7e9dbd 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "datatables.net/datatables.net-bs5": "2.0.8", "datatables.net/datatables.net-buttons-bs5": "3.0.2", "fortawesome/font-awesome": "v6.5.2", - "ltb-project/ldap": "v0.1.0", + "ltb-project/ldap": "v0.2.0", "twbs/bootstrap": "v5.3.2" }, "scripts": { diff --git a/composer.lock b/composer.lock index 2f45b2a3..2cbbfb44 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "02bfd526cb5f0b2450d74d9013fad616", + "content-hash": "c98dcd38cdd5282785625d28c440e2a7", "packages": [ { "name": "components/jquery", @@ -286,16 +286,16 @@ }, { "name": "ltb-project/ldap", - "version": "v0.1.0", + "version": "v0.2.0", "source": { "type": "git", "url": "https://github.com/ltb-project/ltb-ldap.git", - "reference": "5acd3c86998acbc302937196e8495e81cdcfb4a1" + "reference": "bd4259e7e3f5a00ac163dfd3bbcb6700bb9a9c74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ltb-project/ltb-ldap/zipball/5acd3c86998acbc302937196e8495e81cdcfb4a1", - "reference": "5acd3c86998acbc302937196e8495e81cdcfb4a1", + "url": "https://api.github.com/repos/ltb-project/ltb-ldap/zipball/bd4259e7e3f5a00ac163dfd3bbcb6700bb9a9c74", + "reference": "bd4259e7e3f5a00ac163dfd3bbcb6700bb9a9c74", "shasum": "" }, "require": { @@ -303,6 +303,10 @@ "php": ">=7.4", "phpmailer/phpmailer": "^6.5.0" }, + "require-dev": { + "mockery/mockery": ">=1.4", + "phpunit/phpunit": ">=8" + }, "type": "library", "autoload": { "psr-4": { @@ -316,9 +320,9 @@ "description": "PHP framework for LTB project applications", "support": { "issues": "https://github.com/ltb-project/ltb-ldap/issues", - "source": "https://github.com/ltb-project/ltb-ldap/tree/v0.1.0" + "source": "https://github.com/ltb-project/ltb-ldap/tree/v0.2.0" }, - "time": "2023-04-24T13:24:07+00:00" + "time": "2024-04-24T13:16:19+00:00" }, { "name": "phpmailer/phpmailer", From ff60e46cfc158d67a7ae612bc83e9838464dcf33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 12 Jul 2024 11:20:40 +0200 Subject: [PATCH 02/35] Migration of send_mail function --- htdocs/index.php | 24 ++++++++++++++++++++++++ htdocs/resetpassword.php | 2 +- lib/mail.inc.php | 2 +- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index 733f883a..e0349491 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -24,6 +24,30 @@ require_once("../conf/$lang.inc.php"); } +#============================================================================== +# Email Config +#============================================================================== +$mailer = new \Ltb\Mail( + $mail_priority, + $mail_charset, + $mail_contenttype, + $mail_wordwrap, + $mail_sendmailpath, + $mail_protocol, + $mail_smtp_debug, + $mail_debug_format, + $mail_smtp_host, + $mail_smtp_port, + $mail_smtp_secure, + $mail_smtp_autotls, + $mail_smtp_auth, + $mail_smtp_user, + $mail_smtp_pass, + $mail_smtp_keepalive, + $mail_smtp_options, + $mail_smtp_timeout + ); + #============================================================================== # Smarty #============================================================================== diff --git a/htdocs/resetpassword.php b/htdocs/resetpassword.php index 5ca764b8..22bca351 100644 --- a/htdocs/resetpassword.php +++ b/htdocs/resetpassword.php @@ -121,7 +121,7 @@ $username = $username_values[0]; if ($mail) { $data = array( "name" => $username, "mail" => $mail, "password" => $newpassword); - if ( !\Ltb\Mail::send_mail_global($mail, $mail_from, $mail_from_name, $messages["changesubject"], $messages["changemessage"].$mail_signature, $data) ) { + if ( !$mailer-send_mail($mail, $mail_from, $mail_from_name, $messages["changesubject"], $messages["changemessage"].$mail_signature, $data) ) { error_log("Error while sending change email to $mail (user $dn)"); } } diff --git a/lib/mail.inc.php b/lib/mail.inc.php index 0f863010..7ca39537 100644 --- a/lib/mail.inc.php +++ b/lib/mail.inc.php @@ -24,7 +24,7 @@ function notify_admin_by_mail($mail_from, $mail_from_name, $changesubject, $chan if (! empty($admin_mail_list)) { - if ( !\Ltb\Mail::send_mail_global($admin_mail_list, $mail_from, $mail_from_name, $changesubject, $changemessage.$mail_signature, $data) ) { + if ( !$mailer->send_mail($admin_mail_list, $mail_from, $mail_from_name, $changesubject, $changemessage.$mail_signature, $data) ) { error_log("Error while sending email to administrators $admin_mail_list"); } } From 657f23a5919bf73965eb1535cca6606e9bb459c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 12 Jul 2024 11:24:50 +0200 Subject: [PATCH 03/35] Migration of connect function --- htdocs/checkpassword.php | 2 +- htdocs/display.php | 2 +- htdocs/index.php | 14 ++++++++++++++ htdocs/lockaccount.php | 2 +- htdocs/resetpassword.php | 2 +- htdocs/unlockaccount.php | 2 +- 6 files changed, 19 insertions(+), 5 deletions(-) diff --git a/htdocs/checkpassword.php b/htdocs/checkpassword.php index 93293167..8cadd312 100644 --- a/htdocs/checkpassword.php +++ b/htdocs/checkpassword.php @@ -27,7 +27,7 @@ require __DIR__ . '/../vendor/autoload.php'; # Connect to LDAP - $ldap_connection = \Ltb\Ldap::connect($ldap_url, $ldap_starttls, $dn, $password, $ldap_network_timeout); + $ldap_connection = $ldapInstance->connect(); $ldap = $ldap_connection[0]; $result = $ldap_connection[1]; diff --git a/htdocs/display.php b/htdocs/display.php index 2bd3ce91..fd53aad8 100644 --- a/htdocs/display.php +++ b/htdocs/display.php @@ -54,7 +54,7 @@ require_once("../lib/date.inc.php"); # Connect to LDAP - $ldap_connection = \Ltb\Ldap::connect($ldap_url, $ldap_starttls, $ldap_binddn, $ldap_bindpw, $ldap_network_timeout); + $ldap_connection = $ldapInstance->connect(); $ldap = $ldap_connection[0]; $result = $ldap_connection[1]; diff --git a/htdocs/index.php b/htdocs/index.php index e0349491..bd9ed413 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -48,6 +48,20 @@ $mail_smtp_timeout ); +#============================================================================== +# LDAP Config +#============================================================================== +$ldapInstance = new \Ltb\Ldap( + $ldap_url, + $ldap_starttls, + isset($ldap_binddn) ? $ldap_binddn : null, + isset($ldap_bindpw) ? $ldap_bindpw : null, + isset($ldap_network_timeout) ? $ldap_network_timeout : null, + $ldap_base, + null, + isset($ldap_krb5ccname) ? $ldap_krb5ccname : null + ); + #============================================================================== # Smarty #============================================================================== diff --git a/htdocs/lockaccount.php b/htdocs/lockaccount.php index ccf6eb20..160e4cbb 100644 --- a/htdocs/lockaccount.php +++ b/htdocs/lockaccount.php @@ -19,7 +19,7 @@ require __DIR__ . '/../vendor/autoload.php'; # Connect to LDAP - $ldap_connection = \Ltb\Ldap::connect($ldap_url, $ldap_starttls, $ldap_binddn, $ldap_bindpw, $ldap_network_timeout); + $ldap_connection = $ldapInstance->connect(); $ldap = $ldap_connection[0]; $result = $ldap_connection[1]; diff --git a/htdocs/resetpassword.php b/htdocs/resetpassword.php index 22bca351..a54ee362 100644 --- a/htdocs/resetpassword.php +++ b/htdocs/resetpassword.php @@ -37,7 +37,7 @@ require_once("../lib/hook.inc.php"); # Connect to LDAP - $ldap_connection = \Ltb\Ldap::connect($ldap_url, $ldap_starttls, $ldap_binddn, $ldap_bindpw, $ldap_network_timeout); + $ldap_connection = $ldapInstance->connect(); $ldap = $ldap_connection[0]; $result = $ldap_connection[1]; diff --git a/htdocs/unlockaccount.php b/htdocs/unlockaccount.php index 9eeb7d27..cfdff35d 100644 --- a/htdocs/unlockaccount.php +++ b/htdocs/unlockaccount.php @@ -26,7 +26,7 @@ require __DIR__ . '/../vendor/autoload.php'; # Connect to LDAP - $ldap_connection = \Ltb\Ldap::connect($ldap_url, $ldap_starttls, $ldap_binddn, $ldap_bindpw, $ldap_network_timeout); + $ldap_connection = $ldapInstance->connect(); $ldap = $ldap_connection[0]; $result = $ldap_connection[1]; From 8f947aa8a7643b6c2fd6e09ae78258a0ea59cd50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 12 Jul 2024 11:26:09 +0200 Subject: [PATCH 04/35] Migration of ldap_get_mail_for_notification function --- htdocs/resetpassword.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/resetpassword.php b/htdocs/resetpassword.php index a54ee362..22ecb949 100644 --- a/htdocs/resetpassword.php +++ b/htdocs/resetpassword.php @@ -116,7 +116,7 @@ # Get user DN $entry = ldap_first_entry($ldap, $search); - $mail = \Ltb\AttributeValue::ldap_get_mail_for_notification($ldap, $entry); + $mail = \Ltb\AttributeValue::ldap_get_mail_for_notification($ldap, $entry, $mail_attributes); $username_values = ldap_get_values( $ldap, $entry, $mail_username_attribute ); $username = $username_values[0]; if ($mail) { From 9617d3dcbbd56fcd4ca6c67260a9926f25491fe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 12 Jul 2024 11:32:06 +0200 Subject: [PATCH 05/35] Require autoload in index --- composer.json | 2 +- composer.lock | 14 +++++++------- htdocs/index.php | 5 +++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index bb7e9dbd..8db76f0e 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "datatables.net/datatables.net-bs5": "2.0.8", "datatables.net/datatables.net-buttons-bs5": "3.0.2", "fortawesome/font-awesome": "v6.5.2", - "ltb-project/ldap": "v0.2.0", + "ltb-project/ldap": "v0.2.1", "twbs/bootstrap": "v5.3.2" }, "scripts": { diff --git a/composer.lock b/composer.lock index 2cbbfb44..31c2d9c8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c98dcd38cdd5282785625d28c440e2a7", + "content-hash": "15e6cbc1d32cce34408fded8f296353a", "packages": [ { "name": "components/jquery", @@ -286,16 +286,16 @@ }, { "name": "ltb-project/ldap", - "version": "v0.2.0", + "version": "v0.2.1", "source": { "type": "git", "url": "https://github.com/ltb-project/ltb-ldap.git", - "reference": "bd4259e7e3f5a00ac163dfd3bbcb6700bb9a9c74" + "reference": "0ca06f8aafd116f214418efe9e3f22609c94f431" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ltb-project/ltb-ldap/zipball/bd4259e7e3f5a00ac163dfd3bbcb6700bb9a9c74", - "reference": "bd4259e7e3f5a00ac163dfd3bbcb6700bb9a9c74", + "url": "https://api.github.com/repos/ltb-project/ltb-ldap/zipball/0ca06f8aafd116f214418efe9e3f22609c94f431", + "reference": "0ca06f8aafd116f214418efe9e3f22609c94f431", "shasum": "" }, "require": { @@ -320,9 +320,9 @@ "description": "PHP framework for LTB project applications", "support": { "issues": "https://github.com/ltb-project/ltb-ldap/issues", - "source": "https://github.com/ltb-project/ltb-ldap/tree/v0.2.0" + "source": "https://github.com/ltb-project/ltb-ldap/tree/v0.2.1" }, - "time": "2024-04-24T13:16:19+00:00" + "time": "2024-04-26T10:05:38+00:00" }, { "name": "phpmailer/phpmailer", diff --git a/htdocs/index.php b/htdocs/index.php index bd9ed413..9253527e 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -10,6 +10,11 @@ #============================================================================== require_once("../conf/config.inc.php"); +#============================================================================== +# Includes +#============================================================================== +require_once("../vendor/autoload.php"); + #============================================================================== # Language #============================================================================== From 2f8e76fefabbc4c9f617c9663633886c74d2b7d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 12 Jul 2024 12:05:31 +0200 Subject: [PATCH 06/35] Migration of search function --- htdocs/search.php | 2 +- htdocs/searchexpired.php | 2 +- htdocs/searchidle.php | 2 +- htdocs/searchlocked.php | 2 +- htdocs/searchwillexpire.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/search.php b/htdocs/search.php index e1bcbdb2..8a0cc4f1 100644 --- a/htdocs/search.php +++ b/htdocs/search.php @@ -29,7 +29,7 @@ # Search attributes $attributes = array(); - [$ldap,$result,$nb_entries,$entries,$size_limit_reached]=\Ltb\LtbUtil::search($ldap_filter,$attributes); + [$ldap,$result,$nb_entries,$entries,$size_limit_reached]=$ldapInstance->search($ldap_filter, $attributes, $attributes_map, $search_result_title, $search_result_sortby, $search_result_items); if ( ! empty($entries) ) { diff --git a/htdocs/searchexpired.php b/htdocs/searchexpired.php index c079ae4d..1d2cf5d6 100644 --- a/htdocs/searchexpired.php +++ b/htdocs/searchexpired.php @@ -17,7 +17,7 @@ # Search attributes $attributes = array('pwdChangedTime', 'pwdPolicySubentry'); -[$ldap,$result,$nb_entries,$entries,$size_limit_reached]=\Ltb\LtbUtil::search($ldap_filter,$attributes); +[$ldap,$result,$nb_entries,$entries,$size_limit_reached]=$ldapInstance->search($ldap_filter, $attributes, $attributes_map, $search_result_title, $search_result_sortby, $search_result_items); if ( ! empty($entries) ) { diff --git a/htdocs/searchidle.php b/htdocs/searchidle.php index 1bea0bdc..4570e29a 100644 --- a/htdocs/searchidle.php +++ b/htdocs/searchidle.php @@ -20,7 +20,7 @@ # Search attributes $attributes = array(); -[$ldap,$result,$nb_entries,$entries,$size_limit_reached]=\Ltb\LtbUtil::search($ldap_filter,$attributes); +[$ldap,$result,$nb_entries,$entries,$size_limit_reached]=$ldapInstance->search($ldap_filter, $attributes, $attributes_map, $search_result_title, $search_result_sortby, $search_result_items); if ( ! empty($entries) ) { diff --git a/htdocs/searchlocked.php b/htdocs/searchlocked.php index e9fab6bd..d358532f 100644 --- a/htdocs/searchlocked.php +++ b/htdocs/searchlocked.php @@ -15,7 +15,7 @@ # Search attributes $attributes = array('pwdAccountLockedTime', 'pwdPolicySubentry'); -[$ldap,$result,$nb_entries,$entries,$size_limit_reached]=\Ltb\LtbUtil::search($ldap_filter,$attributes); +[$ldap,$result,$nb_entries,$entries,$size_limit_reached]=$ldapInstance->search($ldap_filter, $attributes, $attributes_map, $search_result_title, $search_result_sortby, $search_result_items); if ( ! empty($entries) ) { diff --git a/htdocs/searchwillexpire.php b/htdocs/searchwillexpire.php index 85cfc9bc..e25f5634 100644 --- a/htdocs/searchwillexpire.php +++ b/htdocs/searchwillexpire.php @@ -17,7 +17,7 @@ # Search attributes $attributes = array('pwdChangedTime', 'pwdPolicySubentry'); -[$ldap,$result,$nb_entries,$entries,$size_limit_reached]=\Ltb\LtbUtil::search($ldap_filter,$attributes); +[$ldap,$result,$nb_entries,$entries,$size_limit_reached]=$ldapInstance->search($ldap_filter, $attributes, $attributes_map, $search_result_title, $search_result_sortby, $search_result_items); if ( ! empty($entries) ) { From 15a6b2c7904843c7e6457267f7ff7c952ba4a6d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 12 Jul 2024 14:32:48 +0200 Subject: [PATCH 07/35] Use ldapInstance in smarty plugin --- lib/smarty.inc.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/smarty.inc.php b/lib/smarty.inc.php index f29fac02..7b29f807 100644 --- a/lib/smarty.inc.php +++ b/lib/smarty.inc.php @@ -16,8 +16,19 @@ function get_attribute($params) { $ldap_bindpw = $params["ldap_bindpw"]; $ldap_filter = $params["ldap_filter"]; + $ldapInstance = new \Ltb\Ldap( + $ldap_url, + $ldap_starttls, + isset($ldap_binddn) ? $ldap_binddn : null, + isset($ldap_bindpw) ? $ldap_bindpw : null, + isset($ldap_network_timeout) ? $ldap_network_timeout : null, + $dn, + null, + isset($ldap_krb5ccname) ? $ldap_krb5ccname : null + ); + # Connect to LDAP - $ldap_connection = \Ltb\Ldap::connect($ldap_url, $ldap_starttls, $ldap_binddn, $ldap_bindpw, $ldap_network_timeout); + $ldap_connection = $ldapInstance->connect(); $ldap = $ldap_connection[0]; $result = $ldap_connection[1]; From ae68327085705cbfa0c37889c956e191a3496092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 12 Jul 2024 15:47:26 +0200 Subject: [PATCH 08/35] Call ldap_bind to check password --- htdocs/checkpassword.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/checkpassword.php b/htdocs/checkpassword.php index 8cadd312..6b27598f 100644 --- a/htdocs/checkpassword.php +++ b/htdocs/checkpassword.php @@ -33,7 +33,9 @@ $result = $ldap_connection[1]; if( !$result ) { - $result = "passwordok"; + + $bind = \Ltb\PhpLDAP::ldap_bind($ldap, $dn, $password); + $result = $bind ? "passwordok" : "ldaperror"; } } From a25da54d4b61a2d25a776b85c379588cf0fff2a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 12 Jul 2024 15:47:44 +0200 Subject: [PATCH 09/35] Fix typo --- htdocs/resetpassword.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/resetpassword.php b/htdocs/resetpassword.php index 22ecb949..21e88a55 100644 --- a/htdocs/resetpassword.php +++ b/htdocs/resetpassword.php @@ -121,7 +121,7 @@ $username = $username_values[0]; if ($mail) { $data = array( "name" => $username, "mail" => $mail, "password" => $newpassword); - if ( !$mailer-send_mail($mail, $mail_from, $mail_from_name, $messages["changesubject"], $messages["changemessage"].$mail_signature, $data) ) { + if ( !$mailer->send_mail($mail, $mail_from, $mail_from_name, $messages["changesubject"], $messages["changemessage"].$mail_signature, $data) ) { error_log("Error while sending change email to $mail (user $dn)"); } } From 4a13a43714fed7d74aea795f392744cf6643ce64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 12 Jul 2024 18:14:15 +0200 Subject: [PATCH 10/35] Migrate notify_admin_by_mail function --- htdocs/resetpassword.php | 3 ++- lib/mail.inc.php | 14 +++----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/htdocs/resetpassword.php b/htdocs/resetpassword.php index 21e88a55..dfb34fe3 100644 --- a/htdocs/resetpassword.php +++ b/htdocs/resetpassword.php @@ -130,7 +130,8 @@ # Notify administrator if needed $data = array( "dn" => $dn ); - notify_admin_by_mail($mail_from, $mail_from_name, $messages["changesubjectforadmin"], $messages["changemessageforadmin"], $mail_signature, $data); + $admin_mail_list = get_admin_mail_list($notify_admin_by_mail, $notify_admin_by_mail_list); + $mailer->send_mail($admin_mail_list, $mail_from, $mail_from_name, $messages["changesubjectforadmin"], $messages["changemessageforadmin"], $mail_signature, $data); } } diff --git a/lib/mail.inc.php b/lib/mail.inc.php index 7ca39537..ad14c439 100644 --- a/lib/mail.inc.php +++ b/lib/mail.inc.php @@ -1,10 +1,8 @@ send_mail($admin_mail_list, $mail_from, $mail_from_name, $changesubject, $changemessage.$mail_signature, $data) ) { - error_log("Error while sending email to administrators $admin_mail_list"); - } - } - + return $admin_mail_list; } ?> From 30c40efd859e0af162184550648180f9ba69a42e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Mon, 15 Jul 2024 19:12:50 +0200 Subject: [PATCH 11/35] Function to convert AD date --- lib/date.inc.php | 6 ++++++ lib/smarty.inc.php | 5 +++++ templates/value_displayer.tpl | 4 ++++ 3 files changed, 15 insertions(+) diff --git a/lib/date.inc.php b/lib/date.inc.php index 0a594b69..0b4c4ae9 100644 --- a/lib/date.inc.php +++ b/lib/date.inc.php @@ -82,3 +82,9 @@ function string2ldapDate($string) { return $ldapdate; } + +function adDate2phpDate($string) { + $winSecs = (int)($string / 10000000); // divide by 10 000 000 to get seconds + $unixTimestamp = ($winSecs - 11644473600); // 1.1.1600 -> 1.1.1970 difference in seconds + return date(DateTime::RFC822, $unixTimestamp); +} diff --git a/lib/smarty.inc.php b/lib/smarty.inc.php index 7b29f807..9d226b4b 100644 --- a/lib/smarty.inc.php +++ b/lib/smarty.inc.php @@ -64,6 +64,11 @@ function convert_ldap_date($date) { } +function convert_ad_date($date) { + + return adDate2phpDate( $date ); + +} function convert_bytes($bytes) { return FileSizeConvert( $bytes ); diff --git a/templates/value_displayer.tpl b/templates/value_displayer.tpl index 0a4384c0..aeb189cf 100644 --- a/templates/value_displayer.tpl +++ b/templates/value_displayer.tpl @@ -19,6 +19,10 @@ {convert_ldap_date($value)|date_format:{$date_specifiers}|truncate:{$truncate_value_after}}
{/if} +{if $type eq 'ad_date'} + {convert_ad_date($value)|date_format:{$date_specifiers}|truncate:{$truncate_value_after}}
+{/if} + {if $type eq 'list'} {$value|truncate:{$truncate_value_after}}
{/if} From 50312789b34dbb2f17bc218db433e18ca2fa3a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Mon, 15 Jul 2024 19:13:27 +0200 Subject: [PATCH 12/35] First mapping between OpenLDAP and AD --- conf/config.inc.php | 10 +++++++++- htdocs/index.php | 11 +++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/conf/config.inc.php b/conf/config.inc.php index a1eb1304..72015eab 100644 --- a/conf/config.inc.php +++ b/conf/config.inc.php @@ -37,6 +37,7 @@ #$ldap_default_ppolicy = "cn=default,ou=ppolicy,dc=example,dc=com"; $ldap_lastauth_attribute = "authTimestamp"; #$ldap_network_timeout = 10; +$ldap_type = "openldap"; # How display attributes $attributes_map = array( @@ -66,7 +67,6 @@ 'postaladdress' => array( 'attribute' => 'postaladdress', 'faclass' => 'map-marker', 'type' => 'address' ), 'postalcode' => array( 'attribute' => 'postalcode', 'faclass' => 'globe', 'type' => 'text' ), 'pwdaccountlockedtime' => array( 'attribute' => 'pwdaccountlockedtime', 'faclass' => 'lock', 'type' => 'date' ), - 'pwdchangedtime' => array( 'attribute' => 'pwdchangedtime', 'faclass' => 'lock', 'type' => 'date' ), 'pwdfailuretime' => array( 'attribute' => 'pwdfailuretime', 'faclass' => 'lock', 'type' => 'date' ), 'pwdlastsuccess' => array( 'attribute' => 'pwdlastsuccess', 'faclass' => 'lock', 'type' => 'date' ), 'pwdpolicysubentry' => array( 'attribute' => 'pwdpolicysubentry', 'faclass' => 'lock', 'type' => 'ppolicy_dn' ), @@ -77,6 +77,14 @@ 'title' => array( 'attribute' => 'title', 'faclass' => 'certificate', 'type' => 'text' ), ); +# Directory specific attributes +$openldap_attributes_map = array( + 'pwdchangedtime' => array( 'attribute' => 'pwdchangedtime', 'faclass' => 'lock', 'type' => 'date' ), +); +$activedirectory_attributes_map = array( + 'pwdchangedtime' => array( 'attribute' => 'pwdlastset', 'faclass' => 'lock', 'type' => 'ad_date' ), +); + # Search $search_attributes = array('uid', 'cn', 'mail'); $search_use_substring_match = true; diff --git a/htdocs/index.php b/htdocs/index.php index 9253527e..afbc6b14 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -10,6 +10,16 @@ #============================================================================== require_once("../conf/config.inc.php"); +# Load specific directory settings +switch($ldap_type) { + case "openldap": + $attributes_map = array_merge($attributes_map, $openldap_attributes_map); + break; + case "activedirectory": + $attributes_map = array_merge($attributes_map, $activedirectory_attributes_map); + break; +} + #============================================================================== # Includes #============================================================================== @@ -134,6 +144,7 @@ require_once("../lib/smarty.inc.php"); $smarty->registerPlugin("function", "get_attribute", "get_attribute"); $smarty->registerPlugin("function", "convert_ldap_date", "convert_ldap_date"); +$smarty->registerPlugin("function", "convert_ad_date", "convert_ad_date"); $smarty->registerPlugin("function", "convert_bytes", "convert_bytes"); $smarty->registerPlugin("function", "split_value", "split_value"); From 3038c67c32f57db4cf980df4020617d48fc37146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Mon, 15 Jul 2024 19:24:41 +0200 Subject: [PATCH 13/35] Manage other AD specific attributes --- conf/config.inc.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/conf/config.inc.php b/conf/config.inc.php index 72015eab..6ec2d81e 100644 --- a/conf/config.inc.php +++ b/conf/config.inc.php @@ -41,7 +41,6 @@ # How display attributes $attributes_map = array( - 'authtimestamp' => array( 'attribute' => 'authtimestamp', 'faclass' => 'lock', 'type' => 'date' ), 'businesscategory' => array( 'attribute' => 'businesscategory', 'faclass' => 'briefcase', 'type' => 'text' ), 'carlicense' => array( 'attribute' => 'carlicense', 'faclass' => 'car', 'type' => 'text' ), 'created' => array( 'attribute' => 'createtimestamp', 'faclass' => 'clock-o', 'type' => 'date' ), @@ -67,7 +66,6 @@ 'postaladdress' => array( 'attribute' => 'postaladdress', 'faclass' => 'map-marker', 'type' => 'address' ), 'postalcode' => array( 'attribute' => 'postalcode', 'faclass' => 'globe', 'type' => 'text' ), 'pwdaccountlockedtime' => array( 'attribute' => 'pwdaccountlockedtime', 'faclass' => 'lock', 'type' => 'date' ), - 'pwdfailuretime' => array( 'attribute' => 'pwdfailuretime', 'faclass' => 'lock', 'type' => 'date' ), 'pwdlastsuccess' => array( 'attribute' => 'pwdlastsuccess', 'faclass' => 'lock', 'type' => 'date' ), 'pwdpolicysubentry' => array( 'attribute' => 'pwdpolicysubentry', 'faclass' => 'lock', 'type' => 'ppolicy_dn' ), 'pwdreset' => array( 'attribute' => 'pwdreset', 'faclass' => 'lock', 'type' => 'boolean' ), @@ -79,10 +77,14 @@ # Directory specific attributes $openldap_attributes_map = array( + 'authtimestamp' => array( 'attribute' => 'authtimestamp', 'faclass' => 'lock', 'type' => 'date' ), 'pwdchangedtime' => array( 'attribute' => 'pwdchangedtime', 'faclass' => 'lock', 'type' => 'date' ), + 'pwdfailuretime' => array( 'attribute' => 'pwdfailuretime', 'faclass' => 'lock', 'type' => 'date' ), ); $activedirectory_attributes_map = array( + 'authtimestamp' => array( 'attribute' => 'lastlogon', 'faclass' => 'lock', 'type' => 'ad_date' ), 'pwdchangedtime' => array( 'attribute' => 'pwdlastset', 'faclass' => 'lock', 'type' => 'ad_date' ), + 'pwdfailuretime' => array( 'attribute' => 'badpasswordtime', 'faclass' => 'lock', 'type' => 'ad_date' ), ); # Search From a51fc2b41be1312612f1b4ebe50dfb9abf333de8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Tue, 16 Jul 2024 11:01:23 +0200 Subject: [PATCH 14/35] AD lockout time --- conf/config.inc.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conf/config.inc.php b/conf/config.inc.php index 6ec2d81e..0ddb7b20 100644 --- a/conf/config.inc.php +++ b/conf/config.inc.php @@ -65,7 +65,6 @@ 'phone' => array( 'attribute' => 'telephonenumber', 'faclass' => 'phone', 'type' => 'tel' ), 'postaladdress' => array( 'attribute' => 'postaladdress', 'faclass' => 'map-marker', 'type' => 'address' ), 'postalcode' => array( 'attribute' => 'postalcode', 'faclass' => 'globe', 'type' => 'text' ), - 'pwdaccountlockedtime' => array( 'attribute' => 'pwdaccountlockedtime', 'faclass' => 'lock', 'type' => 'date' ), 'pwdlastsuccess' => array( 'attribute' => 'pwdlastsuccess', 'faclass' => 'lock', 'type' => 'date' ), 'pwdpolicysubentry' => array( 'attribute' => 'pwdpolicysubentry', 'faclass' => 'lock', 'type' => 'ppolicy_dn' ), 'pwdreset' => array( 'attribute' => 'pwdreset', 'faclass' => 'lock', 'type' => 'boolean' ), @@ -78,11 +77,13 @@ # Directory specific attributes $openldap_attributes_map = array( 'authtimestamp' => array( 'attribute' => 'authtimestamp', 'faclass' => 'lock', 'type' => 'date' ), + 'pwdaccountlockedtime' => array( 'attribute' => 'pwdaccountlockedtime', 'faclass' => 'lock', 'type' => 'date' ), 'pwdchangedtime' => array( 'attribute' => 'pwdchangedtime', 'faclass' => 'lock', 'type' => 'date' ), 'pwdfailuretime' => array( 'attribute' => 'pwdfailuretime', 'faclass' => 'lock', 'type' => 'date' ), ); $activedirectory_attributes_map = array( 'authtimestamp' => array( 'attribute' => 'lastlogon', 'faclass' => 'lock', 'type' => 'ad_date' ), + 'pwdaccountlockedtime' => array( 'attribute' => 'lockouttime', 'faclass' => 'lock', 'type' => 'ad_date' ), 'pwdchangedtime' => array( 'attribute' => 'pwdlastset', 'faclass' => 'lock', 'type' => 'ad_date' ), 'pwdfailuretime' => array( 'attribute' => 'badpasswordtime', 'faclass' => 'lock', 'type' => 'ad_date' ), ); From 3323ac108f6d7802a639dffdbbdbb33ff5e09c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Tue, 16 Jul 2024 11:04:36 +0200 Subject: [PATCH 15/35] AD identifier --- conf/config.inc.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conf/config.inc.php b/conf/config.inc.php index 0ddb7b20..7624401c 100644 --- a/conf/config.inc.php +++ b/conf/config.inc.php @@ -51,7 +51,6 @@ 'fax' => array( 'attribute' => 'facsimiletelephonenumber', 'faclass' => 'fax', 'type' => 'tel' ), 'firstname' => array( 'attribute' => 'givenname', 'faclass' => 'user-o', 'type' => 'text' ), 'fullname' => array( 'attribute' => 'cn', 'faclass' => 'user-circle', 'type' => 'text' ), - 'identifier' => array( 'attribute' => 'uid', 'faclass' => 'user-o', 'type' => 'text' ), 'l' => array( 'attribute' => 'l', 'faclass' => 'globe', 'type' => 'text' ), 'lastname' => array( 'attribute' => 'sn', 'faclass' => 'user-o', 'type' => 'text' ), 'mail' => array( 'attribute' => 'mail', 'faclass' => 'envelope-o', 'type' => 'mailto' ), @@ -77,12 +76,14 @@ # Directory specific attributes $openldap_attributes_map = array( 'authtimestamp' => array( 'attribute' => 'authtimestamp', 'faclass' => 'lock', 'type' => 'date' ), + 'identifier' => array( 'attribute' => 'uid', 'faclass' => 'user-o', 'type' => 'text' ), 'pwdaccountlockedtime' => array( 'attribute' => 'pwdaccountlockedtime', 'faclass' => 'lock', 'type' => 'date' ), 'pwdchangedtime' => array( 'attribute' => 'pwdchangedtime', 'faclass' => 'lock', 'type' => 'date' ), 'pwdfailuretime' => array( 'attribute' => 'pwdfailuretime', 'faclass' => 'lock', 'type' => 'date' ), ); $activedirectory_attributes_map = array( 'authtimestamp' => array( 'attribute' => 'lastlogon', 'faclass' => 'lock', 'type' => 'ad_date' ), + 'identifier' => array( 'attribute' => 'samaccountname', 'faclass' => 'user-o', 'type' => 'text' ), 'pwdaccountlockedtime' => array( 'attribute' => 'lockouttime', 'faclass' => 'lock', 'type' => 'ad_date' ), 'pwdchangedtime' => array( 'attribute' => 'pwdlastset', 'faclass' => 'lock', 'type' => 'ad_date' ), 'pwdfailuretime' => array( 'attribute' => 'badpasswordtime', 'faclass' => 'lock', 'type' => 'ad_date' ), From c3186ab61ea9c0bb03bbe030945af4f370943dea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Tue, 16 Jul 2024 11:19:59 +0200 Subject: [PATCH 16/35] Move OpenLDAP specific attributes --- conf/config.inc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/conf/config.inc.php b/conf/config.inc.php index 7624401c..0a175b05 100644 --- a/conf/config.inc.php +++ b/conf/config.inc.php @@ -64,9 +64,6 @@ 'phone' => array( 'attribute' => 'telephonenumber', 'faclass' => 'phone', 'type' => 'tel' ), 'postaladdress' => array( 'attribute' => 'postaladdress', 'faclass' => 'map-marker', 'type' => 'address' ), 'postalcode' => array( 'attribute' => 'postalcode', 'faclass' => 'globe', 'type' => 'text' ), - 'pwdlastsuccess' => array( 'attribute' => 'pwdlastsuccess', 'faclass' => 'lock', 'type' => 'date' ), - 'pwdpolicysubentry' => array( 'attribute' => 'pwdpolicysubentry', 'faclass' => 'lock', 'type' => 'ppolicy_dn' ), - 'pwdreset' => array( 'attribute' => 'pwdreset', 'faclass' => 'lock', 'type' => 'boolean' ), 'secretary' => array( 'attribute' => 'secretary', 'faclass' => 'user-circle-o', 'type' => 'dn_link' ), 'state' => array( 'attribute' => 'st', 'faclass' => 'globe', 'type' => 'text' ), 'street' => array( 'attribute' => 'street', 'faclass' => 'map-marker', 'type' => 'text' ), @@ -80,6 +77,9 @@ 'pwdaccountlockedtime' => array( 'attribute' => 'pwdaccountlockedtime', 'faclass' => 'lock', 'type' => 'date' ), 'pwdchangedtime' => array( 'attribute' => 'pwdchangedtime', 'faclass' => 'lock', 'type' => 'date' ), 'pwdfailuretime' => array( 'attribute' => 'pwdfailuretime', 'faclass' => 'lock', 'type' => 'date' ), + 'pwdlastsuccess' => array( 'attribute' => 'pwdlastsuccess', 'faclass' => 'lock', 'type' => 'date' ), + 'pwdpolicysubentry' => array( 'attribute' => 'pwdpolicysubentry', 'faclass' => 'lock', 'type' => 'ppolicy_dn' ), + 'pwdreset' => array( 'attribute' => 'pwdreset', 'faclass' => 'lock', 'type' => 'boolean' ), ); $activedirectory_attributes_map = array( 'authtimestamp' => array( 'attribute' => 'lastlogon', 'faclass' => 'lock', 'type' => 'ad_date' ), From dd551360b9fe287d1ec5e9b0f2f39364301b341b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Thu, 18 Jul 2024 18:52:18 +0200 Subject: [PATCH 17/35] Work on isLocked function --- htdocs/display.php | 37 +++++-------------------------------- htdocs/index.php | 27 +++++++++++++++++---------- 2 files changed, 22 insertions(+), 42 deletions(-) diff --git a/htdocs/display.php b/htdocs/display.php index fd53aad8..a698d780 100644 --- a/htdocs/display.php +++ b/htdocs/display.php @@ -68,7 +68,6 @@ $attributes[] = $attributes_map[$item]['attribute']; } $attributes[] = $attributes_map[$display_title]['attribute']; - $attributes[] = "pwdPolicySubentry"; # Search entry $search = ldap_read($ldap, $dn, $ldap_user_filter, $attributes); @@ -97,54 +96,28 @@ if ( !$entry[0]['pwdpolicysubentry'] and $ldap_default_ppolicy) { $entry[0]['pwdpolicysubentry'][] = $ldap_default_ppolicy; } + $pwdPolicy = $entry[0]['pwdpolicysubentry'][0]; if ($display_edit_link) { # Replace {dn} in URL $edit_link = str_replace("{dn}", urlencode($dn), $display_edit_link); } - # Search user active password policy - $pwdPolicy = ""; - if (isset($entry[0]['pwdpolicysubentry'][0])) { - $pwdPolicy = $entry[0]['pwdpolicysubentry'][0]; - } elseif (isset($ldap_default_ppolicy)) { - $pwdPolicy = $ldap_default_ppolicy; - } - - $isLocked = false; $unlockDate = ""; $isExpired = false; - $ppolicy_entry = ""; + + $isLocked = $directory->isLocked($ldap, $dn, array( 'pwdpolicy' => $pwdPolicy )); if ($pwdPolicy) { - $search_ppolicy = ldap_read($ldap, $pwdPolicy, "(objectClass=pwdPolicy)", array('pwdMaxAge', 'pwdLockoutDuration', 'pwdLockout')); + $search_ppolicy = ldap_read($ldap, $pwdPolicy, "(objectClass=pwdPolicy)", array('pwdMaxAge')); + $ppolicy_entry = ""; if ( $errno ) { error_log("LDAP - PPolicy search error $errno (".ldap_error($ldap).")"); } else { $ppolicy_entry = ldap_get_entries($ldap, $search_ppolicy); } - # Lock - $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; - unset($entry[0]['pwdaccountlockedtime']); - } else if (isset($pwdAccountLockedTime)) { - if (isset($pwdLockoutDuration) and ($pwdLockoutDuration > 0)) { - $lockDate = ldapDate2phpDate($pwdAccountLockedTime); - $unlockDate = date_add( $lockDate, new DateInterval('PT'.$pwdLockoutDuration.'S')); - if ( time() <= $unlockDate->getTimestamp() ) { - $isLocked = true; - } - } else { - $isLocked = true; - } - } - # Expiration $pwdMaxAge = $ppolicy_entry[0]['pwdmaxage'][0]; $pwdChangedTime = $entry[0]['pwdchangedtime'][0]; diff --git a/htdocs/index.php b/htdocs/index.php index afbc6b14..67d38845 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -10,16 +10,6 @@ #============================================================================== require_once("../conf/config.inc.php"); -# Load specific directory settings -switch($ldap_type) { - case "openldap": - $attributes_map = array_merge($attributes_map, $openldap_attributes_map); - break; - case "activedirectory": - $attributes_map = array_merge($attributes_map, $activedirectory_attributes_map); - break; -} - #============================================================================== # Includes #============================================================================== @@ -77,6 +67,23 @@ isset($ldap_krb5ccname) ? $ldap_krb5ccname : null ); +#============================================================================== +# Directory instance +#============================================================================== +$directory; + +# Load specific directory settings +switch($ldap_type) { + case "openldap": + $attributes_map = array_merge($attributes_map, $openldap_attributes_map); + $directory = new \Ltb\Directory\OpenLDAP(); + break; + case "activedirectory": + $attributes_map = array_merge($attributes_map, $activedirectory_attributes_map); + $directory = new \Ltb\Directory\ActiveDirectory(); + break; +} + #============================================================================== # Smarty #============================================================================== From 5c25b593051a317bd891ead35400b334e9eec9c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Mon, 22 Jul 2024 19:59:42 +0200 Subject: [PATCH 18/35] Use new ltb-common Directory functions --- conf/config.inc.php | 1 + htdocs/display.php | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/conf/config.inc.php b/conf/config.inc.php index 4f7f768a..19efb376 100644 --- a/conf/config.inc.php +++ b/conf/config.inc.php @@ -38,6 +38,7 @@ $ldap_lastauth_attribute = "authTimestamp"; #$ldap_network_timeout = 10; $ldap_type = "openldap"; +#$ldap_lockout_duration = 3600; # How display attributes $attributes_map = array( diff --git a/htdocs/display.php b/htdocs/display.php index a698d780..245da43a 100644 --- a/htdocs/display.php +++ b/htdocs/display.php @@ -14,6 +14,7 @@ $prehookresult= ""; $posthookresult= ""; $ldapExpirationDate=""; +$canLockAccount=""; if (isset($_GET["dn"]) and $_GET["dn"]) { $dn = $_GET["dn"]; @@ -71,7 +72,6 @@ # Search entry $search = ldap_read($ldap, $dn, $ldap_user_filter, $attributes); - $errno = ldap_errno($ldap); if ( $errno ) { @@ -103,10 +103,12 @@ $edit_link = str_replace("{dn}", urlencode($dn), $display_edit_link); } - $unlockDate = ""; - $isExpired = false; + $lockoutDuration = $directory->getLockoutDuration($ldap, $dn, array('pwdPolicy' => $pwdPolicy, 'lockoutDuration' => $ldap_lockout_duration)); + $unlockDate = $directory->getUnlockDate($ldap, $dn, array('lockoutDuration' => $lockoutDuration)); + $isLocked = $directory->isLocked($ldap, $dn, array('lockoutDuration' => $lockoutDuration)); + $canLockAccount = $directory->canLockAccount($ldap, $dn, array('pwdPolicy' => $pwdPolicy)); - $isLocked = $directory->isLocked($ldap, $dn, array( 'pwdpolicy' => $pwdPolicy )); + $isExpired = false; if ($pwdPolicy) { $search_ppolicy = ldap_read($ldap, $pwdPolicy, "(objectClass=pwdPolicy)", array('pwdMaxAge')); @@ -158,5 +160,5 @@ $smarty->assign("accountlockresult", $accountlockresult); $smarty->assign("prehookresult", $prehookresult); $smarty->assign("posthookresult", $posthookresult); -if ($pwdLockout == false) $smarty->assign("use_lockaccount", $pwdLockout); +if ($canLockAccount == false) $smarty->assign("use_lockaccount", $canLockAccount); ?> From 6d2b63640ee3c4a1f5778b214884480a24c2299f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Tue, 23 Jul 2024 18:42:26 +0200 Subject: [PATCH 19/35] Hide special value of lockout date --- htdocs/display.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/display.php b/htdocs/display.php index 245da43a..f8dc029f 100644 --- a/htdocs/display.php +++ b/htdocs/display.php @@ -64,7 +64,7 @@ # Search attributes $attributes = array(); - $search_items = array_merge( $display_items, $display_password_items); + $search_items = array_merge($display_items, $display_password_items); foreach( $search_items as $item ) { $attributes[] = $attributes_map[$item]['attribute']; } @@ -103,6 +103,12 @@ $edit_link = str_replace("{dn}", urlencode($dn), $display_edit_link); } + # Remove lockout date if special value + $lockoutDateAttribute = $attributes_map['pwdaccountlockedtime']['attribute']; + if ( isset($entry[0][$lockoutDateAttribute]) and $entry[0][$lockoutDateAttribute][0] === "000001010000Z") { + unset($entry[0][$lockoutDateAttribute]); + } + $lockoutDuration = $directory->getLockoutDuration($ldap, $dn, array('pwdPolicy' => $pwdPolicy, 'lockoutDuration' => $ldap_lockout_duration)); $unlockDate = $directory->getUnlockDate($ldap, $dn, array('lockoutDuration' => $lockoutDuration)); $isLocked = $directory->isLocked($ldap, $dn, array('lockoutDuration' => $lockoutDuration)); From e220b77e95fd21701765a8169bdf1f00235aa7e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Wed, 24 Jul 2024 12:51:36 +0200 Subject: [PATCH 20/35] Use ltb-common password expiration functions --- htdocs/display.php | 33 ++++----------------------------- templates/display.tpl | 2 +- 2 files changed, 5 insertions(+), 30 deletions(-) diff --git a/htdocs/display.php b/htdocs/display.php index f8dc029f..4ed5b805 100644 --- a/htdocs/display.php +++ b/htdocs/display.php @@ -114,34 +114,9 @@ $isLocked = $directory->isLocked($ldap, $dn, array('lockoutDuration' => $lockoutDuration)); $canLockAccount = $directory->canLockAccount($ldap, $dn, array('pwdPolicy' => $pwdPolicy)); - $isExpired = false; - - if ($pwdPolicy) { - $search_ppolicy = ldap_read($ldap, $pwdPolicy, "(objectClass=pwdPolicy)", array('pwdMaxAge')); - - $ppolicy_entry = ""; - if ( $errno ) { - error_log("LDAP - PPolicy search error $errno (".ldap_error($ldap).")"); - } else { - $ppolicy_entry = ldap_get_entries($ldap, $search_ppolicy); - } - - # Expiration - $pwdMaxAge = $ppolicy_entry[0]['pwdmaxage'][0]; - $pwdChangedTime = $entry[0]['pwdchangedtime'][0]; - - if (isset($pwdChangedTime) and isset($pwdMaxAge) and ($pwdMaxAge > 0)) { - $changedDate = ldapDate2phpDate($pwdChangedTime); - $expirationDate = date_add( $changedDate, new DateInterval('PT'.$pwdMaxAge.'S')); - if ( time() >= $expirationDate->getTimestamp() ) { - $isExpired = true; - } - if ( $display_password_expiration_date ) { - $ldapExpirationDate = $expirationDate->format('YmdHis\Z'); - } - } - } - + $pwdMaxAge = $directory->getPasswordMaxAge($ldap, $dn, array('pwdPolicy' => $pwdPolicy, 'pwdMaxAge' => $ldap_password_max_age)); + $expirationDate = $directory->getPasswordExpirationDate($ldap, $dn, array('pwdMaxAge' => $pwdMaxAge)); + $isExpired = $directory->isPasswordExpired($ldap, $dn, array('pwdMaxAge' => $pwdMaxAge)); } } @@ -156,7 +131,7 @@ $smarty->assign("isLocked", $isLocked); $smarty->assign("unlockDate", $unlockDate); $smarty->assign("isExpired", $isExpired); -$smarty->assign("ldapExpirationDate", $ldapExpirationDate); +$smarty->assign("ldapExpirationDate", $expirationDate ? $expirationDate->getTimestamp(): NULL); $smarty->assign("edit_link", $edit_link); diff --git a/templates/display.tpl b/templates/display.tpl index 12e5558f..b63942ea 100644 --- a/templates/display.tpl +++ b/templates/display.tpl @@ -86,7 +86,7 @@ {$msg_label_expirationdate} - {include 'value_displayer.tpl' value=$ldapExpirationDate type="date" truncate_value_after=10000} + {$ldapExpirationDate|date_format:{$date_specifiers}|truncate:10000} {/if} From f0726633288205a2bbb5cdac49a7792c6a95413e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Wed, 24 Jul 2024 15:19:24 +0200 Subject: [PATCH 21/35] Use functions to lock/unlock an account --- htdocs/lockaccount.php | 14 +++++--------- htdocs/unlockaccount.php | 8 +++----- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/htdocs/lockaccount.php b/htdocs/lockaccount.php index 160e4cbb..b0737659 100644 --- a/htdocs/lockaccount.php +++ b/htdocs/lockaccount.php @@ -24,9 +24,7 @@ $ldap = $ldap_connection[0]; $result = $ldap_connection[1]; - - # Consider pwdLockout = false by default - $pwdLockout = false; + $pwdPolicy = NULL; # Search pwdLockout in associated ppolicy if ($ldap) @@ -61,13 +59,11 @@ } # apply the modification only if a password policy set with pwdLockout=TRUE is associated to the account - if ($ldap and $pwdLockout == true) { - $modification = ldap_mod_replace($ldap, $dn, array("pwdAccountLockedTime" => array("000001010000Z"))); - $errno = ldap_errno($ldap); - if ( $errno ) { - $result = "ldaperror"; - } else { + if ($ldap and $directory->canLockAccount($ldap, $dn, array('pwdPolicy' => $pwdPolicy))) { + if ( $directory->lockAccount($ldap, $dn) ) { $result = "accountlocked"; + } else { + $result = "ldaperror"; } } } diff --git a/htdocs/unlockaccount.php b/htdocs/unlockaccount.php index cfdff35d..dd30e153 100644 --- a/htdocs/unlockaccount.php +++ b/htdocs/unlockaccount.php @@ -32,12 +32,10 @@ $result = $ldap_connection[1]; if ($ldap) { - $modification = ldap_mod_del($ldap, $dn, array("pwdAccountLockedTime" => array())); - $errno = ldap_errno($ldap); - if ( $errno ) { - $result = "ldaperror"; - } else { + if ( $directory->unlockAccount($ldap, $dn) ) { $result = "accountunlocked"; + } else { + $result = "ldaperror"; } } } From f692e3bfaa438dcb40865d86dc5e826c4fc66fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Wed, 24 Jul 2024 16:47:58 +0200 Subject: [PATCH 22/35] Use ltb-common function to modify password --- htdocs/resetpassword.php | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/htdocs/resetpassword.php b/htdocs/resetpassword.php index dfb34fe3..6ff91cf9 100644 --- a/htdocs/resetpassword.php +++ b/htdocs/resetpassword.php @@ -57,11 +57,6 @@ } } - $entry["userPassword"] = $password; - if ( $pwdreset === "true" ) { - $entry["pwdReset"] = "TRUE"; - } - if ( isset($prehook) ) { if ( !isset($prehook_login_value) ) { @@ -77,12 +72,11 @@ if ( $prehook_return > 0 and !$ignore_prehook_return) { $result = "passwordrefused"; } else { - $modification = ldap_mod_replace($ldap, $dn, $entry); - $errno = ldap_errno($ldap); - if ( $errno ) { - $result = "passwordrefused"; - } else { + $reset = ($pwdreset === "true") ? true : false; + if ($directory->modifyPassword($ldap, $dn, $password, $reset)) { $result = "passwordchanged"; + } else { + $result = "passwordrefused"; } } From d4d5e21cba87df92de9cbb9f5b892fd1b7c9a343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Wed, 24 Jul 2024 18:52:22 +0200 Subject: [PATCH 23/35] Use ltb-common resetAtNextConnection function --- conf/config.inc.php | 3 +-- htdocs/display.php | 3 +++ templates/display.tpl | 10 ++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/conf/config.inc.php b/conf/config.inc.php index 19efb376..97c5dd59 100644 --- a/conf/config.inc.php +++ b/conf/config.inc.php @@ -80,7 +80,6 @@ 'pwdfailuretime' => array( 'attribute' => 'pwdfailuretime', 'faclass' => 'lock', 'type' => 'date' ), 'pwdlastsuccess' => array( 'attribute' => 'pwdlastsuccess', 'faclass' => 'lock', 'type' => 'date' ), 'pwdpolicysubentry' => array( 'attribute' => 'pwdpolicysubentry', 'faclass' => 'lock', 'type' => 'ppolicy_dn' ), - 'pwdreset' => array( 'attribute' => 'pwdreset', 'faclass' => 'lock', 'type' => 'boolean' ), ); $activedirectory_attributes_map = array( 'authtimestamp' => array( 'attribute' => 'lastlogon', 'faclass' => 'lock', 'type' => 'ad_date' ), @@ -107,7 +106,7 @@ $display_items = array('identifier', 'firstname', 'lastname', 'title', 'businesscategory', 'employeenumber', 'employeetype', 'mail', 'mailquota', 'phone', 'mobile', 'fax', 'postaladdress', 'street', 'postalcode', 'l', 'state', 'organizationalunit', 'organization', 'manager', 'secretary' ); $display_title = "fullname"; $display_show_undefined = false; -$display_password_items = array('pwdchangedtime', 'pwdreset', 'pwdaccountlockedtime', 'pwdfailuretime','pwdpolicysubentry', 'authtimestamp', 'pwdlastsuccess', 'created', 'modified'); +$display_password_items = array('pwdchangedtime', 'pwdaccountlockedtime', 'pwdfailuretime','pwdpolicysubentry', 'authtimestamp', 'pwdlastsuccess', 'created', 'modified'); $display_password_expiration_date = true; # Features diff --git a/htdocs/display.php b/htdocs/display.php index 4ed5b805..0cd2ba21 100644 --- a/htdocs/display.php +++ b/htdocs/display.php @@ -117,6 +117,8 @@ $pwdMaxAge = $directory->getPasswordMaxAge($ldap, $dn, array('pwdPolicy' => $pwdPolicy, 'pwdMaxAge' => $ldap_password_max_age)); $expirationDate = $directory->getPasswordExpirationDate($ldap, $dn, array('pwdMaxAge' => $pwdMaxAge)); $isExpired = $directory->isPasswordExpired($ldap, $dn, array('pwdMaxAge' => $pwdMaxAge)); + + $resetAtNextConnection = $directory->resetAtNextConnection($ldap, $dn); } } @@ -132,6 +134,7 @@ $smarty->assign("unlockDate", $unlockDate); $smarty->assign("isExpired", $isExpired); $smarty->assign("ldapExpirationDate", $expirationDate ? $expirationDate->getTimestamp(): NULL); +$smarty->assign("resetAtNextConnection", $resetAtNextConnection); $smarty->assign("edit_link", $edit_link); diff --git a/templates/display.tpl b/templates/display.tpl index b63942ea..f5267207 100644 --- a/templates/display.tpl +++ b/templates/display.tpl @@ -90,6 +90,16 @@ {/if} + {if $resetAtNextConnection} + + + {$msg_label_pwdreset} + + + {$msg_true} + + + {/if} From 07688920278e53e6e149b6cb7c2d66c8d1e9f5a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 26 Jul 2024 15:06:04 +0200 Subject: [PATCH 24/35] Add feature to enable/disable account --- conf/config.inc.php | 12 ++++++++++ htdocs/disableaccount.php | 44 +++++++++++++++++++++++++++++++++++ htdocs/display.php | 7 ++++++ htdocs/enableaccount.php | 44 +++++++++++++++++++++++++++++++++++ htdocs/index.php | 3 +++ lang/en.inc.php | 7 ++++++ lang/fr.inc.php | 7 ++++++ templates/display.tpl | 48 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 172 insertions(+) create mode 100644 htdocs/disableaccount.php create mode 100644 htdocs/enableaccount.php diff --git a/conf/config.inc.php b/conf/config.inc.php index 97c5dd59..c6811381 100644 --- a/conf/config.inc.php +++ b/conf/config.inc.php @@ -110,21 +110,33 @@ $display_password_expiration_date = true; # Features + $use_checkpassword = true; + $use_resetpassword = true; $use_resetpassword_resetchoice = true; $resetpassword_reset_default = true; + $show_lockstatus = true; $use_unlockaccount = true; $use_lockaccount = true; + $show_expirestatus = true; + $use_searchlocked = true; + $use_searchexpired = true; + $use_searchwillexpire = true; $willexpiredays = 14; + $use_searchidle = true; $idledays = 60; +$use_enableaccount = false; +$use_disableaccount = false; +$show_enablestatus = false; + ## Mail # LDAP mail attribute $mail_attributes = array( "mail", "gosaMailAlternateAddress", "proxyAddresses" ); diff --git a/htdocs/disableaccount.php b/htdocs/disableaccount.php new file mode 100644 index 00000000..f54b4240 --- /dev/null +++ b/htdocs/disableaccount.php @@ -0,0 +1,44 @@ +connect(); + + $ldap = $ldap_connection[0]; + $result = $ldap_connection[1]; + + if ($ldap) { + if ( $directory->disableAccount($ldap, $dn) ) { + $result = "accountdisabled"; + } else { + $result = "ldaperror"; + } + } +} + +if ($audit_log_file) { + auditlog($audit_log_file, $dn, $audit_admin, "disableaccount", $result); +} + +header('Location: index.php?page=display&dn='.$dn.'&disableaccountresult='.$result); diff --git a/htdocs/display.php b/htdocs/display.php index 0cd2ba21..d07f9d6b 100644 --- a/htdocs/display.php +++ b/htdocs/display.php @@ -15,6 +15,7 @@ $posthookresult= ""; $ldapExpirationDate=""; $canLockAccount=""; +$isAccountEnabled = ""; if (isset($_GET["dn"]) and $_GET["dn"]) { $dn = $_GET["dn"]; @@ -119,6 +120,10 @@ $isExpired = $directory->isPasswordExpired($ldap, $dn, array('pwdMaxAge' => $pwdMaxAge)); $resetAtNextConnection = $directory->resetAtNextConnection($ldap, $dn); + + if ($show_enablestatus) { + $isAccountEnabled = $directory->isAccountEnabled($ldap, $dn); + } } } @@ -145,4 +150,6 @@ $smarty->assign("prehookresult", $prehookresult); $smarty->assign("posthookresult", $posthookresult); if ($canLockAccount == false) $smarty->assign("use_lockaccount", $canLockAccount); + +$smarty->assign("isAccountEnabled", $isAccountEnabled); ?> diff --git a/htdocs/enableaccount.php b/htdocs/enableaccount.php new file mode 100644 index 00000000..0756186e --- /dev/null +++ b/htdocs/enableaccount.php @@ -0,0 +1,44 @@ +connect(); + + $ldap = $ldap_connection[0]; + $result = $ldap_connection[1]; + + if ($ldap) { + if ( $directory->enableAccount($ldap, $dn) ) { + $result = "accountenabled"; + } else { + $result = "ldaperror"; + } + } +} + +if ($audit_log_file) { + auditlog($audit_log_file, $dn, $audit_admin, "enableaccount", $result); +} + +header('Location: index.php?page=display&dn='.$dn.'&enableaccountresult='.$result); diff --git a/htdocs/index.php b/htdocs/index.php index 9b08ab47..aea84392 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -135,6 +135,9 @@ $smarty->assign('use_searchwillexpire',$use_searchwillexpire); $smarty->assign('use_searchidle',$use_searchidle); $smarty->assign('fake_password_inputs',$fake_password_inputs); +$smarty->assign('use_enableaccount',$use_enableaccount); +$smarty->assign('use_disableaccount',$use_disableaccount); +$smarty->assign('show_enablestatus',$show_enablestatus); # Assign messages $smarty->assign('lang',$lang); diff --git a/lang/en.inc.php b/lang/en.inc.php index 493600a9..a0a075d1 100644 --- a/lang/en.inc.php +++ b/lang/en.inc.php @@ -4,11 +4,16 @@ # English #============================================================================== +$messages['accountenabled'] = "Account is enabled"; +$messages['accountdisabled'] = "Account is disabled"; $messages['accountlocked'] = "Account is locked"; +$messages['accountnotdisabled'] = "Fail to disable account"; +$messages['accountnotenabled'] = "Fail to enable account"; $messages['accountnotlocked'] = "Fail to lock account"; $messages['accountnotunlocked'] = "Fail to unlock account"; $messages['accountunlocked'] = "Account is not locked"; $messages['accountstatus'] = "Account status"; +$messages['actionforbidden'] = "Action forbidden"; $messages['changesubject'] = "Your password has been changed"; $messages['changesubjectforadmin'] = "User password has been changed"; $messages['changemessage'] = "Hello {name},\n\nYour password has been changed.\n\nIf you didn't request a password reset, please contact your administrator for details."; @@ -16,9 +21,11 @@ $messages['checkpassword'] = "Check password"; $messages['currentpassword'] = "Current password"; $messages['dashboards'] = "Dashboards"; +$messages['disableaccount'] = "Disable account"; $messages['displayentry'] = "Display entry"; $messages['dnrequired'] = "Entry identifier required"; $messages['editentry'] = "Edit entry"; +$messages['enableaccount'] = "Enable account"; $messages['entriesfound'] = "entries found"; $messages['entryfound'] = "entry found"; $messages['expiredaccounts'] = "Passwords expired"; diff --git a/lang/fr.inc.php b/lang/fr.inc.php index ca3ecb87..bf4e1608 100644 --- a/lang/fr.inc.php +++ b/lang/fr.inc.php @@ -4,11 +4,16 @@ # French #============================================================================== +$messages['accountenabled'] = "Le compte est activé"; +$messages['accountdisabled'] = "Le compte est désactivé"; $messages['accountlocked'] = "Le compte est bloqué"; +$messages['accountnotdisabled'] = "Échec de la désactivation du compte"; +$messages['accountnotenabled'] = "Échec de l'activation du compte"; $messages['accountnotlocked'] = "Échec de blocage du compte"; $messages['accountnotunlocked'] = "Échec de déblocage du compte"; $messages['accountstatus'] = "Statut du compte"; $messages['accountunlocked'] = "Le compte n'est pas bloqué"; +$messages['actionforbidden'] = "Action interdite"; $messages['changesubject'] = "Votre mot de passe a été changé"; $messages['changesubjectforadmin'] = "Le mot de passe d'un utilisateur a été changé"; $messages['changemessage'] = "Bonjour {name},\n\nVotre mot de passe a été changé.\nSi vous n'êtes pas à l'origine de cette demande, contactez votre administrateur pour obtenir des précisions."; @@ -16,9 +21,11 @@ $messages['checkpassword'] = "Vérification du mot de passe"; $messages['currentpassword'] = "Mot de passe actuel"; $messages['dashboards'] = "Tableaux de bord"; +$messages['disableaccount'] = "Désactiver le compte"; $messages['displayentry'] = "Afficher l'entrée"; $messages['dnrequired'] = "L'identifiant de l'entrée est requis"; $messages['editentry'] = "Modifier l'entrée"; +$messages['enableaccount'] = "Activer le compte"; $messages['entriesfound'] = "entrées trouvées"; $messages['entryfound'] = "entrée trouvée"; $messages['expiredaccounts'] = "Mots de passe expirés"; diff --git a/templates/display.tpl b/templates/display.tpl index f5267207..f9294b98 100644 --- a/templates/display.tpl +++ b/templates/display.tpl @@ -271,5 +271,53 @@ {/if} {/if} + {if $show_enablestatus} + {if $isAccountEnabled} +
+
+

+ + {$msg_accountenabled} +

+
+ {if $use_disableaccount} +
+
+ {if $disableaccountresult eq 'ldaperror' or $disableaccountresult eq 'actionforbidden'} +
{$msg_accountnotdisabled}
+ {/if} + + +
+
+ {/if} +
+ {else} +
+
+

+ + {$msg_accountdisabled} +

+
+ {if $use_enableaccount} +
+
+ {if $enableaccountresult eq 'ldaperror' or $enableaccountresult eq 'actionforbidden'} +
{$msg_accountnotenabled}
+ {/if} + + +
+
+ {/if} +
+ {/if} + {/if} + From 258b483b192b7874d7f0885b1563df07fd0f3c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 26 Jul 2024 15:46:33 +0200 Subject: [PATCH 25/35] Remove composer.lock --- composer.lock | 468 -------------------------------------------------- 1 file changed, 468 deletions(-) delete mode 100644 composer.lock diff --git a/composer.lock b/composer.lock deleted file mode 100644 index c270ef46..00000000 --- a/composer.lock +++ /dev/null @@ -1,468 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "2ffb8e112bf5f10bd6eb4e8db16e4bfe", - "packages": [ - { - "name": "components/jquery", - "version": "v3.7.1", - "source": { - "type": "git", - "url": "https://github.com/components/jquery.git", - "reference": "8edc7785239bb8c2ad2b83302b856a1d61de60e7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/components/jquery/zipball/8edc7785239bb8c2ad2b83302b856a1d61de60e7", - "reference": "8edc7785239bb8c2ad2b83302b856a1d61de60e7", - "shasum": "" - }, - "type": "component", - "extra": { - "component": { - "scripts": [ - "jquery.js" - ], - "files": [ - "jquery.min.js", - "jquery.min.map", - "jquery.slim.js", - "jquery.slim.min.js", - "jquery.slim.min.map" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "JS Foundation and other contributors" - } - ], - "description": "jQuery JavaScript Library", - "homepage": "http://jquery.com", - "support": { - "forum": "http://forum.jquery.com", - "irc": "irc://irc.freenode.org/jquery", - "issues": "https://github.com/jquery/jquery/issues", - "source": "https://github.com/jquery/jquery", - "wiki": "http://docs.jquery.com/" - }, - "time": "2023-09-22T01:43:46+00:00" - }, - { - "name": "datatables.net/datatables.net", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/DataTables/Dist-DataTables.git", - "reference": "5dcb88d52c3b29c2fd86ba2073f3b95258fd0b61" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/DataTables/Dist-DataTables/zipball/5dcb88d52c3b29c2fd86ba2073f3b95258fd0b61", - "reference": "5dcb88d52c3b29c2fd86ba2073f3b95258fd0b61", - "shasum": "" - }, - "require": { - "components/jquery": ">=1.7" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "SpryMedia", - "homepage": "https://datatables.net" - } - ], - "description": "DataTables is a plug-in for the jQuery Javascript library. It is a highly flexible tool, based upon the foundations of progressive enhancement, which will add advanced interaction controls to any HTML table. This is jQuery DataTables", - "homepage": "http://www.datatables.net/", - "keywords": [ - "datatables", - "jquery", - "table" - ], - "support": { - "forum": "https://datatables.net/forums", - "source": "https://github.com/DataTables/Dist-DataTables" - }, - "time": "2024-07-19T08:20:23+00:00" - }, - { - "name": "datatables.net/datatables.net-bs5", - "version": "2.0.8", - "source": { - "type": "git", - "url": "https://github.com/DataTables/Dist-DataTables-Bootstrap5.git", - "reference": "b6cce12376f469268edf717e8a82e440a610db31" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/DataTables/Dist-DataTables-Bootstrap5/zipball/b6cce12376f469268edf717e8a82e440a610db31", - "reference": "b6cce12376f469268edf717e8a82e440a610db31", - "shasum": "" - }, - "require": { - "datatables.net/datatables.net": ">=1.12.1", - "twbs/bootstrap": "5.*" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "SpryMedia", - "homepage": "https://datatables.net" - } - ], - "description": "DataTables is a plug-in for the jQuery Javascript library. It is a highly flexible tool, based upon the foundations of progressive enhancement, which will add advanced interaction controls to any HTML table. This is DataTables with styling for [Bootstrap5](https://getbootstrap.com/)", - "homepage": "http://www.datatables.net/", - "keywords": [ - "bootstrap", - "bootstrap5", - "datatables", - "jquery", - "table" - ], - "support": { - "forum": "https://datatables.net/forums", - "issues": "https://github.com/DataTables/Dist-DataTables-Bootstrap5/issues", - "source": "https://github.com/DataTables/Dist-DataTables-Bootstrap5" - }, - "time": "2024-05-28T15:36:34+00:00" - }, - { - "name": "datatables.net/datatables.net-buttons", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/DataTables/Dist-DataTables-Buttons.git", - "reference": "68fc52d0385f164024686b456c84c387cca595fa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/DataTables/Dist-DataTables-Buttons/zipball/68fc52d0385f164024686b456c84c387cca595fa", - "reference": "68fc52d0385f164024686b456c84c387cca595fa", - "shasum": "" - }, - "require": { - "datatables.net/datatables.net": ">=1.12.1" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "SpryMedia", - "homepage": "https://datatables.net" - } - ], - "description": "The Buttons extension for DataTables provides a common set of options, API methods and styling to display buttons on a page that will interact with a DataTable. It also provides plug-ins for file export (HTML5 and Flash), print view and column visibility. Other libraries, such as Editor and Select also provide buttons specific to their use cases. This is Buttons for DataTables", - "homepage": "http://www.datatables.net/", - "keywords": [ - "Column Visibility", - "buttons", - "csv", - "datatables", - "excel", - "jquery", - "pdf", - "print", - "table" - ], - "support": { - "forum": "https://datatables.net/forums", - "source": "https://github.com/DataTables/Dist-DataTables-Buttons" - }, - "time": "2024-07-19T08:00:18+00:00" - }, - { - "name": "datatables.net/datatables.net-buttons-bs5", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/DataTables/Dist-DataTables-Buttons-Bootstrap5.git", - "reference": "19d2ff2399af078465989f52ffc969d9ed765f1f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/DataTables/Dist-DataTables-Buttons-Bootstrap5/zipball/19d2ff2399af078465989f52ffc969d9ed765f1f", - "reference": "19d2ff2399af078465989f52ffc969d9ed765f1f", - "shasum": "" - }, - "require": { - "datatables.net/datatables.net-bs5": ">=1.12.1", - "datatables.net/datatables.net-buttons": ">=2.2.3" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "SpryMedia", - "homepage": "https://datatables.net" - } - ], - "description": "The Buttons extension for DataTables provides a common set of options, API methods and styling to display buttons on a page that will interact with a DataTable. It also provides plug-ins for file export (HTML5 and Flash), print view and column visibility. Other libraries, such as Editor and Select also provide buttons specific to their use cases. This is Buttons for DataTables with styling for [Bootstrap5](https://getbootstrap.com/)", - "homepage": "http://www.datatables.net/", - "keywords": [ - "Column Visibility", - "bootstrap", - "bootstrap5", - "buttons", - "csv", - "datatables", - "excel", - "jquery", - "pdf", - "print", - "table" - ], - "support": { - "forum": "https://datatables.net/forums", - "issues": "https://github.com/DataTables/Dist-DataTables-Buttons-Bootstrap5/issues", - "source": "https://github.com/DataTables/Dist-DataTables-Buttons-Bootstrap5" - }, - "time": "2024-04-16T12:07:18+00:00" - }, - { - "name": "fortawesome/font-awesome", - "version": "6.5.2", - "source": { - "type": "git", - "url": "https://github.com/FortAwesome/Font-Awesome.git", - "reference": "c0f460dca7f7688761120415ff3c9cf7f73119be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/FortAwesome/Font-Awesome/zipball/c0f460dca7f7688761120415ff3c9cf7f73119be", - "reference": "c0f460dca7f7688761120415ff3c9cf7f73119be", - "shasum": "" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "CC-BY-4.0", - "OFL-1.1", - "MIT" - ], - "authors": [ - { - "name": "The Font Awesome Team", - "homepage": "https://github.com/orgs/FortAwesome/people" - } - ], - "description": "The iconic font, CSS, and SVG framework", - "homepage": "https://fontawesome.com", - "keywords": [ - "FontAwesome", - "awesome", - "bootstrap", - "font", - "icon", - "svg" - ], - "support": { - "docs": "http://fontawesome.com/docs", - "email": "hello@fontawesome.com", - "issues": "https://github.com/FortAwesome/Font-Awesome/issues", - "source": "https://github.com/FortAwesome/Font-Awesome" - }, - "time": "2024-04-02T18:54:47+00:00" - }, - { - "name": "ltb-project/ltb-common", - "version": "v0.2.1", - "source": { - "type": "git", - "url": "https://github.com/ltb-project/ltb-common.git", - "reference": "0ca06f8aafd116f214418efe9e3f22609c94f431" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ltb-project/ltb-common/zipball/0ca06f8aafd116f214418efe9e3f22609c94f431", - "reference": "0ca06f8aafd116f214418efe9e3f22609c94f431", - "shasum": "" - }, - "require": { - "ext-ldap": ">=7.4", - "php": ">=7.4", - "phpmailer/phpmailer": "^6.5.0" - }, - "require-dev": { - "mockery/mockery": ">=1.4", - "phpunit/phpunit": ">=8" - }, - "type": "library", - "autoload": { - "psr-4": { - "Ltb\\": "src/Ltb" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-3.0-or-later" - ], - "description": "PHP framework for LTB project applications", - "support": { - "issues": "https://github.com/ltb-project/ltb-common/issues", - "source": "https://github.com/ltb-project/ltb-common/tree/v0.2.1" - }, - "time": "2024-04-26T10:05:38+00:00" - }, - { - "name": "phpmailer/phpmailer", - "version": "v6.9.1", - "source": { - "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "039de174cd9c17a8389754d3b877a2ed22743e18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/039de174cd9c17a8389754d3b877a2ed22743e18", - "reference": "039de174cd9c17a8389754d3b877a2ed22743e18", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "php": ">=5.5.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "doctrine/annotations": "^1.2.6 || ^1.13.3", - "php-parallel-lint/php-console-highlighter": "^1.0.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", - "phpcompatibility/php-compatibility": "^9.3.5", - "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.7.2", - "yoast/phpunit-polyfills": "^1.0.4" - }, - "suggest": { - "decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication", - "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", - "ext-openssl": "Needed for secure SMTP sending and DKIM signing", - "greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication", - "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", - "psr/log": "For optional PSR-3 debug logging", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)", - "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPMailer\\PHPMailer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-only" - ], - "authors": [ - { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" - }, - { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" - }, - { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" - }, - { - "name": "Brent R. Matzelle" - } - ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "support": { - "issues": "https://github.com/PHPMailer/PHPMailer/issues", - "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.1" - }, - "funding": [ - { - "url": "https://github.com/Synchro", - "type": "github" - } - ], - "time": "2023-11-25T22:23:28+00:00" - }, - { - "name": "twbs/bootstrap", - "version": "v5.3.2", - "source": { - "type": "git", - "url": "https://github.com/twbs/bootstrap.git", - "reference": "344e912d04b5b6a04482113eff20ab416ff01048" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/twbs/bootstrap/zipball/344e912d04b5b6a04482113eff20ab416ff01048", - "reference": "344e912d04b5b6a04482113eff20ab416ff01048", - "shasum": "" - }, - "replace": { - "twitter/bootstrap": "self.version" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mark Otto", - "email": "markdotto@gmail.com" - }, - { - "name": "Jacob Thornton", - "email": "jacobthornton@gmail.com" - } - ], - "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", - "homepage": "https://getbootstrap.com/", - "keywords": [ - "JS", - "css", - "framework", - "front-end", - "mobile-first", - "responsive", - "sass", - "web" - ], - "support": { - "issues": "https://github.com/twbs/bootstrap/issues", - "source": "https://github.com/twbs/bootstrap/tree/v5.3.2" - }, - "time": "2023-09-14T14:19:27+00:00" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.2.0" -} From e9926715f8fc2dd5a7461da1138ccc55057daec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Wed, 21 Aug 2024 19:38:53 +0200 Subject: [PATCH 26/35] Use new lockDate function to remove OpenLDAP specific code --- conf/config.inc.php | 2 +- htdocs/display.php | 9 +++------ templates/display.tpl | 10 ++++++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/conf/config.inc.php b/conf/config.inc.php index b2d4135a..42ca0827 100644 --- a/conf/config.inc.php +++ b/conf/config.inc.php @@ -107,7 +107,7 @@ $display_items = array('identifier', 'firstname', 'lastname', 'title', 'businesscategory', 'employeenumber', 'employeetype', 'mail', 'mailquota', 'phone', 'mobile', 'fax', 'postaladdress', 'street', 'postalcode', 'l', 'state', 'organizationalunit', 'organization', 'manager', 'secretary' ); $display_title = "fullname"; $display_show_undefined = false; -$display_password_items = array('pwdchangedtime', 'pwdaccountlockedtime', 'pwdfailuretime','pwdpolicysubentry', 'authtimestamp', 'pwdlastsuccess', 'created', 'modified'); +$display_password_items = array('pwdchangedtime', 'pwdfailuretime','pwdpolicysubentry', 'authtimestamp', 'pwdlastsuccess', 'created', 'modified'); $display_password_expiration_date = true; # Features diff --git a/htdocs/display.php b/htdocs/display.php index d07f9d6b..7969b219 100644 --- a/htdocs/display.php +++ b/htdocs/display.php @@ -16,6 +16,7 @@ $ldapExpirationDate=""; $canLockAccount=""; $isAccountEnabled = ""; +$lockDate = ""; if (isset($_GET["dn"]) and $_GET["dn"]) { $dn = $_GET["dn"]; @@ -104,13 +105,8 @@ $edit_link = str_replace("{dn}", urlencode($dn), $display_edit_link); } - # Remove lockout date if special value - $lockoutDateAttribute = $attributes_map['pwdaccountlockedtime']['attribute']; - if ( isset($entry[0][$lockoutDateAttribute]) and $entry[0][$lockoutDateAttribute][0] === "000001010000Z") { - unset($entry[0][$lockoutDateAttribute]); - } - $lockoutDuration = $directory->getLockoutDuration($ldap, $dn, array('pwdPolicy' => $pwdPolicy, 'lockoutDuration' => $ldap_lockout_duration)); + $lockDate = $directory->getLockDate($ldap, $dn); $unlockDate = $directory->getUnlockDate($ldap, $dn, array('lockoutDuration' => $lockoutDuration)); $isLocked = $directory->isLocked($ldap, $dn, array('lockoutDuration' => $lockoutDuration)); $canLockAccount = $directory->canLockAccount($ldap, $dn, array('pwdPolicy' => $pwdPolicy)); @@ -136,6 +132,7 @@ $smarty->assign("show_undef", $display_show_undefined); $smarty->assign("isLocked", $isLocked); +$smarty->assign("lockDate", $lockDate); $smarty->assign("unlockDate", $unlockDate); $smarty->assign("isExpired", $isExpired); $smarty->assign("ldapExpirationDate", $expirationDate ? $expirationDate->getTimestamp(): NULL); diff --git a/templates/display.tpl b/templates/display.tpl index 51cecae8..752a7de5 100644 --- a/templates/display.tpl +++ b/templates/display.tpl @@ -80,6 +80,16 @@ {/foreach} + {if $lockDate} + + + {$msg_label_pwdaccountlockedtime} + + + {$lockDate|date_format:{$date_specifiers}|truncate:10000} + + + {/if} {if {$display_password_expiration_date} and {$ldapExpirationDate}} From 81204792cbc084bffe5890b3726a40edb9e247b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 23 Aug 2024 17:30:38 +0200 Subject: [PATCH 27/35] Clean lock account code --- htdocs/lockaccount.php | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/htdocs/lockaccount.php b/htdocs/lockaccount.php index 7d58feb8..92398872 100644 --- a/htdocs/lockaccount.php +++ b/htdocs/lockaccount.php @@ -30,13 +30,11 @@ $pwdPolicy = NULL; - # Search pwdLockout in associated ppolicy if ($ldap) { $search_ppolicysubentry = ldap_read($ldap, $dn, "(objectClass=*)", array('pwdpolicysubentry')); $user_entry = ldap_get_entries($ldap, $search_ppolicysubentry); - # Search active password policy $pwdPolicy = ""; if (isset($user_entry[0]['pwdpolicysubentry'][0])) { @@ -44,25 +42,9 @@ } elseif (isset($ldap_default_ppolicy)) { $pwdPolicy = $ldap_default_ppolicy; } - - # Search pwdLockout attribute - if ($pwdPolicy) { - $search_ppolicy = ldap_read($ldap, $pwdPolicy, "(objectClass=pwdPolicy)", array('pwdlockout')); - - if ( $errno ) { - error_log("LDAP - PPolicy search error $errno (".ldap_error($ldap).")"); - } else { - $ppolicy_entry = ldap_get_entries($ldap, $search_ppolicy); - $pwdLockout = strtolower($ppolicy_entry[0]['pwdlockout'][0]) == "true" ? true : false; - if( $pwdLockout == false ) - { - error_log("No pwdLockout or pwdLockout=FALSE in associated ppolicy: ".$pwdPolicy.". Account locking disabled"); - } - } - } } - # apply the modification only if a password policy set with pwdLockout=TRUE is associated to the account + # Apply the modification only the password can be locked if ($ldap and $directory->canLockAccount($ldap, $dn, array('pwdPolicy' => $pwdPolicy))) { if ( $directory->lockAccount($ldap, $dn) ) { $result = "accountlocked"; From 5f887b0ed5c8ee25c0776d763e56ad587ace3a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 23 Aug 2024 17:32:56 +0200 Subject: [PATCH 28/35] Use Directory interface for search locked account --- htdocs/searchlocked.php | 120 +++++++++++++--------------------------- 1 file changed, 38 insertions(+), 82 deletions(-) diff --git a/htdocs/searchlocked.php b/htdocs/searchlocked.php index 279b275c..d23be776 100644 --- a/htdocs/searchlocked.php +++ b/htdocs/searchlocked.php @@ -5,92 +5,48 @@ require_once("../conf/config.inc.php"); require __DIR__ . '/../vendor/autoload.php'; -require_once("../lib/date.inc.php"); +[$ldap,$result,$nb_entries,$entries,$size_limit_reached] = $ldapInstance->search($ldap_user_filter, array('pwdpolicysubentry'), $attributes_map, $search_result_title, $search_result_sortby, $search_result_items, $ldap_scope); - -# Search filter -$ldap_filter = "(&".$ldap_user_filter."(pwdAccountLockedTime=*))"; - -# Search attributes -$attributes = array('pwdAccountLockedTime', 'pwdPolicySubentry'); - -[$ldap,$result,$nb_entries,$entries,$size_limit_reached]=$ldapInstance->search($ldap_filter, $attributes, $attributes_map, $search_result_title, $search_result_sortby, $search_result_items, $ldap_scope); - -if ( ! empty($entries) ) +if ( !empty($entries) ) { - # Register policies - $pwdPolicies = array(); - - # Check if entry is still locked - foreach($entries as $entry_key => $entry) { - - # Search active password policy - $pwdPolicy = ""; - if (isset($entry['pwdpolicysubentry'][0])) { - $pwdPolicy = $entry['pwdpolicysubentry'][0]; - } elseif (isset($ldap_default_ppolicy)) { - $pwdPolicy = $ldap_default_ppolicy; - } - - $isLocked = false; - $ppolicy_entry = ""; - - if ($pwdPolicy) { - if (!isset($pwdPolicies[$pwdPolicy])){ - $search_ppolicy = ldap_read($ldap, $pwdPolicy, "(objectClass=pwdPolicy)", array('pwdLockoutDuration')); - - if ( $errno ) { - error_log("LDAP - PPolicy search error $errno (".ldap_error($ldap).")"); - } else { - $ppolicy_entry = ldap_get_entries($ldap, $search_ppolicy); - $pwdPolicies[$pwdPolicy]['pwdLockoutDuration'] = $ppolicy_entry[0]['pwdlockoutduration'][0]; - } - } - - # Lock - $pwdLockoutDuration = $pwdPolicies[$pwdPolicy]['pwdLockoutDuration']; - $pwdAccountLockedTime = $entry['pwdaccountlockedtime'][0]; - - if ( $pwdAccountLockedTime === "000001010000Z" ) { - $isLocked = true; - } else if (isset($pwdAccountLockedTime)) { - if (isset($pwdLockoutDuration) and ($pwdLockoutDuration > 0)) { - $lockDate = ldapDate2phpDate($pwdAccountLockedTime); - $unlockDate = date_add( $lockDate, new DateInterval('PT'.$pwdLockoutDuration.'S')); - if ( time() <= $unlockDate->getTimestamp() ) { - $isLocked = true; - } - } else { - $isLocked = true; - } - } - } - - if ( $isLocked === false ) { - unset($entries[$entry_key]); - $nb_entries--; - } - - } - - $smarty->assign("page_title", "lockedaccounts"); - if ($nb_entries === 0) { - $result = "noentriesfound"; - } else { - $smarty->assign("nb_entries", $nb_entries); - $smarty->assign("entries", $entries); - $smarty->assign("size_limit_reached", $size_limit_reached); - $columns = $search_result_items; - if (! in_array($search_result_title, $columns)) array_unshift($columns, $search_result_title); - $smarty->assign("listing_columns", $columns); - $smarty->assign("listing_linkto", isset($search_result_linkto) ? $search_result_linkto : array($search_result_title)); - $smarty->assign("listing_sortby", array_search($search_result_sortby, $columns)); - $smarty->assign("show_undef", $search_result_show_undefined); - $smarty->assign("truncate_value_after", $search_result_truncate_value_after); - if ($use_unlockaccount) { $smarty->assign("display_unlock_button", true); } - } + # Check if entry is still locked + foreach($entries as $entry_key => $entry) { + # Search active password policy + $pwdPolicy = ""; + if (isset($entry['pwdpolicysubentry'][0])) { + $pwdPolicy = $entry['pwdpolicysubentry'][0]; + } elseif (isset($ldap_default_ppolicy)) { + $pwdPolicy = $ldap_default_ppolicy; + } + $lockoutDuration = $directory->getLockoutDuration($ldap, $entry['dn'], array('pwdPolicy' => $pwdPolicy, 'lockoutDuration' => $ldap_lockout_duration)); + $isLocked = $directory->isLocked($ldap, $entry['dn'], array('lockoutDuration' => $lockoutDuration)); + + if ( $isLocked === false ) { + unset($entries[$entry_key]); + $nb_entries--; + } + + } + + $smarty->assign("page_title", "lockedaccounts"); + if ($nb_entries === 0) { + $result = "noentriesfound"; + } else { + $smarty->assign("nb_entries", $nb_entries); + $smarty->assign("entries", $entries); + $smarty->assign("size_limit_reached", $size_limit_reached); + + $columns = $search_result_items; + if (! in_array($search_result_title, $columns)) array_unshift($columns, $search_result_title); + $smarty->assign("listing_columns", $columns); + $smarty->assign("listing_linkto", isset($search_result_linkto) ? $search_result_linkto : array($search_result_title)); + $smarty->assign("listing_sortby", array_search($search_result_sortby, $columns)); + $smarty->assign("show_undef", $search_result_show_undefined); + $smarty->assign("truncate_value_after", $search_result_truncate_value_after); + if ($use_unlockaccount) { $smarty->assign("display_unlock_button", true); } + } } ?> From 0c4ce5039c988e645229c0abd3f434139b91a192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 23 Aug 2024 17:44:29 +0200 Subject: [PATCH 29/35] Use Directory interface for search expired passwords --- htdocs/searchexpired.php | 119 +++++++++++++-------------------------- 1 file changed, 40 insertions(+), 79 deletions(-) diff --git a/htdocs/searchexpired.php b/htdocs/searchexpired.php index cc96393c..0487fa47 100644 --- a/htdocs/searchexpired.php +++ b/htdocs/searchexpired.php @@ -5,88 +5,49 @@ require_once("../conf/config.inc.php"); require __DIR__ . '/../vendor/autoload.php'; -require_once("../lib/date.inc.php"); +[$ldap,$result,$nb_entries,$entries,$size_limit_reached] = $ldapInstance->search($ldap_user_filter, array('pwdpolicysubentry'), $attributes_map, $search_result_title, $search_result_sortby, $search_result_items, $ldap_scope); - -$ldapExpirationDate=""; - -# Search filter -$ldap_filter = "(&".$ldap_user_filter."(pwdChangedTime=*))"; - -# Search attributes -$attributes = array('pwdChangedTime', 'pwdPolicySubentry'); - -[$ldap,$result,$nb_entries,$entries,$size_limit_reached]=$ldapInstance->search($ldap_filter, $attributes, $attributes_map, $search_result_title, $search_result_sortby, $search_result_items, $ldap_scope); - -if ( ! empty($entries) ) +if ( !empty($entries) ) { - # Register policies - $pwdPolicies = array(); - - # Check if entry is expired - foreach($entries as $entry_key => $entry) { - - # Search active password policy - $pwdPolicy = ""; - if (isset($entry['pwdpolicysubentry'][0])) { - $pwdPolicy = $entry['pwdpolicysubentry'][0]; - } elseif (isset($ldap_default_ppolicy)) { - $pwdPolicy = $ldap_default_ppolicy; - } - - $isExpired = false; - $ppolicy_entry = ""; - - if ($pwdPolicy) { - if (!isset($pwdPolicies[$pwdPolicy])){ - $search_ppolicy = ldap_read($ldap, $pwdPolicy, "(objectClass=pwdPolicy)", array('pwdMaxAge')); - - if ( $errno ) { - error_log("LDAP - PPolicy search error $errno (".ldap_error($ldap).")"); - } else { - $ppolicy_entry = ldap_get_entries($ldap, $search_ppolicy); - $pwdPolicies[$pwdPolicy]['pwdMaxAge'] = $ppolicy_entry[0]['pwdmaxage'][0]; - } - } - - # Expiration - $pwdMaxAge = $pwdPolicies[$pwdPolicy]['pwdMaxAge']; - $pwdChangedTime = $entry['pwdchangedtime'][0]; - - if (isset($pwdChangedTime) and isset($pwdMaxAge) and ($pwdMaxAge > 0)) { - $changedDate = ldapDate2phpDate($pwdChangedTime); - $expirationDate = date_add( $changedDate, new DateInterval('PT'.$pwdMaxAge.'S')); - if ( time() >= $expirationDate->getTimestamp() ) { - $isExpired = true; - } - } - - } - - if ( $isExpired === false ) { - unset($entries[$entry_key]); - $nb_entries--; - } - - } - - $smarty->assign("page_title", "expiredaccounts"); - if ($nb_entries === 0) { - $result = "noentriesfound"; - } else { - $smarty->assign("nb_entries", $nb_entries); - $smarty->assign("entries", $entries); - $smarty->assign("size_limit_reached", $size_limit_reached); - - $columns = $search_result_items; - if (! in_array($search_result_title, $columns)) array_unshift($columns, $search_result_title); - $smarty->assign("listing_columns", $columns); - $smarty->assign("listing_linkto", isset($search_result_linkto) ? $search_result_linkto : array($search_result_title)); - $smarty->assign("listing_sortby", array_search($search_result_sortby, $columns)); - $smarty->assign("show_undef", $search_result_show_undefined); - $smarty->assign("truncate_value_after", $search_result_truncate_value_after); - } + # Check if entry is expired + foreach($entries as $entry_key => $entry) { + + # Search active password policy + $pwdPolicy = ""; + if (isset($entry['pwdpolicysubentry'][0])) { + $pwdPolicy = $entry['pwdpolicysubentry'][0]; + } elseif (isset($ldap_default_ppolicy)) { + $pwdPolicy = $ldap_default_ppolicy; + } + + $pwdMaxAge = $directory->getPasswordMaxAge($ldap, $entry["dn"], array('pwdPolicy' => $pwdPolicy, 'pwdMaxAge' => $ldap_password_max_age)); + $expirationDate = $directory->getPasswordExpirationDate($ldap, $entry["dn"], array('pwdMaxAge' => $pwdMaxAge)); + $isExpired = $directory->isPasswordExpired($ldap, $entry["dn"], array('pwdMaxAge' => $pwdMaxAge)); + + if ( $isExpired === false ) { + unset($entries[$entry_key]); + $nb_entries--; + } + + } + + $smarty->assign("page_title", "expiredaccounts"); + if ($nb_entries === 0) { + $result = "noentriesfound"; + } else { + $smarty->assign("nb_entries", $nb_entries); + $smarty->assign("entries", $entries); + $smarty->assign("size_limit_reached", $size_limit_reached); + + $columns = $search_result_items; + if (! in_array($search_result_title, $columns)) array_unshift($columns, $search_result_title); + $smarty->assign("listing_columns", $columns); + $smarty->assign("listing_linkto", isset($search_result_linkto) ? $search_result_linkto : array($search_result_title)); + $smarty->assign("listing_sortby", array_search($search_result_sortby, $columns)); + $smarty->assign("show_undef", $search_result_show_undefined); + $smarty->assign("truncate_value_after", $search_result_truncate_value_after); + } } ?> From 86de562b61d6b2a12e95abbe8a081397bca96a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 23 Aug 2024 18:21:21 +0200 Subject: [PATCH 30/35] Use Directory interface for search idle accounts --- htdocs/index.php | 1 + htdocs/searchidle.php | 35 +++++++++++++++-------------------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index 7519e4e7..4c95a313 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -81,6 +81,7 @@ case "activedirectory": $attributes_map = array_merge($attributes_map, $activedirectory_attributes_map); $directory = new \Ltb\Directory\ActiveDirectory(); + $ldap_lastauth_attribute = "lastLogon"; break; } diff --git a/htdocs/searchidle.php b/htdocs/searchidle.php index 9904eb23..e2a0c56c 100644 --- a/htdocs/searchidle.php +++ b/htdocs/searchidle.php @@ -7,35 +7,30 @@ require __DIR__ . '/../vendor/autoload.php'; require_once("../lib/date.inc.php"); - - # Compute idle date $dateIdle = new DateTime(); date_sub( $dateIdle, new DateInterval('P'.$idledays.'D') ); -$dateIdleLdap = string2ldapDate( $dateIdle->format('d/m/Y') ); +$dateIdleLdap = $directory->getLdapDate($dateIdle); # Search filter $ldap_filter = "(&".$ldap_user_filter."(|(!(".$ldap_lastauth_attribute."=*))(".$ldap_lastauth_attribute."<=".$dateIdleLdap.")))"; -# Search attributes -$attributes = array(); +[$ldap,$result,$nb_entries,$entries,$size_limit_reached] = $ldapInstance->search($ldap_filter, array(), $attributes_map, $search_result_title, $search_result_sortby, $search_result_items, $ldap_scope); -[$ldap,$result,$nb_entries,$entries,$size_limit_reached]=$ldapInstance->search($ldap_filter, $attributes, $attributes_map, $search_result_title, $search_result_sortby, $search_result_items, $ldap_scope); - -if ( ! empty($entries) ) +if ( !empty($entries) ) { - $smarty->assign("page_title", "idleaccountstitle"); - $smarty->assign("nb_entries", $nb_entries); - $smarty->assign("entries", $entries); - $smarty->assign("size_limit_reached", $size_limit_reached); - - $columns = $search_result_items; - if (! in_array($search_result_title, $columns)) array_unshift($columns, $search_result_title); - $smarty->assign("listing_columns", $columns); - $smarty->assign("listing_linkto", isset($search_result_linkto) ? $search_result_linkto : array($search_result_title)); - $smarty->assign("listing_sortby", array_search($search_result_sortby, $columns)); - $smarty->assign("show_undef", $search_result_show_undefined); - $smarty->assign("truncate_value_after", $search_result_truncate_value_after); + $smarty->assign("page_title", "idleaccountstitle"); + $smarty->assign("nb_entries", $nb_entries); + $smarty->assign("entries", $entries); + $smarty->assign("size_limit_reached", $size_limit_reached); + + $columns = $search_result_items; + if (! in_array($search_result_title, $columns)) array_unshift($columns, $search_result_title); + $smarty->assign("listing_columns", $columns); + $smarty->assign("listing_linkto", isset($search_result_linkto) ? $search_result_linkto : array($search_result_title)); + $smarty->assign("listing_sortby", array_search($search_result_sortby, $columns)); + $smarty->assign("show_undef", $search_result_show_undefined); + $smarty->assign("truncate_value_after", $search_result_truncate_value_after); } ?> From 9ac3878cfdb3776b27d778136674322427736131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 23 Aug 2024 18:41:50 +0200 Subject: [PATCH 31/35] Use Directory interface for search will expire passwords --- htdocs/searchwillexpire.php | 129 +++++++++++++----------------------- 1 file changed, 47 insertions(+), 82 deletions(-) diff --git a/htdocs/searchwillexpire.php b/htdocs/searchwillexpire.php index 2c03b8b9..1238a273 100644 --- a/htdocs/searchwillexpire.php +++ b/htdocs/searchwillexpire.php @@ -5,91 +5,56 @@ require_once("../conf/config.inc.php"); require __DIR__ . '/../vendor/autoload.php'; -require_once("../lib/date.inc.php"); +[$ldap,$result,$nb_entries,$entries,$size_limit_reached] = $ldapInstance->search($ldap_user_filter, array('pwdpolicysubentry'), $attributes_map, $search_result_title, $search_result_sortby, $search_result_items, $ldap_scope); - -$ldapExpirationDate=""; - -# Search filter -$ldap_filter = "(&".$ldap_user_filter."(pwdChangedTime=*))"; - -# Search attributes -$attributes = array('pwdChangedTime', 'pwdPolicySubentry'); - -[$ldap,$result,$nb_entries,$entries,$size_limit_reached]=$ldapInstance->search($ldap_filter, $attributes, $attributes_map, $search_result_title, $search_result_sortby, $search_result_items, $ldap_scope); - -if ( ! empty($entries) ) +if ( !empty($entries) ) { - # Register policies - $pwdPolicies = array(); - - # Check if entry will soon expire - foreach($entries as $entry_key => $entry) { - - # Search active password policy - $pwdPolicy = ""; - if (isset($entry['pwdpolicysubentry'][0])) { - $pwdPolicy = $entry['pwdpolicysubentry'][0]; - } elseif (isset($ldap_default_ppolicy)) { - $pwdPolicy = $ldap_default_ppolicy; - } - - $isWillExpire = false; - $ppolicy_entry = ""; - - if ($pwdPolicy) { - if (!isset($pwdPolicies[$pwdPolicy])){ - $search_ppolicy = ldap_read($ldap, $pwdPolicy, "(objectClass=pwdPolicy)", array('pwdMaxAge')); - - if ( $errno ) { - error_log("LDAP - PPolicy search error $errno (".ldap_error($ldap).")"); - } else { - $ppolicy_entry = ldap_get_entries($ldap, $search_ppolicy); - $pwdPolicies[$pwdPolicy]['pwdMaxAge'] = $ppolicy_entry[0]['pwdmaxage'][0]; - } - } - - # Expiration - $pwdMaxAge = $pwdPolicies[$pwdPolicy]['pwdMaxAge']; - $pwdChangedTime = $entry['pwdchangedtime'][0]; - - if (isset($pwdChangedTime) and isset($pwdMaxAge) and ($pwdMaxAge > 0)) { - $changedDate = ldapDate2phpDate($pwdChangedTime); - $expirationDate = date_add( $changedDate, new DateInterval('PT'.$pwdMaxAge.'S')); - $expirationDateClone = clone($expirationDate); - $willExpireDate = date_sub( $expirationDateClone, new DateInterval('P'.$willexpiredays.'D')); - $time = time(); - if ( $time >= $willExpireDate->getTimestamp() and $time < $expirationDate->getTimestamp() ) { - $isWillExpire = true; - } - } - - } - - if ( $isWillExpire === false ) { - unset($entries[$entry_key]); - $nb_entries--; - } - - } - - $smarty->assign("page_title", "willexpireaccountstitle"); - if ($nb_entries === 0) { - $result = "noentriesfound"; - } else { - $smarty->assign("nb_entries", $nb_entries); - $smarty->assign("entries", $entries); - $smarty->assign("size_limit_reached", $size_limit_reached); - - $columns = $search_result_items; - if (! in_array($search_result_title, $columns)) array_unshift($columns, $search_result_title); - $smarty->assign("listing_columns", $columns); - $smarty->assign("listing_linkto", isset($search_result_linkto) ? $search_result_linkto : array($search_result_title)); - $smarty->assign("listing_sortby", array_search($search_result_sortby, $columns)); - $smarty->assign("show_undef", $search_result_show_undefined); - $smarty->assign("truncate_value_after", $search_result_truncate_value_after); - } + # Check if entry will soon expire + foreach($entries as $entry_key => $entry) { + + # Search active password policy + $pwdPolicy = ""; + if (isset($entry['pwdpolicysubentry'][0])) { + $pwdPolicy = $entry['pwdpolicysubentry'][0]; + } elseif (isset($ldap_default_ppolicy)) { + $pwdPolicy = $ldap_default_ppolicy; + } + + $isWillExpire = false; + $pwdMaxAge = $directory->getPasswordMaxAge($ldap, $entry["dn"], array('pwdPolicy' => $pwdPolicy, 'pwdMaxAge' => $ldap_password_max_age)); + $expirationDate = $directory->getPasswordExpirationDate($ldap, $entry["dn"], array('pwdMaxAge' => $pwdMaxAge)); + + if ($expirationDate) { + $expirationDateClone = clone $expirationDate; + $willExpireDate = date_sub( $expirationDateClone, new DateInterval('P'.$willexpiredays.'D')); + $time = time(); + if ( $time >= $willExpireDate->getTimestamp() and $time < $expirationDate->getTimestamp() ) { + $isWillExpire = true; + } + } + + if ( $isWillExpire === false ) { + unset($entries[$entry_key]); + $nb_entries--; + } + } + $smarty->assign("page_title", "willexpireaccountstitle"); + if ($nb_entries === 0) { + $result = "noentriesfound"; + } else { + $smarty->assign("nb_entries", $nb_entries); + $smarty->assign("entries", $entries); + $smarty->assign("size_limit_reached", $size_limit_reached); + + $columns = $search_result_items; + if (! in_array($search_result_title, $columns)) array_unshift($columns, $search_result_title); + $smarty->assign("listing_columns", $columns); + $smarty->assign("listing_linkto", isset($search_result_linkto) ? $search_result_linkto : array($search_result_title)); + $smarty->assign("listing_sortby", array_search($search_result_sortby, $columns)); + $smarty->assign("show_undef", $search_result_show_undefined); + $smarty->assign("truncate_value_after", $search_result_truncate_value_after); + } } ?> From eeeabbf6940b0a91ffd5ca0ede352e4d5b14f865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Mon, 26 Aug 2024 19:34:55 +0200 Subject: [PATCH 32/35] Use password policy configuration from Directory interface --- conf/config.inc.php | 5 ++++- htdocs/display.php | 21 +++++++++------------ htdocs/lockaccount.php | 32 ++++++++++++-------------------- htdocs/searchexpired.php | 17 ++++++----------- htdocs/searchlocked.php | 18 ++++++++---------- htdocs/searchwillexpire.php | 16 ++++++---------- 6 files changed, 45 insertions(+), 64 deletions(-) diff --git a/conf/config.inc.php b/conf/config.inc.php index e6651dd3..e673a5a9 100644 --- a/conf/config.inc.php +++ b/conf/config.inc.php @@ -39,7 +39,10 @@ $ldap_lastauth_attribute = "authTimestamp"; #$ldap_network_timeout = 10; $ldap_type = "openldap"; -#$ldap_lockout_duration = 3600; + +# Override LDAP password policy configuration +#$ldap_lockout_duration = 3600; # 1 hour +#$ldap_password_max_age = 7889400; # 3 months # How display attributes $attributes_map = array( diff --git a/htdocs/display.php b/htdocs/display.php index 7969b219..754515ba 100644 --- a/htdocs/display.php +++ b/htdocs/display.php @@ -94,26 +94,23 @@ $entry[0][$attr] = $values; } - # Include default password policy - if ( !$entry[0]['pwdpolicysubentry'] and $ldap_default_ppolicy) { - $entry[0]['pwdpolicysubentry'][] = $ldap_default_ppolicy; - } - $pwdPolicy = $entry[0]['pwdpolicysubentry'][0]; + # Get password policy configuration + $pwdPolicyConfiguration = $directory->getPwdPolicyConfiguration($ldap, $dn, $ldap_default_ppolicy); + if ($ldap_lockout_duration) { $pwdPolicyConfiguration['lockout_duration'] = $ldap_lockout_durantion; } + if ($ldap_password_max_age) { $pwdPolicyConfiguration['password_max_age'] = $ldap_password_max_age; } if ($display_edit_link) { # Replace {dn} in URL $edit_link = str_replace("{dn}", urlencode($dn), $display_edit_link); } - $lockoutDuration = $directory->getLockoutDuration($ldap, $dn, array('pwdPolicy' => $pwdPolicy, 'lockoutDuration' => $ldap_lockout_duration)); $lockDate = $directory->getLockDate($ldap, $dn); - $unlockDate = $directory->getUnlockDate($ldap, $dn, array('lockoutDuration' => $lockoutDuration)); - $isLocked = $directory->isLocked($ldap, $dn, array('lockoutDuration' => $lockoutDuration)); - $canLockAccount = $directory->canLockAccount($ldap, $dn, array('pwdPolicy' => $pwdPolicy)); + $unlockDate = $directory->getUnlockDate($ldap, $dn, $pwdPolicyConfiguration); + $isLocked = $directory->isLocked($ldap, $dn, $pwdPolicyConfiguration); + $canLockAccount = $pwdPolicyConfiguration["lockout_enabled"]; - $pwdMaxAge = $directory->getPasswordMaxAge($ldap, $dn, array('pwdPolicy' => $pwdPolicy, 'pwdMaxAge' => $ldap_password_max_age)); - $expirationDate = $directory->getPasswordExpirationDate($ldap, $dn, array('pwdMaxAge' => $pwdMaxAge)); - $isExpired = $directory->isPasswordExpired($ldap, $dn, array('pwdMaxAge' => $pwdMaxAge)); + $expirationDate = $directory->getPasswordExpirationDate($ldap, $dn, $pwdPolicyConfiguration); + $isExpired = $directory->isPasswordExpired($ldap, $dn, $pwdPolicyConfiguration); $resetAtNextConnection = $directory->resetAtNextConnection($ldap, $dn); diff --git a/htdocs/lockaccount.php b/htdocs/lockaccount.php index 92398872..ad22e959 100644 --- a/htdocs/lockaccount.php +++ b/htdocs/lockaccount.php @@ -28,28 +28,20 @@ $ldap = $ldap_connection[0]; $result = $ldap_connection[1]; - $pwdPolicy = NULL; - if ($ldap) { - $search_ppolicysubentry = ldap_read($ldap, $dn, "(objectClass=*)", array('pwdpolicysubentry')); - $user_entry = ldap_get_entries($ldap, $search_ppolicysubentry); - - # Search active password policy - $pwdPolicy = ""; - if (isset($user_entry[0]['pwdpolicysubentry'][0])) { - $pwdPolicy = $user_entry[0]['pwdpolicysubentry'][0]; - } elseif (isset($ldap_default_ppolicy)) { - $pwdPolicy = $ldap_default_ppolicy; - } - } - - # Apply the modification only the password can be locked - if ($ldap and $directory->canLockAccount($ldap, $dn, array('pwdPolicy' => $pwdPolicy))) { - if ( $directory->lockAccount($ldap, $dn) ) { - $result = "accountlocked"; - } else { - $result = "ldaperror"; + # Get password policy configuration + $pwdPolicyConfiguration = $directory->getPwdPolicyConfiguration($ldap, $dn, $ldap_default_ppolicy); + if ($ldap_lockout_duration) { $pwdPolicyConfiguration['lockout_duration'] = $ldap_lockout_durantion; } + if ($ldap_password_max_age) { $pwdPolicyConfiguration['password_max_age'] = $ldap_password_max_age; } + + # Apply the modification only the password can be locked + if ($pwdPolicyConfiguration["lockout_enabled"]) { + if ( $directory->lockAccount($ldap, $dn) ) { + $result = "accountlocked"; + } else { + $result = "ldaperror"; + } } } } diff --git a/htdocs/searchexpired.php b/htdocs/searchexpired.php index 0487fa47..8676733a 100644 --- a/htdocs/searchexpired.php +++ b/htdocs/searchexpired.php @@ -6,24 +6,19 @@ require_once("../conf/config.inc.php"); require __DIR__ . '/../vendor/autoload.php'; -[$ldap,$result,$nb_entries,$entries,$size_limit_reached] = $ldapInstance->search($ldap_user_filter, array('pwdpolicysubentry'), $attributes_map, $search_result_title, $search_result_sortby, $search_result_items, $ldap_scope); +[$ldap,$result,$nb_entries,$entries,$size_limit_reached] = $ldapInstance->search($ldap_user_filter, array(), $attributes_map, $search_result_title, $search_result_sortby, $search_result_items, $ldap_scope); if ( !empty($entries) ) { # Check if entry is expired foreach($entries as $entry_key => $entry) { - # Search active password policy - $pwdPolicy = ""; - if (isset($entry['pwdpolicysubentry'][0])) { - $pwdPolicy = $entry['pwdpolicysubentry'][0]; - } elseif (isset($ldap_default_ppolicy)) { - $pwdPolicy = $ldap_default_ppolicy; - } + # Get password policy configuration + $pwdPolicyConfiguration = $directory->getPwdPolicyConfiguration($ldap, $entry["dn"], $ldap_default_ppolicy); + if ($ldap_lockout_duration) { $pwdPolicyConfiguration['lockout_duration'] = $ldap_lockout_durantion; } + if ($ldap_password_max_age) { $pwdPolicyConfiguration['password_max_age'] = $ldap_password_max_age; } - $pwdMaxAge = $directory->getPasswordMaxAge($ldap, $entry["dn"], array('pwdPolicy' => $pwdPolicy, 'pwdMaxAge' => $ldap_password_max_age)); - $expirationDate = $directory->getPasswordExpirationDate($ldap, $entry["dn"], array('pwdMaxAge' => $pwdMaxAge)); - $isExpired = $directory->isPasswordExpired($ldap, $entry["dn"], array('pwdMaxAge' => $pwdMaxAge)); + $isExpired = $directory->isPasswordExpired($ldap, $entry["dn"], $pwdPolicyConfiguration); if ( $isExpired === false ) { unset($entries[$entry_key]); diff --git a/htdocs/searchlocked.php b/htdocs/searchlocked.php index d23be776..8b10b359 100644 --- a/htdocs/searchlocked.php +++ b/htdocs/searchlocked.php @@ -6,22 +6,20 @@ require_once("../conf/config.inc.php"); require __DIR__ . '/../vendor/autoload.php'; -[$ldap,$result,$nb_entries,$entries,$size_limit_reached] = $ldapInstance->search($ldap_user_filter, array('pwdpolicysubentry'), $attributes_map, $search_result_title, $search_result_sortby, $search_result_items, $ldap_scope); +[$ldap,$result,$nb_entries,$entries,$size_limit_reached] = $ldapInstance->search($ldap_user_filter, array(), $attributes_map, $search_result_title, $search_result_sortby, $search_result_items, $ldap_scope); if ( !empty($entries) ) { # Check if entry is still locked foreach($entries as $entry_key => $entry) { - # Search active password policy - $pwdPolicy = ""; - if (isset($entry['pwdpolicysubentry'][0])) { - $pwdPolicy = $entry['pwdpolicysubentry'][0]; - } elseif (isset($ldap_default_ppolicy)) { - $pwdPolicy = $ldap_default_ppolicy; - } - $lockoutDuration = $directory->getLockoutDuration($ldap, $entry['dn'], array('pwdPolicy' => $pwdPolicy, 'lockoutDuration' => $ldap_lockout_duration)); - $isLocked = $directory->isLocked($ldap, $entry['dn'], array('lockoutDuration' => $lockoutDuration)); + + # Get password policy configuration + $pwdPolicyConfiguration = $directory->getPwdPolicyConfiguration($ldap, $entry["dn"], $ldap_default_ppolicy); + if ($ldap_lockout_duration) { $pwdPolicyConfiguration['lockout_duration'] = $ldap_lockout_durantion; } + if ($ldap_password_max_age) { $pwdPolicyConfiguration['password_max_age'] = $ldap_password_max_age; } + + $isLocked = $directory->isLocked($ldap, $entry['dn'], $pwdPolicyConfiguration); if ( $isLocked === false ) { unset($entries[$entry_key]); diff --git a/htdocs/searchwillexpire.php b/htdocs/searchwillexpire.php index 1238a273..75c609d0 100644 --- a/htdocs/searchwillexpire.php +++ b/htdocs/searchwillexpire.php @@ -6,24 +6,20 @@ require_once("../conf/config.inc.php"); require __DIR__ . '/../vendor/autoload.php'; -[$ldap,$result,$nb_entries,$entries,$size_limit_reached] = $ldapInstance->search($ldap_user_filter, array('pwdpolicysubentry'), $attributes_map, $search_result_title, $search_result_sortby, $search_result_items, $ldap_scope); +[$ldap,$result,$nb_entries,$entries,$size_limit_reached] = $ldapInstance->search($ldap_user_filter, array(), $attributes_map, $search_result_title, $search_result_sortby, $search_result_items, $ldap_scope); if ( !empty($entries) ) { # Check if entry will soon expire foreach($entries as $entry_key => $entry) { - # Search active password policy - $pwdPolicy = ""; - if (isset($entry['pwdpolicysubentry'][0])) { - $pwdPolicy = $entry['pwdpolicysubentry'][0]; - } elseif (isset($ldap_default_ppolicy)) { - $pwdPolicy = $ldap_default_ppolicy; - } + # Get password policy configuration + $pwdPolicyConfiguration = $directory->getPwdPolicyConfiguration($ldap, $entry["dn"], $ldap_default_ppolicy); + if ($ldap_lockout_duration) { $pwdPolicyConfiguration['lockout_duration'] = $ldap_lockout_durantion; } + if ($ldap_password_max_age) { $pwdPolicyConfiguration['password_max_age'] = $ldap_password_max_age; } $isWillExpire = false; - $pwdMaxAge = $directory->getPasswordMaxAge($ldap, $entry["dn"], array('pwdPolicy' => $pwdPolicy, 'pwdMaxAge' => $ldap_password_max_age)); - $expirationDate = $directory->getPasswordExpirationDate($ldap, $entry["dn"], array('pwdMaxAge' => $pwdMaxAge)); + $expirationDate = $directory->getPasswordExpirationDate($ldap, $entry["dn"], $pwdPolicyConfiguration); if ($expirationDate) { $expirationDateClone = clone $expirationDate; From 3ee46ee8766b88c6e2b4e35012faa0d32528a21d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 27 Sep 2024 18:48:53 +0200 Subject: [PATCH 33/35] Fix merge --- htdocs/display.php | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/htdocs/display.php b/htdocs/display.php index 75b41445..1e0b7f3b 100644 --- a/htdocs/display.php +++ b/htdocs/display.php @@ -217,19 +217,12 @@ $smarty->assign("accountlockresult", $accountlockresult); $smarty->assign("prehookresult", $prehookresult); $smarty->assign("posthookresult", $posthookresult); -<<<<<<< HEAD -if ($canLockAccount == false) $smarty->assign("use_lockaccount", $canLockAccount); - +if ($canLockAccount == false) { $smarty->assign("use_lockaccount", $canLockAccount); } $smarty->assign("isAccountEnabled", $isAccountEnabled); -======= -if ($pwdLockout == false) $smarty->assign("use_lockaccount", $pwdLockout); -if(isset($messages[$resetpasswordresult])) -{ - $smarty->assign('msg_resetpasswordresult',$messages[$resetpasswordresult]); -} -else -{ +if (isset($messages[$resetpasswordresult])) { + $smarty->assign('msg_resetpasswordresult', $messages[$resetpasswordresult]); +} else { $smarty->assign('msg_resetpasswordresult',''); } ->>>>>>> master + ?> From 6f8356e6436c639bb1923673ab61d3232ae7b1d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 27 Sep 2024 19:26:54 +0200 Subject: [PATCH 34/35] Fix merge --- htdocs/resetpassword.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/resetpassword.php b/htdocs/resetpassword.php index c01899cb..db9e5650 100644 --- a/htdocs/resetpassword.php +++ b/htdocs/resetpassword.php @@ -111,9 +111,9 @@ } else { $reset = ($pwdreset === "true") ? true : false; if ($directory->modifyPassword($ldap, $dn, $password, $reset)) { - $result = "passwordrefused"; - } else { $result = "passwordchanged"; + } else { + $result = "passwordrefused"; } } } From 91a0ddaaefbe285d9a5c5eb95c90b027dc78f208 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Fri, 27 Sep 2024 19:49:20 +0200 Subject: [PATCH 35/35] Doc for OpenLDAP/AD --- conf/config.inc.php | 3 ++- docs/enableaccount.rst | 33 +++++++++++++++++++++++++++++++++ docs/index.rst | 1 + docs/ldap-parameters.rst | 22 +++++++++++++++++++++- docs/lockaccount.rst | 4 ++-- 5 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 docs/enableaccount.rst diff --git a/conf/config.inc.php b/conf/config.inc.php index cf8dbb4d..29f889e7 100644 --- a/conf/config.inc.php +++ b/conf/config.inc.php @@ -23,7 +23,9 @@ # All the default values are kept here, you should not modify it but use # config.inc.local.php file instead to override the settings from here. #============================================================================== + # LDAP +$ldap_type = "openldap"; $ldap_url = "ldap://localhost"; $ldap_starttls = false; $ldap_binddn = "cn=manager,dc=example,dc=com"; @@ -38,7 +40,6 @@ #$ldap_default_ppolicy = "cn=default,ou=ppolicy,dc=example,dc=com"; $ldap_lastauth_attribute = "authTimestamp"; #$ldap_network_timeout = 10; -$ldap_type = "openldap"; # Override LDAP password policy configuration #$ldap_lockout_duration = 3600; # 1 hour diff --git a/docs/enableaccount.rst b/docs/enableaccount.rst new file mode 100644 index 00000000..8b88451e --- /dev/null +++ b/docs/enableaccount.rst @@ -0,0 +1,33 @@ +Enable and disable account +========================== + +Show enabled status +------------------- + +Service Desk will display if account is enabled or not. To allow this feature: + +.. code-block:: php + + $show_enablestatus = true; + +Enable account +-------------- + +This feature allows to enable the account. The button is only displayed if the account is disabled. + +To enable this feature: + +.. code-block:: php + + $use_enableaccount = true; + +Disable account +--------------- + +This feature allows to disable the account. It is only displayed if the account is enabled. + +To enable this feature: + +.. code-block:: php + + $use_disableaccount = true; diff --git a/docs/index.rst b/docs/index.rst index 87553701..a0bf2767 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -26,6 +26,7 @@ LDAP Tool Box Service Desk documentation checkpassword.rst resetpassword.rst lockaccount.rst + enableaccount.rst hook.rst dashboards.rst configuration-mail.rst diff --git a/docs/ldap-parameters.rst b/docs/ldap-parameters.rst index a6c126b0..0ca76209 100644 --- a/docs/ldap-parameters.rst +++ b/docs/ldap-parameters.rst @@ -1,6 +1,17 @@ LDAP parameters =============== +Type of directory +----------------- + +You can define the type of LDAP directory (``openldap`` or ``activedirectory``). The default value is ``openldap``. + +.. code-block:: php + + $ldap_type = "openldap"; + +.. tip:: Other configuration parameters could be impacted by this choice, check their documentation. + Server address -------------- @@ -40,7 +51,7 @@ Configure DN and password in ``$ldap_bindn`` and ``$ldap_bindpw``: $ldap_binddn = "cn=manager,dc=example,dc=com"; $ldap_bindpw = "secret"; -.. tip:: You can use the LDAP admin account or any service account. The account needs to read users, password policy entries and write ``userPassword`` and ``pwdReset`` attributes in user entries. Note that using the LDAP admin account will bypass any password policy like minimal size or password history when reseting the password. +.. tip:: You can use the LDAP admin account or any service account. The account needs to read users, password policy entries and write password and some other related attributes in user entries. On OpenLDAP, using the LDAP admin account will bypass any password policy like minimal size or password history when reseting the password. LDAP Base --------- @@ -106,6 +117,13 @@ Set ``$ldap_default_ppolicy`` value if a default policy is configured in your LD .. tip:: Password policy is first searched in ``pwdPolicySubentry`` attribute of user entry, then fallback to default policy. +You can override some policies, like lockout duration or password maximal age: + +.. code-block:: php + + $ldap_lockout_duration = 3600; # 1 hour + $ldap_password_max_age = 7889400; # 3 months + Last authentication attribute ----------------------------- @@ -114,3 +132,5 @@ The last authentication date can be stored in different attributes depending on .. code-block:: php $ldap_lastauth_attribute = "pwdLastSuccess"; + +.. tip:: This attribute is automatically configured for Active Directory. diff --git a/docs/lockaccount.rst b/docs/lockaccount.rst index 2fe21e3f..78c134e2 100644 --- a/docs/lockaccount.rst +++ b/docs/lockaccount.rst @@ -1,5 +1,5 @@ -Lock account -============ +Lock and unlock account +======================= Show lock status ----------------