You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
456 lines
11 KiB
456 lines
11 KiB
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#include "common.h"
|
|
#include "security.h"
|
|
#include "debugout.h"
|
|
|
|
|
|
/*
|
|
* GetTokenHandle
|
|
*/
|
|
|
|
BOOL GetTokenHandle(
|
|
PHANDLE pTokenHandle )
|
|
{
|
|
|
|
if (OpenThreadToken( GetCurrentThread(), TOKEN_READ, FALSE, pTokenHandle))
|
|
return TRUE;
|
|
|
|
if (GetLastError() != ERROR_NO_TOKEN)
|
|
return FALSE;
|
|
|
|
if (OpenProcessToken( GetCurrentProcess(), TOKEN_READ, pTokenHandle))
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
* MakeLocalOnlySD
|
|
*
|
|
* Purpose: Generate a self-relative SD whose ACL contains only an
|
|
* entry for LocalSystem/GENERIC_ALL access. This SD will be used
|
|
* in calls to CreateFile() for clipbook page files.
|
|
*
|
|
* Parameters: None
|
|
*
|
|
* Returns: Pointer to the security descriptor. This pointer may be freed.
|
|
* Returns NULL on failure.
|
|
*/
|
|
|
|
PSECURITY_DESCRIPTOR MakeLocalOnlySD (void)
|
|
{
|
|
PSECURITY_DESCRIPTOR pSD;
|
|
PSECURITY_DESCRIPTOR pSDSelfRel = NULL;
|
|
SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
|
|
|
|
PSID sidLocal;
|
|
PACL Acl;
|
|
DWORD dwAclSize;
|
|
|
|
|
|
if (AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID,
|
|
0, 0, 0, 0, 0, 0, 0, &sidLocal))
|
|
{
|
|
if (InitializeSecurityDescriptor(&pSD, SECURITY_DESCRIPTOR_REVISION))
|
|
{
|
|
// Allocate space for DACL with "System Full Control" access
|
|
dwAclSize = sizeof(ACL)+ GetLengthSid(sidLocal) +
|
|
sizeof(ACCESS_ALLOWED_ACE) + 42; // 42==fudge factor
|
|
if (Acl = (PACL)GlobalAlloc(GPTR, dwAclSize))
|
|
{
|
|
if (InitializeAcl(Acl, dwAclSize, ACL_REVISION))
|
|
{
|
|
// LocalSystem gets all access, nobody else gets any.
|
|
if (AddAccessAllowedAce(Acl, ACL_REVISION,
|
|
GENERIC_ALL, sidLocal))
|
|
{
|
|
if (SetSecurityDescriptorDacl(pSD, TRUE, Acl, TRUE))
|
|
{
|
|
DWORD dwSelfRelLen;
|
|
|
|
dwSelfRelLen = GetSecurityDescriptorLength(pSD);
|
|
pSDSelfRel = GlobalAlloc(GPTR, dwSelfRelLen);
|
|
if (pSDSelfRel)
|
|
{
|
|
if (!MakeSelfRelativeSD(pSD, pSDSelfRel, &dwSelfRelLen))
|
|
{
|
|
GlobalFree((HANDLE)pSDSelfRel);
|
|
pSDSelfRel = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GlobalFree((HANDLE)Acl);
|
|
}
|
|
}
|
|
FreeSid(sidLocal);
|
|
}
|
|
return(pSDSelfRel);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
* CurrentUserOnlySD
|
|
*
|
|
* Purpose: Create a security descriptor containing only a single
|
|
* DACL entry-- one to allow the user whose context we are running
|
|
* in GENERIC_ALL access.
|
|
*
|
|
* Parameters: None.
|
|
*
|
|
* Returns: A pointer to the security descriptor described above,
|
|
* or NULL on failure.
|
|
*/
|
|
|
|
PSECURITY_DESCRIPTOR CurrentUserOnlySD (void)
|
|
{
|
|
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
|
|
|
|
SECURITY_DESCRIPTOR aSD;
|
|
PSECURITY_DESCRIPTOR pSD = NULL;
|
|
BOOL OK;
|
|
PACL TmpAcl;
|
|
PACCESS_ALLOWED_ACE TmpAce;
|
|
DWORD lSD;
|
|
LONG DaclLength;
|
|
DWORD lTokenInfo;
|
|
HANDLE hClientToken;
|
|
TOKEN_USER *pUserTokenInfo;
|
|
|
|
|
|
if (!InitializeSecurityDescriptor(&aSD, SECURITY_DESCRIPTOR_REVISION)
|
|
|| GetTokenHandle(&hClientToken))
|
|
{
|
|
PERROR(TEXT("Couldn't get token handle or InitSD bad \r\n"));
|
|
return NULL;
|
|
}
|
|
|
|
|
|
// See if the token info fits in 50 bytes. If it does, fine.
|
|
// If not, realloc to proper size and get the token info.
|
|
pUserTokenInfo = (TOKEN_USER *)LocalAlloc( LMEM_FIXED, 50 );
|
|
if (pUserTokenInfo && !GetTokenInformation( hClientToken, TokenUser,
|
|
(LPVOID) pUserTokenInfo, 50, &lTokenInfo ) )
|
|
{
|
|
LocalFree( pUserTokenInfo );
|
|
pUserTokenInfo = (TOKEN_USER *)LocalAlloc( LMEM_FIXED, lTokenInfo );
|
|
if (!GetTokenInformation( hClientToken, TokenUser,
|
|
(LPVOID) pUserTokenInfo, lTokenInfo, &lTokenInfo ) )
|
|
{
|
|
LocalFree( pUserTokenInfo );
|
|
pUserTokenInfo = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
if (!pUserTokenInfo)
|
|
{
|
|
PERROR(TEXT("Couldn't get usertokeninfo\r\n"));
|
|
}
|
|
else
|
|
{
|
|
// Figure out how big a Dacl we'll need for just me to be on it.
|
|
DaclLength = (DWORD)sizeof(ACL) +
|
|
GetLengthSid( pUserTokenInfo->User.Sid ) +
|
|
(DWORD)sizeof( ACCESS_ALLOWED_ACE );
|
|
|
|
if (!(TmpAcl = (PACL)LocalAlloc(LMEM_FIXED, DaclLength )))
|
|
{
|
|
PERROR(TEXT("LocalAllof for Acl fail\r\n"));
|
|
}
|
|
else
|
|
{
|
|
if (!InitializeAcl( TmpAcl, DaclLength, ACL_REVISION ))
|
|
{
|
|
PERROR(TEXT("InitializeAcl fail\r\n"));
|
|
}
|
|
else if (!AddAccessAllowedAce( TmpAcl, ACL_REVISION,
|
|
GENERIC_ALL, pUserTokenInfo->User.Sid ))
|
|
{
|
|
PERROR(TEXT("AddAccessAllowedAce fail\r\n"));
|
|
}
|
|
else if (!GetAce( TmpAcl, 0, (LPVOID *)&TmpAce))
|
|
{
|
|
PERROR("GetAce error %d", GetLastError());
|
|
}
|
|
else
|
|
{
|
|
TmpAce->Header.AceFlags = 0;
|
|
OK = SetSecurityDescriptorDacl(&aSD, TRUE, TmpAcl, FALSE);
|
|
lSD = GetSecurityDescriptorLength( &aSD);
|
|
|
|
if (pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, lSD))
|
|
{
|
|
MakeSelfRelativeSD( &aSD, pSD, &lSD);
|
|
|
|
if( IsValidSecurityDescriptor( pSD ) )
|
|
{
|
|
LocalFree(pSD);
|
|
pSD = NULL;
|
|
}
|
|
else
|
|
{
|
|
PERROR(TEXT("Failed creating self-relative SD (%d)."),
|
|
GetLastError());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PERROR(TEXT("LocalAlloc for pSD fail\r\n"));
|
|
}
|
|
}
|
|
|
|
LocalFree((HANDLE)TmpAcl);
|
|
}
|
|
|
|
LocalFree((HANDLE)pUserTokenInfo);
|
|
}
|
|
|
|
CloseHandle(hClientToken);
|
|
|
|
return pSD;
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
|
/*
|
|
* HexDumpBytes
|
|
*/
|
|
|
|
void HexDumpBytes(
|
|
char *pv,
|
|
unsigned cb)
|
|
{
|
|
char achHex[]="0123456789ABCDEF";
|
|
char achOut[80];
|
|
unsigned iOut;
|
|
|
|
|
|
|
|
iOut = 0;
|
|
|
|
while (cb)
|
|
{
|
|
if (iOut >= 78)
|
|
{
|
|
PINFO(achOut);
|
|
iOut = 0;
|
|
}
|
|
|
|
achOut[iOut++] = achHex[(*pv >> 4) & 0x0f];
|
|
achOut[iOut++] = achHex[*pv++ & 0x0f];
|
|
achOut[iOut] = '\0';
|
|
cb--;
|
|
}
|
|
|
|
|
|
if (iOut)
|
|
{
|
|
PINFO(achOut);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* PrintSid
|
|
*/
|
|
|
|
void PrintSid(
|
|
PSID sid)
|
|
{
|
|
DWORD cSubAuth;
|
|
DWORD i;
|
|
|
|
PINFO(TEXT("\r\nSID: "));
|
|
|
|
if (sid)
|
|
{
|
|
HexDumpBytes((char *)GetSidIdentifierAuthority(sid), sizeof(SID_IDENTIFIER_AUTHORITY));
|
|
|
|
SetLastError(0);
|
|
cSubAuth = *GetSidSubAuthorityCount(sid);
|
|
if (GetLastError())
|
|
{
|
|
PINFO(TEXT("Invalid SID\r\n"));
|
|
}
|
|
else
|
|
{
|
|
for (i = 0;i < cSubAuth; i++)
|
|
{
|
|
PINFO(TEXT("-"));
|
|
HexDumpBytes((char *)GetSidSubAuthority(sid, i), sizeof(DWORD));
|
|
}
|
|
PINFO(TEXT("\r\n"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PINFO(TEXT("NULL SID\r\n"));
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* PrintAcl
|
|
*
|
|
* Purpose: Print out the entries in an access-control list.
|
|
*/
|
|
|
|
void PrintAcl(
|
|
PACL pacl)
|
|
{
|
|
ACL_SIZE_INFORMATION aclsi;
|
|
ACCESS_ALLOWED_ACE *pace;
|
|
unsigned i;
|
|
|
|
|
|
if (pacl)
|
|
{
|
|
if (GetAclInformation (pacl, &aclsi, sizeof(aclsi), AclSizeInformation))
|
|
{
|
|
for (i = 0;i < aclsi.AceCount;i++)
|
|
{
|
|
GetAce(pacl, i, &pace);
|
|
|
|
PINFO(TEXT("Type(%x) Flags(%x) Access(%lx)\r\nSID:"),
|
|
(int)pace->Header.AceType,
|
|
(int)pace->Header.AceFlags,
|
|
pace->Mask);
|
|
PrintSid((PSID)&(pace->SidStart));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PINFO(TEXT("NULL PACL\r\n"));
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* PrintSD
|
|
*/
|
|
|
|
void PrintSD(
|
|
PSECURITY_DESCRIPTOR pSD)
|
|
{
|
|
DWORD dwRev;
|
|
WORD wSDC;
|
|
BOOL fDefault, fAcl;
|
|
PACL pacl;
|
|
PSID sid;
|
|
|
|
|
|
|
|
if (NULL == pSD)
|
|
{
|
|
PINFO(TEXT("NULL sd\r\n"));
|
|
return;
|
|
}
|
|
|
|
if (!IsValidSecurityDescriptor(pSD))
|
|
{
|
|
PINFO(TEXT("Bad SD %p"), pSD);
|
|
return;
|
|
}
|
|
|
|
// Drop control info and revision
|
|
if (GetSecurityDescriptorControl(pSD, &wSDC, &dwRev))
|
|
{
|
|
PINFO(TEXT("SD - Length: [%ld] Control: [%x] [%lx]\r\nGroup:"),
|
|
GetSecurityDescriptorLength(pSD), wSDC, dwRev);
|
|
}
|
|
else
|
|
{
|
|
PINFO(TEXT("Couldn't get control\r\nGroup"));
|
|
}
|
|
|
|
// Show group and owner
|
|
if (GetSecurityDescriptorGroup(pSD, &sid, &fDefault) &&
|
|
sid &&
|
|
IsValidSid(sid))
|
|
{
|
|
PrintSid(sid);
|
|
PINFO(TEXT(" %s default.\r\nOwner:"), fDefault ? TEXT(" ") : TEXT("Not"));
|
|
}
|
|
else
|
|
{
|
|
PINFO(TEXT("Couldn't get group\r\n"));
|
|
}
|
|
|
|
if (GetSecurityDescriptorOwner(pSD, &sid, &fDefault) &&
|
|
sid &&
|
|
IsValidSid(sid))
|
|
{
|
|
PrintSid(sid);
|
|
PINFO(TEXT(" %s default.\r\n"), fDefault ? TEXT(" ") : TEXT("Not"));
|
|
}
|
|
else
|
|
{
|
|
PINFO(TEXT("Couldn't get owner\r\n"));
|
|
}
|
|
|
|
// Print DACL and SACL
|
|
if (GetSecurityDescriptorDacl(pSD, &fAcl, &pacl, &fDefault))
|
|
{
|
|
PINFO(TEXT("DACL: %s %s\r\n"), fAcl ? "Yes" : "No",
|
|
fDefault ? "Default" : " ");
|
|
if (fAcl)
|
|
{
|
|
if (pacl && IsValidAcl(pacl))
|
|
{
|
|
PrintAcl(pacl);
|
|
}
|
|
else
|
|
{
|
|
PINFO(TEXT("Invalid Acl %p\r\n"), pacl);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PINFO(TEXT("Couldn't get DACL\r\n"));
|
|
}
|
|
|
|
if (GetSecurityDescriptorSacl(pSD, &fAcl, &pacl, &fDefault))
|
|
{
|
|
PINFO(TEXT("SACL: %s %s\r\n"), fAcl ? "Yes" : "No", fDefault ? "Default" : " ");
|
|
if (fAcl)
|
|
{
|
|
if (pacl && IsValidAcl(pacl))
|
|
{
|
|
PrintAcl(pacl);
|
|
}
|
|
else
|
|
{
|
|
PINFO(TEXT("Invalid ACL %p\r\n"), pacl);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PINFO(TEXT("Couldn't get SACL\r\n"));
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
#define PrintSid(x)
|
|
#define PrintSD(x)
|
|
#endif
|