Thomas Weidenmueller w3seek@reactos.com - Fix various security structures and constants - Add code to capture quality of service structures and ACLs - Secure buffer access in NtQueryInformationToken, NtSetInformationToken, NtNotifyChangeDirectoryFile and NtQueryDirectoryFile Modified: trunk/reactos/include/ddk/setypes.h Modified: trunk/reactos/include/ntos/security.h Modified: trunk/reactos/lib/rtl/sid.c Modified: trunk/reactos/ntoskrnl/include/internal/ob.h Modified: trunk/reactos/ntoskrnl/include/internal/se.h Modified: trunk/reactos/ntoskrnl/io/dir.c Modified: trunk/reactos/ntoskrnl/ob/object.c Modified: trunk/reactos/ntoskrnl/se/acl.c Modified: trunk/reactos/ntoskrnl/se/luid.c Modified: trunk/reactos/ntoskrnl/se/sd.c Modified: trunk/reactos/ntoskrnl/se/sid.c Modified: trunk/reactos/ntoskrnl/se/token.c _____
Modified: trunk/reactos/include/ddk/setypes.h --- trunk/reactos/include/ddk/setypes.h 2005-03-12 22:10:11 UTC (rev 13983) +++ trunk/reactos/include/ddk/setypes.h 2005-03-12 22:16:02 UTC (rev 13984) @@ -98,37 +98,36 @@
} SEP_AUDIT_POLICY, *PSEP_AUDIT_POLICY;
typedef struct _TOKEN { - TOKEN_SOURCE TokenSource; /* 0x00 */ - LUID TokenId; /* 0x10 */ - LUID AuthenticationId; /* 0x18 */ - LUID ParentTokenId; /* 0x20 */ - LARGE_INTEGER ExpirationTime; /* 0x28 */ - struct _ERESOURCE *TokenLock; /* 0x30 */ - ULONG Padding; /* 0x34 */ - SEP_AUDIT_POLICY AuditPolicy; /* 0x38 */ - LUID ModifiedId; /* 0x40 */ - ULONG SessionId; /* 0x48 */ - ULONG UserAndGroupCount; /* 0x4C */ - ULONG RestrictedSidCount; /* 0x50 */ - ULONG PrivilegeCount; /* 0x54 */ - ULONG VariableLength; /* 0x58 */ - ULONG DynamicCharged; /* 0x5C */ - ULONG DynamicAvailable; /* 0x60 */ - ULONG DefaultOwnerIndex; /* 0x64 */ - PSID_AND_ATTRIBUTES UserAndGroups; /* 0x68 */ - PSID_AND_ATTRIBUTES RestrictedSids; /* 0x6C */ - PSID PrimaryGroup; /* 0x70 */ - PLUID_AND_ATTRIBUTES Privileges; /* 0x74 */ - PULONG DynamicPart; /* 0x78 */ - PACL DefaultDacl; /* 0x7C */ - TOKEN_TYPE TokenType; /* 0x80 */ - SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; /* 0x84 */ - ULONG TokenFlags; /* 0x88 */ - ULONG TokenInUse; /* 0x8C */ - PVOID ProxyData; /* 0x90 */ - PVOID AuditData; /* 0x94 */ - LUID OriginatingLogonSession; /* 0x98 */ - UCHAR VariablePart[1]; /* 0xA0 */ + TOKEN_SOURCE TokenSource; /* 0x00 */ + LUID TokenId; /* 0x10 */ + LUID AuthenticationId; /* 0x18 */ + LUID ParentTokenId; /* 0x20 */ + LARGE_INTEGER ExpirationTime; /* 0x28 */ + struct _ERESOURCE *TokenLock; /* 0x30 */ + SEP_AUDIT_POLICY AuditPolicy; /* 0x38 */ + LUID ModifiedId; /* 0x40 */ + ULONG SessionId; /* 0x48 */ + ULONG UserAndGroupCount; /* 0x4C */ + ULONG RestrictedSidCount; /* 0x50 */ + ULONG PrivilegeCount; /* 0x54 */ + ULONG VariableLength; /* 0x58 */ + ULONG DynamicCharged; /* 0x5C */ + ULONG DynamicAvailable; /* 0x60 */ + ULONG DefaultOwnerIndex; /* 0x64 */ + PSID_AND_ATTRIBUTES UserAndGroups; /* 0x68 */ + PSID_AND_ATTRIBUTES RestrictedSids; /* 0x6C */ + PSID PrimaryGroup; /* 0x70 */ + PLUID_AND_ATTRIBUTES Privileges; /* 0x74 */ + PULONG DynamicPart; /* 0x78 */ + PACL DefaultDacl; /* 0x7C */ + TOKEN_TYPE TokenType; /* 0x80 */ + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; /* 0x84 */ + ULONG TokenFlags; /* 0x88 */ + BOOLEAN TokenInUse; /* 0x8C */ + PVOID ProxyData; /* 0x90 */ + PVOID AuditData; /* 0x94 */ + LUID OriginatingLogonSession; /* 0x98 */ + ULONG VariablePart; /* 0xA0 */ } TOKEN, *PTOKEN;
typedef PVOID PACCESS_TOKEN; _____
Modified: trunk/reactos/include/ntos/security.h --- trunk/reactos/include/ntos/security.h 2005-03-12 22:10:11 UTC (rev 13983) +++ trunk/reactos/include/ntos/security.h 2005-03-12 22:16:02 UTC (rev 13984) @@ -153,13 +153,14 @@
#define TOKEN_ADJUST_PRIVILEGES (0x0020L) #define TOKEN_ADJUST_GROUPS (0x0040L) #define TOKEN_ADJUST_DEFAULT (0x0080L) +#define TOKEN_ADJUST_SESSIONID (0x0100L)
-#define TOKEN_ALL_ACCESS (0xf00ffL) +#define TOKEN_ALL_ACCESS (0xf01ffL) #define TOKEN_READ (0x20008L) #define TOKEN_WRITE (0x200e0L) #define TOKEN_EXECUTE (0x20000L)
-typedef BOOL SECURITY_CONTEXT_TRACKING_MODE; +typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, *PSECURITY_CONTEXT_TRACKING_MODE;
#define SECURITY_STATIC_TRACKING (0) #define SECURITY_DYNAMIC_TRACKING (1) @@ -192,13 +193,14 @@ TokenOrigin } TOKEN_INFORMATION_CLASS;
-typedef ULONG SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL; +typedef enum _SECURITY_IMPERSONATION_LEVEL +{ + SecurityAnonymous, + SecurityIdentification, + SecurityImpersonation, + SecurityDelegation +} SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
-#define SecurityAnonymous ((SECURITY_IMPERSONATION_LEVEL)0) -#define SecurityIdentification ((SECURITY_IMPERSONATION_LEVEL)1) -#define SecurityImpersonation ((SECURITY_IMPERSONATION_LEVEL)2) -#define SecurityDelegation ((SECURITY_IMPERSONATION_LEVEL)3) - typedef ULONG ACCESS_MASK, *PACCESS_MASK; typedef ULONG TOKEN_TYPE, *PTOKEN_TYPE;
@@ -339,6 +341,20 @@ SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]; } TOKEN_GROUPS, *PTOKEN_GROUPS, *LPTOKEN_GROUPS;
+typedef struct _TOKEN_GROUPS_AND_PRIVILEGES +{ + ULONG SidCount; + ULONG SidLength; + PSID_AND_ATTRIBUTES Sids; + ULONG RestrictedSidCount; + ULONG RestrictedSidLength; + PSID_AND_ATTRIBUTES RestrictedSids; + ULONG PrivilegeCount; + ULONG PrivilegeLength; + PLUID_AND_ATTRIBUTES Privileges; + LUID AuthenticationId; +} TOKEN_GROUPS_AND_PRIVILEGES, *PTOKEN_GROUPS_AND_PRIVILEGES; + typedef struct _TOKEN_PRIVILEGES { DWORD PrivilegeCount; _____
Modified: trunk/reactos/lib/rtl/sid.c --- trunk/reactos/lib/rtl/sid.c 2005-03-12 22:10:11 UTC (rev 13983) +++ trunk/reactos/lib/rtl/sid.c 2005-03-12 22:16:02 UTC (rev 13984) @@ -200,7 +200,7 @@
RtlCopySid(SidLength, SidArea, Src[i].Sid); - SidArea = SidArea + SidLength; + SidArea = (PVOID)((ULONG_PTR)SidArea + SidLength); } *RemainingSidArea = SidArea; *RemainingSidAreaSize = Length; _____
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h --- trunk/reactos/ntoskrnl/include/internal/ob.h 2005-03-12 22:10:11 UTC (rev 13983) +++ trunk/reactos/ntoskrnl/include/internal/ob.h 2005-03-12 22:16:02 UTC (rev 13984) @@ -326,7 +326,7 @@
HANDLE RootDirectory; ULONG Attributes; PSECURITY_DESCRIPTOR SecurityDescriptor; - /* PVOID SecurityQualityOfService; */ + PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService; } CAPTURED_OBJECT_ATTRIBUTES, *PCAPTURED_OBJECT_ATTRIBUTES;
NTSTATUS @@ -377,10 +377,8 @@ else if(ClassList[Class].RequiredSize##Mode > 0 && \ (BufferLen) != ClassList[Class].RequiredSize##Mode) \ { \ - if((!(ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) && \ - (BufferLen) != ClassList[Class].RequiredSize##Mode) || \ - ((ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) && \ - (BufferLen) < ClassList[Class].RequiredSize##Mode)) \ + if(!(ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) && \ + (BufferLen) != ClassList[Class].RequiredSize##Mode) \ { \ *(StatusVar) = STATUS_INFO_LENGTH_MISMATCH; \ } \ _____
Modified: trunk/reactos/ntoskrnl/include/internal/se.h --- trunk/reactos/ntoskrnl/include/internal/se.h 2005-03-12 22:10:11 UTC (rev 13983) +++ trunk/reactos/ntoskrnl/include/internal/se.h 2005-03-12 22:16:02 UTC (rev 13984) @@ -148,7 +148,61 @@
ULONG PrivilegeControl, KPROCESSOR_MODE PreviousMode);
+NTSTATUS +SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN KPROCESSOR_MODE AccessMode, + IN POOL_TYPE PoolType, + IN BOOLEAN CaptureIfKernel, + OUT PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService, + OUT PBOOLEAN Present);
+VOID +SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL, + IN KPROCESSOR_MODE AccessMode, + IN BOOLEAN CaptureIfKernel); + +NTSTATUS +SepCaptureSid(IN PSID InputSid, + IN KPROCESSOR_MODE AccessMode, + IN POOL_TYPE PoolType, + IN BOOLEAN CaptureIfKernel, + OUT PSID *CapturedSid); + +VOID +SepReleaseSid(IN PSID CapturedSid, + IN KPROCESSOR_MODE AccessMode, + IN BOOLEAN CaptureIfKernel); + +NTSTATUS +SepCaptureAcl(IN PACL InputAcl, + IN KPROCESSOR_MODE AccessMode, + IN POOL_TYPE PoolType, + IN BOOLEAN CaptureIfKernel, + OUT PACL *CapturedAcl); + +VOID +SepReleaseAcl(IN PACL CapturedAcl, + IN KPROCESSOR_MODE AccessMode, + IN BOOLEAN CaptureIfKernel); + +#define SepAcquireTokenLockExclusive(Token) \ + do { \ + KeEnterCriticalRegion(); \ + ExAcquireResourceExclusive(((PTOKEN)Token)->TokenLock, TRUE); \ + while(0) + +#define SepAcquireTokenLockShared(Token) \ + do { \ + KeEnterCriticalRegion(); \ + ExAcquireResourceShared(((PTOKEN)Token)->TokenLock, TRUE); \ + while(0) + +#define SepReleaseTokenLock(Token) \ + do { \ + ExReleaseResource(((PTOKEN)Token)->TokenLock); \ + KeLeaveCriticalRegion(); \ + while(0) + #endif /* __NTOSKRNL_INCLUDE_INTERNAL_SE_H */
/* EOF */ _____
Modified: trunk/reactos/ntoskrnl/io/dir.c --- trunk/reactos/ntoskrnl/io/dir.c 2005-03-12 22:10:11 UTC (rev 13983) +++ trunk/reactos/ntoskrnl/io/dir.c 2005-03-12 22:16:02 UTC (rev 13984) @@ -38,13 +38,41 @@
PIRP Irp; PDEVICE_OBJECT DeviceObject; PFILE_OBJECT FileObject; - NTSTATUS Status; PIO_STACK_LOCATION IoStack; KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtNotifyChangeDirectoryFile()\n"); + + PAGED_CODE();
PreviousMode = ExGetPreviousMode(); + + if(PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite(IoStatusBlock, + sizeof(IO_STATUS_BLOCK), + sizeof(ULONG)); + if(BufferSize != 0) + { + ProbeForWrite(Buffer, + BufferSize, + sizeof(ULONG)); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + return Status; + } + }
Status = ObReferenceObjectByHandle(FileHandle, FILE_LIST_DIRECTORY, @@ -155,14 +183,39 @@ PIRP Irp; PDEVICE_OBJECT DeviceObject; PFILE_OBJECT FileObject; - NTSTATUS Status; PIO_STACK_LOCATION IoStack; KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtQueryDirectoryFile()\n"); + + PAGED_CODE();
PreviousMode = ExGetPreviousMode(); + + if(PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite(IoStatusBlock, + sizeof(IO_STATUS_BLOCK), + sizeof(ULONG)); + ProbeForWrite(FileInformation, + Length, + sizeof(ULONG)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END;
+ if(!NT_SUCCESS(Status)) + { + return Status; + } + } + Status = ObReferenceObjectByHandle(FileHandle, FILE_LIST_DIRECTORY, IoFileObjectType, _____
Modified: trunk/reactos/ntoskrnl/ob/object.c --- trunk/reactos/ntoskrnl/ob/object.c 2005-03-12 22:10:11 UTC (rev 13983) +++ trunk/reactos/ntoskrnl/ob/object.c 2005-03-12 22:16:02 UTC (rev 13984) @@ -102,6 +102,7 @@
CapturedObjectAttributes->RootDirectory = ObjectAttributes->RootDirectory; CapturedObjectAttributes->Attributes = ObjectAttributes->Attributes; CapturedObjectAttributes->SecurityDescriptor = ObjectAttributes->SecurityDescriptor; + CapturedObjectAttributes->SecurityQualityOfService = ObjectAttributes->SecurityQualityOfService; }
return STATUS_SUCCESS; @@ -147,6 +148,53 @@ { CapturedObjectAttributes->SecurityDescriptor = NULL; } + + if(AttributesCopy.SecurityQualityOfService != NULL) + { + SECURITY_QUALITY_OF_SERVICE SafeQoS; + + _SEH_TRY + { + ProbeForRead(AttributesCopy.SecurityQualityOfService, + sizeof(SECURITY_QUALITY_OF_SERVICE), + sizeof(ULONG)); + SafeQoS = *(PSECURITY_QUALITY_OF_SERVICE)AttributesCopy.SecurityQualityOfService; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + DPRINT1("Unable to capture QoS!!!\n"); + goto failcleanupsdescriptor; + } + + if(SafeQoS.Length != sizeof(SECURITY_QUALITY_OF_SERVICE)) + { + DPRINT1("Unable to capture QoS, wrong size!!!\n"); + Status = STATUS_INVALID_PARAMETER; + goto failcleanupsdescriptor; + } + + CapturedObjectAttributes->SecurityQualityOfService = ExAllocatePool(PoolType, + sizeof(SECURITY_QUALITY_OF_SERVICE)); + if(CapturedObjectAttributes->SecurityQualityOfService != NULL) + { + *CapturedObjectAttributes->SecurityQualityOfService = SafeQoS; + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto failcleanupsdescriptor; + } + } + else + { + CapturedObjectAttributes->SecurityQualityOfService = NULL; + } }
if(ObjectName != NULL) @@ -259,6 +307,8 @@ { ExFreePool(ObjectName->Buffer); } + +failcleanupsdescriptor: if(CapturedObjectAttributes != NULL) { /* cleanup allocated resources */ @@ -293,11 +343,18 @@ to ObpCaptureObjectAttributes() to avoid memory leaks */ if(AccessMode != KernelMode || CaptureIfKernel) { - if(CapturedObjectAttributes != NULL && - CapturedObjectAttributes->SecurityDescriptor != NULL) + if(CapturedObjectAttributes != NULL) { - ExFreePool(CapturedObjectAttributes->SecurityDescriptor); - CapturedObjectAttributes->SecurityDescriptor = NULL; + if(CapturedObjectAttributes->SecurityDescriptor != NULL) + { + ExFreePool(CapturedObjectAttributes->SecurityDescriptor); + CapturedObjectAttributes->SecurityDescriptor = NULL; + } + if(CapturedObjectAttributes->SecurityQualityOfService != NULL) + { + ExFreePool(CapturedObjectAttributes->SecurityQualityOfService); + CapturedObjectAttributes->SecurityQualityOfService = NULL; + } } if(ObjectName != NULL && ObjectName->Length > 0) _____
Modified: trunk/reactos/ntoskrnl/se/acl.c --- trunk/reactos/ntoskrnl/se/acl.c 2005-03-12 22:10:11 UTC (rev 13983) +++ trunk/reactos/ntoskrnl/se/acl.c 2005-03-12 22:16:02 UTC (rev 13984) @@ -263,4 +263,105 @@
return STATUS_SUCCESS; }
+NTSTATUS +SepCaptureAcl(IN PACL InputAcl, + IN KPROCESSOR_MODE AccessMode, + IN POOL_TYPE PoolType, + IN BOOLEAN CaptureIfKernel, + OUT PACL *CapturedAcl) +{ + PACL NewAcl; + ULONG AclSize = 0; + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + if(AccessMode != KernelMode) + { + _SEH_TRY + { + 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; + } + _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) + { + RtlCopyMemory(NewAcl, + InputAcl, + AclSize); + + *CapturedAcl = NewAcl; + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + } + + return Status; +} + +VOID +SepReleaseAcl(IN PACL CapturedAcl, + IN KPROCESSOR_MODE AccessMode, + IN BOOLEAN CaptureIfKernel) +{ + PAGED_CODE(); + + if(CapturedAcl != NULL && + (AccessMode == UserMode || + (AccessMode == KernelMode && CaptureIfKernel))) + { + ExFreePool(CapturedAcl); + } +} + /* EOF */ _____
Modified: trunk/reactos/ntoskrnl/se/luid.c --- trunk/reactos/ntoskrnl/se/luid.c 2005-03-12 22:10:11 UTC (rev 13983) +++ trunk/reactos/ntoskrnl/se/luid.c 2005-03-12 22:16:02 UTC (rev 13984) @@ -102,32 +102,4 @@
return Status; }
- -/* - * @implemented - */ -VOID STDCALL -RtlCopyLuid(IN PLUID LuidDest, - IN PLUID LuidSrc) -{ - PAGED_CODE_RTL(); - - LuidDest->LowPart = LuidSrc->LowPart; - LuidDest->HighPart = LuidSrc->HighPart; -} - - -/* - * @implemented - */ -BOOLEAN STDCALL -RtlEqualLuid(IN PLUID Luid1, - IN PLUID Luid2) -{ - PAGED_CODE_RTL(); - - return (Luid1->LowPart == Luid2->LowPart && - Luid1->HighPart == Luid2->HighPart); -} - /* EOF */ _____
Modified: trunk/reactos/ntoskrnl/se/sd.c --- trunk/reactos/ntoskrnl/se/sd.c 2005-03-12 22:10:11 UTC (rev 13983) +++ trunk/reactos/ntoskrnl/se/sd.c 2005-03-12 22:16:02 UTC (rev 13984) @@ -108,6 +108,174 @@
return TRUE; }
+ +NTSTATUS +SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN KPROCESSOR_MODE AccessMode, + IN POOL_TYPE PoolType, + IN BOOLEAN CaptureIfKernel, + 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) + { + SECURITY_QUALITY_OF_SERVICE SafeQos; + + _SEH_TRY + { + ProbeForRead(ObjectAttributes, + sizeof(ObjectAttributes), + 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->SecurityQualityOfSer vice)->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->SecurityQualityOfSer vice)->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; + } + } + } + else + { + *CapturedSecurityQualityOfService = NULL; + *Present = FALSE; + } + + return Status; +} + + +VOID +SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL, + IN KPROCESSOR_MODE AccessMode, + IN BOOLEAN CaptureIfKernel) +{ + PAGED_CODE(); + + if(CapturedSecurityQualityOfService != NULL && + (AccessMode == UserMode || + (AccessMode == KernelMode && CaptureIfKernel))) + { + ExFreePool(CapturedSecurityQualityOfService); + } +} + + /* * @implemented */ @@ -572,6 +740,8 @@ 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! */ _____
Modified: trunk/reactos/ntoskrnl/se/sid.c --- trunk/reactos/ntoskrnl/se/sid.c 2005-03-12 22:10:11 UTC (rev 13983) +++ trunk/reactos/ntoskrnl/se/sid.c 2005-03-12 22:16:02 UTC (rev 13984) @@ -466,4 +466,107 @@
return(TRUE); }
+NTSTATUS +SepCaptureSid(IN PSID InputSid, + IN KPROCESSOR_MODE AccessMode, + IN POOL_TYPE PoolType, + 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 + { + ProbeForRead(Sid, + sizeof(*Sid) - sizeof(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; + } + _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) + { + RtlCopyMemory(NewSid, + Sid, + SidSize); + + *CapturedSid = NewSid; + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + } + + return Status; +} + +VOID +SepReleaseSid(IN PSID CapturedSid, + IN KPROCESSOR_MODE AccessMode, + IN BOOLEAN CaptureIfKernel) +{ + PAGED_CODE(); + + if(CapturedSid != NULL && + (AccessMode == UserMode || + (AccessMode == KernelMode && CaptureIfKernel))) + { + ExFreePool(CapturedSid); + } +} + /* EOF */ _____
Modified: trunk/reactos/ntoskrnl/se/token.c --- trunk/reactos/ntoskrnl/se/token.c 2005-03-12 22:10:11 UTC (rev 13983) +++ trunk/reactos/ntoskrnl/se/token.c 2005-03-12 22:16:02 UTC (rev 13984) @@ -18,12 +18,54 @@
/* GLOBALS *******************************************************************/
POBJECT_TYPE SepTokenObjectType = NULL; +ERESOURCE SepTokenLock;
static GENERIC_MAPPING SepTokenMapping = {TOKEN_READ, 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 */ + ICI_SQ_SAME( sizeof(TOKEN_GROUPS), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ), + /* TokenPrivileges */ + ICI_SQ_SAME( sizeof(TOKEN_PRIVILEGES), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ), + /* TokenOwner */ + ICI_SQ_SAME( sizeof(TOKEN_OWNER), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ), + /* TokenPrimaryGroup */ + ICI_SQ_SAME( sizeof(TOKEN_PRIMARY_GROUP), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ), + /* TokenDefaultDacl */ + ICI_SQ_SAME( sizeof(TOKEN_DEFAULT_DACL), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ), + /* TokenSource */ + ICI_SQ_SAME( sizeof(TOKEN_SOURCE), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ), + /* TokenType */ + ICI_SQ_SAME( sizeof(TOKEN_TYPE), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ), + /* TokenImpersonationLevel */ + ICI_SQ_SAME( sizeof(SECURITY_IMPERSONATION_LEVEL), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ), + /* TokenStatistics */ + ICI_SQ_SAME( sizeof(TOKEN_STATISTICS), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ), + /* TokenRestrictedSids */ + ICI_SQ_SAME( sizeof(TOKEN_GROUPS), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ), + /* TokenSessionId */ + ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_QUERY | ICIF_SET ), + /* TokenGroupsAndPrivileges */ + ICI_SQ_SAME( sizeof(TOKEN_GROUPS_AND_PRIVILEGES), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ), + /* TokenSessionReference */ + ICI_SQ_SAME( /* FIXME */0, sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ), + /* TokenSandBoxInert */ + ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ), + /* TokenAuditPolicy */ + ICI_SQ_SAME( /* FIXME */0, sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ), + /* TokenOrigin */ + ICI_SQ_SAME( sizeof(TOKEN_ORIGIN), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ), +}; + /* FUNCTIONS *****************************************************************/
VOID SepFreeProxyData(PVOID ProxyData) @@ -140,6 +182,8 @@ PVOID EndMem; PTOKEN AccessToken; NTSTATUS Status; + + PAGED_CODE();
Status = ObCreateObject(PreviousMode, SepTokenObjectType, @@ -170,6 +214,8 @@ return(Status); }
+ AccessToken->TokenLock = &SepTokenLock; + AccessToken->TokenInUse = 0; AccessToken->TokenType = TokenType; AccessToken->ImpersonationLevel = Level; @@ -189,7 +235,7 @@ uLength += RtlLengthSid(Token->UserAndGroups[i].Sid);
AccessToken->UserAndGroups = - (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(NonPagedPool, + (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, uLength, TAG('T', 'O', 'K', 'u'));
@@ -216,7 +262,7 @@
uLength = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); AccessToken->Privileges = - (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(NonPagedPool, + (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, uLength, TAG('T', 'O', 'K', 'p'));
@@ -231,7 +277,7 @@ if ( Token->DefaultDacl ) { AccessToken->DefaultDacl = - (PACL) ExAllocatePoolWithTag(NonPagedPool, + (PACL) ExAllocatePoolWithTag(PagedPool, Token->DefaultDacl->AclSize, TAG('T', 'O', 'K', 'd')); memcpy(AccessToken->DefaultDacl, @@ -534,6 +580,8 @@ VOID INIT_FUNCTION SepInitializeTokenImplementation(VOID) { + ExInitializeResource(&SepTokenLock); + SepTokenObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
SepTokenObjectType->Tag = TAG('T', 'O', 'K', 'T'); @@ -555,8 +603,7 @@ SepTokenObjectType->Create = NULL; SepTokenObjectType->DuplicationNotify = NULL;
- RtlpCreateUnicodeString(&SepTokenObjectType->TypeName, - L"Token", NonPagedPool); + RtlInitUnicodeString(&SepTokenObjectType->TypeName, L"Token"); ObpCreateTypeObject (SepTokenObjectType); }
@@ -571,266 +618,456 @@ IN ULONG TokenInformationLength, OUT PULONG ReturnLength) { [truncated at 1000 lines; 1262 more skipped]