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