policy_loader_win_unittest.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/policy_loader_win.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <userenv.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <algorithm>
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <cstring>
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <functional>
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <iterator>
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector>
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/base_paths.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/callback.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/files/file_path.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h"
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/path_service.h"
23bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/process/process.h"
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/sys_byteorder.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/registry.h"
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/win/win_util.h"
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/async_policy_provider.h"
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/configuration_policy_provider_test.h"
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/external_data_fetcher.h"
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_bundle.h"
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_map.h"
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/preg_parser_win.h"
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/schema_map.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UTF8ToUTF16;
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UTF16ToUTF8;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::win::RegKey;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Constants for registry key names.
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kPathSep[] = L"\\";
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kThirdParty[] = L"3rdparty";
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kMandatory[] = L"policy";
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kRecommended[] = L"recommended";
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kSchema[] = "schema";
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const wchar_t kTestPolicyKey[] = L"chrome.policy.key";
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Installs |value| in the given registry |path| and |hive|, under the key
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |name|. Returns false on errors.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some of the possible Value types are stored after a conversion (e.g. doubles
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are stored as strings), and can only be retrieved if a corresponding schema
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is written.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallValue(const base::Value& value,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  HKEY hive,
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  const base::string16& path,
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  const base::string16& name) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // KEY_ALL_ACCESS causes the ctor to create the key if it does not exist yet.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegKey key(hive, path.c_str(), KEY_ALL_ACCESS);
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(key.Valid());
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (value.GetType()) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::Value::TYPE_NULL:
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return key.WriteValue(name.c_str(), L"") == ERROR_SUCCESS;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::Value::TYPE_BOOLEAN: {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool bool_value;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!value.GetAsBoolean(&bool_value))
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return key.WriteValue(name.c_str(), bool_value ? 1 : 0) == ERROR_SUCCESS;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::Value::TYPE_INTEGER: {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int int_value;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!value.GetAsInteger(&int_value))
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return key.WriteValue(name.c_str(), int_value) == ERROR_SUCCESS;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::Value::TYPE_DOUBLE: {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      double double_value;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!value.GetAsDouble(&double_value))
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::string16 str_value =
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          UTF8ToUTF16(base::DoubleToString(double_value));
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return key.WriteValue(name.c_str(), str_value.c_str()) == ERROR_SUCCESS;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::Value::TYPE_STRING: {
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::string16 str_value;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!value.GetAsString(&str_value))
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return key.WriteValue(name.c_str(), str_value.c_str()) == ERROR_SUCCESS;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::Value::TYPE_DICTIONARY: {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::DictionaryValue* sub_dict = NULL;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!value.GetAsDictionary(&sub_dict))
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (base::DictionaryValue::Iterator it(*sub_dict);
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           !it.IsAtEnd(); it.Advance()) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!InstallValue(it.value(), hive, path + kPathSep + name,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          UTF8ToUTF16(it.key()))) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return false;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::Value::TYPE_LIST: {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::ListValue* list = NULL;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!value.GetAsList(&list))
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (size_t i = 0; i < list->GetSize(); ++i) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const base::Value* item;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!list->Get(i, &item))
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return false;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!InstallValue(*item, hive, path + kPathSep + name,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          base::UintToString16(i + 1))) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return false;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::Value::TYPE_BINARY:
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class provides sandboxing and mocking for the parts of the Windows
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Registry implementing Group Policy. It prepares two temporary sandbox keys,
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// one for HKLM and one for HKCU. A test's calls to the registry are redirected
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// by Windows to these sandboxes, allowing the tests to manipulate and access
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// policy as if it were active, but without actually changing the parts of the
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Registry that are managed by Group Policy.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScopedGroupPolicyRegistrySandbox {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedGroupPolicyRegistrySandbox();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ScopedGroupPolicyRegistrySandbox();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ActivateOverrides();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveOverrides();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Deletes the sandbox keys.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeleteKeys();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::wstring key_name_;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keys are created for the lifetime of a test to contain
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the sandboxed HKCU and HKLM hives, respectively.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegKey temp_hkcu_hive_key_;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegKey temp_hklm_hive_key_;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedGroupPolicyRegistrySandbox);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A test harness that feeds policy via the Chrome GPO registry subtree.
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class RegistryTestHarness : public PolicyProviderTestHarness,
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            public AppliedGPOListProvider {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegistryTestHarness(HKEY hive, PolicyScope scope);
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~RegistryTestHarness();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // PolicyProviderTestHarness:
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ConfigurationPolicyProvider* CreateProvider(
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      SchemaRegistry* registry,
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallEmptyPolicy() OVERRIDE;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallStringPolicy(const std::string& policy_name,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const std::string& policy_value) OVERRIDE;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallIntegerPolicy(const std::string& policy_name,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int policy_value) OVERRIDE;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallBooleanPolicy(const std::string& policy_name,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool policy_value) OVERRIDE;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallStringListPolicy(
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& policy_name,
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::ListValue* policy_value) OVERRIDE;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallDictionaryPolicy(
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& policy_name,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::DictionaryValue* policy_value) OVERRIDE;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Install3rdPartyPolicy(
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::DictionaryValue* policies) OVERRIDE;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // AppliedGPOListProvider:
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual DWORD GetAppliedGPOList(DWORD flags,
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  LPCTSTR machine_name,
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  PSID sid_user,
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  GUID* extension_guid,
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  PGROUP_POLICY_OBJECT* gpo_list) OVERRIDE;
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual BOOL FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) OVERRIDE;
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a harness instance that will install policy in HKCU or HKLM,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // respectively.
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static PolicyProviderTestHarness* CreateHKCU();
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static PolicyProviderTestHarness* CreateHKLM();
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HKEY hive_;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedGroupPolicyRegistrySandbox registry_sandbox_;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RegistryTestHarness);
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A test harness that generates PReg files for the provider to read.
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class PRegTestHarness : public PolicyProviderTestHarness,
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        public AppliedGPOListProvider {
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PRegTestHarness();
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~PRegTestHarness();
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // PolicyProviderTestHarness:
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUp() OVERRIDE;
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ConfigurationPolicyProvider* CreateProvider(
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      SchemaRegistry* registry,
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE;
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void InstallEmptyPolicy() OVERRIDE;
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void InstallStringPolicy(const std::string& policy_name,
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   const std::string& policy_value) OVERRIDE;
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void InstallIntegerPolicy(const std::string& policy_name,
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    int policy_value) OVERRIDE;
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void InstallBooleanPolicy(const std::string& policy_name,
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    bool policy_value) OVERRIDE;
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void InstallStringListPolicy(
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& policy_name,
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::ListValue* policy_value) OVERRIDE;
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void InstallDictionaryPolicy(
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& policy_name,
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::DictionaryValue* policy_value) OVERRIDE;
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void Install3rdPartyPolicy(
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::DictionaryValue* policies) OVERRIDE;
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // AppliedGPOListProvider:
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual DWORD GetAppliedGPOList(DWORD flags,
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  LPCTSTR machine_name,
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  PSID sid_user,
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  GUID* extension_guid,
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  PGROUP_POLICY_OBJECT* gpo_list) OVERRIDE;
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual BOOL FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) OVERRIDE;
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Creates a harness instance.
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static PolicyProviderTestHarness* Create();
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Helper to append a base::string16 to an uint8 buffer.
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static void AppendChars(std::vector<uint8>* buffer,
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          const base::string16& chars);
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Appends a record with the given fields to the PReg file.
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AppendRecordToPRegFile(const base::string16& path,
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              const std::string& key,
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              DWORD type,
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              DWORD size,
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              uint8* data);
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Appends the given DWORD |value| for |path| + |key| to the PReg file.
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AppendDWORDToPRegFile(const base::string16& path,
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             const std::string& key,
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             DWORD value);
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Appends the given string |value| for |path| + |key| to the PReg file.
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AppendStringToPRegFile(const base::string16& path,
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              const std::string& key,
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              const std::string& value);
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Appends the given policy |value| for |path| + |key| to the PReg file,
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // converting and recursing as necessary.
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AppendPolicyToPRegFile(const base::string16& path,
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              const std::string& key,
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              const base::Value* value);
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::ScopedTempDir temp_dir_;
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath preg_file_path_;
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GROUP_POLICY_OBJECT gpo_;
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PRegTestHarness);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedGroupPolicyRegistrySandbox::ScopedGroupPolicyRegistrySandbox() {
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Generate a unique registry key for the override for each test. This
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // makes sure that tests executing in parallel won't delete each other's
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // key, at DeleteKeys().
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  key_name_ = base::ASCIIToWide(base::StringPrintf(
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "SOFTWARE\\chromium unittest %d",
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Process::Current().pid()));
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::wstring hklm_key_name = key_name_ + L"\\HKLM";
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::wstring hkcu_key_name = key_name_ + L"\\HKCU";
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the subkeys to hold the overridden HKLM and HKCU
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // policy settings.
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  temp_hklm_hive_key_.Create(HKEY_CURRENT_USER,
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             hklm_key_name.c_str(),
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             KEY_ALL_ACCESS);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  temp_hkcu_hive_key_.Create(HKEY_CURRENT_USER,
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             hkcu_key_name.c_str(),
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             KEY_ALL_ACCESS);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ActivateOverrides();
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedGroupPolicyRegistrySandbox::~ScopedGroupPolicyRegistrySandbox() {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveOverrides();
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeleteKeys();
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScopedGroupPolicyRegistrySandbox::ActivateOverrides() {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_LOCAL_MACHINE,
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                temp_hklm_hive_key_.Handle()));
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_CURRENT_USER,
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                temp_hkcu_hive_key_.Handle()));
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScopedGroupPolicyRegistrySandbox::RemoveOverrides() {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_LOCAL_MACHINE, 0));
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_CURRENT_USER, 0));
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScopedGroupPolicyRegistrySandbox::DeleteKeys() {
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RegKey key(HKEY_CURRENT_USER, key_name_.c_str(), KEY_ALL_ACCESS);
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(key.Valid());
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key.DeleteKey(L"");
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)RegistryTestHarness::RegistryTestHarness(HKEY hive, PolicyScope scope)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY, scope), hive_(hive) {}
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)RegistryTestHarness::~RegistryTestHarness() {}
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RegistryTestHarness::SetUp() {}
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ConfigurationPolicyProvider* RegistryTestHarness::CreateProvider(
348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SchemaRegistry* registry,
349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<base::SequencedTaskRunner> task_runner) {
350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::win::SetDomainStateForTesting(true);
351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<AsyncPolicyLoader> loader(
352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new PolicyLoaderWin(task_runner, kTestPolicyKey, this));
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return new AsyncPolicyProvider(registry, loader.Pass());
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RegistryTestHarness::InstallEmptyPolicy() {}
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RegistryTestHarness::InstallStringPolicy(
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& policy_name,
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& policy_value) {
361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegKey key(hive_, kTestPolicyKey, KEY_ALL_ACCESS);
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(key.Valid());
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_HRESULT_SUCCEEDED(key.WriteValue(UTF8ToUTF16(policy_name).c_str(),
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          UTF8ToUTF16(policy_value).c_str()));
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RegistryTestHarness::InstallIntegerPolicy(
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& policy_name,
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int policy_value) {
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegKey key(hive_, kTestPolicyKey, KEY_ALL_ACCESS);
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(key.Valid());
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key.WriteValue(UTF8ToUTF16(policy_name).c_str(),
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 static_cast<DWORD>(policy_value));
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RegistryTestHarness::InstallBooleanPolicy(
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& policy_name,
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool policy_value) {
379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegKey key(hive_, kTestPolicyKey, KEY_ALL_ACCESS);
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(key.Valid());
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key.WriteValue(UTF8ToUTF16(policy_name).c_str(),
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 static_cast<DWORD>(policy_value));
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RegistryTestHarness::InstallStringListPolicy(
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& policy_name,
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::ListValue* policy_value) {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegKey key(hive_,
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             (base::string16(kTestPolicyKey) + base::ASCIIToUTF16("\\") +
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              UTF8ToUTF16(policy_name)).c_str(),
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             KEY_ALL_ACCESS);
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(key.Valid());
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int index = 1;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (base::ListValue::const_iterator element(policy_value->begin());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       element != policy_value->end();
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++element) {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string element_value;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(*element)->GetAsString(&element_value))
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name(base::IntToString(index++));
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key.WriteValue(UTF8ToUTF16(name).c_str(),
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   UTF8ToUTF16(element_value).c_str());
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RegistryTestHarness::InstallDictionaryPolicy(
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& policy_name,
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::DictionaryValue* policy_value) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string json;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::JSONWriter::Write(policy_value, &json);
411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegKey key(hive_, kTestPolicyKey, KEY_ALL_ACCESS);
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(key.Valid());
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key.WriteValue(UTF8ToUTF16(policy_name).c_str(),
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 UTF8ToUTF16(json).c_str());
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RegistryTestHarness::Install3rdPartyPolicy(
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::DictionaryValue* policies) {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first level entries are domains, and the second level entries map
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // components to their policy.
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 kPathPrefix =
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::string16(kTestPolicyKey) + kPathSep + kThirdParty + kPathSep;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (base::DictionaryValue::Iterator domain(*policies);
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       !domain.IsAtEnd(); domain.Advance()) {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::DictionaryValue* components = NULL;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!domain.value().GetAsDictionary(&components)) {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ADD_FAILURE();
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (base::DictionaryValue::Iterator component(*components);
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         !component.IsAtEnd(); component.Advance()) {
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const base::string16 path = kPathPrefix +
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          UTF8ToUTF16(domain.key()) + kPathSep + UTF8ToUTF16(component.key());
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InstallValue(component.value(), hive_, path, kMandatory);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DWORD RegistryTestHarness::GetAppliedGPOList(DWORD flags,
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             LPCTSTR machine_name,
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             PSID sid_user,
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             GUID* extension_guid,
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             PGROUP_POLICY_OBJECT* gpo_list) {
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *gpo_list = NULL;
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return ERROR_ACCESS_DENIED;
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)BOOL RegistryTestHarness::FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) {
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return TRUE;
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PolicyProviderTestHarness* RegistryTestHarness::CreateHKCU() {
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return new RegistryTestHarness(HKEY_CURRENT_USER, POLICY_SCOPE_USER);
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PolicyProviderTestHarness* RegistryTestHarness::CreateHKLM() {
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return new RegistryTestHarness(HKEY_LOCAL_MACHINE, POLICY_SCOPE_MACHINE);
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PRegTestHarness::PRegTestHarness()
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE) {}
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PRegTestHarness::~PRegTestHarness() {}
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PRegTestHarness::SetUp() {
468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::win::SetDomainStateForTesting(false);
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  preg_file_path_ = temp_dir_.path().Append(PolicyLoaderWin::kPRegFileName);
471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(base::WriteFile(preg_file_path_,
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   preg_parser::kPRegFileHeader,
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   arraysize(preg_parser::kPRegFileHeader)));
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  memset(&gpo_, 0, sizeof(GROUP_POLICY_OBJECT));
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_.lpFileSysPath = const_cast<wchar_t*>(temp_dir_.path().value().c_str());
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ConfigurationPolicyProvider* PRegTestHarness::CreateProvider(
480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SchemaRegistry* registry,
481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<base::SequencedTaskRunner> task_runner) {
482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<AsyncPolicyLoader> loader(
483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new PolicyLoaderWin(task_runner, kTestPolicyKey, this));
484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return new AsyncPolicyProvider(registry, loader.Pass());
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PRegTestHarness::InstallEmptyPolicy() {}
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PRegTestHarness::InstallStringPolicy(const std::string& policy_name,
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                          const std::string& policy_value) {
491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AppendStringToPRegFile(kTestPolicyKey, policy_name, policy_value);
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PRegTestHarness::InstallIntegerPolicy(const std::string& policy_name,
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           int policy_value) {
496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AppendDWORDToPRegFile(kTestPolicyKey, policy_name, policy_value);
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PRegTestHarness::InstallBooleanPolicy(const std::string& policy_name,
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           bool policy_value) {
501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AppendDWORDToPRegFile(kTestPolicyKey, policy_name, policy_value);
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PRegTestHarness::InstallStringListPolicy(
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& policy_name,
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::ListValue* policy_value) {
507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AppendPolicyToPRegFile(kTestPolicyKey, policy_name, policy_value);
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PRegTestHarness::InstallDictionaryPolicy(
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& policy_name,
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::DictionaryValue* policy_value) {
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string json;
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::JSONWriter::Write(policy_value, &json);
515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AppendStringToPRegFile(kTestPolicyKey, policy_name, json);
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PRegTestHarness::Install3rdPartyPolicy(
519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::DictionaryValue* policies) {
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The first level entries are domains, and the second level entries map
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // components to their policy.
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 kPathPrefix =
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::string16(kTestPolicyKey) + kPathSep + kThirdParty + kPathSep;
524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (base::DictionaryValue::Iterator domain(*policies);
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       !domain.IsAtEnd(); domain.Advance()) {
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::DictionaryValue* components = NULL;
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!domain.value().GetAsDictionary(&components)) {
528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ADD_FAILURE();
529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16 domain_path = kPathPrefix + UTF8ToUTF16(domain.key());
532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (base::DictionaryValue::Iterator component(*components);
533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         !component.IsAtEnd(); component.Advance()) {
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const base::string16 component_path =
535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          domain_path + kPathSep + UTF8ToUTF16(component.key());
536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AppendPolicyToPRegFile(component_path, UTF16ToUTF8(kMandatory),
537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             &component.value());
538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DWORD PRegTestHarness::GetAppliedGPOList(DWORD flags,
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         LPCTSTR machine_name,
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         PSID sid_user,
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         GUID* extension_guid,
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         PGROUP_POLICY_OBJECT* gpo_list) {
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *gpo_list = flags & GPO_LIST_FLAG_MACHINE ? &gpo_ : NULL;
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return ERROR_SUCCESS;
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)BOOL PRegTestHarness::FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) {
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return TRUE;
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PolicyProviderTestHarness* PRegTestHarness::Create() {
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return new PRegTestHarness();
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PRegTestHarness::AppendChars(std::vector<uint8>* buffer,
5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  const base::string16& chars) {
5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (base::string16::const_iterator c(chars.begin()); c != chars.end(); ++c) {
564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    buffer->push_back(*c & 0xff);
565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    buffer->push_back((*c >> 8) & 0xff);
566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PRegTestHarness::AppendRecordToPRegFile(const base::string16& path,
570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             const std::string& key,
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             DWORD type,
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             DWORD size,
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             uint8* data) {
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<uint8> buffer;
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AppendChars(&buffer, L"[");
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AppendChars(&buffer, path);
5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendChars(&buffer, base::string16(L"\0;", 2));
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AppendChars(&buffer, UTF8ToUTF16(key));
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendChars(&buffer, base::string16(L"\0;", 2));
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  type = base::ByteSwapToLE32(type);
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint8* type_data = reinterpret_cast<uint8*>(&type);
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  buffer.insert(buffer.end(), type_data, type_data + sizeof(DWORD));
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AppendChars(&buffer, L";");
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size = base::ByteSwapToLE32(size);
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint8* size_data = reinterpret_cast<uint8*>(&size);
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  buffer.insert(buffer.end(), size_data, size_data + sizeof(DWORD));
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AppendChars(&buffer, L";");
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  buffer.insert(buffer.end(), data, data + size);
589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AppendChars(&buffer, L"]");
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(buffer.size(),
592a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            base::AppendToFile(
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                preg_file_path_,
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                reinterpret_cast<const char*>(vector_as_array(&buffer)),
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                buffer.size()));
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PRegTestHarness::AppendDWORDToPRegFile(const base::string16& path,
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                            const std::string& key,
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                            DWORD value) {
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  value = base::ByteSwapToLE32(value);
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AppendRecordToPRegFile(path, key, REG_DWORD, sizeof(DWORD),
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         reinterpret_cast<uint8*>(&value));
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PRegTestHarness::AppendStringToPRegFile(const base::string16& path,
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             const std::string& key,
608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             const std::string& value) {
6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 string16_value(UTF8ToUTF16(value));
6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<base::char16> data;
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::transform(string16_value.begin(), string16_value.end(),
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 std::back_inserter(data), std::ptr_fun(base::ByteSwapToLE16));
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data.push_back(base::ByteSwapToLE16(L'\0'));
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendRecordToPRegFile(path, key, REG_SZ, data.size() * sizeof(base::char16),
616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         reinterpret_cast<uint8*>(vector_as_array(&data)));
617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PRegTestHarness::AppendPolicyToPRegFile(const base::string16& path,
620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             const std::string& key,
621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             const base::Value* value) {
622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (value->GetType()) {
623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case base::Value::TYPE_BOOLEAN: {
624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      bool boolean_value = false;
625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ASSERT_TRUE(value->GetAsBoolean(&boolean_value));
626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AppendDWORDToPRegFile(path, key, boolean_value);
627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case base::Value::TYPE_INTEGER: {
630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      int int_value = 0;
631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ASSERT_TRUE(value->GetAsInteger(&int_value));
632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AppendDWORDToPRegFile(path, key, int_value);
633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case base::Value::TYPE_DOUBLE: {
636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      double double_value = 0;
637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ASSERT_TRUE(value->GetAsDouble(&double_value));
638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AppendStringToPRegFile(path, key, base::DoubleToString(double_value));
639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case base::Value::TYPE_STRING: {
642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string string_value;
643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ASSERT_TRUE(value->GetAsString(&string_value));
644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AppendStringToPRegFile(path, key, string_value);
645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case base::Value::TYPE_DICTIONARY: {
6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::string16 subpath = path + kPathSep + UTF8ToUTF16(key);
649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::DictionaryValue* dict = NULL;
650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ASSERT_TRUE(value->GetAsDictionary(&dict));
651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (base::DictionaryValue::Iterator entry(*dict); !entry.IsAtEnd();
652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           entry.Advance()) {
653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        AppendPolicyToPRegFile(subpath, entry.key(), &entry.value());
654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case base::Value::TYPE_LIST: {
6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::string16 subpath = path + kPathSep + UTF8ToUTF16(key);
659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::ListValue* list = NULL;
660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ASSERT_TRUE(value->GetAsList(&list));
661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (size_t i = 0; i < list->GetSize(); ++i) {
662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        const base::Value* entry = NULL;
663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ASSERT_TRUE(list->Get(i, &entry));
664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        AppendPolicyToPRegFile(subpath, base::IntToString(i + 1), entry);
665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case base::Value::TYPE_BINARY:
669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case base::Value::TYPE_NULL: {
670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ADD_FAILURE();
671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Instantiate abstract test case for basic policy reading tests.
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PolicyProviderWinTest,
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConfigurationPolicyProviderTest,
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    testing::Values(RegistryTestHarness::CreateHKCU,
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    RegistryTestHarness::CreateHKLM,
684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    PRegTestHarness::Create));
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Instantiate abstract test case for 3rd party policy reading tests.
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ThirdPartyPolicyProviderWinTest,
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Configuration3rdPartyPolicyProviderTest,
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    testing::Values(RegistryTestHarness::CreateHKCU,
691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    RegistryTestHarness::CreateHKLM,
692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    PRegTestHarness::Create));
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test cases for windows policy provider specific functionality.
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class PolicyLoaderWinTest : public PolicyTestBase,
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            public AppliedGPOListProvider {
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The policy key this tests places data under. This must match the data
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // files in chrome/test/data/policy/gpo.
7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static const base::char16 kTestPolicyKey[];
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PolicyLoaderWinTest()
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : gpo_list_(NULL),
704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        gpo_list_status_(ERROR_ACCESS_DENIED) {}
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PolicyLoaderWinTest() {}
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
708a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::win::SetDomainStateForTesting(false);
709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PolicyTestBase::SetUp();
710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir_));
7123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    test_data_dir_ = test_data_dir_.AppendASCII("chrome")
7133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                   .AppendASCII("test")
7143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                   .AppendASCII("data")
7153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                   .AppendASCII("policy")
7163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                   .AppendASCII("gpo");
717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // AppliedGPOListProvider:
720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual DWORD GetAppliedGPOList(DWORD flags,
721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  LPCTSTR machine_name,
722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  PSID sid_user,
723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  GUID* extension_guid,
724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  PGROUP_POLICY_OBJECT* gpo_list) OVERRIDE {
725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *gpo_list = gpo_list_;
726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return gpo_list_status_;
727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual BOOL FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) OVERRIDE {
729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return TRUE;
730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void InitGPO(GROUP_POLICY_OBJECT* gpo,
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               DWORD options,
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               const base::FilePath& path,
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               GROUP_POLICY_OBJECT* next,
736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               GROUP_POLICY_OBJECT* prev) {
737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    memset(gpo, 0, sizeof(GROUP_POLICY_OBJECT));
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    gpo->dwOptions = options;
739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    gpo->lpFileSysPath = const_cast<wchar_t*>(path.value().c_str());
740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    gpo->pNext = next;
741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    gpo->pPrev = prev;
742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Matches(const PolicyBundle& expected) {
745f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PolicyLoaderWin loader(loop_.message_loop_proxy(), kTestPolicyKey, this);
746f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<PolicyBundle> loaded(
747f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        loader.InitialLoad(schema_registry_.schema_map()));
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return loaded->Equals(expected);
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void InstallRegistrySentinel() {
752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RegKey hklm_key(HKEY_CURRENT_USER, kTestPolicyKey, KEY_ALL_ACCESS);
753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(hklm_key.Valid());
754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    hklm_key.WriteValue(
755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        UTF8ToUTF16(test_keys::kKeyString).c_str(),
756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        UTF8ToUTF16("registry").c_str());
757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool MatchesRegistrySentinel() {
760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::DictionaryValue expected_policy;
761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    expected_policy.SetString(test_keys::kKeyString, "registry");
762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PolicyBundle expected;
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        .LoadFrom(&expected_policy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return Matches(expected);
766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool MatchesTestBundle() {
769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::DictionaryValue expected_policy;
770f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    expected_policy.SetBoolean(test_keys::kKeyBoolean, true);
771f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    expected_policy.SetString(test_keys::kKeyString, "GPO");
772f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    expected_policy.SetInteger(test_keys::kKeyInteger, 42);
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<base::ListValue> list(new base::ListValue());
774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    list->AppendString("GPO 1");
775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    list->AppendString("GPO 2");
776f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    expected_policy.Set(test_keys::kKeyStringList, list.release());
777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PolicyBundle expected;
778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        .LoadFrom(&expected_policy, POLICY_LEVEL_MANDATORY,
780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  POLICY_SCOPE_MACHINE);
781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return Matches(expected);
782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedGroupPolicyRegistrySandbox registry_sandbox_;
785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PGROUP_POLICY_OBJECT gpo_list_;
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DWORD gpo_list_status_;
787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath test_data_dir_;
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const base::char16 PolicyLoaderWinTest::kTestPolicyKey[] =
791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    L"SOFTWARE\\Policies\\Chromium";
792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(PolicyLoaderWinTest, HKLMOverHKCU) {
794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegKey hklm_key(HKEY_LOCAL_MACHINE, kTestPolicyKey, KEY_ALL_ACCESS);
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(hklm_key.Valid());
796f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  hklm_key.WriteValue(UTF8ToUTF16(test_keys::kKeyString).c_str(),
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      UTF8ToUTF16("hklm").c_str());
798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegKey hkcu_key(HKEY_CURRENT_USER, kTestPolicyKey, KEY_ALL_ACCESS);
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(hkcu_key.Valid());
800f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  hkcu_key.WriteValue(UTF8ToUTF16(test_keys::kKeyString).c_str(),
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      UTF8ToUTF16("hkcu").c_str());
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyBundle expected;
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .Set(test_keys::kKeyString,
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           POLICY_LEVEL_MANDATORY,
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           POLICY_SCOPE_MACHINE,
8085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           new base::StringValue("hklm"),
8095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           NULL);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Matches(expected));
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(PolicyLoaderWinTest, Merge3rdPartyPolicies) {
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Policy for the same extension will be provided at the 4 level/scope
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // combinations, to verify that they overlap as expected.
816a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, "merge");
817a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(RegisterSchema(
818a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ns,
819a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "{"
820a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  \"type\": \"object\","
821a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  \"properties\": {"
822a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"a\": { \"type\": \"string\" },"
823a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"b\": { \"type\": \"string\" },"
824a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"c\": { \"type\": \"string\" },"
825a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"d\": { \"type\": \"string\" }"
826a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  }"
827a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "}"));
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 kPathSuffix =
8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions\\merge");
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kUserMandatory[] = "user-mandatory";
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kUserRecommended[] = "user-recommended";
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kMachineMandatory[] = "machine-mandatory";
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kMachineRecommended[] = "machine-recommended";
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::DictionaryValue policy;
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetString("a", kMachineMandatory);
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(InstallValue(policy, HKEY_LOCAL_MACHINE,
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           kPathSuffix, kMandatory));
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetString("a", kUserMandatory);
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetString("b", kUserMandatory);
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(InstallValue(policy, HKEY_CURRENT_USER,
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           kPathSuffix, kMandatory));
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetString("a", kMachineRecommended);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetString("b", kMachineRecommended);
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetString("c", kMachineRecommended);
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(InstallValue(policy, HKEY_LOCAL_MACHINE,
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           kPathSuffix, kRecommended));
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetString("a", kUserRecommended);
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetString("b", kUserRecommended);
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetString("c", kUserRecommended);
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetString("d", kUserRecommended);
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(InstallValue(policy, HKEY_CURRENT_USER,
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           kPathSuffix, kRecommended));
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyBundle expected;
858a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PolicyMap& expected_policy = expected.Get(ns);
8595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  expected_policy.Set("a",
8605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      POLICY_LEVEL_MANDATORY,
8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      POLICY_SCOPE_MACHINE,
8625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      new base::StringValue(kMachineMandatory),
8635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      NULL);
8645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  expected_policy.Set("b",
8655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      POLICY_LEVEL_MANDATORY,
8665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      POLICY_SCOPE_USER,
8675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      new base::StringValue(kUserMandatory),
8685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      NULL);
8695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  expected_policy.Set("c",
8705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      POLICY_LEVEL_RECOMMENDED,
8715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      POLICY_SCOPE_MACHINE,
8725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      new base::StringValue(kMachineRecommended),
8735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      NULL);
8745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  expected_policy.Set("d",
8755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      POLICY_LEVEL_RECOMMENDED,
8765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      POLICY_SCOPE_USER,
8775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      new base::StringValue(kUserRecommended),
8787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                      NULL);
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Matches(expected));
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(PolicyLoaderWinTest, LoadStringEncodedValues) {
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a dictionary with all the types that can be stored encoded in a
884a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // string.
885a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, "string");
886a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(RegisterSchema(
887a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ns,
888a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "{"
889a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  \"type\": \"object\","
890a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  \"id\": \"MainType\","
891a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  \"properties\": {"
892a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"null\": { \"type\": \"null\" },"
893a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"bool\": { \"type\": \"boolean\" },"
894a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"int\": { \"type\": \"integer\" },"
895a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"double\": { \"type\": \"number\" },"
896a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"list\": {"
897a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "      \"type\": \"array\","
898a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "      \"items\": { \"$ref\": \"MainType\" }"
899a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    },"
900a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"dict\": { \"$ref\": \"MainType\" }"
901a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  }"
902a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "}"));
903a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::DictionaryValue policy;
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.Set("null", base::Value::CreateNullValue());
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetBoolean("bool", true);
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetInteger("int", -123);
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetDouble("double", 456.78e9);
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ListValue list;
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  list.Append(policy.DeepCopy());
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  list.Append(policy.DeepCopy());
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.Set("list", list.DeepCopy());
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Encode |policy| before adding the "dict" entry.
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string encoded_dict;
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::JSONWriter::Write(&policy, &encoded_dict);
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(encoded_dict.empty());
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.Set("dict", policy.DeepCopy());
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string encoded_list;
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::JSONWriter::Write(&list, &encoded_list);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(encoded_list.empty());
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::DictionaryValue encoded_policy;
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encoded_policy.SetString("null", "");
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encoded_policy.SetString("bool", "1");
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encoded_policy.SetString("int", "-123");
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encoded_policy.SetString("double", "456.78e9");
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encoded_policy.SetString("list", encoded_list);
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encoded_policy.SetString("dict", encoded_dict);
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 kPathSuffix =
9305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions\\string");
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InstallValue(encoded_policy, HKEY_CURRENT_USER, kPathSuffix, kMandatory));
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyBundle expected;
935a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  expected.Get(ns).LoadFrom(&policy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Matches(expected));
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(PolicyLoaderWinTest, LoadIntegerEncodedValues) {
940a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, "int");
941a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(RegisterSchema(
942a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ns,
943a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "{"
944a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  \"type\": \"object\","
945a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  \"properties\": {"
946a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"bool\": { \"type\": \"boolean\" },"
947a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"int\": { \"type\": \"integer\" },"
948a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"double\": { \"type\": \"number\" }"
949a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  }"
950a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "}"));
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::DictionaryValue encoded_policy;
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encoded_policy.SetInteger("bool", 1);
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encoded_policy.SetInteger("int", 123);
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encoded_policy.SetInteger("double", 456);
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 kPathSuffix =
9585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions\\int");
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InstallValue(encoded_policy, HKEY_CURRENT_USER, kPathSuffix, kMandatory));
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
962a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::DictionaryValue policy;
963a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  policy.SetBoolean("bool", true);
964a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  policy.SetInteger("int", 123);
965a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  policy.SetDouble("double", 456.0);
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyBundle expected;
967a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  expected.Get(ns).LoadFrom(&policy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Matches(expected));
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(PolicyLoaderWinTest, DefaultPropertySchemaType) {
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build a schema for an "object" with a default schema for its properties.
973a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Note that the top-level object can't have "additionalProperties", so
974a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // a "policy" property is used instead.
975a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, "test");
976a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(RegisterSchema(
977a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ns,
978a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "{"
979a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  \"type\": \"object\","
980a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  \"properties\": {"
981a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"policy\": {"
982a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "      \"type\": \"object\","
983a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "      \"properties\": {"
984a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "        \"special-int1\": { \"type\": \"integer\" },"
985a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "        \"special-int2\": { \"type\": \"integer\" }"
986a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "      },"
987a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "      \"additionalProperties\": { \"type\": \"number\" }"
988a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    }"
989a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  }"
990a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "}"));
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Write some test values.
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::DictionaryValue policy;
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These special values have a specific schema for them.
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetInteger("special-int1", 123);
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetString("special-int2", "-456");
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Other values default to be loaded as doubles.
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetInteger("double1", 789.0);
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetString("double2", "123.456e7");
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.SetString("invalid", "omg");
1001a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::DictionaryValue all_policies;
1002a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  all_policies.Set("policy", policy.DeepCopy());
1003a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
10045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 kPathSuffix =
10055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions\\test");
1006a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(
1007a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      InstallValue(all_policies, HKEY_CURRENT_USER, kPathSuffix, kMandatory));
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::DictionaryValue expected_policy;
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_policy.SetInteger("special-int1", 123);
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_policy.SetInteger("special-int2", -456);
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_policy.SetDouble("double1", 789.0);
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_policy.SetDouble("double2", 123.456e7);
1014a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::DictionaryValue expected_policies;
1015a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  expected_policies.Set("policy", expected_policy.DeepCopy());
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyBundle expected;
1017a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  expected.Get(ns).LoadFrom(
1018a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &expected_policies, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Matches(expected));
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(PolicyLoaderWinTest, AppliedPolicyNotPresent) {
1023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InstallRegistrySentinel();
1024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_ = NULL;
1025c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_status_ = ERROR_SUCCESS;
1026c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PolicyBundle empty;
1028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(Matches(empty));
1029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1031c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(PolicyLoaderWinTest, AppliedPolicyEmpty) {
1032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InstallRegistrySentinel();
1033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath gpo_dir(test_data_dir_.AppendASCII("empty"));
1034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GROUP_POLICY_OBJECT gpo;
1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_ = &gpo;
1037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_status_ = ERROR_SUCCESS;
1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PolicyBundle empty;
1040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(Matches(empty));
1041c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1043a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(PolicyLoaderWinTest, AppliedPolicyInDomain) {
1044a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::win::SetDomainStateForTesting(true);
1045a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  InstallRegistrySentinel();
1046a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::FilePath gpo_dir(test_data_dir_.AppendASCII("empty"));
1047a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GROUP_POLICY_OBJECT gpo;
1048a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1049a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gpo_list_ = &gpo;
1050a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gpo_list_status_ = ERROR_SUCCESS;
1051a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1052a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PolicyBundle empty;
1053a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(MatchesRegistrySentinel());
1054a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1055a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1056c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(PolicyLoaderWinTest, AppliedPolicyNonExistingFile) {
1057c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InstallRegistrySentinel();
1058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GROUP_POLICY_OBJECT gpo;
1059c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitGPO(&gpo, 0, test_data_dir_, NULL, NULL);
1060c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_ = &gpo;
1061c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_status_ = ERROR_SUCCESS;
1062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(MatchesRegistrySentinel());
1064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(PolicyLoaderWinTest, AppliedPolicyBadPath) {
1067c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InstallRegistrySentinel();
1068c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath gpo_dir(test_data_dir_.AppendASCII("bad"));
1069c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GROUP_POLICY_OBJECT gpo;
1070c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_ = &gpo;
1072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_status_ = ERROR_SUCCESS;
1073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(MatchesRegistrySentinel());
1075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1076c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1077c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(PolicyLoaderWinTest, AppliedPolicyPresent) {
1078c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InstallRegistrySentinel();
1079c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath gpo_dir(test_data_dir_.AppendASCII("test1"));
1080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GROUP_POLICY_OBJECT gpo;
1081c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_ = &gpo;
1083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_status_ = ERROR_SUCCESS;
1084c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1085c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(MatchesTestBundle());
1086c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1087c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1088c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(PolicyLoaderWinTest, AppliedPolicyMerged) {
1089c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InstallRegistrySentinel();
1090c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath gpo1_dir(test_data_dir_.AppendASCII("test2"));
1091c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath gpo2_dir(test_data_dir_.AppendASCII("test1"));
1092c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GROUP_POLICY_OBJECT gpo1;
1093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GROUP_POLICY_OBJECT gpo2;
1094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitGPO(&gpo1, 0, gpo1_dir, &gpo2, NULL);
1095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitGPO(&gpo2, 0, gpo2_dir, NULL, &gpo1);
1096c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_ = &gpo1;
1097c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_status_ = ERROR_SUCCESS;
1098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(MatchesTestBundle());
1100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(PolicyLoaderWinTest, AppliedPolicyDisabled) {
1103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InstallRegistrySentinel();
1104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath gpo1_dir(test_data_dir_.AppendASCII("test1"));
1105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath gpo2_dir(test_data_dir_.AppendASCII("test2"));
1106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GROUP_POLICY_OBJECT gpo1;
1107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GROUP_POLICY_OBJECT gpo2;
1108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitGPO(&gpo1, 0, gpo1_dir, &gpo2, NULL);
1109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitGPO(&gpo2, GPO_FLAG_DISABLE, gpo2_dir, NULL, &gpo1);
1110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_ = &gpo1;
1111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_status_ = ERROR_SUCCESS;
1112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(MatchesTestBundle());
1114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(PolicyLoaderWinTest, AppliedPolicyForcedPolicy) {
1117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InstallRegistrySentinel();
1118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath gpo1_dir(test_data_dir_.AppendASCII("test1"));
1119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath gpo2_dir(test_data_dir_.AppendASCII("test2"));
1120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GROUP_POLICY_OBJECT gpo1;
1121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GROUP_POLICY_OBJECT gpo2;
1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitGPO(&gpo1, GPO_FLAG_FORCE, gpo1_dir, &gpo2, NULL);
1123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitGPO(&gpo2, 0, gpo2_dir, NULL, &gpo1);
1124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_ = &gpo1;
1125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_status_ = ERROR_SUCCESS;
1126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(MatchesTestBundle());
1128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(PolicyLoaderWinTest, AppliedPolicyUNCPath) {
1131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InstallRegistrySentinel();
1132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath gpo_dir(test_data_dir_.AppendASCII("test1"));
1133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath unc_path(L"\\\\some_share\\GPO");
1134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GROUP_POLICY_OBJECT gpo1;
1135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GROUP_POLICY_OBJECT gpo2;
1136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitGPO(&gpo1, 0, gpo_dir, &gpo2, NULL);
1137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitGPO(&gpo2, 0, unc_path, NULL, &gpo1);
1138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_ = &gpo1;
1139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_status_ = ERROR_SUCCESS;
1140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(MatchesRegistrySentinel());
1142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(PolicyLoaderWinTest, LoadExtensionPolicyAlternativeSpelling) {
1145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath gpo_dir(
1146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      test_data_dir_.AppendASCII("extension_alternative_spelling"));
1147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GROUP_POLICY_OBJECT gpo;
1148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_ = &gpo;
1150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpo_list_status_ = ERROR_SUCCESS;
1151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const char kTestSchema[] =
1153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "{"
1154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  \"type\": \"object\","
1155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  \"properties\": {"
1156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"policy 1\": { \"type\": \"integer\" },"
1157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "    \"policy 2\": { \"type\": \"integer\" }"
1158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "  }"
1159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "}";
1160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const PolicyNamespace ns_a(
1161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      POLICY_DOMAIN_EXTENSIONS, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
1162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const PolicyNamespace ns_b(
1163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      POLICY_DOMAIN_EXTENSIONS, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
1164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(RegisterSchema(ns_a, kTestSchema));
1165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(RegisterSchema(ns_b, kTestSchema));
1166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PolicyBundle expected;
1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::DictionaryValue expected_a;
1169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  expected_a.SetInteger("policy 1", 3);
1170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expected_a.SetInteger("policy 2", 3);
1171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  expected.Get(ns_a).LoadFrom(
1172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &expected_a, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE);
1173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::DictionaryValue expected_b;
1174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expected_b.SetInteger("policy 1", 2);
1175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  expected.Get(ns_b).LoadFrom(
1176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &expected_b, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE);
1177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(Matches(expected));
1178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(PolicyLoaderWinTest, LBSSupport) {
1181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const PolicyNamespace ns(
1182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      POLICY_DOMAIN_EXTENSIONS, "heildphpnddilhkemkielfhnkaagiabh");
1183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  schema_registry_.RegisterComponent(ns, Schema());
1184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const char kIncompleteSchema[] =
1186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "{"
1187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       "  \"type\": \"object\","
1188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       "  \"properties\": {"
1189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       "    \"url_list\": { \"type\": \"array\" },"
1190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       "    \"url_greylist\": { \"type\": \"array\" }"
1191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       "  }"
1192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "}";
1193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
11945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 kPathSuffix =
11955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions");
1196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::ListValue list;
1198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  list.AppendString("youtube.com");
1199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::DictionaryValue policy;
1200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  policy.Set("url_list", list.DeepCopy());
1201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  policy.SetString("alternative_browser_path", "c:\\legacy\\browser.exe");
1202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::DictionaryValue root;
12035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root.Set(base::UTF16ToUTF8(kMandatory), policy.DeepCopy());
1204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.SetString(kSchema, kIncompleteSchema);
1205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(InstallValue(root, HKEY_LOCAL_MACHINE,
12065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           kPathSuffix, base::ASCIIToUTF16(ns.component_id)));
1207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PolicyBundle expected;
1209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PolicyMap& expected_policy = expected.Get(ns);
1210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  expected_policy.Set("alternative_browser_path",
1211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
1212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      new base::StringValue("c:\\legacy\\browser.exe"), NULL);
1213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  expected_policy.Set("url_list", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
1214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      list.DeepCopy(), NULL);
1215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(Matches(expected));
1216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace policy
1219