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
SetLsaString(LPWSTR src,PLSA_UNICODE_STRING dest)35 static void SetLsaString(LPWSTR src, PLSA_UNICODE_STRING dest)
36 {
37 int len = (int)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
GetSid(LPWSTR accountName)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
AddLockMemoryPrivilege()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 }}
182