[PATCH 5 of 6] Framework for NSS multiuser installation on windows
Wald Commits
scm-commit at wald.intevation.org
Thu Jun 26 17:43:21 CEST 2014
# HG changeset patch
# User Andre Heinecke <andre.heinecke at intevation.de>
# Date 1403797344 -7200
# Node ID ef6d3dc9e930f3d539d335343042c43fdd793ca2
# Parent fb69aef056ea2b8616f9610d570ad782123b6e3f
Framework for NSS multiuser installation on windows
diff -r fb69aef056ea -r ef6d3dc9e930 cinst/nssstore_win.c
--- a/cinst/nssstore_win.c Thu Jun 26 17:41:53 2014 +0200
+++ b/cinst/nssstore_win.c Thu Jun 26 17:42:24 2014 +0200
@@ -59,8 +59,12 @@
#define SELECTION_FILE_NAME L"currently_selected.txt"
#endif
+/**@def The maximum time to wait for the NSS Process */
#define PROCESS_TIMEOUT 30000
+/**@def The registry key to look for user profile directories */
+#define PROFILE_LIST L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList"
+
/**@brief Write strv of instructions to a handle
*
* Writes the null terminated list of instructions to
@@ -134,12 +138,113 @@
return true;
}
+/**@brief Get the path to all users default registry hive
+ *
+ * Enumerates the keys in #PROFILE_LIST and retuns a
+ * strv array with the utf-8 encoded paths to their suggested
+ * registry hive location.
+ *
+ * Users with an SID not starting with S-1-5-21- are ignored
+ * as is the current user.
+ *
+ * Use strv_free to free that array.
+ *
+ * @returns a newly allocated strv of the paths to the registry hives or NULL
+ */
+
+static char**
+locate_other_hives()
+{
+ HKEY profile_list = NULL;
+ int ret = 0;
+ DWORD index = 0,
+ key_len = 257;
+ /* According to
+ http://msdn.microsoft.com/en-us/library/windows/desktop/ms724872%28v=vs.85%29.aspx
+ a registry key is limited to 255 characters. But according to
+ http://www.sepago.de/e/holger/2010/07/20/how-long-can-a-registry-key-name-really-be
+ the actual limit is 256 + \0 thus we create a buffer for 257 wchar_t's*/
+ wchar_t key_name[257];
+ char **retval = NULL;
+ bool error = true;
+
+ ret = RegOpenKeyExW (HKEY_LOCAL_MACHINE, PROFILE_LIST, 0,
+ KEY_READ, &profile_list);
+ if (ret != ERROR_SUCCESS)
+ {
+ ERRORPRINTF ("Failed to open profile list. Error: %i", ret);
+ return NULL;
+ }
+
+ while ((ret = RegEnumKeyExW (profile_list, index++,
+ key_name, &key_len,
+ NULL, NULL, NULL, NULL)) == ERROR_SUCCESS)
+ {
+ if (key_len == 257)
+ {
+ ERRORPRINTF ("Registry key too long.");
+ goto done;
+ }
+ DEBUGPRINTF ("Key : %S", key_name);
+
+ /* Reset key_len to buffer size */
+ key_len = 257;
+
+ if (wcsncmp (L"S-1-5-21-", key_name, 9) != 0)
+ {
+ /* S-1-5-21 is the well known prefix for local users. Skip all others */
+ continue;
+ }
+ }
+
+ if (ret != ERROR_NO_MORE_ITEMS)
+ {
+ ERRORPRINTF ("Failed to enumeratre profile list. Error: %i", ret);
+ goto done;
+ }
+
+done:
+ RegCloseKey (profile_list);
+
+ if (error)
+ {
+ strv_free (retval);
+ retval = NULL;
+ }
+
+ return retval;
+}
+
+/**@brief Register NSS process as runOnce for other users
+*
+* Loads the registry hives of other users on the system and
+* adds a RunOnce registry key to start the NSS process to
+* install the current selection on their next login.
+*
+* This should avoid conflicts with their firefox / thunderbird
+* while making the certificates available for their applications.
+*
+* This function needs SE_BACKUP_NAME and SE_RESTORE_NAME
+* privileges.
+*
+* @param [in] selection_file filename of the file containing
+* the users install / remove selection.
+*/
+void
+register_proccesses_for_others (wchar_t *selection_file)
+{
+ char **hives = locate_other_hives();
+
+ strv_free (hives);
+ printf("Selection file %S", selection_file);
+}
+
/**@brief Start the process to install / remove
*
* Starts the NSS installation process for the current user
*
* @param [in] selection_file filename of the file containing
-* the users installall / remove selection.
+* the users install / remove selection.
*
* @returns true on success, false on error.
*/
@@ -518,7 +623,10 @@
DEBUGPRINTF ("Wrote selection file. Loc: %S\n", selection_file_name);
- /* TODO loop over all users create startup entries for them*/
+ if (is_elevated())
+ {
+ register_proccesses_for_others (selection_file_name);
+ }
if (!start_procces_for_user (selection_file_name))
{
More information about the Trustbridge-commits
mailing list