1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+
5
+ Param (
6
+ [parameter (Mandatory = $true , Position = 0 )]
7
+ [ValidateSet (" Enable-AclUtil" )]
8
+ [string ]
9
+ $Command
10
+ )
11
+
12
+ $cs = '
13
+ namespace Microsoft.IIS.Administration.Setup
14
+ {
15
+ using System;
16
+ using System.ComponentModel;
17
+ using System.Runtime.InteropServices;
18
+
19
+ public class AclUtil
20
+ {
21
+ public const string TAKE_OWNERSHIP_PRIVILEGE = "SeTakeOwnershipPrivilege";
22
+ public const string RESTORE_PRIVILEGE = "SeRestorePrivilege";
23
+
24
+ internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
25
+ internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
26
+ internal const int TOKEN_QUERY = 0x00000008;
27
+ internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
28
+
29
+ private const string ADVAPI = "advapi32.dll";
30
+ private const string KERNEL32 = "kernel32.dll";
31
+
32
+ [DllImport(ADVAPI, SetLastError = true)]
33
+ private static extern bool AdjustTokenPrivileges(
34
+ IntPtr hTokenHandle,
35
+ bool fDisableAllPrivileges,
36
+ ref TokPriv1Luid pNewState,
37
+ int nBufferLength,
38
+ IntPtr pPreviousState,
39
+ IntPtr pnReturnLength);
40
+
41
+ [DllImport(KERNEL32, SetLastError = true)]
42
+ private static extern bool CloseHandle(IntPtr hObject);
43
+
44
+ [DllImport(KERNEL32)]
45
+ private static extern IntPtr GetCurrentProcess();
46
+
47
+ [DllImport(ADVAPI, SetLastError = true)]
48
+ private static extern bool GetTokenInformation(
49
+ IntPtr TokenHandle,
50
+ TOKEN_INFORMATION_CLASS TokenInformationClass,
51
+ IntPtr TokenInformation,
52
+ uint TokenInformationLength,
53
+ out uint ReturnLength);
54
+
55
+ [DllImport(ADVAPI, SetLastError = true, CharSet = CharSet.Unicode)]
56
+ private static extern bool LookupPrivilegeValueW(
57
+ string host,
58
+ string name,
59
+ ref long pluid);
60
+
61
+ [DllImport(ADVAPI, ExactSpelling = true, SetLastError = true)]
62
+ private static extern bool OpenProcessToken(
63
+ IntPtr hProcess,
64
+ int TokenAccess,
65
+ ref IntPtr phAccessToken);
66
+
67
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
68
+ private struct TokPriv1Luid
69
+ {
70
+ public int Count;
71
+ public long Luid;
72
+ public int Attr;
73
+ }
74
+
75
+ [StructLayout(LayoutKind.Sequential)]
76
+ private class TOKEN_PRIVILEGES
77
+ {
78
+ public UInt32 PrivilegeCount;
79
+ public LUID_AND_ATTRIBUTES[] Privileges;
80
+ }
81
+
82
+ [StructLayout(LayoutKind.Sequential, Pack = 4)]
83
+ private class LUID_AND_ATTRIBUTES
84
+ {
85
+ public long Luid;
86
+ public UInt32 Attributes;
87
+ }
88
+
89
+ private enum TOKEN_INFORMATION_CLASS
90
+ {
91
+ TokenUser = 1,
92
+ TokenGroups,
93
+ TokenPrivileges
94
+ }
95
+
96
+ public static void SetPrivilege(string privilege, bool enabled)
97
+ {
98
+ IntPtr hAccessToken = IntPtr.Zero;
99
+ int attribute = enabled ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_DISABLED;
100
+
101
+ try {
102
+ IntPtr hProcess = GetCurrentProcess();
103
+
104
+ if (!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref hAccessToken)) {
105
+ throw new Win32Exception(Marshal.GetLastWin32Error());
106
+ }
107
+
108
+ TokPriv1Luid tp = new TokPriv1Luid();
109
+ tp.Count = 1;
110
+ tp.Luid = 0;
111
+ tp.Attr = attribute;
112
+
113
+ if (!LookupPrivilegeValueW(null, privilege, ref tp.Luid)) {
114
+ throw new Win32Exception(Marshal.GetLastWin32Error());
115
+ }
116
+
117
+ if (!AdjustTokenPrivileges(hAccessToken, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero)) {
118
+ throw new Win32Exception(Marshal.GetLastWin32Error());
119
+ }
120
+ }
121
+ finally {
122
+ if (hAccessToken != IntPtr.Zero) {
123
+ CloseHandle(hAccessToken);
124
+ hAccessToken = IntPtr.Zero;
125
+ }
126
+ }
127
+ }
128
+
129
+ public static bool HasPrivilege(string privilege)
130
+ {
131
+ IntPtr hAccessToken = IntPtr.Zero;
132
+ IntPtr pTokenInfo = IntPtr.Zero;
133
+
134
+ try {
135
+ long luid = 0;
136
+
137
+ if (!LookupPrivilegeValueW(null, privilege, ref luid)) {
138
+ throw new Win32Exception(Marshal.GetLastWin32Error());
139
+ }
140
+
141
+ IntPtr hProcess = GetCurrentProcess();
142
+
143
+ if (!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref hAccessToken)) {
144
+ throw new Win32Exception(Marshal.GetLastWin32Error());
145
+ }
146
+
147
+ //
148
+ // Query information size
149
+ uint cb;
150
+ if (!GetTokenInformation(hAccessToken, TOKEN_INFORMATION_CLASS.TokenPrivileges, pTokenInfo, 0, out cb)) {
151
+ pTokenInfo = Marshal.AllocHGlobal((int)cb);
152
+
153
+ if (!GetTokenInformation(hAccessToken, TOKEN_INFORMATION_CLASS.TokenPrivileges, pTokenInfo, cb, out cb)) {
154
+ throw new Win32Exception(Marshal.GetLastWin32Error());
155
+ }
156
+ }
157
+
158
+ TOKEN_PRIVILEGES privileges = MarshalTokenPrivileges(pTokenInfo);
159
+
160
+ foreach (LUID_AND_ATTRIBUTES priv in privileges.Privileges) {
161
+ if (priv.Luid == luid) {
162
+ return (priv.Attributes & SE_PRIVILEGE_ENABLED) > 0;
163
+ }
164
+ }
165
+
166
+ return false;
167
+ }
168
+ finally {
169
+ if (hAccessToken != IntPtr.Zero) {
170
+ CloseHandle(hAccessToken);
171
+ hAccessToken = IntPtr.Zero;
172
+ }
173
+
174
+ if (pTokenInfo != IntPtr.Zero) {
175
+ Marshal.FreeHGlobal(pTokenInfo);
176
+ pTokenInfo = IntPtr.Zero;
177
+ }
178
+ }
179
+ }
180
+
181
+
182
+ private static TOKEN_PRIVILEGES MarshalTokenPrivileges(IntPtr buffer)
183
+ {
184
+ LUID_AND_ATTRIBUTES[] privs = new LUID_AND_ATTRIBUTES[(uint)Marshal.ReadInt32(buffer)];
185
+
186
+ for (int i = 0; i < privs.Length; i++) {
187
+ privs[i] = new LUID_AND_ATTRIBUTES();
188
+ Marshal.PtrToStructure(new IntPtr(buffer.ToInt64() + sizeof(uint) + Marshal.SizeOf(typeof(LUID_AND_ATTRIBUTES)) * i), privs[i]);
189
+ }
190
+
191
+ TOKEN_PRIVILEGES privileges = new TOKEN_PRIVILEGES();
192
+ privileges.PrivilegeCount = (uint)privs.Length;
193
+ privileges.Privileges = privs;
194
+
195
+ return privileges;
196
+ }
197
+ }
198
+ }
199
+ '
200
+
201
+ function InitializeInterop () {
202
+ try {
203
+ [Microsoft.IIS.Administration.Setup.AclUtil ] | Out-Null
204
+ }
205
+ catch {
206
+ Add-Type $cs
207
+ }
208
+ }
209
+
210
+ switch ($Command )
211
+ {
212
+ " Enable-AclUtil"
213
+ {
214
+ InitializeInterop
215
+ }
216
+ default
217
+ {
218
+ throw " Unknown command"
219
+ }
220
+ }
0 commit comments