/** * Modify user preferences * * @param string Option name * @param string Option value * @param int Optional user identifier * @param string Optional value type (bool, int, string) */ public static function mod_pref($name, $value, $userid = null, $type = 'string') { $db = self::db(); if ($userid) { $query = '`user_id` = ' . intval($userid); } else { $query = '1=1'; } $type = strtolower($type); if ($type == 'bool' || $type == 'boolean') { $value = rcube_utils::get_boolean($value); } else { if ($type == 'int' || $type == 'integer') { $value = (int) $value; } } // iterate over all users $sql_result = $db->query("SELECT * FROM " . $db->table_name('users', true) . " WHERE {$query}"); while ($sql_result && ($sql_arr = $db->fetch_assoc($sql_result))) { echo "Updating prefs for user " . $sql_arr['user_id'] . "..."; $user = new rcube_user($sql_arr['user_id'], $sql_arr); $prefs = $old_prefs = $user->get_prefs(); $prefs[$name] = $value; if ($prefs != $old_prefs) { $user->save_prefs($prefs, true); echo "saved.\n"; } else { echo "nothing changed.\n"; } } }
public function init() { $rcmail = rcmail::get_instance(); $this->load_config(); $this->user_name = $rcmail->config->get('globaladdressbook_user'); $this->user_name = str_replace('%d', $rcmail->user->get_username('domain'), $this->user_name); $this->user_name = str_replace('%h', $_SESSION['imap_host'], $this->user_name); $this->readonly = $this->_is_readonly(); $this->groups = $rcmail->config->get('globaladdressbook_groups', false); // check if the global address book user exists if (!($user = rcube_user::query($this->user_name, $this->host))) { // this action overrides the current user information so make a copy and then restore it $cur_user = $rcmail->user; $user = rcube_user::create($this->user_name, $this->host); $rcmail->user = $cur_user; // prevent new_user_dialog plugin from triggering $_SESSION['plugin.newuserdialog'] = false; } $this->user_id = $user->ID; // use this address book for autocompletion queries if ($rcmail->config->get('globaladdressbook_autocomplete')) { $sources = $rcmail->config->get('autocomplete_addressbooks', array('sql')); if (!in_array($this->abook_id, $sources)) { $sources[] = $this->abook_id; $rcmail->config->set('autocomplete_addressbooks', $sources); } } $this->add_hook('addressbooks_list', array($this, 'address_sources')); $this->add_hook('addressbook_get', array($this, 'get_address_book')); }
/** * Destroy session data and remove cookie */ public function kill_session() { $this->plugins->exec_hook('session_destroy'); $this->session->remove(); $_SESSION = array('language' => $this->user->language, 'auth_time' => time(), 'temp' => true); rcmail::setcookie('sessauth', '-del-', time() - 60); $this->user->reset(); }
public function init() { $rcmail = rcube::get_instance(); $this->load_config(); $this->add_texts('localization/'); $this->user_name = $rcmail->config->get('globaladdressbook_user', '[global_addressbook_user]'); $this->user_name = str_replace('%d', $rcmail->user->get_username('domain'), $this->user_name); $this->user_name = str_replace('%h', $_SESSION['storage_host'], $this->user_name); $this->groups = $rcmail->config->get('globaladdressbook_groups', false); $this->name = $this->gettext('globaladdressbook'); $this->_set_permissions(); // email2user hook can be used by other plugins to do post processing on usernames, not just virtual user lookup // matches process of user lookup and creation in the core if (strpos($this->user_name, '@') && ($virtuser = rcube_user::email2user($this->user_name))) { $this->user_name = $virtuser; } // check if the global address book user exists if (!($user = rcube_user::query($this->user_name, $this->host))) { // this action overrides the current user information so make a copy and then restore it $cur_user = $rcmail->user; $user = rcube_user::create($this->user_name, $this->host); $rcmail->user = $cur_user; // prevent new_user_dialog plugin from triggering $_SESSION['plugin.newuserdialog'] = false; } $this->user_id = $user->ID; // use this address book for autocompletion queries if ($rcmail->config->get('globaladdressbook_autocomplete')) { $sources = $rcmail->config->get('autocomplete_addressbooks', array('sql')); if (!in_array($this->abook_id, $sources)) { $sources[] = $this->abook_id; $rcmail->config->set('autocomplete_addressbooks', $sources); } } $this->add_hook('addressbooks_list', array($this, 'address_sources')); $this->add_hook('addressbook_get', array($this, 'get_address_book')); if ($rcmail->config->get('globaladdressbook_check_safe')) { $this->add_hook('message_check_safe', array($this, 'check_known_senders')); } }
/** * Fixes some user preferences according to namespace handling change. * Old Roundcube versions were using folder names with removed namespace prefix. * Now we need to add the prefix on servers where personal namespace has prefix. * * @param rcube_user $user User object */ private function fix_namespace_settings($user) { $prefix = $this->storage->get_namespace('prefix'); $prefix_len = strlen($prefix); if (!$prefix_len) { return; } if ($this->config->get('namespace_fixed')) { return; } $prefs = array(); // Build namespace prefix regexp $ns = $this->storage->get_namespace(); $regexp = array(); foreach ($ns as $entry) { if (!empty($entry)) { foreach ($entry as $item) { if (strlen($item[0])) { $regexp[] = preg_quote($item[0], '/'); } } } } $regexp = '/^(' . implode('|', $regexp) . ')/'; // Fix preferences $opts = array('drafts_mbox', 'junk_mbox', 'sent_mbox', 'trash_mbox', 'archive_mbox'); foreach ($opts as $opt) { if ($value = $this->config->get($opt)) { if ($value != 'INBOX' && !preg_match($regexp, $value)) { $prefs[$opt] = $prefix . $value; } } } if (($search_mods = $this->config->get('search_mods')) && !empty($search_mods)) { $folders = array(); foreach ($search_mods as $idx => $value) { if ($idx != 'INBOX' && $idx != '*' && !preg_match($regexp, $idx)) { $idx = $prefix . $idx; } $folders[$idx] = $value; } $prefs['search_mods'] = $folders; } if (($threading = $this->config->get('message_threading')) && !empty($threading)) { $folders = array(); foreach ($threading as $idx => $value) { if ($idx != 'INBOX' && !preg_match($regexp, $idx)) { $idx = $prefix . $idx; } $folders[$prefix . $idx] = $value; } $prefs['message_threading'] = $folders; } if ($collapsed = $this->config->get('collapsed_folders')) { $folders = explode('&&', $collapsed); $count = count($folders); $folders_str = ''; if ($count) { $folders[0] = substr($folders[0], 1); $folders[$count - 1] = substr($folders[$count - 1], 0, -1); } foreach ($folders as $value) { if ($value != 'INBOX' && !preg_match($regexp, $value)) { $value = $prefix . $value; } $folders_str .= '&' . $value . '&'; } $prefs['collapsed_folders'] = $folders_str; } $prefs['namespace_fixed'] = true; // save updated preferences and reset imap settings (default folders) $user->save_prefs($prefs); $this->set_storage_prop(); }
/** * Send the given message using the configured method. * * @param object $message Reference to Mail_MIME object * @param string $from Sender address string * @param array $mailto Array of recipient address strings * @param array $error SMTP error array (reference) * @param string $body_file Location of file with saved message body (reference), * used when delay_file_io is enabled * @param array $options SMTP options (e.g. DSN request) * * @return boolean Send status. */ public function deliver_message(&$message, $from, $mailto, &$error, &$body_file = null, $options = null) { $plugin = $this->plugins->exec_hook('message_before_send', array('message' => $message, 'from' => $from, 'mailto' => $mailto, 'options' => $options)); if ($plugin['abort']) { if (!empty($plugin['error'])) { $error = $plugin['error']; } if (!empty($plugin['body_file'])) { $body_file = $plugin['body_file']; } return isset($plugin['result']) ? $plugin['result'] : false; } $from = $plugin['from']; $mailto = $plugin['mailto']; $options = $plugin['options']; $message = $plugin['message']; $headers = $message->headers(); // send thru SMTP server using custom SMTP library if ($this->config->get('smtp_server')) { // generate list of recipients $a_recipients = (array) $mailto; if (strlen($headers['Cc'])) { $a_recipients[] = $headers['Cc']; } if (strlen($headers['Bcc'])) { $a_recipients[] = $headers['Bcc']; } // clean Bcc from header for recipients $send_headers = $headers; unset($send_headers['Bcc']); // here too, it because txtHeaders() below use $message->_headers not only $send_headers unset($message->_headers['Bcc']); $smtp_headers = $message->txtHeaders($send_headers, true); if ($message->getParam('delay_file_io')) { // use common temp dir $temp_dir = $this->config->get('temp_dir'); $body_file = tempnam($temp_dir, 'rcmMsg'); if (PEAR::isError($mime_result = $message->saveMessageBody($body_file))) { self::raise_error(array('code' => 650, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Could not create message: " . $mime_result->getMessage()), TRUE, FALSE); return false; } $msg_body = fopen($body_file, 'r'); } else { $msg_body = $message->get(); } // send message if (!is_object($this->smtp)) { $this->smtp_init(true); } $sent = $this->smtp->send_mail($from, $a_recipients, $smtp_headers, $msg_body, $options); $response = $this->smtp->get_response(); $error = $this->smtp->get_error(); // log error if (!$sent) { self::raise_error(array('code' => 800, 'type' => 'smtp', 'line' => __LINE__, 'file' => __FILE__, 'message' => join("\n", $response)), true, false); } } else { // unset some headers because they will be added by the mail() function $headers_enc = $message->headers($headers); $headers_php = $message->_headers; unset($headers_php['To'], $headers_php['Subject']); // reset stored headers and overwrite $message->_headers = array(); $header_str = $message->txtHeaders($headers_php); // #1485779 if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { if (preg_match_all('/<([^@]+@[^>]+)>/', $headers_enc['To'], $m)) { $headers_enc['To'] = implode(', ', $m[1]); } } $msg_body = $message->get(); if (PEAR::isError($msg_body)) { self::raise_error(array('code' => 650, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Could not create message: " . $msg_body->getMessage()), TRUE, FALSE); } else { $delim = $this->config->header_delimiter(); $to = $headers_enc['To']; $subject = $headers_enc['Subject']; $header_str = rtrim($header_str); if ($delim != "\r\n") { $header_str = str_replace("\r\n", $delim, $header_str); $msg_body = str_replace("\r\n", $delim, $msg_body); $to = str_replace("\r\n", $delim, $to); $subject = str_replace("\r\n", $delim, $subject); } if (filter_var(ini_get('safe_mode'), FILTER_VALIDATE_BOOLEAN)) { $sent = mail($to, $subject, $msg_body, $header_str); } else { $sent = mail($to, $subject, $msg_body, $header_str, "-f{$from}"); } } } if ($sent) { $this->plugins->exec_hook('message_sent', array('headers' => $headers, 'body' => $msg_body)); // remove MDN headers after sending unset($headers['Return-Receipt-To'], $headers['Disposition-Notification-To']); if ($this->config->get('smtp_log')) { // get all recipient addresses if (is_array($mailto)) { $mailto = implode(',', $mailto); } if ($headers['Cc']) { $mailto .= ',' . $headers['Cc']; } if ($headers['Bcc']) { $mailto .= ',' . $headers['Bcc']; } $mailto = rcube_mime::decode_address_list($mailto, null, false, null, true); self::write_log('sendmail', sprintf("User %s [%s]; Message for %s; %s", $this->user->get_username(), rcube_utils::remote_addr(), implode(', ', $mailto), !empty($response) ? join('; ', $response) : '')); } } else { // allow plugins to catch sending errors with the same parameters as in 'message_before_send' $this->plugins->exec_hook('message_send_error', $plugin + array('error' => $error)); } if (is_resource($msg_body)) { fclose($msg_body); } $message->_headers = array(); $message->headers($headers); return $sent; }
/** * Perfom login to the IMAP server and to the webmail service. * This will also create a new user entry if auto_create_user is configured. * * @param string IMAP user name * @param string IMAP password * @param string IMAP host * @return boolean True on success, False on failure */ function login($username, $pass, $host = NULL) { $user = NULL; $config = $this->config->all(); if (!$host) { $host = $config['default_host']; } // Validate that selected host is in the list of configured hosts if (is_array($config['default_host'])) { $allowed = false; foreach ($config['default_host'] as $key => $host_allowed) { if (!is_numeric($key)) { $host_allowed = $key; } if ($host == $host_allowed) { $allowed = true; break; } } if (!$allowed) { return false; } } else { if (!empty($config['default_host']) && $host != $config['default_host']) { return false; } } // parse $host URL $a_host = parse_url($host); if ($a_host['host']) { $host = $a_host['host']; $imap_ssl = isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl', 'imaps', 'tls')) ? $a_host['scheme'] : null; $imap_port = isset($a_host['port']) ? $a_host['port'] : ($imap_ssl ? 993 : $config['default_port']); } else { $imap_port = $config['default_port']; } /* Modify username with domain if required Inspired by Marco <P0L0_notspam_binware.org> */ // Check if we need to add domain if (!empty($config['username_domain']) && !strpos($username, '@')) { if (is_array($config['username_domain']) && isset($config['username_domain'][$host])) { $username .= '@' . $config['username_domain'][$host]; } else { if (is_string($config['username_domain'])) { $username .= '@' . $config['username_domain']; } } } // try to resolve email address from virtuser table if (!empty($config['virtuser_file']) && strpos($username, '@')) { $username = rcube_user::email2user($username); } // lowercase username if it's an e-mail address (#1484473) if (strpos($username, '@')) { $username = rc_strtolower($username); } // user already registered -> overwrite username if ($user = rcube_user::query($username, $host)) { $username = $user->data['username']; } // exit if IMAP login failed if (!($imap_login = $this->imap->connect($host, $username, $pass, $imap_port, $imap_ssl))) { return false; } // user already registered -> update user's record if (is_object($user)) { $user->touch(); } else { if ($config['auto_create_user']) { if ($created = rcube_user::create($username, $host)) { $user = $created; // get existing mailboxes (but why?) // $a_mailboxes = $this->imap->list_mailboxes(); } } else { raise_error(array('code' => 600, 'type' => 'php', 'file' => RCMAIL_CONFIG_DIR . "/main.inc.php", 'message' => "Acces denied for new user {$username}. 'auto_create_user' is disabled"), true, false); } } // login succeeded if (is_object($user) && $user->ID) { $this->set_user($user); // set session vars $_SESSION['user_id'] = $user->ID; $_SESSION['username'] = $user->data['username']; $_SESSION['imap_host'] = $host; $_SESSION['imap_port'] = $imap_port; $_SESSION['imap_ssl'] = $imap_ssl; $_SESSION['password'] = $this->encrypt_passwd($pass); $_SESSION['login_time'] = mktime(); if ($_REQUEST['_timezone'] != '_default_') { $_SESSION['timezone'] = floatval($_REQUEST['_timezone']); } // force reloading complete list of subscribed mailboxes $this->set_imap_prop(); $this->imap->clear_cache('mailboxes'); if ($config['create_default_folders']) { $this->imap->create_default_folders(); } return true; } return false; }
/** * Send the given message using the configured method. * * @param object $message Reference to Mail_MIME object * @param string $from Sender address string * @param array $mailto Array of recipient address strings * @param array $error SMTP error array (reference) * @param string $body_file Location of file with saved message body (reference), * used when delay_file_io is enabled * @param array $options SMTP options (e.g. DSN request) * @param bool $disconnect Close SMTP connection ASAP * * @return boolean Send status. */ public function deliver_message(&$message, $from, $mailto, &$error, &$body_file = null, $options = null, $disconnect = false) { $plugin = $this->plugins->exec_hook('message_before_send', array('message' => $message, 'from' => $from, 'mailto' => $mailto, 'options' => $options)); if ($plugin['abort']) { if (!empty($plugin['error'])) { $error = $plugin['error']; } if (!empty($plugin['body_file'])) { $body_file = $plugin['body_file']; } return isset($plugin['result']) ? $plugin['result'] : false; } $from = $plugin['from']; $mailto = $plugin['mailto']; $options = $plugin['options']; $message = $plugin['message']; $headers = $message->headers(); // generate list of recipients $a_recipients = (array) $mailto; if (strlen($headers['Cc'])) { $a_recipients[] = $headers['Cc']; } if (strlen($headers['Bcc'])) { $a_recipients[] = $headers['Bcc']; } // remove Bcc header and get the whole head of the message as string $smtp_headers = $message->txtHeaders(array('Bcc' => null), true); if ($message->getParam('delay_file_io')) { // use common temp dir $temp_dir = $this->config->get('temp_dir'); $body_file = tempnam($temp_dir, 'rcmMsg'); $mime_result = $message->saveMessageBody($body_file); if (is_a($mime_result, 'PEAR_Error')) { self::raise_error(array('code' => 650, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Could not create message: " . $mime_result->getMessage()), true, false); return false; } $msg_body = fopen($body_file, 'r'); } else { $msg_body = $message->get(); } // initialize SMTP connection if (!is_object($this->smtp)) { $this->smtp_init(true); } // send message $sent = $this->smtp->send_mail($from, $a_recipients, $smtp_headers, $msg_body, $options); $response = $this->smtp->get_response(); $error = $this->smtp->get_error(); if (!$sent) { self::raise_error(array('code' => 800, 'type' => 'smtp', 'line' => __LINE__, 'file' => __FILE__, 'message' => join("\n", $response)), true, false); // allow plugins to catch sending errors with the same parameters as in 'message_before_send' $this->plugins->exec_hook('message_send_error', $plugin + array('error' => $error)); } else { $this->plugins->exec_hook('message_sent', array('headers' => $headers, 'body' => $msg_body)); // remove MDN headers after sending unset($headers['Return-Receipt-To'], $headers['Disposition-Notification-To']); if ($this->config->get('smtp_log')) { // get all recipient addresses $mailto = implode(',', $a_recipients); $mailto = rcube_mime::decode_address_list($mailto, null, false, null, true); self::write_log('sendmail', sprintf("User %s [%s]; Message for %s; %s", $this->user->get_username(), rcube_utils::remote_addr(), implode(', ', $mailto), !empty($response) ? join('; ', $response) : '')); } } if (is_resource($msg_body)) { fclose($msg_body); } if ($disconnect) { $this->smtp->disconnect(); } $message->headers($headers, true); return $sent; }