Thomas Weidenmueller <w3seek(a)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]