• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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