ReactOS 0.4.16-dev-257-g6aa11ac
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
37typedef struct _ENUM_CONTEXT
38{
41
47
53
55
59
60static
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
78static
82{
84 ULONG WorldSid[sizeof(SID) / sizeof(ULONG) + SID_MAX_SUB_AUTHORITIES];
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
125static
126ULONG
127GetAccountFlags(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
204static
205ULONG
207{
208 ULONG AccountControl = 0;
209
211 AccountControl |= USER_ACCOUNT_DISABLED;
212
214 AccountControl |= USER_HOME_DIRECTORY_REQUIRED;
215
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;
235 AccountControl |= USER_SERVER_TRUST_ACCOUNT;
236
237 return AccountControl;
238}
239
240
241static
242DWORD
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
261static
262VOID
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
283static
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
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
354done:
357
358 TRACE("done (ApiStatus: 0x%08lx)\n", ApiStatus);
359
360 return ApiStatus;
361}
362
363
364static
365VOID
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)
382
383 if (UserInfo->ProfilePath.Buffer != NULL)
385
386 if (UserInfo->AdminComment.Buffer != NULL)
388
389 if (UserInfo->WorkStations.Buffer != NULL)
391
392 if (UserInfo->UserComment.Buffer != NULL)
394
395 if (UserInfo->Parameters.Buffer != NULL)
397
398 if (UserInfo->PrivateData.Buffer != NULL)
400
401 if (UserInfo->LogonHours.LogonHours != NULL)
403
404 SamFreeMemory(UserInfo);
405}
406
407
408static
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
529done:
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
548static
551 _In_ SAM_HANDLE BuiltinDomainHandle,
552 _In_ SAM_HANDLE UserHandle,
554 _In_ ULONG RelativeId,
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
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
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
864 &UserInfo2->usri2_last_logon);
865
866 if (UserInfo->LastLogoff.QuadPart == 0)
867 UserInfo2->usri2_last_logoff = 0;
868 else
870 &UserInfo2->usri2_last_logoff);
871
872 if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG)
874 else
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
983 &UserInfo3->usri3_last_logon);
984
985 if (UserInfo->LastLogoff.QuadPart == 0)
986 UserInfo3->usri3_last_logoff = 0;
987 else
989 &UserInfo3->usri3_last_logoff);
990
991 if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG)
993 else
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
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
1120 &UserInfo4->usri4_last_logon);
1121
1122 if (UserInfo->LastLogoff.QuadPart == 0)
1123 UserInfo4->usri4_last_logoff = 0;
1124 else
1126 &UserInfo4->usri4_last_logoff);
1127
1128 if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG)
1129 UserInfo4->usri4_acct_expires = TIMEQ_FOREVER;
1130 else
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
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
1277 &UserInfo11->usri11_last_logon);
1278
1279 if (UserInfo->LastLogoff.QuadPart == 0)
1280 UserInfo11->usri11_last_logoff = 0;
1281 else
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
1392done:
1393 if (UserInfo != NULL)
1394 FreeUserInfo(UserInfo);
1395
1396 if (Dacl != NULL)
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
1413static
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;
1479 }
1480
1481 // usri1_password_age ignored
1482
1483// UserInfo1->usri1_priv
1484
1485 if (UserInfo1->usri1_home_dir != NULL)
1486 {
1488 UserInfo1->usri1_home_dir);
1489 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1490 }
1491
1492 if (UserInfo1->usri1_comment != NULL)
1493 {
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;
1522 }
1523
1524 // usri2_password_age ignored
1525
1526// UserInfo2->usri2_priv;
1527
1528 if (UserInfo2->usri2_home_dir != NULL)
1529 {
1531 UserInfo2->usri2_home_dir);
1532 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1533 }
1534
1535 if (UserInfo2->usri2_comment != NULL)
1536 {
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 {
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;
1636 }
1637
1638 // usri3_password_age ignored
1639
1640// UserInfo3->usri3_priv;
1641
1642 if (UserInfo3->usri3_home_dir != NULL)
1643 {
1645 UserInfo3->usri3_home_dir);
1646 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1647 }
1648
1649 if (UserInfo3->usri3_comment != NULL)
1650 {
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 {
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);
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;
1772 }
1773
1774 // usri4_password_age ignored
1775
1776// UserInfo3->usri4_priv;
1777
1778 if (UserInfo4->usri4_home_dir != NULL)
1779 {
1781 UserInfo4->usri4_home_dir);
1782 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1783 }
1784
1785 if (UserInfo4->usri4_comment != NULL)
1786 {
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 {
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);
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 {
1914 UserInfo22->usri22_home_dir);
1915 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1916 }
1917
1918 if (UserInfo22->usri22_comment != NULL)
1919 {
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 {
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;
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 {
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 {
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 {
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
2205done:
2206 if (Dacl != NULL)
2208
2209 return ApiStatus;
2210}
2211
2212
2213static
2216 PUNICODE_STRING UserName,
2218 PSAM_HANDLE UserHandle)
2219{
2220 PULONG RelativeIds = NULL;
2221 PSID_NAME_USE Use = NULL;
2222 NET_API_STATUS ApiStatus = NERR_Success;
2224
2225 /* Get the RID for the given user name */
2226 Status = SamLookupNamesInDomain(DomainHandle,
2227 1,
2228 UserName,
2229 &RelativeIds,
2230 &Use);
2231 if (!NT_SUCCESS(Status))
2232 {
2233 ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", UserName, Status);
2235 }
2236
2237 /* Fail, if it is not an alias account */
2238 if (Use[0] != SidTypeUser)
2239 {
2240 ERR("Object is not a user!\n");
2241 ApiStatus = NERR_GroupNotFound;
2242 goto done;
2243 }
2244
2245 /* Open the alias account */
2246 Status = SamOpenUser(DomainHandle,
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
2257done:
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 */
2272WINAPI
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,
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
2363done:
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 */
2398WINAPI
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;
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))
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,
2512 if (!NT_SUCCESS(Status))
2513 {
2514 ApiStatus = NetpNtStatusToApiStatus(Status);
2515 goto done;
2516 }
2517
2519 {
2521 goto done;
2522 }
2523
2524done:
2525 if (RequestBuffer != NULL)
2526 NetApiBufferFree(RequestBuffer);
2527
2528 if (ResponseBuffer != NULL)
2529 LsaFreeReturnBuffer(ResponseBuffer);
2530
2531 if (LsaHandle != NULL)
2533
2534 return ApiStatus;
2535}
2536
2537
2538/************************************************************
2539 * NetUserDel (NETAPI32.@)
2540 */
2542WINAPI
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,
2576 &DomainHandle);
2577 if (!NT_SUCCESS(Status))
2578 {
2579 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status);
2580 ApiStatus = NetpNtStatusToApiStatus(Status);
2581 goto done;
2582 }
2583
2584 /* Open the user account in the builtin domain */
2585 ApiStatus = OpenUserByName(DomainHandle,
2586 &UserName,
2587 DELETE,
2588 &UserHandle);
2589 if (ApiStatus != NERR_Success && ApiStatus != ERROR_NONE_MAPPED)
2590 {
2591 TRACE("OpenUserByName(%wZ) failed (ApiStatus %lu)\n", &UserName, ApiStatus);
2592 goto done;
2593 }
2594
2595 if (UserHandle == NULL)
2596 {
2597 if (DomainHandle != NULL)
2598 {
2599 SamCloseHandle(DomainHandle);
2600 DomainHandle = NULL;
2601 }
2602
2603 /* Open the Acount Domain */
2604 Status = OpenAccountDomain(ServerHandle,
2605 (servername != NULL) ? &ServerName : NULL,
2607 &DomainHandle);
2608 if (!NT_SUCCESS(Status))
2609 {
2610 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2611 ApiStatus = NetpNtStatusToApiStatus(Status);
2612 goto done;
2613 }
2614
2615 /* Open the user account in the account domain */
2616 ApiStatus = OpenUserByName(DomainHandle,
2617 &UserName,
2618 DELETE,
2619 &UserHandle);
2620 if (ApiStatus != NERR_Success)
2621 {
2622 ERR("OpenUserByName(%wZ) failed (ApiStatus %lu)\n", &UserName, ApiStatus);
2623 if (ApiStatus == ERROR_NONE_MAPPED)
2624 ApiStatus = NERR_UserNotFound;
2625 goto done;
2626 }
2627 }
2628
2629 /* Delete the user */
2630 Status = SamDeleteUser(UserHandle);
2631 if (!NT_SUCCESS(Status))
2632 {
2633 ERR("SamDeleteUser failed (Status %08lx)\n", Status);
2634 ApiStatus = NetpNtStatusToApiStatus(Status);
2635 goto done;
2636 }
2637
2638 /* A successful delete invalidates the handle */
2639 UserHandle = NULL;
2640
2641done:
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
2654static
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 */
2676 if (EnumContext->EnumHandle == 0)
2677 {
2679 }
2680
2681 /* Insert the context in the list */
2685
2686 *AllocatedEnumContext = EnumContext;
2687 return NERR_Success;
2688}
2689
2690static
2691VOID
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
2705static
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 */
2739WINAPI
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 */
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,
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
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,
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
2922done:
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 */
2981WINAPI
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,
3028 if (!NT_SUCCESS(Status))
3029 {
3030 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
3031 ApiStatus = NetpNtStatusToApiStatus(Status);
3032 goto done;
3033 }
3034
3035 /* Open the Account Domain */
3036 Status = SamOpenDomain(ServerHandle,
3039 &AccountDomainHandle);
3040 if (!NT_SUCCESS(Status))
3041 {
3042 ERR("SamOpenDomain failed (Status %08lx)\n", Status);
3043 ApiStatus = NetpNtStatusToApiStatus(Status);
3044 goto done;
3045 }
3046
3047 /* Get the RID for the given user name */
3048 Status = SamLookupNamesInDomain(AccountDomainHandle,
3049 1,
3050 &UserName,
3051 &RelativeIds,
3052 &Use);
3053 if (!NT_SUCCESS(Status))
3054 {
3055 ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", &UserName, Status);
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
3102done:
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 */
3146WINAPI
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,
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,
3215 if (!NT_SUCCESS(Status))
3216 {
3217 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
3218 ApiStatus = NetpNtStatusToApiStatus(Status);
3219 goto done;
3220 }
3221
3222 /* Open the Account Domain */
3223 Status = SamOpenDomain(ServerHandle,
3226 &AccountDomainHandle);
3227 if (!NT_SUCCESS(Status))
3228 {
3229 ERR("SamOpenDomain failed (Status %08lx)\n", Status);
3230 ApiStatus = NetpNtStatusToApiStatus(Status);
3231 goto done;
3232 }
3233
3234 /* Get the RID for the given user name */
3235 Status = SamLookupNamesInDomain(AccountDomainHandle,
3236 1,
3237 &UserName,
3238 &RelativeIds,
3239 &Use);
3240 if (!NT_SUCCESS(Status))
3241 {
3242 ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", &UserName, Status);
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,
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
3288done:
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 */
3323WINAPI
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",
3359 prefmaxlen, entriesread, totalentries);
3360
3361 if (level != 0)
3362 return ERROR_INVALID_LEVEL;
3363
3366
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,
3403 if (!NT_SUCCESS(Status))
3404 {
3405 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
3406 ApiStatus = NetpNtStatusToApiStatus(Status);
3407 goto done;
3408 }
3409
3410 /* Open the Account Domain */
3411 Status = SamOpenDomain(ServerHandle,
3414 &AccountDomainHandle);
3415 if (!NT_SUCCESS(Status))
3416 {
3417 ERR("SamOpenDomain failed (Status %08lx)\n", Status);
3418 ApiStatus = NetpNtStatusToApiStatus(Status);
3419 goto done;
3420 }
3421
3422 /* Get the RID for the given user name */
3423 Status = SamLookupNamesInDomain(AccountDomainHandle,
3424 1,
3425 &UserName,
3426 &RelativeIds,
3427 &Use);
3428 if (!NT_SUCCESS(Status))
3429 {
3430 ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", &UserName, Status);
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
3580done:
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 */
3658WINAPI
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;
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,
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
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
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);
3848 DeltaTimeToSeconds(PasswordInfo->MinPasswordAge);
3849 umi0->usrmod0_force_logoff =
3850 DeltaTimeToSeconds(LogoffInfo->ForceLogoff);
3852 break;
3853
3854 case 1:
3855 umi1 = (PUSER_MODALS_INFO_1)*bufptr;
3856
3857 switch (ServerRoleInfo->DomainServerRole)
3858 {
3861 break;
3862
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
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;
3899 DeltaTimeToSeconds(LockoutInfo->LockoutDuration);
3902 umi3->usrmod3_lockout_threshold = LockoutInfo->LockoutThreshold;
3903 break;
3904 }
3905
3906done:
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 */
3942WINAPI
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 */
3957WINAPI
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 */
3974WINAPI
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 th