diff --git a/.gitignore b/.gitignore index dc9f166..5d0c9b6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ cache/* docs/_build /vendor/ /htdocs/vendor/bootstrap/ +composer.lock +tests/.phpunit.result.cache diff --git a/composer.json b/composer.json index e158c4f..cf13345 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/ltb-common": "v0.2.1", + "ltb-project/ltb-common": "dev-main", "twbs/bootstrap": "v5.3.2" }, "scripts": { diff --git a/conf/.gitignore b/conf/.gitignore new file mode 100644 index 0000000..725843c --- /dev/null +++ b/conf/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!config.inc.php diff --git a/conf/config.inc.php b/conf/config.inc.php index c681138..b2d4135 100644 --- a/conf/config.inc.php +++ b/conf/config.inc.php @@ -30,6 +30,7 @@ $ldap_bindpw = "secret"; $ldap_base = "dc=example,dc=com"; $ldap_user_base = "ou=users,".$ldap_base; +$ldap_scope = "sub"; # possible values: sub, one, base $ldap_user_filter = "(objectClass=inetOrgPerson)"; $ldap_ppolicy_filter = "(objectClass=pwdPolicy)"; $ldap_ppolicy_name_attribute = "cn"; @@ -119,8 +120,13 @@ $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; diff --git a/docs/audit.rst b/docs/audit.rst index a6c18fa..54caa67 100644 --- a/docs/audit.rst +++ b/docs/audit.rst @@ -13,6 +13,7 @@ The items provided in the audit log are: * Who has done the action (see Admin name below) * Action * Result of the action +* Additional comment (Optionally entered by Admin) Example: @@ -24,7 +25,8 @@ Example: "user_dn":"uid=donald,ou=users,dc=example,dc=com", "done_by":"Mickey", "action":"lockaccount", - "result":"accountlocked" + "result":"accountlocked", + "comment":"Security breach" } Audit log file diff --git a/docs/installation.rst b/docs/installation.rst index 23caadc..6e34452 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -107,3 +107,19 @@ Start container, mounting that configuration file: docker run -p 80:80 \ -v /home/test/servicedesk.conf.php:/var/www/conf/config.inc.local.php \ -it docker.io/ltbproject/service-desk:latest + + +From git repository, for developpers only +----------------------------------------- + +You can get the content of git repository + +Update composer dependencies: + +.. prompt:: bash + + composer update + +Depending on your php version, this command will determine the versions of composer dependencies, and create a ``composer.lock`` file. Then it will download these dependencies and put them in vendor/ directory. + +Then you can follow the instructions from `From tarball`_, especially the prerequisites. diff --git a/docs/ldap-parameters.rst b/docs/ldap-parameters.rst index 5627d81..a6c126b 100644 --- a/docs/ldap-parameters.rst +++ b/docs/ldap-parameters.rst @@ -66,6 +66,14 @@ The filter can be set in ``$ldap_user_filter``: $ldap_user_filter = "(objectClass=inetOrgPerson)"; +You can set the scope for each search in ``$ldap_scope``: + +.. code-block:: php + + $ldap_scope = "sub"; + +.. tip:: sub is the default value. Possible values are sub, one, or base + Size limit ---------- diff --git a/docs/lockaccount.rst b/docs/lockaccount.rst index 88e09d7..2fe21e3 100644 --- a/docs/lockaccount.rst +++ b/docs/lockaccount.rst @@ -33,3 +33,25 @@ To enable this feature: .. code-block:: php $use_unlockaccount = true; + +Insert comment +-------------- + +A feature to enable comments when locking and unlocking user accounts can be enabled. + +To enable this feature: + +.. code-block:: php + + $use_lockcomment = true; + $use_unlockcomment = true; + +Comment required +---------------- + +This features ensure a comment is required before locking/unlocking a user. + +.. code-block:: php + + $use_lockcomment_required = true; + $use_unlockcomment_required = true; diff --git a/htdocs/index.php b/htdocs/index.php index aea8439..1d3abbb 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -127,7 +127,11 @@ $smarty->assign('resetpassword_reset_default',$resetpassword_reset_default); $smarty->assign('show_lockstatus',$show_lockstatus); $smarty->assign('use_unlockaccount',$use_unlockaccount); +$smarty->assign('use_unlockcomment',$use_unlockcomment); +$smarty->assign('use_unlockcomment_required',$use_unlockcomment_required); $smarty->assign('use_lockaccount',$use_lockaccount); +$smarty->assign('use_lockcomment',$use_lockcomment); +$smarty->assign('use_lockcomment_required',$use_lockcomment_required); $smarty->assign('show_expirestatus',$show_expirestatus); $smarty->assign('display_password_expiration_date',$display_password_expiration_date); $smarty->assign('use_searchlocked',$use_searchlocked); diff --git a/htdocs/lockaccount.php b/htdocs/lockaccount.php index b073765..7d58feb 100644 --- a/htdocs/lockaccount.php +++ b/htdocs/lockaccount.php @@ -5,7 +5,7 @@ $result = ""; $dn = ""; -$password = ""; +$comment = ""; if (isset($_POST["dn"]) and $_POST["dn"]) { $dn = $_POST["dn"]; @@ -13,6 +13,10 @@ $result = "dnrequired"; } +if (isset($_POST["comment"]) and $_POST["comment"]) { + $comment = $_POST["comment"]; +} + if ($result === "") { require_once("../conf/config.inc.php"); @@ -69,7 +73,7 @@ } if ($audit_log_file) { - auditlog($audit_log_file, $dn, $audit_admin, "lockaccount", $result); + auditlog($audit_log_file, $dn, $audit_admin, "lockaccount", $result, $comment); } header('Location: index.php?page=display&dn='.$dn.'&lockaccountresult='.$result); diff --git a/htdocs/search.php b/htdocs/search.php index 8a0cc4f..13bbe06 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]=$ldapInstance->search($ldap_filter, $attributes, $attributes_map, $search_result_title, $search_result_sortby, $search_result_items); + [$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) ) { diff --git a/htdocs/searchexpired.php b/htdocs/searchexpired.php index 1d2cf5d..cc96393 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]=$ldapInstance->search($ldap_filter, $attributes, $attributes_map, $search_result_title, $search_result_sortby, $search_result_items); +[$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) ) { diff --git a/htdocs/searchidle.php b/htdocs/searchidle.php index 4570e29..9904eb2 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]=$ldapInstance->search($ldap_filter, $attributes, $attributes_map, $search_result_title, $search_result_sortby, $search_result_items); +[$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) ) { diff --git a/htdocs/searchlocked.php b/htdocs/searchlocked.php index d358532..279b275 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]=$ldapInstance->search($ldap_filter, $attributes, $attributes_map, $search_result_title, $search_result_sortby, $search_result_items); +[$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) ) { diff --git a/htdocs/searchwillexpire.php b/htdocs/searchwillexpire.php index e25f563..2c03b8b 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]=$ldapInstance->search($ldap_filter, $attributes, $attributes_map, $search_result_title, $search_result_sortby, $search_result_items); +[$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) ) { diff --git a/htdocs/unlockaccount.php b/htdocs/unlockaccount.php index dd30e15..388e6ba 100644 --- a/htdocs/unlockaccount.php +++ b/htdocs/unlockaccount.php @@ -5,7 +5,7 @@ $result = ""; $dn = ""; -$password = ""; +$comment = ""; $returnto = "display"; if (isset($_POST["dn"]) and $_POST["dn"]) { @@ -20,6 +20,10 @@ $returnto = $_GET["returnto"]; } +if (isset($_POST["comment"]) and $_POST["comment"]) { + $comment = $_POST["comment"]; +} + if ($result === "") { require_once("../conf/config.inc.php"); @@ -41,7 +45,7 @@ } if ($audit_log_file) { - auditlog($audit_log_file, $dn, $audit_admin, "unlockaccount", $result); + auditlog($audit_log_file, $dn, $audit_admin, "unlockaccount", $result, $comment); } header('Location: index.php?page='.$returnto.'&dn='.$dn.'&unlockaccountresult='.$result); diff --git a/lang/en.inc.php b/lang/en.inc.php index a0a075d..074a1b1 100644 --- a/lang/en.inc.php +++ b/lang/en.inc.php @@ -19,6 +19,8 @@ $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."; $messages['changemessageforadmin'] = "Hello,\n\nThe password of account {dn} has been changed.\n."; $messages['checkpassword'] = "Check password"; +$messages['close'] = "Close"; +$messages['comment_needed'] = "A comment will be asked"; $messages['currentpassword'] = "Current password"; $messages['dashboards'] = "Dashboards"; $messages['disableaccount'] = "Disable account"; @@ -33,6 +35,7 @@ $messages['forcereset'] = "Force reset at next connection"; $messages['idleaccounts'] = "Idle accounts"; $messages['idleaccountstitle'] = "Accounts idle for more than $idledays days"; +$messages['insert_comment'] = "Insert comment"; $messages['pager_all'] = "All"; $messages['print_all'] = "Print all results"; $messages['print_page'] = "Print this page"; diff --git a/lang/fr.inc.php b/lang/fr.inc.php index bf4e160..fef9a38 100644 --- a/lang/fr.inc.php +++ b/lang/fr.inc.php @@ -19,6 +19,8 @@ $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."; $messages['changemessageforadmin'] = "Bonjour,\n\nLe mot de passe du compte {dn} a été changé."; $messages['checkpassword'] = "Vérification du mot de passe"; +$messages['close'] = "Fermer"; +$messages['comment_needed'] = "Un commentaire sera demandé"; $messages['currentpassword'] = "Mot de passe actuel"; $messages['dashboards'] = "Tableaux de bord"; $messages['disableaccount'] = "Désactiver le compte"; @@ -33,6 +35,7 @@ $messages['forcereset'] = "Forcer la réinitialisation à la prochaine connexion"; $messages['idleaccounts'] = "Comptes inactifs"; $messages['idleaccountstitle'] = "Comptes inactifs depuis plus de $idledays jours"; +$messages['insert_comment'] = "Insérer un commentaire"; $messages['pager_all'] = "Tout"; $messages['print_all'] = "Imprimer tous les résultats"; $messages['print_page'] = "Imprimer cette page"; diff --git a/lib/audit.inc.php b/lib/audit.inc.php index 1b4ac02..2e50687 100644 --- a/lib/audit.inc.php +++ b/lib/audit.inc.php @@ -1,6 +1,7 @@ date_format(date_create(), "D, d M Y H:i:s"), "ip" => $_SERVER['REMOTE_ADDR'], "user_dn" => $dn, @@ -8,6 +9,11 @@ function auditlog($file, $dn, $admin, $action, $result) { "action" => $action, "result" => $result ); + + if ($comment) { + $log['comment'] = $comment; + } + file_put_contents($file, json_encode($log, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL, FILE_APPEND | LOCK_EX); } ?> diff --git a/lib/smarty.inc.php b/lib/smarty.inc.php index 9d226b4..a035fc2 100644 --- a/lib/smarty.inc.php +++ b/lib/smarty.inc.php @@ -7,7 +7,7 @@ function get_attribute($params) { - $return = ""; + $value = ""; $dn = $params["dn"]; $attribute = $params["attribute"]; $ldap_url = $params["ldap_url"]; @@ -27,35 +27,11 @@ function get_attribute($params) { isset($ldap_krb5ccname) ? $ldap_krb5ccname : null ); - # Connect to LDAP $ldap_connection = $ldapInstance->connect(); - $ldap = $ldap_connection[0]; - $result = $ldap_connection[1]; + $value = $ldapInstance->get_first_value($dn, "base", $ldap_filter, $attribute); - if ($ldap) { - - # Search entry - $search = ldap_read($ldap, $dn, $ldap_filter, explode(",", $attribute)); - - $errno = ldap_errno($ldap); - - if ( $errno ) { - error_log("LDAP - Search error $errno (".ldap_error($ldap).")"); - } else { - $entry = ldap_get_entries($ldap, $search); - - # Loop over attribute - foreach ( explode(",", $attribute) as $ldap_attribute ) { - if ( isset ($entry[0][$ldap_attribute]) ) { - $return = $entry[0][$ldap_attribute][0]; - break; - } - } - } - } - - return $return; + return $value; } function convert_ldap_date($date) { diff --git a/templates/comment.tpl b/templates/comment.tpl new file mode 100644 index 0000000..8550a87 --- /dev/null +++ b/templates/comment.tpl @@ -0,0 +1,23 @@ +
+ + +
diff --git a/templates/display.tpl b/templates/display.tpl index f9294b9..51cecae 100644 --- a/templates/display.tpl +++ b/templates/display.tpl @@ -214,20 +214,30 @@
- {if $unlockDate} -

{$msg_unlockdate} {$unlockDate|date_format:{$date_specifiers}}

- {/if} - {if $use_unlockaccount} -
- {if $unlockaccountresult eq 'ldaperror'} -
{$msg_accountnotunlocked}
- {/if} - - -
- {/if} + {if $unlockDate} +

{$msg_unlockdate} {$unlockDate|date_format:{$date_specifiers}}

+ {/if} + {if $use_unlockaccount} + {if $unlockaccountresult eq 'ldaperror'} +
{$msg_accountnotunlocked}
+ {/if} + {if $use_unlockcomment} + +
+ {include 'comment.tpl' method=unlock page=unlockaccount title=$msg_unlockaccount} +
+ {else} +
+ + +
+ {/if} + {/if}
{/if} @@ -241,17 +251,27 @@

- {if $use_lockaccount} -
-
- {if $lockaccountresult eq 'ldaperror'} -
{$msg_accountnotlocked}
- {/if} - - -
+ {if $use_lockaccount} +
+ {if $lockaccountresult eq 'ldaperror'} +
{$msg_accountnotlocked}
+ {/if} + {if $use_lockcomment} + +
+ {include 'comment.tpl' method=lock page=lockaccount title=$msg_lockaccount} +
+ {else} +
+ + +
+ {/if}
{/if}