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