diff --git a/include/class.config.php b/include/class.config.php
index 54928de8f28a5e49934d516df8cda0bd5b52e2a2..69e60dcf75f43ce18884157c6152e7df8d604af8 100644
--- a/include/class.config.php
+++ b/include/class.config.php
@@ -150,6 +150,7 @@ class OsticketConfig extends Config {
         'auto_claim_tickets'=>  true,
         'system_language' =>    'en_US',
         'default_storage_bk' => 'D',
+        'allow_client_updates' => false,
     );
 
     function OsticketConfig($section=null) {
@@ -295,6 +296,10 @@ class OsticketConfig extends Config {
         return $this->get('enable_html_thread');
     }
 
+    function allowClientUpdates() {
+        return $this->get('allow_client_updates');
+    }
+
     function getClientTimeout() {
         return $this->getClientSessionTimeout();
     }
@@ -877,6 +882,7 @@ class OsticketConfig extends Config {
             'show_related_tickets'=>isset($vars['show_related_tickets'])?1:0,
             'hide_staff_name'=>isset($vars['hide_staff_name'])?1:0,
             'enable_html_thread'=>isset($vars['enable_html_thread'])?1:0,
+            'allow_client_updates'=>isset($vars['allow_client_updates'])?1:0,
             'allow_attachments'=>isset($vars['allow_attachments'])?1:0,
             'allowed_filetypes'=>strtolower(preg_replace("/\n\r|\r\n|\n|\r/", '',trim($vars['allowed_filetypes']))),
             'max_file_size'=>$vars['max_file_size'],
diff --git a/include/client/edit.inc.php b/include/client/edit.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..21f2ca726b1863bfe1b5f5eaf0f946606b0830b4
--- /dev/null
+++ b/include/client/edit.inc.php
@@ -0,0 +1,30 @@
+<?php
+
+if(!defined('OSTCLIENTINC') || !$thisclient || !$ticket || !$ticket->checkUserAccess($thisclient)) die('Access Denied!');
+
+?>
+
+<h1>
+    Editing Ticket #<?php echo $ticket->getNumber(); ?>
+</h1>
+
+<form action="tickets.php" method="post">
+    <?php echo csrf_token(); ?>
+    <input type="hidden" name="a" value="edit"/>
+    <input type="hidden" name="id" value="<?php echo $_REQUEST['id']; ?>"/>
+<table width="800">
+    <tbody id="dynamic-form">
+    <?php if ($forms)
+        foreach ($forms as $form) {
+            $form->render(false);
+    } ?>
+    </tbody>
+</table>
+<hr>
+<p style="text-align: center;">
+    <input type="submit" value="Update"/>
+    <input type="reset" value="Reset"/>
+    <input type="button" value="Cancel" onclick="javascript:
+        window.location.href='index.php';"/>
+</p>
+</form>
diff --git a/include/client/header.inc.php b/include/client/header.inc.php
index 4f1c93f88433f82744d328bbe7b70e0687ad6669..107cf479c43884bf362b57f72378c40bc1a5be78 100644
--- a/include/client/header.inc.php
+++ b/include/client/header.inc.php
@@ -44,8 +44,9 @@ header("Content-Type: text/html; charset=UTF-8\r\n");
             <p>
              <?php
              if($thisclient && is_object($thisclient) && $thisclient->isValid()) {
-                 echo Format::htmlchars($thisclient->getName()).'&nbsp;-&nbsp;';
+                 echo Format::htmlchars($thisclient->getName()).'&nbsp;|';
                  ?>
+                <a href="<?php echo ROOT_PATH; ?>profile.php">Profile</a> |
                 <?php
                 if($cfg->showRelatedTickets()) {?>
                 <a href="<?php echo ROOT_PATH; ?>tickets.php">Tickets <b>(<?php echo $thisclient->getNumTickets(); ?>)</b></a> -
@@ -54,7 +55,7 @@ header("Content-Type: text/html; charset=UTF-8\r\n");
                 <a href="<?php echo ROOT_PATH; ?>logout.php?auth=<?php echo $ost->getLinkToken(); ?>">Log Out</a>
              <?php
              }elseif($nav){ ?>
-                 Guest User - <a href="<?php echo ROOT_PATH; ?>login.php">Log In</a>
+                 Guest User | <a href="<?php echo ROOT_PATH; ?>login.php">Log In</a>
               <?php
              } ?>
             </p>
diff --git a/include/client/profile.inc.php b/include/client/profile.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..a103ba1f7ec5f00ec1ec182b520ccfb2eaa8077b
--- /dev/null
+++ b/include/client/profile.inc.php
@@ -0,0 +1,25 @@
+<?php
+
+?>
+<h1>Manage Your Profile Information</h1>
+<p>
+Use the forms below to update the information we have on file for your
+account
+</p>
+<form action="profile.php" method="post">
+  <?php csrf_token(); ?>
+<table width="800">
+<?php
+foreach ($user->getForms() as $f) {
+    $f->render(false);
+}
+?>
+</table>
+<hr>
+<p style="text-align: center;">
+    <input type="submit" value="Update"/>
+    <input type="reset" value="Reset"/>
+    <input type="button" value="Cancel" onclick="javascript:
+        window.location.href='index.php';"/>
+</p>
+</form>
diff --git a/include/client/view.inc.php b/include/client/view.inc.php
index c36eaec96dd81d06804a5cd44d26fc986a6d2737..a369ee75db623f3583934048db3902f4bb538b82 100644
--- a/include/client/view.inc.php
+++ b/include/client/view.inc.php
@@ -15,6 +15,10 @@ if(!$dept || !$dept->isPublic())
             <h1>
                 Ticket #<?php echo $ticket->getNumber(); ?> &nbsp;
                 <a href="view.php?id=<?php echo $ticket->getId(); ?>" title="Reload"><span class="Icon refresh">&nbsp;</span></a>
+<?php if ($cfg->allowClientUpdates()) { ?>
+                <a class="action-button" href="tickets.php?a=edit&id=<?php
+                     echo $ticket->getId(); ?>"><i class="icon-edit"></i> Edit</a>
+<?php } ?>
             </h1>
         </td>
     </tr>
diff --git a/include/staff/settings-tickets.inc.php b/include/staff/settings-tickets.inc.php
index b25ad9d597c4daed162e69aa0df78a5f3ef7e32a..a1e5936e9859e1192835fa3c6b4130e5f99a436a 100644
--- a/include/staff/settings-tickets.inc.php
+++ b/include/staff/settings-tickets.inc.php
@@ -135,6 +135,14 @@ if(!($maxfileuploads=ini_get('max_file_uploads')))
                 Enable rich text in ticket thread and autoresponse emails
             </td>
         </tr>
+        <tr>
+            <td>Allow Client Updates:</td>
+            <td>
+                <input type="checkbox" name="allow_client_updates" <?php
+                echo $config['allow_client_updates']?'checked="checked"':''; ?>>
+                Allow clients to update ticket details via the web portal
+            </td>
+        </tr>
         <tr>
             <th colspan="2">
                 <em><b>Attachments</b>:  Size and max. uploads setting mainly apply to web tickets.</em>
diff --git a/profile.php b/profile.php
new file mode 100644
index 0000000000000000000000000000000000000000..e17bf690eb9241ff2b7bbad74efe8684bed447d2
--- /dev/null
+++ b/profile.php
@@ -0,0 +1,35 @@
+<?php
+/*********************************************************************
+    profile.php
+
+    Manage client profile. This will allow a logged-in user to manage
+    his/her own public (non-internal) information
+
+    Peter Rotich <peter@osticket.com>
+    Jared Hancock <jared@osticket.com>
+    Copyright (c)  2006-2013 osTicket
+    http://www.osticket.com
+
+    Released under the GNU General Public License WITHOUT ANY WARRANTY.
+    See LICENSE.TXT for details.
+
+    vim: expandtab sw=4 ts=4 sts=4:
+    $Id: $
+**********************************************************************/
+require 'secure.inc.php';
+
+require_once 'class.user.php';
+$user = User::lookup($thisclient->getId());
+
+if ($user && $_POST) {
+    $errors = array();
+    if ($user->updateInfo($_POST, $errors))
+        Http::redirect('tickets.php');
+}
+
+$inc = 'profile.inc.php';
+
+include(CLIENTINC_DIR.'header.inc.php');
+include(CLIENTINC_DIR.$inc);
+include(CLIENTINC_DIR.'footer.inc.php');
+
diff --git a/tickets.php b/tickets.php
index 7c49a74d34611ff7f7f4b6fd0aeda80c31fcce0f..01d8b799c4220aa9ffc66ad7ce3e238ef2984925 100644
--- a/tickets.php
+++ b/tickets.php
@@ -32,6 +32,25 @@ if($_REQUEST['id']) {
 if($_POST && is_object($ticket) && $ticket->getId()):
     $errors=array();
     switch(strtolower($_POST['a'])){
+    case 'edit':
+        if(!$ticket->checkUserAccess($thisclient)) //double check perm again!
+            $errors['err']='Access Denied. Possibly invalid ticket ID';
+        elseif (!$cfg || !$cfg->allowClientUpdates())
+            $errors['err']='Access Denied. Client updates are currently disabled';
+        else {
+            $forms=DynamicFormEntry::forTicket($ticket->getId());
+            foreach ($forms as $form)
+                if (!$form->isValid())
+                    $errors = array_merge($errors, $form->errors());
+        }
+        if (!$errors) {
+            foreach ($forms as $f) $f->save();
+            $_REQUEST['a'] = null; //Clear edit action - going back to view.
+            $ticket->logNote('Ticket details updated', sprintf(
+                'Ticket details were updated by client %s &lt;%s&gt;',
+                $thisclient->getName(), $thisclient->getEmail()));
+        }
+        break;
     case 'reply':
         if(!$ticket->checkUserAccess($thisclient)) //double check perm again!
             $errors['err']='Access Denied. Possibly invalid ticket ID';
@@ -70,7 +89,15 @@ if($_POST && is_object($ticket) && $ticket->getId()):
 endif;
 $nav->setActiveNav('tickets');
 if($ticket && $ticket->checkUserAccess($thisclient)) {
-    $inc='view.inc.php';
+    if (isset($_REQUEST['a']) && $_REQUEST['a'] == 'edit'
+            && $cfg->allowClientUpdates()) {
+        $inc = 'edit.inc.php';
+        if (!$forms) $forms=DynamicFormEntry::forTicket($ticket->getId());
+        // Auto add new fields to the entries
+        foreach ($forms as $f) $f->addMissingFields();
+    }
+    else
+        $inc='view.inc.php';
 } elseif($cfg->showRelatedTickets() && $thisclient->getNumTickets()) {
     $inc='tickets.inc.php';
 } else {