diff options
Diffstat (limited to 'CPP/Windows/SecurityUtils.cpp')
-rw-r--r-- | CPP/Windows/SecurityUtils.cpp | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/CPP/Windows/SecurityUtils.cpp b/CPP/Windows/SecurityUtils.cpp new file mode 100644 index 0000000..640c90d --- /dev/null +++ b/CPP/Windows/SecurityUtils.cpp | |||
@@ -0,0 +1,181 @@ | |||
1 | // Windows/SecurityUtils.cpp | ||
2 | |||
3 | #include "StdAfx.h" | ||
4 | |||
5 | #include "../Common/MyString.h" | ||
6 | |||
7 | #include "SecurityUtils.h" | ||
8 | |||
9 | namespace NWindows { | ||
10 | namespace NSecurity { | ||
11 | |||
12 | /* | ||
13 | bool MyLookupAccountSid(LPCTSTR systemName, PSID sid, | ||
14 | CSysString &accountName, CSysString &domainName, PSID_NAME_USE sidNameUse) | ||
15 | { | ||
16 | DWORD accountNameSize = 0, domainNameSize = 0; | ||
17 | |||
18 | if (!::LookupAccountSid(systemName, sid, | ||
19 | accountName.GetBuf(0), &accountNameSize, | ||
20 | domainName.GetBuf(0), &domainNameSize, sidNameUse)) | ||
21 | { | ||
22 | if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) | ||
23 | return false; | ||
24 | } | ||
25 | DWORD accountNameSize2 = accountNameSize, domainNameSize2 = domainNameSize; | ||
26 | bool result = BOOLToBool(::LookupAccountSid(systemName, sid, | ||
27 | accountName.GetBuf(accountNameSize), &accountNameSize2, | ||
28 | domainName.GetBuf(domainNameSize), &domainNameSize2, sidNameUse)); | ||
29 | accountName.ReleaseBuf_CalcLen(accountNameSize); | ||
30 | domainName.ReleaseBuf_CalcLen(domainNameSize); | ||
31 | return result; | ||
32 | } | ||
33 | */ | ||
34 | |||
35 | static void SetLsaString(LPWSTR src, PLSA_UNICODE_STRING dest) | ||
36 | { | ||
37 | size_t len = (size_t)wcslen(src); | ||
38 | dest->Length = (USHORT)(len * sizeof(WCHAR)); | ||
39 | dest->MaximumLength = (USHORT)((len + 1) * sizeof(WCHAR)); | ||
40 | dest->Buffer = src; | ||
41 | } | ||
42 | |||
43 | /* | ||
44 | static void MyLookupSids(CPolicy &policy, PSID ps) | ||
45 | { | ||
46 | LSA_REFERENCED_DOMAIN_LIST *referencedDomains = NULL; | ||
47 | LSA_TRANSLATED_NAME *names = NULL; | ||
48 | NTSTATUS nts = policy.LookupSids(1, &ps, &referencedDomains, &names); | ||
49 | int res = LsaNtStatusToWinError(nts); | ||
50 | LsaFreeMemory(referencedDomains); | ||
51 | LsaFreeMemory(names); | ||
52 | } | ||
53 | */ | ||
54 | |||
55 | #ifndef _UNICODE | ||
56 | typedef BOOL (WINAPI * LookupAccountNameWP)( | ||
57 | LPCWSTR lpSystemName, | ||
58 | LPCWSTR lpAccountName, | ||
59 | PSID Sid, | ||
60 | LPDWORD cbSid, | ||
61 | LPWSTR ReferencedDomainName, | ||
62 | LPDWORD cchReferencedDomainName, | ||
63 | PSID_NAME_USE peUse | ||
64 | ); | ||
65 | #endif | ||
66 | |||
67 | static PSID GetSid(LPWSTR accountName) | ||
68 | { | ||
69 | #ifndef _UNICODE | ||
70 | HMODULE hModule = GetModuleHandle(TEXT("Advapi32.dll")); | ||
71 | if (hModule == NULL) | ||
72 | return NULL; | ||
73 | LookupAccountNameWP lookupAccountNameW = (LookupAccountNameWP)GetProcAddress(hModule, "LookupAccountNameW"); | ||
74 | if (lookupAccountNameW == NULL) | ||
75 | return NULL; | ||
76 | #endif | ||
77 | |||
78 | DWORD sidLen = 0, domainLen = 0; | ||
79 | SID_NAME_USE sidNameUse; | ||
80 | if (! | ||
81 | #ifdef _UNICODE | ||
82 | ::LookupAccountNameW | ||
83 | #else | ||
84 | lookupAccountNameW | ||
85 | #endif | ||
86 | (NULL, accountName, NULL, &sidLen, NULL, &domainLen, &sidNameUse)) | ||
87 | { | ||
88 | if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) | ||
89 | { | ||
90 | PSID pSid = ::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sidLen); | ||
91 | LPWSTR domainName = (LPWSTR)::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (domainLen + 1) * sizeof(WCHAR)); | ||
92 | BOOL res = | ||
93 | #ifdef _UNICODE | ||
94 | ::LookupAccountNameW | ||
95 | #else | ||
96 | lookupAccountNameW | ||
97 | #endif | ||
98 | (NULL, accountName, pSid, &sidLen, domainName, &domainLen, &sidNameUse); | ||
99 | ::HeapFree(GetProcessHeap(), 0, domainName); | ||
100 | if (res) | ||
101 | return pSid; | ||
102 | } | ||
103 | } | ||
104 | return NULL; | ||
105 | } | ||
106 | |||
107 | #define MY__SE_LOCK_MEMORY_NAME L"SeLockMemoryPrivilege" | ||
108 | |||
109 | bool AddLockMemoryPrivilege() | ||
110 | { | ||
111 | CPolicy policy; | ||
112 | LSA_OBJECT_ATTRIBUTES attr; | ||
113 | attr.Length = sizeof(attr); | ||
114 | attr.RootDirectory = NULL; | ||
115 | attr.ObjectName = NULL; | ||
116 | attr.Attributes = 0; | ||
117 | attr.SecurityDescriptor = NULL; | ||
118 | attr.SecurityQualityOfService = NULL; | ||
119 | if (policy.Open(NULL, &attr, | ||
120 | // GENERIC_WRITE) | ||
121 | POLICY_ALL_ACCESS) | ||
122 | // STANDARD_RIGHTS_REQUIRED, | ||
123 | // GENERIC_READ | GENERIC_EXECUTE | POLICY_VIEW_LOCAL_INFORMATION | POLICY_LOOKUP_NAMES) | ||
124 | != 0) | ||
125 | return false; | ||
126 | LSA_UNICODE_STRING userRights; | ||
127 | wchar_t s[128] = MY__SE_LOCK_MEMORY_NAME; | ||
128 | SetLsaString(s, &userRights); | ||
129 | WCHAR userName[256 + 2]; | ||
130 | DWORD size = 256; | ||
131 | if (!GetUserNameW(userName, &size)) | ||
132 | return false; | ||
133 | PSID psid = GetSid(userName); | ||
134 | if (psid == NULL) | ||
135 | return false; | ||
136 | bool res = false; | ||
137 | |||
138 | /* | ||
139 | PLSA_UNICODE_STRING userRightsArray; | ||
140 | ULONG countOfRights; | ||
141 | NTSTATUS status = policy.EnumerateAccountRights(psid, &userRightsArray, &countOfRights); | ||
142 | if (status != 0) | ||
143 | return false; | ||
144 | bool finded = false; | ||
145 | for (ULONG i = 0; i < countOfRights; i++) | ||
146 | { | ||
147 | LSA_UNICODE_STRING &ur = userRightsArray[i]; | ||
148 | if (ur.Length != s.Length() * sizeof(WCHAR)) | ||
149 | continue; | ||
150 | if (wcsncmp(ur.Buffer, s, s.Length()) != 0) | ||
151 | continue; | ||
152 | finded = true; | ||
153 | res = true; | ||
154 | break; | ||
155 | } | ||
156 | if (!finded) | ||
157 | */ | ||
158 | { | ||
159 | /* | ||
160 | LSA_ENUMERATION_INFORMATION *enums; | ||
161 | ULONG countReturned; | ||
162 | NTSTATUS status = policy.EnumerateAccountsWithUserRight(&userRights, &enums, &countReturned); | ||
163 | if (status == 0) | ||
164 | { | ||
165 | for (ULONG i = 0; i < countReturned; i++) | ||
166 | MyLookupSids(policy, enums[i].Sid); | ||
167 | if (enums) | ||
168 | ::LsaFreeMemory(enums); | ||
169 | res = true; | ||
170 | } | ||
171 | */ | ||
172 | NTSTATUS status = policy.AddAccountRights(psid, &userRights); | ||
173 | if (status == 0) | ||
174 | res = true; | ||
175 | // ULONG res = LsaNtStatusToWinError(status); | ||
176 | } | ||
177 | HeapFree(GetProcessHeap(), 0, psid); | ||
178 | return res; | ||
179 | } | ||
180 | |||
181 | }} | ||