Mercurial > trustbridge
comparison cinst/nssstore_win.c @ 668:ef6d3dc9e930
Framework for NSS multiuser installation on windows
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Thu, 26 Jun 2014 17:42:24 +0200 |
parents | 69dd092e2512 |
children | 175370634226 |
comparison
equal
deleted
inserted
replaced
667:fb69aef056ea | 668:ef6d3dc9e930 |
---|---|
57 | 57 |
58 #ifndef SELECTION_FILE_NAME | 58 #ifndef SELECTION_FILE_NAME |
59 #define SELECTION_FILE_NAME L"currently_selected.txt" | 59 #define SELECTION_FILE_NAME L"currently_selected.txt" |
60 #endif | 60 #endif |
61 | 61 |
62 /**@def The maximum time to wait for the NSS Process */ | |
62 #define PROCESS_TIMEOUT 30000 | 63 #define PROCESS_TIMEOUT 30000 |
64 | |
65 /**@def The registry key to look for user profile directories */ | |
66 #define PROFILE_LIST L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList" | |
63 | 67 |
64 /**@brief Write strv of instructions to a handle | 68 /**@brief Write strv of instructions to a handle |
65 * | 69 * |
66 * Writes the null terminated list of instructions to | 70 * Writes the null terminated list of instructions to |
67 * the handle. | 71 * the handle. |
132 } | 136 } |
133 } | 137 } |
134 return true; | 138 return true; |
135 } | 139 } |
136 | 140 |
141 /**@brief Get the path to all users default registry hive | |
142 * | |
143 * Enumerates the keys in #PROFILE_LIST and retuns a | |
144 * strv array with the utf-8 encoded paths to their suggested | |
145 * registry hive location. | |
146 * | |
147 * Users with an SID not starting with S-1-5-21- are ignored | |
148 * as is the current user. | |
149 * | |
150 * Use strv_free to free that array. | |
151 * | |
152 * @returns a newly allocated strv of the paths to the registry hives or NULL | |
153 */ | |
154 | |
155 static char** | |
156 locate_other_hives() | |
157 { | |
158 HKEY profile_list = NULL; | |
159 int ret = 0; | |
160 DWORD index = 0, | |
161 key_len = 257; | |
162 /* According to | |
163 http://msdn.microsoft.com/en-us/library/windows/desktop/ms724872%28v=vs.85%29.aspx | |
164 a registry key is limited to 255 characters. But according to | |
165 http://www.sepago.de/e/holger/2010/07/20/how-long-can-a-registry-key-name-really-be | |
166 the actual limit is 256 + \0 thus we create a buffer for 257 wchar_t's*/ | |
167 wchar_t key_name[257]; | |
168 char **retval = NULL; | |
169 bool error = true; | |
170 | |
171 ret = RegOpenKeyExW (HKEY_LOCAL_MACHINE, PROFILE_LIST, 0, | |
172 KEY_READ, &profile_list); | |
173 if (ret != ERROR_SUCCESS) | |
174 { | |
175 ERRORPRINTF ("Failed to open profile list. Error: %i", ret); | |
176 return NULL; | |
177 } | |
178 | |
179 while ((ret = RegEnumKeyExW (profile_list, index++, | |
180 key_name, &key_len, | |
181 NULL, NULL, NULL, NULL)) == ERROR_SUCCESS) | |
182 { | |
183 if (key_len == 257) | |
184 { | |
185 ERRORPRINTF ("Registry key too long."); | |
186 goto done; | |
187 } | |
188 DEBUGPRINTF ("Key : %S", key_name); | |
189 | |
190 /* Reset key_len to buffer size */ | |
191 key_len = 257; | |
192 | |
193 if (wcsncmp (L"S-1-5-21-", key_name, 9) != 0) | |
194 { | |
195 /* S-1-5-21 is the well known prefix for local users. Skip all others */ | |
196 continue; | |
197 } | |
198 } | |
199 | |
200 if (ret != ERROR_NO_MORE_ITEMS) | |
201 { | |
202 ERRORPRINTF ("Failed to enumeratre profile list. Error: %i", ret); | |
203 goto done; | |
204 } | |
205 | |
206 done: | |
207 RegCloseKey (profile_list); | |
208 | |
209 if (error) | |
210 { | |
211 strv_free (retval); | |
212 retval = NULL; | |
213 } | |
214 | |
215 return retval; | |
216 } | |
217 | |
218 /**@brief Register NSS process as runOnce for other users | |
219 * | |
220 * Loads the registry hives of other users on the system and | |
221 * adds a RunOnce registry key to start the NSS process to | |
222 * install the current selection on their next login. | |
223 * | |
224 * This should avoid conflicts with their firefox / thunderbird | |
225 * while making the certificates available for their applications. | |
226 * | |
227 * This function needs SE_BACKUP_NAME and SE_RESTORE_NAME | |
228 * privileges. | |
229 * | |
230 * @param [in] selection_file filename of the file containing | |
231 * the users install / remove selection. | |
232 */ | |
233 void | |
234 register_proccesses_for_others (wchar_t *selection_file) | |
235 { | |
236 char **hives = locate_other_hives(); | |
237 | |
238 strv_free (hives); | |
239 printf("Selection file %S", selection_file); | |
240 } | |
241 | |
137 /**@brief Start the process to install / remove | 242 /**@brief Start the process to install / remove |
138 * | 243 * |
139 * Starts the NSS installation process for the current user | 244 * Starts the NSS installation process for the current user |
140 * | 245 * |
141 * @param [in] selection_file filename of the file containing | 246 * @param [in] selection_file filename of the file containing |
142 * the users installall / remove selection. | 247 * the users install / remove selection. |
143 * | 248 * |
144 * @returns true on success, false on error. | 249 * @returns true on success, false on error. |
145 */ | 250 */ |
146 static bool | 251 static bool |
147 start_procces_for_user (wchar_t *selection_file) | 252 start_procces_for_user (wchar_t *selection_file) |
516 return -1; | 621 return -1; |
517 } | 622 } |
518 | 623 |
519 DEBUGPRINTF ("Wrote selection file. Loc: %S\n", selection_file_name); | 624 DEBUGPRINTF ("Wrote selection file. Loc: %S\n", selection_file_name); |
520 | 625 |
521 /* TODO loop over all users create startup entries for them*/ | 626 if (is_elevated()) |
627 { | |
628 register_proccesses_for_others (selection_file_name); | |
629 } | |
522 | 630 |
523 if (!start_procces_for_user (selection_file_name)) | 631 if (!start_procces_for_user (selection_file_name)) |
524 { | 632 { |
525 ERRORPRINTF ("Failed to run NSS installation process.\n"); | 633 ERRORPRINTF ("Failed to run NSS installation process.\n"); |
526 xfree(selection_file_name); | 634 xfree(selection_file_name); |