[NETAPI32] NetUserEnum, NetUserGetInfo: Get the user privileges and auth flags for...
[reactos.git] / dll / win32 / netapi32 / user.c
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
35 WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
36
37 typedef struct _ENUM_CONTEXT
38 {
39 SAM_HANDLE ServerHandle;
40 SAM_HANDLE BuiltinDomainHandle;
41 SAM_HANDLE AccountDomainHandle;
42 PSID BuiltinDomainSid;
43 PSID AccountDomainSid;
44
45 SAM_ENUMERATE_HANDLE EnumerationContext;
46 PSAM_RID_ENUMERATION Buffer;
47 ULONG Count;
48 ULONG Index;
49 BOOLEAN BuiltinDone;
50
51 } ENUM_CONTEXT, *PENUM_CONTEXT;
52
53
54 static
55 ULONG
56 DeltaTimeToSeconds(LARGE_INTEGER DeltaTime)
57 {
58 LARGE_INTEGER Seconds;
59
60 if (DeltaTime.QuadPart == 0)
61 return 0;
62
63 Seconds.QuadPart = -DeltaTime.QuadPart / 10000000;
64
65 if (Seconds.HighPart != 0)
66 return TIMEQ_FOREVER;
67
68 return Seconds.LowPart;
69 }
70
71
72 static
73 NTSTATUS
74 GetAllowedWorldAce(IN PACL Acl,
75 OUT PACCESS_ALLOWED_ACE *Ace)
76 {
77 SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
78 ULONG WorldSid[sizeof(SID) / sizeof(ULONG) + SID_MAX_SUB_AUTHORITIES];
79 ACL_SIZE_INFORMATION AclSize;
80 PVOID LocalAce = NULL;
81 ULONG i;
82 NTSTATUS Status;
83
84 *Ace = NULL;
85
86 RtlInitializeSid((PSID)WorldSid,
87 &WorldAuthority,
88 1);
89 *(RtlSubAuthoritySid((PSID)WorldSid, 0)) = SECURITY_WORLD_RID;
90
91 Status = RtlQueryInformationAcl(Acl,
92 &AclSize,
93 sizeof(AclSize),
94 AclSizeInformation);
95 if (!NT_SUCCESS(Status))
96 return Status;
97
98 for (i = 0; i < AclSize.AceCount; i++)
99 {
100 Status = RtlGetAce(Acl, i, &LocalAce);
101 if (!NT_SUCCESS(Status))
102 return Status;
103
104 if (((PACE_HEADER)LocalAce)->AceType != ACCESS_ALLOWED_ACE_TYPE)
105 continue;
106
107 if (RtlEqualSid((PSID)WorldSid,
108 (PSID)&((PACCESS_ALLOWED_ACE)LocalAce)->SidStart))
109 {
110 *Ace = (PACCESS_ALLOWED_ACE)LocalAce;
111 return STATUS_SUCCESS;
112 }
113 }
114
115 return STATUS_SUCCESS;
116 }
117
118
119 static
120 ULONG
121 GetAccountFlags(ULONG AccountControl,
122 PACL Dacl)
123 {
124 PACCESS_ALLOWED_ACE Ace = NULL;
125 ULONG Flags = UF_SCRIPT;
126 NTSTATUS Status;
127
128 if (Dacl != NULL)
129 {
130 Status = GetAllowedWorldAce(Dacl, &Ace);
131 if (NT_SUCCESS(Status))
132 {
133 if (Ace == NULL)
134 {
135 Flags |= UF_PASSWD_CANT_CHANGE;
136 }
137 else if ((Ace->Mask & USER_CHANGE_PASSWORD) == 0)
138 {
139 Flags |= UF_PASSWD_CANT_CHANGE;
140 }
141 }
142 }
143
144 if (AccountControl & USER_ACCOUNT_DISABLED)
145 Flags |= UF_ACCOUNTDISABLE;
146
147 if (AccountControl & USER_HOME_DIRECTORY_REQUIRED)
148 Flags |= UF_HOMEDIR_REQUIRED;
149
150 if (AccountControl & USER_PASSWORD_NOT_REQUIRED)
151 Flags |= UF_PASSWD_NOTREQD;
152
153 if (AccountControl & USER_ACCOUNT_AUTO_LOCKED)
154 Flags |= UF_LOCKOUT;
155
156 if (AccountControl & USER_DONT_EXPIRE_PASSWORD)
157 Flags |= UF_DONT_EXPIRE_PASSWD;
158
159 /*
160 if (AccountControl & USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED)
161 Flags |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED;
162
163 if (AccountControl & USER_SMARTCARD_REQUIRED)
164 Flags |= UF_SMARTCARD_REQUIRED;
165
166 if (AccountControl & USER_TRUSTED_FOR_DELEGATION)
167 Flags |= UF_TRUSTED_FOR_DELEGATION;
168
169 if (AccountControl & USER_NOT_DELEGATED)
170 Flags |= UF_NOT_DELEGATED;
171
172 if (AccountControl & USER_USE_DES_KEY_ONLY)
173 Flags |= UF_USE_DES_KEY_ONLY;
174
175 if (AccountControl & USER_DONT_REQUIRE_PREAUTH)
176 Flags |= UF_DONT_REQUIRE_PREAUTH;
177
178 if (AccountControl & USER_PASSWORD_EXPIRED)
179 Flags |= UF_PASSWORD_EXPIRED;
180 */
181
182 /* Set account type flags */
183 if (AccountControl & USER_TEMP_DUPLICATE_ACCOUNT)
184 Flags |= UF_TEMP_DUPLICATE_ACCOUNT;
185 else if (AccountControl & USER_NORMAL_ACCOUNT)
186 Flags |= UF_NORMAL_ACCOUNT;
187 else if (AccountControl & USER_INTERDOMAIN_TRUST_ACCOUNT)
188 Flags |= UF_INTERDOMAIN_TRUST_ACCOUNT;
189 else if (AccountControl & USER_WORKSTATION_TRUST_ACCOUNT)
190 Flags |= UF_WORKSTATION_TRUST_ACCOUNT;
191 else if (AccountControl & USER_SERVER_TRUST_ACCOUNT)
192 Flags |= UF_SERVER_TRUST_ACCOUNT;
193
194 return Flags;
195 }
196
197
198 static
199 ULONG
200 GetAccountControl(ULONG Flags)
201 {
202 ULONG AccountControl = 0;
203
204 if (Flags & UF_ACCOUNTDISABLE)
205 AccountControl |= USER_ACCOUNT_DISABLED;
206
207 if (Flags & UF_HOMEDIR_REQUIRED)
208 AccountControl |= USER_HOME_DIRECTORY_REQUIRED;
209
210 if (Flags & UF_PASSWD_NOTREQD)
211 AccountControl |= USER_PASSWORD_NOT_REQUIRED;
212
213 if (Flags & UF_LOCKOUT)
214 AccountControl |= USER_ACCOUNT_AUTO_LOCKED;
215
216 if (Flags & UF_DONT_EXPIRE_PASSWD)
217 AccountControl |= USER_DONT_EXPIRE_PASSWORD;
218
219 /* Set account type flags */
220 if (Flags & UF_TEMP_DUPLICATE_ACCOUNT)
221 AccountControl |= USER_TEMP_DUPLICATE_ACCOUNT;
222 else if (Flags & UF_NORMAL_ACCOUNT)
223 AccountControl |= USER_NORMAL_ACCOUNT;
224 else if (Flags & UF_INTERDOMAIN_TRUST_ACCOUNT)
225 AccountControl |= USER_INTERDOMAIN_TRUST_ACCOUNT;
226 else if (Flags & UF_WORKSTATION_TRUST_ACCOUNT)
227 AccountControl |= USER_WORKSTATION_TRUST_ACCOUNT;
228 else if (Flags & UF_SERVER_TRUST_ACCOUNT)
229 AccountControl |= USER_SERVER_TRUST_ACCOUNT;
230
231 return AccountControl;
232 }
233
234
235 static
236 DWORD
237 GetPasswordAge(IN PLARGE_INTEGER PasswordLastSet)
238 {
239 LARGE_INTEGER SystemTime;
240 ULONG SystemSecondsSince1970;
241 ULONG PasswordSecondsSince1970;
242 NTSTATUS Status;
243
244 Status = NtQuerySystemTime(&SystemTime);
245 if (!NT_SUCCESS(Status))
246 return 0;
247
248 RtlTimeToSecondsSince1970(&SystemTime, &SystemSecondsSince1970);
249 RtlTimeToSecondsSince1970(PasswordLastSet, &PasswordSecondsSince1970);
250
251 return SystemSecondsSince1970 - PasswordSecondsSince1970;
252 }
253
254
255 static
256 VOID
257 ChangeUserDacl(IN PACL Dacl,
258 IN ULONG Flags)
259 {
260 PACCESS_ALLOWED_ACE Ace = NULL;
261 NTSTATUS Status;
262
263 if (Dacl == NULL)
264 return;
265
266 Status = GetAllowedWorldAce(Dacl, &Ace);
267 if (!NT_SUCCESS(Status))
268 return;
269
270 if (Flags & UF_PASSWD_CANT_CHANGE)
271 Ace->Mask &= ~USER_CHANGE_PASSWORD;
272 else
273 Ace->Mask |= USER_CHANGE_PASSWORD;
274 }
275
276
277 static
278 NET_API_STATUS
279 GetUserDacl(IN SAM_HANDLE UserHandle,
280 OUT PACL *Dacl)
281 {
282 PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
283 PACL SamDacl;
284 PACL LocalDacl;
285 BOOLEAN Defaulted;
286 BOOLEAN Present;
287 ACL_SIZE_INFORMATION AclSize;
288 NET_API_STATUS ApiStatus;
289 NTSTATUS Status;
290
291 TRACE("(%p %p)\n", UserHandle, Dacl);
292
293 *Dacl = NULL;
294
295 Status = SamQuerySecurityObject(UserHandle,
296 DACL_SECURITY_INFORMATION,
297 &SecurityDescriptor);
298 if (!NT_SUCCESS(Status))
299 {
300 TRACE("SamQuerySecurityObject() failed (Status 0x%08lx)\n", Status);
301 ApiStatus = NetpNtStatusToApiStatus(Status);
302 goto done;
303 }
304
305 Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
306 &Present,
307 &SamDacl,
308 &Defaulted);
309 if (!NT_SUCCESS(Status))
310 {
311 TRACE("RtlGetDaclSecurityDescriptor() failed (Status 0x%08lx)\n", Status);
312 ApiStatus = NERR_InternalError;
313 goto done;
314 }
315
316 if (Present == FALSE)
317 {
318 TRACE("No DACL present\n");
319 ApiStatus = NERR_Success;
320 goto done;
321 }
322
323 Status = RtlQueryInformationAcl(SamDacl,
324 &AclSize,
325 sizeof(AclSize),
326 AclSizeInformation);
327 if (!NT_SUCCESS(Status))
328 {
329 TRACE("RtlQueryInformationAcl() failed (Status 0x%08lx)\n", Status);
330 ApiStatus = NERR_InternalError;
331 goto done;
332 }
333
334 LocalDacl = HeapAlloc(GetProcessHeap(), 0, AclSize.AclBytesInUse);
335 if (LocalDacl == NULL)
336 {
337 TRACE("Memory allocation failed\n");
338 ApiStatus = ERROR_NOT_ENOUGH_MEMORY;
339 goto done;
340 }
341
342 RtlCopyMemory(LocalDacl, SamDacl, AclSize.AclBytesInUse);
343
344 *Dacl = LocalDacl;
345
346 ApiStatus = NERR_Success;
347
348 done:
349 if (SecurityDescriptor != NULL)
350 SamFreeMemory(SecurityDescriptor);
351
352 TRACE("done (ApiStatus: 0x%08lx)\n", ApiStatus);
353
354 return ApiStatus;
355 }
356
357
358 static
359 VOID
360 FreeUserInfo(PUSER_ALL_INFORMATION UserInfo)
361 {
362 if (UserInfo->UserName.Buffer != NULL)
363 SamFreeMemory(UserInfo->UserName.Buffer);
364
365 if (UserInfo->FullName.Buffer != NULL)
366 SamFreeMemory(UserInfo->FullName.Buffer);
367
368 if (UserInfo->HomeDirectory.Buffer != NULL)
369 SamFreeMemory(UserInfo->HomeDirectory.Buffer);
370
371 if (UserInfo->HomeDirectoryDrive.Buffer != NULL)
372 SamFreeMemory(UserInfo->HomeDirectoryDrive.Buffer);
373
374 if (UserInfo->ScriptPath.Buffer != NULL)
375 SamFreeMemory(UserInfo->ScriptPath.Buffer);
376
377 if (UserInfo->ProfilePath.Buffer != NULL)
378 SamFreeMemory(UserInfo->ProfilePath.Buffer);
379
380 if (UserInfo->AdminComment.Buffer != NULL)
381 SamFreeMemory(UserInfo->AdminComment.Buffer);
382
383 if (UserInfo->WorkStations.Buffer != NULL)
384 SamFreeMemory(UserInfo->WorkStations.Buffer);
385
386 if (UserInfo->UserComment.Buffer != NULL)
387 SamFreeMemory(UserInfo->UserComment.Buffer);
388
389 if (UserInfo->Parameters.Buffer != NULL)
390 SamFreeMemory(UserInfo->Parameters.Buffer);
391
392 if (UserInfo->PrivateData.Buffer != NULL)
393 SamFreeMemory(UserInfo->PrivateData.Buffer);
394
395 if (UserInfo->LogonHours.LogonHours != NULL)
396 SamFreeMemory(UserInfo->LogonHours.LogonHours);
397
398 SamFreeMemory(UserInfo);
399 }
400
401
402 static
403 NET_API_STATUS
404 GetUserPrivileges(
405 _In_ SAM_HANDLE BuiltinDomainHandle,
406 _In_ SAM_HANDLE UserHandle,
407 _In_ PSID AccountDomainSid,
408 _In_ ULONG RelativeId,
409 _Out_ PDWORD Priv,
410 _Out_ PDWORD AuthFlags)
411 {
412 PGROUP_MEMBERSHIP GroupMembership = NULL;
413 ULONG GroupCount, SidCount, AliasCount, i;
414 PSID *SidArray = NULL;
415 PULONG AliasArray = NULL;
416 BOOL bAdmin = FALSE, bUser = FALSE;
417 NET_API_STATUS ApiStatus = NERR_Success;
418 NTSTATUS Status;
419
420 FIXME("GetUserPrivileges(%p)\n", UserHandle);
421
422 /* Get the users group memberships */
423 Status = SamGetGroupsForUser(UserHandle,
424 &GroupMembership,
425 &GroupCount);
426 if (!NT_SUCCESS(Status))
427 {
428 ERR("SamGetGroupsForUser() failed (Status 0x%08lx)\n", Status);
429 ApiStatus = NetpNtStatusToApiStatus(Status);
430 goto done;
431 }
432
433 /* Allocate the SID array */
434 ApiStatus = NetApiBufferAllocate((GroupCount + 1) * sizeof(PSID),
435 (PVOID*)&SidArray);
436 if (ApiStatus != NERR_Success)
437 {
438 goto done;
439 }
440
441 /* Add the user to the SID array */
442 SidCount = 0;
443 ApiStatus = BuildSidFromSidAndRid(AccountDomainSid,
444 RelativeId,
445 &SidArray[0]);
446 if (ApiStatus != NERR_Success)
447 {
448 goto done;
449 }
450
451 SidCount++;
452
453 /* Add the groups to the SID array */
454 for (i = 0; i < GroupCount; i++)
455 {
456 ApiStatus = BuildSidFromSidAndRid(AccountDomainSid,
457 GroupMembership[i].RelativeId,
458 &SidArray[i + 1]);
459 if (ApiStatus != NERR_Success)
460 {
461 goto done;
462 }
463
464 SidCount++;
465 }
466
467 /* Get aliases for the user and his groups */
468 Status = SamGetAliasMembership(BuiltinDomainHandle,
469 SidCount,
470 SidArray,
471 &AliasCount,
472 &AliasArray);
473 if (!NT_SUCCESS(Status))
474 {
475 ERR("SamGetAliasMembership() failed (Status 0x%08lx)\n", Status);
476 ApiStatus = NetpNtStatusToApiStatus(Status);
477 goto done;
478 }
479
480 *AuthFlags = 0;
481
482 /* Set the AuthFlags */
483 for (i = 0; i < AliasCount; i++)
484 {
485 switch (AliasArray[i])
486 {
487 case DOMAIN_ALIAS_RID_ADMINS:
488 bAdmin = TRUE;
489 break;
490
491 case DOMAIN_ALIAS_RID_USERS:
492 bUser = TRUE;
493 break;
494
495 case DOMAIN_ALIAS_RID_ACCOUNT_OPS:
496 *AuthFlags |= AF_OP_ACCOUNTS;
497 break;
498
499 case DOMAIN_ALIAS_RID_SYSTEM_OPS:
500 *AuthFlags |= AF_OP_SERVER;
501 break;
502
503 case DOMAIN_ALIAS_RID_PRINT_OPS:
504 *AuthFlags |= AF_OP_PRINT;
505 break;
506 }
507 }
508
509 /* Set the prvileges */
510 if (bAdmin)
511 {
512 *Priv = USER_PRIV_ADMIN;
513 }
514 else if (bUser)
515 {
516 *Priv = USER_PRIV_USER;
517 }
518 else
519 {
520 *Priv = USER_PRIV_GUEST;
521 }
522
523 done:
524 if (AliasArray != NULL)
525 SamFreeMemory(AliasArray);
526
527 if (SidArray != NULL)
528 {
529 for (i = 0; i < SidCount; i++)
530 NetApiBufferFree(SidArray[i]);
531
532 NetApiBufferFree(SidArray);
533 }
534
535 if (GroupMembership != NULL)
536 SamFreeMemory(GroupMembership);
537
538 return ApiStatus;
539 }
540
541
542 static
543 NET_API_STATUS
544 BuildUserInfoBuffer(
545 _In_ SAM_HANDLE BuiltinDomainHandle,
546 _In_ SAM_HANDLE UserHandle,
547 _In_ PSID AccountDomainSid,
548 _In_ ULONG RelativeId,
549 _In_ DWORD level,
550 _Out_ LPVOID *Buffer)
551 {
552 UNICODE_STRING LogonServer = RTL_CONSTANT_STRING(L"\\\\*");
553 PUSER_ALL_INFORMATION UserInfo = NULL;
554 LPVOID LocalBuffer = NULL;
555 PACL Dacl = NULL;
556 DWORD Priv = 0, AuthFlags = 0;
557 PUSER_INFO_0 UserInfo0;
558 PUSER_INFO_1 UserInfo1;
559 PUSER_INFO_2 UserInfo2;
560 PUSER_INFO_3 UserInfo3;
561 PUSER_INFO_4 UserInfo4;
562 PUSER_INFO_10 UserInfo10;
563 PUSER_INFO_11 UserInfo11;
564 PUSER_INFO_20 UserInfo20;
565 PUSER_INFO_23 UserInfo23;
566 LPWSTR Ptr;
567 ULONG Size = 0;
568 NTSTATUS Status;
569 NET_API_STATUS ApiStatus = NERR_Success;
570
571 *Buffer = NULL;
572
573 Status = SamQueryInformationUser(UserHandle,
574 UserAllInformation,
575 (PVOID *)&UserInfo);
576 if (!NT_SUCCESS(Status))
577 {
578 ERR("SamQueryInformationUser failed (Status %08lx)\n", Status);
579 ApiStatus = NetpNtStatusToApiStatus(Status);
580 goto done;
581 }
582
583 if ((level == 1) || (level == 2) || (level == 3) ||
584 (level == 4) || (level == 20) || (level == 23))
585 {
586 ApiStatus = GetUserDacl(UserHandle, &Dacl);
587 if (ApiStatus != NERR_Success)
588 goto done;
589 }
590
591 if ((level == 1) || (level == 2) || (level == 3) ||
592 (level == 4) || (level == 11))
593 {
594 ApiStatus = GetUserPrivileges(BuiltinDomainHandle,
595 UserHandle,
596 AccountDomainSid,
597 RelativeId,
598 &Priv,
599 &AuthFlags);
600 if (ApiStatus != NERR_Success)
601 goto done;
602 }
603
604 switch (level)
605 {
606 case 0:
607 Size = sizeof(USER_INFO_0) +
608 UserInfo->UserName.Length + sizeof(WCHAR);
609 break;
610
611 case 1:
612 Size = sizeof(USER_INFO_1) +
613 UserInfo->UserName.Length + sizeof(WCHAR) +
614 UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
615 UserInfo->AdminComment.Length + sizeof(WCHAR) +
616 UserInfo->ScriptPath.Length + sizeof(WCHAR);
617 break;
618
619 case 2:
620 Size = sizeof(USER_INFO_2) +
621 UserInfo->UserName.Length + sizeof(WCHAR) +
622 UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
623 UserInfo->AdminComment.Length + sizeof(WCHAR) +
624 UserInfo->ScriptPath.Length + sizeof(WCHAR) +
625 UserInfo->FullName.Length + sizeof(WCHAR) +
626 UserInfo->UserComment.Length + sizeof(WCHAR) +
627 UserInfo->Parameters.Length + sizeof(WCHAR) +
628 UserInfo->WorkStations.Length + sizeof(WCHAR) +
629 LogonServer.Length + sizeof(WCHAR);
630
631 if (UserInfo->LogonHours.UnitsPerWeek > 0)
632 Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
633 break;
634
635 case 3:
636 Size = sizeof(USER_INFO_3) +
637 UserInfo->UserName.Length + sizeof(WCHAR) +
638 UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
639 UserInfo->AdminComment.Length + sizeof(WCHAR) +
640 UserInfo->ScriptPath.Length + sizeof(WCHAR) +
641 UserInfo->FullName.Length + sizeof(WCHAR) +
642 UserInfo->UserComment.Length + sizeof(WCHAR) +
643 UserInfo->Parameters.Length + sizeof(WCHAR) +
644 UserInfo->WorkStations.Length + sizeof(WCHAR) +
645 LogonServer.Length + sizeof(WCHAR) +
646 UserInfo->ProfilePath.Length + sizeof(WCHAR) +
647 UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR);
648
649 if (UserInfo->LogonHours.UnitsPerWeek > 0)
650 Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
651 break;
652
653 case 4:
654 Size = sizeof(USER_INFO_4) +
655 UserInfo->UserName.Length + sizeof(WCHAR) +
656 UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
657 UserInfo->AdminComment.Length + sizeof(WCHAR) +
658 UserInfo->ScriptPath.Length + sizeof(WCHAR) +
659 UserInfo->FullName.Length + sizeof(WCHAR) +
660 UserInfo->UserComment.Length + sizeof(WCHAR) +
661 UserInfo->Parameters.Length + sizeof(WCHAR) +
662 UserInfo->WorkStations.Length + sizeof(WCHAR) +
663 LogonServer.Length + sizeof(WCHAR) +
664 UserInfo->ProfilePath.Length + sizeof(WCHAR) +
665 UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR);
666
667 if (UserInfo->LogonHours.UnitsPerWeek > 0)
668 Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
669
670 Size += RtlLengthSid(AccountDomainSid) + sizeof(ULONG);
671 break;
672
673 case 10:
674 Size = sizeof(USER_INFO_10) +
675 UserInfo->UserName.Length + sizeof(WCHAR) +
676 UserInfo->AdminComment.Length + sizeof(WCHAR) +
677 UserInfo->UserComment.Length + sizeof(WCHAR) +
678 UserInfo->FullName.Length + sizeof(WCHAR);
679 break;
680
681 case 11:
682 Size = sizeof(USER_INFO_11) +
683 UserInfo->UserName.Length + sizeof(WCHAR) +
684 UserInfo->AdminComment.Length + sizeof(WCHAR) +
685 UserInfo->UserComment.Length + sizeof(WCHAR) +
686 UserInfo->FullName.Length + sizeof(WCHAR) +
687 UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
688 UserInfo->Parameters.Length + sizeof(WCHAR) +
689 LogonServer.Length + sizeof(WCHAR) +
690 UserInfo->WorkStations.Length + sizeof(WCHAR);
691
692 if (UserInfo->LogonHours.UnitsPerWeek > 0)
693 Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
694 break;
695
696 case 20:
697 Size = sizeof(USER_INFO_20) +
698 UserInfo->UserName.Length + sizeof(WCHAR) +
699 UserInfo->FullName.Length + sizeof(WCHAR) +
700 UserInfo->AdminComment.Length + sizeof(WCHAR);
701 break;
702
703 case 23:
704 Size = sizeof(USER_INFO_23) +
705 UserInfo->UserName.Length + sizeof(WCHAR) +
706 UserInfo->FullName.Length + sizeof(WCHAR) +
707 UserInfo->AdminComment.Length + sizeof(WCHAR);
708
709 Size += RtlLengthSid(AccountDomainSid) + sizeof(ULONG);
710 break;
711
712 default:
713 ApiStatus = ERROR_INVALID_LEVEL;
714 goto done;
715 }
716
717 ApiStatus = NetApiBufferAllocate(Size, &LocalBuffer);
718 if (ApiStatus != NERR_Success)
719 goto done;
720
721 ZeroMemory(LocalBuffer, Size);
722
723 switch (level)
724 {
725 case 0:
726 UserInfo0 = (PUSER_INFO_0)LocalBuffer;
727
728 Ptr = (LPWSTR)((ULONG_PTR)UserInfo0 + sizeof(USER_INFO_0));
729
730 UserInfo0->usri0_name = Ptr;
731
732 memcpy(UserInfo0->usri0_name,
733 UserInfo->UserName.Buffer,
734 UserInfo->UserName.Length);
735 UserInfo0->usri0_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
736 break;
737
738 case 1:
739 UserInfo1 = (PUSER_INFO_1)LocalBuffer;
740
741 Ptr = (LPWSTR)((ULONG_PTR)UserInfo1 + sizeof(USER_INFO_1));
742
743 UserInfo1->usri1_name = Ptr;
744
745 memcpy(UserInfo1->usri1_name,
746 UserInfo->UserName.Buffer,
747 UserInfo->UserName.Length);
748 UserInfo1->usri1_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
749
750 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
751
752 UserInfo1->usri1_password = NULL;
753 UserInfo1->usri1_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
754
755 UserInfo1->usri1_priv = Priv;
756
757 UserInfo1->usri1_home_dir = Ptr;
758 memcpy(UserInfo1->usri1_home_dir,
759 UserInfo->HomeDirectory.Buffer,
760 UserInfo->HomeDirectory.Length);
761 UserInfo1->usri1_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
762 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
763
764 UserInfo1->usri1_comment = Ptr;
765 memcpy(UserInfo1->usri1_comment,
766 UserInfo->AdminComment.Buffer,
767 UserInfo->AdminComment.Length);
768 UserInfo1->usri1_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
769 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
770
771 UserInfo1->usri1_flags = GetAccountFlags(UserInfo->UserAccountControl,
772 Dacl);
773
774 UserInfo1->usri1_script_path = Ptr;
775 memcpy(UserInfo1->usri1_script_path,
776 UserInfo->ScriptPath.Buffer,
777 UserInfo->ScriptPath.Length);
778 UserInfo1->usri1_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
779 break;
780
781 case 2:
782 UserInfo2 = (PUSER_INFO_2)LocalBuffer;
783
784 Ptr = (LPWSTR)((ULONG_PTR)UserInfo2 + sizeof(USER_INFO_2));
785
786 UserInfo2->usri2_name = Ptr;
787
788 memcpy(UserInfo2->usri2_name,
789 UserInfo->UserName.Buffer,
790 UserInfo->UserName.Length);
791 UserInfo2->usri2_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
792
793 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
794
795 UserInfo2->usri2_password = NULL;
796 UserInfo2->usri2_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
797
798 UserInfo2->usri2_priv = Priv;
799
800 UserInfo2->usri2_home_dir = Ptr;
801 memcpy(UserInfo2->usri2_home_dir,
802 UserInfo->HomeDirectory.Buffer,
803 UserInfo->HomeDirectory.Length);
804 UserInfo2->usri2_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
805 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
806
807 UserInfo2->usri2_comment = Ptr;
808 memcpy(UserInfo2->usri2_comment,
809 UserInfo->AdminComment.Buffer,
810 UserInfo->AdminComment.Length);
811 UserInfo2->usri2_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
812 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
813
814 UserInfo2->usri2_flags = GetAccountFlags(UserInfo->UserAccountControl,
815 Dacl);
816
817 UserInfo2->usri2_script_path = Ptr;
818 memcpy(UserInfo2->usri2_script_path,
819 UserInfo->ScriptPath.Buffer,
820 UserInfo->ScriptPath.Length);
821 UserInfo2->usri2_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
822 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
823
824 UserInfo2->usri2_auth_flags = AuthFlags;
825
826 UserInfo2->usri2_full_name = Ptr;
827 memcpy(UserInfo2->usri2_full_name,
828 UserInfo->FullName.Buffer,
829 UserInfo->FullName.Length);
830 UserInfo2->usri2_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
831 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
832
833 UserInfo2->usri2_usr_comment = Ptr;
834 memcpy(UserInfo2->usri2_usr_comment,
835 UserInfo->UserComment.Buffer,
836 UserInfo->UserComment.Length);
837 UserInfo2->usri2_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
838 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
839
840 UserInfo2->usri2_parms = Ptr;
841 memcpy(UserInfo2->usri2_parms,
842 UserInfo->Parameters.Buffer,
843 UserInfo->Parameters.Length);
844 UserInfo2->usri2_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
845 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
846
847 UserInfo2->usri2_workstations = Ptr;
848 memcpy(UserInfo2->usri2_workstations,
849 UserInfo->WorkStations.Buffer,
850 UserInfo->WorkStations.Length);
851 UserInfo2->usri2_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
852 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
853
854 if (UserInfo->LastLogon.QuadPart == 0)
855 UserInfo2->usri2_last_logon = 0;
856 else
857 RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
858 &UserInfo2->usri2_last_logon);
859
860 if (UserInfo->LastLogoff.QuadPart == 0)
861 UserInfo2->usri2_last_logoff = 0;
862 else
863 RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
864 &UserInfo2->usri2_last_logoff);
865
866 if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG)
867 UserInfo2->usri2_acct_expires = TIMEQ_FOREVER;
868 else
869 RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
870 &UserInfo2->usri2_acct_expires);
871
872 UserInfo2->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED;
873 UserInfo2->usri2_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
874
875 if (UserInfo->LogonHours.UnitsPerWeek > 0)
876 {
877 UserInfo2->usri2_logon_hours = (PVOID)Ptr;
878
879 memcpy(UserInfo2->usri2_logon_hours,
880 UserInfo->LogonHours.LogonHours,
881 (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
882
883 Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
884 }
885
886 UserInfo2->usri2_bad_pw_count = UserInfo->BadPasswordCount;
887 UserInfo2->usri2_num_logons = UserInfo->LogonCount;
888
889 UserInfo2->usri2_logon_server = Ptr;
890 memcpy(UserInfo2->usri2_logon_server,
891 LogonServer.Buffer,
892 LogonServer.Length);
893 UserInfo2->usri2_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
894 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
895
896 UserInfo2->usri2_country_code = UserInfo->CountryCode;
897 UserInfo2->usri2_code_page = UserInfo->CodePage;
898 break;
899
900 case 3:
901 UserInfo3 = (PUSER_INFO_3)LocalBuffer;
902
903 Ptr = (LPWSTR)((ULONG_PTR)UserInfo3 + sizeof(USER_INFO_3));
904
905 UserInfo3->usri3_name = Ptr;
906
907 memcpy(UserInfo3->usri3_name,
908 UserInfo->UserName.Buffer,
909 UserInfo->UserName.Length);
910 UserInfo3->usri3_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
911
912 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
913
914 UserInfo3->usri3_password = NULL;
915 UserInfo3->usri3_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
916
917 UserInfo3->usri3_priv = Priv;
918
919 UserInfo3->usri3_home_dir = Ptr;
920 memcpy(UserInfo3->usri3_home_dir,
921 UserInfo->HomeDirectory.Buffer,
922 UserInfo->HomeDirectory.Length);
923 UserInfo3->usri3_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
924 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
925
926 UserInfo3->usri3_comment = Ptr;
927 memcpy(UserInfo3->usri3_comment,
928 UserInfo->AdminComment.Buffer,
929 UserInfo->AdminComment.Length);
930 UserInfo3->usri3_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
931 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
932
933 UserInfo3->usri3_flags = GetAccountFlags(UserInfo->UserAccountControl,
934 Dacl);
935
936 UserInfo3->usri3_script_path = Ptr;
937 memcpy(UserInfo3->usri3_script_path,
938 UserInfo->ScriptPath.Buffer,
939 UserInfo->ScriptPath.Length);
940 UserInfo3->usri3_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
941 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
942
943 UserInfo3->usri3_auth_flags = AuthFlags;
944
945 UserInfo3->usri3_full_name = Ptr;
946 memcpy(UserInfo3->usri3_full_name,
947 UserInfo->FullName.Buffer,
948 UserInfo->FullName.Length);
949 UserInfo3->usri3_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
950 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
951
952 UserInfo3->usri3_usr_comment = Ptr;
953 memcpy(UserInfo3->usri3_usr_comment,
954 UserInfo->UserComment.Buffer,
955 UserInfo->UserComment.Length);
956 UserInfo3->usri3_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
957 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
958
959 UserInfo3->usri3_parms = Ptr;
960 memcpy(UserInfo3->usri3_parms,
961 UserInfo->Parameters.Buffer,
962 UserInfo->Parameters.Length);
963 UserInfo3->usri3_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
964 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
965
966 UserInfo3->usri3_workstations = Ptr;
967 memcpy(UserInfo3->usri3_workstations,
968 UserInfo->WorkStations.Buffer,
969 UserInfo->WorkStations.Length);
970 UserInfo3->usri3_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
971 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
972
973 if (UserInfo->LastLogon.QuadPart == 0)
974 UserInfo3->usri3_last_logon = 0;
975 else
976 RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
977 &UserInfo3->usri3_last_logon);
978
979 if (UserInfo->LastLogoff.QuadPart == 0)
980 UserInfo3->usri3_last_logoff = 0;
981 else
982 RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
983 &UserInfo3->usri3_last_logoff);
984
985 if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG)
986 UserInfo3->usri3_acct_expires = TIMEQ_FOREVER;
987 else
988 RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
989 &UserInfo3->usri3_acct_expires);
990
991 UserInfo3->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED;
992 UserInfo3->usri3_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
993
994 if (UserInfo->LogonHours.UnitsPerWeek > 0)
995 {
996 UserInfo3->usri3_logon_hours = (PVOID)Ptr;
997
998 memcpy(UserInfo3->usri3_logon_hours,
999 UserInfo->LogonHours.LogonHours,
1000 (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
1001
1002 Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
1003 }
1004
1005 UserInfo3->usri3_bad_pw_count = UserInfo->BadPasswordCount;
1006 UserInfo3->usri3_num_logons = UserInfo->LogonCount;
1007
1008 UserInfo3->usri3_logon_server = Ptr;
1009 memcpy(UserInfo3->usri3_logon_server,
1010 LogonServer.Buffer,
1011 LogonServer.Length);
1012 UserInfo3->usri3_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
1013 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
1014
1015 UserInfo3->usri3_country_code = UserInfo->CountryCode;
1016 UserInfo3->usri3_code_page = UserInfo->CodePage;
1017 UserInfo3->usri3_user_id = RelativeId;
1018 UserInfo3->usri3_primary_group_id = UserInfo->PrimaryGroupId;
1019
1020 UserInfo3->usri3_profile = Ptr;
1021 memcpy(UserInfo3->usri3_profile,
1022 UserInfo->ProfilePath.Buffer,
1023 UserInfo->ProfilePath.Length);
1024 UserInfo3->usri3_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1025 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR));
1026
1027 UserInfo3->usri3_home_dir_drive = Ptr;
1028 memcpy(UserInfo3->usri3_home_dir_drive,
1029 UserInfo->HomeDirectoryDrive.Buffer,
1030 UserInfo->HomeDirectoryDrive.Length);
1031 UserInfo3->usri3_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL;
1032 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR));
1033
1034 UserInfo3->usri3_password_expired = (UserInfo->UserAccountControl & USER_PASSWORD_EXPIRED);
1035 break;
1036
1037 case 4:
1038 UserInfo4 = (PUSER_INFO_4)LocalBuffer;
1039
1040 Ptr = (LPWSTR)((ULONG_PTR)UserInfo4 + sizeof(USER_INFO_4));
1041
1042 UserInfo4->usri4_name = Ptr;
1043
1044 memcpy(UserInfo4->usri4_name,
1045 UserInfo->UserName.Buffer,
1046 UserInfo->UserName.Length);
1047 UserInfo4->usri4_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1048
1049 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
1050
1051 UserInfo4->usri4_password = NULL;
1052 UserInfo4->usri4_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
1053
1054 UserInfo4->usri4_priv = Priv;
1055
1056 UserInfo4->usri4_home_dir = Ptr;
1057 memcpy(UserInfo4->usri4_home_dir,
1058 UserInfo->HomeDirectory.Buffer,
1059 UserInfo->HomeDirectory.Length);
1060 UserInfo4->usri4_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
1061 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
1062
1063 UserInfo4->usri4_comment = Ptr;
1064 memcpy(UserInfo4->usri4_comment,
1065 UserInfo->AdminComment.Buffer,
1066 UserInfo->AdminComment.Length);
1067 UserInfo4->usri4_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1068 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
1069
1070 UserInfo4->usri4_flags = GetAccountFlags(UserInfo->UserAccountControl,
1071 Dacl);
1072
1073 UserInfo4->usri4_script_path = Ptr;
1074 memcpy(UserInfo4->usri4_script_path,
1075 UserInfo->ScriptPath.Buffer,
1076 UserInfo->ScriptPath.Length);
1077 UserInfo4->usri4_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1078 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
1079
1080 UserInfo4->usri4_auth_flags = AuthFlags;
1081
1082 UserInfo4->usri4_full_name = Ptr;
1083 memcpy(UserInfo4->usri4_full_name,
1084 UserInfo->FullName.Buffer,
1085 UserInfo->FullName.Length);
1086 UserInfo4->usri4_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1087 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
1088
1089 UserInfo4->usri4_usr_comment = Ptr;
1090 memcpy(UserInfo4->usri4_usr_comment,
1091 UserInfo->UserComment.Buffer,
1092 UserInfo->UserComment.Length);
1093 UserInfo4->usri4_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1094 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
1095
1096 UserInfo4->usri4_parms = Ptr;
1097 memcpy(UserInfo4->usri4_parms,
1098 UserInfo->Parameters.Buffer,
1099 UserInfo->Parameters.Length);
1100 UserInfo4->usri4_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
1101 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
1102
1103 UserInfo4->usri4_workstations = Ptr;
1104 memcpy(UserInfo4->usri4_workstations,
1105 UserInfo->WorkStations.Buffer,
1106 UserInfo->WorkStations.Length);
1107 UserInfo4->usri4_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
1108 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
1109
1110 if (UserInfo->LastLogon.QuadPart == 0)
1111 UserInfo4->usri4_last_logon = 0;
1112 else
1113 RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
1114 &UserInfo4->usri4_last_logon);
1115
1116 if (UserInfo->LastLogoff.QuadPart == 0)
1117 UserInfo4->usri4_last_logoff = 0;
1118 else
1119 RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
1120 &UserInfo4->usri4_last_logoff);
1121
1122 if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG)
1123 UserInfo4->usri4_acct_expires = TIMEQ_FOREVER;
1124 else
1125 RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
1126 &UserInfo4->usri4_acct_expires);
1127
1128 UserInfo4->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED;
1129 UserInfo4->usri4_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
1130
1131 if (UserInfo->LogonHours.UnitsPerWeek > 0)
1132 {
1133 UserInfo4->usri4_logon_hours = (PVOID)Ptr;
1134
1135 memcpy(UserInfo4->usri4_logon_hours,
1136 UserInfo->LogonHours.LogonHours,
1137 (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
1138
1139 Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
1140 }
1141
1142 UserInfo4->usri4_bad_pw_count = UserInfo->BadPasswordCount;
1143 UserInfo4->usri4_num_logons = UserInfo->LogonCount;
1144
1145 UserInfo4->usri4_logon_server = Ptr;
1146 memcpy(UserInfo4->usri4_logon_server,
1147 LogonServer.Buffer,
1148 LogonServer.Length);
1149 UserInfo4->usri4_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
1150 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
1151
1152 UserInfo4->usri4_country_code = UserInfo->CountryCode;
1153 UserInfo4->usri4_code_page = UserInfo->CodePage;
1154
1155 UserInfo4->usri4_user_sid = (PVOID)Ptr;
1156 CopySidFromSidAndRid(UserInfo4->usri4_user_sid, AccountDomainSid, RelativeId);
1157 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RtlLengthSid(AccountDomainSid) + sizeof(ULONG));
1158
1159 UserInfo4->usri4_primary_group_id = UserInfo->PrimaryGroupId;
1160
1161 UserInfo4->usri4_profile = Ptr;
1162 memcpy(UserInfo4->usri4_profile,
1163 UserInfo->ProfilePath.Buffer,
1164 UserInfo->ProfilePath.Length);
1165 UserInfo4->usri4_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1166 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR));
1167
1168 UserInfo4->usri4_home_dir_drive = Ptr;
1169 memcpy(UserInfo4->usri4_home_dir_drive,
1170 UserInfo->HomeDirectoryDrive.Buffer,
1171 UserInfo->HomeDirectoryDrive.Length);
1172 UserInfo4->usri4_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL;
1173 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR));
1174
1175 UserInfo4->usri4_password_expired = (UserInfo->UserAccountControl & USER_PASSWORD_EXPIRED);
1176 break;
1177
1178 case 10:
1179 UserInfo10 = (PUSER_INFO_10)LocalBuffer;
1180
1181 Ptr = (LPWSTR)((ULONG_PTR)UserInfo10 + sizeof(USER_INFO_10));
1182
1183 UserInfo10->usri10_name = Ptr;
1184
1185 memcpy(UserInfo10->usri10_name,
1186 UserInfo->UserName.Buffer,
1187 UserInfo->UserName.Length);
1188 UserInfo10->usri10_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1189
1190 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
1191
1192 UserInfo10->usri10_comment = Ptr;
1193 memcpy(UserInfo10->usri10_comment,
1194 UserInfo->AdminComment.Buffer,
1195 UserInfo->AdminComment.Length);
1196 UserInfo10->usri10_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1197 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
1198
1199 UserInfo10->usri10_usr_comment = Ptr;
1200 memcpy(UserInfo10->usri10_usr_comment,
1201 UserInfo->UserComment.Buffer,
1202 UserInfo->UserComment.Length);
1203 UserInfo10->usri10_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1204 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
1205
1206 UserInfo10->usri10_full_name = Ptr;
1207 memcpy(UserInfo10->usri10_full_name,
1208 UserInfo->FullName.Buffer,
1209 UserInfo->FullName.Length);
1210 UserInfo10->usri10_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1211 break;
1212
1213 case 11:
1214 UserInfo11 = (PUSER_INFO_11)LocalBuffer;
1215
1216 Ptr = (LPWSTR)((ULONG_PTR)UserInfo11 + sizeof(USER_INFO_11));
1217
1218 UserInfo11->usri11_name = Ptr;
1219
1220 memcpy(UserInfo11->usri11_name,
1221 UserInfo->UserName.Buffer,
1222 UserInfo->UserName.Length);
1223 UserInfo11->usri11_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1224
1225 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
1226
1227 UserInfo11->usri11_comment = Ptr;
1228 memcpy(UserInfo11->usri11_comment,
1229 UserInfo->AdminComment.Buffer,
1230 UserInfo->AdminComment.Length);
1231 UserInfo11->usri11_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1232 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
1233
1234 UserInfo11->usri11_usr_comment = Ptr;
1235 memcpy(UserInfo11->usri11_usr_comment,
1236 UserInfo->UserComment.Buffer,
1237 UserInfo->UserComment.Length);
1238 UserInfo11->usri11_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1239 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
1240
1241 UserInfo11->usri11_full_name = Ptr;
1242 memcpy(UserInfo11->usri11_full_name,
1243 UserInfo->FullName.Buffer,
1244 UserInfo->FullName.Length);
1245 UserInfo11->usri11_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1246 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
1247
1248 UserInfo11->usri11_priv = Priv;
1249 UserInfo11->usri11_auth_flags = AuthFlags;
1250
1251 UserInfo11->usri11_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
1252
1253 UserInfo11->usri11_home_dir = Ptr;
1254 memcpy(UserInfo11->usri11_home_dir,
1255 UserInfo->HomeDirectory.Buffer,
1256 UserInfo->HomeDirectory.Length);
1257 UserInfo11->usri11_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
1258 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
1259
1260 UserInfo11->usri11_parms = Ptr;
1261 memcpy(UserInfo11->usri11_parms,
1262 UserInfo->Parameters.Buffer,
1263 UserInfo->Parameters.Length);
1264 UserInfo11->usri11_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
1265 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
1266
1267 if (UserInfo->LastLogon.QuadPart == 0)
1268 UserInfo11->usri11_last_logon = 0;
1269 else
1270 RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
1271 &UserInfo11->usri11_last_logon);
1272
1273 if (UserInfo->LastLogoff.QuadPart == 0)
1274 UserInfo11->usri11_last_logoff = 0;
1275 else
1276 RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
1277 &UserInfo11->usri11_last_logoff);
1278
1279 UserInfo11->usri11_bad_pw_count = UserInfo->BadPasswordCount;
1280 UserInfo11->usri11_num_logons = UserInfo->LogonCount;
1281
1282 UserInfo11->usri11_logon_server = Ptr;
1283 memcpy(UserInfo11->usri11_logon_server,
1284 LogonServer.Buffer,
1285 LogonServer.Length);
1286 UserInfo11->usri11_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
1287 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
1288
1289 UserInfo11->usri11_country_code = UserInfo->CountryCode;
1290
1291 UserInfo11->usri11_workstations = Ptr;
1292 memcpy(UserInfo11->usri11_workstations,
1293 UserInfo->WorkStations.Buffer,
1294 UserInfo->WorkStations.Length);
1295 UserInfo11->usri11_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
1296 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
1297
1298 UserInfo11->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED;
1299 UserInfo11->usri11_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
1300
1301 if (UserInfo->LogonHours.UnitsPerWeek > 0)
1302 {
1303 UserInfo11->usri11_logon_hours = (PVOID)Ptr;
1304
1305 memcpy(UserInfo11->usri11_logon_hours,
1306 UserInfo->LogonHours.LogonHours,
1307 (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
1308
1309 Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
1310 }
1311
1312 UserInfo11->usri11_code_page = UserInfo->CodePage;
1313 break;
1314
1315 case 20:
1316 UserInfo20 = (PUSER_INFO_20)LocalBuffer;
1317
1318 Ptr = (LPWSTR)((ULONG_PTR)UserInfo20 + sizeof(USER_INFO_20));
1319
1320 UserInfo20->usri20_name = Ptr;
1321
1322 memcpy(UserInfo20->usri20_name,
1323 UserInfo->UserName.Buffer,
1324 UserInfo->UserName.Length);
1325 UserInfo20->usri20_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1326
1327 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
1328
1329 UserInfo20->usri20_full_name = Ptr;
1330 memcpy(UserInfo20->usri20_full_name,
1331 UserInfo->FullName.Buffer,
1332 UserInfo->FullName.Length);
1333 UserInfo20->usri20_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1334 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
1335
1336 UserInfo20->usri20_comment = Ptr;
1337 memcpy(UserInfo20->usri20_comment,
1338 UserInfo->AdminComment.Buffer,
1339 UserInfo->AdminComment.Length);
1340 UserInfo20->usri20_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1341 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
1342
1343 UserInfo20->usri20_flags = GetAccountFlags(UserInfo->UserAccountControl,
1344 Dacl);
1345
1346 UserInfo20->usri20_user_id = RelativeId;
1347 break;
1348
1349 case 23:
1350 UserInfo23 = (PUSER_INFO_23)LocalBuffer;
1351
1352 Ptr = (LPWSTR)((ULONG_PTR)UserInfo23 + sizeof(USER_INFO_23));
1353
1354 UserInfo23->usri23_name = Ptr;
1355
1356 memcpy(UserInfo23->usri23_name,
1357 UserInfo->UserName.Buffer,
1358 UserInfo->UserName.Length);
1359 UserInfo23->usri23_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1360
1361 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
1362
1363 UserInfo23->usri23_full_name = Ptr;
1364 memcpy(UserInfo23->usri23_full_name,
1365 UserInfo->FullName.Buffer,
1366 UserInfo->FullName.Length);
1367 UserInfo23->usri23_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1368 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
1369
1370 UserInfo23->usri23_comment = Ptr;
1371 memcpy(UserInfo23->usri23_comment,
1372 UserInfo->AdminComment.Buffer,
1373 UserInfo->AdminComment.Length);
1374 UserInfo23->usri23_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1375 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
1376
1377 UserInfo23->usri23_flags = GetAccountFlags(UserInfo->UserAccountControl,
1378 Dacl);
1379
1380 UserInfo23->usri23_user_sid = (PVOID)Ptr;
1381 CopySidFromSidAndRid(UserInfo23->usri23_user_sid, AccountDomainSid, RelativeId);
1382 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RtlLengthSid(AccountDomainSid) + sizeof(ULONG));
1383 break;
1384 }
1385
1386 done:
1387 if (UserInfo != NULL)
1388 FreeUserInfo(UserInfo);
1389
1390 if (Dacl != NULL)
1391 HeapFree(GetProcessHeap(), 0, Dacl);
1392
1393 if (ApiStatus == NERR_Success)
1394 {
1395 *Buffer = LocalBuffer;
1396 }
1397 else
1398 {
1399 if (LocalBuffer != NULL)
1400 NetApiBufferFree(LocalBuffer);
1401 }
1402
1403 return ApiStatus;
1404 }
1405
1406
1407 static
1408 NET_API_STATUS
1409 SetUserInfo(SAM_HANDLE UserHandle,
1410 LPBYTE UserInfo,
1411 DWORD Level,
1412 PDWORD parm_err)
1413 {
1414 USER_ALL_INFORMATION UserAllInfo;
1415 PUSER_INFO_0 UserInfo0;
1416 PUSER_INFO_1 UserInfo1;
1417 PUSER_INFO_2 UserInfo2;
1418 PUSER_INFO_3 UserInfo3;
1419 PUSER_INFO_4 UserInfo4;
1420 PUSER_INFO_22 UserInfo22;
1421 PUSER_INFO_1003 UserInfo1003;
1422 PUSER_INFO_1006 UserInfo1006;
1423 PUSER_INFO_1007 UserInfo1007;
1424 PUSER_INFO_1008 UserInfo1008;
1425 PUSER_INFO_1009 UserInfo1009;
1426 PUSER_INFO_1011 UserInfo1011;
1427 PUSER_INFO_1012 UserInfo1012;
1428 PUSER_INFO_1013 UserInfo1013;
1429 PUSER_INFO_1014 UserInfo1014;
1430 PUSER_INFO_1017 UserInfo1017;
1431 PUSER_INFO_1018 UserInfo1018;
1432 PUSER_INFO_1020 UserInfo1020;
1433 PUSER_INFO_1024 UserInfo1024;
1434 PUSER_INFO_1025 UserInfo1025;
1435 PUSER_INFO_1051 UserInfo1051;
1436 PUSER_INFO_1052 UserInfo1052;
1437 PUSER_INFO_1053 UserInfo1053;
1438 PACL Dacl = NULL;
1439 NET_API_STATUS ApiStatus = NERR_Success;
1440 NTSTATUS Status = STATUS_SUCCESS;
1441
1442 ZeroMemory(&UserAllInfo, sizeof(USER_ALL_INFORMATION));
1443
1444 if ((Level == 1) || (Level == 2) || (Level == 3) ||
1445 (Level == 4) || (Level == 22) || (Level == 1008))
1446 {
1447 ApiStatus = GetUserDacl(UserHandle, &Dacl);
1448 if (ApiStatus != NERR_Success)
1449 goto done;
1450 }
1451
1452 switch (Level)
1453 {
1454 case 0:
1455 UserInfo0 = (PUSER_INFO_0)UserInfo;
1456
1457 RtlInitUnicodeString(&UserAllInfo.UserName,
1458 UserInfo0->usri0_name);
1459
1460 UserAllInfo.WhichFields |= USER_ALL_USERNAME;
1461 break;
1462
1463 case 1:
1464 UserInfo1 = (PUSER_INFO_1)UserInfo;
1465
1466 // usri1_name ignored
1467
1468 if (UserInfo1->usri1_password != NULL)
1469 {
1470 RtlInitUnicodeString(&UserAllInfo.NtPassword,
1471 UserInfo1->usri1_password);
1472 UserAllInfo.NtPasswordPresent = TRUE;
1473 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1474 }
1475
1476 // usri1_password_age ignored
1477
1478 // UserInfo1->usri1_priv
1479
1480 if (UserInfo1->usri1_home_dir != NULL)
1481 {
1482 RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1483 UserInfo1->usri1_home_dir);
1484 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1485 }
1486
1487 if (UserInfo1->usri1_comment != NULL)
1488 {
1489 RtlInitUnicodeString(&UserAllInfo.AdminComment,
1490 UserInfo1->usri1_comment);
1491 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1492 }
1493
1494 ChangeUserDacl(Dacl, UserInfo1->usri1_flags);
1495 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1->usri1_flags);
1496 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
1497
1498 if (UserInfo1->usri1_script_path != NULL)
1499 {
1500 RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1501 UserInfo1->usri1_script_path);
1502 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1503 }
1504 break;
1505
1506 case 2:
1507 UserInfo2 = (PUSER_INFO_2)UserInfo;
1508
1509 // usri2_name ignored
1510
1511 if (UserInfo2->usri2_password != NULL)
1512 {
1513 RtlInitUnicodeString(&UserAllInfo.NtPassword,
1514 UserInfo2->usri2_password);
1515 UserAllInfo.NtPasswordPresent = TRUE;
1516 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1517 }
1518
1519 // usri2_password_age ignored
1520
1521 // UserInfo2->usri2_priv;
1522
1523 if (UserInfo2->usri2_home_dir != NULL)
1524 {
1525 RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1526 UserInfo2->usri2_home_dir);
1527 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1528 }
1529
1530 if (UserInfo2->usri2_comment != NULL)
1531 {
1532 RtlInitUnicodeString(&UserAllInfo.AdminComment,
1533 UserInfo2->usri2_comment);
1534 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1535 }
1536
1537 ChangeUserDacl(Dacl, UserInfo2->usri2_flags);
1538 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo2->usri2_flags);
1539 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
1540
1541 if (UserInfo2->usri2_script_path != NULL)
1542 {
1543 RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1544 UserInfo2->usri2_script_path);
1545 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1546 }
1547
1548 // UserInfo2->usri2_auth_flags;
1549
1550 if (UserInfo2->usri2_full_name != NULL)
1551 {
1552 RtlInitUnicodeString(&UserAllInfo.FullName,
1553 UserInfo2->usri2_full_name);
1554 UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1555 }
1556
1557 if (UserInfo2->usri2_usr_comment != NULL)
1558 {
1559 RtlInitUnicodeString(&UserAllInfo.UserComment,
1560 UserInfo2->usri2_usr_comment);
1561 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1562 }
1563
1564 if (UserInfo2->usri2_parms != NULL)
1565 {
1566 RtlInitUnicodeString(&UserAllInfo.Parameters,
1567 UserInfo2->usri2_parms);
1568 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1569 }
1570
1571 if (UserInfo2->usri2_workstations != NULL)
1572 {
1573 RtlInitUnicodeString(&UserAllInfo.WorkStations,
1574 UserInfo2->usri2_workstations);
1575 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1576 }
1577
1578 // usri2_last_logon ignored
1579 // usri2_last_logoff ignored
1580
1581 if (UserInfo2->usri2_acct_expires == TIMEQ_FOREVER)
1582 {
1583 UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
1584 }
1585 else
1586 {
1587 RtlSecondsSince1970ToTime(UserInfo2->usri2_acct_expires,
1588 &UserAllInfo.AccountExpires);
1589 }
1590 UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1591
1592 if (UserInfo2->usri2_max_storage != USER_MAXSTORAGE_UNLIMITED)
1593 {
1594 if (parm_err != NULL)
1595 *parm_err = USER_MAX_STORAGE_PARMNUM;
1596 ApiStatus = ERROR_INVALID_PARAMETER;
1597 break;
1598 }
1599
1600 if (UserInfo2->usri2_units_per_week > USHRT_MAX)
1601 {
1602 if (parm_err != NULL)
1603 *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
1604 ApiStatus = ERROR_INVALID_PARAMETER;
1605 break;
1606 }
1607
1608 UserAllInfo.LogonHours.UnitsPerWeek = UserInfo2->usri2_units_per_week;
1609 UserAllInfo.LogonHours.LogonHours = UserInfo2->usri2_logon_hours;
1610 UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
1611
1612 // usri2_bad_pw_count ignored
1613 // usri2_num_logons ignored
1614 // usri2_logon_server ignored
1615
1616 UserAllInfo.CountryCode = UserInfo2->usri2_country_code;
1617 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1618
1619 UserAllInfo.CodePage = UserInfo2->usri2_code_page;
1620 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1621 break;
1622
1623 case 3:
1624 UserInfo3 = (PUSER_INFO_3)UserInfo;
1625
1626 // usri3_name ignored
1627
1628 if (UserInfo3->usri3_password != NULL)
1629 {
1630 RtlInitUnicodeString(&UserAllInfo.NtPassword,
1631 UserInfo3->usri3_password);
1632 UserAllInfo.NtPasswordPresent = TRUE;
1633 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1634 }
1635
1636 // usri3_password_age ignored
1637
1638 // UserInfo3->usri3_priv;
1639
1640 if (UserInfo3->usri3_home_dir != NULL)
1641 {
1642 RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1643 UserInfo3->usri3_home_dir);
1644 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1645 }
1646
1647 if (UserInfo3->usri3_comment != NULL)
1648 {
1649 RtlInitUnicodeString(&UserAllInfo.AdminComment,
1650 UserInfo3->usri3_comment);
1651 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1652 }
1653
1654 ChangeUserDacl(Dacl, UserInfo3->usri3_flags);
1655 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo3->usri3_flags);
1656 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
1657
1658 if (UserInfo3->usri3_script_path != NULL)
1659 {
1660 RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1661 UserInfo3->usri3_script_path);
1662 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1663 }
1664
1665 // UserInfo3->usri3_auth_flags;
1666
1667 if (UserInfo3->usri3_full_name != NULL)
1668 {
1669 RtlInitUnicodeString(&UserAllInfo.FullName,
1670 UserInfo3->usri3_full_name);
1671 UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1672 }
1673
1674 if (UserInfo3->usri3_usr_comment != NULL)
1675 {
1676 RtlInitUnicodeString(&UserAllInfo.UserComment,
1677 UserInfo3->usri3_usr_comment);
1678 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1679 }
1680
1681 if (UserInfo3->usri3_parms != NULL)
1682 {
1683 RtlInitUnicodeString(&UserAllInfo.Parameters,
1684 UserInfo3->usri3_parms);
1685 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1686 }
1687
1688 if (UserInfo3->usri3_workstations != NULL)
1689 {
1690 RtlInitUnicodeString(&UserAllInfo.WorkStations,
1691 UserInfo3->usri3_workstations);
1692 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1693 }
1694
1695 // usri3_last_logon ignored
1696 // usri3_last_logoff ignored
1697
1698 if (UserInfo3->usri3_acct_expires == TIMEQ_FOREVER)
1699 {
1700 UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
1701 }
1702 else
1703 {
1704 RtlSecondsSince1970ToTime(UserInfo3->usri3_acct_expires,
1705 &UserAllInfo.AccountExpires);
1706 }
1707 UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1708
1709 if (UserInfo3->usri3_max_storage != USER_MAXSTORAGE_UNLIMITED)
1710 {
1711 if (parm_err != NULL)
1712 *parm_err = USER_MAX_STORAGE_PARMNUM;
1713 ApiStatus = ERROR_INVALID_PARAMETER;
1714 break;
1715 }
1716
1717 if (UserInfo3->usri3_units_per_week > USHRT_MAX)
1718 {
1719 if (parm_err != NULL)
1720 *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
1721 ApiStatus = ERROR_INVALID_PARAMETER;
1722 break;
1723 }
1724
1725 UserAllInfo.LogonHours.UnitsPerWeek = UserInfo3->usri3_units_per_week;
1726 UserAllInfo.LogonHours.LogonHours = UserInfo3->usri3_logon_hours;
1727 UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
1728
1729 // usri3_bad_pw_count ignored
1730 // usri3_num_logons ignored
1731 // usri3_logon_server ignored
1732
1733 UserAllInfo.CountryCode = UserInfo3->usri3_country_code;
1734 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1735
1736 UserAllInfo.CodePage = UserInfo3->usri3_code_page;
1737 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1738
1739 // usri3_user_id ignored
1740
1741 UserAllInfo.PrimaryGroupId = UserInfo3->usri3_primary_group_id;
1742 UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
1743
1744 if (UserInfo3->usri3_profile != NULL)
1745 {
1746 RtlInitUnicodeString(&UserAllInfo.ProfilePath,
1747 UserInfo3->usri3_profile);
1748 UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
1749 }
1750
1751 if (UserInfo3->usri3_home_dir_drive != NULL)
1752 {
1753 RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive,
1754 UserInfo3->usri3_home_dir_drive);
1755 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE;
1756 }
1757
1758 UserAllInfo.PasswordExpired = (UserInfo3->usri3_password_expired != 0);
1759 UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED;
1760 break;
1761
1762 case 4:
1763 UserInfo4 = (PUSER_INFO_4)UserInfo;
1764
1765 // usri4_name ignored
1766
1767 if (UserInfo4->usri4_password != NULL)
1768 {
1769 RtlInitUnicodeString(&UserAllInfo.NtPassword,
1770 UserInfo4->usri4_password);
1771 UserAllInfo.NtPasswordPresent = TRUE;
1772 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1773 }
1774
1775 // usri4_password_age ignored
1776
1777 // UserInfo3->usri4_priv;
1778
1779 if (UserInfo4->usri4_home_dir != NULL)
1780 {
1781 RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1782 UserInfo4->usri4_home_dir);
1783 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1784 }
1785
1786 if (UserInfo4->usri4_comment != NULL)
1787 {
1788 RtlInitUnicodeString(&UserAllInfo.AdminComment,
1789 UserInfo4->usri4_comment);
1790 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1791 }
1792
1793 ChangeUserDacl(Dacl, UserInfo4->usri4_flags);
1794 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo4->usri4_flags);
1795 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
1796
1797 if (UserInfo4->usri4_script_path != NULL)
1798 {
1799 RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1800 UserInfo4->usri4_script_path);
1801 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1802 }
1803
1804 // UserInfo4->usri4_auth_flags;
1805
1806 if (UserInfo4->usri4_full_name != NULL)
1807 {
1808 RtlInitUnicodeString(&UserAllInfo.FullName,
1809 UserInfo4->usri4_full_name);
1810 UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1811 }
1812
1813 if (UserInfo4->usri4_usr_comment != NULL)
1814 {
1815 RtlInitUnicodeString(&UserAllInfo.UserComment,
1816 UserInfo4->usri4_usr_comment);
1817 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1818 }
1819
1820 if (UserInfo4->usri4_parms != NULL)
1821 {
1822 RtlInitUnicodeString(&UserAllInfo.Parameters,
1823 UserInfo4->usri4_parms);
1824 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1825 }
1826
1827 if (UserInfo4->usri4_workstations != NULL)
1828 {
1829 RtlInitUnicodeString(&UserAllInfo.WorkStations,
1830 UserInfo4->usri4_workstations);
1831 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1832 }
1833
1834 // usri4_last_logon ignored
1835 // usri4_last_logoff ignored
1836
1837 if (UserInfo4->usri4_acct_expires == TIMEQ_FOREVER)
1838 {
1839 UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
1840 }
1841 else
1842 {
1843 RtlSecondsSince1970ToTime(UserInfo4->usri4_acct_expires,
1844 &UserAllInfo.AccountExpires);
1845 }
1846 UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1847
1848 if (UserInfo4->usri4_max_storage != USER_MAXSTORAGE_UNLIMITED)
1849 {
1850 if (parm_err != NULL)
1851 *parm_err = USER_MAX_STORAGE_PARMNUM;
1852 ApiStatus = ERROR_INVALID_PARAMETER;
1853 break;
1854 }
1855
1856 if (UserInfo4->usri4_units_per_week > USHRT_MAX)
1857 {
1858 if (parm_err != NULL)
1859 *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
1860 ApiStatus = ERROR_INVALID_PARAMETER;
1861 break;
1862 }
1863
1864 UserAllInfo.LogonHours.UnitsPerWeek = UserInfo4->usri4_units_per_week;
1865 UserAllInfo.LogonHours.LogonHours = UserInfo4->usri4_logon_hours;
1866 UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
1867
1868 // usri4_bad_pw_count ignored
1869 // usri4_num_logons ignored
1870 // usri4_logon_server ignored
1871
1872 UserAllInfo.CountryCode = UserInfo4->usri4_country_code;
1873 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1874
1875 UserAllInfo.CodePage = UserInfo4->usri4_code_page;
1876 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1877
1878 // usri4_user_sid ignored
1879
1880 UserAllInfo.PrimaryGroupId = UserInfo4->usri4_primary_group_id;
1881 UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
1882
1883 if (UserInfo4->usri4_profile != NULL)
1884 {
1885 RtlInitUnicodeString(&UserAllInfo.ProfilePath,
1886 UserInfo4->usri4_profile);
1887 UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
1888 }
1889
1890 if (UserInfo4->usri4_home_dir_drive != NULL)
1891 {
1892 RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive,
1893 UserInfo4->usri4_home_dir_drive);
1894 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE;
1895 }
1896
1897 UserAllInfo.PasswordExpired = (UserInfo4->usri4_password_expired != 0);
1898 UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED;
1899 break;
1900
1901 // case 21:
1902 // break;
1903
1904 case 22:
1905 UserInfo22 = (PUSER_INFO_22)UserInfo;
1906
1907 // usri22_name ignored
1908
1909 // UserInfo22->usri22_password[ENCRYPTED_PWLEN];
1910
1911 // usri22_password_age ignored
1912
1913 // UserInfo3->usri3_priv;
1914
1915 if (UserInfo22->usri22_home_dir != NULL)
1916 {
1917 RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1918 UserInfo22->usri22_home_dir);
1919 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1920 }
1921
1922 if (UserInfo22->usri22_comment != NULL)
1923 {
1924 RtlInitUnicodeString(&UserAllInfo.AdminComment,
1925 UserInfo22->usri22_comment);
1926 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1927 }
1928
1929 ChangeUserDacl(Dacl, UserInfo22->usri22_flags);
1930 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo22->usri22_flags);
1931 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
1932
1933 if (UserInfo22->usri22_script_path != NULL)
1934 {
1935 RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1936 UserInfo22->usri22_script_path);
1937 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1938 }
1939
1940 // UserInfo22->usri22_auth_flags;
1941
1942 if (UserInfo22->usri22_full_name != NULL)
1943 {
1944 RtlInitUnicodeString(&UserAllInfo.FullName,
1945 UserInfo22->usri22_full_name);
1946 UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1947 }
1948
1949 if (UserInfo22->usri22_usr_comment != NULL)
1950 {
1951 RtlInitUnicodeString(&UserAllInfo.UserComment,
1952 UserInfo22->usri22_usr_comment);
1953 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1954 }
1955
1956 if (UserInfo22->usri22_parms != NULL)
1957 {
1958 RtlInitUnicodeString(&UserAllInfo.Parameters,
1959 UserInfo22->usri22_parms);
1960 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1961 }
1962
1963 if (UserInfo22->usri22_workstations != NULL)
1964 {
1965 RtlInitUnicodeString(&UserAllInfo.WorkStations,
1966 UserInfo22->usri22_workstations);
1967 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1968 }
1969
1970 // usri22_last_logon ignored
1971 // usri22_last_logoff ignored
1972
1973 if (UserInfo22->usri22_acct_expires == TIMEQ_FOREVER)
1974 {
1975 UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
1976 }
1977 else
1978 {
1979 RtlSecondsSince1970ToTime(UserInfo22->usri22_acct_expires,
1980 &UserAllInfo.AccountExpires);
1981 }
1982 UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1983
1984 if (UserInfo22->usri22_max_storage != USER_MAXSTORAGE_UNLIMITED)
1985 {
1986 if (parm_err != NULL)
1987 *parm_err = USER_MAX_STORAGE_PARMNUM;
1988 ApiStatus = ERROR_INVALID_PARAMETER;
1989 break;
1990 }
1991
1992 if (UserInfo22->usri22_units_per_week > USHRT_MAX)
1993 {
1994 if (parm_err != NULL)
1995 *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
1996 ApiStatus = ERROR_INVALID_PARAMETER;
1997 break;
1998 }
1999
2000 UserAllInfo.LogonHours.UnitsPerWeek = UserInfo22->usri22_units_per_week;
2001 UserAllInfo.LogonHours.LogonHours = UserInfo22->usri22_logon_hours;
2002 UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
2003
2004 // usri22_bad_pw_count ignored
2005 // usri22_num_logons ignored
2006 // usri22_logon_server ignored
2007
2008 UserAllInfo.CountryCode = UserInfo22->usri22_country_code;
2009 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
2010
2011 UserAllInfo.CodePage = UserInfo22->usri22_code_page;
2012 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
2013 break;
2014
2015 case 1003:
2016 UserInfo1003 = (PUSER_INFO_1003)UserInfo;
2017
2018 if (UserInfo1003->usri1003_password != NULL)
2019 {
2020 RtlInitUnicodeString(&UserAllInfo.NtPassword,
2021 UserInfo1003->usri1003_password);
2022 UserAllInfo.NtPasswordPresent = TRUE;
2023 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
2024 }
2025 break;
2026
2027 // case 1005:
2028 // break;
2029
2030 case 1006:
2031 UserInfo1006 = (PUSER_INFO_1006)UserInfo;
2032
2033 if (UserInfo1006->usri1006_home_dir != NULL)
2034 {
2035 RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
2036 UserInfo1006->usri1006_home_dir);
2037 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
2038 }
2039 break;
2040
2041 case 1007:
2042 UserInfo1007 = (PUSER_INFO_1007)UserInfo;
2043
2044 if (UserInfo1007->usri1007_comment != NULL)
2045 {
2046 RtlInitUnicodeString(&UserAllInfo.AdminComment,
2047 UserInfo1007->usri1007_comment);
2048 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
2049 }
2050 break;
2051
2052 case 1008:
2053 UserInfo1008 = (PUSER_INFO_1008)UserInfo;
2054 ChangeUserDacl(Dacl, UserInfo1008->usri1008_flags);
2055 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1008->usri1008_flags);
2056 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
2057 break;
2058
2059 case 1009:
2060 UserInfo1009 = (PUSER_INFO_1009)UserInfo;
2061
2062 if (UserInfo1009->usri1009_script_path != NULL)
2063 {
2064 RtlInitUnicodeString(&UserAllInfo.ScriptPath,
2065 UserInfo1009->usri1009_script_path);
2066 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
2067 }
2068 break;
2069
2070 // case 1010:
2071 // break;
2072
2073 case 1011:
2074 UserInfo1011 = (PUSER_INFO_1011)UserInfo;
2075
2076 if (UserInfo1011->usri1011_full_name != NULL)
2077 {
2078 RtlInitUnicodeString(&UserAllInfo.FullName,
2079 UserInfo1011->usri1011_full_name);
2080 UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
2081 }
2082 break;
2083
2084 case 1012:
2085 UserInfo1012 = (PUSER_INFO_1012)UserInfo;
2086
2087 if (UserInfo1012->usri1012_usr_comment != NULL)
2088 {
2089 RtlInitUnicodeString(&UserAllInfo.UserComment,
2090 UserInfo1012->usri1012_usr_comment);
2091 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
2092 }
2093 break;
2094
2095 case 1013:
2096 UserInfo1013 = (PUSER_INFO_1013)UserInfo;
2097
2098 if (UserInfo1013->usri1013_parms != NULL)
2099 {
2100 RtlInitUnicodeString(&UserAllInfo.Parameters,
2101 UserInfo1013->usri1013_parms);
2102 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
2103 }
2104 break;
2105
2106 case 1014:
2107 UserInfo1014 = (PUSER_INFO_1014)UserInfo;
2108
2109 if (UserInfo1014->usri1014_workstations != NULL)
2110 {
2111 RtlInitUnicodeString(&UserAllInfo.WorkStations,
2112 UserInfo1014->usri1014_workstations);
2113 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
2114 }
2115 break;
2116
2117 case 1017:
2118 UserInfo1017 = (PUSER_INFO_1017)UserInfo;
2119
2120 if (UserInfo1017->usri1017_acct_expires == TIMEQ_FOREVER)
2121 {
2122 UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
2123 }
2124 else
2125 {
2126 RtlSecondsSince1970ToTime(UserInfo1017->usri1017_acct_expires,
2127 &UserAllInfo.AccountExpires);
2128 }
2129 UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
2130 break;
2131
2132 case 1018:
2133 UserInfo1018 = (PUSER_INFO_1018)UserInfo;
2134
2135 if (UserInfo1018->usri1018_max_storage != USER_MAXSTORAGE_UNLIMITED)
2136 {
2137 if (parm_err != NULL)
2138 *parm_err = USER_MAX_STORAGE_PARMNUM;
2139 ApiStatus = ERROR_INVALID_PARAMETER;
2140 }
2141 break;
2142
2143 case 1020:
2144 UserInfo1020 = (PUSER_INFO_1020)UserInfo;
2145
2146 if (UserInfo1020->usri1020_units_per_week > USHRT_MAX)
2147 {
2148 if (parm_err != NULL)
2149 *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
2150 ApiStatus = ERROR_INVALID_PARAMETER;
2151 break;
2152 }
2153
2154 UserAllInfo.LogonHours.UnitsPerWeek = UserInfo1020->usri1020_units_per_week;
2155 UserAllInfo.LogonHours.LogonHours = UserInfo1020->usri1020_logon_hours;
2156 UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
2157 break;
2158
2159 case 1024:
2160 UserInfo1024 = (PUSER_INFO_1024)UserInfo;
2161
2162 UserAllInfo.CountryCode = UserInfo1024->usri1024_country_code;
2163 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
2164 break;
2165
2166 case 1025:
2167 UserInfo1025 = (PUSER_INFO_1025)UserInfo;
2168
2169 UserAllInfo.CodePage = UserInfo1025->usri1025_code_page;
2170 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
2171 break;
2172
2173 case 1051:
2174 UserInfo1051 = (PUSER_INFO_1051)UserInfo;
2175
2176 UserAllInfo.PrimaryGroupId = UserInfo1051->usri1051_primary_group_id;
2177 UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
2178 break;
2179
2180 case 1052:
2181 UserInfo1052 = (PUSER_INFO_1052)UserInfo;
2182
2183 if (UserInfo1052->usri1052_profile != NULL)
2184 {
2185 RtlInitUnicodeString(&UserAllInfo.ProfilePath,
2186 UserInfo1052->usri1052_profile);
2187 UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
2188 }
2189 break;
2190
2191 case 1053:
2192 UserInfo1053 = (PUSER_INFO_1053)UserInfo;
2193
2194 if (UserInfo1053->usri1053_home_dir_drive != NULL)
2195 {
2196 RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive,
2197 UserInfo1053->usri1053_home_dir_drive);
2198 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE;
2199 }
2200 break;
2201 }
2202
2203 if (ApiStatus != NERR_Success)
2204 goto done;
2205
2206 Status = SamSetInformationUser(UserHandle,
2207 UserAllInformation,
2208 &UserAllInfo);
2209 if (!NT_SUCCESS(Status))
2210 {
2211 ERR("SamSetInformationUser failed (Status %08lx)\n", Status);
2212 ApiStatus = NetpNtStatusToApiStatus(Status);
2213 goto done;
2214 }
2215
2216 done:
2217 if (Dacl != NULL)
2218 HeapFree(GetProcessHeap(), 0, Dacl);
2219
2220 return ApiStatus;
2221 }
2222
2223
2224 static
2225 NET_API_STATUS
2226 OpenUserByName(SAM_HANDLE DomainHandle,
2227 PUNICODE_STRING UserName,
2228 ULONG DesiredAccess,
2229 PSAM_HANDLE UserHandle)
2230 {
2231 PULONG RelativeIds = NULL;
2232 PSID_NAME_USE Use = NULL;
2233 NET_API_STATUS ApiStatus = NERR_Success;
2234 NTSTATUS Status = STATUS_SUCCESS;
2235
2236 /* Get the RID for the given user name */
2237 Status = SamLookupNamesInDomain(DomainHandle,
2238 1,
2239 UserName,
2240 &RelativeIds,
2241 &Use);
2242 if (!NT_SUCCESS(Status))
2243 {
2244 ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status);
2245 return NetpNtStatusToApiStatus(Status);
2246 }
2247
2248 /* Fail, if it is not an alias account */
2249 if (Use[0] != SidTypeUser)
2250 {
2251 ERR("Object is not a user!\n");
2252 ApiStatus = NERR_GroupNotFound;
2253 goto done;
2254 }
2255
2256 /* Open the alias account */
2257 Status = SamOpenUser(DomainHandle,
2258 DesiredAccess,
2259 RelativeIds[0],
2260 UserHandle);
2261 if (!NT_SUCCESS(Status))
2262 {
2263 ERR("SamOpenUser failed (Status %08lx)\n", Status);
2264 ApiStatus = NetpNtStatusToApiStatus(Status);
2265 goto done;
2266 }
2267
2268 done:
2269 if (RelativeIds != NULL)
2270 SamFreeMemory(RelativeIds);
2271
2272 if (Use != NULL)
2273 SamFreeMemory(Use);
2274
2275 return ApiStatus;
2276 }
2277
2278
2279 /************************************************************
2280 * NetUserAdd (NETAPI32.@)
2281 */
2282 NET_API_STATUS
2283 WINAPI
2284 NetUserAdd(LPCWSTR servername,
2285 DWORD level,
2286 LPBYTE bufptr,
2287 LPDWORD parm_err)
2288 {
2289 UNICODE_STRING ServerName;
2290 UNICODE_STRING UserName;
2291 SAM_HANDLE ServerHandle = NULL;
2292 SAM_HANDLE DomainHandle = NULL;
2293 SAM_HANDLE UserHandle = NULL;
2294 ULONG GrantedAccess;
2295 ULONG RelativeId;
2296 NET_API_STATUS ApiStatus = NERR_Success;
2297 NTSTATUS Status = STATUS_SUCCESS;
2298
2299 TRACE("(%s, %d, %p, %p)\n", debugstr_w(servername), level, bufptr, parm_err);
2300
2301 if (parm_err != NULL)
2302 *parm_err = PARM_ERROR_NONE;
2303
2304 /* Check the info level */
2305 switch (level)
2306 {
2307 case 1:
2308 case 2:
2309 case 3:
2310 case 4:
2311 break;
2312
2313 default:
2314 return ERROR_INVALID_LEVEL;
2315 }
2316
2317 if (servername != NULL)
2318 RtlInitUnicodeString(&ServerName, servername);
2319
2320 /* Connect to the SAM Server */
2321 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2322 &ServerHandle,
2323 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
2324 NULL);
2325 if (!NT_SUCCESS(Status))
2326 {
2327 ERR("SamConnect failed (Status %08lx)\n", Status);
2328 ApiStatus = NetpNtStatusToApiStatus(Status);
2329 goto done;
2330 }
2331
2332 /* Open the Account Domain */
2333 Status = OpenAccountDomain(ServerHandle,
2334 (servername != NULL) ? &ServerName : NULL,
2335 DOMAIN_CREATE_USER | DOMAIN_LOOKUP | DOMAIN_READ_PASSWORD_PARAMETERS,
2336 &DomainHandle);
2337 if (!NT_SUCCESS(Status))
2338 {
2339 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2340 ApiStatus = NetpNtStatusToApiStatus(Status);
2341 goto done;
2342 }
2343
2344 /* Initialize the user name string */
2345 RtlInitUnicodeString(&UserName,
2346 ((PUSER_INFO_1)bufptr)->usri1_name);
2347
2348 /* Create the user account */
2349 Status = SamCreateUser2InDomain(DomainHandle,
2350 &UserName,
2351 USER_NORMAL_ACCOUNT,
2352 USER_ALL_ACCESS | DELETE | WRITE_DAC,
2353 &UserHandle,
2354 &GrantedAccess,
2355 &RelativeId);
2356 if (!NT_SUCCESS(Status))
2357 {
2358 ERR("SamCreateUser2InDomain failed (Status %08lx)\n", Status);
2359 ApiStatus = NetpNtStatusToApiStatus(Status);
2360 goto done;
2361 }
2362
2363 /* Set user information */
2364 ApiStatus = SetUserInfo(UserHandle,
2365 bufptr,
2366 level,
2367 parm_err);
2368 if (ApiStatus != NERR_Success)
2369 {
2370 ERR("SetUserInfo failed (Status %lu)\n", ApiStatus);
2371 goto done;
2372 }
2373
2374 done:
2375 if (UserHandle != NULL)
2376 {
2377 if (ApiStatus != NERR_Success)
2378 SamDeleteUser(UserHandle);
2379 else
2380 SamCloseHandle(UserHandle);
2381 }
2382
2383 if (DomainHandle != NULL)
2384 SamCloseHandle(DomainHandle);
2385
2386 if (ServerHandle != NULL)
2387 SamCloseHandle(ServerHandle);
2388
2389 return ApiStatus;
2390 }
2391
2392
2393 /******************************************************************************
2394 * NetUserChangePassword (NETAPI32.@)
2395 * PARAMS
2396 * domainname [I] Optional. Domain on which the user resides or the logon
2397 * domain of the current user if NULL.
2398 * username [I] Optional. Username to change the password for or the name
2399 * of the current user if NULL.
2400 * oldpassword [I] The user's current password.
2401 * newpassword [I] The password that the user will be changed to using.
2402 *
2403 * RETURNS
2404 * Success: NERR_Success.
2405 * Failure: NERR_* failure code or win error code.
2406 *
2407 */
2408 NET_API_STATUS
2409 WINAPI
2410 NetUserChangePassword(LPCWSTR domainname,
2411 LPCWSTR username,
2412 LPCWSTR oldpassword,
2413 LPCWSTR newpassword)
2414 {
2415 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer = NULL;
2416 PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer = NULL;
2417 ULONG RequestBufferSize;
2418 ULONG ResponseBufferSize = 0;
2419 LPWSTR Ptr;
2420 ANSI_STRING PackageName;
2421 ULONG AuthenticationPackage = 0;
2422 HANDLE LsaHandle = NULL;
2423 NET_API_STATUS ApiStatus = NERR_Success;
2424 NTSTATUS Status = STATUS_SUCCESS;
2425 NTSTATUS ProtocolStatus;
2426
2427 TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname), debugstr_w(username));
2428
2429 /* FIXME: handle null domain or user name */
2430
2431 /* Check the parameters */
2432 if ((oldpassword == NULL) ||
2433 (newpassword == NULL))
2434 return ERROR_INVALID_PARAMETER;
2435
2436 /* Connect to the LSA server */
2437 Status = LsaConnectUntrusted(&LsaHandle);
2438 if (!NT_SUCCESS(Status))
2439 return NetpNtStatusToApiStatus(Status);
2440
2441 /* Get the authentication package ID */
2442 RtlInitAnsiString(&PackageName,
2443 MSV1_0_PACKAGE_NAME);
2444
2445 Status = LsaLookupAuthenticationPackage(LsaHandle,
2446 &PackageName,
2447 &AuthenticationPackage);
2448 if (!NT_SUCCESS(Status))
2449 {
2450 ApiStatus = NetpNtStatusToApiStatus(Status);
2451 goto done;
2452 }
2453
2454 /* Calculate the request buffer size */
2455 RequestBufferSize = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST) +
2456 ((wcslen(domainname) + 1) * sizeof(WCHAR)) +
2457 ((wcslen(username) + 1) * sizeof(WCHAR)) +
2458 ((wcslen(oldpassword) + 1) * sizeof(WCHAR)) +
2459 ((wcslen(newpassword) + 1) * sizeof(WCHAR));
2460
2461 /* Allocate the request buffer */
2462 ApiStatus = NetApiBufferAllocate(RequestBufferSize,
2463 (PVOID*)&RequestBuffer);
2464 if (ApiStatus != NERR_Success)
2465 goto done;
2466
2467 /* Initialize the request buffer */
2468 RequestBuffer->MessageType = MsV1_0ChangePassword;
2469 RequestBuffer->Impersonating = TRUE;
2470
2471 Ptr = (LPWSTR)((ULONG_PTR)RequestBuffer + sizeof(MSV1_0_CHANGEPASSWORD_REQUEST));
2472
2473 /* Pack the domain name */
2474 RequestBuffer->DomainName.Length = wcslen(domainname) * sizeof(WCHAR);
2475 RequestBuffer->DomainName.MaximumLength = RequestBuffer->DomainName.Length + sizeof(WCHAR);
2476 RequestBuffer->DomainName.Buffer = Ptr;
2477
2478 RtlCopyMemory(RequestBuffer->DomainName.Buffer,
2479 domainname,
2480 RequestBuffer->DomainName.MaximumLength);
2481
2482 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->DomainName.MaximumLength);
2483
2484 /* Pack the user name */
2485 RequestBuffer->AccountName.Length = wcslen(username) * sizeof(WCHAR);
2486 RequestBuffer->AccountName.MaximumLength = RequestBuffer->AccountName.Length + sizeof(WCHAR);
2487 RequestBuffer->AccountName.Buffer = Ptr;
2488
2489 RtlCopyMemory(RequestBuffer->AccountName.Buffer,
2490 username,
2491 RequestBuffer->AccountName.MaximumLength);
2492
2493 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->AccountName.MaximumLength);
2494
2495 /* Pack the old password */
2496 RequestBuffer->OldPassword.Length = wcslen(oldpassword) * sizeof(WCHAR);
2497 RequestBuffer->OldPassword.MaximumLength = RequestBuffer->OldPassword.Length + sizeof(WCHAR);
2498 RequestBuffer->OldPassword.Buffer = Ptr;
2499
2500 RtlCopyMemory(RequestBuffer->OldPassword.Buffer,
2501 oldpassword,
2502 RequestBuffer->OldPassword.MaximumLength);
2503
2504 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->OldPassword.MaximumLength);
2505
2506 /* Pack the new password */
2507 RequestBuffer->NewPassword.Length = wcslen(newpassword) * sizeof(WCHAR);
2508 RequestBuffer->NewPassword.MaximumLength = RequestBuffer->NewPassword.Length + sizeof(WCHAR);
2509 RequestBuffer->NewPassword.Buffer = Ptr;
2510
2511 RtlCopyMemory(RequestBuffer->NewPassword.Buffer,
2512 newpassword,
2513 RequestBuffer->NewPassword.MaximumLength);
2514
2515 /* Call the authentication package */
2516 Status = LsaCallAuthenticationPackage(LsaHandle,
2517 AuthenticationPackage,
2518 RequestBuffer,
2519 RequestBufferSize,
2520 (PVOID*)&ResponseBuffer,
2521 &ResponseBufferSize,
2522 &ProtocolStatus);
2523 if (!NT_SUCCESS(Status))
2524 {
2525 ApiStatus = NetpNtStatusToApiStatus(Status);
2526 goto done;
2527 }
2528
2529 if (!NT_SUCCESS(ProtocolStatus))
2530 {
2531 ApiStatus = NetpNtStatusToApiStatus(ProtocolStatus);
2532 goto done;
2533 }
2534
2535 done:
2536 if (RequestBuffer != NULL)
2537 NetApiBufferFree(RequestBuffer);
2538
2539 if (ResponseBuffer != NULL)
2540 LsaFreeReturnBuffer(ResponseBuffer);
2541
2542 if (LsaHandle != NULL)
2543 NtClose(LsaHandle);
2544
2545 return ApiStatus;
2546 }
2547
2548
2549 /************************************************************
2550 * NetUserDel (NETAPI32.@)
2551 */
2552 NET_API_STATUS
2553 WINAPI
2554 NetUserDel(LPCWSTR servername,
2555 LPCWSTR username)
2556 {
2557 UNICODE_STRING ServerName;
2558 UNICODE_STRING UserName;
2559 SAM_HANDLE ServerHandle = NULL;
2560 SAM_HANDLE DomainHandle = NULL;
2561 SAM_HANDLE UserHandle = NULL;
2562 NET_API_STATUS ApiStatus = NERR_Success;
2563 NTSTATUS Status = STATUS_SUCCESS;
2564
2565 TRACE("(%s, %s)\n", debugstr_w(servername), debugstr_w(username));
2566
2567 if (servername != NULL)
2568 RtlInitUnicodeString(&ServerName, servername);
2569
2570 RtlInitUnicodeString(&UserName, username);
2571
2572 /* Connect to the SAM Server */
2573 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2574 &ServerHandle,
2575 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
2576 NULL);
2577 if (!NT_SUCCESS(Status))
2578 {
2579 ERR("SamConnect failed (Status %08lx)\n", Status);
2580 ApiStatus = NetpNtStatusToApiStatus(Status);
2581 goto done;
2582 }
2583
2584 /* Open the Builtin Domain */
2585 Status = OpenBuiltinDomain(ServerHandle,
2586 DOMAIN_LOOKUP,
2587 &DomainHandle);
2588 if (!NT_SUCCESS(Status))
2589 {
2590 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status);
2591 ApiStatus = NetpNtStatusToApiStatus(Status);
2592 goto done;
2593 }
2594
2595 /* Open the user account in the builtin domain */
2596 ApiStatus = OpenUserByName(DomainHandle,
2597 &UserName,
2598 DELETE,
2599 &UserHandle);
2600 if (ApiStatus != NERR_Success && ApiStatus != ERROR_NONE_MAPPED)
2601 {
2602 TRACE("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus);
2603 goto done;
2604 }
2605
2606 if (UserHandle == NULL)
2607 {
2608 if (DomainHandle != NULL)
2609 {
2610 SamCloseHandle(DomainHandle);
2611 DomainHandle = NULL;
2612 }
2613
2614 /* Open the Acount Domain */
2615 Status = OpenAccountDomain(ServerHandle,
2616 (servername != NULL) ? &ServerName : NULL,
2617 DOMAIN_LOOKUP,
2618 &DomainHandle);
2619 if (!NT_SUCCESS(Status))
2620 {
2621 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2622 ApiStatus = NetpNtStatusToApiStatus(Status);
2623 goto done;
2624 }
2625
2626 /* Open the user account in the account domain */
2627 ApiStatus = OpenUserByName(DomainHandle,
2628 &UserName,
2629 DELETE,
2630 &UserHandle);
2631 if (ApiStatus != NERR_Success)
2632 {
2633 ERR("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus);
2634 if (ApiStatus == ERROR_NONE_MAPPED)
2635 ApiStatus = NERR_UserNotFound;
2636 goto done;
2637 }
2638 }
2639
2640 /* Delete the user */
2641 Status = SamDeleteUser(UserHandle);
2642 if (!NT_SUCCESS(Status))
2643 {
2644 ERR("SamDeleteUser failed (Status %08lx)\n", Status);
2645 ApiStatus = NetpNtStatusToApiStatus(Status);
2646 goto done;
2647 }
2648
2649 /* A successful delete invalidates the handle */
2650 UserHandle = NULL;
2651
2652 done:
2653 if (UserHandle != NULL)
2654 SamCloseHandle(UserHandle);
2655
2656 if (DomainHandle != NULL)
2657 SamCloseHandle(DomainHandle);
2658
2659 if (ServerHandle != NULL)
2660 SamCloseHandle(ServerHandle);
2661
2662 return ApiStatus;
2663 }
2664
2665
2666 /************************************************************
2667 * NetUserEnum (NETAPI32.@)
2668 */
2669 NET_API_STATUS
2670 WINAPI
2671 NetUserEnum(LPCWSTR servername,
2672 DWORD level,
2673 DWORD filter,
2674 LPBYTE* bufptr,
2675 DWORD prefmaxlen,
2676 LPDWORD entriesread,
2677 LPDWORD totalentries,
2678 LPDWORD resume_handle)
2679 {
2680 UNICODE_STRING ServerName;
2681 PSAM_RID_ENUMERATION CurrentUser;
2682 PENUM_CONTEXT EnumContext = NULL;
2683 LPVOID Buffer = NULL;
2684 ULONG i;
2685 SAM_HANDLE UserHandle = NULL;
2686 ACCESS_MASK DesiredAccess;
2687 NET_API_STATUS ApiStatus = NERR_Success;
2688 NTSTATUS Status = STATUS_SUCCESS;
2689
2690 TRACE("(%s %d 0x%d %p %d %p %p %p)\n", debugstr_w(servername), level,
2691 filter, bufptr, prefmaxlen, entriesread, totalentries, resume_handle);
2692
2693 *entriesread = 0;
2694 *totalentries = 0;
2695 *bufptr = NULL;
2696
2697 if (servername != NULL)
2698 RtlInitUnicodeString(&ServerName, servername);
2699
2700 if (resume_handle != NULL && *resume_handle != 0)
2701 {
2702 EnumContext = (PENUM_CONTEXT)*resume_handle;
2703 }
2704 else
2705 {
2706 ApiStatus = NetApiBufferAllocate(sizeof(ENUM_CONTEXT), (PVOID*)&EnumContext);
2707 if (ApiStatus != NERR_Success)
2708 goto done;
2709
2710 EnumContext->EnumerationContext = 0;
2711 EnumContext->Buffer = NULL;
2712 EnumContext->Count = 0;
2713 EnumContext->Index = 0;
2714 EnumContext->BuiltinDone = FALSE;
2715
2716 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2717 &EnumContext->ServerHandle,
2718 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
2719 NULL);
2720 if (!NT_SUCCESS(Status))
2721 {
2722 ERR("SamConnect failed (Status %08lx)\n", Status);
2723 ApiStatus = NetpNtStatusToApiStatus(Status);
2724 goto done;
2725 }
2726
2727 /* Get the Account Domain SID */
2728 Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
2729 &EnumContext->AccountDomainSid);
2730 if (!NT_SUCCESS(Status))
2731 {
2732 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
2733 ApiStatus = NetpNtStatusToApiStatus(Status);
2734 goto done;
2735 }
2736
2737 /* Open the Account Domain */
2738 Status = SamOpenDomain(EnumContext->ServerHandle,
2739 DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
2740 EnumContext->AccountDomainSid,
2741 &EnumContext->AccountDomainHandle);
2742 if (!NT_SUCCESS(Status))
2743 {
2744 ERR("SamOpenDomain failed (Status %08lx)\n", Status);
2745 ApiStatus = NetpNtStatusToApiStatus(Status);
2746 goto done;
2747 }
2748
2749 /* Get the Builtin Domain SID */
2750 Status = GetBuiltinDomainSid(&EnumContext->BuiltinDomainSid);
2751 if (!NT_SUCCESS(Status))
2752 {
2753 ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status);
2754 ApiStatus = NetpNtStatusToApiStatus(Status);
2755 goto done;
2756 }
2757
2758 DesiredAccess = DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP;
2759 if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
2760 DesiredAccess |= DOMAIN_GET_ALIAS_MEMBERSHIP;
2761
2762 /* Open the Builtin Domain */
2763 Status = SamOpenDomain(EnumContext->ServerHandle,
2764 DesiredAccess,
2765 EnumContext->BuiltinDomainSid,
2766 &EnumContext->BuiltinDomainHandle);
2767 if (!NT_SUCCESS(Status))
2768 {
2769 ERR("SamOpenDomain failed (Status %08lx)\n", Status);
2770 ApiStatus = NetpNtStatusToApiStatus(Status);
2771 goto done;
2772 }
2773 }
2774
2775 // while (TRUE)
2776 // {
2777 TRACE("EnumContext->Index: %lu\n", EnumContext->Index);
2778 TRACE("EnumContext->Count: %lu\n", EnumContext->Count);
2779
2780 if (EnumContext->Index >= EnumContext->Count)
2781 {
2782 // if (EnumContext->BuiltinDone != FALSE)
2783 // {
2784 // ApiStatus = NERR_Success;
2785 // goto done;
2786 // }
2787
2788 TRACE("Calling SamEnumerateUsersInDomain\n");
2789 Status = SamEnumerateUsersInDomain(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
2790 &EnumContext->EnumerationContext,
2791 0,
2792 (PVOID *)&EnumContext->Buffer,
2793 prefmaxlen,
2794 &EnumContext->Count);
2795
2796 TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n", Status);
2797 if (!NT_SUCCESS(Status))
2798 {
2799 ERR("SamEnumerateUsersInDomain failed (Status %08lx)\n", Status);
2800 ApiStatus = NetpNtStatusToApiStatus(Status);
2801 goto done;
2802 }
2803
2804 if (Status == STATUS_MORE_ENTRIES)
2805 {
2806 ApiStatus = NERR_BufTooSmall;
2807 goto done;
2808 }
2809 else
2810 {
2811 EnumContext->BuiltinDone = TRUE;
2812 }
2813 }
2814
2815 TRACE("EnumContext: %lu\n", EnumContext);
2816 TRACE("EnumContext->Count: %lu\n", EnumContext->Count);
2817 TRACE("EnumContext->Buffer: %p\n", EnumContext->Buffer);
2818
2819 /* Get a pointer to the current user */
2820 CurrentUser = &EnumContext->Buffer[EnumContext->Index];
2821
2822 TRACE("RID: %lu\n", CurrentUser->RelativeId);
2823
2824 DesiredAccess = READ_CONTROL | USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT;
2825 if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
2826 DesiredAccess |= USER_LIST_GROUPS;
2827
2828 Status = SamOpenUser(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
2829 DesiredAccess,
2830 CurrentUser->RelativeId,
2831 &UserHandle);
2832 if (!NT_SUCCESS(Status))
2833 {
2834 ERR("SamOpenUser failed (Status %08lx)\n", Status);
2835 ApiStatus = NetpNtStatusToApiStatus(Status);
2836 goto done;
2837 }
2838
2839 ApiStatus = BuildUserInfoBuffer(EnumContext->BuiltinDomainHandle,
2840 UserHandle,
2841 EnumContext->AccountDomainSid,
2842 CurrentUser->RelativeId,
2843 level,
2844 &Buffer);
2845 if (ApiStatus != NERR_Success)
2846 {
2847 ERR("BuildUserInfoBuffer failed (ApiStatus %lu)\n", ApiStatus);
2848 goto done;
2849 }
2850
2851 SamCloseHandle(UserHandle);
2852 UserHandle = NULL;
2853
2854 EnumContext->Index++;
2855
2856 (*entriesread)++;
2857 // }
2858
2859 done:
2860 if (ApiStatus == NERR_Success && EnumContext != NULL && EnumContext->Index < EnumContext->Count)
2861 ApiStatus = ERROR_MORE_DATA;
2862
2863 if (EnumContext != NULL)
2864 *totalentries = EnumContext->Count;
2865
2866 if (resume_handle == NULL || ApiStatus != ERROR_MORE_DATA)
2867 {
2868 if (EnumContext != NULL)
2869 {
2870 if (EnumContext->BuiltinDomainHandle != NULL)
2871 SamCloseHandle(EnumContext->BuiltinDomainHandle);
2872
2873 if (EnumContext->AccountDomainHandle != NULL)
2874 SamCloseHandle(EnumContext->AccountDomainHandle);
2875
2876 if (EnumContext->BuiltinDomainSid != NULL)
2877 RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext->BuiltinDomainSid);
2878
2879 if (EnumContext->AccountDomainSid != NULL)
2880 RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext->AccountDomainSid);
2881
2882 if (EnumContext->ServerHandle != NULL)
2883 SamCloseHandle(EnumContext->ServerHandle);
2884
2885 if (EnumContext->Buffer != NULL)
2886 {
2887 for (i = 0; i < EnumContext->Count; i++)
2888 {
2889 SamFreeMemory(EnumContext->Buffer[i].Name.Buffer);
2890 }
2891
2892 SamFreeMemory(EnumContext->Buffer);
2893 }
2894
2895 NetApiBufferFree(EnumContext);
2896 EnumContext = NULL;
2897 }
2898 }
2899
2900 if (UserHandle != NULL)
2901 SamCloseHandle(UserHandle);
2902
2903 if (resume_handle != NULL)
2904 *resume_handle = (DWORD_PTR)EnumContext;
2905
2906 *bufptr = (LPBYTE)Buffer;
2907
2908 TRACE("return %lu\n", ApiStatus);
2909
2910 return ApiStatus;
2911 }
2912
2913
2914 /************************************************************
2915 * NetUserGetGroups (NETAPI32.@)
2916 */
2917 NET_API_STATUS
2918 WINAPI
2919 NetUserGetGroups(LPCWSTR servername,
2920 LPCWSTR username,
2921 DWORD level,
2922 LPBYTE *bufptr,
2923 DWORD prefixmaxlen,
2924 LPDWORD entriesread,
2925 LPDWORD totalentries)
2926 {
2927 UNICODE_STRING ServerName;
2928 UNICODE_STRING UserName;
2929 SAM_HANDLE ServerHandle = NULL;
2930 SAM_HANDLE AccountDomainHandle = NULL;
2931 SAM_HANDLE UserHandle = NULL;
2932 PSID AccountDomainSid = NULL;
2933 PULONG RelativeIds = NULL;
2934 PSID_NAME_USE Use = NULL;
2935 PGROUP_MEMBERSHIP GroupMembership = NULL;
2936 ULONG GroupCount;
2937
2938 NET_API_STATUS ApiStatus = NERR_Success;
2939 NTSTATUS Status = STATUS_SUCCESS;
2940
2941 TRACE("%s %s %d %p %d %p %p stub\n", debugstr_w(servername),
2942 debugstr_w(username), level, bufptr, prefixmaxlen, entriesread,
2943 totalentries);
2944
2945 if (servername != NULL)
2946 RtlInitUnicodeString(&ServerName, servername);
2947
2948 RtlInitUnicodeString(&UserName, username);
2949
2950 /* Connect to the SAM Server */
2951 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2952 &ServerHandle,
2953 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
2954 NULL);
2955 if (!NT_SUCCESS(Status))
2956 {
2957 ERR("SamConnect failed (Status %08lx)\n", Status);
2958 ApiStatus = NetpNtStatusToApiStatus(Status);
2959 goto done;
2960 }
2961
2962 /* Get the Account Domain SID */
2963 Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
2964 &AccountDomainSid);
2965 if (!NT_SUCCESS(Status))
2966 {
2967 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
2968 ApiStatus = NetpNtStatusToApiStatus(Status);
2969 goto done;
2970 }
2971
2972 /* Open the Account Domain */
2973 Status = SamOpenDomain(ServerHandle,
2974 DOMAIN_LOOKUP | DOMAIN_GET_ALIAS_MEMBERSHIP,
2975 AccountDomainSid,
2976 &AccountDomainHandle);
2977 if (!NT_SUCCESS(Status))
2978 {
2979 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2980 ApiStatus = NetpNtStatusToApiStatus(Status);
2981 goto done;
2982 }
2983
2984 /* Get the RID for the given user name */
2985 Status = SamLookupNamesInDomain(AccountDomainHandle,
2986 1,
2987 &UserName,
2988 &RelativeIds,
2989 &Use);
2990 if (!NT_SUCCESS(Status))
2991 {
2992 ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status);
2993 if (Status == STATUS_NONE_MAPPED)
2994 ApiStatus = NERR_UserNotFound;
2995 else
2996 ApiStatus = NetpNtStatusToApiStatus(Status);
2997 goto done;
2998 }
2999
3000 /* Fail, if it is not a user account */
3001 if (Use[0] != SidTypeUser)
3002 {
3003 ERR("Account is not a User!\n");
3004 ApiStatus = NERR_UserNotFound;
3005 goto done;
3006 }
3007
3008 /* Open the user object */
3009 Status = SamOpenUser(AccountDomainHandle,
3010 USER_LIST_GROUPS,
3011 RelativeIds[0],
3012 &UserHandle);
3013 if (!NT_SUCCESS(Status))
3014 {
3015 ERR("SamOpenUser failed (Status %08lx)\n", Status);
3016 ApiStatus = NetpNtStatusToApiStatus(Status);
3017 goto done;
3018 }
3019
3020 /* Get the group memberships of this user */
3021 Status = SamGetGroupsForUser(UserHandle,
3022 &GroupMembership,
3023 &GroupCount);
3024 if (!NT_SUCCESS(Status))
3025 {
3026 ERR("SamGetGroupsForUser failed (Status %08lx)\n", Status);
3027 ApiStatus = NetpNtStatusToApiStatus(Status);
3028 goto done;
3029 }
3030
3031 /* If there is no group membership, we're done */
3032 if (GroupCount == 0)
3033 {
3034 ApiStatus = NERR_Success;
3035 goto done;
3036 }
3037
3038
3039 done:
3040
3041 if (GroupMembership != NULL)
3042 SamFreeMemory(GroupMembership);
3043
3044 if (UserHandle != NULL)
3045 SamCloseHandle(UserHandle);
3046
3047 if (RelativeIds != NULL)
3048 SamFreeMemory(RelativeIds);
3049
3050 if (Use != NULL)
3051 SamFreeMemory(Use);
3052
3053 if (AccountDomainSid != NULL)
3054 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
3055
3056 if (AccountDomainHandle != NULL)
3057 SamCloseHandle(AccountDomainHandle);
3058
3059 if (ServerHandle != NULL)
3060 SamCloseHandle(ServerHandle);
3061
3062 if (ApiStatus != NERR_Success && ApiStatus != ERROR_MORE_DATA)
3063 {
3064 *entriesread = 0;
3065 *totalentries = 0;
3066 }
3067 else
3068 {
3069 // *entriesread = Count;
3070 // *totalentries = Count;
3071 }
3072
3073 // *bufptr = (LPBYTE)Buffer;
3074
3075 return ApiStatus;
3076 }
3077
3078
3079 /************************************************************
3080 * NetUserGetInfo (NETAPI32.@)
3081 */
3082 NET_API_STATUS
3083 WINAPI
3084 NetUserGetInfo(LPCWSTR servername,
3085 LPCWSTR username,
3086 DWORD level,
3087 LPBYTE* bufptr)
3088 {
3089 UNICODE_STRING ServerName;
3090 UNICODE_STRING UserName;
3091 SAM_HANDLE ServerHandle = NULL;
3092 SAM_HANDLE AccountDomainHandle = NULL;
3093 SAM_HANDLE BuiltinDomainHandle = NULL;
3094 SAM_HANDLE UserHandle = NULL;
3095 PULONG RelativeIds = NULL;
3096 PSID_NAME_USE Use = NULL;
3097 LPVOID Buffer = NULL;
3098 PSID AccountDomainSid = NULL;
3099 PSID BuiltinDomainSid = NULL;
3100 ACCESS_MASK DesiredAccess;
3101 NET_API_STATUS ApiStatus = NERR_Success;
3102 NTSTATUS Status = STATUS_SUCCESS;
3103
3104 TRACE("(%s, %s, %d, %p)\n", debugstr_w(servername),
3105 debugstr_w(username), level, bufptr);
3106
3107 if (servername != NULL)
3108 RtlInitUnicodeString(&ServerName, servername);
3109
3110 RtlInitUnicodeString(&UserName, username);
3111
3112 /* Connect to the SAM Server */
3113 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
3114 &ServerHandle,
3115 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
3116 NULL);
3117 if (!NT_SUCCESS(Status))
3118 {
3119 ERR("SamConnect failed (Status %08lx)\n", Status);
3120 ApiStatus = NetpNtStatusToApiStatus(Status);
3121 goto done;
3122 }
3123
3124 /* Get the Builtin Domain SID */
3125 Status = GetBuiltinDomainSid(&BuiltinDomainSid);
3126 if (!NT_SUCCESS(Status))
3127 {
3128 ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status);
3129 ApiStatus = NetpNtStatusToApiStatus(Status);
3130 goto done;
3131 }
3132
3133 DesiredAccess = DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP;
3134 if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
3135 DesiredAccess |= DOMAIN_GET_ALIAS_MEMBERSHIP;
3136
3137 /* Open the Builtin Domain */
3138 Status = SamOpenDomain(ServerHandle,
3139 DesiredAccess,
3140 BuiltinDomainSid,
3141 &BuiltinDomainHandle);
3142 if (!NT_SUCCESS(Status))
3143 {
3144 ERR("SamOpenDomain failed (Status %08lx)\n", Status);
3145 ApiStatus = NetpNtStatusToApiStatus(Status);
3146 goto done;
3147 }
3148
3149 /* Get the Account Domain SID */
3150 Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
3151 &AccountDomainSid);
3152 if (!NT_SUCCESS(Status))
3153 {
3154 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
3155 ApiStatus = NetpNtStatusToApiStatus(Status);
3156 goto done;
3157 }
3158
3159 /* Open the Account Domain */
3160 Status = SamOpenDomain(ServerHandle,
3161 DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
3162 AccountDomainSid,
3163 &AccountDomainHandle);
3164 if (!NT_SUCCESS(Status))
3165 {
3166 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
3167 ApiStatus = NetpNtStatusToApiStatus(Status);
3168 goto done;
3169 }
3170
3171 /* Get the RID for the given user name */
3172 Status = SamLookupNamesInDomain(AccountDomainHandle,
3173 1,
3174 &UserName,
3175 &RelativeIds,
3176 &Use);
3177 if (!NT_SUCCESS(Status))
3178 {
3179 ERR("SamOpenDomain failed (Status %08lx)\n", Status);
3180 if (Status == STATUS_NONE_MAPPED)
3181 ApiStatus = NERR_UserNotFound;
3182 else
3183 ApiStatus = NetpNtStatusToApiStatus(Status);
3184 goto done;
3185 }
3186
3187 /* Check if the account is a user account */
3188 if (Use[0] != SidTypeUser)
3189 {
3190 ERR("No user found!\n");
3191 ApiStatus = NERR_UserNotFound;
3192 goto done;
3193 }
3194
3195 TRACE("RID: %lu\n", RelativeIds[0]);
3196
3197 DesiredAccess = READ_CONTROL | USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT;
3198 if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
3199 DesiredAccess |= USER_LIST_GROUPS;
3200
3201 /* Open the user object */
3202 Status = SamOpenUser(AccountDomainHandle,
3203 DesiredAccess,
3204 RelativeIds[0],
3205 &UserHandle);
3206 if (!NT_SUCCESS(Status))
3207 {
3208 ERR("SamOpenUser failed (Status %08lx)\n", Status);
3209 ApiStatus = NetpNtStatusToApiStatus(Status);
3210 goto done;
3211 }
3212
3213 ApiStatus = BuildUserInfoBuffer(BuiltinDomainHandle,
3214 UserHandle,
3215 AccountDomainSid,
3216 RelativeIds[0],
3217 level,
3218 &Buffer);
3219 if (ApiStatus != NERR_Success)
3220 {
3221 ERR("BuildUserInfoBuffer failed (ApiStatus %08lu)\n", ApiStatus);
3222 goto done;
3223 }
3224
3225 done:
3226 if (UserHandle != NULL)
3227 SamCloseHandle(UserHandle);
3228
3229 if (RelativeIds != NULL)
3230 SamFreeMemory(RelativeIds);
3231
3232 if (Use != NULL)
3233 SamFreeMemory(Use);
3234
3235 if (AccountDomainHandle != NULL)
3236 SamCloseHandle(AccountDomainHandle);
3237
3238 if (AccountDomainSid != NULL)
3239 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
3240
3241 if (BuiltinDomainHandle != NULL)
3242 SamCloseHandle(BuiltinDomainHandle);
3243
3244 if (BuiltinDomainSid != NULL)
3245 RtlFreeHeap(RtlGetProcessHeap(), 0, BuiltinDomainSid);
3246
3247 if (ServerHandle != NULL)
3248 SamCloseHandle(ServerHandle);
3249
3250 *bufptr = (LPBYTE)Buffer;
3251
3252 return ApiStatus;
3253 }
3254
3255
3256 /************************************************************
3257 * NetUserGetLocalGroups (NETAPI32.@)