update for HEAD-2003091401
[reactos.git] / ntoskrnl / se / token.c
index 1bb70c5..65c8f40 100644 (file)
@@ -12,7 +12,8 @@
 /* INCLUDES *****************************************************************/
 
 #include <limits.h>
-#include <ddk/ntddk.h>
+#define NTOS_MODE_KERNEL
+#include <ntos.h>
 #include <internal/ps.h>
 #include <internal/se.h>
 #include <internal/safe.h>
@@ -144,14 +145,14 @@ SepDuplicateToken(PACCESS_TOKEN Token,
 
   PACCESS_TOKEN AccessToken;
 
-  Status = ObCreateObject(0,
+  Status = ObRosCreateObject(0,
                          TOKEN_ALL_ACCESS,
                          ObjectAttributes,
                          SepTokenObjectType,
                          (PVOID*)&AccessToken);
   if (!NT_SUCCESS(Status))
     {
-      DPRINT1("ObCreateObject() failed (Status %lx)\n");
+      DPRINT1("ObRosCreateObject() failed (Status %lx)\n");
       return(Status);
     }
 
@@ -172,10 +173,14 @@ SepDuplicateToken(PACCESS_TOKEN Token,
   AccessToken->TokenInUse = 0;
   AccessToken->TokenType  = TokenType;
   AccessToken->ImpersonationLevel = Level;
-  AccessToken->AuthenticationId.QuadPart = SYSTEM_LUID;
+  AccessToken->AuthenticationId.LowPart = SYSTEM_LUID;
+  AccessToken->AuthenticationId.HighPart = 0;
 
-  AccessToken->TokenSource.SourceIdentifier.QuadPart = Token->TokenSource.SourceIdentifier.QuadPart;
-  memcpy(AccessToken->TokenSource.SourceName, Token->TokenSource.SourceName, sizeof(Token->TokenSource.SourceName));
+  AccessToken->TokenSource.SourceIdentifier.LowPart = Token->TokenSource.SourceIdentifier.LowPart;
+  AccessToken->TokenSource.SourceIdentifier.HighPart = Token->TokenSource.SourceIdentifier.HighPart;
+  memcpy(AccessToken->TokenSource.SourceName,
+        Token->TokenSource.SourceName,
+        sizeof(Token->TokenSource.SourceName));
   AccessToken->ExpirationTime.QuadPart = Token->ExpirationTime.QuadPart;
   AccessToken->UserAndGroupCount = Token->UserAndGroupCount;
   AccessToken->DefaultOwnerIndex = Token->DefaultOwnerIndex;
@@ -308,6 +313,9 @@ NTSTATUS SeCopyClientToken(PACCESS_TOKEN Token,
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 SeCreateClientSecurity(IN struct _ETHREAD *Thread,
                       IN PSECURITY_QUALITY_OF_SERVICE Qos,
@@ -397,6 +405,9 @@ SeCreateClientSecurity(IN struct _ETHREAD *Thread,
 }
 
 
+/*
+ * @implemented
+ */
 VOID STDCALL
 SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext,
                    IN PETHREAD ServerThread OPTIONAL)
@@ -468,6 +479,9 @@ SepInitializeTokenImplementation(VOID)
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 NtQueryInformationToken(IN HANDLE TokenHandle,
                        IN TOKEN_INFORMATION_CLASS TokenInformationClass,
@@ -731,6 +745,9 @@ NtSetInformationToken(IN HANDLE TokenHandle,
 }
 
 
+/*
+ * @unimplemented
+ */
 NTSTATUS STDCALL
 NtDuplicateToken(IN HANDLE ExistingTokenHandle,
                 IN ACCESS_MASK DesiredAccess,
@@ -820,99 +837,208 @@ NtAdjustGroupsToken(IN HANDLE TokenHandle,
 
 
 #if 0
-NTSTATUS SepAdjustPrivileges(PACCESS_TOKEN Token,           // 0x8
-                            ULONG a,                       // 0xC
-                            KPROCESSOR_MODE PreviousMode,  // 0x10
-                            ULONG PrivilegeCount,          // 0x14
-                            PLUID_AND_ATTRIBUTES Privileges, // 0x18
-                            PTOKEN_PRIVILEGES* PreviousState, // 0x1C
-                            PULONG b, // 0x20
-                            PULONG c, // 0x24
-                            PULONG d) // 0x28
+NTSTATUS
+SepAdjustPrivileges(PACCESS_TOKEN Token,
+                   ULONG a,
+                   KPROCESSOR_MODE PreviousMode,
+                   ULONG PrivilegeCount,
+                   PLUID_AND_ATTRIBUTES Privileges,
+                   PTOKEN_PRIVILEGES* PreviousState,
+                   PULONG b,
+                   PULONG c,
+                   PULONG d)
 {
-   ULONG i;
-   
-   *c = 0;
-   if (Token->PrivilegeCount > 0)
-     {
-       for (i=0; i<Token->PrivilegeCount; i++)
-         {
-            if (PreviousMode != 0)
-              {
-                 if (!(Token->Privileges[i]->Attributes & 
-                       SE_PRIVILEGE_ENABLED))
+  ULONG i;
+
+  *c = 0;
+
+  if (Token->PrivilegeCount > 0)
+    {
+      for (i = 0; i < Token->PrivilegeCount; i++)
+       {
+         if (PreviousMode != KernelMode)
+           {
+             if (Token->Privileges[i]->Attributes & SE_PRIVILEGE_ENABLED == 0)
+               {
+                 if (a != 0)
                    {
-                      if (a != 0)
-                        {
-                           if (PreviousState != NULL)
-                             {
-                                memcpy(&PreviousState[i],
-                                       &Token->Privileges[i],
-                                       sizeof(LUID_AND_ATTRIBUTES));
-                             }
-                           Token->Privileges[i].Attributes = 
-                             Token->Privileges[i].Attributes & 
-                             (~SE_PRIVILEGE_ENABLED);
-                        }
+                     if (PreviousState != NULL)
+                       {
+                         memcpy(&PreviousState[i],
+                                &Token->Privileges[i],
+                                sizeof(LUID_AND_ATTRIBUTES));
+                       }
+                     Token->Privileges[i].Attributes &= (~SE_PRIVILEGE_ENABLED);
                    }
-              }
-         }
-     }
-   if (PreviousMode != 0)
-     {
-       Token->TokenFlags = Token->TokenFlags & (~1);
-     }
-   else
-     {
-       if (PrivilegeCount <= ?)
-         {
-            
-         }
+               }
+           }
+       }
+    }
+
+  if (PreviousMode != KernelMode)
+    {
+      Token->TokenFlags = Token->TokenFlags & (~1);
+    }
+  else
+    {
+      if (PrivilegeCount <= ?)
+       {
+       }
      }
    if (
 }
 #endif
 
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
-NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
-                       IN BOOLEAN DisableAllPrivileges,
-                       IN PTOKEN_PRIVILEGES NewState,
-                       IN ULONG BufferLength,
-                       OUT PTOKEN_PRIVILEGES PreviousState,
-                       OUT PULONG ReturnLength)
+NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
+                        IN BOOLEAN DisableAllPrivileges,
+                        IN PTOKEN_PRIVILEGES NewState,
+                        IN ULONG BufferLength,
+                        OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL,
+                        OUT PULONG ReturnLength OPTIONAL)
 {
+//  PLUID_AND_ATTRIBUTES Privileges;
+  KPROCESSOR_MODE PreviousMode;
+//  ULONG PrivilegeCount;
+  PACCESS_TOKEN Token;
+//  ULONG Length;
+  ULONG i;
+  ULONG j;
+  ULONG k;
 #if 0
-   ULONG PrivilegeCount;
-   ULONG Length;
-   PSID_AND_ATTRIBUTES Privileges;
    ULONG a;
    ULONG b;
    ULONG c;
-   
-   PrivilegeCount = NewState->PrivilegeCount;
-   
-   SeCaptureLuidAndAttributesArray(NewState->Privileges,
-                                  &PrivilegeCount,
-                                  KeGetPreviousMode(),
-                                  NULL,
-                                  0,
-                                  NonPagedPool,
-                                  1,
-                                  &Privileges.
-                                  &Length);
+#endif
+  NTSTATUS Status;
+
+  DPRINT ("NtAdjustPrivilegesToken() called\n");
+
+//  PrivilegeCount = NewState->PrivilegeCount;
+  PreviousMode = KeGetPreviousMode ();
+//  SeCaptureLuidAndAttributesArray(NewState->Privileges,
+//                               PrivilegeCount,
+//                               PreviousMode,
+//                               NULL,
+//                               0,
+//                               NonPagedPool,
+//                               1,
+//                               &Privileges,
+//                               &Length);
+
+  Status = ObReferenceObjectByHandle (TokenHandle,
+                                     TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
+                                     SepTokenObjectType,
+                                     PreviousMode,
+                                     (PVOID*)&Token,
+                                     NULL);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT1 ("Failed to reference token (Status %lx)\n", Status);
+//      SeReleaseLuidAndAttributesArray(Privileges,
+//                                   PreviousMode,
+//                                   0);
+      return Status;
+    }
+
+
+#if 0
    SepAdjustPrivileges(Token,
                       0,
-                      KeGetPreviousMode(),
+                      PreviousMode,
                       PrivilegeCount,
                       Privileges,
                       PreviousState,
                       &a,
                       &b,
                       &c);
-#else
-   UNIMPLEMENTED;
 #endif
+
+  k = 0;
+  if (DisableAllPrivileges == TRUE)
+    {
+      for (i = 0; i < Token->PrivilegeCount; i++)
+       {
+         if (Token->Privileges[i].Attributes != 0)
+           {
+             DPRINT ("Attributes differ\n");
+
+             /* Save current privilege */
+             if (PreviousState != NULL && k < PreviousState->PrivilegeCount)
+               {
+                 PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid;
+                 PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes;
+                 k++;
+               }
+
+             /* Update current privlege */
+             Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
+           }
+       }
+    }
+  else
+    {
+      for (i = 0; i < Token->PrivilegeCount; i++)
+       {
+         for (j = 0; j < NewState->PrivilegeCount; j++)
+           {
+             if (Token->Privileges[i].Luid.LowPart == NewState->Privileges[j].Luid.LowPart &&
+                 Token->Privileges[i].Luid.HighPart == NewState->Privileges[j].Luid.HighPart)
+               {
+                 DPRINT ("Found privilege\n");
+
+                 if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) !=
+                     (NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED))
+                   {
+                     DPRINT ("Attributes differ\n");
+                     DPRINT ("Current attributes %lx  desired attributes %lx\n",
+                             Token->Privileges[i].Attributes,
+                             NewState->Privileges[j].Attributes);
+
+                     /* Save current privilege */
+                     if (PreviousState != NULL && k < PreviousState->PrivilegeCount)
+                       {
+                         PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid;
+                         PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes;
+                         k++;
+                       }
+
+                     /* Update current privlege */
+                     Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
+                     Token->Privileges[i].Attributes |= 
+                       (NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED);
+                     DPRINT ("New attributes %lx\n",
+                             Token->Privileges[i].Attributes);
+                   }
+               }
+           }
+       }
+    }
+
+  if (ReturnLength != NULL)
+    {
+      *ReturnLength = sizeof(TOKEN_PRIVILEGES) +
+                     (sizeof(LUID_AND_ATTRIBUTES) * (k - 1));
+    }
+
+  ObDereferenceObject (Token);
+
+//  SeReleaseLuidAndAttributesArray(Privileges,
+//                               PreviousMode,
+//                               0);
+
+  DPRINT ("NtAdjustPrivilegesToken() done\n");
+
+  if (k < NewState->PrivilegeCount)
+    {
+      return STATUS_NOT_ALL_ASSIGNED;
+    }
+
+  return STATUS_SUCCESS;
 }
 
 
@@ -935,7 +1061,7 @@ SepCreateSystemProcessToken(struct _EPROCESS* Process)
  /*
   * Initialize the token
   */
-  Status = ObCreateObject(NULL,
+  Status = ObRosCreateObject(NULL,
                         TOKEN_ALL_ACCESS,
                         NULL,
                         SepTokenObjectType,
@@ -955,11 +1081,13 @@ SepCreateSystemProcessToken(struct _EPROCESS* Process)
       return(Status);
     }
 
-  AccessToken->AuthenticationId.QuadPart = SYSTEM_LUID;
+  AccessToken->AuthenticationId.LowPart = SYSTEM_LUID;
+  AccessToken->AuthenticationId.HighPart = 0;
 
   AccessToken->TokenType = TokenPrimary;
   AccessToken->ImpersonationLevel = SecurityDelegation;
-  AccessToken->TokenSource.SourceIdentifier.QuadPart = 0;
+  AccessToken->TokenSource.SourceIdentifier.LowPart = 0;
+  AccessToken->TokenSource.SourceIdentifier.HighPart = 0;
   memcpy(AccessToken->TokenSource.SourceName, "SeMgr\0\0\0", 8);
   AccessToken->ExpirationTime.QuadPart = -1;
   AccessToken->UserAndGroupCount = 4;
@@ -1106,6 +1234,7 @@ SepCreateSystemProcessToken(struct _EPROCESS* Process)
   return(STATUS_SUCCESS);
 }
 
+
 NTSTATUS STDCALL
 NtCreateToken(OUT PHANDLE UnsafeTokenHandle,
              IN ACCESS_MASK DesiredAccess,
@@ -1148,14 +1277,14 @@ NtCreateToken(OUT PHANDLE UnsafeTokenHandle,
   if (!NT_SUCCESS(Status))
     return(Status);
 
-  Status = ObCreateObject(&TokenHandle,
+  Status = ObRosCreateObject(&TokenHandle,
                          DesiredAccess,
                          ObjectAttributes,
                          SepTokenObjectType,
                          (PVOID*)&AccessToken);
   if (!NT_SUCCESS(Status))
     {
-      DPRINT1("ObCreateObject() failed (Status %lx)\n");
+      DPRINT1("ObRosCreateObject() failed (Status %lx)\n");
       return(Status);
     }
 
@@ -1180,7 +1309,7 @@ NtCreateToken(OUT PHANDLE UnsafeTokenHandle,
 
   /*
    * Normally we would just point these members into the variable information
-   * area; however, our ObCreateObject() call can't allocate a variable information
+   * area; however, our ObRosCreateObject() call can't allocate a variable information
    * area, so we allocate them seperately and provide a destroy function.
    */
 
@@ -1270,6 +1399,9 @@ NtCreateToken(OUT PHANDLE UnsafeTokenHandle,
 }
 
 
+/*
+ * @implemented
+ */
 SECURITY_IMPERSONATION_LEVEL STDCALL
 SeTokenImpersonationLevel(IN PACCESS_TOKEN Token)
 {
@@ -1277,6 +1409,9 @@ SeTokenImpersonationLevel(IN PACCESS_TOKEN Token)
 }
 
 
+/*
+ * @implemented
+ */
 TOKEN_TYPE STDCALL
 SeTokenType(IN PACCESS_TOKEN Token)
 {