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