diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 2b117bc..1790594 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -331,10 +331,8 @@ function install_begin_request(&$install_state) {
   require_once DRUPAL_ROOT . '/core/includes/ajax.inc';
   // Override the module list with a minimal set of modules.
   $module_list['system']['filename'] = 'core/modules/system/system.module';
-  $module_list['user']['filename']   = 'core/modules/user/user.module';
   module_list(NULL, $module_list);
   drupal_load('module', 'system');
-  drupal_load('module', 'user');
 
   // Load the cache infrastructure using a "fake" cache implementation that
   // does not attempt to write to the database. We need this during the initial
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index d2fe902..7d84ce4 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -2444,10 +2444,7 @@ function template_preprocess(&$variables, $hook) {
     $drupal_static_fast['default_variables'] = &drupal_static(__FUNCTION__);
   }
   $default_variables = &$drupal_static_fast['default_variables'];
-  // Global $user object shouldn't change during a page request once rendering
-  // has started, but if there's an edge case where it does, re-fetch the
-  // variables appropriate for the new user.
-  if (!isset($default_variables) || ($user !== $default_variables['user'])) {
+  if (!isset($default_variables)) {
     $default_variables = _template_preprocess_default_variables();
   }
   if (!isset($default_attributes)) {
@@ -2467,26 +2464,17 @@ function template_preprocess(&$variables, $hook) {
  * Returns hook-independent variables to template_preprocess().
  */
 function _template_preprocess_default_variables() {
-  global $user;
-
   // Variables that don't depend on a database connection.
   $variables = array(
     'title_prefix' => array(),
     'title_suffix' => array(),
-    'user' => $user,
     'db_is_active' => !defined('MAINTENANCE_MODE'),
+    // User module overrides these when it is loaded.
+    'user' => drupal_anonymous_user(),
     'is_admin' => FALSE,
     'logged_in' => FALSE,
   );
 
-  // The user object has no uid property when the database does not exist during
-  // install. The user_access() check deals with issues when in maintenance mode
-  // as uid is set but the user.module has not been included.
-  if (isset($user->uid) && function_exists('user_access')) {
-    $variables['is_admin'] = user_access('access administration pages');
-    $variables['logged_in'] = ($user->uid > 0);
-  }
-
   // drupal_is_front_page() might throw an exception.
   try {
     $variables['is_front'] = drupal_is_front_page();
@@ -2498,6 +2486,9 @@ function _template_preprocess_default_variables() {
     $variables['db_is_active'] = FALSE;
   }
 
+  // Give modules a chance to alter the default template variables.
+  drupal_alter('template_preprocess_default_variables', $variables);
+
   return $variables;
 }
 
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index e4c4ce7..d10d3e0 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -1937,6 +1937,35 @@ function hook_theme_registry_alter(&$theme_registry) {
 }
 
 /**
+ * Alter the default, hook-independent variables for all templates.
+ *
+ * Allows modules to provide additional default template variables or manipulate
+ * existing. This hook is invoked from template_preprocess() after basic default
+ * template variables have been set up and before the next template preprocess
+ * function is invoked.
+ *
+ * Note that the default template variables are statically cached within a
+ * request. When adding a template variable that depends on other context, it is
+ * your responsibility to appropriately reset the static cache in
+ * template_preprocess() when needed:
+ * @code
+ * drupal_static_reset('template_preprocess');
+ * @endcode
+ *
+ * See user_template_preprocess_default_variables_alter() for an example.
+ *
+ * @param array $variables
+ *   An associative array of default template variables, as set up by
+ *   _template_preprocess_default_variables(). Passed by reference.
+ *
+ * @see template_preprocess()
+ * @see _template_preprocess_default_variables()
+ */
+function hook_template_preprocess_default_variables_alter(&$variables) {
+  $variables['is_admin'] = user_access('access administration pages');
+}
+
+/**
  * Return the machine-readable name of the theme to use for the current page.
  *
  * This hook can be used to dynamically set the theme for the current page
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index f1d3254..d292734 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -886,6 +886,20 @@ function user_format_name($account) {
 }
 
 /**
+ * Implements hook_template_preprocess_default_variables_alter().
+ *
+ * @see user_user_login()
+ * @see user_user_logout()
+ */
+function user_template_preprocess_default_variables_alter(&$variables) {
+  global $user;
+
+  $variables['user'] = clone $user;
+  $variables['is_admin'] = user_access('access administration pages');
+  $variables['logged_in'] = ($user->uid > 0);
+}
+
+/**
  * Process variables for user-picture.tpl.php.
  *
  * The $variables array contains the following arguments:
@@ -1745,6 +1759,24 @@ function user_login_form_submit($form, &$form_state) {
 }
 
 /**
+ * Implements hook_user_login().
+ */
+function user_user_login($edit, $account) {
+  // Reset static cache of default variables in template_preprocess() to reflect
+  // the new user.
+  drupal_static_reset('template_preprocess');
+}
+
+/**
+ * Implements hook_user_logout().
+ */
+function user_user_logout($account) {
+  // Reset static cache of default variables in template_preprocess() to reflect
+  // the new user.
+  drupal_static_reset('template_preprocess');
+}
+
+/**
  * Helper function for authentication modules. Either logs in or registers
  * the current user, based on username. Either way, the global $user object is
  * populated and login tasks are performed.
