[PATCH 1 of 2] Obtain privileges required for registry modification
Wald Commits
scm-commit at wald.intevation.org
Mon Jun 30 11:26:08 CEST 2014
# HG changeset patch
# User Andre Heinecke <andre.heinecke at intevation.de>
# Date 1404120340 -7200
# Node ID cb40af11ec3a9471e1208aae2a3ecca7424d3dd4
# Parent 4ad764bfb39caf2f5eaeacb71daa18ac956d95d5
Obtain privileges required for registry modification
diff -r 4ad764bfb39c -r cb40af11ec3a cinst/nssstore_win.c
--- a/cinst/nssstore_win.c Fri Jun 27 18:53:52 2014 +0200
+++ b/cinst/nssstore_win.c Mon Jun 30 11:25:40 2014 +0200
@@ -429,6 +429,105 @@
return retval;
}
+/** @brief Increase the privileges of the current token to allow registry access
+ *
+ * To load another users registry you need SE_BACKUP_NAME and SE_RESTORE_NAME
+ * privileges. Normally if we are running elevated we can obtain them.
+ *
+ * @returns true if the privileges could be obtained. False otherwise
+ */
+static bool
+get_backup_restore_priv()
+{
+ HANDLE hToken = NULL;
+ PTOKEN_PRIVILEGES psToken = NULL;
+ DWORD token_size = 0,
+ dwI = 0,
+ token_size_new = 0,
+ privilege_size = 128;
+ char privilege_name[128];
+ bool retval = false;
+ bool backup_found = false;
+ bool restore_found = false;
+
+
+ if (!OpenProcessToken (GetCurrentProcess(),
+ TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
+ {
+ PRINTLASTERROR ("Failed to get process token.");
+ return false;
+ }
+
+ /* Get the size for the token */
+ GetTokenInformation (hToken, TokenPrivileges, NULL, 0, &token_size);
+ if (token_size == 0)
+ {
+ PRINTLASTERROR ("Failed to get token size.");
+ goto done;
+ }
+
+ psToken = xmalloc(token_size);
+
+ if (!GetTokenInformation (hToken, TokenPrivileges, psToken, token_size, &token_size_new))
+ {
+ PRINTLASTERROR ("Failed to get token information.");
+ goto done;
+ }
+
+ if (token_size != token_size_new)
+ {
+ ERRORPRINTF ("Size changed.");
+ goto done;
+ }
+
+ for(dwI = 0; dwI < psToken->PrivilegeCount; dwI++)
+ {
+ privilege_size = sizeof (privilege_name);
+ if (!LookupPrivilegeNameA (NULL, &psToken->Privileges[dwI].Luid,
+ privilege_name, &privilege_size))
+ {
+ PRINTLASTERROR ("Failed to lookup privilege name");
+ }
+
+ if(strcmp(privilege_name, "SeRestorePrivilege") == 0)
+ {
+ psToken->Privileges[dwI].Attributes |= SE_PRIVILEGE_ENABLED;
+ restore_found = true;
+ continue;
+ }
+ if(strcmp(privilege_name, "SeBackupPrivilege") == 0)
+ {
+ psToken->Privileges[dwI].Attributes |= SE_PRIVILEGE_ENABLED;
+ backup_found = true;
+ continue;
+ }
+ if (backup_found && restore_found)
+ {
+ break;
+ }
+ }
+
+ if (backup_found && restore_found)
+ {
+ if(!AdjustTokenPrivileges (hToken, 0, psToken, token_size, NULL, NULL))
+ {
+ PRINTLASTERROR ("Failed to adjust token privileges.");
+ }
+ else
+ {
+ retval = true;
+ }
+ }
+
+done:
+ if (hToken != NULL)
+ {
+ CloseHandle(hToken);
+ }
+ xfree(psToken);
+ return retval;
+}
+
/**@brief Register NSS process as runOnce for other users
*
* Loads the registry hives of other users on the system and
@@ -444,7 +543,7 @@
* @param [in] selection_file filename of the file containing
* the users install / remove selection.
*/
-void
+static void
register_proccesses_for_others (wchar_t *selection_file)
{
char **hives = locate_other_hives();
@@ -456,6 +555,13 @@
DEBUGPRINTF ("No hives found.");
return;
}
+
+ if (!get_backup_restore_priv())
+ {
+ ERRORPRINTF ("Failed to obtain backup / restore privileges.");
+ return;
+ }
+
run_command = get_command_line (selection_file);
for (i = 0; hives[i] != NULL; i++)
{
More information about the Trustbridge-commits
mailing list