ReactOS  0.4.15-dev-4857-g47842d7
util.c
Go to the documentation of this file.
1 /*
2  * PROJECT: Authentication Package DLL
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Utils for msv1_0
5  * COPYRIGHT: Copyright 2011 Samuel SerapiĆ³n
6  * Copyright 2020 Andreas Maier <staubim@quantentunnel.de>
7  */
8 
9 #include "../precomp.h"
10 
11 #include "wine/debug.h"
13 
14 #define NTLM_ALLOC_TAG "NTLM"
15 #define NTLM_ALLOC_TAG_SIZE strlen(NTLM_ALLOC_TAG)
16 
17 PVOID
19  _In_ size_t Size,
20  _In_ bool UsePrivateLsaHeap)
21 {
22  PVOID buffer = NULL;
23 
24  if (Size == 0)
25  {
26  ERR("Allocating 0 bytes!\n");
27  return NULL;
28  }
29 
31 
32  switch (NtlmMode)
33  {
34  case NtlmLsaMode:
35  {
36  if (UsePrivateLsaHeap)
38  else
40 
41  if (buffer != NULL)
43  break;
44  }
45  case NtlmUserMode:
46  {
48  break;
49  }
50  default:
51  {
52  ERR("NtlmState unknown!\n");
53  break;
54  }
55  }
56 
59 
60  return buffer;
61 }
62 
63 VOID
66  _In_ bool FromPrivateLsaHeap)
67 {
68  if (Buffer)
69  {
72  *(char*)Buffer = 'D';
73 
74  switch (NtlmMode)
75  {
76  case NtlmLsaMode:
77  {
78  if (FromPrivateLsaHeap)
80  else
82  break;
83  }
84  case NtlmUserMode:
85  {
87  break;
88  }
89  default:
90  {
91  ERR("NtlmState unknown!\n");
92  break;
93  }
94  }
95  }
96  else
97  {
98  ERR("Trying to free NULL!\n");
99  }
100 }
101 
102 bool
105  _In_ UINT16 SizeInBytes,
106  _In_ UINT16 InitLength)
107 {
108  Dst->Length = InitLength;
109  Dst->MaximumLength = SizeInBytes;
110  Dst->Buffer = NtlmAllocate(SizeInBytes, false);
111  return (Dst->Buffer != NULL);
112 }
113 
114 VOID
117 {
118  if (String == NULL || String->Buffer == NULL || String->MaximumLength == 0)
119  return;
120 
121  NtlmFree(String->Buffer, false);
122  String->Buffer = NULL;
123  String->MaximumLength = 0;
124 }
125 
155 static
156 bool
158  _In_ PVOID DataStart,
160  _Out_ PWCHAR* DstDataWPtr,
161  _In_ const WCHAR* SrcDataW,
162  _In_ ULONG SrcDataLen,
163  _Inout_ PBYTE* AbsoluteOffsetPtr,
164  _In_ bool TerminateWith0)
165 {
166  ULONG SrcDataMaxLen;
167 
168  if (SrcDataLen == 0)
169  SrcDataLen = wcslen(SrcDataW) * sizeof(WCHAR);
170 
171  SrcDataMaxLen = SrcDataLen;
172  if (TerminateWith0)
173  SrcDataMaxLen += sizeof(WCHAR);
174 
175  if (*AbsoluteOffsetPtr < (PBYTE)DataStart)
176  {
177  ERR("Invalid offset\n");
178  return false;
179  }
180 
181  if (*AbsoluteOffsetPtr + SrcDataMaxLen > (PBYTE)DataStart + DataSize)
182  {
183  ERR("Out of bounds!\n");
184  return false;
185  }
186 
187  memcpy(*AbsoluteOffsetPtr, SrcDataW, SrcDataLen);
188  *DstDataWPtr = (WCHAR*)*AbsoluteOffsetPtr;
189  if (TerminateWith0)
190  (*DstDataWPtr)[SrcDataLen / sizeof(WCHAR)] = 0;
191  *AbsoluteOffsetPtr += SrcDataMaxLen;
192 
193  return true;
194 }
195 
196 bool
198  _In_ PVOID DataStart,
200  _Out_ PUNICODE_STRING DstData,
201  _In_ const PUNICODE_STRING SrcData,
202  _Inout_ PBYTE* AbsoluteOffsetPtr,
203  _In_ bool TerminateWith0)
204 {
205  if (!NtlmStructWriteStrW(DataStart,
206  DataSize,
207  &DstData->Buffer,
208  SrcData->Buffer,
209  SrcData->Length,
210  AbsoluteOffsetPtr,
211  TerminateWith0))
212  return false;
213 
214  DstData->Length = SrcData->Length;
215  DstData->MaximumLength = SrcData->Length;
216  if (TerminateWith0)
217  SrcData->MaximumLength += sizeof(WCHAR);
218 
219  return true;
220 }
221 
222 bool
225  _In_ ULONG_PTR FixupOffset)
226 {
228 
229  if (String->Length)
230  {
231  String->Buffer = FIXUP_POINTER(String->Buffer, FixupOffset);
232  String->MaximumLength = String->Length;
233  }
234  else
235  {
236  String->Buffer = NULL;
237  String->MaximumLength = 0;
238  }
239 
241  return NT_SUCCESS(Status);
242 }
243 
244 bool
247  _In_ ULONG_PTR FixupOffset)
248 {
249  if (String->Length)
250  {
251  String->Buffer = (PCHAR)FIXUP_POINTER(String->Buffer, FixupOffset);
252  String->MaximumLength = String->Length;
253  }
254  else
255  {
256  String->Buffer = NULL;
257  String->MaximumLength = 0;
258  }
259 
260  return true;
261 }
262 
263 NTSTATUS
265  _In_ PLSA_CLIENT_REQUEST ClientRequest,
268 {
270 
271  if (!Buffer)
272  return STATUS_NO_MEMORY;
273 
274  Buffer->LocalBuffer = NtlmAllocate(BufferLength, false);
275  if (!Buffer->LocalBuffer)
276  return STATUS_NO_MEMORY;
277 
278  if ((HANDLE)ClientRequest == INVALID_HANDLE_VALUE)
279  {
280  Buffer->ClientBaseAddress = Buffer->LocalBuffer;
281  //if (!ClientBaseAddress)
282  // return STATUS_INSUFFICIENT_RESOURCES;
283  }
284  else
285  {
286  Status = DispatchTable.AllocateClientBuffer(ClientRequest,
287  BufferLength,
288  &Buffer->ClientBaseAddress);
289  if (!NT_SUCCESS(Status))
290  {
291  NtlmFree(Buffer->LocalBuffer, false);
292  Buffer->LocalBuffer = NULL;
293  }
294  //FIXME: Maybe we have to free ClientBaseAddress if something
295  // goes wrong ...? I'm not sure about that ...
296  }
297  return Status;
298 }
299 
300 NTSTATUS
302  _In_ PLSA_CLIENT_REQUEST ClientRequest,
305 {
307 
308  if ((HANDLE)ClientRequest == INVALID_HANDLE_VALUE)
309  {
310  // If ClientRequest ist INVALID_HANDLE_VALUE
311  // Buffer->LocalBuffer == Buffer->ClientBaseAddress
312  if (Buffer->ClientBaseAddress != Buffer->LocalBuffer)
313  {
314  ERR("Buffer->ClientBaseAddress != Buffer->LocalBuffer (something must be wrong!)\n");
315  return STATUS_INTERNAL_ERROR;
316  }
317  }
318  else
319  {
320  if (!Buffer->ClientBaseAddress ||
321  !Buffer->LocalBuffer)
322  {
323  ERR("Invalid Buffer - not allocated!\n");
324  return STATUS_NO_MEMORY;
325  }
326  Status = DispatchTable.CopyToClientBuffer(ClientRequest,
327  BufferLength,
328  Buffer->ClientBaseAddress,
329  Buffer->LocalBuffer);
330  }
331  return Status;
332 }
333 
334 VOID
336  _In_ PLSA_CLIENT_REQUEST ClientRequest,
337  _In_ bool FreeClientBuffer,
339 {
340  if (!Buffer->ClientBaseAddress)
341  return;
342 
343  if ((HANDLE)ClientRequest == INVALID_HANDLE_VALUE)
344  {
345  if (Buffer->ClientBaseAddress != Buffer->LocalBuffer)
346  {
347  ERR("Buffer->ClientBaseAddress != Buffer->LocalBuffer (something must be wrong!)\n");
348  return;
349  }
350  // LocalBuffer and ClientBaseAddress is the same
351  // so we have only to free it if FreeClientBuffer is TRUE.
352  Buffer->LocalBuffer = NULL;
353  if (FreeClientBuffer)
354  {
355  NtlmFree(Buffer->ClientBaseAddress, false);
356  Buffer->ClientBaseAddress = NULL;
357  }
358  }
359  else
360  {
361  NtlmFree(Buffer->LocalBuffer, false);
362  Buffer->LocalBuffer = NULL;
363  if (FreeClientBuffer)
364  DispatchTable.FreeClientBuffer(ClientRequest, Buffer->ClientBaseAddress);
365  Buffer->ClientBaseAddress = NULL;
366  }
367 }
VOID NtlmFree(_In_ PVOID Buffer, _In_ bool FromPrivateLsaHeap)
Definition: util.c:64
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3767
PLSA_ALLOCATE_PRIVATE_HEAP AllocatePrivateHeap
Definition: ntsecpkg.h:363
WINE_DEFAULT_DEBUG_CHANNEL(d3dx)
PLSA_SECPKG_FUNCTION_TABLE LsaFunctions
Definition: global.c:19
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
LONG NTSTATUS
Definition: precomp.h:26
static bool NtlmStructWriteStrW(_In_ PVOID DataStart, _In_ ULONG DataSize, _Out_ PWCHAR *DstDataWPtr, _In_ const WCHAR *SrcDataW, _In_ ULONG SrcDataLen, _Inout_ PBYTE *AbsoluteOffsetPtr, _In_ bool TerminateWith0)
Helper to fill a WCHAR-String in a struct. The stringdata is appended to the struct....
Definition: util.c:157
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
GLuint buffer
Definition: glext.h:5915
bool NtlmFixupAndValidateUStr(_Inout_ PUNICODE_STRING String, _In_ ULONG_PTR FixupOffset)
Definition: util.c:223
uint16_t * PWCHAR
Definition: typedefs.h:56
NTLM_MODE NtlmMode
Definition: global.c:15
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
PLSA_FREE_PRIVATE_HEAP FreePrivateHeap
Definition: ntsecpkg.h:364
#define FIXUP_POINTER(Pointer, Offset)
Definition: msv1_0.h:9
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
NTSYSAPI NTSTATUS NTAPI RtlValidateUnicodeString(_In_ ULONG Flags, _In_ PCUNICODE_STRING String)
Definition: unicode.c:2559
#define _In_
Definition: ms_sal.h:308
Definition: bufpool.h:45
bool NtlmUStrWriteToStruct(_In_ PVOID DataStart, _In_ ULONG DataSize, _Out_ PUNICODE_STRING DstData, _In_ const PUNICODE_STRING SrcData, _Inout_ PBYTE *AbsoluteOffsetPtr, _In_ bool TerminateWith0)
Definition: util.c:197
#define PCHAR
Definition: match.c:90
Status
Definition: gdiplustypes.h:24
PVOID NtlmAllocate(_In_ size_t Size, _In_ bool UsePrivateLsaHeap)
Definition: util.c:18
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
NTSTATUS NtlmAllocateClientBuffer(_In_ PLSA_CLIENT_REQUEST ClientRequest, _In_ ULONG BufferLength, _Inout_ PNTLM_CLIENT_BUFFER Buffer)
Definition: util.c:264
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
bool NtlmUStrAlloc(_Inout_ PUNICODE_STRING Dst, _In_ UINT16 SizeInBytes, _In_ UINT16 InitLength)
Definition: util.c:103
VOID NtlmUStrFree(_In_ PUNICODE_STRING String)
Definition: util.c:115
#define NTLM_ALLOC_TAG
Definition: util.c:14
bool NtlmFixupAStr(_Inout_ PSTRING String, _In_ ULONG_PTR FixupOffset)
Definition: util.c:245
PLSA_FREE_LSA_HEAP FreeLsaHeap
Definition: ntsecpkg.h:315
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define Dst
Definition: mesh.h:153
#define ERR(fmt,...)
Definition: debug.h:110
PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap
Definition: ntsecpkg.h:314
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
unsigned short UINT16
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
VOID NtlmFreeClientBuffer(_In_ PLSA_CLIENT_REQUEST ClientRequest, _In_ bool FreeClientBuffer, _Inout_ PNTLM_CLIENT_BUFFER Buffer)
Definition: util.c:335
NTSTATUS NtlmCopyToClientBuffer(_In_ PLSA_CLIENT_REQUEST ClientRequest, _In_ ULONG BufferLength, _Inout_ PNTLM_CLIENT_BUFFER Buffer)
Definition: util.c:301
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ PWDFDEVICE_INIT _In_ PWDF_PDO_EVENT_CALLBACKS DispatchTable
Definition: wdfpdo.h:245
BYTE * PBYTE
Definition: pedump.c:66
#define HeapFree(x, y, z)
Definition: compat.h:594
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
#define NTLM_ALLOC_TAG_SIZE
Definition: util.c:15