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