| Index: components/policy/core/common/policy_loader_win.cc
|
| diff --git a/components/policy/core/common/policy_loader_win.cc b/components/policy/core/common/policy_loader_win.cc
|
| index 799b2b21710d4b7173acbb245fa851f8249ef734..ba1072f1cf2a3070e0044de389121ac45a21e0fb 100644
|
| --- a/components/policy/core/common/policy_loader_win.cc
|
| +++ b/components/policy/core/common/policy_loader_win.cc
|
| @@ -20,6 +20,7 @@
|
| #include "base/basictypes.h"
|
| #include "base/file_util.h"
|
| #include "base/json/json_reader.h"
|
| +#include "base/json/json_writer.h"
|
| #include "base/lazy_instance.h"
|
| #include "base/logging.h"
|
| #include "base/scoped_native_library.h"
|
| @@ -27,6 +28,7 @@
|
| #include "base/stl_util.h"
|
| #include "base/strings/string16.h"
|
| #include "base/strings/string_util.h"
|
| +#include "base/values.h"
|
| #include "components/json_schema/json_schema_constants.h"
|
| #include "components/policy/core/common/policy_bundle.h"
|
| #include "components/policy/core/common/policy_load_status.h"
|
| @@ -47,9 +49,49 @@ const char kKeyRecommended[] = "recommended";
|
| const char kKeySchema[] = "schema";
|
| const char kKeyThirdParty[] = "3rdparty";
|
|
|
| +// The Legacy Browser Support was the first user of the policy-for-extensions
|
| +// API, and relied on behavior that will be phased out. If this extension is
|
| +// present then its policies will be loaded in a special way.
|
| +// TODO(joaodasilva): remove this for M35. http://crbug.com/325349
|
| +const char kLegacyBrowserSupportExtensionId[] =
|
| + "heildphpnddilhkemkielfhnkaagiabh";
|
| +
|
| // The GUID of the registry settings group policy extension.
|
| GUID kRegistrySettingsCSEGUID = REGISTRY_EXTENSION_GUID;
|
|
|
| +// If the LBS extension is found and contains a schema in the registry then this
|
| +// function is used to patch it, and make it compliant. The fix is to
|
| +// add an "items" attribute to lists that don't declare it.
|
| +std::string PatchSchema(const std::string& schema) {
|
| + base::JSONParserOptions options = base::JSON_PARSE_RFC;
|
| + scoped_ptr<base::Value> json(base::JSONReader::Read(schema, options));
|
| + base::DictionaryValue* dict = NULL;
|
| + base::DictionaryValue* properties = NULL;
|
| + if (!json ||
|
| + !json->GetAsDictionary(&dict) ||
|
| + !dict->GetDictionary(schema::kProperties, &properties)) {
|
| + return schema;
|
| + }
|
| +
|
| + for (base::DictionaryValue::Iterator it(*properties);
|
| + !it.IsAtEnd(); it.Advance()) {
|
| + base::DictionaryValue* policy_schema = NULL;
|
| + std::string type;
|
| + if (properties->GetDictionary(it.key(), &policy_schema) &&
|
| + policy_schema->GetString(schema::kType, &type) &&
|
| + type == schema::kArray &&
|
| + !policy_schema->HasKey(schema::kItems)) {
|
| + scoped_ptr<base::DictionaryValue> items(new base::DictionaryValue());
|
| + items->SetString(schema::kType, schema::kString);
|
| + policy_schema->Set(schema::kItems, items.release());
|
| + }
|
| + }
|
| +
|
| + std::string serialized;
|
| + base::JSONWriter::Write(json.get(), &serialized);
|
| + return serialized;
|
| +}
|
| +
|
| // A helper class encapsulating run-time-linked function calls to Wow64 APIs.
|
| class Wow64Functions {
|
| public:
|
| @@ -164,32 +206,12 @@ class WinGPOListProvider : public AppliedGPOListProvider {
|
| static base::LazyInstance<WinGPOListProvider> g_win_gpo_list_provider =
|
| LAZY_INSTANCE_INITIALIZER;
|
|
|
| -std::string GetSchemaTypeForValueType(base::Value::Type value_type) {
|
| - switch (value_type) {
|
| - case base::Value::TYPE_DICTIONARY:
|
| - return json_schema_constants::kObject;
|
| - case base::Value::TYPE_INTEGER:
|
| - return json_schema_constants::kInteger;
|
| - case base::Value::TYPE_LIST:
|
| - return json_schema_constants::kArray;
|
| - case base::Value::TYPE_BOOLEAN:
|
| - return json_schema_constants::kBoolean;
|
| - case base::Value::TYPE_STRING:
|
| - return json_schema_constants::kString;
|
| - default:
|
| - break;
|
| - }
|
| -
|
| - NOTREACHED() << "Unsupported policy value type " << value_type;
|
| - return json_schema_constants::kNull;
|
| -}
|
| -
|
| // Parses |gpo_dict| according to |schema| and writes the resulting policy
|
| // settings to |policy| for the given |scope| and |level|.
|
| void ParsePolicy(const RegistryDict* gpo_dict,
|
| PolicyLevel level,
|
| PolicyScope scope,
|
| - const base::DictionaryValue* schema,
|
| + const Schema& schema,
|
| PolicyMap* policy) {
|
| if (!gpo_dict)
|
| return;
|
| @@ -263,9 +285,6 @@ scoped_ptr<PolicyBundle> PolicyLoaderWin::Load() {
|
| if (is_initialized_)
|
| SetupWatches();
|
|
|
| - if (chrome_policy_schema_.empty())
|
| - BuildChromePolicySchema();
|
| -
|
| // Policy scope and corresponding hive.
|
| static const struct {
|
| PolicyScope scope;
|
| @@ -326,36 +345,6 @@ scoped_ptr<PolicyBundle> PolicyLoaderWin::Load() {
|
| return bundle.Pass();
|
| }
|
|
|
| -void PolicyLoaderWin::BuildChromePolicySchema() {
|
| - // TODO(joaodasilva): use the Schema directly instead of building this
|
| - // DictionaryValue.
|
| - scoped_ptr<base::DictionaryValue> properties(new base::DictionaryValue());
|
| - const Schema* chrome_schema =
|
| - schema_map()->GetSchema(PolicyNamespace(POLICY_DOMAIN_CHROME, ""));
|
| - for (Schema::Iterator it = chrome_schema->GetPropertiesIterator();
|
| - !it.IsAtEnd(); it.Advance()) {
|
| - const std::string schema_type =
|
| - GetSchemaTypeForValueType(it.schema().type());
|
| - scoped_ptr<base::DictionaryValue> entry_schema(new base::DictionaryValue());
|
| - entry_schema->SetStringWithoutPathExpansion(json_schema_constants::kType,
|
| - schema_type);
|
| -
|
| - if (it.schema().type() == base::Value::TYPE_LIST) {
|
| - scoped_ptr<base::DictionaryValue> items_schema(
|
| - new base::DictionaryValue());
|
| - items_schema->SetStringWithoutPathExpansion(
|
| - json_schema_constants::kType, json_schema_constants::kString);
|
| - entry_schema->SetWithoutPathExpansion(json_schema_constants::kItems,
|
| - items_schema.release());
|
| - }
|
| - properties->SetWithoutPathExpansion(it.key(), entry_schema.release());
|
| - }
|
| - chrome_policy_schema_.SetStringWithoutPathExpansion(
|
| - json_schema_constants::kType, json_schema_constants::kObject);
|
| - chrome_policy_schema_.SetWithoutPathExpansion(
|
| - json_schema_constants::kProperties, properties.release());
|
| -}
|
| -
|
| bool PolicyLoaderWin::ReadPRegFile(const base::FilePath& preg_file,
|
| RegistryDict* policy,
|
| PolicyLoadStatusSample* status) {
|
| @@ -456,7 +445,9 @@ void PolicyLoaderWin::LoadChromePolicy(const RegistryDict* gpo_dict,
|
| PolicyScope scope,
|
| PolicyMap* chrome_policy_map) {
|
| PolicyMap policy;
|
| - ParsePolicy(gpo_dict, level, scope, &chrome_policy_schema_, &policy);
|
| + const Schema* chrome_schema =
|
| + schema_map()->GetSchema(PolicyNamespace(POLICY_DOMAIN_CHROME, ""));
|
| + ParsePolicy(gpo_dict, level, scope, *chrome_schema, &policy);
|
| chrome_policy_map->MergeFrom(policy);
|
| }
|
|
|
| @@ -491,16 +482,26 @@ void PolicyLoaderWin::Load3rdPartyPolicy(const RegistryDict* gpo_dict,
|
| domain_dict->keys().begin());
|
| component != domain_dict->keys().end();
|
| ++component) {
|
| - // Load the schema.
|
| - const base::DictionaryValue* schema_dict = NULL;
|
| - scoped_ptr<base::Value> schema;
|
| - std::string schema_json;
|
| - const base::Value* schema_value = component->second->GetValue(kKeySchema);
|
| - if (schema_value && schema_value->GetAsString(&schema_json)) {
|
| - schema.reset(base::JSONReader::Read(schema_json));
|
| - if (!schema || !schema->GetAsDictionary(&schema_dict)) {
|
| - LOG(WARNING) << "Failed to parse 3rd-part policy schema for "
|
| - << domain << "/" << component->first;
|
| + const PolicyNamespace policy_namespace(domain, component->first);
|
| +
|
| + const Schema* schema_from_map = schema_map()->GetSchema(policy_namespace);
|
| + if (!schema_from_map) {
|
| + // This extension isn't installed or doesn't support policies.
|
| + continue;
|
| + }
|
| + Schema schema = *schema_from_map;
|
| +
|
| + if (!schema.valid() &&
|
| + policy_namespace.domain == POLICY_DOMAIN_EXTENSIONS &&
|
| + policy_namespace.component_id == kLegacyBrowserSupportExtensionId) {
|
| + // TODO(joaodasilva): remove this special treatment for LBS by M35.
|
| + std::string schema_json;
|
| + const base::Value* value = component->second->GetValue(kKeySchema);
|
| + if (value && value->GetAsString(&schema_json)) {
|
| + std::string error;
|
| + schema = Schema::Parse(PatchSchema(schema_json), &error);
|
| + if (!schema.valid())
|
| + LOG(WARNING) << "Invalid schema in the registry for LBS: " << error;
|
| }
|
| }
|
|
|
| @@ -512,8 +513,7 @@ void PolicyLoaderWin::Load3rdPartyPolicy(const RegistryDict* gpo_dict,
|
| continue;
|
|
|
| PolicyMap policy;
|
| - ParsePolicy(policy_dict, kLevels[j].level, scope, schema_dict, &policy);
|
| - PolicyNamespace policy_namespace(domain, component->first);
|
| + ParsePolicy(policy_dict, kLevels[j].level, scope, schema, &policy);
|
| bundle->Get(policy_namespace).MergeFrom(policy);
|
| }
|
| }
|
|
|