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->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;
+      }
+    }
+  }
+  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]