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