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" |
17 #include "components/policy/policy_constants.h" | 18 #include "components/policy/policy_constants.h" |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 // Checks if the key exists in the given hive and expands any string variables. | 22 // Checks if the key exists in the given hive and expands any string variables. |
22 bool LoadUserDataDirPolicyFromRegistry(HKEY hive, | 23 bool LoadUserDataDirPolicyFromRegistry(HKEY hive, |
23 const char* key_name_str, | 24 const char* key_name_str, |
24 base::FilePath* dir) { | 25 base::FilePath* dir) { |
25 base::string16 value; | 26 base::string16 value; |
26 base::string16 key_name(base::ASCIIToUTF16(key_name_str)); | 27 base::string16 key_name(base::ASCIIToUTF16(key_name_str)); |
27 base::win::RegKey key(hive, policy::kRegistryChromePolicyKey, KEY_READ); | 28 base::win::RegKey key(hive, policy::kRegistryChromePolicyKey, KEY_READ); |
28 if (key.ReadValue(key_name.c_str(), &value) == ERROR_SUCCESS) { | 29 if (key.ReadValue(key_name.c_str(), &value) == ERROR_SUCCESS) { |
29 *dir = base::FilePath(policy::path_parser::ExpandPathVariables(value)); | 30 *dir = base::FilePath(policy::path_parser::ExpandPathVariables(value)); |
30 return true; | 31 return true; |
31 } | 32 } |
32 return false; | 33 return false; |
33 } | 34 } |
34 | 35 |
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 | |
63 } // namespace | 36 } // namespace |
64 | 37 |
65 namespace policy { | 38 namespace policy { |
66 | 39 |
67 namespace path_parser { | 40 namespace path_parser { |
68 | 41 |
69 // Replaces all variable occurances in the policy string with the respective | 42 // Replaces all variable occurances in the policy string with the respective |
70 // system settings values. | 43 // system settings values. |
71 base::FilePath::StringType ExpandPathVariables( | 44 base::FilePath::StringType ExpandPathVariables( |
72 const base::FilePath::StringType& untranslated_string) { | 45 const base::FilePath::StringType& untranslated_string) { |
73 base::FilePath::StringType result(untranslated_string); | 46 // This is implemented in the install_static library so that it can also be |
74 if (result.length() == 0) | 47 // used by Crashpad initialization code in chrome_elf, which has a very |
75 return result; | 48 // constrained set of dependencies. |
76 // Sanitize quotes in case of any around the whole string. | 49 return install_static::ExpandPathVariables(untranslated_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; | |
147 } | 50 } |
148 | 51 |
149 void CheckUserDataDirPolicy(base::FilePath* user_data_dir) { | 52 void CheckUserDataDirPolicy(base::FilePath* user_data_dir) { |
150 DCHECK(user_data_dir); | 53 DCHECK(user_data_dir); |
151 // Policy from the HKLM hive has precedence over HKCU. | 54 // Policy from the HKLM hive has precedence over HKCU. |
152 if (!LoadUserDataDirPolicyFromRegistry(HKEY_LOCAL_MACHINE, key::kUserDataDir, | 55 if (!LoadUserDataDirPolicyFromRegistry(HKEY_LOCAL_MACHINE, key::kUserDataDir, |
153 user_data_dir)) { | 56 user_data_dir)) { |
154 LoadUserDataDirPolicyFromRegistry(HKEY_CURRENT_USER, key::kUserDataDir, | 57 LoadUserDataDirPolicyFromRegistry(HKEY_CURRENT_USER, key::kUserDataDir, |
155 user_data_dir); | 58 user_data_dir); |
156 } | 59 } |
157 } | 60 } |
158 | 61 |
159 void CheckDiskCacheDirPolicy(base::FilePath* disk_cache_dir) { | 62 void CheckDiskCacheDirPolicy(base::FilePath* disk_cache_dir) { |
160 DCHECK(disk_cache_dir); | 63 DCHECK(disk_cache_dir); |
161 if (!LoadUserDataDirPolicyFromRegistry(HKEY_LOCAL_MACHINE, key::kDiskCacheDir, | 64 if (!LoadUserDataDirPolicyFromRegistry(HKEY_LOCAL_MACHINE, key::kDiskCacheDir, |
162 disk_cache_dir)) { | 65 disk_cache_dir)) { |
163 LoadUserDataDirPolicyFromRegistry(HKEY_CURRENT_USER, key::kDiskCacheDir, | 66 LoadUserDataDirPolicyFromRegistry(HKEY_CURRENT_USER, key::kDiskCacheDir, |
164 disk_cache_dir); | 67 disk_cache_dir); |
165 } | 68 } |
166 } | 69 } |
167 | 70 |
168 } // namespace path_parser | 71 } // namespace path_parser |
169 | 72 |
170 } // namespace policy | 73 } // namespace policy |
OLD | NEW |