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