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