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