| Index: chrome/browser/chromeos/device_settings_provider.cc
|
| diff --git a/chrome/browser/chromeos/device_settings_provider.cc b/chrome/browser/chromeos/device_settings_provider.cc
|
| deleted file mode 100644
|
| index 27fb09ddf644d9485f68c1e3828bd8be33b150a0..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/chromeos/device_settings_provider.cc
|
| +++ /dev/null
|
| @@ -1,748 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/chromeos/device_settings_provider.h"
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/bind_helpers.h"
|
| -#include "base/callback.h"
|
| -#include "base/file_util.h"
|
| -#include "base/logging.h"
|
| -#include "base/string_util.h"
|
| -#include "base/threading/thread_restrictions.h"
|
| -#include "base/values.h"
|
| -#include "chrome/browser/browser_process.h"
|
| -#include "chrome/browser/chromeos/cros/cros_library.h"
|
| -#include "chrome/browser/chromeos/cros/network_library.h"
|
| -#include "chrome/browser/chromeos/cros_settings.h"
|
| -#include "chrome/browser/chromeos/cros_settings_names.h"
|
| -#include "chrome/browser/chromeos/login/signed_settings_cache.h"
|
| -#include "chrome/browser/chromeos/login/signed_settings_helper.h"
|
| -#include "chrome/browser/chromeos/login/user_manager.h"
|
| -#include "chrome/browser/policy/app_pack_updater.h"
|
| -#include "chrome/browser/policy/browser_policy_connector.h"
|
| -#include "chrome/browser/policy/cloud_policy_constants.h"
|
| -#include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
|
| -#include "chrome/browser/ui/options/options_util.h"
|
| -#include "chrome/common/chrome_notification_types.h"
|
| -#include "chrome/installer/util/google_update_settings.h"
|
| -#include "content/public/browser/notification_service.h"
|
| -
|
| -using google::protobuf::RepeatedPtrField;
|
| -
|
| -namespace em = enterprise_management;
|
| -
|
| -namespace chromeos {
|
| -
|
| -namespace {
|
| -
|
| -// List of settings handled by the DeviceSettingsProvider.
|
| -const char* kKnownSettings[] = {
|
| - kAccountsPrefAllowGuest,
|
| - kAccountsPrefAllowNewUser,
|
| - kAccountsPrefEphemeralUsersEnabled,
|
| - kAccountsPrefShowUserNamesOnSignIn,
|
| - kAccountsPrefUsers,
|
| - kAppPack,
|
| - kDeviceOwner,
|
| - kIdleLogoutTimeout,
|
| - kIdleLogoutWarningDuration,
|
| - kPolicyMissingMitigationMode,
|
| - kReleaseChannel,
|
| - kReleaseChannelDelegated,
|
| - kReportDeviceActivityTimes,
|
| - kReportDeviceBootMode,
|
| - kReportDeviceLocation,
|
| - kReportDeviceVersionInfo,
|
| - kScreenSaverExtensionId,
|
| - kScreenSaverTimeout,
|
| - kSettingProxyEverywhere,
|
| - kSignedDataRoamingEnabled,
|
| - kStartUpUrls,
|
| - kStatsReportingPref,
|
| -};
|
| -
|
| -// Upper bound for number of retries to fetch a signed setting.
|
| -static const int kNumRetriesLimit = 9;
|
| -
|
| -// Legacy policy file location. Used to detect migration from pre v12 ChromeOS.
|
| -const char kLegacyPolicyFile[] = "/var/lib/whitelist/preferences";
|
| -
|
| -bool IsControlledSetting(const std::string& pref_path) {
|
| - const char** end = kKnownSettings + arraysize(kKnownSettings);
|
| - return std::find(kKnownSettings, end, pref_path) != end;
|
| -}
|
| -
|
| -bool HasOldMetricsFile() {
|
| - // TODO(pastarmovj): Remove this once migration is not needed anymore.
|
| - // If the value is not set we should try to migrate legacy consent file.
|
| - // Loading consent file state causes us to do blocking IO on UI thread.
|
| - // Temporarily allow it until we fix http://crbug.com/62626
|
| - base::ThreadRestrictions::ScopedAllowIO allow_io;
|
| - return GoogleUpdateSettings::GetCollectStatsConsent();
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -DeviceSettingsProvider::DeviceSettingsProvider(
|
| - const NotifyObserversCallback& notify_cb,
|
| - SignedSettingsHelper* signed_settings_helper)
|
| - : CrosSettingsProvider(notify_cb),
|
| - signed_settings_helper_(signed_settings_helper),
|
| - ownership_status_(OwnershipService::GetSharedInstance()->GetStatus(true)),
|
| - migration_helper_(new SignedSettingsMigrationHelper()),
|
| - retries_left_(kNumRetriesLimit),
|
| - trusted_status_(TEMPORARILY_UNTRUSTED) {
|
| - // Register for notification when ownership is taken so that we can update
|
| - // the |ownership_status_| and reload if needed.
|
| - registrar_.Add(this, chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED,
|
| - content::NotificationService::AllSources());
|
| - // Make sure we have at least the cache data immediately.
|
| - RetrieveCachedData();
|
| - // Start prefetching preferences.
|
| - Reload();
|
| -}
|
| -
|
| -DeviceSettingsProvider::~DeviceSettingsProvider() {
|
| -}
|
| -
|
| -void DeviceSettingsProvider::Reload() {
|
| - // While fetching we can't trust the cache anymore.
|
| - trusted_status_ = TEMPORARILY_UNTRUSTED;
|
| - if (ownership_status_ == OwnershipService::OWNERSHIP_NONE) {
|
| - RetrieveCachedData();
|
| - } else {
|
| - // Retrieve the real data.
|
| - signed_settings_helper_->StartRetrievePolicyOp(
|
| - base::Bind(&DeviceSettingsProvider::OnRetrievePolicyCompleted,
|
| - base::Unretained(this)));
|
| - }
|
| -}
|
| -
|
| -void DeviceSettingsProvider::DoSet(const std::string& path,
|
| - const base::Value& in_value) {
|
| - if (!UserManager::Get()->IsCurrentUserOwner() &&
|
| - ownership_status_ != OwnershipService::OWNERSHIP_NONE) {
|
| - LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
|
| -
|
| - // Revert UI change.
|
| - NotifyObservers(path);
|
| - return;
|
| - }
|
| -
|
| - if (IsControlledSetting(path)) {
|
| - pending_changes_.push_back(PendingQueueElement(path, in_value.DeepCopy()));
|
| - if (pending_changes_.size() == 1)
|
| - SetInPolicy();
|
| - } else {
|
| - NOTREACHED() << "Try to set unhandled cros setting " << path;
|
| - }
|
| -}
|
| -
|
| -void DeviceSettingsProvider::Observe(
|
| - int type,
|
| - const content::NotificationSource& source,
|
| - const content::NotificationDetails& details) {
|
| - if (type == chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED) {
|
| - // Reload the policy blob once the owner key has been loaded or updated.
|
| - ownership_status_ = OwnershipService::OWNERSHIP_TAKEN;
|
| - Reload();
|
| - }
|
| -}
|
| -
|
| -const em::PolicyData DeviceSettingsProvider::policy() const {
|
| - return policy_;
|
| -}
|
| -
|
| -void DeviceSettingsProvider::RetrieveCachedData() {
|
| - // If there is no owner yet, this function will pull the policy cache from the
|
| - // temp storage and use that instead.
|
| - em::PolicyData policy;
|
| - if (!signed_settings_cache::Retrieve(&policy,
|
| - g_browser_process->local_state())) {
|
| - VLOG(1) << "Can't retrieve temp store possibly not created yet.";
|
| - // Prepare empty data for the case we don't have temp cache yet.
|
| - policy.set_policy_type(kDevicePolicyType);
|
| - em::ChromeDeviceSettingsProto pol;
|
| - policy.set_policy_value(pol.SerializeAsString());
|
| - }
|
| -
|
| - policy_ = policy;
|
| - UpdateValuesCache();
|
| -}
|
| -
|
| -void DeviceSettingsProvider::SetInPolicy() {
|
| - if (pending_changes_.empty()) {
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| -
|
| - const std::string& prop = pending_changes_[0].first;
|
| - base::Value* value = pending_changes_[0].second;
|
| - if (prop == kDeviceOwner) {
|
| - // Just store it in the memory cache without trusted checks or persisting.
|
| - std::string owner;
|
| - if (value->GetAsString(&owner)) {
|
| - policy_.set_username(owner);
|
| - // In this case the |value_cache_| takes the ownership of |value|.
|
| - values_cache_.SetValue(prop, value);
|
| - NotifyObservers(prop);
|
| - // We can't trust this value anymore until we reload the real username.
|
| - trusted_status_ = TEMPORARILY_UNTRUSTED;
|
| - pending_changes_.erase(pending_changes_.begin());
|
| - if (!pending_changes_.empty())
|
| - SetInPolicy();
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| - return;
|
| - }
|
| -
|
| - if (RequestTrustedEntity() != TRUSTED) {
|
| - // Otherwise we should first reload and apply on top of that.
|
| - signed_settings_helper_->StartRetrievePolicyOp(
|
| - base::Bind(&DeviceSettingsProvider::FinishSetInPolicy,
|
| - base::Unretained(this)));
|
| - return;
|
| - }
|
| -
|
| - trusted_status_ = TEMPORARILY_UNTRUSTED;
|
| - em::PolicyData data = policy();
|
| - em::ChromeDeviceSettingsProto pol;
|
| - pol.ParseFromString(data.policy_value());
|
| - if (prop == kAccountsPrefAllowNewUser) {
|
| - em::AllowNewUsersProto* allow = pol.mutable_allow_new_users();
|
| - bool allow_value;
|
| - if (value->GetAsBoolean(&allow_value))
|
| - allow->set_allow_new_users(allow_value);
|
| - else
|
| - NOTREACHED();
|
| - } else if (prop == kAccountsPrefAllowGuest) {
|
| - em::GuestModeEnabledProto* guest = pol.mutable_guest_mode_enabled();
|
| - bool guest_value;
|
| - if (value->GetAsBoolean(&guest_value))
|
| - guest->set_guest_mode_enabled(guest_value);
|
| - else
|
| - NOTREACHED();
|
| - } else if (prop == kAccountsPrefShowUserNamesOnSignIn) {
|
| - em::ShowUserNamesOnSigninProto* show = pol.mutable_show_user_names();
|
| - bool show_value;
|
| - if (value->GetAsBoolean(&show_value))
|
| - show->set_show_user_names(show_value);
|
| - else
|
| - NOTREACHED();
|
| - } else if (prop == kSignedDataRoamingEnabled) {
|
| - em::DataRoamingEnabledProto* roam = pol.mutable_data_roaming_enabled();
|
| - bool roaming_value = false;
|
| - if (value->GetAsBoolean(&roaming_value))
|
| - roam->set_data_roaming_enabled(roaming_value);
|
| - else
|
| - NOTREACHED();
|
| - ApplyRoamingSetting(roaming_value);
|
| - } else if (prop == kSettingProxyEverywhere) {
|
| - // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed.
|
| - std::string proxy_value;
|
| - if (value->GetAsString(&proxy_value)) {
|
| - bool success =
|
| - pol.mutable_device_proxy_settings()->ParseFromString(proxy_value);
|
| - DCHECK(success);
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| - } else if (prop == kReleaseChannel) {
|
| - em::ReleaseChannelProto* release_channel = pol.mutable_release_channel();
|
| - std::string channel_value;
|
| - if (value->GetAsString(&channel_value))
|
| - release_channel->set_release_channel(channel_value);
|
| - else
|
| - NOTREACHED();
|
| - } else if (prop == kStatsReportingPref) {
|
| - em::MetricsEnabledProto* metrics = pol.mutable_metrics_enabled();
|
| - bool metrics_value = false;
|
| - if (value->GetAsBoolean(&metrics_value))
|
| - metrics->set_metrics_enabled(metrics_value);
|
| - else
|
| - NOTREACHED();
|
| - ApplyMetricsSetting(false, metrics_value);
|
| - } else if (prop == kAccountsPrefUsers) {
|
| - em::UserWhitelistProto* whitelist_proto = pol.mutable_user_whitelist();
|
| - whitelist_proto->clear_user_whitelist();
|
| - base::ListValue& users = static_cast<base::ListValue&>(*value);
|
| - for (base::ListValue::const_iterator i = users.begin();
|
| - i != users.end(); ++i) {
|
| - std::string email;
|
| - if ((*i)->GetAsString(&email))
|
| - whitelist_proto->add_user_whitelist(email.c_str());
|
| - }
|
| - } else if (prop == kAccountsPrefEphemeralUsersEnabled) {
|
| - em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
|
| - pol.mutable_ephemeral_users_enabled();
|
| - bool ephemeral_users_enabled_value = false;
|
| - if (value->GetAsBoolean(&ephemeral_users_enabled_value))
|
| - ephemeral_users_enabled->set_ephemeral_users_enabled(
|
| - ephemeral_users_enabled_value);
|
| - else
|
| - NOTREACHED();
|
| - } else {
|
| - // The remaining settings don't support Set(), since they are not
|
| - // intended to be customizable by the user:
|
| - // kAppPack
|
| - // kIdleLogoutTimeout
|
| - // kIdleLogoutWarningDuration
|
| - // kReleaseChannelDelegated
|
| - // kReportDeviceVersionInfo
|
| - // kReportDeviceActivityTimes
|
| - // kReportDeviceBootMode
|
| - // kReportDeviceLocation
|
| - // kScreenSaverExtensionId
|
| - // kScreenSaverTimeout
|
| - // kStartUpUrls
|
| -
|
| - NOTREACHED();
|
| - }
|
| - data.set_policy_value(pol.SerializeAsString());
|
| - // Set the cache to the updated value.
|
| - policy_ = data;
|
| - UpdateValuesCache();
|
| -
|
| - if (!signed_settings_cache::Store(data, g_browser_process->local_state()))
|
| - LOG(ERROR) << "Couldn't store to the temp storage.";
|
| -
|
| - if (ownership_status_ == OwnershipService::OWNERSHIP_TAKEN) {
|
| - em::PolicyFetchResponse policy_envelope;
|
| - policy_envelope.set_policy_data(policy_.SerializeAsString());
|
| - signed_settings_helper_->StartStorePolicyOp(
|
| - policy_envelope,
|
| - base::Bind(&DeviceSettingsProvider::OnStorePolicyCompleted,
|
| - base::Unretained(this)));
|
| - } else {
|
| - // OnStorePolicyCompleted won't get called in this case so proceed with any
|
| - // pending operations immediately.
|
| - delete pending_changes_[0].second;
|
| - pending_changes_.erase(pending_changes_.begin());
|
| - if (!pending_changes_.empty())
|
| - SetInPolicy();
|
| - }
|
| -}
|
| -
|
| -void DeviceSettingsProvider::FinishSetInPolicy(
|
| - SignedSettings::ReturnCode code,
|
| - const em::PolicyFetchResponse& policy) {
|
| - if (code != SignedSettings::SUCCESS) {
|
| - LOG(ERROR) << "Can't serialize to policy error code: " << code;
|
| - Reload();
|
| - return;
|
| - }
|
| - // Update the internal caches and set the trusted flag to true so that we
|
| - // can pass the trustedness check in the second call to SetInPolicy.
|
| - OnRetrievePolicyCompleted(code, policy);
|
| -
|
| - SetInPolicy();
|
| -}
|
| -
|
| -void DeviceSettingsProvider::DecodeLoginPolicies(
|
| - const em::ChromeDeviceSettingsProto& policy,
|
| - PrefValueMap* new_values_cache) const {
|
| - // For all our boolean settings the following is applicable:
|
| - // true is default permissive value and false is safe prohibitive value.
|
| - // Exceptions:
|
| - // kSignedDataRoamingEnabled has a default value of false.
|
| - // kAccountsPrefEphemeralUsersEnabled has a default value of false.
|
| - if (policy.has_allow_new_users() &&
|
| - policy.allow_new_users().has_allow_new_users() &&
|
| - policy.allow_new_users().allow_new_users()) {
|
| - // New users allowed, user_whitelist() ignored.
|
| - new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true);
|
| - } else if (!policy.has_user_whitelist()) {
|
| - // If we have the allow_new_users bool, and it is true, we honor that above.
|
| - // In all other cases (don't have it, have it and it is set to false, etc),
|
| - // We will honor the user_whitelist() if it is there and populated.
|
| - // Otherwise we default to allowing new users.
|
| - new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true);
|
| - } else {
|
| - new_values_cache->SetBoolean(
|
| - kAccountsPrefAllowNewUser,
|
| - policy.user_whitelist().user_whitelist_size() == 0);
|
| - }
|
| -
|
| - new_values_cache->SetBoolean(
|
| - kAccountsPrefAllowGuest,
|
| - !policy.has_guest_mode_enabled() ||
|
| - !policy.guest_mode_enabled().has_guest_mode_enabled() ||
|
| - policy.guest_mode_enabled().guest_mode_enabled());
|
| -
|
| - new_values_cache->SetBoolean(
|
| - kAccountsPrefShowUserNamesOnSignIn,
|
| - !policy.has_show_user_names() ||
|
| - !policy.show_user_names().has_show_user_names() ||
|
| - policy.show_user_names().show_user_names());
|
| -
|
| - new_values_cache->SetBoolean(
|
| - kAccountsPrefEphemeralUsersEnabled,
|
| - policy.has_ephemeral_users_enabled() &&
|
| - policy.ephemeral_users_enabled().has_ephemeral_users_enabled() &&
|
| - policy.ephemeral_users_enabled().ephemeral_users_enabled());
|
| -
|
| - base::ListValue* list = new base::ListValue();
|
| - const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist();
|
| - const RepeatedPtrField<std::string>& whitelist =
|
| - whitelist_proto.user_whitelist();
|
| - for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin();
|
| - it != whitelist.end(); ++it) {
|
| - list->Append(base::Value::CreateStringValue(*it));
|
| - }
|
| - new_values_cache->SetValue(kAccountsPrefUsers, list);
|
| -}
|
| -
|
| -void DeviceSettingsProvider::DecodeKioskPolicies(
|
| - const em::ChromeDeviceSettingsProto& policy,
|
| - PrefValueMap* new_values_cache) const {
|
| - if (policy.has_forced_logout_timeouts()) {
|
| - if (policy.forced_logout_timeouts().has_idle_logout_timeout()) {
|
| - new_values_cache->SetInteger(
|
| - kIdleLogoutTimeout,
|
| - policy.forced_logout_timeouts().idle_logout_timeout());
|
| - }
|
| -
|
| - if (policy.forced_logout_timeouts().has_idle_logout_warning_duration()) {
|
| - new_values_cache->SetInteger(
|
| - kIdleLogoutWarningDuration,
|
| - policy.forced_logout_timeouts().idle_logout_warning_duration());
|
| - }
|
| - }
|
| -
|
| - if (policy.has_login_screen_saver()) {
|
| - if (policy.login_screen_saver().has_screen_saver_timeout()) {
|
| - new_values_cache->SetInteger(
|
| - kScreenSaverTimeout,
|
| - policy.login_screen_saver().screen_saver_timeout());
|
| - }
|
| -
|
| - if (policy.login_screen_saver().has_screen_saver_extension_id()) {
|
| - new_values_cache->SetString(
|
| - kScreenSaverExtensionId,
|
| - policy.login_screen_saver().screen_saver_extension_id());
|
| - }
|
| - }
|
| -
|
| - if (policy.has_app_pack()) {
|
| - typedef RepeatedPtrField<em::AppPackEntryProto> proto_type;
|
| - base::ListValue* list = new base::ListValue;
|
| - const proto_type& app_pack = policy.app_pack().app_pack();
|
| - for (proto_type::const_iterator it = app_pack.begin();
|
| - it != app_pack.end(); ++it) {
|
| - base::DictionaryValue* entry = new base::DictionaryValue;
|
| - if (it->has_extension_id()) {
|
| - entry->SetString(policy::AppPackUpdater::kExtensionId,
|
| - it->extension_id());
|
| - }
|
| - if (it->has_update_url())
|
| - entry->SetString(policy::AppPackUpdater::kUpdateUrl, it->update_url());
|
| - list->Append(entry);
|
| - }
|
| - new_values_cache->SetValue(kAppPack, list);
|
| - }
|
| -
|
| - if (policy.has_start_up_urls()) {
|
| - base::ListValue* list = new base::ListValue();
|
| - const em::StartUpUrlsProto& urls_proto = policy.start_up_urls();
|
| - const RepeatedPtrField<std::string>& urls = urls_proto.start_up_urls();
|
| - for (RepeatedPtrField<std::string>::const_iterator it = urls.begin();
|
| - it != urls.end(); ++it) {
|
| - list->Append(base::Value::CreateStringValue(*it));
|
| - }
|
| - new_values_cache->SetValue(kStartUpUrls, list);
|
| - }
|
| -}
|
| -
|
| -void DeviceSettingsProvider::DecodeNetworkPolicies(
|
| - const em::ChromeDeviceSettingsProto& policy,
|
| - PrefValueMap* new_values_cache) const {
|
| - new_values_cache->SetBoolean(
|
| - kSignedDataRoamingEnabled,
|
| - policy.has_data_roaming_enabled() &&
|
| - policy.data_roaming_enabled().has_data_roaming_enabled() &&
|
| - policy.data_roaming_enabled().data_roaming_enabled());
|
| -
|
| - // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed.
|
| - std::string serialized;
|
| - if (policy.has_device_proxy_settings() &&
|
| - policy.device_proxy_settings().SerializeToString(&serialized)) {
|
| - new_values_cache->SetString(kSettingProxyEverywhere, serialized);
|
| - }
|
| -}
|
| -
|
| -void DeviceSettingsProvider::DecodeReportingPolicies(
|
| - const em::ChromeDeviceSettingsProto& policy,
|
| - PrefValueMap* new_values_cache) const {
|
| - if (policy.has_device_reporting()) {
|
| - if (policy.device_reporting().has_report_version_info()) {
|
| - new_values_cache->SetBoolean(
|
| - kReportDeviceVersionInfo,
|
| - policy.device_reporting().report_version_info());
|
| - }
|
| - if (policy.device_reporting().has_report_activity_times()) {
|
| - new_values_cache->SetBoolean(
|
| - kReportDeviceActivityTimes,
|
| - policy.device_reporting().report_activity_times());
|
| - }
|
| - if (policy.device_reporting().has_report_boot_mode()) {
|
| - new_values_cache->SetBoolean(
|
| - kReportDeviceBootMode,
|
| - policy.device_reporting().report_boot_mode());
|
| - }
|
| - // Device location reporting needs to pass privacy review before it can be
|
| - // enabled. crosbug.com/24681
|
| - // if (policy.device_reporting().has_report_location()) {
|
| - // new_values_cache->SetBoolean(
|
| - // kReportDeviceLocation,
|
| - // policy.device_reporting().report_location());
|
| - // }
|
| - }
|
| -}
|
| -
|
| -void DeviceSettingsProvider::DecodeGenericPolicies(
|
| - const em::ChromeDeviceSettingsProto& policy,
|
| - PrefValueMap* new_values_cache) const {
|
| - if (policy.has_metrics_enabled()) {
|
| - new_values_cache->SetBoolean(kStatsReportingPref,
|
| - policy.metrics_enabled().metrics_enabled());
|
| - } else {
|
| - new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile());
|
| - }
|
| -
|
| - if (!policy.has_release_channel() ||
|
| - !policy.release_channel().has_release_channel()) {
|
| - // Default to an invalid channel (will be ignored).
|
| - new_values_cache->SetString(kReleaseChannel, "");
|
| - } else {
|
| - new_values_cache->SetString(kReleaseChannel,
|
| - policy.release_channel().release_channel());
|
| - }
|
| -
|
| - new_values_cache->SetBoolean(
|
| - kReleaseChannelDelegated,
|
| - policy.has_release_channel() &&
|
| - policy.release_channel().has_release_channel_delegated() &&
|
| - policy.release_channel().release_channel_delegated());
|
| -}
|
| -
|
| -void DeviceSettingsProvider::UpdateValuesCache() {
|
| - const em::PolicyData data = policy();
|
| - PrefValueMap new_values_cache;
|
| -
|
| - if (data.has_username() && !data.has_request_token())
|
| - new_values_cache.SetString(kDeviceOwner, data.username());
|
| -
|
| - em::ChromeDeviceSettingsProto pol;
|
| - pol.ParseFromString(data.policy_value());
|
| -
|
| - DecodeLoginPolicies(pol, &new_values_cache);
|
| - DecodeKioskPolicies(pol, &new_values_cache);
|
| - DecodeNetworkPolicies(pol, &new_values_cache);
|
| - DecodeReportingPolicies(pol, &new_values_cache);
|
| - DecodeGenericPolicies(pol, &new_values_cache);
|
| -
|
| - // Collect all notifications but send them only after we have swapped the
|
| - // cache so that if somebody actually reads the cache will be already valid.
|
| - std::vector<std::string> notifications;
|
| - // Go through the new values and verify in the old ones.
|
| - PrefValueMap::iterator iter = new_values_cache.begin();
|
| - for (; iter != new_values_cache.end(); ++iter) {
|
| - const base::Value* old_value;
|
| - if (!values_cache_.GetValue(iter->first, &old_value) ||
|
| - !old_value->Equals(iter->second)) {
|
| - notifications.push_back(iter->first);
|
| - }
|
| - }
|
| - // Now check for values that have been removed from the policy blob.
|
| - for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) {
|
| - const base::Value* value;
|
| - if (!new_values_cache.GetValue(iter->first, &value))
|
| - notifications.push_back(iter->first);
|
| - }
|
| - // Swap and notify.
|
| - values_cache_.Swap(&new_values_cache);
|
| - for (size_t i = 0; i < notifications.size(); ++i)
|
| - NotifyObservers(notifications[i]);
|
| -}
|
| -
|
| -void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file,
|
| - bool new_value) const {
|
| - // TODO(pastarmovj): Remove this once migration is not needed anymore.
|
| - // If the value is not set we should try to migrate legacy consent file.
|
| - if (use_file) {
|
| - new_value = HasOldMetricsFile();
|
| - // Make sure the values will get eventually written to the policy file.
|
| - migration_helper_->AddMigrationValue(
|
| - kStatsReportingPref, base::Value::CreateBooleanValue(new_value));
|
| - migration_helper_->MigrateValues();
|
| - LOG(INFO) << "No metrics policy set will revert to checking "
|
| - << "consent file which is "
|
| - << (new_value ? "on." : "off.");
|
| - }
|
| - VLOG(1) << "Metrics policy is being set to : " << new_value
|
| - << "(use file : " << use_file << ")";
|
| - // TODO(pastarmovj): Remove this once we don't need to regenerate the
|
| - // consent file for the GUID anymore.
|
| - OptionsUtil::ResolveMetricsReportingEnabled(new_value);
|
| -}
|
| -
|
| -void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) const {
|
| - NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
|
| - const NetworkDevice* cellular = cros->FindCellularDevice();
|
| - if (cellular) {
|
| - bool device_value = cellular->data_roaming_allowed();
|
| - if (!device_value && cros->IsCellularAlwaysInRoaming()) {
|
| - // If operator requires roaming always enabled, ignore supplied value
|
| - // and set data roaming allowed in true always.
|
| - cros->SetCellularDataRoamingAllowed(true);
|
| - } else if (device_value != new_value) {
|
| - cros->SetCellularDataRoamingAllowed(new_value);
|
| - }
|
| - }
|
| -}
|
| -
|
| -void DeviceSettingsProvider::ApplySideEffects() const {
|
| - const em::PolicyData data = policy();
|
| - em::ChromeDeviceSettingsProto pol;
|
| - pol.ParseFromString(data.policy_value());
|
| - // First migrate metrics settings as needed.
|
| - if (pol.has_metrics_enabled())
|
| - ApplyMetricsSetting(false, pol.metrics_enabled().metrics_enabled());
|
| - else
|
| - ApplyMetricsSetting(true, false);
|
| - // Next set the roaming setting as needed.
|
| - ApplyRoamingSetting(pol.has_data_roaming_enabled() ?
|
| - pol.data_roaming_enabled().data_roaming_enabled() : false);
|
| -}
|
| -
|
| -bool DeviceSettingsProvider::MitigateMissingPolicy() {
|
| - // First check if the device has been owned already and if not exit
|
| - // immediately.
|
| - if (g_browser_process->browser_policy_connector()->GetDeviceMode() !=
|
| - policy::DEVICE_MODE_CONSUMER) {
|
| - return false;
|
| - }
|
| -
|
| - // If we are here the policy file were corrupted or missing. This can happen
|
| - // because we are migrating Pre R11 device to the new secure policies or there
|
| - // was an attempt to circumvent policy system. In this case we should populate
|
| - // the policy cache with "safe-mode" defaults which should allow the owner to
|
| - // log in but lock the device for anyone else until the policy blob has been
|
| - // recreated by the session manager.
|
| - LOG(ERROR) << "Corruption of the policy data has been detected."
|
| - << "Switching to \"safe-mode\" policies until the owner logs in "
|
| - << "to regenerate the policy data.";
|
| - values_cache_.SetBoolean(kAccountsPrefAllowNewUser, true);
|
| - values_cache_.SetBoolean(kAccountsPrefAllowGuest, true);
|
| - values_cache_.SetBoolean(kPolicyMissingMitigationMode, true);
|
| - trusted_status_ = TRUSTED;
|
| - // Make sure we will recreate the policy once the owner logs in.
|
| - // Any value not in this list will be left to the default which is fine as
|
| - // we repopulate the whitelist with the owner and all other existing users
|
| - // every time the owner enables whitelist filtering on the UI.
|
| - migration_helper_->AddMigrationValue(
|
| - kAccountsPrefAllowNewUser, base::Value::CreateBooleanValue(true));
|
| - migration_helper_->MigrateValues();
|
| - return true;
|
| -}
|
| -
|
| -const base::Value* DeviceSettingsProvider::Get(const std::string& path) const {
|
| - if (IsControlledSetting(path)) {
|
| - const base::Value* value;
|
| - if (values_cache_.GetValue(path, &value))
|
| - return value;
|
| - } else {
|
| - NOTREACHED() << "Trying to get non cros setting.";
|
| - }
|
| -
|
| - return NULL;
|
| -}
|
| -
|
| -DeviceSettingsProvider::TrustedStatus
|
| - DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) {
|
| - TrustedStatus status = RequestTrustedEntity();
|
| - if (status == TEMPORARILY_UNTRUSTED && !cb.is_null())
|
| - callbacks_.push_back(cb);
|
| - return status;
|
| -}
|
| -
|
| -bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
|
| - return IsControlledSetting(path);
|
| -}
|
| -
|
| -DeviceSettingsProvider::TrustedStatus
|
| - DeviceSettingsProvider::RequestTrustedEntity() {
|
| - if (ownership_status_ == OwnershipService::OWNERSHIP_NONE)
|
| - return TRUSTED;
|
| - return trusted_status_;
|
| -}
|
| -
|
| -void DeviceSettingsProvider::OnStorePolicyCompleted(
|
| - SignedSettings::ReturnCode code) {
|
| - // In any case reload the policy cache to now.
|
| - if (code != SignedSettings::SUCCESS)
|
| - Reload();
|
| - else
|
| - trusted_status_ = TRUSTED;
|
| -
|
| - // Clear the finished task and proceed with any other stores that could be
|
| - // pending by now.
|
| - delete pending_changes_[0].second;
|
| - pending_changes_.erase(pending_changes_.begin());
|
| - if (!pending_changes_.empty())
|
| - SetInPolicy();
|
| -}
|
| -
|
| -void DeviceSettingsProvider::OnRetrievePolicyCompleted(
|
| - SignedSettings::ReturnCode code,
|
| - const em::PolicyFetchResponse& policy_data) {
|
| - VLOG(1) << "OnRetrievePolicyCompleted. Error code: " << code
|
| - << ", trusted status : " << trusted_status_
|
| - << ", ownership status : " << ownership_status_;
|
| - switch (code) {
|
| - case SignedSettings::SUCCESS: {
|
| - DCHECK(policy_data.has_policy_data());
|
| - policy_.ParseFromString(policy_data.policy_data());
|
| - signed_settings_cache::Store(policy(),
|
| - g_browser_process->local_state());
|
| - UpdateValuesCache();
|
| - trusted_status_ = TRUSTED;
|
| - // TODO(pastarmovj): Make those side effects responsibility of the
|
| - // respective subsystems.
|
| - ApplySideEffects();
|
| - break;
|
| - }
|
| - case SignedSettings::NOT_FOUND:
|
| - if (MitigateMissingPolicy())
|
| - break;
|
| - case SignedSettings::KEY_UNAVAILABLE: {
|
| - if (ownership_status_ != OwnershipService::OWNERSHIP_TAKEN)
|
| - NOTREACHED() << "No policies present yet, will use the temp storage.";
|
| - trusted_status_ = PERMANENTLY_UNTRUSTED;
|
| - break;
|
| - }
|
| - case SignedSettings::BAD_SIGNATURE:
|
| - case SignedSettings::OPERATION_FAILED: {
|
| - LOG(ERROR) << "Failed to retrieve cros policies. Reason:" << code;
|
| - if (retries_left_ > 0) {
|
| - trusted_status_ = TEMPORARILY_UNTRUSTED;
|
| - retries_left_ -= 1;
|
| - Reload();
|
| - return;
|
| - }
|
| - LOG(ERROR) << "No retries left";
|
| - trusted_status_ = PERMANENTLY_UNTRUSTED;
|
| - break;
|
| - }
|
| - }
|
| - // Notify the observers we are done.
|
| - std::vector<base::Closure> callbacks;
|
| - callbacks.swap(callbacks_);
|
| - for (size_t i = 0; i < callbacks.size(); ++i)
|
| - callbacks[i].Run();
|
| -}
|
| -
|
| -} // namespace chromeos
|
|
|