2022-06-16 13:15:28 +02:00
|
|
|
<?php
|
|
|
|
/*******************************************************************************
|
|
|
|
* Copyright (C) 2022 Easter-eggs
|
|
|
|
* http://ldapsaisie.labs.libre-entreprise.org
|
|
|
|
*
|
|
|
|
* Author: See AUTHORS file in top-level directory.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License version 2
|
|
|
|
* as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
LSerror :: defineError('ACCESSLOG_SUPPORT_01',
|
|
|
|
___("accesslog Support : The constant %{const} is not defined.")
|
|
|
|
);
|
|
|
|
|
|
|
|
$GLOBALS['accesslog_reqTypes'] = array(
|
|
|
|
'add' => _('Add'),
|
|
|
|
'bind' => _('Log in'),
|
|
|
|
'compare' => _('Compare'),
|
|
|
|
'delete' => _('Delete'),
|
|
|
|
'extended' => _('Extended'),
|
|
|
|
'modify' => _('Modify'),
|
|
|
|
'modrdn' => _('Modify RDN'),
|
|
|
|
'search' => _('Search'),
|
|
|
|
'unbind' => _('Log out'),
|
|
|
|
);
|
|
|
|
|
|
|
|
$GLOBALS['accesslog_modOps'] = array(
|
|
|
|
'+' => _('Add'),
|
|
|
|
'-' => _('Delete'),
|
|
|
|
'=' => _('Replace'),
|
|
|
|
'' => _('Replace'),
|
|
|
|
'#' => _('Increment'),
|
|
|
|
);
|
|
|
|
|
|
|
|
function LSaddon_accesslog_support() {
|
|
|
|
if (!defined('LS_ACCESSLOG_BASEDN')) {
|
|
|
|
LSerror :: addErrorCode('ACCESSLOG_SUPPORT_01', 'LS_ACCESSLOG_BASEDN');
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (php_sapi_name() === 'cli') {
|
|
|
|
LScli::add_command(
|
|
|
|
'getEntryAccessLog',
|
|
|
|
'cli_getEntryAccessLog',
|
|
|
|
'Get entry access log',
|
2022-07-20 14:53:28 +02:00
|
|
|
'[entry DN] [page]'
|
2022-06-16 13:15:28 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function mapAccessLogEntry(&$entry) {
|
|
|
|
$attrs = $entry['attrs'];
|
|
|
|
$entry['start'] = LSldap::parseDate(LSldap::getAttr($attrs, 'reqStart'));
|
|
|
|
$entry['end'] = LSldap::parseDate(LSldap::getAttr($attrs, 'reqEnd'));
|
|
|
|
$entry['type'] = LSldap::getAttr($attrs, 'reqType');
|
|
|
|
$entry['result'] = ldap_err2str(LSldap::getAttr($attrs, 'reqResult'));
|
|
|
|
$entry['message'] = LSldap::getAttr($attrs, 'reqMessage');
|
|
|
|
if ($entry['type'] === 'modify' && LSldap::getAttr($attrs, 'reqMod', true)) {
|
|
|
|
$mods = array();
|
|
|
|
foreach(LSldap::getAttr($attrs, 'reqMod', true) as $mod) {
|
|
|
|
if (preg_match('/^([^\:]+)\:([^ ]?) (.*)$/', $mod, $m)) {
|
|
|
|
$attr = $m[1];
|
|
|
|
$op = $m[2];
|
|
|
|
$value = $m[3];
|
|
|
|
if (!array_key_exists($attr, $mods)) {
|
|
|
|
$mods[$attr] = array(
|
|
|
|
'mods' => array(),
|
|
|
|
'old_values' => array(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
$mods[$attr]['changes'][] = array(
|
|
|
|
'op' => array_key_exists($op, $GLOBALS['accesslog_modOps']) ? $GLOBALS['accesslog_modOps'][$op] : $op,
|
|
|
|
'value' => $value,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (LSldap::getAttr($attrs, 'reqOld', true)) {
|
|
|
|
foreach(LSldap::getAttr($attrs, 'reqOld', true) as $old) {
|
|
|
|
if (preg_match('/^([^\:]+)\: (.*)$/', $old, $m) && array_key_exists($m[1], $mods)) {
|
|
|
|
$mods[$m[1]]['old_values'][] = $m[2];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$entry['mods'] = $mods;
|
|
|
|
}
|
|
|
|
if (array_key_exists($entry['type'], $GLOBALS['accesslog_reqTypes'])) {
|
|
|
|
$entry['type'] = $GLOBALS['accesslog_reqTypes'][$entry['type']];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function sortLogEntryByDate($a, $b) {
|
|
|
|
return ($a['start'] === $b['start']) ? 0 : ($a['start'] < $b['start']) ? -1 : 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getEntryAccessLog($dn) {
|
|
|
|
$data = LSldap::search(
|
|
|
|
Net_LDAP2_Filter::create('reqDn', 'equals', $dn),
|
|
|
|
LS_ACCESSLOG_BASEDN,
|
|
|
|
array(
|
|
|
|
'attributes' => array(
|
|
|
|
'reqStart',
|
|
|
|
'reqEnd',
|
|
|
|
'reqType',
|
|
|
|
'reqResult',
|
|
|
|
'reqMessage',
|
|
|
|
'reqMod',
|
|
|
|
'reqOld',
|
|
|
|
),
|
2022-07-20 14:53:28 +02:00
|
|
|
)
|
2022-06-16 13:15:28 +02:00
|
|
|
);
|
|
|
|
if (!is_array($data)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$logs = array();
|
|
|
|
foreach($data as $entry) {
|
|
|
|
foreach($entry['attrs'] as $attr => $values) {
|
|
|
|
$entry['attrs'][$attr] = ensureIsArray($values);
|
|
|
|
}
|
|
|
|
mapAccessLogEntry($entry);
|
|
|
|
$logs[] = $entry;
|
|
|
|
}
|
|
|
|
usort($logs, 'sortLogEntryByDate');
|
|
|
|
return array_reverse($logs);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getEntryAccessLogPage($dn, $page = false, $nbByPage = 30) {
|
|
|
|
if (!isset($_SESSION['entryAccessLogPages'])) {
|
|
|
|
$_SESSION['entryAccessLogPages'] = array();
|
|
|
|
}
|
|
|
|
if (!isset($_SESSION['entryAccessLogPages'][$dn]) || isset($_REQUEST['refresh'])) {
|
|
|
|
$_SESSION['entryAccessLogPages'][$dn] = getEntryAccessLog($dn);
|
|
|
|
}
|
|
|
|
if (!is_int($page)) {
|
|
|
|
$page = 1;
|
|
|
|
}
|
|
|
|
return array(
|
|
|
|
'nb' => $page,
|
|
|
|
'nbPages' => ceil(count($_SESSION['entryAccessLogPages'][$dn]) / $nbByPage),
|
|
|
|
'logs' => array_slice(
|
|
|
|
$_SESSION['entryAccessLogPages'][$dn],
|
|
|
|
$page > 1 ? (($page - 1) * $nbByPage) - 1 : 0,
|
2022-07-20 14:53:28 +02:00
|
|
|
$nbByPage
|
2022-06-16 13:15:28 +02:00
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function showObjectAccessLogs($obj) {
|
|
|
|
$pageNb = isset($_REQUEST['page']) ? intval($_REQUEST['page']) : 1;
|
|
|
|
$dn = $obj->getDn();
|
|
|
|
$page = getEntryAccessLogPage($dn, $pageNb);
|
|
|
|
if (!is_array($page)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
LStemplate::assign('page', $page);
|
|
|
|
$LSview_actions = array();
|
|
|
|
$LSview_actions['refresh'] = array (
|
|
|
|
'label' => _('Refresh'),
|
|
|
|
'url' => 'object/'.$obj->getType().'/'.urlencode($dn).'/customAction/showObjectAccessLogs?refresh',
|
|
|
|
'action' => 'refresh',
|
|
|
|
);
|
|
|
|
$LSview_actions['return'] = array (
|
|
|
|
'label' => _('Go back'),
|
|
|
|
'url' => 'object/'.$obj->getType().'/'.urlencode($dn),
|
|
|
|
'action' => 'view',
|
|
|
|
);
|
|
|
|
LStemplate::assign('LSview_actions', $LSview_actions);
|
|
|
|
LSsession::setTemplate('showObjectAccessLogs.tpl');
|
|
|
|
LSsession::displayTemplate();
|
|
|
|
exit();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (php_sapi_name() !== 'cli') {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function cli_getEntryAccessLog($command_args) {
|
|
|
|
if (count($command_args) < 1) {
|
|
|
|
LSlog::fatal('You must specify entry DN as first parameter');
|
|
|
|
}
|
|
|
|
$dn = $command_args[0];
|
|
|
|
$page = isset($command_args[1]) ? intval($command_args[1]) : 1;
|
|
|
|
echo json_encode(
|
|
|
|
getEntryAccessLogPage($dn, $page),
|
2022-07-20 14:53:28 +02:00
|
|
|
JSON_PRETTY_PRINT
|
2022-06-16 13:15:28 +02:00
|
|
|
);
|
|
|
|
}
|