Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
4.1 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. psimpers.c
  5. Abstract:
  6. This module implements the NtImpersonateThread() service.
  7. Author:
  8. Jim Kelly (JimK) 20-Apr-1991
  9. Revision History:
  10. --*/
  11. #include "psp.h"
  12. #ifdef ALLOC_PRAGMA
  13. #pragma alloc_text(PAGE, NtImpersonateThread)
  14. #endif //ALLOC_PRAGMA
  15. NTSTATUS
  16. NtImpersonateThread(
  17. IN HANDLE ServerThreadHandle,
  18. IN HANDLE ClientThreadHandle,
  19. IN PSECURITY_QUALITY_OF_SERVICE SecurityQos
  20. )
  21. /*++
  22. Routine Description:
  23. This routine is used to cause the server thread to impersonate the client
  24. thread. The impersonation is done according to the specified quality
  25. of service parameters.
  26. Arguments:
  27. ServerThreadHandle - Is a handle to the server thread (the impersonator, or
  28. doing the impersonation). This handle must be open for
  29. THREAD_IMPERSONATE access.
  30. ClientThreadHandle - Is a handle to the Client thread (the impersonatee, or
  31. one being impersonated). This handle must be open for
  32. THREAD_DIRECT_IMPERSONATION access.
  33. SecurityQos - A pointer to security quality of service information
  34. indicating what form of impersonation is to be performed.
  35. Return Value:
  36. STATUS_SUCCESS - Indicates the call completed successfully.
  37. --*/
  38. {
  39. KPROCESSOR_MODE PreviousMode;
  40. NTSTATUS Status;
  41. PETHREAD ClientThread, ServerThread;
  42. SECURITY_QUALITY_OF_SERVICE CapturedQos;
  43. SECURITY_CLIENT_CONTEXT ClientSecurityContext;
  44. //
  45. // Get previous processor mode and probe and capture arguments if necessary
  46. //
  47. PreviousMode = KeGetPreviousMode();
  48. try {
  49. if (PreviousMode != KernelMode) {
  50. ProbeForReadSmallStructure (SecurityQos,
  51. sizeof (SECURITY_QUALITY_OF_SERVICE),
  52. sizeof (ULONG));
  53. }
  54. CapturedQos = *SecurityQos;
  55. } except (ExSystemExceptionFilter ()) {
  56. return GetExceptionCode ();
  57. }
  58. //
  59. // Reference the client thread, checking for appropriate access.
  60. //
  61. Status = ObReferenceObjectByHandle (ClientThreadHandle, // Handle
  62. THREAD_DIRECT_IMPERSONATION, // DesiredAccess
  63. PsThreadType, // ObjectType
  64. PreviousMode, // AccessMode
  65. &ClientThread, // Object
  66. NULL); // GrantedAccess
  67. if (!NT_SUCCESS (Status)) {
  68. return Status;
  69. }
  70. //
  71. // Reference the client thread, checking for appropriate access.
  72. //
  73. Status = ObReferenceObjectByHandle (ServerThreadHandle, // Handle
  74. THREAD_IMPERSONATE, // DesiredAccess
  75. PsThreadType, // ObjectType
  76. PreviousMode, // AccessMode
  77. &ServerThread, // Object
  78. NULL); // GrantedAccess
  79. if (!NT_SUCCESS (Status)) {
  80. ObDereferenceObject (ClientThread);
  81. return Status;
  82. }
  83. //
  84. // Get the client's security context
  85. //
  86. Status = SeCreateClientSecurity (ClientThread, // ClientThread
  87. &CapturedQos, // SecurityQos
  88. FALSE, // ServerIsRemote
  89. &ClientSecurityContext); // ClientContext
  90. if (!NT_SUCCESS (Status)) {
  91. ObDereferenceObject (ServerThread);
  92. ObDereferenceObject (ClientThread);
  93. return Status;
  94. }
  95. //
  96. // Impersonate the client
  97. //
  98. Status = SeImpersonateClientEx (&ClientSecurityContext, ServerThread);
  99. SeDeleteClientSecurity (&ClientSecurityContext);
  100. //
  101. // Done.
  102. //
  103. ObDereferenceObject (ServerThread);
  104. ObDereferenceObject (ClientThread);
  105. return Status ;
  106. }