get_scope(), array('user')); } /** * Returns meta data that is interpreted by parent class * * @return array array with meta data * * @see baseModule::get_metaData() */ function get_metaData() { $return = array(); // alias name $return["alias"] = _("Mailbox"); // module dependencies $return['dependencies'] = array('depends' => array(array('inetOrgPerson', 'windowsUser')), 'conflicts' => array()); // managed object classes $return['objectClasses'] = array(); // managed attributes $return['attributes'] = array(); // PHP extensions $return['extensions'] = array('imap'); // icon $return['icon'] = 'mailBig.png'; // help $return['help'] = array( 'ImapServerAddress' => array( "Headline" => _("Server address"), "Text" => _("Address of IMAP server (e.g. mail.example.org).")), 'ImapServerEncryptionProtocol' => array( "Headline" => _("Encryption protocol"), "Text" => _("Encryption protocol for connecting to IMAP server. LAM requires an encrypted connection.")), 'ImapValidateServerCert' => array( "Headline" => _("Validate server certificate"), "Text" => _("This option allows you to disable the certificate check of your IMAP server certificate. Disabling the certificate check is not recommended.")), 'ImapAdmin' => array( "Headline" => _("IMAP admin user"), "Text" => _("The login name of your IMAP user who has rights to create/delete mailboxes.") . ' ' . _('Use wildcards like $uid$ for LDAP attributes of the current LAM admin user.')), 'ImapAdminPasswordSelect' => array( "Headline" => _("IMAP password input"), "Text" => _("Choose the way how to provide the IMAP admin password. You can use the same password as for the LAM login or LAM will ask you for a password when it is required.") . ' ' . _('Storing the password in your server profile is also possible but not recommended.') ), 'ImapAdminPassword_Sess' => array( "Headline" => _("Password of IMAP admin user"), "Text" => _("The password of your IMAP admin user. The login name for the IMAP admin user is stored in the LAM server profile.")), 'ImapUserPrefix' => array( "Headline" => _("Prefix for mailboxes"), "Text" => _("Some IMAP servers store mailboxes with a prefix (e.g. \"user\" for Cyrus which results in \"user.username\").")), 'ImapMailDomain' => array( "Headline" => _("Mail domains"), "Text" => _("Please enter a comma separated list of domain names (e.g. \"company.com,example.com\"). LAM will only manage mailboxes from these domains.")), 'ImapUserNameAttr' => array( "Headline" => _("User name attribute"), "Text" => _("Please choose the attribute to get the IMAP user name. The default is \"mail\" but you can also use \"uid\" or \"userPrincipalName\".")), 'MailAddress' => array( "Headline" => _("Mailbox"), "Text" => _("This mailbox will be created/deleted.")), 'ImapUserQuotaLimit' => array( "Headline" => _("Quota"), "Text" => _("Please enter the quota limit of this mailbox in kilobytes.")), 'pathSeparator' => array( "Headline" => _("Path separator"), "Text" => _("This is the separator for the mailbox path. Usually, this is \".\" but e.g. Cyrus with \"unixhierarchysep\" will require \"/\".")), 'initialFolders' => array( "Headline" => _("Initial folders"), "Text" => _("Use this to provide a list of folders (e.g. Trash) to add for new accounts.")), 'createMailbox' => array( "Headline" => _("Create mailbox"), "Text" => _('Set to "true" to create the mailbox.')), ); // configuration checks $return['config_checks']['all']['ImapAccess_ImapServerAddress'] = array ( 'type' => 'ext_preg', 'regex' => 'DNSname', 'required' => true, 'required_message' => $this->messages['config'][0], 'error_message' => $this->messages['config'][0]); $return['config_checks']['all']['ImapAccess_ImapDomain'] = array ( 'type' => 'regex_i', 'regex' => '[\\*a-z0-9\\._-]+(,[a-z0-9\\._-]+)*', 'required' => true, 'required_message' => $this->messages['config'][1], 'error_message' => $this->messages['config'][1]); // profile options $profileContainer = new htmlResponsiveRow(); $profileContainer->add(new htmlResponsiveInputField(_('Quota'), 'ImapAccess_QuotaLimit', null, 'ImapUserQuotaLimit'), 12); $return['profile_options'] = $profileContainer; $return['profile_checks']['ImapAccess_QuotaLimit'] = array( 'type' => 'ext_preg', 'regex' => 'digit', 'error_message' => $this->messages['managemailbox'][8]); return $return; } /** * This function fills the error message array with messages */ function load_Messages() { $this->messages['config'][0] = array('ERROR', _('Please enter a valid server name where the mailboxes reside.')); $this->messages['config'][1] = array('ERROR', _('Please enter a correct list of valid mail domains.')); $this->messages['config'][2] = array('ERROR', _('The IMAP admin password is empty.')); $this->messages['managemailbox'][0] = array('ERROR', _('Unable to change ACL on IMAP server for mailbox deletion.')); $this->messages['managemailbox'][1] = array('ERROR', _('Unable to delete mailbox from IMAP server.')); $this->messages['managemailbox'][2] = array('ERROR', _('Unable to create mailbox on IMAP server.')); $this->messages['managemailbox'][3] = array('ERROR', _('Unable to locate mailbox on IMAP.')); $this->messages['managemailbox'][4] = array('ERROR', _('Your IMAP domains and email address domain do not match.')); $this->messages['managemailbox'][5] = array('ERROR', _('Invalid password for IMAP admin or other problem occured.')); $this->messages['managemailbox'][6] = array('WARN', _('Your LAM login password was not accepted by the IMAP server.')); $this->messages['managemailbox'][7] = array('ERROR', _('Cannot update quota.')); $this->messages['managemailbox'][8] = array('ERROR', _('Wrong quota format. Quota must be numeric.')); $this->messages['managemailbox'][9] = array('ERROR', _('Account %s:') . ' imapAccess_quota', _('Wrong quota format. Quota must be numeric.')); $this->messages['managemailbox'][10] = array('ERROR', _('Cannot read quota.')); $this->messages['createMailbox'][0] = array('ERROR', _('Account %s:') . ' imapAccess_createMailbox', _('This value can only be "true" or "false".')); } /** * Extracts user name and email address from inetOrgPerson/posixAccount/windowsUser modules. * * @param array $attrs LDAP attributes (retrieved from other account modules if empty) * @return htmlStatusMessage message if any */ private function extractUserAndEmail($attrs = null) { $this->email = ''; if ($attrs === null) { if ($this->getAccountContainer()->getAccountModule('inetOrgPerson') != null) { $attrs = $this->getAccountContainer()->getAccountModule('inetOrgPerson')->getAttributes(); } else { $attrs = $this->getAccountContainer()->getAccountModule('windowsUser')->getAttributes(); } if ($this->getAccountContainer()->getAccountModule('posixAccount') != null) { $attrs = array_merge($attrs, $this->getAccountContainer()->getAccountModule('posixAccount')->getAttributes()); } } $this->email = !empty($attrs['mail'][0]) ? $attrs['mail'][0] : ''; $this->user = ''; // extract user name from email address if (empty($this->moduleSettings['ImapAccess_UserNameAttribute'][0]) || $this->moduleSettings['ImapAccess_UserNameAttribute'][0] == 'mail') { $email_parts = explode('@', $this->email, 2); $this->user = array_shift($email_parts); } elseif ($this->moduleSettings['ImapAccess_UserNameAttribute'][0] == 'userPrincipalName') { if (!empty($attrs['userPrincipalName'][0])) { $parts = explode('@', $attrs['userPrincipalName'][0], 2); $this->user = array_shift($parts); } } // extract user name from Unix user name (might be in inetOrgPerson/windowUser or posixAccount module) else { $this->user = !empty($attrs['uid'][0]) ? $attrs['uid'][0] : ''; } if (empty($this->email)) { $modName = ($this->getAccountContainer()->getAccountModule('inetOrgPerson') != null) ? 'inetOrgPerson' : 'windowsUser'; return new htmlStatusMessage('INFO', _("Please enter an email address on this page: %s"), '', array($this->getAccountContainer()->getAccountModule($modName)->get_alias())); } } /** * @inheritDoc */ public function display_html_attributes() { $return = new htmlResponsiveRow(); if (!checkIfWriteAccessIsAllowed($this->get_scope())) { return $return; } $msg = $this->extractUserAndEmail(); if ($msg != null) { $return->add($msg, 12); return $return; } $prefix = $this->getMailboxPrefix(); $email_domain = substr(strstr($this->email, '@'), 1); $adminPassword = $this->getAdminPassword(); // check for password for fall back mechanism if (!isset($_SESSION['imapAdmPass']) && !isset($adminPassword)) { return $this->display_html_password(); } $return->addLabel(new htmlOutputText(_('Email address'))); $return->addField(new htmlOutputText($this->email)); $adminUser = $this->getAdminUser(); $adminPassword = $this->getAdminPassword(); try { $client = $this->connect($adminUser, $adminPassword); } catch (LAMException $e) { return $this->display_html_password(new htmlStatusMessage('ERROR', $e->getTitle(), $e->getMessage())); } $return->addLabel(new htmlOutputText(_('Mailbox'))); $mailboxGroup = new htmlGroup(); $mailboxGroup->addElement(new htmlOutputText($prefix . $this->getSep() . $this->user)); $mailboxGroup->addElement(new htmlHelpLink('MailAddress')); $return->addField($mailboxGroup); $return->addVerticalSpacer('2rem'); $list = $client->listMailboxes($prefix . $this->getSep() . $this->user, Horde_Imap_Client::MBOX_ALL); if (is_array($list) && sizeof($list) == 1) { $this->renderQuotasForMailbox($return, $client, $prefix . $this->getSep() . $this->user); $return->addVerticalSpacer('2rem'); $return->add(new htmlButton('deleteMailbox', _('Delete mailbox')), 12, 12, 12, 'text-center'); } else { $mailboxMessage = new htmlOutputText(_("Mailbox does not exist on IMAP server.")); $return->add($mailboxMessage, 12, 12, 12, 'text-center'); $return->addVerticalSpacer('2rem'); if ($this->isWrongDomain($email_domain)) { $return->add(new htmlStatusMessage('INFO', $this->messages['managemailbox'][4][1]), 12); $return->addVerticalSpacer('1rem'); } else { $createButton = new htmlButton('createMailbox', _('Create mailbox')); $return->add($createButton, 12, 12, 12, 'text-center'); } } $client->logout(); return $return; } /** * Returns the HTML meta data for the password page. * * @param htmlStatusMessage|null $message status message * @return htmlResponsiveRow HTML meta data */ function display_html_password($message = null) { $return = new htmlResponsiveRow(); if ($message !== null) { $return->add($message, 12); $return->addVerticalSpacer('1rem'); } $passwordInput = new htmlResponsiveInputField(_("Password of IMAP admin user"), 'ImapAdminPassword', '', 'ImapAdminPassword_Sess'); $passwordInput->setIsPassword(true); $passwordInput->setRequired(true); $passwordInput->setOnKeyPress('SubmitForm(\'enterPasswordButton\', event);'); $return->add($passwordInput, 12); $return->addVerticalSpacer('2rem'); $return->add(new htmlButton('enterPasswordButton', _('Ok')), 12, 12, 12, 'text-center'); return $return; } /** * Display the mailbox quota. * * @param htmlResponsiveRow $container structure that contained information to be displayed * @param Horde_Imap_Client_Socket $client IMAP client * @param String $username user name to connect to IMAP server * @return htmlResponsiveRow table with added information about user quotas or controls to add quota */ function renderQuotasForMailbox($container, $client, $username) { if (($this->profileQuotaLimit != null) && ($this->profileQuotaLimit != '')) { $client->setQuota($username, array('storage' => $this->profileQuotaLimit)); $this->profileQuotaLimit = null; } try { $quotaRoot = $client->getQuotaRoot($username); $quota_values = array(); if (!empty($quotaRoot)) { $quota_values = $client->getQuota($username); } if (!empty($quota_values)) { if (isset($quota_values['storage']) && is_array($quota_values['storage'])) { $quotaLimit = $quota_values['storage']['limit']; $container->addLabel(new htmlOutputText(_("Current usage (kB)"))); $container->addField(new htmlOutputText($quota_values['storage']['usage']), true); $quotaLimitInput = new htmlResponsiveInputField(_("Quota limit (kB)"), 'ImapUserQuotaLimit', $quotaLimit, 'ImapUserQuotaLimit'); $container->add($quotaLimitInput, 12); $container->addVerticalSpacer('2rem'); $container->add(new htmlButton('updateQuota', _('Update quota')), 12, 12, 12, 'text-center'); $container->addVerticalSpacer('1rem'); } } else { $quotaLimit = ""; $quotaLimitInput = new htmlResponsiveInputField(_("Quota limit (kB)"), 'ImapUserQuotaLimit', $quotaLimit, 'ImapUserQuotaLimit'); $container->add($quotaLimitInput, 12); $container->addVerticalSpacer('2rem'); $container->add(new htmlButton('updateQuota', _('Update quota')), 12, 12, 12, 'text-center'); $container->addVerticalSpacer('1rem'); } } catch (Exception $e) { $container->add(new htmlStatusMessage('ERROR', $this->messages['managemailbox'][10][1], $e->getMessage()), 12); } return $container; } /** * Processes user input of the primary module page. * It checks if all input values are correct and updates the associated LDAP attributes. * * @return array list of info/error messages */ function process_attributes() { $errors = array(); if (!checkIfWriteAccessIsAllowed($this->get_scope())) { return $errors; } $prefix = $this->getMailboxPrefix(); $user = $this->getAdminUser(); if (isset($_POST['ImapAdminPassword']) && isset($_POST['enterPasswordButton'])) { $errors = $this->doLogin(); } $password = $this->getAdminPassword(); try { $client = $this->connect($user, $password); $this->extractUserAndEmail(); $email_domain = substr(strstr($this->email, '@'), 1); if (isset($_POST['deleteMailbox'])) { if ($this->isWrongDomain($email_domain)) { $errors[] = $this->messages['managemailbox'][4]; } else { $root = $prefix . $this->getSep() . $this->user; try { $client->setACL($root, $user, array('rights' => 'c', 'action' => 'add')); $client->deleteMailbox($root); } catch (Exception $e) { $message = $this->messages['managemailbox'][1]; $message[] = $e->getMessage(); $errors[] = $message; } } } if (isset($_POST['createMailbox'])) { $createMessages = $this->createMailbox($client, $this->user, $email_domain); $errors = array_merge($errors, $createMessages); } if (isset($_POST['updateQuota'])) { $quota = $_POST['ImapUserQuotaLimit']; $quotaMessages = $this->setQuota($client, $this->user, $email_domain, $quota); $errors = array_merge($errors, $quotaMessages); } $client->logout(); } catch (LAMException $e) { return array(array('ERROR', $e->getTitle(), $e->getMessage())); } // Return error-messages return $errors; } /** * Creates the mailbox for a user. * * @param Horde_Imap_Client_Socket $client IMAP client * @param string $userName user name * @param string $email_domain email domain * @return array error messages */ private function createMailbox($client, $userName, $email_domain) { $errors = array(); $prefix = $this->getMailboxPrefix(); if ($this->isWrongDomain($email_domain)) { $errors[] = $this->messages['managemailbox'][4]; } else { $root = $prefix . $this->getSep() . $userName; logNewMessage(LOG_DEBUG, 'Creating mailbox: ' . $root); try { $client->createMailbox($root); logNewMessage(LOG_DEBUG, 'Mailbox created'); $list = $client->listMailboxes($root, Horde_Imap_Client::MBOX_ALL); if (empty($list)) { $errors[] = $this->messages['managemailbox'][3]; return $errors; } // create initial folders foreach ($this->getInitialFolders() as $folder) { $fullFolderName = $root . $this->getSep() . $folder; logNewMessage(LOG_DEBUG, 'Creating folder: ' . $fullFolderName); $client->createMailbox($fullFolderName); logNewMessage(LOG_DEBUG, 'Folder created: ' . $fullFolderName); } } catch (Exception $e) { $message = $this->messages['managemailbox'][2]; $message[] = $e->getMessage(); $errors[] = $message; } } return $errors; } /** * Sets the mailbox quota for a user. * * @param Horde_Imap_Client_Socket $client IMAP client * @param string $userName user name * @param string $email_domain email domain * @param string $quota mailbox quota * @return array error messages */ private function setQuota($client, $userName, $email_domain, $quota) { $prefix = $this->getMailboxPrefix(); $errors = array(); $root = $prefix . $this->getSep() . $userName; if ($this->isWrongDomain($email_domain)) { $errors[] = $this->messages['managemailbox'][4]; } else { if ($quota == '') { try { $client->setQuota($root, array('storage' => '-1')); } catch (Exception $e) { $message = $this->messages['managemailbox'][7]; $message[] = $e->getMessage(); $errors[] = $message; } } elseif (get_preg($quota, 'digit')) { logNewMessage(LOG_DEBUG, 'Setting quota ' . $quota . ' for ' . $root); try { $client->setQuota($root, array('storage' => $quota)); } catch (Exception $e) { $message = $this->messages['managemailbox'][7]; $message[] = $e->getMessage(); $errors[] = $message; } } else { $errors[] = $this->messages['managemailbox'][8]; } } return $errors; } /** * Loads the values of an account profile into internal variables. * * @param array $profile hash array with profile values (identifier => value) */ function load_profile($profile) { // profile mappings in meta data parent::load_profile($profile); if (isset($profile['ImapAccess_QuotaLimit'][0]) && $profile['ImapAccess_QuotaLimit'][0] != '') { $this->profileQuotaLimit = $profile['ImapAccess_QuotaLimit'][0]; } } /** * Returns a list of configuration options. * * @param array $scopes account types (user, group, host) * @param array $allScopes list of all active account modules and their scopes (module => array(scopes)) * @return mixed htmlElement or array of htmlElement * * @see htmlElement */ public function get_configOptions($scopes, $allScopes) { // configuration settings $configContainer = new htmlResponsiveRow(); $configServer = new htmlResponsiveInputField(_('Server address'), 'ImapAccess_ImapServerAddress', '', 'ImapServerAddress'); $configServer->setRequired(true); $configContainer->add($configServer, 12); $configContainer->add(new htmlResponsiveSelect('ImapAccess_ImapServerEncriptionProtocol', array('TLS', 'SSL'), array('TLS'), _("Encryption protocol"), 'ImapServerEncryptionProtocol'), 12); $configCertValidate = new htmlResponsiveSelect('ImapAccess_ImapValidateServerCert', array(_('Yes') => 'validate-cert', _('No') => 'novalidate-cert'), array('validate-cert'), _("Validate server certificate"), 'ImapValidateServerCert'); $configCertValidate->setHasDescriptiveElements(true); $configContainer->add($configCertValidate, 12); $configUser = new htmlResponsiveInputField(_('IMAP admin user'), 'ImapAccess_ImapAdmin', '', 'ImapAdmin'); $configUser->setRequired(true); $configContainer->add($configUser, 12); $pwdSelectOptions = array( _('LAM user password') => 'lam_user_pass', _('Ask') => 'ask_pass', _('Server profile') => 'config'); $configPasswordType = new htmlResponsiveSelect('ImapAccess_ImapAdminPasswordSelect', $pwdSelectOptions, array('ask_pass'), _("IMAP password input"), 'ImapAdminPasswordSelect'); $configPasswordType->setHasDescriptiveElements(true); $configPasswordType->setTableRowsToShow(array('config' => array('ImapAccess_ImapAdminPassword'))); $configPasswordType->setTableRowsToHide(array('lam_user_pass' => array('ImapAccess_ImapAdminPassword'), 'ask_pass' => array('ImapAccess_ImapAdminPassword'))); $configContainer->add($configPasswordType, 12); $adminPwdInput = new htmlResponsiveInputField(_('Admin password'), 'ImapAccess_ImapAdminPassword', null, 'ImapAdminPasswordSelect'); $adminPwdInput->setIsPassword(true); $adminPwdInput->setObfuscate(true); $configContainer->add($adminPwdInput, 12); $mailDomainsInput = new htmlResponsiveInputField(_('Mail domains'), 'ImapAccess_ImapDomain', '', 'ImapMailDomain'); $mailDomainsInput->setRequired(true); $configContainer->add($mailDomainsInput, 12); $configContainer->add(new htmlResponsiveInputField(_('Prefix for mailboxes'), 'ImapAccess_ImapUserPrefix', '', 'ImapUserPrefix'), 12); $configContainer->add(new htmlResponsiveInputTextarea('ImapAccess_initialFolders', '', 10, 3, _('Initial folders'), 'initialFolders'), 12); $configUserName = new htmlResponsiveSelect('ImapAccess_UserNameAttribute', array('mail', 'uid', 'userPrincipalName'), array('mail'), _("User name attribute"), 'ImapUserNameAttr'); $configContainer->add($configUserName, 12); $configPathSeparator = new htmlResponsiveSelect('ImapAccess_pathSeparator', array('.', '/'), array('.'), _("Path separator"), 'pathSeparator'); $configContainer->add($configPathSeparator, 12); return $configContainer; } /** * {@inheritDoc} * @see baseModule::check_configOptions() */ public function check_configOptions($typeIds, &$options) { $errors = parent::check_configOptions($typeIds, $options); if (($options['ImapAccess_ImapAdminPasswordSelect'][0] == 'config') && empty($options['ImapAccess_ImapAdminPassword'][0])) { $errors[] = $this->messages['config'][2]; } return $errors; } /** * Returns the user name of the IMAP admin. * * @return String admin user name */ private function getAdminUser() { if (isset($_SESSION['imapAdmUser'])) { return $_SESSION['imapAdmUser']; } $user = $this->moduleSettings['ImapAccess_ImapAdmin'][0]; // check if user name contains any wildcards that need to be replaced with LDAP attribute values $matches = array(); preg_match_all('/\\$[a-z0-9_-]+\\$/i', $this->moduleSettings['ImapAccess_ImapAdmin'][0], $matches); if (sizeof($matches) > 0) { // find wildcards $attrNames = array(); foreach ($matches as $match) { foreach ($match as $attr) { $attrNames[] = substr($attr, 1, -1); } } $attrNames = array_values(array_unique($attrNames)); $attrNames = array_change_key_case($attrNames, CASE_LOWER); // read LAM login user data $dn = $_SESSION['ldap']->getUserName(); $sr = @ldap_read($_SESSION['ldap']->server(), $dn, '(objectclass=*)', $attrNames, 0, 0, 0, LDAP_DEREF_NEVER); if ($sr) { $info = @ldap_get_entries($_SESSION['ldap']->server(), $sr); if ($info) { cleanLDAPResult($info); $info = $info[0]; } } // replace wildcards foreach ($attrNames as $attr) { if (empty($info[$attr])) { continue; } $user = preg_replace('/\\$' . $attr . '\\$/i', $info[$attr][0], $user); } } logNewMessage(LOG_DEBUG, 'IMAP admin user: ' . $user); $_SESSION['imapAdmUser'] = $user; return $user; } /** * Returns the admin password. * * @return String password */ private function getAdminPassword() { //perform admin password $password = null; //default value is null, it can be changed during the work if (isset($_SESSION['imapAdmPass'])) { $password = lamDecrypt($_SESSION['imapAdmPass']); } elseif (isset($this->moduleSettings['ImapAccess_ImapAdminPasswordSelect'][0]) && ($this->moduleSettings['ImapAccess_ImapAdminPasswordSelect'][0] == "lam_user_pass")) { $password = $_SESSION['ldap']->getPassword(); } elseif (!empty($this->moduleSettings['ImapAccess_ImapAdminPasswordSelect'][0]) && ($this->moduleSettings['ImapAccess_ImapAdminPasswordSelect'][0] == "config") && !empty($this->moduleSettings['ImapAccess_ImapAdminPassword'][0])) { $password = deobfuscateText($this->moduleSettings['ImapAccess_ImapAdminPassword'][0]); } return $password; } /** * Checks the password given by user and save it as session parameter. * * @return array list of error messages */ function doLogin() { $errors = array(); $adminUser = $this->getAdminUser(); if (isset($_POST['ImapAdminPassword']) && $_POST['ImapAdminPassword'] != "") { $adminPassword = $_POST['ImapAdminPassword']; try { $client = $this->connect($adminUser, $adminPassword); $_SESSION['imapAdmPass'] = lamEncrypt($_POST['ImapAdminPassword']); $client->logout(); } catch (LAMException $e) { $error = $this->messages['managemailbox'][5]; $error[] = $e->getMessage(); $errors[] = $error; } } return $errors; } /** * Connects to the IMAP server. * * @param string $user user name * @param string $password password * @return Horde_Imap_Client_Socket IMAP client */ private function connect($user, $password) { include_once __DIR__ . '/../3rdParty/composer/autoload.php'; $encryptionType = $this->moduleSettings['ImapAccess_ImapServerEncriptionProtocol'][0]; if (strrpos($this->moduleSettings['ImapAccess_ImapServerAddress'][0], ":")) { $port = substr(strstr($this->moduleSettings['ImapAccess_ImapServerAddress'][0], ':'), 1); $serverName = array_shift(explode(':', $this->moduleSettings['ImapAccess_ImapServerAddress'][0], 2)); } else { $serverName = $this->moduleSettings['ImapAccess_ImapServerAddress'][0]; if ($encryptionType === "TLS") { $port = 143; } else { $port = 993; } } $context = array( 'ssl' => array( 'cafile' => __DIR__ . '/../../serverCerts.pem' ) ); if (isset($this->moduleSettings['ImapAccess_ImapValidateServerCert'][0]) && ($this->moduleSettings['ImapAccess_ImapValidateServerCert'][0] == 'novalidate-cert')) { $context['ssl']['verify_peer'] = false; $context['ssl']['verify_peer_name'] = false; } try { $client = new Horde_Imap_Client_Socket(array( 'username' => $user, 'password' => $password, 'hostspec' => $serverName, 'port' => $port, 'secure' => strtolower($encryptionType), 'context' => $context )); $client->login(); return $client; } catch (Exception $e) { throw new LAMException(_('Unable to connect to IMAP server.'), $e->getMessage(), $e); } } /** * This function returns the prefix for mailboxes. * If no prefix was given during configuration then "user" will be used (default for Cyrus). * * @return String prefix */ function getMailboxPrefix() { if (!isset($this->moduleSettings['ImapAccess_ImapUserPrefix'][0]) || ($this->moduleSettings['ImapAccess_ImapUserPrefix'][0] == '')) { return "user"; } else { return $this->moduleSettings['ImapAccess_ImapUserPrefix'][0]; } } /** * This function checks if the domain of the mailbox is not in the list of domains listed in the configuration. * If it is in the list then it returns false, otherwise returns true. If the list of domains is not set then it returns true. * * @param String $email_domain email domain * @return boolean true if domains match */ function isWrongDomain($email_domain) { if (isset($this->moduleSettings['ImapAccess_ImapDomain'][0])) { $domain_list_string = $this->moduleSettings['ImapAccess_ImapDomain'][0]; if ($domain_list_string == '*') { return false; } $domains_array = explode(",", $domain_list_string); if ((sizeof($domains_array) == 0) || in_array($email_domain, $domains_array)) { return false; } } else { return false; } return true; } /** * Returns the path separator. * * @return String separator char */ private function getSep() { if (isset($this->moduleSettings['ImapAccess_pathSeparator'][0])) { return $this->moduleSettings['ImapAccess_pathSeparator'][0]; } return '.'; // default } /** * Returns the list of initial folders to create for a new mailbox. * * @return array list of folders */ private function getInitialFolders() { $list = array(); if (!empty($this->moduleSettings['ImapAccess_initialFolders'])) { foreach ($this->moduleSettings['ImapAccess_initialFolders'] as $folder) { $folder = trim($folder); if (!empty($folder)) { $list[] = $folder; } } } return $list; } /** * {@inheritDoc} * @see baseModule::get_uploadColumns() */ public function get_uploadColumns($selectedModules, &$type) { $pwd = $this->getAdminPassword(); if (empty($pwd)) { return array(); } return array( array( 'name' => 'imapAccess_createMailbox', 'description' => _('Create mailbox'), 'example' => 'false', 'default' => 'false', 'values' => 'true, false', 'help' => 'createMailbox' ), array( 'name' => 'imapAccess_quota', 'description' => _('Quota limit (kB)'), 'example' => '1000000', 'help' => 'ImapUserQuotaLimit' ), ); } /** * {@inheritDoc} * @see baseModule::build_uploadAccounts() */ public function build_uploadAccounts($rawAccounts, $ids, &$partialAccounts, $selectedModules, &$type) { $errors = array(); if (!isset($ids['imapAccess_createMailbox'])) { return $errors; } for ($i = 0; $i < sizeof($rawAccounts); $i++) { if (isset($rawAccounts[$i][$ids['imapAccess_createMailbox']]) && !in_array($rawAccounts[$i][$ids['imapAccess_createMailbox']], array('true', 'false'))) { $errMsg = $this->messages['createMailbox'][0]; array_push($errMsg, array($i)); $errors[] = $errMsg; } if (isset($rawAccounts[$i][$ids['imapAccess_createMailbox']]) && ($rawAccounts[$i][$ids['imapAccess_createMailbox']] === 'true') && !empty($ids['imapAccess_quota']) && isset($rawAccounts[$i][$ids['imapAccess_quota']]) && !get_preg($rawAccounts[$i][$ids['imapAccess_quota']], 'digit')) { $errMsg = $this->messages['managemailbox'][9]; array_push($errMsg, array($i)); $errors[] = $errMsg; } } return $errors; } /** * {@inheritDoc} * @see baseModule::doUploadPostActions() */ function doUploadPostActions(&$data, $ids, $failed, &$temp, &$accounts, $selectedModules, $type) { if (!checkIfWriteAccessIsAllowed($this->get_scope())) { die(); } // on first call generate list of IMAP operations if (!isset($temp['counter'])) { $temp['users'] = array(); $temp['counter'] = 0; $errors = array(); if (isset($ids['imapAccess_createMailbox'])) { foreach ($data as $i => $dataRow) { if (in_array($i, $failed)) { continue; // ignore failed accounts } if ($dataRow[$ids['imapAccess_createMailbox']] === 'true') { $limit = ''; if (isset($ids['imapAccess_quota']) && isset($dataRow[$ids['imapAccess_quota']]) && ($dataRow[$ids['imapAccess_quota']] !== '')) { $limit = $dataRow[$ids['imapAccess_quota']]; } $attributes = $accounts[$i]; foreach ($attributes as $name => $value) { if (!is_array($value)) { $attributes[$name] = array($value); } } $extractErrors = $this->extractUserAndEmail($attributes); if (!empty($extractErrors)) { $errors = array_merge($errors, $extractErrors); } $temp['users'][] = array( 'uid' => $this->user, 'limit' => $limit, 'email' => substr(strstr($this->email, '@'), 1) ); } } } return array( 'status' => 'inProgress', 'progress' => 0, 'errors' => $errors ); } // add mailbox elseif ($temp['counter'] < sizeof($temp['users'])) { $errors = array(); $data = $temp['users'][$temp['counter']]; $uid = $data['uid']; $limit = $data['limit']; $email_domain = $data['email']; ob_start(); $imapUser = $this->getAdminUser(); $imapPassword = $this->getAdminPassword(); try { $client = $this->connect($imapUser, $imapPassword); $prefix = $this->getMailboxPrefix(); $list = $client->listMailboxes($prefix . $this->getSep() . $uid); if (empty($list)) { $createErrors = $this->createMailbox($client, $uid, $email_domain); $errors = array_merge($errors, $createErrors); if (empty($createErrors)) { $quotaErrors = $this->setQuota($client, $uid, $email_domain, $limit); $errors = array_merge($errors, $quotaErrors); } } $client->logout(); } catch (Exception $e) { $message = $this->messages['managemailbox'][5]; $message[] = $e->getMessage(); $errors[] = $message; } ob_end_clean(); $temp['counter']++; return array ( 'status' => 'inProgress', 'progress' => ($temp['counter'] * 100) / sizeof($temp['users']), 'errors' => $errors ); } // all modifications are done else { return array ( 'status' => 'finished', 'progress' => 100, 'errors' => array() ); } } }