• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/policy/configuration_policy_pref_store.h"
6 
7 #include <map>
8 #include <set>
9 #include <string>
10 #include <vector>
11 
12 #include "base/command_line.h"
13 #include "base/lazy_instance.h"
14 #include "base/logging.h"
15 #include "base/stl_util-inl.h"
16 #include "base/string16.h"
17 #include "base/string_util.h"
18 #include "base/utf_string_conversions.h"
19 #include "base/values.h"
20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/policy/browser_policy_connector.h"
22 #include "chrome/browser/policy/configuration_policy_provider.h"
23 #include "chrome/browser/policy/policy_path_parser.h"
24 #include "chrome/browser/policy/profile_policy_connector.h"
25 #include "chrome/browser/prefs/pref_value_map.h"
26 #include "chrome/browser/prefs/proxy_config_dictionary.h"
27 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/browser/search_engines/search_terms_data.h"
29 #include "chrome/browser/search_engines/template_url.h"
30 #include "chrome/common/pref_names.h"
31 #include "content/common/notification_service.h"
32 #include "policy/policy_constants.h"
33 
34 namespace policy {
35 
36 // Accepts policy settings from a ConfigurationPolicyProvider, converts them
37 // to preferences and caches the result.
38 class ConfigurationPolicyPrefKeeper
39     : private ConfigurationPolicyStoreInterface {
40  public:
41   explicit ConfigurationPolicyPrefKeeper(ConfigurationPolicyProvider* provider);
42   virtual ~ConfigurationPolicyPrefKeeper();
43 
44   // Get a preference value.
45   PrefStore::ReadResult GetValue(const std::string& key,
46                                  const Value** result) const;
47 
48   // Compute the set of preference names that are different in |keeper|. This
49   // includes preferences that are missing in either one.
50   void GetDifferingPrefPaths(const ConfigurationPolicyPrefKeeper* other,
51                              std::vector<std::string>* differing_prefs) const;
52 
53  private:
54   // ConfigurationPolicyStore methods:
55   virtual void Apply(ConfigurationPolicyType setting, Value* value);
56 
57   // Policies that map to a single preference are handled
58   // by an automated converter. Each one of these policies
59   // has an entry in |simple_policy_map_| with the following type.
60   struct PolicyToPreferenceMapEntry {
61     Value::ValueType value_type;
62     ConfigurationPolicyType policy_type;
63     const char* preference_path;  // A DictionaryValue path, not a file path.
64   };
65 
66   // Remove the preferences found in the map from |prefs_|. Returns true if any
67   // such preferences were found and removed.
68   bool RemovePreferencesOfMap(const PolicyToPreferenceMapEntry* map,
69                               int table_size);
70 
71   bool ApplyPolicyFromMap(ConfigurationPolicyType policy,
72                           Value* value,
73                           const PolicyToPreferenceMapEntry* map,
74                           int size);
75 
76   // Processes proxy-specific policies. Returns true if the specified policy
77   // is a proxy-related policy. ApplyProxyPolicy assumes the ownership
78   // of |value| in the case that the policy is proxy-specific.
79   bool ApplyProxyPolicy(ConfigurationPolicyType policy, Value* value);
80 
81   // Handles sync-related policies. Returns true if the policy was handled.
82   // Assumes ownership of |value| in that case.
83   bool ApplySyncPolicy(ConfigurationPolicyType policy, Value* value);
84 
85   // Handles policies that affect Autofill. Returns true if the policy was
86   // handled and assumes ownership of |value| in that case.
87   bool ApplyAutofillPolicy(ConfigurationPolicyType policy, Value* value);
88 
89   // Processes download directory policy. Returns true if the specified policy
90   // is the download directory policy. ApplyDownloadDirPolicy assumes the
91   // ownership of |value| in the case that the policy is recognized.
92   bool ApplyDownloadDirPolicy(ConfigurationPolicyType policy, Value* value);
93 
94   // Make sure that the |path| if present in |prefs_|.  If not, set it to
95   // a blank string.
96   void EnsureStringPrefExists(const std::string& path);
97 
98   // If the required entries for default search are specified and valid,
99   // finalizes the policy-specified configuration by initializing the
100   // unspecified map entries.  Otherwise wipes all default search related
101   // map entries from |prefs_|.
102   void FinalizeDefaultSearchPolicySettings();
103 
104   // If the required entries for the proxy settings are specified and valid,
105   // finalizes the policy-specified configuration by initializing the
106   // respective values in |prefs_|.
107   void FinalizeProxyPolicySettings();
108 
109   // Returns true if the policy values stored in proxy_* represent a valid proxy
110   // configuration, including the case in which there is no configuration at
111   // all.
112   bool CheckProxySettings();
113 
114   // Assumes CheckProxySettings returns true and applies the values stored
115   // in proxy_*.
116   void ApplyProxySettings();
117 
118   bool HasProxyPolicy(ConfigurationPolicyType policy) const;
119 
120   // Temporary cache that stores values until FinalizeProxyPolicySettings()
121   // is called.
122   std::map<ConfigurationPolicyType, Value*> proxy_policies_;
123 
124   PrefValueMap prefs_;
125 
126   static const PolicyToPreferenceMapEntry kSimplePolicyMap[];
127   static const PolicyToPreferenceMapEntry kDefaultSearchPolicyMap[];
128 
129   DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyPrefKeeper);
130 };
131 
132 const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry
133     ConfigurationPolicyPrefKeeper::kSimplePolicyMap[] = {
134   { Value::TYPE_STRING, kPolicyHomepageLocation,  prefs::kHomePage },
135   { Value::TYPE_BOOLEAN, kPolicyHomepageIsNewTabPage,
136     prefs::kHomePageIsNewTabPage },
137   { Value::TYPE_INTEGER, kPolicyRestoreOnStartup,
138     prefs::kRestoreOnStartup},
139   { Value::TYPE_LIST, kPolicyRestoreOnStartupURLs,
140     prefs::kURLsToRestoreOnStartup },
141   { Value::TYPE_BOOLEAN, kPolicyAlternateErrorPagesEnabled,
142     prefs::kAlternateErrorPagesEnabled },
143   { Value::TYPE_BOOLEAN, kPolicySearchSuggestEnabled,
144     prefs::kSearchSuggestEnabled },
145   { Value::TYPE_BOOLEAN, kPolicyDnsPrefetchingEnabled,
146     prefs::kNetworkPredictionEnabled },
147   { Value::TYPE_BOOLEAN, kPolicyDisableSpdy,
148     prefs::kDisableSpdy },
149   { Value::TYPE_LIST, kPolicyDisabledSchemes,
150     prefs::kDisabledSchemes },
151   { Value::TYPE_BOOLEAN, kPolicySafeBrowsingEnabled,
152     prefs::kSafeBrowsingEnabled },
153   { Value::TYPE_BOOLEAN, kPolicyPasswordManagerEnabled,
154     prefs::kPasswordManagerEnabled },
155   { Value::TYPE_BOOLEAN, kPolicyPasswordManagerAllowShowPasswords,
156     prefs::kPasswordManagerAllowShowPasswords },
157   { Value::TYPE_BOOLEAN, kPolicyPrintingEnabled,
158     prefs::kPrintingEnabled },
159   { Value::TYPE_BOOLEAN, kPolicyMetricsReportingEnabled,
160     prefs::kMetricsReportingEnabled },
161   { Value::TYPE_STRING, kPolicyApplicationLocaleValue,
162     prefs::kApplicationLocale},
163   { Value::TYPE_LIST, kPolicyExtensionInstallWhitelist,
164     prefs::kExtensionInstallAllowList},
165   { Value::TYPE_LIST, kPolicyExtensionInstallBlacklist,
166     prefs::kExtensionInstallDenyList},
167   { Value::TYPE_LIST, kPolicyExtensionInstallForcelist,
168     prefs::kExtensionInstallForceList},
169   { Value::TYPE_LIST, kPolicyDisabledPlugins,
170     prefs::kPluginsDisabledPlugins},
171   { Value::TYPE_LIST, kPolicyDisabledPluginsExceptions,
172     prefs::kPluginsDisabledPluginsExceptions},
173   { Value::TYPE_LIST, kPolicyEnabledPlugins,
174     prefs::kPluginsEnabledPlugins},
175   { Value::TYPE_BOOLEAN, kPolicyShowHomeButton,
176     prefs::kShowHomeButton },
177   { Value::TYPE_BOOLEAN, kPolicyJavascriptEnabled,
178     prefs::kWebKitJavascriptEnabled },
179   { Value::TYPE_BOOLEAN, kPolicyIncognitoEnabled,
180     prefs::kIncognitoEnabled },
181   { Value::TYPE_BOOLEAN, kPolicySavingBrowserHistoryDisabled,
182     prefs::kSavingBrowserHistoryDisabled },
183   { Value::TYPE_BOOLEAN, kPolicyClearSiteDataOnExit,
184     prefs::kClearSiteDataOnExit },
185   { Value::TYPE_BOOLEAN, kPolicyDeveloperToolsDisabled,
186     prefs::kDevToolsDisabled },
187   { Value::TYPE_BOOLEAN, kPolicyBlockThirdPartyCookies,
188     prefs::kBlockThirdPartyCookies },
189   { Value::TYPE_INTEGER, kPolicyDefaultCookiesSetting,
190     prefs::kManagedDefaultCookiesSetting },
191   { Value::TYPE_INTEGER, kPolicyDefaultImagesSetting,
192     prefs::kManagedDefaultImagesSetting },
193   { Value::TYPE_INTEGER, kPolicyDefaultJavaScriptSetting,
194     prefs::kManagedDefaultJavaScriptSetting },
195   { Value::TYPE_INTEGER, kPolicyDefaultPluginsSetting,
196     prefs::kManagedDefaultPluginsSetting },
197   { Value::TYPE_INTEGER, kPolicyDefaultPopupsSetting,
198     prefs::kManagedDefaultPopupsSetting },
199   { Value::TYPE_LIST, kPolicyCookiesAllowedForUrls,
200     prefs::kManagedCookiesAllowedForUrls },
201   { Value::TYPE_LIST, kPolicyCookiesBlockedForUrls,
202     prefs::kManagedCookiesBlockedForUrls },
203   { Value::TYPE_LIST, kPolicyCookiesSessionOnlyForUrls,
204     prefs::kManagedCookiesSessionOnlyForUrls },
205   { Value::TYPE_LIST, kPolicyImagesAllowedForUrls,
206     prefs::kManagedImagesAllowedForUrls },
207   { Value::TYPE_LIST, kPolicyImagesBlockedForUrls,
208     prefs::kManagedImagesBlockedForUrls },
209   { Value::TYPE_LIST, kPolicyJavaScriptAllowedForUrls,
210     prefs::kManagedJavaScriptAllowedForUrls },
211   { Value::TYPE_LIST, kPolicyJavaScriptBlockedForUrls,
212     prefs::kManagedJavaScriptBlockedForUrls },
213   { Value::TYPE_LIST, kPolicyPluginsAllowedForUrls,
214     prefs::kManagedPluginsAllowedForUrls },
215   { Value::TYPE_LIST, kPolicyPluginsBlockedForUrls,
216     prefs::kManagedPluginsBlockedForUrls },
217   { Value::TYPE_LIST, kPolicyPopupsAllowedForUrls,
218     prefs::kManagedPopupsAllowedForUrls },
219   { Value::TYPE_LIST, kPolicyPopupsBlockedForUrls,
220     prefs::kManagedPopupsBlockedForUrls },
221   { Value::TYPE_INTEGER, kPolicyDefaultNotificationSetting,
222     prefs::kDesktopNotificationDefaultContentSetting },
223   { Value::TYPE_INTEGER, kPolicyDefaultGeolocationSetting,
224     prefs::kGeolocationDefaultContentSetting },
225   { Value::TYPE_STRING, kPolicyAuthSchemes,
226     prefs::kAuthSchemes },
227   { Value::TYPE_BOOLEAN, kPolicyDisableAuthNegotiateCnameLookup,
228     prefs::kDisableAuthNegotiateCnameLookup },
229   { Value::TYPE_BOOLEAN, kPolicyEnableAuthNegotiatePort,
230     prefs::kEnableAuthNegotiatePort },
231   { Value::TYPE_STRING, kPolicyAuthServerWhitelist,
232     prefs::kAuthServerWhitelist },
233   { Value::TYPE_STRING, kPolicyAuthNegotiateDelegateWhitelist,
234     prefs::kAuthNegotiateDelegateWhitelist },
235   { Value::TYPE_STRING, kPolicyGSSAPILibraryName,
236     prefs::kGSSAPILibraryName },
237   { Value::TYPE_BOOLEAN, kPolicyDisable3DAPIs,
238     prefs::kDisable3DAPIs },
239   { Value::TYPE_BOOLEAN, kPolicyDisablePluginFinder,
240     prefs::kDisablePluginFinder },
241   { Value::TYPE_INTEGER, kPolicyPolicyRefreshRate,
242     prefs::kPolicyRefreshRate },
243   { Value::TYPE_BOOLEAN, kPolicyInstantEnabled, prefs::kInstantEnabled },
244   { Value::TYPE_BOOLEAN, kPolicyDefaultBrowserSettingEnabled,
245     prefs::kDefaultBrowserSettingEnabled },
246   { Value::TYPE_BOOLEAN, kPolicyCloudPrintProxyEnabled,
247     prefs::kCloudPrintProxyEnabled },
248   { Value::TYPE_BOOLEAN, kPolicyTranslateEnabled, prefs::kEnableTranslate },
249   { Value::TYPE_BOOLEAN, kPolicyBookmarkBarEnabled, prefs::kEnableBookmarkBar },
250   { Value::TYPE_BOOLEAN, kPolicyAllowOutdatedPlugins,
251     prefs::kPluginsAllowOutdated },
252   { Value::TYPE_BOOLEAN, kPolicyEditBookmarksEnabled,
253     prefs::kEditBookmarksEnabled },
254   { Value::TYPE_BOOLEAN, kPolicyAllowFileSelectionDialogs,
255     prefs::kAllowFileSelectionDialogs },
256 
257 #if defined(OS_CHROMEOS)
258   { Value::TYPE_BOOLEAN, kPolicyChromeOsLockOnIdleSuspend,
259     prefs::kEnableScreenLock },
260 #endif
261 };
262 
263 const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry
264     ConfigurationPolicyPrefKeeper::kDefaultSearchPolicyMap[] = {
265   { Value::TYPE_BOOLEAN, kPolicyDefaultSearchProviderEnabled,
266     prefs::kDefaultSearchProviderEnabled },
267   { Value::TYPE_STRING, kPolicyDefaultSearchProviderName,
268     prefs::kDefaultSearchProviderName },
269   { Value::TYPE_STRING, kPolicyDefaultSearchProviderKeyword,
270     prefs::kDefaultSearchProviderKeyword },
271   { Value::TYPE_STRING, kPolicyDefaultSearchProviderSearchURL,
272     prefs::kDefaultSearchProviderSearchURL },
273   { Value::TYPE_STRING, kPolicyDefaultSearchProviderSuggestURL,
274     prefs::kDefaultSearchProviderSuggestURL },
275   { Value::TYPE_STRING, kPolicyDefaultSearchProviderIconURL,
276     prefs::kDefaultSearchProviderIconURL },
277   { Value::TYPE_STRING, kPolicyDefaultSearchProviderEncodings,
278     prefs::kDefaultSearchProviderEncodings },
279 };
280 
ConfigurationPolicyPrefKeeper(ConfigurationPolicyProvider * provider)281 ConfigurationPolicyPrefKeeper::ConfigurationPolicyPrefKeeper(
282     ConfigurationPolicyProvider* provider) {
283   if (!provider->Provide(this))
284     LOG(WARNING) << "Failed to get policy from provider.";
285   FinalizeProxyPolicySettings();
286   FinalizeDefaultSearchPolicySettings();
287 }
288 
~ConfigurationPolicyPrefKeeper()289 ConfigurationPolicyPrefKeeper::~ConfigurationPolicyPrefKeeper() {
290   DCHECK(proxy_policies_.empty());
291 }
292 
293 PrefStore::ReadResult
GetValue(const std::string & key,const Value ** result) const294 ConfigurationPolicyPrefKeeper::GetValue(const std::string& key,
295                                         const Value** result) const {
296   const Value* stored_value = NULL;
297   if (!prefs_.GetValue(key, &stored_value))
298     return PrefStore::READ_NO_VALUE;
299 
300   // Check whether there's a default value, which indicates READ_USE_DEFAULT
301   // should be returned.
302   if (stored_value->IsType(Value::TYPE_NULL))
303     return PrefStore::READ_USE_DEFAULT;
304 
305   *result = stored_value;
306   return PrefStore::READ_OK;
307 }
308 
GetDifferingPrefPaths(const ConfigurationPolicyPrefKeeper * other,std::vector<std::string> * differing_prefs) const309 void ConfigurationPolicyPrefKeeper::GetDifferingPrefPaths(
310     const ConfigurationPolicyPrefKeeper* other,
311     std::vector<std::string>* differing_prefs) const {
312   prefs_.GetDifferingKeys(&other->prefs_, differing_prefs);
313 }
314 
Apply(ConfigurationPolicyType policy,Value * value)315 void ConfigurationPolicyPrefKeeper::Apply(ConfigurationPolicyType policy,
316                                           Value* value) {
317   if (ApplyProxyPolicy(policy, value))
318     return;
319 
320   if (ApplySyncPolicy(policy, value))
321     return;
322 
323   if (ApplyAutofillPolicy(policy, value))
324     return;
325 
326   if (ApplyDownloadDirPolicy(policy, value))
327     return;
328 
329   if (ApplyPolicyFromMap(policy, value, kDefaultSearchPolicyMap,
330                          arraysize(kDefaultSearchPolicyMap)))
331     return;
332 
333   if (ApplyPolicyFromMap(policy, value, kSimplePolicyMap,
334                          arraysize(kSimplePolicyMap)))
335     return;
336 
337   // Other policy implementations go here.
338   NOTIMPLEMENTED();
339   delete value;
340 }
341 
RemovePreferencesOfMap(const PolicyToPreferenceMapEntry * map,int table_size)342 bool ConfigurationPolicyPrefKeeper::RemovePreferencesOfMap(
343     const PolicyToPreferenceMapEntry* map, int table_size) {
344   bool found_any = false;
345   for (int i = 0; i < table_size; ++i) {
346     if (prefs_.RemoveValue(map[i].preference_path))
347       found_any = true;
348   }
349   return found_any;
350 }
351 
ApplyPolicyFromMap(ConfigurationPolicyType policy,Value * value,const PolicyToPreferenceMapEntry * map,int size)352 bool ConfigurationPolicyPrefKeeper::ApplyPolicyFromMap(
353     ConfigurationPolicyType policy,
354     Value* value,
355     const PolicyToPreferenceMapEntry* map,
356     int size) {
357   for (int current = 0; current < size; ++current) {
358     if (map[current].policy_type == policy) {
359       DCHECK_EQ(map[current].value_type, value->GetType())
360           << "mismatch in provided and expected policy value for preferences"
361           << map[current].preference_path << ". expected = "
362           << map[current].value_type << ", actual = "<< value->GetType();
363       prefs_.SetValue(map[current].preference_path, value);
364       return true;
365     }
366   }
367   return false;
368 }
369 
ApplyProxyPolicy(ConfigurationPolicyType policy,Value * value)370 bool ConfigurationPolicyPrefKeeper::ApplyProxyPolicy(
371     ConfigurationPolicyType policy,
372     Value* value) {
373   // We only collect the values until we have sufficient information when
374   // FinalizeProxyPolicySettings() is called to determine whether the presented
375   // values were correct and apply them in that case.
376   if (policy == kPolicyProxyMode ||
377       policy == kPolicyProxyServerMode ||
378       policy == kPolicyProxyServer ||
379       policy == kPolicyProxyPacUrl ||
380       policy == kPolicyProxyBypassList) {
381     delete proxy_policies_[policy];
382     proxy_policies_[policy] = value;
383     return true;
384   }
385   // We are not interested in this policy.
386   return false;
387 }
388 
ApplySyncPolicy(ConfigurationPolicyType policy,Value * value)389 bool ConfigurationPolicyPrefKeeper::ApplySyncPolicy(
390     ConfigurationPolicyType policy, Value* value) {
391   if (policy == kPolicySyncDisabled) {
392     bool disable_sync;
393     if (value->GetAsBoolean(&disable_sync) && disable_sync)
394       prefs_.SetValue(prefs::kSyncManaged, value);
395     else
396       delete value;
397     return true;
398   }
399   return false;
400 }
401 
ApplyAutofillPolicy(ConfigurationPolicyType policy,Value * value)402 bool ConfigurationPolicyPrefKeeper::ApplyAutofillPolicy(
403     ConfigurationPolicyType policy, Value* value) {
404   if (policy == kPolicyAutoFillEnabled) {
405     bool auto_fill_enabled;
406     if (value->GetAsBoolean(&auto_fill_enabled) && !auto_fill_enabled)
407       prefs_.SetValue(prefs::kAutofillEnabled,
408                        Value::CreateBooleanValue(false));
409     delete value;
410     return true;
411   }
412   return false;
413 }
414 
ApplyDownloadDirPolicy(ConfigurationPolicyType policy,Value * value)415 bool ConfigurationPolicyPrefKeeper::ApplyDownloadDirPolicy(
416     ConfigurationPolicyType policy,
417     Value* value) {
418   // Replace the policy string which might contain some user variables to an
419   // expanded string.
420   if (policy == kPolicyDownloadDirectory) {
421     FilePath::StringType string_value;
422     bool result = value->GetAsString(&string_value);
423     DCHECK(result);
424     FilePath::StringType expanded_value =
425         policy::path_parser::ExpandPathVariables(string_value);
426     prefs_.SetValue(prefs::kDownloadDefaultDirectory,
427                     Value::CreateStringValue(expanded_value));
428     prefs_.SetValue(prefs::kPromptForDownload,
429                     Value::CreateBooleanValue(false));
430     delete value;
431     return true;
432   }
433   // We are not interested in this policy.
434   return false;
435 }
436 
EnsureStringPrefExists(const std::string & path)437 void ConfigurationPolicyPrefKeeper::EnsureStringPrefExists(
438     const std::string& path) {
439   std::string value;
440   if (!prefs_.GetString(path, &value))
441     prefs_.SetString(path, value);
442 }
443 
444 namespace {
445 
446 // Implementation of SearchTermsData just for validation.
447 class SearchTermsDataForValidation : public SearchTermsData {
448  public:
SearchTermsDataForValidation()449   SearchTermsDataForValidation() {}
450 
451   // Implementation of SearchTermsData.
GoogleBaseURLValue() const452   virtual std::string GoogleBaseURLValue() const {
453     return "http://www.google.com/";
454   }
GetApplicationLocale() const455   virtual std::string GetApplicationLocale() const {
456     return "en";
457   }
458 #if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
GetRlzParameterValue() const459   virtual string16 GetRlzParameterValue() const {
460     return string16();
461   }
462 #endif
463  private:
464   DISALLOW_COPY_AND_ASSIGN(SearchTermsDataForValidation);
465 };
466 
467 }  // namespace
468 
FinalizeDefaultSearchPolicySettings()469 void ConfigurationPolicyPrefKeeper::FinalizeDefaultSearchPolicySettings() {
470   bool enabled = true;
471   if (prefs_.GetBoolean(prefs::kDefaultSearchProviderEnabled, &enabled) &&
472       !enabled) {
473     // If default search is disabled, we ignore the other fields.
474     prefs_.SetString(prefs::kDefaultSearchProviderName, std::string());
475     prefs_.SetString(prefs::kDefaultSearchProviderSearchURL, std::string());
476     prefs_.SetString(prefs::kDefaultSearchProviderSuggestURL, std::string());
477     prefs_.SetString(prefs::kDefaultSearchProviderIconURL, std::string());
478     prefs_.SetString(prefs::kDefaultSearchProviderEncodings, std::string());
479     prefs_.SetString(prefs::kDefaultSearchProviderKeyword, std::string());
480     prefs_.SetString(prefs::kDefaultSearchProviderInstantURL, std::string());
481     return;
482   }
483   std::string search_url;
484   // The search URL is required.
485   if (prefs_.GetString(prefs::kDefaultSearchProviderSearchURL, &search_url) &&
486       !search_url.empty()) {
487     SearchTermsDataForValidation search_terms_data;
488     const TemplateURLRef search_url_ref(search_url, 0, 0);
489     // It must support replacement (which implies it is valid).
490     if (search_url_ref.SupportsReplacementUsingTermsData(search_terms_data)) {
491       // The other entries are optional.  Just make sure that they are all
492       // specified via policy, so that we don't use regular prefs.
493       EnsureStringPrefExists(prefs::kDefaultSearchProviderSuggestURL);
494       EnsureStringPrefExists(prefs::kDefaultSearchProviderIconURL);
495       EnsureStringPrefExists(prefs::kDefaultSearchProviderEncodings);
496       EnsureStringPrefExists(prefs::kDefaultSearchProviderKeyword);
497       EnsureStringPrefExists(prefs::kDefaultSearchProviderInstantURL);
498 
499       // For the name, default to the host if not specified.
500       std::string name;
501       if (!prefs_.GetString(prefs::kDefaultSearchProviderName, &name) ||
502           name.empty())
503         prefs_.SetString(prefs::kDefaultSearchProviderName,
504                           GURL(search_url).host());
505 
506       // And clear the IDs since these are not specified via policy.
507       prefs_.SetString(prefs::kDefaultSearchProviderID, std::string());
508       prefs_.SetString(prefs::kDefaultSearchProviderPrepopulateID,
509                         std::string());
510       return;
511     }
512   }
513   // Required entries are not there.  Remove any related entries.
514   RemovePreferencesOfMap(kDefaultSearchPolicyMap,
515                          arraysize(kDefaultSearchPolicyMap));
516 }
517 
FinalizeProxyPolicySettings()518 void ConfigurationPolicyPrefKeeper::FinalizeProxyPolicySettings() {
519   if (CheckProxySettings())
520     ApplyProxySettings();
521 
522   STLDeleteContainerPairSecondPointers(proxy_policies_.begin(),
523                                        proxy_policies_.end());
524   proxy_policies_.clear();
525 }
526 
CheckProxySettings()527 bool ConfigurationPolicyPrefKeeper::CheckProxySettings() {
528   bool mode = HasProxyPolicy(kPolicyProxyMode);
529   bool server_mode = HasProxyPolicy(kPolicyProxyServerMode);  // deprecated
530   bool server = HasProxyPolicy(kPolicyProxyServer);
531   bool pac_url = HasProxyPolicy(kPolicyProxyPacUrl);
532   bool bypass_list = HasProxyPolicy(kPolicyProxyBypassList);
533 
534   if ((server || pac_url || bypass_list) && !(mode || server_mode)) {
535     LOG(WARNING) << "A centrally-administered policy defines proxy setting"
536                  << " details without setting a proxy mode.";
537     return false;
538   }
539 
540   // If there's a server mode, convert it into a mode.
541   std::string mode_value;
542   if (mode) {
543     if (server_mode)
544       LOG(WARNING) << "Both ProxyMode and ProxyServerMode policies defined, "
545                    << "ignoring ProxyMode.";
546     if (!proxy_policies_[kPolicyProxyMode]->GetAsString(&mode_value)) {
547       LOG(WARNING) << "Invalid ProxyMode value.";
548       return false;
549     }
550   } else if (server_mode) {
551     int server_mode_value;
552     if (!proxy_policies_[kPolicyProxyServerMode]->GetAsInteger(
553         &server_mode_value)) {
554       LOG(WARNING) << "Invalid ProxyServerMode value.";
555       return false;
556     }
557 
558     switch (server_mode_value) {
559       case kPolicyNoProxyServerMode:
560         mode_value = ProxyPrefs::kDirectProxyModeName;
561         break;
562       case kPolicyAutoDetectProxyServerMode:
563         mode_value = ProxyPrefs::kAutoDetectProxyModeName;
564         break;
565       case kPolicyManuallyConfiguredProxyServerMode:
566         if (server && pac_url) {
567           LOG(WARNING) << "A centrally-administered policy dictates that"
568                        << " both fixed proxy servers and a .pac url. should"
569                        << " be used for proxy configuration.";
570           return false;
571         }
572         if (!server && !pac_url) {
573           LOG(WARNING) << "A centrally-administered policy dictates that the"
574                        << " proxy settings should use either fixed proxy"
575                        << " servers or a .pac url, but specifies neither.";
576           return false;
577         }
578         if (pac_url)
579           mode_value = ProxyPrefs::kPacScriptProxyModeName;
580         else
581           mode_value = ProxyPrefs::kFixedServersProxyModeName;
582         break;
583       case kPolicyUseSystemProxyServerMode:
584         mode_value = ProxyPrefs::kSystemProxyModeName;
585         break;
586       default:
587         LOG(WARNING) << "Invalid proxy mode " << server_mode_value;
588         return false;
589     }
590   }
591 
592   // If neither ProxyMode nor ProxyServerMode are specified, mode_value will be
593   // empty and the proxy shouldn't be configured at all.
594   if (mode_value.empty())
595     return true;
596 
597   if (mode_value == ProxyPrefs::kDirectProxyModeName) {
598     if (server || pac_url || bypass_list) {
599       LOG(WARNING) << "A centrally-administered policy disables the use of"
600                    << " a proxy but also specifies an explicit proxy"
601                    << " configuration.";
602       return false;
603     }
604   } else if (mode_value == ProxyPrefs::kAutoDetectProxyModeName) {
605     if (server || bypass_list || pac_url) {
606       LOG(WARNING) << "A centrally-administered policy dictates that a proxy"
607                    << " shall be auto configured but specifies fixed proxy"
608                    << " servers, a by-pass list or a .pac script URL.";
609       return false;
610     }
611   } else if (mode_value == ProxyPrefs::kPacScriptProxyModeName) {
612     if (server || bypass_list) {
613       LOG(WARNING) << "A centrally-administered policy dictates that a .pac"
614                    << " script URL should be used for proxy configuration but"
615                    << " also specifies policies required only for fixed"
616                    << " proxy servers.";
617       return false;
618     }
619   } else if (mode_value == ProxyPrefs::kFixedServersProxyModeName) {
620     if (pac_url) {
621       LOG(WARNING) << "A centrally-administered policy dictates that"
622                    << " fixed proxy servers should be used but also"
623                    << " specifies a .pac script URL.";
624       return false;
625     }
626   } else if (mode_value == ProxyPrefs::kSystemProxyModeName) {
627     if (server || pac_url || bypass_list) {
628       LOG(WARNING) << "A centrally-administered policy dictates that the"
629                    << " system proxy settings should be used but also "
630                    << " specifies an explicit proxy configuration.";
631       return false;
632     }
633   } else {
634     LOG(WARNING) << "Invalid proxy mode " << mode_value;
635     return false;
636   }
637   return true;
638 }
639 
ApplyProxySettings()640 void ConfigurationPolicyPrefKeeper::ApplyProxySettings() {
641   ProxyPrefs::ProxyMode mode;
642   if (HasProxyPolicy(kPolicyProxyMode)) {
643     std::string string_mode;
644     CHECK(proxy_policies_[kPolicyProxyMode]->GetAsString(&string_mode));
645     if (!ProxyPrefs::StringToProxyMode(string_mode, &mode)) {
646       LOG(WARNING) << "A centrally-administered policy specifies a value for"
647                    << "the ProxyMode policy that isn't recognized.";
648       return;
649     }
650   } else if (HasProxyPolicy(kPolicyProxyServerMode)) {
651     int int_mode = 0;
652     CHECK(proxy_policies_[kPolicyProxyServerMode]->GetAsInteger(&int_mode));
653     switch (int_mode) {
654       case kPolicyNoProxyServerMode:
655         mode = ProxyPrefs::MODE_DIRECT;
656         break;
657       case kPolicyAutoDetectProxyServerMode:
658         mode = ProxyPrefs::MODE_AUTO_DETECT;
659         break;
660       case kPolicyManuallyConfiguredProxyServerMode:
661         mode = ProxyPrefs::MODE_FIXED_SERVERS;
662         if (HasProxyPolicy(kPolicyProxyPacUrl))
663           mode = ProxyPrefs::MODE_PAC_SCRIPT;
664         break;
665       case kPolicyUseSystemProxyServerMode:
666         mode = ProxyPrefs::MODE_SYSTEM;
667         break;
668       default:
669         mode = ProxyPrefs::MODE_DIRECT;
670         NOTREACHED();
671     }
672   } else {
673     return;
674   }
675   switch (mode) {
676     case ProxyPrefs::MODE_DIRECT:
677       prefs_.SetValue(prefs::kProxy, ProxyConfigDictionary::CreateDirect());
678       break;
679     case ProxyPrefs::MODE_AUTO_DETECT:
680       prefs_.SetValue(prefs::kProxy, ProxyConfigDictionary::CreateAutoDetect());
681       break;
682     case ProxyPrefs::MODE_PAC_SCRIPT: {
683       if (!HasProxyPolicy(kPolicyProxyPacUrl)) {
684         LOG(WARNING) << "A centrally-administered policy specifies to use a "
685                      << "PAC script, but doesn't supply the PAC script URL.";
686         return;
687       }
688       std::string pac_url;
689       proxy_policies_[kPolicyProxyPacUrl]->GetAsString(&pac_url);
690       prefs_.SetValue(prefs::kProxy,
691                       ProxyConfigDictionary::CreatePacScript(pac_url));
692       break;
693     }
694     case ProxyPrefs::MODE_FIXED_SERVERS: {
695       if (!HasProxyPolicy(kPolicyProxyServer)) {
696         LOG(WARNING) << "A centrally-administered policy specifies to use a "
697                      << "fixed server, but doesn't supply the server address.";
698         return;
699       }
700       std::string proxy_server;
701       proxy_policies_[kPolicyProxyServer]->GetAsString(&proxy_server);
702       std::string bypass_list;
703       if (HasProxyPolicy(kPolicyProxyBypassList))
704         proxy_policies_[kPolicyProxyBypassList]->GetAsString(&bypass_list);
705       prefs_.SetValue(prefs::kProxy,
706                       ProxyConfigDictionary::CreateFixedServers(proxy_server,
707                                                                 bypass_list));
708       break;
709     }
710     case ProxyPrefs::MODE_SYSTEM:
711       prefs_.SetValue(prefs::kProxy,
712                       ProxyConfigDictionary::CreateSystem());
713       break;
714     case ProxyPrefs::kModeCount:
715       NOTREACHED();
716   }
717 }
718 
HasProxyPolicy(ConfigurationPolicyType policy) const719 bool ConfigurationPolicyPrefKeeper::HasProxyPolicy(
720     ConfigurationPolicyType policy) const {
721   std::map<ConfigurationPolicyType, Value*>::const_iterator iter;
722   iter = proxy_policies_.find(policy);
723   std::string tmp;
724   if (iter == proxy_policies_.end() ||
725       !iter->second ||
726       iter->second->IsType(Value::TYPE_NULL) ||
727       (iter->second->IsType(Value::TYPE_STRING) &&
728        iter->second->GetAsString(&tmp) &&
729        tmp.empty())) {
730     return false;
731   }
732   return true;
733 }
734 
ConfigurationPolicyPrefStore(ConfigurationPolicyProvider * provider)735 ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore(
736     ConfigurationPolicyProvider* provider)
737     : provider_(provider),
738       initialization_complete_(false) {
739   if (provider_) {
740     // Read initial policy.
741     policy_keeper_.reset(new ConfigurationPolicyPrefKeeper(provider));
742     registrar_.Init(provider_, this);
743     initialization_complete_ = provider->IsInitializationComplete();
744   } else {
745     initialization_complete_ = true;
746   }
747 }
748 
~ConfigurationPolicyPrefStore()749 ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() {
750 }
751 
AddObserver(PrefStore::Observer * observer)752 void ConfigurationPolicyPrefStore::AddObserver(PrefStore::Observer* observer) {
753   observers_.AddObserver(observer);
754 }
755 
RemoveObserver(PrefStore::Observer * observer)756 void ConfigurationPolicyPrefStore::RemoveObserver(
757     PrefStore::Observer* observer) {
758   observers_.RemoveObserver(observer);
759 }
760 
IsInitializationComplete() const761 bool ConfigurationPolicyPrefStore::IsInitializationComplete() const {
762   return initialization_complete_;
763 }
764 
765 PrefStore::ReadResult
GetValue(const std::string & key,const Value ** value) const766 ConfigurationPolicyPrefStore::GetValue(const std::string& key,
767                                        const Value** value) const {
768   if (policy_keeper_.get())
769     return policy_keeper_->GetValue(key, value);
770 
771   return PrefStore::READ_NO_VALUE;
772 }
773 
OnUpdatePolicy()774 void ConfigurationPolicyPrefStore::OnUpdatePolicy() {
775   Refresh();
776 }
777 
OnProviderGoingAway()778 void ConfigurationPolicyPrefStore::OnProviderGoingAway() {
779   provider_ = NULL;
780 }
781 
782 // static
783 ConfigurationPolicyPrefStore*
CreateManagedPlatformPolicyPrefStore()784 ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore() {
785   BrowserPolicyConnector* connector =
786       g_browser_process->browser_policy_connector();
787   return new ConfigurationPolicyPrefStore(
788       connector->GetManagedPlatformProvider());
789 }
790 
791 // static
792 ConfigurationPolicyPrefStore*
CreateManagedCloudPolicyPrefStore(Profile * profile)793 ConfigurationPolicyPrefStore::CreateManagedCloudPolicyPrefStore(
794     Profile* profile) {
795   ConfigurationPolicyProvider* provider = NULL;
796   if (profile) {
797     // For user policy, return the profile's policy provider.
798     provider = profile->GetPolicyConnector()->GetManagedCloudProvider();
799   } else {
800     // For device policy, return the provider of the browser process.
801     BrowserPolicyConnector* connector =
802         g_browser_process->browser_policy_connector();
803     provider = connector->GetManagedCloudProvider();
804   }
805   return new ConfigurationPolicyPrefStore(provider);
806 }
807 
808 // static
809 ConfigurationPolicyPrefStore*
CreateRecommendedPlatformPolicyPrefStore()810 ConfigurationPolicyPrefStore::CreateRecommendedPlatformPolicyPrefStore() {
811   BrowserPolicyConnector* connector =
812       g_browser_process->browser_policy_connector();
813   return new ConfigurationPolicyPrefStore(
814       connector->GetRecommendedPlatformProvider());
815 }
816 
817 // static
818 ConfigurationPolicyPrefStore*
CreateRecommendedCloudPolicyPrefStore(Profile * profile)819 ConfigurationPolicyPrefStore::CreateRecommendedCloudPolicyPrefStore(
820     Profile* profile) {
821   ConfigurationPolicyProvider* provider = NULL;
822   if (profile) {
823     // For user policy, return the profile's policy provider.
824     provider = profile->GetPolicyConnector()->GetRecommendedCloudProvider();
825   } else {
826     // For device policy, return the provider of the browser process.
827     BrowserPolicyConnector* connector =
828         g_browser_process->browser_policy_connector();
829     provider = connector->GetRecommendedCloudProvider();
830   }
831   return new ConfigurationPolicyPrefStore(provider);
832 }
833 
834 /* static */
835 const ConfigurationPolicyProvider::PolicyDefinitionList*
GetChromePolicyDefinitionList()836 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList() {
837   static ConfigurationPolicyProvider::PolicyDefinitionList::Entry entries[] = {
838     { kPolicyHomepageLocation, Value::TYPE_STRING, key::kHomepageLocation },
839     { kPolicyHomepageIsNewTabPage, Value::TYPE_BOOLEAN,
840       key::kHomepageIsNewTabPage },
841     { kPolicyRestoreOnStartup, Value::TYPE_INTEGER, key::kRestoreOnStartup },
842     { kPolicyRestoreOnStartupURLs, Value::TYPE_LIST,
843       key::kRestoreOnStartupURLs },
844     { kPolicyDefaultSearchProviderEnabled, Value::TYPE_BOOLEAN,
845       key::kDefaultSearchProviderEnabled },
846     { kPolicyDefaultSearchProviderName, Value::TYPE_STRING,
847       key::kDefaultSearchProviderName },
848     { kPolicyDefaultSearchProviderKeyword, Value::TYPE_STRING,
849       key::kDefaultSearchProviderKeyword },
850     { kPolicyDefaultSearchProviderSearchURL, Value::TYPE_STRING,
851       key::kDefaultSearchProviderSearchURL },
852     { kPolicyDefaultSearchProviderSuggestURL, Value::TYPE_STRING,
853       key::kDefaultSearchProviderSuggestURL },
854     { kPolicyDefaultSearchProviderInstantURL, Value::TYPE_STRING,
855       key::kDefaultSearchProviderInstantURL },
856     { kPolicyDefaultSearchProviderIconURL, Value::TYPE_STRING,
857       key::kDefaultSearchProviderIconURL },
858     { kPolicyDefaultSearchProviderEncodings, Value::TYPE_STRING,
859       key::kDefaultSearchProviderEncodings },
860     { kPolicyProxyMode, Value::TYPE_STRING, key::kProxyMode },
861     { kPolicyProxyServerMode, Value::TYPE_INTEGER, key::kProxyServerMode },
862     { kPolicyProxyServer, Value::TYPE_STRING, key::kProxyServer },
863     { kPolicyProxyPacUrl, Value::TYPE_STRING, key::kProxyPacUrl },
864     { kPolicyProxyBypassList, Value::TYPE_STRING, key::kProxyBypassList },
865     { kPolicyAlternateErrorPagesEnabled, Value::TYPE_BOOLEAN,
866       key::kAlternateErrorPagesEnabled },
867     { kPolicySearchSuggestEnabled, Value::TYPE_BOOLEAN,
868       key::kSearchSuggestEnabled },
869     { kPolicyDnsPrefetchingEnabled, Value::TYPE_BOOLEAN,
870       key::kDnsPrefetchingEnabled },
871     { kPolicyDisableSpdy, Value::TYPE_BOOLEAN, key::kDisableSpdy },
872     { kPolicyDisabledSchemes, Value::TYPE_LIST, key::kDisabledSchemes },
873     { kPolicySafeBrowsingEnabled, Value::TYPE_BOOLEAN,
874       key::kSafeBrowsingEnabled },
875     { kPolicyMetricsReportingEnabled, Value::TYPE_BOOLEAN,
876       key::kMetricsReportingEnabled },
877     { kPolicyPasswordManagerEnabled, Value::TYPE_BOOLEAN,
878       key::kPasswordManagerEnabled },
879     { kPolicyPasswordManagerAllowShowPasswords, Value::TYPE_BOOLEAN,
880       key::kPasswordManagerAllowShowPasswords },
881     { kPolicyAutoFillEnabled, Value::TYPE_BOOLEAN, key::kAutoFillEnabled },
882     { kPolicyDisabledPlugins, Value::TYPE_LIST, key::kDisabledPlugins },
883     { kPolicyDisabledPluginsExceptions, Value::TYPE_LIST,
884       key::kDisabledPluginsExceptions },
885     { kPolicyEnabledPlugins, Value::TYPE_LIST, key::kEnabledPlugins },
886     { kPolicyApplicationLocaleValue, Value::TYPE_STRING,
887       key::kApplicationLocaleValue },
888     { kPolicySyncDisabled, Value::TYPE_BOOLEAN, key::kSyncDisabled },
889     { kPolicyExtensionInstallWhitelist, Value::TYPE_LIST,
890       key::kExtensionInstallWhitelist },
891     { kPolicyExtensionInstallBlacklist, Value::TYPE_LIST,
892       key::kExtensionInstallBlacklist },
893     { kPolicyExtensionInstallForcelist, Value::TYPE_LIST,
894       key::kExtensionInstallForcelist },
895     { kPolicyShowHomeButton, Value::TYPE_BOOLEAN, key::kShowHomeButton },
896     { kPolicyPrintingEnabled, Value::TYPE_BOOLEAN, key::kPrintingEnabled },
897     { kPolicyJavascriptEnabled, Value::TYPE_BOOLEAN, key::kJavascriptEnabled },
898     { kPolicyIncognitoEnabled, Value::TYPE_BOOLEAN, key::kIncognitoEnabled },
899     { kPolicySavingBrowserHistoryDisabled, Value::TYPE_BOOLEAN,
900       key::kSavingBrowserHistoryDisabled },
901     { kPolicyClearSiteDataOnExit, Value::TYPE_BOOLEAN,
902       key::kClearSiteDataOnExit },
903     { kPolicyDeveloperToolsDisabled, Value::TYPE_BOOLEAN,
904       key::kDeveloperToolsDisabled },
905     { kPolicyBlockThirdPartyCookies, Value::TYPE_BOOLEAN,
906       key::kBlockThirdPartyCookies },
907     { kPolicyDefaultCookiesSetting, Value::TYPE_INTEGER,
908       key::kDefaultCookiesSetting },
909     { kPolicyDefaultImagesSetting, Value::TYPE_INTEGER,
910       key::kDefaultImagesSetting },
911     { kPolicyDefaultJavaScriptSetting, Value::TYPE_INTEGER,
912       key::kDefaultJavaScriptSetting },
913     { kPolicyDefaultPluginsSetting, Value::TYPE_INTEGER,
914       key::kDefaultPluginsSetting },
915     { kPolicyDefaultPopupsSetting, Value::TYPE_INTEGER,
916       key::kDefaultPopupsSetting },
917     { kPolicyDefaultNotificationSetting, Value::TYPE_INTEGER,
918       key::kDefaultNotificationSetting },
919     { kPolicyDefaultGeolocationSetting, Value::TYPE_INTEGER,
920       key::kDefaultGeolocationSetting },
921     { kPolicyCookiesAllowedForUrls, Value::TYPE_LIST,
922       key::kCookiesAllowedForUrls },
923     { kPolicyCookiesBlockedForUrls, Value::TYPE_LIST,
924       key::kCookiesBlockedForUrls },
925     { kPolicyCookiesSessionOnlyForUrls, Value::TYPE_LIST,
926       key::kCookiesSessionOnlyForUrls },
927     { kPolicyImagesAllowedForUrls, Value::TYPE_LIST,
928       key::kImagesAllowedForUrls },
929     { kPolicyImagesBlockedForUrls, Value::TYPE_LIST,
930       key::kImagesBlockedForUrls },
931     { kPolicyJavaScriptAllowedForUrls, Value::TYPE_LIST,
932       key::kJavaScriptAllowedForUrls },
933     { kPolicyJavaScriptBlockedForUrls, Value::TYPE_LIST,
934       key::kJavaScriptBlockedForUrls },
935     { kPolicyPluginsAllowedForUrls, Value::TYPE_LIST,
936       key::kPluginsAllowedForUrls },
937     { kPolicyPluginsBlockedForUrls, Value::TYPE_LIST,
938       key::kPluginsBlockedForUrls },
939     { kPolicyPopupsAllowedForUrls, Value::TYPE_LIST,
940       key::kPopupsAllowedForUrls },
941     { kPolicyPopupsBlockedForUrls, Value::TYPE_LIST,
942       key::kPopupsBlockedForUrls },
943     { kPolicyAuthSchemes, Value::TYPE_STRING, key::kAuthSchemes },
944     { kPolicyDisableAuthNegotiateCnameLookup, Value::TYPE_BOOLEAN,
945       key::kDisableAuthNegotiateCnameLookup },
946     { kPolicyEnableAuthNegotiatePort, Value::TYPE_BOOLEAN,
947       key::kEnableAuthNegotiatePort },
948     { kPolicyAuthServerWhitelist, Value::TYPE_STRING,
949       key::kAuthServerWhitelist },
950     { kPolicyAuthNegotiateDelegateWhitelist, Value::TYPE_STRING,
951       key::kAuthNegotiateDelegateWhitelist },
952     { kPolicyGSSAPILibraryName, Value::TYPE_STRING,
953       key::kGSSAPILibraryName },
954     { kPolicyDisable3DAPIs, Value::TYPE_BOOLEAN,
955       key::kDisable3DAPIs },
956     { kPolicyDisablePluginFinder, Value::TYPE_BOOLEAN,
957       key::kDisablePluginFinder },
958     { kPolicyPolicyRefreshRate, Value::TYPE_INTEGER,
959       key::kPolicyRefreshRate },
960     { kPolicyInstantEnabled, Value::TYPE_BOOLEAN, key::kInstantEnabled },
961     { kPolicyDefaultBrowserSettingEnabled, Value::TYPE_BOOLEAN,
962       key::kDefaultBrowserSettingEnabled },
963     { kPolicyCloudPrintProxyEnabled, Value::TYPE_BOOLEAN,
964       key::kCloudPrintProxyEnabled },
965     { kPolicyDownloadDirectory, Value::TYPE_STRING,
966       key::kDownloadDirectory },
967     { kPolicyTranslateEnabled, Value::TYPE_BOOLEAN, key::kTranslateEnabled },
968     { kPolicyAllowOutdatedPlugins, Value::TYPE_BOOLEAN,
969       key::kAllowOutdatedPlugins },
970     { kPolicyBookmarkBarEnabled, Value::TYPE_BOOLEAN,
971       key::kBookmarkBarEnabled },
972     { kPolicyEditBookmarksEnabled, Value::TYPE_BOOLEAN,
973       key::kEditBookmarksEnabled },
974     { kPolicyAllowFileSelectionDialogs, Value::TYPE_BOOLEAN,
975       key::kAllowFileSelectionDialogs },
976 
977 #if defined(OS_CHROMEOS)
978     { kPolicyChromeOsLockOnIdleSuspend, Value::TYPE_BOOLEAN,
979       key::kChromeOsLockOnIdleSuspend },
980 #endif
981   };
982 
983   static ConfigurationPolicyProvider::PolicyDefinitionList policy_list = {
984     entries,
985     entries + arraysize(entries),
986   };
987   return &policy_list;
988 }
989 
Refresh()990 void ConfigurationPolicyPrefStore::Refresh() {
991   if (!provider_)
992     return;
993 
994   // Construct a new keeper, determine what changed and swap the keeper in.
995   scoped_ptr<ConfigurationPolicyPrefKeeper> new_keeper(
996       new ConfigurationPolicyPrefKeeper(provider_));
997   std::vector<std::string> changed_prefs;
998   new_keeper->GetDifferingPrefPaths(policy_keeper_.get(), &changed_prefs);
999   policy_keeper_.reset(new_keeper.release());
1000 
1001   // Send out change notifications.
1002   for (std::vector<std::string>::const_iterator pref(changed_prefs.begin());
1003        pref != changed_prefs.end();
1004        ++pref) {
1005     FOR_EACH_OBSERVER(PrefStore::Observer, observers_,
1006                       OnPrefValueChanged(*pref));
1007   }
1008 
1009   // Update the initialization flag.
1010   if (!initialization_complete_ &&
1011       provider_->IsInitializationComplete()) {
1012     initialization_complete_ = true;
1013     FOR_EACH_OBSERVER(PrefStore::Observer, observers_,
1014                       OnInitializationCompleted());
1015   }
1016 }
1017 
1018 }  // namespace policy
1019