- 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 # pteb regtest sectest shm simple thread vmtest winhello
TEST_APPS = alive apc args atomtest bench consume count dump_shared_data \ TEST_APPS = alive apc args atomtest bench consume count dump_shared_data \
event file gditest hello isotest lpc mstest mutex nptest \ 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 # 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) \ all: tools dk implib $(COMPONENTS) $(HALS) $(BUS) $(DLLS) $(SUBSYS) \
$(LOADERS) $(KERNEL_DRIVERS) $(SYS_APPS) $(TEST_APPS) \ $(LOADERS) $(KERNEL_DRIVERS) $(SYS_APPS) $(TEST_APPS) \
$(WINE_MODULES) $(UTIL_APPS) $(WINE_MODULES)
implib: $(COMPONENTS:%=%_implib) $(HALS:%=%_implib) $(BUS:%=%_implib) \ implib: $(COMPONENTS:%=%_implib) $(HALS:%=%_implib) $(BUS:%=%_implib) \
$(DLLS:%=%_implib) $(LOADERS:%=%_implib) \ $(DLLS:%=%_implib) $(LOADERS:%=%_implib) \
$(KERNEL_DRIVERS:%=%_implib) $(SUBSYS:%=%_implib) \ $(KERNEL_DRIVERS:%=%_implib) $(SUBSYS:%=%_implib) \
$(SYS_APPS:%=%_implib) $(TEST_APPS:%=%_implib) \ $(SYS_APPS:%=%_implib) $(TEST_APPS:%=%_implib) \
$(WINE_MODULES:%=%_implib) $(UTIL_APPS:%=%_implib) $(WINE_MODULES:%=%_implib)
clean: dk_clean $(HALS:%=%_clean) \ clean: dk_clean $(HALS:%=%_clean) \
$(COMPONENTS:%=%_clean) $(BUS:%=%_clean) $(DLLS:%=%_clean) \ $(COMPONENTS:%=%_clean) $(BUS:%=%_clean) $(DLLS:%=%_clean) \
$(LOADERS:%=%_clean) $(KERNEL_DRIVERS:%=%_clean) $(SUBSYS:%=%_clean) \ $(LOADERS:%=%_clean) $(KERNEL_DRIVERS:%=%_clean) $(SUBSYS:%=%_clean) \
$(SYS_APPS:%=%_clean) $(TEST_APPS:%=%_clean) $(NET_APPS:%=%_clean) \ $(SYS_APPS:%=%_clean) $(TEST_APPS:%=%_clean) $(UTIL_APPS:%=%_clean) \
$(WINE_MODULES:%=%_clean) clean_after tools_clean $(NET_APPS:%=%_clean) $(WINE_MODULES:%=%_clean) clean_after tools_clean
clean_after: clean_after:
$(RM) $(PATH_TO_TOP)/include/roscfg.h $(RM) $(PATH_TO_TOP)/include/roscfg.h
@ -138,16 +142,17 @@ install: tools install_dirs install_before \
$(DLLS:%=%_install) $(LOADERS:%=%_install) \ $(DLLS:%=%_install) $(LOADERS:%=%_install) \
$(KERNEL_DRIVERS:%=%_install) $(SUBSYS:%=%_install) \ $(KERNEL_DRIVERS:%=%_install) $(SUBSYS:%=%_install) \
$(SYS_APPS:%=%_install) $(TEST_APPS:%=%_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 \ dist: $(TOOLS_PATH)/rcopy$(EXE_POSTFIX) dist_clean dist_dirs \
$(HALS:%=%_dist) $(COMPONENTS:%=%_dist) $(BUS:%=%_dist) $(DLLS:%=%_dist) \ $(HALS:%=%_dist) $(COMPONENTS:%=%_dist) $(BUS:%=%_dist) $(DLLS:%=%_dist) \
$(LOADERS:%=%_dist) $(KERNEL_DRIVERS:%=%_dist) $(SUBSYS:%=%_dist) \ $(LOADERS:%=%_dist) $(KERNEL_DRIVERS:%=%_dist) $(SUBSYS:%=%_dist) \
$(SYS_APPS:%=%_dist) $(TEST_APPS:%=%_dist) $(NET_APPS:%=%_dist) \ $(SYS_APPS:%=%_dist) $(TEST_APPS:%=%_dist) $(UTIL_APPS:%=%_dist) \
$(WINE_MODULES:%=%_dist) $(NET_APPS:%=%_dist) $(WINE_MODULES:%=%_dist)
.PHONY: all implib clean clean_before install dist .PHONY: all implib clean clean_before install dist
# #
# System Applications # 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) .PHONY: $(SYS_APPS) $(SYS_APPS:%=%_implib) $(SYS_APPS:%=%_clean) $(SYS_APPS:%=%_install) $(SYS_APPS:%=%_dist)
# #
# Applications # Test Applications
# #
$(TEST_APPS): %: $(TEST_APPS): %:
make -C apps/tests/$* 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) .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 # 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) .PHONY: $(WINE_OTHER) $(WINE_OTHER:%=%_implib) $(WINE_OTHER:%=%_clean) $(WINE_OTHER:%=%_install) $(WINE_OTHER:%=%_dist)
# #
# Wine Tools # 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 # Makefile for ReactOS Cabinet Manager
# #
PATH_TO_TOP = ../.. PATH_TO_TOP = ../../..
#FIXME: why doesn't this work? #FIXME: why doesn't this work?
#ZLIB_OBJECTS = $(PATH_TO_TOP)/lib/zlib/zlib.a #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 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 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 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 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 TARGET_NORC = yes

View file

@ -1,6 +1,6 @@
# #
PATH_TO_TOP = ../.. PATH_TO_TOP = ../../..
TARGET_NORC = yes 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 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 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\secur32\secur32.dll %ROS_INSTALL%\system32
copy lib\user32\user32.dll %ROS_INSTALL%\system32 copy lib\user32\user32.dll %ROS_INSTALL%\system32
copy lib\ws2_32\ws2_32.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\smss\smss.exe %ROS_INSTALL%\system32
copy subsys\csrss\csrss.exe %ROS_INSTALL%\system32 copy subsys\csrss\csrss.exe %ROS_INSTALL%\system32
copy subsys\win32k\win32k.sys %ROS_INSTALL%\system32\drivers 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\apc\apc.exe %ROS_INSTALL%\bin
copy apps\tests\shm\shmsrv.exe %ROS_INSTALL%\bin copy apps\tests\shm\shmsrv.exe %ROS_INSTALL%\bin
copy apps\tests\shm\shmclt.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\npserver.exe %ROS_INSTALL%\bin
copy apps\tests\nptest\npclient.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\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\mutex\mutex.exe %ROS_INSTALL%\bin
copy apps\tests\winhello\winhello.exe %ROS_INSTALL%\bin copy apps\tests\winhello\winhello.exe %ROS_INSTALL%\bin
copy apps\tests\sectest\sectest.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\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\helb____.ttf %ROS_INSTALL%\media\fonts
copy media\fonts\timr____.ttf %ROS_INSTALL%\media\fonts copy media\fonts\timr____.ttf %ROS_INSTALL%\media\fonts
copy media\nls\*.nls %ROS_INSTALL%\system32 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -17,9 +17,9 @@
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
BOOLEAN BOOLEAN STDCALL
STDCALL RtlFirstFreeAce(PACL Acl,
RtlFirstFreeAce(PACL Acl, PACE* Ace) PACE* Ace)
{ {
PACE Current; PACE Current;
PVOID AclEnd; PVOID AclEnd;
@ -49,23 +49,51 @@ RtlFirstFreeAce(PACL Acl, PACE* Ace)
} }
Current = (PACE)((PVOID)Current + (ULONG)Current->Header.AceSize); Current = (PACE)((PVOID)Current + (ULONG)Current->Header.AceSize);
i++; i++;
} while (i < Acl->AceCount); }
while (i < Acl->AceCount);
if ((PVOID)Current >= AclEnd) if ((PVOID)Current >= AclEnd)
{ {
return(FALSE); return(FALSE);
} }
*Ace = Current; *Ace = Current;
return(TRUE); return(TRUE);
} }
NTSTATUS
STDCALL NTSTATUS STDCALL
RtlGetAce(PACL Acl, ULONG AceIndex, PACE *Ace) RtlGetAce(PACL Acl,
ULONG AceIndex,
PACE *Ace)
{ {
UNIMPLEMENTED; ULONG i;
return STATUS_UNSUCCESSFUL; 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 NTSTATUS
RtlpAddKnownAce(PACL Acl, RtlpAddKnownAce(PACL Acl,
ULONG Revision, ULONG Revision,
@ -111,39 +139,33 @@ RtlpAddKnownAce(PACL Acl,
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS
STDCALL NTSTATUS STDCALL
RtlAddAccessAllowedAce ( RtlAddAccessAllowedAce(PACL Acl,
PACL Acl,
ULONG Revision, ULONG Revision,
ACCESS_MASK AccessMask, ACCESS_MASK AccessMask,
PSID Sid PSID Sid)
)
{ {
return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0)); return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0));
} }
NTSTATUS
STDCALL NTSTATUS STDCALL
RtlAddAccessDeniedAce ( RtlAddAccessDeniedAce(PACL Acl,
PACL Acl,
ULONG Revision, ULONG Revision,
ACCESS_MASK AccessMask, ACCESS_MASK AccessMask,
PSID Sid PSID Sid)
)
{ {
return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 1)); return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 1));
} }
NTSTATUS
STDCALL NTSTATUS STDCALL
RtlAddAce ( RtlAddAce(PACL Acl,
PACL Acl,
ULONG AclRevision, ULONG AclRevision,
ULONG StartingIndex, ULONG StartingIndex,
PACE AceList, PACE AceList,
ULONG AceListLength ULONG AceListLength)
)
{ {
PACE Ace; PACE Ace;
ULONG i; ULONG i;
@ -204,41 +226,42 @@ RtlAddAce (
return(TRUE); return(TRUE);
} }
NTSTATUS
STDCALL NTSTATUS STDCALL
RtlAddAuditAccessAce ( RtlAddAuditAccessAce(PACL Acl,
PACL Acl,
ULONG Revision, ULONG Revision,
ACCESS_MASK AccessMask, ACCESS_MASK AccessMask,
PSID Sid, PSID Sid,
BOOLEAN Success, BOOLEAN Success,
BOOLEAN Failure BOOLEAN Failure)
)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
NTSTATUS
STDCALL NTSTATUS STDCALL
RtlDeleteAce(PACL Acl, ULONG AceIndex) RtlDeleteAce(PACL Acl,
ULONG AceIndex)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
NTSTATUS
STDCALL NTSTATUS STDCALL
RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision) RtlCreateAcl(PACL Acl,
ULONG AclSize,
ULONG AclRevision)
{ {
if (AclSize < 8) if (AclSize < 8)
{ {
return(STATUS_UNSUCCESSFUL); return(STATUS_BUFFER_TOO_SMALL);
} }
if (AclRevision != 2 || if (AclRevision != 2 &&
AclRevision != 3) AclRevision != 3)
{ {
return(STATUS_UNSUCCESSFUL); return(STATUS_UNKNOWN_REVISION);
} }
if (AclSize > 0xffff) if (AclSize > 0xffff)
{ {
@ -253,34 +276,30 @@ RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS
STDCALL NTSTATUS STDCALL
RtlQueryInformationAcl ( RtlQueryInformationAcl(PACL Acl,
PACL Acl,
PVOID Information, PVOID Information,
ULONG InformationLength, ULONG InformationLength,
ACL_INFORMATION_CLASS InformationClass ACL_INFORMATION_CLASS InformationClass)
)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
NTSTATUS
STDCALL NTSTATUS STDCALL
RtlSetInformationAcl ( RtlSetInformationAcl(PACL Acl,
PACL Acl,
PVOID Information, PVOID Information,
ULONG InformationLength, ULONG InformationLength,
ACL_INFORMATION_CLASS InformationClass ACL_INFORMATION_CLASS InformationClass)
)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
BOOLEAN
STDCALL BOOLEAN STDCALL
RtlValidAcl(PACL Acl) RtlValidAcl(PACL Acl)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;

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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -130,9 +130,9 @@ SepInitDACLs(VOID)
} }
BOOLEAN BOOLEAN STDCALL
STDCALL RtlFirstFreeAce(PACL Acl,
RtlFirstFreeAce(PACL Acl, PACE* Ace) PACE* Ace)
{ {
PACE Current; PACE Current;
PVOID AclEnd; PVOID AclEnd;
@ -171,7 +171,9 @@ RtlFirstFreeAce(PACL Acl, PACE* Ace)
return(TRUE); return(TRUE);
} }
NTSTATUS RtlpAddKnownAce(PACL Acl,
NTSTATUS
RtlpAddKnownAce(PACL Acl,
ULONG Revision, ULONG Revision,
ACCESS_MASK AccessMask, ACCESS_MASK AccessMask,
PSID Sid, PSID Sid,
@ -215,6 +217,7 @@ NTSTATUS RtlpAddKnownAce(PACL Acl,
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS STDCALL NTSTATUS STDCALL
RtlAddAccessAllowedAce(PACL Acl, RtlAddAccessAllowedAce(PACL Acl,
ULONG Revision, ULONG Revision,
@ -224,6 +227,7 @@ RtlAddAccessAllowedAce(PACL Acl,
return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0)); return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0));
} }
NTSTATUS STDCALL NTSTATUS STDCALL
RtlAddAce(PACL Acl, RtlAddAce(PACL Acl,
ULONG AclRevision, ULONG AclRevision,
@ -298,12 +302,12 @@ RtlCreateAcl(PACL Acl,
{ {
if (AclSize < 8) if (AclSize < 8)
{ {
return(STATUS_UNSUCCESSFUL); return(STATUS_BUFFER_TOO_SMALL);
} }
if (AclRevision != 2 || if (AclRevision != 2 &&
AclRevision != 3) AclRevision != 3)
{ {
return(STATUS_UNSUCCESSFUL); return(STATUS_UNKNOWN_REVISION);
} }
if (AclSize > 0xffff) 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -15,6 +15,7 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <internal/ps.h> #include <internal/ps.h>
#include <internal/se.h> #include <internal/se.h>
#include <internal/safe.h>
#include <internal/debug.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 VOID
SepInitializeTokenImplementation(VOID) SepInitializeTokenImplementation(VOID)
{ {
@ -231,7 +248,7 @@ SepInitializeTokenImplementation(VOID)
SepTokenObjectType->Dump = NULL; SepTokenObjectType->Dump = NULL;
SepTokenObjectType->Open = NULL; SepTokenObjectType->Open = NULL;
SepTokenObjectType->Close = NULL; SepTokenObjectType->Close = NULL;
SepTokenObjectType->Delete = NULL; SepTokenObjectType->Delete = SepDeleteToken;
SepTokenObjectType->Parse = NULL; SepTokenObjectType->Parse = NULL;
SepTokenObjectType->Security = NULL; SepTokenObjectType->Security = NULL;
SepTokenObjectType->QueryName = NULL; SepTokenObjectType->QueryName = NULL;
@ -247,35 +264,50 @@ SepInitializeTokenImplementation(VOID)
NTSTATUS NTSTATUS
RtlCopySidAndAttributesArray(ULONG Count, // ebp + 8 RtlCopySidAndAttributesArray(ULONG Count, // ebp + 8
PSID_AND_ATTRIBUTES Src, // ebp + C PSID_AND_ATTRIBUTES Src, // ebp + C
ULONG MaxLength, // ebp + 10 ULONG SidAreaSize, // ebp + 10
PSID_AND_ATTRIBUTES Dest, // ebp + 14 PSID_AND_ATTRIBUTES Dest, // ebp + 14
PVOID e, // ebp + 18 PVOID SidArea, // ebp + 18
PVOID* f, // ebp + 1C PVOID* RemainingSidArea, // ebp + 1C
PULONG g) // ebp + 20 PULONG RemainingSidAreaSize) // ebp + 20
{ {
ULONG Length; // ebp - 4 ULONG Length; // ebp - 4
ULONG i; ULONG i;
Length = MaxLength; Length = SidAreaSize;
for (i=0; i<Count; i++) for (i=0; i<Count; i++)
{ {
if (RtlLengthSid(Src[i].Sid) > Length) if (RtlLengthSid(Src[i].Sid) > Length)
{ {
return(STATUS_UNSUCCESSFUL); return(STATUS_BUFFER_TOO_SMALL);
} }
Length = Length - RtlLengthSid(Src[i].Sid); Length = Length - RtlLengthSid(Src[i].Sid);
Dest[i].Sid = e; Dest[i].Sid = SidArea;
Dest[i].Attributes = Src[i].Attributes; Dest[i].Attributes = Src[i].Attributes;
RtlCopySid(RtlLengthSid(Src[i].Sid), e, Src[i].Sid); RtlCopySid(RtlLengthSid(Src[i].Sid), SidArea, Src[i].Sid);
e = e + RtlLengthSid(Src[i].Sid) + sizeof(ULONG); SidArea = SidArea + RtlLengthSid(Src[i].Sid);
} }
*f = e; *RemainingSidArea = SidArea;
*g = Length; *RemainingSidAreaSize = Length;
return(STATUS_SUCCESS); 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 NTSTATUS STDCALL
NtQueryInformationToken(IN HANDLE TokenHandle, NtQueryInformationToken(IN HANDLE TokenHandle,
IN TOKEN_INFORMATION_CLASS TokenInformationClass, IN TOKEN_INFORMATION_CLASS TokenInformationClass,
@ -290,9 +322,10 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
PTOKEN_GROUPS PtrTokenGroups; PTOKEN_GROUPS PtrTokenGroups;
PTOKEN_DEFAULT_DACL PtrDefaultDacl; PTOKEN_DEFAULT_DACL PtrDefaultDacl;
PTOKEN_STATISTICS PtrTokenStatistics; PTOKEN_STATISTICS PtrTokenStatistics;
ULONG uLength;
Status = ObReferenceObjectByHandle(TokenHandle, Status = ObReferenceObjectByHandle(TokenHandle,
0, (TokenInformationClass == TokenSource) ? TOKEN_QUERY_SOURCE : TOKEN_QUERY,
SepTokenObjectType, SepTokenObjectType,
UserMode, UserMode,
(PVOID*)&Token, (PVOID*)&Token,
@ -305,24 +338,41 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
switch (TokenInformationClass) switch (TokenInformationClass)
{ {
case TokenUser: case TokenUser:
uLength = RtlLengthSidAndAttributes(1, Token->UserAndGroups);
if (TokenInformationLength < uLength)
{
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
if (NT_SUCCESS(Status))
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
Status = RtlCopySidAndAttributesArray(1, Status = RtlCopySidAndAttributesArray(1,
Token->UserAndGroups, Token->UserAndGroups,
TokenInformationLength, TokenInformationLength,
TokenInformation, TokenInformation,
TokenInformation + 8, TokenInformation + 8,
&UnusedInfo, &UnusedInfo,
ReturnLength); &uLength);
if (!NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
ObDereferenceObject(Token); uLength = TokenInformationLength - uLength;
return(Status); Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
}
} }
break; break;
case TokenGroups: case TokenGroups:
EndMem = TokenInformation + uLength = RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]) + sizeof(DWORD);
Token->UserAndGroupCount * sizeof(SID_AND_ATTRIBUTES); if (TokenInformationLength < uLength)
{
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 = (PTOKEN_GROUPS)TokenInformation;
PtrTokenGroups->GroupCount = Token->UserAndGroupCount - 1; PtrTokenGroups->GroupCount = Token->UserAndGroupCount - 1;
Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1, Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1,
@ -331,55 +381,152 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
PtrTokenGroups->Groups, PtrTokenGroups->Groups,
EndMem, EndMem,
&UnusedInfo, &UnusedInfo,
ReturnLength); &uLength);
if (!NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
ObDereferenceObject(Token); uLength = TokenInformationLength - uLength;
return(Status); Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
}
} }
break; break;
case TokenPrivileges: 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; break;
case TokenOwner: case TokenOwner:
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 = ((PTOKEN_OWNER)TokenInformation)->Owner =
(PSID)(((PTOKEN_OWNER)TokenInformation) + 1); (PSID)(((PTOKEN_OWNER)TokenInformation) + 1);
RtlCopySid(TokenInformationLength - sizeof(TOKEN_OWNER), RtlCopySid(TokenInformationLength - sizeof(TOKEN_OWNER),
((PTOKEN_OWNER)TokenInformation)->Owner, ((PTOKEN_OWNER)TokenInformation)->Owner,
Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
Status = STATUS_SUCCESS;
}
break; break;
case TokenPrimaryGroup: case TokenPrimaryGroup:
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 = ((PTOKEN_PRIMARY_GROUP)TokenInformation)->PrimaryGroup =
(PSID)(((PTOKEN_PRIMARY_GROUP)TokenInformation) + 1); (PSID)(((PTOKEN_PRIMARY_GROUP)TokenInformation) + 1);
RtlCopySid(TokenInformationLength - sizeof(TOKEN_OWNER), RtlCopySid(TokenInformationLength - sizeof(TOKEN_PRIMARY_GROUP),
((PTOKEN_PRIMARY_GROUP)TokenInformation)->PrimaryGroup, ((PTOKEN_PRIMARY_GROUP)TokenInformation)->PrimaryGroup,
Token->PrimaryGroup); Token->PrimaryGroup);
Status = STATUS_SUCCESS;
}
break; break;
case TokenDefaultDacl: case TokenDefaultDacl:
PtrDefaultDacl = (PTOKEN_DEFAULT_DACL) TokenInformation; 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); PtrDefaultDacl->DefaultDacl = (PACL) (PtrDefaultDacl + 1);
memmove(PtrDefaultDacl->DefaultDacl, memmove(PtrDefaultDacl->DefaultDacl,
Token->DefaultDacl, Token->DefaultDacl,
Token->DefaultDacl->AclSize); Token->DefaultDacl->AclSize);
Status = MmCopyToCaller(ReturnLength, &uLength, sizeof(ULONG));
}
break; break;
case TokenSource: 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; break;
case TokenType: 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; break;
case TokenImpersonationLevel: case TokenImpersonationLevel:
*((PSECURITY_IMPERSONATION_LEVEL)TokenInformation) = if (TokenInformationLength < sizeof(SECURITY_IMPERSONATION_LEVEL))
Token->ImpersonationLevel; {
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; break;
case TokenStatistics: case TokenStatistics:
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 = (PTOKEN_STATISTICS)TokenInformation;
PtrTokenStatistics->TokenId = Token->TokenId; PtrTokenStatistics->TokenId = Token->TokenId;
PtrTokenStatistics->AuthenticationId = Token->AuthenticationId; PtrTokenStatistics->AuthenticationId = Token->AuthenticationId;
@ -391,11 +538,15 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
PtrTokenStatistics->GroupCount = Token->UserAndGroupCount - 1; PtrTokenStatistics->GroupCount = Token->UserAndGroupCount - 1;
PtrTokenStatistics->PrivilegeCount = Token->PrivilegeCount; PtrTokenStatistics->PrivilegeCount = Token->PrivilegeCount;
PtrTokenStatistics->ModifiedId = Token->ModifiedId; PtrTokenStatistics->ModifiedId = Token->ModifiedId;
Status = STATUS_SUCCESS;
}
break; break;
} }
ObDereferenceObject(Token); ObDereferenceObject(Token);
return(STATUS_SUCCESS);
return(Status);
} }
@ -593,10 +744,11 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
#endif #endif
} }
NTSTATUS STDCALL NTSTATUS STDCALL
NtCreateToken(OUT PHANDLE TokenHandle, NtCreateToken(OUT PHANDLE UnsafeTokenHandle,
IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_ATTRIBUTES UnsafeObjectAttributes,
IN TOKEN_TYPE TokenType, IN TOKEN_TYPE TokenType,
IN PLUID AuthenticationId, IN PLUID AuthenticationId,
IN PLARGE_INTEGER ExpirationTime, IN PLARGE_INTEGER ExpirationTime,
@ -608,10 +760,34 @@ NtCreateToken(OUT PHANDLE TokenHandle,
IN PTOKEN_DEFAULT_DACL TokenDefaultDacl, IN PTOKEN_DEFAULT_DACL TokenDefaultDacl,
IN PTOKEN_SOURCE TokenSource) IN PTOKEN_SOURCE TokenSource)
{ {
HANDLE TokenHandle;
PACCESS_TOKEN AccessToken; PACCESS_TOKEN AccessToken;
NTSTATUS Status; 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, DesiredAccess,
ObjectAttributes, ObjectAttributes,
SepTokenObjectType, SepTokenObjectType,
@ -622,13 +798,125 @@ NtCreateToken(OUT PHANDLE TokenHandle,
return(Status); return(Status);
} }
#if 0 RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier,
AccessToken->TokenType = TokenType; &TokenSource->SourceIdentifier);
memcpy(AccessToken->TokenSource.SourceName,
TokenSource->SourceName,
sizeof(TokenSource->SourceName));
RtlCopyLuid(&AccessToken->TokenId, &TokenId);
RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId); RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId);
AccessToken->ExpirationTime = *ExpirationTime; AccessToken->ExpirationTime = *ExpirationTime;
AccessToken-> RtlCopyLuid(&AccessToken->ModifiedId, &ModifiedId);
#endif
// UNIMPLEMENTED; 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); return(STATUS_SUCCESS);
} }