-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSecurityApi.cs
229 lines (191 loc) · 8.1 KB
/
SecurityApi.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
using System;
using System.Runtime.InteropServices;
namespace HttpConfig
{
public class SecurityApi
{
public enum SidNameUse
{
SidTypeUser = 1,
SidTypeGroup = 2,
SidTypeDomain = 3,
SidTypeAlias = 4,
SidTypeWellKnownGroup = 5,
SidTypeDeletedAccount = 6,
SidTypeInvalid = 7,
SidTypeUnknown = 8,
SidTypeComputer = 9
}
public enum Error
{
SUCCESS = 0,
ERROR_INSUFFICIENT_BUFFER = 122,
ERROR_NONE_MAPPED = 1332,
ERROR_TRUSTED_RELATIONSHIP_FAILURE = 1789,
}
private const int TOKEN_QUERY = 0x0008;
private const int ERROR_INSUFFICIENT_BUFFER = 122;
private const int ERROR_NO_TOKEN = 1008;
private const int SecurityImpersonation = 2;
private const int WinBuiltinAdministratorsSid = 26;
[DllImport("Advapi32.dll", SetLastError=true, EntryPoint="ConvertSidToStringSidW")]
public static extern bool ConvertSidToStringSid(
IntPtr Sid,
out IntPtr StringSid);
[DllImport("Advapi32.dll", SetLastError=true, EntryPoint="ConvertStringSidToSidW")]
public static extern bool ConvertStringSidToSid(
[MarshalAs(UnmanagedType.LPWStr)]string StringSid,
out IntPtr Sid);
[DllImport("Kernel32.dll", SetLastError=true)]
public static extern IntPtr LocalFree(IntPtr hMem);
[DllImport("Advapi32.dll", SetLastError=true, EntryPoint="LookupAccountSidW")]
public static extern bool LookupAccountSid(
[MarshalAs(UnmanagedType.LPWStr)]string lpSystemName,
IntPtr lpSid,
IntPtr lpName, // string
ref int cchName,
IntPtr lpReferencedDomainName, // string
ref int cchReferencedDomainName,
out SidNameUse peUse);
[DllImport("Advapi32.dll", SetLastError=true, EntryPoint="LookupAccountNameW")]
public static extern bool LookupAccountName(
[MarshalAs(UnmanagedType.LPWStr)]string lpSystemName,
[MarshalAs(UnmanagedType.LPWStr)]string lpAccountName,
IntPtr Sid,
ref int cbSid,
IntPtr ReferencedDomainName,
ref int cchReferencedDomainName,
out SidNameUse peUse);
[DllImport("Advapi32", SetLastError = true)]
private static extern bool CheckTokenMembership(
IntPtr TokenHandle,
IntPtr SidToCheck,
out bool IsMember);
[DllImport("Advapi32", SetLastError=true)]
private static extern bool OpenProcessToken(
IntPtr ProcessHandle,
int DesiredAccess,
out IntPtr TokenHandle);
[DllImport("Kernel32", SetLastError = true)]
private static extern bool CloseHandle(
IntPtr hObject);
[DllImport("Advapi32", SetLastError = true)]
private static extern bool CreateWellKnownSid(
int WellKnownSidType,
IntPtr DomainSid,
IntPtr pSid,
ref int cbSid);
[DllImport("Advapi32", SetLastError = true)]
private static extern bool OpenThreadToken(
IntPtr ThreadHandle,
int DesiredAccess,
bool OpenAsSelf,
out IntPtr TokenHandle);
[DllImport("Kernel32", SetLastError = true)]
private static extern IntPtr GetCurrentThread();
[DllImport("Advapi32", SetLastError = true)]
private static extern bool ImpersonateSelf(
int ImpersonationLevel);
[DllImport("Advapi32", SetLastError = true)]
private static extern bool RevertToSelf();
[DllImport("Advapi32", SetLastError = true)]
private static extern bool InitializeAcl(
IntPtr pAcl,
int nAclLength,
int dwAclRevision);
[DllImport("Advapi32", SetLastError = true)]
private static extern int GetLengthSid(
IntPtr pSid);
[DllImport("Advapi32", SetLastError = true)]
private static extern bool AddAccessAllowedAce(
IntPtr pAcl,
int dwAceRevision,
int AccessMask,
IntPtr pSid);
[DllImport("Advapi32", SetLastError = false, CharSet = CharSet.Unicode)]
private static extern int SetNamedSecurityInfo(
string pObjectName,
int ObjectType,
int SecurityInfo,
IntPtr psidOwner,
IntPtr psidGroup,
IntPtr pDacl,
IntPtr pSacl);
[DllImport("Advapi32", SetLastError = false, CharSet = CharSet.Unicode)]
private static extern int GetNamedSecurityInfo(
string pObjectName,
int ObjectType,
int SecurityInfo,
int ppsidOwner,
int ppsidGroup,
out IntPtr ppDacl,
int ppSacl,
out IntPtr ppSecurityDescriptor);
[DllImport("Advapi32", SetLastError = false, CharSet = CharSet.Unicode)]
private static extern int SetEntriesInAcl(
int cCountOfExplicitEntries,
IntPtr pListOfExplicitEntries, // PEXPLICIT_ACCESS
IntPtr OldAcl,
out IntPtr NewAcl);
[DllImport("Advapi32", SetLastError = false, CharSet = CharSet.Unicode)]
private static extern void BuildExplicitAccessWithName(
IntPtr pExplicitAccess,
string pTrusteeName,
int AccessPermissions,
int AccessMode,
int Inheritance);
public static bool IsAdmin
{
get
{
int err;
IntPtr hToken = IntPtr.Zero;
IntPtr pSid = IntPtr.Zero;
try
{
// Not necessary to CloseHandle()
IntPtr hThread = GetCurrentThread();
if(!OpenThreadToken(hThread, TOKEN_QUERY, true, out hToken))
{
err = Marshal.GetLastWin32Error();
if(err != ERROR_NO_TOKEN)
throw new Exception("OpenThreadToken failed (" + Marshal.GetLastWin32Error() + ").");
if(!ImpersonateSelf(SecurityImpersonation))
throw new Exception("ImpersonateSelf failed (" + Marshal.GetLastWin32Error() + ").");
if(!OpenThreadToken(hThread, TOKEN_QUERY, true, out hToken))
throw new Exception("OpenThreadToken failed (" + Marshal.GetLastWin32Error() + ").");
}
pSid = GetSid(WinBuiltinAdministratorsSid);
bool isAdmin;
if(!CheckTokenMembership(hToken, pSid, out isAdmin))
throw new Exception("CheckTokenMembership failed (" + Marshal.GetLastWin32Error() + ").");
return isAdmin;
}
finally
{
if(hToken != IntPtr.Zero)
CloseHandle(hToken);
if(pSid != IntPtr.Zero)
Marshal.FreeHGlobal(pSid);
if(!RevertToSelf())
throw new Exception("RevertToSelf failed (" + Marshal.GetLastWin32Error() + ").");
}
}
}
private static IntPtr GetSid(int sidType)
{
int sidSize = 0;
CreateWellKnownSid(sidType, IntPtr.Zero, IntPtr.Zero, ref sidSize);
int err = Marshal.GetLastWin32Error();
if(err != ERROR_INSUFFICIENT_BUFFER)
throw new Exception("CreateWellKnownSid failed (" + err + ").");
IntPtr pSid = Marshal.AllocHGlobal(sidSize);
if(!CreateWellKnownSid(sidType, IntPtr.Zero, pSid, ref sidSize))
{
Marshal.FreeHGlobal(pSid);
throw new Exception("CreateWellKnownSid failed (" + Marshal.GetLastWin32Error() + ").");
}
return pSid;
}
}
}