- Implement NtCreateToken()

- Implement RtlGetAce()
- Fix bug which cause RtlCreateAcl() to always fail.
- Cleanup parameter names and fix bug that caused a buffer overrun in RtlCopySidAndAttributesArray()
- When referencing the token object in NtQueryInformationToken() pass in either TOKEN_QUERY access or TOKEN_QUERY_SOURCE access. Passing in zero led to ObReferenceObjectByHandle() always failing with ACCESS_DENIED.
- Fixed NtQueryInformationToken() to check the buffer length and return STATUS_BUFFER_TO_SMALL and the required length.
- Ensure that the ReturnLength is set correctly when NtQueryInformationToken() succeeds. Previously, it was set to the number of bytes unused in the user buffer in some cases or not set at all.
- Handle case of NULL default dacl correctly in NtQueryInformationToken()
- Update main makefile to build apps\utils.
- Update makefiles in apps\utils to have the correct PATH_TO_TOP.
- Update main makefile to build apps\tests\tokentest

Written by Joseph Galbraith.

svn path=/trunk/; revision=3024
This commit is contained in:
Eric Kohl 2002-06-07 23:00:20 +00:00
parent 33cc33c731
commit bb14287865
16 changed files with 1186 additions and 314 deletions

View file

@ -82,7 +82,11 @@ SYS_APPS = autochk services shell winlogon
# pteb regtest sectest shm simple thread vmtest winhello
TEST_APPS = alive apc args atomtest bench consume count dump_shared_data \
event file gditest hello isotest lpc mstest mutex nptest \
pteb regtest sectest shm simple thread vmtest winhello
pteb regtest sectest shm simple thread tokentest vmtest winhello
# Test applications
# cabman cat net objdir partinfo pice ps stats
UTIL_APPS = cat objdir partinfo stats
#
# Wine userspace win32 subsystem plus other stuff. This will all be moved
@ -116,19 +120,19 @@ KERNEL_DRIVERS = $(DRIVERS_LIB) $(DEVICE_DRIVERS) $(INPUT_DRIVERS) $(FS_DRIVERS)
all: tools dk implib $(COMPONENTS) $(HALS) $(BUS) $(DLLS) $(SUBSYS) \
$(LOADERS) $(KERNEL_DRIVERS) $(SYS_APPS) $(TEST_APPS) \
$(WINE_MODULES)
$(UTIL_APPS) $(WINE_MODULES)
implib: $(COMPONENTS:%=%_implib) $(HALS:%=%_implib) $(BUS:%=%_implib) \
$(DLLS:%=%_implib) $(LOADERS:%=%_implib) \
$(KERNEL_DRIVERS:%=%_implib) $(SUBSYS:%=%_implib) \
$(SYS_APPS:%=%_implib) $(TEST_APPS:%=%_implib) \
$(WINE_MODULES:%=%_implib)
$(UTIL_APPS:%=%_implib) $(WINE_MODULES:%=%_implib)
clean: dk_clean $(HALS:%=%_clean) \
$(COMPONENTS:%=%_clean) $(BUS:%=%_clean) $(DLLS:%=%_clean) \
$(LOADERS:%=%_clean) $(KERNEL_DRIVERS:%=%_clean) $(SUBSYS:%=%_clean) \
$(SYS_APPS:%=%_clean) $(TEST_APPS:%=%_clean) $(NET_APPS:%=%_clean) \
$(WINE_MODULES:%=%_clean) clean_after tools_clean
$(SYS_APPS:%=%_clean) $(TEST_APPS:%=%_clean) $(UTIL_APPS:%=%_clean) \
$(NET_APPS:%=%_clean) $(WINE_MODULES:%=%_clean) clean_after tools_clean
clean_after:
$(RM) $(PATH_TO_TOP)/include/roscfg.h
@ -138,16 +142,17 @@ install: tools install_dirs install_before \
$(DLLS:%=%_install) $(LOADERS:%=%_install) \
$(KERNEL_DRIVERS:%=%_install) $(SUBSYS:%=%_install) \
$(SYS_APPS:%=%_install) $(TEST_APPS:%=%_install) \
$(WINE_MODULES:%=%_install)
$(UTIL_APPS:%=%_install) $(WINE_MODULES:%=%_install)
dist: $(TOOLS_PATH)/rcopy$(EXE_POSTFIX) dist_clean dist_dirs \
$(HALS:%=%_dist) $(COMPONENTS:%=%_dist) $(BUS:%=%_dist) $(DLLS:%=%_dist) \
$(LOADERS:%=%_dist) $(KERNEL_DRIVERS:%=%_dist) $(SUBSYS:%=%_dist) \
$(SYS_APPS:%=%_dist) $(TEST_APPS:%=%_dist) $(NET_APPS:%=%_dist) \
$(WINE_MODULES:%=%_dist)
$(SYS_APPS:%=%_dist) $(TEST_APPS:%=%_dist) $(UTIL_APPS:%=%_dist) \
$(NET_APPS:%=%_dist) $(WINE_MODULES:%=%_dist)
.PHONY: all implib clean clean_before install dist
#
# System Applications
#
@ -168,8 +173,9 @@ $(SYS_APPS:%=%_install): %_install:
.PHONY: $(SYS_APPS) $(SYS_APPS:%=%_implib) $(SYS_APPS:%=%_clean) $(SYS_APPS:%=%_install) $(SYS_APPS:%=%_dist)
#
# Applications
# Test Applications
#
$(TEST_APPS): %:
make -C apps/tests/$*
@ -188,6 +194,28 @@ $(TEST_APPS:%=%_install): %_install:
.PHONY: $(TEST_APPS) $(TEST_APPS:%=%_implib) $(TEST_APPS:%=%_clean) $(TEST_APPS:%=%_install) $(TEST_APPS:%=%_dist)
#
# Utility Applications
#
$(UTIL_APPS): %:
make -C apps/utils/$*
$(UTIL_APPS:%=%_implib): %_implib:
make -C apps/utils/$* implib
$(UTIL_APPS:%=%_clean): %_clean:
make -C apps/utils/$* clean
$(UTIL_APPS:%=%_dist): %_dist:
make -C apps/utils/$* dist
$(UTIL_APPS:%=%_install): %_install:
make -C apps/utils/$* install
.PHONY: $(UTIL_APPS) $(UTIL_APPS:%=%_implib) $(UTIL_APPS:%=%_clean) $(UTIL_APPS:%=%_install) $(UTIL_APPS:%=%_dist)
#
# Other Wine Modules
#
@ -208,6 +236,7 @@ $(WINE_OTHER:%=%_install): %_install:
.PHONY: $(WINE_OTHER) $(WINE_OTHER:%=%_implib) $(WINE_OTHER:%=%_clean) $(WINE_OTHER:%=%_install) $(WINE_OTHER:%=%_dist)
#
# Wine Tools
#

View file

@ -0,0 +1,21 @@
# $Id: makefile,v 1.1 2002/06/07 22:57:13 ekohl Exp $
PATH_TO_TOP = ../../..
TARGET_NORC = yes
TARGET_TYPE = program
TARGET_APPTYPE = console
TARGET_NAME = tokentest
TARGET_SDKLIBS = ntdll.a kernel32.a
TARGET_OBJECTS = $(TARGET_NAME).o
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
# EOF

View file

@ -0,0 +1,510 @@
#define UNICODE
#define _UNICODE
#define ANONYMOUSUNIONS
#include <windows.h>
#define INCLUDE_THE_DDK_HEADERS
#ifdef INCLUDE_THE_DDK_HEADERS
#include <ddk/ntddk.h>
#define ROS_ACE_HEADER ACE_HEADER
#define ROS_ACE ACE
//
// Allocate the System Luid. The first 1000 LUIDs are reserved.
// Use #999 here (0x3E7 = 999)
//
#define SYSTEM_LUID { 0x3E7, 0x0 }
#define ANONYMOUS_LOGON_LUID { 0x3e6, 0x0 }
#define LOCALSERVICE_LUID { 0x3e5, 0x0 }
#define NETWORKSERVICE_LUID { 0x3e4, 0x0 }
#else
typedef LONG NTSTATUS, *PNTSTATUS;
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef struct _ROS_ACE_HEADER
{
CHAR AceType;
CHAR AceFlags;
USHORT AceSize;
ACCESS_MASK AccessMask;
} ROS_ACE_HEADER, *PROS_ACE_HEADER;
typedef struct
{
ACE_HEADER Header;
} ROS_ACE, *PROS_ACE;
NTSYSAPI
NTSTATUS
NTAPI
RtlConvertSidToUnicodeString (
IN OUT PUNICODE_STRING String,
IN PSID Sid,
IN BOOLEAN AllocateString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateAcl(
PACL Acl,
ULONG AclSize,
ULONG AclRevision);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAccessAllowedAce (
PACL Acl,
ULONG Revision,
ACCESS_MASK AccessMask,
PSID Sid
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetAce (
PACL Acl,
ULONG AceIndex,
PROS_ACE *Ace
);
NTSYSAPI
NTSTATUS
NTAPI
ZwAllocateLocallyUniqueId(
OUT PLUID Luid
);
NTSYSAPI
NTSTATUS
NTAPI
ZwCreateToken(
OUT PHANDLE TokenHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN TOKEN_TYPE TokenType,
IN PLUID AuthenticationId,
IN PLARGE_INTEGER ExpirationTime,
IN PTOKEN_USER TokenUser,
IN PTOKEN_GROUPS TokenGroups,
IN PTOKEN_PRIVILEGES TokenPrivileges,
IN PTOKEN_OWNER TokenOwner,
IN PTOKEN_PRIMARY_GROUP TokenPrimaryGroup,
IN PTOKEN_DEFAULT_DACL TokenDefaultDacl,
IN PTOKEN_SOURCE TokenSource
);
#define NT_SUCCESS(StatCode) ((NTSTATUS)(StatCode) >= 0)
#endif
#include <stdio.h>
#define INITIAL_PRIV_ENABLED SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED
#define INITIAL_PRIV_DISABLED 0
LUID_AND_ATTRIBUTES InitialPrivilegeSet[] =
{
{ { 0x00000007, 0x00000000 }, INITIAL_PRIV_ENABLED }, // SeTcbPrivilege
{ { 0x00000002, 0x00000000 }, INITIAL_PRIV_DISABLED }, // SeCreateTokenPrivilege
{ { 0x00000009, 0x00000000 }, INITIAL_PRIV_DISABLED }, // SeTakeOwnershipPrivilege
{ { 0x0000000f, 0x00000000 }, INITIAL_PRIV_ENABLED }, // SeCreatePagefilePrivilege
{ { 0x00000004, 0x00000000 }, INITIAL_PRIV_ENABLED }, // SeLockMemoryPrivilege
{ { 0x00000003, 0x00000000 }, INITIAL_PRIV_DISABLED }, // SeAssignPrimaryTokenPrivilege
{ { 0x00000005, 0x00000000 }, INITIAL_PRIV_DISABLED }, // SeIncreaseQuotaPrivilege
{ { 0x0000000e, 0x00000000 }, INITIAL_PRIV_ENABLED }, // SeIncreaseBasePriorityPrivilege
{ { 0x00000010, 0x00000000 }, INITIAL_PRIV_ENABLED }, // SeCreatePermanentPrivilege
{ { 0x00000014, 0x00000000 }, INITIAL_PRIV_ENABLED }, // SeDebugPrivilege
{ { 0x00000015, 0x00000000 }, INITIAL_PRIV_ENABLED }, // SeAuditPrivilege
{ { 0x00000008, 0x00000000 }, INITIAL_PRIV_DISABLED }, // SeSecurityPrivilege
{ { 0x00000016, 0x00000000 }, INITIAL_PRIV_DISABLED }, // SeSystemEnvironmentPrivilege
{ { 0x00000017, 0x00000000 }, INITIAL_PRIV_ENABLED }, // SeChangeNotifyPrivilege
{ { 0x00000011, 0x00000000 }, INITIAL_PRIV_DISABLED }, // SeBackupPrivilege
{ { 0x00000012, 0x00000000 }, INITIAL_PRIV_DISABLED }, // SeRestorePrivilege
{ { 0x00000013, 0x00000000 }, INITIAL_PRIV_DISABLED }, // SeShutdownPrivilege
{ { 0x0000000a, 0x00000000 }, INITIAL_PRIV_DISABLED }, // SeLoadDriverPrivilege
{ { 0x0000000d, 0x00000000 }, INITIAL_PRIV_ENABLED }, // SeProfileSingleProcessPrivilege
{ { 0x0000000c, 0x00000000 }, INITIAL_PRIV_DISABLED }, // SeSystemtimePrivilege
{ { 0x00000019, 0x00000000 }, INITIAL_PRIV_DISABLED }, // SeUndockPrivilege
{ { 0x0000001c, 0x00000000 }, INITIAL_PRIV_DISABLED }, // SeManageVolumePrivilege
};
typedef struct _SID_2
{
UCHAR Revision;
UCHAR SubAuthorityCount;
SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
ULONG SubAuthority[2];
} SID_2;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
PrintSid(SID_AND_ATTRIBUTES* pSid, TOKEN_OWNER* pOwner, TOKEN_PRIMARY_GROUP* pPrimary)
{
UNICODE_STRING scSid;
RtlConvertSidToUnicodeString(&scSid, pSid->Sid, TRUE);
printf("%wZ [", &scSid);
LocalFree(scSid.Buffer);
if ( EqualSid(pSid->Sid, pOwner->Owner) )
printf("owner,");
if ( EqualSid(pSid->Sid, pPrimary->PrimaryGroup) )
printf("primary,");
if ( pSid->Attributes & SE_GROUP_ENABLED )
{
if ( pSid->Attributes & SE_GROUP_ENABLED_BY_DEFAULT )
printf("enabled-default,");
else
printf("enabled,");
}
if ( pSid->Attributes & SE_GROUP_LOGON_ID )
printf("logon,");
if ( pSid->Attributes & SE_GROUP_MANDATORY )
printf("mandatory,");
printf("]\n");
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
DisplayTokenSids(TOKEN_USER* pUser,
TOKEN_GROUPS* pGroups,
TOKEN_OWNER* pOwner,
TOKEN_PRIMARY_GROUP* pPrimary)
{
DWORD i;
printf("\nSids:\n");
PrintSid(&pUser->User, pOwner, pPrimary);
printf("\nGroups:\n");
for (i = 0; i < pGroups->GroupCount; i++)
PrintSid(&pGroups->Groups[i], pOwner, pPrimary);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
DisplayTokenPrivileges(TOKEN_PRIVILEGES* pPriv)
{
WCHAR buffer[256];
DWORD i;
printf("\nprivileges:\n");
for (i = 0; i < pPriv->PrivilegeCount; i++)
{
DWORD cbName = sizeof(buffer) / sizeof(buffer[0]);
LookupPrivilegeName(0, &pPriv->Privileges[i].Luid, buffer, &cbName);
printf("%S{0x%08x, 0x%08x} [", buffer, pPriv->Privileges[i].Luid.HighPart, pPriv->Privileges[i].Luid.LowPart);
if ( pPriv->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED )
printf("enabled,");
if ( pPriv->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED_BY_DEFAULT )
printf("default,");
if ( pPriv->Privileges[i].Attributes & SE_PRIVILEGE_USED_FOR_ACCESS )
printf("used");
printf("]\n");
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
DisplayDacl(PACL pAcl)
{
DWORD i;
NTSTATUS status;
if ( ! pAcl )
{
printf("\nNo Default Dacl.\n");
return;
}
printf("\nDacl:\n");
for (i = 0; i < pAcl->AceCount; i++)
{
UNICODE_STRING scSid;
ROS_ACE_HEADER* pAce;
LPWSTR wszType = 0;
status = RtlGetAce(pAcl, i, (ROS_ACE**) &pAce);
if ( pAce->AceType == ACCESS_ALLOWED_ACE_TYPE )
wszType = L"allow";
if ( pAce->AceType == ACCESS_DENIED_ACE_TYPE )
wszType = L"deny ";
RtlConvertSidToUnicodeString(&scSid, (PSID) (pAce + 1), TRUE);
printf("%S %wZ 0x%08x\n", wszType, &scSid, pAce->AccessMask);
LocalFree(scSid.Buffer);
}
{
ROS_ACE_HEADER* pAce;
status = RtlGetAce(pAcl, pAcl->AceCount, (ROS_ACE**) &pAce);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PVOID
GetFromToken(HANDLE hToken, TOKEN_INFORMATION_CLASS tic)
{
BOOL bResult;
DWORD n;
PBYTE p = 0;
bResult = GetTokenInformation(hToken, tic, 0, 0, &n);
if ( ! bResult && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return 0;
p = (PBYTE) malloc(n);
if ( ! GetTokenInformation(hToken, tic, p, n, &n) )
{
printf("GetFromToken() failed for TOKEN_INFORMATION_CLASS(%d): %d\n", tic, GetLastError());
free(p);
return 0;
}
return p;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
DisplayToken(HANDLE hTokenSource)
{
TOKEN_USER* pTokenUser = (PTOKEN_USER) GetFromToken(hTokenSource, TokenUser);
TOKEN_GROUPS* pTokenGroups = (PTOKEN_GROUPS) GetFromToken(hTokenSource, TokenGroups);
TOKEN_OWNER* pTokenOwner = (PTOKEN_OWNER) GetFromToken(hTokenSource, TokenOwner);
TOKEN_PRIMARY_GROUP* pTokenPrimaryGroup = (PTOKEN_PRIMARY_GROUP) GetFromToken(hTokenSource, TokenPrimaryGroup);
TOKEN_PRIVILEGES* pTokenPrivileges = (PTOKEN_PRIVILEGES) GetFromToken(hTokenSource, TokenPrivileges);
TOKEN_DEFAULT_DACL* pTokenDefaultDacl = (PTOKEN_DEFAULT_DACL) GetFromToken(hTokenSource, TokenDefaultDacl);
DisplayTokenSids(pTokenUser, pTokenGroups, pTokenOwner, pTokenPrimaryGroup);
// DisplayTokenPrivileges(pTokenPrivileges);
DisplayDacl(pTokenDefaultDacl->DefaultDacl);
free(pTokenUser);
free(pTokenGroups);
free(pTokenOwner);
free(pTokenPrimaryGroup);
free(pTokenPrivileges);
free(pTokenDefaultDacl);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BOOL
EnablePrivilege(LPWSTR wszName)
{
HANDLE hToken;
TOKEN_PRIVILEGES priv = {1, {0, 0, SE_PRIVILEGE_ENABLED}};
BOOL bResult;
LookupPrivilegeValue(0, wszName, &priv.Privileges[0].Luid);
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof priv, 0, 0);
bResult = GetLastError() == ERROR_SUCCESS;
CloseHandle(hToken);
return bResult;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NTSTATUS
CreateInitialSystemToken(HANDLE* phSystemToken)
{
static SID sidSystem = { 1, 1, SECURITY_NT_AUTHORITY, SECURITY_LOCAL_SYSTEM_RID };
static SID sidEveryone = { 1, 1, SECURITY_WORLD_SID_AUTHORITY, SECURITY_WORLD_RID };
static SID sidAuthenticatedUser = { 1, 1, SECURITY_NT_AUTHORITY, SECURITY_AUTHENTICATED_USER_RID };
static SID_2 sidAdministrators = { 1, 2, SECURITY_NT_AUTHORITY, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS };
static const int nGroupCount = 3;
NTSTATUS status;
ULONG uSize;
DWORD i;
TOKEN_USER tkUser;
TOKEN_OWNER tkDefaultOwner;
TOKEN_PRIMARY_GROUP tkPrimaryGroup;
TOKEN_GROUPS* ptkGroups = 0;
TOKEN_PRIVILEGES* ptkPrivileges = 0;
TOKEN_DEFAULT_DACL tkDefaultDacl = { 0 };
LARGE_INTEGER tkExpiration;
LUID authId = SYSTEM_LUID;
TOKEN_SOURCE source =
{
{ '*', '*', 'A', 'N', 'O', 'N', '*', '*' },
{0, 0}
};
SECURITY_QUALITY_OF_SERVICE sqos =
{
sizeof(sqos),
SecurityAnonymous,
SECURITY_STATIC_TRACKING,
FALSE
};
OBJECT_ATTRIBUTES oa =
{
sizeof(oa),
0,
0,
0,
0,
&sqos
};
tkExpiration.QuadPart = -1;
status = ZwAllocateLocallyUniqueId(&source.SourceIdentifier);
if ( status != 0 )
return status;
tkUser.User.Sid = &sidSystem;
tkUser.User.Attributes = 0;
// Under WinXP (the only MS OS I've tested) ZwCreateToken()
// squawks if we use sidAdministrators here -- though running
// a progrem under AT and using the DisplayToken() function
// shows that the system token does default ownership to
// Administrator.
// For now, default ownership to system, since that works
tkDefaultOwner.Owner = &sidSystem;
tkPrimaryGroup.PrimaryGroup = &sidSystem;
uSize = sizeof(TOKEN_GROUPS) - sizeof(ptkGroups->Groups);
uSize += sizeof(SID_AND_ATTRIBUTES) * nGroupCount;
ptkGroups = (TOKEN_GROUPS*) malloc(uSize);
ptkGroups->GroupCount = nGroupCount;
ptkGroups->Groups[0].Sid = &sidAdministrators;
ptkGroups->Groups[0].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY;
ptkGroups->Groups[1].Sid = &sidEveryone;
ptkGroups->Groups[1].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY;
ptkGroups->Groups[2].Sid = &sidAuthenticatedUser;
ptkGroups->Groups[2].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY;
uSize = sizeof(TOKEN_PRIVILEGES) - sizeof(ptkPrivileges->Privileges);
uSize += sizeof(LUID_AND_ATTRIBUTES) * sizeof(InitialPrivilegeSet) / sizeof(InitialPrivilegeSet[0]);
ptkPrivileges = (TOKEN_PRIVILEGES*) malloc(uSize);
ptkPrivileges->PrivilegeCount = sizeof(InitialPrivilegeSet) / sizeof(InitialPrivilegeSet[0]);
for (i = 0; i < ptkPrivileges->PrivilegeCount; i++)
{
ptkPrivileges->Privileges[i].Luid.HighPart = InitialPrivilegeSet[i].Luid.HighPart;
ptkPrivileges->Privileges[i].Luid.LowPart = InitialPrivilegeSet[i].Luid.LowPart;
ptkPrivileges->Privileges[i].Attributes = InitialPrivilegeSet[i].Attributes;
}
// Calculate the length needed for the ACL
uSize = sizeof(ACL);
uSize += sizeof(ACE_HEADER) + sizeof(sidSystem);
uSize += sizeof(ACE_HEADER) + sizeof(sidAdministrators);
uSize = (uSize & (~3)) + 8;
tkDefaultDacl.DefaultDacl = malloc(uSize);
printf("RtlCreateAcl(0x%08x, %d, %d)\n", tkDefaultDacl.DefaultDacl, uSize, ACL_REVISION);
status = RtlCreateAcl(tkDefaultDacl.DefaultDacl, uSize, ACL_REVISION);
if ( ! NT_SUCCESS(status) )
printf("RtlCreateAcl() failed: 0x%08x\n", status);
status = RtlAddAccessAllowedAce(tkDefaultDacl.DefaultDacl, ACL_REVISION, GENERIC_ALL, &sidSystem);
if ( ! NT_SUCCESS(status) )
printf("RtlAddAccessAllowedAce() failed: 0x%08x\n", status);
status = RtlAddAccessAllowedAce(tkDefaultDacl.DefaultDacl, ACL_REVISION, GENERIC_READ|GENERIC_EXECUTE|READ_CONTROL, &sidAdministrators);
if ( ! NT_SUCCESS(status) )
printf("RtlAddAccessAllowedAce() failed: 0x%08x\n", status);
printf("Calling ZwCreateToken()...\n");
status = ZwCreateToken(phSystemToken,
TOKEN_ALL_ACCESS,
&oa,
TokenPrimary,
&authId,
&tkExpiration,
&tkUser,
ptkGroups,
ptkPrivileges,
&tkDefaultOwner,
&tkPrimaryGroup,
&tkDefaultDacl,
&source);
// Cleanup
free(ptkGroups);
free(ptkPrivileges);
free(tkDefaultDacl.DefaultDacl);
return status;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int
main(int argc, char** argv[])
{
NTSTATUS status;
HANDLE hSystemToken;
CHAR buffer[512];
//#define DUMP_THIS_PROCESS
#ifdef DUMP_THIS_PROCESS
HANDLE hOurToken;
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_QUERY_SOURCE, &hOurToken);
DisplayToken(hOurToken);
CloseHandle(hOurToken);
#endif
//#define ENABLE_PRIVILEGE
#ifdef ENABLE_PRIVILEGE
EnablePrivilege(SE_CREATE_TOKEN_NAME);
#endif
// Now do the other one
status = CreateInitialSystemToken(&hSystemToken);
if ( status == 0 )
{
printf("System Token: 0x%08x\n", hSystemToken);
DisplayToken(hSystemToken);
CloseHandle(hSystemToken);
}
else
{
printf("CreateInitialSystemToken() return: 0x%08x\n", status);
}
printf("press return");
gets(buffer);
return 0;
}

View file

@ -1,7 +1,7 @@
#
# Makefile for ReactOS Cabinet Manager
#
PATH_TO_TOP = ../..
PATH_TO_TOP = ../../..
#FIXME: why doesn't this work?
#ZLIB_OBJECTS = $(PATH_TO_TOP)/lib/zlib/zlib.a

View file

@ -1,6 +1,6 @@
# $Id: makefile,v 1.9 2001/08/21 20:13:00 chorns Exp $
# $Id: makefile,v 1.10 2002/06/07 22:57:41 ekohl Exp $
PATH_TO_TOP = ../..
PATH_TO_TOP = ../../..
TARGET_NORC = yes

View file

@ -1,6 +1,6 @@
# $Id: makefile,v 1.5 2001/08/21 20:13:03 chorns Exp $
# $Id: makefile,v 1.6 2002/06/07 22:57:51 ekohl Exp $
PATH_TO_TOP = ../../..
PATH_TO_TOP = ../../../..
TARGET_PATH = common

View file

@ -1,6 +1,6 @@
# $Id: Makefile,v 1.4 2001/10/16 22:45:39 phreak Exp $
# $Id: Makefile,v 1.5 2002/06/07 22:58:02 ekohl Exp $
PATH_TO_TOP = ../../..
PATH_TO_TOP = ../../../..
TARGET_TYPE = program

View file

@ -1,6 +1,6 @@
# $Id: makefile,v 1.9 2001/10/16 22:45:40 phreak Exp $
# $Id: makefile,v 1.10 2002/06/07 22:58:10 ekohl Exp $
PATH_TO_TOP = ../..
PATH_TO_TOP = ../../..
TARGET_NORC = yes

View file

@ -1,6 +1,6 @@
# $Id: makefile,v 1.1 2001/08/25 17:02:21 ekohl Exp $
# $Id: makefile,v 1.2 2002/06/07 22:58:18 ekohl Exp $
PATH_TO_TOP = ../..
PATH_TO_TOP = ../../..
TARGET_NORC = yes

View file

@ -1,6 +1,6 @@
#
PATH_TO_TOP = ../..
PATH_TO_TOP = ../../..
TARGET_NORC = yes

View file

@ -1,6 +1,6 @@
# $Id: Makefile,v 1.1 2002/01/04 23:50:46 chorns Exp $
# $Id: Makefile,v 1.2 2002/06/07 22:58:37 ekohl Exp $
PATH_TO_TOP = ../..
PATH_TO_TOP = ../../..
TARGET_NORC = yes

View file

@ -1,6 +1,6 @@
# $Id: makefile.reactos,v 1.1 2002/03/17 21:05:02 hyperion Exp $
# $Id: makefile.reactos,v 1.2 2002/06/07 22:59:01 ekohl Exp $
PATH_TO_TOP = ../..
PATH_TO_TOP = ../../..
TARGET_TYPE = library

View file

@ -67,12 +67,17 @@ copy lib\ntdll\ntdll.dll %ROS_INSTALL%\system32
copy lib\secur32\secur32.dll %ROS_INSTALL%\system32
copy lib\user32\user32.dll %ROS_INSTALL%\system32
copy lib\ws2_32\ws2_32.dll %ROS_INSTALL%\system32
copy apps\tests\hello\hello.exe %ROS_INSTALL%\bin
copy apps\tests\args\args.exe %ROS_INSTALL%\bin
copy apps\tests\cat\cat.exe %ROS_INSTALL%\bin
copy subsys\smss\smss.exe %ROS_INSTALL%\system32
copy subsys\csrss\csrss.exe %ROS_INSTALL%\system32
copy subsys\win32k\win32k.sys %ROS_INSTALL%\system32\drivers
copy apps\utils\cat\cat.exe %ROS_INSTALL%\bin
copy apps\utils\partinfo\partinfo.exe %ROS_INSTALL%\bin
copy apps\utils\objdir\objdir.exe %ROS_INSTALL%\bin
copy apps\utils\pice\module\pice.sys %ROS_INSTALL%\system32\drivers
copy apps\utils\pice\module\pice.sym %ROS_INSTALL%\symbols
copy apps\utils\pice\pice.cfg %ROS_INSTALL%\symbols
copy apps\tests\hello\hello.exe %ROS_INSTALL%\bin
copy apps\tests\args\args.exe %ROS_INSTALL%\bin
copy apps\tests\apc\apc.exe %ROS_INSTALL%\bin
copy apps\tests\shm\shmsrv.exe %ROS_INSTALL%\bin
copy apps\tests\shm\shmclt.exe %ROS_INSTALL%\bin
@ -90,15 +95,11 @@ copy apps\tests\mstest\msclient.exe %ROS_INSTALL%\bin
copy apps\tests\nptest\npserver.exe %ROS_INSTALL%\bin
copy apps\tests\nptest\npclient.exe %ROS_INSTALL%\bin
copy apps\tests\atomtest\atomtest.exe %ROS_INSTALL%\bin
copy apps\tests\partinfo\partinfo.exe %ROS_INSTALL%\bin
copy apps\tests\objdir\objdir.exe %ROS_INSTALL%\bin
copy apps\tests\mutex\mutex.exe %ROS_INSTALL%\bin
copy apps\tests\winhello\winhello.exe %ROS_INSTALL%\bin
copy apps\tests\sectest\sectest.exe %ROS_INSTALL%\bin
copy apps\utils\pice\module\pice.sys %ROS_INSTALL%\system32\drivers
copy apps\utils\pice\module\pice.sym %ROS_INSTALL%\symbols
copy apps\utils\pice\pice.cfg %ROS_INSTALL%\symbols
copy apps\tests\isotest\isotest.exe %ROS_INSTALL%\bin
copy apps\tests\tokentest\tokentest.exe %ROS_INSTALL%\bin
copy media\fonts\helb____.ttf %ROS_INSTALL%\media\fonts
copy media\fonts\timr____.ttf %ROS_INSTALL%\media\fonts
copy media\nls\*.nls %ROS_INSTALL%\system32

View file

@ -1,4 +1,4 @@
/* $Id: acl.c,v 1.3 2000/06/29 23:35:28 dwelch Exp $
/* $Id: acl.c,v 1.4 2002/06/07 22:59:19 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -17,55 +17,83 @@
/* FUNCTIONS ***************************************************************/
BOOLEAN
STDCALL
RtlFirstFreeAce(PACL Acl, PACE* Ace)
BOOLEAN STDCALL
RtlFirstFreeAce(PACL Acl,
PACE* Ace)
{
PACE Current;
PVOID AclEnd;
ULONG i;
PACE Current;
PVOID AclEnd;
ULONG i;
Current = (PACE)(Acl + 1);
*Ace = NULL;
i = 0;
if (Acl->AceCount == 0)
{
*Ace = Current;
return(TRUE);
}
AclEnd = Acl->AclSize + Acl;
do
{
if ((PVOID)Current >= AclEnd)
{
return(FALSE);
}
if (Current->Header.AceType == 4)
{
if (Acl->AclRevision < 3)
{
return(FALSE);
}
}
Current = (PACE)((PVOID)Current + (ULONG)Current->Header.AceSize);
i++;
} while (i < Acl->AceCount);
if ((PVOID)Current >= AclEnd)
{
return(FALSE);
}
*Ace = Current;
return(TRUE);
Current = (PACE)(Acl + 1);
*Ace = NULL;
i = 0;
if (Acl->AceCount == 0)
{
*Ace = Current;
return(TRUE);
}
AclEnd = Acl->AclSize + Acl;
do
{
if ((PVOID)Current >= AclEnd)
{
return(FALSE);
}
if (Current->Header.AceType == 4)
{
if (Acl->AclRevision < 3)
{
return(FALSE);
}
}
Current = (PACE)((PVOID)Current + (ULONG)Current->Header.AceSize);
i++;
}
while (i < Acl->AceCount);
if ((PVOID)Current >= AclEnd)
{
return(FALSE);
}
*Ace = Current;
return(TRUE);
}
NTSTATUS
STDCALL
RtlGetAce(PACL Acl, ULONG AceIndex, PACE *Ace)
NTSTATUS STDCALL
RtlGetAce(PACL Acl,
ULONG AceIndex,
PACE *Ace)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
ULONG i;
PACE p = (PACE)(Acl + 1);
*Ace = NULL;
if (Acl->AclRevision != 2 &&
Acl->AclRevision != 3)
{
return(STATUS_UNKNOWN_REVISION);
}
if (AceIndex >= Acl->AceCount)
{
return(STATUS_INVALID_PARAMETER);
}
for (i = 0; i < AceIndex; i++)
{
p = (PACE)((PVOID)p + (ULONG)p->Header.AceSize);
}
*Ace = p;
return(STATUS_SUCCESS);
}
NTSTATUS
RtlpAddKnownAce(PACL Acl,
ULONG Revision,
@ -73,77 +101,71 @@ RtlpAddKnownAce(PACL Acl,
PSID Sid,
ULONG Type)
{
PACE Ace;
if (!RtlValidSid(Sid))
{
return(STATUS_UNSUCCESSFUL);
}
if (Acl->AclRevision > 3 ||
Revision > 3)
{
return(STATUS_UNSUCCESSFUL);
}
if (Revision < Acl->AclRevision)
{
Revision = Acl->AclRevision;
}
if (!RtlFirstFreeAce(Acl, &Ace))
{
return(STATUS_UNSUCCESSFUL);
}
if (Ace == NULL)
{
return(STATUS_UNSUCCESSFUL);
}
if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >=
((PVOID)Acl + Acl->AclSize))
{
return(STATUS_UNSUCCESSFUL);
}
Ace->Header.AceFlags = 0;
Ace->Header.AceType = Type;
Ace->Header.AceSize = RtlLengthSid(Sid) + sizeof(ACE);
Ace->Header.AccessMask = AccessMask;
RtlCopySid(RtlLengthSid(Sid), (PSID)Ace + 1, Sid);
Acl->AceCount++;
Acl->AclRevision = Revision;
return(STATUS_SUCCESS);
PACE Ace;
if (!RtlValidSid(Sid))
{
return(STATUS_UNSUCCESSFUL);
}
if (Acl->AclRevision > 3 ||
Revision > 3)
{
return(STATUS_UNSUCCESSFUL);
}
if (Revision < Acl->AclRevision)
{
Revision = Acl->AclRevision;
}
if (!RtlFirstFreeAce(Acl, &Ace))
{
return(STATUS_UNSUCCESSFUL);
}
if (Ace == NULL)
{
return(STATUS_UNSUCCESSFUL);
}
if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >=
((PVOID)Acl + Acl->AclSize))
{
return(STATUS_UNSUCCESSFUL);
}
Ace->Header.AceFlags = 0;
Ace->Header.AceType = Type;
Ace->Header.AceSize = RtlLengthSid(Sid) + sizeof(ACE);
Ace->Header.AccessMask = AccessMask;
RtlCopySid(RtlLengthSid(Sid), (PSID)Ace + 1, Sid);
Acl->AceCount++;
Acl->AclRevision = Revision;
return(STATUS_SUCCESS);
}
NTSTATUS
STDCALL
RtlAddAccessAllowedAce (
PACL Acl,
ULONG Revision,
ACCESS_MASK AccessMask,
PSID Sid
)
NTSTATUS STDCALL
RtlAddAccessAllowedAce(PACL Acl,
ULONG Revision,
ACCESS_MASK AccessMask,
PSID Sid)
{
return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0));
return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0));
}
NTSTATUS
STDCALL
RtlAddAccessDeniedAce (
PACL Acl,
ULONG Revision,
ACCESS_MASK AccessMask,
PSID Sid
)
NTSTATUS STDCALL
RtlAddAccessDeniedAce(PACL Acl,
ULONG Revision,
ACCESS_MASK AccessMask,
PSID Sid)
{
return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 1));
return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 1));
}
NTSTATUS
STDCALL
RtlAddAce (
PACL Acl,
ULONG AclRevision,
ULONG StartingIndex,
PACE AceList,
ULONG AceListLength
)
NTSTATUS STDCALL
RtlAddAce(PACL Acl,
ULONG AclRevision,
ULONG StartingIndex,
PACE AceList,
ULONG AceListLength)
{
PACE Ace;
ULONG i;
@ -204,41 +226,42 @@ RtlAddAce (
return(TRUE);
}
NTSTATUS
STDCALL
RtlAddAuditAccessAce (
PACL Acl,
ULONG Revision,
ACCESS_MASK AccessMask,
PSID Sid,
BOOLEAN Success,
BOOLEAN Failure
)
NTSTATUS STDCALL
RtlAddAuditAccessAce(PACL Acl,
ULONG Revision,
ACCESS_MASK AccessMask,
PSID Sid,
BOOLEAN Success,
BOOLEAN Failure)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
STDCALL
RtlDeleteAce(PACL Acl, ULONG AceIndex)
NTSTATUS STDCALL
RtlDeleteAce(PACL Acl,
ULONG AceIndex)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
STDCALL
RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSTATUS STDCALL
RtlCreateAcl(PACL Acl,
ULONG AclSize,
ULONG AclRevision)
{
if (AclSize < 8)
{
return(STATUS_UNSUCCESSFUL);
return(STATUS_BUFFER_TOO_SMALL);
}
if (AclRevision != 2 ||
if (AclRevision != 2 &&
AclRevision != 3)
{
return(STATUS_UNSUCCESSFUL);
return(STATUS_UNKNOWN_REVISION);
}
if (AclSize > 0xffff)
{
@ -253,38 +276,34 @@ RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
return(STATUS_SUCCESS);
}
NTSTATUS
STDCALL
RtlQueryInformationAcl (
PACL Acl,
PVOID Information,
ULONG InformationLength,
ACL_INFORMATION_CLASS InformationClass
)
NTSTATUS STDCALL
RtlQueryInformationAcl(PACL Acl,
PVOID Information,
ULONG InformationLength,
ACL_INFORMATION_CLASS InformationClass)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
STDCALL
RtlSetInformationAcl (
PACL Acl,
PVOID Information,
ULONG InformationLength,
ACL_INFORMATION_CLASS InformationClass
)
NTSTATUS STDCALL
RtlSetInformationAcl(PACL Acl,
PVOID Information,
ULONG InformationLength,
ACL_INFORMATION_CLASS InformationClass)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
BOOLEAN
STDCALL
RtlValidAcl (PACL Acl)
BOOLEAN STDCALL
RtlValidAcl(PACL Acl)
{
UNIMPLEMENTED;
return FALSE;
UNIMPLEMENTED;
return FALSE;
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: acl.c,v 1.5 2002/02/20 20:15:38 ekohl Exp $
/* $Id: acl.c,v 1.6 2002/06/07 22:59:42 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -130,14 +130,14 @@ SepInitDACLs(VOID)
}
BOOLEAN
STDCALL
RtlFirstFreeAce(PACL Acl, PACE* Ace)
BOOLEAN STDCALL
RtlFirstFreeAce(PACL Acl,
PACE* Ace)
{
PACE Current;
PVOID AclEnd;
ULONG i;
Current = (PACE)(Acl + 1);
*Ace = NULL;
i = 0;
@ -171,11 +171,13 @@ RtlFirstFreeAce(PACL Acl, PACE* Ace)
return(TRUE);
}
NTSTATUS RtlpAddKnownAce(PACL Acl,
ULONG Revision,
ACCESS_MASK AccessMask,
PSID Sid,
ULONG Type)
NTSTATUS
RtlpAddKnownAce(PACL Acl,
ULONG Revision,
ACCESS_MASK AccessMask,
PSID Sid,
ULONG Type)
{
PACE Ace;
@ -215,6 +217,7 @@ NTSTATUS RtlpAddKnownAce(PACL Acl,
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
RtlAddAccessAllowedAce(PACL Acl,
ULONG Revision,
@ -224,6 +227,7 @@ RtlAddAccessAllowedAce(PACL Acl,
return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0));
}
NTSTATUS STDCALL
RtlAddAce(PACL Acl,
ULONG AclRevision,
@ -298,12 +302,12 @@ RtlCreateAcl(PACL Acl,
{
if (AclSize < 8)
{
return(STATUS_UNSUCCESSFUL);
return(STATUS_BUFFER_TOO_SMALL);
}
if (AclRevision != 2 ||
if (AclRevision != 2 &&
AclRevision != 3)
{
return(STATUS_UNSUCCESSFUL);
return(STATUS_UNKNOWN_REVISION);
}
if (AclSize > 0xffff)
{

View file

@ -1,4 +1,4 @@
/* $Id: token.c,v 1.15 2002/06/04 13:44:06 ekohl Exp $
/* $Id: token.c,v 1.16 2002/06/07 22:59:42 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -15,6 +15,7 @@
#include <ddk/ntddk.h>
#include <internal/ps.h>
#include <internal/se.h>
#include <internal/safe.h>
#include <internal/debug.h>
@ -215,6 +216,22 @@ SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext,
}
VOID STDCALL
SepDeleteToken(PVOID ObjectBody)
{
PACCESS_TOKEN AccessToken = (PACCESS_TOKEN)ObjectBody;
if (AccessToken->UserAndGroups)
ExFreePool(AccessToken->UserAndGroups);
if (AccessToken->Privileges)
ExFreePool(AccessToken->Privileges);
if (AccessToken->DefaultDacl)
ExFreePool(AccessToken->DefaultDacl);
}
VOID
SepInitializeTokenImplementation(VOID)
{
@ -231,7 +248,7 @@ SepInitializeTokenImplementation(VOID)
SepTokenObjectType->Dump = NULL;
SepTokenObjectType->Open = NULL;
SepTokenObjectType->Close = NULL;
SepTokenObjectType->Delete = NULL;
SepTokenObjectType->Delete = SepDeleteToken;
SepTokenObjectType->Parse = NULL;
SepTokenObjectType->Security = NULL;
SepTokenObjectType->QueryName = NULL;
@ -245,37 +262,52 @@ SepInitializeTokenImplementation(VOID)
NTSTATUS
RtlCopySidAndAttributesArray(ULONG Count, // ebp + 8
PSID_AND_ATTRIBUTES Src, // ebp + C
ULONG MaxLength, // ebp + 10
PSID_AND_ATTRIBUTES Dest, // ebp + 14
PVOID e, // ebp + 18
PVOID* f, // ebp + 1C
PULONG g) // ebp + 20
RtlCopySidAndAttributesArray(ULONG Count, // ebp + 8
PSID_AND_ATTRIBUTES Src, // ebp + C
ULONG SidAreaSize, // ebp + 10
PSID_AND_ATTRIBUTES Dest, // ebp + 14
PVOID SidArea, // ebp + 18
PVOID* RemainingSidArea, // ebp + 1C
PULONG RemainingSidAreaSize) // ebp + 20
{
ULONG Length; // ebp - 4
ULONG i;
Length = MaxLength;
Length = SidAreaSize;
for (i=0; i<Count; i++)
{
if (RtlLengthSid(Src[i].Sid) > Length)
{
return(STATUS_UNSUCCESSFUL);
return(STATUS_BUFFER_TOO_SMALL);
}
Length = Length - RtlLengthSid(Src[i].Sid);
Dest[i].Sid = e;
Dest[i].Sid = SidArea;
Dest[i].Attributes = Src[i].Attributes;
RtlCopySid(RtlLengthSid(Src[i].Sid), e, Src[i].Sid);
e = e + RtlLengthSid(Src[i].Sid) + sizeof(ULONG);
RtlCopySid(RtlLengthSid(Src[i].Sid), SidArea, Src[i].Sid);
SidArea = SidArea + RtlLengthSid(Src[i].Sid);
}
*f = e;
*g = Length;
*RemainingSidArea = SidArea;
*RemainingSidAreaSize = Length;
return(STATUS_SUCCESS);
}
static ULONG
RtlLengthSidAndAttributes(ULONG Count,
PSID_AND_ATTRIBUTES Src)
{
ULONG i;
ULONG uLength;
uLength = Count * sizeof(SID_AND_ATTRIBUTES);
for (i = 0; i < Count; i++)
uLength += RtlLengthSid(Src[i].Sid);
return(uLength);
}
NTSTATUS STDCALL
NtQueryInformationToken(IN HANDLE TokenHandle,
IN TOKEN_INFORMATION_CLASS TokenInformationClass,
@ -283,119 +315,238 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
IN ULONG TokenInformationLength,
OUT PULONG ReturnLength)
{
NTSTATUS Status;
PACCESS_TOKEN Token;
PVOID UnusedInfo;
PVOID EndMem;
PTOKEN_GROUPS PtrTokenGroups;
PTOKEN_DEFAULT_DACL PtrDefaultDacl;
PTOKEN_STATISTICS PtrTokenStatistics;
Status = ObReferenceObjectByHandle(TokenHandle,
0,
SepTokenObjectType,
UserMode,
(PVOID*)&Token,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
switch (TokenInformationClass)
{
NTSTATUS Status;
PACCESS_TOKEN Token;
PVOID UnusedInfo;
PVOID EndMem;
PTOKEN_GROUPS PtrTokenGroups;
PTOKEN_DEFAULT_DACL PtrDefaultDacl;
PTOKEN_STATISTICS PtrTokenStatistics;
ULONG uLength;
Status = ObReferenceObjectByHandle(TokenHandle,
(TokenInformationClass == TokenSource) ? TOKEN_QUERY_SOURCE : TOKEN_QUERY,
SepTokenObjectType,
UserMode,
(PVOID*)&Token,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
switch (TokenInformationClass)
{
case TokenUser:
Status = RtlCopySidAndAttributesArray(1,
Token->UserAndGroups,
TokenInformationLength,
TokenInformation,
TokenInformation + 8,
&UnusedInfo,
ReturnLength);
if (!NT_SUCCESS(Status))
uLength = RtlLengthSidAndAttributes(1, Token->UserAndGroups);
if (TokenInformationLength < uLength)
{
ObDereferenceObject(Token);
return(Status);
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
if (NT_SUCCESS(Status))
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Status = RtlCopySidAndAttributesArray(1,
Token->UserAndGroups,
TokenInformationLength,
TokenInformation,
TokenInformation + 8,
&UnusedInfo,
&uLength);
if (NT_SUCCESS(Status))
{
uLength = TokenInformationLength - uLength;
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
}
}
break;
case TokenGroups:
EndMem = TokenInformation +
Token->UserAndGroupCount * sizeof(SID_AND_ATTRIBUTES);
PtrTokenGroups = (PTOKEN_GROUPS)TokenInformation;
PtrTokenGroups->GroupCount = Token->UserAndGroupCount - 1;
Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1,
&Token->UserAndGroups[1],
TokenInformationLength,
PtrTokenGroups->Groups,
EndMem,
&UnusedInfo,
ReturnLength);
if (!NT_SUCCESS(Status))
uLength = RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]) + sizeof(DWORD);
if (TokenInformationLength < uLength)
{
ObDereferenceObject(Token);
return(Status);
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
if (NT_SUCCESS(Status))
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
EndMem = TokenInformation + Token->UserAndGroupCount * sizeof(SID_AND_ATTRIBUTES);
PtrTokenGroups = (PTOKEN_GROUPS)TokenInformation;
PtrTokenGroups->GroupCount = Token->UserAndGroupCount - 1;
Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1,
&Token->UserAndGroups[1],
TokenInformationLength,
PtrTokenGroups->Groups,
EndMem,
&UnusedInfo,
&uLength);
if (NT_SUCCESS(Status))
{
uLength = TokenInformationLength - uLength;
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
}
}
break;
case TokenPrivileges:
uLength = sizeof(DWORD) + Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
if (TokenInformationLength < uLength)
{
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
if (NT_SUCCESS(Status))
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
ULONG i;
TOKEN_PRIVILEGES* pPriv = (TOKEN_PRIVILEGES*)TokenInformation;
pPriv->PrivilegeCount = Token->PrivilegeCount;
for (i = 0; i < Token->PrivilegeCount; i++)
{
RtlCopyLuid(&pPriv->Privileges[i].Luid, &Token->Privileges[i].Luid);
pPriv->Privileges[i].Attributes = Token->Privileges[i].Attributes;
}
Status = STATUS_SUCCESS;
}
break;
case TokenOwner:
((PTOKEN_OWNER)TokenInformation)->Owner =
(PSID)(((PTOKEN_OWNER)TokenInformation) + 1);
RtlCopySid(TokenInformationLength - sizeof(TOKEN_OWNER),
((PTOKEN_OWNER)TokenInformation)->Owner,
Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
uLength = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid) + sizeof(TOKEN_OWNER);
if (TokenInformationLength < uLength)
{
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
if (NT_SUCCESS(Status))
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
((PTOKEN_OWNER)TokenInformation)->Owner =
(PSID)(((PTOKEN_OWNER)TokenInformation) + 1);
RtlCopySid(TokenInformationLength - sizeof(TOKEN_OWNER),
((PTOKEN_OWNER)TokenInformation)->Owner,
Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
Status = STATUS_SUCCESS;
}
break;
case TokenPrimaryGroup:
((PTOKEN_PRIMARY_GROUP)TokenInformation)->PrimaryGroup =
(PSID)(((PTOKEN_PRIMARY_GROUP)TokenInformation) + 1);
RtlCopySid(TokenInformationLength - sizeof(TOKEN_OWNER),
((PTOKEN_PRIMARY_GROUP)TokenInformation)->PrimaryGroup,
Token->PrimaryGroup);
uLength = RtlLengthSid(Token->PrimaryGroup) + sizeof(TOKEN_PRIMARY_GROUP);
if (TokenInformationLength < uLength)
{
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
if (NT_SUCCESS(Status))
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
((PTOKEN_PRIMARY_GROUP)TokenInformation)->PrimaryGroup =
(PSID)(((PTOKEN_PRIMARY_GROUP)TokenInformation) + 1);
RtlCopySid(TokenInformationLength - sizeof(TOKEN_PRIMARY_GROUP),
((PTOKEN_PRIMARY_GROUP)TokenInformation)->PrimaryGroup,
Token->PrimaryGroup);
Status = STATUS_SUCCESS;
}
break;
case TokenDefaultDacl:
PtrDefaultDacl = (PTOKEN_DEFAULT_DACL)TokenInformation;
PtrDefaultDacl->DefaultDacl = (PACL)(PtrDefaultDacl + 1);
memmove(PtrDefaultDacl->DefaultDacl,
Token->DefaultDacl,
Token->DefaultDacl->AclSize);
PtrDefaultDacl = (PTOKEN_DEFAULT_DACL) TokenInformation;
uLength = (Token->DefaultDacl ? Token->DefaultDacl->AclSize : 0) + sizeof(TOKEN_DEFAULT_DACL);
if (TokenInformationLength < uLength)
{
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
if (NT_SUCCESS(Status))
Status = STATUS_BUFFER_TOO_SMALL;
}
else if (!Token->DefaultDacl)
{
PtrDefaultDacl->DefaultDacl = 0;
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
}
else
{
PtrDefaultDacl->DefaultDacl = (PACL) (PtrDefaultDacl + 1);
memmove(PtrDefaultDacl->DefaultDacl,
Token->DefaultDacl,
Token->DefaultDacl->AclSize);
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
}
break;
case TokenSource:
memcpy(TokenInformation, &Token->TokenSource, sizeof(TOKEN_SOURCE));
if (TokenInformationLength < sizeof(TOKEN_SOURCE))
{
uLength = sizeof(TOKEN_SOURCE);
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
if (NT_SUCCESS(Status))
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Status = MmCopyToCaller(TokenInformation, &Token->TokenSource, sizeof(TOKEN_SOURCE));
}
break;
case TokenType:
*((PTOKEN_TYPE)TokenInformation) = Token->TokenType;
if (TokenInformationLength < sizeof(TOKEN_TYPE))
{
uLength = sizeof(TOKEN_TYPE);
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
if (NT_SUCCESS(Status))
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Status = MmCopyToCaller(TokenInformation, &Token->TokenType, sizeof(TOKEN_TYPE));
}
break;
case TokenImpersonationLevel:
*((PSECURITY_IMPERSONATION_LEVEL)TokenInformation) =
Token->ImpersonationLevel;
if (TokenInformationLength < sizeof(SECURITY_IMPERSONATION_LEVEL))
{
uLength = sizeof(SECURITY_IMPERSONATION_LEVEL);
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
if (NT_SUCCESS(Status))
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Status = MmCopyToCaller(TokenInformation, &Token->ImpersonationLevel, sizeof(SECURITY_IMPERSONATION_LEVEL));
}
break;
case TokenStatistics:
PtrTokenStatistics = (PTOKEN_STATISTICS)TokenInformation;
PtrTokenStatistics->TokenId = Token->TokenId;
PtrTokenStatistics->AuthenticationId = Token->AuthenticationId;
PtrTokenStatistics->ExpirationTime = Token->ExpirationTime;
PtrTokenStatistics->TokenType = Token->TokenType;
PtrTokenStatistics->ImpersonationLevel = Token->ImpersonationLevel;
PtrTokenStatistics->DynamicCharged = Token->DynamicCharged;
PtrTokenStatistics->DynamicAvailable = Token->DynamicAvailable;
PtrTokenStatistics->GroupCount = Token->UserAndGroupCount - 1;
PtrTokenStatistics->PrivilegeCount = Token->PrivilegeCount;
PtrTokenStatistics->ModifiedId = Token->ModifiedId;
if (TokenInformationLength < sizeof(TOKEN_STATISTICS))
{
uLength = sizeof(TOKEN_STATISTICS);
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
if (NT_SUCCESS(Status))
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
PtrTokenStatistics = (PTOKEN_STATISTICS)TokenInformation;
PtrTokenStatistics->TokenId = Token->TokenId;
PtrTokenStatistics->AuthenticationId = Token->AuthenticationId;
PtrTokenStatistics->ExpirationTime = Token->ExpirationTime;
PtrTokenStatistics->TokenType = Token->TokenType;
PtrTokenStatistics->ImpersonationLevel = Token->ImpersonationLevel;
PtrTokenStatistics->DynamicCharged = Token->DynamicCharged;
PtrTokenStatistics->DynamicAvailable = Token->DynamicAvailable;
PtrTokenStatistics->GroupCount = Token->UserAndGroupCount - 1;
PtrTokenStatistics->PrivilegeCount = Token->PrivilegeCount;
PtrTokenStatistics->ModifiedId = Token->ModifiedId;
Status = STATUS_SUCCESS;
}
break;
}
ObDereferenceObject(Token);
return(STATUS_SUCCESS);
}
ObDereferenceObject(Token);
return(Status);
}
@ -593,10 +744,11 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
#endif
}
NTSTATUS STDCALL
NtCreateToken(OUT PHANDLE TokenHandle,
NtCreateToken(OUT PHANDLE UnsafeTokenHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN POBJECT_ATTRIBUTES UnsafeObjectAttributes,
IN TOKEN_TYPE TokenType,
IN PLUID AuthenticationId,
IN PLARGE_INTEGER ExpirationTime,
@ -608,10 +760,34 @@ NtCreateToken(OUT PHANDLE TokenHandle,
IN PTOKEN_DEFAULT_DACL TokenDefaultDacl,
IN PTOKEN_SOURCE TokenSource)
{
HANDLE TokenHandle;
PACCESS_TOKEN AccessToken;
NTSTATUS Status;
OBJECT_ATTRIBUTES SafeObjectAttributes;
POBJECT_ATTRIBUTES ObjectAttributes;
LUID TokenId;
LUID ModifiedId;
PVOID EndMem;
ULONG uLength;
ULONG i;
Status = ObCreateObject(TokenHandle,
Status = MmCopyFromCaller(&SafeObjectAttributes,
UnsafeObjectAttributes,
sizeof(OBJECT_ATTRIBUTES));
if (!NT_SUCCESS(Status))
return(Status);
ObjectAttributes = &SafeObjectAttributes;
Status = ZwAllocateLocallyUniqueId(&TokenId);
if (!NT_SUCCESS(Status))
return(Status);
Status = ZwAllocateLocallyUniqueId(&ModifiedId);
if (!NT_SUCCESS(Status))
return(Status);
Status = ObCreateObject(&TokenHandle,
DesiredAccess,
ObjectAttributes,
SepTokenObjectType,
@ -622,13 +798,125 @@ NtCreateToken(OUT PHANDLE TokenHandle,
return(Status);
}
#if 0
AccessToken->TokenType = TokenType;
RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId);
AccessToken->ExpirationTime = *ExpirationTime;
AccessToken->
#endif
// UNIMPLEMENTED;
RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier,
&TokenSource->SourceIdentifier);
memcpy(AccessToken->TokenSource.SourceName,
TokenSource->SourceName,
sizeof(TokenSource->SourceName));
RtlCopyLuid(&AccessToken->TokenId, &TokenId);
RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId);
AccessToken->ExpirationTime = *ExpirationTime;
RtlCopyLuid(&AccessToken->ModifiedId, &ModifiedId);
AccessToken->UserAndGroupCount = TokenGroups->GroupCount + 1;
AccessToken->PrivilegeCount = TokenPrivileges->PrivilegeCount;
AccessToken->UserAndGroups = 0;
AccessToken->Privileges = 0;
AccessToken->TokenType = TokenType;
/*
* Normally we would just point these members into the variable information
* area; however, our ObCreateObject() call can't allocate a variable information
* area, so we allocate them seperately and provide a destroy function.
*/
uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount;
uLength += RtlLengthSid(TokenUser->User.Sid);
for (i = 0; i < TokenGroups->GroupCount; i++)
uLength += RtlLengthSid(TokenGroups->Groups[i].Sid);
AccessToken->UserAndGroups =
(PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(NonPagedPool,
uLength,
TAG('T', 'O', 'K', 'u'));
EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
Status = RtlCopySidAndAttributesArray(1,
&TokenUser->User,
uLength,
AccessToken->UserAndGroups,
EndMem,
&EndMem,
&uLength);
if (NT_SUCCESS(Status))
{
Status = RtlCopySidAndAttributesArray(TokenGroups->GroupCount,
TokenGroups->Groups,
uLength,
&AccessToken->UserAndGroups[1],
EndMem,
&EndMem,
&uLength);
}
if (NT_SUCCESS(Status))
{
AccessToken->DefaultOwnerIndex = AccessToken->UserAndGroupCount;
AccessToken->PrimaryGroup = 0;
/* Validate and set the primary group and user pointers */
for (i = 0; i < AccessToken->UserAndGroupCount; i++)
{
if (RtlEqualSid(AccessToken->UserAndGroups[i].Sid, TokenOwner->Owner))
AccessToken->DefaultOwnerIndex = i;
if (RtlEqualSid(AccessToken->UserAndGroups[i].Sid, TokenPrimaryGroup->PrimaryGroup))
AccessToken->PrimaryGroup = AccessToken->UserAndGroups[i].Sid;
}
if (AccessToken->DefaultOwnerIndex == AccessToken->UserAndGroupCount)
Status = STATUS_INVALID_OWNER;
if (AccessToken->PrimaryGroup == 0)
Status = STATUS_INVALID_PRIMARY_GROUP;
}
if (NT_SUCCESS(Status))
{
uLength = TokenPrivileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
AccessToken->Privileges =
(PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(NonPagedPool,
uLength,
TAG('T', 'O', 'K', 'p'));
for (i = 0; i < TokenPrivileges->PrivilegeCount; i++)
{
Status = MmCopyFromCaller(&AccessToken->Privileges[i],
&TokenPrivileges->Privileges[i],
sizeof(LUID_AND_ATTRIBUTES));
if (!NT_SUCCESS(Status))
break;
}
}
if (NT_SUCCESS(Status))
{
AccessToken->DefaultDacl =
(PACL) ExAllocatePoolWithTag(NonPagedPool,
TokenDefaultDacl->DefaultDacl->AclSize,
TAG('T', 'O', 'K', 'd'));
memcpy(AccessToken->DefaultDacl,
TokenDefaultDacl->DefaultDacl,
TokenDefaultDacl->DefaultDacl->AclSize);
}
ObDereferenceObject(AccessToken);
if (NT_SUCCESS(Status))
{
Status = MmCopyToCaller(UnsafeTokenHandle,
&TokenHandle,
sizeof(HANDLE));
}
if (!NT_SUCCESS(Status))
{
ZwClose(TokenHandle);
return(Status);
}
return(STATUS_SUCCESS);
}