ReactOS  0.4.13-dev-235-g7373cb3
user.c
Go to the documentation of this file.
1 /*
2  * Copyright 2002 Andriy Palamarchuk
3  *
4  * netapi32 user functions
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 /*
22  * TODO:
23  * Implement NetUserGetGroups (WIP)
24  * Implement NetUserSetGroups
25  * NetUserGetLocalGroups does not support LG_INCLUDE_INDIRECT yet.
26  * Add missing information levels.
27  * ...
28  */
29 
30 #include "netapi32.h"
31 
32 #include <ndk/kefuncs.h>
33 #include <ndk/obfuncs.h>
34 
36 
37 typedef struct _ENUM_CONTEXT
38 {
41 
47 
51  ULONG Index;
53 
55 
59 
60 static
61 ULONG
63 {
64  LARGE_INTEGER Seconds;
65 
66  if (DeltaTime.QuadPart == 0)
67  return 0;
68 
69  Seconds.QuadPart = -DeltaTime.QuadPart / 10000000;
70 
71  if (Seconds.HighPart != 0)
72  return TIMEQ_FOREVER;
73 
74  return Seconds.LowPart;
75 }
76 
77 
78 static
82 {
84  ULONG WorldSid[sizeof(SID) / sizeof(ULONG) + SID_MAX_SUB_AUTHORITIES];
85  ACL_SIZE_INFORMATION AclSize;
86  PVOID LocalAce = NULL;
87  ULONG i;
89 
90  *Ace = NULL;
91 
94  1);
96 
98  &AclSize,
99  sizeof(AclSize),
101  if (!NT_SUCCESS(Status))
102  return Status;
103 
104  for (i = 0; i < AclSize.AceCount; i++)
105  {
106  Status = RtlGetAce(Acl, i, &LocalAce);
107  if (!NT_SUCCESS(Status))
108  return Status;
109 
110  if (((PACE_HEADER)LocalAce)->AceType != ACCESS_ALLOWED_ACE_TYPE)
111  continue;
112 
114  (PSID)&((PACCESS_ALLOWED_ACE)LocalAce)->SidStart))
115  {
116  *Ace = (PACCESS_ALLOWED_ACE)LocalAce;
117  return STATUS_SUCCESS;
118  }
119  }
120 
121  return STATUS_SUCCESS;
122 }
123 
124 
125 static
126 ULONG
127 GetAccountFlags(ULONG AccountControl,
128  PACL Dacl)
129 {
133 
134  if (Dacl != NULL)
135  {
137  if (NT_SUCCESS(Status))
138  {
139  if (Ace == NULL)
140  {
142  }
143  else if ((Ace->Mask & USER_CHANGE_PASSWORD) == 0)
144  {
146  }
147  }
148  }
149 
150  if (AccountControl & USER_ACCOUNT_DISABLED)
152 
153  if (AccountControl & USER_HOME_DIRECTORY_REQUIRED)
155 
156  if (AccountControl & USER_PASSWORD_NOT_REQUIRED)
158 
159  if (AccountControl & USER_ACCOUNT_AUTO_LOCKED)
160  Flags |= UF_LOCKOUT;
161 
162  if (AccountControl & USER_DONT_EXPIRE_PASSWORD)
164 
165 /*
166  if (AccountControl & USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED)
167  Flags |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED;
168 
169  if (AccountControl & USER_SMARTCARD_REQUIRED)
170  Flags |= UF_SMARTCARD_REQUIRED;
171 
172  if (AccountControl & USER_TRUSTED_FOR_DELEGATION)
173  Flags |= UF_TRUSTED_FOR_DELEGATION;
174 
175  if (AccountControl & USER_NOT_DELEGATED)
176  Flags |= UF_NOT_DELEGATED;
177 
178  if (AccountControl & USER_USE_DES_KEY_ONLY)
179  Flags |= UF_USE_DES_KEY_ONLY;
180 
181  if (AccountControl & USER_DONT_REQUIRE_PREAUTH)
182  Flags |= UF_DONT_REQUIRE_PREAUTH;
183 
184  if (AccountControl & USER_PASSWORD_EXPIRED)
185  Flags |= UF_PASSWORD_EXPIRED;
186 */
187 
188  /* Set account type flags */
189  if (AccountControl & USER_TEMP_DUPLICATE_ACCOUNT)
191  else if (AccountControl & USER_NORMAL_ACCOUNT)
193  else if (AccountControl & USER_INTERDOMAIN_TRUST_ACCOUNT)
195  else if (AccountControl & USER_WORKSTATION_TRUST_ACCOUNT)
197  else if (AccountControl & USER_SERVER_TRUST_ACCOUNT)
199 
200  return Flags;
201 }
202 
203 
204 static
205 ULONG
207 {
208  ULONG AccountControl = 0;
209 
210  if (Flags & UF_ACCOUNTDISABLE)
211  AccountControl |= USER_ACCOUNT_DISABLED;
212 
214  AccountControl |= USER_HOME_DIRECTORY_REQUIRED;
215 
216  if (Flags & UF_PASSWD_NOTREQD)
217  AccountControl |= USER_PASSWORD_NOT_REQUIRED;
218 
219  if (Flags & UF_LOCKOUT)
220  AccountControl |= USER_ACCOUNT_AUTO_LOCKED;
221 
223  AccountControl |= USER_DONT_EXPIRE_PASSWORD;
224 
225  /* Set account type flags */
227  AccountControl |= USER_TEMP_DUPLICATE_ACCOUNT;
228  else if (Flags & UF_NORMAL_ACCOUNT)
229  AccountControl |= USER_NORMAL_ACCOUNT;
231  AccountControl |= USER_INTERDOMAIN_TRUST_ACCOUNT;
233  AccountControl |= USER_WORKSTATION_TRUST_ACCOUNT;
234  else if (Flags & UF_SERVER_TRUST_ACCOUNT)
235  AccountControl |= USER_SERVER_TRUST_ACCOUNT;
236 
237  return AccountControl;
238 }
239 
240 
241 static
242 DWORD
244 {
245  LARGE_INTEGER SystemTime;
246  ULONG SystemSecondsSince1970;
247  ULONG PasswordSecondsSince1970;
249 
250  Status = NtQuerySystemTime(&SystemTime);
251  if (!NT_SUCCESS(Status))
252  return 0;
253 
254  RtlTimeToSecondsSince1970(&SystemTime, &SystemSecondsSince1970);
255  RtlTimeToSecondsSince1970(PasswordLastSet, &PasswordSecondsSince1970);
256 
257  return SystemSecondsSince1970 - PasswordSecondsSince1970;
258 }
259 
260 
261 static
262 VOID
264  IN ULONG Flags)
265 {
268 
269  if (Dacl == NULL)
270  return;
271 
273  if (!NT_SUCCESS(Status))
274  return;
275 
277  Ace->Mask &= ~USER_CHANGE_PASSWORD;
278  else
279  Ace->Mask |= USER_CHANGE_PASSWORD;
280 }
281 
282 
283 static
286  OUT PACL *Dacl)
287 {
289  PACL SamDacl;
290  PACL LocalDacl;
291  BOOLEAN Defaulted;
292  BOOLEAN Present;
293  ACL_SIZE_INFORMATION AclSize;
294  NET_API_STATUS ApiStatus;
296 
297  TRACE("(%p %p)\n", UserHandle, Dacl);
298 
299  *Dacl = NULL;
300 
301  Status = SamQuerySecurityObject(UserHandle,
304  if (!NT_SUCCESS(Status))
305  {
306  TRACE("SamQuerySecurityObject() failed (Status 0x%08lx)\n", Status);
307  ApiStatus = NetpNtStatusToApiStatus(Status);
308  goto done;
309  }
310 
312  &Present,
313  &SamDacl,
314  &Defaulted);
315  if (!NT_SUCCESS(Status))
316  {
317  TRACE("RtlGetDaclSecurityDescriptor() failed (Status 0x%08lx)\n", Status);
318  ApiStatus = NERR_InternalError;
319  goto done;
320  }
321 
322  if (Present == FALSE)
323  {
324  TRACE("No DACL present\n");
325  ApiStatus = NERR_Success;
326  goto done;
327  }
328 
329  Status = RtlQueryInformationAcl(SamDacl,
330  &AclSize,
331  sizeof(AclSize),
333  if (!NT_SUCCESS(Status))
334  {
335  TRACE("RtlQueryInformationAcl() failed (Status 0x%08lx)\n", Status);
336  ApiStatus = NERR_InternalError;
337  goto done;
338  }
339 
340  LocalDacl = HeapAlloc(GetProcessHeap(), 0, AclSize.AclBytesInUse);
341  if (LocalDacl == NULL)
342  {
343  TRACE("Memory allocation failed\n");
344  ApiStatus = ERROR_NOT_ENOUGH_MEMORY;
345  goto done;
346  }
347 
348  RtlCopyMemory(LocalDacl, SamDacl, AclSize.AclBytesInUse);
349 
350  *Dacl = LocalDacl;
351 
352  ApiStatus = NERR_Success;
353 
354 done:
355  if (SecurityDescriptor != NULL)
357 
358  TRACE("done (ApiStatus: 0x%08lx)\n", ApiStatus);
359 
360  return ApiStatus;
361 }
362 
363 
364 static
365 VOID
367 {
368  if (UserInfo->UserName.Buffer != NULL)
369  SamFreeMemory(UserInfo->UserName.Buffer);
370 
371  if (UserInfo->FullName.Buffer != NULL)
372  SamFreeMemory(UserInfo->FullName.Buffer);
373 
374  if (UserInfo->HomeDirectory.Buffer != NULL)
376 
377  if (UserInfo->HomeDirectoryDrive.Buffer != NULL)
379 
380  if (UserInfo->ScriptPath.Buffer != NULL)
381  SamFreeMemory(UserInfo->ScriptPath.Buffer);
382 
383  if (UserInfo->ProfilePath.Buffer != NULL)
384  SamFreeMemory(UserInfo->ProfilePath.Buffer);
385 
386  if (UserInfo->AdminComment.Buffer != NULL)
387  SamFreeMemory(UserInfo->AdminComment.Buffer);
388 
389  if (UserInfo->WorkStations.Buffer != NULL)
390  SamFreeMemory(UserInfo->WorkStations.Buffer);
391 
392  if (UserInfo->UserComment.Buffer != NULL)
393  SamFreeMemory(UserInfo->UserComment.Buffer);
394 
395  if (UserInfo->Parameters.Buffer != NULL)
396  SamFreeMemory(UserInfo->Parameters.Buffer);
397 
398  if (UserInfo->PrivateData.Buffer != NULL)
399  SamFreeMemory(UserInfo->PrivateData.Buffer);
400 
401  if (UserInfo->LogonHours.LogonHours != NULL)
403 
404  SamFreeMemory(UserInfo);
405 }
406 
407 
408 static
411  _In_ SAM_HANDLE BuiltinDomainHandle,
412  _In_ SAM_HANDLE UserHandle,
414  _In_ ULONG RelativeId,
415  _Out_ PDWORD Priv,
416  _Out_ PDWORD AuthFlags)
417 {
418  PGROUP_MEMBERSHIP GroupMembership = NULL;
419  ULONG GroupCount, SidCount, AliasCount, i;
420  PSID *SidArray = NULL;
421  PULONG AliasArray = NULL;
422  BOOL bAdmin = FALSE, bUser = FALSE;
423  NET_API_STATUS ApiStatus = NERR_Success;
425 
426  FIXME("GetUserPrivileges(%p)\n", UserHandle);
427 
428  /* Get the users group memberships */
429  Status = SamGetGroupsForUser(UserHandle,
430  &GroupMembership,
431  &GroupCount);
432  if (!NT_SUCCESS(Status))
433  {
434  ERR("SamGetGroupsForUser() failed (Status 0x%08lx)\n", Status);
435  ApiStatus = NetpNtStatusToApiStatus(Status);
436  goto done;
437  }
438 
439  /* Allocate the SID array */
440  ApiStatus = NetApiBufferAllocate((GroupCount + 1) * sizeof(PSID),
441  (PVOID*)&SidArray);
442  if (ApiStatus != NERR_Success)
443  {
444  goto done;
445  }
446 
447  /* Add the user to the SID array */
448  SidCount = 0;
450  RelativeId,
451  &SidArray[0]);
452  if (ApiStatus != NERR_Success)
453  {
454  goto done;
455  }
456 
457  SidCount++;
458 
459  /* Add the groups to the SID array */
460  for (i = 0; i < GroupCount; i++)
461  {
463  GroupMembership[i].RelativeId,
464  &SidArray[i + 1]);
465  if (ApiStatus != NERR_Success)
466  {
467  goto done;
468  }
469 
470  SidCount++;
471  }
472 
473  /* Get aliases for the user and his groups */
474  Status = SamGetAliasMembership(BuiltinDomainHandle,
475  SidCount,
476  SidArray,
477  &AliasCount,
478  &AliasArray);
479  if (!NT_SUCCESS(Status))
480  {
481  ERR("SamGetAliasMembership() failed (Status 0x%08lx)\n", Status);
482  ApiStatus = NetpNtStatusToApiStatus(Status);
483  goto done;
484  }
485 
486  *AuthFlags = 0;
487 
488  /* Set the AuthFlags */
489  for (i = 0; i < AliasCount; i++)
490  {
491  switch (AliasArray[i])
492  {
494  bAdmin = TRUE;
495  break;
496 
498  bUser = TRUE;
499  break;
500 
502  *AuthFlags |= AF_OP_ACCOUNTS;
503  break;
504 
506  *AuthFlags |= AF_OP_SERVER;
507  break;
508 
510  *AuthFlags |= AF_OP_PRINT;
511  break;
512  }
513  }
514 
515  /* Set the prvileges */
516  if (bAdmin)
517  {
518  *Priv = USER_PRIV_ADMIN;
519  }
520  else if (bUser)
521  {
522  *Priv = USER_PRIV_USER;
523  }
524  else
525  {
526  *Priv = USER_PRIV_GUEST;
527  }
528 
529 done:
530  if (AliasArray != NULL)
531  SamFreeMemory(AliasArray);
532 
533  if (SidArray != NULL)
534  {
535  for (i = 0; i < SidCount; i++)
536  NetApiBufferFree(SidArray[i]);
537 
538  NetApiBufferFree(SidArray);
539  }
540 
541  if (GroupMembership != NULL)
542  SamFreeMemory(GroupMembership);
543 
544  return ApiStatus;
545 }
546 
547 
548 static
551  _In_ SAM_HANDLE BuiltinDomainHandle,
552  _In_ SAM_HANDLE UserHandle,
554  _In_ ULONG RelativeId,
555  _In_ DWORD level,
557 {
558  UNICODE_STRING LogonServer = RTL_CONSTANT_STRING(L"\\\\*");
559  PUSER_ALL_INFORMATION UserInfo = NULL;
560  LPVOID LocalBuffer = NULL;
561  PACL Dacl = NULL;
562  DWORD Priv = 0, AuthFlags = 0;
563  PUSER_INFO_0 UserInfo0;
564  PUSER_INFO_1 UserInfo1;
565  PUSER_INFO_2 UserInfo2;
566  PUSER_INFO_3 UserInfo3;
567  PUSER_INFO_4 UserInfo4;
568  PUSER_INFO_10 UserInfo10;
569  PUSER_INFO_11 UserInfo11;
570  PUSER_INFO_20 UserInfo20;
571  PUSER_INFO_23 UserInfo23;
572  LPWSTR Ptr;
573  ULONG Size = 0;
575  NET_API_STATUS ApiStatus = NERR_Success;
576 
577  *Buffer = NULL;
578 
579  Status = SamQueryInformationUser(UserHandle,
581  (PVOID *)&UserInfo);
582  if (!NT_SUCCESS(Status))
583  {
584  ERR("SamQueryInformationUser failed (Status %08lx)\n", Status);
585  ApiStatus = NetpNtStatusToApiStatus(Status);
586  goto done;
587  }
588 
589  if ((level == 1) || (level == 2) || (level == 3) ||
590  (level == 4) || (level == 20) || (level == 23))
591  {
592  ApiStatus = GetUserDacl(UserHandle, &Dacl);
593  if (ApiStatus != NERR_Success)
594  goto done;
595  }
596 
597  if ((level == 1) || (level == 2) || (level == 3) ||
598  (level == 4) || (level == 11))
599  {
600  ApiStatus = GetUserPrivileges(BuiltinDomainHandle,
601  UserHandle,
603  RelativeId,
604  &Priv,
605  &AuthFlags);
606  if (ApiStatus != NERR_Success)
607  goto done;
608  }
609 
610  switch (level)
611  {
612  case 0:
613  Size = sizeof(USER_INFO_0) +
614  UserInfo->UserName.Length + sizeof(WCHAR);
615  break;
616 
617  case 1:
618  Size = sizeof(USER_INFO_1) +
619  UserInfo->UserName.Length + sizeof(WCHAR) +
620  UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
621  UserInfo->AdminComment.Length + sizeof(WCHAR) +
622  UserInfo->ScriptPath.Length + sizeof(WCHAR);
623  break;
624 
625  case 2:
626  Size = sizeof(USER_INFO_2) +
627  UserInfo->UserName.Length + sizeof(WCHAR) +
628  UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
629  UserInfo->AdminComment.Length + sizeof(WCHAR) +
630  UserInfo->ScriptPath.Length + sizeof(WCHAR) +
631  UserInfo->FullName.Length + sizeof(WCHAR) +
632  UserInfo->UserComment.Length + sizeof(WCHAR) +
633  UserInfo->Parameters.Length + sizeof(WCHAR) +
634  UserInfo->WorkStations.Length + sizeof(WCHAR) +
635  LogonServer.Length + sizeof(WCHAR);
636 
637  if (UserInfo->LogonHours.UnitsPerWeek > 0)
638  Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
639  break;
640 
641  case 3:
642  Size = sizeof(USER_INFO_3) +
643  UserInfo->UserName.Length + sizeof(WCHAR) +
644  UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
645  UserInfo->AdminComment.Length + sizeof(WCHAR) +
646  UserInfo->ScriptPath.Length + sizeof(WCHAR) +
647  UserInfo->FullName.Length + sizeof(WCHAR) +
648  UserInfo->UserComment.Length + sizeof(WCHAR) +
649  UserInfo->Parameters.Length + sizeof(WCHAR) +
650  UserInfo->WorkStations.Length + sizeof(WCHAR) +
651  LogonServer.Length + sizeof(WCHAR) +
652  UserInfo->ProfilePath.Length + sizeof(WCHAR) +
653  UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR);
654 
655  if (UserInfo->LogonHours.UnitsPerWeek > 0)
656  Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
657  break;
658 
659  case 4:
660  Size = sizeof(USER_INFO_4) +
661  UserInfo->UserName.Length + sizeof(WCHAR) +
662  UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
663  UserInfo->AdminComment.Length + sizeof(WCHAR) +
664  UserInfo->ScriptPath.Length + sizeof(WCHAR) +
665  UserInfo->FullName.Length + sizeof(WCHAR) +
666  UserInfo->UserComment.Length + sizeof(WCHAR) +
667  UserInfo->Parameters.Length + sizeof(WCHAR) +
668  UserInfo->WorkStations.Length + sizeof(WCHAR) +
669  LogonServer.Length + sizeof(WCHAR) +
670  UserInfo->ProfilePath.Length + sizeof(WCHAR) +
671  UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR);
672 
673  if (UserInfo->LogonHours.UnitsPerWeek > 0)
674  Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
675 
676  Size += RtlLengthSid(AccountDomainSid) + sizeof(ULONG);
677  break;
678 
679  case 10:
680  Size = sizeof(USER_INFO_10) +
681  UserInfo->UserName.Length + sizeof(WCHAR) +
682  UserInfo->AdminComment.Length + sizeof(WCHAR) +
683  UserInfo->UserComment.Length + sizeof(WCHAR) +
684  UserInfo->FullName.Length + sizeof(WCHAR);
685  break;
686 
687  case 11:
688  Size = sizeof(USER_INFO_11) +
689  UserInfo->UserName.Length + sizeof(WCHAR) +
690  UserInfo->AdminComment.Length + sizeof(WCHAR) +
691  UserInfo->UserComment.Length + sizeof(WCHAR) +
692  UserInfo->FullName.Length + sizeof(WCHAR) +
693  UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
694  UserInfo->Parameters.Length + sizeof(WCHAR) +
695  LogonServer.Length + sizeof(WCHAR) +
696  UserInfo->WorkStations.Length + sizeof(WCHAR);
697 
698  if (UserInfo->LogonHours.UnitsPerWeek > 0)
699  Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
700  break;
701 
702  case 20:
703  Size = sizeof(USER_INFO_20) +
704  UserInfo->UserName.Length + sizeof(WCHAR) +
705  UserInfo->FullName.Length + sizeof(WCHAR) +
706  UserInfo->AdminComment.Length + sizeof(WCHAR);
707  break;
708 
709  case 23:
710  Size = sizeof(USER_INFO_23) +
711  UserInfo->UserName.Length + sizeof(WCHAR) +
712  UserInfo->FullName.Length + sizeof(WCHAR) +
713  UserInfo->AdminComment.Length + sizeof(WCHAR);
714 
715  Size += RtlLengthSid(AccountDomainSid) + sizeof(ULONG);
716  break;
717 
718  default:
719  ApiStatus = ERROR_INVALID_LEVEL;
720  goto done;
721  }
722 
723  ApiStatus = NetApiBufferAllocate(Size, &LocalBuffer);
724  if (ApiStatus != NERR_Success)
725  goto done;
726 
727  ZeroMemory(LocalBuffer, Size);
728 
729  switch (level)
730  {
731  case 0:
732  UserInfo0 = (PUSER_INFO_0)LocalBuffer;
733 
734  Ptr = (LPWSTR)((ULONG_PTR)UserInfo0 + sizeof(USER_INFO_0));
735 
736  UserInfo0->usri0_name = Ptr;
737 
738  memcpy(UserInfo0->usri0_name,
739  UserInfo->UserName.Buffer,
740  UserInfo->UserName.Length);
741  UserInfo0->usri0_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
742  break;
743 
744  case 1:
745  UserInfo1 = (PUSER_INFO_1)LocalBuffer;
746 
747  Ptr = (LPWSTR)((ULONG_PTR)UserInfo1 + sizeof(USER_INFO_1));
748 
749  UserInfo1->usri1_name = Ptr;
750 
751  memcpy(UserInfo1->usri1_name,
752  UserInfo->UserName.Buffer,
753  UserInfo->UserName.Length);
754  UserInfo1->usri1_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
755 
756  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
757 
758  UserInfo1->usri1_password = NULL;
759  UserInfo1->usri1_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
760 
761  UserInfo1->usri1_priv = Priv;
762 
763  UserInfo1->usri1_home_dir = Ptr;
764  memcpy(UserInfo1->usri1_home_dir,
765  UserInfo->HomeDirectory.Buffer,
766  UserInfo->HomeDirectory.Length);
767  UserInfo1->usri1_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
768  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
769 
770  UserInfo1->usri1_comment = Ptr;
771  memcpy(UserInfo1->usri1_comment,
772  UserInfo->AdminComment.Buffer,
773  UserInfo->AdminComment.Length);
774  UserInfo1->usri1_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
775  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
776 
777  UserInfo1->usri1_flags = GetAccountFlags(UserInfo->UserAccountControl,
778  Dacl);
779 
780  UserInfo1->usri1_script_path = Ptr;
781  memcpy(UserInfo1->usri1_script_path,
782  UserInfo->ScriptPath.Buffer,
783  UserInfo->ScriptPath.Length);
784  UserInfo1->usri1_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
785  break;
786 
787  case 2:
788  UserInfo2 = (PUSER_INFO_2)LocalBuffer;
789 
790  Ptr = (LPWSTR)((ULONG_PTR)UserInfo2 + sizeof(USER_INFO_2));
791 
792  UserInfo2->usri2_name = Ptr;
793 
794  memcpy(UserInfo2->usri2_name,
795  UserInfo->UserName.Buffer,
796  UserInfo->UserName.Length);
797  UserInfo2->usri2_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
798 
799  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
800 
801  UserInfo2->usri2_password = NULL;
802  UserInfo2->usri2_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
803 
804  UserInfo2->usri2_priv = Priv;
805 
806  UserInfo2->usri2_home_dir = Ptr;
807  memcpy(UserInfo2->usri2_home_dir,
808  UserInfo->HomeDirectory.Buffer,
809  UserInfo->HomeDirectory.Length);
810  UserInfo2->usri2_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
811  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
812 
813  UserInfo2->usri2_comment = Ptr;
814  memcpy(UserInfo2->usri2_comment,
815  UserInfo->AdminComment.Buffer,
816  UserInfo->AdminComment.Length);
817  UserInfo2->usri2_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
818  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
819 
820  UserInfo2->usri2_flags = GetAccountFlags(UserInfo->UserAccountControl,
821  Dacl);
822 
823  UserInfo2->usri2_script_path = Ptr;
824  memcpy(UserInfo2->usri2_script_path,
825  UserInfo->ScriptPath.Buffer,
826  UserInfo->ScriptPath.Length);
827  UserInfo2->usri2_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
828  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
829 
830  UserInfo2->usri2_auth_flags = AuthFlags;
831 
832  UserInfo2->usri2_full_name = Ptr;
833  memcpy(UserInfo2->usri2_full_name,
834  UserInfo->FullName.Buffer,
835  UserInfo->FullName.Length);
836  UserInfo2->usri2_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
837  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
838 
839  UserInfo2->usri2_usr_comment = Ptr;
840  memcpy(UserInfo2->usri2_usr_comment,
841  UserInfo->UserComment.Buffer,
842  UserInfo->UserComment.Length);
843  UserInfo2->usri2_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
844  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
845 
846  UserInfo2->usri2_parms = Ptr;
847  memcpy(UserInfo2->usri2_parms,
848  UserInfo->Parameters.Buffer,
849  UserInfo->Parameters.Length);
850  UserInfo2->usri2_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
851  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
852 
853  UserInfo2->usri2_workstations = Ptr;
854  memcpy(UserInfo2->usri2_workstations,
855  UserInfo->WorkStations.Buffer,
856  UserInfo->WorkStations.Length);
857  UserInfo2->usri2_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
858  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
859 
860  if (UserInfo->LastLogon.QuadPart == 0)
861  UserInfo2->usri2_last_logon = 0;
862  else
863  RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
864  &UserInfo2->usri2_last_logon);
865 
866  if (UserInfo->LastLogoff.QuadPart == 0)
867  UserInfo2->usri2_last_logoff = 0;
868  else
869  RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
870  &UserInfo2->usri2_last_logoff);
871 
872  if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG)
873  UserInfo2->usri2_acct_expires = TIMEQ_FOREVER;
874  else
875  RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
876  &UserInfo2->usri2_acct_expires);
877 
879  UserInfo2->usri2_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
880 
881  if (UserInfo->LogonHours.UnitsPerWeek > 0)
882  {
883  UserInfo2->usri2_logon_hours = (PVOID)Ptr;
884 
885  memcpy(UserInfo2->usri2_logon_hours,
886  UserInfo->LogonHours.LogonHours,
887  (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
888 
889  Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
890  }
891 
892  UserInfo2->usri2_bad_pw_count = UserInfo->BadPasswordCount;
893  UserInfo2->usri2_num_logons = UserInfo->LogonCount;
894 
895  UserInfo2->usri2_logon_server = Ptr;
896  memcpy(UserInfo2->usri2_logon_server,
897  LogonServer.Buffer,
898  LogonServer.Length);
899  UserInfo2->usri2_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
900  Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
901 
902  UserInfo2->usri2_country_code = UserInfo->CountryCode;
903  UserInfo2->usri2_code_page = UserInfo->CodePage;
904  break;
905 
906  case 3:
907  UserInfo3 = (PUSER_INFO_3)LocalBuffer;
908 
909  Ptr = (LPWSTR)((ULONG_PTR)UserInfo3 + sizeof(USER_INFO_3));
910 
911  UserInfo3->usri3_name = Ptr;
912 
913  memcpy(UserInfo3->usri3_name,
914  UserInfo->UserName.Buffer,
915  UserInfo->UserName.Length);
916  UserInfo3->usri3_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
917 
918  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
919 
920  UserInfo3->usri3_password = NULL;
921  UserInfo3->usri3_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
922 
923  UserInfo3->usri3_priv = Priv;
924 
925  UserInfo3->usri3_home_dir = Ptr;
926  memcpy(UserInfo3->usri3_home_dir,
927  UserInfo->HomeDirectory.Buffer,
928  UserInfo->HomeDirectory.Length);
929  UserInfo3->usri3_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
930  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
931 
932  UserInfo3->usri3_comment = Ptr;
933  memcpy(UserInfo3->usri3_comment,
934  UserInfo->AdminComment.Buffer,
935  UserInfo->AdminComment.Length);
936  UserInfo3->usri3_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
937  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
938 
939  UserInfo3->usri3_flags = GetAccountFlags(UserInfo->UserAccountControl,
940  Dacl);
941 
942  UserInfo3->usri3_script_path = Ptr;
943  memcpy(UserInfo3->usri3_script_path,
944  UserInfo->ScriptPath.Buffer,
945  UserInfo->ScriptPath.Length);
946  UserInfo3->usri3_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
947  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
948 
949  UserInfo3->usri3_auth_flags = AuthFlags;
950 
951  UserInfo3->usri3_full_name = Ptr;
952  memcpy(UserInfo3->usri3_full_name,
953  UserInfo->FullName.Buffer,
954  UserInfo->FullName.Length);
955  UserInfo3->usri3_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
956  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
957 
958  UserInfo3->usri3_usr_comment = Ptr;
959  memcpy(UserInfo3->usri3_usr_comment,
960  UserInfo->UserComment.Buffer,
961  UserInfo->UserComment.Length);
962  UserInfo3->usri3_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
963  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
964 
965  UserInfo3->usri3_parms = Ptr;
966  memcpy(UserInfo3->usri3_parms,
967  UserInfo->Parameters.Buffer,
968  UserInfo->Parameters.Length);
969  UserInfo3->usri3_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
970  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
971 
972  UserInfo3->usri3_workstations = Ptr;
973  memcpy(UserInfo3->usri3_workstations,
974  UserInfo->WorkStations.Buffer,
975  UserInfo->WorkStations.Length);
976  UserInfo3->usri3_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
977  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
978 
979  if (UserInfo->LastLogon.QuadPart == 0)
980  UserInfo3->usri3_last_logon = 0;
981  else
982  RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
983  &UserInfo3->usri3_last_logon);
984 
985  if (UserInfo->LastLogoff.QuadPart == 0)
986  UserInfo3->usri3_last_logoff = 0;
987  else
988  RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
989  &UserInfo3->usri3_last_logoff);
990 
991  if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG)
992  UserInfo3->usri3_acct_expires = TIMEQ_FOREVER;
993  else
994  RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
995  &UserInfo3->usri3_acct_expires);
996 
998  UserInfo3->usri3_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
999 
1000  if (UserInfo->LogonHours.UnitsPerWeek > 0)
1001  {
1002  UserInfo3->usri3_logon_hours = (PVOID)Ptr;
1003 
1004  memcpy(UserInfo3->usri3_logon_hours,
1005  UserInfo->LogonHours.LogonHours,
1006  (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
1007 
1008  Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
1009  }
1010 
1011  UserInfo3->usri3_bad_pw_count = UserInfo->BadPasswordCount;
1012  UserInfo3->usri3_num_logons = UserInfo->LogonCount;
1013 
1014  UserInfo3->usri3_logon_server = Ptr;
1015  memcpy(UserInfo3->usri3_logon_server,
1016  LogonServer.Buffer,
1017  LogonServer.Length);
1018  UserInfo3->usri3_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
1019  Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
1020 
1021  UserInfo3->usri3_country_code = UserInfo->CountryCode;
1022  UserInfo3->usri3_code_page = UserInfo->CodePage;
1023  UserInfo3->usri3_user_id = RelativeId;
1024  UserInfo3->usri3_primary_group_id = UserInfo->PrimaryGroupId;
1025 
1026  UserInfo3->usri3_profile = Ptr;
1027  memcpy(UserInfo3->usri3_profile,
1028  UserInfo->ProfilePath.Buffer,
1029  UserInfo->ProfilePath.Length);
1030  UserInfo3->usri3_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1031  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR));
1032 
1033  UserInfo3->usri3_home_dir_drive = Ptr;
1034  memcpy(UserInfo3->usri3_home_dir_drive,
1035  UserInfo->HomeDirectoryDrive.Buffer,
1036  UserInfo->HomeDirectoryDrive.Length);
1037  UserInfo3->usri3_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL;
1038  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR));
1039 
1040  UserInfo3->usri3_password_expired = (UserInfo->UserAccountControl & USER_PASSWORD_EXPIRED);
1041  break;
1042 
1043  case 4:
1044  UserInfo4 = (PUSER_INFO_4)LocalBuffer;
1045 
1046  Ptr = (LPWSTR)((ULONG_PTR)UserInfo4 + sizeof(USER_INFO_4));
1047 
1048  UserInfo4->usri4_name = Ptr;
1049 
1050  memcpy(UserInfo4->usri4_name,
1051  UserInfo->UserName.Buffer,
1052  UserInfo->UserName.Length);
1053  UserInfo4->usri4_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1054 
1055  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
1056 
1057  UserInfo4->usri4_password = NULL;
1058  UserInfo4->usri4_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
1059 
1060  UserInfo4->usri4_priv = Priv;
1061 
1062  UserInfo4->usri4_home_dir = Ptr;
1063  memcpy(UserInfo4->usri4_home_dir,
1064  UserInfo->HomeDirectory.Buffer,
1065  UserInfo->HomeDirectory.Length);
1066  UserInfo4->usri4_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
1067  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
1068 
1069  UserInfo4->usri4_comment = Ptr;
1070  memcpy(UserInfo4->usri4_comment,
1071  UserInfo->AdminComment.Buffer,
1072  UserInfo->AdminComment.Length);
1073  UserInfo4->usri4_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1074  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
1075 
1076  UserInfo4->usri4_flags = GetAccountFlags(UserInfo->UserAccountControl,
1077  Dacl);
1078 
1079  UserInfo4->usri4_script_path = Ptr;
1080  memcpy(UserInfo4->usri4_script_path,
1081  UserInfo->ScriptPath.Buffer,
1082  UserInfo->ScriptPath.Length);
1083  UserInfo4->usri4_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1084  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
1085 
1086  UserInfo4->usri4_auth_flags = AuthFlags;
1087 
1088  UserInfo4->usri4_full_name = Ptr;
1089  memcpy(UserInfo4->usri4_full_name,
1090  UserInfo->FullName.Buffer,
1091  UserInfo->FullName.Length);
1092  UserInfo4->usri4_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1093  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
1094 
1095  UserInfo4->usri4_usr_comment = Ptr;
1096  memcpy(UserInfo4->usri4_usr_comment,
1097  UserInfo->UserComment.Buffer,
1098  UserInfo->UserComment.Length);
1099  UserInfo4->usri4_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1100  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
1101 
1102  UserInfo4->usri4_parms = Ptr;
1103  memcpy(UserInfo4->usri4_parms,
1104  UserInfo->Parameters.Buffer,
1105  UserInfo->Parameters.Length);
1106  UserInfo4->usri4_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
1107  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
1108 
1109  UserInfo4->usri4_workstations = Ptr;
1110  memcpy(UserInfo4->usri4_workstations,
1111  UserInfo->WorkStations.Buffer,
1112  UserInfo->WorkStations.Length);
1113  UserInfo4->usri4_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
1114  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
1115 
1116  if (UserInfo->LastLogon.QuadPart == 0)
1117  UserInfo4->usri4_last_logon = 0;
1118  else
1119  RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
1120  &UserInfo4->usri4_last_logon);
1121 
1122  if (UserInfo->LastLogoff.QuadPart == 0)
1123  UserInfo4->usri4_last_logoff = 0;
1124  else
1125  RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
1126  &UserInfo4->usri4_last_logoff);
1127 
1128  if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG)
1129  UserInfo4->usri4_acct_expires = TIMEQ_FOREVER;
1130  else
1131  RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
1132  &UserInfo4->usri4_acct_expires);
1133 
1135  UserInfo4->usri4_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
1136 
1137  if (UserInfo->LogonHours.UnitsPerWeek > 0)
1138  {
1139  UserInfo4->usri4_logon_hours = (PVOID)Ptr;
1140 
1141  memcpy(UserInfo4->usri4_logon_hours,
1142  UserInfo->LogonHours.LogonHours,
1143  (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
1144 
1145  Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
1146  }
1147 
1148  UserInfo4->usri4_bad_pw_count = UserInfo->BadPasswordCount;
1149  UserInfo4->usri4_num_logons = UserInfo->LogonCount;
1150 
1151  UserInfo4->usri4_logon_server = Ptr;
1152  memcpy(UserInfo4->usri4_logon_server,
1153  LogonServer.Buffer,
1154  LogonServer.Length);
1155  UserInfo4->usri4_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
1156  Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
1157 
1158  UserInfo4->usri4_country_code = UserInfo->CountryCode;
1159  UserInfo4->usri4_code_page = UserInfo->CodePage;
1160 
1161  UserInfo4->usri4_user_sid = (PVOID)Ptr;
1162  CopySidFromSidAndRid(UserInfo4->usri4_user_sid, AccountDomainSid, RelativeId);
1164 
1165  UserInfo4->usri4_primary_group_id = UserInfo->PrimaryGroupId;
1166 
1167  UserInfo4->usri4_profile = Ptr;
1168  memcpy(UserInfo4->usri4_profile,
1169  UserInfo->ProfilePath.Buffer,
1170  UserInfo->ProfilePath.Length);
1171  UserInfo4->usri4_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1172  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR));
1173 
1174  UserInfo4->usri4_home_dir_drive = Ptr;
1175  memcpy(UserInfo4->usri4_home_dir_drive,
1176  UserInfo->HomeDirectoryDrive.Buffer,
1177  UserInfo->HomeDirectoryDrive.Length);
1178  UserInfo4->usri4_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL;
1179  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR));
1180 
1181  UserInfo4->usri4_password_expired = (UserInfo->UserAccountControl & USER_PASSWORD_EXPIRED);
1182  break;
1183 
1184  case 10:
1185  UserInfo10 = (PUSER_INFO_10)LocalBuffer;
1186 
1187  Ptr = (LPWSTR)((ULONG_PTR)UserInfo10 + sizeof(USER_INFO_10));
1188 
1189  UserInfo10->usri10_name = Ptr;
1190 
1191  memcpy(UserInfo10->usri10_name,
1192  UserInfo->UserName.Buffer,
1193  UserInfo->UserName.Length);
1194  UserInfo10->usri10_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1195 
1196  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
1197 
1198  UserInfo10->usri10_comment = Ptr;
1199  memcpy(UserInfo10->usri10_comment,
1200  UserInfo->AdminComment.Buffer,
1201  UserInfo->AdminComment.Length);
1202  UserInfo10->usri10_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1203  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
1204 
1205  UserInfo10->usri10_usr_comment = Ptr;
1206  memcpy(UserInfo10->usri10_usr_comment,
1207  UserInfo->UserComment.Buffer,
1208  UserInfo->UserComment.Length);
1209  UserInfo10->usri10_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1210  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
1211 
1212  UserInfo10->usri10_full_name = Ptr;
1213  memcpy(UserInfo10->usri10_full_name,
1214  UserInfo->FullName.Buffer,
1215  UserInfo->FullName.Length);
1216  UserInfo10->usri10_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1217  break;
1218 
1219  case 11:
1220  UserInfo11 = (PUSER_INFO_11)LocalBuffer;
1221 
1222  Ptr = (LPWSTR)((ULONG_PTR)UserInfo11 + sizeof(USER_INFO_11));
1223 
1224  UserInfo11->usri11_name = Ptr;
1225 
1226  memcpy(UserInfo11->usri11_name,
1227  UserInfo->UserName.Buffer,
1228  UserInfo->UserName.Length);
1229  UserInfo11->usri11_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1230 
1231  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
1232 
1233  UserInfo11->usri11_comment = Ptr;
1234  memcpy(UserInfo11->usri11_comment,
1235  UserInfo->AdminComment.Buffer,
1236  UserInfo->AdminComment.Length);
1237  UserInfo11->usri11_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1238  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
1239 
1240  UserInfo11->usri11_usr_comment = Ptr;
1241  memcpy(UserInfo11->usri11_usr_comment,
1242  UserInfo->UserComment.Buffer,
1243  UserInfo->UserComment.Length);
1244  UserInfo11->usri11_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1245  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
1246 
1247  UserInfo11->usri11_full_name = Ptr;
1248  memcpy(UserInfo11->usri11_full_name,
1249  UserInfo->FullName.Buffer,
1250  UserInfo->FullName.Length);
1251  UserInfo11->usri11_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1252  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
1253 
1254  UserInfo11->usri11_priv = Priv;
1255  UserInfo11->usri11_auth_flags = AuthFlags;
1256 
1257  UserInfo11->usri11_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
1258 
1259  UserInfo11->usri11_home_dir = Ptr;
1260  memcpy(UserInfo11->usri11_home_dir,
1261  UserInfo->HomeDirectory.Buffer,
1262  UserInfo->HomeDirectory.Length);
1263  UserInfo11->usri11_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
1264  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
1265 
1266  UserInfo11->usri11_parms = Ptr;
1267  memcpy(UserInfo11->usri11_parms,
1268  UserInfo->Parameters.Buffer,
1269  UserInfo->Parameters.Length);
1270  UserInfo11->usri11_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
1271  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
1272 
1273  if (UserInfo->LastLogon.QuadPart == 0)
1274  UserInfo11->usri11_last_logon = 0;
1275  else
1276  RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
1277  &UserInfo11->usri11_last_logon);
1278 
1279  if (UserInfo->LastLogoff.QuadPart == 0)
1280  UserInfo11->usri11_last_logoff = 0;
1281  else
1282  RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
1283  &UserInfo11->usri11_last_logoff);
1284 
1285  UserInfo11->usri11_bad_pw_count = UserInfo->BadPasswordCount;
1286  UserInfo11->usri11_num_logons = UserInfo->LogonCount;
1287 
1288  UserInfo11->usri11_logon_server = Ptr;
1289  memcpy(UserInfo11->usri11_logon_server,
1290  LogonServer.Buffer,
1291  LogonServer.Length);
1292  UserInfo11->usri11_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
1293  Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
1294 
1295  UserInfo11->usri11_country_code = UserInfo->CountryCode;
1296 
1297  UserInfo11->usri11_workstations = Ptr;
1298  memcpy(UserInfo11->usri11_workstations,
1299  UserInfo->WorkStations.Buffer,
1300  UserInfo->WorkStations.Length);
1301  UserInfo11->usri11_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
1302  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
1303 
1305  UserInfo11->usri11_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
1306 
1307  if (UserInfo->LogonHours.UnitsPerWeek > 0)
1308  {
1309  UserInfo11->usri11_logon_hours = (PVOID)Ptr;
1310 
1311  memcpy(UserInfo11->usri11_logon_hours,
1312  UserInfo->LogonHours.LogonHours,
1313  (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
1314 
1315  Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
1316  }
1317 
1318  UserInfo11->usri11_code_page = UserInfo->CodePage;
1319  break;
1320 
1321  case 20:
1322  UserInfo20 = (PUSER_INFO_20)LocalBuffer;
1323 
1324  Ptr = (LPWSTR)((ULONG_PTR)UserInfo20 + sizeof(USER_INFO_20));
1325 
1326  UserInfo20->usri20_name = Ptr;
1327 
1328  memcpy(UserInfo20->usri20_name,
1329  UserInfo->UserName.Buffer,
1330  UserInfo->UserName.Length);
1331  UserInfo20->usri20_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1332 
1333  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
1334 
1335  UserInfo20->usri20_full_name = Ptr;
1336  memcpy(UserInfo20->usri20_full_name,
1337  UserInfo->FullName.Buffer,
1338  UserInfo->FullName.Length);
1339  UserInfo20->usri20_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1340  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
1341 
1342  UserInfo20->usri20_comment = Ptr;
1343  memcpy(UserInfo20->usri20_comment,
1344  UserInfo->AdminComment.Buffer,
1345  UserInfo->AdminComment.Length);
1346  UserInfo20->usri20_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1347  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
1348 
1349  UserInfo20->usri20_flags = GetAccountFlags(UserInfo->UserAccountControl,
1350  Dacl);
1351 
1352  UserInfo20->usri20_user_id = RelativeId;
1353  break;
1354 
1355  case 23:
1356  UserInfo23 = (PUSER_INFO_23)LocalBuffer;
1357 
1358  Ptr = (LPWSTR)((ULONG_PTR)UserInfo23 + sizeof(USER_INFO_23));
1359 
1360  UserInfo23->usri23_name = Ptr;
1361 
1362  memcpy(UserInfo23->usri23_name,
1363  UserInfo->UserName.Buffer,
1364  UserInfo->UserName.Length);
1365  UserInfo23->usri23_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1366 
1367  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
1368 
1369  UserInfo23->usri23_full_name = Ptr;
1370  memcpy(UserInfo23->usri23_full_name,
1371  UserInfo->FullName.Buffer,
1372  UserInfo->FullName.Length);
1373  UserInfo23->usri23_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1374  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
1375 
1376  UserInfo23->usri23_comment = Ptr;
1377  memcpy(UserInfo23->usri23_comment,
1378  UserInfo->AdminComment.Buffer,
1379  UserInfo->AdminComment.Length);
1380  UserInfo23->usri23_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1381  Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
1382 
1383  UserInfo23->usri23_flags = GetAccountFlags(UserInfo->UserAccountControl,
1384  Dacl);
1385 
1386  UserInfo23->usri23_user_sid = (PVOID)Ptr;
1387  CopySidFromSidAndRid(UserInfo23->usri23_user_sid, AccountDomainSid, RelativeId);
1389  break;
1390  }
1391 
1392 done:
1393  if (UserInfo != NULL)
1394  FreeUserInfo(UserInfo);
1395 
1396  if (Dacl != NULL)
1397  HeapFree(GetProcessHeap(), 0, Dacl);
1398 
1399  if (ApiStatus == NERR_Success)
1400  {
1401  *Buffer = LocalBuffer;
1402  }
1403  else
1404  {
1405  if (LocalBuffer != NULL)
1406  NetApiBufferFree(LocalBuffer);
1407  }
1408 
1409  return ApiStatus;
1410 }
1411 
1412 
1413 static
1416  LPBYTE UserInfo,
1417  DWORD Level,
1418  PDWORD parm_err)
1419 {
1420  USER_ALL_INFORMATION UserAllInfo;
1421  PUSER_INFO_0 UserInfo0;
1422  PUSER_INFO_1 UserInfo1;
1423  PUSER_INFO_2 UserInfo2;
1424  PUSER_INFO_3 UserInfo3;
1425  PUSER_INFO_4 UserInfo4;
1426  PUSER_INFO_22 UserInfo22;
1427  PUSER_INFO_1003 UserInfo1003;
1428  PUSER_INFO_1006 UserInfo1006;
1429  PUSER_INFO_1007 UserInfo1007;
1430  PUSER_INFO_1008 UserInfo1008;
1431  PUSER_INFO_1009 UserInfo1009;
1432  PUSER_INFO_1011 UserInfo1011;
1433  PUSER_INFO_1012 UserInfo1012;
1434  PUSER_INFO_1013 UserInfo1013;
1435  PUSER_INFO_1014 UserInfo1014;
1436  PUSER_INFO_1017 UserInfo1017;
1437  PUSER_INFO_1018 UserInfo1018;
1438  PUSER_INFO_1020 UserInfo1020;
1439  PUSER_INFO_1024 UserInfo1024;
1440  PUSER_INFO_1025 UserInfo1025;
1441  PUSER_INFO_1051 UserInfo1051;
1442  PUSER_INFO_1052 UserInfo1052;
1443  PUSER_INFO_1053 UserInfo1053;
1444  PACL Dacl = NULL;
1445  NET_API_STATUS ApiStatus = NERR_Success;
1447 
1448  ZeroMemory(&UserAllInfo, sizeof(USER_ALL_INFORMATION));
1449 
1450  if ((Level == 1) || (Level == 2) || (Level == 3) ||
1451  (Level == 4) || (Level == 22) || (Level == 1008))
1452  {
1453  ApiStatus = GetUserDacl(UserHandle, &Dacl);
1454  if (ApiStatus != NERR_Success)
1455  goto done;
1456  }
1457 
1458  switch (Level)
1459  {
1460  case 0:
1461  UserInfo0 = (PUSER_INFO_0)UserInfo;
1462 
1463  RtlInitUnicodeString(&UserAllInfo.UserName,
1464  UserInfo0->usri0_name);
1465 
1466  UserAllInfo.WhichFields |= USER_ALL_USERNAME;
1467  break;
1468 
1469  case 1:
1470  UserInfo1 = (PUSER_INFO_1)UserInfo;
1471 
1472  // usri1_name ignored
1473 
1474  if (UserInfo1->usri1_password != NULL)
1475  {
1476  RtlInitUnicodeString(&UserAllInfo.NtPassword,
1477  UserInfo1->usri1_password);
1478  UserAllInfo.NtPasswordPresent = TRUE;
1479  UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1480  }
1481 
1482  // usri1_password_age ignored
1483 
1484 // UserInfo1->usri1_priv
1485 
1486  if (UserInfo1->usri1_home_dir != NULL)
1487  {
1488  RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1489  UserInfo1->usri1_home_dir);
1490  UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1491  }
1492 
1493  if (UserInfo1->usri1_comment != NULL)
1494  {
1495  RtlInitUnicodeString(&UserAllInfo.AdminComment,
1496  UserInfo1->usri1_comment);
1497  UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1498  }
1499 
1500  ChangeUserDacl(Dacl, UserInfo1->usri1_flags);
1501  UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1->usri1_flags);
1503 
1504  if (UserInfo1->usri1_script_path != NULL)
1505  {
1506  RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1507  UserInfo1->usri1_script_path);
1508  UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1509  }
1510  break;
1511 
1512  case 2:
1513  UserInfo2 = (PUSER_INFO_2)UserInfo;
1514 
1515  // usri2_name ignored
1516 
1517  if (UserInfo2->usri2_password != NULL)
1518  {
1519  RtlInitUnicodeString(&UserAllInfo.NtPassword,
1520  UserInfo2->usri2_password);
1521  UserAllInfo.NtPasswordPresent = TRUE;
1522  UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1523  }
1524 
1525  // usri2_password_age ignored
1526 
1527 // UserInfo2->usri2_priv;
1528 
1529  if (UserInfo2->usri2_home_dir != NULL)
1530  {
1531  RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1532  UserInfo2->usri2_home_dir);
1533  UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1534  }
1535 
1536  if (UserInfo2->usri2_comment != NULL)
1537  {
1538  RtlInitUnicodeString(&UserAllInfo.AdminComment,
1539  UserInfo2->usri2_comment);
1540  UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1541  }
1542 
1543  ChangeUserDacl(Dacl, UserInfo2->usri2_flags);
1544  UserAllInfo.UserAccountControl = GetAccountControl(UserInfo2->usri2_flags);
1546 
1547  if (UserInfo2->usri2_script_path != NULL)
1548  {
1549  RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1550  UserInfo2->usri2_script_path);
1551  UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1552  }
1553 
1554 // UserInfo2->usri2_auth_flags;
1555 
1556  if (UserInfo2->usri2_full_name != NULL)
1557  {
1558  RtlInitUnicodeString(&UserAllInfo.FullName,
1559  UserInfo2->usri2_full_name);
1560  UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1561  }
1562 
1563  if (UserInfo2->usri2_usr_comment != NULL)
1564  {
1565  RtlInitUnicodeString(&UserAllInfo.UserComment,
1566  UserInfo2->usri2_usr_comment);
1567  UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1568  }
1569 
1570  if (UserInfo2->usri2_parms != NULL)
1571  {
1572  RtlInitUnicodeString(&UserAllInfo.Parameters,
1573  UserInfo2->usri2_parms);
1574  UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1575  }
1576 
1577  if (UserInfo2->usri2_workstations != NULL)
1578  {
1579  RtlInitUnicodeString(&UserAllInfo.WorkStations,
1580  UserInfo2->usri2_workstations);
1581  UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1582  }
1583 
1584  // usri2_last_logon ignored
1585  // usri2_last_logoff ignored
1586 
1587  if (UserInfo2->usri2_acct_expires == TIMEQ_FOREVER)
1588  {
1589  UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
1590  }
1591  else
1592  {
1594  &UserAllInfo.AccountExpires);
1595  }
1596  UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1597 
1598  if (UserInfo2->usri2_max_storage != USER_MAXSTORAGE_UNLIMITED)
1599  {
1600  if (parm_err != NULL)
1601  *parm_err = USER_MAX_STORAGE_PARMNUM;
1602  ApiStatus = ERROR_INVALID_PARAMETER;
1603  break;
1604  }
1605 
1606  if (UserInfo2->usri2_units_per_week > USHRT_MAX)
1607  {
1608  if (parm_err != NULL)
1609  *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
1610  ApiStatus = ERROR_INVALID_PARAMETER;
1611  break;
1612  }
1613 
1614  UserAllInfo.LogonHours.UnitsPerWeek = UserInfo2->usri2_units_per_week;
1615  UserAllInfo.LogonHours.LogonHours = UserInfo2->usri2_logon_hours;
1616  UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
1617 
1618  // usri2_bad_pw_count ignored
1619  // usri2_num_logons ignored
1620  // usri2_logon_server ignored
1621 
1622  UserAllInfo.CountryCode = UserInfo2->usri2_country_code;
1623  UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1624 
1625  UserAllInfo.CodePage = UserInfo2->usri2_code_page;
1626  UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1627  break;
1628 
1629  case 3:
1630  UserInfo3 = (PUSER_INFO_3)UserInfo;
1631 
1632  // usri3_name ignored
1633 
1634  if (UserInfo3->usri3_password != NULL)
1635  {
1636  RtlInitUnicodeString(&UserAllInfo.NtPassword,
1637  UserInfo3->usri3_password);
1638  UserAllInfo.NtPasswordPresent = TRUE;
1639  UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1640  }
1641 
1642  // usri3_password_age ignored
1643 
1644 // UserInfo3->usri3_priv;
1645 
1646  if (UserInfo3->usri3_home_dir != NULL)
1647  {
1648  RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1649  UserInfo3->usri3_home_dir);
1650  UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1651  }
1652 
1653  if (UserInfo3->usri3_comment != NULL)
1654  {
1655  RtlInitUnicodeString(&UserAllInfo.AdminComment,
1656  UserInfo3->usri3_comment);
1657  UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1658  }
1659 
1660  ChangeUserDacl(Dacl, UserInfo3->usri3_flags);
1661  UserAllInfo.UserAccountControl = GetAccountControl(UserInfo3->usri3_flags);
1663 
1664  if (UserInfo3->usri3_script_path != NULL)
1665  {
1666  RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1667  UserInfo3->usri3_script_path);
1668  UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1669  }
1670 
1671 // UserInfo3->usri3_auth_flags;
1672 
1673  if (UserInfo3->usri3_full_name != NULL)
1674  {
1675  RtlInitUnicodeString(&UserAllInfo.FullName,
1676  UserInfo3->usri3_full_name);
1677  UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1678  }
1679 
1680  if (UserInfo3->usri3_usr_comment != NULL)
1681  {
1682  RtlInitUnicodeString(&UserAllInfo.UserComment,
1683  UserInfo3->usri3_usr_comment);
1684  UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1685  }
1686 
1687  if (UserInfo3->usri3_parms != NULL)
1688  {
1689  RtlInitUnicodeString(&UserAllInfo.Parameters,
1690  UserInfo3->usri3_parms);
1691  UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1692  }
1693 
1694  if (UserInfo3->usri3_workstations != NULL)
1695  {
1696  RtlInitUnicodeString(&UserAllInfo.WorkStations,
1697  UserInfo3->usri3_workstations);
1698  UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1699  }
1700 
1701  // usri3_last_logon ignored
1702  // usri3_last_logoff ignored
1703 
1704  if (UserInfo3->usri3_acct_expires == TIMEQ_FOREVER)
1705  {
1706  UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
1707  }
1708  else
1709  {
1711  &UserAllInfo.AccountExpires);
1712  }
1713  UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1714 
1715  if (UserInfo3->usri3_max_storage != USER_MAXSTORAGE_UNLIMITED)
1716  {
1717  if (parm_err != NULL)
1718  *parm_err = USER_MAX_STORAGE_PARMNUM;
1719  ApiStatus = ERROR_INVALID_PARAMETER;
1720  break;
1721  }
1722 
1723  if (UserInfo3->usri3_units_per_week > USHRT_MAX)
1724  {
1725  if (parm_err != NULL)
1726  *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
1727  ApiStatus = ERROR_INVALID_PARAMETER;
1728  break;
1729  }
1730 
1731  UserAllInfo.LogonHours.UnitsPerWeek = UserInfo3->usri3_units_per_week;
1732  UserAllInfo.LogonHours.LogonHours = UserInfo3->usri3_logon_hours;
1733  UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
1734 
1735  // usri3_bad_pw_count ignored
1736  // usri3_num_logons ignored
1737  // usri3_logon_server ignored
1738 
1739  UserAllInfo.CountryCode = UserInfo3->usri3_country_code;
1740  UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1741 
1742  UserAllInfo.CodePage = UserInfo3->usri3_code_page;
1743  UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1744 
1745  // usri3_user_id ignored
1746 
1747  UserAllInfo.PrimaryGroupId = UserInfo3->usri3_primary_group_id;
1748  UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
1749 
1750  if (UserInfo3->usri3_profile != NULL)
1751  {
1752  RtlInitUnicodeString(&UserAllInfo.ProfilePath,
1753  UserInfo3->usri3_profile);
1754  UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
1755  }
1756 
1757  if (UserInfo3->usri3_home_dir_drive != NULL)
1758  {
1760  UserInfo3->usri3_home_dir_drive);
1762  }
1763 
1764  UserAllInfo.PasswordExpired = (UserInfo3->usri3_password_expired != 0);
1765  UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED;
1766  break;
1767 
1768  case 4:
1769  UserInfo4 = (PUSER_INFO_4)UserInfo;
1770 
1771  // usri4_name ignored
1772 
1773  if (UserInfo4->usri4_password != NULL)
1774  {
1775  RtlInitUnicodeString(&UserAllInfo.NtPassword,
1776  UserInfo4->usri4_password);
1777  UserAllInfo.NtPasswordPresent = TRUE;
1778  UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1779  }
1780 
1781  // usri4_password_age ignored
1782 
1783 // UserInfo3->usri4_priv;
1784 
1785  if (UserInfo4->usri4_home_dir != NULL)
1786  {
1787  RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1788  UserInfo4->usri4_home_dir);
1789  UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1790  }
1791 
1792  if (UserInfo4->usri4_comment != NULL)
1793  {
1794  RtlInitUnicodeString(&UserAllInfo.AdminComment,
1795  UserInfo4->usri4_comment);
1796  UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1797  }
1798 
1799  ChangeUserDacl(Dacl, UserInfo4->usri4_flags);
1800  UserAllInfo.UserAccountControl = GetAccountControl(UserInfo4->usri4_flags);
1802 
1803  if (UserInfo4->usri4_script_path != NULL)
1804  {
1805  RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1806  UserInfo4->usri4_script_path);
1807  UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1808  }
1809 
1810 // UserInfo4->usri4_auth_flags;
1811 
1812  if (UserInfo4->usri4_full_name != NULL)
1813  {
1814  RtlInitUnicodeString(&UserAllInfo.FullName,
1815  UserInfo4->usri4_full_name);
1816  UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1817  }
1818 
1819  if (UserInfo4->usri4_usr_comment != NULL)
1820  {
1821  RtlInitUnicodeString(&UserAllInfo.UserComment,
1822  UserInfo4->usri4_usr_comment);
1823  UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1824  }
1825 
1826  if (UserInfo4->usri4_parms != NULL)
1827  {
1828  RtlInitUnicodeString(&UserAllInfo.Parameters,
1829  UserInfo4->usri4_parms);
1830  UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1831  }
1832 
1833  if (UserInfo4->usri4_workstations != NULL)
1834  {
1835  RtlInitUnicodeString(&UserAllInfo.WorkStations,
1836  UserInfo4->usri4_workstations);
1837  UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1838  }
1839 
1840  // usri4_last_logon ignored
1841  // usri4_last_logoff ignored
1842 
1843  if (UserInfo4->usri4_acct_expires == TIMEQ_FOREVER)
1844  {
1845  UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
1846  }
1847  else
1848  {
1850  &UserAllInfo.AccountExpires);
1851  }
1852  UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1853 
1854  if (UserInfo4->usri4_max_storage != USER_MAXSTORAGE_UNLIMITED)
1855  {
1856  if (parm_err != NULL)
1857  *parm_err = USER_MAX_STORAGE_PARMNUM;
1858  ApiStatus = ERROR_INVALID_PARAMETER;
1859  break;
1860  }
1861 
1862  if (UserInfo4->usri4_units_per_week > USHRT_MAX)
1863  {
1864  if (parm_err != NULL)
1865  *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
1866  ApiStatus = ERROR_INVALID_PARAMETER;
1867  break;
1868  }
1869 
1870  UserAllInfo.LogonHours.UnitsPerWeek = UserInfo4->usri4_units_per_week;
1871  UserAllInfo.LogonHours.LogonHours = UserInfo4->usri4_logon_hours;
1872  UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
1873 
1874  // usri4_bad_pw_count ignored
1875  // usri4_num_logons ignored
1876  // usri4_logon_server ignored
1877 
1878  UserAllInfo.CountryCode = UserInfo4->usri4_country_code;
1879  UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1880 
1881  UserAllInfo.CodePage = UserInfo4->usri4_code_page;
1882  UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1883 
1884  // usri4_user_sid ignored
1885 
1886  UserAllInfo.PrimaryGroupId = UserInfo4->usri4_primary_group_id;
1887  UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
1888 
1889  if (UserInfo4->usri4_profile != NULL)
1890  {
1891  RtlInitUnicodeString(&UserAllInfo.ProfilePath,
1892  UserInfo4->usri4_profile);
1893  UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
1894  }
1895 
1896  if (UserInfo4->usri4_home_dir_drive != NULL)
1897  {
1899  UserInfo4->usri4_home_dir_drive);
1901  }
1902 
1903  UserAllInfo.PasswordExpired = (UserInfo4->usri4_password_expired != 0);
1904  UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED;
1905  break;
1906 
1907 // case 21:
1908 // break;
1909 
1910  case 22:
1911  UserInfo22 = (PUSER_INFO_22)UserInfo;
1912 
1913  // usri22_name ignored
1914 
1915 // UserInfo22->usri22_password[ENCRYPTED_PWLEN];
1916 
1917  // usri22_password_age ignored
1918 
1919 // UserInfo3->usri3_priv;
1920 
1921  if (UserInfo22->usri22_home_dir != NULL)
1922  {
1923  RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1924  UserInfo22->usri22_home_dir);
1925  UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1926  }
1927 
1928  if (UserInfo22->usri22_comment != NULL)
1929  {
1930  RtlInitUnicodeString(&UserAllInfo.AdminComment,
1931  UserInfo22->usri22_comment);
1932  UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1933  }
1934 
1935  ChangeUserDacl(Dacl, UserInfo22->usri22_flags);
1936  UserAllInfo.UserAccountControl = GetAccountControl(UserInfo22->usri22_flags);
1938 
1939  if (UserInfo22->usri22_script_path != NULL)
1940  {
1941  RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1942  UserInfo22->usri22_script_path);
1943  UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1944  }
1945 
1946 // UserInfo22->usri22_auth_flags;
1947 
1948  if (UserInfo22->usri22_full_name != NULL)
1949  {
1950  RtlInitUnicodeString(&UserAllInfo.FullName,
1951  UserInfo22->usri22_full_name);
1952  UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1953  }
1954 
1955  if (UserInfo22->usri22_usr_comment != NULL)
1956  {
1957  RtlInitUnicodeString(&UserAllInfo.UserComment,
1958  UserInfo22->usri22_usr_comment);
1959  UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1960  }
1961 
1962  if (UserInfo22->usri22_parms != NULL)
1963  {
1964  RtlInitUnicodeString(&UserAllInfo.Parameters,
1965  UserInfo22->usri22_parms);
1966  UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1967  }
1968 
1969  if (UserInfo22->usri22_workstations != NULL)
1970  {
1971  RtlInitUnicodeString(&UserAllInfo.WorkStations,
1972  UserInfo22->usri22_workstations);
1973  UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1974  }
1975 
1976  // usri22_last_logon ignored
1977  // usri22_last_logoff ignored
1978 
1979  if (UserInfo22->usri22_acct_expires == TIMEQ_FOREVER)
1980  {
1981  UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
1982  }
1983  else
1984  {
1986  &UserAllInfo.AccountExpires);
1987  }
1988  UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1989 
1990  if (UserInfo22->usri22_max_storage != USER_MAXSTORAGE_UNLIMITED)
1991  {
1992  if (parm_err != NULL)
1993  *parm_err = USER_MAX_STORAGE_PARMNUM;
1994  ApiStatus = ERROR_INVALID_PARAMETER;
1995  break;
1996  }
1997 
1998  if (UserInfo22->usri22_units_per_week > USHRT_MAX)
1999  {
2000  if (parm_err != NULL)
2001  *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
2002  ApiStatus = ERROR_INVALID_PARAMETER;
2003  break;
2004  }
2005 
2006  UserAllInfo.LogonHours.UnitsPerWeek = UserInfo22->usri22_units_per_week;
2007  UserAllInfo.LogonHours.LogonHours = UserInfo22->usri22_logon_hours;
2008  UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
2009 
2010  // usri22_bad_pw_count ignored
2011  // usri22_num_logons ignored
2012  // usri22_logon_server ignored
2013 
2014  UserAllInfo.CountryCode = UserInfo22->usri22_country_code;
2015  UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
2016 
2017  UserAllInfo.CodePage = UserInfo22->usri22_code_page;
2018  UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
2019  break;
2020 
2021  case 1003:
2022  UserInfo1003 = (PUSER_INFO_1003)UserInfo;
2023 
2024  if (UserInfo1003->usri1003_password != NULL)
2025  {
2026  RtlInitUnicodeString(&UserAllInfo.NtPassword,
2027  UserInfo1003->usri1003_password);
2028  UserAllInfo.NtPasswordPresent = TRUE;
2029  UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
2030  }
2031  break;
2032 
2033 // case 1005:
2034 // break;
2035 
2036  case 1006:
2037  UserInfo1006 = (PUSER_INFO_1006)UserInfo;
2038 
2039  if (UserInfo1006->usri1006_home_dir != NULL)
2040  {
2041  RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
2042  UserInfo1006->usri1006_home_dir);
2043  UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
2044  }
2045  break;
2046 
2047  case 1007:
2048  UserInfo1007 = (PUSER_INFO_1007)UserInfo;
2049 
2050  if (UserInfo1007->usri1007_comment != NULL)
2051  {
2052  RtlInitUnicodeString(&UserAllInfo.AdminComment,
2053  UserInfo1007->usri1007_comment);
2054  UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
2055  }
2056  break;
2057 
2058  case 1008:
2059  UserInfo1008 = (PUSER_INFO_1008)UserInfo;
2060  ChangeUserDacl(Dacl, UserInfo1008->usri1008_flags);
2061  UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1008->usri1008_flags);
2063  break;
2064 
2065  case 1009:
2066  UserInfo1009 = (PUSER_INFO_1009)UserInfo;
2067 
2068  if (UserInfo1009->usri1009_script_path != NULL)
2069  {
2070  RtlInitUnicodeString(&UserAllInfo.ScriptPath,
2071  UserInfo1009->usri1009_script_path);
2072  UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
2073  }
2074  break;
2075 
2076 // case 1010:
2077 // break;
2078 
2079  case 1011:
2080  UserInfo1011 = (PUSER_INFO_1011)UserInfo;
2081 
2082  if (UserInfo1011->usri1011_full_name != NULL)
2083  {
2084  RtlInitUnicodeString(&UserAllInfo.FullName,
2085  UserInfo1011->usri1011_full_name);
2086  UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
2087  }
2088  break;
2089 
2090  case 1012:
2091  UserInfo1012 = (PUSER_INFO_1012)UserInfo;
2092 
2093  if (UserInfo1012->usri1012_usr_comment != NULL)
2094  {
2095  RtlInitUnicodeString(&UserAllInfo.UserComment,
2096  UserInfo1012->usri1012_usr_comment);
2097  UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
2098  }
2099  break;
2100 
2101  case 1013:
2102  UserInfo1013 = (PUSER_INFO_1013)UserInfo;
2103 
2104  if (UserInfo1013->usri1013_parms != NULL)
2105  {
2106  RtlInitUnicodeString(&UserAllInfo.Parameters,
2107  UserInfo1013->usri1013_parms);
2108  UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
2109  }
2110  break;
2111 
2112  case 1014:
2113  UserInfo1014 = (PUSER_INFO_1014)UserInfo;
2114 
2115  if (UserInfo1014->usri1014_workstations != NULL)
2116  {
2117  RtlInitUnicodeString(&UserAllInfo.WorkStations,
2118  UserInfo1014->usri1014_workstations);
2119  UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
2120  }
2121  break;
2122 
2123  case 1017:
2124  UserInfo1017 = (PUSER_INFO_1017)UserInfo;
2125 
2126  if (UserInfo1017->usri1017_acct_expires == TIMEQ_FOREVER)
2127  {
2128  UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
2129  }
2130  else
2131  {
2133  &UserAllInfo.AccountExpires);
2134  }
2135  UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
2136  break;
2137 
2138  case 1018:
2139  UserInfo1018 = (PUSER_INFO_1018)UserInfo;
2140 
2141  if (UserInfo1018->usri1018_max_storage != USER_MAXSTORAGE_UNLIMITED)
2142  {
2143  if (parm_err != NULL)
2144  *parm_err = USER_MAX_STORAGE_PARMNUM;
2145  ApiStatus = ERROR_INVALID_PARAMETER;
2146  }
2147  break;
2148 
2149  case 1020:
2150  UserInfo1020 = (PUSER_INFO_1020)UserInfo;
2151 
2152  if (UserInfo1020->usri1020_units_per_week > USHRT_MAX)
2153  {
2154  if (parm_err != NULL)
2155  *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
2156  ApiStatus = ERROR_INVALID_PARAMETER;
2157  break;
2158  }
2159 
2160  UserAllInfo.LogonHours.UnitsPerWeek = UserInfo1020->usri1020_units_per_week;
2161  UserAllInfo.LogonHours.LogonHours = UserInfo1020->usri1020_logon_hours;
2162  UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
2163  break;
2164 
2165  case 1024:
2166  UserInfo1024 = (PUSER_INFO_1024)UserInfo;
2167 
2168  UserAllInfo.CountryCode = UserInfo1024->usri1024_country_code;
2169  UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
2170  break;
2171 
2172  case 1025:
2173  UserInfo1025 = (PUSER_INFO_1025)UserInfo;
2174 
2175  UserAllInfo.CodePage = UserInfo1025->usri1025_code_page;
2176  UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
2177  break;
2178 
2179  case 1051:
2180  UserInfo1051 = (PUSER_INFO_1051)UserInfo;
2181 
2182  UserAllInfo.PrimaryGroupId = UserInfo1051->usri1051_primary_group_id;
2183  UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
2184  break;
2185 
2186  case 1052:
2187  UserInfo1052 = (PUSER_INFO_1052)UserInfo;
2188 
2189  if (UserInfo1052->usri1052_profile != NULL)
2190  {
2191  RtlInitUnicodeString(&UserAllInfo.ProfilePath,
2192  UserInfo1052->usri1052_profile);
2193  UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
2194  }
2195  break;
2196 
2197  case 1053:
2198  UserInfo1053 = (PUSER_INFO_1053)UserInfo;
2199 
2200  if (UserInfo1053->usri1053_home_dir_drive != NULL)
2201  {
2203  UserInfo1053->usri1053_home_dir_drive);
2205  }
2206  break;
2207  }
2208 
2209  if (ApiStatus != NERR_Success)
2210  goto done;
2211 
2212  Status = SamSetInformationUser(UserHandle,
2214  &UserAllInfo);
2215  if (!NT_SUCCESS(Status))
2216  {
2217  ERR("SamSetInformationUser failed (Status %08lx)\n", Status);
2218  ApiStatus = NetpNtStatusToApiStatus(Status);
2219  goto done;
2220  }
2221 
2222 done:
2223  if (Dacl != NULL)
2224  HeapFree(GetProcessHeap(), 0, Dacl);
2225 
2226  return ApiStatus;
2227 }
2228 
2229 
2230 static
2233  PUNICODE_STRING UserName,
2235  PSAM_HANDLE UserHandle)
2236 {
2237  PULONG RelativeIds = NULL;
2238  PSID_NAME_USE Use = NULL;
2239  NET_API_STATUS ApiStatus = NERR_Success;
2241 
2242  /* Get the RID for the given user name */
2243  Status = SamLookupNamesInDomain(DomainHandle,
2244  1,
2245  UserName,
2246  &RelativeIds,
2247  &Use);
2248  if (!NT_SUCCESS(Status))
2249  {
2250  ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status);
2252  }
2253 
2254  /* Fail, if it is not an alias account */
2255  if (Use[0] != SidTypeUser)
2256  {
2257  ERR("Object is not a user!\n");
2258  ApiStatus = NERR_GroupNotFound;
2259  goto done;
2260  }
2261 
2262  /* Open the alias account */
2263  Status = SamOpenUser(DomainHandle,
2264  DesiredAccess,
2265  RelativeIds[0],
2266  UserHandle);
2267  if (!NT_SUCCESS(Status))
2268  {
2269  ERR("SamOpenUser failed (Status %08lx)\n", Status);
2270  ApiStatus = NetpNtStatusToApiStatus(Status);
2271  goto done;
2272  }
2273 
2274 done:
2275  if (RelativeIds != NULL)
2276  SamFreeMemory(RelativeIds);
2277 
2278  if (Use != NULL)
2279  SamFreeMemory(Use);
2280 
2281  return ApiStatus;
2282 }
2283 
2284 
2285 /************************************************************
2286  * NetUserAdd (NETAPI32.@)
2287  */
2289 WINAPI
2290 NetUserAdd(LPCWSTR servername,
2291  DWORD level,
2292  LPBYTE bufptr,
2293  LPDWORD parm_err)
2294 {
2295  UNICODE_STRING ServerName;
2296  UNICODE_STRING UserName;
2297  SAM_HANDLE ServerHandle = NULL;
2298  SAM_HANDLE DomainHandle = NULL;
2299  SAM_HANDLE UserHandle = NULL;
2301  ULONG RelativeId;
2302  NET_API_STATUS ApiStatus = NERR_Success;
2304 
2305  TRACE("(%s, %d, %p, %p)\n", debugstr_w(servername), level, bufptr, parm_err);
2306 
2307  if (parm_err != NULL)
2308  *parm_err = PARM_ERROR_NONE;
2309 
2310  /* Check the info level */
2311  switch (level)
2312  {
2313  case 1:
2314  case 2:
2315  case 3:
2316  case 4:
2317  break;
2318 
2319  default:
2320  return ERROR_INVALID_LEVEL;
2321  }
2322 
2323  if (servername != NULL)
2324  RtlInitUnicodeString(&ServerName, servername);
2325 
2326  /* Connect to the SAM Server */
2327  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2328  &ServerHandle,
2330  NULL);
2331  if (!NT_SUCCESS(Status))
2332  {
2333  ERR("SamConnect failed (Status %08lx)\n", Status);
2334  ApiStatus = NetpNtStatusToApiStatus(Status);
2335  goto done;
2336  }
2337 
2338  /* Open the Account Domain */
2339  Status = OpenAccountDomain(ServerHandle,
2340  (servername != NULL) ? &ServerName : NULL,
2342  &DomainHandle);
2343  if (!NT_SUCCESS(Status))
2344  {
2345  ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2346  ApiStatus = NetpNtStatusToApiStatus(Status);
2347  goto done;
2348  }
2349 
2350  /* Initialize the user name string */
2351  RtlInitUnicodeString(&UserName,
2352  ((PUSER_INFO_1)bufptr)->usri1_name);
2353 
2354  /* Create the user account */
2355  Status = SamCreateUser2InDomain(DomainHandle,
2356  &UserName,
2359  &UserHandle,
2360  &GrantedAccess,
2361  &RelativeId);
2362  if (!NT_SUCCESS(Status))
2363  {
2364  ERR("SamCreateUser2InDomain failed (Status %08lx)\n", Status);
2365  ApiStatus = NetpNtStatusToApiStatus(Status);
2366  goto done;
2367  }
2368 
2369  /* Set user information */
2370  ApiStatus = SetUserInfo(UserHandle,
2371  bufptr,
2372  level,
2373  parm_err);
2374  if (ApiStatus != NERR_Success)
2375  {
2376  ERR("SetUserInfo failed (Status %lu)\n", ApiStatus);
2377  goto done;
2378  }
2379 
2380 done:
2381  if (UserHandle != NULL)
2382  {
2383  if (ApiStatus != NERR_Success)
2384  SamDeleteUser(UserHandle);
2385  else
2386  SamCloseHandle(UserHandle);
2387  }
2388 
2389  if (DomainHandle != NULL)
2390  SamCloseHandle(DomainHandle);
2391 
2392  if (ServerHandle != NULL)
2393  SamCloseHandle(ServerHandle);
2394 
2395  return ApiStatus;
2396 }
2397 
2398 
2399 /******************************************************************************
2400  * NetUserChangePassword (NETAPI32.@)
2401  * PARAMS
2402  * domainname [I] Optional. Domain on which the user resides or the logon
2403  * domain of the current user if NULL.
2404  * username [I] Optional. Username to change the password for or the name
2405  * of the current user if NULL.
2406  * oldpassword [I] The user's current password.
2407  * newpassword [I] The password that the user will be changed to using.
2408  *
2409  * RETURNS
2410  * Success: NERR_Success.
2411  * Failure: NERR_* failure code or win error code.
2412  *
2413  */
2415 WINAPI
2417  LPCWSTR username,
2418  LPCWSTR oldpassword,
2419  LPCWSTR newpassword)
2420 {
2421  PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer = NULL;
2422  PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer = NULL;
2423  ULONG RequestBufferSize;
2424  ULONG ResponseBufferSize = 0;
2425  LPWSTR Ptr;
2426  ANSI_STRING PackageName;
2428  HANDLE LsaHandle = NULL;
2429  NET_API_STATUS ApiStatus = NERR_Success;
2432 
2433  TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname), debugstr_w(username));
2434 
2435  /* FIXME: handle null domain or user name */
2436 
2437  /* Check the parameters */
2438  if ((oldpassword == NULL) ||
2439  (newpassword == NULL))
2440  return ERROR_INVALID_PARAMETER;
2441 
2442  /* Connect to the LSA server */
2444  if (!NT_SUCCESS(Status))
2446 
2447  /* Get the authentication package ID */
2448  RtlInitAnsiString(&PackageName,
2450 
2452  &PackageName,
2454  if (!NT_SUCCESS(Status))
2455  {
2456  ApiStatus = NetpNtStatusToApiStatus(Status);
2457  goto done;
2458  }
2459 
2460  /* Calculate the request buffer size */
2461  RequestBufferSize = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST) +
2462  ((wcslen(domainname) + 1) * sizeof(WCHAR)) +
2463  ((wcslen(username) + 1) * sizeof(WCHAR)) +
2464  ((wcslen(oldpassword) + 1) * sizeof(WCHAR)) +
2465  ((wcslen(newpassword) + 1) * sizeof(WCHAR));
2466 
2467  /* Allocate the request buffer */
2468  ApiStatus = NetApiBufferAllocate(RequestBufferSize,
2469  (PVOID*)&RequestBuffer);
2470  if (ApiStatus != NERR_Success)
2471  goto done;
2472 
2473  /* Initialize the request buffer */
2474  RequestBuffer->MessageType = MsV1_0ChangePassword;
2475  RequestBuffer->Impersonating = TRUE;
2476 
2477  Ptr = (LPWSTR)((ULONG_PTR)RequestBuffer + sizeof(MSV1_0_CHANGEPASSWORD_REQUEST));
2478 
2479  /* Pack the domain name */
2480  RequestBuffer->DomainName.Length = wcslen(domainname) * sizeof(WCHAR);
2481  RequestBuffer->DomainName.MaximumLength = RequestBuffer->DomainName.Length + sizeof(WCHAR);
2482  RequestBuffer->DomainName.Buffer = Ptr;
2483 
2484  RtlCopyMemory(RequestBuffer->DomainName.Buffer,
2485  domainname,
2486  RequestBuffer->DomainName.MaximumLength);
2487 
2488  Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->DomainName.MaximumLength);
2489 
2490  /* Pack the user name */
2491  RequestBuffer->AccountName.Length = wcslen(username) * sizeof(WCHAR);
2492  RequestBuffer->AccountName.MaximumLength = RequestBuffer->AccountName.Length + sizeof(WCHAR);
2493  RequestBuffer->AccountName.Buffer = Ptr;
2494 
2495  RtlCopyMemory(RequestBuffer->AccountName.Buffer,
2496  username,
2497  RequestBuffer->AccountName.MaximumLength);
2498 
2499  Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->AccountName.MaximumLength);
2500 
2501  /* Pack the old password */
2502  RequestBuffer->OldPassword.Length = wcslen(oldpassword) * sizeof(WCHAR);
2503  RequestBuffer->OldPassword.MaximumLength = RequestBuffer->OldPassword.Length + sizeof(WCHAR);
2504  RequestBuffer->OldPassword.Buffer = Ptr;
2505 
2506  RtlCopyMemory(RequestBuffer->OldPassword.Buffer,
2507  oldpassword,
2508  RequestBuffer->OldPassword.MaximumLength);
2509 
2510  Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->OldPassword.MaximumLength);
2511 
2512  /* Pack the new password */
2513  RequestBuffer->NewPassword.Length = wcslen(newpassword) * sizeof(WCHAR);
2514  RequestBuffer->NewPassword.MaximumLength = RequestBuffer->NewPassword.Length + sizeof(WCHAR);
2515  RequestBuffer->NewPassword.Buffer = Ptr;
2516 
2517  RtlCopyMemory(RequestBuffer->NewPassword.Buffer,
2518  newpassword,
2519  RequestBuffer->NewPassword.MaximumLength);
2520 
2521  /* Call the authentication package */
2524  RequestBuffer,
2525  RequestBufferSize,
2526  (PVOID*)&ResponseBuffer,
2527  &ResponseBufferSize,
2528  &ProtocolStatus);
2529  if (!NT_SUCCESS(Status))
2530  {
2531  ApiStatus = NetpNtStatusToApiStatus(Status);
2532  goto done;
2533  }
2534 
2535  if (!NT_SUCCESS(ProtocolStatus))
2536  {
2538  goto done;
2539  }
2540 
2541 done:
2542  if (RequestBuffer != NULL)
2543  NetApiBufferFree(RequestBuffer);
2544 
2545  if (ResponseBuffer != NULL)
2546  LsaFreeReturnBuffer(ResponseBuffer);
2547 
2548  if (LsaHandle != NULL)
2549  NtClose(LsaHandle);
2550 
2551  return ApiStatus;
2552 }
2553 
2554 
2555 /************************************************************
2556  * NetUserDel (NETAPI32.@)
2557  */
2559 WINAPI
2560 NetUserDel(LPCWSTR servername,
2561  LPCWSTR username)
2562 {
2563  UNICODE_STRING ServerName;
2564  UNICODE_STRING UserName;
2565  SAM_HANDLE ServerHandle = NULL;
2566  SAM_HANDLE DomainHandle = NULL;
2567  SAM_HANDLE UserHandle = NULL;
2568  NET_API_STATUS ApiStatus = NERR_Success;
2570 
2571  TRACE("(%s, %s)\n", debugstr_w(servername), debugstr_w(username));
2572 
2573  if (servername != NULL)
2574  RtlInitUnicodeString(&ServerName, servername);
2575 
2576  RtlInitUnicodeString(&UserName, username);
2577 
2578  /* Connect to the SAM Server */
2579  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2580  &ServerHandle,
2582  NULL);
2583  if (!NT_SUCCESS(Status))
2584  {
2585  ERR("SamConnect failed (Status %08lx)\n", Status);
2586  ApiStatus = NetpNtStatusToApiStatus(Status);
2587  goto done;
2588  }
2589 
2590  /* Open the Builtin Domain */
2591  Status = OpenBuiltinDomain(ServerHandle,
2592  DOMAIN_LOOKUP,
2593  &DomainHandle);
2594  if (!NT_SUCCESS(Status))
2595  {
2596  ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status);
2597  ApiStatus = NetpNtStatusToApiStatus(Status);
2598  goto done;
2599  }
2600 
2601  /* Open the user account in the builtin domain */
2602  ApiStatus = OpenUserByName(DomainHandle,
2603  &UserName,
2604  DELETE,
2605  &UserHandle);
2606  if (ApiStatus != NERR_Success && ApiStatus != ERROR_NONE_MAPPED)
2607  {
2608  TRACE("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus);
2609  goto done;
2610  }
2611 
2612  if (UserHandle == NULL)
2613  {
2614  if (DomainHandle != NULL)
2615  {
2616  SamCloseHandle(DomainHandle);
2617  DomainHandle = NULL;
2618  }
2619 
2620  /* Open the Acount Domain */
2621  Status = OpenAccountDomain(ServerHandle,
2622  (servername != NULL) ? &ServerName : NULL,
2623  DOMAIN_LOOKUP,
2624  &DomainHandle);
2625  if (!NT_SUCCESS(Status))
2626  {
2627  ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2628  ApiStatus = NetpNtStatusToApiStatus(Status);
2629  goto done;
2630  }
2631 
2632  /* Open the user account in the account domain */
2633  ApiStatus = OpenUserByName(DomainHandle,
2634  &UserName,
2635  DELETE,
2636  &UserHandle);
2637  if (ApiStatus != NERR_Success)
2638  {
2639  ERR("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus);
2640  if (ApiStatus == ERROR_NONE_MAPPED)
2641  ApiStatus = NERR_UserNotFound;
2642  goto done;
2643  }
2644  }
2645 
2646  /* Delete the user */
2647  Status = SamDeleteUser(UserHandle);
2648  if (!NT_SUCCESS(Status))
2649  {
2650  ERR("SamDeleteUser failed (Status %08lx)\n", Status);
2651  ApiStatus = NetpNtStatusToApiStatus(Status);
2652  goto done;
2653  }
2654 
2655  /* A successful delete invalidates the handle */
2656  UserHandle = NULL;
2657 
2658 done:
2659  if (UserHandle != NULL)
2660  SamCloseHandle(UserHandle);
2661 
2662  if (DomainHandle != NULL)
2663  SamCloseHandle(DomainHandle);
2664 
2665  if (ServerHandle != NULL)
2666  SamCloseHandle(ServerHandle);
2667 
2668  return ApiStatus;
2669 }
2670 
2671 static
2674  PENUM_CONTEXT *AllocatedEnumContext)
2675 {
2676  NET_API_STATUS ApiStatus;
2677  PENUM_CONTEXT EnumContext;
2678 
2679  /* Allocate the context structure */
2680  ApiStatus = NetApiBufferAllocate(sizeof(ENUM_CONTEXT), (PVOID*)&EnumContext);
2681  if (ApiStatus != NERR_Success)
2682  return ApiStatus;
2683 
2684  /* Initialize the fields */
2685  EnumContext->EnumerationContext = 0;
2686  EnumContext->Buffer = NULL;
2687  EnumContext->Count = 0;
2688  EnumContext->Index = 0;
2689  EnumContext->BuiltinDone = FALSE;
2690 
2691  /* Set a "unique" handle */
2692  EnumContext->EnumHandle = InterlockedIncrement(&g_EnumContextHandle);
2693  if (EnumContext->EnumHandle == 0)
2694  {
2695  EnumContext->EnumHandle = InterlockedIncrement(&g_EnumContextHandle);
2696  }
2697 
2698  /* Insert the context in the list */
2700  InsertTailList(&g_EnumContextListHead, &EnumContext->ListLink);
2702 
2703  *AllocatedEnumContext = EnumContext;
2704  return NERR_Success;
2705 }
2706 
2707 static
2708 VOID
2710  PENUM_CONTEXT EnumContext)
2711 
2712 {
2713  /* Remove the context from the list */
2715  RemoveEntryList(&EnumContext->ListLink);
2717 
2718  /* Free it */
2719  NetApiBufferFree(EnumContext);
2720 }
2721 
2722 static
2725  SAM_ENUMERATE_HANDLE EnumerationHandle)
2726 {
2727  PENUM_CONTEXT FoundEnumContext = NULL;
2728  PLIST_ENTRY ListEntry;
2729 
2730  /* Acquire the list lock */
2732 
2733  /* Search the list for the handle */
2734  for (ListEntry = g_EnumContextListHead.Flink;
2735  ListEntry != &g_EnumContextListHead;
2736  ListEntry = ListEntry->Flink)
2737  {
2738  PENUM_CONTEXT EnumContext = CONTAINING_RECORD(ListEntry, ENUM_CONTEXT, ListLink);
2739  if (EnumContext->EnumHandle == EnumerationHandle)
2740  {
2741  FoundEnumContext = EnumContext;
2742  break;
2743  }
2744  }
2745 
2746  /* Release the list lock */
2748 
2749  return FoundEnumContext;
2750 }
2751 
2752 /************************************************************
2753  * NetUserEnum (NETAPI32.@)
2754  */
2756 WINAPI
2758  DWORD level,
2759  DWORD filter,
2760  LPBYTE* bufptr,
2761  DWORD prefmaxlen,
2762  LPDWORD entriesread,
2763  LPDWORD totalentries,
2764  LPDWORD resume_handle)
2765 {
2766  UNICODE_STRING ServerName;
2768  PENUM_CONTEXT EnumContext = NULL;
2769  LPVOID Buffer = NULL;
2770  ULONG i;
2771  SAM_HANDLE UserHandle = NULL;
2773  NET_API_STATUS ApiStatus = NERR_Success;
2775 
2776  TRACE("(%s %d 0x%d %p %d %p %p %p)\n", debugstr_w(servername), level,
2777  filter, bufptr, prefmaxlen, entriesread, totalentries, resume_handle);
2778 
2779  *entriesread = 0;
2780  *totalentries = 0;
2781  *bufptr = NULL;
2782 
2783  if (servername != NULL)
2784  RtlInitUnicodeString(&ServerName, servername);
2785 
2786  if (resume_handle != NULL && *resume_handle != 0)
2787  {
2788  EnumContext = LookupEnumContext(*resume_handle);
2789  }
2790  else
2791  {
2792  ApiStatus = AllocateEnumContext(&EnumContext);
2793  if (ApiStatus != NERR_Success)
2794  goto done;
2795 
2796  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2797  &EnumContext->ServerHandle,
2799  NULL);
2800  if (!NT_SUCCESS(Status))
2801  {
2802  ERR("SamConnect failed (Status %08lx)\n", Status);
2803  ApiStatus = NetpNtStatusToApiStatus(Status);
2804  goto done;
2805  }
2806 
2807  /* Get the Account Domain SID */
2808  Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
2809  &EnumContext->AccountDomainSid);
2810  if (!NT_SUCCESS(Status))
2811  {
2812  ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
2813  ApiStatus = NetpNtStatusToApiStatus(Status);
2814  goto done;
2815  }
2816 
2817  /* Open the Account Domain */
2818  Status = SamOpenDomain(EnumContext->ServerHandle,
2820  EnumContext->AccountDomainSid,
2821  &EnumContext->AccountDomainHandle);
2822  if (!NT_SUCCESS(Status))
2823  {
2824  ERR("SamOpenDomain failed (Status %08lx)\n", Status);
2825  ApiStatus = NetpNtStatusToApiStatus(Status);
2826  goto done;
2827  }
2828 
2829  /* Get the Builtin Domain SID */
2830  Status = GetBuiltinDomainSid(&EnumContext->BuiltinDomainSid);
2831  if (!NT_SUCCESS(Status))
2832  {
2833  ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status);
2834  ApiStatus = NetpNtStatusToApiStatus(Status);
2835  goto done;
2836  }
2837 
2839  if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
2841 
2842  /* Open the Builtin Domain */
2843  Status = SamOpenDomain(EnumContext->ServerHandle,
2844  DesiredAccess,
2845  EnumContext->BuiltinDomainSid,
2846  &EnumContext->BuiltinDomainHandle);
2847  if (!NT_SUCCESS(Status))
2848  {
2849  ERR("SamOpenDomain failed (Status %08lx)\n", Status);
2850  ApiStatus = NetpNtStatusToApiStatus(Status);
2851  goto done;
2852  }
2853  }
2854 
2855 // while (TRUE)
2856 // {
2857  TRACE("EnumContext->Index: %lu\n", EnumContext->Index);
2858  TRACE("EnumContext->Count: %lu\n", EnumContext->Count);
2859 
2860  if (EnumContext->Index >= EnumContext->Count)
2861  {
2862 // if (EnumContext->BuiltinDone != FALSE)
2863 // {
2864 // ApiStatus = NERR_Success;
2865 // goto done;
2866 // }
2867 
2868  TRACE("Calling SamEnumerateUsersInDomain\n");
2869  Status = SamEnumerateUsersInDomain(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
2870  &EnumContext->EnumerationContext,
2871  0,
2872  (PVOID *)&EnumContext->Buffer,
2873  prefmaxlen,
2874  &EnumContext->Count);
2875 
2876  TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n", Status);
2877  if (!NT_SUCCESS(Status))
2878  {
2879  ERR("SamEnumerateUsersInDomain failed (Status %08lx)\n", Status);
2880  ApiStatus = NetpNtStatusToApiStatus(Status);
2881  goto done;
2882  }
2883 
2884  if (Status == STATUS_MORE_ENTRIES)
2885  {
2886  ApiStatus = NERR_BufTooSmall;
2887  goto done;
2888  }
2889  else
2890  {
2891  EnumContext->BuiltinDone = TRUE;
2892  }
2893  }
2894 
2895  TRACE("EnumContext: %lu\n", EnumContext);
2896  TRACE("EnumContext->Count: %lu\n", EnumContext->Count);
2897  TRACE("EnumContext->Buffer: %p\n", EnumContext->Buffer);
2898 
2899  /* Get a pointer to the current user */
2900  CurrentUser = &EnumContext->Buffer[EnumContext->Index];
2901 
2902  TRACE("RID: %lu\n", CurrentUser->RelativeId);
2903 
2905  if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
2907 
2908  Status = SamOpenUser(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
2909  DesiredAccess,
2910  CurrentUser->RelativeId,
2911  &UserHandle);
2912  if (!NT_SUCCESS(Status))
2913  {
2914  ERR("SamOpenUser failed (Status %08lx)\n", Status);
2915  ApiStatus = NetpNtStatusToApiStatus(Status);
2916  goto done;
2917  }
2918 
2919  ApiStatus = BuildUserInfoBuffer(EnumContext->BuiltinDomainHandle,
2920  UserHandle,
2921  EnumContext->AccountDomainSid,
2922  CurrentUser->RelativeId,
2923  level,
2924  &Buffer);
2925  if (ApiStatus != NERR_Success)
2926  {
2927  ERR("BuildUserInfoBuffer failed (ApiStatus %lu)\n", ApiStatus);
2928  goto done;
2929  }
2930 
2931  SamCloseHandle(UserHandle);
2932  UserHandle = NULL;
2933 
2934  EnumContext->Index++;
2935 
2936  (*entriesread)++;
2937 // }
2938 
2939 done:
2940  if (ApiStatus == NERR_Success && EnumContext != NULL && EnumContext->Index < EnumContext->Count)
2941  ApiStatus = ERROR_MORE_DATA;
2942 
2943  if (EnumContext != NULL)
2944  *totalentries = EnumContext->Count;
2945 
2946  if (resume_handle == NULL || ApiStatus != ERROR_MORE_DATA)
2947  {
2948  if (EnumContext != NULL)
2949  {
2950  if (EnumContext->BuiltinDomainHandle != NULL)
2951  SamCloseHandle(EnumContext->BuiltinDomainHandle);
2952 
2953  if (EnumContext->AccountDomainHandle != NULL)
2954  SamCloseHandle(EnumContext->AccountDomainHandle);
2955 
2956  if (EnumContext->BuiltinDomainSid != NULL)
2957  RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext->BuiltinDomainSid);
2958 
2959  if (EnumContext->AccountDomainSid != NULL)
2960  RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext->AccountDomainSid);
2961 
2962  if (EnumContext->ServerHandle != NULL)
2963  SamCloseHandle(EnumContext->ServerHandle);
2964 
2965  if (EnumContext->Buffer != NULL)
2966  {
2967  for (i = 0; i < EnumContext->Count; i++)
2968  {
2969  SamFreeMemory(EnumContext->Buffer[i].Name.Buffer);
2970  }
2971 
2972  SamFreeMemory(EnumContext->Buffer);
2973  }
2974 
2975  FreeEnumContext(EnumContext);
2976  EnumContext = NULL;
2977  }
2978  }
2979 
2980  if (UserHandle != NULL)
2981  SamCloseHandle(UserHandle);
2982 
2983  if (resume_handle != NULL)
2984  *resume_handle = EnumContext ? EnumContext->EnumHandle : 0;
2985 
2986  *bufptr = (LPBYTE)Buffer;
2987 
2988  TRACE("return %lu\n", ApiStatus);
2989 
2990  return ApiStatus;
2991 }
2992 
2993 
2994 /************************************************************
2995  * NetUserGetGroups (NETAPI32.@)
2996  */
2998 WINAPI
3000  LPCWSTR username,
3001  DWORD level,
3002  LPBYTE *bufptr,
3003  DWORD prefixmaxlen,
3004  LPDWORD entriesread,
3005  LPDWORD totalentries)
3006 {
3007  UNICODE_STRING ServerName;
3008  UNICODE_STRING UserName;
3009  SAM_HANDLE ServerHandle = NULL;
3010  SAM_HANDLE AccountDomainHandle = NULL;
3011  SAM_HANDLE UserHandle = NULL;
3013  PULONG RelativeIds = NULL;
3014  PSID_NAME_USE Use = NULL;
3015  PGROUP_MEMBERSHIP GroupMembership = NULL;
3016  ULONG GroupCount;
3017 
3018  NET_API_STATUS ApiStatus = NERR_Success;
3020 
3021  TRACE("%s %s %d %p %d %p %p stub\n", debugstr_w(servername),
3022  debugstr_w(username), level, bufptr, prefixmaxlen, entriesread,
3023  totalentries);
3024 
3025  if (servername != NULL)
3026  RtlInitUnicodeString(&ServerName, servername);
3027 
3028  RtlInitUnicodeString(&UserName, username);
3029 
3030  /* Connect to the SAM Server */
3031  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
3032  &ServerHandle,
3034  NULL);
3035  if (!NT_SUCCESS(Status))
3036  {
3037  ERR("SamConnect failed (Status %08lx)\n", Status);
3038  ApiStatus = NetpNtStatusToApiStatus(Status);
3039  goto done;
3040  }
3041 
3042  /* Get the Account Domain SID */
3043  Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
3044  &AccountDomainSid);
3045  if (!NT_SUCCESS(Status))
3046  {
3047  ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
3048  ApiStatus = NetpNtStatusToApiStatus(Status);
3049  goto done;
3050  }
3051 
3052  /* Open the Account Domain */
3053  Status = SamOpenDomain(ServerHandle,
3056  &AccountDomainHandle);
3057  if (!NT_SUCCESS(Status))
3058  {
3059  ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
3060  ApiStatus = NetpNtStatusToApiStatus(Status);
3061  goto done;
3062  }
3063 
3064  /* Get the RID for the given user name */
3065  Status = SamLookupNamesInDomain(AccountDomainHandle,
3066  1,
3067  &UserName,
3068  &RelativeIds,
3069  &Use);
3070  if (!NT_SUCCESS(Status))
3071  {
3072  ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status);
3073  if (Status == STATUS_NONE_MAPPED)
3074  ApiStatus = NERR_UserNotFound;
3075  else
3076  ApiStatus = NetpNtStatusToApiStatus(Status);
3077  goto done;
3078  }
3079 
3080  /* Fail, if it is not a user account */
3081  if (Use[0] != SidTypeUser)
3082  {
3083  ERR("Account is not a User!\n");
3084  ApiStatus = NERR_UserNotFound;
3085  goto done;
3086  }
3087 
3088  /* Open the user object */
3089  Status = SamOpenUser(AccountDomainHandle,
3091  RelativeIds[0],
3092  &UserHandle);
3093  if (!NT_SUCCESS(Status))
3094  {
3095  ERR("SamOpenUser failed (Status %08lx)\n", Status);
3096  ApiStatus = NetpNtStatusToApiStatus(Status);
3097  goto done;
3098  }
3099 
3100  /* Get the group memberships of this user */
3101  Status = SamGetGroupsForUser(UserHandle,
3102  &GroupMembership,
3103  &GroupCount);
3104  if (!NT_SUCCESS(Status))
3105  {
3106  ERR("SamGetGroupsForUser failed (Status %08lx)\n", Status);
3107  ApiStatus = NetpNtStatusToApiStatus(Status);
3108  goto done;
3109  }
3110 
3111  /* If there is no group membership, we're done */
3112  if (GroupCount == 0)
3113  {
3114  ApiStatus = NERR_Success;
3115  goto done;
3116  }
3117 
3118 
3119 done:
3120 
3121  if (GroupMembership != NULL)
3122  SamFreeMemory(GroupMembership);
3123 
3124  if (UserHandle != NULL)
3125  SamCloseHandle(UserHandle);
3126 
3127  if (RelativeIds != NULL)
3128  SamFreeMemory(RelativeIds);
3129 
3130  if (Use != NULL)
3131  SamFreeMemory(Use);
3132 
3133  if (AccountDomainSid != NULL)
3134  RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
3135 
3136  if (AccountDomainHandle != NULL)
3137  SamCloseHandle(AccountDomainHandle);
3138 
3139  if (ServerHandle != NULL)
3140  SamCloseHandle(ServerHandle);
3141 
3142  if (ApiStatus != NERR_Success && ApiStatus != ERROR_MORE_DATA)
3143  {
3144  *entriesread = 0;
3145  *totalentries = 0;
3146  }
3147  else
3148  {
3149 // *entriesread = Count;
3150 // *totalentries = Count;
3151  }
3152 
3153 // *bufptr = (LPBYTE)Buffer;
3154 
3155  return ApiStatus;
3156 }
3157 
3158 
3159 /************************************************************
3160  * NetUserGetInfo (NETAPI32.@)
3161  */
3163 WINAPI
3165  LPCWSTR username,
3166  DWORD level,
3167  LPBYTE* bufptr)
3168 {
3169  UNICODE_STRING ServerName;
3170  UNICODE_STRING UserName;
3171  SAM_HANDLE ServerHandle = NULL;
3172  SAM_HANDLE AccountDomainHandle = NULL;
3173  SAM_HANDLE BuiltinDomainHandle = NULL;
3174  SAM_HANDLE UserHandle = NULL;
3175  PULONG RelativeIds = NULL;
3176  PSID_NAME_USE Use = NULL;
3177  LPVOID Buffer = NULL;
3181  NET_API_STATUS ApiStatus = NERR_Success;
3183 
3184  TRACE("(%s, %s, %d, %p)\n", debugstr_w(servername),
3186 
3187  if (servername != NULL)
3188  RtlInitUnicodeString(&ServerName, servername);
3189 
3190  RtlInitUnicodeString(&UserName, username);
3191 
3192  /* Connect to the SAM Server */
3193  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
3194  &ServerHandle,
3196  NULL);
3197  if (!NT_SUCCESS(Status))
3198  {
3199  ERR("SamConnect failed (Status %08lx)\n", Status);
3200  ApiStatus = NetpNtStatusToApiStatus(Status);
3201  goto done;
3202  }
3203 
3204  /* Get the Builtin Domain SID */
3206  if (!NT_SUCCESS(Status))
3207  {
3208  ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status);
3209  ApiStatus = NetpNtStatusToApiStatus(Status);
3210  goto done;
3211  }
3212 
3214  if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
3216 
3217  /* Open the Builtin Domain */
3218  Status = SamOpenDomain(ServerHandle,
3219  DesiredAccess,
3221  &BuiltinDomainHandle);
3222  if (!NT_SUCCESS(Status))
3223  {
3224  ERR("SamOpenDomain failed (Status %08lx)\n", Status);
3225  ApiStatus = NetpNtStatusToApiStatus(Status);
3226  goto done;
3227  }
3228 
3229  /* Get the Account Domain SID */
3230  Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
3231  &AccountDomainSid);
3232  if (!NT_SUCCESS(Status))
3233  {
3234  ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
3235  ApiStatus = NetpNtStatusToApiStatus(Status);
3236  goto done;
3237  }
3238 
3239  /* Open the Account Domain */
3240  Status = SamOpenDomain(ServerHandle,
3243  &AccountDomainHandle);
3244  if (!NT_SUCCESS(Status))
3245  {
3246  ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
3247  ApiStatus = NetpNtStatusToApiStatus(Status);
3248  goto done;
3249  }
3250 
3251  /* Get the RID for the given user name */
3252  Status = SamLookupNamesInDomain(AccountDomainHandle,
3253  1,
3254  &UserName,
3255  &RelativeIds,
3256  &Use);
3257  if (!NT_SUCCESS(Status))
3258  {
3259  ERR("SamOpenDomain failed (Status %08lx)\n", Status);
3260  if (Status == STATUS_NONE_MAPPED)
3261  ApiStatus = NERR_UserNotFound;
3262  else
3263  ApiStatus = NetpNtStatusToApiStatus(Status);
3264  goto done;
3265  }
3266 
3267  /* Check if the account is a user account */
3268  if (Use[0] != SidTypeUser)
3269  {
3270  ERR("No user found!\n");
3271  ApiStatus = NERR_UserNotFound;
3272  goto done;
3273  }
3274 
3275  TRACE("RID: %lu\n", RelativeIds[0]);
3276 
3278  if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
3280 
3281  /* Open the user object */
3282  Status = SamOpenUser(AccountDomainHandle,
3283  DesiredAccess,
3284  RelativeIds[0],
3285  &UserHandle);
3286  if (!NT_SUCCESS(Status))
3287  {
3288  ERR("SamOpenUser failed (Status %08lx)\n", Status);
3289  ApiStatus = NetpNtStatusToApiStatus(Status);
3290  goto done;
3291  }
3292 
3293  ApiStatus = BuildUserInfoBuffer(BuiltinDomainHandle,
3294  UserHandle,
3296  RelativeIds[0],
3297  level,
3298  &Buffer);
3299  if (ApiStatus != NERR_Success)
3300  {
3301  ERR("BuildUserInfoBuffer failed (ApiStatus %08lu)\n", ApiStatus);
3302  goto done;
3303  }
3304 
3305 done:
3306  if (UserHandle != NULL)
3307  SamCloseHandle(UserHandle);
3308 
3309  if (RelativeIds != NULL)
3310  SamFreeMemory(RelativeIds);
3311 
3312  if (Use != NULL)
3313  SamFreeMemory(Use);
3314 
3315  if (AccountDomainHandle != NULL)
3316  SamCloseHandle(AccountDomainHandle);
3317 
3318  if (AccountDomainSid != NULL)
3319  RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
3320 
3321  if (BuiltinDomainHandle != NULL)
3322  SamCloseHandle(BuiltinDomainHandle);
3323 
3324  if (BuiltinDomainSid != NULL)
3325  RtlFreeHeap(RtlGetProcessHeap(), 0, BuiltinDomainSid);
3326 
3327  if (ServerHandle != NULL)
3328  SamCloseHandle(ServerHandle);
3329 
3330  *bufptr = (LPBYTE)Buffer;
3331 
3332  return ApiStatus;
3333 }
3334 
3335 
3336 /************************************************************
3337  * NetUserGetLocalGroups (NETAPI32.@)
3338  */
3340 WINAPI
3342  LPCWSTR username,
3343  DWORD level,
3344  DWORD flags,
3345  LPBYTE* bufptr,
3346  DWORD prefmaxlen,
3347  LPDWORD entriesread,
3348  LPDWORD totalentries)
3349 {
3350  UNICODE_STRING ServerName;
3351  UNICODE_STRING UserName;
3352  SAM_HANDLE ServerHandle = NULL;
3353  SAM_HANDLE BuiltinDomainHandle = NULL;
3354  SAM_HANDLE AccountDomainHandle = NULL;
3356  PSID UserSid = NULL;
3357  PULONG RelativeIds = NULL;
3358  PSID_NAME_USE Use = NULL;
3359  ULONG BuiltinMemberCount = 0;
3360  ULONG AccountMemberCount = 0;
3361  PULONG BuiltinAliases = NULL;
3362  PULONG AccountAliases = NULL;
3363  PUNICODE_STRING BuiltinNames = NULL;
3364  PUNICODE_STRING AccountNames = NULL;
3366  ULONG Size;
3367  ULONG Count = 0;
3368  ULONG Index;
3369  ULONG i;
3370  LPWSTR StrPtr;
3371  NET_API_STATUS ApiStatus = NERR_Success;
3373 
3374  TRACE("(%s, %s, %d, %08x, %p %d, %p, %p) stub!\n",
3375  debugstr_w(servername), debugstr_w(username), level, flags, bufptr,
3376  prefmaxlen, entriesread, totalentries);
3377 
3378  if (level != 0)
3379  return ERROR_INVALID_LEVEL;
3380 
3381  if (flags & ~LG_INCLUDE_INDIRECT)
3382  return ERROR_INVALID_PARAMETER;
3383 
3384  if (flags & LG_INCLUDE_INDIRECT)
3385  {
3386  WARN("The flag LG_INCLUDE_INDIRECT is not supported yet!\n");
3387  }
3388 
3389  if (servername != NULL)
3390  RtlInitUnicodeString(&ServerName, servername);
3391 
3392  RtlInitUnicodeString(&UserName, username);
3393 
3394  /* Connect to the SAM Server */
3395  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
3396  &ServerHandle,
3398  NULL);
3399  if (!NT_SUCCESS(Status))
3400  {
3401  ERR("SamConnect failed (Status %08lx)\n", Status);
3402  ApiStatus = NetpNtStatusToApiStatus(Status);
3403  goto done;
3404  }
3405 
3406  /* Open the Builtin Domain */
3407  Status = OpenBuiltinDomain(ServerHandle,
3409  &BuiltinDomainHandle);
3410  if (!NT_SUCCESS(Status))
3411  {
3412  ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status);
3413  ApiStatus = NetpNtStatusToApiStatus(Status);
3414  goto done;
3415  }
3416 
3417  /* Get the Account Domain SID */
3418  Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
3419  &AccountDomainSid);
3420  if (!NT_SUCCESS(Status))
3421  {
3422  ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
3423  ApiStatus = NetpNtStatusToApiStatus(Status);
3424  goto done;
3425  }
3426 
3427  /* Open the Account Domain */
3428  Status = SamOpenDomain(ServerHandle,
3431  &AccountDomainHandle);
3432  if (!NT_SUCCESS(Status))
3433  {
3434  ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
3435  ApiStatus = NetpNtStatusToApiStatus(Status);
3436  goto done;
3437  }
3438 
3439  /* Get the RID for the given user name */
3440  Status = SamLookupNamesInDomain(AccountDomainHandle,
3441  1,
3442  &UserName,
3443  &RelativeIds,
3444  &Use);
3445  if (!NT_SUCCESS(Status))
3446  {
3447  ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status);
3448  if (Status == STATUS_NONE_MAPPED)
3449  ApiStatus = NERR_UserNotFound;
3450  else
3451  ApiStatus = NetpNtStatusToApiStatus(Status);
3452  goto done;
3453  }
3454 
3455  /* Fail, if it is not a user account */
3456  if (Use[0] != SidTypeUser)
3457  {
3458  ERR("Account is not a User!\n");
3459  ApiStatus = NERR_UserNotFound;
3460  goto done;
3461  }
3462 
3463  /* Build the User SID from the Account Domain SID and the users RID */
3465  RelativeIds[0],
3466  &UserSid);
3467  if (ApiStatus != NERR_Success)
3468  {
3469  ERR("BuildSidFromSidAndRid failed!\n");
3470  goto done;
3471  }
3472 
3473  /* Get alias memberships in the Builtin Domain */
3474  Status = SamGetAliasMembership(BuiltinDomainHandle,
3475  1,
3476  &UserSid,
3477  &BuiltinMemberCount,
3478  &BuiltinAliases);
3479  if (!NT_SUCCESS(Status))
3480  {
3481  ERR("SamGetAliasMembership failed (Status %08lx)\n", Status);
3482  ApiStatus = NetpNtStatusToApiStatus(Status);
3483  goto done;
3484  }
3485 
3486  if (BuiltinMemberCount > 0)
3487  {
3488  /* Get the Names of the builtin alias members */
3489  Status = SamLookupIdsInDomain(BuiltinDomainHandle,
3490  BuiltinMemberCount,
3491  BuiltinAliases,
3492  &BuiltinNames,
3493  NULL);
3494  if (!NT_SUCCESS(Status))
3495  {
3496  ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status);
3497  ApiStatus = NetpNtStatusToApiStatus(Status);
3498  goto done;
3499  }
3500  }
3501 
3502  /* Get alias memberships in the Account Domain */
3503  Status = SamGetAliasMembership(AccountDomainHandle,
3504  1,
3505  &UserSid,
3506  &AccountMemberCount,
3507  &AccountAliases);
3508  if (!NT_SUCCESS(Status))
3509  {
3510  ERR("SamGetAliasMembership failed (Status %08lx)\n", Status);
3511  ApiStatus = NetpNtStatusToApiStatus(Status);
3512  goto done;
3513  }
3514 
3515  if (AccountMemberCount > 0)
3516  {
3517  /* Get the Names of the builtin alias members */
3518  Status = SamLookupIdsInDomain(AccountDomainHandle,
3519  AccountMemberCount,
3520  AccountAliases,
3521  &AccountNames,
3522  NULL);
3523  if (!NT_SUCCESS(Status))
3524  {
3525  ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status);
3526  ApiStatus = NetpNtStatusToApiStatus(Status);
3527  goto done;
3528  }
3529  }
3530 
3531  /* Calculate the required buffer size */
3532  Size = 0;
3533 
3534  for (i = 0; i < BuiltinMemberCount; i++)
3535  {
3536  if (BuiltinNames[i].Length > 0)
3537  {
3538  Size += (sizeof(LOCALGROUP_USERS_INFO_0) + BuiltinNames[i].Length + sizeof(UNICODE_NULL));
3539  Count++;
3540  }
3541  }
3542 
3543  for (i = 0; i < AccountMemberCount; i++)
3544  {
3545  if (AccountNames[i].Length > 0)
3546  {
3547  Size += (sizeof(LOCALGROUP_USERS_INFO_0) + AccountNames[i].Length + sizeof(UNICODE_NULL));
3548  Count++;
3549  }
3550  }
3551 
3552  if (Size == 0)
3553  {
3554  ApiStatus = NERR_Success;
3555  goto done;
3556  }
3557 
3558  /* Allocate buffer */
3559  ApiStatus = NetApiBufferAllocate(Size, (LPVOID*)&Buffer);
3560  if (ApiStatus != NERR_Success)
3561  goto done;
3562 
3564 
3565  StrPtr = (LPWSTR)((INT_PTR)Buffer + Count * sizeof(LOCALGROUP_USERS_INFO_0));
3566 
3567  /* Copy data to the allocated buffer */
3568  Index = 0;
3569  for (i = 0; i < BuiltinMemberCount; i++)
3570  {
3571  if (BuiltinNames[i].Length > 0)
3572  {
3573  CopyMemory(StrPtr,
3574  BuiltinNames[i].Buffer,
3575  BuiltinNames[i].Length);
3576  Buffer[Index].lgrui0_name = StrPtr;
3577 
3578  StrPtr = (LPWSTR)((INT_PTR)StrPtr + BuiltinNames[i].Length + sizeof(UNICODE_NULL));
3579  Index++;
3580  }
3581  }
3582 
3583  for (i = 0; i < AccountMemberCount; i++)
3584  {
3585  if (AccountNames[i].Length > 0)
3586  {
3587  CopyMemory(StrPtr,
3588  AccountNames[i].Buffer,
3589  AccountNames[i].Length);
3590  Buffer[Index].lgrui0_name = StrPtr;
3591 
3592  StrPtr = (LPWSTR)((INT_PTR)StrPtr + AccountNames[i].Length + sizeof(UNICODE_NULL));
3593  Index++;
3594  }
3595  }
3596 
3597 done:
3598  if (AccountNames != NULL)
3599  SamFreeMemory(AccountNames);
3600 
3601  if (BuiltinNames != NULL)
3602  SamFreeMemory(BuiltinNames);
3603 
3604  if (AccountAliases != NULL)
3605  SamFreeMemory(AccountAliases);
3606 
3607  if (BuiltinAliases != NULL)
3608  SamFreeMemory(BuiltinAliases);
3609 
3610  if (RelativeIds != NULL)
3611  SamFreeMemory(RelativeIds);
3612 
3613  if (Use != NULL)
3614  SamFreeMemory(Use);
3615 
3616  if (UserSid != NULL)
3617  NetApiBufferFree(UserSid);
3618 
3619  if (AccountDomainSid != NULL)
3620  RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
3621 
3622  if (AccountDomainHandle != NULL)
3623  SamCloseHandle(AccountDomainHandle);
3624 
3625  if (BuiltinDomainHandle != NULL)
3626  SamCloseHandle(BuiltinDomainHandle);
3627 
3628  if (ServerHandle != NULL)
3629  SamCloseHandle(ServerHandle);
3630 
3631  if (ApiStatus != NERR_Success && ApiStatus != ERROR_MORE_DATA)
3632  {
3633  *entriesread = 0;
3634  *totalentries = 0;
3635  }
3636  else
3637  {
3638  *entriesread = Count;
3639  *totalentries = Count;
3640  }
3641 
3642  *bufptr = (LPBYTE)Buffer;
3643 
3644  return ApiStatus;
3645 }
3646 
3647 
3648 /******************************************************************************
3649  * NetUserModalsGet (NETAPI32.@)
3650  *
3651  * Retrieves global information for all users and global groups in the security
3652  * database.
3653  *
3654  * PARAMS
3655  * servername [I] Specifies the DNS or the NetBIOS name of the remote server
3656  * on which the function is to execute.
3657  * level [I] Information level of the data.
3658  * 0 Return global passwords parameters. bufptr points to a
3659  * USER_MODALS_INFO_0 struct.
3660  * 1 Return logon server and domain controller information. bufptr
3661  * points to a USER_MODALS_INFO_1 struct.
3662  * 2 Return domain name and identifier. bufptr points to a
3663  * USER_MODALS_INFO_2 struct.
3664  * 3 Return lockout information. bufptr points to a USER_MODALS_INFO_3
3665  * struct.
3666  * bufptr [O] Buffer that receives the data.
3667  *
3668  * RETURNS
3669  * Success: NERR_Success.
3670  * Failure:
3671  * ERROR_ACCESS_DENIED - the user does not have access to the info.
3672  * NERR_InvalidComputer - computer name is invalid.
3673  */
3675 WINAPI
3677  DWORD level,
3678  LPBYTE *bufptr)
3679 {
3680  UNICODE_STRING ServerName;
3681  SAM_HANDLE ServerHandle = NULL;
3682  SAM_HANDLE DomainHandle = NULL;
3683  PSID DomainSid = NULL;
3684  PDOMAIN_PASSWORD_INFORMATION PasswordInfo = NULL;
3685  PDOMAIN_LOGOFF_INFORMATION LogoffInfo = NULL;
3686  PDOMAIN_SERVER_ROLE_INFORMATION ServerRoleInfo = NULL;
3687  PDOMAIN_REPLICATION_INFORMATION ReplicationInfo = NULL;
3688  PDOMAIN_NAME_INFORMATION NameInfo = NULL;
3689  PDOMAIN_LOCKOUT_INFORMATION LockoutInfo = NULL;
3691  ULONG BufferSize;
3692  PUSER_MODALS_INFO_0 umi0;
3693  PUSER_MODALS_INFO_1 umi1;
3694  PUSER_MODALS_INFO_2 umi2;
3695  PUSER_MODALS_INFO_3 umi3;
3696  NET_API_STATUS ApiStatus = NERR_Success;
3698 
3699  TRACE("(%s %d %p)\n", debugstr_w(servername), level, bufptr);
3700 
3701  *bufptr = NULL;
3702 
3703  if (servername != NULL)
3704  RtlInitUnicodeString(&ServerName, servername);
3705 
3706  /* Connect to the SAM Server */
3707  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
3708  &ServerHandle,
3710  NULL);
3711  if (!NT_SUCCESS(Status))
3712  {
3713  ERR("SamConnect failed (Status %08lx)\n", Status);
3714  ApiStatus = NetpNtStatusToApiStatus(Status);
3715  goto done;
3716  }
3717 
3718  /* Get the Account Domain SID */
3719  Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
3720  &DomainSid);
3721  if (!NT_SUCCESS(Status))
3722  {
3723  ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
3724  ApiStatus = NetpNtStatusToApiStatus(Status);
3725  goto done;
3726  }
3727 
3728  switch (level)
3729  {
3730  case 0:
3732  break;
3733 
3734  case 1:
3736  break;
3737 
3738  case 2:
3740  break;
3741 
3742  case 3:
3744  break;
3745 
3746  default:
3747  ApiStatus = ERROR_INVALID_LEVEL;
3748  goto done;
3749  }
3750 
3751  /* Open the Account Domain */
3752  Status = SamOpenDomain(ServerHandle,
3753  DesiredAccess,
3754  DomainSid,
3755  &DomainHandle);
3756  if (!NT_SUCCESS(Status))
3757  {
3758  ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
3759  ApiStatus = NetpNtStatusToApiStatus(Status);
3760  goto done;
3761  }
3762 
3763  switch (level)
3764  {
3765  case 0:
3766  /* return global passwords parameters */
3767  Status = SamQueryInformationDomain(DomainHandle,
3769  (PVOID*)&PasswordInfo);
3770  if (!NT_SUCCESS(Status))
3771  {
3772  ApiStatus = NetpNtStatusToApiStatus(Status);
3773  goto done;
3774  }
3775 
3776  Status = SamQueryInformationDomain(DomainHandle,
3778  (PVOID*)&LogoffInfo);
3779  if (!NT_SUCCESS(Status))
3780  {
3781  ApiStatus = NetpNtStatusToApiStatus(Status);
3782  goto done;
3783  }
3784 
3785  BufferSize = sizeof(USER_MODALS_INFO_0);
3786  break;
3787 
3788  case 1:
3789  /* return logon server and domain controller info */
3790  Status = SamQueryInformationDomain(DomainHandle,
3792  (PVOID*)&ServerRoleInfo);
3793  if (!NT_SUCCESS(Status))
3794  {
3795  ApiStatus = NetpNtStatusToApiStatus(Status);
3796  goto done;
3797  }
3798 
3799  Status = SamQueryInformationDomain(DomainHandle,
3801  (PVOID*)&ReplicationInfo);
3802  if (!NT_SUCCESS(Status))
3803  {
3804  ApiStatus = NetpNtStatusToApiStatus(Status);
3805  goto done;
3806  }
3807 
3808  BufferSize = sizeof(USER_MODALS_INFO_1) +
3809  ReplicationInfo->ReplicaSourceNodeName.Length + sizeof(WCHAR);
3810  break;
3811 
3812  case 2:
3813  /* return domain name and identifier */
3814  Status = SamQueryInformationDomain(DomainHandle,
3816  (PVOID*)&NameInfo);
3817  if (!NT_SUCCESS(Status))
3818  {
3819  ApiStatus = NetpNtStatusToApiStatus(Status);
3820  goto done;
3821  }
3822 
3823  BufferSize = sizeof( USER_MODALS_INFO_2 ) +
3824  NameInfo->DomainName.Length + sizeof(WCHAR) +
3825  RtlLengthSid(DomainSid);
3826  break;
3827 
3828  case 3:
3829  /* return lockout information */
3830  Status = SamQueryInformationDomain(DomainHandle,
3832  (PVOID*)&LockoutInfo);
3833  if (!NT_SUCCESS(Status))
3834  {
3835  ApiStatus = NetpNtStatusToApiStatus(Status);
3836  goto done;
3837  }
3838 
3839  BufferSize = sizeof(USER_MODALS_INFO_3);
3840  break;
3841 
3842  default:
3843  TRACE("Invalid level %d is specified\n", level);
3844  ApiStatus = ERROR_INVALID_LEVEL;
3845  goto done;
3846  }
3847 
3848 
3849  ApiStatus = NetApiBufferAllocate(BufferSize,
3850  (LPVOID *)bufptr);
3851  if (ApiStatus != NERR_Success)
3852  {
3853  WARN("NetApiBufferAllocate() failed\n");
3854  goto done;
3855  }
3856 
3857  switch (level)
3858  {
3859  case 0:
3860  umi0 = (PUSER_MODALS_INFO_0)*bufptr;
3861 
3862  umi0->usrmod0_min_passwd_len = PasswordInfo->MinPasswordLength;
3863  umi0->usrmod0_max_passwd_age = (ULONG)(-PasswordInfo->MaxPasswordAge.QuadPart / 10000000);
3864  umi0->usrmod0_min_passwd_age =
3865  DeltaTimeToSeconds(PasswordInfo->MinPasswordAge);
3866  umi0->usrmod0_force_logoff =
3867  DeltaTimeToSeconds(LogoffInfo->ForceLogoff);
3868  umi0->usrmod0_password_hist_len = PasswordInfo->PasswordHistoryLength;
3869  break;
3870 
3871  case 1:
3872  umi1 = (PUSER_MODALS_INFO_1)*bufptr;
3873 
3874  switch (ServerRoleInfo->DomainServerRole)
3875  {
3878  break;
3879 
3881  umi1->usrmod1_role = UAS_ROLE_BACKUP;
3882  break;
3883 
3884  default:
3885  ApiStatus = NERR_InternalError;
3886  goto done;
3887  }
3888 
3889  umi1->usrmod1_primary = (LPWSTR)(*bufptr + sizeof(USER_MODALS_INFO_1));
3891  ReplicationInfo->ReplicaSourceNodeName.Buffer,
3892  ReplicationInfo->ReplicaSourceNodeName.Length);
3893  umi1->usrmod1_primary[ReplicationInfo->ReplicaSourceNodeName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3894  break;
3895 
3896  case 2:
3897  umi2 = (PUSER_MODALS_INFO_2)*bufptr;
3898 
3899  umi2->usrmod2_domain_name = (LPWSTR)(*bufptr + sizeof(USER_MODALS_INFO_2));
3901  NameInfo->DomainName.Buffer,
3902  NameInfo->DomainName.Length);
3903  umi2->usrmod2_domain_name[NameInfo->DomainName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3904 
3905  umi2->usrmod2_domain_id = *bufptr +
3906  sizeof(USER_MODALS_INFO_2) +
3907  NameInfo->DomainName.Length + sizeof(WCHAR);
3909  DomainSid,
3910  RtlLengthSid(DomainSid));
3911  break;
3912 
3913  case 3:
3914  umi3 = (PUSER_MODALS_INFO_3)*bufptr;
3915  umi3->usrmod3_lockout_duration =
3916  DeltaTimeToSeconds(LockoutInfo->LockoutDuration);
3919  umi3->usrmod3_lockout_threshold = LockoutInfo->LockoutThreshold;
3920  break;
3921  }
3922 
3923 done:
3924  if (LockoutInfo != NULL)
3925  SamFreeMemory(LockoutInfo);
3926 
3927  if (NameInfo != NULL)
3928  SamFreeMemory(NameInfo);
3929 
3930  if (ReplicationInfo != NULL)
3931  SamFreeMemory(ReplicationInfo);
3932 
3933  if (ServerRoleInfo != NULL)
3934  SamFreeMemory(ServerRoleInfo);
3935 
3936  if (LogoffInfo != NULL)
3937  SamFreeMemory(LogoffInfo);
3938 
3939  if (PasswordInfo != NULL)
3940  SamFreeMemory(PasswordInfo);
3941 
3942  if (DomainSid != NULL)
3943  RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
3944 
3945  if (DomainHandle != NULL)
3946  SamCloseHandle(DomainHandle);
3947 
3948  if (ServerHandle != NULL)
3949  SamCloseHandle(ServerHandle);
3950 
3951  return ApiStatus;
3952 }
3953 
3954 
3955 /******************************************************************************
3956  * NetUserModalsSet (NETAPI32.@)
3957  */
3959 WINAPI
3961  IN DWORD level,
3962  IN LPBYTE buf,
3963  OUT LPDWORD parm_err)
3964 {
3965  FIXME("(%s %d %p %p)\n", debugstr_w(servername), level, buf, parm_err);
3966  return ERROR_ACCESS_DENIED;
3967 }
3968 
3969 
3970 /******************************************************************************
3971  * NetUserSetGroups (NETAPI32.@)
3972  */
3974 WINAPI
3976  LPCWSTR username,
3977  DWORD level,
3978  LPBYTE buf,
3979  DWORD num_entries)
3980 {
3981  FIXME("(%s %s %lu %p %lu)\n",
3982  debugstr_w(servername), debugstr_w(username), level, buf, num_entries);
3983  return ERROR_ACCESS_DENIED;
3984 }
3985 
3986 
3987 /******************************************************************************
3988  * NetUserSetInfo (NETAPI32.@)
3989  */
3991 WINAPI
3993  LPCWSTR username,
3994  DWORD level,
3995  LPBYTE buf,
3996  LPDWORD parm_err)
3997 {
3998  UNICODE_STRING ServerName;
3999  UNICODE_STRING UserName;
4000  SAM_HANDLE ServerHandle = NULL;
4001  SAM_HANDLE AccountDomainHandle = NULL;
4002  SAM_HANDLE UserHandle = NULL;
4003  NET_API_STATUS ApiStatus = NERR_Success;
4005 
4006  TRACE("(%s %s %lu %p %p)\n",
4007  debugstr_w(servername), debugstr_w(username), level, buf, parm_err);
4008 
4009  if (parm_err != NULL)
4010  *parm_err = PARM_ERROR_NONE;
4011 
4012  /* Check the info level */
4013  switch (level)
4014  {
4015  case 0:
4016  case 1:
4017  case 2:
4018  case 3:
4019  case 4:
4020 // case 21:
4021  case 22:
4022  case 1003:
4023 // case 1005:
4024  case 1006:
4025  case 1007:
4026  case 1008:
4027  case 1009:
4028 // case 1010:
4029  case 1011:
4030  case 1012:
4031  case 1013:
4032  case 1014:
4033  case 1017:
4034  case 1018:
4035  case 1020:
4036  case 1024:
4037  case 1025:
4038  case 1051:
4039  case 1052:
4040  case 1053:
4041  break;
4042 
4043  default:
4044  return ERROR_INVALID_LEVEL;
4045  }
4046 
4047  if (servername != NULL)
4048  RtlInitUnicodeString(&ServerName, servername);
4049 
4050  RtlInitUnicodeString(&UserName, username);
4051 
4052  /* Connect to the SAM Server */
4053  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
4054  &ServerHandle,
4056  NULL);
4057  if (!NT_SUCCESS(Status))
4058  {
4059  ERR("SamConnect failed (Status %08lx)\n", Status);
4060  ApiStatus = NetpNtStatusToApiStatus(Status);
4061  goto done;
4062  }
4063 
4064  /* Open the Account Domain */
4065  Status = OpenAccountDomain(ServerHandle,
4066  (servername != NULL) ? &ServerName : NULL,
4068  &AccountDomainHandle);
4069  if (!NT_SUCCESS(Status))
4070  {
4071  ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
4072  ApiStatus = NetpNtStatusToApiStatus(Status);
4073  goto done;
4074  }
4075 
4076  /* Open the User Account */
4077  ApiStatus = OpenUserByName(AccountDomainHandle,
4078  &UserName,
4080  &UserHandle);
4081  if (ApiStatus != NERR_Success)
4082  {
4083  ERR("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus);
4084  goto done;
4085  }
4086 
4087  /* Set user information */
4088  ApiStatus = SetUserInfo(UserHandle,
4089  buf,
4090  level,
4091  parm_err);
4092  if (ApiStatus != NERR_Success)
4093  {
4094  ERR("SetUserInfo failed (Status %lu)\n", ApiStatus);
4095  }
4096 
4097 done:
4098  if (UserHandle != NULL)
4099  SamCloseHandle(UserHandle);
4100 
4101  if (AccountDomainHandle != NULL)
4102  SamCloseHandle(AccountDomainHandle);
4103 
4104  if (ServerHandle != NULL)
4105  SamCloseHandle(ServerHandle);
4106 
4107  return ApiStatus;
4108 }
4109 
4110 /* EOF */
#define AF_OP_ACCOUNTS
Definition: lmaccess.h:48
static ULONG GetAccountControl(ULONG Flags)
Definition: user.c:206
#define USER_INTERDOMAIN_TRUST_ACCOUNT
Definition: ntsam.h:173
DWORD usri4_password_expired
Definition: lmaccess.h:298
DWORD usri4_last_logoff
Definition: lmaccess.h:284
NET_API_STATUS WINAPI NetApiBufferAllocate(DWORD ByteCount, LPVOID *Buffer)
Definition: apibuf.c:28
LPWSTR usri11_usr_comment
Definition: lmaccess.h:309
LPWSTR usri1014_workstations
Definition: lmaccess.h:402
LOGON_HOURS LogonHours
Definition: ntsam.h:682
#define USER_ALL_PARAMETERS
Definition: ntsam.h:217
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
NTSTATUS NTAPI SamCloseHandle(IN SAM_HANDLE SamHandle)
Definition: samlib.c:476
#define USER_PASSWORD_EXPIRED
Definition: ntsam.h:184
DWORD usri11_auth_flags
Definition: lmaccess.h:312
DWORD usri1_password_age
Definition: lmaccess.h:205
NTSTATUS NTAPI SamGetGroupsForUser(IN SAM_HANDLE UserHandle, OUT PGROUP_MEMBERSHIP *Groups, OUT PULONG MembershipCount)
Definition: samlib.c:1058
#define SAM_SERVER_CONNECT
Definition: ntsam.h:99
LPWSTR usri1_password
Definition: lmaccess.h:204
GLint level
Definition: gl.h:1546
#define IN
Definition: typedefs.h:38
LPWSTR usri22_parms
Definition: lmaccess.h:350
ULONG PrimaryGroupId
Definition: ntsam.h:679
LPWSTR usri3_comment
Definition: lmaccess.h:244
struct _USER_INFO_1006 * PUSER_INFO_1006
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define USER_ALL_ACCOUNTEXPIRES
Definition: ntsam.h:215
#define USER_UNITS_PER_WEEK_PARMNUM
Definition: lmaccess.h:71
DWORD usri11_units_per_week
Definition: lmaccess.h:324
LARGE_INTEGER AccountExpires
Definition: ntsam.h:661
#define MSV1_0_PACKAGE_NAME
Definition: ntsecapi.h:42
struct _USER_INFO_4 * PUSER_INFO_4
LPWSTR usri23_name
Definition: lmaccess.h:365
LPWSTR usri3_parms
Definition: lmaccess.h:250
LPWSTR usri2_logon_server
Definition: lmaccess.h:234
#define USER_PASSWORD_NOT_REQUIRED
Definition: ntsam.h:169
PBYTE usri11_logon_hours
Definition: lmaccess.h:325
DWORD usri3_bad_pw_count
Definition: lmaccess.h:258
UNICODE_STRING ScriptPath
Definition: ntsam.h:668
struct _MSV1_0_CHANGEPASSWORD_REQUEST MSV1_0_CHANGEPASSWORD_REQUEST
LPWSTR usri11_logon_server
Definition: lmaccess.h:320
CRITICAL_SECTION g_EnumContextListLock
Definition: user.c:57
BOOLEAN PasswordExpired
Definition: ntsam.h:689
static unsigned int bufptr
Definition: tncon.cpp:77
static NET_API_STATUS BuildUserInfoBuffer(_In_ SAM_HANDLE BuiltinDomainHandle, _In_ SAM_HANDLE UserHandle, _In_ PSID AccountDomainSid, _In_ ULONG RelativeId, _In_ DWORD level, _Out_ LPVOID *Buffer)
Definition: user.c:550
USHORT CountryCode
Definition: ntsam.h:685
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define DOMAIN_GET_ALIAS_MEMBERSHIP
Definition: ntsam.h:40
#define UF_INTERDOMAIN_TRUST_ACCOUNT
Definition: lmaccess.h:31
UNICODE_STRING PrivateData
Definition: ntsam.h:676
LARGE_INTEGER LockoutDuration
Definition: ntsam.h:422
struct _USER_MODALS_INFO_1 USER_MODALS_INFO_1
struct _USER_INFO_1009 * PUSER_INFO_1009
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
struct _SID SID
struct _USER_INFO_11 * PUSER_INFO_11
BOOLEAN NTAPI RtlTimeToSecondsSince1970(PLARGE_INTEGER Time, PULONG ElapsedSeconds)
SAM_HANDLE BuiltinDomainHandle
Definition: local_group.c:36
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
LPWSTR usri3_home_dir
Definition: lmaccess.h:243
struct _USER_INFO_20 USER_INFO_20
DWORD usri2_priv
Definition: lmaccess.h:216
NTSYSAPI VOID NTAPI RtlSecondsSince1970ToTime(_In_ ULONG SecondsSince1970, _Out_ PLARGE_INTEGER Time)
static NET_API_STATUS OpenUserByName(SAM_HANDLE DomainHandle, PUNICODE_STRING UserName, ULONG DesiredAccess, PSAM_HANDLE UserHandle)
Definition: user.c:2232
#define DOMAIN_ALIAS_RID_ACCOUNT_OPS
Definition: setypes.h:629
DWORD usri11_last_logon
Definition: lmaccess.h:316
DWORD usri2_num_logons
Definition: lmaccess.h:233
UNICODE_STRING HomeDirectoryDrive
Definition: ntsam.h:667
struct _USER_MODALS_INFO_1 * PUSER_MODALS_INFO_1
DOMAIN_SERVER_ROLE DomainServerRole
Definition: ntsam.h:391
DWORD usri11_last_logoff
Definition: lmaccess.h:317
DWORD usrmod3_lockout_threshold
Definition: lmaccess.h:450
LPWSTR usri3_profile
Definition: lmaccess.h:265
NTSTATUS NTAPI SamOpenDomain(IN SAM_HANDLE ServerHandle, IN ACCESS_MASK DesiredAccess, IN PSID DomainId, OUT PSAM_HANDLE DomainHandle)
Definition: samlib.c:1441
struct _USER_INFO_1018 * PUSER_INFO_1018
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define WARN(fmt,...)
Definition: debug.h:111
LPWSTR usri2_name
Definition: lmaccess.h:213
#define USER_TEMP_DUPLICATE_ACCOUNT
Definition: ntsam.h:170
#define ERROR_NONE_MAPPED
Definition: winerror.h:814
LONG NTSTATUS
Definition: precomp.h:26
LPWSTR usri22_workstations
Definition: lmaccess.h:351
static SID_IDENTIFIER_AUTHORITY WorldAuthority
Definition: security.c:14
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
struct _USER_INFO_10 USER_INFO_10
LPWSTR usri0_name
Definition: lmaccess.h:201
DWORD usri1025_code_page
Definition: lmaccess.h:421
#define UF_TEMP_DUPLICATE_ACCOUNT
Definition: lmaccess.h:29
UNICODE_STRING Name
Definition: ntsam.h:268
DWORD usri3_code_page
Definition: lmaccess.h:262
LPWSTR usrmod1_primary
Definition: lmaccess.h:441
DWORD usri22_country_code
Definition: lmaccess.h:361
PSAM_RID_ENUMERATION Buffer
Definition: local_group.c:40
LPWSTR usri4_home_dir
Definition: lmaccess.h:274
struct _USER_INFO_10 * PUSER_INFO_10
LPWSTR usri10_comment
Definition: lmaccess.h:302
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DWORD usri22_code_page
Definition: lmaccess.h:362
DWORD usrmod3_lockout_duration
Definition: lmaccess.h:448
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define ZeroMemory
Definition: winbase.h:1635
NTSYSAPI PULONG NTAPI RtlSubAuthoritySid(_In_ PSID Sid, _In_ ULONG SubAuthority)
#define USER_ALL_LOGONHOURS
Definition: ntsam.h:209
NTSTATUS NTAPI SamQueryInformationDomain(IN SAM_HANDLE DomainHandle, IN DOMAIN_INFORMATION_CLASS DomainInformationClass, OUT PVOID *Buffer)
Definition: samlib.c:1641
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
LPWSTR usri10_name
Definition: lmaccess.h:301
BOOLEAN BuiltinDone
Definition: user.c:52
DWORD usri3_acct_expires
Definition: lmaccess.h:254
NTSYSAPI NTSTATUS NTAPI RtlGetAce(PACL Acl, ULONG AceIndex, PVOID *Ace)
#define AF_OP_SERVER
Definition: lmaccess.h:47
LPWSTR usri1011_full_name
Definition: lmaccess.h:393
LPWSTR usri11_full_name
Definition: lmaccess.h:310
struct _USER_INFO_4 USER_INFO_4
#define USER_HOME_DIRECTORY_REQUIRED
Definition: ntsam.h:168
DWORD usri4_flags
Definition: lmaccess.h:276
NTSTATUS NTAPI SamEnumerateUsersInDomain(IN SAM_HANDLE DomainHandle, IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, IN ULONG UserAccountControl, OUT PVOID *Buffer, IN ULONG PreferedMaximumLength, OUT PULONG CountReturned)
Definition: samlib.c:897
UNICODE_STRING ProfilePath
Definition: ntsam.h:669
#define MAXLONGLONG
PBYTE usri1020_logon_hours
Definition: lmaccess.h:412
DWORD usri4_auth_flags
Definition: lmaccess.h:278
DWORD usri2_auth_flags
Definition: lmaccess.h:221
PSID BuiltinDomainSid
Definition: globals.c:16
#define NERR_GroupNotFound
Definition: lmerr.h:87
LPWSTR usri4_logon_server
Definition: lmaccess.h:291
int32_t INT_PTR
Definition: typedefs.h:62
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define InsertTailList(ListHead, Entry)
DWORD usri1008_flags
Definition: lmaccess.h:384
struct _USER_INFO_1014 * PUSER_INFO_1014
ULONG UserAccountControl
Definition: ntsam.h:680
static DWORD GetPasswordAge(IN PLARGE_INTEGER PasswordLastSet)
Definition: user.c:243
#define USER_MAX_STORAGE_PARMNUM
Definition: lmaccess.h:70
#define PARM_ERROR_NONE
Definition: lmcons.h:56
NTSTATUS OpenAccountDomain(IN SAM_HANDLE ServerHandle, IN PUNICODE_STRING ServerName, IN ULONG DesiredAccess, OUT PSAM_HANDLE DomainHandle)
Definition: utils.c:113
USHORT UnitsPerWeek
Definition: ntsam.h:474
DWORD usri11_bad_pw_count
Definition: lmaccess.h:318
static PENUM_CONTEXT LookupEnumContext(SAM_ENUMERATE_HANDLE EnumerationHandle)
Definition: user.c:2724
DWORD usri3_num_logons
Definition: lmaccess.h:259
DWORD usri2_acct_expires
Definition: lmaccess.h:228
NTSYSAPI NTSTATUS NTAPI RtlGetDaclSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Out_ PBOOLEAN DaclPresent, _Out_ PACL *Dacl, _Out_ PBOOLEAN DaclDefaulted)
#define STATUS_NONE_MAPPED
Definition: ntstatus.h:337
#define USER_ALL_USERNAME
Definition: ntsam.h:196
DWORD usri4_priv
Definition: lmaccess.h:273
struct _USER_INFO_1007 * PUSER_INFO_1007
#define USER_ACCOUNT_DISABLED
Definition: ntsam.h:167
LPWSTR usri3_home_dir_drive
Definition: lmaccess.h:266
#define NERR_Success
Definition: lmerr.h:5
DWORD usrmod0_min_passwd_len
Definition: lmaccess.h:433
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define USHRT_MAX
Definition: limits.h:38
static ULONG DeltaTimeToSeconds(LARGE_INTEGER DeltaTime)
Definition: user.c:62
struct _USER_MODALS_INFO_3 USER_MODALS_INFO_3
#define NERR_InternalError
Definition: lmerr.h:28
struct _USER_INFO_1012 * PUSER_INFO_1012
DWORD usri2_last_logoff
Definition: lmaccess.h:227
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
DWORD usri4_country_code
Definition: lmaccess.h:292
#define USER_PRIV_USER
Definition: lmaccess.h:117
DWORD usri1024_country_code
Definition: lmaccess.h:418
static NET_API_STATUS SetUserInfo(SAM_HANDLE UserHandle, LPBYTE UserInfo, DWORD Level, PDWORD parm_err)
Definition: user.c:1415
LPWSTR usri1003_password
Definition: lmaccess.h:372
HANDLE LsaHandle
Definition: logon.c:14
#define USER_MAXSTORAGE_UNLIMITED
Definition: lmaccess.h:111
#define UF_PASSWD_CANT_CHANGE
Definition: lmaccess.h:28
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
NTSYSAPI NTSTATUS NTAPI RtlInitializeSid(IN OUT PSID Sid, IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static NTSTATUS GetAccountDomainSid(PRPC_SID *Sid)
Definition: msv1_0.c:25
static NET_API_STATUS GetUserDacl(IN SAM_HANDLE UserHandle, OUT PACL *Dacl)
Definition: user.c:285
unsigned char * LPBYTE
Definition: typedefs.h:52
VOID NTAPI ProtocolStatus(NDIS_HANDLE BindingContext, NDIS_STATUS GenerelStatus, PVOID StatusBuffer, UINT StatusBufferSize)
Called by NDIS when the underlying driver has changed state.
Definition: lan.c:461
#define USER_READ_GENERAL
Definition: ntsam.h:126
#define USER_ALL_FULLNAME
Definition: ntsam.h:197
DWORD usri2_password_age
Definition: lmaccess.h:215
#define UNICODE_NULL
LPWSTR usri20_full_name
Definition: lmaccess.h:330
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
DWORD usri2_units_per_week
Definition: lmaccess.h:230
DWORD usri11_password_age
Definition: lmaccess.h:313
unsigned int BOOL
Definition: ntddk_ex.h:94
DWORD usrmod0_max_passwd_age
Definition: lmaccess.h:434
long LONG
Definition: pedump.c:60
DWORD usri2_max_storage
Definition: lmaccess.h:229
NET_API_STATUS WINAPI NetUserModalsGet(LPCWSTR servername, DWORD level, LPBYTE *bufptr)
Definition: user.c:3676
PUCHAR LogonHours
Definition: ntsam.h:475
DWORD usri4_last_logon
Definition: lmaccess.h:283
struct _USER_INFO_1 USER_INFO_1
DWORD usri3_primary_group_id
Definition: lmaccess.h:264
NTSTATUS NTAPI SamCreateUser2InDomain(IN SAM_HANDLE DomainHandle, IN PUNICODE_STRING AccountName, IN ULONG AccountType, IN ACCESS_MASK DesiredAccess, OUT PSAM_HANDLE UserHandle, OUT PULONG GrantedAccess, OUT PULONG RelativeId)
Definition: samlib.c:594
struct _USER_INFO_1011 * PUSER_INFO_1011
LPWSTR usri4_workstations
Definition: lmaccess.h:282
static NET_API_STATUS GetUserPrivileges(_In_ SAM_HANDLE BuiltinDomainHandle, _In_ SAM_HANDLE UserHandle, _In_ PSID AccountDomainSid, _In_ ULONG RelativeId, _Out_ PDWORD Priv, _Out_ PDWORD AuthFlags)
Definition: user.c:410
LPWSTR usri4_full_name
Definition: lmaccess.h:279
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:110
LPWSTR usri3_full_name
Definition: lmaccess.h:248
NTSTATUS NTAPI SamLookupIdsInDomain(IN SAM_HANDLE DomainHandle, IN ULONG Count, IN PULONG RelativeIds, OUT PUNICODE_STRING *Names, OUT PSID_NAME_USE *Use OPTIONAL)
Definition: samlib.c:1220
PSID AccountDomainSid
Definition: user.c:46
struct _USER_INFO_20 * PUSER_INFO_20
struct _USER_INFO_2 * PUSER_INFO_2
NET_API_STATUS WINAPI NetUserAdd(LPCWSTR servername, DWORD level, LPBYTE bufptr, LPDWORD parm_err)
Definition: user.c:2290
Definition: card.h:12
NTSTATUS NTAPI SamLookupNamesInDomain(IN SAM_HANDLE DomainHandle, IN ULONG Count, IN PUNICODE_STRING Names, OUT PULONG *RelativeIds, OUT PSID_NAME_USE *Use)
Definition: samlib.c:1335
LARGE_INTEGER MinPasswordAge
Definition: ntsam.h:348
#define AF_OP_PRINT
Definition: lmaccess.h:45
DWORD usri4_primary_group_id
Definition: lmaccess.h:295
LPWSTR usri4_password
Definition: lmaccess.h:271
unsigned char BOOLEAN
LPWSTR usri20_comment
Definition: lmaccess.h:331
#define SID_MAX_SUB_AUTHORITIES
Definition: setypes.h:454
struct _USER_INFO_1052 * PUSER_INFO_1052
smooth NULL
Definition: ftsmooth.c:416
struct _USER_INFO_3 USER_INFO_3
LPWSTR usri1009_script_path
Definition: lmaccess.h:387
DWORD usri1017_acct_expires
Definition: lmaccess.h:405
LPWSTR usri22_home_dir
Definition: lmaccess.h:343
DWORD usri3_flags
Definition: lmaccess.h:245
#define _Out_
Definition: no_sal2.h:323
#define SAM_SERVER_LOOKUP_DOMAIN
Definition: ntsam.h:104
SAM_ENUMERATE_HANDLE EnumerationContext
Definition: local_group.c:39
static VOID ChangeUserDacl(IN PACL Dacl, IN ULONG Flags)
Definition: user.c:263
struct _USER_INFO_1053 * PUSER_INFO_1053
#define LG_INCLUDE_INDIRECT
Definition: lmaccess.h:44
Definition: bufpool.h:45
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
LPWSTR usri20_name
Definition: lmaccess.h:329
#define UAS_ROLE_BACKUP
Definition: lmaccess.h:52
#define USER_ALL_USERACCOUNTCONTROL
Definition: ntsam.h:216
#define UF_PASSWD_NOTREQD
Definition: lmaccess.h:27
NTSTATUS NTAPI SamSetInformationUser(IN SAM_HANDLE UserHandle, IN USER_INFORMATION_CLASS UserInformationClass, IN PVOID Buffer)
Definition: samlib.c:1964
static VOID FreeEnumContext(PENUM_CONTEXT EnumContext)
Definition: user.c:2709
NET_API_STATUS WINAPI NetUserGetInfo(LPCWSTR servername, LPCWSTR username, DWORD level, LPBYTE *bufptr)
Definition: user.c:3164
void * PVOID
Definition: retypes.h:9
struct _USER_INFO_1 * PUSER_INFO_1
#define USER_LIST_GROUPS
Definition: ntsam.h:134
UNICODE_STRING AdminComment
Definition: ntsam.h:670
ULONG EnumHandle
Definition: user.c:40
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
LPWSTR usri1007_comment
Definition: lmaccess.h:381
DWORD usri3_last_logoff
Definition: lmaccess.h:253
DWORD usri3_auth_flags
Definition: lmaccess.h:247
UNICODE_STRING DomainName
Definition: ntsam.h:381
struct _USER_INFO_11 USER_INFO_11
static WCHAR username[]
Definition: url.c:32
struct _USER_INFO_1051 * PUSER_INFO_1051
DWORD usri2_country_code
Definition: lmaccess.h:235
LPWSTR usri2_parms
Definition: lmaccess.h:224
struct _USER_MODALS_INFO_2 * PUSER_MODALS_INFO_2
DWORD usri4_units_per_week
Definition: lmaccess.h:287
LONG g_EnumContextHandle
Definition: user.c:58
DWORD NET_API_STATUS
Definition: ms-dtyp.idl:91
LPWSTR usri2_full_name
Definition: lmaccess.h:222
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
DWORD usri11_num_logons
Definition: lmaccess.h:319
LPWSTR usri11_workstations
Definition: lmaccess.h:322
DWORD usri2_code_page
Definition: lmaccess.h:236
NET_API_STATUS WINAPI NetUserGetLocalGroups(LPCWSTR servername, LPCWSTR username, DWORD level, DWORD flags, LPBYTE *bufptr, DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries)
Definition: user.c:3341
LPWSTR usri3_name
Definition: lmaccess.h:239
enum _SID_NAME_USE * PSID_NAME_USE
#define TRACE(s)
Definition: solgame.cpp:4
#define USER_ALL_PRIMARYGROUPID
Definition: ntsam.h:199
#define USER_ALL_HOMEDIRECTORY
Definition: ntsam.h:202
NTSTATUS NTAPI SamDeleteUser(IN SAM_HANDLE UserHandle)
Definition: samlib.c:724
DWORD usri1020_units_per_week
Definition: lmaccess.h:411
DWORD usri22_acct_expires
Definition: lmaccess.h:354
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD usri4_acct_expires
Definition: lmaccess.h:285
LPWSTR usri11_home_dir
Definition: lmaccess.h:314
struct _USER_INFO_23 * PUSER_INFO_23
__wchar_t WCHAR
Definition: xmlstorage.h:180
LPWSTR usri2_workstations
Definition: lmaccess.h:225
LPWSTR usri1_comment
Definition: lmaccess.h:208
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _ENUM_CONTEXT * PENUM_CONTEXT
#define USER_READ_ACCOUNT
Definition: ntsam.h:130
struct _USER_INFO_1008 * PUSER_INFO_1008
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:499
NET_API_STATUS WINAPI NetUserModalsSet(IN LPCWSTR servername, IN DWORD level, IN LPBYTE buf, OUT LPDWORD parm_err)
Definition: user.c:3960
DWORD usri11_max_storage
Definition: lmaccess.h:323
DWORD usri4_code_page
Definition: lmaccess.h:293
LPWSTR usri3_logon_server
Definition: lmaccess.h:260
struct _USER_MODALS_INFO_2 USER_MODALS_INFO_2
struct _USER_INFO_22 * PUSER_INFO_22
SAM_HANDLE AccountDomainHandle
Definition: local_group.c:37
#define UAS_ROLE_PRIMARY
Definition: lmaccess.h:53
struct _USER_INFO_1025 * PUSER_INFO_1025
LPWSTR usri2_script_path
Definition: lmaccess.h:220
PSID BuiltinDomainSid
Definition: user.c:45
LARGE_INTEGER MaxPasswordAge
Definition: ntsam.h:347
#define DOMAIN_READ_PASSWORD_PARAMETERS
Definition: ntsam.h:33
#define UF_SERVER_TRUST_ACCOUNT
Definition: lmaccess.h:33
#define WINAPI
Definition: msvc.h:8
struct _USER_INFO_1017 * PUSER_INFO_1017
UNICODE_STRING HomeDirectory
Definition: ntsam.h:666
static VOID FreeUserInfo(PUSER_ALL_INFORMATION UserInfo)
Definition: user.c:366
LPWSTR usri11_comment
Definition: lmaccess.h:308
#define CopyMemory
Definition: winbase.h:1633
static const UCHAR Index[8]
Definition: usbohci.c:18
#define DOMAIN_ALIAS_RID_SYSTEM_OPS
Definition: setypes.h:630
static NET_API_STATUS AllocateEnumContext(PENUM_CONTEXT *AllocatedEnumContext)
Definition: user.c:2673
#define BufferSize
Definition: classpnp.h:419
NET_API_STATUS WINAPI NetUserSetGroups(LPCWSTR servername, LPCWSTR username, DWORD level, LPBYTE buf, DWORD num_entries)
Definition: user.c:3975
DWORD usri20_flags
Definition: lmaccess.h:332
LPWSTR usri4_profile
Definition: lmaccess.h:296
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ACCESS_ALLOWED_ACE_TYPE
Definition: setypes.h:685
#define WRITE_DAC
Definition: nt_native.h:59
#define USER_ALL_ACCESS
Definition: ntsam.h:153
#define USER_NORMAL_ACCOUNT
Definition: ntsam.h:171
LPWSTR usri11_name
Definition: lmaccess.h:307
DWORD usri4_max_storage
Definition: lmaccess.h:286
NET_API_STATUS WINAPI NetUserGetGroups(LPCWSTR servername, LPCWSTR username, DWORD level, LPBYTE *bufptr, DWORD prefixmaxlen, LPDWORD entriesread, LPDWORD totalentries)
Definition: user.c:2999
#define DOMAIN_CREATE_USER
Definition: ntsam.h:37
#define USER_ALL_ADMINCOMMENT
Definition: ntsam.h:200
DWORD usri4_password_age
Definition: lmaccess.h:272
LPWSTR usri1_name
Definition: lmaccess.h:203
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
LPWSTR usri2_home_dir
Definition: lmaccess.h:217
LPWSTR usri11_parms
Definition: lmaccess.h:315
DWORD usrmod0_password_hist_len
Definition: lmaccess.h:437
PSID usri4_user_sid
Definition: lmaccess.h:294
#define SECURITY_WORLD_RID
Definition: setypes.h:513
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
GLbitfield f