LABEL_CREATE_ANOTHER_ACCOUNT = _('Create another user'); $this->LABEL_BACK_TO_ACCOUNT_LIST = _('Back to user list'); } /** * Returns the alias name of this account type. * * @return string alias name */ function getAlias() { return _("Users"); } /** * Returns the description of this account type. * * @return string description */ function getDescription() { return _("User accounts (e.g. Unix, Samba and Kolab)"); } /** * Returns the class name for the list object. * * @return string class name */ function getListClassName() { return "lamUserList"; } /** * Returns the default attribute list for this account type. * * @return string attribute list */ function getDefaultListAttributes() { return "#uid;#givenName;#sn;#uidNumber;#gidNumber"; } /** * Returns a list of attributes which have a translated description. * This is used for the head row in the list view. * * @return array list of descriptions */ function getListAttributeDescriptions() { return array_merge( parent::getListAttributeDescriptions(), array( "cn" => _("Common name"), 'company' => _('Company'), 'departmentNumber' => _('Department'), 'displayName' => _('Display name'), 'employeeNumber' => _('Employee number'), "gecos" => _("Description"), "gidnumber" => _("GID number"), "givenname" => _("First name"), "homedirectory" => _("Home directory"), "host" => _("Allowed hosts"), "jpegphoto" => _('Photo'), "loginshell" => _("Login shell"), "mail" => _("Email"), 'manager' => _('Manager'), 'o' => _('Organisation'), 'ou' => _('Organisational unit'), 'proxyAddresses' => _('Proxy-Addresses'), 'sambakickofftime' => _('Account expiration date'), 'shadowexpire' => _('Account expiration date'), "sn" => _("Last name"), 'streetAddress' => _('Street'), 'telephoneNumber' => _('Telephone number'), 'title' => _('Job title'), "uid" => _("User name"), "uidnumber" => _("UID number"), 'userPrincipalName' => _('User name'), )); } /** * Returns the the title text for the title bar on the new/edit page. * * @param accountContainer $container account container * @return String title text */ public function getTitleBarTitle($container) { $title = $this->buildAccountStatusIcon($container); // get attributes $personalAttributes = null; if ($container->getAccountModule('inetOrgPerson') != null) { $personalAttributes = $container->getAccountModule('inetOrgPerson')->getAttributes(); } elseif ($container->getAccountModule('windowsUser') != null) { $personalAttributes = $container->getAccountModule('windowsUser')->getAttributes(); } $accountAttributes = null; if ($container->getAccountModule('account') != null) { $accountAttributes = $container->getAccountModule('account')->getAttributes(); } $sambaAttributes = null; if ($container->getAccountModule('sambaSamAccount') != null) { $sambaAttributes = $container->getAccountModule('sambaSamAccount')->getAttributes(); } $unixAttributes = null; if ($container->getAccountModule('posixAccount') != null) { $unixAttributes = $container->getAccountModule('posixAccount')->getAttributes(); } $mitKerberosAttributes = null; if ($container->getAccountModule('mitKerberosStructural') != null) { $mitKerberosAttributes = $container->getAccountModule('mitKerberosStructural')->getAttributes(); } elseif ($container->getAccountModule('mitKerberos') != null) { $mitKerberosAttributes = $container->getAccountModule('mitKerberos')->getAttributes(); } // check if first and last name can be shown if (($personalAttributes != null) && isset($personalAttributes['sn'][0]) && !empty($personalAttributes['sn'][0]) && isset($personalAttributes['givenName'][0]) && !empty($personalAttributes['givenName'][0])) { return $title . htmlspecialchars($personalAttributes['givenName'][0] . ' ' . $personalAttributes['sn'][0]); } // check if a display name is set if (($sambaAttributes != null) && isset($sambaAttributes['displayName'][0]) && !empty($sambaAttributes['displayName'][0])) { return $title . htmlspecialchars($sambaAttributes['displayName'][0]); } // check if a common name is set if (($personalAttributes != null) && isset($personalAttributes['cn'][0]) && !empty($personalAttributes['cn'][0])) { return $title . htmlspecialchars($personalAttributes['cn'][0]); } if (($unixAttributes != null) && isset($unixAttributes['cn'][0]) && !empty($unixAttributes['cn'][0])) { return $title . htmlspecialchars($unixAttributes['cn'][0]); } // check if a user name is set if (($unixAttributes != null) && isset($unixAttributes['uid'][0]) && !empty($unixAttributes['uid'][0])) { return $title . htmlspecialchars($unixAttributes['uid'][0]); } if (($personalAttributes != null) && isset($personalAttributes['uid'][0]) && !empty($personalAttributes['uid'][0])) { return $title . htmlspecialchars($personalAttributes['uid'][0]); } if (($accountAttributes != null) && isset($accountAttributes['uid'][0]) && !empty($accountAttributes['uid'][0])) { return $title . htmlspecialchars($accountAttributes['uid'][0]); } if (($mitKerberosAttributes != null) && isset($mitKerberosAttributes['krbPrincipalName'][0]) && !empty($mitKerberosAttributes['krbPrincipalName'][0])) { return $title . htmlspecialchars($mitKerberosAttributes['krbPrincipalName'][0]); } if ($container->isNewAccount) { return $title . _("New user"); } // fall back to default return $title . parent::getTitleBarTitle($container); } /** * Returns the the title text for the title bar on the new/edit page. * * @param accountContainer $container account container * @return String title text */ public function getTitleBarSubtitle($container) { $personalAttributes = null; if ($container->getAccountModule('inetOrgPerson') != null) { $personalAttributes = $container->getAccountModule('inetOrgPerson')->getAttributes(); } elseif ($container->getAccountModule('windowsUser') != null) { $personalAttributes = $container->getAccountModule('windowsUser')->getAttributes(); } if ($personalAttributes == null) { return ''; } $subtitle = ''; $spacer = '     '; // check if an email address can be shown if (isset($personalAttributes['mail'][0]) && !empty($personalAttributes['mail'][0])) { $subtitle .= '' . htmlspecialchars($personalAttributes['mail'][0]) . '' . $spacer; } // check if an telephone number can be shown if (isset($personalAttributes['telephoneNumber'][0]) && !empty($personalAttributes['telephoneNumber'][0])) { $subtitle .= _('Telephone number') . ' ' . htmlspecialchars($personalAttributes['telephoneNumber'][0]) . $spacer; } // check if an mobile number can be shown if (isset($personalAttributes['mobile'][0]) && !empty($personalAttributes['mobile'][0])) { $subtitle .= _('Mobile number') . ' ' . htmlspecialchars($personalAttributes['mobile'][0]); } if ($subtitle == '') { return null; } return $subtitle; } /** * Builds the HTML code for the icon that shows the account status (locked/unlocked). * * @param accountContainer $container account container * @return String HTML code for icon */ private function buildAccountStatusIcon($container) { $modules = $this->getType()->getModules(); // check if there are account parts that can be locked $unixAvailable = ($container->getAccountModule('posixAccount') != null) && $container->getAccountModule('posixAccount')->isLockable($modules); $sambaAvailable = (($container->getAccountModule('sambaSamAccount') != null) && $container->getAccountModule('sambaSamAccount')->isExtensionEnabled()); $ppolicyAvailable = ($container->getAccountModule('ppolicyUser') != null); $windowsAvailable = ($container->getAccountModule('windowsUser') != null); $is389dsAvailable = ($container->getAccountModule('locking389ds') != null); $is389dsLocked = $is389dsAvailable && $container->getAccountModule('locking389ds')->isLocked(); $is389dsDeactivated = $is389dsAvailable && $container->getAccountModule('locking389ds')->isDeactivated(); $is389dsPwdExpired = $is389dsAvailable && locking389ds::isPasswordExpired($container->getAccountModule('locking389ds')->getAttributes()); if (!$unixAvailable && !$sambaAvailable && !$ppolicyAvailable && !$windowsAvailable && !$is389dsAvailable) { return ''; } $isEditable = checkIfWriteAccessIsAllowed('user') && ($unixAvailable || $sambaAvailable || $ppolicyAvailable || $windowsAvailable || $is389dsAvailable); // get locking status $unixLocked = false; if ($unixAvailable && $container->getAccountModule('posixAccount')->isLocked($modules)) { $unixLocked = true; } $sambaLocked = false; if ($sambaAvailable && $container->getAccountModule('sambaSamAccount')->isDeactivated()) { $sambaLocked = true; } $ppolicyLocked = false; if ($ppolicyAvailable && $container->getAccountModule('ppolicyUser')->isLocked()) { $ppolicyLocked = true; } $windowsLocked = false; $windowsPasswordLockedTime = null; $windowsPasswordLocked = false; if ($windowsAvailable){ $attrs = $container->getAccountModule('windowsUser')->getAttributes(); $attrs['dn'] = $container->dn_orig; if (windowsUser::isDeactivated($attrs)) { $windowsLocked = true; } $windowsPasswordLockedTime = windowsUser::getPasswordLocked($attrs, $this->getType()); if ($windowsPasswordLockedTime != null) { $windowsPasswordLocked = true; } } $partiallyLocked = $unixLocked || $sambaLocked || $ppolicyLocked || $windowsLocked || $windowsPasswordLocked || $is389dsDeactivated || $is389dsLocked || $is389dsPwdExpired; $fullyLocked = ($unixAvailable || $sambaAvailable || $ppolicyAvailable || $windowsAvailable || $is389dsDeactivated || $is389dsLocked) && (!$unixAvailable || $unixLocked) && (!$sambaAvailable || $sambaLocked) && (!$ppolicyAvailable || $ppolicyLocked) && (!$windowsAvailable || $windowsLocked); // build tooltip $icon = 'unlocked.png'; if ($fullyLocked) { $icon = 'lock.png'; } elseif ($partiallyLocked) { $icon = 'partiallyLocked.png'; } $statusTable = ''; // Unix if ($unixAvailable) { $unixIcon = 'unlocked.png'; if ($unixLocked) { $unixIcon = 'lock.png'; } $statusTable .= ''; } // Samba if ($sambaAvailable) { $sambaIcon = 'unlocked.png'; if ($sambaLocked) { $sambaIcon = 'lock.png'; } $statusTable .= ''; } // PPolicy if ($ppolicyAvailable) { $ppolicyIcon = 'unlocked.png'; if ($ppolicyLocked) { $ppolicyIcon = 'lock.png'; } $statusTable .= ''; } // Windows if ($windowsAvailable) { $windowsIcon = 'unlocked.png'; if ($windowsLocked) { $windowsIcon = 'lock.png'; } $statusTable .= ''; } if ($windowsAvailable && $windowsPasswordLocked) { $statusTable .= ''; } // 389ds locked if ($is389dsLocked) { $statusTable .= ''; } // 389ds deactivated if ($is389dsAvailable) { $text389dsActivation = $is389dsDeactivated ? _('Deactivated') : _('Active'); $icon389dsActivation = $is389dsDeactivated ? 'lock.png' : 'unlocked.png'; $statusTable .= ''; } // 389ds password expired if ($is389dsPwdExpired) { $statusTable .= ''; } $statusTable .= '
' . _('Unix') . '  
' . _('Samba 3') . '  
' . _('Password policy') . '  
' . _('Windows') . '  
' . _('Locked till') . '  ' . $windowsPasswordLockedTime->format('Y-m-d H:i:s') . '
' . _('Locked') . '  
' . $text389dsActivation . '  
' . _('Password expired') . '  
'; $tipContent = $statusTable; if ($isEditable) { $tipContent .= '
"hint" '; $tipContent .= _('Please click to lock/unlock this account.'); } $dialogDiv = $this->buildAccountStatusDialogDiv($unixAvailable, $unixLocked, $sambaAvailable, $sambaLocked, $ppolicyAvailable, $ppolicyLocked, $windowsAvailable, $windowsLocked, $windowsPasswordLockedTime, $is389dsAvailable, $is389dsLocked, $is389dsDeactivated, $is389dsPwdExpired); $onClick = ''; if ($isEditable) { $onClick = 'onclick="showConfirmationDialog(\'' . _('Change account status') . '\', \'' . _('Ok') . '\', \'' . _('Cancel') . '\', \'lam_accountStatusDialog\', \'inputForm\', \'lam_accountStatusResult\');"'; } $dialogDiv .= 'status   '; // expiration status $expiredLabels = array(); $shadowModule = $container->getAccountModule('shadowAccount'); if ($shadowModule != null) { $shadowAttrs = $shadowModule->getAttributes(); if (shadowAccount::isAccountExpired($shadowAttrs)) { $expiredLabels[] = _('Shadow') . ': ' . _('Account expiration'); } elseif (shadowAccount::isPasswordExpired($shadowAttrs)) { $expiredLabels[] = _('Shadow') . ': ' . _('Password expiration'); } } $windowsModule = $container->getAccountModule('windowsUser'); if ($windowsModule != null) { $windowsAttrs = $windowsModule->getAttributes(); if (windowsUser::isAccountExpired($windowsAttrs)) { $expiredLabels[] = _('Windows') . ': ' . _('Account expiration'); } } if (!empty($expiredLabels)) { $expiredTip = ''; foreach ($expiredLabels as $label) { $expiredTip .= ''; } $expiredTip .= '
' . $label . '
'; $dialogDiv .= 'expired   '; } return $dialogDiv; } /** * Builds the dialog to (un)lock parts of an account. * * @param boolean $unixAvailable Unix part is active * @param boolean $unixLocked Unix part is locked * @param boolean $sambaAvailable Samba part is active * @param boolean $sambaLocked Samba part is locked * @param boolean $ppolicyAvailable PPolicy part is active * @param boolean $ppolicyLocked PPolicy part is locked * @param boolean $windowsAvailable Windows part is active * @param boolean $windowsLocked Windows part is locked * @param DateTime $windowsPasswordLockedTime lock time for Windows or null * @param boolean $is389dsAvailable 389ds is available * @param boolean $is389dsLocked account is locked * @param boolean $is389dsDeactivated account is deactivated * @param boolean $is389dsPwdExpired password expired */ private function buildAccountStatusDialogDiv($unixAvailable, $unixLocked, $sambaAvailable, $sambaLocked, $ppolicyAvailable, $ppolicyLocked, $windowsAvailable, $windowsLocked, $windowsPasswordLockedTime, $is389dsAvailable, $is389dsLocked, $is389dsDeactivated, $is389dsPwdExpired) { $windowsPasswordLocked = ($windowsPasswordLockedTime != null); $partiallyLocked = $unixLocked || $sambaLocked || $ppolicyLocked || $windowsLocked || $windowsPasswordLocked || $is389dsLocked || $is389dsDeactivated || $is389dsPwdExpired; $fullyLocked = ($unixAvailable || $sambaAvailable || $ppolicyAvailable || $windowsAvailable || $is389dsLocked || $is389dsDeactivated) && (!$unixAvailable || $unixLocked) && (!$sambaAvailable || $sambaLocked) && (!$ppolicyAvailable || $ppolicyLocked) && (!$windowsAvailable || $windowsLocked || $windowsPasswordLocked); $container = new htmlResponsiveRow(); // show radio buttons for lock/unlock $radioDisabled = true; $selectedRadio = 'unlock'; $onchange = ''; if ($partiallyLocked && !$fullyLocked) { $radioDisabled = false; $onchange = 'if (jQuery(\'#lam_accountStatusAction0:checked\').val()) {' . 'jQuery(\'#lam_accountStatusDialogLockDiv\').removeClass(\'hidden\');' . 'jQuery(\'#lam_accountStatusDialogUnlockDiv\').addClass(\'hidden\');' . '}' . 'else {' . 'jQuery(\'#lam_accountStatusDialogLockDiv\').addClass(\'hidden\');' . 'jQuery(\'#lam_accountStatusDialogUnlockDiv\').removeClass(\'hidden\');' . '};'; } if (!$fullyLocked && !$partiallyLocked) { $selectedRadio = 'lock'; } if (!$radioDisabled) { $radio = new htmlRadio('lam_accountStatusAction', array(_('Lock') => 'lock', _('Unlock') => 'unlock'), $selectedRadio); $radio->setOnchangeEvent($onchange); $container->add($radio, 12); } else { $radio = new htmlRadio('lam_accountStatusActionDisabled', array(_('Lock') => 'lock', _('Unlock') => 'unlock'), $selectedRadio); $radio->setIsEnabled(false); $container->add($radio, 12); $container->add(new htmlHiddenInput('lam_accountStatusAction', $selectedRadio), 12); } $container->add(new htmlHiddenInput('lam_accountStatusResult', 'cancel'), 12); // locking part if (!$fullyLocked) { $lockContent = new htmlTable(); if ($unixAvailable && !$unixLocked) { $lockContent->addElement(new htmlImage('../../graphics/tux.png')); $lockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusLockUnix', true, _('Unix'), null, false), true); } if ($sambaAvailable && !$sambaLocked) { $lockContent->addElement(new htmlImage('../../graphics/samba.png')); $lockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusLockSamba', true, _('Samba 3'), null, false), true); } if ($ppolicyAvailable && !$ppolicyLocked) { $lockContent->addElement(new htmlImage('../../graphics/security.png')); $lockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusLockPPolicy', true, _('PPolicy'), null, false), true); } if ($is389dsAvailable && !$is389dsDeactivated) { $lockContent->addElement(new htmlImage('../../graphics/security.png')); $lockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusDeactivate389ds', true, _('Deactivate'), null, false), true); } if ($windowsAvailable && !$windowsLocked) { $lockContent->addElement(new htmlImage('../../graphics/samba.png')); $lockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusLockWindows', true, _('Windows'), null, false), true); } if ($unixAvailable) { $lockContent->addElement(new htmlImage('../../graphics/groupBig.png')); $lockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusRemoveUnixGroups', true, _('Remove from all Unix groups'), null, false), true); } if ($unixAvailable && posixAccount::areGroupOfNamesActive()) { // check unixAvailable because Unix module removes group memberships $lockContent->addElement(new htmlImage('../../graphics/groupBig.png')); $lockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusRemoveGONGroups', true, _('Remove from all group of (unique) names'), null, false), true); } $lockDiv = new htmlDiv('lam_accountStatusDialogLockDiv', $lockContent); if ($fullyLocked || $partiallyLocked) { $lockDiv->setCSSClasses(array('hidden')); } $container->add($lockDiv, 12); } // unlocking part if ($partiallyLocked) { $unlockContent = new htmlTable(); if ($unixAvailable && $unixLocked) { $unlockContent->addElement(new htmlImage('../../graphics/tux.png')); $unlockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusUnlockUnix', true, _('Unix'), null, false), true); } if ($sambaAvailable && $sambaLocked) { $unlockContent->addElement(new htmlImage('../../graphics/samba.png')); $unlockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusUnlockSamba', true, _('Samba 3'), null, false), true); } if ($ppolicyAvailable && $ppolicyLocked) { $unlockContent->addElement(new htmlImage('../../graphics/security.png')); $unlockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusUnlockPPolicy', true, _('PPolicy'), null, false), true); } if ($is389dsAvailable && $is389dsDeactivated) { $unlockContent->addElement(new htmlImage('../../graphics/security.png')); $unlockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusActivate389ds', true, _('Activate'), null, false), true); } if ($is389dsAvailable && $is389dsPwdExpired) { $unlockContent->addElement(new htmlImage('../../graphics/security.png')); $unlockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusPwdUnexpire389ds', true, _('Clear password expiration'), null, false), true); } if ($windowsAvailable && $windowsLocked) { $unlockContent->addElement(new htmlImage('../../graphics/samba.png')); $unlockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusUnlockWindows', true, _('Windows'), null, false), true); } if ($windowsAvailable && $windowsPasswordLocked) { $unlockContent->addElement(new htmlImage('../../graphics/samba.png')); $unlockContent->addElement(new htmlTableExtendedInputCheckbox('lam_accountStatusUnlockWindowsPassword', true, _('Locked till') . ' ' . $windowsPasswordLockedTime->format('Y-m-d H:i:s'), 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 && !$partiallyLocked) { $unlockDiv->setCSSClasses(array('hidden')); } $container->add($unlockDiv, 12); } $div = new htmlDiv('lam_accountStatusDialog', $container); $div->setCSSClasses(array('hidden')); $tabindex = 999; ob_start(); parseHtml(null, $div, array(), false, $tabindex, 'user'); $output = ob_get_contents(); ob_clean(); return $output; } /** * This function is called after the edit page is processed and before the page content is generated. * This can be used to run custom handlers after each page processing. * * @param accountContainer $container account container */ public function runEditPagePostAction(&$container) { $modules = $this->getType()->getModules(); // check if account status should be changed if (isset($_POST['lam_accountStatusResult']) && ($_POST['lam_accountStatusResult'] == 'ok')) { // lock account if ($_POST['lam_accountStatusAction'] == 'lock') { // Unix if (isset($_POST['lam_accountStatusLockUnix']) && ($_POST['lam_accountStatusLockUnix'] == 'on')) { $container->getAccountModule('posixAccount')->lock($modules); } // Samba if (isset($_POST['lam_accountStatusLockSamba']) && ($_POST['lam_accountStatusLockSamba'] == 'on')) { $container->getAccountModule('sambaSamAccount')->deactivate(); } // PPolicy if (isset($_POST['lam_accountStatusLockPPolicy']) && ($_POST['lam_accountStatusLockPPolicy'] == 'on')) { $container->getAccountModule('ppolicyUser')->lock(); } // 389ds if (isset($_POST['lam_accountStatusDeactivate389ds']) && ($_POST['lam_accountStatusDeactivate389ds'] == 'on')) { $container->getAccountModule('locking389ds')->deactivate(); } // Windows if (isset($_POST['lam_accountStatusLockWindows']) && ($_POST['lam_accountStatusLockWindows'] == 'on')) { $container->getAccountModule('windowsUser')->setIsDeactivated(true); } // remove Unix groups if (isset($_POST['lam_accountStatusRemoveUnixGroups']) && ($_POST['lam_accountStatusRemoveUnixGroups'] == 'on')) { $container->getAccountModule('posixAccount')->removeFromUnixGroups(); } // remove group of names memberships if (isset($_POST['lam_accountStatusRemoveGONGroups']) && ($_POST['lam_accountStatusRemoveGONGroups'] == 'on')) { $container->getAccountModule('posixAccount')->removeFromGONGroups(); } } // unlock account elseif ($_POST['lam_accountStatusAction'] == 'unlock') { // Unix if (isset($_POST['lam_accountStatusUnlockUnix']) && ($_POST['lam_accountStatusUnlockUnix'] == 'on')) { $container->getAccountModule('posixAccount')->unlock($modules); } // Samba if (isset($_POST['lam_accountStatusUnlockSamba']) && ($_POST['lam_accountStatusUnlockSamba'] == 'on')) { $container->getAccountModule('sambaSamAccount')->activate(); } // PPolicy if (isset($_POST['lam_accountStatusUnlockPPolicy']) && ($_POST['lam_accountStatusUnlockPPolicy'] == 'on')) { $container->getAccountModule('ppolicyUser')->unlock(); } // 389ds if (isset($_POST['lam_accountStatusActivate389ds']) && ($_POST['lam_accountStatusActivate389ds'] == 'on')) { $container->getAccountModule('locking389ds')->activate(); } if (isset($_POST['lam_accountStatusPwdUnexpire389ds']) && ($_POST['lam_accountStatusPwdUnexpire389ds'] == 'on')) { $container->getAccountModule('locking389ds')->clearPasswordExpiration(); } // Windows if (isset($_POST['lam_accountStatusUnlockWindows']) && ($_POST['lam_accountStatusUnlockWindows'] == 'on')) { $container->getAccountModule('windowsUser')->setIsDeactivated(false); } // Windows password if (isset($_POST['lam_accountStatusUnlockWindowsPassword']) && ($_POST['lam_accountStatusUnlockWindowsPassword'] == 'on')) { $container->getAccountModule('windowsUser')->unlockPassword(); } // 389ds unlocking if (isset($_POST['lam_accountStatusUnlock389ds']) && ($_POST['lam_accountStatusUnlock389ds'] == 'on')) { $container->getAccountModule('locking389ds')->unlock(false); } } } } } /** * Generates the list view. * * @package lists * @author Roland Gruber * */ class lamUserList extends lamList { /** Controls if GID number is translated to group name */ private $trans_primary = false; /** Controls if the account status is shown */ private $showAccountStatus = false; /** translates GID to group name */ private $trans_primary_hash = array(); /** filter value for account status */ private $accountStatusFilter = null; /** ID for config option to translate primary group GIDs to group names */ const TRANS_PRIMARY_OPTION_NAME = "LU_TP"; /** ID for config option to show account status */ const ACCOUNT_STATUS_OPTION_NAME = "LU_AS"; /** virtual attribute name for account status column */ const ATTR_ACCOUNT_STATUS = 'lam_virtual_account_status'; /** filter value for expired accounts */ const FILTER_EXPIRED = 1; /** filter value for locked accounts */ const FILTER_LOCKED = 2; /** filter value for partially locked accounts */ const FILTER_SEMILOCKED = 3; /** filter value for unlocked accounts */ const FILTER_UNLOCKED = 4; /** * Constructor * * @param string $type account type * @return lamList list object */ public function __construct($type) { parent::__construct($type); $this->labels = array( 'nav' => _("User count: %s"), 'error_noneFound' => _("No users found!"), 'newEntry' => _("New user"), 'deleteEntry' => _("Delete selected users")); } /** * Sets some internal parameters. */ protected function listGetParams() { parent::listGetParams(); // generate hash table for group translation if ($this->trans_primary == "on" && !$this->refresh && (sizeof($this->trans_primary_hash) == 0)) { $this->refreshPrimaryGroupTranslation(); } } /** * Rereads the entries from LDAP. */ protected function listRefreshData() { parent::listRefreshData(); // show group names if ($this->trans_primary == "on") { $this->refreshPrimaryGroupTranslation(); } // show account status if ($this->showAccountStatus) { $this->injectAccountStatusAttribute(); } } /** * Refreshes the GID to group name cache. */ protected function refreshPrimaryGroupTranslation() { $this->trans_primary_hash = array(); $attrs = array("cn", "gidNumber"); $entries = searchLDAPByAttribute(null, null, 'posixGroup', $attrs, array('group')); $entryCount = sizeof($entries); for ($i = 0; $i < $entryCount; $i++) { $this->trans_primary_hash[$entries[$i]['gidnumber'][0]] = $entries[$i]['cn'][0]; } } /** * {@inheritDoc} * @see lamList::getTableCellContent() */ protected function getTableCellContent(&$entry, &$attribute) { // check if there is something to display at all if (($attribute != self::ATTR_ACCOUNT_STATUS) && (!isset($entry[$attribute]) || !is_array($entry[$attribute]) || (sizeof($entry[$attribute]) < 1))) { return parent::getTableCellContent($entry, $attribute); } // translate GID to group name if (($attribute == "gidnumber") && ($this->trans_primary == "on")) { if (isset($this->trans_primary_hash[$entry[$attribute][0]])) { return new htmlOutputText($this->trans_primary_hash[$entry[$attribute][0]]); } else { return parent::getTableCellContent($entry, $attribute); } } // show user photos elseif (($attribute == "jpegphoto") && (!empty($entry[$attribute][0]))) { if (strlen($entry[$attribute][0]) < 100) { // looks like we have read broken binary data, reread photo $result = @ldap_read($_SESSION['ldap']->server(), escapeDN($entry['dn']), $attribute . "=*", array($attribute), 0, 0, 0, LDAP_DEREF_NEVER); if ($result) { $tempEntry = @ldap_first_entry($_SESSION['ldap']->server(), $result); if ($tempEntry) { $binData = ldap_get_values_len($_SESSION['ldap']->server(), $tempEntry, $attribute); $entry[$attribute] = $binData; } } } $imgNumber = getRandomNumber(); $jpeg_filename = 'jpg' . $imgNumber . '.jpg'; $outjpeg = @fopen(dirname(__FILE__) . '/../../tmp/' . $jpeg_filename, "wb"); fwrite($outjpeg, $entry[$attribute][0]); fclose ($outjpeg); $photoFile = '../../tmp/' . $jpeg_filename; $image = new htmlImage($photoFile); $image->enableLightbox(); $image->setCSSClasses(array('thumbnail')); return $image; } elseif (($attribute == 'mail') || ($attribute == 'rfc822Mailbox')) { $group = new htmlGroup(); if (isset($entry[$attribute][0]) && ($entry[$attribute][0] != '')) { for ($i = 0; $i < sizeof($entry[$attribute]); $i++) { if ($i > 0) { $group->addElement(new htmlOutputText(", ")); } $group->addElement(new htmlLink($entry[$attribute][$i], "mailto:" . $entry[$attribute][$i])); } } return $group; } // expire dates elseif ($attribute == 'shadowexpire') { if (!empty($entry[$attribute][0])) { $time = new DateTime('@' . $entry[$attribute][0] * 24 * 3600, getTimeZone()); return new htmlOutputText($time->format('d.m.Y')); } } elseif ($attribute == 'sambakickofftime') { if (!empty($entry[$attribute][0])) { if ($entry[$attribute][0] > 2147483648) { return new htmlOutputText("∞"); } else { $date = new DateTime('@' . $entry[$attribute][0], new DateTimeZone('UTC')); return new htmlOutputText($date->format('d.m.Y')); } } } // account status elseif ($attribute == self::ATTR_ACCOUNT_STATUS) { return $this->getAccountStatus($entry); } // print all other attributes else { return parent::getTableCellContent($entry, $attribute); } } /** * Returns a list of lamListTool objects to display next to the edit/delete buttons. * * @return lamListTool[] tools */ protected function getAdditionalTools() { if (!isLAMProVersion()) { return array(); } if (checkIfWriteAccessIsAllowed('user') || (checkIfPasswordChangeIsAllowed() && !checkIfWriteAccessIsAllowed())) { $passwordTool = new lamListTool(_('Change password'), 'key.png', 'changePassword.php'); return array($passwordTool); } return array(); } /** * Returns a list of possible configuration options. * * @return array list of lamListOption objects */ protected function listGetAllConfigOptions() { $options = parent::listGetAllConfigOptions(); $options[] = new lamBooleanListOption(_('Translate GID number to group name'), self::TRANS_PRIMARY_OPTION_NAME); $options[] = new lamBooleanListOption(_('Show account status'), self::ACCOUNT_STATUS_OPTION_NAME); return $options; } /** * Called when the configuration options changed. */ protected function listConfigurationChanged() { parent::listConfigurationChanged(); $tpOption = $this->listGetConfigOptionByID(self::TRANS_PRIMARY_OPTION_NAME); $this->trans_primary = $tpOption->isSelected(); $asOption = $this->listGetConfigOptionByID(self::ACCOUNT_STATUS_OPTION_NAME); // if account status was activated, reload LDAP data $asOptionOldValue = $this->showAccountStatus; $this->showAccountStatus = $asOption->isSelected(); if ($this->showAccountStatus && !$asOptionOldValue) { $this->forceRefresh(); } } /** * Returns an hash array containing with all attributes to be shown and their descriptions. *
Format: array(attribute => description) *
*
The user list may display an additional account status column * * @return array attribute list */ protected function listGetAttributeDescriptionList() { $list = parent::listGetAttributeDescriptionList(); if ($this->showAccountStatus) { $list[self::ATTR_ACCOUNT_STATUS] = _('Account status'); } return $list; } /** * Returns if the given attribute can be filtered. * If filtering is not possible then no filter box will be displayed. *
*
The user list allows no filtering for account status. * * @param String $attr attribute name * @return boolean filtering possible */ protected function canBeFiltered($attr) { if (strtolower($attr) == 'jpegphoto') { return false; } return true; } /** * {@inheritDoc} * @see lamList::getFilterArea() */ protected function getFilterArea($attrName, $clearFilter) { if ($attrName != self::ATTR_ACCOUNT_STATUS) { return parent::getFilterArea($attrName, $clearFilter); } $value = "-"; if (!$clearFilter && isset($this->filters[$attrName])) { $value = $this->filters[$attrName]; } $filterOptions = array( '' => '', _('Unlocked') => self::FILTER_UNLOCKED, _('Partially locked') => self::FILTER_SEMILOCKED, _('Locked') => self::FILTER_LOCKED, _('Expired') => self::FILTER_EXPIRED, ); $filterInput = new htmlSelect('filter' . strtolower($attrName), $filterOptions, array($value)); $filterInput->setCSSClasses(array($this->type->getScope() . '-bright')); $filterInput->setHasDescriptiveElements(true); $filterInput->setOnchangeEvent('document.getElementsByName(\'apply_filter\')[0].click();'); return $filterInput; } /** * Builds the LDAP filter based on the filter entries in the GUI. * * @return String LDAP filter */ protected function buildLDAPAttributeFilter() { $this->accountStatusFilter = null; foreach ($this->filters as $attr => $filter) { if ($attr == self::ATTR_ACCOUNT_STATUS) { $this->accountStatusFilter = $filter; break; } } return parent::buildLDAPAttributeFilter(); } /** * {@inheritDoc} * @see lamList::isAttributeFilteredByServer() */ protected function isAttributeFilteredByServer($attrName) { // do not filter status server side if ($attrName == self::ATTR_ACCOUNT_STATUS) { return false; } return parent::isAttributeFilteredByServer($attrName); } /** * Returns a list of additional LDAP attributes that should be read. * This can be used to show additional data even if the user selected other attributes to show in the list. *
*
The user list reads pwdAccountLockedTime, sambaAcctFlags and userPassword * * @return array additional attribute names */ protected function getAdditionalLDAPAttributesToRead() { $attrs = parent::getAdditionalLDAPAttributesToRead(); if ($this->showAccountStatus) { $attrs[] = 'pwdAccountLockedTime'; $attrs[] = 'sambaAcctFlags'; $attrs[] = 'userPassword'; $attrs[] = 'userAccountControl'; $attrs[] = 'lockoutTime'; $attrs[] = 'nsAccountLock'; $attrs[] = 'accountUnlockTime'; $attrs[] = 'shadowExpire'; $attrs[] = 'shadowLastChange'; $attrs[] = 'shadowMax'; $attrs[] = 'shadowInactive'; $attrs[] = 'accountExpires'; $attrs[] = 'passwordExpirationTime'; $attrs[] = 'objectClass'; } return $attrs; } /** * Injects values for the virtual account status attribute to make it sortable. */ private function injectAccountStatusAttribute() { $entryCount = sizeof($this->ldapEntries); for ($i = 0; $i < $entryCount; $i++) { $unixAvailable = self::isUnixAvailable($this->ldapEntries[$i]); $sambaAvailable = self::isSambaAvailable($this->ldapEntries[$i]); $ppolicyAvailable = $this->isPPolicyAvailable($this->ldapEntries[$i]); $windowsAvailable = self::isWindowsAvailable($this->ldapEntries[$i]); $unixLocked = self::isUnixLocked($this->ldapEntries[$i]); $sambaLocked = self::isSambaLocked($this->ldapEntries[$i]); $ppolicyLocked = self::isPPolicyLocked($this->ldapEntries[$i]); $windowsLocked = self::isWindowsLocked($this->ldapEntries[$i]); $windowsPasswordLocked = ($this->getWindowsPasswordLockedTime($this->ldapEntries[$i]) != null); $is389dsLocked = self::is389dsLocked($this->ldapEntries[$i]); $is389dsDeactivated = self::is389dsDeactivated($this->ldapEntries[$i]); $is389dsPwdExpired = self::is389dsPwdExpired($this->ldapEntries[$i]); $hasLocked = ($unixAvailable && $unixLocked) || ($sambaAvailable && $sambaLocked) || ($ppolicyAvailable && $ppolicyLocked) || ($windowsAvailable && ($windowsLocked || $windowsPasswordLocked)) || $is389dsDeactivated || $is389dsPwdExpired || $is389dsLocked; $hasUnlocked = ($unixAvailable && !$unixLocked) || ($sambaAvailable && !$sambaLocked) || ($ppolicyAvailable && !$ppolicyLocked) || ($windowsAvailable && !$windowsLocked); $shadowExpired = shadowAccount::isAccountExpired($this->ldapEntries[$i]); $shadowPasswordExpired = shadowAccount::isPasswordExpired($this->ldapEntries[$i]); $windowsExpired = windowsUser::isAccountExpired($this->ldapEntries[$i]); $expired = $shadowExpired || $shadowPasswordExpired || $windowsExpired; $status = self::FILTER_UNLOCKED; if ($expired) { $status = self::FILTER_EXPIRED; } elseif ($hasLocked && $hasUnlocked) { $status = self::FILTER_SEMILOCKED; } elseif (!$hasUnlocked && $hasLocked) { $status = self::FILTER_LOCKED; } // add virtual attribute $this->ldapEntries[$i][self::ATTR_ACCOUNT_STATUS][0] = $status; } } /** * {@inheritDoc} * @see lamList::isFilterMatching() */ protected function isFilterMatching(&$data, $filterAttribute, $regex) { if ($filterAttribute == self::ATTR_ACCOUNT_STATUS) { return preg_match($regex, $data[self::ATTR_ACCOUNT_STATUS][0]); } if (($filterAttribute == 'gidnumber') && ($this->trans_primary == "on")) { if (!isset($data[$filterAttribute])) { return false; } if (!isset($this->trans_primary_hash[$data[$filterAttribute][0]])) { return false; } return preg_match($regex, $this->trans_primary_hash[$data[$filterAttribute][0]]); } return parent::isFilterMatching($data, $filterAttribute, $regex); } /** * Returns the account status. * * @param array $attrs LDAP attributes * @return htmlElement content */ private function getAccountStatus(&$attrs) { // check status $unixAvailable = self::isUnixAvailable($attrs); $sambaAvailable = self::isSambaAvailable($attrs); $ppolicyAvailable = $this->isPPolicyAvailable($attrs); $windowsAvailable = self::isWindowsAvailable($attrs); $unixLocked = self::isUnixLocked($attrs); $sambaLocked = self::isSambaLocked($attrs); $ppolicyLocked = self::isPPolicyLocked($attrs); $windowsLocked = self::isWindowsLocked($attrs); $windowsPasswordLockedTime = $this->getWindowsPasswordLockedTime($attrs); $windowsPasswordLocked = ($windowsPasswordLockedTime != null); $is389dsDeactivated = self::is389dsDeactivated($attrs); $is389dsLocked = self::is389dsLocked($attrs); $is389dsPwdExpired = self::is389dsPwdExpired($attrs); $partiallyLocked = $unixLocked || $sambaLocked || $ppolicyLocked || $windowsLocked || $windowsPasswordLocked || $is389dsDeactivated || $is389dsLocked || $is389dsPwdExpired; $fullyLocked = ($unixAvailable || $sambaAvailable || $ppolicyAvailable || $windowsAvailable || $is389dsDeactivated || $is389dsLocked) && (!$unixAvailable || $unixLocked) && (!$sambaAvailable || $sambaLocked) && (!$ppolicyAvailable || $ppolicyLocked) && (!$windowsAvailable || $windowsLocked); $shadowExpired = shadowAccount::isAccountExpired($attrs); $shadowPasswordExpired = shadowAccount::isPasswordExpired($attrs); $windowsExpired = windowsUser::isAccountExpired($attrs); $expired = $shadowExpired || $shadowPasswordExpired || $windowsExpired; $icon = 'unlocked.png'; if ($expired) { $icon = 'expired.png'; } elseif ($fullyLocked) { $icon = 'lock.png'; } elseif ($partiallyLocked) { $icon = 'partiallyLocked.png'; } // print icon and detail tooltips if ($unixAvailable || $sambaAvailable || $ppolicyAvailable || $windowsAvailable || $is389dsDeactivated || $is389dsLocked || $is389dsPwdExpired || $expired) { $tipContent = ''; // Shadow expired if ($shadowExpired) { $tipContent .= ''; } elseif ($shadowPasswordExpired) { $tipContent .= ''; } // Unix if ($unixAvailable) { $unixIcon = 'unlocked.png'; if ($unixLocked) { $unixIcon = 'lock.png'; } $tipContent .= ''; } // Samba if ($sambaAvailable) { $sambaIcon = 'unlocked.png'; if ($sambaLocked) { $sambaIcon = 'lock.png'; } $tipContent .= ''; } // PPolicy if ($ppolicyAvailable) { $ppolicyIcon = 'unlocked.png'; if ($ppolicyLocked) { $ppolicyIcon = 'lock.png'; } $tipContent .= ''; } // Windows if ($windowsAvailable) { $windowsIcon = 'unlocked.png'; if ($windowsLocked) { $windowsIcon = 'lock.png'; } $tipContent .= ''; if ($windowsExpired) { $tipContent .= ''; } } if ($windowsAvailable && $windowsPasswordLocked) { $tipContent .= ''; } // 389 locked if ($is389dsLocked) { $tipContent .= ''; } // 389 deactivation if ($is389dsDeactivated) { $tipContent .= ''; } // 389 password expired if ($is389dsPwdExpired) { $tipContent .= ''; } $tipContent .= '
' . _('Shadow') . ': ' . _('Account expiration') . '  
' . _('Shadow') . ': ' . _('Password expiration') . '  
' . _('Unix') . '  
' . _('Samba 3') . '  
' . _('Password policy') . '  
' . _('Windows') . '  
' . _('Windows') . ': ' . _('Account expiration') . '  
' . _('Locked till') . '  ' . $windowsPasswordLockedTime->format('Y-m-d H:i:s') . '
' . _('Locked') . '  
' . _('Deactivated') . '  
' . _('Password expired') . '  
'; return new htmlOutputText('status', false); } else { return new htmlImage('../../graphics/' . $icon, 16, 16, 'status'); } } /** * Returns if the Unix part exists. * * @param array $attrs LDAP attributes * @return boolean Unix part exists */ public static function isUnixAvailable(&$attrs) { return (isset($attrs['objectclass']) && in_array_ignore_case('posixAccount', $attrs['objectclass']) && isset($attrs['userpassword'][0])); } /** * Returns if the Shadow part exists. * * @param array $attrs LDAP attributes * @return boolean Shadow part exists */ public static function isShadowAvailable(&$attrs) { return (isset($attrs['objectclass']) && in_array_ignore_case('shadowAccount', $attrs['objectclass'])); } /** * Returns if the Unix part is locked. * * @param array $attrs LDAP attributes * @return boolean Unix part locked */ public static function isUnixLocked(&$attrs) { return (isset($attrs['userpassword'][0]) && !pwd_is_enabled($attrs['userpassword'][0])); } /** * Returns if the Samba part exists. * * @param array $attrs LDAP attributes * @return boolean Samba part exists */ public static function isSambaAvailable(&$attrs) { return (isset($attrs['objectclass']) && in_array_ignore_case('sambaSamAccount', $attrs['objectclass'])); } /** * Returns if the Samba part is locked. * * @param array $attrs LDAP attributes * @return boolean Samba part is locked */ public static function isSambaLocked(&$attrs) { return (isset($attrs['sambaacctflags'][0]) && strpos($attrs['sambaacctflags'][0], "D")); } /** * Returns if the PPolicy part exists. * * @param array $attrs LDAP attributes * @return boolean PPolicy part exists */ public function isPPolicyAvailable(&$attrs) { return in_array('ppolicyUser', $this->type->getModules()); } /** * Returns if the PPolicy part is locked. * * @param array $attrs LDAP attributes * @return boolean PPolicy part is locked */ public static function isPPolicyLocked(&$attrs) { return (isset($attrs['pwdaccountlockedtime'][0]) && ($attrs['pwdaccountlockedtime'][0] != '')); } /** * Returns if the Windows part exists. * * @param array $attrs LDAP attributes * @return boolean Windows part exists */ public static function isWindowsAvailable(&$attrs) { return (isset($attrs['objectclass']) && in_array_ignore_case('user', $attrs['objectclass']) && isset($attrs['useraccountcontrol'][0])); } /** * Returns if the Windows part is locked. * * @param array $attrs LDAP attributes * @return boolean Windows part is locked */ public static function isWindowsLocked(&$attrs) { return windowsUser::isDeactivated($attrs); } /** * Returns if the Windows password is locked. * * @param array $attrs LDAP attributes * @return DateTime Windows password lock time or null */ public function getWindowsPasswordLockedTime(&$attrs) { return windowsUser::getPasswordLocked($attrs, $this->type); } /** * Returns if the 389ds is activated. * * @param array $attrs LDAP attributes * @return boolean 389ds available */ public function is389dsAvailable(&$attrs) { return in_array('locking389ds', $this->type->getModules()); } /** * Returns if deactivated by nsAccountLock. * * @param array $attrs LDAP attributes * @return boolean account is deactivated */ public static function is389dsDeactivated(&$attrs) { return (isset($attrs['nsaccountlock'][0]) && ($attrs['nsaccountlock'][0] == 'true')); } /** * Returns if password expired. * * @param array $attrs LDAP attributes * @return boolean password is expired */ public static function is389dsPwdExpired(&$attrs) { return (class_exists('locking389ds') && locking389ds::isPasswordExpired($attrs)); } /** * Returns if locked by accountUnlockTime. * * @param array $attrs LDAP attributes * @return boolean account is locked */ public static function is389dsLocked(&$attrs) { return (isset($attrs['accountunlocktime'][0]) && !empty($attrs['accountunlocktime'][0])); } } ?>