Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / chromeos / ownership / owner_settings_service_chromeos.cc
blob6a4ba6d3f9f3ab39118d875e19a7704240040fb4
1 // Copyright 2014 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.
5 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
7 #include <keyhi.h>
9 #include <algorithm>
10 #include <string>
12 #include "base/bind.h"
13 #include "base/bind_helpers.h"
14 #include "base/callback.h"
15 #include "base/command_line.h"
16 #include "base/prefs/pref_service.h"
17 #include "base/threading/thread_checker.h"
18 #include "chrome/browser/chrome_notification_types.h"
19 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
20 #include "chrome/browser/chromeos/profiles/profile_helper.h"
21 #include "chrome/browser/chromeos/settings/cros_settings.h"
22 #include "chrome/browser/chromeos/settings/device_settings_provider.h"
23 #include "chrome/browser/chromeos/settings/session_manager_operation.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chromeos/chromeos_switches.h"
26 #include "chromeos/dbus/dbus_thread_manager.h"
27 #include "chromeos/tpm/tpm_token_loader.h"
28 #include "components/ownership/owner_key_util.h"
29 #include "components/user_manager/user.h"
30 #include "content/public/browser/browser_thread.h"
31 #include "content/public/browser/notification_details.h"
32 #include "content/public/browser/notification_service.h"
33 #include "content/public/browser/notification_source.h"
34 #include "content/public/common/content_switches.h"
35 #include "crypto/nss_key_util.h"
36 #include "crypto/nss_util.h"
37 #include "crypto/nss_util_internal.h"
38 #include "crypto/scoped_nss_types.h"
39 #include "crypto/signature_creator.h"
41 namespace em = enterprise_management;
43 using content::BrowserThread;
44 using ownership::OwnerKeyUtil;
45 using ownership::PrivateKey;
46 using ownership::PublicKey;
48 namespace chromeos {
50 namespace {
52 bool IsOwnerInTests(const std::string& user_id) {
53 if (user_id.empty() ||
54 !base::CommandLine::ForCurrentProcess()->HasSwitch(
55 ::switches::kTestType) ||
56 !CrosSettings::IsInitialized()) {
57 return false;
59 const base::Value* value = CrosSettings::Get()->GetPref(kDeviceOwner);
60 if (!value || value->GetType() != base::Value::TYPE_STRING)
61 return false;
62 return static_cast<const base::StringValue*>(value)->GetString() == user_id;
65 void LoadPrivateKeyByPublicKey(
66 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
67 scoped_refptr<PublicKey> public_key,
68 const std::string& username_hash,
69 const base::Callback<void(const scoped_refptr<PublicKey>& public_key,
70 const scoped_refptr<PrivateKey>& private_key)>&
71 callback) {
72 crypto::EnsureNSSInit();
73 crypto::ScopedPK11Slot public_slot =
74 crypto::GetPublicSlotForChromeOSUser(username_hash);
75 crypto::ScopedPK11Slot private_slot = crypto::GetPrivateSlotForChromeOSUser(
76 username_hash, base::Callback<void(crypto::ScopedPK11Slot)>());
78 // If private slot is already available, this will check it. If not, we'll get
79 // called again later when the TPM Token is ready, and the slot will be
80 // available then. FindPrivateKeyInSlot internally checks for a null slot if
81 // needbe.
83 // TODO(davidben): The null check should be in the caller rather than
84 // internally in the OwnerKeyUtil implementation. The tests currently get a
85 // null private_slot and expect the mock OwnerKeyUtil to still be called.
86 scoped_refptr<PrivateKey> private_key(
87 new PrivateKey(owner_key_util->FindPrivateKeyInSlot(public_key->data(),
88 private_slot.get())));
89 if (!private_key->key()) {
90 private_key = new PrivateKey(owner_key_util->FindPrivateKeyInSlot(
91 public_key->data(), public_slot.get()));
93 BrowserThread::PostTask(BrowserThread::UI,
94 FROM_HERE,
95 base::Bind(callback, public_key, private_key));
98 void LoadPrivateKey(
99 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
100 const std::string username_hash,
101 const base::Callback<void(const scoped_refptr<PublicKey>& public_key,
102 const scoped_refptr<PrivateKey>& private_key)>&
103 callback) {
104 std::vector<uint8> public_key_data;
105 scoped_refptr<PublicKey> public_key;
106 if (!owner_key_util->ImportPublicKey(&public_key_data)) {
107 scoped_refptr<PrivateKey> private_key;
108 BrowserThread::PostTask(BrowserThread::UI,
109 FROM_HERE,
110 base::Bind(callback, public_key, private_key));
111 return;
113 public_key = new PublicKey();
114 public_key->data().swap(public_key_data);
115 bool rv = BrowserThread::PostTask(BrowserThread::IO,
116 FROM_HERE,
117 base::Bind(&LoadPrivateKeyByPublicKey,
118 owner_key_util,
119 public_key,
120 username_hash,
121 callback));
122 if (!rv) {
123 // IO thread doesn't exists in unit tests, but it's safe to use NSS from
124 // BlockingPool in unit tests.
125 LoadPrivateKeyByPublicKey(
126 owner_key_util, public_key, username_hash, callback);
130 bool DoesPrivateKeyExistAsyncHelper(
131 const scoped_refptr<OwnerKeyUtil>& owner_key_util) {
132 std::vector<uint8> public_key;
133 if (!owner_key_util->ImportPublicKey(&public_key))
134 return false;
135 crypto::ScopedSECKEYPrivateKey key =
136 crypto::FindNSSKeyFromPublicKeyInfo(public_key);
137 return key && SECKEY_GetPrivateKeyType(key.get()) == rsaKey;
140 // Checks whether NSS slots with private key are mounted or
141 // not. Responds via |callback|.
142 void DoesPrivateKeyExistAsync(
143 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
144 const OwnerSettingsServiceChromeOS::IsOwnerCallback& callback) {
145 if (!owner_key_util.get()) {
146 callback.Run(false);
147 return;
149 scoped_refptr<base::TaskRunner> task_runner =
150 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
151 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
152 base::PostTaskAndReplyWithResult(
153 task_runner.get(),
154 FROM_HERE,
155 base::Bind(&DoesPrivateKeyExistAsyncHelper, owner_key_util),
156 callback);
159 // Returns true if it is okay to transfer from the current mode to the new
160 // mode. This function should be called in SetManagementMode().
161 bool CheckManagementModeTransition(policy::ManagementMode current_mode,
162 policy::ManagementMode new_mode) {
163 // Mode is not changed.
164 if (current_mode == new_mode)
165 return true;
167 switch (current_mode) {
168 case policy::MANAGEMENT_MODE_LOCAL_OWNER:
169 // For consumer management enrollment.
170 return new_mode == policy::MANAGEMENT_MODE_CONSUMER_MANAGED;
172 case policy::MANAGEMENT_MODE_ENTERPRISE_MANAGED:
173 // Management mode cannot be set when it is currently ENTERPRISE_MANAGED.
174 return false;
176 case policy::MANAGEMENT_MODE_CONSUMER_MANAGED:
177 // For consumer management unenrollment.
178 return new_mode == policy::MANAGEMENT_MODE_LOCAL_OWNER;
181 NOTREACHED();
182 return false;
185 } // namespace
187 OwnerSettingsServiceChromeOS::ManagementSettings::ManagementSettings() {
190 OwnerSettingsServiceChromeOS::ManagementSettings::~ManagementSettings() {
193 OwnerSettingsServiceChromeOS::OwnerSettingsServiceChromeOS(
194 DeviceSettingsService* device_settings_service,
195 Profile* profile,
196 const scoped_refptr<OwnerKeyUtil>& owner_key_util)
197 : ownership::OwnerSettingsService(owner_key_util),
198 device_settings_service_(device_settings_service),
199 profile_(profile),
200 waiting_for_profile_creation_(true),
201 waiting_for_tpm_token_(true),
202 has_pending_fixups_(false),
203 has_pending_management_settings_(false),
204 weak_factory_(this),
205 store_settings_factory_(this) {
206 if (TPMTokenLoader::IsInitialized()) {
207 TPMTokenLoader::TPMTokenStatus tpm_token_status =
208 TPMTokenLoader::Get()->IsTPMTokenEnabled(
209 base::Bind(&OwnerSettingsServiceChromeOS::OnTPMTokenReady,
210 weak_factory_.GetWeakPtr()));
211 waiting_for_tpm_token_ =
212 tpm_token_status == TPMTokenLoader::TPM_TOKEN_STATUS_UNDETERMINED;
215 if (DBusThreadManager::IsInitialized() &&
216 DBusThreadManager::Get()->GetSessionManagerClient()) {
217 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
220 if (device_settings_service_)
221 device_settings_service_->AddObserver(this);
223 registrar_.Add(this,
224 chrome::NOTIFICATION_PROFILE_CREATED,
225 content::Source<Profile>(profile_));
228 OwnerSettingsServiceChromeOS::~OwnerSettingsServiceChromeOS() {
229 DCHECK(thread_checker_.CalledOnValidThread());
231 if (device_settings_service_)
232 device_settings_service_->RemoveObserver(this);
234 if (DBusThreadManager::IsInitialized() &&
235 DBusThreadManager::Get()->GetSessionManagerClient()) {
236 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
240 OwnerSettingsServiceChromeOS* OwnerSettingsServiceChromeOS::FromWebUI(
241 content::WebUI* web_ui) {
242 if (!web_ui)
243 return nullptr;
244 Profile* profile = Profile::FromWebUI(web_ui);
245 if (!profile)
246 return nullptr;
247 return OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(profile);
250 void OwnerSettingsServiceChromeOS::OnTPMTokenReady(
251 bool /* tpm_token_enabled */) {
252 DCHECK(thread_checker_.CalledOnValidThread());
253 waiting_for_tpm_token_ = false;
255 // TPMTokenLoader initializes the TPM and NSS database which is necessary to
256 // determine ownership. Force a reload once we know these are initialized.
257 ReloadKeypair();
260 bool OwnerSettingsServiceChromeOS::HasPendingChanges() const {
261 return !pending_changes_.empty() || tentative_settings_.get() ||
262 has_pending_management_settings_ || has_pending_fixups_;
265 bool OwnerSettingsServiceChromeOS::HandlesSetting(const std::string& setting) {
266 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
267 switches::kStubCrosSettings)) {
268 return false;
270 return DeviceSettingsProvider::IsDeviceSetting(setting);
273 bool OwnerSettingsServiceChromeOS::Set(const std::string& setting,
274 const base::Value& value) {
275 DCHECK(thread_checker_.CalledOnValidThread());
276 if (!IsOwner() && !IsOwnerInTests(user_id_))
277 return false;
279 pending_changes_.add(setting, make_scoped_ptr(value.DeepCopy()));
281 em::ChromeDeviceSettingsProto settings;
282 if (tentative_settings_.get()) {
283 settings = *tentative_settings_;
284 } else if (device_settings_service_->status() ==
285 DeviceSettingsService::STORE_SUCCESS &&
286 device_settings_service_->device_settings()) {
287 settings = *device_settings_service_->device_settings();
289 UpdateDeviceSettings(setting, value, settings);
290 em::PolicyData policy_data;
291 policy_data.set_username(user_id_);
292 CHECK(settings.SerializeToString(policy_data.mutable_policy_value()));
293 FOR_EACH_OBSERVER(OwnerSettingsService::Observer, observers_,
294 OnTentativeChangesInPolicy(policy_data));
295 StorePendingChanges();
296 return true;
299 bool OwnerSettingsServiceChromeOS::AppendToList(const std::string& setting,
300 const base::Value& value) {
301 DCHECK(thread_checker_.CalledOnValidThread());
302 const base::Value* old_value = CrosSettings::Get()->GetPref(setting);
303 if (old_value && !old_value->IsType(base::Value::TYPE_LIST))
304 return false;
305 scoped_ptr<base::ListValue> new_value(
306 old_value ? static_cast<const base::ListValue*>(old_value)->DeepCopy()
307 : new base::ListValue());
308 new_value->Append(value.DeepCopy());
309 return Set(setting, *new_value);
312 bool OwnerSettingsServiceChromeOS::RemoveFromList(const std::string& setting,
313 const base::Value& value) {
314 DCHECK(thread_checker_.CalledOnValidThread());
315 const base::Value* old_value = CrosSettings::Get()->GetPref(setting);
316 if (old_value && !old_value->IsType(base::Value::TYPE_LIST))
317 return false;
318 scoped_ptr<base::ListValue> new_value(
319 old_value ? static_cast<const base::ListValue*>(old_value)->DeepCopy()
320 : new base::ListValue());
321 new_value->Remove(value, nullptr);
322 return Set(setting, *new_value);
325 bool OwnerSettingsServiceChromeOS::CommitTentativeDeviceSettings(
326 scoped_ptr<enterprise_management::PolicyData> policy) {
327 if (!IsOwner() && !IsOwnerInTests(user_id_))
328 return false;
329 if (policy->username() != user_id_) {
330 LOG(ERROR) << "Username mismatch: " << policy->username() << " vs. "
331 << user_id_;
332 return false;
334 tentative_settings_.reset(new em::ChromeDeviceSettingsProto);
335 CHECK(tentative_settings_->ParseFromString(policy->policy_value()));
336 StorePendingChanges();
337 return true;
340 void OwnerSettingsServiceChromeOS::Observe(
341 int type,
342 const content::NotificationSource& source,
343 const content::NotificationDetails& details) {
344 DCHECK(thread_checker_.CalledOnValidThread());
345 if (type != chrome::NOTIFICATION_PROFILE_CREATED) {
346 NOTREACHED();
347 return;
350 Profile* profile = content::Source<Profile>(source).ptr();
351 if (profile != profile_) {
352 NOTREACHED();
353 return;
356 waiting_for_profile_creation_ = false;
357 ReloadKeypair();
360 void OwnerSettingsServiceChromeOS::OwnerKeySet(bool success) {
361 DCHECK(thread_checker_.CalledOnValidThread());
362 if (success)
363 ReloadKeypair();
366 void OwnerSettingsServiceChromeOS::OwnershipStatusChanged() {
367 DCHECK(thread_checker_.CalledOnValidThread());
368 StorePendingChanges();
371 void OwnerSettingsServiceChromeOS::DeviceSettingsUpdated() {
372 DCHECK(thread_checker_.CalledOnValidThread());
373 StorePendingChanges();
376 void OwnerSettingsServiceChromeOS::OnDeviceSettingsServiceShutdown() {
377 device_settings_service_ = nullptr;
380 void OwnerSettingsServiceChromeOS::SetManagementSettings(
381 const ManagementSettings& settings,
382 const OnManagementSettingsSetCallback& callback) {
383 if ((!IsOwner() && !IsOwnerInTests(user_id_))) {
384 if (!callback.is_null())
385 callback.Run(false /* success */);
386 return;
389 policy::ManagementMode current_mode = policy::MANAGEMENT_MODE_LOCAL_OWNER;
390 if (has_pending_management_settings_) {
391 current_mode = pending_management_settings_.management_mode;
392 } else if (device_settings_service_ &&
393 device_settings_service_->policy_data()) {
394 current_mode =
395 policy::GetManagementMode(*device_settings_service_->policy_data());
398 if (!CheckManagementModeTransition(current_mode, settings.management_mode)) {
399 LOG(ERROR) << "Invalid management mode transition: current mode = "
400 << current_mode << ", new mode = " << settings.management_mode;
401 if (!callback.is_null())
402 callback.Run(false /* success */);
403 return;
406 pending_management_settings_ = settings;
407 has_pending_management_settings_ = true;
408 pending_management_settings_callbacks_.push_back(callback);
409 StorePendingChanges();
412 // static
413 void OwnerSettingsServiceChromeOS::IsOwnerForSafeModeAsync(
414 const std::string& user_hash,
415 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
416 const IsOwnerCallback& callback) {
417 CHECK(chromeos::LoginState::Get()->IsInSafeMode());
419 // Make sure NSS is initialized and NSS DB is loaded for the user before
420 // searching for the owner key.
421 BrowserThread::PostTaskAndReply(
422 BrowserThread::IO,
423 FROM_HERE,
424 base::Bind(base::IgnoreResult(&crypto::InitializeNSSForChromeOSUser),
425 user_hash,
426 ProfileHelper::GetProfilePathByUserIdHash(user_hash)),
427 base::Bind(&DoesPrivateKeyExistAsync, owner_key_util, callback));
430 // static
431 scoped_ptr<em::PolicyData> OwnerSettingsServiceChromeOS::AssemblePolicy(
432 const std::string& user_id,
433 const em::PolicyData* policy_data,
434 bool apply_pending_management_settings,
435 const ManagementSettings& pending_management_settings,
436 em::ChromeDeviceSettingsProto* settings) {
437 scoped_ptr<em::PolicyData> policy(new em::PolicyData());
438 if (policy_data) {
439 // Preserve management settings.
440 if (policy_data->has_management_mode())
441 policy->set_management_mode(policy_data->management_mode());
442 if (policy_data->has_request_token())
443 policy->set_request_token(policy_data->request_token());
444 if (policy_data->has_device_id())
445 policy->set_device_id(policy_data->device_id());
446 } else {
447 // If there's no previous policy data, this is the first time the device
448 // setting is set. We set the management mode to LOCAL_OWNER initially.
449 policy->set_management_mode(em::PolicyData::LOCAL_OWNER);
451 if (apply_pending_management_settings) {
452 policy::SetManagementMode(*policy,
453 pending_management_settings.management_mode);
455 if (pending_management_settings.request_token.empty())
456 policy->clear_request_token();
457 else
458 policy->set_request_token(pending_management_settings.request_token);
460 if (pending_management_settings.device_id.empty())
461 policy->clear_device_id();
462 else
463 policy->set_device_id(pending_management_settings.device_id);
465 policy->set_policy_type(policy::dm_protocol::kChromeDevicePolicyType);
466 policy->set_timestamp(
467 (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds());
468 policy->set_username(user_id);
469 if (policy_data->management_mode() == em::PolicyData::LOCAL_OWNER ||
470 policy_data->management_mode() == em::PolicyData::CONSUMER_MANAGED) {
471 FixupLocalOwnerPolicy(user_id, settings);
473 if (!settings->SerializeToString(policy->mutable_policy_value()))
474 return scoped_ptr<em::PolicyData>();
476 return policy.Pass();
479 // static
480 void OwnerSettingsServiceChromeOS::FixupLocalOwnerPolicy(
481 const std::string& user_id,
482 enterprise_management::ChromeDeviceSettingsProto* settings) {
483 if (!settings->has_allow_new_users())
484 settings->mutable_allow_new_users()->set_allow_new_users(true);
486 em::UserWhitelistProto* whitelist_proto = settings->mutable_user_whitelist();
487 if (whitelist_proto->user_whitelist().end() ==
488 std::find(whitelist_proto->user_whitelist().begin(),
489 whitelist_proto->user_whitelist().end(), user_id)) {
490 whitelist_proto->add_user_whitelist(user_id);
494 // static
495 void OwnerSettingsServiceChromeOS::UpdateDeviceSettings(
496 const std::string& path,
497 const base::Value& value,
498 enterprise_management::ChromeDeviceSettingsProto& settings) {
499 if (path == kAccountsPrefAllowNewUser) {
500 em::AllowNewUsersProto* allow = settings.mutable_allow_new_users();
501 bool allow_value;
502 if (value.GetAsBoolean(&allow_value)) {
503 allow->set_allow_new_users(allow_value);
504 } else {
505 NOTREACHED();
507 } else if (path == kAccountsPrefAllowGuest) {
508 em::GuestModeEnabledProto* guest = settings.mutable_guest_mode_enabled();
509 bool guest_value;
510 if (value.GetAsBoolean(&guest_value))
511 guest->set_guest_mode_enabled(guest_value);
512 else
513 NOTREACHED();
514 } else if (path == kAccountsPrefSupervisedUsersEnabled) {
515 em::SupervisedUsersSettingsProto* supervised =
516 settings.mutable_supervised_users_settings();
517 bool supervised_value;
518 if (value.GetAsBoolean(&supervised_value))
519 supervised->set_supervised_users_enabled(supervised_value);
520 else
521 NOTREACHED();
522 } else if (path == kAccountsPrefShowUserNamesOnSignIn) {
523 em::ShowUserNamesOnSigninProto* show = settings.mutable_show_user_names();
524 bool show_value;
525 if (value.GetAsBoolean(&show_value))
526 show->set_show_user_names(show_value);
527 else
528 NOTREACHED();
529 } else if (path == kAccountsPrefDeviceLocalAccounts) {
530 em::DeviceLocalAccountsProto* device_local_accounts =
531 settings.mutable_device_local_accounts();
532 device_local_accounts->clear_account();
533 const base::ListValue* accounts_list = NULL;
534 if (value.GetAsList(&accounts_list)) {
535 for (base::ListValue::const_iterator entry(accounts_list->begin());
536 entry != accounts_list->end();
537 ++entry) {
538 const base::DictionaryValue* entry_dict = NULL;
539 if ((*entry)->GetAsDictionary(&entry_dict)) {
540 em::DeviceLocalAccountInfoProto* account =
541 device_local_accounts->add_account();
542 std::string account_id;
543 if (entry_dict->GetStringWithoutPathExpansion(
544 kAccountsPrefDeviceLocalAccountsKeyId, &account_id)) {
545 account->set_account_id(account_id);
547 int type;
548 if (entry_dict->GetIntegerWithoutPathExpansion(
549 kAccountsPrefDeviceLocalAccountsKeyType, &type)) {
550 account->set_type(
551 static_cast<em::DeviceLocalAccountInfoProto::AccountType>(
552 type));
554 std::string kiosk_app_id;
555 if (entry_dict->GetStringWithoutPathExpansion(
556 kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
557 &kiosk_app_id)) {
558 account->mutable_kiosk_app()->set_app_id(kiosk_app_id);
560 std::string kiosk_app_update_url;
561 if (entry_dict->GetStringWithoutPathExpansion(
562 kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL,
563 &kiosk_app_update_url)) {
564 account->mutable_kiosk_app()->set_update_url(kiosk_app_update_url);
566 } else {
567 NOTREACHED();
570 } else {
571 NOTREACHED();
573 } else if (path == kAccountsPrefDeviceLocalAccountAutoLoginId) {
574 em::DeviceLocalAccountsProto* device_local_accounts =
575 settings.mutable_device_local_accounts();
576 std::string id;
577 if (value.GetAsString(&id))
578 device_local_accounts->set_auto_login_id(id);
579 else
580 NOTREACHED();
581 } else if (path == kAccountsPrefDeviceLocalAccountAutoLoginDelay) {
582 em::DeviceLocalAccountsProto* device_local_accounts =
583 settings.mutable_device_local_accounts();
584 int delay;
585 if (value.GetAsInteger(&delay))
586 device_local_accounts->set_auto_login_delay(delay);
587 else
588 NOTREACHED();
589 } else if (path == kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled) {
590 em::DeviceLocalAccountsProto* device_local_accounts =
591 settings.mutable_device_local_accounts();
592 bool enabled;
593 if (value.GetAsBoolean(&enabled))
594 device_local_accounts->set_enable_auto_login_bailout(enabled);
595 else
596 NOTREACHED();
597 } else if (path ==
598 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline) {
599 em::DeviceLocalAccountsProto* device_local_accounts =
600 settings.mutable_device_local_accounts();
601 bool should_prompt;
602 if (value.GetAsBoolean(&should_prompt))
603 device_local_accounts->set_prompt_for_network_when_offline(should_prompt);
604 else
605 NOTREACHED();
606 } else if (path == kSignedDataRoamingEnabled) {
607 em::DataRoamingEnabledProto* roam = settings.mutable_data_roaming_enabled();
608 bool roaming_value = false;
609 if (value.GetAsBoolean(&roaming_value))
610 roam->set_data_roaming_enabled(roaming_value);
611 else
612 NOTREACHED();
613 } else if (path == kReleaseChannel) {
614 em::ReleaseChannelProto* release_channel =
615 settings.mutable_release_channel();
616 std::string channel_value;
617 if (value.GetAsString(&channel_value))
618 release_channel->set_release_channel(channel_value);
619 else
620 NOTREACHED();
621 } else if (path == kStatsReportingPref) {
622 em::MetricsEnabledProto* metrics = settings.mutable_metrics_enabled();
623 bool metrics_value = false;
624 if (value.GetAsBoolean(&metrics_value))
625 metrics->set_metrics_enabled(metrics_value);
626 else
627 NOTREACHED();
628 } else if (path == kAccountsPrefUsers) {
629 em::UserWhitelistProto* whitelist_proto = settings.mutable_user_whitelist();
630 whitelist_proto->clear_user_whitelist();
631 const base::ListValue* users;
632 if (value.GetAsList(&users)) {
633 for (base::ListValue::const_iterator i = users->begin();
634 i != users->end();
635 ++i) {
636 std::string email;
637 if ((*i)->GetAsString(&email))
638 whitelist_proto->add_user_whitelist(email);
641 } else if (path == kAccountsPrefEphemeralUsersEnabled) {
642 em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
643 settings.mutable_ephemeral_users_enabled();
644 bool ephemeral_users_enabled_value = false;
645 if (value.GetAsBoolean(&ephemeral_users_enabled_value)) {
646 ephemeral_users_enabled->set_ephemeral_users_enabled(
647 ephemeral_users_enabled_value);
648 } else {
649 NOTREACHED();
651 } else if (path == kAllowRedeemChromeOsRegistrationOffers) {
652 em::AllowRedeemChromeOsRegistrationOffersProto* allow_redeem_offers =
653 settings.mutable_allow_redeem_offers();
654 bool allow_redeem_offers_value;
655 if (value.GetAsBoolean(&allow_redeem_offers_value)) {
656 allow_redeem_offers->set_allow_redeem_offers(allow_redeem_offers_value);
657 } else {
658 NOTREACHED();
660 } else if (path == kStartUpFlags) {
661 em::StartUpFlagsProto* flags_proto = settings.mutable_start_up_flags();
662 flags_proto->Clear();
663 const base::ListValue* flags;
664 if (value.GetAsList(&flags)) {
665 for (base::ListValue::const_iterator i = flags->begin();
666 i != flags->end();
667 ++i) {
668 std::string flag;
669 if ((*i)->GetAsString(&flag))
670 flags_proto->add_flags(flag);
673 } else if (path == kSystemUse24HourClock) {
674 em::SystemUse24HourClockProto* use_24hour_clock_proto =
675 settings.mutable_use_24hour_clock();
676 use_24hour_clock_proto->Clear();
677 bool use_24hour_clock_value;
678 if (value.GetAsBoolean(&use_24hour_clock_value)) {
679 use_24hour_clock_proto->set_use_24hour_clock(use_24hour_clock_value);
680 } else {
681 NOTREACHED();
683 } else if (path == kAttestationForContentProtectionEnabled) {
684 em::AttestationSettingsProto* attestation_settings =
685 settings.mutable_attestation_settings();
686 bool setting_enabled;
687 if (value.GetAsBoolean(&setting_enabled)) {
688 attestation_settings->set_content_protection_enabled(setting_enabled);
689 } else {
690 NOTREACHED();
692 } else {
693 // The remaining settings don't support Set(), since they are not
694 // intended to be customizable by the user:
695 // kAccountsPrefTransferSAMLCookies
696 // kDeviceAttestationEnabled
697 // kDeviceOwner
698 // kHeartbeatEnabled
699 // kHeartbeatFrequency
700 // kReleaseChannelDelegated
701 // kReportDeviceActivityTimes
702 // kReportDeviceBootMode
703 // kReportDeviceHardwareStatus
704 // kReportDeviceLocation
705 // kReportDeviceNetworkInterfaces
706 // kReportDeviceSessionStatus
707 // kReportDeviceVersionInfo
708 // kReportDeviceUsers
709 // kServiceAccountIdentity
710 // kSystemTimezonePolicy
711 // kVariationsRestrictParameter
712 // kDeviceDisabled
713 // kDeviceDisabledMessage
715 LOG(FATAL) << "Device setting " << path << " is read-only.";
719 void OwnerSettingsServiceChromeOS::OnPostKeypairLoadedActions() {
720 DCHECK(thread_checker_.CalledOnValidThread());
722 const user_manager::User* user =
723 ProfileHelper::Get()->GetUserByProfile(profile_);
724 user_id_ = user ? user->GetUserID() : std::string();
726 const bool is_owner = IsOwner() || IsOwnerInTests(user_id_);
727 if (is_owner && device_settings_service_)
728 device_settings_service_->InitOwner(user_id_, weak_factory_.GetWeakPtr());
730 has_pending_fixups_ = true;
733 void OwnerSettingsServiceChromeOS::ReloadKeypairImpl(const base::Callback<
734 void(const scoped_refptr<PublicKey>& public_key,
735 const scoped_refptr<PrivateKey>& private_key)>& callback) {
736 DCHECK(thread_checker_.CalledOnValidThread());
738 if (waiting_for_profile_creation_ || waiting_for_tpm_token_)
739 return;
740 scoped_refptr<base::TaskRunner> task_runner =
741 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
742 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
743 task_runner->PostTask(
744 FROM_HERE,
745 base::Bind(&LoadPrivateKey,
746 owner_key_util_,
747 ProfileHelper::GetUserIdHashFromProfile(profile_),
748 callback));
751 void OwnerSettingsServiceChromeOS::StorePendingChanges() {
752 if (!HasPendingChanges() || store_settings_factory_.HasWeakPtrs() ||
753 !device_settings_service_ || user_id_.empty()) {
754 return;
757 em::ChromeDeviceSettingsProto settings;
758 if (tentative_settings_.get()) {
759 settings.Swap(tentative_settings_.get());
760 tentative_settings_.reset();
761 } else if (device_settings_service_->status() ==
762 DeviceSettingsService::STORE_SUCCESS &&
763 device_settings_service_->device_settings()) {
764 settings = *device_settings_service_->device_settings();
765 } else {
766 return;
769 for (const auto& change : pending_changes_)
770 UpdateDeviceSettings(change.first, *change.second, settings);
771 pending_changes_.clear();
773 scoped_ptr<em::PolicyData> policy =
774 AssemblePolicy(user_id_, device_settings_service_->policy_data(),
775 has_pending_management_settings_,
776 pending_management_settings_, &settings);
777 has_pending_fixups_ = false;
778 has_pending_management_settings_ = false;
780 bool rv = AssembleAndSignPolicyAsync(
781 content::BrowserThread::GetBlockingPool(), policy.Pass(),
782 base::Bind(&OwnerSettingsServiceChromeOS::OnPolicyAssembledAndSigned,
783 store_settings_factory_.GetWeakPtr()));
784 if (!rv)
785 ReportStatusAndContinueStoring(false /* success */);
788 void OwnerSettingsServiceChromeOS::OnPolicyAssembledAndSigned(
789 scoped_ptr<em::PolicyFetchResponse> policy_response) {
790 if (!policy_response.get() || !device_settings_service_) {
791 ReportStatusAndContinueStoring(false /* success */);
792 return;
794 device_settings_service_->Store(
795 policy_response.Pass(),
796 base::Bind(&OwnerSettingsServiceChromeOS::OnSignedPolicyStored,
797 store_settings_factory_.GetWeakPtr(),
798 true /* success */));
801 void OwnerSettingsServiceChromeOS::OnSignedPolicyStored(bool success) {
802 CHECK(device_settings_service_);
803 ReportStatusAndContinueStoring(success &&
804 device_settings_service_->status() ==
805 DeviceSettingsService::STORE_SUCCESS);
808 void OwnerSettingsServiceChromeOS::ReportStatusAndContinueStoring(
809 bool success) {
810 store_settings_factory_.InvalidateWeakPtrs();
811 FOR_EACH_OBSERVER(OwnerSettingsService::Observer, observers_,
812 OnSignedPolicyStored(success));
814 std::vector<OnManagementSettingsSetCallback> callbacks;
815 pending_management_settings_callbacks_.swap(callbacks);
816 for (const auto& callback : callbacks) {
817 if (!callback.is_null())
818 callback.Run(success);
820 StorePendingChanges();
823 } // namespace chromeos