如何在IIS下模拟管理员权限执行程序
首先建立一个关于身份验证的类
api.cs
1 using System;
2 using System.Collections;
3 using System.Text;
4 using System.Security.Principal;
5 using System.Runtime.InteropServices;
6
7
8 /// <summary>
9 /// Impersonate 的摘要说明。
10 /// </summary>
11 public class Impersonate
12 {
13 #region 模拟
14 private WindowsImpersonationContext impersonationContext;
15
16 private const int LOGON32_LOGON_INTERACTIVE = 2;
17 private const int LOGON32_PROVIDER_DEFAULT = 0;
18 //LogonUser登录一个新用户
19 [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
20 private static extern int LogonUser(String lpszUserName, String lpszDomain, String lpszPassword,
21 int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
22
23 [DllImport("advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
24 private extern static int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
25
26 [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
27 private static extern bool RevertToSelf();
28
29 [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
30 private extern static bool CloseHandle(IntPtr handle);
31
32 /// <summary>
33 /// 模拟一个用户
34 /// </summary>
35 /// <param name="userName">用户名</param>
36 /// <param name="password">密码</param>
37 /// <param name="domain">域名/计算机名</param>
38 /// <returns>true 模拟成功,false 模拟失败</returns>
39 public bool ImpersonateUser(string userName, string password, string domain)
40 {
41 WindowsIdentity wi;
42 IntPtr token = IntPtr.Zero;
43 IntPtr tokenDuplicate = IntPtr.Zero;
44 if (RevertToSelf())
45 {
46 if (LogonUser(userName, domain, password,
47 LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
48 {
49 if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
50 {
51 wi = new WindowsIdentity(tokenDuplicate);
52 impersonationContext = wi.Impersonate();
53 if (impersonationContext != null)
54 {
55 CloseHandle(tokenDuplicate);
56 CloseHandle(token);
57 return true;
58 }
59 else
60 {
61 if (tokenDuplicate != IntPtr.Zero) CloseHandle(tokenDuplicate);
62 if (token != IntPtr.Zero) CloseHandle(token);
63 return false;
64 }
65 }
66 else
67 {
68 if (token != IntPtr.Zero) CloseHandle(token);
69 return false;
70 }
71 }
72 else
73 return false;
74 }
75 else
76 return false;
77 }
78
79 /// <summary>
80 /// 取消模拟
81 /// </summary>
82 public void UndoImpersonation()
83 {
84 impersonationContext.Undo();
85 }
86 #endregion
87
88 #region 关机
89 [StructLayout(LayoutKind.Sequential, Pack = 1)]
90 private struct TokPriv1Luid
91 {
92 public int Count;
93 public long Luid;
94 public int Attr;
95 }
96
97 [DllImport("kernel32.dll", ExactSpelling = true)]
98 private static extern IntPtr GetCurrentThread();
99 [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
100 private static extern bool OpenThreadToken(IntPtr h, int acc, bool openAsSelf, ref IntPtr phtok);
101 [DllImport("advapi32.dll", SetLastError = true)]
102 private static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
103 [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
104 private static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst,
105 int len, IntPtr prev, IntPtr relen);
106 [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
107 private static extern bool ExitWindowsEx(int flg, int rea);
108 [DllImport("advapi32.dll")]
109 private static extern bool InitiateSystemShutdown(string Machinename, string Message,
110 long Timeout, bool ForceAppsClosed, bool RebootAfterShutdown);
111 private const int SE_PRIVILEGE_ENABLED = 0x00000002;
112 private const int TOKEN_QUERY = 0x00000008;
113 private const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
114 private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
115 private const int EWX_LOGOFF = 0x00000000;
116 private const int EWX_SHUTDOWN = 0x00000001;
117 private const int EWX_REBOOT = 0x00000002;
118 private const int EWX_FORCE = 0x00000004;
119 private const int EWX_POWEROFF = 0x00000008;
120 private const int EWX_FORCEIFHUNG = 0x00000010;
121
122 /// <summary>
123 /// 关机
124 /// </summary>
125 /// <returns></returns>
126 public bool ShutDown()
127 {
128 bool result;
129 TokPriv1Luid tp;
130 //注意:这里用的是GetCurrentThread,而不是GetCurrentProcess
131 IntPtr hproc = GetCurrentThread();
132 IntPtr htok = IntPtr.Zero;
133 //注意:这里用的是OpenThreadToken(打开线程令牌),而不是OpenProcessToken(打开进程令牌)
134 result = OpenThreadToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
135 true, ref htok);
136 tp.Count = 1;
137 tp.Luid = 0;
138 tp.Attr = SE_PRIVILEGE_ENABLED;
139 result = LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tp.Luid);
140 result = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
141 result = InitiateSystemShutdown("", "", 120, true, true);
142 return result;
143 }
144 #endregion
145 }
146
1 using System;
2 using System.Collections;
3 using System.Text;
4 using System.Security.Principal;
5 using System.Runtime.InteropServices;
6
7
8 /// <summary>
9 /// Impersonate 的摘要说明。
10 /// </summary>
11 public class Impersonate
12 {
13 #region 模拟
14 private WindowsImpersonationContext impersonationContext;
15
16 private const int LOGON32_LOGON_INTERACTIVE = 2;
17 private const int LOGON32_PROVIDER_DEFAULT = 0;
18 //LogonUser登录一个新用户
19 [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
20 private static extern int LogonUser(String lpszUserName, String lpszDomain, String lpszPassword,
21 int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
22
23 [DllImport("advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
24 private extern static int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
25
26 [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
27 private static extern bool RevertToSelf();
28
29 [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
30 private extern static bool CloseHandle(IntPtr handle);
31
32 /// <summary>
33 /// 模拟一个用户
34 /// </summary>
35 /// <param name="userName">用户名</param>
36 /// <param name="password">密码</param>
37 /// <param name="domain">域名/计算机名</param>
38 /// <returns>true 模拟成功,false 模拟失败</returns>
39 public bool ImpersonateUser(string userName, string password, string domain)
40 {
41 WindowsIdentity wi;
42 IntPtr token = IntPtr.Zero;
43 IntPtr tokenDuplicate = IntPtr.Zero;
44 if (RevertToSelf())
45 {
46 if (LogonUser(userName, domain, password,
47 LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
48 {
49 if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
50 {
51 wi = new WindowsIdentity(tokenDuplicate);
52 impersonationContext = wi.Impersonate();
53 if (impersonationContext != null)
54 {
55 CloseHandle(tokenDuplicate);
56 CloseHandle(token);
57 return true;
58 }
59 else
60 {
61 if (tokenDuplicate != IntPtr.Zero) CloseHandle(tokenDuplicate);
62 if (token != IntPtr.Zero) CloseHandle(token);
63 return false;
64 }
65 }
66 else
67 {
68 if (token != IntPtr.Zero) CloseHandle(token);
69 return false;
70 }
71 }
72 else
73 return false;
74 }
75 else
76 return false;
77 }
78
79 /// <summary>
80 /// 取消模拟
81 /// </summary>
82 public void UndoImpersonation()
83 {
84 impersonationContext.Undo();
85 }
86 #endregion
87
88 #region 关机
89 [StructLayout(LayoutKind.Sequential, Pack = 1)]
90 private struct TokPriv1Luid
91 {
92 public int Count;
93 public long Luid;
94 public int Attr;
95 }
96
97 [DllImport("kernel32.dll", ExactSpelling = true)]
98 private static extern IntPtr GetCurrentThread();
99 [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
100 private static extern bool OpenThreadToken(IntPtr h, int acc, bool openAsSelf, ref IntPtr phtok);
101 [DllImport("advapi32.dll", SetLastError = true)]
102 private static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
103 [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
104 private static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst,
105 int len, IntPtr prev, IntPtr relen);
106 [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
107 private static extern bool ExitWindowsEx(int flg, int rea);
108 [DllImport("advapi32.dll")]
109 private static extern bool InitiateSystemShutdown(string Machinename, string Message,
110 long Timeout, bool ForceAppsClosed, bool RebootAfterShutdown);
111 private const int SE_PRIVILEGE_ENABLED = 0x00000002;
112 private const int TOKEN_QUERY = 0x00000008;
113 private const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
114 private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
115 private const int EWX_LOGOFF = 0x00000000;
116 private const int EWX_SHUTDOWN = 0x00000001;
117 private const int EWX_REBOOT = 0x00000002;
118 private const int EWX_FORCE = 0x00000004;
119 private const int EWX_POWEROFF = 0x00000008;
120 private const int EWX_FORCEIFHUNG = 0x00000010;
121
122 /// <summary>
123 /// 关机
124 /// </summary>
125 /// <returns></returns>
126 public bool ShutDown()
127 {
128 bool result;
129 TokPriv1Luid tp;
130 //注意:这里用的是GetCurrentThread,而不是GetCurrentProcess
131 IntPtr hproc = GetCurrentThread();
132 IntPtr htok = IntPtr.Zero;
133 //注意:这里用的是OpenThreadToken(打开线程令牌),而不是OpenProcessToken(打开进程令牌)
134 result = OpenThreadToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
135 true, ref htok);
136 tp.Count = 1;
137 tp.Luid = 0;
138 tp.Attr = SE_PRIVILEGE_ENABLED;
139 result = LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tp.Luid);
140 result = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
141 result = InitiateSystemShutdown("", "", 120, true, true);
142 return result;
143 }
144 #endregion
145 }
146
web.config add
<identity impersonate="true" userName="adm" password="密码" />
调用就很简单
Impersonate sd = new Impersonate();
sd.ShutDown();