Index: client/singlesignon_client.module
===================================================================
--- client/singlesignon_client.module	(revision 6803)
+++ client/singlesignon_client.module	(working copy)
@@ -124,6 +124,19 @@
   }
 }
 
+function singlesignon_client_init() {
+  $i = 0;
+  while (isset($_GET['ssomessage'. $i])) {
+    drupal_set_message(filter_xss($_GET['ssomessage'. $i]));
+    ++$i;
+  }
+  $i = 0;
+  while (isset($_GET['ssowarning'. $i])) {
+    drupal_set_message(filter_xss($_GET['ssowarning'. $i]), 'warning');
+    ++$i;
+  }
+}
+
 /**
  * Notify the user that cookie support is required.
  */
@@ -168,13 +181,23 @@
   switch ($form_id) {
     case 'user_pass':
       $action = 'user/password';
+      singlesignon_client_set_form_error();
       break;
 
+    case 'user_pass_reset':
+      // Redirect password reset login attempts to controller site.
+      $form_action = explode('/', $form['#action']);
+      if ($form_action[count($form_action) - 1] == 'login') {
+        $action = implode('/', array_slice($form_action, -6));
+      }
+      break;
+
     case 'user_register':
       if (stripos($form['#action'], 'user/register') && !variable_get('user_email_verification', TRUE) && variable_get('user_register', 1) < 2) {
         // User is registering, email verifications are turned off and admin approval is not required.
         $_SESSION['singlesignon_message'] = t('You have successfully registered on this site. Please Log in now.');
       }
+      singlesignon_client_set_form_error();
       break;
 
     case 'user_login_block':
@@ -182,12 +205,7 @@
       $action = 'user/login';
       // Ensure the block submits to the stand-alone form.
       $form['form_id']['#value'] = 'user_login';
-      $i = 0;
-      // Set any login errors that may have been returned from the controller site.
-      while (isset($_GET['ssologinerror'. $i])) {
-        form_set_error('', filter_xss($_GET['ssologinerror'. $i]));
-        ++$i;
-      }
+      singlesignon_client_set_form_error();
       break;
   }
 
@@ -211,6 +229,19 @@
   }
 }
 
+function singlesignon_client_set_form_error($type = 'form') {
+  $i = 0;
+  // Set any login errors that may have been returned from the controller site.
+  while (isset($_GET['ssoerror'. $i])) {
+    if ($type == 'form') {
+      form_set_error('', filter_xss($_GET['ssoerror'. $i]));
+    }
+    else {
+      drupal_set_message(filter_xss($_GET['ssoerror'. $i]), 'error');
+    }
+    ++$i;
+  }
+}
 /**
  * Helper function for converting a list of tokens into a regular expression.
  */
Index: controller/singlesignon_controller.module
===================================================================
--- controller/singlesignon_controller.module	(revision 6803)
+++ controller/singlesignon_controller.module	(working copy)
@@ -37,6 +37,23 @@
   header('P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
 }
 
+function singlesignon_controller_init() {
+  // Redirect all user paths back to the set user domain
+  if ($domain = variable_get('singlesignon_controller_user_domain', '')) {
+    $arg = arg();
+    if ($arg[0] == 'user' && !in_array($arg[1], array('login', 'logout', 'reset', 'password'))) {
+      $query = '';
+      if ($messages = drupal_get_messages('status')) {
+        foreach($messages['status'] as $key => $message) {
+          $messages['status'][$key] = urlencode($message);
+        }
+        $query .= '&ssomessage0='. implode('&ssomessage'. $i++ .'=', $messages['status']);
+      }
+      drupal_goto($domain . implode('/', $arg), $query);
+    }
+  }
+}
+
 /**
  * Implementation of hook_perm().
  */
@@ -51,28 +68,49 @@
   // Catch remote submissions to user forms from client sites.
   global $base_url;
   switch ($form_id) {
-    case 'user_register':
-    case 'user_pass':
     case 'user_login_block':
     case 'user_login':
-      $form['#validate'][] = 'singlesignon_controller_user_form_validate';
+      $form['#validate'][] = 'singlesignon_controller_user_login_form_validate';
       $form['#submit'][] = 'singlesignon_controller_user_form_submit';
       break;
+    case 'user_register':
+      $form['#validate'][] = 'singlesignon_controller_user_register_form_validate';
+      $form['#submit'][] = 'singlesignon_controller_user_form_submit';
+      break;
+    case 'user_pass':
+    case 'user_pass_reset':
+      $form['#validate'][] = 'singlesignon_controller_user_reset_form_validate';
+      $form['#submit'][] = 'singlesignon_controller_user_form_submit';
+      break;
   }
 }
 
-function singlesignon_controller_user_form_validate($form, &$form_state) {
+function singlesignon_controller_user_form_validate($form, &$form_state, $path) {
   // Pass login errors back to the origin site.
   if ($errors = form_get_errors()) {
     list ($url, $query) = explode('?', $_GET['origin'], 2);
     foreach($errors as $key => $error) {
       $errors[$key] = urlencode($error);
     }
-    $query .= '&ssologinerror0='. implode('&ssologinerror='. $i++, $errors);
-    drupal_goto($url .'/user/login', $query);
+    $query .= '&ssoerror0='. implode('&ssoerror'. $i++ .'=', $errors);
   }
+  if ($query) {
+    drupal_goto($url .'/'. $path, $query);
+  }
 }
 
+function singlesignon_controller_user_login_form_validate($form, &$form_state) {
+  singlesignon_controller_user_form_validate($form, &$form_state, 'user/login');
+}
+
+function singlesignon_controller_user_register_form_validate($form, &$form_state) {
+  singlesignon_controller_user_form_validate($form, &$form_state, 'user/register');
+}
+
+function singlesignon_controller_user_reset_form_validate($form, &$form_state) {
+  singlesignon_controller_user_form_validate($form, &$form_state, 'user/password');
+}
+
 /**
  * Submit callback for user forms redirect.
  *
@@ -91,6 +129,18 @@
     // Redirect to given origin.
     $form_state['redirect'] = $_GET['origin'];
   }
+
+  // Return messages back to the origin slite
+  if ($messages = drupal_get_messages('status')) {
+    foreach($messages['status'] as $key => $message) {
+      $messages['status'][$key] = urlencode($message);
+    }
+    $query .= '&ssomessage0='. implode('&ssomessage'. $i++ .'=', $messages['status']);
+  }
+  if ($query) {
+    $form_state['redirect'] .= $query;
+  }
+
 }
 
 /**
@@ -120,9 +170,26 @@
     '#description' => t('Copy this private key to sites running the Single sign-on client module.'),
   );
 
+  $form['user_domain'] = array(
+    '#type' => 'textfield',
+    '#title' => t('User domain'),
+    '#default_value' => variable_get('singlesignon_controller_user_domain', check_plain($base_url)),
+    '#description' => t('Enter the domain you want to use to handle all user administration from.'),
+  );
+
+  $form['#submit'][] = 'singlesignon_controller_admin_settings_submit';
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => 'Submit',
+  );
   return $form;
 }
 
+function singlesignon_controller_admin_settings_submit($form, &$form_state) {
+  variable_set('singlesignon_controller_user_domain', $form_state['values']['user_domain']);
+}
+
 /**
  * Menu callback: associate with a given client site.
  */
Index: singlesignon.inc
===================================================================
--- singlesignon.inc	(revision 6803)
+++ singlesignon.inc	(working copy)
@@ -142,7 +142,7 @@
   $query = array();
   foreach ($arguments as $key => $value) {
     // Don't pass error messages back to the controller
-    if (strpos($key, 'ssologinerror') !== 0) {
+    if (strpos($key, 'ssoerror') !== 0 && strpos($key, 'ssowarning') !== 0 && strpos($key, 'ssomessage') !== 0) {
       $query[] = urlencode($key) .'='. urlencode($value);
     }
   }
