changeset 670:175370634226

Move getProcessOwner to util and use it to skip the current user in locate other hives
author Andre Heinecke <andre.heinecke@intevation.de>
date Fri, 27 Jun 2014 10:27:08 +0200
parents 7147550ee15d
children d4766b4922c9
files cinst/nssstore_win.c common/util.c common/util.h ui/processhelp_win.cpp
diffstat 4 files changed, 106 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/cinst/nssstore_win.c	Thu Jun 26 17:42:52 2014 +0200
+++ b/cinst/nssstore_win.c	Fri Jun 27 10:27:08 2014 +0200
@@ -39,6 +39,7 @@
 */
 
 #include <windows.h>
+#include <sddl.h>
 #include <stdio.h>
 #include <stdbool.h>
 #include <userenv.h>
@@ -164,9 +165,11 @@
      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];
+  wchar_t key_name[257],
+          *current_user_sid = NULL;
   char **retval = NULL;
   bool error = true;
+  PSID current_user = NULL;
 
   ret = RegOpenKeyExW (HKEY_LOCAL_MACHINE, PROFILE_LIST, 0,
                        KEY_READ, &profile_list);
@@ -176,6 +179,22 @@
       return NULL;
     }
 
+
+  /* Obtain the current user sid to prevent it from being returned. */
+  current_user = get_process_owner (GetCurrentProcess());
+
+  if (!current_user)
+    {
+      ERRORPRINTF ("Failed to get the current user.");
+      goto done;
+    }
+
+  if (!ConvertSidToStringSidW (current_user, &current_user_sid))
+    {
+      PRINTLASTERROR ("Failed to convert sid to string.");
+      goto done;
+    }
+
   while ((ret = RegEnumKeyExW (profile_list, index++,
                                key_name, &key_len,
                                NULL, NULL, NULL, NULL)) == ERROR_SUCCESS)
@@ -185,16 +204,19 @@
           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)
+      if (wcsncmp (L"S-1-5-21-", key_name, 9) != 0 ||
+          wcscmp (current_user_sid, key_name) == 0)
         {
-          /* S-1-5-21 is the well known prefix for local users. Skip all others */
+          /* S-1-5-21 is the well known prefix for local users. Skip all
+             others and the current user*/
           continue;
         }
+
+      DEBUGPRINTF ("Key : %S", key_name);
     }
 
   if (ret != ERROR_NO_MORE_ITEMS)
@@ -204,8 +226,15 @@
     }
 
 done:
+  xfree (current_user);
+
   RegCloseKey (profile_list);
 
+  if (current_user_sid)
+    {
+      LocalFree (current_user_sid);
+    }
+
   if (error)
     {
       strv_free (retval);
--- a/common/util.c	Thu Jun 26 17:42:52 2014 +0200
+++ b/common/util.c	Fri Jun 27 10:27:08 2014 +0200
@@ -19,6 +19,55 @@
 #include <windows.h>
 #endif
 
+static PSID
+copy_sid(PSID from)
+{
+  if (!from)
+    {
+      return 0;
+    }
+
+  DWORD sidLength = GetLengthSid(from);
+  PSID to = (PSID) xmalloc(sidLength);
+  CopySid(sidLength, to, from);
+  return to;
+}
+
+
+PSID
+get_process_owner(HANDLE hProcess)
+{
+    HANDLE hToken = NULL;
+    PSID sid;
+
+    if (hProcess == NULL)
+      {
+        ERRORPRINTF ("invalid call to get_process_owner");
+        return NULL;
+      }
+
+    OpenProcessToken(hProcess, TOKEN_READ, &hToken);
+    if (hToken)
+      {
+        DWORD size = 0;
+        PTOKEN_USER userStruct;
+
+        // check how much space is needed
+        GetTokenInformation(hToken, TokenUser, NULL, 0, &size);
+        if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
+          {
+            userStruct = (PTOKEN_USER) xmalloc (size);
+            GetTokenInformation(hToken, TokenUser, userStruct, size, &size);
+
+            sid = copy_sid(userStruct->User.Sid);
+            CloseHandle(hToken);
+            xfree (userStruct);
+            return sid;
+          }
+      }
+    return NULL;
+}
+
 bool
 is_elevated()
 {
--- a/common/util.h	Thu Jun 26 17:42:52 2014 +0200
+++ b/common/util.h	Fri Jun 27 10:27:08 2014 +0200
@@ -12,6 +12,11 @@
  */
 #include <stdbool.h>
 
+#ifdef WIN32
+#include <windows.h>
+#include <psapi.h>
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -33,6 +38,21 @@
  */
 bool is_admin();
 
+#ifdef WIN32
+/**@brief Get a copy of the processes owner sid
+ *
+ * Copy the SID of the owner of the process hProcess.
+ *
+ * The returned sid structure has to be freed with free by the caller
+ *
+ * @param[in] hProcess A handle to the process whose user should be obtained.
+ * The process must have the PROCESS_QUERY_INFORMATION access permission.
+ *
+ * @returns A copy of the process owners sid or NULL on error.
+ */
+PSID get_process_owner(HANDLE hProcess);
+#endif
+
 #ifdef __cplusplus
 }
 #endif
--- a/ui/processhelp_win.cpp	Thu Jun 26 17:42:52 2014 +0200
+++ b/ui/processhelp_win.cpp	Fri Jun 27 10:27:08 2014 +0200
@@ -8,6 +8,7 @@
 #ifdef WIN32
 #include "processhelp.h"
 #include "strhelp.h"
+#include "util.h"
 
 #include <windows.h>
 #include <tlhelp32.h>
@@ -22,43 +23,6 @@
     HWND windowId;
 };
 
-PSID copySid(PSID from)
-{
-    if (!from) {
-        return 0;
-    }
-
-    int sidLength = GetLengthSid(from);
-    PSID to = (PSID) xmalloc(sidLength);
-    CopySid(sidLength, to, from);
-    return to;
-}
-
-static PSID getProcessOwner(HANDLE hProcess)
-{
-    HANDLE hToken = NULL;
-    PSID sid;
-
-    OpenProcessToken(hProcess, TOKEN_READ, &hToken);
-    if (hToken) {
-        DWORD size;
-        PTOKEN_USER userStruct;
-
-        // check how much space is needed
-        GetTokenInformation(hToken, TokenUser, NULL, 0, &size);
-        if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
-            userStruct = reinterpret_cast<PTOKEN_USER>(new BYTE[size]);
-            GetTokenInformation(hToken, TokenUser, userStruct, size, &size);
-
-            sid = copySid(userStruct->User.Sid);
-            CloseHandle(hToken);
-            delete [] userStruct;
-            return sid;
-        }
-    }
-    return 0;
-}
-
 BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
 {
     if (GetWindowLong(hwnd, GWL_STYLE) & WS_VISIBLE) {
@@ -74,7 +38,6 @@
     return TRUE;
 }
 
-
 static HANDLE getProcessHandle(int processID)
 {
     return OpenProcess(SYNCHRONIZE |
@@ -108,7 +71,7 @@
     do {
         const QString exeFile = QString::fromWCharArray(pe32.szExeFile).toLower();
         if (exeFile == processNameLower || exeFile == processNameExe) {
-            PSID user_sid = getProcessOwner(GetCurrentProcess());
+            PSID user_sid = get_process_owner(GetCurrentProcess());
             if (user_sid) {
                 // Also check that we are the owner of that process
                 HANDLE hProcess = getProcessHandle(pe32.th32ProcessID);
@@ -116,8 +79,8 @@
                     continue;
                 }
 
-                PSID sid = getProcessOwner(hProcess);
-                PSID userSid = getProcessOwner(GetCurrentProcess());
+                PSID sid = get_process_owner(hProcess);
+                PSID userSid = get_process_owner(GetCurrentProcess());
                 if (!sid || (userSid && !EqualSid(userSid, sid))) {
                     free(sid);
                     continue;

http://wald.intevation.org/projects/trustbridge/