ReactOS  0.4.15-dev-4603-gb922b6d
sam.c File Reference
#include "precomp.h"
#include "wine/debug.h"
Include dependency graph for sam.c:

Go to the source code of this file.

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (msv1_0_sam)
 
static NTSTATUS GetAccountDomainSid (_In_ PRPC_SID *Sid)
 
static NTSTATUS MsvpCheckPassword (_In_ PLSA_SAM_PWD_DATA UserPwdData, _In_ PSAMPR_USER_INFO_BUFFER UserInfo)
 
static bool MsvpCheckLogonHours (_In_ PSAMPR_LOGON_HOURS LogonHours, _In_ LARGE_INTEGER LogonTime)
 
static bool MsvpCheckWorkstations (_In_ PRPC_UNICODE_STRING WorkStations, _In_ PWSTR ComputerName)
 
static NTSTATUS SamValidateNormalUser (_In_ PUNICODE_STRING UserName, _In_ PLSA_SAM_PWD_DATA PwdData, _In_ PUNICODE_STRING ComputerName, _Out_ PRPC_SID *AccountDomainSidPtr, _Out_ SAMPR_HANDLE *UserHandlePtr, _Out_ PSAMPR_USER_INFO_BUFFER *UserInfoPtr, _Out_ PNTSTATUS SubStatus)
 
static NTSTATUS GetNtAuthorityDomainSid (_In_ PRPC_SID *Sid)
 
NTSTATUS SamValidateUser (_In_ SECURITY_LOGON_TYPE LogonType, _In_ PUNICODE_STRING LogonUserName, _In_ PUNICODE_STRING LogonDomain, _In_ PLSA_SAM_PWD_DATA LogonPwdData, _In_ PUNICODE_STRING ComputerName, _Out_ PBOOL SpecialAccount, _Out_ PRPC_SID *AccountDomainSidPtr, _Out_ SAMPR_HANDLE *UserHandlePtr, _Out_ PSAMPR_USER_INFO_BUFFER *UserInfoPtr, _Out_ PNTSTATUS SubStatus)
 Validates a user by checking if it exists in the sam database. Some other checks are done further. More...
 

Function Documentation

◆ GetAccountDomainSid()

static NTSTATUS GetAccountDomainSid ( _In_ PRPC_SID Sid)
static

Definition at line 16 of file sam.c.

18 {
19  LSAPR_HANDLE PolicyHandle = NULL;
20  PLSAPR_POLICY_INFORMATION PolicyInfo = NULL;
21  ULONG Length = 0;
23 
24  Status = LsaIOpenPolicyTrusted(&PolicyHandle);
25  if (!NT_SUCCESS(Status))
26  {
27  TRACE("LsaIOpenPolicyTrusted() failed (Status 0x%08lx)\n", Status);
28  return Status;
29  }
30 
31  Status = LsarQueryInformationPolicy(PolicyHandle,
33  &PolicyInfo);
34  if (!NT_SUCCESS(Status))
35  {
36  TRACE("LsarQueryInformationPolicy() failed (Status 0x%08lx)\n", Status);
37  goto done;
38  }
39 
41 
42  *Sid = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
43  if (*Sid == NULL)
44  {
45  ERR("Failed to allocate SID\n");
47  goto done;
48  }
49 
51 
52 done:
53  if (PolicyInfo != NULL)
55  PolicyInfo);
56 
57  if (PolicyHandle != NULL)
58  LsarClose(&PolicyHandle);
59 
60  return Status;
61 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
LONG NTSTATUS
Definition: precomp.h:26
LSAPR_POLICY_ACCOUNT_DOM_INFO PolicyAccountDomainInfo
Definition: msv1_0.h:276
NTSTATUS WINAPI LsaIOpenPolicyTrusted(OUT LSAPR_HANDLE *PolicyHandle)
Definition: policy.c:15
VOID NTAPI LsaIFree_LSAPR_POLICY_INFORMATION(IN POLICY_INFORMATION_CLASS InformationClass, IN PLSAPR_POLICY_INFORMATION PolicyInformation)
Definition: lsasrv.c:51
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1103
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
NTSTATUS WINAPI LsarQueryInformationPolicy(LSAPR_HANDLE PolicyHandle, POLICY_INFORMATION_CLASS InformationClass, PLSAPR_POLICY_INFORMATION *PolicyInformation)
Definition: lsarpc.c:531
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS WINAPI LsarClose(LSAPR_HANDLE *ObjectHandle)
Definition: lsarpc.c:125
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1

Referenced by NetUserEnum(), NetUserGetGroups(), NetUserGetInfo(), NetUserGetLocalGroups(), NetUserModalsGet(), and SamValidateNormalUser().

◆ GetNtAuthorityDomainSid()

static NTSTATUS GetNtAuthorityDomainSid ( _In_ PRPC_SID Sid)
static

Definition at line 439 of file sam.c.

441 {
443  ULONG Length = 0;
444 
446  *Sid = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
447  if (*Sid == NULL)
448  {
449  ERR("Failed to allocate SID\n");
451  }
452 
454 
455  return STATUS_SUCCESS;
456 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NTSYSAPI NTSTATUS NTAPI RtlInitializeSid(IN OUT PSID Sid, IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount)
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1103
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
static SID_IDENTIFIER_AUTHORITY NtAuthority
Definition: security.c:40
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSYSAPI ULONG NTAPI RtlLengthRequiredSid(IN ULONG SubAuthorityCount)
Definition: sid.c:54

Referenced by SamValidateUser().

◆ MsvpCheckLogonHours()

static bool MsvpCheckLogonHours ( _In_ PSAMPR_LOGON_HOURS  LogonHours,
_In_ LARGE_INTEGER  LogonTime 
)
static

Definition at line 157 of file sam.c.

160 {
161 #if 0
162  LARGE_INTEGER LocalLogonTime;
164  USHORT MinutesPerUnit, Offset;
165  bool bFound;
166 
167  FIXME("MsvpCheckLogonHours(%p %llx)\n", LogonHours, LogonTime);
168 
169  if (LogonHours->UnitsPerWeek == 0 || LogonHours->LogonHours == NULL)
170  {
171  FIXME("No logon hours!\n");
172  return true;
173  }
174 
175  RtlSystemTimeToLocalTime(&LogonTime, &LocalLogonTime);
176  RtlTimeToTimeFields(&LocalLogonTime, &TimeFields);
177 
178  FIXME("UnitsPerWeek: %u\n", LogonHours->UnitsPerWeek);
179  MinutesPerUnit = 10080 / LogonHours->UnitsPerWeek;
180 
181  Offset = ((TimeFields.Weekday * 24 + TimeFields.Hour) * 60 + TimeFields.Minute) / MinutesPerUnit;
182  FIXME("Offset: %us\n", Offset);
183 
184  bFound = (bool)(LogonHours->LogonHours[Offset / 8] & (1 << (Offset % 8)));
185  FIXME("Logon permitted: %s\n", bFound ? "Yes" : "No");
186 
187  return bFound;
188 #endif
189  return true;
190 }
USHORT Weekday
Definition: env_spec_w32.h:718
#define FIXME(fmt,...)
Definition: debug.h:111
NTSYSAPI NTSTATUS NTAPI RtlSystemTimeToLocalTime(_In_ PLARGE_INTEGER SystemTime, _Out_ PLARGE_INTEGER LocalTime)
typedef bool(CARDLIBPROC *pCanDragProc)(CardRegion &stackobj
BOOLEAN RtlTimeToTimeFields(IN PLARGE_INTEGER Time, IN PTIME_FIELDS TimeFields)
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
unsigned short USHORT
Definition: pedump.c:61
#define NULL
Definition: types.h:112
static PTIME_FIELDS TimeFields
Definition: time.c:104

Referenced by SamValidateNormalUser().

◆ MsvpCheckPassword()

static NTSTATUS MsvpCheckPassword ( _In_ PLSA_SAM_PWD_DATA  UserPwdData,
_In_ PSAMPR_USER_INFO_BUFFER  UserInfo 
)
static

Definition at line 66 of file sam.c.

69 {
70  ENCRYPTED_NT_OWF_PASSWORD UserNtPassword;
71  ENCRYPTED_LM_OWF_PASSWORD UserLmPassword;
72  BOOLEAN UserLmPasswordPresent = FALSE;
73  BOOLEAN UserNtPasswordPresent = FALSE;
74  OEM_STRING LmPwdString;
75  CHAR LmPwdBuffer[15];
77 
78  TRACE("(%p %p)\n", UserPwdData, UserInfo);
79 
80  /* Calculate the LM password and hash for the users password */
81  LmPwdString.Length = 15;
82  LmPwdString.MaximumLength = 15;
83  LmPwdString.Buffer = LmPwdBuffer;
84  ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
85 
87  UserPwdData->PlainPwd,
88  FALSE);
89  if (NT_SUCCESS(Status))
90  {
91  /* Calculate the LM hash value of the users password */
92  Status = SystemFunction006(LmPwdString.Buffer,
93  (LPSTR)&UserLmPassword);
94  if (NT_SUCCESS(Status))
95  {
96  UserLmPasswordPresent = TRUE;
97  }
98  }
99 
100  /* Calculate the NT hash of the users password */
101  Status = SystemFunction007(UserPwdData->PlainPwd,
102  (LPBYTE)&UserNtPassword);
103  if (NT_SUCCESS(Status))
104  {
105  UserNtPasswordPresent = TRUE;
106  }
107 
109 
110  /* Succeed, if no password has been set */
111  if (UserInfo->All.NtPasswordPresent == FALSE &&
112  UserInfo->All.LmPasswordPresent == FALSE)
113  {
114  TRACE("No password check!\n");
116  goto done;
117  }
118 
119  /* Succeed, if NT password matches */
120  if (UserNtPasswordPresent && UserInfo->All.NtPasswordPresent)
121  {
122  TRACE("Check NT password hashes:\n");
123  if (RtlEqualMemory(&UserNtPassword,
124  UserInfo->All.NtOwfPassword.Buffer,
125  sizeof(ENCRYPTED_NT_OWF_PASSWORD)))
126  {
127  TRACE(" success!\n");
129  goto done;
130  }
131 
132  TRACE(" failed!\n");
133  }
134 
135  /* Succeed, if LM password matches */
136  if (UserLmPasswordPresent && UserInfo->All.LmPasswordPresent)
137  {
138  TRACE("Check LM password hashes:\n");
139  if (RtlEqualMemory(&UserLmPassword,
140  UserInfo->All.LmOwfPassword.Buffer,
141  sizeof(ENCRYPTED_LM_OWF_PASSWORD)))
142  {
143  TRACE(" success!\n");
145  goto done;
146  }
147  TRACE(" failed!\n");
148  }
149 
150 done:
151  return Status;
152 }
#define STATUS_WRONG_PASSWORD
Definition: ntstatus.h:342
#define TRUE
Definition: types.h:120
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
#define ZeroMemory
Definition: winbase.h:1667
NTSTATUS WINAPI SystemFunction006(LPCSTR password, LPSTR hash)
Definition: crypt_lmhash.c:53
STRING OEM_STRING
Definition: umtypes.h:203
char * LPSTR
Definition: xmlstorage.h:182
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
NTSYSAPI NTSTATUS NTAPI RtlUpcaseUnicodeStringToOemString(POEM_STRING DestinationString, PCUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS WINAPI SystemFunction007(const UNICODE_STRING *string, LPBYTE hash)
Definition: sysfunc.c:245
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by SamValidateNormalUser().

◆ MsvpCheckWorkstations()

static bool MsvpCheckWorkstations ( _In_ PRPC_UNICODE_STRING  WorkStations,
_In_ PWSTR  ComputerName 
)
static

Definition at line 195 of file sam.c.

198 {
199  PWSTR pStart, pEnd;
200  bool bFound = false;
201 
202  TRACE("MsvpCheckWorkstations(%p %S)\n", WorkStations, ComputerName);
203 
204  if (WorkStations->Length == 0 || WorkStations->Buffer == NULL)
205  {
206  TRACE("No workstations!\n");
207  return true;
208  }
209 
210  TRACE("Workstations: %wZ\n", WorkStations);
211 
212  pStart = WorkStations->Buffer;
213  for (;;)
214  {
215  pEnd = wcschr(pStart, L',');
216  if (pEnd != NULL)
217  *pEnd = UNICODE_NULL;
218 
219  TRACE("Comparing '%S' and '%S'\n", ComputerName, pStart);
220  if (_wcsicmp(ComputerName, pStart) == 0)
221  {
222  bFound = true;
223  if (pEnd != NULL)
224  *pEnd = L',';
225  break;
226  }
227 
228  if (pEnd == NULL)
229  break;
230 
231  *pEnd = L',';
232  pStart = pEnd + 1;
233  }
234 
235  TRACE("Found allowed workstation: %s\n", (bFound) ? "Yes" : "No");
236 
237  return bFound;
238 }
uint16_t * PWSTR
Definition: typedefs.h:56
#define L(x)
Definition: ntvdm.h:50
#define UNICODE_NULL
#define TRACE(s)
Definition: solgame.cpp:4
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
#define NULL
Definition: types.h:112
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)

Referenced by SamValidateNormalUser().

◆ SamValidateNormalUser()

static NTSTATUS SamValidateNormalUser ( _In_ PUNICODE_STRING  UserName,
_In_ PLSA_SAM_PWD_DATA  PwdData,
_In_ PUNICODE_STRING  ComputerName,
_Out_ PRPC_SID AccountDomainSidPtr,
_Out_ SAMPR_HANDLE UserHandlePtr,
_Out_ PSAMPR_USER_INFO_BUFFER UserInfoPtr,
_Out_ PNTSTATUS  SubStatus 
)
static

Definition at line 243 of file sam.c.

251 {
253  SAMPR_HANDLE ServerHandle = NULL;
254  SAMPR_HANDLE DomainHandle = NULL;
257  SAMPR_HANDLE UserHandle = NULL;
258  SAMPR_ULONG_ARRAY RelativeIds = {0, NULL};
259  SAMPR_ULONG_ARRAY Use = {0, NULL};
260  PSAMPR_USER_INFO_BUFFER UserInfo = NULL;
261  LARGE_INTEGER LogonTime;
262 
263  /* Get the logon time */
264  NtQuerySystemTime(&LogonTime);
265 
266  /* Get the account domain SID */
268  if (!NT_SUCCESS(Status))
269  {
270  ERR("GetAccountDomainSid() failed (Status 0x%08lx)\n", Status);
271  return Status;
272  }
273 
274  /* Connect to the SAM server */
276  if (!NT_SUCCESS(Status))
277  {
278  TRACE("SamIConnect() failed (Status 0x%08lx)\n", Status);
279  goto done;
280  }
281 
282  /* Open the account domain */
283  Status = SamrOpenDomain(ServerHandle, DOMAIN_LOOKUP, AccountDomainSid, &DomainHandle);
284  if (!NT_SUCCESS(Status))
285  {
286  ERR("SamrOpenDomain failed (Status %08lx)\n", Status);
287  goto done;
288  }
289 
290  Names[0].Length = UserName->Length;
291  Names[0].MaximumLength = UserName->MaximumLength;
292  Names[0].Buffer = UserName->Buffer;
293 
294  /* Try to get the RID for the user name */
295  Status = SamrLookupNamesInDomain(DomainHandle, 1, Names, &RelativeIds, &Use);
296  if (!NT_SUCCESS(Status))
297  {
298  ERR("SamrLookupNamesInDomain failed (Status %08lx)\n", Status);
300  // FIXME: Try without domain?
301  goto done;
302  }
303 
304  /* Fail, if it is not a user account */
305  if (Use.Element[0] != SidTypeUser)
306  {
307  ERR("Account is not a user account!\n");
309  goto done;
310  }
311 
312  /* Open the user object */
313  Status = SamrOpenUser(DomainHandle,
316  RelativeIds.Element[0],
317  &UserHandle);
318  if (!NT_SUCCESS(Status))
319  {
320  ERR("SamrOpenUser failed (Status %08lx)\n", Status);
321  goto done;
322  }
323 
324  Status = SamrQueryInformationUser(UserHandle, UserAllInformation, &UserInfo);
325  if (!NT_SUCCESS(Status))
326  {
327  ERR("SamrQueryInformationUser failed (Status %08lx)\n", Status);
328  goto done;
329  }
330 
331  TRACE("UserName: %wZ\n", &UserInfo->All.UserName);
332 
333  /* Check the password */
334  if ((UserInfo->All.UserAccountControl & USER_PASSWORD_NOT_REQUIRED) == 0)
335  {
336  Status = MsvpCheckPassword(PwdData, UserInfo);
337  if (!NT_SUCCESS(Status))
338  {
339  ERR("MsvpCheckPassword failed (Status %08lx)\n", Status);
340  goto done;
341  }
342  }
343 
344  /* Check account restrictions for non-administrator accounts */
345  if (RelativeIds.Element[0] != DOMAIN_USER_RID_ADMIN)
346  {
347  /* Check if the account has been disabled */
349  {
350  ERR("Account disabled!\n");
353  goto done;
354  }
355 
356  /* Check if the account has been locked */
358  {
359  ERR("Account locked!\n");
362  goto done;
363  }
364 
365  /* Check if the account expired */
366  if (LogonTime.QuadPart >= *(UINT64*)&UserInfo->All.AccountExpires)
367  {
368  ERR("Account expired!\n");
371  goto done;
372  }
373 
374  /* Check if the password expired */
375  if (LogonTime.QuadPart >= *(UINT64*)&UserInfo->All.PasswordMustChange)
376  {
377  ERR("Password expired!\n");
378  if (*(UINT64*)&UserInfo->All.PasswordLastSet == 0)
380  else
382 
384  goto done;
385  }
386 
387  /* Check logon hours */
388  if (!MsvpCheckLogonHours(&UserInfo->All.LogonHours, LogonTime))
389  {
390  ERR("Invalid logon hours!\n");
393  goto done;
394  }
395 
396  /* Check workstations */
397  if (!MsvpCheckWorkstations(&UserInfo->All.WorkStations, ComputerName->Buffer))
398  {
399  ERR("Invalid workstation!\n");
402  goto done;
403  }
404  }
405 done:
406  if (NT_SUCCESS(Status))
407  {
408  *UserHandlePtr = UserHandle;
409  *AccountDomainSidPtr = AccountDomainSid;
410  *UserInfoPtr = UserInfo;
411  }
412  else
413  {
414  if (AccountDomainSid != NULL)
415  RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
416 
417  if (UserHandle != NULL)
418  SamrCloseHandle(&UserHandle);
419 
422  }
423 
424  SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds);
426 
427  if (DomainHandle != NULL)
428  SamrCloseHandle(&DomainHandle);
429 
430  if (ServerHandle != NULL)
431  SamrCloseHandle(&ServerHandle);
432 
433  return Status;
434 }
unsigned long * Element
Definition: lsasrv.h:88
RPC_UNICODE_STRING UserName
Definition: msv1_0.h:86
#define SAM_SERVER_CONNECT
Definition: ntsam.h:99
#define USER_PASSWORD_NOT_REQUIRED
Definition: ntsam.h:169
NTSTATUS __stdcall SamrOpenDomain(SAMPR_HANDLE ServerHandle, ACCESS_MASK DesiredAccess, PRPC_SID DomainId, SAMPR_HANDLE *DomainHandle)
PWSTR Names[]
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
OLD_LARGE_INTEGER PasswordLastSet
Definition: msv1_0.h:82
NTSTATUS NTAPI SamrLookupNamesInDomain(IN SAMPR_HANDLE DomainHandle, IN ULONG Count, IN RPC_UNICODE_STRING Names[], OUT PSAMPR_ULONG_ARRAY RelativeIds, OUT PSAMPR_ULONG_ARRAY Use)
Definition: samrpc.c:3464
#define STATUS_ACCOUNT_LOCKED_OUT
Definition: ntstatus.h:696
#define STATUS_ACCOUNT_EXPIRED
Definition: ntstatus.h:636
SAMPR_USER_ALL_INFORMATION All
Definition: msv1_0.h:141
#define STATUS_INVALID_LOGON_HOURS
Definition: ntstatus.h:347
#define USER_ACCOUNT_DISABLED
Definition: ntsam.h:167
#define STATUS_ACCOUNT_RESTRICTION
Definition: ntstatus.h:346
NTSTATUS NTAPI SamIConnect(PSAMPR_SERVER_NAME ServerName, SAMPR_HANDLE *ServerHandle, ACCESS_MASK DesiredAccess, BOOLEAN Trusted)
#define USER_READ_GENERAL
Definition: ntsam.h:126
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE _Out_ PQUOTA_LIMITS _Out_ PNTSTATUS SubStatus
#define DOMAIN_USER_RID_ADMIN
Definition: setypes.h:631
static bool MsvpCheckWorkstations(_In_ PRPC_UNICODE_STRING WorkStations, _In_ PWSTR ComputerName)
Definition: sam.c:195
#define SAM_SERVER_LOOKUP_DOMAIN
Definition: ntsam.h:104
static NTSTATUS MsvpCheckPassword(_In_ PLSA_SAM_PWD_DATA UserPwdData, _In_ PSAMPR_USER_INFO_BUFFER UserInfo)
Definition: sam.c:66
OLD_LARGE_INTEGER AccountExpires
Definition: msv1_0.h:83
static NTSTATUS GetAccountDomainSid(_In_ PRPC_SID *Sid)
Definition: sam.c:16
Status
Definition: gdiplustypes.h:24
#define STATUS_NO_SUCH_USER
Definition: ntstatus.h:336
#define STATUS_ACCOUNT_DISABLED
Definition: ntstatus.h:350
OLD_LARGE_INTEGER PasswordMustChange
Definition: msv1_0.h:85
#define TRACE(s)
Definition: solgame.cpp:4
#define STATUS_PASSWORD_EXPIRED
Definition: ntstatus.h:349
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define USER_READ_ACCOUNT
Definition: ntsam.h:130
SAMPR_LOGON_HOURS LogonHours
Definition: msv1_0.h:104
#define USER_ACCOUNT_AUTO_LOCKED
Definition: ntsam.h:177
VOID NTAPI SamIFree_SAMPR_USER_INFO_BUFFER(PSAMPR_USER_INFO_BUFFER Ptr, USER_INFORMATION_CLASS InformationClass)
Definition: samsrv.c:540
#define ERR(fmt,...)
Definition: debug.h:110
VOID NTAPI SamIFree_SAMPR_ULONG_ARRAY(PSAMPR_ULONG_ARRAY Ptr)
Definition: samsrv.c:524
#define STATUS_INVALID_WORKSTATION
Definition: ntstatus.h:348
#define STATUS_PASSWORD_MUST_CHANGE
Definition: ntstatus.h:680
static bool MsvpCheckLogonHours(_In_ PSAMPR_LOGON_HOURS LogonHours, _In_ LARGE_INTEGER LogonTime)
Definition: sam.c:157
unsigned long UserAccountControl
Definition: msv1_0.h:102
NTSTATUS __stdcall SamrCloseHandle(SAMPR_HANDLE *SamHandle)
#define NULL
Definition: types.h:112
NTSTATUS NTAPI SamrOpenUser(IN SAMPR_HANDLE DomainHandle, IN ACCESS_MASK DesiredAccess, IN ULONG UserId, OUT SAMPR_HANDLE *UserHandle)
#define USER_READ_PREFERENCES
Definition: ntsam.h:127
#define DOMAIN_LOOKUP
Definition: ntsam.h:42
NTSTATUS NTAPI NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
Definition: time.c:472
PSID AccountDomainSid
Definition: database.c:24
NTSTATUS NTAPI SamrQueryInformationUser(IN SAMPR_HANDLE UserHandle, IN USER_INFORMATION_CLASS UserInformationClass, OUT PSAMPR_USER_INFO_BUFFER *Buffer)
Definition: samrpc.c:7234
unsigned long long UINT64
#define USER_READ_LOGON
Definition: ntsam.h:129
RPC_UNICODE_STRING WorkStations
Definition: msv1_0.h:93
LONGLONG QuadPart
Definition: typedefs.h:114
wchar_t * Buffer
Definition: msv1_0.h:24

Referenced by SamValidateUser().

◆ SamValidateUser()

NTSTATUS SamValidateUser ( _In_ SECURITY_LOGON_TYPE  LogonType,
_In_ PUNICODE_STRING  LogonUserName,
_In_ PUNICODE_STRING  LogonDomain,
_In_ PLSA_SAM_PWD_DATA  LogonPwdData,
_In_ PUNICODE_STRING  ComputerName,
_Out_ PBOOL  SpecialAccount,
_Out_ PRPC_SID AccountDomainSidPtr,
_Out_ SAMPR_HANDLE UserHandlePtr,
_Out_ PSAMPR_USER_INFO_BUFFER UserInfoPtr,
_Out_ PNTSTATUS  SubStatus 
)

Validates a user by checking if it exists in the sam database. Some other checks are done further.

Definition at line 460 of file sam.c.

471 {
472  static const UNICODE_STRING NtAuthorityU = RTL_CONSTANT_STRING(L"NT AUTHORITY");
473  static const UNICODE_STRING LocalServiceU = RTL_CONSTANT_STRING(L"LocalService");
474  static const UNICODE_STRING NetworkServiceU = RTL_CONSTANT_STRING(L"NetworkService");
475 
477 
478  *SpecialAccount = FALSE;
479  *UserInfoPtr = NULL;
481 
482  /* Check for special accounts */
483  // FIXME: Windows does not do this that way!! (msv1_0 does not contain these hardcoded values)
484  if (RtlEqualUnicodeString(LogonDomain, &NtAuthorityU, TRUE))
485  {
486  *SpecialAccount = TRUE;
487 
488  /* Get the authority domain SID */
489  Status = GetNtAuthorityDomainSid(AccountDomainSidPtr);
490  if (!NT_SUCCESS(Status))
491  {
492  ERR("GetNtAuthorityDomainSid() failed (Status 0x%08lx)\n", Status);
493  return Status;
494  }
495 
496  if (RtlEqualUnicodeString(LogonUserName, &LocalServiceU, TRUE))
497  {
498  TRACE("SpecialAccount: LocalService\n");
499 
500  if (LogonType != Service)
501  return STATUS_LOGON_FAILURE;
502 
503  *UserInfoPtr = RtlAllocateHeap(RtlGetProcessHeap(),
506  if (*UserInfoPtr == NULL)
508 
509  (*UserInfoPtr)->All.UserId = SECURITY_LOCAL_SERVICE_RID;
510  (*UserInfoPtr)->All.PrimaryGroupId = SECURITY_LOCAL_SERVICE_RID;
511  }
512  else if (RtlEqualUnicodeString(LogonUserName, &NetworkServiceU, TRUE))
513  {
514  TRACE("SpecialAccount: NetworkService\n");
515 
516  if (LogonType != Service)
517  return STATUS_LOGON_FAILURE;
518 
519  *UserInfoPtr = RtlAllocateHeap(RtlGetProcessHeap(),
522  if (*UserInfoPtr == NULL)
524 
525  (*UserInfoPtr)->All.UserId = SECURITY_NETWORK_SERVICE_RID;
526  (*UserInfoPtr)->All.PrimaryGroupId = SECURITY_NETWORK_SERVICE_RID;
527  }
528  else
529  {
530  return STATUS_NO_SUCH_USER;
531  }
532  }
533  else
534  {
535  TRACE("NormalAccount\n");
536  Status = SamValidateNormalUser(LogonUserName,
537  LogonPwdData,
538  ComputerName,
539  AccountDomainSidPtr,
540  UserHandlePtr,
541  UserInfoPtr,
542  SubStatus);
543  if (!NT_SUCCESS(Status))
544  {
545  ERR("SamValidateNormalUser() failed (Status 0x%08lx)\n", Status);
546  return Status;
547  }
548  }
549 
550  return Status;
551 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE _Out_ PQUOTA_LIMITS _Out_ PNTSTATUS SubStatus
static NTSTATUS SamValidateNormalUser(_In_ PUNICODE_STRING UserName, _In_ PLSA_SAM_PWD_DATA PwdData, _In_ PUNICODE_STRING ComputerName, _Out_ PRPC_SID *AccountDomainSidPtr, _Out_ SAMPR_HANDLE *UserHandlePtr, _Out_ PSAMPR_USER_INFO_BUFFER *UserInfoPtr, _Out_ PNTSTATUS SubStatus)
Definition: sam.c:243
#define SECURITY_LOCAL_SERVICE_RID
Definition: setypes.h:575
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
#define STATUS_NO_SUCH_USER
Definition: ntstatus.h:336
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SECURITY_NETWORK_SERVICE_RID
Definition: setypes.h:576
#define ERR(fmt,...)
Definition: debug.h:110
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE LogonType
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static NTSTATUS GetNtAuthorityDomainSid(_In_ PRPC_SID *Sid)
Definition: sam.c:439
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define STATUS_LOGON_FAILURE
Definition: ntstatus.h:345
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by LsaApLogonUserEx2(), and LsaApLogonUserEx2_Network().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msv1_0_sam  )