xref: /aosp_15_r20/external/lzma/CPP/Windows/SecurityUtils.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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