support for 389ds locking and deactivation
This commit is contained in:
		
							parent
							
								
									616b11e362
								
							
						
					
					
						commit
						cf5132745d
					
				|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | 
|  | @ -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. | ||||
| 	 * | ||||
|  |  | |||
|  | @ -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()))); | ||||
|  |  | |||
|  | @ -34,3 +34,4 @@ | |||
| /zarafaGroup.inc | ||||
| /zarafaServer.inc | ||||
| /zarafaUser.inc | ||||
| /locking389ds.inc | ||||
|  |  | |||
|  | @ -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() { | ||||
|  |  | |||
|  | @ -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. | ||||
| 	* | ||||
|  |  | |||
|  | @ -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') . '  </td><td><img height=16 width=16 src="../../graphics/' . $windowsIcon . '"></td></tr>'; | ||||
| 		} | ||||
| 		// 389ds locked
 | ||||
| 		if ($is389dsLocked) { | ||||
| 			$statusTable .= '<tr><td>' . _('Locked') . '  </td><td><img height=16 width=16 src="../../graphics/lock.png"></td></tr>'; | ||||
| 		} | ||||
| 		// 389ds deactivated
 | ||||
| 		if ($is389dsDeactivated) { | ||||
| 			$statusTable .= '<tr><td>' . _('Deactivated') . '  </td><td><img height=16 width=16 src="../../graphics/lock.png"></td></tr>'; | ||||
| 		} | ||||
| 		$statusTable .= '</table>'; | ||||
| 		$tipContent = $statusTable; | ||||
| 		if (checkIfWriteAccessIsAllowed('user')) { | ||||
| 		if ($isEditable) { | ||||
| 			$tipContent .= '<br><img alt="hint" src="../../graphics/light.png"> '; | ||||
| 			$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>   '; | ||||
|  | @ -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) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue