Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1619)

Side by Side Diff: chrome/browser/policy/policy_loader_win.cc

Issue 102493002: Use schemas bundled in extensions to convert policies loaded on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: added bug url Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/policy/policy_loader_win.h" 5 #include "chrome/browser/policy/policy_loader_win.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <rpc.h> // For struct GUID 8 #include <rpc.h> // For struct GUID
9 #include <shlwapi.h> // For PathIsUNC() 9 #include <shlwapi.h> // For PathIsUNC()
10 #include <userenv.h> // For GPO functions 10 #include <userenv.h> // For GPO functions
11 11
12 #include <string> 12 #include <string>
13 #include <vector> 13 #include <vector>
14 14
15 // shlwapi.dll is required for PathIsUNC(). 15 // shlwapi.dll is required for PathIsUNC().
16 #pragma comment(lib, "shlwapi.lib") 16 #pragma comment(lib, "shlwapi.lib")
17 // userenv.dll is required for various GPO functions. 17 // userenv.dll is required for various GPO functions.
18 #pragma comment(lib, "userenv.lib") 18 #pragma comment(lib, "userenv.lib")
19 19
20 #include "base/basictypes.h" 20 #include "base/basictypes.h"
21 #include "base/file_util.h" 21 #include "base/file_util.h"
22 #include "base/json/json_reader.h"
23 #include "base/lazy_instance.h" 22 #include "base/lazy_instance.h"
24 #include "base/logging.h" 23 #include "base/logging.h"
25 #include "base/scoped_native_library.h" 24 #include "base/scoped_native_library.h"
26 #include "base/sequenced_task_runner.h" 25 #include "base/sequenced_task_runner.h"
27 #include "base/stl_util.h" 26 #include "base/stl_util.h"
28 #include "base/strings/string16.h" 27 #include "base/strings/string16.h"
29 #include "base/strings/string_util.h" 28 #include "base/strings/string_util.h"
29 #include "base/values.h"
30 #include "chrome/browser/policy/policy_load_status.h" 30 #include "chrome/browser/policy/policy_load_status.h"
31 #include "chrome/browser/policy/preg_parser_win.h" 31 #include "chrome/browser/policy/preg_parser_win.h"
32 #include "components/json_schema/json_schema_constants.h"
33 #include "components/policy/core/common/policy_bundle.h" 32 #include "components/policy/core/common/policy_bundle.h"
34 #include "components/policy/core/common/policy_map.h" 33 #include "components/policy/core/common/policy_map.h"
35 #include "components/policy/core/common/policy_namespace.h" 34 #include "components/policy/core/common/policy_namespace.h"
36 #include "components/policy/core/common/registry_dict_win.h" 35 #include "components/policy/core/common/registry_dict_win.h"
37 #include "components/policy/core/common/schema.h" 36 #include "components/policy/core/common/schema.h"
38 37
39 namespace schema = json_schema_constants;
40
41 namespace policy { 38 namespace policy {
42 39
43 namespace { 40 namespace {
44 41
45 const char kKeyMandatory[] = "policy"; 42 const char kKeyMandatory[] = "policy";
46 const char kKeyRecommended[] = "recommended"; 43 const char kKeyRecommended[] = "recommended";
47 const char kKeySchema[] = "schema"; 44 const char kKeySchema[] = "schema";
48 const char kKeyThirdParty[] = "3rdparty"; 45 const char kKeyThirdParty[] = "3rdparty";
49 46
50 // The GUID of the registry settings group policy extension. 47 // The GUID of the registry settings group policy extension.
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 154
158 virtual BOOL FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) OVERRIDE { 155 virtual BOOL FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) OVERRIDE {
159 return ::FreeGPOList(gpo_list); 156 return ::FreeGPOList(gpo_list);
160 } 157 }
161 }; 158 };
162 159
163 // The default windows GPO list provider used for PolicyLoaderWin. 160 // The default windows GPO list provider used for PolicyLoaderWin.
164 static base::LazyInstance<WinGPOListProvider> g_win_gpo_list_provider = 161 static base::LazyInstance<WinGPOListProvider> g_win_gpo_list_provider =
165 LAZY_INSTANCE_INITIALIZER; 162 LAZY_INSTANCE_INITIALIZER;
166 163
167 std::string GetSchemaTypeForValueType(base::Value::Type value_type) {
168 switch (value_type) {
169 case base::Value::TYPE_DICTIONARY:
170 return json_schema_constants::kObject;
171 case base::Value::TYPE_INTEGER:
172 return json_schema_constants::kInteger;
173 case base::Value::TYPE_LIST:
174 return json_schema_constants::kArray;
175 case base::Value::TYPE_BOOLEAN:
176 return json_schema_constants::kBoolean;
177 case base::Value::TYPE_STRING:
178 return json_schema_constants::kString;
179 default:
180 break;
181 }
182
183 NOTREACHED() << "Unsupported policy value type " << value_type;
184 return json_schema_constants::kNull;
185 }
186
187 // Parses |gpo_dict| according to |schema| and writes the resulting policy 164 // Parses |gpo_dict| according to |schema| and writes the resulting policy
188 // settings to |policy| for the given |scope| and |level|. 165 // settings to |policy| for the given |scope| and |level|.
189 void ParsePolicy(const RegistryDict* gpo_dict, 166 void ParsePolicy(const RegistryDict* gpo_dict,
190 PolicyLevel level, 167 PolicyLevel level,
191 PolicyScope scope, 168 PolicyScope scope,
192 const base::DictionaryValue* schema, 169 const Schema& schema,
193 PolicyMap* policy) { 170 PolicyMap* policy) {
194 if (!gpo_dict) 171 if (!gpo_dict)
195 return; 172 return;
196 173
197 scoped_ptr<base::Value> policy_value(gpo_dict->ConvertToJSON(schema)); 174 scoped_ptr<base::Value> policy_value(gpo_dict->ConvertToJSON(schema));
198 const base::DictionaryValue* policy_dict = NULL; 175 const base::DictionaryValue* policy_dict = NULL;
199 if (!policy_value->GetAsDictionary(&policy_dict) || !policy_dict) { 176 if (!policy_value->GetAsDictionary(&policy_dict) || !policy_dict) {
200 LOG(WARNING) << "Root policy object is not a dictionary!"; 177 LOG(WARNING) << "Root policy object is not a dictionary!";
201 return; 178 return;
202 } 179 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 is_initialized_ = true; 233 is_initialized_ = true;
257 SetupWatches(); 234 SetupWatches();
258 } 235 }
259 236
260 scoped_ptr<PolicyBundle> PolicyLoaderWin::Load() { 237 scoped_ptr<PolicyBundle> PolicyLoaderWin::Load() {
261 // Reset the watches BEFORE reading the individual policies to avoid 238 // Reset the watches BEFORE reading the individual policies to avoid
262 // missing a change notification. 239 // missing a change notification.
263 if (is_initialized_) 240 if (is_initialized_)
264 SetupWatches(); 241 SetupWatches();
265 242
266 if (chrome_policy_schema_.empty())
267 BuildChromePolicySchema();
268
269 // Policy scope and corresponding hive. 243 // Policy scope and corresponding hive.
270 static const struct { 244 static const struct {
271 PolicyScope scope; 245 PolicyScope scope;
272 HKEY hive; 246 HKEY hive;
273 } kScopes[] = { 247 } kScopes[] = {
274 { POLICY_SCOPE_MACHINE, HKEY_LOCAL_MACHINE }, 248 { POLICY_SCOPE_MACHINE, HKEY_LOCAL_MACHINE },
275 { POLICY_SCOPE_USER, HKEY_CURRENT_USER }, 249 { POLICY_SCOPE_USER, HKEY_CURRENT_USER },
276 }; 250 };
277 251
278 // Load policy data for the different scopes/levels and merge them. 252 // Load policy data for the different scopes/levels and merge them.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 chrome_policy); 293 chrome_policy);
320 294
321 // Load 3rd-party policy. 295 // Load 3rd-party policy.
322 if (third_party_dict) 296 if (third_party_dict)
323 Load3rdPartyPolicy(third_party_dict.get(), scope, bundle.get()); 297 Load3rdPartyPolicy(third_party_dict.get(), scope, bundle.get());
324 } 298 }
325 299
326 return bundle.Pass(); 300 return bundle.Pass();
327 } 301 }
328 302
329 void PolicyLoaderWin::BuildChromePolicySchema() {
330 // TODO(joaodasilva): use the Schema directly instead of building this
331 // DictionaryValue.
332 scoped_ptr<base::DictionaryValue> properties(new base::DictionaryValue());
333 const Schema* chrome_schema =
334 schema_map()->GetSchema(PolicyNamespace(POLICY_DOMAIN_CHROME, ""));
335 for (Schema::Iterator it = chrome_schema->GetPropertiesIterator();
336 !it.IsAtEnd(); it.Advance()) {
337 const std::string schema_type =
338 GetSchemaTypeForValueType(it.schema().type());
339 scoped_ptr<base::DictionaryValue> entry_schema(new base::DictionaryValue());
340 entry_schema->SetStringWithoutPathExpansion(json_schema_constants::kType,
341 schema_type);
342
343 if (it.schema().type() == base::Value::TYPE_LIST) {
344 scoped_ptr<base::DictionaryValue> items_schema(
345 new base::DictionaryValue());
346 items_schema->SetStringWithoutPathExpansion(
347 json_schema_constants::kType, json_schema_constants::kString);
348 entry_schema->SetWithoutPathExpansion(json_schema_constants::kItems,
349 items_schema.release());
350 }
351 properties->SetWithoutPathExpansion(it.key(), entry_schema.release());
352 }
353 chrome_policy_schema_.SetStringWithoutPathExpansion(
354 json_schema_constants::kType, json_schema_constants::kObject);
355 chrome_policy_schema_.SetWithoutPathExpansion(
356 json_schema_constants::kProperties, properties.release());
357 }
358
359 bool PolicyLoaderWin::ReadPRegFile(const base::FilePath& preg_file, 303 bool PolicyLoaderWin::ReadPRegFile(const base::FilePath& preg_file,
360 RegistryDict* policy, 304 RegistryDict* policy,
361 PolicyLoadStatusSample* status) { 305 PolicyLoadStatusSample* status) {
362 // The following deals with the minor annoyance that Wow64 FS redirection 306 // The following deals with the minor annoyance that Wow64 FS redirection
363 // might need to be turned off: This is the case if running as a 32-bit 307 // might need to be turned off: This is the case if running as a 32-bit
364 // process on a 64-bit system, in which case Wow64 FS redirection redirects 308 // process on a 64-bit system, in which case Wow64 FS redirection redirects
365 // access to the %WINDIR%/System32/GroupPolicy directory to 309 // access to the %WINDIR%/System32/GroupPolicy directory to
366 // %WINDIR%/SysWOW64/GroupPolicy, but the file is actually in the 310 // %WINDIR%/SysWOW64/GroupPolicy, but the file is actually in the
367 // system-native directory. 311 // system-native directory.
368 if (base::PathExists(preg_file)) { 312 if (base::PathExists(preg_file)) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 } 393 }
450 394
451 return result; 395 return result;
452 } 396 }
453 397
454 void PolicyLoaderWin::LoadChromePolicy(const RegistryDict* gpo_dict, 398 void PolicyLoaderWin::LoadChromePolicy(const RegistryDict* gpo_dict,
455 PolicyLevel level, 399 PolicyLevel level,
456 PolicyScope scope, 400 PolicyScope scope,
457 PolicyMap* chrome_policy_map) { 401 PolicyMap* chrome_policy_map) {
458 PolicyMap policy; 402 PolicyMap policy;
459 ParsePolicy(gpo_dict, level, scope, &chrome_policy_schema_, &policy); 403 const Schema* chrome_schema =
404 schema_map()->GetSchema(PolicyNamespace(POLICY_DOMAIN_CHROME, ""));
405 ParsePolicy(gpo_dict, level, scope, *chrome_schema, &policy);
460 chrome_policy_map->MergeFrom(policy); 406 chrome_policy_map->MergeFrom(policy);
461 } 407 }
462 408
463 void PolicyLoaderWin::Load3rdPartyPolicy(const RegistryDict* gpo_dict, 409 void PolicyLoaderWin::Load3rdPartyPolicy(const RegistryDict* gpo_dict,
464 PolicyScope scope, 410 PolicyScope scope,
465 PolicyBundle* bundle) { 411 PolicyBundle* bundle) {
466 // Map of known 3rd party policy domain name to their enum values. 412 // Map of known 3rd party policy domain name to their enum values.
467 static const struct { 413 static const struct {
468 const char* name; 414 const char* name;
469 PolicyDomain domain; 415 PolicyDomain domain;
(...skipping 14 matching lines...) Expand all
484 const char* name = k3rdPartyDomains[i].name; 430 const char* name = k3rdPartyDomains[i].name;
485 const PolicyDomain domain = k3rdPartyDomains[i].domain; 431 const PolicyDomain domain = k3rdPartyDomains[i].domain;
486 const RegistryDict* domain_dict = gpo_dict->GetKey(name); 432 const RegistryDict* domain_dict = gpo_dict->GetKey(name);
487 if (!domain_dict) 433 if (!domain_dict)
488 continue; 434 continue;
489 435
490 for (RegistryDict::KeyMap::const_iterator component( 436 for (RegistryDict::KeyMap::const_iterator component(
491 domain_dict->keys().begin()); 437 domain_dict->keys().begin());
492 component != domain_dict->keys().end(); 438 component != domain_dict->keys().end();
493 ++component) { 439 ++component) {
494 // Load the schema. 440 const PolicyNamespace policy_namespace(domain, component->first);
495 const base::DictionaryValue* schema_dict = NULL; 441
496 scoped_ptr<base::Value> schema; 442 Schema schema;
497 std::string schema_json; 443 const Schema* schema_from_map = schema_map()->GetSchema(policy_namespace);
498 const base::Value* schema_value = component->second->GetValue(kKeySchema); 444 if (schema_from_map)
499 if (schema_value && schema_value->GetAsString(&schema_json)) { 445 schema = *schema_from_map;
500 schema.reset(base::JSONReader::Read(schema_json)); 446 if (!schema.valid()) {
501 if (!schema || !schema->GetAsDictionary(&schema_dict)) { 447 // TODO(joaodasilva): the schema should come from the schema_map(), but
502 LOG(WARNING) << "Failed to parse 3rd-part policy schema for " 448 // the Legacy Browser Support extension was launched when this loader
503 << domain << "/" << component->first; 449 // used a schema embedded in the registry. Remove this for M35.
450 // http://crbug.com/325349
451 std::string schema_json;
452 const base::Value* value = component->second->GetValue(kKeySchema);
453 if (value && value->GetAsString(&schema_json)) {
454 std::string error;
455 schema = Schema::ParseWithBackwardsCompatibility(
456 schema_json, &error, true);
457 if (!schema.valid()) {
458 LOG(WARNING) << "Invalid schema in the registry for "
459 << name << "/" << component->first << ": " << error;
460 }
504 } 461 }
505 } 462 }
506 463
507 // Parse policy. 464 // Parse policy.
508 for (size_t j = 0; j < arraysize(kLevels); j++) { 465 for (size_t j = 0; j < arraysize(kLevels); j++) {
509 const RegistryDict* policy_dict = 466 const RegistryDict* policy_dict =
510 component->second->GetKey(kLevels[j].path); 467 component->second->GetKey(kLevels[j].path);
511 if (!policy_dict) 468 if (!policy_dict)
512 continue; 469 continue;
513 470
514 PolicyMap policy; 471 PolicyMap policy;
515 ParsePolicy(policy_dict, kLevels[j].level, scope, schema_dict, &policy); 472 ParsePolicy(policy_dict, kLevels[j].level, scope, schema, &policy);
516 PolicyNamespace policy_namespace(domain, component->first);
517 bundle->Get(policy_namespace).MergeFrom(policy); 473 bundle->Get(policy_namespace).MergeFrom(policy);
518 } 474 }
519 } 475 }
520 } 476 }
521 } 477 }
522 478
523 void PolicyLoaderWin::SetupWatches() { 479 void PolicyLoaderWin::SetupWatches() {
524 DCHECK(is_initialized_); 480 DCHECK(is_initialized_);
525 if (!user_policy_watcher_failed_ && 481 if (!user_policy_watcher_failed_ &&
526 !user_policy_watcher_.GetWatchedObject() && 482 !user_policy_watcher_.GetWatchedObject() &&
(...skipping 13 matching lines...) Expand all
540 496
541 void PolicyLoaderWin::OnObjectSignaled(HANDLE object) { 497 void PolicyLoaderWin::OnObjectSignaled(HANDLE object) {
542 DCHECK(object == user_policy_changed_event_.handle() || 498 DCHECK(object == user_policy_changed_event_.handle() ||
543 object == machine_policy_changed_event_.handle()) 499 object == machine_policy_changed_event_.handle())
544 << "unexpected object signaled policy reload, obj = " 500 << "unexpected object signaled policy reload, obj = "
545 << std::showbase << std::hex << object; 501 << std::showbase << std::hex << object;
546 Reload(false); 502 Reload(false);
547 } 503 }
548 504
549 } // namespace policy 505 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698