diff --git a/reactos/ntoskrnl/po/povolume.c b/reactos/ntoskrnl/po/povolume.c index 58cc3327deb..15aaebf7586 100644 --- a/reactos/ntoskrnl/po/povolume.c +++ b/reactos/ntoskrnl/po/povolume.c @@ -84,16 +84,13 @@ PoVolumeDevice(IN PDEVICE_OBJECT DeviceObject) PAGED_CODE(); /* Get dope from the device (if the device has no dope, it will receive some) */ - DPRINT1("New volume: %p\n", DeviceObject); Dope = PopGetDope(DeviceObject); if (Dope) { /* Make sure we can flush safely */ - DPRINT1("Acquiring volume lock\n"); KeAcquireGuardedMutex(&PopVolumeLock); /* Add this volume into the list of power-manager volumes */ - DPRINT1("Got DOPE: %p\n", Dope); if (!Dope->Volume.Flink) InsertTailList(&PopVolumeDevices, &Dope->Volume); /* Allow flushes to go through */ diff --git a/reactos/ntoskrnl/ps/security.c b/reactos/ntoskrnl/ps/security.c index 27895d35057..f45b09175dd 100644 --- a/reactos/ntoskrnl/ps/security.c +++ b/reactos/ntoskrnl/ps/security.c @@ -965,32 +965,32 @@ NtImpersonateThread(IN HANDLE ThreadHandle, /* Reference the thread */ Status = ObReferenceObjectByHandle(ThreadHandle, - THREAD_IMPERSONATE, + THREAD_DIRECT_IMPERSONATION, PsThreadType, PreviousMode, (PVOID*)&Thread, NULL); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { /* Reference the impersonating thead */ Status = ObReferenceObjectByHandle(ThreadToImpersonateHandle, - THREAD_DIRECT_IMPERSONATION, + THREAD_IMPERSONATE, PsThreadType, PreviousMode, (PVOID*)&ThreadToImpersonate, NULL); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { /* Create a client security context */ Status = SeCreateClientSecurity(ThreadToImpersonate, SecurityQualityOfService, 0, &ClientContext); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { /* Do the impersonation */ SeImpersonateClient(&ClientContext, Thread); - if(ClientContext.ClientToken) + if (ClientContext.ClientToken) { /* Dereference the client token if we had one */ ObDereferenceObject(ClientContext.ClientToken); diff --git a/reactos/ntoskrnl/se/semgr.c b/reactos/ntoskrnl/se/semgr.c index fdee0973027..8ed056becb8 100644 --- a/reactos/ntoskrnl/se/semgr.c +++ b/reactos/ntoskrnl/se/semgr.c @@ -279,6 +279,7 @@ SeDefaultObjectMethod(IN PVOID Object, return STATUS_SUCCESS; } +ULONG SidInTokenCalls = 0; static BOOLEAN SepSidInToken(PACCESS_TOKEN _Token, @@ -289,6 +290,9 @@ SepSidInToken(PACCESS_TOKEN _Token, PAGED_CODE(); + SidInTokenCalls++; + if (!(SidInTokenCalls % 10000)) DPRINT1("SidInToken Calls: %d\n", SidInTokenCalls); + if (Token->UserAndGroupCount == 0) { return FALSE; @@ -298,7 +302,7 @@ SepSidInToken(PACCESS_TOKEN _Token, { if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid)) { - if (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED) + if ((i == 0)|| (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)) { return TRUE; } @@ -470,7 +474,16 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, SeUnlockSubjectContext(SubjectSecurityContext); } - *GrantedAccess = DesiredAccess; + if (DesiredAccess & MAXIMUM_ALLOWED) + { + *GrantedAccess = GenericMapping->GenericAll; + *GrantedAccess |= (DesiredAccess & ~MAXIMUM_ALLOWED); + } + else + { + *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess; + } + *AccessStatus = STATUS_SUCCESS; return TRUE; } diff --git a/reactos/ntoskrnl/se/token.c b/reactos/ntoskrnl/se/token.c index 38e5012c559..c27d7f8c40a 100644 --- a/reactos/ntoskrnl/se/token.c +++ b/reactos/ntoskrnl/se/token.c @@ -22,6 +22,9 @@ POBJECT_TYPE SepTokenObjectType = NULL; ERESOURCE SepTokenLock; +TOKEN_SOURCE SeSystemTokenSource = {"*SYSTEM*", {0}}; +LUID SeSystemAuthenticationId = SYSTEM_LUID; + static GENERIC_MAPPING SepTokenMapping = {TOKEN_READ, TOKEN_WRITE, TOKEN_EXECUTE, @@ -244,7 +247,7 @@ SepDuplicateToken(PTOKEN Token, (PVOID*)&AccessToken); if (!NT_SUCCESS(Status)) { - DPRINT1("ObCreateObject() failed (Status %lx)\n"); + DPRINT1("ObCreateObject() failed (Status %lx)\n", Status); return(Status); } @@ -510,34 +513,80 @@ SeAssignPrimaryToken(IN PEPROCESS Process, ObInitializeFastReference(&Process->Token, Token); } -PTOKEN + +NTSTATUS NTAPI -SepCreateSystemProcessToken(VOID) -{ - NTSTATUS Status; - ULONG uSize; - ULONG i; - ULONG uLocalSystemLength; - ULONG uWorldLength; - ULONG uAuthUserLength; - ULONG uAdminsLength; +SepCreateToken(OUT PHANDLE TokenHandle, + IN KPROCESSOR_MODE PreviousMode, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN TOKEN_TYPE TokenType, + IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, + IN PLUID AuthenticationId, + IN PLARGE_INTEGER ExpirationTime, + IN PSID_AND_ATTRIBUTES User, + IN ULONG GroupCount, + IN PSID_AND_ATTRIBUTES Groups, + IN ULONG GroupLength, + IN ULONG PrivilegeCount, + IN PLUID_AND_ATTRIBUTES Privileges, + IN PSID Owner, + IN PSID PrimaryGroup, + IN PACL DefaultDacl, + IN PTOKEN_SOURCE TokenSource, + IN BOOLEAN SystemToken) +{ PTOKEN AccessToken; - PVOID SidArea; + LUID TokenId; + LUID ModifiedId; + PVOID EndMem; + ULONG uLength; + ULONG i; + NTSTATUS Status; + ULONG TokenFlags = 0; - PAGED_CODE(); + /* Loop all groups */ + for (i = 0; i < GroupCount; i++) + { + /* Check for mandatory groups */ + if (Groups[i].Attributes & SE_GROUP_MANDATORY) + { + /* Force them to be enabled */ + Groups[i].Attributes |= (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT); + } + + /* Check of the group is an admin group */ + if (RtlEqualSid(SeAliasAdminsSid, Groups[i].Sid)) + { + /* Remember this so we can optimize queries later */ + TokenFlags |= TOKEN_HAS_ADMIN_GROUP; + } + } - uLocalSystemLength = RtlLengthSid(SeLocalSystemSid); - uWorldLength = RtlLengthSid(SeWorldSid); - uAuthUserLength = RtlLengthSid(SeAuthenticatedUserSid); - uAdminsLength = RtlLengthSid(SeAliasAdminsSid); + /* Loop all privileges */ + for (i = 0; i < PrivilegeCount; i++) + { + /* For optimization, check for change notify and impersonate rights */ + if (((RtlEqualLuid(&Privileges[i].Luid, &SeChangeNotifyPrivilege)) && + (Privileges[i].Attributes & SE_PRIVILEGE_ENABLED))) + { + /* Remember token has traverse */ + TokenFlags |= TOKEN_HAS_TRAVERSE_PRIVILEGE; + } + } + + Status = ZwAllocateLocallyUniqueId(&TokenId); + if (!NT_SUCCESS(Status)) + return(Status); - /* - * Initialize the token - */ - Status = ObCreateObject(KernelMode, + Status = ZwAllocateLocallyUniqueId(&ModifiedId); + if (!NT_SUCCESS(Status)) + return(Status); + + Status = ObCreateObject(PreviousMode, SepTokenObjectType, - NULL, - KernelMode, + ObjectAttributes, + PreviousMode, NULL, sizeof(TOKEN), 0, @@ -545,180 +594,279 @@ SepCreateSystemProcessToken(VOID) (PVOID*)&AccessToken); if (!NT_SUCCESS(Status)) { - return NULL; + DPRINT1("ObCreateObject() failed (Status %lx)\n"); + return(Status); } /* Zero out the buffer */ RtlZeroMemory(AccessToken, sizeof(TOKEN)); - 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; - memcpy(AccessToken->TokenSource.SourceName, "SeMgr\0\0\0", 8); - AccessToken->ExpirationTime.QuadPart = -1; - AccessToken->UserAndGroupCount = 4; + RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier, + &TokenSource->SourceIdentifier); + memcpy(AccessToken->TokenSource.SourceName, + TokenSource->SourceName, + sizeof(TokenSource->SourceName)); - uSize = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount; - uSize += uLocalSystemLength; - uSize += uWorldLength; - uSize += uAuthUserLength; - uSize += uAdminsLength; + RtlCopyLuid(&AccessToken->TokenId, &TokenId); + RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId); + AccessToken->ExpirationTime = *ExpirationTime; + RtlCopyLuid(&AccessToken->ModifiedId, &ModifiedId); + + AccessToken->UserAndGroupCount = GroupCount + 1; + AccessToken->PrivilegeCount = PrivilegeCount; + + AccessToken->TokenFlags = TokenFlags; + AccessToken->TokenType = TokenType; + AccessToken->ImpersonationLevel = 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(User); + for (i = 0; i < GroupCount; i++) + uLength += RtlLengthSid(Groups[i].Sid); AccessToken->UserAndGroups = (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, - uSize, + uLength, 'uKOT'); - SidArea = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount]; + EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount]; + + Status = RtlCopySidAndAttributesArray(1, + User, + uLength, + AccessToken->UserAndGroups, + EndMem, + &EndMem, + &uLength); + if (NT_SUCCESS(Status)) + { + Status = RtlCopySidAndAttributesArray(GroupCount, + Groups, + uLength, + &AccessToken->UserAndGroups[1], + EndMem, + &EndMem, + &uLength); + } + + if (NT_SUCCESS(Status)) + { + Status = SepFindPrimaryGroupAndDefaultOwner( + AccessToken, + PrimaryGroup, + Owner); + } + + if (NT_SUCCESS(Status)) + { + uLength = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); + AccessToken->Privileges = + (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, + uLength, + 'pKOT'); + + if (PreviousMode != KernelMode) + { + _SEH2_TRY + { + RtlCopyMemory(AccessToken->Privileges, + Privileges, + PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + else + { + RtlCopyMemory(AccessToken->Privileges, + Privileges, + PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); + } + } + + if (NT_SUCCESS(Status)) + { + AccessToken->DefaultDacl = + (PACL) ExAllocatePoolWithTag(PagedPool, + DefaultDacl->AclSize, + 'kDOT'); + memcpy(AccessToken->DefaultDacl, + DefaultDacl, + DefaultDacl->AclSize); + } + + if (!SystemToken) + { + + Status = ObInsertObject ((PVOID)AccessToken, + NULL, + DesiredAccess, + 0, + NULL, + TokenHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ObInsertObject() failed (Status %lx)\n", Status); + } + } + else + { + /* Return pointer instead of handle */ + *TokenHandle = (HANDLE)AccessToken; + } + + return Status; +} + +PTOKEN +NTAPI +SepCreateSystemProcessToken(VOID) +{ + LUID_AND_ATTRIBUTES Privileges[25]; + ULONG GroupAttributes, OwnerAttributes; + SID_AND_ATTRIBUTES Groups[32]; + LARGE_INTEGER Expiration; + SID_AND_ATTRIBUTES UserSid; + ULONG GroupLength; + PSID PrimaryGroup; + OBJECT_ATTRIBUTES ObjectAttributes; + PSID Owner; + ULONG i; + PTOKEN Token; + NTSTATUS Status; + + /* Don't ever expire */ + Expiration.QuadPart = -1; + + /* All groups mandatory and enabled */ + GroupAttributes = SE_GROUP_ENABLED | SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT; + OwnerAttributes = SE_GROUP_ENABLED | SE_GROUP_OWNER | SE_GROUP_ENABLED_BY_DEFAULT; + + /* User is system */ + UserSid.Sid = SeLocalSystemSid; + UserSid.Attributes = 0; + + /* Primary group is local system */ + PrimaryGroup = SeLocalSystemSid; + + /* Owner is admins */ + Owner = SeAliasAdminsSid; + + /* Groups are admins, world, and authenticated users */ + Groups[0].Sid = SeAliasAdminsSid; + Groups[0].Attributes = OwnerAttributes; + Groups[1].Sid = SeWorldSid; + Groups[1].Attributes = GroupAttributes; + Groups[2].Sid = SeAuthenticatedUserSid; + Groups[2].Attributes = OwnerAttributes; + GroupLength = sizeof(SID_AND_ATTRIBUTES) + + SeLengthSid(Groups[0].Sid) + + SeLengthSid(Groups[1].Sid) + + SeLengthSid(Groups[2].Sid); + ASSERT(GroupLength <= sizeof(Groups)); + + /* Setup the privileges */ i = 0; - AccessToken->UserAndGroups[i].Sid = (PSID) SidArea; - AccessToken->UserAndGroups[i++].Attributes = 0; - RtlCopySid(uLocalSystemLength, SidArea, SeLocalSystemSid); - SidArea = (char*)SidArea + uLocalSystemLength; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeTcbPrivilege; - 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; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeCreateTokenPrivilege; - 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; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeTakeOwnershipPrivilege; - 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; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeCreatePagefilePrivilege; - AccessToken->PrivilegeCount = 20; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeLockMemoryPrivilege; - uSize = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); - AccessToken->Privileges = - (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, - uSize, - 'pKOT'); + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege; - i = 0; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeTcbPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeIncreaseQuotaPrivilege; - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeCreateTokenPrivilege; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege; - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeTakeOwnershipPrivilege; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeCreatePermanentPrivilege; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeCreatePagefilePrivilege; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeDebugPrivilege; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeLockMemoryPrivilege; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeAuditPrivilege; - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeSecurityPrivilege; - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeIncreaseQuotaPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeSystemEnvironmentPrivilege; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege; + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeChangeNotifyPrivilege; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeCreatePermanentPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeBackupPrivilege; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeDebugPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeRestorePrivilege; - AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; - AccessToken->Privileges[i++].Luid = SeAuditPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeShutdownPrivilege; - AccessToken->Privileges[i].Attributes = 0; - AccessToken->Privileges[i++].Luid = SeSecurityPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeLoadDriverPrivilege; - 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 + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + Privileges[i++].Luid = SeProfileSingleProcessPrivilege; + Privileges[i].Attributes = 0; + Privileges[i++].Luid = SeSystemtimePrivilege; ASSERT(i == 20); - uSize = sizeof(ACL); - uSize += sizeof(ACE) + uLocalSystemLength; - uSize += sizeof(ACE) + uAdminsLength; - uSize = (uSize & (~3)) + 8; - AccessToken->DefaultDacl = - (PACL) ExAllocatePoolWithTag(PagedPool, - uSize, - 'kDOT'); - Status = RtlCreateAcl(AccessToken->DefaultDacl, uSize, ACL_REVISION); - if ( NT_SUCCESS(Status) ) - { - Status = RtlAddAccessAllowedAce(AccessToken->DefaultDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); - } + /* Setup the object attributes */ + InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); + ASSERT(SeSystemDefaultDacl != NULL); - if ( NT_SUCCESS(Status) ) - { - Status = RtlAddAccessAllowedAce(AccessToken->DefaultDacl, ACL_REVISION, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE|READ_CONTROL, SeAliasAdminsSid); - } + /* Create the token */ + Status = SepCreateToken((PHANDLE)&Token, + KernelMode, + 0, + &ObjectAttributes, + TokenPrimary, + 0, + &SeSystemAuthenticationId, + &Expiration, + &UserSid, + 3, + Groups, + GroupLength, + 20, + Privileges, + Owner, + PrimaryGroup, + SeSystemDefaultDacl, + &SeSystemTokenSource, + TRUE); + ASSERT(Status == STATUS_SUCCESS); - if ( ! NT_SUCCESS(Status) ) - { - ObDereferenceObject(AccessToken); - return NULL; - } - - return AccessToken; + /* Return the token */ + return Token; } /* PUBLIC FUNCTIONS ***********************************************************/ @@ -1920,7 +2068,8 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, return Status; } -NTSTATUS NTAPI +NTSTATUS +NTAPI NtCreateToken(OUT PHANDLE TokenHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, @@ -1936,12 +2085,6 @@ NtCreateToken(OUT PHANDLE TokenHandle, 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, 0}}; @@ -1996,148 +2139,25 @@ NtCreateToken(OUT PHANDLE TokenHandle, 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, + Status = SepCreateToken(&hToken, PreviousMode, - NULL, - sizeof(TOKEN), - 0, - 0, - (PVOID*)&AccessToken); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ObCreateObject() failed (Status %lx)\n"); - return(Status); - } - - /* Zero out the buffer */ - RtlZeroMemory(AccessToken, sizeof(TOKEN)); - - 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->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, - 'uKOT'); - - EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount]; - - Status = RtlCopySidAndAttributesArray(1, - &TokenUser->User, - uLength, - AccessToken->UserAndGroups, - EndMem, - &EndMem, - &uLength); - if (NT_SUCCESS(Status)) - { - Status = RtlCopySidAndAttributesArray(TokenGroups->GroupCount, - TokenGroups->Groups, - uLength, - &AccessToken->UserAndGroups[1], - EndMem, - &EndMem, - &uLength); - } - - if (NT_SUCCESS(Status)) - { - Status = SepFindPrimaryGroupAndDefaultOwner( - AccessToken, - TokenPrimaryGroup->PrimaryGroup, - TokenOwner->Owner); - } - - if (NT_SUCCESS(Status)) - { - uLength = TokenPrivileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); - AccessToken->Privileges = - (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, - uLength, - 'pKOT'); - - if (PreviousMode != KernelMode) - { - _SEH2_TRY - { - RtlCopyMemory(AccessToken->Privileges, - TokenPrivileges->Privileges, - nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES)); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - } - else - { - RtlCopyMemory(AccessToken->Privileges, - TokenPrivileges->Privileges, - nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES)); - } - } - - if (NT_SUCCESS(Status)) - { - AccessToken->DefaultDacl = - (PACL) ExAllocatePoolWithTag(PagedPool, - TokenDefaultDacl->DefaultDacl->AclSize, - 'kDOT'); - memcpy(AccessToken->DefaultDacl, - TokenDefaultDacl->DefaultDacl, - TokenDefaultDacl->DefaultDacl->AclSize); - } - - Status = ObInsertObject ((PVOID)AccessToken, - NULL, - DesiredAccess, - 0, - NULL, - &hToken); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ObInsertObject() failed (Status %lx)\n", Status); - } - + DesiredAccess, + ObjectAttributes, + TokenType, + ((PSECURITY_QUALITY_OF_SERVICE)(ObjectAttributes->SecurityQualityOfService))->ImpersonationLevel, + AuthenticationId, + &LocalExpirationTime, + &TokenUser->User, + TokenGroups->GroupCount, + TokenGroups->Groups, + 0, // FIXME: Should capture + nTokenPrivileges, + TokenPrivileges->Privileges, + TokenOwner->Owner, + TokenPrimaryGroup->PrimaryGroup, + TokenDefaultDacl->DefaultDacl, + TokenSource, + FALSE); if (NT_SUCCESS(Status)) { _SEH2_TRY @@ -2165,7 +2185,7 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, IN ULONG HandleAttributes, OUT PHANDLE TokenHandle) { - PETHREAD Thread; + PETHREAD Thread, NewThread; HANDLE hToken; PTOKEN Token, NewToken, PrimaryToken; BOOLEAN CopyOnOpen, EffectiveOnly; @@ -2215,12 +2235,11 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, ObDereferenceObject(Thread); return STATUS_NO_TOKEN; } - - ObDereferenceObject(Thread); - + if (ImpersonationLevel == SecurityAnonymous) { - ObDereferenceObject(Token); + PsDereferenceImpersonationToken(Token); + ObDereferenceObject(Thread); return STATUS_CANT_OPEN_ANONYMOUS; } @@ -2236,58 +2255,41 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, if (CopyOnOpen) { Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS, - PsThreadType, PreviousMode, - (PVOID*)&Thread, NULL); - if (!NT_SUCCESS(Status)) + PsThreadType, KernelMode, + (PVOID*)&NewThread, NULL); + if (NT_SUCCESS(Status)) { - ObDereferenceObject(Token); - if (OpenAsSelf) + PrimaryToken = PsReferencePrimaryToken(NewThread->ThreadsProcess); + + Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl); + + ObFastDereferenceObject(&NewThread->ThreadsProcess->Token, PrimaryToken); + + if (NT_SUCCESS(Status)) { - PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); + if (Dacl) + { + RtlCreateSecurityDescriptor(&SecurityDescriptor, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl, + FALSE); + } + + InitializeObjectAttributes(&ObjectAttributes, NULL, HandleAttributes, + NULL, Dacl ? &SecurityDescriptor : NULL); + + + Status = SepDuplicateToken(Token, &ObjectAttributes, EffectiveOnly, + TokenImpersonation, ImpersonationLevel, + KernelMode, &NewToken); + if (NT_SUCCESS(Status)) + { + ObReferenceObject(NewToken); + Status = ObInsertObject(NewToken, NULL, DesiredAccess, 0, NULL, + &hToken); + } } - return Status; } - - PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess); - Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl); - ASSERT(FALSE); - ObDereferenceObject(PrimaryToken); - ObDereferenceObject(Thread); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(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)) - { - ObDereferenceObject(Token); - if (OpenAsSelf) - { - PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); - } - return Status; - } - - Status = ObInsertObject(NewToken, NULL, DesiredAccess, 0, NULL, - &hToken); - } else { @@ -2296,13 +2298,24 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, PreviousMode, &hToken); } - ObDereferenceObject(Token); + if (Dacl) ExFreePool(Dacl); if (OpenAsSelf) { PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); } + ObDereferenceObject(Token); + + if (NT_SUCCESS(Status) && CopyOnOpen) + { + PsImpersonateClient(Thread, NewToken, FALSE, EffectiveOnly, ImpersonationLevel); + } + + if (NewToken) ObDereferenceObject(NewToken); + + if (CopyOnOpen && NewThread) ObDereferenceObject(NewThread); + if(NT_SUCCESS(Status)) { _SEH2_TRY diff --git a/reactos/subsystems/csr/csrsrv/process.c b/reactos/subsystems/csr/csrsrv/process.c index c26a6c1d94e..1de2286b549 100644 --- a/reactos/subsystems/csr/csrsrv/process.c +++ b/reactos/subsystems/csr/csrsrv/process.c @@ -916,7 +916,7 @@ CsrGetProcessLuid(HANDLE hProcess OPTIONAL, /* Now query the information */ Status = NtQueryInformationToken(hToken, TokenStatistics, - &TokenStats, + TokenStats, Length, &Length);