diff --git a/include/api.tickets.php b/include/api.tickets.php
index 55dc5cf1ea6ceccd93a54fb51e7a5467ff7c6991..7268d0ffabaacedf3707c9a50071a955b17809e0 100644
--- a/include/api.tickets.php
+++ b/include/api.tickets.php
@@ -72,6 +72,15 @@ class TicketApiController extends ApiController {
                     if(!($attachment['data'] = base64_decode($attachment['data'], true)))
                         $attachment['error'] = sprintf('%s: Poorly encoded base64 data', Format::htmlchars($attachment['name']));
                 }
+                if (!$attachment['error']
+                        && ($size = $ost->getConfig()->getMaxFileSize())
+                        && ($fsize = $attachment['size'] ?: strlen($attachment['data']))
+                        && $fsize > $size) {
+                    $attachment['error'] = sprintf('File %s (%s) is too big. Maximum of %s allowed',
+                            Format::htmlchars($attachment['name']),
+                            Format::file_size($fsize),
+                            Format::file_size($size));
+                }
             }
             unset($attachment);
         }
diff --git a/include/class.mailer.php b/include/class.mailer.php
index c80421fcb798e51b2aa7011c902e78f9d6e30615..1c43398bcf4d3af04540fdbe6c01fbc181d2f2e2 100644
--- a/include/class.mailer.php
+++ b/include/class.mailer.php
@@ -206,21 +206,38 @@ class Mailer {
         $body = $mime->get($encodings);
         //encode the headers.
         $headers = $mime->headers($headers, true);
+
+        // Cache smtp connections made during this request
+        static $smtp_connections = array();
         if(($smtp=$this->getSMTPInfo())) { //Send via SMTP
-            $mail = mail::factory('smtp',
-                    array ('host' => $smtp['host'],
-                           'port' => $smtp['port'],
-                           'auth' => $smtp['auth'],
-                           'username' => $smtp['username'],
-                           'password' => $smtp['password'],
-                           'timeout'  => 20,
-                           'debug' => false,
-                           ));
+            $key = sprintf("%s:%s:%s", $smtp['host'], $smtp['port'],
+                $smtp['username']);
+            if (!isset($smtp_connections[$key])) {
+                $mail = mail::factory('smtp', array(
+                    'host' => $smtp['host'],
+                    'port' => $smtp['port'],
+                    'auth' => $smtp['auth'],
+                    'username' => $smtp['username'],
+                    'password' => $smtp['password'],
+                    'timeout'  => 20,
+                    'debug' => false,
+                    'persist' => true,
+                ));
+                if ($mail->connect())
+                    $smtp_connections[$key] = $mail;
+            }
+            else {
+                // Use persistent connection
+                $mail = $smtp_connections[$key];
+            }
 
             $result = $mail->send($to, $headers, $body);
             if(!PEAR::isError($result))
                 return $messageId;
 
+            // Force reconnect on next ->send()
+            unset($smtp_connections[$key]);
+
             $alert=sprintf("Unable to email via SMTP:%s:%d [%s]\n\n%s\n",
                     $smtp['host'], $smtp['port'], $smtp['username'], $result->getMessage());
             $this->logError($alert);
diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php
index 0c24fa72cfa1ee11b27a16c25f908692b2b8d2b8..73ac6184521639c58142324c269127d185b51c0f 100644
--- a/include/class.mailfetch.php
+++ b/include/class.mailfetch.php
@@ -20,6 +20,7 @@ require_once(INCLUDE_DIR.'class.dept.php');
 require_once(INCLUDE_DIR.'class.email.php');
 require_once(INCLUDE_DIR.'class.filter.php');
 require_once(INCLUDE_DIR.'html2text.php');
+require_once(INCLUDE_DIR.'tnef_decoder.php');
 
 class MailFetcher {
 
@@ -30,6 +31,8 @@ class MailFetcher {
 
     var $charset = 'UTF-8';
 
+    var $tnef = false;
+
     function MailFetcher($email, $charset='UTF-8') {
 
 
@@ -290,10 +293,21 @@ class MailFetcher {
         if($headerinfo->cc)
             $tolist['cc'] = $headerinfo->cc;
 
+        //Add delivered-to address to list.
+        if (stripos($header['header'], 'delivered-to:') !==false
+                && ($dt = Mail_Parse::findHeaderEntry($header['header'],
+                     'delivered-to', true))) {
+            if (($delivered_to = Mail_Parse::parseAddressList($dt)))
+                $tolist['delivered-to'] = $delivered_to;
+        }
+
         $header['recipients'] = array();
         foreach($tolist as $source => $list) {
             foreach($list as $addr) {
-                if(!($emailId=Email::getIdByEmail(strtolower($addr->mailbox).'@'.$addr->host))) {
+                if (!($emailId=Email::getIdByEmail(strtolower($addr->mailbox).'@'.$addr->host))) {
+                    //Skip virtual Delivered-To addresses
+                    if ($source == 'delivered-to') continue;
+
                     $header['recipients'][] = array(
                             'source' => "Email ($source)",
                             'name' => $this->mime_decode(@$addr->personal),
@@ -304,6 +318,16 @@ class MailFetcher {
             }
         }
 
+        //See if any of the recipients is a delivered to address
+        if ($tolist['delivered-to']) {
+            foreach ($tolist['delivered-to'] as $addr) {
+                foreach ($header['recipients'] as $i => $r) {
+                    if (strcasecmp($r['email'], $addr->mailbox.'@'.$addr->host) === 0)
+                        $header['recipients'][$i]['source'] = 'delivered-to';
+                }
+            }
+        }
+
         //BCCed?
         if(!$header['emailId']) {
             if ($headerinfo->bcc) {
@@ -356,6 +380,10 @@ class MailFetcher {
             }
         }
 
+        if ($this->tnef && !strcasecmp($mimeType, 'text/html')
+                && ($content = $this->tnef->getBody('text/html', $encoding)))
+            return $content;
+
         //Do recursive search
         $text='';
         if($struct && $struct->parts && $recurse) {
@@ -491,6 +519,10 @@ class MailFetcher {
     }
 
     function getPriority($mid) {
+        if ($this->tnef && isset($this->tnef->Importance))
+            // PidTagImportance is 0, 1, or 2
+            // http://msdn.microsoft.com/en-us/library/ee237166(v=exchg.80).aspx
+            return $this->tnef->Importance + 1;
         return Mail_Parse::parsePriority($this->getHeader($mid));
     }
 
@@ -549,6 +581,23 @@ class MailFetcher {
 	        return true; //Report success (moved or delete)
         }
 
+        // Parse MS TNEF emails
+        if (($struct = imap_fetchstructure($this->mbox, $mid))
+                && ($attachments = $this->getAttachments($struct))) {
+            foreach ($attachments as $i=>$info) {
+                if (0 === strcasecmp('application/ms-tnef', $info['type'])) {
+                    $data = $this->decode(imap_fetchbody($self->mbox,
+                        $mid, $info['index']), $info['encoding']);
+                    $tnef = new TnefStreamParser($data);
+                    $this->tnef = $tnef->getMessage();
+                    // No longer considered an attachment
+                    unset($attachments[$i]);
+                    // There should only be one of these
+                    break;
+                }
+            }
+        }
+
         $vars = $mailinfo;
         $vars['name'] = $mailinfo['name'];
         $vars['subject'] = $mailinfo['subject'] ? $mailinfo['subject'] : '[No Subject]';
@@ -583,10 +632,18 @@ class MailFetcher {
         $seen = false;
 
         // Fetch attachments if any.
-        if($ost->getConfig()->allowEmailAttachments()
-                && ($struct = imap_fetchstructure($this->mbox, $mid))
-                && ($attachments=$this->getAttachments($struct))) {
-
+        if($ost->getConfig()->allowEmailAttachments()) {
+            // Include TNEF attachments in the attachments list
+            if ($this->tnef) {
+                foreach ($this->tnef->attachments as $at) {
+                    $attachments[] = array(
+                        'cid' => @$at->AttachContentId ?: false,
+                        'data' => $at->Data,
+                        'type' => @$at->AttachMimeTag ?: false,
+                        'name' => $at->getName(),
+                    );
+                }
+            }
             $vars['attachments'] = array();
             foreach($attachments as $a ) {
                 $file = array('name' => $a['name'], 'type' => $a['type']);
diff --git a/include/class.mailparse.php b/include/class.mailparse.php
index 9b1e669715223d8d9a0a48b9e3834ca4184c6685..6883cdaf6a7560437c4ee0fcc5a00886bf111004 100644
--- a/include/class.mailparse.php
+++ b/include/class.mailparse.php
@@ -163,9 +163,9 @@ class Mail_Parse {
     }
 
     /* static */
-    function findHeaderEntry($headers, $name) {
+    function findHeaderEntry($headers, $name, $allEntries=false) {
         if (!is_array($headers))
-            $headers = self::splitHeaders($headers);
+            $headers = self::splitHeaders($headers, $allEntries);
         foreach ($headers as $key=>$val)
             if (strcasecmp($key, $name) === 0)
                 return $val;
@@ -400,7 +400,6 @@ class Mail_Parse {
                     'data' => $at->Data,
                     'type' => @$at->AttachMimeTag ?: false,
                     'name' => $at->getName(),
-                    'encoding' => @$at->AttachEncoding ?: false,
                 );
             }
             return $files;
diff --git a/include/class.ostsession.php b/include/class.ostsession.php
index db51e89e771caaaff6fe9bdb1d3e2808b96e548c..beb344f9f3734f5e286e9d2e4aff0060d6406cb2 100644
--- a/include/class.ostsession.php
+++ b/include/class.ostsession.php
@@ -26,8 +26,12 @@ class osTicketSession {
         if(!$this->ttl)
             $this->ttl=SESSION_TTL;
 
+        // Set osTicket specific session name.
         session_name('OSTSESSID');
 
+        // Forced cleanup on shutdown
+        register_shutdown_function('session_write_close');
+
         if (OsticketConfig::getDBVersion())
             return session_start();
 
@@ -56,8 +60,6 @@ class osTicketSession {
             array(&$this, 'destroy'),
             array(&$this, 'gc')
         );
-        //Forced cleanup.
-        register_shutdown_function('session_write_close');
 
         //Start the session.
         session_start();
diff --git a/include/class.staff.php b/include/class.staff.php
index 217b36c50c17babcaae390ba5ca492057790fd02..1334a785dcc88761e10e2c68bca1a3489d62e361 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -137,6 +137,10 @@ class Staff extends AuthenticatedUser {
         return $this->check_passwd($password, false);
     }
 
+    function hasPassword() {
+        return (bool) $this->ht['passwd'];
+    }
+
     function forcePasswdRest() {
         return db_query('UPDATE '.STAFF_TABLE.' SET change_passwd=1 WHERE staff_id='.db_input($this->getId()));
     }
@@ -862,6 +866,8 @@ class Staff extends AuthenticatedUser {
             if(isset($vars['change_passwd']))
                 $sql.=' ,change_passwd=1';
         }
+        elseif (!isset($vars['change_passwd']))
+            $sql .= ' ,change_passwd=0';
 
         if($id) {
             $sql='UPDATE '.STAFF_TABLE.' '.$sql.' WHERE staff_id='.db_input($id);
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 855d4650431164713b28c85ee2390e4482c7f258..df83644a8da74e58bda87435ab10701eb9adf1a2 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -2234,6 +2234,10 @@ class Ticket {
         # function
         if (isset($vars['autorespond'])) $autorespond=$vars['autorespond'];
 
+        # Apply filter-specific priority
+        if ($vars['priorityId'])
+            $form->setAnswer('priority', null, $vars['priorityId']);
+
         // OK...just do it.
         $deptId=$vars['deptId']; //pre-selected Dept if any.
         $source=ucfirst($vars['source']);
diff --git a/include/tnef_decoder.php b/include/tnef_decoder.php
index f0eba4e792914621fefbbbdf4f2f1cd5f9c94e76..18e95d697c5eba8bb218ff81d5e9c903b2cedbd7 100644
--- a/include/tnef_decoder.php
+++ b/include/tnef_decoder.php
@@ -110,10 +110,13 @@ class TnefStreamReader implements Iterator {
     }
 
     function check($block) {
-        $sum = 0;
-        for ($i=0, $k=strlen($block['data']); $i < $k; $i++)
-            $sum += ord($block['data'][$i]);
-        if ($block['checksum'] != ($sum % 65536))
+        $sum = 0; $bytes = strlen($block['data']); $bs = 1024;
+        for ($i=0; $i < $bytes; $i+=$bs) {
+            $b = unpack('C*', substr($block['data'], $i, min($bs, $bytes-$i)));
+            $sum += array_sum($b);
+            $sum = $sum % 65536;
+        }
+        if ($block['checksum'] != $sum)
             throw new TnefException('Corrupted block. Invalid checksum');
     }
 
diff --git a/scp/pwreset.php b/scp/pwreset.php
index 6d749e2d5fe8c3b882bf2e0ffb1f012a046d3636..735765b05b0e780cfe7e0f704d72f748f2466ee8 100644
--- a/scp/pwreset.php
+++ b/scp/pwreset.php
@@ -36,7 +36,10 @@ if($_POST) {
     switch ($_POST['do']) {
         case 'sendmail':
             if (($staff=Staff::lookup($_POST['userid']))) {
-                if (!$staff->sendResetEmail()) {
+                if (!$staff->hasPassword()) {
+                    $msg = 'Unable to reset password. Contact your administrator';
+                }
+                elseif (!$staff->sendResetEmail()) {
                     $tpl = 'pwreset.sent.php';
                 }
             }