Hervé Poussineau poussine@freesurf.fr (Partial) implementation of CheckTokenMembership() Modified: trunk/reactos/lib/advapi32/token/token.c _____
Modified: trunk/reactos/lib/advapi32/token/token.c --- trunk/reactos/lib/advapi32/token/token.c 2005-02-06 22:06:44 UTC (rev 13452) +++ trunk/reactos/lib/advapi32/token/token.c 2005-02-06 22:16:05 UTC (rev 13453) @@ -313,16 +313,85 @@
/* - * @unimplemented + * @implemented */ BOOL STDCALL -CheckTokenMembership(HANDLE Token, PSID SidToCheck, PBOOL IsMember) +CheckTokenMembership (HANDLE ExistingTokenHandle, + PSID SidToCheck, + PBOOL IsMember) { - DPRINT1("CheckTokenMembership not implemented\n"); - - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - - return FALSE; + HANDLE AccessToken; + BOOL ReleaseToken = FALSE; + BOOL Result = FALSE; + DWORD dwSize; + DWORD i; + PTOKEN_GROUPS lpGroups = NULL; + TOKEN_TYPE TokenInformation; + + if (IsMember == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (ExistingTokenHandle == NULL) + { + /* Get impersonation token of the calling thread */ + if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &ExistingTokenHandle)) + return FALSE; + + if (!DuplicateToken(ExistingTokenHandle, SecurityAnonymous, &AccessToken)) + { + CloseHandle(ExistingTokenHandle); + goto ByeBye; + } + CloseHandle(ExistingTokenHandle); + ReleaseToken = TRUE; + } + else + { + if (!GetTokenInformation(ExistingTokenHandle, TokenType, &TokenInformation, sizeof(TokenInformation), &dwSize)) + goto ByeBye; + if (TokenInformation != TokenImpersonation) + { + /* Duplicate token to have a impersonation token */ + if (!DuplicateToken(ExistingTokenHandle, SecurityAnonymous, &AccessToken)) + return FALSE; + ReleaseToken = TRUE; + } + else + AccessToken = ExistingTokenHandle; + } + + *IsMember = FALSE; + /* Search in groups of the token */ + if (!GetTokenInformation(AccessToken, TokenGroups, NULL, 0, &dwSize)) + goto ByeBye; + lpGroups = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), 0, dwSize); + if (!lpGroups) + goto ByeBye; + if (!GetTokenInformation(AccessToken, TokenGroups, lpGroups, dwSize, &dwSize)) + goto ByeBye; + for (i = 0; i < lpGroups->GroupCount; i++) + { + if (EqualSid(SidToCheck, &lpGroups->Groups[i].Sid)) + { + Result = TRUE; + *IsMember = TRUE; + goto ByeBye; + } + } + /* FIXME: Search in users of the token? */ + DPRINT1("CheckTokenMembership() partially implemented!\n"); + Result = TRUE; + +ByeBye: + if (lpGroups != NULL) + HeapFree(GetProcessHeap(), 0, lpGroups); + if (ReleaseToken) + CloseHandle(AccessToken); + + return Result; }
/* EOF */