OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_path_parser.h" | 5 #include "chrome/browser/policy/policy_path_parser.h" |
6 | 6 |
7 #include <shlobj.h> | 7 #include <shlobj.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <wtsapi32.h> | 9 #include <wtsapi32.h> |
10 | 10 |
11 #include <memory> | 11 #include <memory> |
12 | 12 |
13 #include "base/macros.h" | 13 #include "base/macros.h" |
14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
15 #include "base/win/registry.h" | 15 #include "base/win/registry.h" |
16 #include "chrome/common/chrome_switches.h" | 16 #include "chrome/common/chrome_switches.h" |
17 #include "chrome/install_static/policy_path_parser.h" | |
18 #include "components/policy/policy_constants.h" | 17 #include "components/policy/policy_constants.h" |
19 | 18 |
20 namespace { | 19 namespace { |
21 | 20 |
22 // Checks if the key exists in the given hive and expands any string variables. | 21 // Checks if the key exists in the given hive and expands any string variables. |
23 bool LoadUserDataDirPolicyFromRegistry(HKEY hive, | 22 bool LoadUserDataDirPolicyFromRegistry(HKEY hive, |
24 const char* key_name_str, | 23 const char* key_name_str, |
25 base::FilePath* dir) { | 24 base::FilePath* dir) { |
26 base::string16 value; | 25 base::string16 value; |
27 base::string16 key_name(base::ASCIIToUTF16(key_name_str)); | 26 base::string16 key_name(base::ASCIIToUTF16(key_name_str)); |
28 base::win::RegKey key(hive, policy::kRegistryChromePolicyKey, KEY_READ); | 27 base::win::RegKey key(hive, policy::kRegistryChromePolicyKey, KEY_READ); |
29 if (key.ReadValue(key_name.c_str(), &value) == ERROR_SUCCESS) { | 28 if (key.ReadValue(key_name.c_str(), &value) == ERROR_SUCCESS) { |
30 *dir = base::FilePath(policy::path_parser::ExpandPathVariables(value)); | 29 *dir = base::FilePath(policy::path_parser::ExpandPathVariables(value)); |
31 return true; | 30 return true; |
32 } | 31 } |
33 return false; | 32 return false; |
34 } | 33 } |
35 | 34 |
| 35 const WCHAR* kMachineNamePolicyVarName = L"${machine_name}"; |
| 36 const WCHAR* kUserNamePolicyVarName = L"${user_name}"; |
| 37 const WCHAR* kWinDocumentsFolderVarName = L"${documents}"; |
| 38 const WCHAR* kWinLocalAppDataFolderVarName = L"${local_app_data}"; |
| 39 const WCHAR* kWinRoamingAppDataFolderVarName = L"${roaming_app_data}"; |
| 40 const WCHAR* kWinProfileFolderVarName = L"${profile}"; |
| 41 const WCHAR* kWinProgramDataFolderVarName = L"${global_app_data}"; |
| 42 const WCHAR* kWinProgramFilesFolderVarName = L"${program_files}"; |
| 43 const WCHAR* kWinWindowsFolderVarName = L"${windows}"; |
| 44 const WCHAR* kWinClientName = L"${client_name}"; |
| 45 const WCHAR* kWinSessionName = L"${session_name}"; |
| 46 |
| 47 struct WinFolderNamesToCSIDLMapping { |
| 48 const WCHAR* name; |
| 49 int id; |
| 50 }; |
| 51 |
| 52 // Mapping from variable names to Windows CSIDL ids. |
| 53 const WinFolderNamesToCSIDLMapping win_folder_mapping[] = { |
| 54 { kWinWindowsFolderVarName, CSIDL_WINDOWS}, |
| 55 { kWinProgramFilesFolderVarName, CSIDL_PROGRAM_FILES}, |
| 56 { kWinProgramDataFolderVarName, CSIDL_COMMON_APPDATA}, |
| 57 { kWinProfileFolderVarName, CSIDL_PROFILE}, |
| 58 { kWinLocalAppDataFolderVarName, CSIDL_LOCAL_APPDATA}, |
| 59 { kWinRoamingAppDataFolderVarName, CSIDL_APPDATA}, |
| 60 { kWinDocumentsFolderVarName, CSIDL_PERSONAL} |
| 61 }; |
| 62 |
36 } // namespace | 63 } // namespace |
37 | 64 |
38 namespace policy { | 65 namespace policy { |
39 | 66 |
40 namespace path_parser { | 67 namespace path_parser { |
41 | 68 |
42 // Replaces all variable occurances in the policy string with the respective | 69 // Replaces all variable occurances in the policy string with the respective |
43 // system settings values. | 70 // system settings values. |
44 base::FilePath::StringType ExpandPathVariables( | 71 base::FilePath::StringType ExpandPathVariables( |
45 const base::FilePath::StringType& untranslated_string) { | 72 const base::FilePath::StringType& untranslated_string) { |
46 // This is implemented in the install_static library so that it can also be | 73 base::FilePath::StringType result(untranslated_string); |
47 // used by Crashpad initialization code in chrome_elf, which has a very | 74 if (result.length() == 0) |
48 // constrained set of dependencies. | 75 return result; |
49 return install_static::ExpandPathVariables(untranslated_string); | 76 // Sanitize quotes in case of any around the whole string. |
| 77 if (result.length() > 1 && |
| 78 ((result.front() == L'"' && result.back() == L'"') || |
| 79 (result.front() == L'\'' && result.back() == L'\''))) { |
| 80 // Strip first and last char which should be matching quotes now. |
| 81 result = result.substr(1, result.length() - 2); |
| 82 } |
| 83 // First translate all path variables we recognize. |
| 84 for (size_t i = 0; i < arraysize(win_folder_mapping); ++i) { |
| 85 size_t position = result.find(win_folder_mapping[i].name); |
| 86 if (position != std::wstring::npos) { |
| 87 WCHAR path[MAX_PATH]; |
| 88 ::SHGetSpecialFolderPath(0, path, win_folder_mapping[i].id, false); |
| 89 std::wstring path_string(path); |
| 90 result.replace(position, wcslen(win_folder_mapping[i].name), path_string); |
| 91 } |
| 92 } |
| 93 // Next translate other windows specific variables. |
| 94 size_t position = result.find(kUserNamePolicyVarName); |
| 95 if (position != std::wstring::npos) { |
| 96 DWORD return_length = 0; |
| 97 ::GetUserName(NULL, &return_length); |
| 98 if (return_length != 0) { |
| 99 std::unique_ptr<WCHAR[]> username(new WCHAR[return_length]); |
| 100 ::GetUserName(username.get(), &return_length); |
| 101 std::wstring username_string(username.get()); |
| 102 result.replace(position, wcslen(kUserNamePolicyVarName), username_string); |
| 103 } |
| 104 } |
| 105 position = result.find(kMachineNamePolicyVarName); |
| 106 if (position != std::wstring::npos) { |
| 107 DWORD return_length = 0; |
| 108 ::GetComputerNameEx(ComputerNamePhysicalDnsHostname, NULL, &return_length); |
| 109 if (return_length != 0) { |
| 110 std::unique_ptr<WCHAR[]> machinename(new WCHAR[return_length]); |
| 111 ::GetComputerNameEx(ComputerNamePhysicalDnsHostname, |
| 112 machinename.get(), &return_length); |
| 113 std::wstring machinename_string(machinename.get()); |
| 114 result.replace( |
| 115 position, wcslen(kMachineNamePolicyVarName), machinename_string); |
| 116 } |
| 117 } |
| 118 position = result.find(kWinClientName); |
| 119 if (position != std::wstring::npos) { |
| 120 LPWSTR buffer = NULL; |
| 121 DWORD buffer_length = 0; |
| 122 if (::WTSQuerySessionInformation(WTS_CURRENT_SERVER, WTS_CURRENT_SESSION, |
| 123 WTSClientName, |
| 124 &buffer, &buffer_length)) { |
| 125 std::wstring clientname_string(buffer); |
| 126 result.replace(position, wcslen(kWinClientName), clientname_string); |
| 127 ::WTSFreeMemory(buffer); |
| 128 } |
| 129 } |
| 130 position = result.find(kWinSessionName); |
| 131 if (position != std::wstring::npos) { |
| 132 LPWSTR buffer = NULL; |
| 133 DWORD buffer_length = 0; |
| 134 if (::WTSQuerySessionInformation(WTS_CURRENT_SERVER, WTS_CURRENT_SESSION, |
| 135 WTSWinStationName, |
| 136 &buffer, &buffer_length)) { |
| 137 std::wstring sessionname_string(buffer); |
| 138 result.replace(position, wcslen(kWinSessionName), sessionname_string); |
| 139 ::WTSFreeMemory(buffer); |
| 140 } |
| 141 } |
| 142 // TODO(pastarmovj): Consider reorganizing this code once there are even more |
| 143 // variables to be supported. The search for the var and its replacement can |
| 144 // be extracted as common functionality. |
| 145 |
| 146 return result; |
50 } | 147 } |
51 | 148 |
52 void CheckUserDataDirPolicy(base::FilePath* user_data_dir) { | 149 void CheckUserDataDirPolicy(base::FilePath* user_data_dir) { |
53 DCHECK(user_data_dir); | 150 DCHECK(user_data_dir); |
54 // Policy from the HKLM hive has precedence over HKCU. | 151 // Policy from the HKLM hive has precedence over HKCU. |
55 if (!LoadUserDataDirPolicyFromRegistry(HKEY_LOCAL_MACHINE, key::kUserDataDir, | 152 if (!LoadUserDataDirPolicyFromRegistry(HKEY_LOCAL_MACHINE, key::kUserDataDir, |
56 user_data_dir)) { | 153 user_data_dir)) { |
57 LoadUserDataDirPolicyFromRegistry(HKEY_CURRENT_USER, key::kUserDataDir, | 154 LoadUserDataDirPolicyFromRegistry(HKEY_CURRENT_USER, key::kUserDataDir, |
58 user_data_dir); | 155 user_data_dir); |
59 } | 156 } |
60 } | 157 } |
61 | 158 |
62 void CheckDiskCacheDirPolicy(base::FilePath* disk_cache_dir) { | 159 void CheckDiskCacheDirPolicy(base::FilePath* disk_cache_dir) { |
63 DCHECK(disk_cache_dir); | 160 DCHECK(disk_cache_dir); |
64 if (!LoadUserDataDirPolicyFromRegistry(HKEY_LOCAL_MACHINE, key::kDiskCacheDir, | 161 if (!LoadUserDataDirPolicyFromRegistry(HKEY_LOCAL_MACHINE, key::kDiskCacheDir, |
65 disk_cache_dir)) { | 162 disk_cache_dir)) { |
66 LoadUserDataDirPolicyFromRegistry(HKEY_CURRENT_USER, key::kDiskCacheDir, | 163 LoadUserDataDirPolicyFromRegistry(HKEY_CURRENT_USER, key::kDiskCacheDir, |
67 disk_cache_dir); | 164 disk_cache_dir); |
68 } | 165 } |
69 } | 166 } |
70 | 167 |
71 } // namespace path_parser | 168 } // namespace path_parser |
72 | 169 |
73 } // namespace policy | 170 } // namespace policy |
OLD | NEW |