configuration_policy_pref_store.cc revision 4a5e2dc747d50c653511c68ccb2cfbfb740bd5a7
1// Copyright (c) 2010 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 "base/command_line.h"
8#include "base/logging.h"
9#include "base/path_service.h"
10#include "base/singleton.h"
11#include "base/string16.h"
12#include "base/string_util.h"
13#include "base/utf_string_conversions.h"
14#include "base/values.h"
15#include "chrome/browser/policy/configuration_policy_provider.h"
16#if defined(OS_WIN)
17#include "chrome/browser/policy/configuration_policy_provider_win.h"
18#elif defined(OS_MACOSX)
19#include "chrome/browser/policy/configuration_policy_provider_mac.h"
20#elif defined(OS_POSIX)
21#include "chrome/browser/policy/config_dir_policy_provider.h"
22#endif
23#include "chrome/browser/policy/device_management_policy_provider.h"
24#include "chrome/browser/policy/dummy_configuration_policy_provider.h"
25#include "chrome/browser/search_engines/search_terms_data.h"
26#include "chrome/browser/search_engines/template_url.h"
27#include "chrome/common/chrome_paths.h"
28#include "chrome/common/chrome_switches.h"
29#include "chrome/common/policy_constants.h"
30#include "chrome/common/pref_names.h"
31
32namespace policy {
33
34// Manages the lifecycle of the shared platform-specific policy providers for
35// managed platform, device management and recommended policy. Instantiated as a
36// Singleton.
37class ConfigurationPolicyProviderKeeper {
38 public:
39  ConfigurationPolicyProviderKeeper()
40      : managed_platform_provider_(CreateManagedPlatformProvider()),
41        device_management_provider_(CreateDeviceManagementProvider()),
42        recommended_provider_(CreateRecommendedProvider()) {}
43  virtual ~ConfigurationPolicyProviderKeeper() {}
44
45  ConfigurationPolicyProvider* managed_platform_provider() const {
46    return managed_platform_provider_.get();
47  }
48
49  ConfigurationPolicyProvider* device_management_provider() const {
50    return device_management_provider_.get();
51  }
52
53ConfigurationPolicyProvider* recommended_provider() const {
54    return recommended_provider_.get();
55  }
56
57 private:
58  scoped_ptr<ConfigurationPolicyProvider> managed_platform_provider_;
59  scoped_ptr<ConfigurationPolicyProvider> device_management_provider_;
60  scoped_ptr<ConfigurationPolicyProvider> recommended_provider_;
61
62  static ConfigurationPolicyProvider* CreateManagedPlatformProvider();
63  static ConfigurationPolicyProvider* CreateDeviceManagementProvider();
64  static ConfigurationPolicyProvider* CreateRecommendedProvider();
65
66  DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyProviderKeeper);
67};
68
69
70ConfigurationPolicyProvider*
71    ConfigurationPolicyProviderKeeper::CreateDeviceManagementProvider() {
72  const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list =
73      ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList();
74  if (CommandLine::ForCurrentProcess()->HasSwitch(
75          switches::kDeviceManagementUrl)) {
76    return new DeviceManagementPolicyProvider(policy_list);
77  } else {
78    return new DummyConfigurationPolicyProvider(policy_list);
79  }
80}
81
82ConfigurationPolicyProvider*
83    ConfigurationPolicyProviderKeeper::CreateManagedPlatformProvider() {
84  const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list =
85      ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList();
86#if defined(OS_WIN)
87  return new ConfigurationPolicyProviderWin(policy_list);
88#elif defined(OS_MACOSX)
89  return new ConfigurationPolicyProviderMac(policy_list);
90#elif defined(OS_POSIX)
91  FilePath config_dir_path;
92  if (PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) {
93    return new ConfigDirPolicyProvider(
94        policy_list,
95        config_dir_path.Append(FILE_PATH_LITERAL("managed")));
96  } else {
97    return new DummyConfigurationPolicyProvider(policy_list);
98  }
99#else
100  return new DummyConfigurationPolicyProvider(policy_list);
101#endif
102}
103
104ConfigurationPolicyProvider*
105    ConfigurationPolicyProviderKeeper::CreateRecommendedProvider() {
106  const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list =
107      ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList();
108#if defined(OS_POSIX) && !defined(OS_MACOSX)
109  FilePath config_dir_path;
110  if (PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) {
111    return new ConfigDirPolicyProvider(
112        policy_list,
113        config_dir_path.Append(FILE_PATH_LITERAL("recommended")));
114  } else {
115    return new DummyConfigurationPolicyProvider(policy_list);
116  }
117#else
118  return new DummyConfigurationPolicyProvider(policy_list);
119#endif
120}
121
122const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry
123    ConfigurationPolicyPrefStore::kSimplePolicyMap[] = {
124  { Value::TYPE_STRING, kPolicyHomePage,  prefs::kHomePage },
125  { Value::TYPE_BOOLEAN, kPolicyHomepageIsNewTabPage,
126    prefs::kHomePageIsNewTabPage },
127  { Value::TYPE_INTEGER, kPolicyRestoreOnStartup,
128    prefs::kRestoreOnStartup},
129  { Value::TYPE_LIST, kPolicyURLsToRestoreOnStartup,
130    prefs::kURLsToRestoreOnStartup },
131  { Value::TYPE_BOOLEAN, kPolicyAlternateErrorPagesEnabled,
132    prefs::kAlternateErrorPagesEnabled },
133  { Value::TYPE_BOOLEAN, kPolicySearchSuggestEnabled,
134    prefs::kSearchSuggestEnabled },
135  { Value::TYPE_BOOLEAN, kPolicyDnsPrefetchingEnabled,
136    prefs::kDnsPrefetchingEnabled },
137  { Value::TYPE_BOOLEAN, kPolicyDisableSpdy,
138    prefs::kDisableSpdy },
139  { Value::TYPE_BOOLEAN, kPolicySafeBrowsingEnabled,
140    prefs::kSafeBrowsingEnabled },
141  { Value::TYPE_BOOLEAN, kPolicyPasswordManagerEnabled,
142    prefs::kPasswordManagerEnabled },
143  { Value::TYPE_BOOLEAN, kPolicyPasswordManagerAllowShowPasswords,
144    prefs::kPasswordManagerAllowShowPasswords },
145  { Value::TYPE_BOOLEAN, kPolicyPrintingEnabled,
146    prefs::kPrintingEnabled },
147  { Value::TYPE_BOOLEAN, kPolicyMetricsReportingEnabled,
148    prefs::kMetricsReportingEnabled },
149  { Value::TYPE_STRING, kPolicyApplicationLocale,
150    prefs::kApplicationLocale},
151  { Value::TYPE_LIST, kPolicyExtensionInstallAllowList,
152    prefs::kExtensionInstallAllowList},
153  { Value::TYPE_LIST, kPolicyExtensionInstallDenyList,
154    prefs::kExtensionInstallDenyList},
155  { Value::TYPE_LIST, kPolicyExtensionInstallForceList,
156    prefs::kExtensionInstallForceList},
157  { Value::TYPE_LIST, kPolicyDisabledPlugins,
158    prefs::kPluginsPluginsBlacklist},
159  { Value::TYPE_BOOLEAN, kPolicyShowHomeButton,
160    prefs::kShowHomeButton },
161  { Value::TYPE_BOOLEAN, kPolicyJavascriptEnabled,
162    prefs::kWebKitJavascriptEnabled },
163  { Value::TYPE_BOOLEAN, kPolicySavingBrowserHistoryDisabled,
164    prefs::kSavingBrowserHistoryDisabled },
165  { Value::TYPE_BOOLEAN, kPolicyDeveloperToolsDisabled,
166    prefs::kDevToolsDisabled },
167  { Value::TYPE_BOOLEAN, kPolicyBlockThirdPartyCookies,
168    prefs::kBlockThirdPartyCookies},
169  { Value::TYPE_INTEGER, kPolicyDefaultCookiesSetting,
170    prefs::kManagedDefaultCookiesSetting},
171  { Value::TYPE_INTEGER, kPolicyDefaultImagesSetting,
172    prefs::kManagedDefaultImagesSetting},
173  { Value::TYPE_INTEGER, kPolicyDefaultJavaScriptSetting,
174    prefs::kManagedDefaultJavaScriptSetting},
175  { Value::TYPE_INTEGER, kPolicyDefaultPluginsSetting,
176    prefs::kManagedDefaultPluginsSetting},
177  { Value::TYPE_INTEGER, kPolicyDefaultPopupsSetting,
178    prefs::kManagedDefaultPopupsSetting},
179  { Value::TYPE_STRING, kPolicyAuthSchemes,
180    prefs::kAuthSchemes },
181  { Value::TYPE_BOOLEAN, kPolicyDisableAuthNegotiateCnameLookup,
182    prefs::kDisableAuthNegotiateCnameLookup },
183  { Value::TYPE_BOOLEAN, kPolicyEnableAuthNegotiatePort,
184    prefs::kEnableAuthNegotiatePort },
185  { Value::TYPE_STRING, kPolicyAuthServerWhitelist,
186    prefs::kAuthServerWhitelist },
187  { Value::TYPE_STRING, kPolicyAuthNegotiateDelegateWhitelist,
188    prefs::kAuthNegotiateDelegateWhitelist },
189  { Value::TYPE_STRING, kPolicyGSSAPILibraryName,
190    prefs::kGSSAPILibraryName },
191
192#if defined(OS_CHROMEOS)
193  { Value::TYPE_BOOLEAN, kPolicyChromeOsLockOnIdleSuspend,
194    prefs::kEnableScreenLock },
195#endif
196};
197
198const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry
199    ConfigurationPolicyPrefStore::kDefaultSearchPolicyMap[] = {
200  { Value::TYPE_BOOLEAN, kPolicyDefaultSearchProviderEnabled,
201    prefs::kDefaultSearchProviderEnabled },
202  { Value::TYPE_STRING, kPolicyDefaultSearchProviderName,
203    prefs::kDefaultSearchProviderName },
204  { Value::TYPE_STRING, kPolicyDefaultSearchProviderKeyword,
205    prefs::kDefaultSearchProviderKeyword },
206  { Value::TYPE_STRING, kPolicyDefaultSearchProviderSearchURL,
207    prefs::kDefaultSearchProviderSearchURL },
208  { Value::TYPE_STRING, kPolicyDefaultSearchProviderSuggestURL,
209    prefs::kDefaultSearchProviderSuggestURL },
210  { Value::TYPE_STRING, kPolicyDefaultSearchProviderIconURL,
211    prefs::kDefaultSearchProviderIconURL },
212  { Value::TYPE_STRING, kPolicyDefaultSearchProviderEncodings,
213    prefs::kDefaultSearchProviderEncodings },
214};
215
216const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry
217    ConfigurationPolicyPrefStore::kProxyPolicyMap[] = {
218  { Value::TYPE_STRING, kPolicyProxyServer, prefs::kProxyServer },
219  { Value::TYPE_STRING, kPolicyProxyPacUrl, prefs::kProxyPacUrl },
220  { Value::TYPE_STRING, kPolicyProxyBypassList, prefs::kProxyBypassList }
221};
222
223/* static */
224const ConfigurationPolicyProvider::PolicyDefinitionList*
225ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList() {
226  static ConfigurationPolicyProvider::PolicyDefinitionList::Entry entries[] = {
227    { kPolicyHomePage, Value::TYPE_STRING, key::kHomepageLocation },
228    { kPolicyHomepageIsNewTabPage, Value::TYPE_BOOLEAN,
229      key::kHomepageIsNewTabPage },
230    { kPolicyRestoreOnStartup, Value::TYPE_INTEGER, key::kRestoreOnStartup },
231    { kPolicyURLsToRestoreOnStartup, Value::TYPE_LIST,
232      key::kURLsToRestoreOnStartup },
233    { kPolicyDefaultSearchProviderEnabled, Value::TYPE_BOOLEAN,
234      key::kDefaultSearchProviderEnabled },
235    { kPolicyDefaultSearchProviderName, Value::TYPE_STRING,
236      key::kDefaultSearchProviderName },
237    { kPolicyDefaultSearchProviderKeyword, Value::TYPE_STRING,
238      key::kDefaultSearchProviderKeyword },
239    { kPolicyDefaultSearchProviderSearchURL, Value::TYPE_STRING,
240      key::kDefaultSearchProviderSearchURL },
241    { kPolicyDefaultSearchProviderSuggestURL, Value::TYPE_STRING,
242      key::kDefaultSearchProviderSuggestURL },
243    { kPolicyDefaultSearchProviderIconURL, Value::TYPE_STRING,
244      key::kDefaultSearchProviderIconURL },
245    { kPolicyDefaultSearchProviderEncodings, Value::TYPE_STRING,
246      key::kDefaultSearchProviderEncodings },
247    { kPolicyProxyServerMode, Value::TYPE_INTEGER, key::kProxyServerMode },
248    { kPolicyProxyServer, Value::TYPE_STRING, key::kProxyServer },
249    { kPolicyProxyPacUrl, Value::TYPE_STRING, key::kProxyPacUrl },
250    { kPolicyProxyBypassList, Value::TYPE_STRING, key::kProxyBypassList },
251    { kPolicyAlternateErrorPagesEnabled, Value::TYPE_BOOLEAN,
252      key::kAlternateErrorPagesEnabled },
253    { kPolicySearchSuggestEnabled, Value::TYPE_BOOLEAN,
254      key::kSearchSuggestEnabled },
255    { kPolicyDnsPrefetchingEnabled, Value::TYPE_BOOLEAN,
256      key::kDnsPrefetchingEnabled },
257    { kPolicyDisableSpdy, Value::TYPE_BOOLEAN, key::kDisableSpdy },
258    { kPolicySafeBrowsingEnabled, Value::TYPE_BOOLEAN,
259      key::kSafeBrowsingEnabled },
260    { kPolicyMetricsReportingEnabled, Value::TYPE_BOOLEAN,
261      key::kMetricsReportingEnabled },
262    { kPolicyPasswordManagerEnabled, Value::TYPE_BOOLEAN,
263      key::kPasswordManagerEnabled },
264    { kPolicyPasswordManagerAllowShowPasswords, Value::TYPE_BOOLEAN,
265      key::kPasswordManagerAllowShowPasswords },
266    { kPolicyAutoFillEnabled, Value::TYPE_BOOLEAN, key::kAutoFillEnabled },
267    { kPolicyDisabledPlugins, Value::TYPE_LIST, key::kDisabledPlugins },
268    { kPolicyApplicationLocale, Value::TYPE_STRING,
269      key::kApplicationLocaleValue },
270    { kPolicySyncDisabled, Value::TYPE_BOOLEAN, key::kSyncDisabled },
271    { kPolicyExtensionInstallAllowList, Value::TYPE_LIST,
272      key::kExtensionInstallAllowList },
273    { kPolicyExtensionInstallDenyList, Value::TYPE_LIST,
274      key::kExtensionInstallDenyList },
275    { kPolicyExtensionInstallForceList, Value::TYPE_LIST,
276      key::kExtensionInstallForceList },
277    { kPolicyShowHomeButton, Value::TYPE_BOOLEAN, key::kShowHomeButton },
278    { kPolicyPrintingEnabled, Value::TYPE_BOOLEAN, key::kPrintingEnabled },
279    { kPolicyJavascriptEnabled, Value::TYPE_BOOLEAN, key::kJavascriptEnabled },
280    { kPolicySavingBrowserHistoryDisabled, Value::TYPE_BOOLEAN,
281      key::kSavingBrowserHistoryDisabled },
282    { kPolicyDeveloperToolsDisabled, Value::TYPE_BOOLEAN,
283      key::kDeveloperToolsDisabled },
284    { kPolicyBlockThirdPartyCookies, Value::TYPE_BOOLEAN,
285      key::kBlockThirdPartyCookies },
286    { kPolicyDefaultCookiesSetting, Value::TYPE_INTEGER,
287      key::kDefaultCookiesSetting},
288    { kPolicyDefaultImagesSetting, Value::TYPE_INTEGER,
289      key::kDefaultImagesSetting},
290    { kPolicyDefaultJavaScriptSetting, Value::TYPE_INTEGER,
291      key::kDefaultJavaScriptSetting},
292    { kPolicyDefaultPluginsSetting, Value::TYPE_INTEGER,
293      key::kDefaultPluginsSetting},
294    { kPolicyDefaultPopupsSetting, Value::TYPE_INTEGER,
295      key::kDefaultPopupsSetting},
296    { kPolicyAuthSchemes, Value::TYPE_STRING, key::kAuthSchemes },
297    { kPolicyDisableAuthNegotiateCnameLookup, Value::TYPE_BOOLEAN,
298      key::kDisableAuthNegotiateCnameLookup },
299    { kPolicyEnableAuthNegotiatePort, Value::TYPE_BOOLEAN,
300      key::kEnableAuthNegotiatePort },
301    { kPolicyAuthServerWhitelist, Value::TYPE_STRING,
302      key::kAuthServerWhitelist },
303    { kPolicyAuthNegotiateDelegateWhitelist, Value::TYPE_STRING,
304      key::kAuthNegotiateDelegateWhitelist },
305    { kPolicyGSSAPILibraryName, Value::TYPE_STRING,
306      key::kGSSAPILibraryName },
307
308
309#if defined(OS_CHROMEOS)
310    { kPolicyChromeOsLockOnIdleSuspend, Value::TYPE_BOOLEAN,
311      key::kChromeOsLockOnIdleSuspend },
312#endif
313  };
314
315  static ConfigurationPolicyProvider::PolicyDefinitionList policy_list = {
316    entries,
317    entries + arraysize(entries),
318  };
319  return &policy_list;
320}
321
322ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore(
323    ConfigurationPolicyProvider* provider)
324    : provider_(provider),
325      prefs_(new DictionaryValue()),
326      lower_priority_proxy_settings_overridden_(false),
327      proxy_disabled_(false),
328      proxy_configuration_specified_(false),
329      use_system_proxy_(false) {
330}
331
332PrefStore::PrefReadError ConfigurationPolicyPrefStore::ReadPrefs() {
333  proxy_disabled_ = false;
334  proxy_configuration_specified_ = false;
335  lower_priority_proxy_settings_overridden_ = false;
336
337  const bool success = (provider_ == NULL || provider_->Provide(this));
338  FinalizeDefaultSearchPolicySettings();
339  return success ? PrefStore::PREF_READ_ERROR_NONE :
340      PrefStore::PREF_READ_ERROR_OTHER;
341}
342
343void ConfigurationPolicyPrefStore::Apply(ConfigurationPolicyType policy,
344                                         Value* value) {
345  if (ApplyProxyPolicy(policy, value))
346    return;
347
348  if (ApplySyncPolicy(policy, value))
349    return;
350
351  if (ApplyAutoFillPolicy(policy, value))
352    return;
353
354  if (ApplyPolicyFromMap(policy, value, kDefaultSearchPolicyMap,
355                         arraysize(kDefaultSearchPolicyMap)))
356    return;
357
358  if (ApplyPolicyFromMap(policy, value, kSimplePolicyMap,
359                         arraysize(kSimplePolicyMap)))
360    return;
361
362  // Other policy implementations go here.
363  NOTIMPLEMENTED();
364  delete value;
365}
366
367// static
368ConfigurationPolicyPrefStore*
369ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore() {
370  ConfigurationPolicyProviderKeeper* keeper =
371      Singleton<ConfigurationPolicyProviderKeeper>::get();
372  return new ConfigurationPolicyPrefStore(keeper->managed_platform_provider());
373}
374
375// static
376ConfigurationPolicyPrefStore*
377ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore() {
378  ConfigurationPolicyProviderKeeper* keeper =
379      Singleton<ConfigurationPolicyProviderKeeper>::get();
380  return new ConfigurationPolicyPrefStore(
381      keeper->device_management_provider());
382}
383
384// static
385ConfigurationPolicyPrefStore*
386ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore() {
387  ConfigurationPolicyProviderKeeper* keeper =
388      Singleton<ConfigurationPolicyProviderKeeper>::get();
389  return new ConfigurationPolicyPrefStore(keeper->recommended_provider());
390}
391
392// static
393void ConfigurationPolicyPrefStore::GetProxyPreferenceSet(
394    ProxyPreferenceSet* proxy_pref_set) {
395  proxy_pref_set->clear();
396  for (size_t current = 0; current < arraysize(kProxyPolicyMap); ++current) {
397    proxy_pref_set->insert(kProxyPolicyMap[current].preference_path);
398  }
399  proxy_pref_set->insert(prefs::kNoProxyServer);
400  proxy_pref_set->insert(prefs::kProxyAutoDetect);
401}
402
403const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry*
404ConfigurationPolicyPrefStore::FindPolicyInMap(
405    ConfigurationPolicyType policy,
406    const PolicyToPreferenceMapEntry* map,
407    int table_size) const {
408  for (int i = 0; i < table_size; ++i) {
409    if (map[i].policy_type == policy)
410      return map + i;
411  }
412  return NULL;
413}
414
415bool ConfigurationPolicyPrefStore::RemovePreferencesOfMap(
416    const PolicyToPreferenceMapEntry* map, int table_size) {
417  bool found_any = false;
418  for (int i = 0; i < table_size; ++i) {
419    if (prefs_->Remove(map[i].preference_path, NULL))
420      found_any = true;
421  }
422  return found_any;
423}
424
425bool ConfigurationPolicyPrefStore::ApplyPolicyFromMap(
426    ConfigurationPolicyType policy,
427    Value* value,
428    const PolicyToPreferenceMapEntry* map,
429    int size) {
430  for (int current = 0; current < size; ++current) {
431    if (map[current].policy_type == policy) {
432      DCHECK_EQ(map[current].value_type, value->GetType())
433          << "mismatch in provided and expected policy value for preferences"
434          << map[current].preference_path << ". expected = "
435          << map[current].value_type << ", actual = "<< value->GetType();
436      prefs_->Set(map[current].preference_path, value);
437      return true;
438    }
439  }
440  return false;
441}
442
443bool ConfigurationPolicyPrefStore::ApplyProxyPolicy(
444    ConfigurationPolicyType policy,
445    Value* value) {
446  bool result = false;
447  bool warn_about_proxy_disable_config = false;
448  bool warn_about_proxy_system_config = false;
449
450  const PolicyToPreferenceMapEntry* match_entry =
451      FindPolicyInMap(policy, kProxyPolicyMap, arraysize(kProxyPolicyMap));
452
453  // When the first proxy-related policy is applied, ALL proxy-related
454  // preferences that have been set by command-line switches, extensions,
455  // user preferences or any other mechanism are overridden. Otherwise
456  // it's possible for a user to interfere with proxy policy by setting
457  // proxy-related command-line switches or set proxy-related prefs in an
458  // extension that are related, but not identical, to the ones set through
459  // policy.
460  if (!lower_priority_proxy_settings_overridden_ &&
461      (match_entry ||
462       policy == kPolicyProxyServerMode)) {
463    ProxyPreferenceSet proxy_preference_set;
464    GetProxyPreferenceSet(&proxy_preference_set);
465    for (ProxyPreferenceSet::const_iterator i = proxy_preference_set.begin();
466         i != proxy_preference_set.end(); ++i) {
467      prefs_->Set(*i, PrefStore::CreateUseDefaultSentinelValue());
468    }
469    lower_priority_proxy_settings_overridden_ = true;
470  }
471
472  // Translate the proxy policy into preferences.
473  if (policy == kPolicyProxyServerMode) {
474    int int_value;
475    bool proxy_auto_detect = false;
476    if (value->GetAsInteger(&int_value)) {
477      result = true;
478      switch (int_value) {
479        case kPolicyNoProxyServerMode:
480          if (!proxy_disabled_) {
481            if (proxy_configuration_specified_)
482              warn_about_proxy_disable_config = true;
483            proxy_disabled_ = true;
484          }
485          break;
486        case kPolicyAutoDetectProxyMode:
487          proxy_auto_detect = true;
488          break;
489        case kPolicyManuallyConfiguredProxyMode:
490          break;
491        case kPolicyUseSystemProxyMode:
492          if (!use_system_proxy_) {
493            if (proxy_configuration_specified_)
494              warn_about_proxy_system_config = true;
495            use_system_proxy_ = true;
496          }
497          break;
498        default:
499          // Not a valid policy, don't assume ownership of |value|
500          result = false;
501          break;
502      }
503
504      if (int_value != kPolicyUseSystemProxyMode) {
505        prefs_->Set(prefs::kNoProxyServer,
506                    Value::CreateBooleanValue(proxy_disabled_));
507        prefs_->Set(prefs::kProxyAutoDetect,
508                    Value::CreateBooleanValue(proxy_auto_detect));
509      }
510    }
511  } else if (match_entry) {
512    // Determine if the applied proxy policy settings conflict and issue
513    // a corresponding warning if they do.
514    if (!proxy_configuration_specified_) {
515      if (proxy_disabled_)
516        warn_about_proxy_disable_config = true;
517      if (use_system_proxy_)
518        warn_about_proxy_system_config = true;
519      proxy_configuration_specified_ = true;
520    }
521    if (!use_system_proxy_ && !proxy_disabled_) {
522      prefs_->Set(match_entry->preference_path, value);
523      // The ownership of value has been passed on to |prefs_|,
524      // don't clean it up later.
525      value = NULL;
526    }
527    result = true;
528  }
529
530  if (warn_about_proxy_disable_config) {
531    LOG(WARNING) << "A centrally-administered policy disables the use of"
532                 << " a proxy but also specifies an explicit proxy"
533                 << " configuration.";
534  }
535
536  if (warn_about_proxy_system_config) {
537    LOG(WARNING) << "A centrally-administered policy dictates that the"
538                 << " system proxy settings should be used but also specifies"
539                 << " an explicit proxy configuration.";
540  }
541
542  // If the policy was a proxy policy, cleanup |value|.
543  if (result && value)
544    delete value;
545  return result;
546}
547
548bool ConfigurationPolicyPrefStore::ApplySyncPolicy(
549    ConfigurationPolicyType policy, Value* value) {
550  if (policy == kPolicySyncDisabled) {
551    bool disable_sync;
552    if (value->GetAsBoolean(&disable_sync) && disable_sync)
553      prefs_->Set(prefs::kSyncManaged, value);
554    else
555      delete value;
556    return true;
557  }
558  return false;
559}
560
561bool ConfigurationPolicyPrefStore::ApplyAutoFillPolicy(
562    ConfigurationPolicyType policy, Value* value) {
563  if (policy == kPolicyAutoFillEnabled) {
564    bool auto_fill_enabled;
565    if (value->GetAsBoolean(&auto_fill_enabled) && !auto_fill_enabled)
566      prefs_->Set(prefs::kAutoFillEnabled, Value::CreateBooleanValue(false));
567    delete value;
568    return true;
569  }
570  return false;
571}
572
573void ConfigurationPolicyPrefStore::EnsureStringPrefExists(
574    const std::string& path) {
575  std::string value;
576  if (!prefs_->GetString(path, &value))
577    prefs_->SetString(path, value);
578}
579
580namespace {
581
582// Implementation of SearchTermsData just for validation.
583class SearchTermsDataForValidation : public SearchTermsData {
584 public:
585  SearchTermsDataForValidation() {}
586
587  // Implementation of SearchTermsData.
588  virtual std::string GoogleBaseURLValue() const {
589    return "http://www.google.com/";
590  }
591  virtual std::string GetApplicationLocale() const {
592    return "en";
593  }
594#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
595  virtual std::wstring GetRlzParameterValue() const {
596    return std::wstring();
597  }
598#endif
599 private:
600  DISALLOW_COPY_AND_ASSIGN(SearchTermsDataForValidation);
601};
602
603}  // namepsace
604
605void ConfigurationPolicyPrefStore::FinalizeDefaultSearchPolicySettings() {
606  bool enabled = true;
607  if (prefs_->GetBoolean(prefs::kDefaultSearchProviderEnabled, &enabled) &&
608      !enabled) {
609    // If default search is disabled, we ignore the other fields.
610    prefs_->SetString(prefs::kDefaultSearchProviderName, std::string());
611    prefs_->SetString(prefs::kDefaultSearchProviderSearchURL, std::string());
612    prefs_->SetString(prefs::kDefaultSearchProviderSuggestURL, std::string());
613    prefs_->SetString(prefs::kDefaultSearchProviderIconURL, std::string());
614    prefs_->SetString(prefs::kDefaultSearchProviderEncodings, std::string());
615    prefs_->SetString(prefs::kDefaultSearchProviderKeyword, std::string());
616    return;
617  }
618  std::string search_url;
619  // The search URL is required.
620  if (prefs_->GetString(prefs::kDefaultSearchProviderSearchURL, &search_url) &&
621      !search_url.empty()) {
622    SearchTermsDataForValidation search_terms_data;
623    const TemplateURLRef search_url_ref(search_url, 0, 0);
624    // It must support replacement (which implies it is valid).
625    if (search_url_ref.SupportsReplacementUsingTermsData(search_terms_data)) {
626      // The other entries are optional.  Just make sure that they are all
627      // specified via policy, so that we don't use regular prefs.
628      EnsureStringPrefExists(prefs::kDefaultSearchProviderSuggestURL);
629      EnsureStringPrefExists(prefs::kDefaultSearchProviderIconURL);
630      EnsureStringPrefExists(prefs::kDefaultSearchProviderEncodings);
631      EnsureStringPrefExists(prefs::kDefaultSearchProviderKeyword);
632
633      // For the name, default to the host if not specified.
634      std::string name;
635      if (!prefs_->GetString(prefs::kDefaultSearchProviderName, &name) ||
636          name.empty())
637        prefs_->SetString(prefs::kDefaultSearchProviderName,
638                          GURL(search_url).host());
639
640      // And clear the IDs since these are not specified via policy.
641      prefs_->SetString(prefs::kDefaultSearchProviderID, std::string());
642      prefs_->SetString(prefs::kDefaultSearchProviderPrepopulateID,
643                        std::string());
644      return;
645    }
646  }
647  // Required entries are not there.  Remove any related entries.
648  RemovePreferencesOfMap(kDefaultSearchPolicyMap,
649                         arraysize(kDefaultSearchPolicyMap));
650}
651
652}  // namespace policy
653