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"
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
;
52 bool IsOwnerInTests(const std::string
& user_id
) {
53 if (user_id
.empty() ||
54 !base::CommandLine::ForCurrentProcess()->HasSwitch(
55 ::switches::kTestType
) ||
56 !CrosSettings::IsInitialized()) {
59 const base::Value
* value
= CrosSettings::Get()->GetPref(kDeviceOwner
);
60 if (!value
|| value
->GetType() != base::Value::TYPE_STRING
)
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
)>&
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
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
,
95 base::Bind(callback
, public_key
, private_key
));
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
)>&
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
,
110 base::Bind(callback
, public_key
, private_key
));
113 public_key
= new PublicKey();
114 public_key
->data().swap(public_key_data
);
115 bool rv
= BrowserThread::PostTask(BrowserThread::IO
,
117 base::Bind(&LoadPrivateKeyByPublicKey
,
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
))
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()) {
149 scoped_refptr
<base::TaskRunner
> task_runner
=
150 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
151 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
);
152 base::PostTaskAndReplyWithResult(
155 base::Bind(&DoesPrivateKeyExistAsyncHelper
, owner_key_util
),
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
)
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.
176 case policy::MANAGEMENT_MODE_CONSUMER_MANAGED
:
177 // For consumer management unenrollment.
178 return new_mode
== policy::MANAGEMENT_MODE_LOCAL_OWNER
;
187 OwnerSettingsServiceChromeOS::ManagementSettings::ManagementSettings() {
190 OwnerSettingsServiceChromeOS::ManagementSettings::~ManagementSettings() {
193 OwnerSettingsServiceChromeOS::OwnerSettingsServiceChromeOS(
194 DeviceSettingsService
* device_settings_service
,
196 const scoped_refptr
<OwnerKeyUtil
>& owner_key_util
)
197 : ownership::OwnerSettingsService(owner_key_util
),
198 device_settings_service_(device_settings_service
),
200 waiting_for_profile_creation_(true),
201 waiting_for_tpm_token_(true),
202 has_pending_fixups_(false),
203 has_pending_management_settings_(false),
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);
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
) {
244 Profile
* profile
= Profile::FromWebUI(web_ui
);
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.
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
)) {
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_
))
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();
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
))
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
))
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_
))
329 if (policy
->username() != user_id_
) {
330 LOG(ERROR
) << "Username mismatch: " << policy
->username() << " vs. "
334 tentative_settings_
.reset(new em::ChromeDeviceSettingsProto
);
335 CHECK(tentative_settings_
->ParseFromString(policy
->policy_value()));
336 StorePendingChanges();
340 void OwnerSettingsServiceChromeOS::Observe(
342 const content::NotificationSource
& source
,
343 const content::NotificationDetails
& details
) {
344 DCHECK(thread_checker_
.CalledOnValidThread());
345 if (type
!= chrome::NOTIFICATION_PROFILE_CREATED
) {
350 Profile
* profile
= content::Source
<Profile
>(source
).ptr();
351 if (profile
!= profile_
) {
356 waiting_for_profile_creation_
= false;
360 void OwnerSettingsServiceChromeOS::OwnerKeySet(bool success
) {
361 DCHECK(thread_checker_
.CalledOnValidThread());
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 */);
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()) {
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 */);
406 pending_management_settings_
= settings
;
407 has_pending_management_settings_
= true;
408 pending_management_settings_callbacks_
.push_back(callback
);
409 StorePendingChanges();
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(
424 base::Bind(base::IgnoreResult(&crypto::InitializeNSSForChromeOSUser
),
426 ProfileHelper::GetProfilePathByUserIdHash(user_hash
)),
427 base::Bind(&DoesPrivateKeyExistAsync
, owner_key_util
, callback
));
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());
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());
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();
458 policy
->set_request_token(pending_management_settings
.request_token
);
460 if (pending_management_settings
.device_id
.empty())
461 policy
->clear_device_id();
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();
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
);
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();
502 if (value
.GetAsBoolean(&allow_value
)) {
503 allow
->set_allow_new_users(allow_value
);
507 } else if (path
== kAccountsPrefAllowGuest
) {
508 em::GuestModeEnabledProto
* guest
= settings
.mutable_guest_mode_enabled();
510 if (value
.GetAsBoolean(&guest_value
))
511 guest
->set_guest_mode_enabled(guest_value
);
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
);
522 } else if (path
== kAccountsPrefShowUserNamesOnSignIn
) {
523 em::ShowUserNamesOnSigninProto
* show
= settings
.mutable_show_user_names();
525 if (value
.GetAsBoolean(&show_value
))
526 show
->set_show_user_names(show_value
);
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();
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
);
548 if (entry_dict
->GetIntegerWithoutPathExpansion(
549 kAccountsPrefDeviceLocalAccountsKeyType
, &type
)) {
551 static_cast<em::DeviceLocalAccountInfoProto::AccountType
>(
554 std::string kiosk_app_id
;
555 if (entry_dict
->GetStringWithoutPathExpansion(
556 kAccountsPrefDeviceLocalAccountsKeyKioskAppId
,
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
);
573 } else if (path
== kAccountsPrefDeviceLocalAccountAutoLoginId
) {
574 em::DeviceLocalAccountsProto
* device_local_accounts
=
575 settings
.mutable_device_local_accounts();
577 if (value
.GetAsString(&id
))
578 device_local_accounts
->set_auto_login_id(id
);
581 } else if (path
== kAccountsPrefDeviceLocalAccountAutoLoginDelay
) {
582 em::DeviceLocalAccountsProto
* device_local_accounts
=
583 settings
.mutable_device_local_accounts();
585 if (value
.GetAsInteger(&delay
))
586 device_local_accounts
->set_auto_login_delay(delay
);
589 } else if (path
== kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled
) {
590 em::DeviceLocalAccountsProto
* device_local_accounts
=
591 settings
.mutable_device_local_accounts();
593 if (value
.GetAsBoolean(&enabled
))
594 device_local_accounts
->set_enable_auto_login_bailout(enabled
);
598 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline
) {
599 em::DeviceLocalAccountsProto
* device_local_accounts
=
600 settings
.mutable_device_local_accounts();
602 if (value
.GetAsBoolean(&should_prompt
))
603 device_local_accounts
->set_prompt_for_network_when_offline(should_prompt
);
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
);
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
);
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
);
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();
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
);
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
);
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();
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
);
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
);
693 // The remaining settings don't support Set(), since they are not
694 // intended to be customizable by the user:
695 // kAccountsPrefTransferSAMLCookies
696 // kDeviceAttestationEnabled
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
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_
)
740 scoped_refptr
<base::TaskRunner
> task_runner
=
741 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
742 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
);
743 task_runner
->PostTask(
745 base::Bind(&LoadPrivateKey
,
747 ProfileHelper::GetUserIdHashFromProfile(profile_
),
751 void OwnerSettingsServiceChromeOS::StorePendingChanges() {
752 if (!HasPendingChanges() || store_settings_factory_
.HasWeakPtrs() ||
753 !device_settings_service_
|| user_id_
.empty()) {
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();
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()));
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 */);
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(
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