1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/chromeos/settings/device_settings_provider.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "base/callback.h" 10 #include "base/logging.h" 11 #include "base/metrics/histogram.h" 12 #include "base/prefs/pref_service.h" 13 #include "base/threading/thread_restrictions.h" 14 #include "base/values.h" 15 #include "chrome/browser/browser_process.h" 16 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" 17 #include "chrome/browser/chromeos/policy/device_local_account.h" 18 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h" 19 #include "chrome/browser/chromeos/settings/cros_settings.h" 20 #include "chrome/browser/chromeos/settings/device_settings_cache.h" 21 #include "chrome/browser/ui/options/options_util.h" 22 #include "chrome/installer/util/google_update_settings.h" 23 #include "chromeos/chromeos_switches.h" 24 #include "chromeos/dbus/cryptohome_client.h" 25 #include "chromeos/dbus/dbus_thread_manager.h" 26 #include "chromeos/settings/cros_settings_names.h" 27 #include "policy/proto/device_management_backend.pb.h" 28 29 using google::protobuf::RepeatedField; 30 using google::protobuf::RepeatedPtrField; 31 32 namespace em = enterprise_management; 33 34 namespace chromeos { 35 36 namespace { 37 38 // List of settings handled by the DeviceSettingsProvider. 39 const char* kKnownSettings[] = { 40 kAccountsPrefAllowGuest, 41 kAccountsPrefAllowNewUser, 42 kAccountsPrefDeviceLocalAccounts, 43 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, 44 kAccountsPrefDeviceLocalAccountAutoLoginDelay, 45 kAccountsPrefDeviceLocalAccountAutoLoginId, 46 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline, 47 kAccountsPrefEphemeralUsersEnabled, 48 kAccountsPrefShowUserNamesOnSignIn, 49 kAccountsPrefSupervisedUsersEnabled, 50 kAccountsPrefUsers, 51 kAllowRedeemChromeOsRegistrationOffers, 52 kAllowedConnectionTypesForUpdate, 53 kAppPack, 54 kAttestationForContentProtectionEnabled, 55 kDeviceAttestationEnabled, 56 kDeviceOwner, 57 kIdleLogoutTimeout, 58 kIdleLogoutWarningDuration, 59 kPolicyMissingMitigationMode, 60 kReleaseChannel, 61 kReleaseChannelDelegated, 62 kReportDeviceActivityTimes, 63 kReportDeviceBootMode, 64 kReportDeviceLocation, 65 kReportDeviceNetworkInterfaces, 66 kReportDeviceUsers, 67 kReportDeviceVersionInfo, 68 kScreenSaverExtensionId, 69 kScreenSaverTimeout, 70 kServiceAccountIdentity, 71 kSignedDataRoamingEnabled, 72 kStartUpFlags, 73 kStartUpUrls, 74 kStatsReportingPref, 75 kSystemTimezonePolicy, 76 kSystemUse24HourClock, 77 kUpdateDisabled, 78 kVariationsRestrictParameter, 79 }; 80 81 bool HasOldMetricsFile() { 82 // TODO(pastarmovj): Remove this once migration is not needed anymore. 83 // If the value is not set we should try to migrate legacy consent file. 84 // Loading consent file state causes us to do blocking IO on UI thread. 85 // Temporarily allow it until we fix http://crbug.com/62626 86 base::ThreadRestrictions::ScopedAllowIO allow_io; 87 return GoogleUpdateSettings::GetCollectStatsConsent(); 88 } 89 90 } // namespace 91 92 DeviceSettingsProvider::DeviceSettingsProvider( 93 const NotifyObserversCallback& notify_cb, 94 DeviceSettingsService* device_settings_service) 95 : CrosSettingsProvider(notify_cb), 96 device_settings_service_(device_settings_service), 97 trusted_status_(TEMPORARILY_UNTRUSTED), 98 ownership_status_(device_settings_service_->GetOwnershipStatus()), 99 store_callback_factory_(this) { 100 device_settings_service_->AddObserver(this); 101 if (!UpdateFromService()) { 102 // Make sure we have at least the cache data immediately. 103 RetrieveCachedData(); 104 } 105 } 106 107 DeviceSettingsProvider::~DeviceSettingsProvider() { 108 device_settings_service_->RemoveObserver(this); 109 } 110 111 // static 112 bool DeviceSettingsProvider::IsDeviceSetting(const std::string& name) { 113 const char** end = kKnownSettings + arraysize(kKnownSettings); 114 return std::find(kKnownSettings, end, name) != end; 115 } 116 117 void DeviceSettingsProvider::DoSet(const std::string& path, 118 const base::Value& in_value) { 119 // Make sure that either the current user is the device owner or the 120 // device doesn't have an owner yet. 121 if (!(device_settings_service_->HasPrivateOwnerKey() || 122 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) { 123 LOG(WARNING) << "Changing settings from non-owner, setting=" << path; 124 125 // Revert UI change. 126 NotifyObservers(path); 127 return; 128 } 129 130 if (IsDeviceSetting(path)) { 131 pending_changes_.push_back(PendingQueueElement(path, in_value.DeepCopy())); 132 if (!store_callback_factory_.HasWeakPtrs()) 133 SetInPolicy(); 134 } else { 135 NOTREACHED() << "Try to set unhandled cros setting " << path; 136 } 137 } 138 139 void DeviceSettingsProvider::OwnershipStatusChanged() { 140 DeviceSettingsService::OwnershipStatus new_ownership_status = 141 device_settings_service_->GetOwnershipStatus(); 142 143 // If the device just became owned, write the settings accumulated in the 144 // cache to device settings proper. It is important that writing only happens 145 // in this case, as during normal operation, the contents of the cache should 146 // never overwrite actual device settings. 147 if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN && 148 ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE && 149 device_settings_service_->HasPrivateOwnerKey()) { 150 // There shouldn't be any pending writes, since the cache writes are all 151 // immediate. 152 DCHECK(!store_callback_factory_.HasWeakPtrs()); 153 154 trusted_status_ = TEMPORARILY_UNTRUSTED; 155 // Apply the locally-accumulated device settings on top of the initial 156 // settings from the service and write back the result. 157 if (device_settings_service_->device_settings()) { 158 em::ChromeDeviceSettingsProto new_settings( 159 *device_settings_service_->device_settings()); 160 new_settings.MergeFrom(device_settings_); 161 device_settings_.Swap(&new_settings); 162 } 163 StoreDeviceSettings(); 164 } 165 166 // The owner key might have become available, allowing migration to happen. 167 AttemptMigration(); 168 169 ownership_status_ = new_ownership_status; 170 } 171 172 void DeviceSettingsProvider::DeviceSettingsUpdated() { 173 if (!store_callback_factory_.HasWeakPtrs()) 174 UpdateAndProceedStoring(); 175 } 176 177 void DeviceSettingsProvider::RetrieveCachedData() { 178 em::PolicyData policy_data; 179 if (!device_settings_cache::Retrieve(&policy_data, 180 g_browser_process->local_state()) || 181 !device_settings_.ParseFromString(policy_data.policy_value())) { 182 VLOG(1) << "Can't retrieve temp store, possibly not created yet."; 183 } 184 185 UpdateValuesCache(policy_data, device_settings_, trusted_status_); 186 } 187 188 void DeviceSettingsProvider::SetInPolicy() { 189 if (pending_changes_.empty()) { 190 NOTREACHED(); 191 return; 192 } 193 194 if (RequestTrustedEntity() != TRUSTED) { 195 // Re-sync device settings before proceeding. 196 device_settings_service_->Load(); 197 return; 198 } 199 200 std::string prop(pending_changes_.front().first); 201 scoped_ptr<base::Value> value(pending_changes_.front().second); 202 pending_changes_.pop_front(); 203 204 trusted_status_ = TEMPORARILY_UNTRUSTED; 205 if (prop == kAccountsPrefAllowNewUser) { 206 em::AllowNewUsersProto* allow = 207 device_settings_.mutable_allow_new_users(); 208 bool allow_value; 209 if (value->GetAsBoolean(&allow_value)) 210 allow->set_allow_new_users(allow_value); 211 else 212 NOTREACHED(); 213 } else if (prop == kAccountsPrefAllowGuest) { 214 em::GuestModeEnabledProto* guest = 215 device_settings_.mutable_guest_mode_enabled(); 216 bool guest_value; 217 if (value->GetAsBoolean(&guest_value)) 218 guest->set_guest_mode_enabled(guest_value); 219 else 220 NOTREACHED(); 221 } else if (prop == kAccountsPrefSupervisedUsersEnabled) { 222 em::SupervisedUsersSettingsProto* supervised = 223 device_settings_.mutable_supervised_users_settings(); 224 bool supervised_value; 225 if (value->GetAsBoolean(&supervised_value)) 226 supervised->set_supervised_users_enabled(supervised_value); 227 else 228 NOTREACHED(); 229 } else if (prop == kAccountsPrefShowUserNamesOnSignIn) { 230 em::ShowUserNamesOnSigninProto* show = 231 device_settings_.mutable_show_user_names(); 232 bool show_value; 233 if (value->GetAsBoolean(&show_value)) 234 show->set_show_user_names(show_value); 235 else 236 NOTREACHED(); 237 } else if (prop == kAccountsPrefDeviceLocalAccounts) { 238 em::DeviceLocalAccountsProto* device_local_accounts = 239 device_settings_.mutable_device_local_accounts(); 240 device_local_accounts->clear_account(); 241 const base::ListValue* accounts_list = NULL; 242 if (value->GetAsList(&accounts_list)) { 243 for (base::ListValue::const_iterator entry(accounts_list->begin()); 244 entry != accounts_list->end(); ++entry) { 245 const base::DictionaryValue* entry_dict = NULL; 246 if ((*entry)->GetAsDictionary(&entry_dict)) { 247 em::DeviceLocalAccountInfoProto* account = 248 device_local_accounts->add_account(); 249 std::string account_id; 250 if (entry_dict->GetStringWithoutPathExpansion( 251 kAccountsPrefDeviceLocalAccountsKeyId, &account_id)) { 252 account->set_account_id(account_id); 253 } 254 int type; 255 if (entry_dict->GetIntegerWithoutPathExpansion( 256 kAccountsPrefDeviceLocalAccountsKeyType, &type)) { 257 account->set_type( 258 static_cast<em::DeviceLocalAccountInfoProto::AccountType>( 259 type)); 260 } 261 std::string kiosk_app_id; 262 if (entry_dict->GetStringWithoutPathExpansion( 263 kAccountsPrefDeviceLocalAccountsKeyKioskAppId, 264 &kiosk_app_id)) { 265 account->mutable_kiosk_app()->set_app_id(kiosk_app_id); 266 } 267 } else { 268 NOTREACHED(); 269 } 270 } 271 } else { 272 NOTREACHED(); 273 } 274 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginId) { 275 em::DeviceLocalAccountsProto* device_local_accounts = 276 device_settings_.mutable_device_local_accounts(); 277 std::string id; 278 if (value->GetAsString(&id)) 279 device_local_accounts->set_auto_login_id(id); 280 else 281 NOTREACHED(); 282 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginDelay) { 283 em::DeviceLocalAccountsProto* device_local_accounts = 284 device_settings_.mutable_device_local_accounts(); 285 int delay; 286 if (value->GetAsInteger(&delay)) 287 device_local_accounts->set_auto_login_delay(delay); 288 else 289 NOTREACHED(); 290 } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled) { 291 em::DeviceLocalAccountsProto* device_local_accounts = 292 device_settings_.mutable_device_local_accounts(); 293 bool enabled; 294 if (value->GetAsBoolean(&enabled)) 295 device_local_accounts->set_enable_auto_login_bailout(enabled); 296 else 297 NOTREACHED(); 298 } else if (prop == 299 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline) { 300 em::DeviceLocalAccountsProto* device_local_accounts = 301 device_settings_.mutable_device_local_accounts(); 302 bool should_prompt; 303 if (value->GetAsBoolean(&should_prompt)) 304 device_local_accounts->set_prompt_for_network_when_offline(should_prompt); 305 else 306 NOTREACHED(); 307 } else if (prop == kSignedDataRoamingEnabled) { 308 em::DataRoamingEnabledProto* roam = 309 device_settings_.mutable_data_roaming_enabled(); 310 bool roaming_value = false; 311 if (value->GetAsBoolean(&roaming_value)) 312 roam->set_data_roaming_enabled(roaming_value); 313 else 314 NOTREACHED(); 315 } else if (prop == kReleaseChannel) { 316 em::ReleaseChannelProto* release_channel = 317 device_settings_.mutable_release_channel(); 318 std::string channel_value; 319 if (value->GetAsString(&channel_value)) 320 release_channel->set_release_channel(channel_value); 321 else 322 NOTREACHED(); 323 } else if (prop == kStatsReportingPref) { 324 em::MetricsEnabledProto* metrics = 325 device_settings_.mutable_metrics_enabled(); 326 bool metrics_value = false; 327 if (value->GetAsBoolean(&metrics_value)) 328 metrics->set_metrics_enabled(metrics_value); 329 else 330 NOTREACHED(); 331 ApplyMetricsSetting(false, metrics_value); 332 } else if (prop == kAccountsPrefUsers) { 333 em::UserWhitelistProto* whitelist_proto = 334 device_settings_.mutable_user_whitelist(); 335 whitelist_proto->clear_user_whitelist(); 336 const base::ListValue* users; 337 if (value->GetAsList(&users)) { 338 for (base::ListValue::const_iterator i = users->begin(); 339 i != users->end(); ++i) { 340 std::string email; 341 if ((*i)->GetAsString(&email)) 342 whitelist_proto->add_user_whitelist(email); 343 } 344 } 345 } else if (prop == kAccountsPrefEphemeralUsersEnabled) { 346 em::EphemeralUsersEnabledProto* ephemeral_users_enabled = 347 device_settings_.mutable_ephemeral_users_enabled(); 348 bool ephemeral_users_enabled_value = false; 349 if (value->GetAsBoolean(&ephemeral_users_enabled_value)) { 350 ephemeral_users_enabled->set_ephemeral_users_enabled( 351 ephemeral_users_enabled_value); 352 } else { 353 NOTREACHED(); 354 } 355 } else if (prop == kAllowRedeemChromeOsRegistrationOffers) { 356 em::AllowRedeemChromeOsRegistrationOffersProto* allow_redeem_offers = 357 device_settings_.mutable_allow_redeem_offers(); 358 bool allow_redeem_offers_value; 359 if (value->GetAsBoolean(&allow_redeem_offers_value)) { 360 allow_redeem_offers->set_allow_redeem_offers( 361 allow_redeem_offers_value); 362 } else { 363 NOTREACHED(); 364 } 365 } else if (prop == kStartUpFlags) { 366 em::StartUpFlagsProto* flags_proto = 367 device_settings_.mutable_start_up_flags(); 368 flags_proto->Clear(); 369 const base::ListValue* flags; 370 if (value->GetAsList(&flags)) { 371 for (base::ListValue::const_iterator i = flags->begin(); 372 i != flags->end(); ++i) { 373 std::string flag; 374 if ((*i)->GetAsString(&flag)) 375 flags_proto->add_flags(flag); 376 } 377 } 378 } else if (prop == kSystemUse24HourClock) { 379 em::SystemUse24HourClockProto* use_24hour_clock_proto = 380 device_settings_.mutable_use_24hour_clock(); 381 use_24hour_clock_proto->Clear(); 382 bool use_24hour_clock_value; 383 if (value->GetAsBoolean(&use_24hour_clock_value)) { 384 use_24hour_clock_proto->set_use_24hour_clock(use_24hour_clock_value); 385 } else { 386 NOTREACHED(); 387 } 388 } else if (prop == kAttestationForContentProtectionEnabled) { 389 em::AttestationSettingsProto* attestation_settings = 390 device_settings_.mutable_attestation_settings(); 391 bool setting_enabled; 392 if (value->GetAsBoolean(&setting_enabled)) { 393 attestation_settings->set_content_protection_enabled(setting_enabled); 394 } else { 395 NOTREACHED(); 396 } 397 } else { 398 // The remaining settings don't support Set(), since they are not 399 // intended to be customizable by the user: 400 // kAppPack 401 // kDeviceAttestationEnabled 402 // kDeviceOwner 403 // kIdleLogoutTimeout 404 // kIdleLogoutWarningDuration 405 // kReleaseChannelDelegated 406 // kReportDeviceActivityTimes 407 // kReportDeviceBootMode 408 // kReportDeviceLocation 409 // kReportDeviceVersionInfo 410 // kReportDeviceNetworkInterfaces 411 // kReportDeviceUsers 412 // kScreenSaverExtensionId 413 // kScreenSaverTimeout 414 // kServiceAccountIdentity 415 // kStartUpUrls 416 // kSystemTimezonePolicy 417 // kVariationsRestrictParameter 418 419 LOG(FATAL) << "Device setting " << prop << " is read-only."; 420 } 421 422 em::PolicyData data; 423 data.set_username(device_settings_service_->GetUsername()); 424 CHECK(device_settings_.SerializeToString(data.mutable_policy_value())); 425 426 // Set the cache to the updated value. 427 UpdateValuesCache(data, device_settings_, trusted_status_); 428 429 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_TAKEN) { 430 StoreDeviceSettings(); 431 } else { 432 if (!device_settings_cache::Store(data, g_browser_process->local_state())) 433 LOG(ERROR) << "Couldn't store to the temp storage."; 434 435 // OnStorePolicyCompleted won't get called in this case so proceed with any 436 // pending operations immediately. 437 if (!pending_changes_.empty()) 438 SetInPolicy(); 439 } 440 } 441 442 void DeviceSettingsProvider::DecodeLoginPolicies( 443 const em::ChromeDeviceSettingsProto& policy, 444 PrefValueMap* new_values_cache) const { 445 // For all our boolean settings the following is applicable: 446 // true is default permissive value and false is safe prohibitive value. 447 // Exceptions: 448 // kAccountsPrefEphemeralUsersEnabled has a default value of false. 449 // kAccountsPrefSupervisedUsersEnabled has a default value of false 450 // for enterprise devices and true for consumer devices. 451 if (policy.has_allow_new_users() && 452 policy.allow_new_users().has_allow_new_users()) { 453 if (policy.allow_new_users().allow_new_users()) { 454 // New users allowed, user whitelist ignored. 455 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true); 456 } else { 457 // New users not allowed, enforce user whitelist if present. 458 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, 459 !policy.has_user_whitelist()); 460 } 461 } else { 462 // No configured allow-new-users value, enforce whitelist if non-empty. 463 new_values_cache->SetBoolean( 464 kAccountsPrefAllowNewUser, 465 policy.user_whitelist().user_whitelist_size() == 0); 466 } 467 468 new_values_cache->SetBoolean( 469 kAccountsPrefAllowGuest, 470 !policy.has_guest_mode_enabled() || 471 !policy.guest_mode_enabled().has_guest_mode_enabled() || 472 policy.guest_mode_enabled().guest_mode_enabled()); 473 474 policy::BrowserPolicyConnectorChromeOS* connector = 475 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 476 bool supervised_users_enabled = false; 477 if (connector->IsEnterpriseManaged()) { 478 supervised_users_enabled = 479 policy.has_supervised_users_settings() && 480 policy.supervised_users_settings().has_supervised_users_enabled() && 481 policy.supervised_users_settings().supervised_users_enabled(); 482 } else { 483 supervised_users_enabled = 484 !policy.has_supervised_users_settings() || 485 !policy.supervised_users_settings().has_supervised_users_enabled() || 486 policy.supervised_users_settings().supervised_users_enabled(); 487 } 488 new_values_cache->SetBoolean( 489 kAccountsPrefSupervisedUsersEnabled, supervised_users_enabled); 490 491 new_values_cache->SetBoolean( 492 kAccountsPrefShowUserNamesOnSignIn, 493 !policy.has_show_user_names() || 494 !policy.show_user_names().has_show_user_names() || 495 policy.show_user_names().show_user_names()); 496 497 new_values_cache->SetBoolean( 498 kAccountsPrefEphemeralUsersEnabled, 499 policy.has_ephemeral_users_enabled() && 500 policy.ephemeral_users_enabled().has_ephemeral_users_enabled() && 501 policy.ephemeral_users_enabled().ephemeral_users_enabled()); 502 503 base::ListValue* list = new base::ListValue(); 504 const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist(); 505 const RepeatedPtrField<std::string>& whitelist = 506 whitelist_proto.user_whitelist(); 507 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin(); 508 it != whitelist.end(); ++it) { 509 list->Append(new base::StringValue(*it)); 510 } 511 new_values_cache->SetValue(kAccountsPrefUsers, list); 512 513 scoped_ptr<base::ListValue> account_list(new base::ListValue()); 514 const em::DeviceLocalAccountsProto device_local_accounts_proto = 515 policy.device_local_accounts(); 516 const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts = 517 device_local_accounts_proto.account(); 518 RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry; 519 for (entry = accounts.begin(); entry != accounts.end(); ++entry) { 520 scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue()); 521 if (entry->has_type()) { 522 if (entry->has_account_id()) { 523 entry_dict->SetStringWithoutPathExpansion( 524 kAccountsPrefDeviceLocalAccountsKeyId, entry->account_id()); 525 } 526 entry_dict->SetIntegerWithoutPathExpansion( 527 kAccountsPrefDeviceLocalAccountsKeyType, entry->type()); 528 if (entry->kiosk_app().has_app_id()) { 529 entry_dict->SetStringWithoutPathExpansion( 530 kAccountsPrefDeviceLocalAccountsKeyKioskAppId, 531 entry->kiosk_app().app_id()); 532 } 533 } else if (entry->has_deprecated_public_session_id()) { 534 // Deprecated public session specification. 535 entry_dict->SetStringWithoutPathExpansion( 536 kAccountsPrefDeviceLocalAccountsKeyId, 537 entry->deprecated_public_session_id()); 538 entry_dict->SetIntegerWithoutPathExpansion( 539 kAccountsPrefDeviceLocalAccountsKeyType, 540 policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION); 541 } 542 account_list->Append(entry_dict.release()); 543 } 544 new_values_cache->SetValue(kAccountsPrefDeviceLocalAccounts, 545 account_list.release()); 546 547 if (policy.has_device_local_accounts()) { 548 if (policy.device_local_accounts().has_auto_login_id()) { 549 new_values_cache->SetString( 550 kAccountsPrefDeviceLocalAccountAutoLoginId, 551 policy.device_local_accounts().auto_login_id()); 552 } 553 if (policy.device_local_accounts().has_auto_login_delay()) { 554 new_values_cache->SetInteger( 555 kAccountsPrefDeviceLocalAccountAutoLoginDelay, 556 policy.device_local_accounts().auto_login_delay()); 557 } 558 } 559 560 new_values_cache->SetBoolean( 561 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, 562 policy.device_local_accounts().enable_auto_login_bailout()); 563 new_values_cache->SetBoolean( 564 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline, 565 policy.device_local_accounts().prompt_for_network_when_offline()); 566 567 if (policy.has_start_up_flags()) { 568 base::ListValue* list = new base::ListValue(); 569 const em::StartUpFlagsProto& flags_proto = policy.start_up_flags(); 570 const RepeatedPtrField<std::string>& flags = flags_proto.flags(); 571 for (RepeatedPtrField<std::string>::const_iterator it = flags.begin(); 572 it != flags.end(); ++it) { 573 list->Append(new base::StringValue(*it)); 574 } 575 new_values_cache->SetValue(kStartUpFlags, list); 576 } 577 } 578 579 void DeviceSettingsProvider::DecodeKioskPolicies( 580 const em::ChromeDeviceSettingsProto& policy, 581 PrefValueMap* new_values_cache) const { 582 if (policy.has_forced_logout_timeouts()) { 583 if (policy.forced_logout_timeouts().has_idle_logout_timeout()) { 584 new_values_cache->SetInteger( 585 kIdleLogoutTimeout, 586 policy.forced_logout_timeouts().idle_logout_timeout()); 587 } 588 589 if (policy.forced_logout_timeouts().has_idle_logout_warning_duration()) { 590 new_values_cache->SetInteger( 591 kIdleLogoutWarningDuration, 592 policy.forced_logout_timeouts().idle_logout_warning_duration()); 593 } 594 } 595 596 if (policy.has_login_screen_saver()) { 597 if (policy.login_screen_saver().has_screen_saver_timeout()) { 598 new_values_cache->SetInteger( 599 kScreenSaverTimeout, 600 policy.login_screen_saver().screen_saver_timeout()); 601 } 602 603 if (policy.login_screen_saver().has_screen_saver_extension_id()) { 604 new_values_cache->SetString( 605 kScreenSaverExtensionId, 606 policy.login_screen_saver().screen_saver_extension_id()); 607 } 608 } 609 610 if (policy.has_app_pack()) { 611 typedef RepeatedPtrField<em::AppPackEntryProto> proto_type; 612 base::ListValue* list = new base::ListValue; 613 const proto_type& app_pack = policy.app_pack().app_pack(); 614 for (proto_type::const_iterator it = app_pack.begin(); 615 it != app_pack.end(); ++it) { 616 base::DictionaryValue* entry = new base::DictionaryValue; 617 if (it->has_extension_id()) { 618 entry->SetStringWithoutPathExpansion(kAppPackKeyExtensionId, 619 it->extension_id()); 620 } 621 if (it->has_update_url()) { 622 entry->SetStringWithoutPathExpansion(kAppPackKeyUpdateUrl, 623 it->update_url()); 624 } 625 list->Append(entry); 626 } 627 new_values_cache->SetValue(kAppPack, list); 628 } 629 630 if (policy.has_start_up_urls()) { 631 base::ListValue* list = new base::ListValue(); 632 const em::StartUpUrlsProto& urls_proto = policy.start_up_urls(); 633 const RepeatedPtrField<std::string>& urls = urls_proto.start_up_urls(); 634 for (RepeatedPtrField<std::string>::const_iterator it = urls.begin(); 635 it != urls.end(); ++it) { 636 list->Append(new base::StringValue(*it)); 637 } 638 new_values_cache->SetValue(kStartUpUrls, list); 639 } 640 } 641 642 void DeviceSettingsProvider::DecodeNetworkPolicies( 643 const em::ChromeDeviceSettingsProto& policy, 644 PrefValueMap* new_values_cache) const { 645 // kSignedDataRoamingEnabled has a default value of false. 646 new_values_cache->SetBoolean( 647 kSignedDataRoamingEnabled, 648 policy.has_data_roaming_enabled() && 649 policy.data_roaming_enabled().has_data_roaming_enabled() && 650 policy.data_roaming_enabled().data_roaming_enabled()); 651 } 652 653 void DeviceSettingsProvider::DecodeAutoUpdatePolicies( 654 const em::ChromeDeviceSettingsProto& policy, 655 PrefValueMap* new_values_cache) const { 656 if (policy.has_auto_update_settings()) { 657 const em::AutoUpdateSettingsProto& au_settings_proto = 658 policy.auto_update_settings(); 659 if (au_settings_proto.has_update_disabled()) { 660 new_values_cache->SetBoolean(kUpdateDisabled, 661 au_settings_proto.update_disabled()); 662 } 663 const RepeatedField<int>& allowed_connection_types = 664 au_settings_proto.allowed_connection_types(); 665 base::ListValue* list = new base::ListValue(); 666 for (RepeatedField<int>::const_iterator i(allowed_connection_types.begin()); 667 i != allowed_connection_types.end(); ++i) { 668 list->Append(new base::FundamentalValue(*i)); 669 } 670 new_values_cache->SetValue(kAllowedConnectionTypesForUpdate, list); 671 } 672 } 673 674 void DeviceSettingsProvider::DecodeReportingPolicies( 675 const em::ChromeDeviceSettingsProto& policy, 676 PrefValueMap* new_values_cache) const { 677 if (policy.has_device_reporting()) { 678 const em::DeviceReportingProto& reporting_policy = 679 policy.device_reporting(); 680 if (reporting_policy.has_report_version_info()) { 681 new_values_cache->SetBoolean( 682 kReportDeviceVersionInfo, 683 reporting_policy.report_version_info()); 684 } 685 if (reporting_policy.has_report_activity_times()) { 686 new_values_cache->SetBoolean( 687 kReportDeviceActivityTimes, 688 reporting_policy.report_activity_times()); 689 } 690 if (reporting_policy.has_report_boot_mode()) { 691 new_values_cache->SetBoolean( 692 kReportDeviceBootMode, 693 reporting_policy.report_boot_mode()); 694 } 695 if (reporting_policy.has_report_network_interfaces()) { 696 new_values_cache->SetBoolean( 697 kReportDeviceNetworkInterfaces, 698 reporting_policy.report_network_interfaces()); 699 } 700 if (reporting_policy.has_report_users()) { 701 new_values_cache->SetBoolean( 702 kReportDeviceUsers, 703 reporting_policy.report_users()); 704 } 705 } 706 } 707 708 void DeviceSettingsProvider::DecodeGenericPolicies( 709 const em::ChromeDeviceSettingsProto& policy, 710 PrefValueMap* new_values_cache) const { 711 if (policy.has_metrics_enabled()) { 712 new_values_cache->SetBoolean(kStatsReportingPref, 713 policy.metrics_enabled().metrics_enabled()); 714 } else { 715 new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile()); 716 } 717 718 if (!policy.has_release_channel() || 719 !policy.release_channel().has_release_channel()) { 720 // Default to an invalid channel (will be ignored). 721 new_values_cache->SetString(kReleaseChannel, ""); 722 } else { 723 new_values_cache->SetString(kReleaseChannel, 724 policy.release_channel().release_channel()); 725 } 726 727 new_values_cache->SetBoolean( 728 kReleaseChannelDelegated, 729 policy.has_release_channel() && 730 policy.release_channel().has_release_channel_delegated() && 731 policy.release_channel().release_channel_delegated()); 732 733 if (policy.has_system_timezone()) { 734 if (policy.system_timezone().has_timezone()) { 735 new_values_cache->SetString( 736 kSystemTimezonePolicy, 737 policy.system_timezone().timezone()); 738 } 739 } 740 741 if (policy.has_use_24hour_clock()) { 742 if (policy.use_24hour_clock().has_use_24hour_clock()) { 743 new_values_cache->SetBoolean( 744 kSystemUse24HourClock, policy.use_24hour_clock().use_24hour_clock()); 745 } 746 } 747 748 if (policy.has_allow_redeem_offers()) { 749 new_values_cache->SetBoolean( 750 kAllowRedeemChromeOsRegistrationOffers, 751 policy.allow_redeem_offers().allow_redeem_offers()); 752 } else { 753 new_values_cache->SetBoolean( 754 kAllowRedeemChromeOsRegistrationOffers, 755 true); 756 } 757 758 if (policy.has_variations_parameter()) { 759 new_values_cache->SetString( 760 kVariationsRestrictParameter, 761 policy.variations_parameter().parameter()); 762 } 763 764 new_values_cache->SetBoolean( 765 kDeviceAttestationEnabled, 766 policy.attestation_settings().attestation_enabled()); 767 768 if (policy.has_attestation_settings() && 769 policy.attestation_settings().has_content_protection_enabled()) { 770 new_values_cache->SetBoolean( 771 kAttestationForContentProtectionEnabled, 772 policy.attestation_settings().content_protection_enabled()); 773 } else { 774 new_values_cache->SetBoolean(kAttestationForContentProtectionEnabled, true); 775 } 776 } 777 778 void DeviceSettingsProvider::UpdateValuesCache( 779 const em::PolicyData& policy_data, 780 const em::ChromeDeviceSettingsProto& settings, 781 TrustedStatus trusted_status) { 782 PrefValueMap new_values_cache; 783 784 if (policy_data.has_username() && !policy_data.has_request_token()) 785 new_values_cache.SetString(kDeviceOwner, policy_data.username()); 786 787 if (policy_data.has_service_account_identity()) { 788 new_values_cache.SetString(kServiceAccountIdentity, 789 policy_data.service_account_identity()); 790 } 791 792 DecodeLoginPolicies(settings, &new_values_cache); 793 DecodeKioskPolicies(settings, &new_values_cache); 794 DecodeNetworkPolicies(settings, &new_values_cache); 795 DecodeAutoUpdatePolicies(settings, &new_values_cache); 796 DecodeReportingPolicies(settings, &new_values_cache); 797 DecodeGenericPolicies(settings, &new_values_cache); 798 799 // Collect all notifications but send them only after we have swapped the 800 // cache so that if somebody actually reads the cache will be already valid. 801 std::vector<std::string> notifications; 802 // Go through the new values and verify in the old ones. 803 PrefValueMap::iterator iter = new_values_cache.begin(); 804 for (; iter != new_values_cache.end(); ++iter) { 805 const base::Value* old_value; 806 if (!values_cache_.GetValue(iter->first, &old_value) || 807 !old_value->Equals(iter->second)) { 808 notifications.push_back(iter->first); 809 } 810 } 811 // Now check for values that have been removed from the policy blob. 812 for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) { 813 const base::Value* value; 814 if (!new_values_cache.GetValue(iter->first, &value)) 815 notifications.push_back(iter->first); 816 } 817 // Swap and notify. 818 values_cache_.Swap(&new_values_cache); 819 trusted_status_ = trusted_status; 820 for (size_t i = 0; i < notifications.size(); ++i) 821 NotifyObservers(notifications[i]); 822 } 823 824 void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file, 825 bool new_value) { 826 // TODO(pastarmovj): Remove this once migration is not needed anymore. 827 // If the value is not set we should try to migrate legacy consent file. 828 if (use_file) { 829 new_value = HasOldMetricsFile(); 830 // Make sure the values will get eventually written to the policy file. 831 migration_values_.SetValue(kStatsReportingPref, 832 base::Value::CreateBooleanValue(new_value)); 833 AttemptMigration(); 834 VLOG(1) << "No metrics policy set will revert to checking " 835 << "consent file which is " 836 << (new_value ? "on." : "off."); 837 UMA_HISTOGRAM_COUNTS("DeviceSettings.MetricsMigrated", 1); 838 } 839 VLOG(1) << "Metrics policy is being set to : " << new_value 840 << "(use file : " << use_file << ")"; 841 // TODO(pastarmovj): Remove this once we don't need to regenerate the 842 // consent file for the GUID anymore. 843 OptionsUtil::ResolveMetricsReportingEnabled(new_value); 844 } 845 846 void DeviceSettingsProvider::ApplySideEffects( 847 const em::ChromeDeviceSettingsProto& settings) { 848 // First migrate metrics settings as needed. 849 if (settings.has_metrics_enabled()) 850 ApplyMetricsSetting(false, settings.metrics_enabled().metrics_enabled()); 851 else 852 ApplyMetricsSetting(true, false); 853 } 854 855 bool DeviceSettingsProvider::MitigateMissingPolicy() { 856 // First check if the device has been owned already and if not exit 857 // immediately. 858 policy::BrowserPolicyConnectorChromeOS* connector = 859 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 860 if (connector->GetDeviceMode() != policy::DEVICE_MODE_CONSUMER) 861 return false; 862 863 // If we are here the policy file were corrupted or missing. This can happen 864 // because we are migrating Pre R11 device to the new secure policies or there 865 // was an attempt to circumvent policy system. In this case we should populate 866 // the policy cache with "safe-mode" defaults which should allow the owner to 867 // log in but lock the device for anyone else until the policy blob has been 868 // recreated by the session manager. 869 LOG(ERROR) << "Corruption of the policy data has been detected." 870 << "Switching to \"safe-mode\" policies until the owner logs in " 871 << "to regenerate the policy data."; 872 873 device_settings_.Clear(); 874 device_settings_.mutable_allow_new_users()->set_allow_new_users(true); 875 device_settings_.mutable_guest_mode_enabled()->set_guest_mode_enabled(true); 876 em::PolicyData empty_policy_data; 877 UpdateValuesCache(empty_policy_data, device_settings_, TRUSTED); 878 values_cache_.SetBoolean(kPolicyMissingMitigationMode, true); 879 880 return true; 881 } 882 883 const base::Value* DeviceSettingsProvider::Get(const std::string& path) const { 884 if (IsDeviceSetting(path)) { 885 const base::Value* value; 886 if (values_cache_.GetValue(path, &value)) 887 return value; 888 } else { 889 NOTREACHED() << "Trying to get non cros setting."; 890 } 891 892 return NULL; 893 } 894 895 DeviceSettingsProvider::TrustedStatus 896 DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) { 897 TrustedStatus status = RequestTrustedEntity(); 898 if (status == TEMPORARILY_UNTRUSTED && !cb.is_null()) 899 callbacks_.push_back(cb); 900 return status; 901 } 902 903 bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const { 904 return IsDeviceSetting(path); 905 } 906 907 DeviceSettingsProvider::TrustedStatus 908 DeviceSettingsProvider::RequestTrustedEntity() { 909 if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE) 910 return TRUSTED; 911 return trusted_status_; 912 } 913 914 void DeviceSettingsProvider::UpdateAndProceedStoring() { 915 // Re-sync the cache from the service. 916 UpdateFromService(); 917 918 // Trigger the next change if necessary. 919 if (trusted_status_ == TRUSTED && !pending_changes_.empty()) 920 SetInPolicy(); 921 } 922 923 bool DeviceSettingsProvider::UpdateFromService() { 924 bool settings_loaded = false; 925 switch (device_settings_service_->status()) { 926 case DeviceSettingsService::STORE_SUCCESS: { 927 const em::PolicyData* policy_data = 928 device_settings_service_->policy_data(); 929 const em::ChromeDeviceSettingsProto* device_settings = 930 device_settings_service_->device_settings(); 931 if (policy_data && device_settings) { 932 if (!device_settings_cache::Store(*policy_data, 933 g_browser_process->local_state())) { 934 LOG(ERROR) << "Couldn't update the local state cache."; 935 } 936 UpdateValuesCache(*policy_data, *device_settings, TRUSTED); 937 device_settings_ = *device_settings; 938 939 // TODO(pastarmovj): Make those side effects responsibility of the 940 // respective subsystems. 941 ApplySideEffects(*device_settings); 942 943 settings_loaded = true; 944 } else { 945 // Initial policy load is still pending. 946 trusted_status_ = TEMPORARILY_UNTRUSTED; 947 } 948 break; 949 } 950 case DeviceSettingsService::STORE_NO_POLICY: 951 if (MitigateMissingPolicy()) 952 break; 953 // fall through. 954 case DeviceSettingsService::STORE_KEY_UNAVAILABLE: 955 VLOG(1) << "No policies present yet, will use the temp storage."; 956 trusted_status_ = PERMANENTLY_UNTRUSTED; 957 break; 958 case DeviceSettingsService::STORE_POLICY_ERROR: 959 case DeviceSettingsService::STORE_VALIDATION_ERROR: 960 case DeviceSettingsService::STORE_INVALID_POLICY: 961 case DeviceSettingsService::STORE_OPERATION_FAILED: 962 LOG(ERROR) << "Failed to retrieve cros policies. Reason: " 963 << device_settings_service_->status(); 964 trusted_status_ = PERMANENTLY_UNTRUSTED; 965 break; 966 case DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR: 967 // The policy has failed to validate due to temporary error but it might 968 // take a long time until we recover so behave as it is a permanent error. 969 LOG(ERROR) << "Failed to retrieve cros policies because a temporary " 970 << "validation error has occurred. Retrying might succeed."; 971 trusted_status_ = PERMANENTLY_UNTRUSTED; 972 break; 973 } 974 975 // Notify the observers we are done. 976 std::vector<base::Closure> callbacks; 977 callbacks.swap(callbacks_); 978 for (size_t i = 0; i < callbacks.size(); ++i) 979 callbacks[i].Run(); 980 981 return settings_loaded; 982 } 983 984 void DeviceSettingsProvider::StoreDeviceSettings() { 985 // Mute all previous callbacks to guarantee the |pending_changes_| queue is 986 // processed serially. 987 store_callback_factory_.InvalidateWeakPtrs(); 988 989 device_settings_service_->SignAndStore( 990 scoped_ptr<em::ChromeDeviceSettingsProto>( 991 new em::ChromeDeviceSettingsProto(device_settings_)), 992 base::Bind(&DeviceSettingsProvider::UpdateAndProceedStoring, 993 store_callback_factory_.GetWeakPtr())); 994 } 995 996 void DeviceSettingsProvider::AttemptMigration() { 997 if (device_settings_service_->HasPrivateOwnerKey()) { 998 PrefValueMap::const_iterator i; 999 for (i = migration_values_.begin(); i != migration_values_.end(); ++i) 1000 DoSet(i->first, *i->second); 1001 migration_values_.Clear(); 1002 } 1003 } 1004 1005 } // namespace chromeos 1006