/project/core/util/Impersonation.cs

https://github.com/bertvan/CruiseControl.NET · C# · 121 lines · 61 code · 15 blank · 45 comment · 6 complexity · 270900eebb4490bed1900858add7bbdf MD5 · raw file

  1. //-----------------------------------------------------------------------
  2. // <copyright file="Impersonation.cs" company="DockOfTheBay">
  3. // http://www.dotbay.be
  4. // </copyright>
  5. // <summary>Defines the Impersonation class.</summary>
  6. //-----------------------------------------------------------------------
  7. // Class copied from http://dotbay.blogspot.com/2009/05/windows-impersonation-in-c.html
  8. using System;
  9. using System.Runtime.InteropServices;
  10. using System.Security.Permissions;
  11. using System.Security.Principal;
  12. namespace ThoughtWorks.CruiseControl.Core.Util
  13. {
  14. /// <summary>
  15. /// Facilitates impersonation of a Windows User.
  16. /// </summary>
  17. public class Impersonation
  18. : IDisposable
  19. {
  20. /// <summary>
  21. /// Windows Token.
  22. /// </summary>
  23. private IntPtr tokenHandle = new IntPtr(0);
  24. /// <summary>
  25. /// The impersonated User.
  26. /// </summary>
  27. private WindowsImpersonationContext impersonatedUser;
  28. /// <summary>
  29. /// Initializes a new instance of the Impersonation class.
  30. /// </summary>
  31. /// <param name="domainName">Domain name of the impersonated user.</param>
  32. /// <param name="userName">Name of the impersonated user.</param>
  33. /// <param name="password">Password of the impersonated user.</param>
  34. /// <remarks>
  35. /// Uses the unmanaged LogonUser function to get the user token for
  36. /// the specified user, domain, and password.
  37. /// </remarks>
  38. public Impersonation(string domainName, string userName, string password)
  39. {
  40. // Use the standard logon provider.
  41. const int logoN32ProviderDefault = 0;
  42. // Create a primary token.
  43. const int logoN32LogonInteractive = 2;
  44. this.tokenHandle = IntPtr.Zero;
  45. // Call LogonUser to obtain a handle to an access token.
  46. bool returnValue = LogonUser(
  47. userName,
  48. domainName,
  49. password,
  50. logoN32LogonInteractive,
  51. logoN32ProviderDefault,
  52. ref this.tokenHandle);
  53. if (false == returnValue)
  54. {
  55. // Something went wrong.
  56. int ret = Marshal.GetLastWin32Error();
  57. throw new System.ComponentModel.Win32Exception(ret);
  58. }
  59. }
  60. /// <summary>
  61. /// Starts the impersonation.
  62. /// </summary>
  63. public void Impersonate()
  64. {
  65. // Create Identity.
  66. WindowsIdentity newId = new WindowsIdentity(this.tokenHandle);
  67. // Start impersonating.
  68. this.impersonatedUser = newId.Impersonate();
  69. }
  70. /// <summary>
  71. /// Stops the impersonation and releases security token.
  72. /// </summary>
  73. public void Revert()
  74. {
  75. // Stop impersonating.
  76. if (this.impersonatedUser != null)
  77. {
  78. this.impersonatedUser.Undo();
  79. }
  80. // Release the token.
  81. if (this.tokenHandle != IntPtr.Zero)
  82. {
  83. CloseHandle(this.tokenHandle);
  84. }
  85. }
  86. [DllImport("advapi32.dll", SetLastError = true)]
  87. private static extern bool LogonUser(
  88. string lpszUsername,
  89. string lpszDomain,
  90. string lpszPassword,
  91. int dwLogonType,
  92. int dwLogonProvider,
  93. ref IntPtr phToken);
  94. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  95. private static extern bool CloseHandle(IntPtr handle);
  96. // Make sure revert has been called.
  97. /// <summary>
  98. /// Releases unmanaged and - optionally - managed resources
  99. /// </summary>
  100. /// <remarks></remarks>
  101. public void Dispose()
  102. {
  103. Revert();
  104. }
  105. }
  106. }