ReactOS  0.4.15-dev-1367-g07cc0b5
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_1020 UserInfo1020;
1438  PUSER_INFO_1024 UserInfo1024;
1439  PUSER_INFO_1025 UserInfo1025;
1440  PUSER_INFO_1051 UserInfo1051;
1441  PUSER_INFO_1052 UserInfo1052;
1442  PUSER_INFO_1053 UserInfo1053;
1443  PACL Dacl = NULL;
1444  NET_API_STATUS ApiStatus = NERR_Success;
1446 
1447  ZeroMemory(&UserAllInfo, sizeof(USER_ALL_INFORMATION));
1448 
1449  if ((Level == 1) || (Level == 2) || (Level == 3) ||
1450  (Level == 4) || (Level == 22) || (Level == 1008))
1451  {
1452  ApiStatus = GetUserDacl(UserHandle, &Dacl);
1453  if (ApiStatus != NERR_Success)
1454  goto done;
1455  }
1456 
1457  switch (Level)
1458  {
1459  case 0:
1460  UserInfo0 = (PUSER_INFO_0)UserInfo;
1461 
1462  RtlInitUnicodeString(&UserAllInfo.UserName,
1463  UserInfo0->usri0_name);
1464 
1465  UserAllInfo.WhichFields |= USER_ALL_USERNAME;
1466  break;
1467 
1468  case 1:
1469  UserInfo1 = (PUSER_INFO_1)UserInfo;
1470 
1471  // usri1_name ignored
1472 
1473  if (UserInfo1->usri1_password != NULL)
1474  {
1475  RtlInitUnicodeString(&UserAllInfo.NtPassword,
1476  UserInfo1->usri1_password);
1477  UserAllInfo.NtPasswordPresent = TRUE;
1478  UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1479  }
1480 
1481  // usri1_password_age ignored
1482 
1483 // UserInfo1->usri1_priv
1484 
1485  if (UserInfo1->usri1_home_dir != NULL)
1486  {
1487  RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1488  UserInfo1->usri1_home_dir);
1489  UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1490  }
1491 
1492  if (UserInfo1->usri1_comment != NULL)
1493  {
1494  RtlInitUnicodeString(&UserAllInfo.AdminComment,
1495  UserInfo1->usri1_comment);
1496  UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1497  }
1498 
1499  ChangeUserDacl(Dacl, UserInfo1->usri1_flags);
1500  UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1->usri1_flags);
1502 
1503  if (UserInfo1->usri1_script_path != NULL)
1504  {
1505  RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1506  UserInfo1->usri1_script_path);
1507  UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1508  }
1509  break;
1510 
1511  case 2:
1512  UserInfo2 = (PUSER_INFO_2)UserInfo;
1513 
1514  // usri2_name ignored
1515 
1516  if (UserInfo2->usri2_password != NULL)
1517  {
1518  RtlInitUnicodeString(&UserAllInfo.NtPassword,
1519  UserInfo2->usri2_password);
1520  UserAllInfo.NtPasswordPresent = TRUE;
1521  UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1522  }
1523 
1524  // usri2_password_age ignored
1525 
1526 // UserInfo2->usri2_priv;
1527 
1528  if (UserInfo2->usri2_home_dir != NULL)
1529  {
1530  RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1531  UserInfo2->usri2_home_dir);
1532  UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1533  }
1534 
1535  if (UserInfo2->usri2_comment != NULL)
1536  {
1537  RtlInitUnicodeString(&UserAllInfo.AdminComment,
1538  UserInfo2->usri2_comment);
1539  UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1540  }
1541 
1542  ChangeUserDacl(Dacl, UserInfo2->usri2_flags);
1543  UserAllInfo.UserAccountControl = GetAccountControl(UserInfo2->usri2_flags);
1545 
1546  if (UserInfo2->usri2_script_path != NULL)
1547  {
1548  RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1549  UserInfo2->usri2_script_path);
1550  UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1551  }
1552 
1553 // UserInfo2->usri2_auth_flags;
1554 
1555  if (UserInfo2->usri2_full_name != NULL)
1556  {
1557  RtlInitUnicodeString(&UserAllInfo.FullName,
1558  UserInfo2->usri2_full_name);
1559  UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1560  }
1561 
1562  if (UserInfo2->usri2_usr_comment != NULL)
1563  {
1564  RtlInitUnicodeString(&UserAllInfo.UserComment,
1565  UserInfo2->usri2_usr_comment);
1566  UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1567  }
1568 
1569  if (UserInfo2->usri2_parms != NULL)
1570  {
1571  RtlInitUnicodeString(&UserAllInfo.Parameters,
1572  UserInfo2->usri2_parms);
1573  UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1574  }
1575 
1576  if (UserInfo2->usri2_workstations != NULL)
1577  {
1578  RtlInitUnicodeString(&UserAllInfo.WorkStations,
1579  UserInfo2->usri2_workstations);
1580  UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1581  }
1582 
1583  // usri2_last_logon ignored
1584  // usri2_last_logoff ignored
1585 
1586  if (UserInfo2->usri2_acct_expires == TIMEQ_FOREVER)
1587  {
1588  UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
1589  }
1590  else
1591  {
1593  &UserAllInfo.AccountExpires);
1594  }
1595  UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1596 
1597  // usri2_max_storage ignored
1598 
1599  if (UserInfo2->usri2_logon_hours != NULL)
1600  {
1601  if (UserInfo2->usri2_units_per_week > USHRT_MAX)
1602  {
1603  if (parm_err != NULL)
1604  *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
1605  ApiStatus = ERROR_INVALID_PARAMETER;
1606  break;
1607  }
1608 
1609  UserAllInfo.LogonHours.UnitsPerWeek = UserInfo2->usri2_units_per_week;
1610  UserAllInfo.LogonHours.LogonHours = UserInfo2->usri2_logon_hours;
1611  UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
1612  }
1613 
1614  // usri2_bad_pw_count ignored
1615  // usri2_num_logons ignored
1616  // usri2_logon_server ignored
1617 
1618  UserAllInfo.CountryCode = UserInfo2->usri2_country_code;
1619  UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1620 
1621  UserAllInfo.CodePage = UserInfo2->usri2_code_page;
1622  UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1623  break;
1624 
1625  case 3:
1626  UserInfo3 = (PUSER_INFO_3)UserInfo;
1627 
1628  // usri3_name ignored
1629 
1630  if (UserInfo3->usri3_password != NULL)
1631  {
1632  RtlInitUnicodeString(&UserAllInfo.NtPassword,
1633  UserInfo3->usri3_password);
1634  UserAllInfo.NtPasswordPresent = TRUE;
1635  UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1636  }
1637 
1638  // usri3_password_age ignored
1639 
1640 // UserInfo3->usri3_priv;
1641 
1642  if (UserInfo3->usri3_home_dir != NULL)
1643  {
1644  RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1645  UserInfo3->usri3_home_dir);
1646  UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1647  }
1648 
1649  if (UserInfo3->usri3_comment != NULL)
1650  {
1651  RtlInitUnicodeString(&UserAllInfo.AdminComment,
1652  UserInfo3->usri3_comment);
1653  UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1654  }
1655 
1656  ChangeUserDacl(Dacl, UserInfo3->usri3_flags);
1657  UserAllInfo.UserAccountControl = GetAccountControl(UserInfo3->usri3_flags);
1659 
1660  if (UserInfo3->usri3_script_path != NULL)
1661  {
1662  RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1663  UserInfo3->usri3_script_path);
1664  UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1665  }
1666 
1667 // UserInfo3->usri3_auth_flags;
1668 
1669  if (UserInfo3->usri3_full_name != NULL)
1670  {
1671  RtlInitUnicodeString(&UserAllInfo.FullName,
1672  UserInfo3->usri3_full_name);
1673  UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1674  }
1675 
1676  if (UserInfo3->usri3_usr_comment != NULL)
1677  {
1678  RtlInitUnicodeString(&UserAllInfo.UserComment,
1679  UserInfo3->usri3_usr_comment);
1680  UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1681  }
1682 
1683  if (UserInfo3->usri3_parms != NULL)
1684  {
1685  RtlInitUnicodeString(&UserAllInfo.Parameters,
1686  UserInfo3->usri3_parms);
1687  UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1688  }
1689 
1690  if (UserInfo3->usri3_workstations != NULL)
1691  {
1692  RtlInitUnicodeString(&UserAllInfo.WorkStations,
1693  UserInfo3->usri3_workstations);
1694  UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1695  }
1696 
1697  // usri3_last_logon ignored
1698  // usri3_last_logoff ignored
1699 
1700  if (UserInfo3->usri3_acct_expires == TIMEQ_FOREVER)
1701  {
1702  UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
1703  }
1704  else
1705  {
1707  &UserAllInfo.AccountExpires);
1708  }
1709  UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1710 
1711  // usri3_max_storage ignored
1712 
1713  if (UserInfo3->usri3_logon_hours != NULL)
1714  {
1715  if (UserInfo3->usri3_units_per_week > USHRT_MAX)
1716  {
1717  if (parm_err != NULL)
1718  *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
1719  ApiStatus = ERROR_INVALID_PARAMETER;
1720  break;
1721  }
1722 
1723  UserAllInfo.LogonHours.UnitsPerWeek = UserInfo3->usri3_units_per_week;
1724  UserAllInfo.LogonHours.LogonHours = UserInfo3->usri3_logon_hours;
1725  UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
1726  }
1727 
1728  // usri3_bad_pw_count ignored
1729  // usri3_num_logons ignored
1730  // usri3_logon_server ignored
1731 
1732  UserAllInfo.CountryCode = UserInfo3->usri3_country_code;
1733  UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1734 
1735  UserAllInfo.CodePage = UserInfo3->usri3_code_page;
1736  UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1737 
1738  // usri3_user_id ignored
1739 
1740  UserAllInfo.PrimaryGroupId = UserInfo3->usri3_primary_group_id;
1741  UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
1742 
1743  if (UserInfo3->usri3_profile != NULL)
1744  {
1745  RtlInitUnicodeString(&UserAllInfo.ProfilePath,
1746  UserInfo3->usri3_profile);
1747  UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
1748  }
1749 
1750  if (UserInfo3->usri3_home_dir_drive != NULL)
1751  {
1753  UserInfo3->usri3_home_dir_drive);
1755  }
1756 
1757  UserAllInfo.PasswordExpired = (UserInfo3->usri3_password_expired != 0);
1758  UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED;
1759  break;
1760 
1761  case 4:
1762  UserInfo4 = (PUSER_INFO_4)UserInfo;
1763 
1764  // usri4_name ignored
1765 
1766  if (UserInfo4->usri4_password != NULL)
1767  {
1768  RtlInitUnicodeString(&UserAllInfo.NtPassword,
1769  UserInfo4->usri4_password);
1770  UserAllInfo.NtPasswordPresent = TRUE;
1771  UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1772  }
1773 
1774  // usri4_password_age ignored
1775 
1776 // UserInfo3->usri4_priv;
1777 
1778  if (UserInfo4->usri4_home_dir != NULL)
1779  {
1780  RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1781  UserInfo4->usri4_home_dir);
1782  UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1783  }
1784 
1785  if (UserInfo4->usri4_comment != NULL)
1786  {
1787  RtlInitUnicodeString(&UserAllInfo.AdminComment,
1788  UserInfo4->usri4_comment);
1789  UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1790  }
1791 
1792  ChangeUserDacl(Dacl, UserInfo4->usri4_flags);
1793  UserAllInfo.UserAccountControl = GetAccountControl(UserInfo4->usri4_flags);
1795 
1796  if (UserInfo4->usri4_script_path != NULL)
1797  {
1798  RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1799  UserInfo4->usri4_script_path);
1800  UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1801  }
1802 
1803 // UserInfo4->usri4_auth_flags;
1804 
1805  if (UserInfo4->usri4_full_name != NULL)
1806  {
1807  RtlInitUnicodeString(&UserAllInfo.FullName,
1808  UserInfo4->usri4_full_name);
1809  UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1810  }
1811 
1812  if (UserInfo4->usri4_usr_comment != NULL)
1813  {
1814  RtlInitUnicodeString(&UserAllInfo.UserComment,
1815  UserInfo4->usri4_usr_comment);
1816  UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1817  }
1818 
1819  if (UserInfo4->usri4_parms != NULL)
1820  {
1821  RtlInitUnicodeString(&UserAllInfo.Parameters,
1822  UserInfo4->usri4_parms);
1823  UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1824  }
1825 
1826  if (UserInfo4->usri4_workstations != NULL)
1827  {
1828  RtlInitUnicodeString(&UserAllInfo.WorkStations,
1829  UserInfo4->usri4_workstations);
1830  UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1831  }
1832 
1833  // usri4_last_logon ignored
1834  // usri4_last_logoff ignored
1835 
1836  if (UserInfo4->usri4_acct_expires == TIMEQ_FOREVER)
1837  {
1838  UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
1839  }
1840  else
1841  {
1843  &UserAllInfo.AccountExpires);
1844  }
1845  UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1846 
1847  // usri4_max_storage ignored
1848 
1849  if (UserInfo4->usri4_logon_hours != NULL)
1850  {
1851  if (UserInfo4->usri4_units_per_week > USHRT_MAX)
1852  {
1853  if (parm_err != NULL)
1854  *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
1855  ApiStatus = ERROR_INVALID_PARAMETER;
1856  break;
1857  }
1858 
1859  UserAllInfo.LogonHours.UnitsPerWeek = UserInfo4->usri4_units_per_week;
1860  UserAllInfo.LogonHours.LogonHours = UserInfo4->usri4_logon_hours;
1861  UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
1862  }
1863 
1864  // usri4_bad_pw_count ignored
1865  // usri4_num_logons ignored
1866  // usri4_logon_server ignored
1867 
1868  UserAllInfo.CountryCode = UserInfo4->usri4_country_code;
1869  UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1870 
1871  UserAllInfo.CodePage = UserInfo4->usri4_code_page;
1872  UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1873 
1874  // usri4_user_sid ignored
1875 
1876  UserAllInfo.PrimaryGroupId = UserInfo4->usri4_primary_group_id;
1877  UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
1878 
1879  if (UserInfo4->usri4_profile != NULL)
1880  {
1881  RtlInitUnicodeString(&UserAllInfo.ProfilePath,
1882  UserInfo4->usri4_profile);
1883  UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
1884  }
1885 
1886  if (UserInfo4->usri4_home_dir_drive != NULL)
1887  {
1889  UserInfo4->usri4_home_dir_drive);
1891  }
1892 
1893  UserAllInfo.PasswordExpired = (UserInfo4->usri4_password_expired != 0);
1894  UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED;
1895  break;
1896 
1897 // case 21:
1898 // break;
1899 
1900  case 22:
1901  UserInfo22 = (PUSER_INFO_22)UserInfo;
1902 
1903  // usri22_name ignored
1904 
1905 // UserInfo22->usri22_password[ENCRYPTED_PWLEN];
1906 
1907  // usri22_password_age ignored
1908 
1909 // UserInfo3->usri3_priv;
1910 
1911  if (UserInfo22->usri22_home_dir != NULL)
1912  {
1913  RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1914  UserInfo22->usri22_home_dir);
1915  UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1916  }
1917 
1918  if (UserInfo22->usri22_comment != NULL)
1919  {
1920  RtlInitUnicodeString(&UserAllInfo.AdminComment,
1921  UserInfo22->usri22_comment);
1922  UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1923  }
1924 
1925  ChangeUserDacl(Dacl, UserInfo22->usri22_flags);
1926  UserAllInfo.UserAccountControl = GetAccountControl(UserInfo22->usri22_flags);
1928 
1929  if (UserInfo22->usri22_script_path != NULL)
1930  {
1931  RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1932  UserInfo22->usri22_script_path);
1933  UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1934  }
1935 
1936 // UserInfo22->usri22_auth_flags;
1937 
1938  if (UserInfo22->usri22_full_name != NULL)
1939  {
1940  RtlInitUnicodeString(&UserAllInfo.FullName,
1941  UserInfo22->usri22_full_name);
1942  UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1943  }
1944 
1945  if (UserInfo22->usri22_usr_comment != NULL)
1946  {
1947  RtlInitUnicodeString(&UserAllInfo.UserComment,
1948  UserInfo22->usri22_usr_comment);
1949  UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1950  }
1951 
1952  if (UserInfo22->usri22_parms != NULL)
1953  {
1954  RtlInitUnicodeString(&UserAllInfo.Parameters,
1955  UserInfo22->usri22_parms);
1956  UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1957  }
1958 
1959  if (UserInfo22->usri22_workstations != NULL)
1960  {
1961  RtlInitUnicodeString(&UserAllInfo.WorkStations,
1962  UserInfo22->usri22_workstations);
1963  UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1964  }
1965 
1966  // usri22_last_logon ignored
1967  // usri22_last_logoff ignored
1968 
1969  if (UserInfo22->usri22_acct_expires == TIMEQ_FOREVER)
1970  {
1971  UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
1972  }
1973  else
1974  {
1976  &UserAllInfo.AccountExpires);
1977  }
1978  UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1979 
1980  // usri22_max_storage ignored
1981 
1982  if (UserInfo22->usri22_logon_hours != NULL)
1983  {
1984  if (UserInfo22->usri22_units_per_week > USHRT_MAX)
1985  {
1986  if (parm_err != NULL)
1987  *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
1988  ApiStatus = ERROR_INVALID_PARAMETER;
1989  break;
1990  }
1991 
1992  UserAllInfo.LogonHours.UnitsPerWeek = UserInfo22->usri22_units_per_week;
1993  UserAllInfo.LogonHours.LogonHours = UserInfo22->usri22_logon_hours;
1994  UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
1995  }
1996 
1997  // usri22_bad_pw_count ignored
1998  // usri22_num_logons ignored
1999  // usri22_logon_server ignored
2000 
2001  UserAllInfo.CountryCode = UserInfo22->usri22_country_code;
2002  UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
2003 
2004  UserAllInfo.CodePage = UserInfo22->usri22_code_page;
2005  UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
2006  break;
2007 
2008  case 1003:
2009  UserInfo1003 = (PUSER_INFO_1003)UserInfo;
2010 
2011  if (UserInfo1003->usri1003_password != NULL)
2012  {
2013  RtlInitUnicodeString(&UserAllInfo.NtPassword,
2014  UserInfo1003->usri1003_password);
2015  UserAllInfo.NtPasswordPresent = TRUE;
2016  UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
2017  }
2018  break;
2019 
2020 // case 1005:
2021 // break;
2022 
2023  case 1006:
2024  UserInfo1006 = (PUSER_INFO_1006)UserInfo;
2025 
2026  if (UserInfo1006->usri1006_home_dir != NULL)
2027  {
2028  RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
2029  UserInfo1006->usri1006_home_dir);
2030  UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
2031  }
2032  break;
2033 
2034  case 1007:
2035  UserInfo1007 = (PUSER_INFO_1007)UserInfo;
2036 
2037  if (UserInfo1007->usri1007_comment != NULL)
2038  {
2039  RtlInitUnicodeString(&UserAllInfo.AdminComment,
2040  UserInfo1007->usri1007_comment);
2041  UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
2042  }
2043  break;
2044 
2045  case 1008:
2046  UserInfo1008 = (PUSER_INFO_1008)UserInfo;
2047  ChangeUserDacl(Dacl, UserInfo1008->usri1008_flags);
2048  UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1008->usri1008_flags);
2050  break;
2051 
2052  case 1009:
2053  UserInfo1009 = (PUSER_INFO_1009)UserInfo;
2054 
2055  if (UserInfo1009->usri1009_script_path != NULL)
2056  {
2057  RtlInitUnicodeString(&UserAllInfo.ScriptPath,
2058  UserInfo1009->usri1009_script_path);
2059  UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
2060  }
2061  break;
2062 
2063 // case 1010:
2064 // break;
2065 
2066  case 1011:
2067  UserInfo1011 = (PUSER_INFO_1011)UserInfo;
2068 
2069  if (UserInfo1011->usri1011_full_name != NULL)
2070  {
2071  RtlInitUnicodeString(&UserAllInfo.FullName,
2072  UserInfo1011->usri1011_full_name);
2073  UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
2074  }
2075  break;
2076 
2077  case 1012:
2078  UserInfo1012 = (PUSER_INFO_1012)UserInfo;
2079 
2080  if (UserInfo1012->usri1012_usr_comment != NULL)
2081  {
2082  RtlInitUnicodeString(&UserAllInfo.UserComment,
2083  UserInfo1012->usri1012_usr_comment);
2084  UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
2085  }
2086  break;
2087 
2088  case 1013:
2089  UserInfo1013 = (PUSER_INFO_1013)UserInfo;
2090 
2091  if (UserInfo1013->usri1013_parms != NULL)
2092  {
2093  RtlInitUnicodeString(&UserAllInfo.Parameters,
2094  UserInfo1013->usri1013_parms);
2095  UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
2096  }
2097  break;
2098 
2099  case 1014:
2100  UserInfo1014 = (PUSER_INFO_1014)UserInfo;
2101 
2102  if (UserInfo1014->usri1014_workstations != NULL)
2103  {
2104  RtlInitUnicodeString(&UserAllInfo.WorkStations,
2105  UserInfo1014->usri1014_workstations);
2106  UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
2107  }
2108  break;
2109 
2110  case 1017:
2111  UserInfo1017 = (PUSER_INFO_1017)UserInfo;
2112 
2113  if (UserInfo1017->usri1017_acct_expires == TIMEQ_FOREVER)
2114  {
2115  UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
2116  }
2117  else
2118  {
2120  &UserAllInfo.AccountExpires);
2121  }
2122  UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
2123  break;
2124 
2125  case 1018:
2126  // usri1018_max_storage ignored
2127  break;
2128 
2129  case 1020:
2130  UserInfo1020 = (PUSER_INFO_1020)UserInfo;
2131 
2132  if (UserInfo1020->usri1020_logon_hours != NULL)
2133  {
2134  if (UserInfo1020->usri1020_units_per_week > USHRT_MAX)
2135  {
2136  if (parm_err != NULL)
2137  *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
2138  ApiStatus = ERROR_INVALID_PARAMETER;
2139  break;
2140  }
2141 
2142  UserAllInfo.LogonHours.UnitsPerWeek = UserInfo1020->usri1020_units_per_week;
2143  UserAllInfo.LogonHours.LogonHours = UserInfo1020->usri1020_logon_hours;
2144  UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
2145  }
2146  break;
2147 
2148  case 1024:
2149  UserInfo1024 = (PUSER_INFO_1024)UserInfo;
2150 
2151  UserAllInfo.CountryCode = UserInfo1024->usri1024_country_code;
2152  UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
2153  break;
2154 
2155  case 1025:
2156  UserInfo1025 = (PUSER_INFO_1025)UserInfo;
2157 
2158  UserAllInfo.CodePage = UserInfo1025->usri1025_code_page;
2159  UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
2160  break;
2161 
2162  case 1051:
2163  UserInfo1051 = (PUSER_INFO_1051)UserInfo;
2164 
2165  UserAllInfo.PrimaryGroupId = UserInfo1051->usri1051_primary_group_id;
2166  UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
2167  break;
2168 
2169  case 1052:
2170  UserInfo1052 = (PUSER_INFO_1052)UserInfo;
2171 
2172  if (UserInfo1052->usri1052_profile != NULL)
2173  {
2174  RtlInitUnicodeString(&UserAllInfo.ProfilePath,
2175  UserInfo1052->usri1052_profile);
2176  UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
2177  }
2178  break;
2179 
2180  case 1053:
2181  UserInfo1053 = (PUSER_INFO_1053)UserInfo;
2182 
2183  if (UserInfo1053->usri1053_home_dir_drive != NULL)
2184  {
2186  UserInfo1053->usri1053_home_dir_drive);
2188  }
2189  break;
2190  }
2191 
2192  if (ApiStatus != NERR_Success)
2193  goto done;
2194 
2195  Status = SamSetInformationUser(UserHandle,
2197  &UserAllInfo);
2198  if (!NT_SUCCESS(Status))
2199  {
2200  ERR("SamSetInformationUser failed (Status %08lx)\n", Status);
2201  ApiStatus = NetpNtStatusToApiStatus(Status);
2202  goto done;
2203  }
2204 
2205 done:
2206  if (Dacl != NULL)
2207  HeapFree(GetProcessHeap(), 0, Dacl);
2208 
2209  return ApiStatus;
2210 }
2211 
2212 
2213 static
2216  PUNICODE_STRING UserName,
2218  PSAM_HANDLE UserHandle)
2219 {
2220  PULONG RelativeIds = NULL;
2221  PSID_NAME_USE Use = NULL;
2222  NET_API_STATUS ApiStatus = NERR_Success;
2224 
2225  /* Get the RID for the given user name */
2226  Status = SamLookupNamesInDomain(DomainHandle,
2227  1,
2228  UserName,
2229  &RelativeIds,
2230  &Use);
2231  if (!NT_SUCCESS(Status))
2232  {
2233  ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", UserName, Status);
2235  }
2236 
2237  /* Fail, if it is not an alias account */
2238  if (Use[0] != SidTypeUser)
2239  {
2240  ERR("Object is not a user!\n");
2241  ApiStatus = NERR_GroupNotFound;
2242  goto done;
2243  }
2244 
2245  /* Open the alias account */
2246  Status = SamOpenUser(DomainHandle,
2247  DesiredAccess,
2248  RelativeIds[0],
2249  UserHandle);
2250  if (!NT_SUCCESS(Status))
2251  {
2252  ERR("SamOpenUser failed (Status %08lx)\n", Status);
2253  ApiStatus = NetpNtStatusToApiStatus(Status);
2254  goto done;
2255  }
2256 
2257 done:
2258  if (RelativeIds != NULL)
2259  SamFreeMemory(RelativeIds);
2260 
2261  if (Use != NULL)
2262  SamFreeMemory(Use);
2263 
2264  return ApiStatus;
2265 }
2266 
2267 
2268 /************************************************************
2269  * NetUserAdd (NETAPI32.@)
2270  */
2272 WINAPI
2273 NetUserAdd(LPCWSTR servername,
2274  DWORD level,
2275  LPBYTE bufptr,
2276  LPDWORD parm_err)
2277 {
2278  UNICODE_STRING ServerName;
2279  UNICODE_STRING UserName;
2280  SAM_HANDLE ServerHandle = NULL;
2281  SAM_HANDLE DomainHandle = NULL;
2282  SAM_HANDLE UserHandle = NULL;
2284  ULONG RelativeId;
2285  NET_API_STATUS ApiStatus = NERR_Success;
2287 
2288  TRACE("(%s, %d, %p, %p)\n", debugstr_w(servername), level, bufptr, parm_err);
2289 
2290  if (parm_err != NULL)
2291  *parm_err = PARM_ERROR_NONE;
2292 
2293  /* Check the info level */
2294  switch (level)
2295  {
2296  case 1:
2297  case 2:
2298  case 3:
2299  case 4:
2300  break;
2301 
2302  default:
2303  return ERROR_INVALID_LEVEL;
2304  }
2305 
2306  if (servername != NULL)
2307  RtlInitUnicodeString(&ServerName, servername);
2308 
2309  /* Connect to the SAM Server */
2310  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2311  &ServerHandle,
2313  NULL);
2314  if (!NT_SUCCESS(Status))
2315  {
2316  ERR("SamConnect failed (Status %08lx)\n", Status);
2317  ApiStatus = NetpNtStatusToApiStatus(Status);
2318  goto done;
2319  }
2320 
2321  /* Open the Account Domain */
2322  Status = OpenAccountDomain(ServerHandle,
2323  (servername != NULL) ? &ServerName : NULL,
2325  &DomainHandle);
2326  if (!NT_SUCCESS(Status))
2327  {
2328  ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2329  ApiStatus = NetpNtStatusToApiStatus(Status);
2330  goto done;
2331  }
2332 
2333  /* Initialize the user name string */
2334  RtlInitUnicodeString(&UserName,
2335  ((PUSER_INFO_1)bufptr)->usri1_name);
2336 
2337  /* Create the user account */
2338  Status = SamCreateUser2InDomain(DomainHandle,
2339  &UserName,
2342  &UserHandle,
2343  &GrantedAccess,
2344  &RelativeId);
2345  if (!NT_SUCCESS(Status))
2346  {
2347  ERR("SamCreateUser2InDomain failed (Status %08lx)\n", Status);
2348  ApiStatus = NetpNtStatusToApiStatus(Status);
2349  goto done;
2350  }
2351 
2352  /* Set user information */
2353  ApiStatus = SetUserInfo(UserHandle,
2354  bufptr,
2355  level,
2356  parm_err);
2357  if (ApiStatus != NERR_Success)
2358  {
2359  ERR("SetUserInfo failed (Status %lu)\n", ApiStatus);
2360  goto done;
2361  }
2362 
2363 done:
2364  if (UserHandle != NULL)
2365  {
2366  if (ApiStatus != NERR_Success)
2367  SamDeleteUser(UserHandle);
2368  else
2369  SamCloseHandle(UserHandle);
2370  }
2371 
2372  if (DomainHandle != NULL)
2373  SamCloseHandle(DomainHandle);
2374 
2375  if (ServerHandle != NULL)
2376  SamCloseHandle(ServerHandle);
2377 
2378  return ApiStatus;
2379 }
2380 
2381 
2382 /******************************************************************************
2383  * NetUserChangePassword (NETAPI32.@)
2384  * PARAMS
2385  * domainname [I] Optional. Domain on which the user resides or the logon
2386  * domain of the current user if NULL.
2387  * username [I] Optional. Username to change the password for or the name
2388  * of the current user if NULL.
2389  * oldpassword [I] The user's current password.
2390  * newpassword [I] The password that the user will be changed to using.
2391  *
2392  * RETURNS
2393  * Success: NERR_Success.
2394  * Failure: NERR_* failure code or win error code.
2395  *
2396  */
2398 WINAPI
2400  LPCWSTR username,
2401  LPCWSTR oldpassword,
2402  LPCWSTR newpassword)
2403 {
2404  PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer = NULL;
2405  PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer = NULL;
2406  ULONG RequestBufferSize;
2407  ULONG ResponseBufferSize = 0;
2408  LPWSTR Ptr;
2409  ANSI_STRING PackageName;
2411  HANDLE LsaHandle = NULL;
2412  NET_API_STATUS ApiStatus = NERR_Success;
2415 
2416  TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname), debugstr_w(username));
2417 
2418  /* FIXME: handle null domain or user name */
2419 
2420  /* Check the parameters */
2421  if ((oldpassword == NULL) ||
2422  (newpassword == NULL))
2423  return ERROR_INVALID_PARAMETER;
2424 
2425  /* Connect to the LSA server */
2427  if (!NT_SUCCESS(Status))
2429 
2430  /* Get the authentication package ID */
2431  RtlInitAnsiString(&PackageName,
2433 
2435  &PackageName,
2437  if (!NT_SUCCESS(Status))
2438  {
2439  ApiStatus = NetpNtStatusToApiStatus(Status);
2440  goto done;
2441  }
2442 
2443  /* Calculate the request buffer size */
2444  RequestBufferSize = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST) +
2445  ((wcslen(domainname) + 1) * sizeof(WCHAR)) +
2446  ((wcslen(username) + 1) * sizeof(WCHAR)) +
2447  ((wcslen(oldpassword) + 1) * sizeof(WCHAR)) +
2448  ((wcslen(newpassword) + 1) * sizeof(WCHAR));
2449 
2450  /* Allocate the request buffer */
2451  ApiStatus = NetApiBufferAllocate(RequestBufferSize,
2452  (PVOID*)&RequestBuffer);
2453  if (ApiStatus != NERR_Success)
2454  goto done;
2455 
2456  /* Initialize the request buffer */
2457  RequestBuffer->MessageType = MsV1_0ChangePassword;
2458  RequestBuffer->Impersonating = TRUE;
2459 
2460  Ptr = (LPWSTR)((ULONG_PTR)RequestBuffer + sizeof(MSV1_0_CHANGEPASSWORD_REQUEST));
2461 
2462  /* Pack the domain name */
2463  RequestBuffer->DomainName.Length = wcslen(domainname) * sizeof(WCHAR);
2464  RequestBuffer->DomainName.MaximumLength = RequestBuffer->DomainName.Length + sizeof(WCHAR);
2465  RequestBuffer->DomainName.Buffer = Ptr;
2466 
2467  RtlCopyMemory(RequestBuffer->DomainName.Buffer,
2468  domainname,
2469  RequestBuffer->DomainName.MaximumLength);
2470 
2471  Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->DomainName.MaximumLength);
2472 
2473  /* Pack the user name */
2474  RequestBuffer->AccountName.Length = wcslen(username) * sizeof(WCHAR);
2475  RequestBuffer->AccountName.MaximumLength = RequestBuffer->AccountName.Length + sizeof(WCHAR);
2476  RequestBuffer->AccountName.Buffer = Ptr;
2477 
2478  RtlCopyMemory(RequestBuffer->AccountName.Buffer,
2479  username,
2480  RequestBuffer->AccountName.MaximumLength);
2481 
2482  Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->AccountName.MaximumLength);
2483 
2484  /* Pack the old password */
2485  RequestBuffer->OldPassword.Length = wcslen(oldpassword) * sizeof(WCHAR);
2486  RequestBuffer->OldPassword.MaximumLength = RequestBuffer->OldPassword.Length + sizeof(WCHAR);
2487  RequestBuffer->OldPassword.Buffer = Ptr;
2488 
2489  RtlCopyMemory(RequestBuffer->OldPassword.Buffer,
2490  oldpassword,
2491  RequestBuffer->OldPassword.MaximumLength);
2492 
2493  Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->OldPassword.MaximumLength);
2494 
2495  /* Pack the new password */
2496  RequestBuffer->NewPassword.Length = wcslen(newpassword) * sizeof(WCHAR);
2497  RequestBuffer->NewPassword.MaximumLength = RequestBuffer->NewPassword.Length + sizeof(WCHAR);
2498  RequestBuffer->NewPassword.Buffer = Ptr;
2499 
2500  RtlCopyMemory(RequestBuffer->NewPassword.Buffer,
2501  newpassword,
2502  RequestBuffer->NewPassword.MaximumLength);
2503 
2504  /* Call the authentication package */
2507  RequestBuffer,
2508  RequestBufferSize,
2509  (PVOID*)&ResponseBuffer,
2510  &ResponseBufferSize,
2511  &ProtocolStatus);
2512  if (!NT_SUCCESS(Status))
2513  {
2514  ApiStatus = NetpNtStatusToApiStatus(Status);
2515  goto done;
2516  }
2517 
2518  if (!NT_SUCCESS(ProtocolStatus))
2519  {
2521  goto done;
2522  }
2523 
2524 done:
2525  if (RequestBuffer != NULL)
2526  NetApiBufferFree(RequestBuffer);
2527 
2528  if (ResponseBuffer != NULL)
2529  LsaFreeReturnBuffer(ResponseBuffer);
2530 
2531  if (LsaHandle != NULL)
2532  NtClose(LsaHandle);
2533 
2534  return ApiStatus;
2535 }
2536 
2537 
2538 /************************************************************
2539  * NetUserDel (NETAPI32.@)
2540  */
2542 WINAPI
2543 NetUserDel(LPCWSTR servername,
2544  LPCWSTR username)
2545 {
2546  UNICODE_STRING ServerName;
2547  UNICODE_STRING UserName;
2548  SAM_HANDLE ServerHandle = NULL;
2549  SAM_HANDLE DomainHandle = NULL;
2550  SAM_HANDLE UserHandle = NULL;
2551  NET_API_STATUS ApiStatus = NERR_Success;
2553 
2554  TRACE("(%s, %s)\n", debugstr_w(servername), debugstr_w(username));
2555 
2556  if (servername != NULL)
2557  RtlInitUnicodeString(&ServerName, servername);
2558 
2559  RtlInitUnicodeString(&UserName, username);
2560 
2561  /* Connect to the SAM Server */
2562  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2563  &ServerHandle,
2565  NULL);
2566  if (!NT_SUCCESS(Status))
2567  {
2568  ERR("SamConnect failed (Status %08lx)\n", Status);
2569  ApiStatus = NetpNtStatusToApiStatus(Status);
2570  goto done;
2571  }
2572 
2573  /* Open the Builtin Domain */
2574  Status = OpenBuiltinDomain(ServerHandle,
2575  DOMAIN_LOOKUP,
2576  &DomainHandle);
2577  if (!NT_SUCCESS(Status))
2578  {
2579  ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status);
2580  ApiStatus = NetpNtStatusToApiStatus(Status);
2581  goto done;
2582  }
2583 
2584  /* Open the user account in the builtin domain */
2585  ApiStatus = OpenUserByName(DomainHandle,
2586  &UserName,
2587  DELETE,
2588  &UserHandle);
2589  if (ApiStatus != NERR_Success && ApiStatus != ERROR_NONE_MAPPED)
2590  {
2591  TRACE("OpenUserByName(%wZ) failed (ApiStatus %lu)\n", &UserName, ApiStatus);
2592  goto done;
2593  }
2594 
2595  if (UserHandle == NULL)
2596  {
2597  if (DomainHandle != NULL)
2598  {
2599  SamCloseHandle(DomainHandle);
2600  DomainHandle = NULL;
2601  }
2602 
2603  /* Open the Acount Domain */
2604  Status = OpenAccountDomain(ServerHandle,
2605  (servername != NULL) ? &ServerName : NULL,
2606  DOMAIN_LOOKUP,
2607  &DomainHandle);
2608  if (!NT_SUCCESS(Status))
2609  {
2610  ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2611  ApiStatus = NetpNtStatusToApiStatus(Status);
2612  goto done;
2613  }
2614 
2615  /* Open the user account in the account domain */
2616  ApiStatus = OpenUserByName(DomainHandle,
2617  &UserName,
2618  DELETE,
2619  &UserHandle);
2620  if (ApiStatus != NERR_Success)
2621  {
2622  ERR("OpenUserByName(%wZ) failed (ApiStatus %lu)\n", &UserName, ApiStatus);
2623  if (ApiStatus == ERROR_NONE_MAPPED)
2624  ApiStatus = NERR_UserNotFound;
2625  goto done;
2626  }
2627  }
2628 
2629  /* Delete the user */
2630  Status = SamDeleteUser(UserHandle);
2631  if (!NT_SUCCESS(Status))
2632  {
2633  ERR("SamDeleteUser failed (Status %08lx)\n", Status);
2634  ApiStatus = NetpNtStatusToApiStatus(Status);
2635  goto done;
2636  }
2637 
2638  /* A successful delete invalidates the handle */
2639  UserHandle = NULL;
2640 
2641 done:
2642  if (UserHandle != NULL)
2643  SamCloseHandle(UserHandle);
2644 
2645  if (DomainHandle != NULL)
2646  SamCloseHandle(DomainHandle);
2647 
2648  if (ServerHandle != NULL)
2649  SamCloseHandle(ServerHandle);
2650 
2651  return ApiStatus;
2652 }
2653 
2654 static
2657  PENUM_CONTEXT *AllocatedEnumContext)
2658 {
2659  NET_API_STATUS ApiStatus;
2660  PENUM_CONTEXT EnumContext;
2661 
2662  /* Allocate the context structure */
2663  ApiStatus = NetApiBufferAllocate(sizeof(ENUM_CONTEXT), (PVOID*)&EnumContext);
2664  if (ApiStatus != NERR_Success)
2665  return ApiStatus;
2666 
2667  /* Initialize the fields */
2668  EnumContext->EnumerationContext = 0;
2669  EnumContext->Buffer = NULL;
2670  EnumContext->Count = 0;
2671  EnumContext->Index = 0;
2672  EnumContext->BuiltinDone = FALSE;
2673 
2674  /* Set a "unique" handle */
2675  EnumContext->EnumHandle = InterlockedIncrement(&g_EnumContextHandle);
2676  if (EnumContext->EnumHandle == 0)
2677  {
2678  EnumContext->EnumHandle = InterlockedIncrement(&g_EnumContextHandle);
2679  }
2680 
2681  /* Insert the context in the list */
2683  InsertTailList(&g_EnumContextListHead, &EnumContext->ListLink);
2685 
2686  *AllocatedEnumContext = EnumContext;
2687  return NERR_Success;
2688 }
2689 
2690 static
2691 VOID
2693  PENUM_CONTEXT EnumContext)
2694 
2695 {
2696  /* Remove the context from the list */
2698  RemoveEntryList(&EnumContext->ListLink);
2700 
2701  /* Free it */
2702  NetApiBufferFree(EnumContext);
2703 }
2704 
2705 static
2708  SAM_ENUMERATE_HANDLE EnumerationHandle)
2709 {
2710  PENUM_CONTEXT FoundEnumContext = NULL;
2711  PLIST_ENTRY ListEntry;
2712 
2713  /* Acquire the list lock */
2715 
2716  /* Search the list for the handle */
2717  for (ListEntry = g_EnumContextListHead.Flink;
2718  ListEntry != &g_EnumContextListHead;
2719  ListEntry = ListEntry->Flink)
2720  {
2721  PENUM_CONTEXT EnumContext = CONTAINING_RECORD(ListEntry, ENUM_CONTEXT, ListLink);
2722  if (EnumContext->EnumHandle == EnumerationHandle)
2723  {
2724  FoundEnumContext = EnumContext;
2725  break;
2726  }
2727  }
2728 
2729  /* Release the list lock */
2731 
2732  return FoundEnumContext;
2733 }
2734 
2735 /************************************************************
2736  * NetUserEnum (NETAPI32.@)
2737  */
2739 WINAPI
2741  DWORD level,
2742  DWORD filter,
2743  LPBYTE* bufptr,
2744  DWORD prefmaxlen,
2745  LPDWORD entriesread,
2746  LPDWORD totalentries,
2747  LPDWORD resume_handle)
2748 {
2749  UNICODE_STRING ServerName;
2751  PENUM_CONTEXT EnumContext = NULL;
2752  LPVOID Buffer = NULL;
2753  ULONG i;
2754  SAM_HANDLE UserHandle = NULL;
2756  NET_API_STATUS ApiStatus = NERR_Success;
2758 
2759  TRACE("(%s %d 0x%d %p %d %p %p %p)\n", debugstr_w(servername), level,
2760  filter, bufptr, prefmaxlen, entriesread, totalentries, resume_handle);
2761 
2762  *entriesread = 0;
2763  *totalentries = 0;
2764  *bufptr = NULL;
2765 
2766  if (servername != NULL)
2767  RtlInitUnicodeString(&ServerName, servername);
2768 
2769  if (resume_handle != NULL && *resume_handle != 0)
2770  {
2771  EnumContext = LookupEnumContext(*resume_handle);
2772  }
2773  else
2774  {
2775  ApiStatus = AllocateEnumContext(&EnumContext);
2776  if (ApiStatus != NERR_Success)
2777  goto done;
2778 
2779  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2780  &EnumContext->ServerHandle,
2782  NULL);
2783  if (!NT_SUCCESS(Status))
2784  {
2785  ERR("SamConnect failed (Status %08lx)\n", Status);
2786  ApiStatus = NetpNtStatusToApiStatus(Status);
2787  goto done;
2788  }
2789 
2790  /* Get the Account Domain SID */
2791  Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
2792  &EnumContext->AccountDomainSid);
2793  if (!NT_SUCCESS(Status))
2794  {
2795  ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
2796  ApiStatus = NetpNtStatusToApiStatus(Status);
2797  goto done;
2798  }
2799 
2800  /* Open the Account Domain */
2801  Status = SamOpenDomain(EnumContext->ServerHandle,
2803  EnumContext->AccountDomainSid,
2804  &EnumContext->AccountDomainHandle);
2805  if (!NT_SUCCESS(Status))
2806  {
2807  ERR("SamOpenDomain failed (Status %08lx)\n", Status);
2808  ApiStatus = NetpNtStatusToApiStatus(Status);
2809  goto done;
2810  }
2811 
2812  /* Get the Builtin Domain SID */
2813  Status = GetBuiltinDomainSid(&EnumContext->BuiltinDomainSid);
2814  if (!NT_SUCCESS(Status))
2815  {
2816  ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status);
2817  ApiStatus = NetpNtStatusToApiStatus(Status);
2818  goto done;
2819  }
2820 
2822  if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
2824 
2825  /* Open the Builtin Domain */
2826  Status = SamOpenDomain(EnumContext->ServerHandle,
2827  DesiredAccess,
2828  EnumContext->BuiltinDomainSid,
2829  &EnumContext->BuiltinDomainHandle);
2830  if (!NT_SUCCESS(Status))
2831  {
2832  ERR("SamOpenDomain failed (Status %08lx)\n", Status);
2833  ApiStatus = NetpNtStatusToApiStatus(Status);
2834  goto done;
2835  }
2836  }
2837 
2838 // while (TRUE)
2839 // {
2840  TRACE("EnumContext->Index: %lu\n", EnumContext->Index);
2841  TRACE("EnumContext->Count: %lu\n", EnumContext->Count);
2842 
2843  if (EnumContext->Index >= EnumContext->Count)
2844  {
2845 // if (EnumContext->BuiltinDone != FALSE)
2846 // {
2847 // ApiStatus = NERR_Success;
2848 // goto done;
2849 // }
2850 
2851  TRACE("Calling SamEnumerateUsersInDomain\n");
2852  Status = SamEnumerateUsersInDomain(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
2853  &EnumContext->EnumerationContext,
2854  0,
2855  (PVOID *)&EnumContext->Buffer,
2856  prefmaxlen,
2857  &EnumContext->Count);
2858 
2859  TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n", Status);
2860  if (!NT_SUCCESS(Status))
2861  {
2862  ERR("SamEnumerateUsersInDomain failed (Status %08lx)\n", Status);
2863  ApiStatus = NetpNtStatusToApiStatus(Status);
2864  goto done;
2865  }
2866 
2867  if (Status == STATUS_MORE_ENTRIES)
2868  {
2869  ApiStatus = NERR_BufTooSmall;
2870  goto done;
2871  }
2872  else
2873  {
2874  EnumContext->BuiltinDone = TRUE;
2875  }
2876  }
2877 
2878  TRACE("EnumContext: %lu\n", EnumContext);
2879  TRACE("EnumContext->Count: %lu\n", EnumContext->Count);
2880  TRACE("EnumContext->Buffer: %p\n", EnumContext->Buffer);
2881 
2882  /* Get a pointer to the current user */
2883  CurrentUser = &EnumContext->Buffer[EnumContext->Index];
2884 
2885  TRACE("RID: %lu\n", CurrentUser->RelativeId);
2886 
2888  if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
2890 
2891  Status = SamOpenUser(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
2892  DesiredAccess,
2893  CurrentUser->RelativeId,
2894  &UserHandle);
2895  if (!NT_SUCCESS(Status))
2896  {
2897  ERR("SamOpenUser failed (Status %08lx)\n", Status);
2898  ApiStatus = NetpNtStatusToApiStatus(Status);
2899  goto done;
2900  }
2901 
2902  ApiStatus = BuildUserInfoBuffer(EnumContext->BuiltinDomainHandle,
2903  UserHandle,
2904  EnumContext->AccountDomainSid,
2905  CurrentUser->RelativeId,
2906  level,
2907  &Buffer);
2908  if (ApiStatus != NERR_Success)
2909  {
2910  ERR("BuildUserInfoBuffer failed (ApiStatus %lu)\n", ApiStatus);
2911  goto done;
2912  }
2913 
2914  SamCloseHandle(UserHandle);
2915  UserHandle = NULL;
2916 
2917  EnumContext->Index++;
2918 
2919  (*entriesread)++;
2920 // }
2921 
2922 done:
2923  if (ApiStatus == NERR_Success && EnumContext != NULL && EnumContext->Index < EnumContext->Count)
2924  ApiStatus = ERROR_MORE_DATA;
2925 
2926  if (EnumContext != NULL)
2927  *totalentries = EnumContext->Count;
2928 
2929  if (resume_handle == NULL || ApiStatus != ERROR_MORE_DATA)
2930  {
2931  if (EnumContext != NULL)
2932  {
2933  if (EnumContext->BuiltinDomainHandle != NULL)
2934  SamCloseHandle(EnumContext->BuiltinDomainHandle);
2935 
2936  if (EnumContext->AccountDomainHandle != NULL)
2937  SamCloseHandle(EnumContext->AccountDomainHandle);
2938 
2939  if (EnumContext->BuiltinDomainSid != NULL)
2940  RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext->BuiltinDomainSid);
2941 
2942  if (EnumContext->AccountDomainSid != NULL)
2943  RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext->AccountDomainSid);
2944 
2945  if (EnumContext->ServerHandle != NULL)
2946  SamCloseHandle(EnumContext->ServerHandle);
2947 
2948  if (EnumContext->Buffer != NULL)
2949  {
2950  for (i = 0; i < EnumContext->Count; i++)
2951  {
2952  SamFreeMemory(EnumContext->Buffer[i].Name.Buffer);
2953  }
2954 
2955  SamFreeMemory(EnumContext->Buffer);
2956  }
2957 
2958  FreeEnumContext(EnumContext);
2959  EnumContext = NULL;
2960  }
2961  }
2962 
2963  if (UserHandle != NULL)
2964  SamCloseHandle(UserHandle);
2965 
2966  if (resume_handle != NULL)
2967  *resume_handle = EnumContext ? EnumContext->EnumHandle : 0;
2968 
2969  *bufptr = (LPBYTE)Buffer;
2970 
2971  TRACE("return %lu\n", ApiStatus);
2972 
2973  return ApiStatus;
2974 }
2975 
2976 
2977 /************************************************************
2978  * NetUserGetGroups (NETAPI32.@)
2979  */
2981 WINAPI
2983  LPCWSTR username,
2984  DWORD level,
2985  LPBYTE *bufptr,
2986  DWORD prefixmaxlen,
2987  LPDWORD entriesread,
2988  LPDWORD totalentries)
2989 {
2990  UNICODE_STRING ServerName;
2991  UNICODE_STRING UserName;
2992  SAM_HANDLE ServerHandle = NULL;
2993  SAM_HANDLE AccountDomainHandle = NULL;
2994  SAM_HANDLE UserHandle = NULL;
2996  PULONG RelativeIds = NULL;
2997  PSID_NAME_USE Use = NULL;
2998  PGROUP_MEMBERSHIP GroupMembership = NULL;
2999  ULONG GroupCount;
3000 
3001  NET_API_STATUS ApiStatus = NERR_Success;
3003 
3004  TRACE("%s %s %d %p %d %p %p stub\n", debugstr_w(servername),
3005  debugstr_w(username), level, bufptr, prefixmaxlen, entriesread,
3006  totalentries);
3007 
3008  if (servername != NULL)
3009  RtlInitUnicodeString(&ServerName, servername);
3010 
3011  RtlInitUnicodeString(&UserName, username);
3012 
3013  /* Connect to the SAM Server */
3014  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
3015  &ServerHandle,
3017  NULL);
3018  if (!NT_SUCCESS(Status))
3019  {
3020  ERR("SamConnect failed (Status %08lx)\n", Status);
3021  ApiStatus = NetpNtStatusToApiStatus(Status);
3022  goto done;
3023  }
3024 
3025  /* Get the Account Domain SID */
3026  Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
3027  &AccountDomainSid);
3028  if (!NT_SUCCESS(Status))
3029  {
3030  ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
3031  ApiStatus = NetpNtStatusToApiStatus(Status);
3032  goto done;
3033  }
3034 
3035  /* Open the Account Domain */
3036  Status = SamOpenDomain(ServerHandle,
3039  &AccountDomainHandle);
3040  if (!NT_SUCCESS(Status))
3041  {
3042  ERR("SamOpenDomain failed (Status %08lx)\n", Status);
3043  ApiStatus = NetpNtStatusToApiStatus(Status);
3044  goto done;
3045  }
3046 
3047  /* Get the RID for the given user name */
3048  Status = SamLookupNamesInDomain(AccountDomainHandle,
3049  1,
3050  &UserName,
3051  &RelativeIds,
3052  &Use);
3053  if (!NT_SUCCESS(Status))
3054  {
3055  ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", &UserName, Status);
3056  if (Status == STATUS_NONE_MAPPED)
3057  ApiStatus = NERR_UserNotFound;
3058  else
3059  ApiStatus = NetpNtStatusToApiStatus(Status);
3060  goto done;
3061  }
3062 
3063  /* Fail, if it is not a user account */
3064  if (Use[0] != SidTypeUser)
3065  {
3066  ERR("Account is not a User!\n");
3067  ApiStatus = NERR_UserNotFound;
3068  goto done;
3069  }
3070 
3071  /* Open the user object */
3072  Status = SamOpenUser(AccountDomainHandle,
3074  RelativeIds[0],
3075  &UserHandle);
3076  if (!NT_SUCCESS(Status))
3077  {
3078  ERR("SamOpenUser failed (Status %08lx)\n", Status);
3079  ApiStatus = NetpNtStatusToApiStatus(Status);
3080  goto done;
3081  }
3082 
3083  /* Get the group memberships of this user */
3084  Status = SamGetGroupsForUser(UserHandle,
3085  &GroupMembership,
3086  &GroupCount);
3087  if (!NT_SUCCESS(Status))
3088  {
3089  ERR("SamGetGroupsForUser failed (Status %08lx)\n", Status);
3090  ApiStatus = NetpNtStatusToApiStatus(Status);
3091  goto done;
3092  }
3093 
3094  /* If there is no group membership, we're done */
3095  if (GroupCount == 0)
3096  {
3097  ApiStatus = NERR_Success;
3098  goto done;
3099  }
3100 
3101 
3102 done:
3103 
3104  if (GroupMembership != NULL)
3105  SamFreeMemory(GroupMembership);
3106 
3107  if (UserHandle != NULL)
3108  SamCloseHandle(UserHandle);
3109 
3110  if (RelativeIds != NULL)
3111  SamFreeMemory(RelativeIds);
3112 
3113  if (Use != NULL)
3114  SamFreeMemory(Use);
3115 
3116  if (AccountDomainSid != NULL)
3117  RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
3118 
3119  if (AccountDomainHandle != NULL)
3120  SamCloseHandle(AccountDomainHandle);
3121 
3122  if (ServerHandle != NULL)
3123  SamCloseHandle(ServerHandle);
3124 
3125  if (ApiStatus != NERR_Success && ApiStatus != ERROR_MORE_DATA)
3126  {
3127  *entriesread = 0;
3128  *totalentries = 0;
3129  }
3130  else
3131  {
3132 // *entriesread = Count;
3133 // *totalentries = Count;
3134  }
3135 
3136 // *bufptr = (LPBYTE)Buffer;
3137 
3138  return ApiStatus;
3139 }
3140 
3141 
3142 /************************************************************
3143  * NetUserGetInfo (NETAPI32.@)
3144  */
3146 WINAPI
3148  LPCWSTR username,
3149  DWORD level,
3150  LPBYTE* bufptr)
3151 {
3152  UNICODE_STRING ServerName;
3153  UNICODE_STRING UserName;
3154  SAM_HANDLE ServerHandle = NULL;
3155  SAM_HANDLE AccountDomainHandle = NULL;
3156  SAM_HANDLE BuiltinDomainHandle = NULL;
3157  SAM_HANDLE UserHandle = NULL;
3158  PULONG RelativeIds = NULL;
3159  PSID_NAME_USE Use = NULL;
3160  LPVOID Buffer = NULL;
3164  NET_API_STATUS ApiStatus = NERR_Success;
3166 
3167  TRACE("(%s, %s, %d, %p)\n", debugstr_w(servername),
3169 
3170  if (servername != NULL)
3171  RtlInitUnicodeString(&ServerName, servername);
3172 
3173  RtlInitUnicodeString(&UserName, username);
3174 
3175  /* Connect to the SAM Server */
3176  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
3177  &ServerHandle,
3179  NULL);
3180  if (!NT_SUCCESS(Status))
3181  {
3182  ERR("SamConnect failed (Status %08lx)\n", Status);
3183  ApiStatus = NetpNtStatusToApiStatus(Status);
3184  goto done;
3185  }
3186 
3187  /* Get the Builtin Domain SID */
3189  if (!NT_SUCCESS(Status))
3190  {
3191  ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status);
3192  ApiStatus = NetpNtStatusToApiStatus(Status);
3193  goto done;
3194  }
3195 
3197  if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
3199 
3200  /* Open the Builtin Domain */
3201  Status = SamOpenDomain(ServerHandle,
3202  DesiredAccess,
3204  &BuiltinDomainHandle);
3205  if (!NT_SUCCESS(Status))
3206  {
3207  ERR("SamOpenDomain failed (Status %08lx)\n", Status);
3208  ApiStatus = NetpNtStatusToApiStatus(Status);
3209  goto done;
3210  }
3211 
3212  /* Get the Account Domain SID */
3213  Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
3214  &AccountDomainSid);
3215  if (!NT_SUCCESS(Status))
3216  {
3217  ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
3218  ApiStatus = NetpNtStatusToApiStatus(Status);
3219  goto done;
3220  }
3221 
3222  /* Open the Account Domain */
3223  Status = SamOpenDomain(ServerHandle,
3226  &AccountDomainHandle);
3227  if (!NT_SUCCESS(Status))
3228  {
3229  ERR("SamOpenDomain failed (Status %08lx)\n", Status);
3230  ApiStatus = NetpNtStatusToApiStatus(Status);
3231  goto done;
3232  }
3233 
3234  /* Get the RID for the given user name */
3235  Status = SamLookupNamesInDomain(AccountDomainHandle,
3236  1,
3237  &UserName,
3238  &RelativeIds,
3239  &Use);
3240  if (!NT_SUCCESS(Status))
3241  {
3242  ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", &UserName, Status);
3243  if (Status == STATUS_NONE_MAPPED)
3244  ApiStatus = NERR_UserNotFound;
3245  else
3246  ApiStatus = NetpNtStatusToApiStatus(Status);
3247  goto done;
3248  }
3249 
3250  /* Check if the account is a user account */
3251  if (Use[0] != SidTypeUser)
3252  {
3253  ERR("No user found!\n");
3254  ApiStatus = NERR_UserNotFound;
3255  goto done;
3256  }
3257 
3258  TRACE("RID: %lu\n", RelativeIds[0]);
3259 
3261  if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
3263 
3264  /* Open the user object */
3265  Status = SamOpenUser(AccountDomainHandle,
3266  DesiredAccess,
3267  RelativeIds[0],
3268  &UserHandle);
3269  if (!NT_SUCCESS(Status))
3270  {
3271  ERR("SamOpenUser failed (Status %08lx)\n", Status);
3272  ApiStatus = NetpNtStatusToApiStatus(Status);
3273  goto done;
3274  }
3275 
3276  ApiStatus = BuildUserInfoBuffer(BuiltinDomainHandle,
3277  UserHandle,
3279  RelativeIds[0],
3280  level,
3281  &Buffer);
3282  if (ApiStatus != NERR_Success)
3283  {
3284  ERR("BuildUserInfoBuffer failed (ApiStatus %08lu)\n", ApiStatus);
3285  goto done;
3286  }
3287 
3288 done:
3289  if (UserHandle != NULL)
3290  SamCloseHandle(UserHandle);
3291 
3292  if (RelativeIds != NULL)
3293  SamFreeMemory(RelativeIds);
3294 
3295  if (Use != NULL)
3296  SamFreeMemory(Use);
3297 
3298  if (AccountDomainHandle != NULL)
3299  SamCloseHandle(AccountDomainHandle);
3300 
3301  if (AccountDomainSid != NULL)
3302  RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
3303 
3304  if (BuiltinDomainHandle != NULL)
3305  SamCloseHandle(BuiltinDomainHandle);
3306 
3307  if (BuiltinDomainSid != NULL)
3308  RtlFreeHeap(RtlGetProcessHeap(), 0, BuiltinDomainSid);
3309 
3310  if (ServerHandle != NULL)
3311  SamCloseHandle(ServerHandle);
3312 
3313  *bufptr = (LPBYTE)Buffer;
3314 
3315  return ApiStatus;
3316 }
3317 
3318 
3319 /************************************************************
3320  * NetUserGetLocalGroups (NETAPI32.@)
3321  */
3323 WINAPI
3325  LPCWSTR username,
3326  DWORD level,
3327  DWORD flags,
3328  LPBYTE* bufptr,
3329  DWORD prefmaxlen,
3330  LPDWORD entriesread,
3331  LPDWORD totalentries)
3332 {
3333  UNICODE_STRING ServerName;
3334  UNICODE_STRING UserName;
3335  SAM_HANDLE ServerHandle = NULL;
3336  SAM_HANDLE BuiltinDomainHandle = NULL;
3337  SAM_HANDLE AccountDomainHandle = NULL;
3339  PSID UserSid = NULL;
3340  PULONG RelativeIds = NULL;
3341  PSID_NAME_USE Use = NULL;
3342  ULONG BuiltinMemberCount = 0;
3343  ULONG AccountMemberCount = 0;
3344  PULONG BuiltinAliases = NULL;
3345  PULONG AccountAliases = NULL;
3346  PUNICODE_STRING BuiltinNames = NULL;
3347  PUNICODE_STRING AccountNames = NULL;
3349  ULONG Size;
3350  ULONG Count = 0;
3351  ULONG Index;
3352  ULONG i;
3353  LPWSTR StrPtr;
3354  NET_API_STATUS ApiStatus = NERR_Success;
3356 
3357  TRACE("(%s, %s, %d, %08x, %p %d, %p, %p) stub!\n",
3358  debugstr_w(servername), debugstr_w(username), level, flags, bufptr,
3359  prefmaxlen, entriesread, totalentries);
3360 
3361  if (level != 0)
3362  return ERROR_INVALID_LEVEL;
3363 
3364  if (flags & ~LG_INCLUDE_INDIRECT)
3365  return ERROR_INVALID_PARAMETER;
3366 
3367  if (flags & LG_INCLUDE_INDIRECT)
3368  {
3369  WARN("The flag LG_INCLUDE_INDIRECT is not supported yet!\n");
3370  }
3371 
3372  if (servername != NULL)
3373  RtlInitUnicodeString(&ServerName, servername);
3374 
3375  RtlInitUnicodeString(&UserName, username);
3376 
3377  /* Connect to the SAM Server */
3378  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
3379  &ServerHandle,
3381  NULL);
3382  if (!NT_SUCCESS(Status))
3383  {
3384  ERR("SamConnect failed (Status %08lx)\n", Status);
3385  ApiStatus = NetpNtStatusToApiStatus(Status);
3386  goto done;
3387  }
3388 
3389  /* Open the Builtin Domain */
3390  Status = OpenBuiltinDomain(ServerHandle,
3392  &BuiltinDomainHandle);
3393  if (!NT_SUCCESS(Status))
3394  {
3395  ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status);
3396  ApiStatus = NetpNtStatusToApiStatus(Status);
3397  goto done;
3398  }
3399 
3400  /* Get the Account Domain SID */
3401  Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
3402  &AccountDomainSid);
3403  if (!NT_SUCCESS(Status))
3404  {
3405  ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
3406  ApiStatus = NetpNtStatusToApiStatus(Status);
3407  goto done;
3408  }
3409 
3410  /* Open the Account Domain */
3411  Status = SamOpenDomain(ServerHandle,
3414  &AccountDomainHandle);
3415  if (!NT_SUCCESS(Status))
3416  {
3417  ERR("SamOpenDomain failed (Status %08lx)\n", Status);
3418  ApiStatus = NetpNtStatusToApiStatus(Status);
3419  goto done;
3420  }
3421 
3422  /* Get the RID for the given user name */
3423  Status = SamLookupNamesInDomain(AccountDomainHandle,
3424  1,
3425  &UserName,
3426  &RelativeIds,
3427  &Use);
3428  if (!NT_SUCCESS(Status))
3429  {
3430  ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", &UserName, Status);
3431  if (Status == STATUS_NONE_MAPPED)
3432  ApiStatus = NERR_UserNotFound;
3433  else
3434  ApiStatus = NetpNtStatusToApiStatus(Status);
3435  goto done;
3436  }
3437 
3438  /* Fail, if it is not a user account */
3439  if (Use[0] != SidTypeUser)
3440  {
3441  ERR("Account is not a User!\n");
3442  ApiStatus = NERR_UserNotFound;
3443  goto done;
3444  }
3445 
3446  /* Build the User SID from the Account Domain SID and the users RID */
3448  RelativeIds[0],
3449  &UserSid);
3450  if (ApiStatus != NERR_Success)
3451  {
3452  ERR("BuildSidFromSidAndRid failed!\n");
3453  goto done;
3454  }
3455 
3456  /* Get alias memberships in the Builtin Domain */
3457  Status = SamGetAliasMembership(BuiltinDomainHandle,
3458  1,
3459  &UserSid,
3460  &BuiltinMemberCount,
3461  &BuiltinAliases);
3462  if (!NT_SUCCESS(Status))
3463  {
3464  ERR("SamGetAliasMembership failed (Status %08lx)\n", Status);
3465  ApiStatus = NetpNtStatusToApiStatus(Status);
3466  goto done;
3467  }
3468 
3469  if (BuiltinMemberCount > 0)
3470  {
3471  /* Get the Names of the builtin alias members */
3472  Status = SamLookupIdsInDomain(BuiltinDomainHandle,
3473  BuiltinMemberCount,
3474  BuiltinAliases,
3475  &BuiltinNames,
3476  NULL);
3477  if (!NT_SUCCESS(Status))
3478  {
3479  ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status);
3480  ApiStatus = NetpNtStatusToApiStatus(Status);
3481  goto done;
3482  }
3483  }
3484 
3485  /* Get alias memberships in the Account Domain */
3486  Status = SamGetAliasMembership(AccountDomainHandle,
3487  1,
3488  &UserSid,
3489  &AccountMemberCount,
3490  &AccountAliases);
3491  if (!NT_SUCCESS(Status))
3492  {
3493  ERR("SamGetAliasMembership failed (Status %08lx)\n", Status);
3494  ApiStatus = NetpNtStatusToApiStatus(Status);
3495  goto done;
3496  }
3497 
3498  if (AccountMemberCount > 0)
3499  {
3500  /* Get the Names of the builtin alias members */
3501  Status = SamLookupIdsInDomain(AccountDomainHandle,
3502  AccountMemberCount,
3503  AccountAliases,
3504  &AccountNames,
3505  NULL);
3506  if (!NT_SUCCESS(Status))
3507  {
3508  ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status);
3509  ApiStatus = NetpNtStatusToApiStatus(Status);
3510  goto done;
3511  }
3512  }
3513 
3514  /* Calculate the required buffer size */
3515  Size = 0;
3516 
3517  for (i = 0; i < BuiltinMemberCount; i++)
3518  {
3519  if (BuiltinNames[i].Length > 0)
3520  {
3521  Size += (sizeof(LOCALGROUP_USERS_INFO_0) + BuiltinNames[i].Length + sizeof(UNICODE_NULL));
3522  Count++;
3523  }
3524  }
3525 
3526  for (i = 0; i < AccountMemberCount; i++)
3527  {
3528  if (AccountNames[i].Length > 0)
3529  {
3530  Size += (sizeof(LOCALGROUP_USERS_INFO_0) + AccountNames[i].Length + sizeof(UNICODE_NULL));
3531  Count++;
3532  }
3533  }
3534 
3535  if (Size == 0)
3536  {
3537  ApiStatus = NERR_Success;
3538  goto done;
3539  }
3540 
3541  /* Allocate buffer */
3542  ApiStatus = NetApiBufferAllocate(Size, (LPVOID*)&Buffer);
3543  if (ApiStatus != NERR_Success)
3544  goto done;
3545 
3547 
3548  StrPtr = (LPWSTR)((INT_PTR)Buffer + Count * sizeof(LOCALGROUP_USERS_INFO_0));
3549 
3550  /* Copy data to the allocated buffer */
3551  Index = 0;
3552  for (i = 0; i < BuiltinMemberCount; i++)
3553  {
3554  if (BuiltinNames[i].Length > 0)
3555  {
3556  CopyMemory(StrPtr,
3557  BuiltinNames[i].Buffer,
3558  BuiltinNames[i].Length);
3559  Buffer[Index].lgrui0_name = StrPtr;
3560 
3561  StrPtr = (LPWSTR)((INT_PTR)StrPtr + BuiltinNames[i].Length + sizeof(UNICODE_NULL));
3562  Index++;
3563  }
3564  }
3565 
3566  for (i = 0; i < AccountMemberCount; i++)
3567  {
3568  if (AccountNames[i].Length > 0)
3569  {
3570  CopyMemory(StrPtr,
3571  AccountNames[i].Buffer,
3572  AccountNames[i].Length);
3573  Buffer[Index].lgrui0_name = StrPtr;
3574 
3575  StrPtr = (LPWSTR)((INT_PTR)StrPtr + AccountNames[i].Length + sizeof(UNICODE_NULL));
3576  Index++;
3577  }
3578  }
3579 
3580 done:
3581  if (AccountNames != NULL)
3582  SamFreeMemory(AccountNames);
3583 
3584  if (BuiltinNames != NULL)
3585  SamFreeMemory(BuiltinNames);
3586 
3587  if (AccountAliases != NULL)
3588  SamFreeMemory(AccountAliases);
3589 
3590  if (BuiltinAliases != NULL)
3591  SamFreeMemory(BuiltinAliases);
3592 
3593  if (RelativeIds != NULL)
3594  SamFreeMemory(RelativeIds);
3595 
3596  if (Use != NULL)
3597  SamFreeMemory(Use);
3598 
3599  if (UserSid != NULL)
3600  NetApiBufferFree(UserSid);
3601 
3602  if (AccountDomainSid != NULL)
3603  RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
3604 
3605  if (AccountDomainHandle != NULL)
3606  SamCloseHandle(AccountDomainHandle);
3607 
3608  if (BuiltinDomainHandle != NULL)
3609  SamCloseHandle(BuiltinDomainHandle);
3610 
3611  if (ServerHandle != NULL)
3612  SamCloseHandle(ServerHandle);
3613 
3614  if (ApiStatus != NERR_Success && ApiStatus != ERROR_MORE_DATA)
3615  {
3616  *entriesread = 0;
3617  *totalentries = 0;
3618  }
3619  else
3620  {
3621  *entriesread = Count;
3622  *totalentries = Count;
3623  }
3624 
3625  *bufptr = (LPBYTE)Buffer;
3626 
3627  return ApiStatus;
3628 }
3629 
3630 
3631 /******************************************************************************
3632  * NetUserModalsGet (NETAPI32.@)
3633  *
3634  * Retrieves global information for all users and global groups in the security
3635  * database.
3636  *
3637  * PARAMS
3638  * servername [I] Specifies the DNS or the NetBIOS name of the remote server
3639  * on which the function is to execute.
3640  * level [I] Information level of the data.
3641  * 0 Return global passwords parameters. bufptr points to a
3642  * USER_MODALS_INFO_0 struct.
3643  * 1 Return logon server and domain controller information. bufptr
3644  * points to a USER_MODALS_INFO_1 struct.
3645  * 2 Return domain name and identifier. bufptr points to a
3646  * USER_MODALS_INFO_2 struct.
3647  * 3 Return lockout information. bufptr points to a USER_MODALS_INFO_3
3648  * struct.
3649  * bufptr [O] Buffer that receives the data.
3650  *
3651  * RETURNS
3652  * Success: NERR_Success.
3653  * Failure:
3654  * ERROR_ACCESS_DENIED - the user does not have access to the info.
3655  * NERR_InvalidComputer - computer name is invalid.
3656  */
3658 WINAPI
3660  DWORD level,
3661  LPBYTE *bufptr)
3662 {
3663  UNICODE_STRING ServerName;
3664  SAM_HANDLE ServerHandle = NULL;
3665  SAM_HANDLE DomainHandle = NULL;
3666  PSID DomainSid = NULL;
3667  PDOMAIN_PASSWORD_INFORMATION PasswordInfo = NULL;
3668  PDOMAIN_LOGOFF_INFORMATION LogoffInfo = NULL;
3669  PDOMAIN_SERVER_ROLE_INFORMATION ServerRoleInfo = NULL;
3670  PDOMAIN_REPLICATION_INFORMATION ReplicationInfo = NULL;
3671  PDOMAIN_NAME_INFORMATION NameInfo = NULL;
3672  PDOMAIN_LOCKOUT_INFORMATION LockoutInfo = NULL;
3674  ULONG BufferSize;
3675  PUSER_MODALS_INFO_0 umi0;
3676  PUSER_MODALS_INFO_1 umi1;
3677  PUSER_MODALS_INFO_2 umi2;
3678  PUSER_MODALS_INFO_3 umi3;
3679  NET_API_STATUS ApiStatus = NERR_Success;
3681 
3682  TRACE("(%s %d %p)\n", debugstr_w(servername), level, bufptr);
3683 
3684  *bufptr = NULL;
3685 
3686  if (servername != NULL)
3687  RtlInitUnicodeString(&ServerName, servername);
3688 
3689  /* Connect to the SAM Server */
3690  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
3691  &ServerHandle,
3693  NULL);
3694  if (!NT_SUCCESS(Status))
3695  {
3696  ERR("SamConnect failed (Status %08lx)\n", Status);
3697  ApiStatus = NetpNtStatusToApiStatus(Status);
3698  goto done;
3699  }
3700 
3701  /* Get the Account Domain SID */
3702  Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
3703  &DomainSid);
3704  if (!NT_SUCCESS(Status))
3705  {
3706  ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
3707  ApiStatus = NetpNtStatusToApiStatus(Status);
3708  goto done;
3709  }
3710 
3711  switch (level)
3712  {
3713  case 0:
3715  break;
3716 
3717  case 1:
3719  break;
3720 
3721  case 2:
3723  break;
3724 
3725  case 3:
3727  break;
3728 
3729  default:
3730  ApiStatus = ERROR_INVALID_LEVEL;
3731  goto done;
3732  }
3733 
3734  /* Open the Account Domain */
3735  Status = SamOpenDomain(ServerHandle,
3736  DesiredAccess,
3737  DomainSid,
3738  &DomainHandle);
3739  if (!NT_SUCCESS(Status))
3740  {
3741  ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
3742  ApiStatus = NetpNtStatusToApiStatus(Status);
3743  goto done;
3744  }
3745 
3746  switch (level)
3747  {
3748  case 0:
3749  /* return global passwords parameters */
3750  Status = SamQueryInformationDomain(DomainHandle,
3752  (PVOID*)&PasswordInfo);
3753  if (!NT_SUCCESS(Status))
3754  {
3755  ApiStatus = NetpNtStatusToApiStatus(Status);
3756  goto done;
3757  }
3758 
3759  Status = SamQueryInformationDomain(DomainHandle,
3761  (PVOID*)&LogoffInfo);
3762  if (!NT_SUCCESS(Status))
3763  {
3764  ApiStatus = NetpNtStatusToApiStatus(Status);
3765  goto done;
3766  }
3767 
3768  BufferSize = sizeof(USER_MODALS_INFO_0);
3769  break;
3770 
3771  case 1:
3772  /* return logon server and domain controller info */
3773  Status = SamQueryInformationDomain(DomainHandle,
3775  (PVOID*)&ServerRoleInfo);
3776  if (!NT_SUCCESS(Status))
3777  {
3778  ApiStatus = NetpNtStatusToApiStatus(Status);
3779  goto done;
3780  }
3781 
3782  Status = SamQueryInformationDomain(DomainHandle,
3784  (PVOID*)&ReplicationInfo);
3785  if (!NT_SUCCESS(Status))
3786  {
3787  ApiStatus = NetpNtStatusToApiStatus(Status);
3788  goto done;
3789  }
3790 
3791  BufferSize = sizeof(USER_MODALS_INFO_1) +
3792  ReplicationInfo->ReplicaSourceNodeName.Length + sizeof(WCHAR);
3793  break;
3794 
3795  case 2:
3796  /* return domain name and identifier */
3797  Status = SamQueryInformationDomain(DomainHandle,
3799  (PVOID*)&NameInfo);
3800  if (!NT_SUCCESS(Status))
3801  {
3802  ApiStatus = NetpNtStatusToApiStatus(Status);
3803  goto done;
3804  }
3805 
3806  BufferSize = sizeof( USER_MODALS_INFO_2 ) +
3807  NameInfo->DomainName.Length + sizeof(WCHAR) +
3808  RtlLengthSid(DomainSid);
3809  break;
3810 
3811  case 3:
3812  /* return lockout information */
3813  Status = SamQueryInformationDomain(DomainHandle,
3815  (PVOID*)&LockoutInfo);
3816  if (!NT_SUCCESS(Status))
3817  {
3818  ApiStatus = NetpNtStatusToApiStatus(Status);
3819  goto done;
3820  }
3821 
3822  BufferSize = sizeof(USER_MODALS_INFO_3);
3823  break;
3824 
3825  default:
3826  TRACE("Invalid level %d is specified\n", level);
3827  ApiStatus = ERROR_INVALID_LEVEL;
3828  goto done;
3829  }
3830 
3831 
3832  ApiStatus = NetApiBufferAllocate(BufferSize,
3833  (LPVOID *)bufptr);
3834  if (ApiStatus != NERR_Success)
3835  {
3836  WARN("NetApiBufferAllocate() failed\n");
3837  goto done;
3838  }
3839 
3840  switch (level)
3841  {
3842  case 0:
3843  umi0 = (PUSER_MODALS_INFO_0)*bufptr;
3844 
3845  umi0->usrmod0_min_passwd_len = PasswordInfo->MinPasswordLength;
3846  umi0->usrmod0_max_passwd_age = (ULONG)(-PasswordInfo->MaxPasswordAge.QuadPart / 10000000);
3847  umi0->usrmod0_min_passwd_age =
3848  DeltaTimeToSeconds(PasswordInfo->MinPasswordAge);
3849  umi0->usrmod0_force_logoff =
3850  DeltaTimeToSeconds(LogoffInfo->ForceLogoff);
3851  umi0->usrmod0_password_hist_len = PasswordInfo->PasswordHistoryLength;
3852  break;
3853 
3854  case 1:
3855  umi1 = (PUSER_MODALS_INFO_1)*bufptr;
3856 
3857  switch (ServerRoleInfo->DomainServerRole)
3858  {
3861  break;
3862 
3864  umi1->usrmod1_role = UAS_ROLE_BACKUP;
3865  break;
3866 
3867  default:
3868  ApiStatus = NERR_InternalError;
3869  goto done;
3870  }
3871 
3872  umi1->usrmod1_primary = (LPWSTR)(*bufptr + sizeof(USER_MODALS_INFO_1));
3874  ReplicationInfo->ReplicaSourceNodeName.Buffer,
3875  ReplicationInfo->ReplicaSourceNodeName.Length);
3876  umi1->usrmod1_primary[ReplicationInfo->ReplicaSourceNodeName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3877  break;
3878 
3879  case 2:
3880  umi2 = (PUSER_MODALS_INFO_2)*bufptr;
3881 
3882  umi2->usrmod2_domain_name = (LPWSTR)(*bufptr + sizeof(USER_MODALS_INFO_2));
3884  NameInfo->DomainName.Buffer,
3885  NameInfo->DomainName.Length);
3886  umi2->usrmod2_domain_name[NameInfo->DomainName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3887 
3888  umi2->usrmod2_domain_id = *bufptr +
3889  sizeof(USER_MODALS_INFO_2) +
3890  NameInfo->DomainName.Length + sizeof(WCHAR);
3892  DomainSid,
3893  RtlLengthSid(DomainSid));
3894  break;
3895 
3896  case 3:
3897  umi3 = (PUSER_MODALS_INFO_3)*bufptr;
3898  umi3->usrmod3_lockout_duration =
3899  DeltaTimeToSeconds(LockoutInfo->LockoutDuration);
3902  umi3->usrmod3_lockout_threshold = LockoutInfo->LockoutThreshold;
3903  break;
3904  }
3905 
3906 done:
3907  if (LockoutInfo != NULL)
3908  SamFreeMemory(LockoutInfo);
3909 
3910  if (NameInfo != NULL)
3911  SamFreeMemory(NameInfo);
3912 
3913  if (ReplicationInfo != NULL)
3914  SamFreeMemory(ReplicationInfo);
3915 
3916  if (ServerRoleInfo != NULL)
3917  SamFreeMemory(ServerRoleInfo);
3918 
3919  if (LogoffInfo != NULL)
3920  SamFreeMemory(LogoffInfo);
3921 
3922  if (PasswordInfo != NULL)
3923  SamFreeMemory(PasswordInfo);
3924 
3925  if (DomainSid != NULL)
3926  RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
3927 
3928  if (DomainHandle != NULL)
3929  SamCloseHandle(DomainHandle);
3930 
3931  if (ServerHandle != NULL)
3932  SamCloseHandle(ServerHandle);
3933 
3934  return ApiStatus;
3935 }
3936 
3937 
3938 /******************************************************************************
3939  * NetUserModalsSet (NETAPI32.@)
3940  */
3942 WINAPI
3944  IN DWORD level,
3945  IN LPBYTE buf,
3946  OUT LPDWORD parm_err)
3947 {
3948  FIXME("(%s %d %p %p)\n", debugstr_w(servername), level, buf, parm_err);
3949  return ERROR_ACCESS_DENIED;
3950 }
3951 
3952 
3953 /******************************************************************************
3954  * NetUserSetGroups (NETAPI32.@)
3955  */
3957 WINAPI
3959  LPCWSTR username,
3960  DWORD level,
3961  LPBYTE buf,
3962  DWORD num_entries)
3963 {
3964  FIXME("(%s %s %lu %p %lu)\n",
3965  debugstr_w(servername), debugstr_w(username), level, buf, num_entries);
3966  return ERROR_ACCESS_DENIED;
3967 }
3968 
3969 
3970 /******************************************************************************
3971  * NetUserSetInfo (NETAPI32.@)
3972  */
3974 WINAPI
3976  LPCWSTR username,
3977  DWORD level,
3978  LPBYTE buf,
3979  LPDWORD parm_err)
3980 {
3981  UNICODE_STRING ServerName;
3982  UNICODE_STRING UserName;
3983  SAM_HANDLE ServerHandle = NULL;
3984  SAM_HANDLE AccountDomainHandle = NULL;
3985  SAM_HANDLE UserHandle = NULL;
3986  NET_API_STATUS ApiStatus = NERR_Success;
3988 
3989  TRACE("(%s %s %lu %p %p)\n",
3990  debugstr_w(servername), debugstr_w(username), level, buf, parm_err);
3991 
3992  if (parm_err != NULL)
3993  *parm_err = PARM_ERROR_NONE;
3994 
3995  /* Check the info level */
3996  switch (level)
3997  {
3998  case 0:
3999  case 1:
4000  case 2:
4001  case 3:
4002  case 4:
4003 // case 21:
4004  case 22:
4005  case 1003:
4006 // case 1005:
4007  case 1006:
4008  case 1007:
4009  case 1008:
4010  case 1009:
4011 // case 1010:
4012  case 1011:
4013  case 1012:
4014  case 1013:
4015  case 1014:
4016  case 1017:
4017  case 1018:
4018  case 1020:
4019  case 1024:
4020  case 1025:
4021  case 1051:
4022  case 1052:
4023  case 1053:
4024  break;
4025 
4026  default:
4027  return ERROR_INVALID_LEVEL;
4028  }
4029 
4030  if (servername != NULL)
4031  RtlInitUnicodeString(&ServerName, servername);
4032 
4033  RtlInitUnicodeString(&UserName, username);
4034 
4035  /* Connect to the SAM Server */
4036  Status = SamConnect((servername != NULL) ? &ServerName : NULL,
4037  &ServerHandle,
4039  NULL);
4040  if (!NT_SUCCESS(Status))
4041  {
4042  ERR("SamConnect failed (Status %08lx)\n", Status);
4043  ApiStatus = NetpNtStatusToApiStatus(Status);
4044  goto done;
4045  }
4046 
4047  /* Open the Account Domain */
4048  Status = OpenAccountDomain(ServerHandle,
4049  (servername != NULL) ? &ServerName : NULL,
4051  &AccountDomainHandle);
4052  if (!NT_SUCCESS(Status))
4053  {
4054  ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
4055  ApiStatus = NetpNtStatusToApiStatus(Status);
4056  goto done;
4057  }
4058 
4059  /* Open the User Account */
4060  ApiStatus = OpenUserByName(AccountDomainHandle,
4061  &UserName,
4063  &UserHandle);
4064  if (ApiStatus != NERR_Success)
4065  {
4066  ERR("OpenUserByName(%wZ) failed (ApiStatus %lu)\n", &UserName, ApiStatus);
4067  goto done;
4068  }
4069 
4070  /* Set user information */
4071  ApiStatus = SetUserInfo(UserHandle,
4072  buf,
4073  level,
4074  parm_err);
4075  if (ApiStatus != NERR_Success)
4076  {
4077  ERR("SetUserInfo failed (Status %lu)\n", ApiStatus);
4078  }
4079 
4080 done:
4081  if (UserHandle != NULL)
4082  SamCloseHandle(UserHandle);
4083 
4084  if (AccountDomainHandle != NULL)
4085  SamCloseHandle(AccountDomainHandle);
4086 
4087  if (ServerHandle != NULL)
4088  SamCloseHandle(ServerHandle);
4089 
4090  return ApiStatus;
4091 }
4092 
4093 /* 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:101
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:39
LPWSTR usri22_parms
Definition: lmaccess.h:350
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
ULONG PrimaryGroupId
Definition: ntsam.h:679
LPWSTR usri3_comment
Definition: lmaccess.h:244
struct _USER_INFO_1006 * PUSER_INFO_1006
#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
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
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
struct _SID SID
struct _USER_INFO_11 * PUSER_INFO_11
SAM_HANDLE BuiltinDomainHandle
Definition: local_group.c:36
#define TRUE
Definition: types.h:120
_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:2215
#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
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define WARN(fmt,...)
Definition: debug.h:112
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:606
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
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
#define ZeroMemory
Definition: winbase.h:1648
NTSYSAPI PULONG NTAPI RtlSubAuthoritySid(_In_ PSID Sid, _In_ ULONG SubAuthority)
#define USER_ALL_LOGONHOURS
Definition: ntsam.h:209
NTSYSAPI NTSTATUS WINAPI RtlQueryInformationAcl(PACL, LPVOID, DWORD, ACL_INFORMATION_CLASS)
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:64
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 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:2707
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:351
#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:65
#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
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
HANDLE LsaHandle
Definition: logon.c:17
#define USER_MAXSTORAGE_UNLIMITED
Definition: lmaccess.h:111
#define UF_PASSWD_CANT_CHANGE
Definition: lmaccess.h:28
NTSYSAPI NTSTATUS NTAPI RtlInitializeSid(IN OUT PSID Sid, IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount)
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:53
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
#define FALSE
Definition: types.h:117
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:97
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:3659
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:111
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:2273
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
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:160
#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:2692
NET_API_STATUS WINAPI NetUserGetInfo(LPCWSTR servername, LPCWSTR username, DWORD level, LPBYTE *bufptr)
Definition: user.c:3147
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
Status
Definition: gdiplustypes.h:24
LPWSTR usri2_full_name
Definition: lmaccess.h:222
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
DWORD usri11_num_logons
Definition: lmaccess.h:319
LPWSTR usri11_workstations
Definition: lmaccess.h:322
DWORD usri2_code_page
Definition: lmaccess.h:236
int Count
Definition: noreturn.cpp:7
NET_API_STATUS WINAPI NetUserGetLocalGroups(LPCWSTR servername, LPCWSTR username, DWORD level, DWORD flags, LPBYTE *bufptr, DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries)
Definition: user.c:3324
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
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
DWORD usri22_acct_expires
Definition: lmaccess.h:354
#define GetProcessHeap()
Definition: compat.h:595
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:3943
DWORD usri11_max_storage
Definition: lmaccess.h:323
DWORD usri4_code_page
Definition: lmaccess.h:293
LPWSTR usri3_logon_server
Definition: lmaccess.h:260
_In_ WDFCOLLECTION _In_ ULONG Index
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:6
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:1646
#define DOMAIN_ALIAS_RID_SYSTEM_OPS
Definition: setypes.h:630
static NET_API_STATUS AllocateEnumContext(PENUM_CONTEXT *AllocatedEnumContext)
Definition: user.c:2656
NET_API_STATUS WINAPI NetUserSetGroups(LPCWSTR servername, LPCWSTR username, DWORD level, LPBYTE buf, DWORD num_entries)
Definition: user.c:3958
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:2982
#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
LPWSTR usri2_home_dir
Definition: lmaccess.h:217
LPWSTR usri11_parms
Definition: lmaccess.h:315
DWORD usrmod0_password_hist_len
Definition: lmaccess.h:437