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

Side by Side Diff: chrome/browser/group_policy.cc

Issue 450037: Adds basic group policy support. Resubmitting r33093 with a new unit test.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/group_policy.h ('k') | chrome/browser/group_policy_settings.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // Implementation of group policy lookup code.
6
7 #include "base/logging.h"
8 #include "base/registry.h"
9 #include "base/scoped_ptr.h"
10 #include "base/string_util.h"
11 #include "base/values.h"
12 #include "build/build_config.h"
13 #include "chrome/browser/group_policy.h"
14 #include "chrome/browser/group_policy_settings.h"
15 #include "chrome/installer/util/browser_distribution.h"
16
17 namespace group_policy {
18
19 // In GetPolicySettingsRootKey(), this gets appended with:
20 // [Publisher Name]\\[App name]\\. Thus, this should be
21 // SOFTWARE\\Policies\\Chromium\\Chromium\\ in the case of Chromium.
22 #define kPolicyKey L"SOFTWARE\\Policies\\"
23
24 bool g_has_hklm_policies = false;
25 bool g_has_hkcu_policies = false;
26 bool g_has_settings_initialized = false;
27
28 // Get the root registry location of group policy settings.
29 bool GetPolicySettingsRootKey(std::wstring* policy_key) {
30 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
31 std::wstring app_name = dist->GetApplicationName();
32 std::wstring publisher_name = dist->GetPublisherName();
33 std::wstring separator = std::wstring(L"\\");
34 policy_key->append(kPolicyKey);
35 policy_key->append(app_name);
36 policy_key->append(separator);
37 policy_key->append(publisher_name);
38 policy_key->append(separator);
39 return true;
40 }
41
42 // TODO(gwilson): Add a method that will check if group policy settings have
43 // been updated since we last checked, so as not to require a restart.
44 bool HasGroupPolicySettings() {
45 if (g_has_settings_initialized)
46 return g_has_hkcu_policies || g_has_hklm_policies;
47 std::wstring policy_key(L"");
48 GetPolicySettingsRootKey(&policy_key);
49 RegKey hkcu = RegKey(HKEY_CURRENT_USER, policy_key.c_str(), KEY_QUERY_VALUE);
50 RegKey hklm = RegKey(HKEY_LOCAL_MACHINE, policy_key.c_str(), KEY_QUERY_VALUE);
51 g_has_hkcu_policies = hkcu.Valid();
52 g_has_hklm_policies = hklm.Valid();
53 g_has_settings_initialized = true;
54 return g_has_hkcu_policies || g_has_hklm_policies;
55 }
56
57 bool HasHkcuSettings() {
58 if (!g_has_settings_initialized)
59 HasGroupPolicySettings();
60 return g_has_hkcu_policies;
61 }
62
63 bool HasHklmSettings() {
64 if (!g_has_settings_initialized)
65 HasGroupPolicySettings();
66 return g_has_hklm_policies;
67 }
68
69 // Returns true iff the setting is currently controlled by group policy.
70 // If anyone adds a policy that can only be present in HKLM or HKCU but
71 // not both, this code will need to be updated to reflect that.
72 bool SettingBase::IsPolicyControlled() const {
73 DCHECK(regvalue_ != NULL && regkey_ != NULL) <<
74 "Setting not initialized - don't call at static init time!";
75
76 if (!HasGroupPolicySettings())
77 return false;
78
79 std::wstring regkey_path(L"");
80 DCHECK(GetPolicySettingsRootKey(&regkey_path));
81 regkey_path.append(regkey_);
82
83 if (HasHklmSettings()) {
84 RegKey key;
85 HRESULT hr;
86 hr = key.Open(HKEY_LOCAL_MACHINE, regkey_path.c_str(), KEY_QUERY_VALUE);
87 if (SUCCEEDED(hr) && key.ValueExists(regvalue_))
88 return true;
89 }
90
91 if (HasHkcuSettings()) {
92 RegKey key;
93 HRESULT hr;
94 hr = key.Open(HKEY_CURRENT_USER, regkey_path.c_str(), KEY_QUERY_VALUE);
95 if (SUCCEEDED(hr) && key.ValueExists(regvalue_))
96 return true;
97 }
98
99 return false;
100 }
101
102 // Gets the current policy setting as a wstring.
103 HRESULT SettingBase::GetSetting(std::wstring* value, bool* found) const {
104 // Default to an empty value.
105 value->clear();
106
107 // Failure is perfectly normal here, but continue to check HKCU.
108 std::wstring hklm_value(L"");
109 bool hklm_found = false;
110 if (HasHklmSettings())
111 GetSettingFromTree(HKEY_LOCAL_MACHINE, &hklm_value, &hklm_found);
112
113 std::wstring hkcu_value(L"");
114 bool hkcu_found = false;
115 if (HasHkcuSettings())
116 GetSettingFromTree(HKEY_CURRENT_USER, &hkcu_value, &hkcu_found);
117
118 switch (combine_) {
119 case POLICYCOMBINE_PREFERMACHINE:
120 if (hklm_found) {
121 value->assign(hklm_value);
122 *found = true;
123 } else if (hkcu_found) {
124 value->assign(hkcu_value);
125 *found = true;
126 }
127 break;
128
129 case POLICYCOMBINE_PREFERUSER:
130 if (hkcu_found) {
131 value->assign(hkcu_value);
132 *found = true;
133 } else if (hklm_found) {
134 value->assign(hklm_value);
135 *found = true;
136 }
137 break;
138
139 case POLICYCOMBINE_CONCATENATE:
140 if (hklm_found) {
141 value->assign(hklm_value);
142 *found = true;
143 }
144 if (hkcu_found) {
145 value->append(hkcu_value);
146 *found = true;
147 }
148 break;
149
150 default:
151 DCHECK(FALSE) << "Unimplemented";
152 NOTREACHED();
153 break;
154 }
155
156 return S_OK;
157 }
158
159 // Gets the current policy setting as a ListVale of StringValue objects.
160 HRESULT SettingBase::GetSetting(ListValue* list, bool* found) const {
161 if (regvalue_ == NULL || regkey_ == NULL)
162 return E_UNEXPECTED;
163
164 // Failure is perfectly normal here, but continue to check HKCU.
165 scoped_ptr<ListValue> hklm_value(new ListValue());
166 bool hklm_found = false;
167 if (HasHklmSettings())
168 GetSettingFromTree(HKEY_LOCAL_MACHINE, hklm_value.get(), &hklm_found);
169
170 scoped_ptr<ListValue> hkcu_value(new ListValue());
171 bool hkcu_found = false;
172 if (HasHkcuSettings())
173 GetSettingFromTree(HKEY_CURRENT_USER, hkcu_value.get(), &hkcu_found);
174
175 // TODO(gwilson): Optimize / refactor this algorithm so that all of the
176 // GetSetting() methods only read from the keys they must, rather than
177 // reading from both HKCU and HKLM now.
178 switch (combine_) {
179 case POLICYCOMBINE_PREFERMACHINE:
180 if (hklm_found) {
181 AppendAll(list, hklm_value.get());
182 *found = true;
183 } else if (hkcu_found) {
184 AppendAll(list, hkcu_value.get());
185 *found = true;
186 }
187 break;
188
189 case POLICYCOMBINE_PREFERUSER:
190 if (hkcu_found) {
191 AppendAll(list, hkcu_value.get());
192 *found = true;
193 } else if (hklm_found) {
194 AppendAll(list, hklm_value.get());
195 *found = true;
196 }
197 break;
198
199 case POLICYCOMBINE_CONCATENATE:
200 if (hklm_found) {
201 AppendAll(list, hklm_value.get());
202 *found = true;
203 }
204 if (hkcu_found) {
205 AppendAll(list, hkcu_value.get());
206 *found = true;
207 }
208 break;
209
210 default:
211 DCHECK(FALSE) << "Unimplemented";
212 NOTREACHED();
213 break;
214 }
215
216 return S_OK;
217 }
218
219 void AppendAll(ListValue* target, ListValue* source) {
220 DCHECK(source);
221 DCHECK(target);
222 for (size_t i = 0; i < source->GetSize(); ++i) {
223 // The string must be copied here, since the Value object in the
224 // source list gets destroyed before we return the target list.
225 std::string str;
226 source->GetString(i, &str);
227 target->Append(Value::CreateStringValue(str));
228 }
229 }
230
231 // Gets the current policy setting as a bool.
232 HRESULT SettingBase::GetSetting(bool* value, bool* found) const {
233 // Default to false.
234 *value = false;
235
236 // Failure is perfectly normal here, but continue to check HKCU.
237 bool hklm_value = false;
238 bool hklm_found = false;
239 if (HasHklmSettings())
240 GetSettingFromTree(HKEY_LOCAL_MACHINE, &hklm_value, &hklm_found);
241
242 bool hkcu_value = false;
243 bool hkcu_found = false;
244 if (HasHkcuSettings())
245 GetSettingFromTree(HKEY_CURRENT_USER, &hkcu_value, &hkcu_found);
246
247 switch (combine_) {
248 case POLICYCOMBINE_PREFERMACHINE:
249 if (hklm_found) {
250 *value = hklm_value;
251 *found = true;
252 } else if (hkcu_found) {
253 *value = hkcu_value;
254 *found = true;
255 }
256 break;
257
258 case POLICYCOMBINE_PREFERUSER:
259 if (hkcu_found) {
260 *value = hkcu_value;
261 *found = true;
262 } else if (hklm_found) {
263 *value = hklm_value;
264 *found = true;
265 }
266 break;
267
268 case POLICYCOMBINE_LOGICALOR:
269 *value = hkcu_value || hklm_value;
270 *found = hkcu_found || hklm_found;
271 break;
272
273 default:
274 DCHECK(FALSE) << "Unimplemented";
275 NOTREACHED();
276 break;
277 }
278
279 return S_OK;
280 }
281
282 // Gets the current policy setting as a DWORD.
283 HRESULT SettingBase::GetSetting(DWORD* value, bool* found) const {
284 // Default to zero.
285 *value = 0;
286
287 // Failure is perfectly normal here, but continue to check HKCU.
288 DWORD hklm_value = 0;
289 bool hklm_found = false;
290 if (HasHklmSettings())
291 GetSettingFromTree(HKEY_LOCAL_MACHINE, &hklm_value, &hklm_found);
292
293 DWORD hkcu_value = 0;
294 bool hkcu_found = false;
295 if (HasHkcuSettings())
296 GetSettingFromTree(HKEY_CURRENT_USER, &hkcu_value, &hkcu_found);
297
298 switch (combine_) {
299 case POLICYCOMBINE_PREFERMACHINE:
300 if (hklm_found) {
301 *value = hklm_value;
302 *found = true;
303 } else if (hkcu_found) {
304 *value = hkcu_value;
305 *found = true;
306 }
307 break;
308
309 case POLICYCOMBINE_PREFERUSER:
310 if (hkcu_found) {
311 *value = hkcu_value;
312 *found = true;
313 } else if (hklm_found) {
314 *value = hklm_value;
315 *found = true;
316 }
317 break;
318
319 case POLICYCOMBINE_LOGICALOR:
320 *value = hkcu_value || hklm_value;
321 *found = hkcu_found || hklm_found;
322 break;
323
324 default:
325 DCHECK(FALSE) << "Unimplemented";
326 NOTREACHED();
327 break;
328 }
329
330 return S_OK;
331 }
332
333 // Gets the current policy setting in the specified tree.
334 HRESULT SettingBase::GetSettingFromTree(HKEY tree, DWORD* value,
335 bool* found) const {
336 *found = false;
337
338 std::wstring reg_value_name(L"");
339 DCHECK(GetPolicySettingsRootKey(&reg_value_name));
340 reg_value_name.append(regkey_);
341
342 HRESULT hr;
343 RegKey key;
344 // Failure is perfectly normal here.
345 hr = key.Open(tree, reg_value_name.c_str(), KEY_QUERY_VALUE);
346
347 if (FAILED(hr))
348 return hr;
349
350 DCHECK(storage_ == POLICYSTORAGE_SINGLEVALUE);
351 hr = key.ReadValueDW(regvalue_, value);
352 if (FAILED(hr))
353 return hr;
354
355 *found = true;
356
357 return hr;
358 }
359
360 // Gets the current policy setting in the specified tree.
361 HRESULT SettingBase::GetSettingFromTree(HKEY tree, ListValue* list,
362 bool* found) const {
363 *found = false;
364 list->Clear();
365
366 std::wstring reg_value_name(L"");
367 DCHECK(GetPolicySettingsRootKey(&reg_value_name));
368 reg_value_name.append(regkey_);
369
370 HRESULT hr;
371 RegKey key;
372 // Failure is perfectly normal here.
373 hr = key.Open(tree,
374 reg_value_name.c_str(),
375 KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS);
376 if (FAILED(hr))
377 return hr;
378
379 std::wstring reg_value;
380 switch (storage_) {
381 case POLICYSTORAGE_SINGLEVALUE:
382 hr = key.ReadValue(regvalue_, &reg_value);
383 if (FAILED(hr))
384 return hr;
385 list->Append(list->CreateStringValue(reg_value));
386 *found = true;
387 break;
388
389 case POLICYSTORAGE_CONCATSUBKEYS: {
390 int key_count = key.ValueCount();
391 if (key_count == 0) {
392 hr = E_FAIL;
393 } else {
394 // We'll return S_OK if we can succesfully read any of the subkeys.
395 hr = E_FAIL;
396 RegistryValueIterator iterator(tree, reg_value_name.c_str());
397 for (; iterator.Valid(); ++iterator) {
398 if (SUCCEEDED(key.ReadValue(iterator.Name(), &reg_value))) {
399 list->Append(Value::CreateStringValue(reg_value.c_str()));
400 *found = true;
401 hr = S_OK;
402 }
403 }
404 }
405 }
406 break;
407 }
408 return hr;
409 }
410
411 // Gets the current policy setting in the specified tree.
412 HRESULT SettingBase::GetSettingFromTree(HKEY tree, std::wstring* value,
413 bool* found) const {
414 *found = false;
415 value->clear();
416
417 std::wstring reg_value_name(L"");
418 DCHECK(GetPolicySettingsRootKey(&reg_value_name));
419 reg_value_name.append(regkey_);
420
421 HRESULT hr;
422 RegKey key;
423 // Failure is perfectly normal here.
424 hr = key.Open(tree, reg_value_name.c_str(), KEY_QUERY_VALUE);
425 if (FAILED(hr))
426 return hr;
427
428 DCHECK(storage_ == POLICYSTORAGE_SINGLEVALUE);
429
430 hr = key.ReadValue(regvalue_, value);
431 if (FAILED(hr))
432 return hr;
433
434 *found = true;
435
436 return hr;
437 }
438
439 // Gets the current policy setting in the specified tree.
440 HRESULT SettingBase::GetSettingFromTree(HKEY tree, bool* value,
441 bool* found) const {
442 *found = false;
443
444 std::wstring reg_value_name(L"");
445 DCHECK(GetPolicySettingsRootKey(&reg_value_name));
446 reg_value_name.append(regkey_);
447
448 HRESULT hr;
449 RegKey key;
450 // Failure is perfectly normal here.
451 hr = key.Open(tree, reg_value_name.c_str(), KEY_QUERY_VALUE);
452 if (FAILED(hr))
453 return hr;
454
455 DCHECK(storage_ == POLICYSTORAGE_SINGLEVALUE);
456 DWORD full_value;
457 hr = key.ReadValueDW(regvalue_, &full_value);
458 if (FAILED(hr))
459 return hr;
460
461 *value = (full_value != 0);
462 *found = true;
463
464 return hr;
465 }
466
467 bool IsBoolOptionSet(const Setting<bool>& setting) {
468 bool found = false;
469 bool set = false;
470 HRESULT hr = setting.GetSetting(&set, &found);
471 if (FAILED(hr) || !found) {
472 set = false;
473 }
474 return set;
475 }
476
477 }; // namespace group_policy
478
OLDNEW
« no previous file with comments | « chrome/browser/group_policy.h ('k') | chrome/browser/group_policy_settings.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698