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