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