Merge branch 'develop' into configImportExport
This commit is contained in:
		
						commit
						9ec8d2ce57
					
				| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
September 2020
 | 
			
		||||
  - PHP 7.4 compatibility
 | 
			
		||||
  - Windows users: group display format can be configured (cn/dn)
 | 
			
		||||
 | 
			
		||||
01.05.2020 7.2
 | 
			
		||||
  - Unix: allow to create group with same name during user creation
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1487,8 +1487,9 @@ function getDefaultLDAPErrorString($server) {
 | 
			
		|||
		logNewMessage(LOG_DEBUG, 'Password change failed because of ' . $extError);
 | 
			
		||||
		$extError = _('Your password does not meet the password strength qualifications. Please retry with another one.');
 | 
			
		||||
	}
 | 
			
		||||
	$message = _('LDAP error, server says:') . ' ' . ldap_error($server);
 | 
			
		||||
	if (!empty($extError)) {
 | 
			
		||||
	$genericErrorMessage = ldap_error($server);
 | 
			
		||||
	$message = _('LDAP error, server says:') . ' ' . $genericErrorMessage;
 | 
			
		||||
	if (!empty($extError) && ($genericErrorMessage != $extError)) {
 | 
			
		||||
		$message .= ' - ' . $extError;
 | 
			
		||||
	}
 | 
			
		||||
	return $message;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,19 +67,19 @@ class Ldap{
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	* Connects to the server using the given username and password
 | 
			
		||||
	*
 | 
			
		||||
	* @param string $user user name
 | 
			
		||||
	* @param string $passwd password
 | 
			
		||||
	* @param boolean $allowAnonymous specifies if anonymous binds are allowed
 | 
			
		||||
	* @return mixed if connect succeeds the 0 is returned, else false or error number
 | 
			
		||||
	*/
 | 
			
		||||
	 * Connects to the server using the given username and password
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $user user name
 | 
			
		||||
	 * @param string $passwd password
 | 
			
		||||
	 * @param boolean $allowAnonymous specifies if anonymous binds are allowed
 | 
			
		||||
	 * @throws LAMException unable to connect
 | 
			
		||||
	 */
 | 
			
		||||
	public function connect($user, $passwd, $allowAnonymous=false) {
 | 
			
		||||
		// close any prior connection
 | 
			
		||||
		@$this->close();
 | 
			
		||||
		// do not allow anonymous bind
 | 
			
		||||
		if (!$allowAnonymous && ((!$user)||($user == "")||(!$passwd))) {
 | 
			
		||||
			return false;
 | 
			
		||||
			throw new LAMException(_("Cannot connect to specified LDAP server. Please try again."));
 | 
			
		||||
		}
 | 
			
		||||
		// save password und username encrypted
 | 
			
		||||
		$this->encrypt_login($user, $passwd);
 | 
			
		||||
| 
						 | 
				
			
			@ -94,17 +94,29 @@ class Ldap{
 | 
			
		|||
			if ($bind) {
 | 
			
		||||
				$return = ldap_errno($this->server);
 | 
			
		||||
				$this->is_connected = true;
 | 
			
		||||
				// return success number
 | 
			
		||||
				return $return;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			// return error number
 | 
			
		||||
			$errorNumber = ldap_errno($this->server);
 | 
			
		||||
			$clientSource = empty($_SERVER['REMOTE_ADDR']) ? '' : $_SERVER['REMOTE_ADDR'];
 | 
			
		||||
			if (($errorNumber === False)
 | 
			
		||||
				|| ($errorNumber == 81)) {
 | 
			
		||||
				// connection failed
 | 
			
		||||
				logNewMessage(LOG_ERR, 'User ' . $user . ' (' . $clientSource . ') failed to log in (LDAP error: ' . getDefaultLDAPErrorString($this->server) . ').');
 | 
			
		||||
				throw new LAMException(_("Cannot connect to specified LDAP server. Please try again."));
 | 
			
		||||
			}
 | 
			
		||||
			elseif ($errorNumber == 49) {
 | 
			
		||||
				// user name/password invalid. Return to login page.
 | 
			
		||||
				logNewMessage(LOG_ERR, 'User ' . $user . ' (' . $clientSource . ') failed to log in (wrong password). ' . getDefaultLDAPErrorString($this->server));
 | 
			
		||||
				throw new LAMException(_("Wrong password/user name combination. Please try again."), getDefaultLDAPErrorString($this->server));
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				return ldap_errno($this->server);
 | 
			
		||||
				// other errors
 | 
			
		||||
				logNewMessage(LOG_ERR, 'User ' . $user . ' (' . $clientSource . ') failed to log in (LDAP error: ' . getDefaultLDAPErrorString($this->server) . ').');
 | 
			
		||||
				throw new LAMException(_("LDAP error, server says:"),  "($errorNumber) " . getDefaultLDAPErrorString($this->server));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		throw new LAMException(_("Cannot connect to specified LDAP server. Please try again."));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Closes connection to server */
 | 
			
		||||
| 
						 | 
				
			
			@ -121,8 +133,13 @@ class Ldap{
 | 
			
		|||
	*/
 | 
			
		||||
	public function server() {
 | 
			
		||||
		if (!$this->is_connected) {
 | 
			
		||||
			$this->connect($this->getUserName(), $this->getPassword());
 | 
			
		||||
			$this->is_connected = true;
 | 
			
		||||
			try {
 | 
			
		||||
				$this->connect($this->getUserName(), $this->getPassword());
 | 
			
		||||
				$this->is_connected = true;
 | 
			
		||||
			}
 | 
			
		||||
			catch (LAMException $e) {
 | 
			
		||||
				logNewMessage(LOG_ERR, $e->getTitle() . ' ' . $e->getMessage());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return $this->server;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -631,7 +631,7 @@ class posixAccount extends baseModule implements passwordService {
 | 
			
		|||
			// Remove primary group from additional groups
 | 
			
		||||
			if (!isset($this->moduleSettings['posixAccount_primaryGroupAsSecondary'][0])
 | 
			
		||||
				|| ($this->moduleSettings['posixAccount_primaryGroupAsSecondary'][0] != 'true')) {
 | 
			
		||||
				for ($i=0; $i<count($this->groups); $i++) {
 | 
			
		||||
				for ($i = 0; $i < count($this->groups); $i++) {
 | 
			
		||||
					if ($this->groups[$i] == $this->getGroupName($this->attributes['gidNumber'][0])) {
 | 
			
		||||
						unset($this->groups[$i]);
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			@ -639,8 +639,21 @@ class posixAccount extends baseModule implements passwordService {
 | 
			
		|||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				// add user as memberuid in primary group
 | 
			
		||||
				if (!in_array($this->getGroupName($this->attributes['gidNumber'][0]), $this->groups)) {
 | 
			
		||||
					$this->groups[] = $this->getGroupName($this->attributes['gidNumber'][0]);
 | 
			
		||||
				$primaryGroupName = $this->getGroupName($this->attributes['gidNumber'][0]);
 | 
			
		||||
				if (!in_array($primaryGroupName, $this->groups)) {
 | 
			
		||||
					$this->groups[] = $primaryGroupName;
 | 
			
		||||
				}
 | 
			
		||||
				// add user as member in group of names if auto-sync is activated
 | 
			
		||||
				if ($this->isBooleanConfigOptionSet('posixGroup_autoSyncGon')) {
 | 
			
		||||
					$allGons = $this->findGroupOfNames();
 | 
			
		||||
					foreach ($allGons as $gonDn => $gonData) {
 | 
			
		||||
						if (in_array_ignore_case('posixGroup', $gonData['objectclass'])) {
 | 
			
		||||
							$gonCn =  $gonData['cn'][0];
 | 
			
		||||
							if (($gonCn === $primaryGroupName) && !in_array($gonDn, $this->gonList)) {
 | 
			
		||||
								$this->gonList[] = $gonDn;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1034,6 +1047,21 @@ class posixAccount extends baseModule implements passwordService {
 | 
			
		|||
				if (!empty($oldGroupName) && !empty($newGroupName)) {
 | 
			
		||||
					$this->groups = array_delete(array($oldGroupName), $this->groups);
 | 
			
		||||
					$this->groups[] = $newGroupName;
 | 
			
		||||
					// sync group of names if needed
 | 
			
		||||
					if ($this->isBooleanConfigOptionSet('posixGroup_autoSyncGon')) {
 | 
			
		||||
						$allGons = $this->findGroupOfNames();
 | 
			
		||||
						foreach ($allGons as $gonDn => $gonData) {
 | 
			
		||||
							if (in_array_ignore_case('posixGroup', $gonData['objectclass'])) {
 | 
			
		||||
								$gonCn =  $gonData['cn'][0];
 | 
			
		||||
								if (($gonCn === $newGroupName) && !in_array($gonDn, $this->gonList)) {
 | 
			
		||||
									$this->gonList[] = $gonDn;
 | 
			
		||||
								}
 | 
			
		||||
								if (($gonCn === $oldGroupName) && in_array($gonDn, $this->gonList)) {
 | 
			
		||||
									$this->gonList = array_delete(array($gonDn), $this->gonList);
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1006,12 +1006,12 @@ class posixGroup extends baseModule implements passwordService {
 | 
			
		|||
		}
 | 
			
		||||
		$added = array_delete($oldValues, $this->attributes['memberUid']);
 | 
			
		||||
		if (!empty($added)) {
 | 
			
		||||
			$return[] = array('INFO', _('Added users'), htmlspecialchars(implode($added, ', ')));
 | 
			
		||||
			$return[] = array('INFO', _('Added users'), htmlspecialchars(implode(', ', $added)));
 | 
			
		||||
		}
 | 
			
		||||
		if ($delete) {
 | 
			
		||||
			$deleted = array_delete($this->attributes['memberUid'], $oldValues);
 | 
			
		||||
			if (!empty($deleted)) {
 | 
			
		||||
				$return[] = array('INFO', _('Removed users'), htmlspecialchars(implode($deleted, ', ')));
 | 
			
		||||
				$return[] = array('INFO', _('Removed users'), htmlspecialchars(implode(', ', $deleted)));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return $return;
 | 
			
		||||
| 
						 | 
				
			
			@ -1049,12 +1049,12 @@ class posixGroup extends baseModule implements passwordService {
 | 
			
		|||
		}
 | 
			
		||||
		$added = array_delete($oldValues, $this->attributes['memberUid']);
 | 
			
		||||
		if (!empty($added)) {
 | 
			
		||||
			$return[] = array('INFO', _('Added users'), htmlspecialchars(implode($added, ', ')));
 | 
			
		||||
			$return[] = array('INFO', _('Added users'), htmlspecialchars(implode(', ', $added)));
 | 
			
		||||
		}
 | 
			
		||||
		if ($delete) {
 | 
			
		||||
			$deleted = array_delete($this->attributes['memberUid'], $oldValues);
 | 
			
		||||
			if (!empty($deleted)) {
 | 
			
		||||
				$return[] = array('INFO', _('Removed users'), htmlspecialchars(implode($deleted, ', ')));
 | 
			
		||||
				$return[] = array('INFO', _('Removed users'), htmlspecialchars(implode(', ', $deleted)));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return $return;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -267,13 +267,13 @@ class quota extends baseModule {
 | 
			
		|||
			return $value;
 | 
			
		||||
		}
 | 
			
		||||
		if ($value >= $tebibytes) {
 | 
			
		||||
			return round($value / $tebibytes, 3) . 'T';
 | 
			
		||||
			return round($value / $tebibytes, 2) . 'T';
 | 
			
		||||
		}
 | 
			
		||||
		if ($value >= $gibibytes) {
 | 
			
		||||
			return round($value / $gibibytes, 3) . 'G';
 | 
			
		||||
			return round($value / $gibibytes, 2) . 'G';
 | 
			
		||||
		}
 | 
			
		||||
		if ($value >= $mebibytes) {
 | 
			
		||||
			return round($value / $mebibytes, 3) . 'M';
 | 
			
		||||
			return round($value / $mebibytes, 2) . 'M';
 | 
			
		||||
		}
 | 
			
		||||
		return $value;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -322,16 +322,16 @@ class quota extends baseModule {
 | 
			
		|||
			return $value;
 | 
			
		||||
		}
 | 
			
		||||
		if ($value >= $trillion) {
 | 
			
		||||
			return round($value / $trillion, 3) . 't';
 | 
			
		||||
			return round($value / $trillion, 2) . 't';
 | 
			
		||||
		}
 | 
			
		||||
		if ($value >= $billion) {
 | 
			
		||||
			return round($value / $billion, 3) . 'g';
 | 
			
		||||
			return round($value / $billion, 2) . 'g';
 | 
			
		||||
		}
 | 
			
		||||
		if ($value >= $million) {
 | 
			
		||||
			return round($value / $million, 3) . 'm';
 | 
			
		||||
			return round($value / $million, 2) . 'm';
 | 
			
		||||
		}
 | 
			
		||||
		if ($value >= $kilo) {
 | 
			
		||||
			return round($value / $kilo, 3) . 'k';
 | 
			
		||||
			return round($value / $kilo, 2) . 'k';
 | 
			
		||||
		}
 | 
			
		||||
		return $value;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,6 +45,11 @@ class windowsUser extends baseModule implements passwordService {
 | 
			
		|||
	/** account is disabled */
 | 
			
		||||
	const AC_ACCOUNT_DISABLED = 0x00000002;
 | 
			
		||||
 | 
			
		||||
	/** display groups as dn */
 | 
			
		||||
	const DISPLAY_GROUPS_DN = 'DN';
 | 
			
		||||
	/** display groups as cn */
 | 
			
		||||
	const DISPLAY_GROUPS_CN = 'CN';
 | 
			
		||||
 | 
			
		||||
	/** current group list */
 | 
			
		||||
	private $groupList = array();
 | 
			
		||||
	/** original group list */
 | 
			
		||||
| 
						 | 
				
			
			@ -412,6 +417,10 @@ class windowsUser extends baseModule implements passwordService {
 | 
			
		|||
				"Headline" => _("Workstations"), 'attr' => 'userWorkstations',
 | 
			
		||||
				"Text" => _("Comma separated list of workstations the user is allowed to login. Empty means every workstation."). ' '. _("Can be left empty.")
 | 
			
		||||
			),
 | 
			
		||||
			'displayGroups' => array(
 | 
			
		||||
				"Headline" => _('Display format'),
 | 
			
		||||
				"Text" => _('Specifies how groups are displayed.')
 | 
			
		||||
			),
 | 
			
		||||
		);
 | 
			
		||||
		// upload fields
 | 
			
		||||
		$return['upload_columns'] = array(
 | 
			
		||||
| 
						 | 
				
			
			@ -1359,24 +1368,62 @@ class windowsUser extends baseModule implements passwordService {
 | 
			
		|||
		$containerRight->add(new htmlAccountPageButton(get_class($this), 'group', 'edit', _('Edit groups')), 12);
 | 
			
		||||
		$containerRight->addVerticalSpacer('1rem');
 | 
			
		||||
		$groupsList = new htmlGroup();
 | 
			
		||||
		$groupCNs = array();
 | 
			
		||||
		for ($i = 0; $i < sizeof($this->groupList); $i++) {
 | 
			
		||||
			$groupCNs[] = extractRDNValue($this->groupList[$i]);
 | 
			
		||||
		$groupNames = array();
 | 
			
		||||
		if ($this->groupDisplayContainsDn()) {
 | 
			
		||||
			usort($this->groupList, 'compareDN');
 | 
			
		||||
		}
 | 
			
		||||
		natcasesort($groupCNs);
 | 
			
		||||
		foreach ($groupCNs as $cn) {
 | 
			
		||||
		foreach ($this->groupList as $groupDn) {
 | 
			
		||||
			$groupCn = extractRDNValue($groupDn);
 | 
			
		||||
			$groupNames[] = $this->formatGroupName($groupCn, $groupDn);
 | 
			
		||||
		}
 | 
			
		||||
		if (!$this->groupDisplayContainsDn()) {
 | 
			
		||||
			natcasesort($groupNames);
 | 
			
		||||
		}
 | 
			
		||||
		foreach ($groupNames as $cn) {
 | 
			
		||||
			$groupsList->addElement(new htmlOutputText($cn));
 | 
			
		||||
			$groupsList->addElement(new htmlOutputText('<br>', false));
 | 
			
		||||
		}
 | 
			
		||||
		$containerRight->add($groupsList, 12);
 | 
			
		||||
		$groupsListClass = $this->groupDisplayContainsDn() ? 'rightToLeftText' : '';
 | 
			
		||||
		$groupsListDiv = new htmlDiv(null, $groupsList, array($groupsListClass));
 | 
			
		||||
		$containerRight->add($groupsListDiv, 12);
 | 
			
		||||
 | 
			
		||||
		$container = new htmlResponsiveRow();
 | 
			
		||||
		$container->add($containerLeft, 12, 7);
 | 
			
		||||
		$container->add(new htmlSpacer('1rem', null), 0, 1);
 | 
			
		||||
		$container->add($containerRight, 12, 4);
 | 
			
		||||
		$container->add($containerLeft, 12, 12, 7);
 | 
			
		||||
		$container->add(new htmlSpacer('1rem', null), 0, 0, 1);
 | 
			
		||||
		$container->add($containerRight, 12, 12, 4);
 | 
			
		||||
		return $container;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Formats a group name for the display.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $cn common name
 | 
			
		||||
	 * @param string $dn DN
 | 
			
		||||
	 * @return string formatted name
 | 
			
		||||
	 */
 | 
			
		||||
	private function formatGroupName($cn, $dn) {
 | 
			
		||||
		$mode = empty($this->moduleSettings['windowsUser_displayGroups'][0]) ? 'dn' : $this->moduleSettings['windowsUser_displayGroups'][0];
 | 
			
		||||
		switch ($mode) {
 | 
			
		||||
			case self::DISPLAY_GROUPS_CN:
 | 
			
		||||
				return $cn;
 | 
			
		||||
				break;
 | 
			
		||||
			case self::DISPLAY_GROUPS_DN:
 | 
			
		||||
			default:
 | 
			
		||||
				return getAbstractDN($dn);
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns if the group display name contains the DN.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return bool contains DN.
 | 
			
		||||
	 */
 | 
			
		||||
	private function groupDisplayContainsDn() {
 | 
			
		||||
		$mode = empty($this->moduleSettings['windowsUser_displayGroups'][0]) ? 'dn' : $this->moduleSettings['windowsUser_displayGroups'][0];
 | 
			
		||||
		return ($mode == self::DISPLAY_GROUPS_DN);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns if any of the work details attributes should be managed.
 | 
			
		||||
	 *
 | 
			
		||||
| 
						 | 
				
			
			@ -1820,26 +1867,45 @@ class windowsUser extends baseModule implements passwordService {
 | 
			
		|||
		$return->setCSSClasses(array('maxrow'));
 | 
			
		||||
		$return->add(new htmlSubTitle(_("Groups")), 12);
 | 
			
		||||
		$groups = $this->findGroups();
 | 
			
		||||
		$groupDisplayContainsDn = $this->groupDisplayContainsDn();
 | 
			
		||||
		// sort by DN
 | 
			
		||||
		usort($groups, 'compareDN');
 | 
			
		||||
		if ($groupDisplayContainsDn) {
 | 
			
		||||
			usort($groups, 'compareDN');
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$selectedGroups = array();
 | 
			
		||||
		// sort by DN
 | 
			
		||||
		usort($this->groupList, 'compareDN');
 | 
			
		||||
		if ($groupDisplayContainsDn) {
 | 
			
		||||
			usort($this->groupList, 'compareDN');
 | 
			
		||||
		}
 | 
			
		||||
		for ($i = 0; $i < sizeof($this->groupList); $i++) {
 | 
			
		||||
			if (in_array($this->groupList[$i], $groups)) {
 | 
			
		||||
				$selectedGroups[getAbstractDN($this->groupList[$i])] = $this->groupList[$i];
 | 
			
		||||
				$groupDn = $this->groupList[$i];
 | 
			
		||||
				$groupCn = extractRDNValue($groupDn);
 | 
			
		||||
				$displayName = $this->formatGroupName($groupCn, $groupDn);
 | 
			
		||||
				$selectedGroups[$displayName] = $groupDn;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		$availableGroups = array();
 | 
			
		||||
		foreach ($groups as $dn) {
 | 
			
		||||
			if (!in_array($dn, $this->groupList)) {
 | 
			
		||||
				$availableGroups[getAbstractDN($dn)] = $dn;
 | 
			
		||||
				$groupCn = extractRDNValue($dn);
 | 
			
		||||
				$displayName = $this->formatGroupName($groupCn, $dn);
 | 
			
		||||
				$availableGroups[$displayName] = $dn;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!$groupDisplayContainsDn) {
 | 
			
		||||
			$selectedGroups = array_flip($selectedGroups);
 | 
			
		||||
			natcasesort($selectedGroups);
 | 
			
		||||
			$selectedGroups = array_flip($selectedGroups);
 | 
			
		||||
			$availableGroups = array_flip($availableGroups);
 | 
			
		||||
			natcasesort($availableGroups);
 | 
			
		||||
			$availableGroups = array_flip($availableGroups);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$this->addDoubleSelectionArea($return, _("Selected groups"), _("Available groups"),
 | 
			
		||||
				$selectedGroups, null, $availableGroups, null, 'groups', true, true);
 | 
			
		||||
				$selectedGroups, null, $availableGroups, null, 'groups', $groupDisplayContainsDn, true);
 | 
			
		||||
 | 
			
		||||
		// sync options
 | 
			
		||||
		$typeManager = new TypeManager();
 | 
			
		||||
| 
						 | 
				
			
			@ -3689,6 +3755,13 @@ class windowsUser extends baseModule implements passwordService {
 | 
			
		|||
		// configuration options
 | 
			
		||||
		$configContainer = new htmlResponsiveRow();
 | 
			
		||||
		$configContainer->add(new htmlResponsiveInputTextarea('windowsUser_domains', '', 30, 3, _('Domains'), 'domains'), 12);
 | 
			
		||||
		$displayOptions = array(
 | 
			
		||||
			'dn' => self::DISPLAY_GROUPS_DN,
 | 
			
		||||
			'cn' => self::DISPLAY_GROUPS_CN,
 | 
			
		||||
		);
 | 
			
		||||
		$groupDisplaySelect = new htmlResponsiveSelect('windowsUser_displayGroups', $displayOptions, array(), _('Display format'), 'displayGroups');
 | 
			
		||||
		$groupDisplaySelect->setHasDescriptiveElements(true);
 | 
			
		||||
		$configContainer->add($groupDisplaySelect, 12);
 | 
			
		||||
		$configHiddenGroup = new htmlGroup();
 | 
			
		||||
		$configHiddenGroup->addElement(new htmlOutputText(_('Hidden options')));
 | 
			
		||||
		$configHiddenGroup->addElement(new htmlHelpLink('hiddenOptions'));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -114,7 +114,7 @@ function readAccountProfileFile($fileName) {
 | 
			
		|||
		if ($file) {
 | 
			
		||||
			while (!feof($file)) {
 | 
			
		||||
				$line = fgets($file, 1024);
 | 
			
		||||
				if (($line == '') || ($line == "\n") || ($line[0] == "#")) {
 | 
			
		||||
				if (($line === false) || ($line == '') || ($line == "\n") || ($line[0] == "#")) {
 | 
			
		||||
					continue; // ignore comments
 | 
			
		||||
				}
 | 
			
		||||
				// search keywords
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@ use \htmlGroup;
 | 
			
		|||
use \htmlInputCheckbox;
 | 
			
		||||
use \htmlButton;
 | 
			
		||||
use \htmlStatusMessage;
 | 
			
		||||
use LAMException;
 | 
			
		||||
use \Ldap;
 | 
			
		||||
use \htmlResponsiveRow;
 | 
			
		||||
use \htmlDiv;
 | 
			
		||||
| 
						 | 
				
			
			@ -170,12 +171,13 @@ $manifestUrl = preg_replace('/\\?.*/', '', $manifestUrl);
 | 
			
		|||
$_SESSION['header'] .= '<link rel="manifest" href="' . $manifestUrl . '/templates/manifest.php" crossorigin="use-credentials">';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* Displays the login window.
 | 
			
		||||
*
 | 
			
		||||
* @param \LAM\ENV\LAMLicenseValidator $licenseValidator license validator
 | 
			
		||||
* @param string $error_message error message to display
 | 
			
		||||
*/
 | 
			
		||||
function display_LoginPage($licenseValidator, $error_message) {
 | 
			
		||||
 * Displays the login window.
 | 
			
		||||
 *
 | 
			
		||||
 * @param \LAM\ENV\LAMLicenseValidator $licenseValidator license validator
 | 
			
		||||
 * @param string $error_message error message to display
 | 
			
		||||
 * @param string $errorDetails error details
 | 
			
		||||
 */
 | 
			
		||||
function display_LoginPage($licenseValidator, $error_message, $errorDetails = null) {
 | 
			
		||||
	$config_object = $_SESSION['config'];
 | 
			
		||||
	$cfgMain = $_SESSION["cfgMain"];
 | 
			
		||||
	logNewMessage(LOG_DEBUG, "Display login page");
 | 
			
		||||
| 
						 | 
				
			
			@ -405,7 +407,7 @@ function display_LoginPage($licenseValidator, $error_message) {
 | 
			
		|||
							// error message
 | 
			
		||||
							if(!empty($error_message)) {
 | 
			
		||||
								$row->add(new \htmlSpacer(null, '5px'), 12);
 | 
			
		||||
								$message = new htmlStatusMessage('ERROR', $error_message);
 | 
			
		||||
								$message = new htmlStatusMessage('ERROR', $error_message, $errorDetails);
 | 
			
		||||
								$message->colspan = 3;
 | 
			
		||||
								$row->add($message, 12);
 | 
			
		||||
							}
 | 
			
		||||
| 
						 | 
				
			
			@ -506,7 +508,7 @@ if(isset($_POST['checklogin'])) {
 | 
			
		|||
	// search user in LDAP if needed
 | 
			
		||||
	if ($_SESSION['config']->getLoginMethod() == LAMConfig::LOGIN_SEARCH) {
 | 
			
		||||
		$searchFilter = $_SESSION['config']->getLoginSearchFilter();
 | 
			
		||||
		$searchFilter = str_replace('%USER%', $username ,$searchFilter);
 | 
			
		||||
		$searchFilter = str_replace('%USER%', $username, $searchFilter);
 | 
			
		||||
		$searchDN = '';
 | 
			
		||||
		$searchPassword = '';
 | 
			
		||||
		$configLoginSearchDn = $_SESSION['config']->getLoginSearchDN();
 | 
			
		||||
| 
						 | 
				
			
			@ -517,57 +519,58 @@ if(isset($_POST['checklogin'])) {
 | 
			
		|||
		$searchSuccess = true;
 | 
			
		||||
		$searchError = '';
 | 
			
		||||
		$searchLDAP = new Ldap($_SESSION['config']);
 | 
			
		||||
		$searchLDAPResult = $searchLDAP->connect($searchDN, $searchPassword, true);
 | 
			
		||||
		if (! ($searchLDAPResult == 0)) {
 | 
			
		||||
			$searchSuccess = false;
 | 
			
		||||
			$searchError = _('Cannot connect to specified LDAP server. Please try again.') . ' ' . getDefaultLDAPErrorString($searchLDAP->server());
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			$searchResult = ldap_search($searchLDAP->server(), $_SESSION['config']->getLoginSearchSuffix(), $searchFilter, array('dn'), 0, 0, 0, LDAP_DEREF_NEVER);
 | 
			
		||||
			if ($searchResult) {
 | 
			
		||||
				$searchInfo = ldap_get_entries($searchLDAP->server(), $searchResult);
 | 
			
		||||
				if ($searchInfo) {
 | 
			
		||||
					cleanLDAPResult($searchInfo);
 | 
			
		||||
					if (sizeof($searchInfo) == 0) {
 | 
			
		||||
						$searchSuccess = false;
 | 
			
		||||
						$searchError = _('Wrong password/user name combination. Please try again.');
 | 
			
		||||
					}
 | 
			
		||||
					elseif (sizeof($searchInfo) > 1) {
 | 
			
		||||
						$searchSuccess = false;
 | 
			
		||||
						$searchError = _('The given user name matches multiple LDAP entries.');
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						$username = $searchInfo[0]['dn'];
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					$searchSuccess = false;
 | 
			
		||||
					$searchError = _('Unable to find the user name in LDAP.');
 | 
			
		||||
					if (ldap_errno($searchLDAP->server()) != 0) {
 | 
			
		||||
						$searchError .= ' ' . getDefaultLDAPErrorString($searchLDAP->server());
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
		try {
 | 
			
		||||
			$searchLDAP->connect($searchDN, $searchPassword, true);
 | 
			
		||||
            $searchResult = ldap_search($searchLDAP->server(), $_SESSION['config']->getLoginSearchSuffix(), $searchFilter, array('dn'), 0, 0, 0, LDAP_DEREF_NEVER);
 | 
			
		||||
            if ($searchResult) {
 | 
			
		||||
                $searchInfo = ldap_get_entries($searchLDAP->server(), $searchResult);
 | 
			
		||||
                if ($searchInfo) {
 | 
			
		||||
                    cleanLDAPResult($searchInfo);
 | 
			
		||||
                    if (sizeof($searchInfo) == 0) {
 | 
			
		||||
                        $searchSuccess = false;
 | 
			
		||||
                        $searchError = _('Wrong password/user name combination. Please try again.');
 | 
			
		||||
                    }
 | 
			
		||||
                    elseif (sizeof($searchInfo) > 1) {
 | 
			
		||||
                        $searchSuccess = false;
 | 
			
		||||
                        $searchError = _('The given user name matches multiple LDAP entries.');
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        $username = $searchInfo[0]['dn'];
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    $searchSuccess = false;
 | 
			
		||||
                    $searchError = _('Unable to find the user name in LDAP.');
 | 
			
		||||
                    if (ldap_errno($searchLDAP->server()) != 0) {
 | 
			
		||||
                        $searchError .= ' ' . getDefaultLDAPErrorString($searchLDAP->server());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                $searchSuccess = false;
 | 
			
		||||
                $searchError = _('Unable to find the user name in LDAP.');
 | 
			
		||||
                if (ldap_errno($searchLDAP->server()) != 0) {
 | 
			
		||||
                    $searchError .= ' ' . getDefaultLDAPErrorString($searchLDAP->server());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
			if (!$searchSuccess) {
 | 
			
		||||
				$error_message = $searchError;
 | 
			
		||||
				logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in. ' . $searchError . '');
 | 
			
		||||
				$searchLDAP->close();
 | 
			
		||||
				display_LoginPage($licenseValidator, $error_message);
 | 
			
		||||
				exit();
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				$searchSuccess = false;
 | 
			
		||||
				$searchError = _('Unable to find the user name in LDAP.');
 | 
			
		||||
				if (ldap_errno($searchLDAP->server()) != 0) {
 | 
			
		||||
					$searchError .= ' ' . getDefaultLDAPErrorString($searchLDAP->server());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (!$searchSuccess) {
 | 
			
		||||
			$error_message = $searchError;
 | 
			
		||||
			logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in. ' . $searchError . '');
 | 
			
		||||
			$searchLDAP->close();
 | 
			
		||||
			display_LoginPage($licenseValidator, $error_message);
 | 
			
		||||
			exit();
 | 
			
		||||
		}
 | 
			
		||||
		$searchLDAP->close();
 | 
			
		||||
        catch (LAMException $e) {
 | 
			
		||||
	        $searchLDAP->close();
 | 
			
		||||
	        display_LoginPage($licenseValidator, $e->getTitle(), $e->getMessage());
 | 
			
		||||
	        exit();
 | 
			
		||||
        }
 | 
			
		||||
	}
 | 
			
		||||
	// try to connect to LDAP
 | 
			
		||||
	$result = $_SESSION['ldap']->connect($username, $password); // Connect to LDAP server for verifying username/password
 | 
			
		||||
	if($result === 0) {// Username/password correct. Do some configuration and load main frame.
 | 
			
		||||
    try {
 | 
			
		||||
	    $_SESSION['ldap']->connect($username, $password); // Connect to LDAP server for verifying username/password
 | 
			
		||||
		$_SESSION['loggedIn'] = true;
 | 
			
		||||
		// set security settings for session
 | 
			
		||||
		$_SESSION['sec_session_id'] = session_id();
 | 
			
		||||
| 
						 | 
				
			
			@ -586,26 +589,10 @@ if(isset($_POST['checklogin'])) {
 | 
			
		|||
		}
 | 
			
		||||
		die();
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		if (($result === False)
 | 
			
		||||
				|| ($result == 81)) {
 | 
			
		||||
			// connection failed
 | 
			
		||||
			$error_message = _("Cannot connect to specified LDAP server. Please try again.");
 | 
			
		||||
			logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in (LDAP error: ' . ldap_err2str($result) . ').');
 | 
			
		||||
		}
 | 
			
		||||
		elseif ($result == 49) {
 | 
			
		||||
			// user name/password invalid. Return to login page.
 | 
			
		||||
			$error_message = _("Wrong password/user name combination. Please try again.");
 | 
			
		||||
			logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in (wrong password).');
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			// other errors
 | 
			
		||||
			$error_message = _("LDAP error, server says:") .  "\n<br>($result) " . ldap_err2str($result);
 | 
			
		||||
			logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in (LDAP error: ' . ldap_err2str($result) . ').');
 | 
			
		||||
		}
 | 
			
		||||
		display_LoginPage($licenseValidator, $error_message);
 | 
			
		||||
	catch (LAMException $e) {
 | 
			
		||||
		display_LoginPage($licenseValidator, $e->getTitle(), $e->getMessage());
 | 
			
		||||
		exit();
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//displays the login window
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,10 +56,10 @@ class QuotaTest extends TestCase {
 | 
			
		|||
		$this->assertEquals('123G', $quota->formatBlockUsage(1024*1024*123));
 | 
			
		||||
		$this->assertEquals('123M', $quota->formatBlockUsage(1024*123));
 | 
			
		||||
		$this->assertEquals('123', $quota->formatBlockUsage(123));
 | 
			
		||||
		$this->assertEquals('1.001M', $quota->formatBlockUsage(1025));
 | 
			
		||||
		$this->assertEquals('4.883T', $quota->formatBlockUsage(1024*1024*5000));
 | 
			
		||||
		$this->assertEquals('4.883G', $quota->formatBlockUsage(1024*5000));
 | 
			
		||||
		$this->assertEquals('4.883M', $quota->formatBlockUsage(5000));
 | 
			
		||||
		$this->assertEquals('1M', $quota->formatBlockUsage(1025));
 | 
			
		||||
		$this->assertEquals('4.88T', $quota->formatBlockUsage(1024*1024*5000));
 | 
			
		||||
		$this->assertEquals('4.88G', $quota->formatBlockUsage(1024*5000));
 | 
			
		||||
		$this->assertEquals('4.88M', $quota->formatBlockUsage(5000));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function testAddInodeUnits() {
 | 
			
		||||
| 
						 | 
				
			
			@ -85,11 +85,11 @@ class QuotaTest extends TestCase {
 | 
			
		|||
		$this->assertEquals('123m', $quota->formatInodeUsage(1000*1000*123));
 | 
			
		||||
		$this->assertEquals('123k', $quota->formatInodeUsage(1000*123));
 | 
			
		||||
		$this->assertEquals('123', $quota->formatInodeUsage(123));
 | 
			
		||||
		$this->assertEquals('1.025k', $quota->formatInodeUsage(1025));
 | 
			
		||||
		$this->assertEquals('5.001t', $quota->formatInodeUsage(1000*1000*1000*5001));
 | 
			
		||||
		$this->assertEquals('5.001g', $quota->formatInodeUsage(1000*1000*5001));
 | 
			
		||||
		$this->assertEquals('5.001m', $quota->formatInodeUsage(1000*5001));
 | 
			
		||||
		$this->assertEquals('5.001k', $quota->formatInodeUsage(5001));
 | 
			
		||||
		$this->assertEquals('1.03k', $quota->formatInodeUsage(1025));
 | 
			
		||||
		$this->assertEquals('5t', $quota->formatInodeUsage(1000*1000*1000*5001));
 | 
			
		||||
		$this->assertEquals('5g', $quota->formatInodeUsage(1000*1000*5001));
 | 
			
		||||
		$this->assertEquals('5m', $quota->formatInodeUsage(1000*5001));
 | 
			
		||||
		$this->assertEquals('5k', $quota->formatInodeUsage(5001));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue