Implement Access State support (SeCreate/DeleteAccessState and SeSetAccessStateGenericMapping. Based on a patch by Javier M. Mellid
Modified: trunk/reactos/include/ddk/sefuncs.h
Modified: trunk/reactos/include/ddk/setypes.h
Modified: trunk/reactos/ntoskrnl/se/access.c

Modified: trunk/reactos/include/ddk/sefuncs.h
--- trunk/reactos/include/ddk/sefuncs.h	2005-05-09 19:08:49 UTC (rev 15189)
+++ trunk/reactos/include/ddk/sefuncs.h	2005-05-09 19:57:41 UTC (rev 15190)
@@ -122,7 +122,7 @@
 STDCALL
 SeCreateAccessState(
 	PACCESS_STATE AccessState,
-	PVOID AuxData,
+	PAUX_DATA AuxData,
 	ACCESS_MASK Access,
 	PGENERIC_MAPPING GenericMapping
 	);

Modified: trunk/reactos/include/ddk/setypes.h
--- trunk/reactos/include/ddk/setypes.h	2005-05-09 19:08:49 UTC (rev 15189)
+++ trunk/reactos/include/ddk/setypes.h	2005-05-09 19:57:41 UTC (rev 15190)
@@ -97,6 +97,7 @@
     };
 } SEP_AUDIT_POLICY, *PSEP_AUDIT_POLICY;
  
+#define TOKEN_HAS_TRAVERSE_PRIVILEGE    0x01
 typedef struct _TOKEN {
   TOKEN_SOURCE TokenSource;                         /* 0x00 */
   LUID TokenId;                                     /* 0x10 */
@@ -222,6 +223,13 @@
   AssignSecurityDescriptor
 } SECURITY_OPERATION_CODE, *PSECURITY_OPERATION_CODE;
 
+typedef struct _AUX_DATA
+{
+    PPRIVILEGE_SET PrivilegeSet;
+    GENERIC_MAPPING GenericMapping;
+    ULONG Reserved;
+} AUX_DATA, *PAUX_DATA;
+
 typedef struct _ACCESS_STATE
 {
   LUID OperationID;

Modified: trunk/reactos/ntoskrnl/se/access.c
--- trunk/reactos/ntoskrnl/se/access.c	2005-05-09 19:08:49 UTC (rev 15189)
+++ trunk/reactos/ntoskrnl/se/access.c	2005-05-09 19:57:41 UTC (rev 15190)
@@ -4,7 +4,8 @@
  * FILE:            ntoskrnl/se/access.c
  * PURPOSE:         Access state functions
  *
- * PROGRAMMERS:     Eric Kohl
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net) - 
+ *                               Based on patch by Javier M. Mellid
  */
 
 /* INCLUDES *****************************************************************/
@@ -13,47 +14,108 @@
 #define NDEBUG
 #include <internal/debug.h>
 
+#define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | \
+                        GENERIC_ALL)
+
 /* FUNCTIONS ***************************************************************/
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 STDCALL
-SeCreateAccessState(
-	PACCESS_STATE AccessState,
-	PVOID AuxData,
-	ACCESS_MASK Access,
-	PGENERIC_MAPPING GenericMapping
-	)
+SeCreateAccessState(PACCESS_STATE AccessState,
+                    PAUX_DATA AuxData,
+                    ACCESS_MASK Access,
+                    PGENERIC_MAPPING GenericMapping)
 {
-	UNIMPLEMENTED;
-	return STATUS_NOT_IMPLEMENTED;
+    ACCESS_MASK AccessMask = Access;
+    PTOKEN Token;
+    
+    PAGED_CODE();
+
+    /* Map the Generic Acess to Specific Access if we have a Mapping */
+    if ((Access & GENERIC_ACCESS) && (GenericMapping))
+    {
+        RtlMapGenericMask(&AccessMask, GenericMapping);
+    }
+
+    /* Initialize the Access State */
+    RtlZeroMemory(AccessState, sizeof(ACCESS_STATE));
+
+    /* Capture the Subject Context */
+    SeCaptureSubjectContext(&AccessState->SubjectSecurityContext);
+    
+    /* Set Access State Data */
+    AccessState->AuxData = AuxData;
+    AccessState->RemainingDesiredAccess  = AccessMask;
+    AccessState->OriginallyDesiredAccess = AccessMask;
+    ExpAllocateLocallyUniqueId(&AccessState->OperationID);
+
+    /* Get the Token to use */
+    Token =  AccessState->SubjectSecurityContext.ClientToken ?
+             (PTOKEN)&AccessState->SubjectSecurityContext.ClientToken :
+             (PTOKEN)&AccessState->SubjectSecurityContext.PrimaryToken;
+             
+    /* Check for Travers Privilege */
+    if (Token->TokenFlags & TOKEN_HAS_TRAVERSE_PRIVILEGE)
+    {
+        /* Preserve the Traverse Privilege */
+        AccessState->Flags = TOKEN_HAS_TRAVERSE_PRIVILEGE;
+    }
+
+    /* Set the Auxiliary Data */
+    AuxData->PrivilegeSet = (PPRIVILEGE_SET)((ULONG_PTR)AccessState +
+                                             FIELD_OFFSET(ACCESS_STATE,
+                                                          Privileges));    
+    if (GenericMapping) AuxData->GenericMapping = *GenericMapping;
+
+    /* Return Sucess */
+    return STATUS_SUCCESS;
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 VOID
 STDCALL
-SeDeleteAccessState(
-	IN PACCESS_STATE AccessState
-	)
+SeDeleteAccessState(IN PACCESS_STATE AccessState)
 {
-	UNIMPLEMENTED;
+    PAUX_DATA AuxData;
+    PAGED_CODE();
+
+    /* Get the Auxiliary Data */
+    AuxData = AccessState->AuxData;
+
+    /* Deallocate Privileges */
+    if (AccessState->PrivilegesAllocated) ExFreePool(AuxData->PrivilegeSet);
+    
+    /* Deallocate Name and Type Name */
+    if (AccessState->ObjectName.Buffer)
+    {
+        ExFreePool(AccessState->ObjectName.Buffer);
+    }
+    if (AccessState->ObjectTypeName.Buffer) 
+    {
+        ExFreePool(AccessState->ObjectTypeName.Buffer);
+    }
+
+    /* Release the Subject Context */
+    SeReleaseSubjectContext(&AccessState->SubjectSecurityContext);
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 VOID
 STDCALL
-SeSetAccessStateGenericMapping(
-	PACCESS_STATE AccessState,
-	PGENERIC_MAPPING GenericMapping
-	)
+SeSetAccessStateGenericMapping(PACCESS_STATE AccessState,
+                               PGENERIC_MAPPING GenericMapping)
 {
-	UNIMPLEMENTED;
+    PAGED_CODE();
+
+    /* Set the Generic Mapping */
+    ((PAUX_DATA)AccessState->AuxData)->GenericMapping = *GenericMapping;
 }
 
 /* EOF */