mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
- 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:
parent
33cc33c731
commit
bb14287865
16 changed files with 1186 additions and 314 deletions
|
@ -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
|
||||
#
|
||||
|
|
21
reactos/apps/tests/tokentest/makefile
Normal file
21
reactos/apps/tests/tokentest/makefile
Normal 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
|
510
reactos/apps/tests/tokentest/tokentest.c
Normal file
510
reactos/apps/tests/tokentest/tokentest.c
Normal 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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#
|
||||
|
||||
PATH_TO_TOP = ../..
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
TARGET_NORC = yes
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue