diff --git a/reactos/ntoskrnl/ex/uuid.c b/reactos/ntoskrnl/ex/uuid.c index e2f6f1011f8..c3957a5c4ab 100644 --- a/reactos/ntoskrnl/ex/uuid.c +++ b/reactos/ntoskrnl/ex/uuid.c @@ -40,8 +40,8 @@ static BOOLEAN UuidSequenceInitialized = FALSE; static BOOLEAN UuidSequenceChanged = FALSE; static UCHAR UuidSeed[SEED_BUFFER_SIZE]; static ULONG UuidCount; - - +static LARGE_INTEGER LuidIncrement; +static LARGE_INTEGER LuidValue; /* FUNCTIONS ****************************************************************/ @@ -214,6 +214,91 @@ ExpCreateUuids(PULARGE_INTEGER Time, return STATUS_SUCCESS; } +VOID +INIT_FUNCTION +NTAPI +ExpInitLuid(VOID) +{ + LUID DummyLuidValue = SYSTEM_LUID; + + LuidValue.u.HighPart = DummyLuidValue.HighPart; + LuidValue.u.LowPart = DummyLuidValue.LowPart; + LuidIncrement.QuadPart = 1; +} + + +NTSTATUS +NTAPI +ExpAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId) +{ + LARGE_INTEGER NewLuid, PrevLuid; + + /* atomically increment the luid */ + do + { + PrevLuid = LuidValue; + NewLuid = RtlLargeIntegerAdd(PrevLuid, + LuidIncrement); + } while(ExfInterlockedCompareExchange64(&LuidValue.QuadPart, + &NewLuid.QuadPart, + &PrevLuid.QuadPart) != PrevLuid.QuadPart); + + LocallyUniqueId->LowPart = NewLuid.u.LowPart; + LocallyUniqueId->HighPart = NewLuid.u.HighPart; + + return STATUS_SUCCESS; +} + + +/* + * @implemented + */ +NTSTATUS STDCALL +NtAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId) +{ + LUID NewLuid; + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + PreviousMode = ExGetPreviousMode(); + + if(PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite(LocallyUniqueId, + sizeof(LUID), + sizeof(ULONG)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + return Status; + } + } + + Status = ExpAllocateLocallyUniqueId(&NewLuid); + + _SEH_TRY + { + *LocallyUniqueId = NewLuid; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + return Status; +} + /* * @unimplemented */ diff --git a/reactos/ntoskrnl/include/internal/se.h b/reactos/ntoskrnl/include/internal/se.h index fa36a79577f..27af7647547 100644 --- a/reactos/ntoskrnl/include/internal/se.h +++ b/reactos/ntoskrnl/include/internal/se.h @@ -94,7 +94,7 @@ SeInitSRM(VOID); VOID NTAPI -SepInitLuid(VOID); +ExpInitLuid(VOID); VOID NTAPI @@ -315,6 +315,15 @@ SeSetWorldSecurityDescriptor( PULONG BufferLength ); +NTSTATUS +STDCALL +SeCopyClientToken( + IN PACCESS_TOKEN Token, + IN SECURITY_IMPERSONATION_LEVEL Level, + IN KPROCESSOR_MODE PreviousMode, + OUT PACCESS_TOKEN* NewToken +); + #define SepAcquireTokenLockExclusive(Token) \ do { \ KeEnterCriticalRegion(); \ diff --git a/reactos/ntoskrnl/ntoskrnl-generic.rbuild b/reactos/ntoskrnl/ntoskrnl-generic.rbuild index 39997cd9a3b..0cbf1d0ceac 100644 --- a/reactos/ntoskrnl/ntoskrnl-generic.rbuild +++ b/reactos/ntoskrnl/ntoskrnl-generic.rbuild @@ -425,7 +425,6 @@ acl.c audit.c lsa.c - luid.c priv.c sd.c semgr.c diff --git a/reactos/ntoskrnl/se/access.c b/reactos/ntoskrnl/se/access.c index 2d5f721c6f2..9f756da24cf 100644 --- a/reactos/ntoskrnl/se/access.c +++ b/reactos/ntoskrnl/se/access.c @@ -8,14 +8,114 @@ * Based on patch by Javier M. Mellid */ -/* INCLUDES *****************************************************************/ +/* INCLUDES *******************************************************************/ #include #define NDEBUG -#include +#include -/* FUNCTIONS ***************************************************************/ +/* GLOBALS ********************************************************************/ +ERESOURCE SepSubjectContextLock; + +/* FUNCTIONS ******************************************************************/ + +/* + * @implemented + */ +VOID +NTAPI +SeCaptureSubjectContextEx(IN PETHREAD Thread, + IN PEPROCESS Process, + OUT PSECURITY_SUBJECT_CONTEXT SubjectContext) +{ + BOOLEAN CopyOnOpen, EffectiveOnly; + PAGED_CODE(); + + /* Save the unique ID */ + SubjectContext->ProcessAuditId = Process->UniqueProcessId; + + /* Check if we have a thread */ + if (!Thread) + { + /* We don't, so no token */ + SubjectContext->ClientToken = NULL; + } + else + { + /* Get the impersonation token */ + SubjectContext->ClientToken = PsReferenceImpersonationToken(Thread, + &CopyOnOpen, + &EffectiveOnly, + &SubjectContext->ImpersonationLevel); + } + + /* Get the primary token */ + SubjectContext->PrimaryToken = PsReferencePrimaryToken(Process); +} + +/* + * @implemented + */ +VOID +NTAPI +SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext) +{ + /* Call the extended API */ + SeCaptureSubjectContextEx(PsGetCurrentThread(), + PsGetCurrentProcess(), + SubjectContext); +} + +/* + * @implemented + */ +VOID +NTAPI +SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext) +{ + PAGED_CODE(); + + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&SepSubjectContextLock, TRUE); +} + +/* + * @implemented + */ +VOID +NTAPI +SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext) +{ + PAGED_CODE(); + + ExReleaseResourceLite(&SepSubjectContextLock); + KeLeaveCriticalRegion(); +} + +/* + * @implemented + */ +VOID +NTAPI +SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext) +{ + PAGED_CODE(); + + if (SubjectContext->PrimaryToken != NULL) + { + ObFastDereferenceObject(&PsGetCurrentProcess()->Token, SubjectContext->PrimaryToken); + } + + if (SubjectContext->ClientToken != NULL) + { + ObDereferenceObject(SubjectContext->ClientToken); + } +} + +/* + * @implemented + */ NTSTATUS NTAPI SeCreateAccessStateEx(IN PETHREAD Thread, @@ -83,7 +183,7 @@ SeCreateAccessState(IN OUT PACCESS_STATE AccessState, { PAGED_CODE(); - /* Call the internal API */ + /* Call the extended API */ return SeCreateAccessStateEx(PsGetCurrentThread(), PsGetCurrentProcess(), AccessState, @@ -127,8 +227,8 @@ SeDeleteAccessState(IN PACCESS_STATE AccessState) */ VOID STDCALL -SeSetAccessStateGenericMapping(PACCESS_STATE AccessState, - PGENERIC_MAPPING GenericMapping) +SeSetAccessStateGenericMapping(IN PACCESS_STATE AccessState, + IN PGENERIC_MAPPING GenericMapping) { PAGED_CODE(); @@ -136,4 +236,137 @@ SeSetAccessStateGenericMapping(PACCESS_STATE AccessState, ((PAUX_DATA)AccessState->AuxData)->GenericMapping = *GenericMapping; } +/* + * @implemented + */ +NTSTATUS +NTAPI +SeCreateClientSecurity(IN PETHREAD Thread, + IN PSECURITY_QUALITY_OF_SERVICE Qos, + IN BOOLEAN RemoteClient, + OUT PSECURITY_CLIENT_CONTEXT ClientContext) +{ + TOKEN_TYPE TokenType; + BOOLEAN ThreadEffectiveOnly; + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + PACCESS_TOKEN Token; + NTSTATUS Status; + PACCESS_TOKEN NewToken; + PAGED_CODE(); + + Token = PsReferenceEffectiveToken(Thread, + &TokenType, + &ThreadEffectiveOnly, + &ImpersonationLevel); + if (TokenType != TokenImpersonation) + { + ClientContext->DirectAccessEffectiveOnly = Qos->EffectiveOnly; + } + else + { + if (Qos->ImpersonationLevel > ImpersonationLevel) + { + if (Token) ObDereferenceObject(Token); + return STATUS_BAD_IMPERSONATION_LEVEL; + } + + if ((ImpersonationLevel == SecurityAnonymous) || + (ImpersonationLevel == SecurityIdentification) || + ((RemoteClient) && (ImpersonationLevel != SecurityDelegation))) + { + if (Token) ObDereferenceObject(Token); + return STATUS_BAD_IMPERSONATION_LEVEL; + } + + ClientContext->DirectAccessEffectiveOnly = ((ThreadEffectiveOnly) || + (Qos->EffectiveOnly)) ? + TRUE : FALSE; + } + + if (Qos->ContextTrackingMode == SECURITY_STATIC_TRACKING) + { + ClientContext->DirectlyAccessClientToken = FALSE; + Status = SeCopyClientToken(Token, ImpersonationLevel, 0, &NewToken); + if (!NT_SUCCESS(Status)) return Status; + } + else + { + ClientContext->DirectlyAccessClientToken = TRUE; + if (RemoteClient != FALSE) + { +#if 0 + SeGetTokenControlInformation(Token, + &ClientContext->ClientTokenControl); +#endif + } + + NewToken = Token; + } + + ClientContext->SecurityQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); + ClientContext->SecurityQos.ImpersonationLevel = Qos->ImpersonationLevel; + ClientContext->SecurityQos.ContextTrackingMode = Qos->ContextTrackingMode; + ClientContext->SecurityQos.EffectiveOnly = Qos->EffectiveOnly; + ClientContext->ServerIsRemote = RemoteClient; + ClientContext->ClientToken = NewToken; + return STATUS_SUCCESS; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +SeCreateClientSecurityFromSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext, + IN PSECURITY_QUALITY_OF_SERVICE ClientSecurityQos, + IN BOOLEAN ServerIsRemote, + OUT PSECURITY_CLIENT_CONTEXT ClientContext) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +SeImpersonateClientEx(IN PSECURITY_CLIENT_CONTEXT ClientContext, + IN PETHREAD ServerThread OPTIONAL) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @implemented + */ +VOID +NTAPI +SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext, + IN PETHREAD ServerThread OPTIONAL) +{ + UCHAR b; + + PAGED_CODE(); + + if (ClientContext->DirectlyAccessClientToken == FALSE) + { + b = ClientContext->SecurityQos.EffectiveOnly; + } + else + { + b = ClientContext->DirectAccessEffectiveOnly; + } + if (ServerThread == NULL) + { + ServerThread = PsGetCurrentThread(); + } + PsImpersonateClient(ServerThread, + ClientContext->ClientToken, + 1, + b, + ClientContext->SecurityQos.ImpersonationLevel); +} + /* EOF */ diff --git a/reactos/ntoskrnl/se/acl.c b/reactos/ntoskrnl/se/acl.c index cbde82d7f64..196750870da 100644 --- a/reactos/ntoskrnl/se/acl.c +++ b/reactos/ntoskrnl/se/acl.c @@ -7,218 +7,216 @@ * PROGRAMMERS: David Welch */ -/* INCLUDES *****************************************************************/ +/* INCLUDES *******************************************************************/ #include -#include +#define NDEBUG +#include #if defined (ALLOC_PRAGMA) #pragma alloc_text(INIT, SepInitDACLs) #endif - -/* GLOBALS ******************************************************************/ +/* GLOBALS ********************************************************************/ PACL SePublicDefaultDacl = NULL; PACL SeSystemDefaultDacl = NULL; - PACL SePublicDefaultUnrestrictedDacl = NULL; PACL SePublicOpenDacl = NULL; PACL SePublicOpenUnrestrictedDacl = NULL; PACL SeUnrestrictedDacl = NULL; - -/* FUNCTIONS ****************************************************************/ +/* FUNCTIONS ******************************************************************/ BOOLEAN INIT_FUNCTION NTAPI SepInitDACLs(VOID) { - ULONG AclLength; - - /* create PublicDefaultDacl */ - AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)); - - SePublicDefaultDacl = ExAllocatePoolWithTag(PagedPool, - AclLength, - TAG_ACL); - if (SePublicDefaultDacl == NULL) - return FALSE; - - RtlCreateAcl(SePublicDefaultDacl, - AclLength, - ACL_REVISION); - - RtlAddAccessAllowedAce(SePublicDefaultDacl, - ACL_REVISION, - GENERIC_EXECUTE, - SeWorldSid); - - RtlAddAccessAllowedAce(SePublicDefaultDacl, - ACL_REVISION, - GENERIC_ALL, - SeLocalSystemSid); - - - /* create PublicDefaultUnrestrictedDacl */ - AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + - (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + - (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); - - SePublicDefaultUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool, - AclLength, - TAG_ACL); - if (SePublicDefaultUnrestrictedDacl == NULL) - return FALSE; - - RtlCreateAcl(SePublicDefaultUnrestrictedDacl, - AclLength, - ACL_REVISION); - - RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, - ACL_REVISION, - GENERIC_EXECUTE, - SeWorldSid); - - RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, - ACL_REVISION, - GENERIC_ALL, - SeLocalSystemSid); - - RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, - ACL_REVISION, - GENERIC_ALL, - SeAliasAdminsSid); - - RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, - ACL_REVISION, - GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL, - SeRestrictedCodeSid); - - /* create PublicOpenDacl */ - AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + - (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)); - - SePublicOpenDacl = ExAllocatePoolWithTag(PagedPool, - AclLength, - TAG_ACL); - if (SePublicOpenDacl == NULL) - return FALSE; - - RtlCreateAcl(SePublicOpenDacl, - AclLength, - ACL_REVISION); - - RtlAddAccessAllowedAce(SePublicOpenDacl, - ACL_REVISION, - GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, - SeWorldSid); - - RtlAddAccessAllowedAce(SePublicOpenDacl, - ACL_REVISION, - GENERIC_ALL, - SeLocalSystemSid); - - RtlAddAccessAllowedAce(SePublicOpenDacl, - ACL_REVISION, - GENERIC_ALL, - SeAliasAdminsSid); - - /* create PublicOpenUnrestrictedDacl */ - AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + - (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + - (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); - - SePublicOpenUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool, - AclLength, - TAG_ACL); - if (SePublicOpenUnrestrictedDacl == NULL) - return FALSE; - - RtlCreateAcl(SePublicOpenUnrestrictedDacl, - AclLength, - ACL_REVISION); - - RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, - ACL_REVISION, - GENERIC_ALL, - SeWorldSid); - - RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, - ACL_REVISION, - GENERIC_ALL, - SeLocalSystemSid); - - RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, - ACL_REVISION, - GENERIC_ALL, - SeAliasAdminsSid); - - RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, - ACL_REVISION, - GENERIC_READ | GENERIC_EXECUTE, - SeRestrictedCodeSid); - - /* create SystemDefaultDacl */ - AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + - (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)); - - SeSystemDefaultDacl = ExAllocatePoolWithTag(PagedPool, - AclLength, - TAG_ACL); - if (SeSystemDefaultDacl == NULL) - return FALSE; - - RtlCreateAcl(SeSystemDefaultDacl, - AclLength, - ACL_REVISION); - - RtlAddAccessAllowedAce(SeSystemDefaultDacl, - ACL_REVISION, - GENERIC_ALL, - SeLocalSystemSid); - - RtlAddAccessAllowedAce(SeSystemDefaultDacl, - ACL_REVISION, - GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL, - SeAliasAdminsSid); - - /* create UnrestrictedDacl */ - AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); - - SeUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool, - AclLength, - TAG_ACL); - if (SeUnrestrictedDacl == NULL) - return FALSE; - - RtlCreateAcl(SeUnrestrictedDacl, - AclLength, - ACL_REVISION); - - RtlAddAccessAllowedAce(SeUnrestrictedDacl, - ACL_REVISION, - GENERIC_ALL, - SeWorldSid); - - RtlAddAccessAllowedAce(SeUnrestrictedDacl, - ACL_REVISION, - GENERIC_READ | GENERIC_EXECUTE, - SeRestrictedCodeSid); - - return(TRUE); + ULONG AclLength; + + /* create PublicDefaultDacl */ + AclLength = sizeof(ACL) + + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)); + + SePublicDefaultDacl = ExAllocatePoolWithTag(PagedPool, + AclLength, + TAG_ACL); + if (SePublicDefaultDacl == NULL) + return FALSE; + + RtlCreateAcl(SePublicDefaultDacl, + AclLength, + ACL_REVISION); + + RtlAddAccessAllowedAce(SePublicDefaultDacl, + ACL_REVISION, + GENERIC_EXECUTE, + SeWorldSid); + + RtlAddAccessAllowedAce(SePublicDefaultDacl, + ACL_REVISION, + GENERIC_ALL, + SeLocalSystemSid); + + + /* create PublicDefaultUnrestrictedDacl */ + AclLength = sizeof(ACL) + + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + + (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); + + SePublicDefaultUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool, + AclLength, + TAG_ACL); + if (SePublicDefaultUnrestrictedDacl == NULL) + return FALSE; + + RtlCreateAcl(SePublicDefaultUnrestrictedDacl, + AclLength, + ACL_REVISION); + + RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, + ACL_REVISION, + GENERIC_EXECUTE, + SeWorldSid); + + RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, + ACL_REVISION, + GENERIC_ALL, + SeLocalSystemSid); + + RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, + ACL_REVISION, + GENERIC_ALL, + SeAliasAdminsSid); + + RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, + ACL_REVISION, + GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL, + SeRestrictedCodeSid); + + /* create PublicOpenDacl */ + AclLength = sizeof(ACL) + + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)); + + SePublicOpenDacl = ExAllocatePoolWithTag(PagedPool, + AclLength, + TAG_ACL); + if (SePublicOpenDacl == NULL) + return FALSE; + + RtlCreateAcl(SePublicOpenDacl, + AclLength, + ACL_REVISION); + + RtlAddAccessAllowedAce(SePublicOpenDacl, + ACL_REVISION, + GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, + SeWorldSid); + + RtlAddAccessAllowedAce(SePublicOpenDacl, + ACL_REVISION, + GENERIC_ALL, + SeLocalSystemSid); + + RtlAddAccessAllowedAce(SePublicOpenDacl, + ACL_REVISION, + GENERIC_ALL, + SeAliasAdminsSid); + + /* create PublicOpenUnrestrictedDacl */ + AclLength = sizeof(ACL) + + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + + (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); + + SePublicOpenUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool, + AclLength, + TAG_ACL); + if (SePublicOpenUnrestrictedDacl == NULL) + return FALSE; + + RtlCreateAcl(SePublicOpenUnrestrictedDacl, + AclLength, + ACL_REVISION); + + RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, + ACL_REVISION, + GENERIC_ALL, + SeWorldSid); + + RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, + ACL_REVISION, + GENERIC_ALL, + SeLocalSystemSid); + + RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, + ACL_REVISION, + GENERIC_ALL, + SeAliasAdminsSid); + + RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, + ACL_REVISION, + GENERIC_READ | GENERIC_EXECUTE, + SeRestrictedCodeSid); + + /* create SystemDefaultDacl */ + AclLength = sizeof(ACL) + + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)); + + SeSystemDefaultDacl = ExAllocatePoolWithTag(PagedPool, + AclLength, + TAG_ACL); + if (SeSystemDefaultDacl == NULL) + return FALSE; + + RtlCreateAcl(SeSystemDefaultDacl, + AclLength, + ACL_REVISION); + + RtlAddAccessAllowedAce(SeSystemDefaultDacl, + ACL_REVISION, + GENERIC_ALL, + SeLocalSystemSid); + + RtlAddAccessAllowedAce(SeSystemDefaultDacl, + ACL_REVISION, + GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL, + SeAliasAdminsSid); + + /* create UnrestrictedDacl */ + AclLength = sizeof(ACL) + + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); + + SeUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool, + AclLength, + TAG_ACL); + if (SeUnrestrictedDacl == NULL) + return FALSE; + + RtlCreateAcl(SeUnrestrictedDacl, + AclLength, + ACL_REVISION); + + RtlAddAccessAllowedAce(SeUnrestrictedDacl, + ACL_REVISION, + GENERIC_ALL, + SeWorldSid); + + RtlAddAccessAllowedAce(SeUnrestrictedDacl, + ACL_REVISION, + GENERIC_READ | GENERIC_EXECUTE, + SeRestrictedCodeSid); + + return(TRUE); } NTSTATUS STDCALL @@ -226,44 +224,44 @@ SepCreateImpersonationTokenDacl(PTOKEN Token, PTOKEN PrimaryToken, PACL *Dacl) { - ULONG AclLength; - PVOID TokenDacl; - - PAGED_CODE(); - - AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + - (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + - (sizeof(ACE) + RtlLengthSid(Token->UserAndGroups->Sid)) + - (sizeof(ACE) + RtlLengthSid(PrimaryToken->UserAndGroups->Sid)); - - TokenDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); - if (TokenDacl == NULL) + ULONG AclLength; + PVOID TokenDacl; + + PAGED_CODE(); + + AclLength = sizeof(ACL) + + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + + (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)) + + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(Token->UserAndGroups->Sid)) + + (sizeof(ACE) + RtlLengthSid(PrimaryToken->UserAndGroups->Sid)); + + TokenDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); + if (TokenDacl == NULL) { - return STATUS_INSUFFICIENT_RESOURCES; + return STATUS_INSUFFICIENT_RESOURCES; } - - RtlCreateAcl(TokenDacl, AclLength, ACL_REVISION); - RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL, - Token->UserAndGroups->Sid); - RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL, - PrimaryToken->UserAndGroups->Sid); - RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL, - SeAliasAdminsSid); - RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL, - SeLocalSystemSid); - - /* FIXME */ + + RtlCreateAcl(TokenDacl, AclLength, ACL_REVISION); + RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL, + Token->UserAndGroups->Sid); + RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL, + PrimaryToken->UserAndGroups->Sid); + RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL, + SeAliasAdminsSid); + RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL, + SeLocalSystemSid); + + /* FIXME */ #if 0 - if (Token->RestrictedSids != NULL || PrimaryToken->RestrictedSids != NULL) + if (Token->RestrictedSids != NULL || PrimaryToken->RestrictedSids != NULL) { - RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL, - SeRestrictedCodeSid); + RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL, + SeRestrictedCodeSid); } #endif - - return STATUS_SUCCESS; + + return STATUS_SUCCESS; } NTSTATUS @@ -274,83 +272,83 @@ SepCaptureAcl(IN PACL InputAcl, IN BOOLEAN CaptureIfKernel, OUT PACL *CapturedAcl) { - PACL NewAcl; - ULONG AclSize = 0; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - if(AccessMode != KernelMode) - { - _SEH_TRY + PACL NewAcl; + ULONG AclSize = 0; + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + if(AccessMode != KernelMode) { - ProbeForRead(InputAcl, - sizeof(ACL), - sizeof(ULONG)); - AclSize = InputAcl->AclSize; - ProbeForRead(InputAcl, - AclSize, - sizeof(ULONG)); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(NT_SUCCESS(Status)) - { - NewAcl = ExAllocatePool(PoolType, - AclSize); - if(NewAcl != NULL) - { _SEH_TRY { - RtlCopyMemory(NewAcl, - InputAcl, - AclSize); - - *CapturedAcl = NewAcl; + ProbeForRead(InputAcl, + sizeof(ACL), + sizeof(ULONG)); + AclSize = InputAcl->AclSize; + ProbeForRead(InputAcl, + AclSize, + sizeof(ULONG)); } _SEH_HANDLE { - ExFreePool(NewAcl); - Status = _SEH_GetExceptionCode(); + Status = _SEH_GetExceptionCode(); } _SEH_END; - } - else - { - Status = STATUS_INSUFFICIENT_RESOURCES; - } + + if(NT_SUCCESS(Status)) + { + NewAcl = ExAllocatePool(PoolType, + AclSize); + if(NewAcl != NULL) + { + _SEH_TRY + { + RtlCopyMemory(NewAcl, + InputAcl, + AclSize); + + *CapturedAcl = NewAcl; + } + _SEH_HANDLE + { + ExFreePool(NewAcl); + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + } } - } - else if(!CaptureIfKernel) - { - *CapturedAcl = InputAcl; - } - else - { - AclSize = InputAcl->AclSize; - - NewAcl = ExAllocatePool(PoolType, - AclSize); - - if(NewAcl != NULL) + else if(!CaptureIfKernel) { - RtlCopyMemory(NewAcl, - InputAcl, - AclSize); - - *CapturedAcl = NewAcl; + *CapturedAcl = InputAcl; } else { - Status = STATUS_INSUFFICIENT_RESOURCES; + AclSize = InputAcl->AclSize; + + NewAcl = ExAllocatePool(PoolType, + AclSize); + + if(NewAcl != NULL) + { + RtlCopyMemory(NewAcl, + InputAcl, + AclSize); + + *CapturedAcl = NewAcl; + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } } - } - - return Status; + + return Status; } VOID @@ -359,14 +357,14 @@ SepReleaseAcl(IN PACL CapturedAcl, IN KPROCESSOR_MODE AccessMode, IN BOOLEAN CaptureIfKernel) { - PAGED_CODE(); - - if(CapturedAcl != NULL && - (AccessMode != KernelMode || - (AccessMode == KernelMode && CaptureIfKernel))) - { - ExFreePool(CapturedAcl); - } + PAGED_CODE(); + + if(CapturedAcl != NULL && + (AccessMode != KernelMode || + (AccessMode == KernelMode && CaptureIfKernel))) + { + ExFreePool(CapturedAcl); + } } /* EOF */ diff --git a/reactos/ntoskrnl/se/audit.c b/reactos/ntoskrnl/se/audit.c index 9b6edb54593..de535b3f161 100644 --- a/reactos/ntoskrnl/se/audit.c +++ b/reactos/ntoskrnl/se/audit.c @@ -7,12 +7,13 @@ * PROGRAMMERS: Eric Kohl */ -/* INCLUDES *****************************************************************/ +/* INCLUDES *******************************************************************/ #include -#include +#define NDEBUG +#include -/* INTERNAL *****************************************************************/ +/* PRIVATE FUNCTIONS***********************************************************/ BOOLEAN NTAPI @@ -179,7 +180,165 @@ SeLocateProcessImageName(IN PEPROCESS Process, return Status; } -/* FUNCTIONS ****************************************************************/ +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * @unimplemented + */ +VOID +STDCALL +SeAuditHardLinkCreation(IN PUNICODE_STRING FileName, + IN PUNICODE_STRING LinkName, + IN BOOLEAN bSuccess) +{ + UNIMPLEMENTED; +} + +/* + * @unimplemented + */ +BOOLEAN +STDCALL +SeAuditingFileEvents(IN BOOLEAN AccessGranted, + IN PSECURITY_DESCRIPTOR SecurityDescriptor) +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +BOOLEAN +STDCALL +SeAuditingFileEventsWithContext(IN BOOLEAN AccessGranted, + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext OPTIONAL) +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +BOOLEAN +STDCALL +SeAuditingHardLinkEvents(IN BOOLEAN AccessGranted, + IN PSECURITY_DESCRIPTOR SecurityDescriptor) +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +BOOLEAN +STDCALL +SeAuditingHardLinkEventsWithContext(IN BOOLEAN AccessGranted, + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext OPTIONAL) +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +BOOLEAN +STDCALL +SeAuditingFileOrGlobalEvents(IN BOOLEAN AccessGranted, + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext) +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +VOID +STDCALL +SeCloseObjectAuditAlarm( + IN PVOID Object, + IN HANDLE Handle, + IN BOOLEAN PerformAction + ) +{ + UNIMPLEMENTED; +} + +/* + * @unimplemented + */ +VOID STDCALL +SeDeleteObjectAuditAlarm(IN PVOID Object, + IN HANDLE Handle) +{ + UNIMPLEMENTED; +} + +/* + * @unimplemented + */ +VOID +NTAPI +SeOpenObjectAuditAlarm(IN PUNICODE_STRING ObjectTypeName, + IN PVOID Object OPTIONAL, + IN PUNICODE_STRING AbsoluteObjectName OPTIONAL, + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN PACCESS_STATE AccessState, + IN BOOLEAN ObjectCreated, + IN BOOLEAN AccessGranted, + IN KPROCESSOR_MODE AccessMode, + OUT PBOOLEAN GenerateOnClose) +{ + PAGED_CODE(); + + /* Audits aren't done on kernel-mode access */ + if (AccessMode == KernelMode) return; + + /* Otherwise, unimplemented! */ + //UNIMPLEMENTED; + return; +} + +/* + * @unimplemented + */ +VOID STDCALL +SeOpenObjectForDeleteAuditAlarm(IN PUNICODE_STRING ObjectTypeName, + IN PVOID Object OPTIONAL, + IN PUNICODE_STRING AbsoluteObjectName OPTIONAL, + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN PACCESS_STATE AccessState, + IN BOOLEAN ObjectCreated, + IN BOOLEAN AccessGranted, + IN KPROCESSOR_MODE AccessMode, + OUT PBOOLEAN GenerateOnClose) +{ + UNIMPLEMENTED; +} + +/* + * @unimplemented + */ +VOID +STDCALL +SePrivilegeObjectAuditAlarm(IN HANDLE Handle, + IN PSECURITY_SUBJECT_CONTEXT SubjectContext, + IN ACCESS_MASK DesiredAccess, + IN PPRIVILEGE_SET Privileges, + IN BOOLEAN AccessGranted, + IN KPROCESSOR_MODE CurrentMode) +{ + UNIMPLEMENTED; +} + +/* SYSTEM CALLS ***************************************************************/ NTSTATUS NTAPI @@ -202,236 +361,65 @@ NtAccessCheckAndAuditAlarm(IN PUNICODE_STRING SubsystemName, NTSTATUS STDCALL NtCloseObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, - IN PVOID HandleId, - IN BOOLEAN GenerateOnClose) + IN PVOID HandleId, + IN BOOLEAN GenerateOnClose) { - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + UNIMPLEMENTED; + return(STATUS_NOT_IMPLEMENTED); } NTSTATUS STDCALL NtDeleteObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, - IN PVOID HandleId, - IN BOOLEAN GenerateOnClose) + IN PVOID HandleId, + IN BOOLEAN GenerateOnClose) { - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + UNIMPLEMENTED; + return(STATUS_NOT_IMPLEMENTED); } NTSTATUS STDCALL NtOpenObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, - IN PVOID HandleId, - IN PUNICODE_STRING ObjectTypeName, - IN PUNICODE_STRING ObjectName, - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN HANDLE ClientToken, - IN ULONG DesiredAccess, - IN ULONG GrantedAccess, - IN PPRIVILEGE_SET Privileges, - IN BOOLEAN ObjectCreation, - IN BOOLEAN AccessGranted, - OUT PBOOLEAN GenerateOnClose) + IN PVOID HandleId, + IN PUNICODE_STRING ObjectTypeName, + IN PUNICODE_STRING ObjectName, + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN HANDLE ClientToken, + IN ULONG DesiredAccess, + IN ULONG GrantedAccess, + IN PPRIVILEGE_SET Privileges, + IN BOOLEAN ObjectCreation, + IN BOOLEAN AccessGranted, + OUT PBOOLEAN GenerateOnClose) { - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + UNIMPLEMENTED; + return(STATUS_NOT_IMPLEMENTED); } NTSTATUS STDCALL NtPrivilegedServiceAuditAlarm(IN PUNICODE_STRING SubsystemName, - IN PUNICODE_STRING ServiceName, - IN HANDLE ClientToken, - IN PPRIVILEGE_SET Privileges, - IN BOOLEAN AccessGranted) + IN PUNICODE_STRING ServiceName, + IN HANDLE ClientToken, + IN PPRIVILEGE_SET Privileges, + IN BOOLEAN AccessGranted) { - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + UNIMPLEMENTED; + return(STATUS_NOT_IMPLEMENTED); } NTSTATUS STDCALL NtPrivilegeObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, - IN PVOID HandleId, - IN HANDLE ClientToken, - IN ULONG DesiredAccess, - IN PPRIVILEGE_SET Privileges, - IN BOOLEAN AccessGranted) + IN PVOID HandleId, + IN HANDLE ClientToken, + IN ULONG DesiredAccess, + IN PPRIVILEGE_SET Privileges, + IN BOOLEAN AccessGranted) { - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); -} - - -/* - * @unimplemented - */ -VOID -STDCALL -SeAuditHardLinkCreation( - IN PUNICODE_STRING FileName, - IN PUNICODE_STRING LinkName, - IN BOOLEAN bSuccess - ) -{ - UNIMPLEMENTED; -} - -/* - * @unimplemented - */ -BOOLEAN -STDCALL -SeAuditingFileEvents( - IN BOOLEAN AccessGranted, - IN PSECURITY_DESCRIPTOR SecurityDescriptor - ) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * @unimplemented - */ -BOOLEAN -STDCALL -SeAuditingFileEventsWithContext( - IN BOOLEAN AccessGranted, - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext OPTIONAL - ) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * @unimplemented - */ -BOOLEAN -STDCALL -SeAuditingHardLinkEvents( - IN BOOLEAN AccessGranted, - IN PSECURITY_DESCRIPTOR SecurityDescriptor - ) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * @unimplemented - */ -BOOLEAN -STDCALL -SeAuditingHardLinkEventsWithContext( - IN BOOLEAN AccessGranted, - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext OPTIONAL - ) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * @unimplemented - */ -BOOLEAN -STDCALL -SeAuditingFileOrGlobalEvents( - IN BOOLEAN AccessGranted, - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext - ) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * @unimplemented - */ -VOID -STDCALL -SeCloseObjectAuditAlarm( - IN PVOID Object, - IN HANDLE Handle, - IN BOOLEAN PerformAction - ) -{ - UNIMPLEMENTED; -} - -/* - * @unimplemented - */ -VOID STDCALL -SeDeleteObjectAuditAlarm(IN PVOID Object, - IN HANDLE Handle) -{ - UNIMPLEMENTED; -} - -/* - * @unimplemented - */ -VOID -NTAPI -SeOpenObjectAuditAlarm(IN PUNICODE_STRING ObjectTypeName, - IN PVOID Object OPTIONAL, - IN PUNICODE_STRING AbsoluteObjectName OPTIONAL, - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN PACCESS_STATE AccessState, - IN BOOLEAN ObjectCreated, - IN BOOLEAN AccessGranted, - IN KPROCESSOR_MODE AccessMode, - OUT PBOOLEAN GenerateOnClose) -{ - PAGED_CODE(); - - /* Audits aren't done on kernel-mode access */ - if (AccessMode == KernelMode) return; - - /* Otherwise, unimplemented! */ - //UNIMPLEMENTED; - return; -} - -/* - * @unimplemented - */ -VOID STDCALL -SeOpenObjectForDeleteAuditAlarm(IN PUNICODE_STRING ObjectTypeName, - IN PVOID Object OPTIONAL, - IN PUNICODE_STRING AbsoluteObjectName OPTIONAL, - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN PACCESS_STATE AccessState, - IN BOOLEAN ObjectCreated, - IN BOOLEAN AccessGranted, - IN KPROCESSOR_MODE AccessMode, - OUT PBOOLEAN GenerateOnClose) -{ - UNIMPLEMENTED; -} - -/* - * @unimplemented - */ -VOID -STDCALL -SePrivilegeObjectAuditAlarm( - IN HANDLE Handle, - IN PSECURITY_SUBJECT_CONTEXT SubjectContext, - IN ACCESS_MASK DesiredAccess, - IN PPRIVILEGE_SET Privileges, - IN BOOLEAN AccessGranted, - IN KPROCESSOR_MODE CurrentMode - ) -{ - UNIMPLEMENTED; + UNIMPLEMENTED; + return(STATUS_NOT_IMPLEMENTED); } /* EOF */ diff --git a/reactos/ntoskrnl/se/lsa.c b/reactos/ntoskrnl/se/lsa.c index 24b81b2902a..d6ba8f07ac5 100644 --- a/reactos/ntoskrnl/se/lsa.c +++ b/reactos/ntoskrnl/se/lsa.c @@ -1,28 +1,32 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: ntoskrnl/se/lsa.c - * PURPOSE: No purpose listed. + * FILE: ntoskrnl/se/sid.c + * PURPOSE: Security manager * - * PROGRAMMERS: No programmer listed. + * PROGRAMMERS: David Welch */ +/* INCLUDES *******************************************************************/ + #include #define NDEBUG -#include +#include + +/* FUNCTIONS ******************************************************************/ /* * @unimplemented */ -NTSTATUS STDCALL LsaCallAuthenticationPackage ( - ULONG Unknown0, - ULONG Unknown1, - ULONG Unknown2, - ULONG Unknown3, - ULONG Unknown4, - ULONG Unknown5, - ULONG Unknown6 - ) +NTSTATUS +NTAPI +LsaCallAuthenticationPackage(ULONG Unknown0, + ULONG Unknown1, + ULONG Unknown2, + ULONG Unknown3, + ULONG Unknown4, + ULONG Unknown5, + ULONG Unknown6) { return STATUS_NOT_IMPLEMENTED; } @@ -30,10 +34,10 @@ NTSTATUS STDCALL LsaCallAuthenticationPackage ( /* * @unimplemented */ -NTSTATUS STDCALL LsaDeregisterLogonProcess ( - ULONG Unknown0, - ULONG Unknown1 - ) +NTSTATUS +NTAPI +LsaDeregisterLogonProcess(ULONG Unknown0, + ULONG Unknown1) { return STATUS_NOT_IMPLEMENTED; } @@ -41,16 +45,15 @@ NTSTATUS STDCALL LsaDeregisterLogonProcess ( /* * @implemented */ -NTSTATUS STDCALL LsaFreeReturnBuffer (PVOID Buffer) +NTSTATUS +NTAPI +LsaFreeReturnBuffer(PVOID Buffer) { - ULONG Size = 0; /* required by MEM_RELEASE */ - - return ZwFreeVirtualMemory ( - NtCurrentProcess(), - & Buffer, - & Size, - MEM_RELEASE - ); + ULONG Size = 0; + return ZwFreeVirtualMemory(NtCurrentProcess(), + &Buffer, + &Size, + MEM_RELEASE); } /* @@ -79,11 +82,11 @@ LsaLogonUser(IN HANDLE LsaHandle, /* * @unimplemented */ -NTSTATUS STDCALL LsaLookupAuthenticationPackage ( - ULONG Unknown0, - ULONG Unknown1, - ULONG Unknown2 - ) +NTSTATUS +NTAPI +LsaLookupAuthenticationPackage(ULONG Unknown0, + ULONG Unknown1, + ULONG Unknown2) { return STATUS_NOT_IMPLEMENTED; } @@ -93,9 +96,9 @@ NTSTATUS STDCALL LsaLookupAuthenticationPackage ( */ NTSTATUS NTAPI -LsaRegisterLogonProcess (IN PLSA_STRING LogonProcessName, - OUT PHANDLE LsaHandle, - OUT PLSA_OPERATIONAL_MODE SecurityMode) +LsaRegisterLogonProcess(IN PLSA_STRING LogonProcessName, + OUT PHANDLE LsaHandle, + OUT PLSA_OPERATIONAL_MODE SecurityMode) { return STATUS_NOT_IMPLEMENTED; } @@ -105,9 +108,7 @@ LsaRegisterLogonProcess (IN PLSA_STRING LogonProcessName, */ NTSTATUS STDCALL -SeMarkLogonSessionForTerminationNotification( - IN PLUID LogonId - ) +SeMarkLogonSessionForTerminationNotification(IN PLUID LogonId) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; @@ -118,9 +119,7 @@ SeMarkLogonSessionForTerminationNotification( */ NTSTATUS STDCALL -SeRegisterLogonSessionTerminatedRoutine( - IN PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine - ) +SeRegisterLogonSessionTerminatedRoutine(IN PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; @@ -131,13 +130,10 @@ SeRegisterLogonSessionTerminatedRoutine( */ NTSTATUS STDCALL -SeUnregisterLogonSessionTerminatedRoutine( - IN PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine - ) +SeUnregisterLogonSessionTerminatedRoutine(IN PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; } - /* EOF */ diff --git a/reactos/ntoskrnl/se/luid.c b/reactos/ntoskrnl/se/luid.c deleted file mode 100644 index 1fbb2c7390b..00000000000 --- a/reactos/ntoskrnl/se/luid.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/se/luid.c - * PURPOSE: Security manager - * - * PROGRAMMERS: No programmer listed. - */ - -/* INCLUDES *****************************************************************/ - -#include -#include - -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, SepInitLuid) -#endif - - -/* GLOBALS *******************************************************************/ - -static LARGE_INTEGER LuidIncrement; -static LARGE_INTEGER LuidValue; - -/* FUNCTIONS *****************************************************************/ - -VOID -INIT_FUNCTION -NTAPI -SepInitLuid(VOID) -{ - LUID DummyLuidValue = SYSTEM_LUID; - - LuidValue.u.HighPart = DummyLuidValue.HighPart; - LuidValue.u.LowPart = DummyLuidValue.LowPart; - LuidIncrement.QuadPart = 1; -} - - -NTSTATUS -NTAPI -ExpAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId) -{ - LARGE_INTEGER NewLuid, PrevLuid; - - /* atomically increment the luid */ - do - { - PrevLuid = LuidValue; - NewLuid = RtlLargeIntegerAdd(PrevLuid, - LuidIncrement); - } while(ExfInterlockedCompareExchange64(&LuidValue.QuadPart, - &NewLuid.QuadPart, - &PrevLuid.QuadPart) != PrevLuid.QuadPart); - - LocallyUniqueId->LowPart = NewLuid.u.LowPart; - LocallyUniqueId->HighPart = NewLuid.u.HighPart; - - return STATUS_SUCCESS; -} - - -/* - * @implemented - */ -NTSTATUS STDCALL -NtAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId) -{ - LUID NewLuid; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH_TRY - { - ProbeForWrite(LocallyUniqueId, - sizeof(LUID), - sizeof(ULONG)); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(!NT_SUCCESS(Status)) - { - return Status; - } - } - - Status = ExpAllocateLocallyUniqueId(&NewLuid); - - _SEH_TRY - { - *LocallyUniqueId = NewLuid; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - return Status; -} - -/* EOF */ diff --git a/reactos/ntoskrnl/se/priv.c b/reactos/ntoskrnl/se/priv.c index ef7f7f5dc32..61506db4b17 100644 --- a/reactos/ntoskrnl/se/priv.c +++ b/reactos/ntoskrnl/se/priv.c @@ -7,18 +7,17 @@ * PROGRAMMERS: No programmer listed. */ -/* INCLUDES *****************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG -#include +#include #if defined (ALLOC_PRAGMA) #pragma alloc_text(INIT, SepInitPrivileges) #endif - -/* GLOBALS *******************************************************************/ +/* GLOBALS ********************************************************************/ LUID SeCreateTokenPrivilege; LUID SeAssignPrimaryTokenPrivilege; @@ -47,166 +46,164 @@ LUID SeUndockPrivilege; LUID SeSyncAgentPrivilege; LUID SeEnableDelegationPrivilege; - -/* FUNCTIONS ***************************************************************/ +/* PRIVATE FUNCTIONS **********************************************************/ VOID INIT_FUNCTION NTAPI SepInitPrivileges (VOID) { - SeCreateTokenPrivilege.LowPart = SE_CREATE_TOKEN_PRIVILEGE; - SeCreateTokenPrivilege.HighPart = 0; - SeAssignPrimaryTokenPrivilege.LowPart = SE_ASSIGNPRIMARYTOKEN_PRIVILEGE; - SeAssignPrimaryTokenPrivilege.HighPart = 0; - SeLockMemoryPrivilege.LowPart = SE_LOCK_MEMORY_PRIVILEGE; - SeLockMemoryPrivilege.HighPart = 0; - SeIncreaseQuotaPrivilege.LowPart = SE_INCREASE_QUOTA_PRIVILEGE; - SeIncreaseQuotaPrivilege.HighPart = 0; - SeUnsolicitedInputPrivilege.LowPart = SE_UNSOLICITED_INPUT_PRIVILEGE; - SeUnsolicitedInputPrivilege.HighPart = 0; - SeTcbPrivilege.LowPart = SE_TCB_PRIVILEGE; - SeTcbPrivilege.HighPart = 0; - SeSecurityPrivilege.LowPart = SE_SECURITY_PRIVILEGE; - SeSecurityPrivilege.HighPart = 0; - SeTakeOwnershipPrivilege.LowPart = SE_TAKE_OWNERSHIP_PRIVILEGE; - SeTakeOwnershipPrivilege.HighPart = 0; - SeLoadDriverPrivilege.LowPart = SE_LOAD_DRIVER_PRIVILEGE; - SeLoadDriverPrivilege.HighPart = 0; - SeSystemProfilePrivilege.LowPart = SE_SYSTEM_PROFILE_PRIVILEGE; - SeSystemProfilePrivilege.HighPart = 0; - SeSystemtimePrivilege.LowPart = SE_SYSTEMTIME_PRIVILEGE; - SeSystemtimePrivilege.HighPart = 0; - SeProfileSingleProcessPrivilege.LowPart = SE_PROF_SINGLE_PROCESS_PRIVILEGE; - SeProfileSingleProcessPrivilege.HighPart = 0; - SeIncreaseBasePriorityPrivilege.LowPart = SE_INC_BASE_PRIORITY_PRIVILEGE; - SeIncreaseBasePriorityPrivilege.HighPart = 0; - SeCreatePagefilePrivilege.LowPart = SE_CREATE_PAGEFILE_PRIVILEGE; - SeCreatePagefilePrivilege.HighPart = 0; - SeCreatePermanentPrivilege.LowPart = SE_CREATE_PERMANENT_PRIVILEGE; - SeCreatePermanentPrivilege.HighPart = 0; - SeBackupPrivilege.LowPart = SE_BACKUP_PRIVILEGE; - SeBackupPrivilege.HighPart = 0; - SeRestorePrivilege.LowPart = SE_RESTORE_PRIVILEGE; - SeRestorePrivilege.HighPart = 0; - SeShutdownPrivilege.LowPart = SE_SHUTDOWN_PRIVILEGE; - SeShutdownPrivilege.HighPart = 0; - SeDebugPrivilege.LowPart = SE_DEBUG_PRIVILEGE; - SeDebugPrivilege.HighPart = 0; - SeAuditPrivilege.LowPart = SE_AUDIT_PRIVILEGE; - SeAuditPrivilege.HighPart = 0; - SeSystemEnvironmentPrivilege.LowPart = SE_SYSTEM_ENVIRONMENT_PRIVILEGE; - SeSystemEnvironmentPrivilege.HighPart = 0; - SeChangeNotifyPrivilege.LowPart = SE_CHANGE_NOTIFY_PRIVILEGE; - SeChangeNotifyPrivilege.HighPart = 0; - SeRemoteShutdownPrivilege.LowPart = SE_REMOTE_SHUTDOWN_PRIVILEGE; - SeRemoteShutdownPrivilege.HighPart = 0; - SeUndockPrivilege.LowPart = SE_UNDOCK_PRIVILEGE; - SeUndockPrivilege.HighPart = 0; - SeSyncAgentPrivilege.LowPart = SE_SYNC_AGENT_PRIVILEGE; - SeSyncAgentPrivilege.HighPart = 0; - SeEnableDelegationPrivilege.LowPart = SE_ENABLE_DELEGATION_PRIVILEGE; - SeEnableDelegationPrivilege.HighPart = 0; + SeCreateTokenPrivilege.LowPart = SE_CREATE_TOKEN_PRIVILEGE; + SeCreateTokenPrivilege.HighPart = 0; + SeAssignPrimaryTokenPrivilege.LowPart = SE_ASSIGNPRIMARYTOKEN_PRIVILEGE; + SeAssignPrimaryTokenPrivilege.HighPart = 0; + SeLockMemoryPrivilege.LowPart = SE_LOCK_MEMORY_PRIVILEGE; + SeLockMemoryPrivilege.HighPart = 0; + SeIncreaseQuotaPrivilege.LowPart = SE_INCREASE_QUOTA_PRIVILEGE; + SeIncreaseQuotaPrivilege.HighPart = 0; + SeUnsolicitedInputPrivilege.LowPart = SE_UNSOLICITED_INPUT_PRIVILEGE; + SeUnsolicitedInputPrivilege.HighPart = 0; + SeTcbPrivilege.LowPart = SE_TCB_PRIVILEGE; + SeTcbPrivilege.HighPart = 0; + SeSecurityPrivilege.LowPart = SE_SECURITY_PRIVILEGE; + SeSecurityPrivilege.HighPart = 0; + SeTakeOwnershipPrivilege.LowPart = SE_TAKE_OWNERSHIP_PRIVILEGE; + SeTakeOwnershipPrivilege.HighPart = 0; + SeLoadDriverPrivilege.LowPart = SE_LOAD_DRIVER_PRIVILEGE; + SeLoadDriverPrivilege.HighPart = 0; + SeSystemProfilePrivilege.LowPart = SE_SYSTEM_PROFILE_PRIVILEGE; + SeSystemProfilePrivilege.HighPart = 0; + SeSystemtimePrivilege.LowPart = SE_SYSTEMTIME_PRIVILEGE; + SeSystemtimePrivilege.HighPart = 0; + SeProfileSingleProcessPrivilege.LowPart = SE_PROF_SINGLE_PROCESS_PRIVILEGE; + SeProfileSingleProcessPrivilege.HighPart = 0; + SeIncreaseBasePriorityPrivilege.LowPart = SE_INC_BASE_PRIORITY_PRIVILEGE; + SeIncreaseBasePriorityPrivilege.HighPart = 0; + SeCreatePagefilePrivilege.LowPart = SE_CREATE_PAGEFILE_PRIVILEGE; + SeCreatePagefilePrivilege.HighPart = 0; + SeCreatePermanentPrivilege.LowPart = SE_CREATE_PERMANENT_PRIVILEGE; + SeCreatePermanentPrivilege.HighPart = 0; + SeBackupPrivilege.LowPart = SE_BACKUP_PRIVILEGE; + SeBackupPrivilege.HighPart = 0; + SeRestorePrivilege.LowPart = SE_RESTORE_PRIVILEGE; + SeRestorePrivilege.HighPart = 0; + SeShutdownPrivilege.LowPart = SE_SHUTDOWN_PRIVILEGE; + SeShutdownPrivilege.HighPart = 0; + SeDebugPrivilege.LowPart = SE_DEBUG_PRIVILEGE; + SeDebugPrivilege.HighPart = 0; + SeAuditPrivilege.LowPart = SE_AUDIT_PRIVILEGE; + SeAuditPrivilege.HighPart = 0; + SeSystemEnvironmentPrivilege.LowPart = SE_SYSTEM_ENVIRONMENT_PRIVILEGE; + SeSystemEnvironmentPrivilege.HighPart = 0; + SeChangeNotifyPrivilege.LowPart = SE_CHANGE_NOTIFY_PRIVILEGE; + SeChangeNotifyPrivilege.HighPart = 0; + SeRemoteShutdownPrivilege.LowPart = SE_REMOTE_SHUTDOWN_PRIVILEGE; + SeRemoteShutdownPrivilege.HighPart = 0; + SeUndockPrivilege.LowPart = SE_UNDOCK_PRIVILEGE; + SeUndockPrivilege.HighPart = 0; + SeSyncAgentPrivilege.LowPart = SE_SYNC_AGENT_PRIVILEGE; + SeSyncAgentPrivilege.HighPart = 0; + SeEnableDelegationPrivilege.LowPart = SE_ENABLE_DELEGATION_PRIVILEGE; + SeEnableDelegationPrivilege.HighPart = 0; } BOOLEAN NTAPI SepPrivilegeCheck (PTOKEN Token, - PLUID_AND_ATTRIBUTES Privileges, - ULONG PrivilegeCount, - ULONG PrivilegeControl, - KPROCESSOR_MODE PreviousMode) + PLUID_AND_ATTRIBUTES Privileges, + ULONG PrivilegeCount, + ULONG PrivilegeControl, + KPROCESSOR_MODE PreviousMode) { - ULONG i; - ULONG j; - ULONG k; - - DPRINT ("SepPrivilegeCheck() called\n"); - - PAGED_CODE(); - - if (PreviousMode == KernelMode) + ULONG i; + ULONG j; + ULONG k; + + DPRINT ("SepPrivilegeCheck() called\n"); + + PAGED_CODE(); + + if (PreviousMode == KernelMode) { - return TRUE; + return TRUE; } - - k = 0; - if (PrivilegeCount > 0) + + k = 0; + if (PrivilegeCount > 0) { - for (i = 0; i < Token->PrivilegeCount; i++) - { - for (j = 0; j < PrivilegeCount; j++) - { - if (Token->Privileges[i].Luid.LowPart == Privileges[j].Luid.LowPart && - Token->Privileges[i].Luid.HighPart == Privileges[j].Luid.HighPart) - { - DPRINT ("Found privilege\n"); - DPRINT ("Privilege attributes %lx\n", - Token->Privileges[i].Attributes); - - if (Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) - { - Privileges[j].Attributes |= SE_PRIVILEGE_USED_FOR_ACCESS; - k++; - } - } - } - } + for (i = 0; i < Token->PrivilegeCount; i++) + { + for (j = 0; j < PrivilegeCount; j++) + { + if (Token->Privileges[i].Luid.LowPart == Privileges[j].Luid.LowPart && + Token->Privileges[i].Luid.HighPart == Privileges[j].Luid.HighPart) + { + DPRINT ("Found privilege\n"); + DPRINT ("Privilege attributes %lx\n", + Token->Privileges[i].Attributes); + + if (Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) + { + Privileges[j].Attributes |= SE_PRIVILEGE_USED_FOR_ACCESS; + k++; + } + } + } + } } - - if ((PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY) && - PrivilegeCount == k) + + if ((PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY) && + PrivilegeCount == k) { - return TRUE; + return TRUE; } - - if (k > 0 && - !(PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY)) + + if (k > 0 && + !(PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY)) { - return TRUE; + return TRUE; } - - return FALSE; + + return FALSE; } - NTSTATUS NTAPI SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src, - ULONG PrivilegeCount, - KPROCESSOR_MODE PreviousMode, - PLUID_AND_ATTRIBUTES AllocatedMem, - ULONG AllocatedLength, - POOL_TYPE PoolType, - BOOLEAN CaptureIfKernel, - PLUID_AND_ATTRIBUTES* Dest, - PULONG Length) + ULONG PrivilegeCount, + KPROCESSOR_MODE PreviousMode, + PLUID_AND_ATTRIBUTES AllocatedMem, + ULONG AllocatedLength, + POOL_TYPE PoolType, + BOOLEAN CaptureIfKernel, + PLUID_AND_ATTRIBUTES* Dest, + PULONG Length) { ULONG BufferSize; NTSTATUS Status = STATUS_SUCCESS; - + PAGED_CODE(); - + if (PrivilegeCount == 0) { *Dest = 0; *Length = 0; return STATUS_SUCCESS; } - + if (PreviousMode == KernelMode && !CaptureIfKernel) { *Dest = Src; return STATUS_SUCCESS; } - + /* FIXME - check PrivilegeCount for a valid number so we don't - cause an integer overflow or exhaust system resources! */ - + cause an integer overflow or exhaust system resources! */ + BufferSize = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); *Length = ROUND_UP(BufferSize, 4); /* round up to a 4 byte alignment */ - + /* probe the buffer */ if (PreviousMode != KernelMode) { @@ -221,35 +218,35 @@ SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src, Status = _SEH_GetExceptionCode(); } _SEH_END; - + if (!NT_SUCCESS(Status)) { return Status; } } - + /* allocate enough memory or check if the provided buffer is - large enough to hold the array */ + large enough to hold the array */ if (AllocatedMem != NULL) { if (AllocatedLength < BufferSize) { return STATUS_BUFFER_TOO_SMALL; } - + *Dest = AllocatedMem; } else { *Dest = ExAllocatePool(PoolType, BufferSize); - + if (&Dest == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } } - + /* copy the array to the buffer */ _SEH_TRY { @@ -262,24 +259,23 @@ SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src, Status = _SEH_GetExceptionCode(); } _SEH_END; - + if (!NT_SUCCESS(Status) && AllocatedMem == NULL) { ExFreePool(*Dest); } - + return Status; } - VOID NTAPI SeReleaseLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Privilege, - KPROCESSOR_MODE PreviousMode, - BOOLEAN CaptureIfKernel) + KPROCESSOR_MODE PreviousMode, + BOOLEAN CaptureIfKernel) { PAGED_CODE(); - + if (Privilege != NULL && (PreviousMode != KernelMode || CaptureIfKernel)) { @@ -287,208 +283,232 @@ SeReleaseLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Privilege, } } +/* PUBLIC FUNCTIONS ***********************************************************/ -NTSTATUS STDCALL -NtPrivilegeCheck (IN HANDLE ClientToken, - IN PPRIVILEGE_SET RequiredPrivileges, - OUT PBOOLEAN Result) +/* + * @unimplemented + */ +NTSTATUS +STDCALL +SeAppendPrivileges(PACCESS_STATE AccessState, + PPRIVILEGE_SET Privileges) { - PLUID_AND_ATTRIBUTES Privileges; - PTOKEN Token; - ULONG PrivilegeCount = 0; - ULONG PrivilegeControl = 0; - ULONG Length; - BOOLEAN CheckResult; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = KeGetPreviousMode(); - - /* probe the buffers */ - if (PreviousMode != KernelMode) - { - _SEH_TRY - { - ProbeForWrite(RequiredPrivileges, - FIELD_OFFSET(PRIVILEGE_SET, - Privilege), - sizeof(ULONG)); - - PrivilegeCount = RequiredPrivileges->PrivilegeCount; - PrivilegeControl = RequiredPrivileges->Control; - - /* Check PrivilegeCount to avoid an integer overflow! */ - if (FIELD_OFFSET(PRIVILEGE_SET, - Privilege[PrivilegeCount]) / - sizeof(RequiredPrivileges->Privilege[0]) != PrivilegeCount) - { - Status = STATUS_INVALID_PARAMETER; - _SEH_LEAVE; - } - - /* probe all of the array */ - ProbeForWrite(RequiredPrivileges, - FIELD_OFFSET(PRIVILEGE_SET, - Privilege[PrivilegeCount]), - sizeof(ULONG)); - - ProbeForWriteBoolean(Result); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if (!NT_SUCCESS(Status)) - { - return Status; - } - } - else - { - PrivilegeCount = RequiredPrivileges->PrivilegeCount; - PrivilegeControl = RequiredPrivileges->Control; - } - - /* reference the token and make sure we're - not doing an anonymous impersonation */ - Status = ObReferenceObjectByHandle (ClientToken, - TOKEN_QUERY, - SepTokenObjectType, - PreviousMode, - (PVOID*)&Token, - NULL); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - if (Token->TokenType == TokenImpersonation && - Token->ImpersonationLevel < SecurityIdentification) - { - ObDereferenceObject (Token); - return STATUS_BAD_IMPERSONATION_LEVEL; - } - - /* capture the privileges */ - Status = SeCaptureLuidAndAttributesArray (RequiredPrivileges->Privilege, - PrivilegeCount, - PreviousMode, - NULL, - 0, - PagedPool, - TRUE, - &Privileges, - &Length); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject (Token); - return Status; - } - - CheckResult = SepPrivilegeCheck (Token, - Privileges, - PrivilegeCount, - PrivilegeControl, - PreviousMode); - - ObDereferenceObject (Token); - - /* return the array */ - _SEH_TRY - { - RtlCopyMemory(RequiredPrivileges->Privilege, - Privileges, - PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); - *Result = CheckResult; - Status = STATUS_SUCCESS; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - SeReleaseLuidAndAttributesArray (Privileges, - PreviousMode, - TRUE); - - return Status; + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } +/* + * @unimplemented + */ +VOID +STDCALL +SeFreePrivileges(IN PPRIVILEGE_SET Privileges) +{ + UNIMPLEMENTED; +} /* * @implemented */ BOOLEAN STDCALL SePrivilegeCheck (PPRIVILEGE_SET Privileges, - PSECURITY_SUBJECT_CONTEXT SubjectContext, - KPROCESSOR_MODE PreviousMode) + PSECURITY_SUBJECT_CONTEXT SubjectContext, + KPROCESSOR_MODE PreviousMode) { - PACCESS_TOKEN Token = NULL; - - PAGED_CODE(); - - if (SubjectContext->ClientToken == NULL) + PACCESS_TOKEN Token = NULL; + + PAGED_CODE(); + + if (SubjectContext->ClientToken == NULL) { - Token = SubjectContext->PrimaryToken; + Token = SubjectContext->PrimaryToken; } - else + else { - Token = SubjectContext->ClientToken; - if (SubjectContext->ImpersonationLevel < 2) - { - return FALSE; - } + Token = SubjectContext->ClientToken; + if (SubjectContext->ImpersonationLevel < 2) + { + return FALSE; + } } - - return SepPrivilegeCheck (Token, - Privileges->Privilege, - Privileges->PrivilegeCount, - Privileges->Control, - PreviousMode); + + return SepPrivilegeCheck (Token, + Privileges->Privilege, + Privileges->PrivilegeCount, + Privileges->Control, + PreviousMode); } - /* * @implemented */ BOOLEAN STDCALL SeSinglePrivilegeCheck (IN LUID PrivilegeValue, - IN KPROCESSOR_MODE PreviousMode) + IN KPROCESSOR_MODE PreviousMode) { - SECURITY_SUBJECT_CONTEXT SubjectContext; - PRIVILEGE_SET Priv; - BOOLEAN Result; - - PAGED_CODE(); - - SeCaptureSubjectContext (&SubjectContext); - - Priv.PrivilegeCount = 1; - Priv.Control = PRIVILEGE_SET_ALL_NECESSARY; - Priv.Privilege[0].Luid = PrivilegeValue; - Priv.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED; - - Result = SePrivilegeCheck (&Priv, - &SubjectContext, - PreviousMode); - - if (PreviousMode != KernelMode) + SECURITY_SUBJECT_CONTEXT SubjectContext; + PRIVILEGE_SET Priv; + BOOLEAN Result; + + PAGED_CODE(); + + SeCaptureSubjectContext (&SubjectContext); + + Priv.PrivilegeCount = 1; + Priv.Control = PRIVILEGE_SET_ALL_NECESSARY; + Priv.Privilege[0].Luid = PrivilegeValue; + Priv.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED; + + Result = SePrivilegeCheck (&Priv, + &SubjectContext, + PreviousMode); + + if (PreviousMode != KernelMode) { #if 0 - SePrivilegedServiceAuditAlarm (0, - &SubjectContext, - &PrivilegeValue); + SePrivilegedServiceAuditAlarm (0, + &SubjectContext, + &PrivilegeValue); #endif } - - SeReleaseSubjectContext (&SubjectContext); - - return Result; + + SeReleaseSubjectContext (&SubjectContext); + + return Result; } +/* SYSTEM CALLS ***************************************************************/ + +NTSTATUS STDCALL +NtPrivilegeCheck (IN HANDLE ClientToken, + IN PPRIVILEGE_SET RequiredPrivileges, + OUT PBOOLEAN Result) +{ + PLUID_AND_ATTRIBUTES Privileges; + PTOKEN Token; + ULONG PrivilegeCount = 0; + ULONG PrivilegeControl = 0; + ULONG Length; + BOOLEAN CheckResult; + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + PreviousMode = KeGetPreviousMode(); + + /* probe the buffers */ + if (PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite(RequiredPrivileges, + FIELD_OFFSET(PRIVILEGE_SET, + Privilege), + sizeof(ULONG)); + + PrivilegeCount = RequiredPrivileges->PrivilegeCount; + PrivilegeControl = RequiredPrivileges->Control; + + /* Check PrivilegeCount to avoid an integer overflow! */ + if (FIELD_OFFSET(PRIVILEGE_SET, + Privilege[PrivilegeCount]) / + sizeof(RequiredPrivileges->Privilege[0]) != PrivilegeCount) + { + Status = STATUS_INVALID_PARAMETER; + _SEH_LEAVE; + } + + /* probe all of the array */ + ProbeForWrite(RequiredPrivileges, + FIELD_OFFSET(PRIVILEGE_SET, + Privilege[PrivilegeCount]), + sizeof(ULONG)); + + ProbeForWriteBoolean(Result); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + else + { + PrivilegeCount = RequiredPrivileges->PrivilegeCount; + PrivilegeControl = RequiredPrivileges->Control; + } + + /* reference the token and make sure we're + not doing an anonymous impersonation */ + Status = ObReferenceObjectByHandle (ClientToken, + TOKEN_QUERY, + SepTokenObjectType, + PreviousMode, + (PVOID*)&Token, + NULL); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + if (Token->TokenType == TokenImpersonation && + Token->ImpersonationLevel < SecurityIdentification) + { + ObDereferenceObject (Token); + return STATUS_BAD_IMPERSONATION_LEVEL; + } + + /* capture the privileges */ + Status = SeCaptureLuidAndAttributesArray (RequiredPrivileges->Privilege, + PrivilegeCount, + PreviousMode, + NULL, + 0, + PagedPool, + TRUE, + &Privileges, + &Length); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject (Token); + return Status; + } + + CheckResult = SepPrivilegeCheck (Token, + Privileges, + PrivilegeCount, + PrivilegeControl, + PreviousMode); + + ObDereferenceObject (Token); + + /* return the array */ + _SEH_TRY + { + RtlCopyMemory(RequiredPrivileges->Privilege, + Privileges, + PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); + *Result = CheckResult; + Status = STATUS_SUCCESS; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + SeReleaseLuidAndAttributesArray (Privileges, + PreviousMode, + TRUE); + + return Status; +} + + /* EOF */ diff --git a/reactos/ntoskrnl/se/sd.c b/reactos/ntoskrnl/se/sd.c index 46ad70b94ee..2c58e399b12 100644 --- a/reactos/ntoskrnl/se/sd.c +++ b/reactos/ntoskrnl/se/sd.c @@ -7,17 +7,17 @@ * PROGRAMMERS: David Welch */ -/* INCLUDES *****************************************************************/ +/* INCLUDES *******************************************************************/ #include -#include +#define NDEBUG +#include #if defined (ALLOC_PRAGMA) #pragma alloc_text(INIT, SepInitSDs) #endif - -/* GLOBALS ******************************************************************/ +/* GLOBALS ********************************************************************/ PSECURITY_DESCRIPTOR SePublicDefaultSd = NULL; PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd = NULL; @@ -26,92 +26,92 @@ PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd = NULL; PSECURITY_DESCRIPTOR SeSystemDefaultSd = NULL; PSECURITY_DESCRIPTOR SeUnrestrictedSd = NULL; -/* FUNCTIONS ***************************************************************/ +/* PRIVATE FUNCTIONS **********************************************************/ BOOLEAN INIT_FUNCTION NTAPI SepInitSDs(VOID) { - /* Create PublicDefaultSd */ - SePublicDefaultSd = ExAllocatePoolWithTag(PagedPool, - sizeof(SECURITY_DESCRIPTOR), TAG_SD); - if (SePublicDefaultSd == NULL) - return FALSE; - - RtlCreateSecurityDescriptor(SePublicDefaultSd, - SECURITY_DESCRIPTOR_REVISION); - RtlSetDaclSecurityDescriptor(SePublicDefaultSd, - TRUE, - SePublicDefaultDacl, - FALSE); - - /* Create PublicDefaultUnrestrictedSd */ - SePublicDefaultUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, - sizeof(SECURITY_DESCRIPTOR), TAG_SD); - if (SePublicDefaultUnrestrictedSd == NULL) - return FALSE; - - RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd, - SECURITY_DESCRIPTOR_REVISION); - RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd, - TRUE, - SePublicDefaultUnrestrictedDacl, - FALSE); - - /* Create PublicOpenSd */ - SePublicOpenSd = ExAllocatePoolWithTag(PagedPool, - sizeof(SECURITY_DESCRIPTOR), TAG_SD); - if (SePublicOpenSd == NULL) - return FALSE; - - RtlCreateSecurityDescriptor(SePublicOpenSd, - SECURITY_DESCRIPTOR_REVISION); - RtlSetDaclSecurityDescriptor(SePublicOpenSd, - TRUE, - SePublicOpenDacl, - FALSE); - - /* Create PublicOpenUnrestrictedSd */ - SePublicOpenUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, - sizeof(SECURITY_DESCRIPTOR), TAG_SD); - if (SePublicOpenUnrestrictedSd == NULL) - return FALSE; - - RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd, - SECURITY_DESCRIPTOR_REVISION); - RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd, - TRUE, - SePublicOpenUnrestrictedDacl, - FALSE); - - /* Create SystemDefaultSd */ - SeSystemDefaultSd = ExAllocatePoolWithTag(PagedPool, - sizeof(SECURITY_DESCRIPTOR), TAG_SD); - if (SeSystemDefaultSd == NULL) - return FALSE; - - RtlCreateSecurityDescriptor(SeSystemDefaultSd, - SECURITY_DESCRIPTOR_REVISION); - RtlSetDaclSecurityDescriptor(SeSystemDefaultSd, - TRUE, - SeSystemDefaultDacl, - FALSE); - - /* Create UnrestrictedSd */ - SeUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, - sizeof(SECURITY_DESCRIPTOR), TAG_SD); - if (SeUnrestrictedSd == NULL) - return FALSE; - - RtlCreateSecurityDescriptor(SeUnrestrictedSd, - SECURITY_DESCRIPTOR_REVISION); - RtlSetDaclSecurityDescriptor(SeUnrestrictedSd, - TRUE, - SeUnrestrictedDacl, - FALSE); - - return TRUE; + /* Create PublicDefaultSd */ + SePublicDefaultSd = ExAllocatePoolWithTag(PagedPool, + sizeof(SECURITY_DESCRIPTOR), TAG_SD); + if (SePublicDefaultSd == NULL) + return FALSE; + + RtlCreateSecurityDescriptor(SePublicDefaultSd, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(SePublicDefaultSd, + TRUE, + SePublicDefaultDacl, + FALSE); + + /* Create PublicDefaultUnrestrictedSd */ + SePublicDefaultUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, + sizeof(SECURITY_DESCRIPTOR), TAG_SD); + if (SePublicDefaultUnrestrictedSd == NULL) + return FALSE; + + RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd, + TRUE, + SePublicDefaultUnrestrictedDacl, + FALSE); + + /* Create PublicOpenSd */ + SePublicOpenSd = ExAllocatePoolWithTag(PagedPool, + sizeof(SECURITY_DESCRIPTOR), TAG_SD); + if (SePublicOpenSd == NULL) + return FALSE; + + RtlCreateSecurityDescriptor(SePublicOpenSd, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(SePublicOpenSd, + TRUE, + SePublicOpenDacl, + FALSE); + + /* Create PublicOpenUnrestrictedSd */ + SePublicOpenUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, + sizeof(SECURITY_DESCRIPTOR), TAG_SD); + if (SePublicOpenUnrestrictedSd == NULL) + return FALSE; + + RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd, + TRUE, + SePublicOpenUnrestrictedDacl, + FALSE); + + /* Create SystemDefaultSd */ + SeSystemDefaultSd = ExAllocatePoolWithTag(PagedPool, + sizeof(SECURITY_DESCRIPTOR), TAG_SD); + if (SeSystemDefaultSd == NULL) + return FALSE; + + RtlCreateSecurityDescriptor(SeSystemDefaultSd, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(SeSystemDefaultSd, + TRUE, + SeSystemDefaultDacl, + FALSE); + + /* Create UnrestrictedSd */ + SeUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, + sizeof(SECURITY_DESCRIPTOR), TAG_SD); + if (SeUnrestrictedSd == NULL) + return FALSE; + + RtlCreateSecurityDescriptor(SeUnrestrictedSd, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(SeUnrestrictedSd, + TRUE, + SeUnrestrictedDacl, + FALSE); + + return TRUE; } NTSTATUS @@ -120,93 +120,93 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, PISECURITY_DESCRIPTOR SecurityDescriptor, PULONG BufferLength) { - ULONG_PTR Current; - ULONG SidSize; - ULONG SdSize; - NTSTATUS Status; - PISECURITY_DESCRIPTOR_RELATIVE SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor; - - DPRINT("SeSetWorldSecurityDescriptor() called\n"); - - if (SecurityInformation == 0) + ULONG_PTR Current; + ULONG SidSize; + ULONG SdSize; + NTSTATUS Status; + PISECURITY_DESCRIPTOR_RELATIVE SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor; + + DPRINT("SeSetWorldSecurityDescriptor() called\n"); + + if (SecurityInformation == 0) { - return STATUS_ACCESS_DENIED; + return STATUS_ACCESS_DENIED; } - - /* calculate the minimum size of the buffer */ - SidSize = RtlLengthSid(SeWorldSid); - SdSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE); - if (SecurityInformation & OWNER_SECURITY_INFORMATION) - SdSize += SidSize; - if (SecurityInformation & GROUP_SECURITY_INFORMATION) - SdSize += SidSize; - if (SecurityInformation & DACL_SECURITY_INFORMATION) + + /* calculate the minimum size of the buffer */ + SidSize = RtlLengthSid(SeWorldSid); + SdSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE); + if (SecurityInformation & OWNER_SECURITY_INFORMATION) + SdSize += SidSize; + if (SecurityInformation & GROUP_SECURITY_INFORMATION) + SdSize += SidSize; + if (SecurityInformation & DACL_SECURITY_INFORMATION) { - SdSize += sizeof(ACL) + sizeof(ACE) + SidSize; + SdSize += sizeof(ACL) + sizeof(ACE) + SidSize; } - - if (*BufferLength < SdSize) + + if (*BufferLength < SdSize) { - *BufferLength = SdSize; - return STATUS_BUFFER_TOO_SMALL; + *BufferLength = SdSize; + return STATUS_BUFFER_TOO_SMALL; } - - *BufferLength = SdSize; - - Status = RtlCreateSecurityDescriptorRelative(SdRel, - SECURITY_DESCRIPTOR_REVISION); - if (!NT_SUCCESS(Status)) + + *BufferLength = SdSize; + + Status = RtlCreateSecurityDescriptorRelative(SdRel, + SECURITY_DESCRIPTOR_REVISION); + if (!NT_SUCCESS(Status)) { - return Status; + return Status; } - - Current = (ULONG_PTR)(SdRel + 1); - - if (SecurityInformation & OWNER_SECURITY_INFORMATION) + + Current = (ULONG_PTR)(SdRel + 1); + + if (SecurityInformation & OWNER_SECURITY_INFORMATION) { - RtlCopyMemory((PVOID)Current, - SeWorldSid, - SidSize); - SdRel->Owner = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); - Current += SidSize; + RtlCopyMemory((PVOID)Current, + SeWorldSid, + SidSize); + SdRel->Owner = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); + Current += SidSize; } - - if (SecurityInformation & GROUP_SECURITY_INFORMATION) + + if (SecurityInformation & GROUP_SECURITY_INFORMATION) { - RtlCopyMemory((PVOID)Current, - SeWorldSid, - SidSize); - SdRel->Group = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); - Current += SidSize; + RtlCopyMemory((PVOID)Current, + SeWorldSid, + SidSize); + SdRel->Group = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); + Current += SidSize; } - - if (SecurityInformation & DACL_SECURITY_INFORMATION) + + if (SecurityInformation & DACL_SECURITY_INFORMATION) { - PACL Dacl = (PACL)Current; - SdRel->Control |= SE_DACL_PRESENT; - - Status = RtlCreateAcl(Dacl, - sizeof(ACL) + sizeof(ACE) + SidSize, - ACL_REVISION); - if (!NT_SUCCESS(Status)) - return Status; - - Status = RtlAddAccessAllowedAce(Dacl, - ACL_REVISION, - GENERIC_ALL, - SeWorldSid); - if (!NT_SUCCESS(Status)) - return Status; - - SdRel->Dacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); + PACL Dacl = (PACL)Current; + SdRel->Control |= SE_DACL_PRESENT; + + Status = RtlCreateAcl(Dacl, + sizeof(ACL) + sizeof(ACE) + SidSize, + ACL_REVISION); + if (!NT_SUCCESS(Status)) + return Status; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + GENERIC_ALL, + SeWorldSid); + if (!NT_SUCCESS(Status)) + return Status; + + SdRel->Dacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); } - - if (SecurityInformation & SACL_SECURITY_INFORMATION) + + if (SecurityInformation & SACL_SECURITY_INFORMATION) { - /* FIXME - SdRel->Control |= SE_SACL_PRESENT; */ + /* FIXME - SdRel->Control |= SE_SACL_PRESENT; */ } - - return STATUS_SUCCESS; + + return STATUS_SUCCESS; } @@ -219,146 +219,146 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIO OUT PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService, OUT PBOOLEAN Present) { - PSECURITY_QUALITY_OF_SERVICE CapturedQos; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - ASSERT(CapturedSecurityQualityOfService); - ASSERT(Present); - - if(ObjectAttributes != NULL) - { - if(AccessMode != KernelMode) + PSECURITY_QUALITY_OF_SERVICE CapturedQos; + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + ASSERT(CapturedSecurityQualityOfService); + ASSERT(Present); + + if(ObjectAttributes != NULL) { - SECURITY_QUALITY_OF_SERVICE SafeQos; - - _SEH_TRY - { - ProbeForRead(ObjectAttributes, - sizeof(OBJECT_ATTRIBUTES), - sizeof(ULONG)); - if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) + if(AccessMode != KernelMode) { - if(ObjectAttributes->SecurityQualityOfService != NULL) - { - ProbeForRead(ObjectAttributes->SecurityQualityOfService, - sizeof(SECURITY_QUALITY_OF_SERVICE), - sizeof(ULONG)); - - if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == - sizeof(SECURITY_QUALITY_OF_SERVICE)) + SECURITY_QUALITY_OF_SERVICE SafeQos; + + _SEH_TRY { - /* don't allocate memory here because ExAllocate should bugcheck - the system if it's buggy, SEH would catch that! So make a local - copy of the qos structure.*/ - RtlCopyMemory(&SafeQos, - ObjectAttributes->SecurityQualityOfService, - sizeof(SECURITY_QUALITY_OF_SERVICE)); - *Present = TRUE; + ProbeForRead(ObjectAttributes, + sizeof(OBJECT_ATTRIBUTES), + sizeof(ULONG)); + if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) + { + if(ObjectAttributes->SecurityQualityOfService != NULL) + { + ProbeForRead(ObjectAttributes->SecurityQualityOfService, + sizeof(SECURITY_QUALITY_OF_SERVICE), + sizeof(ULONG)); + + if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == + sizeof(SECURITY_QUALITY_OF_SERVICE)) + { + /* don't allocate memory here because ExAllocate should bugcheck + the system if it's buggy, SEH would catch that! So make a local + copy of the qos structure.*/ + RtlCopyMemory(&SafeQos, + ObjectAttributes->SecurityQualityOfService, + sizeof(SECURITY_QUALITY_OF_SERVICE)); + *Present = TRUE; + } + else + { + Status = STATUS_INVALID_PARAMETER; + } + } + else + { + *CapturedSecurityQualityOfService = NULL; + *Present = FALSE; + } + } + else + { + Status = STATUS_INVALID_PARAMETER; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(NT_SUCCESS(Status)) + { + if(*Present) + { + CapturedQos = ExAllocatePool(PoolType, + sizeof(SECURITY_QUALITY_OF_SERVICE)); + if(CapturedQos != NULL) + { + RtlCopyMemory(CapturedQos, + &SafeQos, + sizeof(SECURITY_QUALITY_OF_SERVICE)); + *CapturedSecurityQualityOfService = CapturedQos; + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + } + else + { + *CapturedSecurityQualityOfService = NULL; + } + } + } + else + { + if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) + { + if(CaptureIfKernel) + { + if(ObjectAttributes->SecurityQualityOfService != NULL) + { + if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == + sizeof(SECURITY_QUALITY_OF_SERVICE)) + { + CapturedQos = ExAllocatePool(PoolType, + sizeof(SECURITY_QUALITY_OF_SERVICE)); + if(CapturedQos != NULL) + { + RtlCopyMemory(CapturedQos, + ObjectAttributes->SecurityQualityOfService, + sizeof(SECURITY_QUALITY_OF_SERVICE)); + *CapturedSecurityQualityOfService = CapturedQos; + *Present = TRUE; + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + } + else + { + Status = STATUS_INVALID_PARAMETER; + } + } + else + { + *CapturedSecurityQualityOfService = NULL; + *Present = FALSE; + } + } + else + { + *CapturedSecurityQualityOfService = (PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService; + *Present = (ObjectAttributes->SecurityQualityOfService != NULL); + } } else { - Status = STATUS_INVALID_PARAMETER; + Status = STATUS_INVALID_PARAMETER; } - } - else - { - *CapturedSecurityQualityOfService = NULL; - *Present = FALSE; - } } - else - { - Status = STATUS_INVALID_PARAMETER; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(NT_SUCCESS(Status)) - { - if(*Present) - { - CapturedQos = ExAllocatePool(PoolType, - sizeof(SECURITY_QUALITY_OF_SERVICE)); - if(CapturedQos != NULL) - { - RtlCopyMemory(CapturedQos, - &SafeQos, - sizeof(SECURITY_QUALITY_OF_SERVICE)); - *CapturedSecurityQualityOfService = CapturedQos; - } - else - { - Status = STATUS_INSUFFICIENT_RESOURCES; - } - } - else - { - *CapturedSecurityQualityOfService = NULL; - } - } } else { - if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) - { - if(CaptureIfKernel) - { - if(ObjectAttributes->SecurityQualityOfService != NULL) - { - if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == - sizeof(SECURITY_QUALITY_OF_SERVICE)) - { - CapturedQos = ExAllocatePool(PoolType, - sizeof(SECURITY_QUALITY_OF_SERVICE)); - if(CapturedQos != NULL) - { - RtlCopyMemory(CapturedQos, - ObjectAttributes->SecurityQualityOfService, - sizeof(SECURITY_QUALITY_OF_SERVICE)); - *CapturedSecurityQualityOfService = CapturedQos; - *Present = TRUE; - } - else - { - Status = STATUS_INSUFFICIENT_RESOURCES; - } - } - else - { - Status = STATUS_INVALID_PARAMETER; - } - } - else - { - *CapturedSecurityQualityOfService = NULL; - *Present = FALSE; - } - } - else - { - *CapturedSecurityQualityOfService = (PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService; - *Present = (ObjectAttributes->SecurityQualityOfService != NULL); - } - } - else - { - Status = STATUS_INVALID_PARAMETER; - } + *CapturedSecurityQualityOfService = NULL; + *Present = FALSE; } - } - else - { - *CapturedSecurityQualityOfService = NULL; - *Present = FALSE; - } - - return Status; + + return Status; } @@ -368,353 +368,352 @@ SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecur IN KPROCESSOR_MODE AccessMode, IN BOOLEAN CaptureIfKernel) { - PAGED_CODE(); - - if(CapturedSecurityQualityOfService != NULL && - (AccessMode != KernelMode || CaptureIfKernel)) - { - ExFreePool(CapturedSecurityQualityOfService); - } + PAGED_CODE(); + + if(CapturedSecurityQualityOfService != NULL && + (AccessMode != KernelMode || CaptureIfKernel)) + { + ExFreePool(CapturedSecurityQualityOfService); + } } +/* PUBLIC FUNCTIONS ***********************************************************/ /* * @implemented */ NTSTATUS STDCALL -SeCaptureSecurityDescriptor( - IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, - IN KPROCESSOR_MODE CurrentMode, - IN POOL_TYPE PoolType, - IN BOOLEAN CaptureIfKernel, - OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor - ) +SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, + IN KPROCESSOR_MODE CurrentMode, + IN POOL_TYPE PoolType, + IN BOOLEAN CaptureIfKernel, + OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor) { - PISECURITY_DESCRIPTOR OriginalSecurityDescriptor = _OriginalSecurityDescriptor; - SECURITY_DESCRIPTOR DescriptorCopy; - PISECURITY_DESCRIPTOR NewDescriptor; - ULONG OwnerSAC = 0, GroupSAC = 0; - ULONG OwnerSize = 0, GroupSize = 0; - ULONG SaclSize = 0, DaclSize = 0; - ULONG DescriptorSize = 0; - NTSTATUS Status = STATUS_SUCCESS; - - if(OriginalSecurityDescriptor != NULL) - { - if(CurrentMode != KernelMode) + PISECURITY_DESCRIPTOR OriginalSecurityDescriptor = _OriginalSecurityDescriptor; + SECURITY_DESCRIPTOR DescriptorCopy; + PISECURITY_DESCRIPTOR NewDescriptor; + ULONG OwnerSAC = 0, GroupSAC = 0; + ULONG OwnerSize = 0, GroupSize = 0; + ULONG SaclSize = 0, DaclSize = 0; + ULONG DescriptorSize = 0; + NTSTATUS Status = STATUS_SUCCESS; + + if(OriginalSecurityDescriptor != NULL) { - RtlZeroMemory(&DescriptorCopy, sizeof(DescriptorCopy)); - - _SEH_TRY - { - /* first only probe and copy until the control field of the descriptor - to determine whether it's a self-relative descriptor */ - DescriptorSize = FIELD_OFFSET(SECURITY_DESCRIPTOR, - Owner); - ProbeForRead(OriginalSecurityDescriptor, - DescriptorSize, - sizeof(ULONG)); - - if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) + if(CurrentMode != KernelMode) { - Status = STATUS_UNKNOWN_REVISION; - _SEH_LEAVE; + RtlZeroMemory(&DescriptorCopy, sizeof(DescriptorCopy)); + + _SEH_TRY + { + /* first only probe and copy until the control field of the descriptor + to determine whether it's a self-relative descriptor */ + DescriptorSize = FIELD_OFFSET(SECURITY_DESCRIPTOR, + Owner); + ProbeForRead(OriginalSecurityDescriptor, + DescriptorSize, + sizeof(ULONG)); + + if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) + { + Status = STATUS_UNKNOWN_REVISION; + _SEH_LEAVE; + } + + /* make a copy on the stack */ + DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision; + DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1; + DescriptorCopy.Control = OriginalSecurityDescriptor->Control; + DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ? + sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR)); + + /* probe and copy the entire security descriptor structure. The SIDs + and ACLs will be probed and copied later though */ + ProbeForRead(OriginalSecurityDescriptor, + DescriptorSize, + sizeof(ULONG)); + if(DescriptorCopy.Control & SE_SELF_RELATIVE) + { + PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor; + + DescriptorCopy.Owner = (PSID)RelSD->Owner; + DescriptorCopy.Group = (PSID)RelSD->Group; + DescriptorCopy.Sacl = (PACL)RelSD->Sacl; + DescriptorCopy.Dacl = (PACL)RelSD->Dacl; + } + else + { + DescriptorCopy.Owner = OriginalSecurityDescriptor->Owner; + DescriptorCopy.Group = OriginalSecurityDescriptor->Group; + DescriptorCopy.Sacl = OriginalSecurityDescriptor->Sacl; + DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + return Status; + } } - - /* make a copy on the stack */ - DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision; - DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1; - DescriptorCopy.Control = OriginalSecurityDescriptor->Control; - DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ? - sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR)); - - /* probe and copy the entire security descriptor structure. The SIDs - and ACLs will be probed and copied later though */ - ProbeForRead(OriginalSecurityDescriptor, - DescriptorSize, - sizeof(ULONG)); - if(DescriptorCopy.Control & SE_SELF_RELATIVE) + else if(!CaptureIfKernel) { - PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor; - - DescriptorCopy.Owner = (PSID)RelSD->Owner; - DescriptorCopy.Group = (PSID)RelSD->Group; - DescriptorCopy.Sacl = (PACL)RelSD->Sacl; - DescriptorCopy.Dacl = (PACL)RelSD->Dacl; + if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) + { + return STATUS_UNKNOWN_REVISION; + } + + *CapturedSecurityDescriptor = OriginalSecurityDescriptor; + return STATUS_SUCCESS; } else { - DescriptorCopy.Owner = OriginalSecurityDescriptor->Owner; - DescriptorCopy.Group = OriginalSecurityDescriptor->Group; - DescriptorCopy.Sacl = OriginalSecurityDescriptor->Sacl; - DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl; + if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) + { + return STATUS_UNKNOWN_REVISION; + } + + /* make a copy on the stack */ + DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision; + DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1; + DescriptorCopy.Control = OriginalSecurityDescriptor->Control; + DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ? + sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR)); + if(DescriptorCopy.Control & SE_SELF_RELATIVE) + { + PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor; + + DescriptorCopy.Owner = (PSID)RelSD->Owner; + DescriptorCopy.Group = (PSID)RelSD->Group; + DescriptorCopy.Sacl = (PACL)RelSD->Sacl; + DescriptorCopy.Dacl = (PACL)RelSD->Dacl; + } + else + { + DescriptorCopy.Owner = OriginalSecurityDescriptor->Owner; + DescriptorCopy.Group = OriginalSecurityDescriptor->Group; + DescriptorCopy.Sacl = OriginalSecurityDescriptor->Sacl; + DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl; + } } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(!NT_SUCCESS(Status)) - { - return Status; - } - } - else if(!CaptureIfKernel) - { - if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) - { - return STATUS_UNKNOWN_REVISION; - } - - *CapturedSecurityDescriptor = OriginalSecurityDescriptor; - return STATUS_SUCCESS; - } - else - { - if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) - { - return STATUS_UNKNOWN_REVISION; - } - - /* make a copy on the stack */ - DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision; - DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1; - DescriptorCopy.Control = OriginalSecurityDescriptor->Control; - DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ? - sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR)); - if(DescriptorCopy.Control & SE_SELF_RELATIVE) - { - PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor; - - DescriptorCopy.Owner = (PSID)RelSD->Owner; - DescriptorCopy.Group = (PSID)RelSD->Group; - DescriptorCopy.Sacl = (PACL)RelSD->Sacl; - DescriptorCopy.Dacl = (PACL)RelSD->Dacl; - } - else - { - DescriptorCopy.Owner = OriginalSecurityDescriptor->Owner; - DescriptorCopy.Group = OriginalSecurityDescriptor->Group; - DescriptorCopy.Sacl = OriginalSecurityDescriptor->Sacl; - DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl; - } - } - - if(DescriptorCopy.Control & SE_SELF_RELATIVE) - { - /* in case we're dealing with a self-relative descriptor, do a basic convert - to an absolute descriptor. We do this so we can simply access the data - using the pointers without calculating them again. */ - DescriptorCopy.Control &= ~SE_SELF_RELATIVE; - if(DescriptorCopy.Owner != NULL) - { - DescriptorCopy.Owner = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Owner); - } - if(DescriptorCopy.Group != NULL) - { - DescriptorCopy.Group = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Group); - } - if(DescriptorCopy.Dacl != NULL) - { - DescriptorCopy.Dacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Dacl); - } - if(DescriptorCopy.Sacl != NULL) - { - DescriptorCopy.Sacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Sacl); - } - } - - /* determine the size of the SIDs */ + + if(DescriptorCopy.Control & SE_SELF_RELATIVE) + { + /* in case we're dealing with a self-relative descriptor, do a basic convert + to an absolute descriptor. We do this so we can simply access the data + using the pointers without calculating them again. */ + DescriptorCopy.Control &= ~SE_SELF_RELATIVE; + if(DescriptorCopy.Owner != NULL) + { + DescriptorCopy.Owner = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Owner); + } + if(DescriptorCopy.Group != NULL) + { + DescriptorCopy.Group = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Group); + } + if(DescriptorCopy.Dacl != NULL) + { + DescriptorCopy.Dacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Dacl); + } + if(DescriptorCopy.Sacl != NULL) + { + DescriptorCopy.Sacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Sacl); + } + } + + /* determine the size of the SIDs */ #define DetermineSIDSize(SidType) \ - do { \ - if(DescriptorCopy.SidType != NULL) \ - { \ - SID *SidType = (SID*)DescriptorCopy.SidType; \ - \ - if(CurrentMode != KernelMode) \ - { \ - /* securely access the buffers! */ \ - _SEH_TRY \ - { \ - SidType##SAC = ProbeForReadUchar(&SidType->SubAuthorityCount); \ - SidType##Size = RtlLengthRequiredSid(SidType##SAC); \ - DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \ - ProbeForRead(SidType, \ - SidType##Size, \ - sizeof(ULONG)); \ - } \ - _SEH_HANDLE \ - { \ - Status = _SEH_GetExceptionCode(); \ - } \ - _SEH_END; \ - \ - if(!NT_SUCCESS(Status)) \ - { \ - return Status; \ - } \ - } \ - else \ - { \ - SidType##SAC = SidType->SubAuthorityCount; \ - SidType##Size = RtlLengthRequiredSid(SidType##SAC); \ - DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \ - } \ - } \ - } while(0) - - DetermineSIDSize(Owner); - DetermineSIDSize(Group); - +do { \ +if(DescriptorCopy.SidType != NULL) \ +{ \ +SID *SidType = (SID*)DescriptorCopy.SidType; \ +\ +if(CurrentMode != KernelMode) \ +{ \ +/* securely access the buffers! */ \ +_SEH_TRY \ +{ \ +SidType##SAC = ProbeForReadUchar(&SidType->SubAuthorityCount); \ +SidType##Size = RtlLengthRequiredSid(SidType##SAC); \ +DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \ +ProbeForRead(SidType, \ +SidType##Size, \ +sizeof(ULONG)); \ +} \ +_SEH_HANDLE \ +{ \ +Status = _SEH_GetExceptionCode(); \ +} \ +_SEH_END; \ +\ +if(!NT_SUCCESS(Status)) \ +{ \ +return Status; \ +} \ +} \ +else \ +{ \ +SidType##SAC = SidType->SubAuthorityCount; \ +SidType##Size = RtlLengthRequiredSid(SidType##SAC); \ +DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \ +} \ +} \ +} while(0) + + DetermineSIDSize(Owner); + DetermineSIDSize(Group); + #undef DetermineSIDSize - - /* determine the size of the ACLs */ + + /* determine the size of the ACLs */ #define DetermineACLSize(AclType, AclFlag) \ - do { \ - if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) && \ - DescriptorCopy.AclType != NULL) \ - { \ - PACL AclType = (PACL)DescriptorCopy.AclType; \ - \ - if(CurrentMode != KernelMode) \ - { \ - /* securely access the buffers! */ \ - _SEH_TRY \ - { \ - AclType##Size = ProbeForReadUshort(&AclType->AclSize); \ - DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \ - ProbeForRead(AclType, \ - AclType##Size, \ - sizeof(ULONG)); \ - } \ - _SEH_HANDLE \ - { \ - Status = _SEH_GetExceptionCode(); \ - } \ - _SEH_END; \ - \ - if(!NT_SUCCESS(Status)) \ - { \ - return Status; \ - } \ - } \ - else \ - { \ - AclType##Size = AclType->AclSize; \ - DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \ - } \ - } \ - else \ - { \ - DescriptorCopy.AclType = NULL; \ - } \ - } while(0) - - DetermineACLSize(Sacl, SACL); - DetermineACLSize(Dacl, DACL); - +do { \ +if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) && \ +DescriptorCopy.AclType != NULL) \ +{ \ +PACL AclType = (PACL)DescriptorCopy.AclType; \ +\ +if(CurrentMode != KernelMode) \ +{ \ +/* securely access the buffers! */ \ +_SEH_TRY \ +{ \ +AclType##Size = ProbeForReadUshort(&AclType->AclSize); \ +DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \ +ProbeForRead(AclType, \ +AclType##Size, \ +sizeof(ULONG)); \ +} \ +_SEH_HANDLE \ +{ \ +Status = _SEH_GetExceptionCode(); \ +} \ +_SEH_END; \ +\ +if(!NT_SUCCESS(Status)) \ +{ \ +return Status; \ +} \ +} \ +else \ +{ \ +AclType##Size = AclType->AclSize; \ +DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \ +} \ +} \ +else \ +{ \ +DescriptorCopy.AclType = NULL; \ +} \ +} while(0) + + DetermineACLSize(Sacl, SACL); + DetermineACLSize(Dacl, DACL); + #undef DetermineACLSize - - /* allocate enough memory to store a complete copy of a self-relative - security descriptor */ - NewDescriptor = ExAllocatePool(PoolType, - DescriptorSize); - if(NewDescriptor != NULL) - { - ULONG_PTR Offset = sizeof(SECURITY_DESCRIPTOR); - - RtlZeroMemory(NewDescriptor, DescriptorSize); - NewDescriptor->Revision = DescriptorCopy.Revision; - NewDescriptor->Sbz1 = DescriptorCopy.Sbz1; - NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE; - - _SEH_TRY - { - /* setup the offsets and copy the SIDs and ACLs to the new - self-relative security descriptor. Probing the pointers is not - neccessary anymore as we did that when collecting the sizes! - Make sure to validate the SIDs and ACLs *again* as they could have - been modified in the meanwhile! */ + + /* allocate enough memory to store a complete copy of a self-relative + security descriptor */ + NewDescriptor = ExAllocatePool(PoolType, + DescriptorSize); + if(NewDescriptor != NULL) + { + ULONG_PTR Offset = sizeof(SECURITY_DESCRIPTOR); + + RtlZeroMemory(NewDescriptor, DescriptorSize); + NewDescriptor->Revision = DescriptorCopy.Revision; + NewDescriptor->Sbz1 = DescriptorCopy.Sbz1; + NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE; + + _SEH_TRY + { + /* setup the offsets and copy the SIDs and ACLs to the new + self-relative security descriptor. Probing the pointers is not + neccessary anymore as we did that when collecting the sizes! + Make sure to validate the SIDs and ACLs *again* as they could have + been modified in the meanwhile! */ #define CopySID(Type) \ - do { \ - if(DescriptorCopy.Type != NULL) \ - { \ - NewDescriptor->Type = (PVOID)Offset; \ - RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \ - (ULONG_PTR)NewDescriptor->Type), \ - DescriptorCopy.Type, \ - Type##Size); \ - if (!RtlValidSid((PSID)((ULONG_PTR)NewDescriptor + \ - (ULONG_PTR)NewDescriptor->Type))) \ - { \ - RtlRaiseStatus(STATUS_INVALID_SID); \ - } \ - Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \ - } \ - } while(0) - - CopySID(Owner); - CopySID(Group); - +do { \ +if(DescriptorCopy.Type != NULL) \ +{ \ +NewDescriptor->Type = (PVOID)Offset; \ +RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \ +(ULONG_PTR)NewDescriptor->Type), \ +DescriptorCopy.Type, \ +Type##Size); \ +if (!RtlValidSid((PSID)((ULONG_PTR)NewDescriptor + \ +(ULONG_PTR)NewDescriptor->Type))) \ +{ \ +RtlRaiseStatus(STATUS_INVALID_SID); \ +} \ +Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \ +} \ +} while(0) + + CopySID(Owner); + CopySID(Group); + #undef CopySID - + #define CopyACL(Type) \ - do { \ - if(DescriptorCopy.Type != NULL) \ - { \ - NewDescriptor->Type = (PVOID)Offset; \ - RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \ - (ULONG_PTR)NewDescriptor->Type), \ - DescriptorCopy.Type, \ - Type##Size); \ - if (!RtlValidAcl((PACL)((ULONG_PTR)NewDescriptor + \ - (ULONG_PTR)NewDescriptor->Type))) \ - { \ - RtlRaiseStatus(STATUS_INVALID_ACL); \ - } \ - Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \ - } \ - } while(0) - - CopyACL(Sacl); - CopyACL(Dacl); - +do { \ +if(DescriptorCopy.Type != NULL) \ +{ \ +NewDescriptor->Type = (PVOID)Offset; \ +RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \ +(ULONG_PTR)NewDescriptor->Type), \ +DescriptorCopy.Type, \ +Type##Size); \ +if (!RtlValidAcl((PACL)((ULONG_PTR)NewDescriptor + \ +(ULONG_PTR)NewDescriptor->Type))) \ +{ \ +RtlRaiseStatus(STATUS_INVALID_ACL); \ +} \ +Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \ +} \ +} while(0) + + CopyACL(Sacl); + CopyACL(Dacl); + #undef CopyACL - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(NT_SUCCESS(Status)) - { - /* we're finally done! copy the pointer to the captured descriptor to - to the caller */ - *CapturedSecurityDescriptor = NewDescriptor; - return STATUS_SUCCESS; - } - else - { - /* we failed to copy the data to the new descriptor */ - ExFreePool(NewDescriptor); - } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(NT_SUCCESS(Status)) + { + /* we're finally done! copy the pointer to the captured descriptor to + to the caller */ + *CapturedSecurityDescriptor = NewDescriptor; + return STATUS_SUCCESS; + } + else + { + /* we failed to copy the data to the new descriptor */ + ExFreePool(NewDescriptor); + } + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } } else { - Status = STATUS_INSUFFICIENT_RESOURCES; + /* nothing to do... */ + *CapturedSecurityDescriptor = NULL; } - } - else - { - /* nothing to do... */ - *CapturedSecurityDescriptor = NULL; - } - - return Status; + + return Status; } /* @@ -722,136 +721,136 @@ SeCaptureSecurityDescriptor( */ NTSTATUS STDCALL SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, - IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, - IN OUT PULONG Length, - IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor OPTIONAL) + IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, + IN OUT PULONG Length, + IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor OPTIONAL) { - PISECURITY_DESCRIPTOR ObjectSd; - PISECURITY_DESCRIPTOR_RELATIVE RelSD; - PSID Owner = NULL; - PSID Group = NULL; - PACL Dacl = NULL; - PACL Sacl = NULL; - ULONG OwnerLength = 0; - ULONG GroupLength = 0; - ULONG DaclLength = 0; - ULONG SaclLength = 0; - ULONG Control = 0; - ULONG_PTR Current; - ULONG SdLength; - - RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor; - - if (*ObjectsSecurityDescriptor == NULL) + PISECURITY_DESCRIPTOR ObjectSd; + PISECURITY_DESCRIPTOR_RELATIVE RelSD; + PSID Owner = NULL; + PSID Group = NULL; + PACL Dacl = NULL; + PACL Sacl = NULL; + ULONG OwnerLength = 0; + ULONG GroupLength = 0; + ULONG DaclLength = 0; + ULONG SaclLength = 0; + ULONG Control = 0; + ULONG_PTR Current; + ULONG SdLength; + + RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor; + + if (*ObjectsSecurityDescriptor == NULL) { - if (*Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE)) - { - *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE); - return STATUS_BUFFER_TOO_SMALL; - } - - *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE); - RtlCreateSecurityDescriptorRelative(RelSD, - SECURITY_DESCRIPTOR_REVISION); - return STATUS_SUCCESS; + if (*Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE)) + { + *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE); + return STATUS_BUFFER_TOO_SMALL; + } + + *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE); + RtlCreateSecurityDescriptorRelative(RelSD, + SECURITY_DESCRIPTOR_REVISION); + return STATUS_SUCCESS; } - - ObjectSd = *ObjectsSecurityDescriptor; - - /* Calculate the required security descriptor length */ - Control = SE_SELF_RELATIVE; - if ((*SecurityInformation & OWNER_SECURITY_INFORMATION) && - (ObjectSd->Owner != NULL)) + + ObjectSd = *ObjectsSecurityDescriptor; + + /* Calculate the required security descriptor length */ + Control = SE_SELF_RELATIVE; + if ((*SecurityInformation & OWNER_SECURITY_INFORMATION) && + (ObjectSd->Owner != NULL)) { - Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd); - OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); - Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED); + Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd); + OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); + Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED); } - - if ((*SecurityInformation & GROUP_SECURITY_INFORMATION) && - (ObjectSd->Group != NULL)) + + if ((*SecurityInformation & GROUP_SECURITY_INFORMATION) && + (ObjectSd->Group != NULL)) { - Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd); - GroupLength = ROUND_UP(RtlLengthSid(Group), 4); - Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED); + Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd); + GroupLength = ROUND_UP(RtlLengthSid(Group), 4); + Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED); } - - if ((*SecurityInformation & DACL_SECURITY_INFORMATION) && - (ObjectSd->Control & SE_DACL_PRESENT)) + + if ((*SecurityInformation & DACL_SECURITY_INFORMATION) && + (ObjectSd->Control & SE_DACL_PRESENT)) { - if (ObjectSd->Dacl != NULL) - { - Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd); - DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4); - } - Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT)); + if (ObjectSd->Dacl != NULL) + { + Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd); + DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4); + } + Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT)); } - - if ((*SecurityInformation & SACL_SECURITY_INFORMATION) && - (ObjectSd->Control & SE_SACL_PRESENT)) + + if ((*SecurityInformation & SACL_SECURITY_INFORMATION) && + (ObjectSd->Control & SE_SACL_PRESENT)) { - if (ObjectSd->Sacl != NULL) - { - Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd); - SaclLength = ROUND_UP(Sacl->AclSize, 4); - } - Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT)); + if (ObjectSd->Sacl != NULL) + { + Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd); + SaclLength = ROUND_UP(Sacl->AclSize, 4); + } + Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT)); } - - SdLength = OwnerLength + GroupLength + DaclLength + - SaclLength + sizeof(SECURITY_DESCRIPTOR_RELATIVE); - if (*Length < SdLength) + + SdLength = OwnerLength + GroupLength + DaclLength + + SaclLength + sizeof(SECURITY_DESCRIPTOR_RELATIVE); + if (*Length < SdLength) { - *Length = SdLength; - return STATUS_BUFFER_TOO_SMALL; + *Length = SdLength; + return STATUS_BUFFER_TOO_SMALL; } - - /* Build the new security descrtiptor */ - RtlCreateSecurityDescriptorRelative(RelSD, - SECURITY_DESCRIPTOR_REVISION); - RelSD->Control = (USHORT)Control; - - Current = (ULONG_PTR)(RelSD + 1); - - if (OwnerLength != 0) + + /* Build the new security descrtiptor */ + RtlCreateSecurityDescriptorRelative(RelSD, + SECURITY_DESCRIPTOR_REVISION); + RelSD->Control = (USHORT)Control; + + Current = (ULONG_PTR)(RelSD + 1); + + if (OwnerLength != 0) { - RtlCopyMemory((PVOID)Current, - Owner, - OwnerLength); - RelSD->Owner = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); - Current += OwnerLength; + RtlCopyMemory((PVOID)Current, + Owner, + OwnerLength); + RelSD->Owner = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); + Current += OwnerLength; } - - if (GroupLength != 0) + + if (GroupLength != 0) { - RtlCopyMemory((PVOID)Current, - Group, - GroupLength); - RelSD->Group = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); - Current += GroupLength; + RtlCopyMemory((PVOID)Current, + Group, + GroupLength); + RelSD->Group = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); + Current += GroupLength; } - - if (DaclLength != 0) + + if (DaclLength != 0) { - RtlCopyMemory((PVOID)Current, - Dacl, - DaclLength); - RelSD->Dacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); - Current += DaclLength; + RtlCopyMemory((PVOID)Current, + Dacl, + DaclLength); + RelSD->Dacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); + Current += DaclLength; } - - if (SaclLength != 0) + + if (SaclLength != 0) { - RtlCopyMemory((PVOID)Current, - Sacl, - SaclLength); - RelSD->Sacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); - Current += SaclLength; + RtlCopyMemory((PVOID)Current, + Sacl, + SaclLength); + RelSD->Sacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); + Current += SaclLength; } - - *Length = SdLength; - - return STATUS_SUCCESS; + + *Length = SdLength; + + return STATUS_SUCCESS; } /* @@ -859,26 +858,24 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, */ NTSTATUS STDCALL -SeReleaseSecurityDescriptor( - IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, - IN KPROCESSOR_MODE CurrentMode, - IN BOOLEAN CaptureIfKernelMode - ) +SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, + IN KPROCESSOR_MODE CurrentMode, + IN BOOLEAN CaptureIfKernelMode) { - PAGED_CODE(); - - /* WARNING! You need to call this function with the same value for CurrentMode - and CaptureIfKernelMode that you previously passed to - SeCaptureSecurityDescriptor() in order to avoid memory leaks! */ - if(CapturedSecurityDescriptor != NULL && - (CurrentMode != KernelMode || - (CurrentMode == KernelMode && CaptureIfKernelMode))) - { - /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */ - ExFreePool(CapturedSecurityDescriptor); - } - - return STATUS_SUCCESS; + PAGED_CODE(); + + /* WARNING! You need to call this function with the same value for CurrentMode + and CaptureIfKernelMode that you previously passed to + SeCaptureSecurityDescriptor() in order to avoid memory leaks! */ + if(CapturedSecurityDescriptor != NULL && + (CurrentMode != KernelMode || + (CurrentMode == KernelMode && CaptureIfKernelMode))) + { + /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */ + ExFreePool(CapturedSecurityDescriptor); + } + + return STATUS_SUCCESS; } /* @@ -906,7 +903,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, ULONG Control = 0; ULONG_PTR Current; SECURITY_INFORMATION SecurityInformation; - + ObjectSd = *ObjectsSecurityDescriptor; if (!ObjectSd) @@ -1076,21 +1073,19 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, */ NTSTATUS STDCALL -SeSetSecurityDescriptorInfoEx( - IN PVOID Object OPTIONAL, - IN PSECURITY_INFORMATION SecurityInformation, - IN PSECURITY_DESCRIPTOR ModificationDescriptor, - IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor, - IN ULONG AutoInheritFlags, - IN POOL_TYPE PoolType, - IN PGENERIC_MAPPING GenericMapping - ) +SeSetSecurityDescriptorInfoEx(IN PVOID Object OPTIONAL, + IN PSECURITY_INFORMATION SecurityInformation, + IN PSECURITY_DESCRIPTOR ModificationDescriptor, + IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor, + IN ULONG AutoInheritFlags, + IN POOL_TYPE PoolType, + IN PGENERIC_MAPPING GenericMapping) { PISECURITY_DESCRIPTOR ObjectSd = *ObjectsSecurityDescriptor; if (!ObjectSd) return STATUS_NO_SECURITY_ON_OBJECT; // The object does not have a security descriptor. - + UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; } @@ -1101,135 +1096,424 @@ SeSetSecurityDescriptorInfoEx( */ BOOLEAN STDCALL SeValidSecurityDescriptor(IN ULONG Length, - IN PSECURITY_DESCRIPTOR _SecurityDescriptor) + IN PSECURITY_DESCRIPTOR _SecurityDescriptor) { - ULONG SdLength; - PISID Sid; - PACL Acl; - PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor; - - if (Length < SECURITY_DESCRIPTOR_MIN_LENGTH) + ULONG SdLength; + PISID Sid; + PACL Acl; + PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor; + + if (Length < SECURITY_DESCRIPTOR_MIN_LENGTH) { - DPRINT1("Invalid Security Descriptor revision\n"); - return FALSE; + DPRINT1("Invalid Security Descriptor revision\n"); + return FALSE; } - - if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) + + if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) { - DPRINT1("Invalid Security Descriptor revision\n"); - return FALSE; + DPRINT1("Invalid Security Descriptor revision\n"); + return FALSE; } - - if (!(SecurityDescriptor->Control & SE_SELF_RELATIVE)) + + if (!(SecurityDescriptor->Control & SE_SELF_RELATIVE)) { - DPRINT1("No self-relative Security Descriptor\n"); - return FALSE; + DPRINT1("No self-relative Security Descriptor\n"); + return FALSE; } - - SdLength = sizeof(SECURITY_DESCRIPTOR); - - /* Check Owner SID */ - if (SecurityDescriptor->Owner == NULL) + + SdLength = sizeof(SECURITY_DESCRIPTOR); + + /* Check Owner SID */ + if (SecurityDescriptor->Owner == NULL) { - DPRINT1("No Owner SID\n"); - return FALSE; + DPRINT1("No Owner SID\n"); + return FALSE; } - - if ((ULONG_PTR)SecurityDescriptor->Owner % sizeof(ULONG)) + + if ((ULONG_PTR)SecurityDescriptor->Owner % sizeof(ULONG)) { - DPRINT1("Invalid Owner SID alignment\n"); - return FALSE; + DPRINT1("Invalid Owner SID alignment\n"); + return FALSE; } - - Sid = (PISID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Owner); - if (Sid->Revision != SID_REVISION) + + Sid = (PISID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Owner); + if (Sid->Revision != SID_REVISION) { - DPRINT1("Invalid Owner SID revision\n"); - return FALSE; + DPRINT1("Invalid Owner SID revision\n"); + return FALSE; } - - SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG)); - if (Length < SdLength) + + SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG)); + if (Length < SdLength) { - DPRINT1("Invalid Owner SID size\n"); - return FALSE; + DPRINT1("Invalid Owner SID size\n"); + return FALSE; } - - /* Check Group SID */ - if (SecurityDescriptor->Group != NULL) + + /* Check Group SID */ + if (SecurityDescriptor->Group != NULL) { - if ((ULONG_PTR)SecurityDescriptor->Group % sizeof(ULONG)) - { - DPRINT1("Invalid Group SID alignment\n"); - return FALSE; - } - - Sid = (PSID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Group); - if (Sid->Revision != SID_REVISION) - { - DPRINT1("Invalid Group SID revision\n"); - return FALSE; - } - - SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG)); - if (Length < SdLength) - { - DPRINT1("Invalid Group SID size\n"); - return FALSE; - } + if ((ULONG_PTR)SecurityDescriptor->Group % sizeof(ULONG)) + { + DPRINT1("Invalid Group SID alignment\n"); + return FALSE; + } + + Sid = (PSID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Group); + if (Sid->Revision != SID_REVISION) + { + DPRINT1("Invalid Group SID revision\n"); + return FALSE; + } + + SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG)); + if (Length < SdLength) + { + DPRINT1("Invalid Group SID size\n"); + return FALSE; + } } - - /* Check DACL */ - if (SecurityDescriptor->Dacl != NULL) + + /* Check DACL */ + if (SecurityDescriptor->Dacl != NULL) { - if ((ULONG_PTR)SecurityDescriptor->Dacl % sizeof(ULONG)) - { - DPRINT1("Invalid DACL alignment\n"); - return FALSE; - } - - Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Dacl); - if ((Acl->AclRevision < MIN_ACL_REVISION) && - (Acl->AclRevision > MAX_ACL_REVISION)) - { - DPRINT1("Invalid DACL revision\n"); - return FALSE; - } - - SdLength += Acl->AclSize; - if (Length < SdLength) - { - DPRINT1("Invalid DACL size\n"); - return FALSE; - } + if ((ULONG_PTR)SecurityDescriptor->Dacl % sizeof(ULONG)) + { + DPRINT1("Invalid DACL alignment\n"); + return FALSE; + } + + Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Dacl); + if ((Acl->AclRevision < MIN_ACL_REVISION) && + (Acl->AclRevision > MAX_ACL_REVISION)) + { + DPRINT1("Invalid DACL revision\n"); + return FALSE; + } + + SdLength += Acl->AclSize; + if (Length < SdLength) + { + DPRINT1("Invalid DACL size\n"); + return FALSE; + } } - - /* Check SACL */ - if (SecurityDescriptor->Sacl != NULL) + + /* Check SACL */ + if (SecurityDescriptor->Sacl != NULL) { - if ((ULONG_PTR)SecurityDescriptor->Sacl % sizeof(ULONG)) - { - DPRINT1("Invalid SACL alignment\n"); - return FALSE; - } - - Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Sacl); - if ((Acl->AclRevision < MIN_ACL_REVISION) || - (Acl->AclRevision > MAX_ACL_REVISION)) - { - DPRINT1("Invalid SACL revision\n"); - return FALSE; - } - - SdLength += Acl->AclSize; - if (Length < SdLength) - { - DPRINT1("Invalid SACL size\n"); - return FALSE; - } + if ((ULONG_PTR)SecurityDescriptor->Sacl % sizeof(ULONG)) + { + DPRINT1("Invalid SACL alignment\n"); + return FALSE; + } + + Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Sacl); + if ((Acl->AclRevision < MIN_ACL_REVISION) || + (Acl->AclRevision > MAX_ACL_REVISION)) + { + DPRINT1("Invalid SACL revision\n"); + return FALSE; + } + + SdLength += Acl->AclSize; + if (Length < SdLength) + { + DPRINT1("Invalid SACL size\n"); + return FALSE; + } } + + return TRUE; +} - return TRUE; +/* + * @implemented + */ +NTSTATUS STDCALL +SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor) +{ + PAGED_CODE(); + + if (*SecurityDescriptor != NULL) + { + ExFreePool(*SecurityDescriptor); + *SecurityDescriptor = NULL; + } + + return STATUS_SUCCESS; +} + + +/* + * @unimplemented + */ +NTSTATUS STDCALL +SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, + IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL, + OUT PSECURITY_DESCRIPTOR *NewDescriptor, + IN GUID *ObjectType OPTIONAL, + IN BOOLEAN IsDirectoryObject, + IN ULONG AutoInheritFlags, + IN PSECURITY_SUBJECT_CONTEXT SubjectContext, + IN PGENERIC_MAPPING GenericMapping, + IN POOL_TYPE PoolType) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @implemented + */ +NTSTATUS STDCALL +SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, + PSECURITY_DESCRIPTOR _ExplicitDescriptor OPTIONAL, + PSECURITY_DESCRIPTOR *NewDescriptor, + BOOLEAN IsDirectoryObject, + PSECURITY_SUBJECT_CONTEXT SubjectContext, + PGENERIC_MAPPING GenericMapping, + POOL_TYPE PoolType) +{ + PISECURITY_DESCRIPTOR ParentDescriptor = _ParentDescriptor; + PISECURITY_DESCRIPTOR ExplicitDescriptor = _ExplicitDescriptor; + PISECURITY_DESCRIPTOR Descriptor; + PTOKEN Token; + ULONG OwnerLength = 0; + ULONG GroupLength = 0; + ULONG DaclLength = 0; + ULONG SaclLength = 0; + ULONG Length = 0; + ULONG Control = 0; + ULONG_PTR Current; + PSID Owner = NULL; + PSID Group = NULL; + PACL Dacl = NULL; + PACL Sacl = NULL; + + PAGED_CODE(); + + /* Lock subject context */ + SeLockSubjectContext(SubjectContext); + + if (SubjectContext->ClientToken != NULL) + { + Token = SubjectContext->ClientToken; + } + else + { + Token = SubjectContext->PrimaryToken; + } + + + /* Inherit the Owner SID */ + if (ExplicitDescriptor != NULL && ExplicitDescriptor->Owner != NULL) + { + DPRINT("Use explicit owner sid!\n"); + Owner = ExplicitDescriptor->Owner; + + if (ExplicitDescriptor->Control & SE_SELF_RELATIVE) + { + Owner = (PSID)(((ULONG_PTR)Owner) + (ULONG_PTR)ExplicitDescriptor); + + } + } + else + { + if (Token != NULL) + { + DPRINT("Use token owner sid!\n"); + Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid; + } + else + { + DPRINT("Use default owner sid!\n"); + Owner = SeLocalSystemSid; + } + + Control |= SE_OWNER_DEFAULTED; + } + + OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); + + + /* Inherit the Group SID */ + if (ExplicitDescriptor != NULL && ExplicitDescriptor->Group != NULL) + { + DPRINT("Use explicit group sid!\n"); + Group = ExplicitDescriptor->Group; + if (ExplicitDescriptor->Control & SE_SELF_RELATIVE) + { + Group = (PSID)(((ULONG_PTR)Group) + (ULONG_PTR)ExplicitDescriptor); + } + } + else + { + if (Token != NULL) + { + DPRINT("Use token group sid!\n"); + Group = Token->PrimaryGroup; + } + else + { + DPRINT("Use default group sid!\n"); + Group = SeLocalSystemSid; + } + + Control |= SE_OWNER_DEFAULTED; + } + + GroupLength = ROUND_UP(RtlLengthSid(Group), 4); + + + /* Inherit the DACL */ + if (ExplicitDescriptor != NULL && + (ExplicitDescriptor->Control & SE_DACL_PRESENT) && + !(ExplicitDescriptor->Control & SE_DACL_DEFAULTED)) + { + DPRINT("Use explicit DACL!\n"); + Dacl = ExplicitDescriptor->Dacl; + if (Dacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE)) + { + Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ExplicitDescriptor); + } + + Control |= SE_DACL_PRESENT; + } + else if (ParentDescriptor != NULL && + (ParentDescriptor->Control & SE_DACL_PRESENT)) + { + DPRINT("Use parent DACL!\n"); + /* FIXME: Inherit */ + Dacl = ParentDescriptor->Dacl; + if (Dacl != NULL && (ParentDescriptor->Control & SE_SELF_RELATIVE)) + { + Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ParentDescriptor); + } + Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED); + } + else if (Token != NULL && Token->DefaultDacl != NULL) + { + DPRINT("Use token default DACL!\n"); + /* FIXME: Inherit */ + Dacl = Token->DefaultDacl; + Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED); + } + else + { + DPRINT("Use NULL DACL!\n"); + Dacl = NULL; + Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED); + } + + DaclLength = (Dacl != NULL) ? ROUND_UP(Dacl->AclSize, 4) : 0; + + + /* Inherit the SACL */ + if (ExplicitDescriptor != NULL && + (ExplicitDescriptor->Control & SE_SACL_PRESENT) && + !(ExplicitDescriptor->Control & SE_SACL_DEFAULTED)) + { + DPRINT("Use explicit SACL!\n"); + Sacl = ExplicitDescriptor->Sacl; + if (Sacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE)) + { + Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ExplicitDescriptor); + } + + Control |= SE_SACL_PRESENT; + } + else if (ParentDescriptor != NULL && + (ParentDescriptor->Control & SE_SACL_PRESENT)) + { + DPRINT("Use parent SACL!\n"); + /* FIXME: Inherit */ + Sacl = ParentDescriptor->Sacl; + if (Sacl != NULL && (ParentDescriptor->Control & SE_SELF_RELATIVE)) + { + Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ParentDescriptor); + } + Control |= (SE_SACL_PRESENT | SE_SACL_DEFAULTED); + } + + SaclLength = (Sacl != NULL) ? ROUND_UP(Sacl->AclSize, 4) : 0; + + + /* Allocate and initialize the new security descriptor */ + Length = sizeof(SECURITY_DESCRIPTOR) + + OwnerLength + GroupLength + DaclLength + SaclLength; + + DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n", + sizeof(SECURITY_DESCRIPTOR), + OwnerLength, + GroupLength, + DaclLength, + SaclLength); + + Descriptor = ExAllocatePool(PagedPool, + Length); + if (Descriptor == NULL) + { + DPRINT1("ExAlloctePool() failed\n"); + /* FIXME: Unlock subject context */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory( Descriptor, Length ); + RtlCreateSecurityDescriptor(Descriptor, + SECURITY_DESCRIPTOR_REVISION); + + Descriptor->Control = (USHORT)Control | SE_SELF_RELATIVE; + + Current = (ULONG_PTR)Descriptor + sizeof(SECURITY_DESCRIPTOR); + + if (SaclLength != 0) + { + RtlCopyMemory((PVOID)Current, + Sacl, + SaclLength); + Descriptor->Sacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor); + Current += SaclLength; + } + + if (DaclLength != 0) + { + RtlCopyMemory((PVOID)Current, + Dacl, + DaclLength); + Descriptor->Dacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor); + Current += DaclLength; + } + + if (OwnerLength != 0) + { + RtlCopyMemory((PVOID)Current, + Owner, + OwnerLength); + Descriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor); + Current += OwnerLength; + DPRINT("Owner of %x at %x\n", Descriptor, Descriptor->Owner); + } + else + DPRINT("Owner of %x is zero length\n", Descriptor); + + if (GroupLength != 0) + { + memmove((PVOID)Current, + Group, + GroupLength); + Descriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor); + } + + /* Unlock subject context */ + SeUnlockSubjectContext(SubjectContext); + + *NewDescriptor = Descriptor; + + DPRINT("Descrptor %x\n", Descriptor); + ASSERT(RtlLengthSecurityDescriptor(Descriptor)); + + return STATUS_SUCCESS; } /* EOF */ diff --git a/reactos/ntoskrnl/se/semgr.c b/reactos/ntoskrnl/se/semgr.c index 137851d9692..262723b811d 100644 --- a/reactos/ntoskrnl/se/semgr.c +++ b/reactos/ntoskrnl/se/semgr.c @@ -7,49 +7,103 @@ * PROGRAMMERS: No programmer listed. */ -/* INCLUDES *****************************************************************/ +/* INCLUDES *******************************************************************/ #include #define NDEBUG -#include +#include -/* GLOBALS ******************************************************************/ +/* GLOBALS ********************************************************************/ PSE_EXPORTS SeExports = NULL; SE_EXPORTS SepExports; -static ERESOURCE SepSubjectContextLock; extern ULONG ExpInitializationPhase; +extern ERESOURCE SepSubjectContextLock; +/* PRIVATE FUNCTIONS **********************************************************/ -/* PROTOTYPES ***************************************************************/ +static BOOLEAN INIT_FUNCTION +SepInitExports(VOID) +{ + SepExports.SeCreateTokenPrivilege = SeCreateTokenPrivilege; + SepExports.SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege; + SepExports.SeLockMemoryPrivilege = SeLockMemoryPrivilege; + SepExports.SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege; + SepExports.SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege; + SepExports.SeTcbPrivilege = SeTcbPrivilege; + SepExports.SeSecurityPrivilege = SeSecurityPrivilege; + SepExports.SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege; + SepExports.SeLoadDriverPrivilege = SeLoadDriverPrivilege; + SepExports.SeCreatePagefilePrivilege = SeCreatePagefilePrivilege; + SepExports.SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege; + SepExports.SeSystemProfilePrivilege = SeSystemProfilePrivilege; + SepExports.SeSystemtimePrivilege = SeSystemtimePrivilege; + SepExports.SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege; + SepExports.SeCreatePermanentPrivilege = SeCreatePermanentPrivilege; + SepExports.SeBackupPrivilege = SeBackupPrivilege; + SepExports.SeRestorePrivilege = SeRestorePrivilege; + SepExports.SeShutdownPrivilege = SeShutdownPrivilege; + SepExports.SeDebugPrivilege = SeDebugPrivilege; + SepExports.SeAuditPrivilege = SeAuditPrivilege; + SepExports.SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege; + SepExports.SeChangeNotifyPrivilege = SeChangeNotifyPrivilege; + SepExports.SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege; + + SepExports.SeNullSid = SeNullSid; + SepExports.SeWorldSid = SeWorldSid; + SepExports.SeLocalSid = SeLocalSid; + SepExports.SeCreatorOwnerSid = SeCreatorOwnerSid; + SepExports.SeCreatorGroupSid = SeCreatorGroupSid; + SepExports.SeNtAuthoritySid = SeNtAuthoritySid; + SepExports.SeDialupSid = SeDialupSid; + SepExports.SeNetworkSid = SeNetworkSid; + SepExports.SeBatchSid = SeBatchSid; + SepExports.SeInteractiveSid = SeInteractiveSid; + SepExports.SeLocalSystemSid = SeLocalSystemSid; + SepExports.SeAliasAdminsSid = SeAliasAdminsSid; + SepExports.SeAliasUsersSid = SeAliasUsersSid; + SepExports.SeAliasGuestsSid = SeAliasGuestsSid; + SepExports.SeAliasPowerUsersSid = SeAliasPowerUsersSid; + SepExports.SeAliasAccountOpsSid = SeAliasAccountOpsSid; + SepExports.SeAliasSystemOpsSid = SeAliasSystemOpsSid; + SepExports.SeAliasPrintOpsSid = SeAliasPrintOpsSid; + SepExports.SeAliasBackupOpsSid = SeAliasBackupOpsSid; + SepExports.SeAuthenticatedUsersSid = SeAuthenticatedUsersSid; + SepExports.SeRestrictedSid = SeRestrictedSid; + SepExports.SeAnonymousLogonSid = SeAnonymousLogonSid; + + SepExports.SeUndockPrivilege = SeUndockPrivilege; + SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege; + SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege; + + SeExports = &SepExports; + return TRUE; +} -static BOOLEAN SepInitExports(VOID); - -/* FUNCTIONS ****************************************************************/ BOOLEAN NTAPI SepInitializationPhase0(VOID) { - SepInitLuid(); + ExpInitLuid(); if (!SepInitSecurityIDs()) return FALSE; if (!SepInitDACLs()) return FALSE; if (!SepInitSDs()) return FALSE; SepInitPrivileges(); if (!SepInitExports()) return FALSE; - + /* Initialize the subject context lock */ ExInitializeResource(&SepSubjectContextLock); - + /* Initialize token objects */ SepInitializeTokenImplementation(); - + /* Clear impersonation info for the idle thread */ PsGetCurrentThread()->ImpersonationInfo = NULL; PspClearCrossThreadFlag(PsGetCurrentThread(), CT_ACTIVE_IMPERSONATION_INFO_BIT); - + /* Initialize the boot token */ ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL); ObInitializeFastReference(&PsGetCurrentProcess()->Token, @@ -63,7 +117,7 @@ SepInitializationPhase1(VOID) { NTSTATUS Status; PAGED_CODE(); - + /* Insert the system token into the tree */ Status = ObInsertObject((PVOID)(PsGetCurrentProcess()->Token.Value & ~MAX_FAST_REFS), @@ -73,7 +127,7 @@ SepInitializationPhase1(VOID) NULL, NULL); ASSERT(NT_SUCCESS(Status)); - + /* FIXME: TODO \\ Security directory */ return TRUE; } @@ -85,25 +139,25 @@ SeInit(VOID) /* Check the initialization phase */ switch (ExpInitializationPhase) { - case 0: - - /* Do Phase 0 */ - return SepInitializationPhase0(); - - case 1: - - /* Do Phase 1 */ - return SepInitializationPhase1(); - - default: - - /* Don't know any other phase! Bugcheck! */ - KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL, - 0, - ExpInitializationPhase, - 0, - 0); - return FALSE; + case 0: + + /* Do Phase 0 */ + return SepInitializationPhase0(); + + case 1: + + /* Do Phase 1 */ + return SepInitializationPhase1(); + + default: + + /* Don't know any other phase! Bugcheck! */ + KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL, + 0, + ExpInitializationPhase, + 0, + 0); + return FALSE; } } @@ -111,125 +165,55 @@ BOOLEAN NTAPI SeInitSRM(VOID) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING Name; - HANDLE DirectoryHandle; - HANDLE EventHandle; - NTSTATUS Status; - - /* Create '\Security' directory */ - RtlInitUnicodeString(&Name, - L"\\Security"); - InitializeObjectAttributes(&ObjectAttributes, - &Name, - OBJ_PERMANENT, - 0, - NULL); - Status = ZwCreateDirectoryObject(&DirectoryHandle, - DIRECTORY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING Name; + HANDLE DirectoryHandle; + HANDLE EventHandle; + NTSTATUS Status; + + /* Create '\Security' directory */ + RtlInitUnicodeString(&Name, + L"\\Security"); + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_PERMANENT, + 0, + NULL); + Status = ZwCreateDirectoryObject(&DirectoryHandle, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to create 'Security' directory!\n"); - return FALSE; + DPRINT1("Failed to create 'Security' directory!\n"); + return FALSE; } - - /* Create 'LSA_AUTHENTICATION_INITALIZED' event */ - RtlInitUnicodeString(&Name, - L"\\LSA_AUTHENTICATION_INITALIZED"); - InitializeObjectAttributes(&ObjectAttributes, - &Name, - OBJ_PERMANENT, - DirectoryHandle, - SePublicDefaultSd); - Status = ZwCreateEvent(&EventHandle, - EVENT_ALL_ACCESS, - &ObjectAttributes, - SynchronizationEvent, - FALSE); - if (!NT_SUCCESS(Status)) + + /* Create 'LSA_AUTHENTICATION_INITALIZED' event */ + RtlInitUnicodeString(&Name, + L"\\LSA_AUTHENTICATION_INITALIZED"); + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_PERMANENT, + DirectoryHandle, + SePublicDefaultSd); + Status = ZwCreateEvent(&EventHandle, + EVENT_ALL_ACCESS, + &ObjectAttributes, + SynchronizationEvent, + FALSE); + if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n"); - NtClose(DirectoryHandle); - return FALSE; + DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n"); + NtClose(DirectoryHandle); + return FALSE; } - - ZwClose(EventHandle); - ZwClose(DirectoryHandle); - - /* FIXME: Create SRM port and listener thread */ - - return TRUE; -} - - -static BOOLEAN INIT_FUNCTION -SepInitExports(VOID) -{ - SepExports.SeCreateTokenPrivilege = SeCreateTokenPrivilege; - SepExports.SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege; - SepExports.SeLockMemoryPrivilege = SeLockMemoryPrivilege; - SepExports.SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege; - SepExports.SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege; - SepExports.SeTcbPrivilege = SeTcbPrivilege; - SepExports.SeSecurityPrivilege = SeSecurityPrivilege; - SepExports.SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege; - SepExports.SeLoadDriverPrivilege = SeLoadDriverPrivilege; - SepExports.SeCreatePagefilePrivilege = SeCreatePagefilePrivilege; - SepExports.SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege; - SepExports.SeSystemProfilePrivilege = SeSystemProfilePrivilege; - SepExports.SeSystemtimePrivilege = SeSystemtimePrivilege; - SepExports.SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege; - SepExports.SeCreatePermanentPrivilege = SeCreatePermanentPrivilege; - SepExports.SeBackupPrivilege = SeBackupPrivilege; - SepExports.SeRestorePrivilege = SeRestorePrivilege; - SepExports.SeShutdownPrivilege = SeShutdownPrivilege; - SepExports.SeDebugPrivilege = SeDebugPrivilege; - SepExports.SeAuditPrivilege = SeAuditPrivilege; - SepExports.SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege; - SepExports.SeChangeNotifyPrivilege = SeChangeNotifyPrivilege; - SepExports.SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege; - - SepExports.SeNullSid = SeNullSid; - SepExports.SeWorldSid = SeWorldSid; - SepExports.SeLocalSid = SeLocalSid; - SepExports.SeCreatorOwnerSid = SeCreatorOwnerSid; - SepExports.SeCreatorGroupSid = SeCreatorGroupSid; - SepExports.SeNtAuthoritySid = SeNtAuthoritySid; - SepExports.SeDialupSid = SeDialupSid; - SepExports.SeNetworkSid = SeNetworkSid; - SepExports.SeBatchSid = SeBatchSid; - SepExports.SeInteractiveSid = SeInteractiveSid; - SepExports.SeLocalSystemSid = SeLocalSystemSid; - SepExports.SeAliasAdminsSid = SeAliasAdminsSid; - SepExports.SeAliasUsersSid = SeAliasUsersSid; - SepExports.SeAliasGuestsSid = SeAliasGuestsSid; - SepExports.SeAliasPowerUsersSid = SeAliasPowerUsersSid; - SepExports.SeAliasAccountOpsSid = SeAliasAccountOpsSid; - SepExports.SeAliasSystemOpsSid = SeAliasSystemOpsSid; - SepExports.SeAliasPrintOpsSid = SeAliasPrintOpsSid; - SepExports.SeAliasBackupOpsSid = SeAliasBackupOpsSid; - SepExports.SeAuthenticatedUsersSid = SeAuthenticatedUsersSid; - SepExports.SeRestrictedSid = SeRestrictedSid; - SepExports.SeAnonymousLogonSid = SeAnonymousLogonSid; - - SepExports.SeUndockPrivilege = SeUndockPrivilege; - SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege; - SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege; - - SeExports = &SepExports; - return TRUE; -} - - -VOID SepReferenceLogonSession(PLUID AuthenticationId) -{ - UNIMPLEMENTED; -} - -VOID SepDeReferenceLogonSession(PLUID AuthenticationId) -{ - UNIMPLEMENTED; + + ZwClose(EventHandle); + ZwClose(DirectoryHandle); + + /* FIXME: Create SRM port and listener thread */ + + return TRUE; } NTSTATUS @@ -244,16 +228,16 @@ SeDefaultObjectMethod(IN PVOID Object, IN PGENERIC_MAPPING GenericMapping) { PAGED_CODE(); - + /* Select the operation type */ switch (OperationType) - { - /* Setting a new descriptor */ + { + /* Setting a new descriptor */ case SetSecurityDescriptor: - + /* Sanity check */ ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool)); - + /* Set the information */ return ObSetSecurityDescriptorInfo(Object, SecurityInformation, @@ -261,479 +245,110 @@ SeDefaultObjectMethod(IN PVOID Object, OldSecurityDescriptor, PoolType, GenericMapping); - + case QuerySecurityDescriptor: - + /* Query the information */ return ObQuerySecurityDescriptorInfo(Object, SecurityInformation, SecurityDescriptor, ReturnLength, OldSecurityDescriptor); - + case DeleteSecurityDescriptor: - + /* De-assign it */ return ObDeassignSecurity(OldSecurityDescriptor); - + case AssignSecurityDescriptor: - + /* Assign it */ ObAssignObjectSecurityDescriptor(Object, SecurityDescriptor, PoolType); return STATUS_SUCCESS; - + default: - + /* Bug check */ KeBugCheckEx(SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0); } - + /* Should never reach here */ ASSERT(FALSE); return STATUS_SUCCESS; } -VOID -NTAPI -SeCaptureSubjectContextEx(IN PETHREAD Thread, - IN PEPROCESS Process, - OUT PSECURITY_SUBJECT_CONTEXT SubjectContext) -{ - BOOLEAN CopyOnOpen, EffectiveOnly; - PAGED_CODE(); - - /* Save the unique ID */ - SubjectContext->ProcessAuditId = Process->UniqueProcessId; - - /* Check if we have a thread */ - if (!Thread) - { - /* We don't, so no token */ - SubjectContext->ClientToken = NULL; - } - else - { - /* Get the impersonation token */ - SubjectContext->ClientToken = - PsReferenceImpersonationToken(Thread, - &CopyOnOpen, - &EffectiveOnly, - &SubjectContext->ImpersonationLevel); - } - - /* Get the primary token */ - SubjectContext->PrimaryToken = PsReferencePrimaryToken(Process); -} - -/* - * @implemented - */ -VOID -NTAPI -SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext) -{ - /* Call the internal API */ - SeCaptureSubjectContextEx(PsGetCurrentThread(), - PsGetCurrentProcess(), - SubjectContext); -} - - -/* - * @implemented - */ -VOID STDCALL -SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext) -{ - PAGED_CODE(); - - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(&SepSubjectContextLock, TRUE); -} - - -/* - * @implemented - */ -VOID STDCALL -SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext) -{ - PAGED_CODE(); - - ExReleaseResourceLite(&SepSubjectContextLock); - KeLeaveCriticalRegion(); -} - - -/* - * @implemented - */ -VOID STDCALL -SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext) -{ - PAGED_CODE(); - - if (SubjectContext->PrimaryToken != NULL) - { - ObFastDereferenceObject(&PsGetCurrentProcess()->Token, SubjectContext->PrimaryToken); - } - - if (SubjectContext->ClientToken != NULL) - { - ObDereferenceObject(SubjectContext->ClientToken); - } -} - - -/* - * @implemented - */ -NTSTATUS STDCALL -SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor) -{ - PAGED_CODE(); - - if (*SecurityDescriptor != NULL) - { - ExFreePool(*SecurityDescriptor); - *SecurityDescriptor = NULL; - } - - return STATUS_SUCCESS; -} - - -/* - * @unimplemented - */ -NTSTATUS STDCALL -SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, - IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL, - OUT PSECURITY_DESCRIPTOR *NewDescriptor, - IN GUID *ObjectType OPTIONAL, - IN BOOLEAN IsDirectoryObject, - IN ULONG AutoInheritFlags, - IN PSECURITY_SUBJECT_CONTEXT SubjectContext, - IN PGENERIC_MAPPING GenericMapping, - IN POOL_TYPE PoolType) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - - -/* - * FUNCTION: Creates a security descriptor for a new object. - * ARGUMENTS: - * ParentDescriptor = - * ExplicitDescriptor = - * NewDescriptor = - * IsDirectoryObject = - * SubjectContext = - * GeneralMapping = - * PoolType = - * RETURNS: Status - * - * @implemented - */ -NTSTATUS STDCALL -SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, - PSECURITY_DESCRIPTOR _ExplicitDescriptor OPTIONAL, - PSECURITY_DESCRIPTOR *NewDescriptor, - BOOLEAN IsDirectoryObject, - PSECURITY_SUBJECT_CONTEXT SubjectContext, - PGENERIC_MAPPING GenericMapping, - POOL_TYPE PoolType) -{ - PISECURITY_DESCRIPTOR ParentDescriptor = _ParentDescriptor; - PISECURITY_DESCRIPTOR ExplicitDescriptor = _ExplicitDescriptor; - PISECURITY_DESCRIPTOR Descriptor; - PTOKEN Token; - ULONG OwnerLength = 0; - ULONG GroupLength = 0; - ULONG DaclLength = 0; - ULONG SaclLength = 0; - ULONG Length = 0; - ULONG Control = 0; - ULONG_PTR Current; - PSID Owner = NULL; - PSID Group = NULL; - PACL Dacl = NULL; - PACL Sacl = NULL; - - PAGED_CODE(); - - /* Lock subject context */ - SeLockSubjectContext(SubjectContext); - - if (SubjectContext->ClientToken != NULL) - { - Token = SubjectContext->ClientToken; - } - else - { - Token = SubjectContext->PrimaryToken; - } - - - /* Inherit the Owner SID */ - if (ExplicitDescriptor != NULL && ExplicitDescriptor->Owner != NULL) - { - DPRINT("Use explicit owner sid!\n"); - Owner = ExplicitDescriptor->Owner; - - if (ExplicitDescriptor->Control & SE_SELF_RELATIVE) - { - Owner = (PSID)(((ULONG_PTR)Owner) + (ULONG_PTR)ExplicitDescriptor); - - } - } - else - { - if (Token != NULL) - { - DPRINT("Use token owner sid!\n"); - Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid; - } - else - { - DPRINT("Use default owner sid!\n"); - Owner = SeLocalSystemSid; - } - - Control |= SE_OWNER_DEFAULTED; - } - - OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); - - - /* Inherit the Group SID */ - if (ExplicitDescriptor != NULL && ExplicitDescriptor->Group != NULL) - { - DPRINT("Use explicit group sid!\n"); - Group = ExplicitDescriptor->Group; - if (ExplicitDescriptor->Control & SE_SELF_RELATIVE) - { - Group = (PSID)(((ULONG_PTR)Group) + (ULONG_PTR)ExplicitDescriptor); - } - } - else - { - if (Token != NULL) - { - DPRINT("Use token group sid!\n"); - Group = Token->PrimaryGroup; - } - else - { - DPRINT("Use default group sid!\n"); - Group = SeLocalSystemSid; - } - - Control |= SE_OWNER_DEFAULTED; - } - - GroupLength = ROUND_UP(RtlLengthSid(Group), 4); - - - /* Inherit the DACL */ - if (ExplicitDescriptor != NULL && - (ExplicitDescriptor->Control & SE_DACL_PRESENT) && - !(ExplicitDescriptor->Control & SE_DACL_DEFAULTED)) - { - DPRINT("Use explicit DACL!\n"); - Dacl = ExplicitDescriptor->Dacl; - if (Dacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE)) - { - Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ExplicitDescriptor); - } - - Control |= SE_DACL_PRESENT; - } - else if (ParentDescriptor != NULL && - (ParentDescriptor->Control & SE_DACL_PRESENT)) - { - DPRINT("Use parent DACL!\n"); - /* FIXME: Inherit */ - Dacl = ParentDescriptor->Dacl; - if (Dacl != NULL && (ParentDescriptor->Control & SE_SELF_RELATIVE)) - { - Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ParentDescriptor); - } - Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED); - } - else if (Token != NULL && Token->DefaultDacl != NULL) - { - DPRINT("Use token default DACL!\n"); - /* FIXME: Inherit */ - Dacl = Token->DefaultDacl; - Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED); - } - else - { - DPRINT("Use NULL DACL!\n"); - Dacl = NULL; - Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED); - } - - DaclLength = (Dacl != NULL) ? ROUND_UP(Dacl->AclSize, 4) : 0; - - - /* Inherit the SACL */ - if (ExplicitDescriptor != NULL && - (ExplicitDescriptor->Control & SE_SACL_PRESENT) && - !(ExplicitDescriptor->Control & SE_SACL_DEFAULTED)) - { - DPRINT("Use explicit SACL!\n"); - Sacl = ExplicitDescriptor->Sacl; - if (Sacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE)) - { - Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ExplicitDescriptor); - } - - Control |= SE_SACL_PRESENT; - } - else if (ParentDescriptor != NULL && - (ParentDescriptor->Control & SE_SACL_PRESENT)) - { - DPRINT("Use parent SACL!\n"); - /* FIXME: Inherit */ - Sacl = ParentDescriptor->Sacl; - if (Sacl != NULL && (ParentDescriptor->Control & SE_SELF_RELATIVE)) - { - Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ParentDescriptor); - } - Control |= (SE_SACL_PRESENT | SE_SACL_DEFAULTED); - } - - SaclLength = (Sacl != NULL) ? ROUND_UP(Sacl->AclSize, 4) : 0; - - - /* Allocate and initialize the new security descriptor */ - Length = sizeof(SECURITY_DESCRIPTOR) + - OwnerLength + GroupLength + DaclLength + SaclLength; - - DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n", - sizeof(SECURITY_DESCRIPTOR), - OwnerLength, - GroupLength, - DaclLength, - SaclLength); - - Descriptor = ExAllocatePool(PagedPool, - Length); - if (Descriptor == NULL) - { - DPRINT1("ExAlloctePool() failed\n"); - /* FIXME: Unlock subject context */ - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlZeroMemory( Descriptor, Length ); - RtlCreateSecurityDescriptor(Descriptor, - SECURITY_DESCRIPTOR_REVISION); - - Descriptor->Control = (USHORT)Control | SE_SELF_RELATIVE; - - Current = (ULONG_PTR)Descriptor + sizeof(SECURITY_DESCRIPTOR); - - if (SaclLength != 0) - { - RtlCopyMemory((PVOID)Current, - Sacl, - SaclLength); - Descriptor->Sacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor); - Current += SaclLength; - } - - if (DaclLength != 0) - { - RtlCopyMemory((PVOID)Current, - Dacl, - DaclLength); - Descriptor->Dacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor); - Current += DaclLength; - } - - if (OwnerLength != 0) - { - RtlCopyMemory((PVOID)Current, - Owner, - OwnerLength); - Descriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor); - Current += OwnerLength; - DPRINT("Owner of %x at %x\n", Descriptor, Descriptor->Owner); - } - else - DPRINT("Owner of %x is zero length\n", Descriptor); - - if (GroupLength != 0) - { - memmove((PVOID)Current, - Group, - GroupLength); - Descriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor); - } - - /* Unlock subject context */ - SeUnlockSubjectContext(SubjectContext); - - *NewDescriptor = Descriptor; - - DPRINT("Descrptor %x\n", Descriptor); - ASSERT(RtlLengthSecurityDescriptor(Descriptor)); - - return STATUS_SUCCESS; -} - static BOOLEAN SepSidInToken(PACCESS_TOKEN _Token, PSID Sid) { - ULONG i; - PTOKEN Token = (PTOKEN)_Token; - - PAGED_CODE(); - - if (Token->UserAndGroupCount == 0) - { - return FALSE; - } - - for (i=0; iUserAndGroupCount; i++) - { - if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid)) + ULONG i; + PTOKEN Token = (PTOKEN)_Token; + + PAGED_CODE(); + + if (Token->UserAndGroupCount == 0) { - if (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED) - { - return TRUE; - } - - return FALSE; + return FALSE; } - } - - return FALSE; + + for (i=0; iUserAndGroupCount; i++) + { + if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid)) + { + if (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED) + { + return TRUE; + } + + return FALSE; + } + } + + return FALSE; } +VOID STDCALL +SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, + OUT PACCESS_MASK DesiredAccess) +{ + *DesiredAccess = 0; + + if (SecurityInformation & (OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION)) + { + *DesiredAccess |= READ_CONTROL; + } + if (SecurityInformation & SACL_SECURITY_INFORMATION) + { + *DesiredAccess |= ACCESS_SYSTEM_SECURITY; + } +} + +VOID STDCALL +SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, + OUT PACCESS_MASK DesiredAccess) +{ + *DesiredAccess = 0; + + if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION)) + { + *DesiredAccess |= WRITE_OWNER; + } + if (SecurityInformation & DACL_SECURITY_INFORMATION) + { + *DesiredAccess |= WRITE_DAC; + } + if (SecurityInformation & SACL_SECURITY_INFORMATION) + { + *DesiredAccess |= ACCESS_SYSTEM_SECURITY; + } +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + /* - * FUNCTION: Determines whether the requested access rights can be granted - * to an object protected by a security descriptor and an object owner - * ARGUMENTS: - * SecurityDescriptor = Security descriptor protecting the object - * SubjectSecurityContext = Subject's captured security context - * SubjectContextLocked = Indicates the user's subject context is locked - * DesiredAccess = Access rights the caller is trying to acquire - * PreviouslyGrantedAccess = Specified the access rights already granted - * Privileges = ? - * GenericMapping = Generic mapping associated with the object - * AccessMode = Access mode used for the check - * GrantedAccess (OUT) = On return specifies the access granted - * AccessStatus (OUT) = Status indicating why access was denied - * RETURNS: If access was granted, returns TRUE - * * @implemented */ BOOLEAN STDCALL @@ -759,7 +374,7 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, PSID Sid; NTSTATUS Status; PAGED_CODE(); - + /* Check if this is kernel mode */ if (AccessMode == KernelMode) { @@ -776,12 +391,12 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, /* Give the desired and previous access */ *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess; } - + /* Success */ *AccessStatus = STATUS_SUCCESS; return TRUE; } - + /* Check if we didn't get an SD */ if (!SecurityDescriptor) { @@ -789,7 +404,7 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, *AccessStatus = STATUS_ACCESS_DENIED; return FALSE; } - + /* Check for invalid impersonation */ if ((SubjectSecurityContext->ClientToken) && (SubjectSecurityContext->ImpersonationLevel < SecurityImpersonation)) @@ -797,7 +412,7 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, *AccessStatus = STATUS_BAD_IMPERSONATION_LEVEL; return FALSE; } - + /* Check for no access desired */ if (!DesiredAccess) { @@ -808,200 +423,201 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, *AccessStatus = STATUS_ACCESS_DENIED; return FALSE; } - + /* Return the previous access only */ *GrantedAccess = PreviouslyGrantedAccess; *AccessStatus = STATUS_SUCCESS; *Privileges = NULL; return TRUE; } - + /* Acquire the lock if needed */ if (!SubjectContextLocked) SeLockSubjectContext(SubjectSecurityContext); - - /* Map given accesses */ - RtlMapGenericMask(&DesiredAccess, GenericMapping); - if (PreviouslyGrantedAccess) - RtlMapGenericMask(&PreviouslyGrantedAccess, GenericMapping); - - - - CurrentAccess = PreviouslyGrantedAccess; - - - - Token = SubjectSecurityContext->ClientToken ? - SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken; - - /* Get the DACL */ - Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor, - &Present, - &Dacl, - &Defaulted); - if (!NT_SUCCESS(Status)) + + /* Map given accesses */ + RtlMapGenericMask(&DesiredAccess, GenericMapping); + if (PreviouslyGrantedAccess) + RtlMapGenericMask(&PreviouslyGrantedAccess, GenericMapping); + + + + CurrentAccess = PreviouslyGrantedAccess; + + + + Token = SubjectSecurityContext->ClientToken ? + SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken; + + /* Get the DACL */ + Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor, + &Present, + &Dacl, + &Defaulted); + if (!NT_SUCCESS(Status)) { - if (SubjectContextLocked == FALSE) + if (SubjectContextLocked == FALSE) { - SeUnlockSubjectContext(SubjectSecurityContext); + SeUnlockSubjectContext(SubjectSecurityContext); } - - *AccessStatus = Status; - return FALSE; + + *AccessStatus = Status; + return FALSE; } - - /* RULE 1: Grant desired access if the object is unprotected */ - if (Present == TRUE && Dacl == NULL) + + /* RULE 1: Grant desired access if the object is unprotected */ + if (Present == TRUE && Dacl == NULL) { - if (SubjectContextLocked == FALSE) + if (SubjectContextLocked == FALSE) { - SeUnlockSubjectContext(SubjectSecurityContext); + SeUnlockSubjectContext(SubjectSecurityContext); } - - *GrantedAccess = DesiredAccess; - *AccessStatus = STATUS_SUCCESS; - return TRUE; + + *GrantedAccess = DesiredAccess; + *AccessStatus = STATUS_SUCCESS; + return TRUE; } - - CurrentAccess = PreviouslyGrantedAccess; - - /* RULE 2: Check token for 'take ownership' privilege */ - Privilege.Luid = SeTakeOwnershipPrivilege; - Privilege.Attributes = SE_PRIVILEGE_ENABLED; - - if (SepPrivilegeCheck(Token, - &Privilege, - 1, - PRIVILEGE_SET_ALL_NECESSARY, - AccessMode)) + + CurrentAccess = PreviouslyGrantedAccess; + + /* RULE 2: Check token for 'take ownership' privilege */ + Privilege.Luid = SeTakeOwnershipPrivilege; + Privilege.Attributes = SE_PRIVILEGE_ENABLED; + + if (SepPrivilegeCheck(Token, + &Privilege, + 1, + PRIVILEGE_SET_ALL_NECESSARY, + AccessMode)) { - CurrentAccess |= WRITE_OWNER; - if ((DesiredAccess & ~VALID_INHERIT_FLAGS) == - (CurrentAccess & ~VALID_INHERIT_FLAGS)) + CurrentAccess |= WRITE_OWNER; + if ((DesiredAccess & ~VALID_INHERIT_FLAGS) == + (CurrentAccess & ~VALID_INHERIT_FLAGS)) { - if (SubjectContextLocked == FALSE) + if (SubjectContextLocked == FALSE) { - SeUnlockSubjectContext(SubjectSecurityContext); + SeUnlockSubjectContext(SubjectSecurityContext); } - - *GrantedAccess = CurrentAccess; - *AccessStatus = STATUS_SUCCESS; - return TRUE; + + *GrantedAccess = CurrentAccess; + *AccessStatus = STATUS_SUCCESS; + return TRUE; } } - - /* RULE 3: Check whether the token is the owner */ - Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor, - &Sid, - &Defaulted); - if (!NT_SUCCESS(Status)) + + /* RULE 3: Check whether the token is the owner */ + Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor, + &Sid, + &Defaulted); + if (!NT_SUCCESS(Status)) { - DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status); - if (SubjectContextLocked == FALSE) + DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status); + if (SubjectContextLocked == FALSE) { - SeUnlockSubjectContext(SubjectSecurityContext); + SeUnlockSubjectContext(SubjectSecurityContext); } - - *AccessStatus = Status; - return FALSE; - } - - if (Sid && SepSidInToken(Token, Sid)) + + *AccessStatus = Status; + return FALSE; + } + + if (Sid && SepSidInToken(Token, Sid)) { - CurrentAccess |= (READ_CONTROL | WRITE_DAC); - if ((DesiredAccess & ~VALID_INHERIT_FLAGS) == - (CurrentAccess & ~VALID_INHERIT_FLAGS)) + CurrentAccess |= (READ_CONTROL | WRITE_DAC); + if ((DesiredAccess & ~VALID_INHERIT_FLAGS) == + (CurrentAccess & ~VALID_INHERIT_FLAGS)) { - if (SubjectContextLocked == FALSE) + if (SubjectContextLocked == FALSE) { - SeUnlockSubjectContext(SubjectSecurityContext); + SeUnlockSubjectContext(SubjectSecurityContext); } - - *GrantedAccess = CurrentAccess; - *AccessStatus = STATUS_SUCCESS; - return TRUE; + + *GrantedAccess = CurrentAccess; + *AccessStatus = STATUS_SUCCESS; + return TRUE; } } - - /* Fail if DACL is absent */ - if (Present == FALSE) + + /* Fail if DACL is absent */ + if (Present == FALSE) { - if (SubjectContextLocked == FALSE) + if (SubjectContextLocked == FALSE) { - SeUnlockSubjectContext(SubjectSecurityContext); + SeUnlockSubjectContext(SubjectSecurityContext); } - - *GrantedAccess = 0; - *AccessStatus = STATUS_ACCESS_DENIED; - return FALSE; + + *GrantedAccess = 0; + *AccessStatus = STATUS_ACCESS_DENIED; + return FALSE; } - - /* RULE 4: Grant rights according to the DACL */ - CurrentAce = (PACE)(Dacl + 1); - for (i = 0; i < Dacl->AceCount; i++) + + /* RULE 4: Grant rights according to the DACL */ + CurrentAce = (PACE)(Dacl + 1); + for (i = 0; i < Dacl->AceCount; i++) { - Sid = (PSID)(CurrentAce + 1); - if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE) + Sid = (PSID)(CurrentAce + 1); + if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE) { - if (SepSidInToken(Token, Sid)) + if (SepSidInToken(Token, Sid)) { - if (SubjectContextLocked == FALSE) + if (SubjectContextLocked == FALSE) { - SeUnlockSubjectContext(SubjectSecurityContext); + SeUnlockSubjectContext(SubjectSecurityContext); } - - *GrantedAccess = 0; - *AccessStatus = STATUS_ACCESS_DENIED; - return FALSE; + + *GrantedAccess = 0; + *AccessStatus = STATUS_ACCESS_DENIED; + return FALSE; } } - - else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) + + else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) { - if (SepSidInToken(Token, Sid)) + if (SepSidInToken(Token, Sid)) { - AccessMask = CurrentAce->AccessMask; - RtlMapGenericMask(&AccessMask, GenericMapping); - CurrentAccess |= AccessMask; + AccessMask = CurrentAce->AccessMask; + RtlMapGenericMask(&AccessMask, GenericMapping); + CurrentAccess |= AccessMask; } } else { - DPRINT1("Unknown Ace type 0x%lx\n", CurrentAce->Header.AceType); - } + DPRINT1("Unknown Ace type 0x%lx\n", CurrentAce->Header.AceType); + } CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize); } - - if (SubjectContextLocked == FALSE) + + if (SubjectContextLocked == FALSE) { - SeUnlockSubjectContext(SubjectSecurityContext); + SeUnlockSubjectContext(SubjectSecurityContext); } - - DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n", - CurrentAccess, DesiredAccess); - - *GrantedAccess = CurrentAccess & DesiredAccess; - - if (DesiredAccess & MAXIMUM_ALLOWED) + + DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n", + CurrentAccess, DesiredAccess); + + *GrantedAccess = CurrentAccess & DesiredAccess; + + if (DesiredAccess & MAXIMUM_ALLOWED) { - *GrantedAccess = CurrentAccess; - *AccessStatus = STATUS_SUCCESS; - return TRUE; + *GrantedAccess = CurrentAccess; + *AccessStatus = STATUS_SUCCESS; + return TRUE; } - else if ((*GrantedAccess & ~VALID_INHERIT_FLAGS) == - (DesiredAccess & ~VALID_INHERIT_FLAGS)) + else if ((*GrantedAccess & ~VALID_INHERIT_FLAGS) == + (DesiredAccess & ~VALID_INHERIT_FLAGS)) { - *AccessStatus = STATUS_SUCCESS; - return TRUE; + *AccessStatus = STATUS_SUCCESS; + return TRUE; } - else + else { - DPRINT1("Denying access for caller: granted 0x%lx, desired 0x%lx (generic mapping %p)\n", - *GrantedAccess, DesiredAccess, GenericMapping); - *AccessStatus = STATUS_ACCESS_DENIED; - return FALSE; + DPRINT1("Denying access for caller: granted 0x%lx, desired 0x%lx (generic mapping %p)\n", + *GrantedAccess, DesiredAccess, GenericMapping); + *AccessStatus = STATUS_ACCESS_DENIED; + return FALSE; } } +/* SYSTEM CALLS ***************************************************************/ NTSTATUS STDCALL NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, @@ -1013,83 +629,83 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PACCESS_MASK GrantedAccess, OUT PNTSTATUS AccessStatus) { - SECURITY_SUBJECT_CONTEXT SubjectSecurityContext = {0}; - KPROCESSOR_MODE PreviousMode; - PTOKEN Token; - NTSTATUS Status; - - PAGED_CODE(); - - DPRINT("NtAccessCheck() called\n"); - - PreviousMode = KeGetPreviousMode(); - if (PreviousMode == KernelMode) + SECURITY_SUBJECT_CONTEXT SubjectSecurityContext = {0}; + KPROCESSOR_MODE PreviousMode; + PTOKEN Token; + NTSTATUS Status; + + PAGED_CODE(); + + DPRINT("NtAccessCheck() called\n"); + + PreviousMode = KeGetPreviousMode(); + if (PreviousMode == KernelMode) { - *GrantedAccess = DesiredAccess; - *AccessStatus = STATUS_SUCCESS; - return STATUS_SUCCESS; + *GrantedAccess = DesiredAccess; + *AccessStatus = STATUS_SUCCESS; + return STATUS_SUCCESS; } - - Status = ObReferenceObjectByHandle(TokenHandle, - TOKEN_QUERY, - SepTokenObjectType, - PreviousMode, - (PVOID*)&Token, - NULL); - if (!NT_SUCCESS(Status)) + + Status = ObReferenceObjectByHandle(TokenHandle, + TOKEN_QUERY, + SepTokenObjectType, + PreviousMode, + (PVOID*)&Token, + NULL); + if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to reference token (Status %lx)\n", Status); - return Status; + DPRINT1("Failed to reference token (Status %lx)\n", Status); + return Status; } - - /* Check token type */ - if (Token->TokenType != TokenImpersonation) + + /* Check token type */ + if (Token->TokenType != TokenImpersonation) { - DPRINT1("No impersonation token\n"); - ObDereferenceObject(Token); - return STATUS_ACCESS_VIOLATION; + DPRINT1("No impersonation token\n"); + ObDereferenceObject(Token); + return STATUS_ACCESS_VIOLATION; } - - /* Check impersonation level */ - if (Token->ImpersonationLevel < SecurityAnonymous) + + /* Check impersonation level */ + if (Token->ImpersonationLevel < SecurityAnonymous) { - DPRINT1("Invalid impersonation level\n"); - ObDereferenceObject(Token); - return STATUS_ACCESS_VIOLATION; + DPRINT1("Invalid impersonation level\n"); + ObDereferenceObject(Token); + return STATUS_ACCESS_VIOLATION; } - - SubjectSecurityContext.ClientToken = Token; - SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel; - - /* Lock subject context */ - SeLockSubjectContext(&SubjectSecurityContext); - - if (SeAccessCheck(SecurityDescriptor, - &SubjectSecurityContext, - TRUE, - DesiredAccess, - 0, - &PrivilegeSet, - GenericMapping, - PreviousMode, - GrantedAccess, - AccessStatus)) + + SubjectSecurityContext.ClientToken = Token; + SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel; + + /* Lock subject context */ + SeLockSubjectContext(&SubjectSecurityContext); + + if (SeAccessCheck(SecurityDescriptor, + &SubjectSecurityContext, + TRUE, + DesiredAccess, + 0, + &PrivilegeSet, + GenericMapping, + PreviousMode, + GrantedAccess, + AccessStatus)) { - Status = *AccessStatus; + Status = *AccessStatus; } - else + else { - Status = STATUS_ACCESS_DENIED; + Status = STATUS_ACCESS_DENIED; } - - /* Unlock subject context */ - SeUnlockSubjectContext(&SubjectSecurityContext); - - ObDereferenceObject(Token); - - DPRINT("NtAccessCheck() done\n"); - - return Status; + + /* Unlock subject context */ + SeUnlockSubjectContext(&SubjectSecurityContext); + + ObDereferenceObject(Token); + + DPRINT("NtAccessCheck() done\n"); + + return Status; } NTSTATUS @@ -1198,41 +814,4 @@ NtAccessCheckByTypeResultListAndAuditAlarmByHandle(IN PUNICODE_STRING SubsystemN return STATUS_NOT_IMPLEMENTED; } -VOID STDCALL -SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, - OUT PACCESS_MASK DesiredAccess) -{ - *DesiredAccess = 0; - - if (SecurityInformation & (OWNER_SECURITY_INFORMATION | - GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION)) - { - *DesiredAccess |= READ_CONTROL; - } - if (SecurityInformation & SACL_SECURITY_INFORMATION) - { - *DesiredAccess |= ACCESS_SYSTEM_SECURITY; - } -} - -VOID STDCALL -SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, - OUT PACCESS_MASK DesiredAccess) -{ - *DesiredAccess = 0; - - if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION)) - { - *DesiredAccess |= WRITE_OWNER; - } - if (SecurityInformation & DACL_SECURITY_INFORMATION) - { - *DesiredAccess |= WRITE_DAC; - } - if (SecurityInformation & SACL_SECURITY_INFORMATION) - { - *DesiredAccess |= ACCESS_SYSTEM_SECURITY; - } -} - /* EOF */ diff --git a/reactos/ntoskrnl/se/sid.c b/reactos/ntoskrnl/se/sid.c index 2f1a6091087..e037806b5de 100644 --- a/reactos/ntoskrnl/se/sid.c +++ b/reactos/ntoskrnl/se/sid.c @@ -7,19 +7,17 @@ * PROGRAMMERS: David Welch */ -/* INCLUDES *****************************************************************/ +/* INCLUDES *******************************************************************/ #include - #define NDEBUG -#include +#include #if defined (ALLOC_PRAGMA) #pragma alloc_text(INIT, SepInitSecurityIDs) #endif - -/* GLOBALS ******************************************************************/ +/* GLOBALS ********************************************************************/ SID_IDENTIFIER_AUTHORITY SeNullSidAuthority = {SECURITY_NULL_SID_AUTHORITY}; SID_IDENTIFIER_AUTHORITY SeWorldSidAuthority = {SECURITY_WORLD_SID_AUTHORITY}; @@ -56,174 +54,172 @@ PSID SeAuthenticatedUsersSid = NULL; PSID SeRestrictedSid = NULL; PSID SeAnonymousLogonSid = NULL; - -/* FUNCTIONS ****************************************************************/ - +/* FUNCTIONS ******************************************************************/ BOOLEAN INIT_FUNCTION NTAPI SepInitSecurityIDs(VOID) { - ULONG SidLength0; - ULONG SidLength1; - ULONG SidLength2; - PULONG SubAuthority; - - SidLength0 = RtlLengthRequiredSid(0); - SidLength1 = RtlLengthRequiredSid(1); - SidLength2 = RtlLengthRequiredSid(2); - - /* create NullSid */ - SeNullSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeWorldSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeLocalSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeCreatorOwnerSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeCreatorGroupSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeCreatorOwnerServerSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeCreatorGroupServerSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeNtAuthoritySid = ExAllocatePoolWithTag(PagedPool, SidLength0, TAG_SID); - SeDialupSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeNetworkSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeBatchSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeInteractiveSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeServiceSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SePrincipalSelfSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeLocalSystemSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeAuthenticatedUserSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeRestrictedCodeSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeAliasAdminsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); - SeAliasUsersSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); - SeAliasGuestsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); - SeAliasPowerUsersSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); - SeAliasAccountOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); - SeAliasSystemOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); - SeAliasPrintOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); - SeAliasBackupOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); - SeAuthenticatedUsersSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeRestrictedSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - SeAnonymousLogonSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); - - if (SeNullSid == NULL || SeWorldSid == NULL || - SeLocalSid == NULL || SeCreatorOwnerSid == NULL || - SeCreatorGroupSid == NULL || SeCreatorOwnerServerSid == NULL || - SeCreatorGroupServerSid == NULL || SeNtAuthoritySid == NULL || - SeDialupSid == NULL || SeNetworkSid == NULL || SeBatchSid == NULL || - SeInteractiveSid == NULL || SeServiceSid == NULL || - SePrincipalSelfSid == NULL || SeLocalSystemSid == NULL || - SeAuthenticatedUserSid == NULL || SeRestrictedCodeSid == NULL || - SeAliasAdminsSid == NULL || SeAliasUsersSid == NULL || - SeAliasGuestsSid == NULL || SeAliasPowerUsersSid == NULL || - SeAliasAccountOpsSid == NULL || SeAliasSystemOpsSid == NULL || - SeAliasPrintOpsSid == NULL || SeAliasBackupOpsSid == NULL || - SeAuthenticatedUsersSid == NULL || SeRestrictedSid == NULL || - SeAnonymousLogonSid == NULL) - { - /* FIXME: We're leaking memory here. */ - return(FALSE); - } - - RtlInitializeSid(SeNullSid, &SeNullSidAuthority, 1); - RtlInitializeSid(SeWorldSid, &SeWorldSidAuthority, 1); - RtlInitializeSid(SeLocalSid, &SeLocalSidAuthority, 1); - RtlInitializeSid(SeCreatorOwnerSid, &SeCreatorSidAuthority, 1); - RtlInitializeSid(SeCreatorGroupSid, &SeCreatorSidAuthority, 1); - RtlInitializeSid(SeCreatorOwnerServerSid, &SeCreatorSidAuthority, 1); - RtlInitializeSid(SeCreatorGroupServerSid, &SeCreatorSidAuthority, 1); - RtlInitializeSid(SeNtAuthoritySid, &SeNtSidAuthority, 0); - RtlInitializeSid(SeDialupSid, &SeNtSidAuthority, 1); - RtlInitializeSid(SeNetworkSid, &SeNtSidAuthority, 1); - RtlInitializeSid(SeBatchSid, &SeNtSidAuthority, 1); - RtlInitializeSid(SeInteractiveSid, &SeNtSidAuthority, 1); - RtlInitializeSid(SeServiceSid, &SeNtSidAuthority, 1); - RtlInitializeSid(SePrincipalSelfSid, &SeNtSidAuthority, 1); - RtlInitializeSid(SeLocalSystemSid, &SeNtSidAuthority, 1); - RtlInitializeSid(SeAuthenticatedUserSid, &SeNtSidAuthority, 1); - RtlInitializeSid(SeRestrictedCodeSid, &SeNtSidAuthority, 1); - RtlInitializeSid(SeAliasAdminsSid, &SeNtSidAuthority, 2); - RtlInitializeSid(SeAliasUsersSid, &SeNtSidAuthority, 2); - RtlInitializeSid(SeAliasGuestsSid, &SeNtSidAuthority, 2); - RtlInitializeSid(SeAliasPowerUsersSid, &SeNtSidAuthority, 2); - RtlInitializeSid(SeAliasAccountOpsSid, &SeNtSidAuthority, 2); - RtlInitializeSid(SeAliasSystemOpsSid, &SeNtSidAuthority, 2); - RtlInitializeSid(SeAliasPrintOpsSid, &SeNtSidAuthority, 2); - RtlInitializeSid(SeAliasBackupOpsSid, &SeNtSidAuthority, 2); - RtlInitializeSid(SeAuthenticatedUsersSid, &SeNtSidAuthority, 1); - RtlInitializeSid(SeRestrictedSid, &SeNtSidAuthority, 1); - RtlInitializeSid(SeAnonymousLogonSid, &SeNtSidAuthority, 1); - - SubAuthority = RtlSubAuthoritySid(SeNullSid, 0); - *SubAuthority = SECURITY_NULL_RID; - SubAuthority = RtlSubAuthoritySid(SeWorldSid, 0); - *SubAuthority = SECURITY_WORLD_RID; - SubAuthority = RtlSubAuthoritySid(SeLocalSid, 0); - *SubAuthority = SECURITY_LOCAL_RID; - SubAuthority = RtlSubAuthoritySid(SeCreatorOwnerSid, 0); - *SubAuthority = SECURITY_CREATOR_OWNER_RID; - SubAuthority = RtlSubAuthoritySid(SeCreatorGroupSid, 0); - *SubAuthority = SECURITY_CREATOR_GROUP_RID; - SubAuthority = RtlSubAuthoritySid(SeCreatorOwnerServerSid, 0); - *SubAuthority = SECURITY_CREATOR_OWNER_SERVER_RID; - SubAuthority = RtlSubAuthoritySid(SeCreatorGroupServerSid, 0); - *SubAuthority = SECURITY_CREATOR_GROUP_SERVER_RID; - SubAuthority = RtlSubAuthoritySid(SeDialupSid, 0); - *SubAuthority = SECURITY_DIALUP_RID; - SubAuthority = RtlSubAuthoritySid(SeNetworkSid, 0); - *SubAuthority = SECURITY_NETWORK_RID; - SubAuthority = RtlSubAuthoritySid(SeBatchSid, 0); - *SubAuthority = SECURITY_BATCH_RID; - SubAuthority = RtlSubAuthoritySid(SeInteractiveSid, 0); - *SubAuthority = SECURITY_INTERACTIVE_RID; - SubAuthority = RtlSubAuthoritySid(SeServiceSid, 0); - *SubAuthority = SECURITY_SERVICE_RID; - SubAuthority = RtlSubAuthoritySid(SePrincipalSelfSid, 0); - *SubAuthority = SECURITY_PRINCIPAL_SELF_RID; - SubAuthority = RtlSubAuthoritySid(SeLocalSystemSid, 0); - *SubAuthority = SECURITY_LOCAL_SYSTEM_RID; - SubAuthority = RtlSubAuthoritySid(SeAuthenticatedUserSid, 0); - *SubAuthority = SECURITY_AUTHENTICATED_USER_RID; - SubAuthority = RtlSubAuthoritySid(SeRestrictedCodeSid, 0); - *SubAuthority = SECURITY_RESTRICTED_CODE_RID; - SubAuthority = RtlSubAuthoritySid(SeAliasAdminsSid, 0); - *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; - SubAuthority = RtlSubAuthoritySid(SeAliasAdminsSid, 1); - *SubAuthority = DOMAIN_ALIAS_RID_ADMINS; - SubAuthority = RtlSubAuthoritySid(SeAliasUsersSid, 0); - *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; - SubAuthority = RtlSubAuthoritySid(SeAliasUsersSid, 1); - *SubAuthority = DOMAIN_ALIAS_RID_USERS; - SubAuthority = RtlSubAuthoritySid(SeAliasGuestsSid, 0); - *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; - SubAuthority = RtlSubAuthoritySid(SeAliasGuestsSid, 1); - *SubAuthority = DOMAIN_ALIAS_RID_GUESTS; - SubAuthority = RtlSubAuthoritySid(SeAliasPowerUsersSid, 0); - *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; - SubAuthority = RtlSubAuthoritySid(SeAliasPowerUsersSid, 1); - *SubAuthority = DOMAIN_ALIAS_RID_POWER_USERS; - SubAuthority = RtlSubAuthoritySid(SeAliasAccountOpsSid, 0); - *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; - SubAuthority = RtlSubAuthoritySid(SeAliasAccountOpsSid, 1); - *SubAuthority = DOMAIN_ALIAS_RID_ACCOUNT_OPS; - SubAuthority = RtlSubAuthoritySid(SeAliasSystemOpsSid, 0); - *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; - SubAuthority = RtlSubAuthoritySid(SeAliasSystemOpsSid, 1); - *SubAuthority = DOMAIN_ALIAS_RID_SYSTEM_OPS; - SubAuthority = RtlSubAuthoritySid(SeAliasPrintOpsSid, 0); - *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; - SubAuthority = RtlSubAuthoritySid(SeAliasPrintOpsSid, 1); - *SubAuthority = DOMAIN_ALIAS_RID_PRINT_OPS; - SubAuthority = RtlSubAuthoritySid(SeAliasBackupOpsSid, 0); - *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; - SubAuthority = RtlSubAuthoritySid(SeAliasBackupOpsSid, 1); - *SubAuthority = DOMAIN_ALIAS_RID_BACKUP_OPS; - SubAuthority = RtlSubAuthoritySid(SeAuthenticatedUsersSid, 0); - *SubAuthority = SECURITY_AUTHENTICATED_USER_RID; - SubAuthority = RtlSubAuthoritySid(SeRestrictedSid, 0); - *SubAuthority = SECURITY_RESTRICTED_CODE_RID; - SubAuthority = RtlSubAuthoritySid(SeAnonymousLogonSid, 0); - *SubAuthority = SECURITY_ANONYMOUS_LOGON_RID; - - return(TRUE); + ULONG SidLength0; + ULONG SidLength1; + ULONG SidLength2; + PULONG SubAuthority; + + SidLength0 = RtlLengthRequiredSid(0); + SidLength1 = RtlLengthRequiredSid(1); + SidLength2 = RtlLengthRequiredSid(2); + + /* create NullSid */ + SeNullSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeWorldSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeLocalSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeCreatorOwnerSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeCreatorGroupSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeCreatorOwnerServerSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeCreatorGroupServerSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeNtAuthoritySid = ExAllocatePoolWithTag(PagedPool, SidLength0, TAG_SID); + SeDialupSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeNetworkSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeBatchSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeInteractiveSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeServiceSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SePrincipalSelfSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeLocalSystemSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeAuthenticatedUserSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeRestrictedCodeSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeAliasAdminsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); + SeAliasUsersSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); + SeAliasGuestsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); + SeAliasPowerUsersSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); + SeAliasAccountOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); + SeAliasSystemOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); + SeAliasPrintOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); + SeAliasBackupOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); + SeAuthenticatedUsersSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeRestrictedSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + SeAnonymousLogonSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); + + if (SeNullSid == NULL || SeWorldSid == NULL || + SeLocalSid == NULL || SeCreatorOwnerSid == NULL || + SeCreatorGroupSid == NULL || SeCreatorOwnerServerSid == NULL || + SeCreatorGroupServerSid == NULL || SeNtAuthoritySid == NULL || + SeDialupSid == NULL || SeNetworkSid == NULL || SeBatchSid == NULL || + SeInteractiveSid == NULL || SeServiceSid == NULL || + SePrincipalSelfSid == NULL || SeLocalSystemSid == NULL || + SeAuthenticatedUserSid == NULL || SeRestrictedCodeSid == NULL || + SeAliasAdminsSid == NULL || SeAliasUsersSid == NULL || + SeAliasGuestsSid == NULL || SeAliasPowerUsersSid == NULL || + SeAliasAccountOpsSid == NULL || SeAliasSystemOpsSid == NULL || + SeAliasPrintOpsSid == NULL || SeAliasBackupOpsSid == NULL || + SeAuthenticatedUsersSid == NULL || SeRestrictedSid == NULL || + SeAnonymousLogonSid == NULL) + { + /* FIXME: We're leaking memory here. */ + return(FALSE); + } + + RtlInitializeSid(SeNullSid, &SeNullSidAuthority, 1); + RtlInitializeSid(SeWorldSid, &SeWorldSidAuthority, 1); + RtlInitializeSid(SeLocalSid, &SeLocalSidAuthority, 1); + RtlInitializeSid(SeCreatorOwnerSid, &SeCreatorSidAuthority, 1); + RtlInitializeSid(SeCreatorGroupSid, &SeCreatorSidAuthority, 1); + RtlInitializeSid(SeCreatorOwnerServerSid, &SeCreatorSidAuthority, 1); + RtlInitializeSid(SeCreatorGroupServerSid, &SeCreatorSidAuthority, 1); + RtlInitializeSid(SeNtAuthoritySid, &SeNtSidAuthority, 0); + RtlInitializeSid(SeDialupSid, &SeNtSidAuthority, 1); + RtlInitializeSid(SeNetworkSid, &SeNtSidAuthority, 1); + RtlInitializeSid(SeBatchSid, &SeNtSidAuthority, 1); + RtlInitializeSid(SeInteractiveSid, &SeNtSidAuthority, 1); + RtlInitializeSid(SeServiceSid, &SeNtSidAuthority, 1); + RtlInitializeSid(SePrincipalSelfSid, &SeNtSidAuthority, 1); + RtlInitializeSid(SeLocalSystemSid, &SeNtSidAuthority, 1); + RtlInitializeSid(SeAuthenticatedUserSid, &SeNtSidAuthority, 1); + RtlInitializeSid(SeRestrictedCodeSid, &SeNtSidAuthority, 1); + RtlInitializeSid(SeAliasAdminsSid, &SeNtSidAuthority, 2); + RtlInitializeSid(SeAliasUsersSid, &SeNtSidAuthority, 2); + RtlInitializeSid(SeAliasGuestsSid, &SeNtSidAuthority, 2); + RtlInitializeSid(SeAliasPowerUsersSid, &SeNtSidAuthority, 2); + RtlInitializeSid(SeAliasAccountOpsSid, &SeNtSidAuthority, 2); + RtlInitializeSid(SeAliasSystemOpsSid, &SeNtSidAuthority, 2); + RtlInitializeSid(SeAliasPrintOpsSid, &SeNtSidAuthority, 2); + RtlInitializeSid(SeAliasBackupOpsSid, &SeNtSidAuthority, 2); + RtlInitializeSid(SeAuthenticatedUsersSid, &SeNtSidAuthority, 1); + RtlInitializeSid(SeRestrictedSid, &SeNtSidAuthority, 1); + RtlInitializeSid(SeAnonymousLogonSid, &SeNtSidAuthority, 1); + + SubAuthority = RtlSubAuthoritySid(SeNullSid, 0); + *SubAuthority = SECURITY_NULL_RID; + SubAuthority = RtlSubAuthoritySid(SeWorldSid, 0); + *SubAuthority = SECURITY_WORLD_RID; + SubAuthority = RtlSubAuthoritySid(SeLocalSid, 0); + *SubAuthority = SECURITY_LOCAL_RID; + SubAuthority = RtlSubAuthoritySid(SeCreatorOwnerSid, 0); + *SubAuthority = SECURITY_CREATOR_OWNER_RID; + SubAuthority = RtlSubAuthoritySid(SeCreatorGroupSid, 0); + *SubAuthority = SECURITY_CREATOR_GROUP_RID; + SubAuthority = RtlSubAuthoritySid(SeCreatorOwnerServerSid, 0); + *SubAuthority = SECURITY_CREATOR_OWNER_SERVER_RID; + SubAuthority = RtlSubAuthoritySid(SeCreatorGroupServerSid, 0); + *SubAuthority = SECURITY_CREATOR_GROUP_SERVER_RID; + SubAuthority = RtlSubAuthoritySid(SeDialupSid, 0); + *SubAuthority = SECURITY_DIALUP_RID; + SubAuthority = RtlSubAuthoritySid(SeNetworkSid, 0); + *SubAuthority = SECURITY_NETWORK_RID; + SubAuthority = RtlSubAuthoritySid(SeBatchSid, 0); + *SubAuthority = SECURITY_BATCH_RID; + SubAuthority = RtlSubAuthoritySid(SeInteractiveSid, 0); + *SubAuthority = SECURITY_INTERACTIVE_RID; + SubAuthority = RtlSubAuthoritySid(SeServiceSid, 0); + *SubAuthority = SECURITY_SERVICE_RID; + SubAuthority = RtlSubAuthoritySid(SePrincipalSelfSid, 0); + *SubAuthority = SECURITY_PRINCIPAL_SELF_RID; + SubAuthority = RtlSubAuthoritySid(SeLocalSystemSid, 0); + *SubAuthority = SECURITY_LOCAL_SYSTEM_RID; + SubAuthority = RtlSubAuthoritySid(SeAuthenticatedUserSid, 0); + *SubAuthority = SECURITY_AUTHENTICATED_USER_RID; + SubAuthority = RtlSubAuthoritySid(SeRestrictedCodeSid, 0); + *SubAuthority = SECURITY_RESTRICTED_CODE_RID; + SubAuthority = RtlSubAuthoritySid(SeAliasAdminsSid, 0); + *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; + SubAuthority = RtlSubAuthoritySid(SeAliasAdminsSid, 1); + *SubAuthority = DOMAIN_ALIAS_RID_ADMINS; + SubAuthority = RtlSubAuthoritySid(SeAliasUsersSid, 0); + *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; + SubAuthority = RtlSubAuthoritySid(SeAliasUsersSid, 1); + *SubAuthority = DOMAIN_ALIAS_RID_USERS; + SubAuthority = RtlSubAuthoritySid(SeAliasGuestsSid, 0); + *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; + SubAuthority = RtlSubAuthoritySid(SeAliasGuestsSid, 1); + *SubAuthority = DOMAIN_ALIAS_RID_GUESTS; + SubAuthority = RtlSubAuthoritySid(SeAliasPowerUsersSid, 0); + *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; + SubAuthority = RtlSubAuthoritySid(SeAliasPowerUsersSid, 1); + *SubAuthority = DOMAIN_ALIAS_RID_POWER_USERS; + SubAuthority = RtlSubAuthoritySid(SeAliasAccountOpsSid, 0); + *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; + SubAuthority = RtlSubAuthoritySid(SeAliasAccountOpsSid, 1); + *SubAuthority = DOMAIN_ALIAS_RID_ACCOUNT_OPS; + SubAuthority = RtlSubAuthoritySid(SeAliasSystemOpsSid, 0); + *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; + SubAuthority = RtlSubAuthoritySid(SeAliasSystemOpsSid, 1); + *SubAuthority = DOMAIN_ALIAS_RID_SYSTEM_OPS; + SubAuthority = RtlSubAuthoritySid(SeAliasPrintOpsSid, 0); + *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; + SubAuthority = RtlSubAuthoritySid(SeAliasPrintOpsSid, 1); + *SubAuthority = DOMAIN_ALIAS_RID_PRINT_OPS; + SubAuthority = RtlSubAuthoritySid(SeAliasBackupOpsSid, 0); + *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; + SubAuthority = RtlSubAuthoritySid(SeAliasBackupOpsSid, 1); + *SubAuthority = DOMAIN_ALIAS_RID_BACKUP_OPS; + SubAuthority = RtlSubAuthoritySid(SeAuthenticatedUsersSid, 0); + *SubAuthority = SECURITY_AUTHENTICATED_USER_RID; + SubAuthority = RtlSubAuthoritySid(SeRestrictedSid, 0); + *SubAuthority = SECURITY_RESTRICTED_CODE_RID; + SubAuthority = RtlSubAuthoritySid(SeAnonymousLogonSid, 0); + *SubAuthority = SECURITY_ANONYMOUS_LOGON_RID; + + return(TRUE); } NTSTATUS @@ -234,86 +230,86 @@ SepCaptureSid(IN PSID InputSid, IN BOOLEAN CaptureIfKernel, OUT PSID *CapturedSid) { - ULONG SidSize = 0; - PISID NewSid, Sid = (PISID)InputSid; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - if(AccessMode != KernelMode) - { - _SEH_TRY + ULONG SidSize = 0; + PISID NewSid, Sid = (PISID)InputSid; + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + if(AccessMode != KernelMode) { - ProbeForRead(Sid, - FIELD_OFFSET(SID, - SubAuthority), - sizeof(UCHAR)); - SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount); - ProbeForRead(Sid, - SidSize, - sizeof(UCHAR)); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(NT_SUCCESS(Status)) - { - /* allocate a SID and copy it */ - NewSid = ExAllocatePool(PoolType, - SidSize); - if(NewSid != NULL) - { _SEH_TRY { - RtlCopyMemory(NewSid, - Sid, - SidSize); - - *CapturedSid = NewSid; + ProbeForRead(Sid, + FIELD_OFFSET(SID, + SubAuthority), + sizeof(UCHAR)); + SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount); + ProbeForRead(Sid, + SidSize, + sizeof(UCHAR)); } _SEH_HANDLE { - ExFreePool(NewSid); - Status = _SEH_GetExceptionCode(); + Status = _SEH_GetExceptionCode(); } _SEH_END; - } - else - { - Status = STATUS_INSUFFICIENT_RESOURCES; - } + + if(NT_SUCCESS(Status)) + { + /* allocate a SID and copy it */ + NewSid = ExAllocatePool(PoolType, + SidSize); + if(NewSid != NULL) + { + _SEH_TRY + { + RtlCopyMemory(NewSid, + Sid, + SidSize); + + *CapturedSid = NewSid; + } + _SEH_HANDLE + { + ExFreePool(NewSid); + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + } } - } - else if(!CaptureIfKernel) - { - *CapturedSid = InputSid; - return STATUS_SUCCESS; - } - else - { - SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount); - - /* allocate a SID and copy it */ - NewSid = ExAllocatePool(PoolType, - SidSize); - if(NewSid != NULL) + else if(!CaptureIfKernel) { - RtlCopyMemory(NewSid, - Sid, - SidSize); - - *CapturedSid = NewSid; + *CapturedSid = InputSid; + return STATUS_SUCCESS; } else { - Status = STATUS_INSUFFICIENT_RESOURCES; + SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount); + + /* allocate a SID and copy it */ + NewSid = ExAllocatePool(PoolType, + SidSize); + if(NewSid != NULL) + { + RtlCopyMemory(NewSid, + Sid, + SidSize); + + *CapturedSid = NewSid; + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } } - } - - return Status; + + return Status; } VOID @@ -322,14 +318,14 @@ SepReleaseSid(IN PSID CapturedSid, IN KPROCESSOR_MODE AccessMode, IN BOOLEAN CaptureIfKernel) { - PAGED_CODE(); - - if(CapturedSid != NULL && - (AccessMode != KernelMode || - (AccessMode == KernelMode && CaptureIfKernel))) - { - ExFreePool(CapturedSid); - } + PAGED_CODE(); + + if(CapturedSid != NULL && + (AccessMode != KernelMode || + (AccessMode == KernelMode && CaptureIfKernel))) + { + ExFreePool(CapturedSid); + } } /* EOF */ diff --git a/reactos/ntoskrnl/se/token.c b/reactos/ntoskrnl/se/token.c index 241e7a31098..c80a5da97f4 100644 --- a/reactos/ntoskrnl/se/token.c +++ b/reactos/ntoskrnl/se/token.c @@ -7,33 +7,31 @@ * PROGRAMMERS: David Welch */ -/* INCLUDES *****************************************************************/ +/* INCLUDES *******************************************************************/ #include - #define NDEBUG -#include +#include #if defined (ALLOC_PRAGMA) #pragma alloc_text(INIT, SepInitializeTokenImplementation) #endif - -/* GLOBALS *******************************************************************/ +/* GLOBALS ********************************************************************/ POBJECT_TYPE SepTokenObjectType = NULL; ERESOURCE SepTokenLock; static GENERIC_MAPPING SepTokenMapping = {TOKEN_READ, - TOKEN_WRITE, - TOKEN_EXECUTE, - TOKEN_ALL_ACCESS}; + TOKEN_WRITE, + TOKEN_EXECUTE, +TOKEN_ALL_ACCESS}; static const INFORMATION_CLASS_INFO SeTokenInformationClass[] = { - + /* Class 0 not used, blame M$! */ ICI_SQ_SAME( 0, 0, 0), - + /* TokenUser */ ICI_SQ_SAME( sizeof(TOKEN_USER), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ), /* TokenGroups */ @@ -72,19 +70,45 @@ static const INFORMATION_CLASS_INFO SeTokenInformationClass[] = { /* FUNCTIONS *****************************************************************/ +static NTSTATUS +SepCompareTokens(IN PTOKEN FirstToken, + IN PTOKEN SecondToken, + OUT PBOOLEAN Equal) +{ + BOOLEAN Restricted, IsEqual = FALSE; + + ASSERT(FirstToken != SecondToken); + + /* FIXME: Check if every SID that is present in either token is also present in the other one */ + + Restricted = SeTokenIsRestricted(FirstToken); + if (Restricted == SeTokenIsRestricted(SecondToken)) + { + if (Restricted) + { + /* FIXME: Check if every SID that is restricted in either token is also restricted in the other one */ + } + + /* FIXME: Check if every privilege that is present in either token is also present in the other one */ + } + + *Equal = IsEqual; + return STATUS_SUCCESS; +} + VOID NTAPI SepFreeProxyData(PVOID ProxyData) { - UNIMPLEMENTED; + UNIMPLEMENTED; } NTSTATUS NTAPI SepCopyProxyData(PVOID* Dest, PVOID Src) { - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + UNIMPLEMENTED; + return(STATUS_NOT_IMPLEMENTED); } NTSTATUS @@ -95,24 +119,24 @@ SeExchangePrimaryToken(PEPROCESS Process, { PTOKEN OldToken; PTOKEN NewToken = (PTOKEN)NewTokenP; - + PAGED_CODE(); - + if (NewToken->TokenType != TokenPrimary) return(STATUS_BAD_TOKEN_TYPE); if (NewToken->TokenInUse) return(STATUS_TOKEN_ALREADY_IN_USE); - + /* Mark new token in use */ NewToken->TokenInUse = 1; - + /* Reference the New Token */ ObReferenceObject(NewToken); - + /* Replace the old with the new */ OldToken = ObFastReplaceObject(&Process->Token, NewToken); - + /* Mark the Old Token as free */ OldToken->TokenInUse = 0; - + *OldTokenP = (PACCESS_TOKEN)OldToken; return STATUS_SUCCESS; } @@ -122,10 +146,10 @@ NTAPI SeDeassignPrimaryToken(PEPROCESS Process) { PTOKEN OldToken; - + /* Remove the Token */ OldToken = ObFastReplaceObject(&Process->Token, NULL); - + /* Mark the Old Token as free */ OldToken->TokenInUse = 0; } @@ -134,16 +158,16 @@ static ULONG RtlLengthSidAndAttributes(ULONG Count, PSID_AND_ATTRIBUTES Src) { - ULONG i; - ULONG uLength; - - PAGED_CODE(); - - uLength = Count * sizeof(SID_AND_ATTRIBUTES); - for (i = 0; i < Count; i++) - uLength += RtlLengthSid(Src[i].Sid); - - return(uLength); + ULONG i; + ULONG uLength; + + PAGED_CODE(); + + uLength = Count * sizeof(SID_AND_ATTRIBUTES); + for (i = 0; i < Count; i++) + uLength += RtlLengthSid(Src[i].Sid); + + return(uLength); } @@ -153,41 +177,41 @@ SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token, PSID PrimaryGroup, PSID DefaultOwner) { - ULONG i; - - Token->PrimaryGroup = 0; - - if (DefaultOwner) + ULONG i; + + Token->PrimaryGroup = 0; + + if (DefaultOwner) { - Token->DefaultOwnerIndex = Token->UserAndGroupCount; + Token->DefaultOwnerIndex = Token->UserAndGroupCount; } - - /* Validate and set the primary group and user pointers */ - for (i = 0; i < Token->UserAndGroupCount; i++) + + /* Validate and set the primary group and user pointers */ + for (i = 0; i < Token->UserAndGroupCount; i++) { - if (DefaultOwner && - RtlEqualSid(Token->UserAndGroups[i].Sid, DefaultOwner)) + if (DefaultOwner && + RtlEqualSid(Token->UserAndGroups[i].Sid, DefaultOwner)) { - Token->DefaultOwnerIndex = i; + Token->DefaultOwnerIndex = i; } - - if (RtlEqualSid(Token->UserAndGroups[i].Sid, PrimaryGroup)) + + if (RtlEqualSid(Token->UserAndGroups[i].Sid, PrimaryGroup)) { - Token->PrimaryGroup = Token->UserAndGroups[i].Sid; + Token->PrimaryGroup = Token->UserAndGroups[i].Sid; } } - - if (Token->DefaultOwnerIndex == Token->UserAndGroupCount) + + if (Token->DefaultOwnerIndex == Token->UserAndGroupCount) { - return(STATUS_INVALID_OWNER); + return(STATUS_INVALID_OWNER); } - - if (Token->PrimaryGroup == 0) + + if (Token->PrimaryGroup == 0) { - return(STATUS_INVALID_PRIMARY_GROUP); + return(STATUS_INVALID_PRIMARY_GROUP); } - - return(STATUS_SUCCESS); + + return(STATUS_SUCCESS); } @@ -201,126 +225,126 @@ SepDuplicateToken(PTOKEN Token, KPROCESSOR_MODE PreviousMode, PTOKEN* NewAccessToken) { - ULONG uLength; - ULONG i; - PVOID EndMem; - PTOKEN AccessToken; - NTSTATUS Status; - - PAGED_CODE(); - - Status = ObCreateObject(PreviousMode, - SepTokenObjectType, - ObjectAttributes, - PreviousMode, - NULL, - sizeof(TOKEN), - 0, - 0, - (PVOID*)&AccessToken); - if (!NT_SUCCESS(Status)) + ULONG uLength; + ULONG i; + PVOID EndMem; + PTOKEN AccessToken; + NTSTATUS Status; + + PAGED_CODE(); + + Status = ObCreateObject(PreviousMode, + SepTokenObjectType, + ObjectAttributes, + PreviousMode, + NULL, + sizeof(TOKEN), + 0, + 0, + (PVOID*)&AccessToken); + if (!NT_SUCCESS(Status)) { - DPRINT1("ObCreateObject() failed (Status %lx)\n"); - return(Status); + DPRINT1("ObCreateObject() failed (Status %lx)\n"); + return(Status); } - - Status = ZwAllocateLocallyUniqueId(&AccessToken->TokenId); - if (!NT_SUCCESS(Status)) + + Status = ZwAllocateLocallyUniqueId(&AccessToken->TokenId); + if (!NT_SUCCESS(Status)) { - ObDereferenceObject(AccessToken); - return(Status); + ObDereferenceObject(AccessToken); + return(Status); } - - Status = ZwAllocateLocallyUniqueId(&AccessToken->ModifiedId); - if (!NT_SUCCESS(Status)) + + Status = ZwAllocateLocallyUniqueId(&AccessToken->ModifiedId); + if (!NT_SUCCESS(Status)) { - ObDereferenceObject(AccessToken); - return(Status); + ObDereferenceObject(AccessToken); + return(Status); } - - AccessToken->TokenLock = &SepTokenLock; - - AccessToken->TokenInUse = 0; - AccessToken->TokenType = TokenType; - AccessToken->ImpersonationLevel = Level; - RtlCopyLuid(&AccessToken->AuthenticationId, &Token->AuthenticationId); - - AccessToken->TokenSource.SourceIdentifier.LowPart = Token->TokenSource.SourceIdentifier.LowPart; - AccessToken->TokenSource.SourceIdentifier.HighPart = Token->TokenSource.SourceIdentifier.HighPart; - memcpy(AccessToken->TokenSource.SourceName, - Token->TokenSource.SourceName, - sizeof(Token->TokenSource.SourceName)); - AccessToken->ExpirationTime.QuadPart = Token->ExpirationTime.QuadPart; - AccessToken->UserAndGroupCount = Token->UserAndGroupCount; - AccessToken->DefaultOwnerIndex = Token->DefaultOwnerIndex; - - uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount; - for (i = 0; i < Token->UserAndGroupCount; i++) - uLength += RtlLengthSid(Token->UserAndGroups[i].Sid); - - AccessToken->UserAndGroups = + + AccessToken->TokenLock = &SepTokenLock; + + AccessToken->TokenInUse = 0; + AccessToken->TokenType = TokenType; + AccessToken->ImpersonationLevel = Level; + RtlCopyLuid(&AccessToken->AuthenticationId, &Token->AuthenticationId); + + AccessToken->TokenSource.SourceIdentifier.LowPart = Token->TokenSource.SourceIdentifier.LowPart; + AccessToken->TokenSource.SourceIdentifier.HighPart = Token->TokenSource.SourceIdentifier.HighPart; + memcpy(AccessToken->TokenSource.SourceName, + Token->TokenSource.SourceName, + sizeof(Token->TokenSource.SourceName)); + AccessToken->ExpirationTime.QuadPart = Token->ExpirationTime.QuadPart; + AccessToken->UserAndGroupCount = Token->UserAndGroupCount; + AccessToken->DefaultOwnerIndex = Token->DefaultOwnerIndex; + + uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount; + for (i = 0; i < Token->UserAndGroupCount; i++) + uLength += RtlLengthSid(Token->UserAndGroups[i].Sid); + + AccessToken->UserAndGroups = (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, uLength, TAG('T', 'O', 'K', 'u')); - - EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount]; - - Status = RtlCopySidAndAttributesArray(AccessToken->UserAndGroupCount, - Token->UserAndGroups, - uLength, - AccessToken->UserAndGroups, - EndMem, - &EndMem, - &uLength); - if (NT_SUCCESS(Status)) + + EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount]; + + Status = RtlCopySidAndAttributesArray(AccessToken->UserAndGroupCount, + Token->UserAndGroups, + uLength, + AccessToken->UserAndGroups, + EndMem, + &EndMem, + &uLength); + if (NT_SUCCESS(Status)) { - Status = SepFindPrimaryGroupAndDefaultOwner( - AccessToken, - Token->PrimaryGroup, - 0); + Status = SepFindPrimaryGroupAndDefaultOwner( + AccessToken, + Token->PrimaryGroup, + 0); } - - if (NT_SUCCESS(Status)) + + if (NT_SUCCESS(Status)) { - AccessToken->PrivilegeCount = Token->PrivilegeCount; - - uLength = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); - AccessToken->Privileges = + AccessToken->PrivilegeCount = Token->PrivilegeCount; + + uLength = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); + AccessToken->Privileges = (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, uLength, TAG('T', 'O', 'K', 'p')); - - for (i = 0; i < AccessToken->PrivilegeCount; i++) + + for (i = 0; i < AccessToken->PrivilegeCount; i++) { - RtlCopyLuid(&AccessToken->Privileges[i].Luid, - &Token->Privileges[i].Luid); - AccessToken->Privileges[i].Attributes = + RtlCopyLuid(&AccessToken->Privileges[i].Luid, + &Token->Privileges[i].Luid); + AccessToken->Privileges[i].Attributes = Token->Privileges[i].Attributes; } - - if ( Token->DefaultDacl ) + + if ( Token->DefaultDacl ) { - AccessToken->DefaultDacl = + AccessToken->DefaultDacl = (PACL) ExAllocatePoolWithTag(PagedPool, Token->DefaultDacl->AclSize, TAG('T', 'O', 'K', 'd')); - memcpy(AccessToken->DefaultDacl, - Token->DefaultDacl, - Token->DefaultDacl->AclSize); + memcpy(AccessToken->DefaultDacl, + Token->DefaultDacl, + Token->DefaultDacl->AclSize); } - else + else { - AccessToken->DefaultDacl = 0; + AccessToken->DefaultDacl = 0; } } - - if ( NT_SUCCESS(Status) ) + + if ( NT_SUCCESS(Status) ) { - *NewAccessToken = AccessToken; - return(STATUS_SUCCESS); + *NewAccessToken = AccessToken; + return(STATUS_SUCCESS); } - - return(Status); + + return(Status); } NTSTATUS @@ -333,7 +357,7 @@ SeSubProcessToken(IN PTOKEN ParentToken, PTOKEN NewToken; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; - + /* Initialize the attributes and duplicate it */ InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = SepDuplicateToken(ParentToken, @@ -357,12 +381,12 @@ SeSubProcessToken(IN PTOKEN ParentToken, /* Set the session ID */ NewToken->SessionId = SessionId; NewToken->TokenInUse = InUse; - + /* Return the token */ *Token = NewToken; } } - + /* Return status */ return Status; } @@ -374,253 +398,70 @@ SeIsTokenChild(IN PTOKEN Token, { PTOKEN ProcessToken; LUID ProcessLuid, CallerLuid; - + /* Assume failure */ *IsChild = FALSE; - + /* Reference the process token */ ProcessToken = PsReferencePrimaryToken(PsGetCurrentProcess()); - + /* Get the ID */ ProcessLuid = ProcessToken->TokenId; - + /* Dereference the token */ ObFastDereferenceObject(&PsGetCurrentProcess()->Token, ProcessToken); - + /* Get our LUID */ CallerLuid = Token->TokenId; - + /* Compare the LUIDs */ if (RtlEqualLuid(&CallerLuid, &ProcessLuid)) *IsChild = TRUE; - + /* Return success */ return STATUS_SUCCESS; } -/* - * @unimplemented - */ NTSTATUS STDCALL -SeAppendPrivileges( - PACCESS_STATE AccessState, - PPRIVILEGE_SET Privileges - ) +SeCopyClientToken(IN PACCESS_TOKEN Token, + IN SECURITY_IMPERSONATION_LEVEL Level, + IN KPROCESSOR_MODE PreviousMode, + OUT PACCESS_TOKEN* NewToken) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -STDCALL -SeCopyClientToken(PACCESS_TOKEN Token, - SECURITY_IMPERSONATION_LEVEL Level, - KPROCESSOR_MODE PreviousMode, - PACCESS_TOKEN* NewToken) -{ - NTSTATUS Status; - OBJECT_ATTRIBUTES ObjectAttributes; - - PAGED_CODE(); - - InitializeObjectAttributes(&ObjectAttributes, - NULL, - 0, - NULL, - NULL); - Status = SepDuplicateToken(Token, - &ObjectAttributes, - FALSE, - TokenImpersonation, - Level, - PreviousMode, - (PTOKEN*)NewToken); - - return(Status); -} - - -/* - * @implemented - */ -NTSTATUS -NTAPI -SeCreateClientSecurity(IN PETHREAD Thread, - IN PSECURITY_QUALITY_OF_SERVICE Qos, - IN BOOLEAN RemoteClient, - OUT PSECURITY_CLIENT_CONTEXT ClientContext) -{ - TOKEN_TYPE TokenType; - BOOLEAN ThreadEffectiveOnly; - SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; - PACCESS_TOKEN Token; NTSTATUS Status; - PACCESS_TOKEN NewToken; + OBJECT_ATTRIBUTES ObjectAttributes; + PAGED_CODE(); - - Token = PsReferenceEffectiveToken(Thread, - &TokenType, - &ThreadEffectiveOnly, - &ImpersonationLevel); - if (TokenType != TokenImpersonation) - { - ClientContext->DirectAccessEffectiveOnly = Qos->EffectiveOnly; - } - else - { - if (Qos->ImpersonationLevel > ImpersonationLevel) - { - if (Token) ObDereferenceObject(Token); - return STATUS_BAD_IMPERSONATION_LEVEL; - } - - if ((ImpersonationLevel == SecurityAnonymous) || - (ImpersonationLevel == SecurityIdentification) || - ((RemoteClient) && (ImpersonationLevel != SecurityDelegation))) - { - if (Token) ObDereferenceObject(Token); - return STATUS_BAD_IMPERSONATION_LEVEL; - } - - ClientContext->DirectAccessEffectiveOnly = ((ThreadEffectiveOnly) || - (Qos->EffectiveOnly)) ? - TRUE : FALSE; - } - - if (Qos->ContextTrackingMode == SECURITY_STATIC_TRACKING) - { - ClientContext->DirectlyAccessClientToken = FALSE; - Status = SeCopyClientToken(Token, ImpersonationLevel, 0, &NewToken); - if (!NT_SUCCESS(Status)) return Status; - } - else - { - ClientContext->DirectlyAccessClientToken = TRUE; - if (RemoteClient != FALSE) - { -#if 0 - SeGetTokenControlInformation(Token, - &ClientContext->ClientTokenControl); -#endif - } - - NewToken = Token; - } - - ClientContext->SecurityQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); - ClientContext->SecurityQos.ImpersonationLevel = Qos->ImpersonationLevel; - ClientContext->SecurityQos.ContextTrackingMode = Qos->ContextTrackingMode; - ClientContext->SecurityQos.EffectiveOnly = Qos->EffectiveOnly; - ClientContext->ServerIsRemote = RemoteClient; - ClientContext->ClientToken = NewToken; - return STATUS_SUCCESS; + + InitializeObjectAttributes(&ObjectAttributes, + NULL, + 0, + NULL, + NULL); + Status = SepDuplicateToken(Token, + &ObjectAttributes, + FALSE, + TokenImpersonation, + Level, + PreviousMode, + (PTOKEN*)NewToken); + + return(Status); } -/* - * @unimplemented - */ -NTSTATUS -STDCALL -SeCreateClientSecurityFromSubjectContext( - IN PSECURITY_SUBJECT_CONTEXT SubjectContext, - IN PSECURITY_QUALITY_OF_SERVICE ClientSecurityQos, - IN BOOLEAN ServerIsRemote, - OUT PSECURITY_CLIENT_CONTEXT ClientContext - ) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/* - * @unimplemented - */ -NTSTATUS -STDCALL -SeFilterToken( - IN PACCESS_TOKEN ExistingToken, - IN ULONG Flags, - IN PTOKEN_GROUPS SidsToDisable OPTIONAL, - IN PTOKEN_PRIVILEGES PrivilegesToDelete OPTIONAL, - IN PTOKEN_GROUPS RestrictedSids OPTIONAL, - OUT PACCESS_TOKEN * FilteredToken - ) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/* - * @unimplemented - */ -VOID -STDCALL -SeFreePrivileges( - IN PPRIVILEGE_SET Privileges - ) -{ - UNIMPLEMENTED; -} - - -/* - * @unimplemented - */ -NTSTATUS -STDCALL -SeImpersonateClientEx( - IN PSECURITY_CLIENT_CONTEXT ClientContext, - IN PETHREAD ServerThread OPTIONAL - ) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/* - * @implemented - */ -VOID STDCALL -SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext, - IN PETHREAD ServerThread OPTIONAL) -{ - UCHAR b; - - PAGED_CODE(); - - if (ClientContext->DirectlyAccessClientToken == FALSE) - { - b = ClientContext->SecurityQos.EffectiveOnly; - } - else - { - b = ClientContext->DirectAccessEffectiveOnly; - } - if (ServerThread == NULL) - { - ServerThread = PsGetCurrentThread(); - } - PsImpersonateClient(ServerThread, - ClientContext->ClientToken, - 1, - b, - ClientContext->SecurityQos.ImpersonationLevel); -} - - VOID STDCALL SepDeleteToken(PVOID ObjectBody) { - PTOKEN AccessToken = (PTOKEN)ObjectBody; - - if (AccessToken->UserAndGroups) - ExFreePool(AccessToken->UserAndGroups); - - if (AccessToken->Privileges) - ExFreePool(AccessToken->Privileges); - - if (AccessToken->DefaultDacl) - ExFreePool(AccessToken->DefaultDacl); + PTOKEN AccessToken = (PTOKEN)ObjectBody; + + if (AccessToken->UserAndGroups) + ExFreePool(AccessToken->UserAndGroups); + + if (AccessToken->Privileges) + ExFreePool(AccessToken->Privileges); + + if (AccessToken->DefaultDacl) + ExFreePool(AccessToken->DefaultDacl); } @@ -635,7 +476,7 @@ SepInitializeTokenImplementation(VOID) ExInitializeResource(&SepTokenLock); DPRINT("Creating Token Object Type\n"); - + /* Initialize the Token type */ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"Token"); @@ -651,6 +492,353 @@ SepInitializeTokenImplementation(VOID) ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &SepTokenObjectType); } +VOID +NTAPI +SeAssignPrimaryToken(IN PEPROCESS Process, + IN PTOKEN Token) +{ + PAGED_CODE(); + + /* Sanity checks */ + ASSERT(Token->TokenType == TokenPrimary); + ASSERT(!Token->TokenInUse); + + /* Clean any previous token */ + if (Process->Token.Object) SeDeassignPrimaryToken(Process); + + /* Set the new token */ + ObReferenceObject(Token); + Token->TokenInUse = TRUE; + ObInitializeFastReference(&Process->Token, Token); +} + +PTOKEN +STDCALL +SepCreateSystemProcessToken(VOID) +{ + NTSTATUS Status; + ULONG uSize; + ULONG i; + ULONG uLocalSystemLength; + ULONG uWorldLength; + ULONG uAuthUserLength; + ULONG uAdminsLength; + PTOKEN AccessToken; + PVOID SidArea; + + PAGED_CODE(); + + uLocalSystemLength = RtlLengthSid(SeLocalSystemSid); + uWorldLength = RtlLengthSid(SeWorldSid); + uAuthUserLength = RtlLengthSid(SeAuthenticatedUserSid); + uAdminsLength = RtlLengthSid(SeAliasAdminsSid); + + /* + * Initialize the token + */ + Status = ObCreateObject(KernelMode, + SepTokenObjectType, + NULL, + KernelMode, + NULL, + sizeof(TOKEN), + 0, + 0, + (PVOID*)&AccessToken); + if (!NT_SUCCESS(Status)) + { + return NULL; + } + + Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(AccessToken); + return NULL; + } + + Status = ExpAllocateLocallyUniqueId(&AccessToken->ModifiedId); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(AccessToken); + return NULL; + } + + Status = ExpAllocateLocallyUniqueId(&AccessToken->AuthenticationId); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(AccessToken); + return NULL; + } + + AccessToken->TokenLock = &SepTokenLock; + + AccessToken->TokenType = TokenPrimary; + AccessToken->ImpersonationLevel = SecurityDelegation; + AccessToken->TokenSource.SourceIdentifier.LowPart = 0; + AccessToken->TokenSource.SourceIdentifier.HighPart = 0; + memcpy(AccessToken->TokenSource.SourceName, "SeMgr\0\0\0", 8); + AccessToken->ExpirationTime.QuadPart = -1; + AccessToken->UserAndGroupCount = 4; + + uSize = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount; + uSize += uLocalSystemLength; + uSize += uWorldLength; + uSize += uAuthUserLength; + uSize += uAdminsLength; + + AccessToken->UserAndGroups = + (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, + uSize, + TAG('T', 'O', 'K', 'u')); + SidArea = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount]; + + i = 0; + AccessToken->UserAndGroups[i].Sid = (PSID) SidArea; + AccessToken->UserAndGroups[i++].Attributes = 0; + RtlCopySid(uLocalSystemLength, SidArea, SeLocalSystemSid); + SidArea = (char*)SidArea + uLocalSystemLength; + + AccessToken->DefaultOwnerIndex = i; + AccessToken->UserAndGroups[i].Sid = (PSID) SidArea; + AccessToken->PrimaryGroup = (PSID) SidArea; + AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT; + Status = RtlCopySid(uAdminsLength, SidArea, SeAliasAdminsSid); + SidArea = (char*)SidArea + uAdminsLength; + + AccessToken->UserAndGroups[i].Sid = (PSID) SidArea; + AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY; + RtlCopySid(uWorldLength, SidArea, SeWorldSid); + SidArea = (char*)SidArea + uWorldLength; + + AccessToken->UserAndGroups[i].Sid = (PSID) SidArea; + AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY; + RtlCopySid(uAuthUserLength, SidArea, SeAuthenticatedUserSid); + SidArea = (char*)SidArea + uAuthUserLength; + + AccessToken->PrivilegeCount = 20; + + uSize = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); + AccessToken->Privileges = + (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, + uSize, + TAG('T', 'O', 'K', 'p')); + + i = 0; + AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + AccessToken->Privileges[i++].Luid = SeTcbPrivilege; + + AccessToken->Privileges[i].Attributes = 0; + AccessToken->Privileges[i++].Luid = SeCreateTokenPrivilege; + + AccessToken->Privileges[i].Attributes = 0; + AccessToken->Privileges[i++].Luid = SeTakeOwnershipPrivilege; + + AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + AccessToken->Privileges[i++].Luid = SeCreatePagefilePrivilege; + + AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + AccessToken->Privileges[i++].Luid = SeLockMemoryPrivilege; + + AccessToken->Privileges[i].Attributes = 0; + AccessToken->Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege; + + AccessToken->Privileges[i].Attributes = 0; + AccessToken->Privileges[i++].Luid = SeIncreaseQuotaPrivilege; + + AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + AccessToken->Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege; + + AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + AccessToken->Privileges[i++].Luid = SeCreatePermanentPrivilege; + + AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + AccessToken->Privileges[i++].Luid = SeDebugPrivilege; + + AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + AccessToken->Privileges[i++].Luid = SeAuditPrivilege; + + AccessToken->Privileges[i].Attributes = 0; + AccessToken->Privileges[i++].Luid = SeSecurityPrivilege; + + AccessToken->Privileges[i].Attributes = 0; + AccessToken->Privileges[i++].Luid = SeSystemEnvironmentPrivilege; + + AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + AccessToken->Privileges[i++].Luid = SeChangeNotifyPrivilege; + + AccessToken->Privileges[i].Attributes = 0; + AccessToken->Privileges[i++].Luid = SeBackupPrivilege; + + AccessToken->Privileges[i].Attributes = 0; + AccessToken->Privileges[i++].Luid = SeRestorePrivilege; + + AccessToken->Privileges[i].Attributes = 0; + AccessToken->Privileges[i++].Luid = SeShutdownPrivilege; + + AccessToken->Privileges[i].Attributes = 0; + AccessToken->Privileges[i++].Luid = SeLoadDriverPrivilege; + + AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + AccessToken->Privileges[i++].Luid = SeProfileSingleProcessPrivilege; + + AccessToken->Privileges[i].Attributes = 0; + AccessToken->Privileges[i++].Luid = SeSystemtimePrivilege; +#if 0 + AccessToken->Privileges[i].Attributes = 0; + AccessToken->Privileges[i++].Luid = SeUndockPrivilege; + + AccessToken->Privileges[i].Attributes = 0; + AccessToken->Privileges[i++].Luid = SeManageVolumePrivilege; +#endif + + ASSERT(i == 20); + + uSize = sizeof(ACL); + uSize += sizeof(ACE) + uLocalSystemLength; + uSize += sizeof(ACE) + uAdminsLength; + uSize = (uSize & (~3)) + 8; + AccessToken->DefaultDacl = + (PACL) ExAllocatePoolWithTag(PagedPool, + uSize, + TAG('T', 'O', 'K', 'd')); + Status = RtlCreateAcl(AccessToken->DefaultDacl, uSize, ACL_REVISION); + if ( NT_SUCCESS(Status) ) + { + Status = RtlAddAccessAllowedAce(AccessToken->DefaultDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); + } + + if ( NT_SUCCESS(Status) ) + { + Status = RtlAddAccessAllowedAce(AccessToken->DefaultDacl, ACL_REVISION, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE|READ_CONTROL, SeAliasAdminsSid); + } + + if ( ! NT_SUCCESS(Status) ) + { + ObDereferenceObject(AccessToken); + return NULL; + } + + return AccessToken; +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * @unimplemented + */ +NTSTATUS +STDCALL +SeFilterToken(IN PACCESS_TOKEN ExistingToken, + IN ULONG Flags, + IN PTOKEN_GROUPS SidsToDisable OPTIONAL, + IN PTOKEN_PRIVILEGES PrivilegesToDelete OPTIONAL, + IN PTOKEN_GROUPS RestrictedSids OPTIONAL, + OUT PACCESS_TOKEN * FilteredToken) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @unimplemented + */ +NTSTATUS +STDCALL +SeQueryInformationToken(IN PACCESS_TOKEN Token, + IN TOKEN_INFORMATION_CLASS TokenInformationClass, + OUT PVOID *TokenInformation) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @implemented + */ +NTSTATUS +STDCALL +SeQuerySessionIdToken(IN PACCESS_TOKEN Token, + IN PULONG pSessionId) +{ + *pSessionId = ((PTOKEN)Token)->SessionId; + return STATUS_SUCCESS; +} + +/* + * @implemented + */ +NTSTATUS STDCALL +SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token, + OUT PLUID LogonId) +{ + PAGED_CODE(); + + *LogonId = ((PTOKEN)Token)->AuthenticationId; + + return STATUS_SUCCESS; +} + + +/* + * @implemented + */ +SECURITY_IMPERSONATION_LEVEL +STDCALL +SeTokenImpersonationLevel(IN PACCESS_TOKEN Token) +{ + PAGED_CODE(); + + return ((PTOKEN)Token)->ImpersonationLevel; +} + + +/* + * @implemented + */ +TOKEN_TYPE STDCALL +SeTokenType(IN PACCESS_TOKEN Token) +{ + PAGED_CODE(); + + return ((PTOKEN)Token)->TokenType; +} + + +/* + * @implemented + */ +BOOLEAN +STDCALL +SeTokenIsAdmin(IN PACCESS_TOKEN Token) +{ + PAGED_CODE(); + return (((PTOKEN)Token)->TokenFlags & TOKEN_WRITE_RESTRICTED) != 0; +} + +/* + * @implemented + */ +BOOLEAN +STDCALL +SeTokenIsRestricted(IN PACCESS_TOKEN Token) +{ + PAGED_CODE(); + return (((PTOKEN)Token)->TokenFlags & TOKEN_IS_RESTRICTED) != 0; +} + +/* + * @implemented + */ +BOOLEAN +STDCALL +SeTokenIsWriteRestricted(IN PACCESS_TOKEN Token) +{ + PAGED_CODE(); + return (((PTOKEN)Token)->TokenFlags & TOKEN_HAS_RESTORE_PRIVILEGE) != 0; +} + +/* SYSTEM CALLS ***************************************************************/ /* * @implemented @@ -662,582 +850,554 @@ NtQueryInformationToken(IN HANDLE TokenHandle, IN ULONG TokenInformationLength, OUT PULONG ReturnLength) { - union - { - PVOID Ptr; - ULONG Ulong; - } Unused; - PTOKEN Token; - ULONG RequiredLength; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - /* Check buffers and class validity */ - Status = DefaultQueryInfoBufferCheck(TokenInformationClass, - SeTokenInformationClass, - sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]), - TokenInformation, - TokenInformationLength, - ReturnLength, - PreviousMode); - - if(!NT_SUCCESS(Status)) - { - DPRINT("NtQueryInformationToken() failed, Status: 0x%x\n", Status); - return Status; - } - - Status = ObReferenceObjectByHandle(TokenHandle, - (TokenInformationClass == TokenSource) ? TOKEN_QUERY_SOURCE : TOKEN_QUERY, - SepTokenObjectType, - PreviousMode, - (PVOID*)&Token, - NULL); - if (NT_SUCCESS(Status)) - { - switch (TokenInformationClass) + union { - case TokenUser: - { - PTOKEN_USER tu = (PTOKEN_USER)TokenInformation; - - DPRINT("NtQueryInformationToken(TokenUser)\n"); - RequiredLength = sizeof(TOKEN_USER) + - RtlLengthSid(Token->UserAndGroups[0].Sid); - - _SEH_TRY - { - if(TokenInformationLength >= RequiredLength) - { - Status = RtlCopySidAndAttributesArray(1, - &Token->UserAndGroups[0], - RequiredLength - sizeof(TOKEN_USER), - &tu->User, - (PSID)(tu + 1), - &Unused.Ptr, - &Unused.Ulong); - } - else - { - Status = STATUS_BUFFER_TOO_SMALL; - } - - if(ReturnLength != NULL) - { - *ReturnLength = RequiredLength; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - break; - } - - case TokenGroups: - { - PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation; - - DPRINT("NtQueryInformationToken(TokenGroups)\n"); - RequiredLength = sizeof(tg->GroupCount) + - RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]); - - _SEH_TRY - { - if(TokenInformationLength >= RequiredLength) - { - ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) - - ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES)); - PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) + - ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES))); - - tg->GroupCount = Token->UserAndGroupCount - 1; - Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1, - &Token->UserAndGroups[1], - SidLen, - &tg->Groups[0], - (PSID)Sid, - &Unused.Ptr, - &Unused.Ulong); - } - else - { - Status = STATUS_BUFFER_TOO_SMALL; - } - - if(ReturnLength != NULL) - { - *ReturnLength = RequiredLength; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - break; - } - - case TokenPrivileges: - { - PTOKEN_PRIVILEGES tp = (PTOKEN_PRIVILEGES)TokenInformation; - - DPRINT("NtQueryInformationToken(TokenPrivileges)\n"); - RequiredLength = sizeof(tp->PrivilegeCount) + - (Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); - - _SEH_TRY - { - if(TokenInformationLength >= RequiredLength) - { - tp->PrivilegeCount = Token->PrivilegeCount; - RtlCopyLuidAndAttributesArray(Token->PrivilegeCount, - Token->Privileges, - &tp->Privileges[0]); - } - else - { - Status = STATUS_BUFFER_TOO_SMALL; - } - - if(ReturnLength != NULL) - { - *ReturnLength = RequiredLength; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - break; - } - - case TokenOwner: - { - ULONG SidLen; - PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation; - - DPRINT("NtQueryInformationToken(TokenOwner)\n"); - SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); - RequiredLength = sizeof(TOKEN_OWNER) + SidLen; - - _SEH_TRY - { - if(TokenInformationLength >= RequiredLength) - { - to->Owner = (PSID)(to + 1); - Status = RtlCopySid(SidLen, - to->Owner, - Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); - } - else - { - Status = STATUS_BUFFER_TOO_SMALL; - } - - if(ReturnLength != NULL) - { - *ReturnLength = RequiredLength; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - break; - } - - case TokenPrimaryGroup: - { - ULONG SidLen; - PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation; - - DPRINT("NtQueryInformationToken(TokenPrimaryGroup)\n"); - SidLen = RtlLengthSid(Token->PrimaryGroup); - RequiredLength = sizeof(TOKEN_PRIMARY_GROUP) + SidLen; - - _SEH_TRY - { - if(TokenInformationLength >= RequiredLength) - { - tpg->PrimaryGroup = (PSID)(tpg + 1); - Status = RtlCopySid(SidLen, - tpg->PrimaryGroup, - Token->PrimaryGroup); - } - else - { - Status = STATUS_BUFFER_TOO_SMALL; - } - - if(ReturnLength != NULL) - { - *ReturnLength = RequiredLength; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - break; - } - - case TokenDefaultDacl: - { - PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation; - - DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n"); - RequiredLength = sizeof(TOKEN_DEFAULT_DACL); - - if(Token->DefaultDacl != NULL) - { - RequiredLength += Token->DefaultDacl->AclSize; - } - - _SEH_TRY - { - if(TokenInformationLength >= RequiredLength) - { - if(Token->DefaultDacl != NULL) - { - tdd->DefaultDacl = (PACL)(tdd + 1); - RtlCopyMemory(tdd->DefaultDacl, - Token->DefaultDacl, - Token->DefaultDacl->AclSize); - } - else - { - tdd->DefaultDacl = NULL; - } - } - else - { - Status = STATUS_BUFFER_TOO_SMALL; - } - - if(ReturnLength != NULL) - { - *ReturnLength = RequiredLength; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - break; - } - - case TokenSource: - { - PTOKEN_SOURCE ts = (PTOKEN_SOURCE)TokenInformation; - - DPRINT("NtQueryInformationToken(TokenSource)\n"); - RequiredLength = sizeof(TOKEN_SOURCE); - - _SEH_TRY - { - if(TokenInformationLength >= RequiredLength) - { - *ts = Token->TokenSource; - } - else - { - Status = STATUS_BUFFER_TOO_SMALL; - } - - if(ReturnLength != NULL) - { - *ReturnLength = RequiredLength; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - break; - } - - case TokenType: - { - PTOKEN_TYPE tt = (PTOKEN_TYPE)TokenInformation; - - DPRINT("NtQueryInformationToken(TokenType)\n"); - RequiredLength = sizeof(TOKEN_TYPE); - - _SEH_TRY - { - if(TokenInformationLength >= RequiredLength) - { - *tt = Token->TokenType; - } - else - { - Status = STATUS_BUFFER_TOO_SMALL; - } - - if(ReturnLength != NULL) - { - *ReturnLength = RequiredLength; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - break; - } - - case TokenImpersonationLevel: - { - PSECURITY_IMPERSONATION_LEVEL sil = (PSECURITY_IMPERSONATION_LEVEL)TokenInformation; - - DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n"); - RequiredLength = sizeof(SECURITY_IMPERSONATION_LEVEL); - - _SEH_TRY - { - if(TokenInformationLength >= RequiredLength) - { - *sil = Token->ImpersonationLevel; - } - else - { - Status = STATUS_BUFFER_TOO_SMALL; - } - - if(ReturnLength != NULL) - { - *ReturnLength = RequiredLength; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - break; - } - - case TokenStatistics: - { - PTOKEN_STATISTICS ts = (PTOKEN_STATISTICS)TokenInformation; - - DPRINT("NtQueryInformationToken(TokenStatistics)\n"); - RequiredLength = sizeof(TOKEN_STATISTICS); - - _SEH_TRY - { - if(TokenInformationLength >= RequiredLength) - { - ts->TokenId = Token->TokenId; - ts->AuthenticationId = Token->AuthenticationId; - ts->ExpirationTime = Token->ExpirationTime; - ts->TokenType = Token->TokenType; - ts->ImpersonationLevel = Token->ImpersonationLevel; - ts->DynamicCharged = Token->DynamicCharged; - ts->DynamicAvailable = Token->DynamicAvailable; - ts->GroupCount = Token->UserAndGroupCount - 1; - ts->PrivilegeCount = Token->PrivilegeCount; - ts->ModifiedId = Token->ModifiedId; - } - else - { - Status = STATUS_BUFFER_TOO_SMALL; - } - - if(ReturnLength != NULL) - { - *ReturnLength = RequiredLength; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - break; - } - - case TokenOrigin: - { - PTOKEN_ORIGIN to = (PTOKEN_ORIGIN)TokenInformation; - - DPRINT("NtQueryInformationToken(TokenOrigin)\n"); - RequiredLength = sizeof(TOKEN_ORIGIN); - - _SEH_TRY - { - if(TokenInformationLength >= RequiredLength) - { - RtlCopyLuid(&to->OriginatingLogonSession, - &Token->AuthenticationId); - } - else - { - Status = STATUS_BUFFER_TOO_SMALL; - } - - if(ReturnLength != NULL) - { - *ReturnLength = RequiredLength; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - break; - } - - case TokenGroupsAndPrivileges: - DPRINT1("NtQueryInformationToken(TokenGroupsAndPrivileges) not implemented\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - - case TokenRestrictedSids: - { - PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation; - - DPRINT("NtQueryInformationToken(TokenRestrictedSids)\n"); - RequiredLength = sizeof(tg->GroupCount) + - RtlLengthSidAndAttributes(Token->RestrictedSidCount, Token->RestrictedSids); - - _SEH_TRY - { - if(TokenInformationLength >= RequiredLength) - { - ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) - - (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)); - PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) + - (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES))); - - tg->GroupCount = Token->RestrictedSidCount; - Status = RtlCopySidAndAttributesArray(Token->RestrictedSidCount, - Token->RestrictedSids, - SidLen, - &tg->Groups[0], - (PSID)Sid, - &Unused.Ptr, - &Unused.Ulong); - } - else - { - Status = STATUS_BUFFER_TOO_SMALL; - } - - if(ReturnLength != NULL) - { - *ReturnLength = RequiredLength; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - break; - } - - case TokenSandBoxInert: - DPRINT1("NtQueryInformationToken(TokenSandboxInert) not implemented\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - - case TokenSessionId: - { - ULONG SessionId = 0; - - DPRINT("NtQueryInformationToken(TokenSessionId)\n"); - - Status = SeQuerySessionIdToken(Token, - &SessionId); - - if(NT_SUCCESS(Status)) - { - _SEH_TRY - { - /* buffer size was already verified, no need to check here again */ - *(PULONG)TokenInformation = SessionId; - - if(ReturnLength != NULL) - { - *ReturnLength = sizeof(ULONG); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - } - - break; - } - - default: - DPRINT1("NtQueryInformationToken(%d) invalid information class\n", TokenInformationClass); - Status = STATUS_INVALID_INFO_CLASS; - break; + PVOID Ptr; + ULONG Ulong; + } Unused; + PTOKEN Token; + ULONG RequiredLength; + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + PreviousMode = ExGetPreviousMode(); + + /* Check buffers and class validity */ + Status = DefaultQueryInfoBufferCheck(TokenInformationClass, + SeTokenInformationClass, + sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]), + TokenInformation, + TokenInformationLength, + ReturnLength, + PreviousMode); + + if(!NT_SUCCESS(Status)) + { + DPRINT("NtQueryInformationToken() failed, Status: 0x%x\n", Status); + return Status; } - - ObDereferenceObject(Token); - } - - return(Status); + + Status = ObReferenceObjectByHandle(TokenHandle, + (TokenInformationClass == TokenSource) ? TOKEN_QUERY_SOURCE : TOKEN_QUERY, + SepTokenObjectType, + PreviousMode, + (PVOID*)&Token, + NULL); + if (NT_SUCCESS(Status)) + { + switch (TokenInformationClass) + { + case TokenUser: + { + PTOKEN_USER tu = (PTOKEN_USER)TokenInformation; + + DPRINT("NtQueryInformationToken(TokenUser)\n"); + RequiredLength = sizeof(TOKEN_USER) + + RtlLengthSid(Token->UserAndGroups[0].Sid); + + _SEH_TRY + { + if(TokenInformationLength >= RequiredLength) + { + Status = RtlCopySidAndAttributesArray(1, + &Token->UserAndGroups[0], + RequiredLength - sizeof(TOKEN_USER), + &tu->User, + (PSID)(tu + 1), + &Unused.Ptr, + &Unused.Ulong); + } + else + { + Status = STATUS_BUFFER_TOO_SMALL; + } + + if(ReturnLength != NULL) + { + *ReturnLength = RequiredLength; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + break; + } + + case TokenGroups: + { + PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation; + + DPRINT("NtQueryInformationToken(TokenGroups)\n"); + RequiredLength = sizeof(tg->GroupCount) + + RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]); + + _SEH_TRY + { + if(TokenInformationLength >= RequiredLength) + { + ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) - + ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES)); + PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) + + ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES))); + + tg->GroupCount = Token->UserAndGroupCount - 1; + Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1, + &Token->UserAndGroups[1], + SidLen, + &tg->Groups[0], + (PSID)Sid, + &Unused.Ptr, + &Unused.Ulong); + } + else + { + Status = STATUS_BUFFER_TOO_SMALL; + } + + if(ReturnLength != NULL) + { + *ReturnLength = RequiredLength; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + break; + } + + case TokenPrivileges: + { + PTOKEN_PRIVILEGES tp = (PTOKEN_PRIVILEGES)TokenInformation; + + DPRINT("NtQueryInformationToken(TokenPrivileges)\n"); + RequiredLength = sizeof(tp->PrivilegeCount) + + (Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); + + _SEH_TRY + { + if(TokenInformationLength >= RequiredLength) + { + tp->PrivilegeCount = Token->PrivilegeCount; + RtlCopyLuidAndAttributesArray(Token->PrivilegeCount, + Token->Privileges, + &tp->Privileges[0]); + } + else + { + Status = STATUS_BUFFER_TOO_SMALL; + } + + if(ReturnLength != NULL) + { + *ReturnLength = RequiredLength; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + break; + } + + case TokenOwner: + { + ULONG SidLen; + PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation; + + DPRINT("NtQueryInformationToken(TokenOwner)\n"); + SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); + RequiredLength = sizeof(TOKEN_OWNER) + SidLen; + + _SEH_TRY + { + if(TokenInformationLength >= RequiredLength) + { + to->Owner = (PSID)(to + 1); + Status = RtlCopySid(SidLen, + to->Owner, + Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); + } + else + { + Status = STATUS_BUFFER_TOO_SMALL; + } + + if(ReturnLength != NULL) + { + *ReturnLength = RequiredLength; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + break; + } + + case TokenPrimaryGroup: + { + ULONG SidLen; + PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation; + + DPRINT("NtQueryInformationToken(TokenPrimaryGroup)\n"); + SidLen = RtlLengthSid(Token->PrimaryGroup); + RequiredLength = sizeof(TOKEN_PRIMARY_GROUP) + SidLen; + + _SEH_TRY + { + if(TokenInformationLength >= RequiredLength) + { + tpg->PrimaryGroup = (PSID)(tpg + 1); + Status = RtlCopySid(SidLen, + tpg->PrimaryGroup, + Token->PrimaryGroup); + } + else + { + Status = STATUS_BUFFER_TOO_SMALL; + } + + if(ReturnLength != NULL) + { + *ReturnLength = RequiredLength; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + break; + } + + case TokenDefaultDacl: + { + PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation; + + DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n"); + RequiredLength = sizeof(TOKEN_DEFAULT_DACL); + + if(Token->DefaultDacl != NULL) + { + RequiredLength += Token->DefaultDacl->AclSize; + } + + _SEH_TRY + { + if(TokenInformationLength >= RequiredLength) + { + if(Token->DefaultDacl != NULL) + { + tdd->DefaultDacl = (PACL)(tdd + 1); + RtlCopyMemory(tdd->DefaultDacl, + Token->DefaultDacl, + Token->DefaultDacl->AclSize); + } + else + { + tdd->DefaultDacl = NULL; + } + } + else + { + Status = STATUS_BUFFER_TOO_SMALL; + } + + if(ReturnLength != NULL) + { + *ReturnLength = RequiredLength; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + break; + } + + case TokenSource: + { + PTOKEN_SOURCE ts = (PTOKEN_SOURCE)TokenInformation; + + DPRINT("NtQueryInformationToken(TokenSource)\n"); + RequiredLength = sizeof(TOKEN_SOURCE); + + _SEH_TRY + { + if(TokenInformationLength >= RequiredLength) + { + *ts = Token->TokenSource; + } + else + { + Status = STATUS_BUFFER_TOO_SMALL; + } + + if(ReturnLength != NULL) + { + *ReturnLength = RequiredLength; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + break; + } + + case TokenType: + { + PTOKEN_TYPE tt = (PTOKEN_TYPE)TokenInformation; + + DPRINT("NtQueryInformationToken(TokenType)\n"); + RequiredLength = sizeof(TOKEN_TYPE); + + _SEH_TRY + { + if(TokenInformationLength >= RequiredLength) + { + *tt = Token->TokenType; + } + else + { + Status = STATUS_BUFFER_TOO_SMALL; + } + + if(ReturnLength != NULL) + { + *ReturnLength = RequiredLength; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + break; + } + + case TokenImpersonationLevel: + { + PSECURITY_IMPERSONATION_LEVEL sil = (PSECURITY_IMPERSONATION_LEVEL)TokenInformation; + + DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n"); + RequiredLength = sizeof(SECURITY_IMPERSONATION_LEVEL); + + _SEH_TRY + { + if(TokenInformationLength >= RequiredLength) + { + *sil = Token->ImpersonationLevel; + } + else + { + Status = STATUS_BUFFER_TOO_SMALL; + } + + if(ReturnLength != NULL) + { + *ReturnLength = RequiredLength; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + break; + } + + case TokenStatistics: + { + PTOKEN_STATISTICS ts = (PTOKEN_STATISTICS)TokenInformation; + + DPRINT("NtQueryInformationToken(TokenStatistics)\n"); + RequiredLength = sizeof(TOKEN_STATISTICS); + + _SEH_TRY + { + if(TokenInformationLength >= RequiredLength) + { + ts->TokenId = Token->TokenId; + ts->AuthenticationId = Token->AuthenticationId; + ts->ExpirationTime = Token->ExpirationTime; + ts->TokenType = Token->TokenType; + ts->ImpersonationLevel = Token->ImpersonationLevel; + ts->DynamicCharged = Token->DynamicCharged; + ts->DynamicAvailable = Token->DynamicAvailable; + ts->GroupCount = Token->UserAndGroupCount - 1; + ts->PrivilegeCount = Token->PrivilegeCount; + ts->ModifiedId = Token->ModifiedId; + } + else + { + Status = STATUS_BUFFER_TOO_SMALL; + } + + if(ReturnLength != NULL) + { + *ReturnLength = RequiredLength; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + break; + } + + case TokenOrigin: + { + PTOKEN_ORIGIN to = (PTOKEN_ORIGIN)TokenInformation; + + DPRINT("NtQueryInformationToken(TokenOrigin)\n"); + RequiredLength = sizeof(TOKEN_ORIGIN); + + _SEH_TRY + { + if(TokenInformationLength >= RequiredLength) + { + RtlCopyLuid(&to->OriginatingLogonSession, + &Token->AuthenticationId); + } + else + { + Status = STATUS_BUFFER_TOO_SMALL; + } + + if(ReturnLength != NULL) + { + *ReturnLength = RequiredLength; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + break; + } + + case TokenGroupsAndPrivileges: + DPRINT1("NtQueryInformationToken(TokenGroupsAndPrivileges) not implemented\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + + case TokenRestrictedSids: + { + PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation; + + DPRINT("NtQueryInformationToken(TokenRestrictedSids)\n"); + RequiredLength = sizeof(tg->GroupCount) + + RtlLengthSidAndAttributes(Token->RestrictedSidCount, Token->RestrictedSids); + + _SEH_TRY + { + if(TokenInformationLength >= RequiredLength) + { + ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) - + (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)); + PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) + + (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES))); + + tg->GroupCount = Token->RestrictedSidCount; + Status = RtlCopySidAndAttributesArray(Token->RestrictedSidCount, + Token->RestrictedSids, + SidLen, + &tg->Groups[0], + (PSID)Sid, + &Unused.Ptr, + &Unused.Ulong); + } + else + { + Status = STATUS_BUFFER_TOO_SMALL; + } + + if(ReturnLength != NULL) + { + *ReturnLength = RequiredLength; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + break; + } + + case TokenSandBoxInert: + DPRINT1("NtQueryInformationToken(TokenSandboxInert) not implemented\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + + case TokenSessionId: + { + ULONG SessionId = 0; + + DPRINT("NtQueryInformationToken(TokenSessionId)\n"); + + Status = SeQuerySessionIdToken(Token, + &SessionId); + + if(NT_SUCCESS(Status)) + { + _SEH_TRY + { + /* buffer size was already verified, no need to check here again */ + *(PULONG)TokenInformation = SessionId; + + if(ReturnLength != NULL) + { + *ReturnLength = sizeof(ULONG); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + + break; + } + + default: + DPRINT1("NtQueryInformationToken(%d) invalid information class\n", TokenInformationClass); + Status = STATUS_INVALID_INFO_CLASS; + break; + } + + ObDereferenceObject(Token); + } + + return(Status); } -/* - * @unimplemented - */ -NTSTATUS -STDCALL -SeQueryInformationToken( - IN PACCESS_TOKEN Token, - IN TOKEN_INFORMATION_CLASS TokenInformationClass, - OUT PVOID *TokenInformation - ) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/* - * @implemented - */ -NTSTATUS -STDCALL -SeQuerySessionIdToken( - IN PACCESS_TOKEN Token, - IN PULONG pSessionId - ) -{ - *pSessionId = ((PTOKEN)Token)->SessionId; - return STATUS_SUCCESS; -} /* * NtSetTokenInformation: Partly implemented. @@ -1251,231 +1411,231 @@ NtSetInformationToken(IN HANDLE TokenHandle, OUT PVOID TokenInformation, IN ULONG TokenInformationLength) { - PTOKEN Token; - KPROCESSOR_MODE PreviousMode; - ULONG NeededAccess = TOKEN_ADJUST_DEFAULT; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - Status = DefaultSetInfoBufferCheck(TokenInformationClass, - SeTokenInformationClass, - sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]), - TokenInformation, - TokenInformationLength, - PreviousMode); - - if(!NT_SUCCESS(Status)) - { - /* Invalid buffers */ - DPRINT("NtSetInformationToken() failed, Status: 0x%x\n", Status); - return Status; - } - - if(TokenInformationClass == TokenSessionId) - { - NeededAccess |= TOKEN_ADJUST_SESSIONID; - } - - Status = ObReferenceObjectByHandle(TokenHandle, - NeededAccess, - SepTokenObjectType, - PreviousMode, - (PVOID*)&Token, - NULL); - if (NT_SUCCESS(Status)) - { - switch (TokenInformationClass) + PTOKEN Token; + KPROCESSOR_MODE PreviousMode; + ULONG NeededAccess = TOKEN_ADJUST_DEFAULT; + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + PreviousMode = ExGetPreviousMode(); + + Status = DefaultSetInfoBufferCheck(TokenInformationClass, + SeTokenInformationClass, + sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]), + TokenInformation, + TokenInformationLength, + PreviousMode); + + if(!NT_SUCCESS(Status)) { - case TokenOwner: - { - if(TokenInformationLength >= sizeof(TOKEN_OWNER)) - { - PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation; - PSID InputSid = NULL; - - _SEH_TRY - { - InputSid = to->Owner; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(NT_SUCCESS(Status)) - { - PSID CapturedSid; - - Status = SepCaptureSid(InputSid, - PreviousMode, - PagedPool, - FALSE, - &CapturedSid); - if(NT_SUCCESS(Status)) - { - RtlCopySid(RtlLengthSid(CapturedSid), - Token->UserAndGroups[Token->DefaultOwnerIndex].Sid, - CapturedSid); - SepReleaseSid(CapturedSid, - PreviousMode, - FALSE); - } - } - } - else - { - Status = STATUS_INFO_LENGTH_MISMATCH; - } - break; - } - - case TokenPrimaryGroup: - { - if(TokenInformationLength >= sizeof(TOKEN_PRIMARY_GROUP)) - { - PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation; - PSID InputSid = NULL; - - _SEH_TRY - { - InputSid = tpg->PrimaryGroup; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(NT_SUCCESS(Status)) - { - PSID CapturedSid; - - Status = SepCaptureSid(InputSid, - PreviousMode, - PagedPool, - FALSE, - &CapturedSid); - if(NT_SUCCESS(Status)) - { - RtlCopySid(RtlLengthSid(CapturedSid), - Token->PrimaryGroup, - CapturedSid); - SepReleaseSid(CapturedSid, - PreviousMode, - FALSE); - } - } - } - else - { - Status = STATUS_INFO_LENGTH_MISMATCH; - } - break; - } - - case TokenDefaultDacl: - { - if(TokenInformationLength >= sizeof(TOKEN_DEFAULT_DACL)) - { - PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation; - PACL InputAcl = NULL; - - _SEH_TRY - { - InputAcl = tdd->DefaultDacl; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(NT_SUCCESS(Status)) - { - if(InputAcl != NULL) - { - PACL CapturedAcl; - - /* capture and copy the dacl */ - Status = SepCaptureAcl(InputAcl, - PreviousMode, - PagedPool, - TRUE, - &CapturedAcl); - if(NT_SUCCESS(Status)) - { - /* free the previous dacl if present */ - if(Token->DefaultDacl != NULL) - { - ExFreePool(Token->DefaultDacl); - } - - /* set the new dacl */ - Token->DefaultDacl = CapturedAcl; - } - } - else - { - /* clear and free the default dacl if present */ - if(Token->DefaultDacl != NULL) - { - ExFreePool(Token->DefaultDacl); - Token->DefaultDacl = NULL; - } - } - } - } - else - { - Status = STATUS_INFO_LENGTH_MISMATCH; - } - break; - } - - case TokenSessionId: - { - ULONG SessionId = 0; - - _SEH_TRY - { - /* buffer size was already verified, no need to check here again */ - SessionId = *(PULONG)TokenInformation; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(NT_SUCCESS(Status)) - { - if(!SeSinglePrivilegeCheck(SeTcbPrivilege, - PreviousMode)) - { - Status = STATUS_PRIVILEGE_NOT_HELD; - break; - } - - Token->SessionId = SessionId; - } - break; - } - - default: - { - Status = STATUS_NOT_IMPLEMENTED; - break; - } + /* Invalid buffers */ + DPRINT("NtSetInformationToken() failed, Status: 0x%x\n", Status); + return Status; } - - ObDereferenceObject(Token); - } - - return(Status); + + if(TokenInformationClass == TokenSessionId) + { + NeededAccess |= TOKEN_ADJUST_SESSIONID; + } + + Status = ObReferenceObjectByHandle(TokenHandle, + NeededAccess, + SepTokenObjectType, + PreviousMode, + (PVOID*)&Token, + NULL); + if (NT_SUCCESS(Status)) + { + switch (TokenInformationClass) + { + case TokenOwner: + { + if(TokenInformationLength >= sizeof(TOKEN_OWNER)) + { + PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation; + PSID InputSid = NULL; + + _SEH_TRY + { + InputSid = to->Owner; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(NT_SUCCESS(Status)) + { + PSID CapturedSid; + + Status = SepCaptureSid(InputSid, + PreviousMode, + PagedPool, + FALSE, + &CapturedSid); + if(NT_SUCCESS(Status)) + { + RtlCopySid(RtlLengthSid(CapturedSid), + Token->UserAndGroups[Token->DefaultOwnerIndex].Sid, + CapturedSid); + SepReleaseSid(CapturedSid, + PreviousMode, + FALSE); + } + } + } + else + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + break; + } + + case TokenPrimaryGroup: + { + if(TokenInformationLength >= sizeof(TOKEN_PRIMARY_GROUP)) + { + PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation; + PSID InputSid = NULL; + + _SEH_TRY + { + InputSid = tpg->PrimaryGroup; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(NT_SUCCESS(Status)) + { + PSID CapturedSid; + + Status = SepCaptureSid(InputSid, + PreviousMode, + PagedPool, + FALSE, + &CapturedSid); + if(NT_SUCCESS(Status)) + { + RtlCopySid(RtlLengthSid(CapturedSid), + Token->PrimaryGroup, + CapturedSid); + SepReleaseSid(CapturedSid, + PreviousMode, + FALSE); + } + } + } + else + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + break; + } + + case TokenDefaultDacl: + { + if(TokenInformationLength >= sizeof(TOKEN_DEFAULT_DACL)) + { + PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation; + PACL InputAcl = NULL; + + _SEH_TRY + { + InputAcl = tdd->DefaultDacl; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(NT_SUCCESS(Status)) + { + if(InputAcl != NULL) + { + PACL CapturedAcl; + + /* capture and copy the dacl */ + Status = SepCaptureAcl(InputAcl, + PreviousMode, + PagedPool, + TRUE, + &CapturedAcl); + if(NT_SUCCESS(Status)) + { + /* free the previous dacl if present */ + if(Token->DefaultDacl != NULL) + { + ExFreePool(Token->DefaultDacl); + } + + /* set the new dacl */ + Token->DefaultDacl = CapturedAcl; + } + } + else + { + /* clear and free the default dacl if present */ + if(Token->DefaultDacl != NULL) + { + ExFreePool(Token->DefaultDacl); + Token->DefaultDacl = NULL; + } + } + } + } + else + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + break; + } + + case TokenSessionId: + { + ULONG SessionId = 0; + + _SEH_TRY + { + /* buffer size was already verified, no need to check here again */ + SessionId = *(PULONG)TokenInformation; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(NT_SUCCESS(Status)) + { + if(!SeSinglePrivilegeCheck(SeTcbPrivilege, + PreviousMode)) + { + Status = STATUS_PRIVILEGE_NOT_HELD; + break; + } + + Token->SessionId = SessionId; + } + break; + } + + default: + { + Status = STATUS_NOT_IMPLEMENTED; + break; + } + } + + ObDereferenceObject(Token); + } + + return(Status); } @@ -1495,114 +1655,98 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, IN TOKEN_TYPE TokenType, OUT PHANDLE NewTokenHandle) { - KPROCESSOR_MODE PreviousMode; - HANDLE hToken; - PTOKEN Token; - PTOKEN NewToken; - PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService; - BOOLEAN QoSPresent; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = KeGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH_TRY + KPROCESSOR_MODE PreviousMode; + HANDLE hToken; + PTOKEN Token; + PTOKEN NewToken; + PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService; + BOOLEAN QoSPresent; + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + PreviousMode = KeGetPreviousMode(); + + if(PreviousMode != KernelMode) { - ProbeForWriteHandle(NewTokenHandle); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(!NT_SUCCESS(Status)) - { - return Status; - } - } - - Status = SepCaptureSecurityQualityOfService(ObjectAttributes, - PreviousMode, - PagedPool, - FALSE, - &CapturedSecurityQualityOfService, - &QoSPresent); - if(!NT_SUCCESS(Status)) - { - DPRINT1("NtDuplicateToken() failed to capture QoS! Status: 0x%x\n", Status); - return Status; - } - - Status = ObReferenceObjectByHandle(ExistingTokenHandle, - TOKEN_DUPLICATE, - SepTokenObjectType, - PreviousMode, - (PVOID*)&Token, - NULL); - if (NT_SUCCESS(Status)) - { - Status = SepDuplicateToken(Token, - ObjectAttributes, - EffectiveOnly, - TokenType, - (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous), - PreviousMode, - &NewToken); - - ObDereferenceObject(Token); - - if (NT_SUCCESS(Status)) - { - Status = ObInsertObject((PVOID)NewToken, - NULL, - DesiredAccess, - 0, - NULL, - &hToken); - - if (NT_SUCCESS(Status)) - { _SEH_TRY { - *NewTokenHandle = hToken; + ProbeForWriteHandle(NewTokenHandle); } _SEH_HANDLE { - Status = _SEH_GetExceptionCode(); + Status = _SEH_GetExceptionCode(); } _SEH_END; - } + + if(!NT_SUCCESS(Status)) + { + return Status; + } } - } - - /* free the captured structure */ - SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, - PreviousMode, - FALSE); - - return Status; + + Status = SepCaptureSecurityQualityOfService(ObjectAttributes, + PreviousMode, + PagedPool, + FALSE, + &CapturedSecurityQualityOfService, + &QoSPresent); + if(!NT_SUCCESS(Status)) + { + DPRINT1("NtDuplicateToken() failed to capture QoS! Status: 0x%x\n", Status); + return Status; + } + + Status = ObReferenceObjectByHandle(ExistingTokenHandle, + TOKEN_DUPLICATE, + SepTokenObjectType, + PreviousMode, + (PVOID*)&Token, + NULL); + if (NT_SUCCESS(Status)) + { + Status = SepDuplicateToken(Token, + ObjectAttributes, + EffectiveOnly, + TokenType, + (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous), + PreviousMode, + &NewToken); + + ObDereferenceObject(Token); + + if (NT_SUCCESS(Status)) + { + Status = ObInsertObject((PVOID)NewToken, + NULL, + DesiredAccess, + 0, + NULL, + &hToken); + + if (NT_SUCCESS(Status)) + { + _SEH_TRY + { + *NewTokenHandle = hToken; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + } + } + + /* free the captured structure */ + SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, + PreviousMode, + FALSE); + + return Status; } - -VOID SepAdjustGroups(PACCESS_TOKEN Token, - ULONG a, - BOOLEAN ResetToDefault, - PSID_AND_ATTRIBUTES Groups, - ULONG b, - KPROCESSOR_MODE PreviousMode, - ULONG c, - PULONG d, - PULONG e, - PULONG f) -{ - UNIMPLEMENTED; -} - - NTSTATUS STDCALL NtAdjustGroupsToken(IN HANDLE TokenHandle, IN BOOLEAN ResetToDefault, @@ -1611,94 +1755,10 @@ NtAdjustGroupsToken(IN HANDLE TokenHandle, OUT PTOKEN_GROUPS PreviousState OPTIONAL, OUT PULONG ReturnLength) { -#if 0 - NTSTATUS Status; - PACCESS_TOKEN Token; - ULONG a; - ULONG b; - ULONG c; - - PAGED_CODE(); - - Status = ObReferenceObjectByHandle(TokenHandle, - ?, - SepTokenObjectType, - UserMode, - (PVOID*)&Token, - NULL); - - - SepAdjustGroups(Token, - 0, - ResetToDefault, - NewState->Groups, - ?, - PreviousState, - 0, - &a, - &b, - &c); -#else - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); -#endif + UNIMPLEMENTED; + return(STATUS_NOT_IMPLEMENTED); } - -#if 0 -NTSTATUS -SepAdjustPrivileges(PACCESS_TOKEN Token, - ULONG a, - KPROCESSOR_MODE PreviousMode, - ULONG PrivilegeCount, - PLUID_AND_ATTRIBUTES Privileges, - PTOKEN_PRIVILEGES* PreviousState, - PULONG b, - PULONG c, - PULONG d) -{ - ULONG i; - - *c = 0; - - if (Token->PrivilegeCount > 0) - { - for (i = 0; i < Token->PrivilegeCount; i++) - { - if (PreviousMode != KernelMode) - { - if (Token->Privileges[i]->Attributes & SE_PRIVILEGE_ENABLED == 0) - { - if (a != 0) - { - if (PreviousState != NULL) - { - memcpy(&PreviousState[i], - &Token->Privileges[i], - sizeof(LUID_AND_ATTRIBUTES)); - } - Token->Privileges[i].Attributes &= (~SE_PRIVILEGE_ENABLED); - } - } - } - } - } - - if (PreviousMode != KernelMode) - { - Token->TokenFlags = Token->TokenFlags & (~1); - } - else - { - if (PrivilegeCount <= ?) - { - } - } - if ( -} -#endif - - /* * @implemented */ @@ -1710,407 +1770,176 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL, OUT PULONG ReturnLength OPTIONAL) { -// PLUID_AND_ATTRIBUTES Privileges; - KPROCESSOR_MODE PreviousMode; - ULONG PrivilegeCount; - PTOKEN Token; -// ULONG Length; - ULONG i; - ULONG j; - ULONG k; - ULONG Count; + // PLUID_AND_ATTRIBUTES Privileges; + KPROCESSOR_MODE PreviousMode; + ULONG PrivilegeCount; + PTOKEN Token; + // ULONG Length; + ULONG i; + ULONG j; + ULONG k; + ULONG Count; #if 0 - ULONG a; - ULONG b; - ULONG c; + ULONG a; + ULONG b; + ULONG c; #endif - NTSTATUS Status; - - PAGED_CODE(); - - DPRINT ("NtAdjustPrivilegesToken() called\n"); - -// PrivilegeCount = NewState->PrivilegeCount; - PreviousMode = KeGetPreviousMode (); -// SeCaptureLuidAndAttributesArray(NewState->Privileges, -// PrivilegeCount, -// PreviousMode, -// NULL, -// 0, -// NonPagedPool, -// 1, -// &Privileges, -// &Length); - - Status = ObReferenceObjectByHandle (TokenHandle, - TOKEN_ADJUST_PRIVILEGES | (PreviousState != NULL ? TOKEN_QUERY : 0), - SepTokenObjectType, - PreviousMode, - (PVOID*)&Token, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("Failed to reference token (Status %lx)\n", Status); -// SeReleaseLuidAndAttributesArray(Privileges, -// PreviousMode, -// 0); - return Status; - } - - -#if 0 - SepAdjustPrivileges(Token, - 0, - PreviousMode, - PrivilegeCount, - Privileges, - PreviousState, - &a, - &b, - &c); -#endif - - PrivilegeCount = (BufferLength - FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges)) / - sizeof(LUID_AND_ATTRIBUTES); - - if (PreviousState != NULL) - PreviousState->PrivilegeCount = 0; - - k = 0; - if (DisableAllPrivileges == TRUE) - { - for (i = 0; i < Token->PrivilegeCount; i++) - { - if (Token->Privileges[i].Attributes != 0) - { - DPRINT ("Attributes differ\n"); - - /* Save current privilege */ - if (PreviousState != NULL) - { - if (k < PrivilegeCount) - { - PreviousState->PrivilegeCount++; - PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid; - PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes; - } - else - { - /* FIXME: Should revert all the changes, calculate how - * much space would be needed, set ResultLength - * accordingly and fail. - */ - } - k++; - } - - /* Update current privlege */ - Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED; - } - } - Status = STATUS_SUCCESS; - } - else - { - Count = 0; - for (i = 0; i < Token->PrivilegeCount; i++) - { - for (j = 0; j < NewState->PrivilegeCount; j++) - { - if (Token->Privileges[i].Luid.LowPart == NewState->Privileges[j].Luid.LowPart && - Token->Privileges[i].Luid.HighPart == NewState->Privileges[j].Luid.HighPart) - { - DPRINT ("Found privilege\n"); - - if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) != - (NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED)) - { - DPRINT ("Attributes differ\n"); - DPRINT ("Current attributes %lx desired attributes %lx\n", - Token->Privileges[i].Attributes, - NewState->Privileges[j].Attributes); - - /* Save current privilege */ - if (PreviousState != NULL) - { - if (k < PrivilegeCount) - { - PreviousState->PrivilegeCount++; - PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid; - PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes; - } - else - { - /* FIXME: Should revert all the changes, calculate how - * much space would be needed, set ResultLength - * accordingly and fail. - */ - } - k++; - } - - /* Update current privlege */ - Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED; - Token->Privileges[i].Attributes |= - (NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED); - DPRINT ("New attributes %lx\n", - Token->Privileges[i].Attributes); - } - Count++; - } - } - } - Status = Count < NewState->PrivilegeCount ? STATUS_NOT_ALL_ASSIGNED : STATUS_SUCCESS; - } - - if (ReturnLength != NULL) - { - *ReturnLength = sizeof(TOKEN_PRIVILEGES) + - (sizeof(LUID_AND_ATTRIBUTES) * (k - 1)); - } - - ObDereferenceObject (Token); - -// SeReleaseLuidAndAttributesArray(Privileges, -// PreviousMode, -// 0); - - DPRINT ("NtAdjustPrivilegesToken() done\n"); - - return Status; -} - -VOID -NTAPI -SeAssignPrimaryToken(IN PEPROCESS Process, - IN PTOKEN Token) -{ + NTSTATUS Status; + PAGED_CODE(); - - /* Sanity checks */ - ASSERT(Token->TokenType == TokenPrimary); - ASSERT(!Token->TokenInUse); - - /* Clean any previous token */ - if (Process->Token.Object) SeDeassignPrimaryToken(Process); - - /* Set the new token */ - ObReferenceObject(Token); - Token->TokenInUse = TRUE; - ObInitializeFastReference(&Process->Token, Token); -} - -PTOKEN -STDCALL -SepCreateSystemProcessToken(VOID) -{ - NTSTATUS Status; - ULONG uSize; - ULONG i; - ULONG uLocalSystemLength; - ULONG uWorldLength; - ULONG uAuthUserLength; - ULONG uAdminsLength; - PTOKEN AccessToken; - PVOID SidArea; - - PAGED_CODE(); - - uLocalSystemLength = RtlLengthSid(SeLocalSystemSid); - uWorldLength = RtlLengthSid(SeWorldSid); - uAuthUserLength = RtlLengthSid(SeAuthenticatedUserSid); - uAdminsLength = RtlLengthSid(SeAliasAdminsSid); - - /* - * Initialize the token - */ - Status = ObCreateObject(KernelMode, - SepTokenObjectType, - NULL, - KernelMode, - NULL, - sizeof(TOKEN), - 0, - 0, - (PVOID*)&AccessToken); - if (!NT_SUCCESS(Status)) + + DPRINT ("NtAdjustPrivilegesToken() called\n"); + + // PrivilegeCount = NewState->PrivilegeCount; + PreviousMode = KeGetPreviousMode (); + // SeCaptureLuidAndAttributesArray(NewState->Privileges, + // PrivilegeCount, + // PreviousMode, + // NULL, + // 0, + // NonPagedPool, + // 1, + // &Privileges, + // &Length); + + Status = ObReferenceObjectByHandle (TokenHandle, + TOKEN_ADJUST_PRIVILEGES | (PreviousState != NULL ? TOKEN_QUERY : 0), + SepTokenObjectType, + PreviousMode, + (PVOID*)&Token, + NULL); + if (!NT_SUCCESS(Status)) { - return NULL; + DPRINT1 ("Failed to reference token (Status %lx)\n", Status); + // SeReleaseLuidAndAttributesArray(Privileges, + // PreviousMode, + // 0); + return Status; } - - Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(AccessToken); - return NULL; - } - - Status = ExpAllocateLocallyUniqueId(&AccessToken->ModifiedId); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(AccessToken); - return NULL; - } - - Status = ExpAllocateLocallyUniqueId(&AccessToken->AuthenticationId); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(AccessToken); - return NULL; - } - - AccessToken->TokenLock = &SepTokenLock; - - AccessToken->TokenType = TokenPrimary; - AccessToken->ImpersonationLevel = SecurityDelegation; - AccessToken->TokenSource.SourceIdentifier.LowPart = 0; - AccessToken->TokenSource.SourceIdentifier.HighPart = 0; - memcpy(AccessToken->TokenSource.SourceName, "SeMgr\0\0\0", 8); - AccessToken->ExpirationTime.QuadPart = -1; - AccessToken->UserAndGroupCount = 4; - - uSize = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount; - uSize += uLocalSystemLength; - uSize += uWorldLength; - uSize += uAuthUserLength; - uSize += uAdminsLength; - - AccessToken->UserAndGroups = - (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, - uSize, - TAG('T', 'O', 'K', 'u')); - SidArea = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount]; - - i = 0; - AccessToken->UserAndGroups[i].Sid = (PSID) SidArea; - AccessToken->UserAndGroups[i++].Attributes = 0; - RtlCopySid(uLocalSystemLength, SidArea, SeLocalSystemSid); - SidArea = (char*)SidArea + uLocalSystemLength; - - AccessToken->DefaultOwnerIndex = i; - AccessToken->UserAndGroups[i].Sid = (PSID) SidArea; - AccessToken->PrimaryGroup = (PSID) SidArea; - AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT; - Status = RtlCopySid(uAdminsLength, SidArea, SeAliasAdminsSid); - SidArea = (char*)SidArea + uAdminsLength; - - AccessToken->UserAndGroups[i].Sid = (PSID) SidArea; - AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY; - RtlCopySid(uWorldLength, SidArea, SeWorldSid); - SidArea = (char*)SidArea + uWorldLength; - - AccessToken->UserAndGroups[i].Sid = (PSID) SidArea; - AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY; - RtlCopySid(uAuthUserLength, SidArea, SeAuthenticatedUserSid); - SidArea = (char*)SidArea + uAuthUserLength; - - AccessToken->PrivilegeCount = 20; - - uSize = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); - AccessToken->Privileges = - (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, - uSize, - TAG('T', 'O', 'K', 'p')); - - i = 0; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeTcbPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeCreateTokenPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeTakeOwnershipPrivilege; - - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeCreatePagefilePrivilege; - - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeLockMemoryPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeIncreaseQuotaPrivilege; - - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege; - - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeCreatePermanentPrivilege; - - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeDebugPrivilege; - - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeAuditPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeSecurityPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeSystemEnvironmentPrivilege; - - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeChangeNotifyPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeBackupPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeRestorePrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeShutdownPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeLoadDriverPrivilege; - - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeProfileSingleProcessPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeSystemtimePrivilege; + + #if 0 - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeUndockPrivilege; - - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeManageVolumePrivilege; + SepAdjustPrivileges(Token, + 0, + PreviousMode, + PrivilegeCount, + Privileges, + PreviousState, + &a, + &b, + &c); #endif - - ASSERT(i == 20); - - uSize = sizeof(ACL); - uSize += sizeof(ACE) + uLocalSystemLength; - uSize += sizeof(ACE) + uAdminsLength; - uSize = (uSize & (~3)) + 8; - AccessToken->DefaultDacl = - (PACL) ExAllocatePoolWithTag(PagedPool, - uSize, - TAG('T', 'O', 'K', 'd')); - Status = RtlCreateAcl(AccessToken->DefaultDacl, uSize, ACL_REVISION); - if ( NT_SUCCESS(Status) ) + + PrivilegeCount = (BufferLength - FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges)) / + sizeof(LUID_AND_ATTRIBUTES); + + if (PreviousState != NULL) + PreviousState->PrivilegeCount = 0; + + k = 0; + if (DisableAllPrivileges == TRUE) { - Status = RtlAddAccessAllowedAce(AccessToken->DefaultDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); + for (i = 0; i < Token->PrivilegeCount; i++) + { + if (Token->Privileges[i].Attributes != 0) + { + DPRINT ("Attributes differ\n"); + + /* Save current privilege */ + if (PreviousState != NULL) + { + if (k < PrivilegeCount) + { + PreviousState->PrivilegeCount++; + PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid; + PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes; + } + else + { + /* FIXME: Should revert all the changes, calculate how + * much space would be needed, set ResultLength + * accordingly and fail. + */ + } + k++; + } + + /* Update current privlege */ + Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED; + } + } + Status = STATUS_SUCCESS; } - - if ( NT_SUCCESS(Status) ) + else { - Status = RtlAddAccessAllowedAce(AccessToken->DefaultDacl, ACL_REVISION, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE|READ_CONTROL, SeAliasAdminsSid); + Count = 0; + for (i = 0; i < Token->PrivilegeCount; i++) + { + for (j = 0; j < NewState->PrivilegeCount; j++) + { + if (Token->Privileges[i].Luid.LowPart == NewState->Privileges[j].Luid.LowPart && + Token->Privileges[i].Luid.HighPart == NewState->Privileges[j].Luid.HighPart) + { + DPRINT ("Found privilege\n"); + + if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) != + (NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED)) + { + DPRINT ("Attributes differ\n"); + DPRINT ("Current attributes %lx desired attributes %lx\n", + Token->Privileges[i].Attributes, + NewState->Privileges[j].Attributes); + + /* Save current privilege */ + if (PreviousState != NULL) + { + if (k < PrivilegeCount) + { + PreviousState->PrivilegeCount++; + PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid; + PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes; + } + else + { + /* FIXME: Should revert all the changes, calculate how + * much space would be needed, set ResultLength + * accordingly and fail. + */ + } + k++; + } + + /* Update current privlege */ + Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED; + Token->Privileges[i].Attributes |= + (NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED); + DPRINT ("New attributes %lx\n", + Token->Privileges[i].Attributes); + } + Count++; + } + } + } + Status = Count < NewState->PrivilegeCount ? STATUS_NOT_ALL_ASSIGNED : STATUS_SUCCESS; } - - if ( ! NT_SUCCESS(Status) ) + + if (ReturnLength != NULL) { - ObDereferenceObject(AccessToken); - return NULL; + *ReturnLength = sizeof(TOKEN_PRIVILEGES) + + (sizeof(LUID_AND_ATTRIBUTES) * (k - 1)); } - - return AccessToken; + + ObDereferenceObject (Token); + + // SeReleaseLuidAndAttributesArray(Privileges, + // PreviousMode, + // 0); + + DPRINT ("NtAdjustPrivilegesToken() done\n"); + + return Status; } - NTSTATUS STDCALL NtCreateToken(OUT PHANDLE TokenHandle, IN ACCESS_MASK DesiredAccess, @@ -2126,323 +1955,228 @@ NtCreateToken(OUT PHANDLE TokenHandle, IN PTOKEN_DEFAULT_DACL TokenDefaultDacl, IN PTOKEN_SOURCE TokenSource) { - HANDLE hToken; - PTOKEN AccessToken; - LUID TokenId; - LUID ModifiedId; - PVOID EndMem; - ULONG uLength; - ULONG i; - KPROCESSOR_MODE PreviousMode; - ULONG nTokenPrivileges = 0; - LARGE_INTEGER LocalExpirationTime = {{0}}; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH_TRY + HANDLE hToken; + PTOKEN AccessToken; + LUID TokenId; + LUID ModifiedId; + PVOID EndMem; + ULONG uLength; + ULONG i; + KPROCESSOR_MODE PreviousMode; + ULONG nTokenPrivileges = 0; + LARGE_INTEGER LocalExpirationTime = {{0}}; + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + PreviousMode = ExGetPreviousMode(); + + if(PreviousMode != KernelMode) { - ProbeForWriteHandle(TokenHandle); - ProbeForRead(AuthenticationId, - sizeof(LUID), - sizeof(ULONG)); - LocalExpirationTime = ProbeForReadLargeInteger(ExpirationTime); - ProbeForRead(TokenUser, - sizeof(TOKEN_USER), - sizeof(ULONG)); - ProbeForRead(TokenGroups, - sizeof(TOKEN_GROUPS), - sizeof(ULONG)); - ProbeForRead(TokenPrivileges, - sizeof(TOKEN_PRIVILEGES), - sizeof(ULONG)); - ProbeForRead(TokenOwner, - sizeof(TOKEN_OWNER), - sizeof(ULONG)); - ProbeForRead(TokenPrimaryGroup, - sizeof(TOKEN_PRIMARY_GROUP), - sizeof(ULONG)); - ProbeForRead(TokenDefaultDacl, - sizeof(TOKEN_DEFAULT_DACL), - sizeof(ULONG)); - ProbeForRead(TokenSource, - sizeof(TOKEN_SOURCE), - sizeof(ULONG)); - nTokenPrivileges = TokenPrivileges->PrivilegeCount; + _SEH_TRY + { + ProbeForWriteHandle(TokenHandle); + ProbeForRead(AuthenticationId, + sizeof(LUID), + sizeof(ULONG)); + LocalExpirationTime = ProbeForReadLargeInteger(ExpirationTime); + ProbeForRead(TokenUser, + sizeof(TOKEN_USER), + sizeof(ULONG)); + ProbeForRead(TokenGroups, + sizeof(TOKEN_GROUPS), + sizeof(ULONG)); + ProbeForRead(TokenPrivileges, + sizeof(TOKEN_PRIVILEGES), + sizeof(ULONG)); + ProbeForRead(TokenOwner, + sizeof(TOKEN_OWNER), + sizeof(ULONG)); + ProbeForRead(TokenPrimaryGroup, + sizeof(TOKEN_PRIMARY_GROUP), + sizeof(ULONG)); + ProbeForRead(TokenDefaultDacl, + sizeof(TOKEN_DEFAULT_DACL), + sizeof(ULONG)); + ProbeForRead(TokenSource, + sizeof(TOKEN_SOURCE), + sizeof(ULONG)); + nTokenPrivileges = TokenPrivileges->PrivilegeCount; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + return Status; + } } - _SEH_HANDLE + else { - Status = _SEH_GetExceptionCode(); + nTokenPrivileges = TokenPrivileges->PrivilegeCount; + LocalExpirationTime = *ExpirationTime; } - _SEH_END; - - if(!NT_SUCCESS(Status)) + + Status = ZwAllocateLocallyUniqueId(&TokenId); + if (!NT_SUCCESS(Status)) + return(Status); + + Status = ZwAllocateLocallyUniqueId(&ModifiedId); + if (!NT_SUCCESS(Status)) + return(Status); + + Status = ObCreateObject(PreviousMode, + SepTokenObjectType, + ObjectAttributes, + PreviousMode, + NULL, + sizeof(TOKEN), + 0, + 0, + (PVOID*)&AccessToken); + if (!NT_SUCCESS(Status)) { - return Status; + DPRINT1("ObCreateObject() failed (Status %lx)\n"); + return(Status); } - } - else - { - nTokenPrivileges = TokenPrivileges->PrivilegeCount; - LocalExpirationTime = *ExpirationTime; - } - - Status = ZwAllocateLocallyUniqueId(&TokenId); - if (!NT_SUCCESS(Status)) - return(Status); - - Status = ZwAllocateLocallyUniqueId(&ModifiedId); - if (!NT_SUCCESS(Status)) - return(Status); - - Status = ObCreateObject(PreviousMode, - SepTokenObjectType, - ObjectAttributes, - PreviousMode, - NULL, - sizeof(TOKEN), - 0, - 0, - (PVOID*)&AccessToken); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ObCreateObject() failed (Status %lx)\n"); - return(Status); - } - - AccessToken->TokenLock = &SepTokenLock; - - 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; - AccessToken->ImpersonationLevel = ((PSECURITY_QUALITY_OF_SERVICE) - (ObjectAttributes->SecurityQualityOfService))->ImpersonationLevel; - - /* - * 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 = + + AccessToken->TokenLock = &SepTokenLock; + + 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; + AccessToken->ImpersonationLevel = ((PSECURITY_QUALITY_OF_SERVICE) + (ObjectAttributes->SecurityQualityOfService))->ImpersonationLevel; + + /* + * 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(PagedPool, 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)) + + 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); + Status = RtlCopySidAndAttributesArray(TokenGroups->GroupCount, + TokenGroups->Groups, + uLength, + &AccessToken->UserAndGroups[1], + EndMem, + &EndMem, + &uLength); } - - if (NT_SUCCESS(Status)) + + if (NT_SUCCESS(Status)) { - Status = SepFindPrimaryGroupAndDefaultOwner( - AccessToken, - TokenPrimaryGroup->PrimaryGroup, - TokenOwner->Owner); + Status = SepFindPrimaryGroupAndDefaultOwner( + AccessToken, + TokenPrimaryGroup->PrimaryGroup, + TokenOwner->Owner); } - - if (NT_SUCCESS(Status)) + + if (NT_SUCCESS(Status)) { - uLength = TokenPrivileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); - AccessToken->Privileges = + uLength = TokenPrivileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); + AccessToken->Privileges = (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, uLength, TAG('T', 'O', 'K', 'p')); - - if (PreviousMode != KernelMode) + + if (PreviousMode != KernelMode) { - _SEH_TRY + _SEH_TRY { - RtlCopyMemory(AccessToken->Privileges, - TokenPrivileges->Privileges, - nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES)); + RtlCopyMemory(AccessToken->Privileges, + TokenPrivileges->Privileges, + nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES)); } - _SEH_HANDLE + _SEH_HANDLE { - Status = _SEH_GetExceptionCode(); + Status = _SEH_GetExceptionCode(); } - _SEH_END; + _SEH_END; } - else + else { - RtlCopyMemory(AccessToken->Privileges, - TokenPrivileges->Privileges, - nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES)); + RtlCopyMemory(AccessToken->Privileges, + TokenPrivileges->Privileges, + nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES)); } } - - if (NT_SUCCESS(Status)) + + if (NT_SUCCESS(Status)) { - AccessToken->DefaultDacl = + AccessToken->DefaultDacl = (PACL) ExAllocatePoolWithTag(PagedPool, TokenDefaultDacl->DefaultDacl->AclSize, TAG('T', 'O', 'K', 'd')); - memcpy(AccessToken->DefaultDacl, - TokenDefaultDacl->DefaultDacl, - TokenDefaultDacl->DefaultDacl->AclSize); + memcpy(AccessToken->DefaultDacl, + TokenDefaultDacl->DefaultDacl, + TokenDefaultDacl->DefaultDacl->AclSize); } - - Status = ObInsertObject ((PVOID)AccessToken, - NULL, - DesiredAccess, - 0, - NULL, - &hToken); - if (!NT_SUCCESS(Status)) + + Status = ObInsertObject ((PVOID)AccessToken, + NULL, + DesiredAccess, + 0, + NULL, + &hToken); + if (!NT_SUCCESS(Status)) { - DPRINT1("ObInsertObject() failed (Status %lx)\n", Status); + DPRINT1("ObInsertObject() failed (Status %lx)\n", Status); } - - if (NT_SUCCESS(Status)) + + if (NT_SUCCESS(Status)) { - _SEH_TRY - { - *TokenHandle = hToken; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; + _SEH_TRY + { + *TokenHandle = hToken; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; } - - return Status; + + return Status; } - -/* - * @implemented - */ -NTSTATUS STDCALL -SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token, - OUT PLUID LogonId) -{ - PAGED_CODE(); - - *LogonId = ((PTOKEN)Token)->AuthenticationId; - - return STATUS_SUCCESS; -} - - -/* - * @implemented - */ -SECURITY_IMPERSONATION_LEVEL -STDCALL -SeTokenImpersonationLevel(IN PACCESS_TOKEN Token) -{ - PAGED_CODE(); - - return ((PTOKEN)Token)->ImpersonationLevel; -} - - -/* - * @implemented - */ -TOKEN_TYPE STDCALL -SeTokenType(IN PACCESS_TOKEN Token) -{ - PAGED_CODE(); - - return ((PTOKEN)Token)->TokenType; -} - - -/* - * @implemented - */ -BOOLEAN -STDCALL -SeTokenIsAdmin( - IN PACCESS_TOKEN Token - ) -{ - PAGED_CODE(); - return (((PTOKEN)Token)->TokenFlags & TOKEN_WRITE_RESTRICTED) != 0; -} - -/* - * @implemented - */ -BOOLEAN -STDCALL -SeTokenIsRestricted( - IN PACCESS_TOKEN Token - ) -{ - PAGED_CODE(); - return (((PTOKEN)Token)->TokenFlags & TOKEN_IS_RESTRICTED) != 0; -} - -/* - * @implemented - */ -BOOLEAN -STDCALL -SeTokenIsWriteRestricted( - IN PACCESS_TOKEN Token - ) -{ - PAGED_CODE(); - return (((PTOKEN)Token)->TokenFlags & TOKEN_HAS_RESTORE_PRIVILEGE) != 0; -} - - -/* - * @unimplemented - */ -NTSTATUS -STDCALL -NtImpersonateAnonymousToken( - IN HANDLE Thread - ) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - - /* * @implemented */ @@ -2454,162 +2188,162 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, IN ULONG HandleAttributes, OUT PHANDLE TokenHandle) { - PETHREAD Thread; - HANDLE hToken; - PTOKEN Token, NewToken, PrimaryToken; - BOOLEAN CopyOnOpen, EffectiveOnly; - SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; - SE_IMPERSONATION_STATE ImpersonationState; - OBJECT_ATTRIBUTES ObjectAttributes; - SECURITY_DESCRIPTOR SecurityDescriptor; - PACL Dacl = NULL; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH_TRY + PETHREAD Thread; + HANDLE hToken; + PTOKEN Token, NewToken, PrimaryToken; + BOOLEAN CopyOnOpen, EffectiveOnly; + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + SE_IMPERSONATION_STATE ImpersonationState; + OBJECT_ATTRIBUTES ObjectAttributes; + SECURITY_DESCRIPTOR SecurityDescriptor; + PACL Dacl = NULL; + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + PreviousMode = ExGetPreviousMode(); + + if(PreviousMode != KernelMode) { - ProbeForWriteHandle(TokenHandle); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(!NT_SUCCESS(Status)) - { - return Status; - } - } - - /* - * At first open the thread token for information access and verify - * that the token associated with thread is valid. - */ - - Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION, - PsThreadType, PreviousMode, (PVOID*)&Thread, - NULL); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Token = PsReferenceImpersonationToken(Thread, &CopyOnOpen, &EffectiveOnly, - &ImpersonationLevel); - if (Token == NULL) - { - ObfDereferenceObject(Thread); - return STATUS_NO_TOKEN; - } - - ObDereferenceObject(Thread); - - if (ImpersonationLevel == SecurityAnonymous) - { - ObfDereferenceObject(Token); - return STATUS_CANT_OPEN_ANONYMOUS; - } - - /* - * Revert to self if OpenAsSelf is specified. - */ - - if (OpenAsSelf) - { - PsDisableImpersonation(PsGetCurrentThread(), &ImpersonationState); - } - - if (CopyOnOpen) - { - Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS, - PsThreadType, PreviousMode, - (PVOID*)&Thread, NULL); - if (!NT_SUCCESS(Status)) + _SEH_TRY { - ObfDereferenceObject(Token); - if (OpenAsSelf) - { - PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); - } - return Status; + ProbeForWriteHandle(TokenHandle); } - - PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess); - Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl); - KEBUGCHECK(0); - ObfDereferenceObject(PrimaryToken); - ObfDereferenceObject(Thread); - if (!NT_SUCCESS(Status)) + _SEH_HANDLE { - ObfDereferenceObject(Token); - if (OpenAsSelf) - { - PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); - } - return Status; + Status = _SEH_GetExceptionCode(); } - - RtlCreateSecurityDescriptor(&SecurityDescriptor, - SECURITY_DESCRIPTOR_REVISION); - RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl, - FALSE); - - InitializeObjectAttributes(&ObjectAttributes, NULL, HandleAttributes, - NULL, &SecurityDescriptor); - - Status = SepDuplicateToken(Token, &ObjectAttributes, EffectiveOnly, - TokenImpersonation, ImpersonationLevel, - KernelMode, &NewToken); - ExFreePool(Dacl); - if (!NT_SUCCESS(Status)) + _SEH_END; + + if(!NT_SUCCESS(Status)) { - ObfDereferenceObject(Token); - if (OpenAsSelf) - { - PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); - } - return Status; + return Status; } - - Status = ObInsertObject(NewToken, NULL, DesiredAccess, 0, NULL, - &hToken); - } - else + + /* + * At first open the thread token for information access and verify + * that the token associated with thread is valid. + */ + + Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION, + PsThreadType, PreviousMode, (PVOID*)&Thread, + NULL); + if (!NT_SUCCESS(Status)) { - Status = ObOpenObjectByPointer(Token, HandleAttributes, - NULL, DesiredAccess, SepTokenObjectType, - PreviousMode, &hToken); + return Status; } - - ObfDereferenceObject(Token); - - if (OpenAsSelf) + + Token = PsReferenceImpersonationToken(Thread, &CopyOnOpen, &EffectiveOnly, + &ImpersonationLevel); + if (Token == NULL) { - PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); + ObfDereferenceObject(Thread); + return STATUS_NO_TOKEN; } - - if(NT_SUCCESS(Status)) - { - _SEH_TRY + + ObDereferenceObject(Thread); + + if (ImpersonationLevel == SecurityAnonymous) { - *TokenHandle = hToken; + ObfDereferenceObject(Token); + return STATUS_CANT_OPEN_ANONYMOUS; } - _SEH_HANDLE + + /* + * Revert to self if OpenAsSelf is specified. + */ + + if (OpenAsSelf) { - Status = _SEH_GetExceptionCode(); + PsDisableImpersonation(PsGetCurrentThread(), &ImpersonationState); } - _SEH_END; - } - - return Status; + + if (CopyOnOpen) + { + Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS, + PsThreadType, PreviousMode, + (PVOID*)&Thread, NULL); + if (!NT_SUCCESS(Status)) + { + ObfDereferenceObject(Token); + if (OpenAsSelf) + { + PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); + } + return Status; + } + + PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess); + Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl); + KEBUGCHECK(0); + ObfDereferenceObject(PrimaryToken); + ObfDereferenceObject(Thread); + if (!NT_SUCCESS(Status)) + { + ObfDereferenceObject(Token); + if (OpenAsSelf) + { + PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); + } + return Status; + } + + RtlCreateSecurityDescriptor(&SecurityDescriptor, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl, + FALSE); + + InitializeObjectAttributes(&ObjectAttributes, NULL, HandleAttributes, + NULL, &SecurityDescriptor); + + Status = SepDuplicateToken(Token, &ObjectAttributes, EffectiveOnly, + TokenImpersonation, ImpersonationLevel, + KernelMode, &NewToken); + ExFreePool(Dacl); + if (!NT_SUCCESS(Status)) + { + ObfDereferenceObject(Token); + if (OpenAsSelf) + { + PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); + } + return Status; + } + + Status = ObInsertObject(NewToken, NULL, DesiredAccess, 0, NULL, + &hToken); + + } + else + { + Status = ObOpenObjectByPointer(Token, HandleAttributes, + NULL, DesiredAccess, SepTokenObjectType, + PreviousMode, &hToken); + } + + ObfDereferenceObject(Token); + + if (OpenAsSelf) + { + PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); + } + + if(NT_SUCCESS(Status)) + { + _SEH_TRY + { + *TokenHandle = hToken; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + + return Status; } /* @@ -2621,35 +2355,11 @@ NtOpenThreadToken(IN HANDLE ThreadHandle, IN BOOLEAN OpenAsSelf, OUT PHANDLE TokenHandle) { - return NtOpenThreadTokenEx(ThreadHandle, DesiredAccess, OpenAsSelf, 0, - TokenHandle); + return NtOpenThreadTokenEx(ThreadHandle, DesiredAccess, OpenAsSelf, 0, + TokenHandle); } -static NTSTATUS -SepCompareTokens(IN PTOKEN FirstToken, - IN PTOKEN SecondToken, - OUT PBOOLEAN Equal) -{ - BOOLEAN Restricted, IsEqual = FALSE; - ASSERT(FirstToken != SecondToken); - - /* FIXME: Check if every SID that is present in either token is also present in the other one */ - - Restricted = SeTokenIsRestricted(FirstToken); - if (Restricted == SeTokenIsRestricted(SecondToken)) - { - if (Restricted) - { - /* FIXME: Check if every SID that is restricted in either token is also restricted in the other one */ - } - - /* FIXME: Check if every privilege that is present in either token is also present in the other one */ - } - - *Equal = IsEqual; - return STATUS_SUCCESS; -} /* * @unimplemented @@ -2664,11 +2374,11 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, PTOKEN FirstToken, SecondToken; BOOLEAN IsEqual; NTSTATUS Status = STATUS_SUCCESS; - + PAGED_CODE(); - + PreviousMode = ExGetPreviousMode(); - + if (PreviousMode != KernelMode) { _SEH_TRY @@ -2680,11 +2390,11 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, Status = _SEH_GetExceptionCode(); } _SEH_END; - + if (!NT_SUCCESS(Status)) return Status; } - + Status = ObReferenceObjectByHandle(FirstTokenHandle, TOKEN_QUERY, SepTokenObjectType, @@ -2693,7 +2403,7 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, NULL); if (!NT_SUCCESS(Status)) return Status; - + Status = ObReferenceObjectByHandle(SecondTokenHandle, TOKEN_QUERY, SepTokenObjectType, @@ -2705,7 +2415,7 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, ObDereferenceObject(FirstToken); return Status; } - + if (FirstToken != SecondToken) { Status = SepCompareTokens(FirstToken, @@ -2714,10 +2424,10 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, } else IsEqual = TRUE; - + ObDereferenceObject(FirstToken); ObDereferenceObject(SecondToken); - + if (NT_SUCCESS(Status)) { _SEH_TRY @@ -2730,7 +2440,7 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, } _SEH_END; } - + return Status; } @@ -2747,4 +2457,15 @@ NtFilterToken(IN HANDLE ExistingTokenHandle, return STATUS_NOT_IMPLEMENTED; } +/* + * @unimplemented + */ +NTSTATUS +STDCALL +NtImpersonateAnonymousToken(IN HANDLE Thread) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + /* EOF */