1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file. 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/schema_map.h" 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h" 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/values.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_bundle.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_map.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace policy { 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SchemaMap::SchemaMap() {} 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SchemaMap::SchemaMap(DomainMap& map) { 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) map_.swap(map); 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SchemaMap::~SchemaMap() {} 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const DomainMap& SchemaMap::GetDomains() const { 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return map_; 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const ComponentMap* SchemaMap::GetComponents(PolicyDomain domain) const { 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DomainMap::const_iterator it = map_.find(domain); 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return it == map_.end() ? NULL : &it->second; 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const Schema* SchemaMap::GetSchema(const PolicyNamespace& ns) const { 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const ComponentMap* map = GetComponents(ns.domain); 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!map) 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NULL; 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ComponentMap::const_iterator it = map->find(ns.component_id); 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return it == map->end() ? NULL : &it->second; 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SchemaMap::FilterBundle(PolicyBundle* bundle) const { 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (PolicyBundle::iterator it = bundle->begin(); it != bundle->end(); ++it) { 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Chrome policies are not filtered, so that typos appear in about:policy. 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Everything else gets filtered, so that components only see valid policy. 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (it->first.domain == POLICY_DOMAIN_CHROME) 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue; 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Schema* schema = GetSchema(it->first); 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!schema) { 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it->second->Clear(); 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue; 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(joaodasilva): if a component is registered but doesn't have a schema 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // then its policies aren't filtered. This behavior is enabled to allow a 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // graceful update of the Legacy Browser Support extension; it'll be removed 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // in a future release. http://crbug.com/240704 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static const char kLegacyBrowserSupportExtensionId[] = 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "heildphpnddilhkemkielfhnkaagiabh"; 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (it->first.domain == POLICY_DOMAIN_EXTENSIONS && 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it->first.component_id == kLegacyBrowserSupportExtensionId) { 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue; 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!schema->valid()) { 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Don't serve unknown policies. 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it->second->Clear(); 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch continue; 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyMap* map = it->second; 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (PolicyMap::const_iterator it_map = map->begin(); 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it_map != map->end();) { 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& policy_name = it_map->first; 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const base::Value* policy_value = it_map->second.value; 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Schema policy_schema = schema->GetProperty(policy_name); 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ++it_map; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string error_path; 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string error; 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!policy_value || 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !policy_schema.Validate(*policy_value, 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SCHEMA_STRICT, 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &error_path, 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &error)) { 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << "Dropping policy " << policy_name << " for " 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << it->first.component_id 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " because it's not valid: " << error 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " at " << error_path; 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) map->Erase(policy_name); 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool SchemaMap::HasComponents() const { 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (DomainMap::const_iterator domain = map_.begin(); 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) domain != map_.end(); ++domain) { 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (domain->first == POLICY_DOMAIN_CHROME) 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue; 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!domain->second.empty()) 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SchemaMap::GetChanges(const scoped_refptr<SchemaMap>& older, 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyNamespaceList* removed, 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyNamespaceList* added) const { 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetNamespacesNotInOther(older.get(), added); 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) older->GetNamespacesNotInOther(this, removed); 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SchemaMap::GetNamespacesNotInOther(const SchemaMap* other, 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyNamespaceList* list) const { 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) list->clear(); 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (DomainMap::const_iterator domain = map_.begin(); 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) domain != map_.end(); ++domain) { 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const ComponentMap& components = domain->second; 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (ComponentMap::const_iterator comp = components.begin(); 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) comp != components.end(); ++comp) { 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PolicyNamespace ns(domain->first, comp->first); 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!other->GetSchema(ns)) 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) list->push_back(ns); 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace policy 128