Leaked source code of windows server 2003
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.
 
 
 
 
 
 

343 lines
7.0 KiB

//
// Copyright (C) 2000, Microsoft Corporation
//
// File: gensecurity.c
//
// Contents:
//
// History:
//
//-----------------------------------------------------------------------------
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include "rpc.h"
#include "rpcdce.h"
#include <ole2.h>
#include <activeds.h>
#include <WinLdap.h>
#include <NtLdap.h>
#include <ntdsapi.h>
#include "dfsheader.h"
#include "dfsmisc.h"
PVOID
DfsAllocateSecurityData(ULONG Size )
{
PVOID pBuff = NULL;
pBuff = (PVOID) malloc (Size);
return pBuff;
}
VOID
DfsDeallocateSecurityData(PVOID pPointer )
{
if(pPointer)
{
free (pPointer);
}
}
DFSSTATUS
AccessImpersonateCheckRpcClientEx(PSECURITY_DESCRIPTOR DfsAdminSecurityDesc,
GENERIC_MAPPING * DfsAdminGenericMapping,
DWORD DesiredAccess)
{
BOOL accessGranted = FALSE;
DWORD grantedAccess = 0;
HANDLE clientToken = NULL;
DWORD privilegeSetSize = 0;
DFSSTATUS dwErr = 0;
DFSSTATUS RevertStatus = 0;
BYTE privilegeSet[500]; // Large buffer
if (RpcImpersonateClient(NULL) != ERROR_SUCCESS)
{
return ERROR_ACCESS_DENIED;
}
privilegeSetSize = sizeof(privilegeSet);
if (OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_QUERY,
TRUE, &clientToken))
{
if (AccessCheck(
DfsAdminSecurityDesc,
clientToken,
DesiredAccess,
DfsAdminGenericMapping,
(PPRIVILEGE_SET) privilegeSet,
&privilegeSetSize,
&grantedAccess,
&accessGranted) != TRUE)
{
accessGranted = FALSE; // paranoia
//
// No need to call GetLastError since we intend to return
// ACCESS_DENIED regardless.
//
dwErr = GetLastError();
}
}
RevertStatus = RpcRevertToSelf();
if (clientToken != NULL)
{
CloseHandle( clientToken );
}
if( !accessGranted )
{
dwErr = ERROR_ACCESS_DENIED;
}
return dwErr;
}
VOID DumpSID(
CHAR *pad,
PSID sid_to_dump,
ULONG Flag
)
{
NTSTATUS ntstatus;
UNICODE_STRING us;
Flag;
if (sid_to_dump)
{
WCHAR rgchName[256];
DWORD cbName = sizeof(rgchName);
WCHAR rgchDomain[256];
DWORD cbDomain = sizeof(rgchDomain);
SID_NAME_USE snu;
ntstatus = RtlConvertSidToUnicodeString(&us, sid_to_dump, TRUE);
if (NT_SUCCESS(ntstatus))
{
printf("%s%wZ", pad, &us);
RtlFreeUnicodeString(&us);
}
else
{
printf("0x%08lx: Can't Convert SID to UnicodeString\n", ntstatus);
}
if (LookupAccountSid(NULL, sid_to_dump, rgchName, &cbName, rgchDomain, &cbDomain, &snu))
{
printf(" %ws\\%ws:", rgchDomain, rgchName);
switch (snu)
{
case SidTypeUser:
printf("User");
break;
case SidTypeGroup:
printf("Group");
break;
case SidTypeDomain:
printf("Domain");
break;
case SidTypeAlias:
printf("Alias");
break;
case SidTypeWellKnownGroup:
printf("Well Known Group");
break;
case SidTypeDeletedAccount:
printf("Deleted Account");
break;
case SidTypeInvalid:
printf("Invalid");
break;
case SidTypeUnknown:
printf("Unknown");
break;
case SidTypeComputer:
printf("Computer");
break;
default:
printf("Unknown use: %d\n", snu);
}
}
printf("\n");
}
else
{
printf("%s is NULL\n", pad);
}
}
/*
- DumpToken
-
* Purpose:
* to dump a token
*
* Parameters:
*
* pad IN the string the prepend
* htoken IN the token to dump
*/
BOOL
DumpToken(
IN char *pad,
IN HANDLE htoken)
{
BOOL fRet;
DWORD dwError;
DWORD dwLenNeeded;
BYTE rgb[128];
PTOKEN_USER ptu = (PTOKEN_USER) rgb;
PTOKEN_USER ptuToFree = NULL;
TOKEN_PRIMARY_GROUP *ptpg = (TOKEN_PRIMARY_GROUP*) rgb;
TOKEN_PRIMARY_GROUP *ptpgToFree = NULL;
TOKEN_GROUPS *ptg = (TOKEN_GROUPS*) rgb;
TOKEN_GROUPS *ptgToFree = NULL;
// dump token user
fRet = GetTokenInformation(htoken, TokenUser, (void*) ptu, sizeof(rgb), &dwLenNeeded);
if (!fRet)
{
dwError = GetLastError();
if (dwError == ERROR_INSUFFICIENT_BUFFER)
{
ptuToFree = (PTOKEN_USER) malloc(dwLenNeeded);
if (!ptuToFree)
{
printf("OOM\n");
goto Error;
}
ptu = ptuToFree;
fRet = GetTokenInformation(htoken, TokenUser, (void*) ptu, dwLenNeeded, &dwLenNeeded);
if (!fRet)
{
dwError = GetLastError();
}
}
}
if (fRet)
{
printf("%s Token user is:\n", pad);
DumpSID("", ptu->User.Sid, 0);
}
else
{
printf("%s 0x%08lx: Failed to get TokenUser\n", pad, dwError);
}
// dump token primary group
fRet = GetTokenInformation(htoken, TokenPrimaryGroup, (void*) ptpg, sizeof(rgb), &dwLenNeeded);
if (!fRet)
{
dwError = GetLastError();
if (dwError == ERROR_INSUFFICIENT_BUFFER)
{
ptpgToFree = (TOKEN_PRIMARY_GROUP*) malloc(dwLenNeeded);
if (!ptpgToFree)
{
printf("OOM\n");
goto Error;
}
ptpg = ptpgToFree;
fRet = GetTokenInformation(htoken, TokenPrimaryGroup, (void*) ptpg, dwLenNeeded, &dwLenNeeded);
if (!fRet)
{
dwError = GetLastError();
}
}
}
if (fRet)
{
printf("%s Token's primary group is: \n", pad);
DumpSID("", ptpg->PrimaryGroup, 0);
}
else
{
printf("%s 0x%08lx: Failed to get TokenPrimaryGroup\n", pad, dwError);
}
// dump token groups
// TODO: add code to dump group attributes (in Text format)
fRet = GetTokenInformation(htoken, TokenGroups, (void*) ptg, sizeof(rgb), &dwLenNeeded);
if (!fRet)
{
dwError = GetLastError();
if (dwError == ERROR_INSUFFICIENT_BUFFER)
{
ptgToFree = (TOKEN_GROUPS*) malloc(dwLenNeeded);
if (!ptgToFree)
{
printf("OOM\n");
goto Error;
}
ptg = ptgToFree;
fRet = GetTokenInformation(htoken, TokenGroups, (void*) ptg, dwLenNeeded, &dwLenNeeded);
if (!fRet)
{
dwError = GetLastError();
}
}
}
if (fRet)
{
UINT i;
printf("%s token's groups are:\n", pad);
for (i = 0; i < ptg->GroupCount; i++)
{
DumpSID("", ptg->Groups[i].Sid, 0);
}
}
else
{
printf("%s 0x%08lx: Failed to get TokenGroups\n", pad, dwError);
}
// TODO: add code to dump other stuff later
Cleanup:
if (ptuToFree)
{
free(ptuToFree);
}
if (ptpgToFree)
{
free(ptpgToFree);
}
if (ptgToFree)
{
free(ptgToFree);
}
return fRet;
Error:
fRet = FALSE;
goto Cleanup;
}