From c8447beac4b92ad0405aa841c59aa0dda691a7bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20=22KPTN=22=20OUDOT?= Date: Fri, 27 Sep 2024 19:55:27 +0200 Subject: [PATCH] Draft - Active Directory support (#156) * Switch to LTB LDAP 0.2 * Migration of send_mail function * Migration of connect function * Migration of ldap_get_mail_for_notification function * Require autoload in index * Migration of search function * Use ldapInstance in smarty plugin * Call ldap_bind to check password * Fix typo * Migrate notify_admin_by_mail function * Function to convert AD date * First mapping between OpenLDAP and AD * Manage other AD specific attributes * AD lockout time * AD identifier * Move OpenLDAP specific attributes * Work on isLocked function * Use new ltb-common Directory functions * Hide special value of lockout date * Use ltb-common password expiration functions * Use functions to lock/unlock an account * Use ltb-common function to modify password * Use ltb-common resetAtNextConnection function * Add feature to enable/disable account * Remove composer.lock * Use new lockDate function to remove OpenLDAP specific code * Clean lock account code * Use Directory interface for search locked account * Use Directory interface for search expired passwords * Use Directory interface for search idle accounts * Use Directory interface for search will expire passwords * Use password policy configuration from Directory interface * Fix merge * Fix merge * Doc for OpenLDAP/AD --- conf/config.inc.php | 44 +++++++++--- docs/enableaccount.rst | 33 +++++++++ docs/index.rst | 1 + docs/ldap-parameters.rst | 22 +++++- docs/lockaccount.rst | 4 +- htdocs/disableaccount.php | 44 ++++++++++++ htdocs/display.php | 50 ++++++++------ htdocs/enableaccount.php | 44 ++++++++++++ htdocs/index.php | 22 ++++++ htdocs/lockaccount.php | 54 ++++----------- htdocs/resetpassword.php | 15 ++-- htdocs/searchexpired.php | 114 ++++++++++--------------------- htdocs/searchidle.php | 35 ++++------ htdocs/searchlocked.php | 118 ++++++++++---------------------- htdocs/searchwillexpire.php | 125 ++++++++++++---------------------- htdocs/unlockaccount.php | 8 +-- lang/en.inc.php | 7 ++ lang/fr.inc.php | 8 +++ lib/date.inc.php | 6 ++ lib/smarty.inc.php | 5 ++ templates/display.tpl | 71 ++++++++++++++++++- templates/value_displayer.tpl | 4 ++ 22 files changed, 480 insertions(+), 354 deletions(-) create mode 100644 docs/enableaccount.rst 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 84cc0998..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"; @@ -39,9 +41,12 @@ $ldap_lastauth_attribute = "authTimestamp"; #$ldap_network_timeout = 10; +# Override LDAP password policy configuration +#$ldap_lockout_duration = 3600; # 1 hour +#$ldap_password_max_age = 7889400; # 3 months + # 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' ), @@ -52,7 +57,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' ), @@ -66,16 +70,28 @@ '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' ), + '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' ), + 'title' => array( 'attribute' => 'title', 'faclass' => 'certificate', 'type' => 'text' ), +); + +# 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' ), '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' ), - 'title' => array( 'attribute' => 'title', 'faclass' => 'certificate', 'type' => 'text' ) +); +$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' ), ); # Search @@ -95,29 +111,41 @@ $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', 'pwdfailuretime','pwdpolicysubentry', 'authtimestamp', 'pwdlastsuccess', 'created', 'modified'); $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_unlockcomment = false; $use_unlockcomment_required = false; $use_lockaccount = true; + $use_lockcomment = false; $use_lockcomment_required = false; + $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; # Local password policy # This is applied before directory password policy 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 ---------------- 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 21feccaa..1e0b7f3b 100644 --- a/htdocs/display.php +++ b/htdocs/display.php @@ -14,6 +14,9 @@ $prehookresult= ""; $posthookresult= ""; $ldapExpirationDate=""; +$canLockAccount=""; +$isAccountEnabled = ""; +$lockDate = ""; if (isset($_GET["dn"]) and $_GET["dn"]) { $dn = $_GET["dn"]; @@ -63,16 +66,14 @@ # 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']; } $attributes[] = $attributes_map[$display_title]['attribute']; - $attributes[] = "pwdPolicySubentry"; # Search entry $search = ldap_read($ldap, $dn, $ldap_user_filter, $attributes); - $errno = ldap_errno($ldap); if ( $errno ) { @@ -93,22 +94,28 @@ $entry[0][$attr] = $values; } - # Include default password policy - if ( !$entry[0]['pwdpolicysubentry'] and $ldap_default_ppolicy) { - $entry[0]['pwdpolicysubentry'][] = $ldap_default_ppolicy; - } + # 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); } - # 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; + $lockDate = $directory->getLockDate($ldap, $dn); + $unlockDate = $directory->getUnlockDate($ldap, $dn, $pwdPolicyConfiguration); + $isLocked = $directory->isLocked($ldap, $dn, $pwdPolicyConfiguration); + $canLockAccount = $pwdPolicyConfiguration["lockout_enabled"]; + + $expirationDate = $directory->getPasswordExpirationDate($ldap, $dn, $pwdPolicyConfiguration); + $isExpired = $directory->isPasswordExpired($ldap, $dn, $pwdPolicyConfiguration); + + $resetAtNextConnection = $directory->resetAtNextConnection($ldap, $dn); + + if ($show_enablestatus) { + $isAccountEnabled = $directory->isAccountEnabled($ldap, $dn); } $isLocked = false; @@ -196,9 +203,11 @@ $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", $ldapExpirationDate); +$smarty->assign("ldapExpirationDate", $expirationDate ? $expirationDate->getTimestamp(): NULL); +$smarty->assign("resetAtNextConnection", $resetAtNextConnection); $smarty->assign("edit_link", $edit_link); @@ -208,13 +217,12 @@ $smarty->assign("accountlockresult", $accountlockresult); $smarty->assign("prehookresult", $prehookresult); $smarty->assign("posthookresult", $posthookresult); -if ($pwdLockout == false) $smarty->assign("use_lockaccount", $pwdLockout); -if(isset($messages[$resetpasswordresult])) -{ - $smarty->assign('msg_resetpasswordresult',$messages[$resetpasswordresult]); -} -else -{ +if ($canLockAccount == false) { $smarty->assign("use_lockaccount", $canLockAccount); } +$smarty->assign("isAccountEnabled", $isAccountEnabled); +if (isset($messages[$resetpasswordresult])) { + $smarty->assign('msg_resetpasswordresult', $messages[$resetpasswordresult]); +} else { $smarty->assign('msg_resetpasswordresult',''); } + ?> 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 81508294..d557301c 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -67,6 +67,24 @@ 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(); + $ldap_lastauth_attribute = "lastLogon"; + break; +} + #============================================================================== # Other default values #============================================================================== @@ -164,6 +182,9 @@ $smarty->assign('use_searchidle',$use_searchidle); $smarty->assign('use_showauditlog',$use_showauditlog); $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 @@ -181,6 +202,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"); diff --git a/htdocs/lockaccount.php b/htdocs/lockaccount.php index 0e942a5b..ad22e959 100644 --- a/htdocs/lockaccount.php +++ b/htdocs/lockaccount.php @@ -28,50 +28,20 @@ $ldap = $ldap_connection[0]; $result = $ldap_connection[1]; - - # Consider pwdLockout = false by default - $pwdLockout = false; - - # 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])) { - $pwdPolicy = $user_entry[0]['pwdpolicysubentry'][0]; - } 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 - if ($ldap and $pwdLockout == true) { - $modification = ldap_mod_replace($ldap, $dn, array("pwdAccountLockedTime" => array("000001010000Z"))); - $errno = ldap_errno($ldap); - if ( $errno ) { - $result = "ldaperror"; - } else { - $result = "accountlocked"; + # 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/resetpassword.php b/htdocs/resetpassword.php index 164f8810..db9e5650 100644 --- a/htdocs/resetpassword.php +++ b/htdocs/resetpassword.php @@ -57,12 +57,6 @@ } } - # save LDAP modifications to apply in $entry variable - $entry["userPassword"] = $password; - if ( $pwdreset === "true" ) { - $entry["pwdReset"] = "TRUE"; - } - # Get current entry first $entries_search = $ldapInstance->search_with_scope("base", $dn, '(objectClass=*)'); $errno = ldap_errno($ldap); @@ -115,12 +109,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"; } } } diff --git a/htdocs/searchexpired.php b/htdocs/searchexpired.php index cc96393c..8676733a 100644 --- a/htdocs/searchexpired.php +++ b/htdocs/searchexpired.php @@ -5,88 +5,44 @@ 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(), $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) { + + # 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; } + + $isExpired = $directory->isPasswordExpired($ldap, $entry["dn"], $pwdPolicyConfiguration); + + 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); + } } ?> 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); } ?> diff --git a/htdocs/searchlocked.php b/htdocs/searchlocked.php index 279b275c..8b10b359 100644 --- a/htdocs/searchlocked.php +++ b/htdocs/searchlocked.php @@ -5,92 +5,46 @@ 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(), $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) { + + # 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]); + $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); } + } } ?> diff --git a/htdocs/searchwillexpire.php b/htdocs/searchwillexpire.php index 2c03b8b9..75c609d0 100644 --- a/htdocs/searchwillexpire.php +++ b/htdocs/searchwillexpire.php @@ -5,91 +5,52 @@ 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(), $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) { + + # 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; + $expirationDate = $directory->getPasswordExpirationDate($ldap, $entry["dn"], $pwdPolicyConfiguration); + + 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); + } } ?> diff --git a/htdocs/unlockaccount.php b/htdocs/unlockaccount.php index ff791dcb..388e6ba7 100644 --- a/htdocs/unlockaccount.php +++ b/htdocs/unlockaccount.php @@ -36,12 +36,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"; } } } diff --git a/lang/en.inc.php b/lang/en.inc.php index ee1a93e0..b5d488ff 100644 --- a/lang/en.inc.php +++ b/lang/en.inc.php @@ -4,13 +4,18 @@ # English #============================================================================== +$messages['accountenabled'] = "Account is enabled"; +$messages['accountdisabled'] = "Account is disabled"; $messages['auditlogs'] = "Audit logs"; $messages['auditlogtitle'] = "Audit log for the last $audit_log_days days"; $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."; @@ -20,9 +25,11 @@ $messages['comment_needed'] = "A comment will be asked"; $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['eventfound'] = "event found"; diff --git a/lang/fr.inc.php b/lang/fr.inc.php index 911d6886..4d0bc138 100644 --- a/lang/fr.inc.php +++ b/lang/fr.inc.php @@ -3,13 +3,19 @@ #============================================================================== # French #============================================================================== + +$messages['accountenabled'] = "Le compte est activé"; +$messages['accountdisabled'] = "Le compte est désactivé"; $messages['auditlogs'] = "Audit"; $messages['auditlogtitle'] = "Traces d'audit pour les $audit_log_days derniers jours"; $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."; @@ -19,9 +25,11 @@ $messages['comment_needed'] = "Un commentaire sera demandé"; $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['eventfound'] = "événement trouvé"; 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 ca31cf51..a035fc28 100644 --- a/lib/smarty.inc.php +++ b/lib/smarty.inc.php @@ -40,6 +40,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/display.tpl b/templates/display.tpl index a8f0a434..2e6d5293 100644 --- a/templates/display.tpl +++ b/templates/display.tpl @@ -80,13 +80,33 @@ {/foreach} + {if $lockDate} + + + {$msg_label_pwdaccountlockedtime} + + + {$lockDate|date_format:{$date_specifiers}|truncate:10000} + + + {/if} {if {$display_password_expiration_date} and {$ldapExpirationDate}} {$msg_label_expirationdate} - {include 'value_displayer.tpl' value=$ldapExpirationDate type="date" truncate_value_after=10000} + {$ldapExpirationDate|date_format:{$date_specifiers}|truncate:10000} + + + {/if} + {if $resetAtNextConnection} + + + {$msg_label_pwdreset} + + + {$msg_true} {/if} @@ -287,5 +307,54 @@ {/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} + 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}