shell32: Check if token references the current user

ge at gse.nl ge at gse.nl
Sat Dec 29 14:55:54 CST 2007


Changelog:
  Ge van Geldorp <ge at thinstall.com>
  Check if token references the current user
  Fixes bug 10905

---
 dlls/shell32/shellpath.c |   83 +++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 82 insertions(+), 1 deletions(-)

diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c
index 5be77d7..37f2f8e 100644
--- a/dlls/shell32/shellpath.c
+++ b/dlls/shell32/shellpath.c
@@ -1359,6 +1359,52 @@ static HRESULT _SHGetCurrentVersionPath(DWORD dwFlags, BYTE folder,
     return hr;
 }
 
+static PSID GetUserFromToken(HANDLE Token)
+{
+    char InfoBuffer[64];
+    PTOKEN_USER UserInfo;
+    DWORD InfoSize;
+    PSID Sid;
+    DWORD SidSize;
+
+    UserInfo = (PTOKEN_USER) InfoBuffer;
+    if (! GetTokenInformation(Token, TokenUser, InfoBuffer, sizeof(InfoBuffer),
+                              &InfoSize))
+    {
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+            return NULL;
+        UserInfo = HeapAlloc(GetProcessHeap(), 0, InfoSize);
+        if (UserInfo == NULL)
+            return NULL;
+        if (! GetTokenInformation(Token, TokenUser, UserInfo, InfoSize,
+                                  &InfoSize))
+        {
+            HeapFree(GetProcessHeap(), 0, UserInfo);
+            return NULL;
+        }
+    }
+
+    SidSize = GetLengthSid(UserInfo->User.Sid);
+    Sid = HeapAlloc(GetProcessHeap(), 0, SidSize);
+    if (Sid == NULL)
+    {
+        if (UserInfo != (PTOKEN_USER) InfoBuffer)
+            HeapFree(GetProcessHeap(), 0, UserInfo);
+        return NULL;
+    }
+
+    if (! CopySid(SidSize, Sid, UserInfo->User.Sid))
+    {
+        HeapFree(GetProcessHeap(), 0, Sid);
+        Sid = NULL;
+    }
+
+    if (UserInfo != (PTOKEN_USER) InfoBuffer)
+        HeapFree(GetProcessHeap(), 0, UserInfo);
+
+    return Sid;
+}
+
 /* Gets the user's path (unexpanded) for the CSIDL with index folder:
  * If SHGFP_TYPE_DEFAULT is set, calls _SHGetDefaultValue for it.  Otherwise
  * calls _SHGetUserShellFolderPath for it.  Where it looks depends on hToken:
@@ -1371,6 +1417,9 @@ static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder,
  LPWSTR pszPath)
 {
     HRESULT hr;
+    PSID UserFromToken;
+    HANDLE ProcessToken;
+    PSID CurrentUser;
 
     TRACE("%p,0x%08x,0x%02x,%p\n", hToken, dwFlags, folder, pszPath);
 
@@ -1382,7 +1431,8 @@ static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder,
         return E_INVALIDARG;
 
     /* Only the current user and the default user are supported right now
-     * I'm afraid.
+     * I'm afraid. We do handle the case where the token references the
+     * current user.
      * FIXME: should be able to call GetTokenInformation on the token,
      * then call ConvertSidToStringSidW on it to get the user prefix.
      * But Wine's registry doesn't store user info by sid, it stores it
@@ -1391,6 +1441,37 @@ static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder,
      */
     if (hToken != NULL && hToken != (HANDLE)-1)
     {
+        UserFromToken = GetUserFromToken(hToken);
+        if (UserFromToken != NULL)
+        {
+            if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY,
+                                 &ProcessToken))
+            {
+                CurrentUser = GetUserFromToken(ProcessToken);
+                if (CurrentUser != NULL)
+                {
+                    if (EqualSid(CurrentUser, UserFromToken))
+                    {
+                        TRACE("Token is for current user\n");
+                        hToken = NULL;
+                    }
+                    HeapFree(GetProcessHeap(), 0, CurrentUser);
+                }
+                else
+                    ERR("Failed to get current user sid, error %d\n",
+                        GetLastError());
+                CloseHandle(ProcessToken);
+            }
+            else
+                ERR("Failed to open process token, error %d\n", GetLastError());
+            HeapFree(GetProcessHeap(), 0, UserFromToken);
+        }
+        else
+            ERR("Failed to get user sid from token, error %d\n",
+                GetLastError());
+    }
+    if (hToken != NULL && hToken != (HANDLE)-1)
+    {
         FIXME("unsupported for user other than current or default\n");
         return E_FAIL;
     }
-- 
1.5.2.4




More information about the wine-patches mailing list