190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/policy/policy_domain_descriptor.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/logging.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/stl_util.h" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/values.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/policy/policy_bundle.h" 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/policy/policy_map.h" 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/common/policy/policy_schema.h" 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace policy { 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace { 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool Matches(const PolicySchema* schema, const base::Value& value) { 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!schema) { 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Schema not found, invalid entry. 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!value.IsType(schema->type())) 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::DictionaryValue* dict = NULL; 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::ListValue* list = NULL; 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value.GetAsDictionary(&dict)) { 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it.Advance()) { 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!Matches(schema->GetSchemaForProperty(it.key()), it.value())) 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else if (value.GetAsList(&list)) { 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (base::ListValue::const_iterator it = list->begin(); 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it != list->end(); ++it) { 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!*it || !Matches(schema->GetSchemaForItems(), **it)) 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)PolicyDomainDescriptor::PolicyDomainDescriptor(PolicyDomain domain) 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : domain_(domain) {} 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PolicyDomainDescriptor::RegisterComponent( 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& component_id, 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<PolicySchema> schema) { 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const PolicySchema*& entry = schema_map_[component_id]; 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delete entry; 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry = schema.release(); 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PolicyDomainDescriptor::FilterBundle(PolicyBundle* bundle) const { 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Chrome policies are not filtered, so that typos appear in about:policy. 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_NE(POLICY_DOMAIN_CHROME, domain_); 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (PolicyBundle::iterator it_bundle = bundle->begin(); 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it_bundle != bundle->end(); ++it_bundle) { 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const PolicyNamespace& ns = it_bundle->first; 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (ns.domain != domain_) 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SchemaMap::const_iterator it_schema = schema_map_.find(ns.component_id); 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (it_schema == schema_map_.end()) { 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Component ID not found. 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it_bundle->second->Clear(); 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(joaodasilva): if a component is registered but doesn't have a schema 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // then its policies aren't filtered. This behavior is enabled for M29 to 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // allow a graceful update of the Legacy Browser Support extension; it'll 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // be removed for M30. http://crbug.com/240704 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!it_schema->second) 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const PolicySchema* component_schema = it_schema->second; 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PolicyMap* map = it_bundle->second; 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (PolicyMap::const_iterator it_map = map->begin(); 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it_map != map->end();) { 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& policy_name = it_map->first; 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Value* policy_value = it_map->second.value; 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const PolicySchema* policy_schema = 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) component_schema->GetSchemaForProperty(policy_name); 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ++it_map; 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!policy_value || !Matches(policy_schema, *policy_value)) 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) map->Erase(policy_name); 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)PolicyDomainDescriptor::~PolicyDomainDescriptor() { 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) STLDeleteValues(&schema_map_); 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace policy 103