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