2013-11-17 19:05:10 +00:00
|
|
|
<?php
|
2016-12-26 18:11:05 +00:00
|
|
|
namespace LAM\TOOLS\MULTI_EDIT;
|
|
|
|
use \htmlTable;
|
|
|
|
use \htmlTitle;
|
|
|
|
use \htmlSelect;
|
|
|
|
use \htmlOutputText;
|
|
|
|
use \htmlInputField;
|
|
|
|
use \htmlSubTitle;
|
|
|
|
use \htmlButton;
|
|
|
|
use \htmlStatusMessage;
|
|
|
|
use \htmlSpacer;
|
|
|
|
use \htmlHiddenInput;
|
|
|
|
use \htmlGroup;
|
|
|
|
use \htmlDiv;
|
|
|
|
use \htmlJavaScript;
|
|
|
|
use \htmlLink;
|
|
|
|
use \htmlInputTextarea;
|
2018-04-16 18:46:09 +00:00
|
|
|
use \htmlResponsiveRow;
|
|
|
|
use \htmlResponsiveSelect;
|
|
|
|
use \htmlResponsiveInputField;
|
|
|
|
use \htmlResponsiveTable;
|
2013-11-17 19:05:10 +00:00
|
|
|
/*
|
|
|
|
|
|
|
|
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
2018-04-16 18:46:09 +00:00
|
|
|
Copyright (C) 2013 - 2018 Roland Gruber
|
2013-11-17 19:05:10 +00:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Multi edit tool that allows LDAP operations on multiple entries.
|
|
|
|
*
|
|
|
|
* @author Roland Gruber
|
|
|
|
* @package tools
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** security functions */
|
2018-12-23 16:32:17 +00:00
|
|
|
include_once(__DIR__ . "/../../lib/security.inc");
|
2013-11-17 19:05:10 +00:00
|
|
|
/** access to configuration data */
|
2018-12-23 16:32:17 +00:00
|
|
|
include_once(__DIR__ . "/../../lib/config.inc");
|
2013-11-17 19:05:10 +00:00
|
|
|
/** access LDAP server */
|
2018-12-23 16:32:17 +00:00
|
|
|
include_once(__DIR__ . "/../../lib/ldap.inc");
|
2013-11-17 19:05:10 +00:00
|
|
|
/** used to print status messages */
|
2018-12-23 16:32:17 +00:00
|
|
|
include_once(__DIR__ . "/../../lib/status.inc");
|
2013-11-17 19:05:10 +00:00
|
|
|
|
|
|
|
// start session
|
|
|
|
startSecureSession();
|
2017-02-11 16:11:37 +00:00
|
|
|
enforceUserIsLoggedIn();
|
2013-11-17 19:05:10 +00:00
|
|
|
|
|
|
|
// die if no write access
|
|
|
|
if (!checkIfWriteAccessIsAllowed()) die();
|
|
|
|
|
|
|
|
checkIfToolIsActive('toolMultiEdit');
|
|
|
|
|
|
|
|
setlanguage();
|
|
|
|
|
2015-05-15 19:16:46 +00:00
|
|
|
if (!empty($_POST)) {
|
|
|
|
validateSecurityToken();
|
|
|
|
}
|
|
|
|
|
2014-10-25 13:00:00 +00:00
|
|
|
define('ADD', 'add');
|
|
|
|
define('MOD', 'mod');
|
|
|
|
define('DEL', 'del');
|
2013-11-17 19:05:10 +00:00
|
|
|
|
2014-10-25 13:00:00 +00:00
|
|
|
define('STAGE_START', 'start');
|
|
|
|
define('STAGE_READ_FINISHED', 'readFinished');
|
|
|
|
define('STAGE_ACTIONS_CALCULATED', 'actionsCalculated');
|
|
|
|
define('STAGE_WRITING', 'writing');
|
|
|
|
define('STAGE_FINISHED', 'finished');
|
2013-11-18 21:52:27 +00:00
|
|
|
|
2013-11-17 19:05:10 +00:00
|
|
|
if (isset($_GET['ajaxStatus'])) {
|
|
|
|
runAjaxActions();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
displayStartPage();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Displays the main page of the multi edit tool.
|
|
|
|
*/
|
|
|
|
function displayStartPage() {
|
|
|
|
// display main page
|
2018-12-23 16:32:17 +00:00
|
|
|
include __DIR__ . '/../../lib/adminHeader.inc';
|
2013-11-17 19:05:10 +00:00
|
|
|
echo '<div class="user-bright smallPaddingContent">';
|
2015-05-15 19:16:46 +00:00
|
|
|
echo "<form action=\"multiEdit.php\" method=\"post\">\n";
|
2013-11-17 19:05:10 +00:00
|
|
|
$errors = array();
|
|
|
|
$tabindex = 1;
|
2018-04-16 18:46:09 +00:00
|
|
|
$container = new htmlResponsiveRow();
|
|
|
|
$container->add(new htmlTitle(_("Multi edit")), 12);
|
2013-11-17 19:05:10 +00:00
|
|
|
// LDAP suffix
|
|
|
|
$showRules = array('-' => array('otherSuffix'));
|
|
|
|
$hideRules = array();
|
2016-12-26 18:11:05 +00:00
|
|
|
$typeManager = new \LAM\TYPES\TypeManager();
|
|
|
|
$types = $typeManager->getConfiguredTypes();
|
2013-11-17 19:05:10 +00:00
|
|
|
$suffixes = array();
|
|
|
|
foreach ($types as $type) {
|
2016-12-26 18:11:05 +00:00
|
|
|
if ($type->isHidden()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$suffixes[$type->getAlias()] = $type->getSuffix();
|
|
|
|
$hideRules[$type->getSuffix()] = array('otherSuffix');
|
2013-11-17 19:05:10 +00:00
|
|
|
}
|
|
|
|
$treeSuffix = $_SESSION['config']->get_Suffix('tree');
|
|
|
|
if (!empty($treeSuffix)) {
|
|
|
|
$suffixes[_('Tree view')] = $_SESSION['config']->get_Suffix('tree');
|
|
|
|
$hideRules[$_SESSION['config']->get_Suffix('tree')] = array('otherSuffix');
|
|
|
|
}
|
|
|
|
$suffixes = array_flip($suffixes);
|
|
|
|
natcasesort($suffixes);
|
|
|
|
$suffixes = array_flip($suffixes);
|
2013-11-23 13:51:48 +00:00
|
|
|
$suffixes[_('Other')] = '-';
|
2013-11-17 19:05:10 +00:00
|
|
|
$suffixValues = array_values($suffixes);
|
|
|
|
$valSuffix = empty($_POST['suffix']) ? $suffixValues[0] : $_POST['suffix'];
|
2018-04-16 18:46:09 +00:00
|
|
|
$suffixSelect = new htmlResponsiveSelect('suffix', $suffixes, array($valSuffix), _('LDAP suffix'), '700');
|
2013-11-17 19:05:10 +00:00
|
|
|
$suffixSelect->setHasDescriptiveElements(true);
|
|
|
|
$suffixSelect->setSortElements(false);
|
|
|
|
$suffixSelect->setTableRowsToShow($showRules);
|
|
|
|
$suffixSelect->setTableRowsToHide($hideRules);
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->add($suffixSelect, 12);
|
2013-11-17 19:05:10 +00:00
|
|
|
$valOtherSuffix = empty($_POST['otherSuffix']) ? '' : $_POST['otherSuffix'];
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->add(new htmlResponsiveInputField(_('Other'), 'otherSuffix', $valOtherSuffix), 12);
|
2013-11-17 19:05:10 +00:00
|
|
|
// LDAP filter
|
2013-11-23 13:22:54 +00:00
|
|
|
$valFilter = empty($_POST['filter']) ? '(objectClass=inetOrgPerson)' : $_POST['filter'];
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->add(new htmlResponsiveInputField(_('LDAP filter'), 'filter', $valFilter, '701'), 12);
|
2013-11-17 19:05:10 +00:00
|
|
|
// operation fields
|
2018-04-16 18:46:09 +00:00
|
|
|
$operationsTitle = new htmlSubTitle(_('Operations'));
|
|
|
|
$operationsTitle->setHelpId('702');
|
|
|
|
$container->add($operationsTitle, 12);
|
|
|
|
$operationsTitles = array(_('Type'), _('Attribute name'), _('Value'));
|
|
|
|
$data = array();
|
2013-11-17 19:05:10 +00:00
|
|
|
$opCount = empty($_POST['opcount']) ? '3' : $_POST['opcount'];
|
|
|
|
if (isset($_POST['addFields'])) {
|
|
|
|
$opCount += 3;
|
|
|
|
}
|
|
|
|
$operations = array(_('Add') => ADD, _('Modify') => MOD, _('Delete') => DEL);
|
|
|
|
for ($i = 0; $i < $opCount; $i++) {
|
|
|
|
// operation type
|
|
|
|
$selOp = empty($_POST['op_' . $i]) ? ADD : $_POST['op_' . $i];
|
|
|
|
$opSelect = new htmlSelect('op_' . $i, $operations, array($selOp));
|
|
|
|
$opSelect->setHasDescriptiveElements(true);
|
2018-04-16 18:46:09 +00:00
|
|
|
$data[$i][] = $opSelect;
|
2013-11-17 19:05:10 +00:00
|
|
|
// attribute name
|
|
|
|
$attrVal = empty($_POST['attr_' . $i]) ? '' : $_POST['attr_' . $i];
|
2018-04-16 18:46:09 +00:00
|
|
|
$data[$i][] = new htmlInputField('attr_' . $i, $attrVal);
|
2013-11-17 19:05:10 +00:00
|
|
|
$valVal = empty($_POST['val_' . $i]) ? '' : $_POST['val_' . $i];
|
2018-04-16 18:46:09 +00:00
|
|
|
$data[$i][] = new htmlInputField('val_' . $i, $valVal);
|
2013-11-17 19:05:10 +00:00
|
|
|
// check input
|
|
|
|
if (($selOp == ADD) && !empty($attrVal) && empty($valVal)) {
|
|
|
|
$errors[] = new htmlStatusMessage('ERROR', _('Please enter a value to add.'), htmlspecialchars($attrVal));
|
|
|
|
}
|
|
|
|
if (($selOp == MOD) && !empty($attrVal) && empty($valVal)) {
|
|
|
|
$errors[] = new htmlStatusMessage('ERROR', _('Please enter a value to modify.'), htmlspecialchars($attrVal));
|
|
|
|
}
|
|
|
|
}
|
2018-04-16 18:46:09 +00:00
|
|
|
$operationsTable = new htmlResponsiveTable($operationsTitles, $data);
|
|
|
|
$container->add($operationsTable, 12);
|
2013-11-17 19:05:10 +00:00
|
|
|
// add more fields
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->addVerticalSpacer('1rem');
|
|
|
|
$container->add(new htmlButton('addFields', _('Add more fields')), 12);
|
|
|
|
$container->add(new htmlHiddenInput('opcount', $opCount), 12);
|
2013-11-17 19:05:10 +00:00
|
|
|
// error messages
|
|
|
|
if (sizeof($errors) > 0) {
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->addVerticalSpacer('5rem');
|
2013-11-17 19:05:10 +00:00
|
|
|
foreach ($errors as $error) {
|
|
|
|
$error->colspan = 5;
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->add($error, 12);
|
2013-11-17 19:05:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// action buttons
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->addVerticalSpacer('2rem');
|
2013-11-17 19:05:10 +00:00
|
|
|
$buttonGroup = new htmlGroup();
|
|
|
|
$buttonGroup->colspan = 3;
|
|
|
|
$dryRunButton = new htmlButton('dryRun', _('Dry run'));
|
|
|
|
$dryRunButton->setIconClass('dryRunButton');
|
|
|
|
$buttonGroup->addElement($dryRunButton);
|
|
|
|
$buttonGroup->addElement(new htmlSpacer('10px', null));
|
|
|
|
$applyButton = new htmlButton('applyChanges', _('Apply changes'));
|
|
|
|
$applyButton->setIconClass('saveButton');
|
|
|
|
$buttonGroup->addElement($applyButton);
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->add($buttonGroup, 12);
|
|
|
|
$container->addVerticalSpacer('1rem');
|
2016-12-19 20:32:08 +00:00
|
|
|
|
2013-11-17 19:05:10 +00:00
|
|
|
// run actions
|
|
|
|
if ((sizeof($errors) == 0) && (isset($_POST['dryRun']) || isset($_POST['applyChanges']))) {
|
|
|
|
runActions($container);
|
|
|
|
}
|
2016-12-19 20:32:08 +00:00
|
|
|
|
2015-05-15 19:16:46 +00:00
|
|
|
addSecurityTokenToMetaHTML($container);
|
2016-12-19 20:32:08 +00:00
|
|
|
|
2013-11-17 19:05:10 +00:00
|
|
|
parseHtml(null, $container, array(), false, $tabindex, 'user');
|
2018-12-23 10:01:29 +00:00
|
|
|
echo "</form>\n";
|
2013-11-17 19:05:10 +00:00
|
|
|
echo '</div>';
|
2018-12-23 16:32:17 +00:00
|
|
|
include __DIR__ . '/../../lib/adminFooter.inc';
|
2013-11-17 19:05:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Runs the dry run and change actions.
|
2016-12-19 20:32:08 +00:00
|
|
|
*
|
2018-04-16 18:46:09 +00:00
|
|
|
* @param htmlResponsiveRow $container container
|
2013-11-17 19:05:10 +00:00
|
|
|
*/
|
2018-04-16 18:46:09 +00:00
|
|
|
function runActions(htmlResponsiveRow &$container) {
|
2013-11-17 19:05:10 +00:00
|
|
|
// LDAP suffix
|
|
|
|
if ($_POST['suffix'] == '-') {
|
|
|
|
$suffix = trim($_POST['otherSuffix']);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$suffix = $_POST['suffix'];
|
|
|
|
}
|
|
|
|
if (empty($suffix)) {
|
|
|
|
$error = new htmlStatusMessage('ERROR', _('LDAP Suffix is invalid!'));
|
|
|
|
$error->colspan = 5;
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->add($error, 12);
|
2013-11-17 19:05:10 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
// LDAP filter
|
|
|
|
$filter = trim($_POST['filter']);
|
|
|
|
// operations
|
|
|
|
$operations = array();
|
2013-11-19 20:10:03 +00:00
|
|
|
for ($i = 0; $i < $_POST['opcount']; $i++) {
|
2013-11-17 19:05:10 +00:00
|
|
|
if (!empty($_POST['attr_' . $i])) {
|
2013-11-18 21:52:27 +00:00
|
|
|
$operations[] = array($_POST['op_' . $i], strtolower(trim($_POST['attr_' . $i])), trim($_POST['val_' . $i]));
|
2013-11-17 19:05:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (sizeof($operations) == 0) {
|
|
|
|
$error = new htmlStatusMessage('ERROR', _('Please specify at least one operation.'));
|
|
|
|
$error->colspan = 5;
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->add($error, 12);
|
2013-11-17 19:05:10 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
$_SESSION['multiEdit_suffix'] = $suffix;
|
|
|
|
$_SESSION['multiEdit_filter'] = $filter;
|
|
|
|
$_SESSION['multiEdit_operations'] = $operations;
|
2013-11-18 21:52:27 +00:00
|
|
|
$_SESSION['multiEdit_status'] = array('stage' => STAGE_START);
|
|
|
|
$_SESSION['multiEdit_dryRun'] = isset($_POST['dryRun']);
|
2013-11-17 19:05:10 +00:00
|
|
|
// disable all input elements
|
|
|
|
$jsContent = '
|
|
|
|
jQuery(\'input\').attr(\'disabled\', true);
|
|
|
|
jQuery(\'select\').attr(\'disabled\', true);
|
|
|
|
jQuery(\'button\').attr(\'disabled\', true);
|
|
|
|
';
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->add(new htmlJavaScript($jsContent), 12);
|
2013-11-17 19:05:10 +00:00
|
|
|
// progress area
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->add(new htmlSubTitle(_('Progress')), 12);
|
2013-11-18 21:52:27 +00:00
|
|
|
$progressBarDiv = new htmlDiv('progressBar', '');
|
|
|
|
$progressBarDiv->colspan = 5;
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->add($progressBarDiv, 12);
|
2013-11-17 19:05:10 +00:00
|
|
|
$progressDiv = new htmlDiv('progressArea', '');
|
|
|
|
$progressDiv->colspan = 5;
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->add($progressDiv, 12);
|
2013-11-17 19:05:10 +00:00
|
|
|
// JS block for AJAX status update
|
|
|
|
$ajaxBlock = '
|
|
|
|
jQuery.get(\'multiEdit.php?ajaxStatus\', null, function(data) {handleReply(data);}, \'json\');
|
2016-12-19 20:32:08 +00:00
|
|
|
|
2013-11-17 19:05:10 +00:00
|
|
|
function handleReply(data) {
|
2013-11-18 21:52:27 +00:00
|
|
|
jQuery(\'#progressBar\').progressbar({value: data.progress, max: 120});
|
2013-11-17 19:05:10 +00:00
|
|
|
jQuery(\'#progressArea\').html(data.content);
|
|
|
|
if (data.status != "finished") {
|
|
|
|
jQuery.get(\'multiEdit.php?ajaxStatus\', null, function(data) {handleReply(data);}, \'json\');
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
jQuery(\'input\').removeAttr(\'disabled\');
|
|
|
|
jQuery(\'select\').removeAttr(\'disabled\');
|
|
|
|
jQuery(\'button\').removeAttr(\'disabled\');
|
2013-11-18 21:52:27 +00:00
|
|
|
jQuery(\'#progressBar\').hide();
|
2013-11-17 19:05:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
';
|
2018-04-16 18:46:09 +00:00
|
|
|
$container->add(new htmlJavaScript($ajaxBlock), 12);
|
2013-11-17 19:05:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Performs the modify operations.
|
|
|
|
*/
|
|
|
|
function runAjaxActions() {
|
|
|
|
$jsonReturn = array(
|
2013-11-18 21:52:27 +00:00
|
|
|
'status' => STAGE_START,
|
|
|
|
'progress' => 0,
|
|
|
|
'content' => ''
|
2013-11-17 19:05:10 +00:00
|
|
|
);
|
2013-11-18 21:52:27 +00:00
|
|
|
switch ($_SESSION['multiEdit_status']['stage']) {
|
|
|
|
case STAGE_START:
|
|
|
|
$jsonReturn = readLDAPData();
|
|
|
|
break;
|
|
|
|
case STAGE_READ_FINISHED:
|
|
|
|
$jsonReturn = generateActions();
|
|
|
|
break;
|
|
|
|
case STAGE_ACTIONS_CALCULATED:
|
2013-11-23 13:22:54 +00:00
|
|
|
case STAGE_WRITING:
|
2013-11-18 21:52:27 +00:00
|
|
|
if ($_SESSION['multiEdit_dryRun']) {
|
|
|
|
$jsonReturn = dryRun();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$jsonReturn = doModify();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2013-11-17 19:05:10 +00:00
|
|
|
echo json_encode($jsonReturn);
|
|
|
|
}
|
|
|
|
|
2013-11-18 21:52:27 +00:00
|
|
|
/**
|
|
|
|
* Reads the LDAP entries from the directory.
|
2016-12-19 20:32:08 +00:00
|
|
|
*
|
2013-11-18 21:52:27 +00:00
|
|
|
* @return array status
|
|
|
|
*/
|
|
|
|
function readLDAPData() {
|
|
|
|
$suffix = $_SESSION['multiEdit_suffix'];
|
|
|
|
$filter = $_SESSION['multiEdit_filter'];
|
|
|
|
if (empty($filter)) {
|
|
|
|
$filter = '(objectClass=*)';
|
|
|
|
}
|
|
|
|
$operations = $_SESSION['multiEdit_operations'];
|
|
|
|
$attributes = array();
|
|
|
|
foreach ($operations as $op) {
|
|
|
|
if (!in_array(strtolower($op[1]), $attributes)) {
|
|
|
|
$attributes[] = strtolower($op[1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// run LDAP query
|
|
|
|
$results = searchLDAP($suffix, $filter, $attributes);
|
|
|
|
// print error message if no data returned
|
|
|
|
if (empty($results)) {
|
|
|
|
$code = ldap_errno($_SESSION['ldap']->server());
|
|
|
|
if ($code !== 0) {
|
|
|
|
$msg = new htmlStatusMessage('ERROR', _('Encountered an error while performing search.'), getDefaultLDAPErrorString($_SESSION['ldap']->server()));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$msg = new htmlStatusMessage('ERROR', _('No objects found!'));
|
|
|
|
}
|
2013-11-23 13:22:54 +00:00
|
|
|
$content = getMessageHTML($msg);
|
2013-11-18 21:52:27 +00:00
|
|
|
return array(
|
|
|
|
'status' => STAGE_FINISHED,
|
|
|
|
'progress' => 120,
|
|
|
|
'content' => $content
|
|
|
|
);
|
|
|
|
}
|
|
|
|
// save LDAP data
|
|
|
|
$_SESSION['multiEdit_status']['entries'] = $results;
|
|
|
|
$_SESSION['multiEdit_status']['stage'] = STAGE_READ_FINISHED;
|
|
|
|
return array(
|
|
|
|
'status' => STAGE_READ_FINISHED,
|
|
|
|
'progress' => 10,
|
|
|
|
'content' => ''
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generates the required actions based on the read LDAP data.
|
2016-12-19 20:32:08 +00:00
|
|
|
*
|
2013-11-18 21:52:27 +00:00
|
|
|
* @return array status
|
|
|
|
*/
|
|
|
|
function generateActions() {
|
|
|
|
$actions = array();
|
|
|
|
foreach ($_SESSION['multiEdit_status']['entries'] as $entry) {
|
2013-11-19 20:10:03 +00:00
|
|
|
$dn = $entry['dn'];
|
2013-11-18 21:52:27 +00:00
|
|
|
foreach ($_SESSION['multiEdit_operations'] as $op) {
|
|
|
|
$opType = $op[0];
|
|
|
|
$attr = $op[1];
|
|
|
|
$val = $op[2];
|
|
|
|
switch ($opType) {
|
|
|
|
case ADD:
|
|
|
|
if (empty($entry[$attr]) || !in_array_ignore_case($val, $entry[$attr])) {
|
2013-11-19 20:10:03 +00:00
|
|
|
$actions[] = array(ADD, $dn, $attr, $val);
|
2013-11-18 21:52:27 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOD:
|
2013-11-19 20:10:03 +00:00
|
|
|
if (empty($entry[$attr])) {
|
|
|
|
// attribute not yet exists, add it
|
|
|
|
$actions[] = array(ADD, $dn, $attr, $val);
|
|
|
|
}
|
|
|
|
elseif (!empty($entry[$attr]) && !in_array_ignore_case($val, $entry[$attr])) {
|
|
|
|
// attribute exists and value is not included, replace old values
|
|
|
|
$actions[] = array(MOD, $dn, $attr, $val);
|
2013-11-18 21:52:27 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DEL:
|
|
|
|
if (empty($val) && !empty($entry[$attr])) {
|
2013-11-19 20:10:03 +00:00
|
|
|
$actions[] = array(DEL, $dn, $attr, null);
|
2013-11-18 21:52:27 +00:00
|
|
|
}
|
2018-04-16 18:46:09 +00:00
|
|
|
elseif (!empty($val) && isset($entry[$attr]) && in_array($val, $entry[$attr])) {
|
2013-11-19 20:10:03 +00:00
|
|
|
$actions[] = array(DEL, $dn, $attr, $val);
|
2013-11-18 21:52:27 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// save actions
|
|
|
|
$_SESSION['multiEdit_status']['actions'] = $actions;
|
|
|
|
$_SESSION['multiEdit_status']['stage'] = STAGE_ACTIONS_CALCULATED;
|
|
|
|
return array(
|
|
|
|
'status' => STAGE_ACTIONS_CALCULATED,
|
|
|
|
'progress' => 20,
|
|
|
|
'content' => ''
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2013-11-19 20:10:03 +00:00
|
|
|
/**
|
|
|
|
* Prints the dryRun output.
|
2016-12-19 20:32:08 +00:00
|
|
|
*
|
2013-11-19 20:10:03 +00:00
|
|
|
* @return array status
|
|
|
|
*/
|
|
|
|
function dryRun() {
|
2013-11-23 13:22:54 +00:00
|
|
|
$pro = isLAMProVersion() ? ' Pro' : '';
|
|
|
|
$ldif = '# LDAP Account Manager' . $pro . ' ' . LAMVersion() . "\n\nversion: 1\n\n";
|
2013-11-19 20:10:03 +00:00
|
|
|
$log = '';
|
|
|
|
// fill LDIF and log file
|
|
|
|
$lastDN = '';
|
|
|
|
foreach ($_SESSION['multiEdit_status']['actions'] as $action) {
|
|
|
|
$opType = $action[0];
|
|
|
|
$dn = $action[1];
|
|
|
|
$attr = $action[2];
|
|
|
|
$val = $action[3];
|
|
|
|
if ($lastDN != $dn) {
|
|
|
|
if ($lastDN != '') {
|
|
|
|
$log .= "\r\n";
|
|
|
|
}
|
|
|
|
$lastDN = $dn;
|
|
|
|
$log .= $dn . "\r\n";
|
|
|
|
}
|
|
|
|
if ($lastDN != '') {
|
|
|
|
$ldif .= "\n";
|
|
|
|
}
|
|
|
|
$ldif .= 'dn: ' . $dn . "\n";
|
|
|
|
$ldif .= 'changetype: modify' . "\n";
|
|
|
|
switch ($opType) {
|
|
|
|
case ADD:
|
|
|
|
$log .= '+' . $attr . '=' . $val . "\r\n";
|
|
|
|
$ldif .= 'add: ' . $attr . "\n";
|
|
|
|
$ldif .= $attr . ': ' . $val . "\n";
|
|
|
|
break;
|
|
|
|
case DEL:
|
|
|
|
$ldif .= 'delete: ' . $attr . "\n";
|
|
|
|
if (empty($val)) {
|
2016-12-19 20:32:08 +00:00
|
|
|
$log .= '-' . $attr . "\r\n";
|
2013-11-19 20:10:03 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
$log .= '-' . $attr . '=' . $val . "\r\n";
|
|
|
|
$ldif .= $attr . ': ' . $val . "\n";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOD:
|
|
|
|
$log .= '*' . $attr . '=' . $val . "\r\n";
|
|
|
|
$ldif .= 'replace: ' . $attr . "\n";
|
|
|
|
$ldif .= $attr . ': ' . $val . "\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// build meta HTML
|
|
|
|
$container = new htmlTable();
|
2014-10-25 13:00:00 +00:00
|
|
|
$container->addElement(new htmlOutputText(_('Dry run finished.')), true);
|
2013-11-19 20:10:03 +00:00
|
|
|
$container->addVerticalSpace('20px');
|
|
|
|
// store LDIF
|
|
|
|
$filename = 'ldif' . getRandomNumber() . '.ldif';
|
2018-08-28 18:19:49 +00:00
|
|
|
$out = @fopen(dirname(__FILE__) . '/../../tmp/' . $filename, "wb");
|
2013-11-19 20:10:03 +00:00
|
|
|
fwrite($out, $ldif);
|
|
|
|
$container->addElement(new htmlOutputText(_('LDIF file')), true);
|
2018-08-28 18:19:49 +00:00
|
|
|
$ldifLink = new htmlLink($filename, '../../tmp/' . $filename);
|
2013-11-19 20:10:03 +00:00
|
|
|
$ldifLink->setTargetWindow('_blank');
|
|
|
|
$container->addElement($ldifLink, true);
|
|
|
|
$container->addVerticalSpace('20px');
|
|
|
|
$container->addElement(new htmlOutputText(_('Log output')), true);
|
|
|
|
$container->addElement(new htmlInputTextarea('log', $log, 100, 30), true);
|
|
|
|
// generate HTML
|
|
|
|
fclose ($out);
|
|
|
|
ob_start();
|
|
|
|
$tabindex = 1;
|
|
|
|
parseHtml(null, $container, array(), true, $tabindex, 'user');
|
|
|
|
$content = ob_get_contents();
|
|
|
|
ob_end_clean();
|
|
|
|
return array(
|
|
|
|
'status' => STAGE_FINISHED,
|
|
|
|
'progress' => 120,
|
|
|
|
'content' => $content
|
|
|
|
);
|
|
|
|
}
|
2013-11-23 13:22:54 +00:00
|
|
|
|
2017-10-25 18:38:39 +00:00
|
|
|
/**
|
|
|
|
* Error handler
|
|
|
|
*
|
|
|
|
* @param int $errno error number
|
|
|
|
* @param string $errstr error message
|
|
|
|
* @param string $errfile error file
|
|
|
|
* @param int $errline error line
|
|
|
|
*/
|
|
|
|
function multiEditLdapErrorHandler($errno, $errstr, $errfile, $errline) {
|
|
|
|
switch ($errno) {
|
|
|
|
case E_USER_ERROR:
|
2017-10-25 18:40:28 +00:00
|
|
|
logNewMessage(LOG_ERR, 'Error occured: ' . $errstr . " ($errfile: $errline)");
|
2017-10-25 18:38:39 +00:00
|
|
|
$_REQUEST['multiEdit_error'] = true;
|
|
|
|
;
|
|
|
|
break;
|
|
|
|
case E_USER_WARNING:
|
2017-10-25 18:40:28 +00:00
|
|
|
logNewMessage(LOG_WARNING, 'Error occured: ' . $errstr . " ($errfile: $errline)");
|
2017-10-25 18:38:39 +00:00
|
|
|
$_REQUEST['multiEdit_error'] = true;
|
|
|
|
;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-23 13:22:54 +00:00
|
|
|
/**
|
|
|
|
* Runs the actual modifications.
|
2016-12-19 20:32:08 +00:00
|
|
|
*
|
2013-11-23 13:22:54 +00:00
|
|
|
* @return array status
|
|
|
|
*/
|
|
|
|
function doModify() {
|
2017-10-25 18:38:39 +00:00
|
|
|
set_error_handler('\LAM\TOOLS\MULTI_EDIT\multiEditLdapErrorHandler');
|
2013-11-23 13:22:54 +00:00
|
|
|
// initial action index
|
|
|
|
if (!isset($_SESSION['multiEdit_status']['index'])) {
|
|
|
|
$_SESSION['multiEdit_status']['index'] = 0;
|
|
|
|
}
|
|
|
|
// initial content
|
|
|
|
if (!isset($_SESSION['multiEdit_status']['modContent'])) {
|
|
|
|
$_SESSION['multiEdit_status']['modContent'] = '';
|
|
|
|
}
|
|
|
|
// run 10 modifications in each call
|
|
|
|
$localCount = 0;
|
|
|
|
while (($localCount < 10) && ($_SESSION['multiEdit_status']['index'] < sizeof($_SESSION['multiEdit_status']['actions']))) {
|
|
|
|
$action = $_SESSION['multiEdit_status']['actions'][$_SESSION['multiEdit_status']['index']];
|
|
|
|
$opType = $action[0];
|
|
|
|
$dn = $action[1];
|
|
|
|
$attr = $action[2];
|
|
|
|
$val = $action[3];
|
|
|
|
$_SESSION['multiEdit_status']['modContent'] .= htmlspecialchars($dn) . "<br>";
|
|
|
|
// run LDAP commands
|
|
|
|
$success = false;
|
|
|
|
switch ($opType) {
|
|
|
|
case ADD:
|
2017-10-24 18:48:34 +00:00
|
|
|
$success = ldap_mod_add($_SESSION['ldap']->server(), $dn, array($attr => array($val)));
|
2013-11-23 13:22:54 +00:00
|
|
|
break;
|
|
|
|
case DEL:
|
|
|
|
if (empty($val)) {
|
|
|
|
$success = ldap_modify($_SESSION['ldap']->server(), $dn, array($attr => array()));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$success = ldap_mod_del($_SESSION['ldap']->server(), $dn, array($attr => array($val)));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOD:
|
|
|
|
$success = ldap_modify($_SESSION['ldap']->server(), $dn, array($attr => array($val)));
|
|
|
|
break;
|
|
|
|
}
|
2017-10-25 18:38:39 +00:00
|
|
|
if (!$success || isset($_REQUEST['multiEdit_error'])) {
|
2013-11-23 13:22:54 +00:00
|
|
|
$msg = new htmlStatusMessage('ERROR', getDefaultLDAPErrorString($_SESSION['ldap']->server()));
|
|
|
|
$_SESSION['multiEdit_status']['modContent'] .= getMessageHTML($msg);
|
|
|
|
}
|
|
|
|
$localCount++;
|
|
|
|
$_SESSION['multiEdit_status']['index']++;
|
|
|
|
}
|
|
|
|
// check if finished
|
|
|
|
if ($_SESSION['multiEdit_status']['index'] == sizeof($_SESSION['multiEdit_status']['actions'])) {
|
|
|
|
$_SESSION['multiEdit_status']['modContent'] .= '<br><br>' . _('Finished all operations.');
|
|
|
|
return array(
|
|
|
|
'status' => STAGE_FINISHED,
|
|
|
|
'progress' => 120,
|
|
|
|
'content' => $_SESSION['multiEdit_status']['modContent']
|
|
|
|
);
|
|
|
|
}
|
|
|
|
// return current status
|
|
|
|
return array(
|
|
|
|
'status' => STAGE_WRITING,
|
|
|
|
'progress' => 20 + (($_SESSION['multiEdit_status']['index'] / sizeof($_SESSION['multiEdit_status']['actions'])) * 100),
|
|
|
|
'content' => $_SESSION['multiEdit_status']['modContent']
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the HTML code for a htmlStatusMessage
|
2016-12-19 20:32:08 +00:00
|
|
|
*
|
2013-11-23 13:22:54 +00:00
|
|
|
* @param htmlStatusMessage $msg message
|
|
|
|
* @return String HTML code
|
|
|
|
*/
|
|
|
|
function getMessageHTML($msg) {
|
|
|
|
$tabindex = 0;
|
|
|
|
ob_start();
|
|
|
|
parseHtml(null, $msg, array(), true, $tabindex, 'user');
|
|
|
|
$content = ob_get_contents();
|
|
|
|
ob_end_clean();
|
|
|
|
return $content;
|
|
|
|
}
|