ReactOS  0.4.14-dev-50-g13bb5e2
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 failed (Status %08lx)\n", 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 failed (ApiStatus %lu)\n", 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 failed (ApiStatus %lu)\n", 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("OpenAccountDomain 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 failed (Status %08lx)\n", 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("OpenAccountDomain 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("SamOpenDomain failed (Status %08lx)\n", 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("OpenAccountDomain 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 failed (Status %08lx)\n", 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 failed (ApiStatus %lu)\n", 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:91
NTSTATUS NTAPI SamCloseHandle(IN SAM_HANDLE SamHandle)
Definition: samlib.c:476
#define USER_PASSWORD_EXPIRED
Definition: ntsam.h:184
DWORD usri11_auth_flags
Definition: lmaccess.h:312
DWORD usri1_password_age
Definition: lmaccess.h:205
NTSTATUS NTAPI SamGetGroupsForUser(IN SAM_HANDLE UserHandle, OUT PGROUP_MEMBERSHIP *Groups, OUT PULONG MembershipCount)
Definition: samlib.c:1058
#define SAM_SERVER_CONNECT
Definition: ntsam.h:99
LPWSTR usri1_password
Definition: lmaccess.h:204
GLint level
Definition: gl.h:1546
#define IN
Definition: typedefs.h:38
LPWSTR usri22_parms
Definition: lmaccess.h:350
ULONG PrimaryGroupId
Definition: ntsam.h:679
LPWSTR usri3_comment
Definition: lmaccess.h:244
struct _USER_INFO_1006 * PUSER_INFO_1006
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define USER_ALL_ACCOUNTEXPIRES
Definition: ntsam.h:215
#define USER_UNITS_PER_WEEK_PARMNUM
Definition: lmaccess.h:71
DWORD usri11_units_per_week
Definition: lmaccess.h:324
LARGE_INTEGER AccountExpires
Definition: ntsam.h:661
#define MSV1_0_PACKAGE_NAME
Definition: ntsecapi.h:42
struct _USER_INFO_4 * PUSER_INFO_4
LPWSTR usri23_name
Definition: lmaccess.h:365
LPWSTR usri3_parms
Definition: lmaccess.h:250
LPWSTR usri2_logon_server
Definition: lmaccess.h:234
#define USER_PASSWORD_NOT_REQUIRED
Definition: ntsam.h:169
PBYTE usri11_logon_hours
Definition: lmaccess.h:325
DWORD usri3_bad_pw_count
Definition: lmaccess.h:258
UNICODE_STRING ScriptPath
Definition: ntsam.h:668
struct _MSV1_0_CHANGEPASSWORD_REQUEST MSV1_0_CHANGEPASSWORD_REQUEST
LPWSTR usri11_logon_server
Definition: lmaccess.h:320
CRITICAL_SECTION g_EnumContextListLock
Definition: user.c:57
BOOLEAN PasswordExpired
Definition: ntsam.h:689
static unsigned int bufptr
Definition: tncon.cpp:77
static NET_API_STATUS BuildUserInfoBuffer(_In_ SAM_HANDLE BuiltinDomainHandle, _In_ SAM_HANDLE UserHandle, _In_ PSID AccountDomainSid, _In_ ULONG RelativeId, _In_ DWORD level, _Out_ LPVOID *Buffer)
Definition: user.c:550
USHORT CountryCode
Definition: ntsam.h:685
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define DOMAIN_GET_ALIAS_MEMBERSHIP
Definition: ntsam.h:40
#define UF_INTERDOMAIN_TRUST_ACCOUNT
Definition: lmaccess.h:31
UNICODE_STRING PrivateData
Definition: ntsam.h:676
LARGE_INTEGER LockoutDuration
Definition: ntsam.h:422
struct _USER_MODALS_INFO_1 USER_MODALS_INFO_1
struct _USER_INFO_1009 * PUSER_INFO_1009
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
struct _SID SID
struct _USER_INFO_11 * PUSER_INFO_11
BOOLEAN NTAPI RtlTimeToSecondsSince1970(PLARGE_INTEGER Time, PULONG ElapsedSeconds)
SAM_HANDLE BuiltinDomainHandle
Definition: local_group.c:36
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
LPWSTR usri3_home_dir
Definition: lmaccess.h:243
struct _USER_INFO_20 USER_INFO_20
DWORD usri2_priv
Definition: lmaccess.h:216
NTSYSAPI VOID NTAPI RtlSecondsSince1970ToTime(_In_ ULONG SecondsSince1970, _Out_ PLARGE_INTEGER Time)
static NET_API_STATUS OpenUserByName(SAM_HANDLE DomainHandle, PUNICODE_STRING UserName, ULONG DesiredAccess, PSAM_HANDLE UserHandle)
Definition: user.c: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:111
LPWSTR usri2_name
Definition: lmaccess.h:213
#define USER_TEMP_DUPLICATE_ACCOUNT
Definition: ntsam.h:170
#define ERROR_NONE_MAPPED
Definition: winerror.h:814
LONG NTSTATUS
Definition: precomp.h:26
LPWSTR usri22_workstations
Definition: lmaccess.h:351
static SID_IDENTIFIER_AUTHORITY WorldAuthority
Definition: security.c:14
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c: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
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define ZeroMemory
Definition: winbase.h:1635
NTSYSAPI PULONG NTAPI RtlSubAuthoritySid(_In_ PSID Sid, _In_ ULONG SubAuthority)
#define USER_ALL_LOGONHOURS
Definition: ntsam.h:209
NTSTATUS NTAPI SamQueryInformationDomain(IN SAM_HANDLE DomainHandle, IN DOMAIN_INFORMATION_CLASS DomainInformationClass, OUT PVOID *Buffer)
Definition: samlib.c:1641
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
LPWSTR usri10_name
Definition: lmaccess.h:301
BOOLEAN BuiltinDone
Definition: user.c:52
DWORD usri3_acct_expires
Definition: lmaccess.h:254
NTSYSAPI NTSTATUS NTAPI RtlGetAce(PACL Acl, ULONG AceIndex, PVOID *Ace)
#define AF_OP_SERVER
Definition: lmaccess.h:47
LPWSTR usri1011_full_name
Definition: lmaccess.h:393
LPWSTR usri11_full_name
Definition: lmaccess.h:310
struct _USER_INFO_4 USER_INFO_4
#define USER_HOME_DIRECTORY_REQUIRED
Definition: ntsam.h:168
DWORD usri4_flags
Definition: lmaccess.h:276
NTSTATUS NTAPI SamEnumerateUsersInDomain(IN SAM_HANDLE DomainHandle, IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, IN ULONG UserAccountControl, OUT PVOID *Buffer, IN ULONG PreferedMaximumLength, OUT PULONG CountReturned)
Definition: samlib.c:897
UNICODE_STRING ProfilePath
Definition: ntsam.h:669
#define MAXLONGLONG
PBYTE usri1020_logon_hours
Definition: lmaccess.h:412
DWORD usri4_auth_flags
Definition: lmaccess.h:278
DWORD usri2_auth_flags
Definition: lmaccess.h:221
PSID BuiltinDomainSid
Definition: globals.c:16
#define NERR_GroupNotFound
Definition: lmerr.h:87
LPWSTR usri4_logon_server
Definition: lmaccess.h:291
int32_t INT_PTR
Definition: typedefs.h:62
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define InsertTailList(ListHead, Entry)
DWORD usri1008_flags
Definition: lmaccess.h:384
struct _USER_INFO_1014 * PUSER_INFO_1014
ULONG UserAccountControl
Definition: ntsam.h:680
static DWORD GetPasswordAge(IN PLARGE_INTEGER PasswordLastSet)
Definition: user.c:243
#define 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:337
#define USER_ALL_USERNAME
Definition: ntsam.h:196
DWORD usri4_priv
Definition: lmaccess.h:273
struct _USER_INFO_1007 * PUSER_INFO_1007
#define USER_ACCOUNT_DISABLED
Definition: ntsam.h:167
LPWSTR usri3_home_dir_drive
Definition: lmaccess.h:266
#define NERR_Success
Definition: lmerr.h:5
DWORD usrmod0_min_passwd_len
Definition: lmaccess.h:433
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define USHRT_MAX
Definition: limits.h:38
static ULONG DeltaTimeToSeconds(LARGE_INTEGER DeltaTime)
Definition: user.c:62
struct _USER_MODALS_INFO_3 USER_MODALS_INFO_3
#define NERR_InternalError
Definition: lmerr.h:28
struct _USER_INFO_1012 * PUSER_INFO_1012
DWORD usri2_last_logoff
Definition: lmaccess.h:227
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
DWORD usri4_country_code
Definition: lmaccess.h:292
#define USER_PRIV_USER
Definition: lmaccess.h:117
DWORD usri1024_country_code
Definition: lmaccess.h:418
static NET_API_STATUS SetUserInfo(SAM_HANDLE UserHandle, LPBYTE UserInfo, DWORD Level, PDWORD parm_err)
Definition: user.c:1415
LPWSTR usri1003_password
Definition: lmaccess.h:372
HANDLE LsaHandle
Definition: logon.c:17
#define USER_MAXSTORAGE_UNLIMITED
Definition: lmaccess.h:111
#define UF_PASSWD_CANT_CHANGE
Definition: lmaccess.h:28
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
NTSYSAPI NTSTATUS NTAPI RtlInitializeSid(IN OUT PSID Sid, IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static NTSTATUS GetAccountDomainSid(PRPC_SID *Sid)
Definition: msv1_0.c:25
static NET_API_STATUS GetUserDacl(IN SAM_HANDLE UserHandle, OUT PACL *Dacl)
Definition: user.c:285
unsigned char * LPBYTE
Definition: typedefs.h:52
VOID NTAPI ProtocolStatus(NDIS_HANDLE BindingContext, NDIS_STATUS GenerelStatus, PVOID StatusBuffer, UINT StatusBufferSize)
Called by NDIS when the underlying driver has changed state.
Definition: lan.c:461
#define USER_READ_GENERAL
Definition: ntsam.h:126
#define USER_ALL_FULLNAME
Definition: ntsam.h:197
DWORD usri2_password_age
Definition: lmaccess.h:215
#define UNICODE_NULL
LPWSTR usri20_full_name
Definition: lmaccess.h:330
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
DWORD usri2_units_per_week
Definition: lmaccess.h:230
DWORD usri11_password_age
Definition: lmaccess.h:313
unsigned int BOOL
Definition: ntddk_ex.h:94
DWORD usrmod0_max_passwd_age
Definition: lmaccess.h:434
long LONG
Definition: pedump.c:60
DWORD usri2_max_storage
Definition: lmaccess.h:229
NET_API_STATUS WINAPI NetUserModalsGet(LPCWSTR servername, DWORD level, LPBYTE *bufptr)
Definition: user.c: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:110
LPWSTR usri3_full_name
Definition: lmaccess.h:248
NTSTATUS NTAPI SamLookupIdsInDomain(IN SAM_HANDLE DomainHandle, IN ULONG Count, IN PULONG RelativeIds, OUT PUNICODE_STRING *Names, OUT PSID_NAME_USE *Use OPTIONAL)
Definition: samlib.c:1220
PSID AccountDomainSid
Definition: user.c:46
struct _USER_INFO_20 * PUSER_INFO_20
struct _USER_INFO_2 * PUSER_INFO_2
NET_API_STATUS WINAPI NetUserAdd(LPCWSTR servername, DWORD level, LPBYTE bufptr, LPDWORD parm_err)
Definition: user.c: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
smooth NULL
Definition: ftsmooth.c:416
struct _USER_INFO_3 USER_INFO_3
LPWSTR usri1009_script_path
Definition: lmaccess.h:387
DWORD usri1017_acct_expires
Definition: lmaccess.h:405
LPWSTR usri22_home_dir
Definition: lmaccess.h:343
DWORD usri3_flags
Definition: lmaccess.h:245
#define _Out_
Definition: no_sal2.h:323
#define SAM_SERVER_LOOKUP_DOMAIN
Definition: ntsam.h:104
SAM_ENUMERATE_HANDLE EnumerationContext
Definition: local_group.c:39
static VOID ChangeUserDacl(IN PACL Dacl, IN ULONG Flags)
Definition: user.c:263
struct _USER_INFO_1053 * PUSER_INFO_1053
#define LG_INCLUDE_INDIRECT
Definition: lmaccess.h:44
Definition: bufpool.h:45
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
LPWSTR usri20_name
Definition: lmaccess.h:329
#define UAS_ROLE_BACKUP
Definition: lmaccess.h:52
#define USER_ALL_USERACCOUNTCONTROL
Definition: ntsam.h:216
#define UF_PASSWD_NOTREQD
Definition: lmaccess.h:27
NTSTATUS NTAPI SamSetInformationUser(IN SAM_HANDLE UserHandle, IN USER_INFORMATION_CLASS UserInformationClass, IN PVOID Buffer)
Definition: samlib.c:1964
static VOID FreeEnumContext(PENUM_CONTEXT EnumContext)
Definition: user.c: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
LPWSTR usri2_full_name
Definition: lmaccess.h:222
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
DWORD usri11_num_logons
Definition: lmaccess.h:319
LPWSTR usri11_workstations
Definition: lmaccess.h:322
DWORD usri2_code_page
Definition: lmaccess.h:236
NET_API_STATUS WINAPI NetUserGetLocalGroups(LPCWSTR servername, LPCWSTR username, DWORD level, DWORD flags, LPBYTE *bufptr, DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries)
Definition: user.c: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
DWORD usri22_acct_expires
Definition: lmaccess.h:354
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD usri4_acct_expires
Definition: lmaccess.h:285
LPWSTR usri11_home_dir
Definition: lmaccess.h:314
struct _USER_INFO_23 * PUSER_INFO_23
__wchar_t WCHAR
Definition: xmlstorage.h:180
LPWSTR usri2_workstations
Definition: lmaccess.h:225
LPWSTR usri1_comment
Definition: lmaccess.h:208
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _ENUM_CONTEXT * PENUM_CONTEXT
#define USER_READ_ACCOUNT
Definition: ntsam.h:130
struct _USER_INFO_1008 * PUSER_INFO_1008
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:499
NET_API_STATUS WINAPI NetUserModalsSet(IN LPCWSTR servername, IN DWORD level, IN LPBYTE buf, OUT LPDWORD parm_err)
Definition: user.c: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
struct _USER_MODALS_INFO_2 USER_MODALS_INFO_2
struct _USER_INFO_22 * PUSER_INFO_22
SAM_HANDLE AccountDomainHandle
Definition: local_group.c:37
#define UAS_ROLE_PRIMARY
Definition: lmaccess.h:53
struct _USER_INFO_1025 * PUSER_INFO_1025
LPWSTR usri2_script_path
Definition: lmaccess.h:220
PSID BuiltinDomainSid
Definition: user.c:45
LARGE_INTEGER MaxPasswordAge
Definition: ntsam.h:347
#define DOMAIN_READ_PASSWORD_PARAMETERS
Definition: ntsam.h:33
#define UF_SERVER_TRUST_ACCOUNT
Definition: lmaccess.h:33
#define WINAPI
Definition: msvc.h:8
struct _USER_INFO_1017 * PUSER_INFO_1017
UNICODE_STRING HomeDirectory
Definition: ntsam.h:666
static VOID FreeUserInfo(PUSER_ALL_INFORMATION UserInfo)
Definition: user.c:366
LPWSTR usri11_comment
Definition: lmaccess.h:308
#define CopyMemory
Definition: winbase.h:1633
static const UCHAR Index[8]
Definition: usbohci.c:18
#define DOMAIN_ALIAS_RID_SYSTEM_OPS
Definition: setypes.h:630
static NET_API_STATUS AllocateEnumContext(PENUM_CONTEXT *AllocatedEnumContext)
Definition: user.c:2656
#define BufferSize
Definition: classpnp.h:419
NET_API_STATUS WINAPI NetUserSetGroups(LPCWSTR servername, LPCWSTR username, DWORD level, LPBYTE buf, DWORD num_entries)
Definition: user.c: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
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
LPWSTR usri2_home_dir
Definition: lmaccess.h:217
LPWSTR usri11_parms
Definition: lmaccess.h:315
DWORD usrmod0_password_hist_len
Definition: lmaccess.h:437
PSID usri4_user_sid
Definition: lmaccess.h:294
#define SECURITY_WORLD_RID
Definition: setypes.h:513
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
GLbitfield flags
Definition: glext.h:7161
DWORD usrmod0_min_passwd_age
Definition: lmaccess.h:435
#define READ_CONTROL
Definition: nt_native.h:58
DWORD usri11_country_code
Definition: lmaccess.h:321
LPWSTR usrmod2_domain_name
Definition: lmaccess.h:444
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1553
DWORD usri2_last_logon
Definition: lmaccess.h:226
UNICODE_STRING UserName
Definition: ntsam.h:664
DWORD usri3_last_logon
Definition: lmaccess.h:252
NET_API_STATUS WINAPI NetUserDel(LPCWSTR servername, LPCWSTR username)
Definition: user.c:2543