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

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

Issue 10656046: Use a schema to decode 3rd party policy on windows, when present. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 6 months 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 <string> 7 #include <string>
8 8
9 #include <string.h> 9 #include <string.h>
10 10
(...skipping 16 matching lines...) Expand all
27 #include "policy/policy_constants.h" 27 #include "policy/policy_constants.h"
28 28
29 using base::win::RegKey; 29 using base::win::RegKey;
30 using base::win::RegistryKeyIterator; 30 using base::win::RegistryKeyIterator;
31 using base::win::RegistryValueIterator; 31 using base::win::RegistryValueIterator;
32 32
33 namespace policy { 33 namespace policy {
34 34
35 namespace { 35 namespace {
36 36
37 // Path separator for registry keys.
38 const wchar_t kPathSep[] = L"\\";
39
37 // Suffix of kRegistryMandatorySubKey where 3rd party policies are stored. 40 // Suffix of kRegistryMandatorySubKey where 3rd party policies are stored.
38 const char k3rdPartyPolicySubKey[] = "\\3rdparty\\"; 41 const char k3rdPartyPolicySubKey[] = "\\3rdparty\\";
39 42
40 // Path separator for registry keys. 43 // Registry value that contains a component's schema.
41 const wchar_t kPathSep[] = L"\\"; 44 const wchar_t kSchema[] = L"schema";
45
46 // Entry in a JSON schema that contains the expected type of an entry.
47 const char kType[] = "type";
48
49 // Entry in a JSON schema that describes the expected properties of an object.
50 const char kProperties[] = "properties";
51
52 // Entry in a JSON schema that describes the expected type of array elements.
53 const char kItems[] = "items";
42 54
43 // Map of registry hives to their corresponding policy scope, in decreasing 55 // Map of registry hives to their corresponding policy scope, in decreasing
44 // order of priority. 56 // order of priority.
45 const struct { 57 const struct {
46 HKEY hive; 58 HKEY hive;
47 PolicyScope scope; 59 PolicyScope scope;
48 } kHives[] = { 60 } kHives[] = {
49 { HKEY_LOCAL_MACHINE, POLICY_SCOPE_MACHINE }, 61 { HKEY_LOCAL_MACHINE, POLICY_SCOPE_MACHINE },
50 { HKEY_CURRENT_USER, POLICY_SCOPE_USER }, 62 { HKEY_CURRENT_USER, POLICY_SCOPE_USER },
51 }; 63 };
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 uint32* result) { 138 uint32* result) {
127 DWORD dword; 139 DWORD dword;
128 if (key->ReadValueDW(name.c_str(), &dword) != ERROR_SUCCESS) 140 if (key->ReadValueDW(name.c_str(), &dword) != ERROR_SUCCESS)
129 return false; 141 return false;
130 *result = dword; 142 *result = dword;
131 return true; 143 return true;
132 } 144 }
133 145
134 // Returns the Value for a Chrome string policy named |name|, or NULL if 146 // Returns the Value for a Chrome string policy named |name|, or NULL if
135 // it wasn't found. The caller owns the returned value. 147 // it wasn't found. The caller owns the returned value.
136 base::Value* ReadStringValue(const string16& name, 148 base::Value* ReadChromeStringValue(const string16& name,
137 PolicyLevel* level, 149 PolicyLevel* level,
138 PolicyScope* scope) { 150 PolicyScope* scope) {
139 RegKey key; 151 RegKey key;
140 if (!LoadHighestPriorityKey(string16(), name, &key, level, scope)) 152 if (!LoadHighestPriorityKey(string16(), name, &key, level, scope))
141 return NULL; 153 return NULL;
142 string16 value; 154 string16 value;
143 if (!ReadRegistryString(&key, name, &value)) 155 if (!ReadRegistryString(&key, name, &value))
144 return NULL; 156 return NULL;
145 return base::Value::CreateStringValue(value); 157 return base::Value::CreateStringValue(value);
146 } 158 }
147 159
148 // Returns the Value for a Chrome string list policy named |name|, 160 // Returns the Value for a Chrome string list policy named |name|,
149 // or NULL if it wasn't found. The caller owns the returned value. 161 // or NULL if it wasn't found. The caller owns the returned value.
150 base::Value* ReadStringListValue(const string16& name, 162 base::Value* ReadChromeStringListValue(const string16& name,
151 PolicyLevel* level, 163 PolicyLevel* level,
152 PolicyScope* scope) { 164 PolicyScope* scope) {
153 RegKey key; 165 RegKey key;
154 if (!LoadHighestPriorityKey(name, string16(), &key, level, scope)) 166 if (!LoadHighestPriorityKey(name, string16(), &key, level, scope))
155 return NULL; 167 return NULL;
156 base::ListValue* result = new base::ListValue(); 168 base::ListValue* result = new base::ListValue();
157 string16 value; 169 string16 value;
158 int index = 0; 170 int index = 0;
159 while (ReadRegistryString(&key, base::IntToString16(++index), &value)) 171 while (ReadRegistryString(&key, base::IntToString16(++index), &value))
160 result->Append(base::Value::CreateStringValue(value)); 172 result->Append(base::Value::CreateStringValue(value));
161 return result; 173 return result;
162 } 174 }
163 175
164 // Returns the Value for a Chrome boolean policy named |name|, 176 // Returns the Value for a Chrome boolean policy named |name|,
165 // or NULL if it wasn't found. The caller owns the returned value. 177 // or NULL if it wasn't found. The caller owns the returned value.
166 base::Value* ReadBooleanValue(const string16& name, 178 base::Value* ReadChromeBooleanValue(const string16& name,
167 PolicyLevel* level, 179 PolicyLevel* level,
168 PolicyScope* scope) { 180 PolicyScope* scope) {
169 RegKey key; 181 RegKey key;
170 if (!LoadHighestPriorityKey(string16(), name, &key, level, scope)) 182 if (!LoadHighestPriorityKey(string16(), name, &key, level, scope))
171 return NULL; 183 return NULL;
172 uint32 value; 184 uint32 value;
173 if (!ReadRegistryInteger(&key, name, &value)) 185 if (!ReadRegistryInteger(&key, name, &value))
174 return NULL; 186 return NULL;
175 return base::Value::CreateBooleanValue(value != 0u); 187 return base::Value::CreateBooleanValue(value != 0u);
176 } 188 }
177 189
178 // Returns the Value for a Chrome integer policy named |name|, 190 // Returns the Value for a Chrome integer policy named |name|,
179 // or NULL if it wasn't found. The caller owns the returned value. 191 // or NULL if it wasn't found. The caller owns the returned value.
180 base::Value* ReadIntegerValue(const string16& name, 192 base::Value* ReadChromeIntegerValue(const string16& name,
181 PolicyLevel* level, 193 PolicyLevel* level,
182 PolicyScope* scope) { 194 PolicyScope* scope) {
183 RegKey key; 195 RegKey key;
184 if (!LoadHighestPriorityKey(string16(), name, &key, level, scope)) 196 if (!LoadHighestPriorityKey(string16(), name, &key, level, scope))
185 return NULL; 197 return NULL;
186 uint32 value; 198 uint32 value;
187 if (!ReadRegistryInteger(&key, name, &value)) 199 if (!ReadRegistryInteger(&key, name, &value))
188 return NULL; 200 return NULL;
189 return base::Value::CreateIntegerValue(value); 201 return base::Value::CreateIntegerValue(value);
190 } 202 }
191 203
192 // Returns the Value for a Chrome dictionary policy named |name|, 204 // Returns the Value for a Chrome dictionary policy named |name|,
193 // or NULL if it wasn't found. The caller owns the returned value. 205 // or NULL if it wasn't found. The caller owns the returned value.
194 base::Value* ReadDictionaryValue(const string16& name, 206 base::Value* ReadChromeDictionaryValue(const string16& name,
195 PolicyLevel* level, 207 PolicyLevel* level,
196 PolicyScope* scope) { 208 PolicyScope* scope) {
197 // Dictionaries are encoded as JSON strings on Windows. 209 // Dictionaries are encoded as JSON strings on Windows.
198 // 210 //
199 // A dictionary could be stored as a subkey, with each of its entries 211 // A dictionary could be stored as a subkey, with each of its entries
200 // within that subkey. However, it would be impossible to recover the 212 // within that subkey. However, it would be impossible to recover the
201 // type for some of those entries: 213 // type for some of those entries:
202 // - Booleans are stored as DWORDS and are indistinguishable from 214 // - Booleans are stored as DWORDS and are indistinguishable from
203 // integers; 215 // integers;
204 // - Lists are stored as a subkey, with entries mapping 0 to N-1 to 216 // - Lists are stored as a subkey, with entries mapping 0 to N-1 to
205 // their value. This is indistinguishable from a Dictionary with 217 // their value. This is indistinguishable from a Dictionary with
206 // integer keys. 218 // integer keys.
207 // 219 //
208 // The GPO policy editor also has a limited data entry form that doesn't 220 // The GPO policy editor also has a limited data entry form that doesn't
209 // support dictionaries. 221 // support dictionaries.
210 RegKey key; 222 RegKey key;
211 if (!LoadHighestPriorityKey(string16(), name, &key, level, scope)) 223 if (!LoadHighestPriorityKey(string16(), name, &key, level, scope))
212 return NULL; 224 return NULL;
213 string16 value; 225 string16 value;
214 if (!ReadRegistryString(&key, name, &value)) 226 if (!ReadRegistryString(&key, name, &value))
215 return NULL; 227 return NULL;
216 return base::JSONReader::Read(UTF16ToUTF8(value)); 228 return base::JSONReader::Read(UTF16ToUTF8(value));
217 } 229 }
218 230
219 // Loads the dictionary at |path| in the given |hive|. Ownership is transferred 231 // Returns the Value type described in |schema|, or |default_type| if not found.
220 // to the caller. 232 base::Value::Type GetType(const base::DictionaryValue* schema,
221 base::DictionaryValue* ReadRegistryDictionaryValue(HKEY hive, 233 base::Value::Type default_type) {
222 const string16& path) { 234 // JSON-schema types to base::Value::Type mapping.
235 static const struct {
236 // JSON schema type.
237 const char* schema_type;
238 // Correspondent value type.
239 base::Value::Type value_type;
240 } kSchemaToValueTypeMap[] = {
241 { "array", base::Value::TYPE_LIST },
242 { "boolean", base::Value::TYPE_BOOLEAN },
243 { "integer", base::Value::TYPE_INTEGER },
244 { "null", base::Value::TYPE_NULL },
245 { "number", base::Value::TYPE_DOUBLE },
246 { "object", base::Value::TYPE_DICTIONARY },
247 { "string", base::Value::TYPE_STRING },
248 };
249
250 if (!schema)
251 return default_type;
252 std::string type;
253 if (!schema->GetString(kType, &type))
254 return default_type;
255 for (size_t i = 0; i < arraysize(kSchemaToValueTypeMap); ++i) {
256 if (type == kSchemaToValueTypeMap[i].schema_type)
257 return kSchemaToValueTypeMap[i].value_type;
258 }
259 return default_type;
260 }
261
262 // Returns the default type for registry entries of |reg_type|, when there is
263 // no schema defined type for a policy.
264 base::Value::Type GetDefaultFor(DWORD reg_type) {
265 return reg_type == REG_DWORD ? base::Value::TYPE_INTEGER :
266 base::Value::TYPE_STRING;
267 }
268
269 // Returns the entry with key |name| in |dictionary| (can be NULL), or NULL.
270 base::DictionaryValue* GetEntry(const base::DictionaryValue* dictionary,
271 const std::string& name) {
272 if (!dictionary)
273 return NULL;
274 base::DictionaryValue* entry = NULL;
275 dictionary->GetDictionary(name, &entry);
276 return entry;
277 }
278
279 // Converts string |value| to another |type|, if possible.
280 base::Value* ConvertComponentStringValue(const string16& value,
281 base::Value::Type type) {
282 switch (type) {
283 case base::Value::TYPE_DICTIONARY:
284 return base::JSONReader::Read(UTF16ToUTF8(value));
285
286 case base::Value::TYPE_NULL:
287 return base::Value::CreateNullValue();
288
289 case base::Value::TYPE_DOUBLE: {
290 double double_value;
291 if (base::StringToDouble(UTF16ToUTF8(value), &double_value))
292 return base::Value::CreateDoubleValue(double_value);
293 DLOG(WARNING) << "Failed to read policy value as double: " << value;
294 return NULL;
295 }
296
297 case base::Value::TYPE_STRING:
298 return base::Value::CreateStringValue(value);
299
Mattias Nissler (ping if slow) 2012/06/27 12:07:17 what about TYPE_LIST and TYPE_INTEGER? Should they
Joao da Silva 2012/06/27 14:31:15 Sure, done. Also added a conversion to TYPE_BOOLEA
300 default:
Mattias Nissler (ping if slow) 2012/06/27 12:07:17 I'd list the remaining enum constants here and rem
Joao da Silva 2012/06/27 14:31:15 Done.
301 DLOG(WARNING) << "Cannot convert REG_SZ entry to type " << type;
302 return NULL;
303 }
304 }
305
306 // Converts an integer |value| to another |type|, if possible.
307 base::Value* ConvertComponentIntegerValue(uint32 value,
308 base::Value::Type type) {
309 switch (type) {
310 case base::Value::TYPE_BOOLEAN:
311 return base::Value::CreateBooleanValue(value != 0);
312
313 case base::Value::TYPE_DOUBLE:
314 return base::Value::CreateDoubleValue(value);
315
316 case base::Value::TYPE_INTEGER:
317 return base::Value::CreateIntegerValue(value);
318
319 default:
Mattias Nissler (ping if slow) 2012/06/27 12:07:17 same comment regarding remaining constants, defaul
Joao da Silva 2012/06/27 14:31:15 Done.
320 DLOG(WARNING) << "Cannot convert REG_DWORD entry to type " << type;
321 return NULL;
322 }
323 }
324
325 // Reads a simple (non-Dictionary, non-Array) value from the registry |key|
326 // named |name| with registry type |reg_type| as a value of type |type|.
327 // Returns NULL if the value could not be loaded or converted.
328 base::Value* ReadComponentSimpleValue(RegKey* key,
329 const string16& name,
330 DWORD reg_type,
331 base::Value::Type type) {
332 switch (reg_type) {
333 case REG_SZ: {
334 string16 value;
335 if (ReadRegistryString(key, name, &value))
336 return ConvertComponentStringValue(value, type);
337 break;
338 }
339
340 case REG_DWORD: {
341 uint32 value;
342 if (ReadRegistryInteger(key, name, &value))
343 return ConvertComponentIntegerValue(value, type);
344 break;
345 }
346
347 default:
348 DLOG(WARNING) << "Registry type not supported for key " << name;
349 break;
350 }
351 NOTREACHED();
352 return NULL;
353 }
354
355 // Forward declaration for ReadComponentListValue().
356 base::DictionaryValue* ReadComponentDictionaryValue(
357 HKEY hive,
358 const string16& path,
359 const base::DictionaryValue* schema);
360
361 // Loads the list at |path| in the given |hive|. |schema| is a JSON schema
362 // (http://json-schema.org/) that describes the expected type of the list's
363 // elements. Ownership of the result is transferred to the caller.
364 base::ListValue* ReadComponentListValue(HKEY hive,
365 const string16& path,
366 const base::DictionaryValue* schema) {
367 // The sub-elements are indexed from 1 to N. They can be represented as
368 // registry values or registry keys though; use |schema| first to try to
369 // determine the right type, and if that fails default to STRING.
370
371 RegKey key(hive, path.c_str(), KEY_READ);
372 if (!key.Valid())
373 return NULL;
374
375 base::Value::Type type = GetType(schema, base::Value::TYPE_STRING);
376 base::ListValue* list = new base::ListValue();
377 for (int i = 1; ; ++i) {
378 string16 name = base::IntToString16(i);
379 base::Value* value = NULL;
380 base::DictionaryValue* sub_schema = NULL;
381 if (type == base::Value::TYPE_DICTIONARY) {
382 value = ReadComponentDictionaryValue(hive, path + kPathSep + name,
383 GetEntry(schema, kProperties));
384 } else if (type == base::Value::TYPE_LIST) {
385 value = ReadComponentListValue(hive, path + kPathSep + name,
386 GetEntry(schema, kItems));
387 } else {
388 DWORD reg_type;
389 key.ReadValue(name.c_str(), NULL, NULL, &reg_type);
390 value = ReadComponentSimpleValue(&key, name, reg_type, type);
391 }
392 if (!value)
393 break;
394 list->Append(value);
395 }
396 return list;
397 }
398
399 // Loads the dictionary at |path| in the given |hive|. |schema| is a JSON
400 // schema (http://json-schema.org/) that describes the expected types for the
401 // dictionary entries. When the type for a certain entry isn't described in the
402 // schema, a default conversion takes place. |schema| can be NULL.
403 // Ownership of the result is transferred to the caller.
404 base::DictionaryValue* ReadComponentDictionaryValue(
405 HKEY hive,
406 const string16& path,
407 const base::DictionaryValue* schema) {
223 // A "value" in the registry is like a file in a filesystem, and a "key" is 408 // A "value" in the registry is like a file in a filesystem, and a "key" is
224 // like a directory, that contains other "values" and "keys". 409 // like a directory, that contains other "values" and "keys".
225 // Unfortunately it is possible to have a name both as a "value" and a "key". 410 // Unfortunately it is possible to have a name both as a "value" and a "key".
226 // In those cases, the sub "key" will be ignored; this choice is arbitrary. 411 // In those cases, the sub "key" will be ignored; this choice is arbitrary.
227 412
228 // First iterate over all the "values" in |path| and convert them; then 413 // First iterate over all the "values" in |path| and convert them; then
229 // recurse into each "key" in |path| and convert them as dictionaries. 414 // recurse into each "key" in |path| and convert them as dictionaries.
230 415
416 RegKey key(hive, path.c_str(), KEY_READ);
417 if (!key.Valid())
418 return NULL;
419
231 base::DictionaryValue* dict = new base::DictionaryValue(); 420 base::DictionaryValue* dict = new base::DictionaryValue();
232 RegKey key(hive, path.c_str(), KEY_READ);
233
234 for (RegistryValueIterator it(hive, path.c_str()); it.Valid(); ++it) { 421 for (RegistryValueIterator it(hive, path.c_str()); it.Valid(); ++it) {
235 string16 name(it.Name()); 422 string16 name16(it.Name());
236 switch (it.Type()) { 423 std::string name(UTF16ToUTF8(name16));
237 case REG_SZ: { 424 const base::DictionaryValue* sub_schema = GetEntry(schema, name);
Mattias Nissler (ping if slow) 2012/06/27 12:07:17 What about the case of a dictionary with arbitrary
Joao da Silva 2012/06/27 14:31:15 Great idea, and json-schema even has something for
238 string16 value; 425 base::Value::Type type = GetType(sub_schema, GetDefaultFor(it.Type()));
239 if (ReadRegistryString(&key, name, &value)) 426 base::Value* value =
240 dict->SetString(UTF16ToUTF8(name), value); 427 ReadComponentSimpleValue(&key, name16, it.Type(), type);
Mattias Nissler (ping if slow) 2012/06/27 12:07:17 Why can't this be an encoded dictionary or list?
Joao da Silva 2012/06/27 14:31:15 Because we're using a RegistryValueIterator, so th
241 break; 428 if (value)
242 } 429 dict->Set(name, value);
243
244 case REG_DWORD: {
245 uint32 value;
246 if (ReadRegistryInteger(&key, name, &value))
247 dict->SetInteger(UTF16ToUTF8(name), value);
248 break;
249 }
250
251 default:
252 // TODO(joaodasilva): use a schema to determine the correct types.
253 LOG(WARNING) << "Ignoring registry value with unsupported type: "
254 << path << kPathSep << name;
255 }
256 } 430 }
257 431
258 for (RegistryKeyIterator it(hive, path.c_str()); it.Valid(); ++it) { 432 for (RegistryKeyIterator it(hive, path.c_str()); it.Valid(); ++it) {
259 string16 name16(it.Name()); 433 string16 name16(it.Name());
260 std::string name(UTF16ToUTF8(name16)); 434 std::string name(UTF16ToUTF8(name16));
261 if (dict->HasKey(name)) { 435 if (dict->HasKey(name)) {
262 LOG(WARNING) << "Ignoring registry key because a value exists with the " 436 DLOG(WARNING) << "Ignoring registry key because a value exists with the "
263 "same name: " << path << kPathSep << name; 437 "same name: " << path << kPathSep << name;
264 continue; 438 continue;
265 } 439 }
266 base::DictionaryValue* value = 440
267 ReadRegistryDictionaryValue(hive, path + kPathSep + name16); 441 base::DictionaryValue* sub_schema = GetEntry(schema, name);
442 base::Value::Type type = GetType(sub_schema, base::Value::TYPE_DICTIONARY);
443 base::Value* value = NULL;
444 const string16 sub_path = path + kPathSep + name16;
445 if (type == base::Value::TYPE_DICTIONARY) {
446 sub_schema = GetEntry(sub_schema, kProperties);
447 value = ReadComponentDictionaryValue(hive, sub_path, sub_schema);
448 } else if (type == base::Value::TYPE_LIST) {
449 sub_schema = GetEntry(sub_schema, kItems);
450 value = ReadComponentListValue(hive, sub_path, sub_schema);
451 } else {
452 DLOG(WARNING) << "Can't read a simple type in registry key at " << path;
453 }
268 if (value) 454 if (value)
269 dict->Set(name, value); 455 dict->Set(name, value);
270 } 456 }
271 457
272 return dict; 458 return dict;
273 } 459 }
274 460
461 // Reads a JSON schema from the given |registry_value|, at the given
462 // |registry_key| in |hive|. |registry_value| must be a string (REG_SZ), and
463 // is decoded as JSON data. Returns NULL on failure. Ownership is transferred
464 // to the caller.
465 base::DictionaryValue* ReadRegistrySchema(HKEY hive,
466 const string16& registry_key,
467 const string16& registry_value) {
468 RegKey key(hive, registry_key.c_str(), KEY_READ);
469 string16 schema;
470 if (!ReadRegistryString(&key, registry_value, &schema))
471 return NULL;
472 // A JSON schema is represented in JSON too.
473 scoped_ptr<base::Value> value(base::JSONReader::Read(UTF16ToUTF8(schema)));
474 if (!value.get())
475 return NULL;
476 base::DictionaryValue* dict = NULL;
477 if (!value->GetAsDictionary(&dict))
478 return NULL;
479 // The top-level entry must be an object, and each of its properties maps
480 // a policy name to its schema.
481 if (GetType(dict, base::Value::TYPE_DICTIONARY) !=
482 base::Value::TYPE_DICTIONARY) {
483 DLOG(WARNING) << "schema top-level type isn't \"object\"";
484 return NULL;
485 }
486 base::DictionaryValue* properties = GetEntry(dict, kProperties);
487 if (!properties)
488 return NULL;
489 value.release();
490 return properties;
491 }
492
275 } // namespace 493 } // namespace
276 494
277 PolicyLoaderWin::PolicyLoaderWin(const PolicyDefinitionList* policy_list) 495 PolicyLoaderWin::PolicyLoaderWin(const PolicyDefinitionList* policy_list)
278 : is_initialized_(false), 496 : is_initialized_(false),
279 policy_list_(policy_list), 497 policy_list_(policy_list),
280 user_policy_changed_event_(false, false), 498 user_policy_changed_event_(false, false),
281 machine_policy_changed_event_(false, false), 499 machine_policy_changed_event_(false, false),
282 user_policy_watcher_failed_(false), 500 user_policy_watcher_failed_(false),
283 machine_policy_watcher_failed_(false) { 501 machine_policy_watcher_failed_(false) {
284 if (!RegisterGPNotification(user_policy_changed_event_.handle(), false)) { 502 if (!RegisterGPNotification(user_policy_changed_event_.handle(), false)) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 534
317 const PolicyDefinitionList::Entry* current; 535 const PolicyDefinitionList::Entry* current;
318 for (current = policy_list_->begin; current != policy_list_->end; ++current) { 536 for (current = policy_list_->begin; current != policy_list_->end; ++current) {
319 const string16 name(ASCIIToUTF16(current->name)); 537 const string16 name(ASCIIToUTF16(current->name));
320 PolicyLevel level = POLICY_LEVEL_MANDATORY; 538 PolicyLevel level = POLICY_LEVEL_MANDATORY;
321 PolicyScope scope = POLICY_SCOPE_MACHINE; 539 PolicyScope scope = POLICY_SCOPE_MACHINE;
322 base::Value* value = NULL; 540 base::Value* value = NULL;
323 541
324 switch (current->value_type) { 542 switch (current->value_type) {
325 case base::Value::TYPE_STRING: 543 case base::Value::TYPE_STRING:
326 value = ReadStringValue(name, &level, &scope); 544 value = ReadChromeStringValue(name, &level, &scope);
327 break; 545 break;
328 546
329 case base::Value::TYPE_LIST: 547 case base::Value::TYPE_LIST:
330 value = ReadStringListValue(name, &level, &scope); 548 value = ReadChromeStringListValue(name, &level, &scope);
331 break; 549 break;
332 550
333 case base::Value::TYPE_BOOLEAN: 551 case base::Value::TYPE_BOOLEAN:
334 value = ReadBooleanValue(name, &level, &scope); 552 value = ReadChromeBooleanValue(name, &level, &scope);
335 break; 553 break;
336 554
337 case base::Value::TYPE_INTEGER: 555 case base::Value::TYPE_INTEGER:
338 value = ReadIntegerValue(name, &level, &scope); 556 value = ReadChromeIntegerValue(name, &level, &scope);
339 break; 557 break;
340 558
341 case base::Value::TYPE_DICTIONARY: 559 case base::Value::TYPE_DICTIONARY:
342 value = ReadDictionaryValue(name, &level, &scope); 560 value = ReadChromeDictionaryValue(name, &level, &scope);
343 break; 561 break;
344 562
345 default: 563 default:
346 NOTREACHED(); 564 NOTREACHED();
347 } 565 }
348 566
349 if (value) 567 if (value)
350 chrome_policies->Set(current->name, level, scope, value); 568 chrome_policies->Set(current->name, level, scope, value);
351 } 569 }
352 } 570 }
(...skipping 30 matching lines...) Expand all
383 for (size_t d = 0; d < arraysize(kDomains); ++d) { 601 for (size_t d = 0; d < arraysize(kDomains); ++d) {
384 // Each subkey under this domain is a component of that domain. 602 // Each subkey under this domain is a component of that domain.
385 // |domain_path| == SOFTWARE\Policies\Chromium\3rdparty\<domain> 603 // |domain_path| == SOFTWARE\Policies\Chromium\3rdparty\<domain>
386 string16 domain_path = kPathPrefix + ASCIIToUTF16(kDomains[d].name); 604 string16 domain_path = kPathPrefix + ASCIIToUTF16(kDomains[d].name);
387 605
388 for (RegistryKeyIterator domain_iterator(hkey, domain_path.c_str()); 606 for (RegistryKeyIterator domain_iterator(hkey, domain_path.c_str());
389 domain_iterator.Valid(); ++domain_iterator) { 607 domain_iterator.Valid(); ++domain_iterator) {
390 string16 component(domain_iterator.Name()); 608 string16 component(domain_iterator.Name());
391 string16 component_path = domain_path + kPathSep + component; 609 string16 component_path = domain_path + kPathSep + component;
392 610
611 // Load the schema for this component's policy, if present.
612 scoped_ptr<base::DictionaryValue> schema(
613 ReadRegistrySchema(hkey, component_path, kSchema));
614
393 for (size_t k = 0; k < arraysize(kKeyPaths); ++k) { 615 for (size_t k = 0; k < arraysize(kKeyPaths); ++k) {
394 string16 path = 616 string16 path =
395 component_path + kPathSep + ASCIIToUTF16(kKeyPaths[k].path); 617 component_path + kPathSep + ASCIIToUTF16(kKeyPaths[k].path);
396 618
397 scoped_ptr<base::DictionaryValue> dictionary( 619 scoped_ptr<base::DictionaryValue> dictionary(
398 ReadRegistryDictionaryValue(hkey, path)); 620 ReadComponentDictionaryValue(hkey, path, schema.get()));
399 if (dictionary.get()) { 621 if (dictionary.get()) {
400 PolicyMap policies; 622 PolicyMap policies;
401 policies.LoadFrom( 623 policies.LoadFrom(
402 dictionary.get(), kKeyPaths[k].level, kHives[h].scope); 624 dictionary.get(), kKeyPaths[k].level, kHives[h].scope);
403 // LoadFrom() overwrites any existing values. Use a temporary map 625 // LoadFrom() overwrites any existing values. Use a temporary map
404 // and then use MergeFrom(), that only overwrites values with lower 626 // and then use MergeFrom(), that only overwrites values with lower
405 // priority. 627 // priority.
406 bundle->Get(kDomains[d].domain, UTF16ToUTF8(component)) 628 bundle->Get(kDomains[d].domain, UTF16ToUTF8(component))
407 .MergeFrom(policies); 629 .MergeFrom(policies);
408 } 630 }
(...skipping 23 matching lines...) Expand all
432 654
433 void PolicyLoaderWin::OnObjectSignaled(HANDLE object) { 655 void PolicyLoaderWin::OnObjectSignaled(HANDLE object) {
434 DCHECK(object == user_policy_changed_event_.handle() || 656 DCHECK(object == user_policy_changed_event_.handle() ||
435 object == machine_policy_changed_event_.handle()) 657 object == machine_policy_changed_event_.handle())
436 << "unexpected object signaled policy reload, obj = " 658 << "unexpected object signaled policy reload, obj = "
437 << std::showbase << std::hex << object; 659 << std::showbase << std::hex << object;
438 Reload(false); 660 Reload(false);
439 } 661 }
440 662
441 } // namespace policy 663 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698