support for 389ds locking and deactivation

This commit is contained in:
Roland Gruber 2016-05-15 12:15:30 +02:00
parent 616b11e362
commit cf5132745d
11 changed files with 92 additions and 47 deletions

View File

@ -1,6 +1,7 @@
June 2016 5.4
- Unix: support magic numbers for UIDs/GIDs (e.g. 389 server DNA plugin)
- LAM Pro:
-> New module for 389ds unlocking and deactivation status
-> Self registration: support for Google reCAPTCHA
-> Password notification jobs support CC and BCC

View File

@ -2698,8 +2698,8 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<para><emphasis>Show account status:</emphasis> If you activate this
option then there will be an additional column displayed that shows if
the account is locked. You can see more details when moving the mouse
cursor over the lock icon. This function supports Unix, Samba and
PPolicy.</para>
cursor over the lock icon. This function supports Unix, Samba, PPolicy,
Windows and 389ds locking+deactivation.</para>
<screenshot>
<mediaobject>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 760 B

After

Width:  |  Height:  |  Size: 907 B

View File

@ -1267,10 +1267,9 @@ abstract class baseModule {
* @param integer $length field length
* @param boolean $isTextArea show as text area (default false)
* @param array $autoCompleteValues values for auto-completion
* @param boolean $readOnly this field is read-only
* @return mixed reference to htmlTableExtendedInputField/htmlTableExtendedInputTextarea
*/
protected function &addSimpleInputTextField(&$container, $attrName, $label, $required = false, $length = null, $isTextArea = false, $autoCompleteValues = null, $readOnly = false) {
protected function &addSimpleInputTextField(&$container, $attrName, $label, $required = false, $length = null, $isTextArea = false, $autoCompleteValues = null) {
$value = '';
if (isset($this->attributes[$attrName][0])) {
$value = $this->attributes[$attrName][0];
@ -1296,6 +1295,28 @@ abstract class baseModule {
return $input;
}
/**
* Adds a simple read-only field to the given container.
*
* @param htmlTable $container parent container
* @param String $attrName attribute name
* @param String $label field label
*/
protected function addSimpleReadOnlyField(&$container, $attrName, $label) {
$val = '';
if (!empty($this->attributes[$attrName][0])) {
$values = $this->attributes[$attrName];
array_map('htmlspecialchars', $values);
$val = implode('<br>', $values);
}
$labelBox = new htmlOutputText($label);
if (!empty($this->attributes[$attrName]) && (sizeof($this->attributes[$attrName]) > 1)) {
$labelBox->alignment = htmlElement::ALIGN_TOP;
}
$container->addElement($labelBox);
$container->addElement(new htmlOutputText($val, false), true);
}
/**
* Adds a text input field that may contain multiple values to the given htmlTable.
* The field name will be the same as the attribute name plus a counting number (e.g. street_0).
@ -1598,6 +1619,18 @@ abstract class baseModule {
else return array();
}
/**
* Returns a list of operational LDAP attributes which are managed by this module and need to be explicitly set for LDAP search.
*
* @return array list of hidden attributes
*
* @see baseModule::get_metaData()
*/
public function getManagedHiddenAttributes() {
if (isset($this->meta['hiddenAttributes']) && is_array($this->meta['hiddenAttributes'])) return $this->meta['hiddenAttributes'];
else return array();
}
/**
* This function returns a list of PHP extensions (e.g. hash) which are needed by this module.
*

View File

@ -1553,8 +1553,11 @@ class accountContainer {
$this->module = array();
$modules = $_SESSION['config']->get_AccountModules($this->type);
$search = substr($dn, 0, strpos($dn, ','));
$searchAttrs = array('*', '+', 'creatorsName', 'createTimestamp', 'modifiersName',
'modifyTimestamp', 'hasSubordinates', 'pwdChangedTime');
$searchAttrs = array('*', '+');
foreach ($modules as $module) {
$modTmp = new $module($this->type);
$searchAttrs = array_merge($searchAttrs, $modTmp->getManagedHiddenAttributes());
}
$result = @ldap_read($_SESSION['ldap']->server(), escapeDN($dn), escapeDN($search), $searchAttrs, 0, 0, 0, LDAP_DEREF_NEVER);
if (!$result) {
return array(array("ERROR", _("Unable to load LDAP entry:") . " " . htmlspecialchars($dn), getDefaultLDAPErrorString($_SESSION['ldap']->server())));

View File

@ -34,3 +34,4 @@
/zarafaGroup.inc
/zarafaServer.inc
/zarafaUser.inc
/locking389ds.inc

View File

@ -3,7 +3,7 @@
$Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2011 Roland Gruber
Copyright (C) 2011 - 2016 Roland Gruber
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
@ -36,7 +36,7 @@ class generalInformation extends baseModule {
/**
* Returns true if this module can manage accounts of the current type, otherwise false.
*
*
* @return boolean true if module fits
*/
public function can_manage() {
@ -47,7 +47,7 @@ class generalInformation extends baseModule {
* Returns meta data that is interpreted by parent class
*
* @return array array with meta data
*
*
* @see baseModule::get_metaData()
*/
public function get_metaData() {
@ -60,13 +60,15 @@ class generalInformation extends baseModule {
$return['dependencies'] = array('depends' => array(), 'conflicts' => array());
// managed attributes
$return['attributes'] = array('creatorsName', 'createTimestamp', 'modifiersName',
'modifyTimestamp', 'hasSubordinates', 'memberOf', 'pwdChangedTime');
'modifyTimestamp', 'hasSubordinates', 'memberOf');
$return['hiddenAttributes'] = array('creatorsName', 'createTimestamp', 'modifiersName',
'modifyTimestamp', 'hasSubordinates');
return $return;
}
/**
* Returns the HTML meta data for the main account page.
*
*
* @return htmlElement HTML meta data
*/
public function display_html_attributes() {

View File

@ -3601,28 +3601,6 @@ class inetOrgPerson extends baseModule implements passwordService {
return $this->isBooleanConfigOptionSet('inetOrgPerson_readOnly_' . $attrName);
}
/**
* Adds a simple read-only field to the given container.
*
* @param htmlTable $container parent container
* @param String $attrName attribute name
* @param String $label field label
*/
private function addSimpleReadOnlyField(&$container, $attrName, $label) {
$val = '';
if (!empty($this->attributes[$attrName][0])) {
$values = $this->attributes[$attrName];
array_map('htmlspecialchars', $values);
$val = implode('<br>', $values);
}
$labelBox = new htmlOutputText($label);
if (!empty($this->attributes[$attrName]) && (sizeof($this->attributes[$attrName]) > 1)) {
$labelBox->alignment = htmlElement::ALIGN_TOP;
}
$container->addElement($labelBox);
$container->addElement(new htmlOutputText($val, false), true);
}
/**
* Returns a list of configuration options.
*

View File

@ -224,9 +224,12 @@ class user extends baseType {
$sambaAvailable = (($container->getAccountModule('sambaSamAccount') != null) && $container->getAccountModule('sambaSamAccount')->isExtensionEnabled());
$ppolicyAvailable = ($container->getAccountModule('ppolicyUser') != null);
$windowsAvailable = ($container->getAccountModule('windowsUser') != null);
if (!$unixAvailable && !$sambaAvailable && !$ppolicyAvailable && !$windowsAvailable) {
$is389dsLocked = ($container->getAccountModule('locking389ds') != null) && $container->getAccountModule('locking389ds')->isLocked();
$is389dsDeactivated = ($container->getAccountModule('locking389ds') != null) && $container->getAccountModule('locking389ds')->isDeactivated();
if (!$unixAvailable && !$sambaAvailable && !$ppolicyAvailable && !$windowsAvailable && !$is389dsDeactivated && !$is389dsLocked) {
return '';
}
$isEditable = checkIfWriteAccessIsAllowed('user') && ($unixAvailable || $sambaAvailable || $ppolicyAvailable || $windowsAvailable || $is389dsLocked);
// get locking status
$unixLocked = false;
if ($unixAvailable && $container->getAccountModule('posixAccount')->isLocked()) {
@ -244,8 +247,8 @@ class user extends baseType {
if ($windowsAvailable && windowsUser::isDeactivated($container->getAccountModule('windowsUser')->getAttributes())) {
$windowsLocked = true;
}
$partiallyLocked = $unixLocked || $sambaLocked || $ppolicyLocked || $windowsLocked;
$fullyLocked = ($unixAvailable || $sambaAvailable || $ppolicyAvailable || $windowsAvailable)
$partiallyLocked = $unixLocked || $sambaLocked || $ppolicyLocked || $windowsLocked || $is389dsDeactivated || $is389dsLocked;
$fullyLocked = ($unixAvailable || $sambaAvailable || $ppolicyAvailable || $windowsAvailable || $is389dsDeactivated || $is389dsLocked)
&& (!$unixAvailable || $unixLocked)
&& (!$sambaAvailable || $sambaLocked)
&& (!$ppolicyAvailable || $ppolicyLocked)
@ -291,15 +294,23 @@ class user extends baseType {
}
$statusTable .= '<tr><td>' . _('Windows') . '&nbsp;&nbsp;</td><td><img height=16 width=16 src=&quot;../../graphics/' . $windowsIcon . '&quot;></td></tr>';
}
// 389ds locked
if ($is389dsLocked) {
$statusTable .= '<tr><td>' . _('Locked') . '&nbsp;&nbsp;</td><td><img height=16 width=16 src=&quot;../../graphics/lock.png&quot;></td></tr>';
}
// 389ds deactivated
if ($is389dsDeactivated) {
$statusTable .= '<tr><td>' . _('Deactivated') . '&nbsp;&nbsp;</td><td><img height=16 width=16 src=&quot;../../graphics/lock.png&quot;></td></tr>';
}
$statusTable .= '</table>';
$tipContent = $statusTable;
if (checkIfWriteAccessIsAllowed('user')) {
if ($isEditable) {
$tipContent .= '<br><img alt=&quot;hint&quot; src=&quot;../../graphics/light.png&quot;> ';
$tipContent .= _('Please click to lock/unlock this account.');
}
$dialogDiv = $this->buildAccountStatusDialogDiv($unixAvailable, $unixLocked, $sambaAvailable, $sambaLocked, $ppolicyAvailable, $ppolicyLocked, $windowsAvailable, $windowsLocked);
$dialogDiv = $this->buildAccountStatusDialogDiv($unixAvailable, $unixLocked, $sambaAvailable, $sambaLocked, $ppolicyAvailable, $ppolicyLocked, $windowsAvailable, $windowsLocked, $is389dsLocked);
$onClick = '';
if (checkIfWriteAccessIsAllowed('user')) {
if ($isEditable) {
$onClick = 'onclick="showConfirmationDialog(\'' . _('Change account status') . '\', \'' . _('Ok') . '\', \'' . _('Cancel') . '\', \'lam_accountStatusDialog\', \'inputForm\', \'lam_accountStatusResult\');"';
}
return $dialogDiv . '<a href="#"><img id="lam_accountStatus" alt="status" ' . $onClick . ' helptitle="' . _('Account status') . '" helpdata="' . $tipContent . '" height=16 width=16 src="../../graphics/' . $icon . '"></a>&nbsp;&nbsp;&nbsp;';
@ -316,10 +327,11 @@ class user extends baseType {
* @param boolean $ppolicyLocked PPolicy part is locked
* @param boolean $windowsAvailable Windows part is active
* @param boolean $windowsLocked Windows part is locked
* @param boolean $is389dsLocked account is locked
*/
private function buildAccountStatusDialogDiv($unixAvailable, $unixLocked, $sambaAvailable, $sambaLocked, $ppolicyAvailable, $ppolicyLocked, $windowsAvailable, $windowsLocked) {
$partiallyLocked = $unixLocked || $sambaLocked || $ppolicyLocked || $windowsLocked;
$fullyLocked = ($unixAvailable || $sambaAvailable || $ppolicyAvailable || $windowsAvailable)
private function buildAccountStatusDialogDiv($unixAvailable, $unixLocked, $sambaAvailable, $sambaLocked, $ppolicyAvailable, $ppolicyLocked, $windowsAvailable, $windowsLocked, $is389dsLocked) {
$partiallyLocked = $unixLocked || $sambaLocked || $ppolicyLocked || $windowsLocked || $is389dsLocked;
$fullyLocked = ($unixAvailable || $sambaAvailable || $ppolicyAvailable || $windowsAvailable || $is389dsLocked)
&& (!$unixAvailable || $unixLocked)
&& (!$sambaAvailable || $sambaLocked)
&& (!$ppolicyAvailable || $ppolicyLocked)
@ -329,7 +341,7 @@ class user extends baseType {
// show radio buttons for lock/unlock
$radioDisabled = true;
$selectedRadio = 'lock';
$selectedRadio = 'unlock';
$onchange = '';
if ($partiallyLocked && !$fullyLocked) {
$radioDisabled = false;
@ -342,8 +354,8 @@ class user extends baseType {
'jQuery(\'#lam_accountStatusDialogUnlockDiv\').removeClass(\'hidden\');' .
'};';
}
if ($fullyLocked) {
$selectedRadio = 'unlock';
if (!$fullyLocked && !$partiallyLocked) {
$selectedRadio = 'lock';
}
if (!$radioDisabled) {
$radio = new htmlRadio('lam_accountStatusAction', array(_('Lock') => 'lock', _('Unlock') => 'unlock'), $selectedRadio);
@ -389,6 +401,9 @@ class user extends baseType {
}
$lockDiv = new htmlDiv('lam_accountStatusDialogLockDiv', $lockContent);
if ($fullyLocked || $partiallyLocked) {
$lockDiv->setCSSClasses(array('hidden'));
}
$container->addElement($lockDiv, true);
}
// unlocking part
@ -411,9 +426,13 @@ class user extends baseType {
$unlockContent->addElement(new htmlImage('../../graphics/samba.png'));
$unlockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusUnlockWindows', true, _('Windows'), null, false), true);
}
if ($is389dsLocked) {
$unlockContent->addElement(new htmlImage('../../graphics/security.png'));
$unlockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusUnlock389ds', true, _('Unlock'), null, false), true);
}
$unlockDiv = new htmlDiv('lam_accountStatusDialogUnlockDiv', $unlockContent);
if (!$fullyLocked) {
if (!$fullyLocked && !$partiallyLocked) {
$unlockDiv->setCSSClasses(array('hidden'));
}
$container->addElement($unlockDiv, true);
@ -485,6 +504,10 @@ class user extends baseType {
if (isset($_POST['lam_accountStatusUnlockWindows']) && ($_POST['lam_accountStatusUnlockWindows'] == 'on')) {
$container->getAccountModule('windowsUser')->setIsDeactivated(false);
}
// 389ds unlocking
if (isset($_POST['lam_accountStatusUnlock389ds']) && ($_POST['lam_accountStatusUnlock389ds'] == 'on')) {
$container->getAccountModule('locking389ds')->unlock(false);
}
}
}
}
@ -829,10 +852,14 @@ class lamUserList extends lamList {
$sambaLocked = self::isSambaLocked($this->entries[$i]);
$ppolicyLocked = self::isPPolicyLocked($this->entries[$i]);
$windowsLocked = self::isWindowsLocked($this->entries[$i]);
$is389dsLocked = self::is389dsLocked($this->entries[$i]);
$is389dsDeactivated = self::is389dsDeactivated($this->entries[$i]);
$hasLocked = ($unixAvailable && $unixLocked)
|| ($sambaAvailable && $sambaLocked)
|| ($ppolicyAvailable && $ppolicyLocked)
|| ($windowsAvailable && $windowsLocked);
|| ($windowsAvailable && $windowsLocked)
|| $is389dsDeactivated
|| $is389dsLocked;
$hasUnlocked = ($unixAvailable && !$unixLocked)
|| ($sambaAvailable && !$sambaLocked)
|| ($ppolicyAvailable && !$ppolicyLocked)