diff --git a/base/hash_tables.h b/base/hash_tables.h
index 250b27d9f886d..e320670f9c736 100644
--- a/base/hash_tables.h
+++ b/base/hash_tables.h
@@ -58,7 +58,7 @@ using __gnu_cxx::hash_set;
 
 namespace __gnu_cxx {
 
-// The GNU C++ library provides identiy hash functions for many integral types,
+// The GNU C++ library provides identity hash functions for many integral types,
 // but not for |long long|.  This hash function will truncate if |size_t| is
 // narrower than |long long|.  This is probably good enough for what we will
 // use it for.
diff --git a/chrome/browser/chromeos/dom_ui/accounts_options_handler.cc b/chrome/browser/chromeos/dom_ui/accounts_options_handler.cc
index e461989150213..8cc42600752a9 100644
--- a/chrome/browser/chromeos/dom_ui/accounts_options_handler.cc
+++ b/chrome/browser/chromeos/dom_ui/accounts_options_handler.cc
@@ -17,7 +17,7 @@
 namespace chromeos {
 
 AccountsOptionsHandler::AccountsOptionsHandler()
-    : CrosOptionsPageUIHandler(new UserCrosSettingsProvider()) {
+    : CrosOptionsPageUIHandler(new UserCrosSettingsProvider) {
 }
 
 AccountsOptionsHandler::~AccountsOptionsHandler() {
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
index 0492d397da303..8ce8df89add1f 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -126,7 +126,8 @@ ExistingUserController::ExistingUserController(
       selected_view_index_(kNotSelected),
       num_login_attempts_(0),
       bubble_(NULL),
-      user_settings_(new UserCrosSettingsProvider()) {
+      user_settings_(new UserCrosSettingsProvider),
+      method_factory_(this) {
   if (delete_scheduled_instance_)
     delete_scheduled_instance_->Delete();
 
@@ -302,8 +303,19 @@ void ExistingUserController::WhiteListCheckFailed(const std::string& email) {
 
 void ExistingUserController::LoginOffTheRecord() {
   // Check allow_guest in case this call is fired from key accelerator.
-  if (!UserCrosSettingsProvider::cached_allow_guest())
+  // Must not proceed without signature verification.
+  bool trusted_setting_available = user_settings_->RequestTrustedAllowGuest(
+      method_factory_.NewRunnableMethod(
+          &ExistingUserController::LoginOffTheRecord));
+  if (!trusted_setting_available) {
+    // Value of AllowGuest setting is still not verified.
+    // Another attempt will be invoked again after verification completion.
     return;
+  }
+  if (!UserCrosSettingsProvider::cached_allow_guest()) {
+    // Disallowed.
+    return;
+  }
 
   // Disable clicking on other windows.
   SendSetLoginState(false);
@@ -356,11 +368,10 @@ void ExistingUserController::ActivateWizard(const std::string& screen_name) {
 void ExistingUserController::RemoveUser(UserController* source) {
   ClearErrors();
 
-  // TODO(xiyuan): Wait for the cached settings update before using them.
-  if (UserCrosSettingsProvider::cached_owner() == source->user().email()) {
-    // Owner is not allowed to be removed from the device.
-    return;
-  }
+  // Owner is not allowed to be removed from the device.
+  // It must be enforced at upper levels.
+  DCHECK(user_settings_->RequestTrustedOwner(NULL));
+  DCHECK(source->user().email() != UserCrosSettingsProvider::cached_owner());
 
   UserManager::Get()->RemoveUser(source->user().email());
 
@@ -548,9 +559,18 @@ void ExistingUserController::OnPasswordChangeDetected(
     return;
   }
 
+  // Must not proceed without signature verification.
+  bool trusted_setting_available = user_settings_->RequestTrustedOwner(
+      method_factory_.NewRunnableMethod(
+          &ExistingUserController::OnPasswordChangeDetected,
+          credentials));
+  if (!trusted_setting_available) {
+    // Value of owner email is still not verified.
+    // Another attempt will be invoked after verification completion.
+    return;
+  }
   // TODO(altimofeev): remove this constrain when full sync for the owner will
   // be correctly handled.
-  // TODO(xiyuan): Wait for the cached settings update before using them.
   bool full_sync_disabled = (UserCrosSettingsProvider::cached_owner() ==
       controllers_[selected_view_index_]->user().email());
 
diff --git a/chrome/browser/chromeos/login/existing_user_controller.h b/chrome/browser/chromeos/login/existing_user_controller.h
index e150a31fb3155..61e941a26acae 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.h
+++ b/chrome/browser/chromeos/login/existing_user_controller.h
@@ -166,9 +166,12 @@ class ExistingUserController : public WmMessageListener::Observer,
   // Help application used for help dialogs.
   scoped_ptr<HelpAppLauncher> help_app_;
 
-  // A user settings provider instance to trigger settings cache update.
+  // Triggers prefetching of user settings.
   scoped_ptr<UserCrosSettingsProvider> user_settings_;
 
+  // Factory of callbacks.
+  ScopedRunnableMethodFactory<ExistingUserController> method_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(ExistingUserController);
 };
 
diff --git a/chrome/browser/chromeos/login/login_performer.cc b/chrome/browser/chromeos/login/login_performer.cc
index eb5304d2e41f9..1f10bfb7a02b7 100644
--- a/chrome/browser/chromeos/login/login_performer.cc
+++ b/chrome/browser/chromeos/login/login_performer.cc
@@ -21,7 +21,8 @@ namespace {
 
 LoginPerformer::LoginPerformer(Delegate* delegate)
     : last_login_failure_(LoginFailure::None()),
-      delegate_(delegate) {}
+      delegate_(delegate),
+      method_factory_(this) {}
 
 ////////////////////////////////////////////////////////////////////////////////
 // LoginPerformer, LoginStatusConsumer implementation:
@@ -100,6 +101,18 @@ void LoginPerformer::Login(const std::string& username,
                            const std::string& password) {
   username_ = username;
   password_ = password;
+  // Must not proceed without signature verification.
+  UserCrosSettingsProvider user_settings;
+  bool trusted_setting_available = user_settings.RequestTrustedAllowNewUser(
+      method_factory_.NewRunnableMethod(
+          &LoginPerformer::Login,
+          username,
+          password));
+  if (!trusted_setting_available) {
+    // Value of AllowNewUser setting is still not verified.
+    // Another attempt will be invoked after verification completion.
+    return;
+  }
   if (UserCrosSettingsProvider::cached_allow_new_user()) {
     // Starts authentication if guest login is allowed.
     StartAuthentication();
diff --git a/chrome/browser/chromeos/login/login_performer.h b/chrome/browser/chromeos/login/login_performer.h
index e594723c0dffc..7edf3cfee46e1 100644
--- a/chrome/browser/chromeos/login/login_performer.h
+++ b/chrome/browser/chromeos/login/login_performer.h
@@ -10,6 +10,7 @@
 
 #include "base/basictypes.h"
 #include "base/ref_counted.h"
+#include "base/task.h"
 #include "chrome/browser/chromeos/login/authenticator.h"
 #include "chrome/browser/chromeos/login/login_status_consumer.h"
 #include "chrome/browser/chromeos/login/signed_settings_helper.h"
@@ -107,6 +108,8 @@ class LoginPerformer : public LoginStatusConsumer,
   // Notifications receiver.
   Delegate* delegate_;
 
+  ScopedRunnableMethodFactory<LoginPerformer> method_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(LoginPerformer);
 };
 
diff --git a/chrome/browser/chromeos/login/owner_manager.cc b/chrome/browser/chromeos/login/owner_manager.cc
index 71b15a83e0bbf..389d0a82698fc 100644
--- a/chrome/browser/chromeos/login/owner_manager.cc
+++ b/chrome/browser/chromeos/login/owner_manager.cc
@@ -73,8 +73,16 @@ void OwnerManager::GenerateKeysAndExportPublic() {
 }
 
 void OwnerManager::ExportKey() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   VLOG(1) << "Exporting public key";
-  if (!utils_->ExportPublicKeyViaDbus(private_key_.get(), this)) {
+  if (utils_->ExportPublicKeyViaDbus(private_key_.get(), this)) {
+    BrowserThread::PostTask(
+        BrowserThread::UI, FROM_HERE,
+        NewRunnableMethod(this,
+                          &OwnerManager::SendNotification,
+                          NotificationType::OWNERSHIP_TAKEN,
+                          NotificationService::NoDetails()));
+  } else {
     private_key_.reset(NULL);
     BrowserThread::PostTask(
         BrowserThread::UI, FROM_HERE,
diff --git a/chrome/browser/chromeos/login/user_controller.cc b/chrome/browser/chromeos/login/user_controller.cc
index 1a526c24717f1..639909cc74cbb 100644
--- a/chrome/browser/chromeos/login/user_controller.cc
+++ b/chrome/browser/chromeos/login/user_controller.cc
@@ -148,7 +148,8 @@ UserController::UserController(Delegate* delegate, bool is_guest)
       existing_user_view_(NULL),
       guest_user_view_(NULL),
       label_view_(NULL),
-      unselected_label_view_(NULL) {
+      unselected_label_view_(NULL),
+      method_factory_(this) {
   registrar_.Add(
       this,
       NotificationType::LOGIN_USER_IMAGE_CHANGED,
@@ -163,9 +164,7 @@ UserController::UserController(Delegate* delegate,
       is_guest_(false),
       // Empty 'cached_owner()' means that owner hasn't been cached yet, not
       // that owner has an empty email.
-      is_owner_(
-          !user.email().empty() &&
-          UserCrosSettingsProvider::cached_owner() == user.email()),
+      is_owner_(user.email() == UserCrosSettingsProvider::cached_owner()),
       show_name_tooltip_(false),
       user_(user),
       delegate_(delegate),
@@ -179,7 +178,9 @@ UserController::UserController(Delegate* delegate,
       existing_user_view_(NULL),
       guest_user_view_(NULL),
       label_view_(NULL),
-      unselected_label_view_(NULL) {
+      unselected_label_view_(NULL),
+      method_factory_(this) {
+  DCHECK(!user.email().empty());
   registrar_.Add(
       this,
       NotificationType::LOGIN_USER_IMAGE_CHANGED,
@@ -552,6 +553,19 @@ void UserController::NavigateAway() {
 }
 
 void UserController::OnRemoveUser() {
+  // Must not proceed without signature verification.
+  UserCrosSettingsProvider user_settings;
+  bool trusted_owner_available = user_settings.RequestTrustedOwner(
+      method_factory_.NewRunnableMethod(&UserController::OnRemoveUser));
+  if (!trusted_owner_available) {
+    // Value of owner email is still not verified.
+    // Another attempt will be invoked after verification completion.
+    return;
+  }
+  if (user().email() == UserCrosSettingsProvider::cached_owner()) {
+    // Owner is not allowed to be removed from the device.
+    return;
+  }
   delegate_->RemoveUser(this);
 }
 
diff --git a/chrome/browser/chromeos/login/user_controller.h b/chrome/browser/chromeos/login/user_controller.h
index 62608e6879b3d..0de0e4bb194b1 100644
--- a/chrome/browser/chromeos/login/user_controller.h
+++ b/chrome/browser/chromeos/login/user_controller.h
@@ -9,6 +9,7 @@
 #include <string>
 
 #include "base/string16.h"
+#include "base/task.h"
 #include "chrome/browser/chromeos/login/new_user_view.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/login/user_view.h"
@@ -19,7 +20,6 @@
 #include "views/controls/button/button.h"
 #include "views/controls/textfield/textfield.h"
 #include "views/widget/widget_delegate.h"
-
 namespace views {
 class WidgetGtk;
 }
@@ -231,6 +231,8 @@ class UserController : public views::ButtonListener,
 
   NotificationRegistrar registrar_;
 
+  ScopedRunnableMethodFactory<UserController> method_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(UserController);
 };
 
diff --git a/chrome/browser/chromeos/user_cros_settings_provider.cc b/chrome/browser/chromeos/user_cros_settings_provider.cc
index 1cdfd3a447580..4f90c203ed6ce 100644
--- a/chrome/browser/chromeos/user_cros_settings_provider.cc
+++ b/chrome/browser/chromeos/user_cros_settings_provider.cc
@@ -4,21 +4,87 @@
 
 #include "chrome/browser/chromeos/user_cros_settings_provider.h"
 
+#include <map>
+#include <set>
+
+#include "base/hash_tables.h"
 #include "base/logging.h"
+#include "base/singleton.h"
 #include "base/string_util.h"
+#include "base/task.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_thread.h"
 #include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/login_library.h"
 #include "chrome/browser/chromeos/cros_settings.h"
 #include "chrome/browser/chromeos/cros_settings_names.h"
+#include "chrome/browser/chromeos/login/ownership_service.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/prefs/pref_service.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_type.h"
 
 namespace chromeos {
 
 namespace {
 
+const char kTrueIncantation[] = "true";
+const char kFalseIncantation[] = "false";
+const char kTrustedSuffix[] = "/trusted";
+
+// For all our boolean settings following is applicable:
+// true is default permissive value and false is safe prohibitic value.
+const char* kBooleanSettings[] = {
+  kAccountsPrefAllowNewUser,
+  kAccountsPrefAllowGuest,
+  kAccountsPrefShowUserNamesOnSignIn
+};
+
+const char* kStringSettings[] = {
+  kDeviceOwner
+};
+
+const char* kListSettings[] = {
+  kAccountsPrefUsers
+};
+
+bool IsControlledBooleanSetting(const std::string& pref_path) {
+  return std::find(kBooleanSettings,
+                   kBooleanSettings + arraysize(kBooleanSettings),
+                   pref_path) !=
+      kBooleanSettings + arraysize(kBooleanSettings);
+}
+
+bool IsControlledStringSetting(const std::string& pref_path) {
+  return std::find(kStringSettings,
+                   kStringSettings + arraysize(kStringSettings),
+                   pref_path) !=
+      kStringSettings + arraysize(kStringSettings);
+}
+
+bool IsControlledListSetting(const std::string& pref_path) {
+  return std::find(kListSettings,
+                   kListSettings + arraysize(kListSettings),
+                   pref_path) !=
+      kListSettings + arraysize(kListSettings);
+}
+
+void RegisterSetting(PrefService* local_state, const std::string& pref_path) {
+  local_state->RegisterBooleanPref((pref_path + kTrustedSuffix).c_str(),
+                                   false);
+  if (IsControlledBooleanSetting(pref_path)) {
+    local_state->RegisterBooleanPref(pref_path.c_str(), true);
+  } else if (IsControlledStringSetting(pref_path)) {
+    local_state->RegisterStringPref(pref_path.c_str(), "");
+  } else {
+    DCHECK(IsControlledListSetting(pref_path));
+    local_state->RegisterListPref(pref_path.c_str());
+  }
+}
+
 Value* CreateSettingsBooleanValue(bool value, bool managed) {
   DictionaryValue* dict = new DictionaryValue;
   dict->Set("value", Value::CreateBooleanValue(value));
@@ -26,16 +92,30 @@ Value* CreateSettingsBooleanValue(bool value, bool managed) {
   return dict;
 }
 
-// static
-void UpdateCacheBool(const char* name, bool value) {
+enum UseValue {
+  USE_VALUE_SUPPLIED,
+  USE_VALUE_DEFAULT
+};
+
+void UpdateCacheBool(const std::string& name,
+                     bool value,
+                     UseValue use_value) {
   PrefService* prefs = g_browser_process->local_state();
-  prefs->SetBoolean(name, value);
+  if (use_value == USE_VALUE_DEFAULT)
+    prefs->ClearPref(name.c_str());
+  else
+    prefs->SetBoolean(name.c_str(), value);
   prefs->ScheduleSavePersistentPrefs();
 }
 
-void UpdateCacheString(const char* name, const std::string& value) {
+void UpdateCacheString(const std::string& name,
+                       const std::string& value,
+                       UseValue use_value) {
   PrefService* prefs = g_browser_process->local_state();
-  prefs->SetString(name, value);
+  if (use_value == USE_VALUE_DEFAULT)
+    prefs->ClearPref(name.c_str());
+  else
+    prefs->SetString(name.c_str(), value);
   prefs->ScheduleSavePersistentPrefs();
 }
 
@@ -74,43 +154,333 @@ bool GetUserWhitelist(ListValue* user_list) {
   return true;
 }
 
+class UserCrosSettingsTrust : public SignedSettingsHelper::Callback,
+                              public NotificationObserver {
+ public:
+  static UserCrosSettingsTrust* GetSharedInstance() {
+    return Singleton<UserCrosSettingsTrust>::get();
+  }
+
+  // Working horse for UserCrosSettingsProvider::RequestTrusted* family.
+  bool RequestTrustedEntity(const std::string& name, Task* callback) {
+    if (GetOwnershipStatus() == OWNERSHIP_NONE)
+      return true;
+    if (GetOwnershipStatus() == OWNERSHIP_TAKEN) {
+      DCHECK(g_browser_process);
+      PrefService* prefs = g_browser_process->local_state();
+      DCHECK(prefs);
+      if (prefs->GetBoolean((name + kTrustedSuffix).c_str()))
+        return true;
+    }
+    if (callback)
+      callbacks_[name].push_back(callback);
+    return false;
+  }
+
+  void Set(const std::string& path, Value* in_value) {
+    if (!UserManager::Get()->current_user_is_owner()) {
+      LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
+
+      // Revert UI change.
+      CrosSettings::Get()->FireObservers(path.c_str());
+      return;
+    }
+
+    if (IsControlledBooleanSetting(path)) {
+      bool bool_value = false;
+      if (in_value->GetAsBoolean(&bool_value)) {
+        std::string value = bool_value ? kTrueIncantation : kFalseIncantation;
+        SignedSettingsHelper::Get()->StartStorePropertyOp(path, value, this);
+        UpdateCacheBool(path, bool_value, USE_VALUE_SUPPLIED);
+
+        VLOG(1) << "Set cros setting " << path << "=" << value;
+      }
+    } else if (path == kDeviceOwner) {
+      VLOG(1) << "Setting owner is not supported. Please use "
+                 "'UpdateCachedOwner' instead.";
+    } else if (path == kAccountsPrefUsers) {
+      VLOG(1) << "Setting user whitelist is not implemented.  Please use "
+                 "whitelist/unwhitelist instead.";
+    } else {
+      LOG(WARNING) << "Try to set unhandled cros setting " << path;
+    }
+  }
+
+ private:
+  // Listed in upgrade order.
+  enum OwnershipStatus {
+    OWNERSHIP_UNKNOWN = 0,
+    OWNERSHIP_NONE,
+    OWNERSHIP_TAKEN
+  };
+
+  // Used to discriminate different sources of ownership status info.
+  enum OwnershipSource {
+    SOURCE_FETCH,  // Info comes from FetchOwnershipStatus method.
+    SOURCE_OBSERVE // Info comes from Observe method.
+  };
+
+  // upper bound for number of retries to fetch a signed setting.
+  static const int kNumRetriesLimit = 9;
+
+  UserCrosSettingsTrust() : ownership_status_(OWNERSHIP_UNKNOWN),
+                            retries_left_(kNumRetriesLimit) {
+    notification_registrar_.Add(this,
+                                NotificationType::OWNERSHIP_TAKEN,
+                                NotificationService::AllSources());
+    // Start getting ownership status.
+    BrowserThread::PostTask(
+        BrowserThread::FILE,
+        FROM_HERE,
+        NewRunnableMethod(this, &UserCrosSettingsTrust::FetchOwnershipStatus));
+  }
+
+  ~UserCrosSettingsTrust() {
+    if (BrowserThread::CurrentlyOn(BrowserThread::UI) &&
+        CrosLibrary::Get()->EnsureLoaded()) {
+      // Cancels all pending callbacks from us.
+      SignedSettingsHelper::Get()->CancelCallback(this);
+    }
+  }
+
+  void FetchOwnershipStatus() {
+    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+    OwnershipStatus status =
+        OwnershipService::GetSharedInstance()->IsAlreadyOwned() ?
+        OWNERSHIP_TAKEN : OWNERSHIP_NONE;
+    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+        NewRunnableMethod(this, &UserCrosSettingsTrust::SetOwnershipStatus,
+            status, SOURCE_FETCH));
+  }
+
+  void SetOwnershipStatus(OwnershipStatus new_status,
+                          OwnershipSource source) {
+    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+    DCHECK(new_status == OWNERSHIP_TAKEN || new_status == OWNERSHIP_NONE);
+    if (source == SOURCE_FETCH) {
+      DCHECK(ownership_status_ != OWNERSHIP_NONE);
+      if (ownership_status_ == OWNERSHIP_TAKEN) {
+        // OWNERSHIP_TAKEN notification was observed earlier.
+        return;
+      }
+    }
+    ownership_status_ = new_status;
+    if (source == SOURCE_FETCH) {
+      // Start prefetching Boolean and String preferences.
+      for (size_t i = 0; i < arraysize(kBooleanSettings); ++i)
+        StartFetchingSetting(kBooleanSettings[i]);
+      for (size_t i = 0; i < arraysize(kStringSettings); ++i)
+        StartFetchingSetting(kStringSettings[i]);
+    } else if (source == SOURCE_OBSERVE) {
+      DCHECK(new_status == OWNERSHIP_TAKEN);
+      if (CrosLibrary::Get()->EnsureLoaded()) {
+        // TODO(dilmah,cmasone): We would not need following piece of code as
+        // long as failure callback from SignedSettings will allow us to
+        // discriminate missing settings from failed signature verification.
+        // Otherwise we must set default values for boolean settings.
+        UserManager::Get()->set_current_user_is_owner(true);
+        for (size_t i = 0; i < arraysize(kBooleanSettings); ++i)
+          Set(kBooleanSettings[i], Value::CreateBooleanValue(true));
+      }
+    }
+  }
+
+  // Returns ownership status.
+  // Called on UI thread unlike OwnershipService::IsAlreadyOwned.
+  OwnershipStatus GetOwnershipStatus() {
+    return ownership_status_;
+  }
+
+  void StartFetchingSetting(const std::string& name) {
+    DCHECK(g_browser_process);
+    PrefService* prefs = g_browser_process->local_state();
+    if (!prefs)
+      return;
+    // Do not trust before fetching complete.
+    prefs->ClearPref((name + kTrustedSuffix).c_str());
+    prefs->ScheduleSavePersistentPrefs();
+    if (CrosLibrary::Get()->EnsureLoaded()) {
+      SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
+    }
+  }
+
+  // Implementation of SignedSettingsHelper::Callback.
+  virtual void OnRetrievePropertyCompleted(bool success,
+                                           const std::string& name,
+                                           const std::string& value) {
+    if (!IsControlledBooleanSetting(name) && !IsControlledStringSetting(name)) {
+      NOTREACHED();
+      return;
+    }
+    DCHECK(GetOwnershipStatus() != OWNERSHIP_UNKNOWN);
+
+    PrefService* prefs = g_browser_process->local_state();
+    if (!success && GetOwnershipStatus() == OWNERSHIP_TAKEN) {
+      LOG(ERROR) << "On owned device: failed to retrieve cros "
+                    "setting, name=" << name;
+      if (retries_left_ > 0) {
+        retries_left_ -= 1;
+        StartFetchingSetting(name);
+        return;
+      }
+      LOG(ERROR) << "No retries left";
+      if (IsControlledBooleanSetting(name)) {
+        // For boolean settings we can just set safe (false) values
+        // and continue as trusted.
+        UpdateCacheBool(name, false, USE_VALUE_SUPPLIED);
+      } else {
+        prefs->ClearPref((name + kTrustedSuffix).c_str());
+        return;
+      }
+    } else {
+      DCHECK(success || GetOwnershipStatus() == OWNERSHIP_NONE);
+      if (success)
+        VLOG(1) << "Retrieved cros setting " << name << "=" << value;
+      else
+        VLOG(1) << "We are disowned. Going default for cros setting " << name;
+      if (IsControlledBooleanSetting(name)) {
+        // Our boolean settings are true by default (if not explicitly present).
+        UpdateCacheBool(name, (value == kTrueIncantation),
+                        success ? USE_VALUE_SUPPLIED : USE_VALUE_DEFAULT);
+      } else if (IsControlledStringSetting(name)) {
+        UpdateCacheString(name, value,
+                          success ? USE_VALUE_SUPPLIED : USE_VALUE_DEFAULT);
+      }
+    }
+    prefs->SetBoolean((name + kTrustedSuffix).c_str(), true);
+    {
+      DCHECK(GetOwnershipStatus() != OWNERSHIP_UNKNOWN);
+      std::vector<Task*>& callbacks_vector = callbacks_[name];
+      for (size_t i = 0; i < callbacks_vector.size(); ++i)
+        MessageLoop::current()->PostTask(FROM_HERE, callbacks_vector[i]);
+      callbacks_vector.clear();
+    }
+    if (success)
+      CrosSettings::Get()->FireObservers(name.c_str());
+  }
+
+  // Implementation of SignedSettingsHelper::Callback.
+  virtual void OnStorePropertyCompleted(bool success,
+                                        const std::string& name,
+                                        const std::string& value) {
+    VLOG(1) << "Store cros setting " << name << "=" << value << ", success="
+            << success;
+
+    // Reload the setting if store op fails.
+    if (!success)
+      SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
+  }
+
+  // Implementation of SignedSettingsHelper::Callback.
+  virtual void OnWhitelistCompleted(bool success, const std::string& email) {
+    VLOG(1) << "Add " << email << " to whitelist, success=" << success;
+
+    // Reload the whitelist on settings op failure.
+    if (!success)
+      CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
+  }
+
+  // Implementation of SignedSettingsHelper::Callback.
+  virtual void OnUnwhitelistCompleted(bool success, const std::string& email) {
+    VLOG(1) << "Remove " << email << " from whitelist, success=" << success;
+
+    // Reload the whitelist on settings op failure.
+    if (!success)
+      CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
+  }
+
+  // NotificationObserver implementation.
+  virtual void Observe(NotificationType type,
+                       const NotificationSource& source,
+                       const NotificationDetails& details) {
+    if (type.value == NotificationType::OWNERSHIP_TAKEN) {
+      SetOwnershipStatus(OWNERSHIP_TAKEN, SOURCE_OBSERVE);
+      notification_registrar_.RemoveAll();
+    } else {
+      NOTREACHED();
+    }
+  }
+
+  // Pending callbacks that need to be invoked after settings verification.
+  base::hash_map< std::string, std::vector< Task* > > callbacks_;
+
+  NotificationRegistrar notification_registrar_;
+  OwnershipStatus ownership_status_;
+
+  // In order to guard against occasional failure to fetch a property
+  // we allow for some number of retries.
+  int retries_left_;
+
+  friend class SignedSettingsHelper;
+  friend struct DefaultSingletonTraits<UserCrosSettingsTrust>;
+
+  DISALLOW_COPY_AND_ASSIGN(UserCrosSettingsTrust);
+};
+
 }  // namespace
 
-UserCrosSettingsProvider::UserCrosSettingsProvider() {
-  StartFetchingBoolSetting(kAccountsPrefAllowGuest);
-  StartFetchingBoolSetting(kAccountsPrefAllowNewUser);
-  StartFetchingBoolSetting(kAccountsPrefShowUserNamesOnSignIn);
-  StartFetchingStringSetting(kDeviceOwner);
-}
+}  // namespace chromeos
 
-UserCrosSettingsProvider::~UserCrosSettingsProvider() {
-  // Cancels all pending callbacks from us.
-  SignedSettingsHelper::Get()->CancelCallback(this);
+// We want to use NewRunnableMethod with this class but need to disable
+// reference counting since it is singleton.
+DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::UserCrosSettingsTrust);
+
+namespace chromeos {
+
+UserCrosSettingsProvider::UserCrosSettingsProvider() {
+  // Trigger prefetching of settings.
+  UserCrosSettingsTrust::GetSharedInstance();
 }
 
 // static
 void UserCrosSettingsProvider::RegisterPrefs(PrefService* local_state) {
-  // Cached signed settings values
-  local_state->RegisterBooleanPref(kAccountsPrefAllowGuest, true);
-  local_state->RegisterBooleanPref(kAccountsPrefAllowNewUser, true);
-  local_state->RegisterBooleanPref(kAccountsPrefShowUserNamesOnSignIn, true);
-  local_state->RegisterListPref(kAccountsPrefUsers);
-  local_state->RegisterStringPref(kDeviceOwner, "");
+  for (size_t i = 0; i < arraysize(kBooleanSettings); ++i)
+    RegisterSetting(local_state, kBooleanSettings[i]);
+  for (size_t i = 0; i < arraysize(kStringSettings); ++i)
+    RegisterSetting(local_state, kStringSettings[i]);
+  for (size_t i = 0; i < arraysize(kListSettings); ++i)
+    RegisterSetting(local_state, kListSettings[i]);
+}
+
+bool UserCrosSettingsProvider::RequestTrustedAllowGuest(Task* callback) {
+  return UserCrosSettingsTrust::GetSharedInstance()->RequestTrustedEntity(
+      kAccountsPrefAllowGuest, callback);
+}
+
+bool UserCrosSettingsProvider::RequestTrustedAllowNewUser(Task* callback) {
+  return UserCrosSettingsTrust::GetSharedInstance()->RequestTrustedEntity(
+      kAccountsPrefAllowNewUser, callback);
+}
+
+bool UserCrosSettingsProvider::RequestTrustedShowUsersOnSignin(Task* callback) {
+  return UserCrosSettingsTrust::GetSharedInstance()->RequestTrustedEntity(
+      kAccountsPrefShowUserNamesOnSignIn, callback);
+}
+
+bool UserCrosSettingsProvider::RequestTrustedOwner(Task* callback) {
+  return UserCrosSettingsTrust::GetSharedInstance()->RequestTrustedEntity(
+      kDeviceOwner, callback);
 }
 
 // static
 bool UserCrosSettingsProvider::cached_allow_guest() {
+  // Trigger prefetching if singleton object still does not exist.
+  UserCrosSettingsTrust::GetSharedInstance();
   return g_browser_process->local_state()->GetBoolean(kAccountsPrefAllowGuest);
 }
 
 // static
 bool UserCrosSettingsProvider::cached_allow_new_user() {
+  // Trigger prefetching if singleton object still does not exist.
+  UserCrosSettingsTrust::GetSharedInstance();
   return g_browser_process->local_state()->GetBoolean(
     kAccountsPrefAllowNewUser);
 }
 
 // static
 bool UserCrosSettingsProvider::cached_show_users_on_signin() {
+  // Trigger prefetching if singleton object still does not exist.
+  UserCrosSettingsTrust::GetSharedInstance();
   return g_browser_process->local_state()->GetBoolean(
       kAccountsPrefShowUserNamesOnSignIn);
 }
@@ -132,6 +502,8 @@ const ListValue* UserCrosSettingsProvider::cached_whitelist() {
 
 // static
 std::string UserCrosSettingsProvider::cached_owner() {
+  // Trigger prefetching if singleton object still does not exist.
+  UserCrosSettingsTrust::GetSharedInstance();
   if (!g_browser_process || !g_browser_process->local_state())
     return std::string();
   return g_browser_process->local_state()->GetString(kDeviceOwner);
@@ -154,41 +526,12 @@ bool UserCrosSettingsProvider::IsEmailInCachedWhitelist(
 
 void UserCrosSettingsProvider::DoSet(const std::string& path,
                                      Value* in_value) {
-  if (!UserManager::Get()->current_user_is_owner()) {
-    LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
-
-    // Revert UI change.
-    CrosSettings::Get()->FireObservers(path.c_str());
-    return;
-  }
-
-  if (path == kAccountsPrefAllowGuest ||
-      path == kAccountsPrefAllowNewUser ||
-      path == kAccountsPrefShowUserNamesOnSignIn) {
-    bool bool_value = false;
-    if (in_value->GetAsBoolean(&bool_value)) {
-      std::string value = bool_value ? "true" : "false";
-      SignedSettingsHelper::Get()->StartStorePropertyOp(path, value, this);
-      UpdateCacheBool(path.c_str(), bool_value);
-
-      VLOG(1) << "Set cros setting " << path << "=" << value;
-    }
-  } else if (path == kDeviceOwner) {
-    VLOG(1) << "Setting owner is not supported. Please use 'UpdateCachedOwner' "
-               "instead.";
-  } else if (path == kAccountsPrefUsers) {
-    VLOG(1) << "Setting user whitelist is not implemented.  Please use "
-               "whitelist/unwhitelist instead.";
-  } else {
-    LOG(WARNING) << "Try to set unhandled cros setting " << path;
-  }
+  UserCrosSettingsTrust::GetSharedInstance()->Set(path, in_value);
 }
 
 bool UserCrosSettingsProvider::Get(const std::string& path,
                                    Value** out_value) const {
-  if (path == kAccountsPrefAllowGuest ||
-      path == kAccountsPrefAllowNewUser ||
-      path == kAccountsPrefShowUserNamesOnSignIn) {
+  if (IsControlledBooleanSetting(path)) {
     *out_value = CreateSettingsBooleanValue(
         g_browser_process->local_state()->GetBoolean(path.c_str()),
         !UserManager::Get()->current_user_is_owner());
@@ -207,56 +550,9 @@ bool UserCrosSettingsProvider::HandlesSetting(const std::string& path) {
   return ::StartsWithASCII(path, "cros.accounts.", true);
 }
 
-void UserCrosSettingsProvider::OnWhitelistCompleted(bool success,
-    const std::string& email) {
-  VLOG(1) << "Add " << email << " to whitelist, success=" << success;
-
-  // Reload the whitelist on settings op failure.
-  if (!success)
-    CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
-}
-
-void UserCrosSettingsProvider::OnUnwhitelistCompleted(bool success,
-    const std::string& email) {
-  VLOG(1) << "Remove " << email << " from whitelist, success=" << success;
-
-  // Reload the whitelist on settings op failure.
-  if (!success)
-    CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
-}
-
-void UserCrosSettingsProvider::OnStorePropertyCompleted(
-    bool success, const std::string& name, const std::string& value) {
-  VLOG(1) << "Store cros setting " << name << "=" << value << ", success="
-          << success;
-
-  // Reload the setting if store op fails.
-  if (!success)
-    SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
-}
-
-void UserCrosSettingsProvider::OnRetrievePropertyCompleted(
-    bool success, const std::string& name, const std::string& value) {
-  if (!success) {
-    LOG(WARNING) << "Failed to retrieve cros setting, name=" << name;
-    return;
-  }
-
-  VLOG(1) << "Retrieved cros setting " << name << "=" << value;
-
-  if (bool_settings_.count(name)) {
-    UpdateCacheBool(name.c_str(), value == "true" ? true : false);
-  }
-
-  if (string_settings_.count(name)) {
-    UpdateCacheString(name.c_str(), value);
-  }
-
-  CrosSettings::Get()->FireObservers(name.c_str());
-}
-
 void UserCrosSettingsProvider::WhitelistUser(const std::string& email) {
-  SignedSettingsHelper::Get()->StartWhitelistOp(email, true, this);
+  SignedSettingsHelper::Get()->StartWhitelistOp(
+      email, true, UserCrosSettingsTrust::GetSharedInstance());
 
   PrefService* prefs = g_browser_process->local_state();
   ListValue* cached_whitelist = prefs->GetMutableList(kAccountsPrefUsers);
@@ -265,7 +561,8 @@ void UserCrosSettingsProvider::WhitelistUser(const std::string& email) {
 }
 
 void UserCrosSettingsProvider::UnwhitelistUser(const std::string& email) {
-  SignedSettingsHelper::Get()->StartWhitelistOp(email, false, this);
+  SignedSettingsHelper::Get()->StartWhitelistOp(
+      email, false, UserCrosSettingsTrust::GetSharedInstance());
 
   PrefService* prefs = g_browser_process->local_state();
   ListValue* cached_whitelist = prefs->GetMutableList(kAccountsPrefUsers);
@@ -276,25 +573,7 @@ void UserCrosSettingsProvider::UnwhitelistUser(const std::string& email) {
 
 // static
 void UserCrosSettingsProvider::UpdateCachedOwner(const std::string& email) {
-  UpdateCacheString(kDeviceOwner, email);
-}
-
-void UserCrosSettingsProvider::StartFetchingBoolSetting(
-    const std::string& name) {
-  bool_settings_.insert(name);
-  StartFetchingSetting(name);
-}
-
-void UserCrosSettingsProvider::StartFetchingStringSetting(
-    const std::string& name) {
-  string_settings_.insert(name);
-  StartFetchingSetting(name);
-}
-
-void UserCrosSettingsProvider::StartFetchingSetting(
-    const std::string& name) {
-  if (CrosLibrary::Get()->EnsureLoaded())
-    SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
+  UpdateCacheString(kDeviceOwner, email, USE_VALUE_SUPPLIED);
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/user_cros_settings_provider.h b/chrome/browser/chromeos/user_cros_settings_provider.h
index aa7db0f2047cd..7b000ca5b0156 100644
--- a/chrome/browser/chromeos/user_cros_settings_provider.h
+++ b/chrome/browser/chromeos/user_cros_settings_provider.h
@@ -9,24 +9,33 @@
 #include <string>
 
 #include "base/basictypes.h"
-#include "base/hash_tables.h"
 #include "chrome/browser/chromeos/cros_settings_provider.h"
 #include "chrome/browser/chromeos/login/signed_settings_helper.h"
 
 class ListValue;
 class PrefService;
+class Task;
 
 namespace chromeos {
 
-class UserCrosSettingsProvider : public CrosSettingsProvider,
-                                 public SignedSettingsHelper::Callback {
+class UserCrosSettingsProvider : public CrosSettingsProvider {
  public:
   UserCrosSettingsProvider();
-  virtual ~UserCrosSettingsProvider();
+  virtual ~UserCrosSettingsProvider() {}
 
   // Registers cached users settings in preferences.
   static void RegisterPrefs(PrefService* local_state);
 
+  // Methods to use when trusted (signature verified) values are required.
+  // Return true if subsequent call to corresponding cached_* getter shall
+  // return trusted value.
+  // Return false if trusted values are unavailable at a moment.
+  // In latter case passed task will be posted when ready.
+  bool RequestTrustedAllowGuest(Task* callback);
+  bool RequestTrustedAllowNewUser(Task* callback);
+  bool RequestTrustedShowUsersOnSignin(Task* callback);
+  bool RequestTrustedOwner(Task* callback);
+
   // Helper functions to access cached settings.
   static bool cached_allow_guest();
   static bool cached_allow_new_user();
@@ -43,14 +52,6 @@ class UserCrosSettingsProvider : public CrosSettingsProvider,
   virtual bool Get(const std::string& path, Value** out_value) const;
   virtual bool HandlesSetting(const std::string& path);
 
-  // SignedSettingsHelper::Callback overrides.
-  virtual void OnWhitelistCompleted(bool success, const std::string& email);
-  virtual void OnUnwhitelistCompleted(bool success, const std::string& email);
-  virtual void OnStorePropertyCompleted(
-      bool success, const std::string& name, const std::string& value);
-  virtual void OnRetrievePropertyCompleted(
-      bool success, const std::string& name, const std::string& value);
-
   void WhitelistUser(const std::string& email);
   void UnwhitelistUser(const std::string& email);
 
@@ -61,13 +62,6 @@ class UserCrosSettingsProvider : public CrosSettingsProvider,
   // CrosSettingsProvider implementation.
   virtual void DoSet(const std::string& path, Value* value);
 
-  void StartFetchingBoolSetting(const std::string& name);
-  void StartFetchingStringSetting(const std::string& name);
-  void StartFetchingSetting(const std::string& name);
-
-  base::hash_set<std::string> bool_settings_;
-  base::hash_set<std::string> string_settings_;
-
   DISALLOW_COPY_AND_ASSIGN(UserCrosSettingsProvider);
 };
 
diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h
index eba0332358617..3adc3ff0641b0 100644
--- a/chrome/common/notification_type.h
+++ b/chrome/common/notification_type.h
@@ -1243,6 +1243,9 @@ class NotificationType {
     // os device has failed.
     OWNER_KEY_FETCH_ATTEMPT_FAILED,
 
+    // Sent after device was successfully owned.
+    OWNERSHIP_TAKEN,
+
     // This is sent to a ChromeOS settings observer when a system setting is
     // changed. The source is the CrosSettings and the details a std::string of
     // the changed setting.