1370b324cSopenharmony_ci// Windows/SecurityUtils.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include "SecurityUtils.h"
6370b324cSopenharmony_ci
7370b324cSopenharmony_cinamespace NWindows {
8370b324cSopenharmony_cinamespace NSecurity {
9370b324cSopenharmony_ci
10370b324cSopenharmony_ci/*
11370b324cSopenharmony_cibool MyLookupAccountSid(LPCTSTR systemName, PSID sid,
12370b324cSopenharmony_ci  CSysString &accountName, CSysString &domainName, PSID_NAME_USE sidNameUse)
13370b324cSopenharmony_ci{
14370b324cSopenharmony_ci  DWORD accountNameSize = 0, domainNameSize = 0;
15370b324cSopenharmony_ci
16370b324cSopenharmony_ci  if (!::LookupAccountSid(systemName, sid,
17370b324cSopenharmony_ci      accountName.GetBuf(0), &accountNameSize,
18370b324cSopenharmony_ci      domainName.GetBuf(0), &domainNameSize, sidNameUse))
19370b324cSopenharmony_ci  {
20370b324cSopenharmony_ci    if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
21370b324cSopenharmony_ci      return false;
22370b324cSopenharmony_ci  }
23370b324cSopenharmony_ci  DWORD accountNameSize2 = accountNameSize, domainNameSize2 = domainNameSize;
24370b324cSopenharmony_ci  bool result = BOOLToBool(::LookupAccountSid(systemName, sid,
25370b324cSopenharmony_ci      accountName.GetBuf(accountNameSize), &accountNameSize2,
26370b324cSopenharmony_ci      domainName.GetBuf(domainNameSize), &domainNameSize2, sidNameUse));
27370b324cSopenharmony_ci  accountName.ReleaseBuf_CalcLen(accountNameSize);
28370b324cSopenharmony_ci  domainName.ReleaseBuf_CalcLen(domainNameSize);
29370b324cSopenharmony_ci  return result;
30370b324cSopenharmony_ci}
31370b324cSopenharmony_ci*/
32370b324cSopenharmony_ci
33370b324cSopenharmony_cistatic void SetLsaString(LPWSTR src, PLSA_UNICODE_STRING dest)
34370b324cSopenharmony_ci{
35370b324cSopenharmony_ci  const size_t len = (size_t)wcslen(src);
36370b324cSopenharmony_ci  dest->Length = (USHORT)(len * sizeof(WCHAR));
37370b324cSopenharmony_ci  dest->MaximumLength = (USHORT)((len + 1) * sizeof(WCHAR));
38370b324cSopenharmony_ci  dest->Buffer = src;
39370b324cSopenharmony_ci}
40370b324cSopenharmony_ci
41370b324cSopenharmony_ci/*
42370b324cSopenharmony_cistatic void MyLookupSids(CPolicy &policy, PSID ps)
43370b324cSopenharmony_ci{
44370b324cSopenharmony_ci  LSA_REFERENCED_DOMAIN_LIST *referencedDomains = NULL;
45370b324cSopenharmony_ci  LSA_TRANSLATED_NAME *names = NULL;
46370b324cSopenharmony_ci  NTSTATUS nts = policy.LookupSids(1, &ps, &referencedDomains, &names);
47370b324cSopenharmony_ci  int res = LsaNtStatusToWinError(nts);
48370b324cSopenharmony_ci  LsaFreeMemory(referencedDomains);
49370b324cSopenharmony_ci  LsaFreeMemory(names);
50370b324cSopenharmony_ci}
51370b324cSopenharmony_ci*/
52370b324cSopenharmony_ci
53370b324cSopenharmony_ciextern "C" {
54370b324cSopenharmony_ci
55370b324cSopenharmony_ci#ifndef _UNICODE
56370b324cSopenharmony_citypedef BOOL (WINAPI * Func_LookupAccountNameW)(
57370b324cSopenharmony_ci    LPCWSTR lpSystemName,
58370b324cSopenharmony_ci    LPCWSTR lpAccountName,
59370b324cSopenharmony_ci    PSID Sid,
60370b324cSopenharmony_ci    LPDWORD cbSid,
61370b324cSopenharmony_ci    LPWSTR ReferencedDomainName,
62370b324cSopenharmony_ci    LPDWORD cchReferencedDomainName,
63370b324cSopenharmony_ci    PSID_NAME_USE peUse
64370b324cSopenharmony_ci    );
65370b324cSopenharmony_ci#endif
66370b324cSopenharmony_ci
67370b324cSopenharmony_ci}
68370b324cSopenharmony_ci
69370b324cSopenharmony_cistatic PSID GetSid(LPWSTR accountName)
70370b324cSopenharmony_ci{
71370b324cSopenharmony_ci  #ifndef _UNICODE
72370b324cSopenharmony_ci  const HMODULE hModule = GetModuleHandle(TEXT("advapi32.dll"));
73370b324cSopenharmony_ci  if (!hModule)
74370b324cSopenharmony_ci    return NULL;
75370b324cSopenharmony_ci  const
76370b324cSopenharmony_ci  Func_LookupAccountNameW lookupAccountNameW = Z7_GET_PROC_ADDRESS(
77370b324cSopenharmony_ci  Func_LookupAccountNameW, hModule,
78370b324cSopenharmony_ci      "LookupAccountNameW");
79370b324cSopenharmony_ci  if (!lookupAccountNameW)
80370b324cSopenharmony_ci    return NULL;
81370b324cSopenharmony_ci  #endif
82370b324cSopenharmony_ci
83370b324cSopenharmony_ci  DWORD sidLen = 0, domainLen = 0;
84370b324cSopenharmony_ci  SID_NAME_USE sidNameUse;
85370b324cSopenharmony_ci  if (!
86370b324cSopenharmony_ci    #ifdef _UNICODE
87370b324cSopenharmony_ci    ::LookupAccountNameW
88370b324cSopenharmony_ci    #else
89370b324cSopenharmony_ci      lookupAccountNameW
90370b324cSopenharmony_ci    #endif
91370b324cSopenharmony_ci        (NULL, accountName, NULL, &sidLen, NULL, &domainLen, &sidNameUse))
92370b324cSopenharmony_ci  {
93370b324cSopenharmony_ci    if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
94370b324cSopenharmony_ci    {
95370b324cSopenharmony_ci      const PSID pSid = ::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sidLen);
96370b324cSopenharmony_ci      LPWSTR domainName = (LPWSTR)::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (domainLen + 1) * sizeof(WCHAR));
97370b324cSopenharmony_ci      const BOOL res =
98370b324cSopenharmony_ci        #ifdef _UNICODE
99370b324cSopenharmony_ci        ::LookupAccountNameW
100370b324cSopenharmony_ci        #else
101370b324cSopenharmony_ci          lookupAccountNameW
102370b324cSopenharmony_ci        #endif
103370b324cSopenharmony_ci            (NULL, accountName, pSid, &sidLen, domainName, &domainLen, &sidNameUse);
104370b324cSopenharmony_ci      ::HeapFree(GetProcessHeap(), 0, domainName);
105370b324cSopenharmony_ci      if (res)
106370b324cSopenharmony_ci        return pSid;
107370b324cSopenharmony_ci    }
108370b324cSopenharmony_ci  }
109370b324cSopenharmony_ci  return NULL;
110370b324cSopenharmony_ci}
111370b324cSopenharmony_ci
112370b324cSopenharmony_ci#define Z7_WIN_SE_LOCK_MEMORY_NAME L"SeLockMemoryPrivilege"
113370b324cSopenharmony_ci
114370b324cSopenharmony_cibool AddLockMemoryPrivilege()
115370b324cSopenharmony_ci{
116370b324cSopenharmony_ci  CPolicy policy;
117370b324cSopenharmony_ci  LSA_OBJECT_ATTRIBUTES attr;
118370b324cSopenharmony_ci  attr.Length = sizeof(attr);
119370b324cSopenharmony_ci  attr.RootDirectory = NULL;
120370b324cSopenharmony_ci  attr.ObjectName  = NULL;
121370b324cSopenharmony_ci  attr.Attributes = 0;
122370b324cSopenharmony_ci  attr.SecurityDescriptor = NULL;
123370b324cSopenharmony_ci  attr.SecurityQualityOfService  = NULL;
124370b324cSopenharmony_ci  if (policy.Open(NULL, &attr,
125370b324cSopenharmony_ci      // GENERIC_WRITE)
126370b324cSopenharmony_ci      POLICY_ALL_ACCESS)
127370b324cSopenharmony_ci      // STANDARD_RIGHTS_REQUIRED,
128370b324cSopenharmony_ci      // GENERIC_READ | GENERIC_EXECUTE | POLICY_VIEW_LOCAL_INFORMATION | POLICY_LOOKUP_NAMES)
129370b324cSopenharmony_ci      != 0)
130370b324cSopenharmony_ci    return false;
131370b324cSopenharmony_ci  LSA_UNICODE_STRING userRights;
132370b324cSopenharmony_ci  wchar_t s[128] = Z7_WIN_SE_LOCK_MEMORY_NAME;
133370b324cSopenharmony_ci  SetLsaString(s, &userRights);
134370b324cSopenharmony_ci  WCHAR userName[256 + 2];
135370b324cSopenharmony_ci  DWORD size = 256;
136370b324cSopenharmony_ci  if (!GetUserNameW(userName, &size))
137370b324cSopenharmony_ci    return false;
138370b324cSopenharmony_ci  const PSID psid = GetSid(userName);
139370b324cSopenharmony_ci  if (psid == NULL)
140370b324cSopenharmony_ci    return false;
141370b324cSopenharmony_ci  bool res = false;
142370b324cSopenharmony_ci
143370b324cSopenharmony_ci  /*
144370b324cSopenharmony_ci  PLSA_UNICODE_STRING userRightsArray;
145370b324cSopenharmony_ci  ULONG countOfRights;
146370b324cSopenharmony_ci  NTSTATUS status = policy.EnumerateAccountRights(psid, &userRightsArray, &countOfRights);
147370b324cSopenharmony_ci  if (status != 0)
148370b324cSopenharmony_ci    return false;
149370b324cSopenharmony_ci  bool finded = false;
150370b324cSopenharmony_ci  for (ULONG i = 0; i < countOfRights; i++)
151370b324cSopenharmony_ci  {
152370b324cSopenharmony_ci    LSA_UNICODE_STRING &ur = userRightsArray[i];
153370b324cSopenharmony_ci    if (ur.Length != s.Length() * sizeof(WCHAR))
154370b324cSopenharmony_ci      continue;
155370b324cSopenharmony_ci    if (wcsncmp(ur.Buffer, s, s.Length()) != 0)
156370b324cSopenharmony_ci      continue;
157370b324cSopenharmony_ci    finded = true;
158370b324cSopenharmony_ci    res = true;
159370b324cSopenharmony_ci    break;
160370b324cSopenharmony_ci  }
161370b324cSopenharmony_ci  if (!finded)
162370b324cSopenharmony_ci  */
163370b324cSopenharmony_ci  {
164370b324cSopenharmony_ci    /*
165370b324cSopenharmony_ci    LSA_ENUMERATION_INFORMATION *enums;
166370b324cSopenharmony_ci    ULONG countReturned;
167370b324cSopenharmony_ci    NTSTATUS status = policy.EnumerateAccountsWithUserRight(&userRights, &enums, &countReturned);
168370b324cSopenharmony_ci    if (status == 0)
169370b324cSopenharmony_ci    {
170370b324cSopenharmony_ci      for (ULONG i = 0; i < countReturned; i++)
171370b324cSopenharmony_ci        MyLookupSids(policy, enums[i].Sid);
172370b324cSopenharmony_ci      if (enums)
173370b324cSopenharmony_ci        ::LsaFreeMemory(enums);
174370b324cSopenharmony_ci      res = true;
175370b324cSopenharmony_ci    }
176370b324cSopenharmony_ci    */
177370b324cSopenharmony_ci    const NTSTATUS status = policy.AddAccountRights(psid, &userRights);
178370b324cSopenharmony_ci    if (status == 0)
179370b324cSopenharmony_ci      res = true;
180370b324cSopenharmony_ci    // ULONG res = LsaNtStatusToWinError(status);
181370b324cSopenharmony_ci  }
182370b324cSopenharmony_ci  HeapFree(GetProcessHeap(), 0, psid);
183370b324cSopenharmony_ci  return res;
184370b324cSopenharmony_ci}
185370b324cSopenharmony_ci
186370b324cSopenharmony_ci}}
187