[take 2] shell32: Check if token references the current user
ge at gse.nl
ge at gse.nl
Thu Jan 10 14:01:17 CST 2008
Incorporates feedback by Juan Lang
Changelog:
Ge van Geldorp <ge at thinstall.com>
Check if token references the current user
Fixes bug 10905
---
dlls/shell32/shellpath.c | 99 +++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 97 insertions(+), 2 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c
index 5be77d7..c1f5e2a 100644
--- a/dlls/shell32/shellpath.c
+++ b/dlls/shell32/shellpath.c
@@ -1359,6 +1359,100 @@ 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;
+}
+
+/*
+ * Return TRUE if the token references the currently logged in user
+ */
+BOOL _IsCurrentUserToken(HANDLE hToken)
+{
+ PSID UserFromToken;
+ BOOL IsCurrentUser;
+
+ if (hToken == NULL)
+ return TRUE;
+ if (hToken == (HANDLE) -1)
+ return FALSE;
+
+ IsCurrentUser = FALSE;
+ UserFromToken = _GetUserFromToken(hToken);
+ if (UserFromToken != NULL)
+ {
+ HANDLE ProcessToken;
+ if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY,
+ &ProcessToken))
+ {
+ PSID CurrentUser;
+ CurrentUser = _GetUserFromToken(ProcessToken);
+ if (CurrentUser != NULL)
+ {
+ if (EqualSid(CurrentUser, UserFromToken))
+ {
+ TRACE("Token is for current user\n");
+ IsCurrentUser = TRUE;
+ }
+ 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());
+
+ return IsCurrentUser;
+}
+
/* 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:
@@ -1382,14 +1476,15 @@ 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
* by user name (and I don't know how to convert from a token to a
* user name).
*/
- if (hToken != NULL && hToken != (HANDLE)-1)
+ if (hToken != NULL && hToken != (HANDLE)-1 && ! _IsCurrentUserToken(hToken))
{
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