Re-land: C++ readability review
[chromium-blink-merge.git] / chrome / browser / chromeos / ownership / owner_settings_service_chromeos.cc
blobbac0fbac2387e19ca2c5be51ac4dd680de03897a
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 <algorithm>
8 #include <string>
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/callback.h"
13 #include "base/command_line.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/threading/thread_checker.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
18 #include "chrome/browser/chromeos/profiles/profile_helper.h"
19 #include "chrome/browser/chromeos/settings/cros_settings.h"
20 #include "chrome/browser/chromeos/settings/device_settings_provider.h"
21 #include "chrome/browser/chromeos/settings/session_manager_operation.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chromeos/dbus/dbus_thread_manager.h"
24 #include "chromeos/tpm/tpm_token_loader.h"
25 #include "components/ownership/owner_key_util.h"
26 #include "components/user_manager/user.h"
27 #include "content/public/browser/browser_thread.h"
28 #include "content/public/browser/notification_details.h"
29 #include "content/public/browser/notification_service.h"
30 #include "content/public/browser/notification_source.h"
31 #include "content/public/common/content_switches.h"
32 #include "crypto/nss_util.h"
33 #include "crypto/nss_util_internal.h"
34 #include "crypto/rsa_private_key.h"
35 #include "crypto/scoped_nss_types.h"
36 #include "crypto/signature_creator.h"
38 namespace em = enterprise_management;
40 using content::BrowserThread;
41 using ownership::OwnerKeyUtil;
42 using ownership::PrivateKey;
43 using ownership::PublicKey;
45 namespace chromeos {
47 namespace {
49 bool IsOwnerInTests(const std::string& user_id) {
50 if (user_id.empty() ||
51 !base::CommandLine::ForCurrentProcess()->HasSwitch(
52 ::switches::kTestType) ||
53 !CrosSettings::IsInitialized()) {
54 return false;
56 const base::Value* value = CrosSettings::Get()->GetPref(kDeviceOwner);
57 if (!value || value->GetType() != base::Value::TYPE_STRING)
58 return false;
59 return static_cast<const base::StringValue*>(value)->GetString() == user_id;
62 void LoadPrivateKeyByPublicKey(
63 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
64 scoped_refptr<PublicKey> public_key,
65 const std::string& username_hash,
66 const base::Callback<void(const scoped_refptr<PublicKey>& public_key,
67 const scoped_refptr<PrivateKey>& private_key)>&
68 callback) {
69 crypto::EnsureNSSInit();
70 crypto::ScopedPK11Slot public_slot =
71 crypto::GetPublicSlotForChromeOSUser(username_hash);
72 crypto::ScopedPK11Slot private_slot = crypto::GetPrivateSlotForChromeOSUser(
73 username_hash, base::Callback<void(crypto::ScopedPK11Slot)>());
75 // If private slot is already available, this will check it. If not,
76 // we'll get called again later when the TPM Token is ready, and the
77 // slot will be available then.
78 scoped_refptr<PrivateKey> private_key(
79 new PrivateKey(owner_key_util->FindPrivateKeyInSlot(public_key->data(),
80 private_slot.get())));
81 if (!private_key->key()) {
82 private_key = new PrivateKey(owner_key_util->FindPrivateKeyInSlot(
83 public_key->data(), public_slot.get()));
85 BrowserThread::PostTask(BrowserThread::UI,
86 FROM_HERE,
87 base::Bind(callback, public_key, private_key));
90 void LoadPrivateKey(
91 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
92 const std::string username_hash,
93 const base::Callback<void(const scoped_refptr<PublicKey>& public_key,
94 const scoped_refptr<PrivateKey>& private_key)>&
95 callback) {
96 std::vector<uint8> public_key_data;
97 scoped_refptr<PublicKey> public_key;
98 if (!owner_key_util->ImportPublicKey(&public_key_data)) {
99 scoped_refptr<PrivateKey> private_key;
100 BrowserThread::PostTask(BrowserThread::UI,
101 FROM_HERE,
102 base::Bind(callback, public_key, private_key));
103 return;
105 public_key = new PublicKey();
106 public_key->data().swap(public_key_data);
107 bool rv = BrowserThread::PostTask(BrowserThread::IO,
108 FROM_HERE,
109 base::Bind(&LoadPrivateKeyByPublicKey,
110 owner_key_util,
111 public_key,
112 username_hash,
113 callback));
114 if (!rv) {
115 // IO thread doesn't exists in unit tests, but it's safe to use NSS from
116 // BlockingPool in unit tests.
117 LoadPrivateKeyByPublicKey(
118 owner_key_util, public_key, username_hash, callback);
122 bool DoesPrivateKeyExistAsyncHelper(
123 const scoped_refptr<OwnerKeyUtil>& owner_key_util) {
124 std::vector<uint8> public_key;
125 if (!owner_key_util->ImportPublicKey(&public_key))
126 return false;
127 scoped_ptr<crypto::RSAPrivateKey> key(
128 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key));
129 bool is_owner = key.get() != NULL;
130 return is_owner;
133 // Checks whether NSS slots with private key are mounted or
134 // not. Responds via |callback|.
135 void DoesPrivateKeyExistAsync(
136 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
137 const OwnerSettingsServiceChromeOS::IsOwnerCallback& callback) {
138 if (!owner_key_util.get()) {
139 callback.Run(false);
140 return;
142 scoped_refptr<base::TaskRunner> task_runner =
143 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
144 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
145 base::PostTaskAndReplyWithResult(
146 task_runner.get(),
147 FROM_HERE,
148 base::Bind(&DoesPrivateKeyExistAsyncHelper, owner_key_util),
149 callback);
152 // Returns true if it is okay to transfer from the current mode to the new
153 // mode. This function should be called in SetManagementMode().
154 bool CheckManagementModeTransition(policy::ManagementMode current_mode,
155 policy::ManagementMode new_mode) {
156 // Mode is not changed.
157 if (current_mode == new_mode)
158 return true;
160 switch (current_mode) {
161 case policy::MANAGEMENT_MODE_LOCAL_OWNER:
162 // For consumer management enrollment.
163 return new_mode == policy::MANAGEMENT_MODE_CONSUMER_MANAGED;
165 case policy::MANAGEMENT_MODE_ENTERPRISE_MANAGED:
166 // Management mode cannot be set when it is currently ENTERPRISE_MANAGED.
167 return false;
169 case policy::MANAGEMENT_MODE_CONSUMER_MANAGED:
170 // For consumer management unenrollment.
171 return new_mode == policy::MANAGEMENT_MODE_LOCAL_OWNER;
174 NOTREACHED();
175 return false;
177 } // namespace
179 OwnerSettingsServiceChromeOS::ManagementSettings::ManagementSettings() {
182 OwnerSettingsServiceChromeOS::ManagementSettings::~ManagementSettings() {
185 OwnerSettingsServiceChromeOS::OwnerSettingsServiceChromeOS(
186 DeviceSettingsService* device_settings_service,
187 Profile* profile,
188 const scoped_refptr<OwnerKeyUtil>& owner_key_util)
189 : ownership::OwnerSettingsService(owner_key_util),
190 device_settings_service_(device_settings_service),
191 profile_(profile),
192 waiting_for_profile_creation_(true),
193 waiting_for_tpm_token_(true),
194 has_pending_fixups_(false),
195 has_pending_management_settings_(false),
196 weak_factory_(this),
197 store_settings_factory_(this) {
198 if (TPMTokenLoader::IsInitialized()) {
199 TPMTokenLoader::TPMTokenStatus tpm_token_status =
200 TPMTokenLoader::Get()->IsTPMTokenEnabled(
201 base::Bind(&OwnerSettingsServiceChromeOS::OnTPMTokenReady,
202 weak_factory_.GetWeakPtr()));
203 waiting_for_tpm_token_ =
204 tpm_token_status == TPMTokenLoader::TPM_TOKEN_STATUS_UNDETERMINED;
207 if (DBusThreadManager::IsInitialized() &&
208 DBusThreadManager::Get()->GetSessionManagerClient()) {
209 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
212 if (device_settings_service_)
213 device_settings_service_->AddObserver(this);
215 registrar_.Add(this,
216 chrome::NOTIFICATION_PROFILE_CREATED,
217 content::Source<Profile>(profile_));
220 OwnerSettingsServiceChromeOS::~OwnerSettingsServiceChromeOS() {
221 DCHECK(thread_checker_.CalledOnValidThread());
223 if (device_settings_service_)
224 device_settings_service_->RemoveObserver(this);
226 if (DBusThreadManager::IsInitialized() &&
227 DBusThreadManager::Get()->GetSessionManagerClient()) {
228 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
232 OwnerSettingsServiceChromeOS* OwnerSettingsServiceChromeOS::FromWebUI(
233 content::WebUI* web_ui) {
234 if (!web_ui)
235 return nullptr;
236 Profile* profile = Profile::FromWebUI(web_ui);
237 if (!profile)
238 return nullptr;
239 return OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(profile);
242 void OwnerSettingsServiceChromeOS::OnTPMTokenReady(
243 bool /* tpm_token_enabled */) {
244 DCHECK(thread_checker_.CalledOnValidThread());
245 waiting_for_tpm_token_ = false;
247 // TPMTokenLoader initializes the TPM and NSS database which is necessary to
248 // determine ownership. Force a reload once we know these are initialized.
249 ReloadKeypair();
252 bool OwnerSettingsServiceChromeOS::HasPendingChanges() const {
253 return !pending_changes_.empty() || tentative_settings_.get() ||
254 has_pending_management_settings_ || has_pending_fixups_;
257 bool OwnerSettingsServiceChromeOS::HandlesSetting(const std::string& setting) {
258 return DeviceSettingsProvider::IsDeviceSetting(setting);
261 bool OwnerSettingsServiceChromeOS::Set(const std::string& setting,
262 const base::Value& value) {
263 DCHECK(thread_checker_.CalledOnValidThread());
264 if (!IsOwner() && !IsOwnerInTests(user_id_))
265 return false;
267 pending_changes_.add(setting, make_scoped_ptr(value.DeepCopy()));
269 em::ChromeDeviceSettingsProto settings;
270 if (tentative_settings_.get()) {
271 settings = *tentative_settings_;
272 } else if (device_settings_service_->status() ==
273 DeviceSettingsService::STORE_SUCCESS &&
274 device_settings_service_->device_settings()) {
275 settings = *device_settings_service_->device_settings();
277 UpdateDeviceSettings(setting, value, settings);
278 em::PolicyData policy_data;
279 policy_data.set_username(user_id_);
280 CHECK(settings.SerializeToString(policy_data.mutable_policy_value()));
281 FOR_EACH_OBSERVER(OwnerSettingsService::Observer, observers_,
282 OnTentativeChangesInPolicy(policy_data));
283 StorePendingChanges();
284 return true;
287 bool OwnerSettingsServiceChromeOS::AppendToList(const std::string& setting,
288 const base::Value& value) {
289 DCHECK(thread_checker_.CalledOnValidThread());
290 const base::Value* old_value = CrosSettings::Get()->GetPref(setting);
291 if (old_value && !old_value->IsType(base::Value::TYPE_LIST))
292 return false;
293 scoped_ptr<base::ListValue> new_value(
294 old_value ? static_cast<const base::ListValue*>(old_value)->DeepCopy()
295 : new base::ListValue());
296 new_value->Append(value.DeepCopy());
297 return Set(setting, *new_value);
300 bool OwnerSettingsServiceChromeOS::RemoveFromList(const std::string& setting,
301 const base::Value& value) {
302 DCHECK(thread_checker_.CalledOnValidThread());
303 const base::Value* old_value = CrosSettings::Get()->GetPref(setting);
304 if (old_value && !old_value->IsType(base::Value::TYPE_LIST))
305 return false;
306 scoped_ptr<base::ListValue> new_value(
307 old_value ? static_cast<const base::ListValue*>(old_value)->DeepCopy()
308 : new base::ListValue());
309 new_value->Remove(value, nullptr);
310 return Set(setting, *new_value);
313 bool OwnerSettingsServiceChromeOS::CommitTentativeDeviceSettings(
314 scoped_ptr<enterprise_management::PolicyData> policy) {
315 if (!IsOwner() && !IsOwnerInTests(user_id_))
316 return false;
317 if (policy->username() != user_id_) {
318 LOG(ERROR) << "Username mismatch: " << policy->username() << " vs. "
319 << user_id_;
320 return false;
322 tentative_settings_.reset(new em::ChromeDeviceSettingsProto);
323 CHECK(tentative_settings_->ParseFromString(policy->policy_value()));
324 StorePendingChanges();
325 return true;
328 void OwnerSettingsServiceChromeOS::Observe(
329 int type,
330 const content::NotificationSource& source,
331 const content::NotificationDetails& details) {
332 DCHECK(thread_checker_.CalledOnValidThread());
333 if (type != chrome::NOTIFICATION_PROFILE_CREATED) {
334 NOTREACHED();
335 return;
338 Profile* profile = content::Source<Profile>(source).ptr();
339 if (profile != profile_) {
340 NOTREACHED();
341 return;
344 waiting_for_profile_creation_ = false;
345 ReloadKeypair();
348 void OwnerSettingsServiceChromeOS::OwnerKeySet(bool success) {
349 DCHECK(thread_checker_.CalledOnValidThread());
350 if (success)
351 ReloadKeypair();
354 void OwnerSettingsServiceChromeOS::OwnershipStatusChanged() {
355 DCHECK(thread_checker_.CalledOnValidThread());
356 StorePendingChanges();
359 void OwnerSettingsServiceChromeOS::DeviceSettingsUpdated() {
360 DCHECK(thread_checker_.CalledOnValidThread());
361 StorePendingChanges();
364 void OwnerSettingsServiceChromeOS::OnDeviceSettingsServiceShutdown() {
365 device_settings_service_ = nullptr;
368 void OwnerSettingsServiceChromeOS::SetManagementSettings(
369 const ManagementSettings& settings,
370 const OnManagementSettingsSetCallback& callback) {
371 if ((!IsOwner() && !IsOwnerInTests(user_id_))) {
372 if (!callback.is_null())
373 callback.Run(false /* success */);
374 return;
377 policy::ManagementMode current_mode = policy::MANAGEMENT_MODE_LOCAL_OWNER;
378 if (has_pending_management_settings_) {
379 current_mode = pending_management_settings_.management_mode;
380 } else if (device_settings_service_ &&
381 device_settings_service_->policy_data()) {
382 current_mode =
383 policy::GetManagementMode(*device_settings_service_->policy_data());
386 if (!CheckManagementModeTransition(current_mode, settings.management_mode)) {
387 LOG(ERROR) << "Invalid management mode transition: current mode = "
388 << current_mode << ", new mode = " << settings.management_mode;
389 if (!callback.is_null())
390 callback.Run(false /* success */);
391 return;
394 pending_management_settings_ = settings;
395 has_pending_management_settings_ = true;
396 pending_management_settings_callbacks_.push_back(callback);
397 StorePendingChanges();
400 // static
401 void OwnerSettingsServiceChromeOS::IsOwnerForSafeModeAsync(
402 const std::string& user_hash,
403 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
404 const IsOwnerCallback& callback) {
405 CHECK(chromeos::LoginState::Get()->IsInSafeMode());
407 // Make sure NSS is initialized and NSS DB is loaded for the user before
408 // searching for the owner key.
409 BrowserThread::PostTaskAndReply(
410 BrowserThread::IO,
411 FROM_HERE,
412 base::Bind(base::IgnoreResult(&crypto::InitializeNSSForChromeOSUser),
413 user_hash,
414 ProfileHelper::GetProfilePathByUserIdHash(user_hash)),
415 base::Bind(&DoesPrivateKeyExistAsync, owner_key_util, callback));
418 // static
419 scoped_ptr<em::PolicyData> OwnerSettingsServiceChromeOS::AssemblePolicy(
420 const std::string& user_id,
421 const em::PolicyData* policy_data,
422 bool apply_pending_management_settings,
423 const ManagementSettings& pending_management_settings,
424 em::ChromeDeviceSettingsProto* settings) {
425 scoped_ptr<em::PolicyData> policy(new em::PolicyData());
426 if (policy_data) {
427 // Preserve management settings.
428 if (policy_data->has_management_mode())
429 policy->set_management_mode(policy_data->management_mode());
430 if (policy_data->has_request_token())
431 policy->set_request_token(policy_data->request_token());
432 if (policy_data->has_device_id())
433 policy->set_device_id(policy_data->device_id());
434 } else {
435 // If there's no previous policy data, this is the first time the device
436 // setting is set. We set the management mode to LOCAL_OWNER initially.
437 policy->set_management_mode(em::PolicyData::LOCAL_OWNER);
439 if (apply_pending_management_settings) {
440 policy::SetManagementMode(*policy,
441 pending_management_settings.management_mode);
443 if (pending_management_settings.request_token.empty())
444 policy->clear_request_token();
445 else
446 policy->set_request_token(pending_management_settings.request_token);
448 if (pending_management_settings.device_id.empty())
449 policy->clear_device_id();
450 else
451 policy->set_device_id(pending_management_settings.device_id);
453 policy->set_policy_type(policy::dm_protocol::kChromeDevicePolicyType);
454 policy->set_timestamp(
455 (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds());
456 policy->set_username(user_id);
457 if (policy_data->management_mode() == em::PolicyData::LOCAL_OWNER ||
458 policy_data->management_mode() == em::PolicyData::CONSUMER_MANAGED) {
459 FixupLocalOwnerPolicy(user_id, settings);
461 if (!settings->SerializeToString(policy->mutable_policy_value()))
462 return scoped_ptr<em::PolicyData>();
464 return policy.Pass();
467 // static
468 void OwnerSettingsServiceChromeOS::FixupLocalOwnerPolicy(
469 const std::string& user_id,
470 enterprise_management::ChromeDeviceSettingsProto* settings) {
471 if (!settings->has_allow_new_users())
472 settings->mutable_allow_new_users()->set_allow_new_users(true);
474 em::UserWhitelistProto* whitelist_proto = settings->mutable_user_whitelist();
475 if (whitelist_proto->user_whitelist().end() ==
476 std::find(whitelist_proto->user_whitelist().begin(),
477 whitelist_proto->user_whitelist().end(), user_id)) {
478 whitelist_proto->add_user_whitelist(user_id);
482 // static
483 void OwnerSettingsServiceChromeOS::UpdateDeviceSettings(
484 const std::string& path,
485 const base::Value& value,
486 enterprise_management::ChromeDeviceSettingsProto& settings) {
487 if (path == kAccountsPrefAllowNewUser) {
488 em::AllowNewUsersProto* allow = settings.mutable_allow_new_users();
489 bool allow_value;
490 if (value.GetAsBoolean(&allow_value)) {
491 allow->set_allow_new_users(allow_value);
492 } else {
493 NOTREACHED();
495 } else if (path == kAccountsPrefAllowGuest) {
496 em::GuestModeEnabledProto* guest = settings.mutable_guest_mode_enabled();
497 bool guest_value;
498 if (value.GetAsBoolean(&guest_value))
499 guest->set_guest_mode_enabled(guest_value);
500 else
501 NOTREACHED();
502 } else if (path == kAccountsPrefSupervisedUsersEnabled) {
503 em::SupervisedUsersSettingsProto* supervised =
504 settings.mutable_supervised_users_settings();
505 bool supervised_value;
506 if (value.GetAsBoolean(&supervised_value))
507 supervised->set_supervised_users_enabled(supervised_value);
508 else
509 NOTREACHED();
510 } else if (path == kAccountsPrefShowUserNamesOnSignIn) {
511 em::ShowUserNamesOnSigninProto* show = settings.mutable_show_user_names();
512 bool show_value;
513 if (value.GetAsBoolean(&show_value))
514 show->set_show_user_names(show_value);
515 else
516 NOTREACHED();
517 } else if (path == kAccountsPrefDeviceLocalAccounts) {
518 em::DeviceLocalAccountsProto* device_local_accounts =
519 settings.mutable_device_local_accounts();
520 device_local_accounts->clear_account();
521 const base::ListValue* accounts_list = NULL;
522 if (value.GetAsList(&accounts_list)) {
523 for (base::ListValue::const_iterator entry(accounts_list->begin());
524 entry != accounts_list->end();
525 ++entry) {
526 const base::DictionaryValue* entry_dict = NULL;
527 if ((*entry)->GetAsDictionary(&entry_dict)) {
528 em::DeviceLocalAccountInfoProto* account =
529 device_local_accounts->add_account();
530 std::string account_id;
531 if (entry_dict->GetStringWithoutPathExpansion(
532 kAccountsPrefDeviceLocalAccountsKeyId, &account_id)) {
533 account->set_account_id(account_id);
535 int type;
536 if (entry_dict->GetIntegerWithoutPathExpansion(
537 kAccountsPrefDeviceLocalAccountsKeyType, &type)) {
538 account->set_type(
539 static_cast<em::DeviceLocalAccountInfoProto::AccountType>(
540 type));
542 std::string kiosk_app_id;
543 if (entry_dict->GetStringWithoutPathExpansion(
544 kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
545 &kiosk_app_id)) {
546 account->mutable_kiosk_app()->set_app_id(kiosk_app_id);
548 std::string kiosk_app_update_url;
549 if (entry_dict->GetStringWithoutPathExpansion(
550 kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL,
551 &kiosk_app_update_url)) {
552 account->mutable_kiosk_app()->set_update_url(kiosk_app_update_url);
554 } else {
555 NOTREACHED();
558 } else {
559 NOTREACHED();
561 } else if (path == kAccountsPrefDeviceLocalAccountAutoLoginId) {
562 em::DeviceLocalAccountsProto* device_local_accounts =
563 settings.mutable_device_local_accounts();
564 std::string id;
565 if (value.GetAsString(&id))
566 device_local_accounts->set_auto_login_id(id);
567 else
568 NOTREACHED();
569 } else if (path == kAccountsPrefDeviceLocalAccountAutoLoginDelay) {
570 em::DeviceLocalAccountsProto* device_local_accounts =
571 settings.mutable_device_local_accounts();
572 int delay;
573 if (value.GetAsInteger(&delay))
574 device_local_accounts->set_auto_login_delay(delay);
575 else
576 NOTREACHED();
577 } else if (path == kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled) {
578 em::DeviceLocalAccountsProto* device_local_accounts =
579 settings.mutable_device_local_accounts();
580 bool enabled;
581 if (value.GetAsBoolean(&enabled))
582 device_local_accounts->set_enable_auto_login_bailout(enabled);
583 else
584 NOTREACHED();
585 } else if (path ==
586 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline) {
587 em::DeviceLocalAccountsProto* device_local_accounts =
588 settings.mutable_device_local_accounts();
589 bool should_prompt;
590 if (value.GetAsBoolean(&should_prompt))
591 device_local_accounts->set_prompt_for_network_when_offline(should_prompt);
592 else
593 NOTREACHED();
594 } else if (path == kSignedDataRoamingEnabled) {
595 em::DataRoamingEnabledProto* roam = settings.mutable_data_roaming_enabled();
596 bool roaming_value = false;
597 if (value.GetAsBoolean(&roaming_value))
598 roam->set_data_roaming_enabled(roaming_value);
599 else
600 NOTREACHED();
601 } else if (path == kReleaseChannel) {
602 em::ReleaseChannelProto* release_channel =
603 settings.mutable_release_channel();
604 std::string channel_value;
605 if (value.GetAsString(&channel_value))
606 release_channel->set_release_channel(channel_value);
607 else
608 NOTREACHED();
609 } else if (path == kStatsReportingPref) {
610 em::MetricsEnabledProto* metrics = settings.mutable_metrics_enabled();
611 bool metrics_value = false;
612 if (value.GetAsBoolean(&metrics_value))
613 metrics->set_metrics_enabled(metrics_value);
614 else
615 NOTREACHED();
616 } else if (path == kAccountsPrefUsers) {
617 em::UserWhitelistProto* whitelist_proto = settings.mutable_user_whitelist();
618 whitelist_proto->clear_user_whitelist();
619 const base::ListValue* users;
620 if (value.GetAsList(&users)) {
621 for (base::ListValue::const_iterator i = users->begin();
622 i != users->end();
623 ++i) {
624 std::string email;
625 if ((*i)->GetAsString(&email))
626 whitelist_proto->add_user_whitelist(email);
629 } else if (path == kAccountsPrefEphemeralUsersEnabled) {
630 em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
631 settings.mutable_ephemeral_users_enabled();
632 bool ephemeral_users_enabled_value = false;
633 if (value.GetAsBoolean(&ephemeral_users_enabled_value)) {
634 ephemeral_users_enabled->set_ephemeral_users_enabled(
635 ephemeral_users_enabled_value);
636 } else {
637 NOTREACHED();
639 } else if (path == kAllowRedeemChromeOsRegistrationOffers) {
640 em::AllowRedeemChromeOsRegistrationOffersProto* allow_redeem_offers =
641 settings.mutable_allow_redeem_offers();
642 bool allow_redeem_offers_value;
643 if (value.GetAsBoolean(&allow_redeem_offers_value)) {
644 allow_redeem_offers->set_allow_redeem_offers(allow_redeem_offers_value);
645 } else {
646 NOTREACHED();
648 } else if (path == kStartUpFlags) {
649 em::StartUpFlagsProto* flags_proto = settings.mutable_start_up_flags();
650 flags_proto->Clear();
651 const base::ListValue* flags;
652 if (value.GetAsList(&flags)) {
653 for (base::ListValue::const_iterator i = flags->begin();
654 i != flags->end();
655 ++i) {
656 std::string flag;
657 if ((*i)->GetAsString(&flag))
658 flags_proto->add_flags(flag);
661 } else if (path == kSystemUse24HourClock) {
662 em::SystemUse24HourClockProto* use_24hour_clock_proto =
663 settings.mutable_use_24hour_clock();
664 use_24hour_clock_proto->Clear();
665 bool use_24hour_clock_value;
666 if (value.GetAsBoolean(&use_24hour_clock_value)) {
667 use_24hour_clock_proto->set_use_24hour_clock(use_24hour_clock_value);
668 } else {
669 NOTREACHED();
671 } else if (path == kAttestationForContentProtectionEnabled) {
672 em::AttestationSettingsProto* attestation_settings =
673 settings.mutable_attestation_settings();
674 bool setting_enabled;
675 if (value.GetAsBoolean(&setting_enabled)) {
676 attestation_settings->set_content_protection_enabled(setting_enabled);
677 } else {
678 NOTREACHED();
680 } else {
681 // The remaining settings don't support Set(), since they are not
682 // intended to be customizable by the user:
683 // kAccountsPrefTransferSAMLCookies
684 // kDeviceAttestationEnabled
685 // kDeviceOwner
686 // kHeartbeatEnabled
687 // kHeartbeatFrequency
688 // kReleaseChannelDelegated
689 // kReportDeviceActivityTimes
690 // kReportDeviceBootMode
691 // kReportDeviceHardwareStatus
692 // kReportDeviceLocation
693 // kReportDeviceNetworkInterfaces
694 // kReportDeviceSessionStatus
695 // kReportDeviceVersionInfo
696 // kReportDeviceUsers
697 // kServiceAccountIdentity
698 // kSystemTimezonePolicy
699 // kVariationsRestrictParameter
700 // kDeviceDisabled
701 // kDeviceDisabledMessage
703 LOG(FATAL) << "Device setting " << path << " is read-only.";
707 void OwnerSettingsServiceChromeOS::OnPostKeypairLoadedActions() {
708 DCHECK(thread_checker_.CalledOnValidThread());
710 const user_manager::User* user =
711 ProfileHelper::Get()->GetUserByProfile(profile_);
712 user_id_ = user ? user->GetUserID() : std::string();
714 const bool is_owner = IsOwner() || IsOwnerInTests(user_id_);
715 if (is_owner && device_settings_service_)
716 device_settings_service_->InitOwner(user_id_, weak_factory_.GetWeakPtr());
718 has_pending_fixups_ = true;
721 void OwnerSettingsServiceChromeOS::ReloadKeypairImpl(const base::Callback<
722 void(const scoped_refptr<PublicKey>& public_key,
723 const scoped_refptr<PrivateKey>& private_key)>& callback) {
724 DCHECK(thread_checker_.CalledOnValidThread());
726 if (waiting_for_profile_creation_ || waiting_for_tpm_token_)
727 return;
728 scoped_refptr<base::TaskRunner> task_runner =
729 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
730 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
731 task_runner->PostTask(
732 FROM_HERE,
733 base::Bind(&LoadPrivateKey,
734 owner_key_util_,
735 ProfileHelper::GetUserIdHashFromProfile(profile_),
736 callback));
739 void OwnerSettingsServiceChromeOS::StorePendingChanges() {
740 if (!HasPendingChanges() || store_settings_factory_.HasWeakPtrs() ||
741 !device_settings_service_ || user_id_.empty()) {
742 return;
745 em::ChromeDeviceSettingsProto settings;
746 if (tentative_settings_.get()) {
747 settings.Swap(tentative_settings_.get());
748 tentative_settings_.reset();
749 } else if (device_settings_service_->status() ==
750 DeviceSettingsService::STORE_SUCCESS &&
751 device_settings_service_->device_settings()) {
752 settings = *device_settings_service_->device_settings();
753 } else {
754 return;
757 for (const auto& change : pending_changes_)
758 UpdateDeviceSettings(change.first, *change.second, settings);
759 pending_changes_.clear();
761 scoped_ptr<em::PolicyData> policy =
762 AssemblePolicy(user_id_, device_settings_service_->policy_data(),
763 has_pending_management_settings_,
764 pending_management_settings_, &settings);
765 has_pending_fixups_ = false;
766 has_pending_management_settings_ = false;
768 bool rv = AssembleAndSignPolicyAsync(
769 content::BrowserThread::GetBlockingPool(), policy.Pass(),
770 base::Bind(&OwnerSettingsServiceChromeOS::OnPolicyAssembledAndSigned,
771 store_settings_factory_.GetWeakPtr()));
772 if (!rv)
773 ReportStatusAndContinueStoring(false /* success */);
776 void OwnerSettingsServiceChromeOS::OnPolicyAssembledAndSigned(
777 scoped_ptr<em::PolicyFetchResponse> policy_response) {
778 if (!policy_response.get() || !device_settings_service_) {
779 ReportStatusAndContinueStoring(false /* success */);
780 return;
782 device_settings_service_->Store(
783 policy_response.Pass(),
784 base::Bind(&OwnerSettingsServiceChromeOS::OnSignedPolicyStored,
785 store_settings_factory_.GetWeakPtr(),
786 true /* success */));
789 void OwnerSettingsServiceChromeOS::OnSignedPolicyStored(bool success) {
790 CHECK(device_settings_service_);
791 ReportStatusAndContinueStoring(success &&
792 device_settings_service_->status() ==
793 DeviceSettingsService::STORE_SUCCESS);
796 void OwnerSettingsServiceChromeOS::ReportStatusAndContinueStoring(
797 bool success) {
798 store_settings_factory_.InvalidateWeakPtrs();
799 FOR_EACH_OBSERVER(OwnerSettingsService::Observer, observers_,
800 OnSignedPolicyStored(success));
802 std::vector<OnManagementSettingsSetCallback> callbacks;
803 pending_management_settings_callbacks_.swap(callbacks);
804 for (const auto& callback : callbacks) {
805 if (!callback.is_null())
806 callback.Run(success);
808 StorePendingChanges();
811 } // namespace chromeos