-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathImpersonateUser.cs
126 lines (104 loc) · 3.23 KB
/
ImpersonateUser.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.IO;
namespace MemCacheDManager
{
public class ImpersonateUser
{
private enum SECURITY_IMPERSONATION_LEVEL : int
{
SecurityAnonymous = 0,
SecurityIdentification = 1,
SecurityImpersonation = 2,
SecurityDelegation = 3
}
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(
String lpszUsername,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(
IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL,
ref IntPtr DuplicateTokenHandle);
private bool _isImpersonating = false;
public bool IsImpersonating
{
get { return _isImpersonating; }
}
private IntPtr _tokenHandle = new IntPtr(0);
private IntPtr _duplicateTokenHandle = new IntPtr(0);
private WindowsImpersonationContext _impersonatedUser;
// If you incorporate this code into a DLL, be sure to demand that it
// runs with FullTrust.
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public ImpersonateUser(string userAndDomanName, string password)
{
string userName = string.Empty;
string domainName = string.Empty;
if (userAndDomanName.Contains("\\") == true)
{
domainName = userAndDomanName.Split('\\')[0];
userName = userAndDomanName.Split('\\')[1];
}
else
{
userName = userAndDomanName;
}
// Use the unmanaged LogonUser function to get the user token for
// the specified user, domain, and password.
// To impersonate a user on this machine, use the local machine
// name for the domain name.
const int LOGON32_PROVIDER_DEFAULT = 0;
// Passing this parameter causes LogonUser to create a primary
// token.
const int LOGON32_LOGON_INTERACTIVE = 2;
_tokenHandle = IntPtr.Zero;
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(
userName,
domainName,
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref _tokenHandle);
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
_duplicateTokenHandle = IntPtr.Zero;
returnValue = DuplicateToken(_tokenHandle,
(int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
ref _duplicateTokenHandle);
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
WindowsIdentity newId = new WindowsIdentity(_duplicateTokenHandle);
_impersonatedUser = newId.Impersonate();
_isImpersonating = true;
}
public void Undo()
{
_impersonatedUser.Undo();
// Free the tokens.
if (_tokenHandle != IntPtr.Zero)
CloseHandle(_tokenHandle);
if (_duplicateTokenHandle != IntPtr.Zero)
CloseHandle(_duplicateTokenHandle);
_isImpersonating = false;
}
}
}