2 * Copyright 2002 Andriy Palamarchuk
4 * netapi32 user functions
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.
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.
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
23 * Implement NetUserGetGroups (WIP)
24 * Implement NetUserSetGroups
25 * NetUserGetLocalGroups does not support LG_INCLUDE_INDIRECT yet.
26 * Add missing information levels.
32 #include <ndk/kefuncs.h>
33 #include <ndk/obfuncs.h>
35 WINE_DEFAULT_DEBUG_CHANNEL(netapi32
);
37 typedef struct _ENUM_CONTEXT
39 SAM_HANDLE ServerHandle
;
40 SAM_HANDLE BuiltinDomainHandle
;
41 SAM_HANDLE AccountDomainHandle
;
42 PSID AccountDomainSid
;
44 SAM_ENUMERATE_HANDLE EnumerationContext
;
45 PSAM_RID_ENUMERATION Buffer
;
50 } ENUM_CONTEXT
, *PENUM_CONTEXT
;
55 DeltaTimeToSeconds(LARGE_INTEGER DeltaTime
)
57 LARGE_INTEGER Seconds
;
59 if (DeltaTime
.QuadPart
== 0)
62 Seconds
.QuadPart
= -DeltaTime
.QuadPart
/ 10000000;
64 if (Seconds
.HighPart
!= 0)
67 return Seconds
.LowPart
;
73 GetAllowedWorldAce(IN PACL Acl
,
74 OUT PACCESS_ALLOWED_ACE
*Ace
)
76 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
77 ULONG WorldSid
[sizeof(SID
) / sizeof(ULONG
) + SID_MAX_SUB_AUTHORITIES
];
78 ACL_SIZE_INFORMATION AclSize
;
79 PVOID LocalAce
= NULL
;
85 RtlInitializeSid((PSID
)WorldSid
,
88 *(RtlSubAuthoritySid((PSID
)WorldSid
, 0)) = SECURITY_WORLD_RID
;
90 Status
= RtlQueryInformationAcl(Acl
,
94 if (!NT_SUCCESS(Status
))
97 for (i
= 0; i
< AclSize
.AceCount
; i
++)
99 Status
= RtlGetAce(Acl
, i
, &LocalAce
);
100 if (!NT_SUCCESS(Status
))
103 if (((PACE_HEADER
)LocalAce
)->AceType
!= ACCESS_ALLOWED_ACE_TYPE
)
106 if (RtlEqualSid((PSID
)WorldSid
,
107 (PSID
)&((PACCESS_ALLOWED_ACE
)LocalAce
)->SidStart
))
109 *Ace
= (PACCESS_ALLOWED_ACE
)LocalAce
;
110 return STATUS_SUCCESS
;
114 return STATUS_SUCCESS
;
120 GetAccountFlags(ULONG AccountControl
,
123 PACCESS_ALLOWED_ACE Ace
= NULL
;
124 ULONG Flags
= UF_SCRIPT
;
129 Status
= GetAllowedWorldAce(Dacl
, &Ace
);
130 if (NT_SUCCESS(Status
))
134 Flags
|= UF_PASSWD_CANT_CHANGE
;
136 else if ((Ace
->Mask
& USER_CHANGE_PASSWORD
) == 0)
138 Flags
|= UF_PASSWD_CANT_CHANGE
;
143 if (AccountControl
& USER_ACCOUNT_DISABLED
)
144 Flags
|= UF_ACCOUNTDISABLE
;
146 if (AccountControl
& USER_HOME_DIRECTORY_REQUIRED
)
147 Flags
|= UF_HOMEDIR_REQUIRED
;
149 if (AccountControl
& USER_PASSWORD_NOT_REQUIRED
)
150 Flags
|= UF_PASSWD_NOTREQD
;
152 if (AccountControl
& USER_ACCOUNT_AUTO_LOCKED
)
155 if (AccountControl
& USER_DONT_EXPIRE_PASSWORD
)
156 Flags
|= UF_DONT_EXPIRE_PASSWD
;
159 if (AccountControl & USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED)
160 Flags |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED;
162 if (AccountControl & USER_SMARTCARD_REQUIRED)
163 Flags |= UF_SMARTCARD_REQUIRED;
165 if (AccountControl & USER_TRUSTED_FOR_DELEGATION)
166 Flags |= UF_TRUSTED_FOR_DELEGATION;
168 if (AccountControl & USER_NOT_DELEGATED)
169 Flags |= UF_NOT_DELEGATED;
171 if (AccountControl & USER_USE_DES_KEY_ONLY)
172 Flags |= UF_USE_DES_KEY_ONLY;
174 if (AccountControl & USER_DONT_REQUIRE_PREAUTH)
175 Flags |= UF_DONT_REQUIRE_PREAUTH;
177 if (AccountControl & USER_PASSWORD_EXPIRED)
178 Flags |= UF_PASSWORD_EXPIRED;
181 /* Set account type flags */
182 if (AccountControl
& USER_TEMP_DUPLICATE_ACCOUNT
)
183 Flags
|= UF_TEMP_DUPLICATE_ACCOUNT
;
184 else if (AccountControl
& USER_NORMAL_ACCOUNT
)
185 Flags
|= UF_NORMAL_ACCOUNT
;
186 else if (AccountControl
& USER_INTERDOMAIN_TRUST_ACCOUNT
)
187 Flags
|= UF_INTERDOMAIN_TRUST_ACCOUNT
;
188 else if (AccountControl
& USER_WORKSTATION_TRUST_ACCOUNT
)
189 Flags
|= UF_WORKSTATION_TRUST_ACCOUNT
;
190 else if (AccountControl
& USER_SERVER_TRUST_ACCOUNT
)
191 Flags
|= UF_SERVER_TRUST_ACCOUNT
;
199 GetAccountControl(ULONG Flags
)
201 ULONG AccountControl
= 0;
203 if (Flags
& UF_ACCOUNTDISABLE
)
204 AccountControl
|= USER_ACCOUNT_DISABLED
;
206 if (Flags
& UF_HOMEDIR_REQUIRED
)
207 AccountControl
|= USER_HOME_DIRECTORY_REQUIRED
;
209 if (Flags
& UF_PASSWD_NOTREQD
)
210 AccountControl
|= USER_PASSWORD_NOT_REQUIRED
;
212 if (Flags
& UF_LOCKOUT
)
213 AccountControl
|= USER_ACCOUNT_AUTO_LOCKED
;
215 if (Flags
& UF_DONT_EXPIRE_PASSWD
)
216 AccountControl
|= USER_DONT_EXPIRE_PASSWORD
;
218 /* Set account type flags */
219 if (Flags
& UF_TEMP_DUPLICATE_ACCOUNT
)
220 AccountControl
|= USER_TEMP_DUPLICATE_ACCOUNT
;
221 else if (Flags
& UF_NORMAL_ACCOUNT
)
222 AccountControl
|= USER_NORMAL_ACCOUNT
;
223 else if (Flags
& UF_INTERDOMAIN_TRUST_ACCOUNT
)
224 AccountControl
|= USER_INTERDOMAIN_TRUST_ACCOUNT
;
225 else if (Flags
& UF_WORKSTATION_TRUST_ACCOUNT
)
226 AccountControl
|= USER_WORKSTATION_TRUST_ACCOUNT
;
227 else if (Flags
& UF_SERVER_TRUST_ACCOUNT
)
228 AccountControl
|= USER_SERVER_TRUST_ACCOUNT
;
230 return AccountControl
;
236 GetPasswordAge(IN PLARGE_INTEGER PasswordLastSet
)
238 LARGE_INTEGER SystemTime
;
239 ULONG SystemSecondsSince1970
;
240 ULONG PasswordSecondsSince1970
;
243 Status
= NtQuerySystemTime(&SystemTime
);
244 if (!NT_SUCCESS(Status
))
247 RtlTimeToSecondsSince1970(&SystemTime
, &SystemSecondsSince1970
);
248 RtlTimeToSecondsSince1970(PasswordLastSet
, &PasswordSecondsSince1970
);
250 return SystemSecondsSince1970
- PasswordSecondsSince1970
;
256 ChangeUserDacl(IN PACL Dacl
,
259 PACCESS_ALLOWED_ACE Ace
= NULL
;
265 Status
= GetAllowedWorldAce(Dacl
, &Ace
);
266 if (!NT_SUCCESS(Status
))
269 if (Flags
& UF_PASSWD_CANT_CHANGE
)
270 Ace
->Mask
&= ~USER_CHANGE_PASSWORD
;
272 Ace
->Mask
|= USER_CHANGE_PASSWORD
;
278 GetUserDacl(IN SAM_HANDLE UserHandle
,
281 PSECURITY_DESCRIPTOR SecurityDescriptor
= NULL
;
286 ACL_SIZE_INFORMATION AclSize
;
287 NET_API_STATUS ApiStatus
;
290 TRACE("(%p %p)\n", UserHandle
, Dacl
);
294 Status
= SamQuerySecurityObject(UserHandle
,
295 DACL_SECURITY_INFORMATION
,
296 &SecurityDescriptor
);
297 if (!NT_SUCCESS(Status
))
299 TRACE("SamQuerySecurityObject() failed (Status 0x%08lx)\n", Status
);
300 ApiStatus
= NetpNtStatusToApiStatus(Status
);
304 Status
= RtlGetDaclSecurityDescriptor(SecurityDescriptor
,
308 if (!NT_SUCCESS(Status
))
310 TRACE("RtlGetDaclSecurityDescriptor() failed (Status 0x%08lx)\n", Status
);
311 ApiStatus
= NERR_InternalError
;
315 if (Present
== FALSE
)
317 TRACE("No DACL present\n");
318 ApiStatus
= NERR_Success
;
322 Status
= RtlQueryInformationAcl(SamDacl
,
326 if (!NT_SUCCESS(Status
))
328 TRACE("RtlQueryInformationAcl() failed (Status 0x%08lx)\n", Status
);
329 ApiStatus
= NERR_InternalError
;
333 LocalDacl
= HeapAlloc(GetProcessHeap(), 0, AclSize
.AclBytesInUse
);
334 if (LocalDacl
== NULL
)
336 TRACE("Memory allocation failed\n");
337 ApiStatus
= ERROR_NOT_ENOUGH_MEMORY
;
341 RtlCopyMemory(LocalDacl
, SamDacl
, AclSize
.AclBytesInUse
);
345 ApiStatus
= NERR_Success
;
348 if (SecurityDescriptor
!= NULL
)
349 SamFreeMemory(SecurityDescriptor
);
351 TRACE("done (ApiStatus: 0x%08lx)\n", ApiStatus
);
359 FreeUserInfo(PUSER_ALL_INFORMATION UserInfo
)
361 if (UserInfo
->UserName
.Buffer
!= NULL
)
362 SamFreeMemory(UserInfo
->UserName
.Buffer
);
364 if (UserInfo
->FullName
.Buffer
!= NULL
)
365 SamFreeMemory(UserInfo
->FullName
.Buffer
);
367 if (UserInfo
->HomeDirectory
.Buffer
!= NULL
)
368 SamFreeMemory(UserInfo
->HomeDirectory
.Buffer
);
370 if (UserInfo
->HomeDirectoryDrive
.Buffer
!= NULL
)
371 SamFreeMemory(UserInfo
->HomeDirectoryDrive
.Buffer
);
373 if (UserInfo
->ScriptPath
.Buffer
!= NULL
)
374 SamFreeMemory(UserInfo
->ScriptPath
.Buffer
);
376 if (UserInfo
->ProfilePath
.Buffer
!= NULL
)
377 SamFreeMemory(UserInfo
->ProfilePath
.Buffer
);
379 if (UserInfo
->AdminComment
.Buffer
!= NULL
)
380 SamFreeMemory(UserInfo
->AdminComment
.Buffer
);
382 if (UserInfo
->WorkStations
.Buffer
!= NULL
)
383 SamFreeMemory(UserInfo
->WorkStations
.Buffer
);
385 if (UserInfo
->UserComment
.Buffer
!= NULL
)
386 SamFreeMemory(UserInfo
->UserComment
.Buffer
);
388 if (UserInfo
->Parameters
.Buffer
!= NULL
)
389 SamFreeMemory(UserInfo
->Parameters
.Buffer
);
391 if (UserInfo
->PrivateData
.Buffer
!= NULL
)
392 SamFreeMemory(UserInfo
->PrivateData
.Buffer
);
394 if (UserInfo
->LogonHours
.LogonHours
!= NULL
)
395 SamFreeMemory(UserInfo
->LogonHours
.LogonHours
);
397 SamFreeMemory(UserInfo
);
403 BuildUserInfoBuffer(SAM_HANDLE UserHandle
,
404 PSID AccountDomainSid
,
409 UNICODE_STRING LogonServer
= RTL_CONSTANT_STRING(L
"\\\\*");
410 PUSER_ALL_INFORMATION UserInfo
= NULL
;
411 LPVOID LocalBuffer
= NULL
;
413 PUSER_INFO_0 UserInfo0
;
414 PUSER_INFO_1 UserInfo1
;
415 PUSER_INFO_2 UserInfo2
;
416 PUSER_INFO_3 UserInfo3
;
417 PUSER_INFO_4 UserInfo4
;
418 PUSER_INFO_10 UserInfo10
;
419 PUSER_INFO_11 UserInfo11
;
420 PUSER_INFO_20 UserInfo20
;
421 PUSER_INFO_23 UserInfo23
;
425 NET_API_STATUS ApiStatus
= NERR_Success
;
429 Status
= SamQueryInformationUser(UserHandle
,
432 if (!NT_SUCCESS(Status
))
434 ERR("SamQueryInformationUser failed (Status %08lx)\n", Status
);
435 ApiStatus
= NetpNtStatusToApiStatus(Status
);
439 if ((level
== 1) || (level
== 2) || (level
== 3) ||
440 (level
== 4) || (level
== 20) || (level
== 23))
442 ApiStatus
= GetUserDacl(UserHandle
, &Dacl
);
443 if (ApiStatus
!= NERR_Success
)
450 Size
= sizeof(USER_INFO_0
) +
451 UserInfo
->UserName
.Length
+ sizeof(WCHAR
);
455 Size
= sizeof(USER_INFO_1
) +
456 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
457 UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
) +
458 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
) +
459 UserInfo
->ScriptPath
.Length
+ sizeof(WCHAR
);
463 Size
= sizeof(USER_INFO_2
) +
464 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
465 UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
) +
466 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
) +
467 UserInfo
->ScriptPath
.Length
+ sizeof(WCHAR
) +
468 UserInfo
->FullName
.Length
+ sizeof(WCHAR
) +
469 UserInfo
->UserComment
.Length
+ sizeof(WCHAR
) +
470 UserInfo
->Parameters
.Length
+ sizeof(WCHAR
) +
471 UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
) +
472 LogonServer
.Length
+ sizeof(WCHAR
);
474 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
475 Size
+= (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8;
479 Size
= sizeof(USER_INFO_3
) +
480 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
481 UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
) +
482 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
) +
483 UserInfo
->ScriptPath
.Length
+ sizeof(WCHAR
) +
484 UserInfo
->FullName
.Length
+ sizeof(WCHAR
) +
485 UserInfo
->UserComment
.Length
+ sizeof(WCHAR
) +
486 UserInfo
->Parameters
.Length
+ sizeof(WCHAR
) +
487 UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
) +
488 LogonServer
.Length
+ sizeof(WCHAR
) +
489 UserInfo
->ProfilePath
.Length
+ sizeof(WCHAR
) +
490 UserInfo
->HomeDirectoryDrive
.Length
+ sizeof(WCHAR
);
492 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
493 Size
+= (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8;
497 Size
= sizeof(USER_INFO_4
) +
498 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
499 UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
) +
500 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
) +
501 UserInfo
->ScriptPath
.Length
+ sizeof(WCHAR
) +
502 UserInfo
->FullName
.Length
+ sizeof(WCHAR
) +
503 UserInfo
->UserComment
.Length
+ sizeof(WCHAR
) +
504 UserInfo
->Parameters
.Length
+ sizeof(WCHAR
) +
505 UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
) +
506 LogonServer
.Length
+ sizeof(WCHAR
) +
507 UserInfo
->ProfilePath
.Length
+ sizeof(WCHAR
) +
508 UserInfo
->HomeDirectoryDrive
.Length
+ sizeof(WCHAR
);
510 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
511 Size
+= (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8;
513 Size
+= RtlLengthSid(AccountDomainSid
) + sizeof(ULONG
);
517 Size
= sizeof(USER_INFO_10
) +
518 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
519 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
) +
520 UserInfo
->UserComment
.Length
+ sizeof(WCHAR
) +
521 UserInfo
->FullName
.Length
+ sizeof(WCHAR
);
525 Size
= sizeof(USER_INFO_11
) +
526 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
527 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
) +
528 UserInfo
->UserComment
.Length
+ sizeof(WCHAR
) +
529 UserInfo
->FullName
.Length
+ sizeof(WCHAR
) +
530 UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
) +
531 UserInfo
->Parameters
.Length
+ sizeof(WCHAR
) +
532 LogonServer
.Length
+ sizeof(WCHAR
) +
533 UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
);
535 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
536 Size
+= (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8;
540 Size
= sizeof(USER_INFO_20
) +
541 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
542 UserInfo
->FullName
.Length
+ sizeof(WCHAR
) +
543 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
);
547 Size
= sizeof(USER_INFO_23
) +
548 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
549 UserInfo
->FullName
.Length
+ sizeof(WCHAR
) +
550 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
);
552 Size
+= RtlLengthSid(AccountDomainSid
) + sizeof(ULONG
);
556 ApiStatus
= ERROR_INVALID_LEVEL
;
560 ApiStatus
= NetApiBufferAllocate(Size
, &LocalBuffer
);
561 if (ApiStatus
!= NERR_Success
)
564 ZeroMemory(LocalBuffer
, Size
);
569 UserInfo0
= (PUSER_INFO_0
)LocalBuffer
;
571 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo0
+ sizeof(USER_INFO_0
));
573 UserInfo0
->usri0_name
= Ptr
;
575 memcpy(UserInfo0
->usri0_name
,
576 UserInfo
->UserName
.Buffer
,
577 UserInfo
->UserName
.Length
);
578 UserInfo0
->usri0_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
582 UserInfo1
= (PUSER_INFO_1
)LocalBuffer
;
584 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo1
+ sizeof(USER_INFO_1
));
586 UserInfo1
->usri1_name
= Ptr
;
588 memcpy(UserInfo1
->usri1_name
,
589 UserInfo
->UserName
.Buffer
,
590 UserInfo
->UserName
.Length
);
591 UserInfo1
->usri1_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
593 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
595 UserInfo1
->usri1_password
= NULL
;
596 UserInfo1
->usri1_password_age
= GetPasswordAge(&UserInfo
->PasswordLastSet
);
598 /* FIXME: usri1_priv */
600 UserInfo1
->usri1_home_dir
= Ptr
;
601 memcpy(UserInfo1
->usri1_home_dir
,
602 UserInfo
->HomeDirectory
.Buffer
,
603 UserInfo
->HomeDirectory
.Length
);
604 UserInfo1
->usri1_home_dir
[UserInfo
->HomeDirectory
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
605 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
));
607 UserInfo1
->usri1_comment
= Ptr
;
608 memcpy(UserInfo1
->usri1_comment
,
609 UserInfo
->AdminComment
.Buffer
,
610 UserInfo
->AdminComment
.Length
);
611 UserInfo1
->usri1_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
612 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
614 UserInfo1
->usri1_flags
= GetAccountFlags(UserInfo
->UserAccountControl
,
617 UserInfo1
->usri1_script_path
= Ptr
;
618 memcpy(UserInfo1
->usri1_script_path
,
619 UserInfo
->ScriptPath
.Buffer
,
620 UserInfo
->ScriptPath
.Length
);
621 UserInfo1
->usri1_script_path
[UserInfo
->ScriptPath
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
625 UserInfo2
= (PUSER_INFO_2
)LocalBuffer
;
627 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo2
+ sizeof(USER_INFO_2
));
629 UserInfo2
->usri2_name
= Ptr
;
631 memcpy(UserInfo2
->usri2_name
,
632 UserInfo
->UserName
.Buffer
,
633 UserInfo
->UserName
.Length
);
634 UserInfo2
->usri2_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
636 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
638 UserInfo2
->usri2_password
= NULL
;
639 UserInfo2
->usri2_password_age
= GetPasswordAge(&UserInfo
->PasswordLastSet
);
641 /* FIXME: usri2_priv */
643 UserInfo2
->usri2_home_dir
= Ptr
;
644 memcpy(UserInfo2
->usri2_home_dir
,
645 UserInfo
->HomeDirectory
.Buffer
,
646 UserInfo
->HomeDirectory
.Length
);
647 UserInfo2
->usri2_home_dir
[UserInfo
->HomeDirectory
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
648 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
));
650 UserInfo2
->usri2_comment
= Ptr
;
651 memcpy(UserInfo2
->usri2_comment
,
652 UserInfo
->AdminComment
.Buffer
,
653 UserInfo
->AdminComment
.Length
);
654 UserInfo2
->usri2_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
655 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
657 UserInfo2
->usri2_flags
= GetAccountFlags(UserInfo
->UserAccountControl
,
660 UserInfo2
->usri2_script_path
= Ptr
;
661 memcpy(UserInfo2
->usri2_script_path
,
662 UserInfo
->ScriptPath
.Buffer
,
663 UserInfo
->ScriptPath
.Length
);
664 UserInfo2
->usri2_script_path
[UserInfo
->ScriptPath
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
665 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->ScriptPath
.Length
+ sizeof(WCHAR
));
667 /* FIXME: usri2_auth_flags */
669 UserInfo2
->usri2_full_name
= Ptr
;
670 memcpy(UserInfo2
->usri2_full_name
,
671 UserInfo
->FullName
.Buffer
,
672 UserInfo
->FullName
.Length
);
673 UserInfo2
->usri2_full_name
[UserInfo
->FullName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
674 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->FullName
.Length
+ sizeof(WCHAR
));
676 UserInfo2
->usri2_usr_comment
= Ptr
;
677 memcpy(UserInfo2
->usri2_usr_comment
,
678 UserInfo
->UserComment
.Buffer
,
679 UserInfo
->UserComment
.Length
);
680 UserInfo2
->usri2_usr_comment
[UserInfo
->UserComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
681 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserComment
.Length
+ sizeof(WCHAR
));
683 UserInfo2
->usri2_parms
= Ptr
;
684 memcpy(UserInfo2
->usri2_parms
,
685 UserInfo
->Parameters
.Buffer
,
686 UserInfo
->Parameters
.Length
);
687 UserInfo2
->usri2_parms
[UserInfo
->Parameters
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
688 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->Parameters
.Length
+ sizeof(WCHAR
));
690 UserInfo2
->usri2_workstations
= Ptr
;
691 memcpy(UserInfo2
->usri2_workstations
,
692 UserInfo
->WorkStations
.Buffer
,
693 UserInfo
->WorkStations
.Length
);
694 UserInfo2
->usri2_workstations
[UserInfo
->WorkStations
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
695 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
));
697 if (UserInfo
->LastLogon
.QuadPart
== 0)
698 UserInfo2
->usri2_last_logon
= 0;
700 RtlTimeToSecondsSince1970(&UserInfo
->LastLogon
,
701 &UserInfo2
->usri2_last_logon
);
703 if (UserInfo
->LastLogoff
.QuadPart
== 0)
704 UserInfo2
->usri2_last_logoff
= 0;
706 RtlTimeToSecondsSince1970(&UserInfo
->LastLogoff
,
707 &UserInfo2
->usri2_last_logoff
);
709 if (UserInfo
->AccountExpires
.QuadPart
== MAXLONGLONG
)
710 UserInfo2
->usri2_acct_expires
= TIMEQ_FOREVER
;
712 RtlTimeToSecondsSince1970(&UserInfo
->AccountExpires
,
713 &UserInfo2
->usri2_acct_expires
);
715 UserInfo2
->usri2_max_storage
= USER_MAXSTORAGE_UNLIMITED
;
716 UserInfo2
->usri2_units_per_week
= UserInfo
->LogonHours
.UnitsPerWeek
;
718 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
720 UserInfo2
->usri2_logon_hours
= (PVOID
)Ptr
;
722 memcpy(UserInfo2
->usri2_logon_hours
,
723 UserInfo
->LogonHours
.LogonHours
,
724 (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
726 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
729 UserInfo2
->usri2_bad_pw_count
= UserInfo
->BadPasswordCount
;
730 UserInfo2
->usri2_num_logons
= UserInfo
->LogonCount
;
732 UserInfo2
->usri2_logon_server
= Ptr
;
733 memcpy(UserInfo2
->usri2_logon_server
,
736 UserInfo2
->usri2_logon_server
[LogonServer
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
737 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LogonServer
.Length
+ sizeof(WCHAR
));
739 UserInfo2
->usri2_country_code
= UserInfo
->CountryCode
;
740 UserInfo2
->usri2_code_page
= UserInfo
->CodePage
;
744 UserInfo3
= (PUSER_INFO_3
)LocalBuffer
;
746 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo3
+ sizeof(USER_INFO_3
));
748 UserInfo3
->usri3_name
= Ptr
;
750 memcpy(UserInfo3
->usri3_name
,
751 UserInfo
->UserName
.Buffer
,
752 UserInfo
->UserName
.Length
);
753 UserInfo3
->usri3_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
755 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
757 UserInfo3
->usri3_password
= NULL
;
758 UserInfo3
->usri3_password_age
= GetPasswordAge(&UserInfo
->PasswordLastSet
);
760 /* FIXME: usri3_priv */
762 UserInfo3
->usri3_home_dir
= Ptr
;
763 memcpy(UserInfo3
->usri3_home_dir
,
764 UserInfo
->HomeDirectory
.Buffer
,
765 UserInfo
->HomeDirectory
.Length
);
766 UserInfo3
->usri3_home_dir
[UserInfo
->HomeDirectory
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
767 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
));
769 UserInfo3
->usri3_comment
= Ptr
;
770 memcpy(UserInfo3
->usri3_comment
,
771 UserInfo
->AdminComment
.Buffer
,
772 UserInfo
->AdminComment
.Length
);
773 UserInfo3
->usri3_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
774 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
776 UserInfo3
->usri3_flags
= GetAccountFlags(UserInfo
->UserAccountControl
,
779 UserInfo3
->usri3_script_path
= Ptr
;
780 memcpy(UserInfo3
->usri3_script_path
,
781 UserInfo
->ScriptPath
.Buffer
,
782 UserInfo
->ScriptPath
.Length
);
783 UserInfo3
->usri3_script_path
[UserInfo
->ScriptPath
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
784 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->ScriptPath
.Length
+ sizeof(WCHAR
));
786 /* FIXME: usri3_auth_flags */
788 UserInfo3
->usri3_full_name
= Ptr
;
789 memcpy(UserInfo3
->usri3_full_name
,
790 UserInfo
->FullName
.Buffer
,
791 UserInfo
->FullName
.Length
);
792 UserInfo3
->usri3_full_name
[UserInfo
->FullName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
793 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->FullName
.Length
+ sizeof(WCHAR
));
795 UserInfo3
->usri3_usr_comment
= Ptr
;
796 memcpy(UserInfo3
->usri3_usr_comment
,
797 UserInfo
->UserComment
.Buffer
,
798 UserInfo
->UserComment
.Length
);
799 UserInfo3
->usri3_usr_comment
[UserInfo
->UserComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
800 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserComment
.Length
+ sizeof(WCHAR
));
802 UserInfo3
->usri3_parms
= Ptr
;
803 memcpy(UserInfo3
->usri3_parms
,
804 UserInfo
->Parameters
.Buffer
,
805 UserInfo
->Parameters
.Length
);
806 UserInfo3
->usri3_parms
[UserInfo
->Parameters
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
807 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->Parameters
.Length
+ sizeof(WCHAR
));
809 UserInfo3
->usri3_workstations
= Ptr
;
810 memcpy(UserInfo3
->usri3_workstations
,
811 UserInfo
->WorkStations
.Buffer
,
812 UserInfo
->WorkStations
.Length
);
813 UserInfo3
->usri3_workstations
[UserInfo
->WorkStations
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
814 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
));
816 if (UserInfo
->LastLogon
.QuadPart
== 0)
817 UserInfo3
->usri3_last_logon
= 0;
819 RtlTimeToSecondsSince1970(&UserInfo
->LastLogon
,
820 &UserInfo3
->usri3_last_logon
);
822 if (UserInfo
->LastLogoff
.QuadPart
== 0)
823 UserInfo3
->usri3_last_logoff
= 0;
825 RtlTimeToSecondsSince1970(&UserInfo
->LastLogoff
,
826 &UserInfo3
->usri3_last_logoff
);
828 if (UserInfo
->AccountExpires
.QuadPart
== MAXLONGLONG
)
829 UserInfo3
->usri3_acct_expires
= TIMEQ_FOREVER
;
831 RtlTimeToSecondsSince1970(&UserInfo
->AccountExpires
,
832 &UserInfo3
->usri3_acct_expires
);
834 UserInfo3
->usri3_max_storage
= USER_MAXSTORAGE_UNLIMITED
;
835 UserInfo3
->usri3_units_per_week
= UserInfo
->LogonHours
.UnitsPerWeek
;
837 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
839 UserInfo3
->usri3_logon_hours
= (PVOID
)Ptr
;
841 memcpy(UserInfo3
->usri3_logon_hours
,
842 UserInfo
->LogonHours
.LogonHours
,
843 (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
845 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
848 UserInfo3
->usri3_bad_pw_count
= UserInfo
->BadPasswordCount
;
849 UserInfo3
->usri3_num_logons
= UserInfo
->LogonCount
;
851 UserInfo3
->usri3_logon_server
= Ptr
;
852 memcpy(UserInfo3
->usri3_logon_server
,
855 UserInfo3
->usri3_logon_server
[LogonServer
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
856 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LogonServer
.Length
+ sizeof(WCHAR
));
858 UserInfo3
->usri3_country_code
= UserInfo
->CountryCode
;
859 UserInfo3
->usri3_code_page
= UserInfo
->CodePage
;
860 UserInfo3
->usri3_user_id
= RelativeId
;
861 UserInfo3
->usri3_primary_group_id
= UserInfo
->PrimaryGroupId
;
863 UserInfo3
->usri3_profile
= Ptr
;
864 memcpy(UserInfo3
->usri3_profile
,
865 UserInfo
->ProfilePath
.Buffer
,
866 UserInfo
->ProfilePath
.Length
);
867 UserInfo3
->usri3_profile
[UserInfo
->ProfilePath
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
868 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->ProfilePath
.Length
+ sizeof(WCHAR
));
870 UserInfo3
->usri3_home_dir_drive
= Ptr
;
871 memcpy(UserInfo3
->usri3_home_dir_drive
,
872 UserInfo
->HomeDirectoryDrive
.Buffer
,
873 UserInfo
->HomeDirectoryDrive
.Length
);
874 UserInfo3
->usri3_home_dir_drive
[UserInfo
->HomeDirectoryDrive
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
875 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->HomeDirectoryDrive
.Length
+ sizeof(WCHAR
));
877 UserInfo3
->usri3_password_expired
= (UserInfo
->UserAccountControl
& USER_PASSWORD_EXPIRED
);
881 UserInfo4
= (PUSER_INFO_4
)LocalBuffer
;
883 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo4
+ sizeof(USER_INFO_4
));
885 UserInfo4
->usri4_name
= Ptr
;
887 memcpy(UserInfo4
->usri4_name
,
888 UserInfo
->UserName
.Buffer
,
889 UserInfo
->UserName
.Length
);
890 UserInfo4
->usri4_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
892 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
894 UserInfo4
->usri4_password
= NULL
;
895 UserInfo4
->usri4_password_age
= GetPasswordAge(&UserInfo
->PasswordLastSet
);
897 /* FIXME: usri4_priv */
899 UserInfo4
->usri4_home_dir
= Ptr
;
900 memcpy(UserInfo4
->usri4_home_dir
,
901 UserInfo
->HomeDirectory
.Buffer
,
902 UserInfo
->HomeDirectory
.Length
);
903 UserInfo4
->usri4_home_dir
[UserInfo
->HomeDirectory
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
904 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
));
906 UserInfo4
->usri4_comment
= Ptr
;
907 memcpy(UserInfo4
->usri4_comment
,
908 UserInfo
->AdminComment
.Buffer
,
909 UserInfo
->AdminComment
.Length
);
910 UserInfo4
->usri4_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
911 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
913 UserInfo4
->usri4_flags
= GetAccountFlags(UserInfo
->UserAccountControl
,
916 UserInfo4
->usri4_script_path
= Ptr
;
917 memcpy(UserInfo4
->usri4_script_path
,
918 UserInfo
->ScriptPath
.Buffer
,
919 UserInfo
->ScriptPath
.Length
);
920 UserInfo4
->usri4_script_path
[UserInfo
->ScriptPath
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
921 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->ScriptPath
.Length
+ sizeof(WCHAR
));
923 /* FIXME: usri4_auth_flags */
925 UserInfo4
->usri4_full_name
= Ptr
;
926 memcpy(UserInfo4
->usri4_full_name
,
927 UserInfo
->FullName
.Buffer
,
928 UserInfo
->FullName
.Length
);
929 UserInfo4
->usri4_full_name
[UserInfo
->FullName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
930 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->FullName
.Length
+ sizeof(WCHAR
));
932 UserInfo4
->usri4_usr_comment
= Ptr
;
933 memcpy(UserInfo4
->usri4_usr_comment
,
934 UserInfo
->UserComment
.Buffer
,
935 UserInfo
->UserComment
.Length
);
936 UserInfo4
->usri4_usr_comment
[UserInfo
->UserComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
937 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserComment
.Length
+ sizeof(WCHAR
));
939 UserInfo4
->usri4_parms
= Ptr
;
940 memcpy(UserInfo4
->usri4_parms
,
941 UserInfo
->Parameters
.Buffer
,
942 UserInfo
->Parameters
.Length
);
943 UserInfo4
->usri4_parms
[UserInfo
->Parameters
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
944 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->Parameters
.Length
+ sizeof(WCHAR
));
946 UserInfo4
->usri4_workstations
= Ptr
;
947 memcpy(UserInfo4
->usri4_workstations
,
948 UserInfo
->WorkStations
.Buffer
,
949 UserInfo
->WorkStations
.Length
);
950 UserInfo4
->usri4_workstations
[UserInfo
->WorkStations
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
951 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
));
953 if (UserInfo
->LastLogon
.QuadPart
== 0)
954 UserInfo4
->usri4_last_logon
= 0;
956 RtlTimeToSecondsSince1970(&UserInfo
->LastLogon
,
957 &UserInfo4
->usri4_last_logon
);
959 if (UserInfo
->LastLogoff
.QuadPart
== 0)
960 UserInfo4
->usri4_last_logoff
= 0;
962 RtlTimeToSecondsSince1970(&UserInfo
->LastLogoff
,
963 &UserInfo4
->usri4_last_logoff
);
965 if (UserInfo
->AccountExpires
.QuadPart
== MAXLONGLONG
)
966 UserInfo4
->usri4_acct_expires
= TIMEQ_FOREVER
;
968 RtlTimeToSecondsSince1970(&UserInfo
->AccountExpires
,
969 &UserInfo4
->usri4_acct_expires
);
971 UserInfo4
->usri4_max_storage
= USER_MAXSTORAGE_UNLIMITED
;
972 UserInfo4
->usri4_units_per_week
= UserInfo
->LogonHours
.UnitsPerWeek
;
974 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
976 UserInfo4
->usri4_logon_hours
= (PVOID
)Ptr
;
978 memcpy(UserInfo4
->usri4_logon_hours
,
979 UserInfo
->LogonHours
.LogonHours
,
980 (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
982 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
985 UserInfo4
->usri4_bad_pw_count
= UserInfo
->BadPasswordCount
;
986 UserInfo4
->usri4_num_logons
= UserInfo
->LogonCount
;
988 UserInfo4
->usri4_logon_server
= Ptr
;
989 memcpy(UserInfo4
->usri4_logon_server
,
992 UserInfo4
->usri4_logon_server
[LogonServer
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
993 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LogonServer
.Length
+ sizeof(WCHAR
));
995 UserInfo4
->usri4_country_code
= UserInfo
->CountryCode
;
996 UserInfo4
->usri4_code_page
= UserInfo
->CodePage
;
998 UserInfo4
->usri4_user_sid
= (PVOID
)Ptr
;
999 CopySidFromSidAndRid(UserInfo4
->usri4_user_sid
, AccountDomainSid
, RelativeId
);
1000 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RtlLengthSid(AccountDomainSid
) + sizeof(ULONG
));
1002 UserInfo4
->usri4_primary_group_id
= UserInfo
->PrimaryGroupId
;
1004 UserInfo4
->usri4_profile
= Ptr
;
1005 memcpy(UserInfo4
->usri4_profile
,
1006 UserInfo
->ProfilePath
.Buffer
,
1007 UserInfo
->ProfilePath
.Length
);
1008 UserInfo4
->usri4_profile
[UserInfo
->ProfilePath
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1009 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->ProfilePath
.Length
+ sizeof(WCHAR
));
1011 UserInfo4
->usri4_home_dir_drive
= Ptr
;
1012 memcpy(UserInfo4
->usri4_home_dir_drive
,
1013 UserInfo
->HomeDirectoryDrive
.Buffer
,
1014 UserInfo
->HomeDirectoryDrive
.Length
);
1015 UserInfo4
->usri4_home_dir_drive
[UserInfo
->HomeDirectoryDrive
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1016 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->HomeDirectoryDrive
.Length
+ sizeof(WCHAR
));
1018 UserInfo4
->usri4_password_expired
= (UserInfo
->UserAccountControl
& USER_PASSWORD_EXPIRED
);
1022 UserInfo10
= (PUSER_INFO_10
)LocalBuffer
;
1024 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo10
+ sizeof(USER_INFO_10
));
1026 UserInfo10
->usri10_name
= Ptr
;
1028 memcpy(UserInfo10
->usri10_name
,
1029 UserInfo
->UserName
.Buffer
,
1030 UserInfo
->UserName
.Length
);
1031 UserInfo10
->usri10_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1033 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
1035 UserInfo10
->usri10_comment
= Ptr
;
1036 memcpy(UserInfo10
->usri10_comment
,
1037 UserInfo
->AdminComment
.Buffer
,
1038 UserInfo
->AdminComment
.Length
);
1039 UserInfo10
->usri10_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1040 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
1042 UserInfo10
->usri10_usr_comment
= Ptr
;
1043 memcpy(UserInfo10
->usri10_usr_comment
,
1044 UserInfo
->UserComment
.Buffer
,
1045 UserInfo
->UserComment
.Length
);
1046 UserInfo10
->usri10_usr_comment
[UserInfo
->UserComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1047 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserComment
.Length
+ sizeof(WCHAR
));
1049 UserInfo10
->usri10_full_name
= Ptr
;
1050 memcpy(UserInfo10
->usri10_full_name
,
1051 UserInfo
->FullName
.Buffer
,
1052 UserInfo
->FullName
.Length
);
1053 UserInfo10
->usri10_full_name
[UserInfo
->FullName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1057 UserInfo11
= (PUSER_INFO_11
)LocalBuffer
;
1059 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo11
+ sizeof(USER_INFO_11
));
1061 UserInfo11
->usri11_name
= Ptr
;
1063 memcpy(UserInfo11
->usri11_name
,
1064 UserInfo
->UserName
.Buffer
,
1065 UserInfo
->UserName
.Length
);
1066 UserInfo11
->usri11_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1068 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
1070 UserInfo11
->usri11_comment
= Ptr
;
1071 memcpy(UserInfo11
->usri11_comment
,
1072 UserInfo
->AdminComment
.Buffer
,
1073 UserInfo
->AdminComment
.Length
);
1074 UserInfo11
->usri11_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1075 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
1077 UserInfo11
->usri11_usr_comment
= Ptr
;
1078 memcpy(UserInfo11
->usri11_usr_comment
,
1079 UserInfo
->UserComment
.Buffer
,
1080 UserInfo
->UserComment
.Length
);
1081 UserInfo11
->usri11_usr_comment
[UserInfo
->UserComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1082 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserComment
.Length
+ sizeof(WCHAR
));
1084 UserInfo11
->usri11_full_name
= Ptr
;
1085 memcpy(UserInfo11
->usri11_full_name
,
1086 UserInfo
->FullName
.Buffer
,
1087 UserInfo
->FullName
.Length
);
1088 UserInfo11
->usri11_full_name
[UserInfo
->FullName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1089 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->FullName
.Length
+ sizeof(WCHAR
));
1091 /* FIXME: usri11_priv */
1092 /* FIXME: usri11_auth_flags */
1094 UserInfo11
->usri11_password_age
= GetPasswordAge(&UserInfo
->PasswordLastSet
);
1096 UserInfo11
->usri11_home_dir
= Ptr
;
1097 memcpy(UserInfo11
->usri11_home_dir
,
1098 UserInfo
->HomeDirectory
.Buffer
,
1099 UserInfo
->HomeDirectory
.Length
);
1100 UserInfo11
->usri11_home_dir
[UserInfo
->HomeDirectory
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1101 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
));
1103 UserInfo11
->usri11_parms
= Ptr
;
1104 memcpy(UserInfo11
->usri11_parms
,
1105 UserInfo
->Parameters
.Buffer
,
1106 UserInfo
->Parameters
.Length
);
1107 UserInfo11
->usri11_parms
[UserInfo
->Parameters
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1108 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->Parameters
.Length
+ sizeof(WCHAR
));
1110 if (UserInfo
->LastLogon
.QuadPart
== 0)
1111 UserInfo11
->usri11_last_logon
= 0;
1113 RtlTimeToSecondsSince1970(&UserInfo
->LastLogon
,
1114 &UserInfo11
->usri11_last_logon
);
1116 if (UserInfo
->LastLogoff
.QuadPart
== 0)
1117 UserInfo11
->usri11_last_logoff
= 0;
1119 RtlTimeToSecondsSince1970(&UserInfo
->LastLogoff
,
1120 &UserInfo11
->usri11_last_logoff
);
1122 UserInfo11
->usri11_bad_pw_count
= UserInfo
->BadPasswordCount
;
1123 UserInfo11
->usri11_num_logons
= UserInfo
->LogonCount
;
1125 UserInfo11
->usri11_logon_server
= Ptr
;
1126 memcpy(UserInfo11
->usri11_logon_server
,
1128 LogonServer
.Length
);
1129 UserInfo11
->usri11_logon_server
[LogonServer
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1130 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LogonServer
.Length
+ sizeof(WCHAR
));
1132 UserInfo11
->usri11_country_code
= UserInfo
->CountryCode
;
1134 UserInfo11
->usri11_workstations
= Ptr
;
1135 memcpy(UserInfo11
->usri11_workstations
,
1136 UserInfo
->WorkStations
.Buffer
,
1137 UserInfo
->WorkStations
.Length
);
1138 UserInfo11
->usri11_workstations
[UserInfo
->WorkStations
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1139 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
));
1141 UserInfo11
->usri11_max_storage
= USER_MAXSTORAGE_UNLIMITED
;
1142 UserInfo11
->usri11_units_per_week
= UserInfo
->LogonHours
.UnitsPerWeek
;
1144 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
1146 UserInfo11
->usri11_logon_hours
= (PVOID
)Ptr
;
1148 memcpy(UserInfo11
->usri11_logon_hours
,
1149 UserInfo
->LogonHours
.LogonHours
,
1150 (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
1152 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
1155 UserInfo11
->usri11_code_page
= UserInfo
->CodePage
;
1159 UserInfo20
= (PUSER_INFO_20
)LocalBuffer
;
1161 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo20
+ sizeof(USER_INFO_20
));
1163 UserInfo20
->usri20_name
= Ptr
;
1165 memcpy(UserInfo20
->usri20_name
,
1166 UserInfo
->UserName
.Buffer
,
1167 UserInfo
->UserName
.Length
);
1168 UserInfo20
->usri20_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1170 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
1172 UserInfo20
->usri20_full_name
= Ptr
;
1173 memcpy(UserInfo20
->usri20_full_name
,
1174 UserInfo
->FullName
.Buffer
,
1175 UserInfo
->FullName
.Length
);
1176 UserInfo20
->usri20_full_name
[UserInfo
->FullName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1177 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->FullName
.Length
+ sizeof(WCHAR
));
1179 UserInfo20
->usri20_comment
= Ptr
;
1180 memcpy(UserInfo20
->usri20_comment
,
1181 UserInfo
->AdminComment
.Buffer
,
1182 UserInfo
->AdminComment
.Length
);
1183 UserInfo20
->usri20_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1184 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
1186 UserInfo20
->usri20_flags
= GetAccountFlags(UserInfo
->UserAccountControl
,
1189 UserInfo20
->usri20_user_id
= RelativeId
;
1193 UserInfo23
= (PUSER_INFO_23
)LocalBuffer
;
1195 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo23
+ sizeof(USER_INFO_23
));
1197 UserInfo23
->usri23_name
= Ptr
;
1199 memcpy(UserInfo23
->usri23_name
,
1200 UserInfo
->UserName
.Buffer
,
1201 UserInfo
->UserName
.Length
);
1202 UserInfo23
->usri23_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1204 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
1206 UserInfo23
->usri23_full_name
= Ptr
;
1207 memcpy(UserInfo23
->usri23_full_name
,
1208 UserInfo
->FullName
.Buffer
,
1209 UserInfo
->FullName
.Length
);
1210 UserInfo23
->usri23_full_name
[UserInfo
->FullName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1211 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->FullName
.Length
+ sizeof(WCHAR
));
1213 UserInfo23
->usri23_comment
= Ptr
;
1214 memcpy(UserInfo23
->usri23_comment
,
1215 UserInfo
->AdminComment
.Buffer
,
1216 UserInfo
->AdminComment
.Length
);
1217 UserInfo23
->usri23_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1218 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
1220 UserInfo23
->usri23_flags
= GetAccountFlags(UserInfo
->UserAccountControl
,
1223 UserInfo23
->usri23_user_sid
= (PVOID
)Ptr
;
1224 CopySidFromSidAndRid(UserInfo23
->usri23_user_sid
, AccountDomainSid
, RelativeId
);
1225 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RtlLengthSid(AccountDomainSid
) + sizeof(ULONG
));
1230 if (UserInfo
!= NULL
)
1231 FreeUserInfo(UserInfo
);
1234 HeapFree(GetProcessHeap(), 0, Dacl
);
1236 if (ApiStatus
== NERR_Success
)
1238 *Buffer
= LocalBuffer
;
1242 if (LocalBuffer
!= NULL
)
1243 NetApiBufferFree(LocalBuffer
);
1252 SetUserInfo(SAM_HANDLE UserHandle
,
1257 USER_ALL_INFORMATION UserAllInfo
;
1258 PUSER_INFO_0 UserInfo0
;
1259 PUSER_INFO_1 UserInfo1
;
1260 PUSER_INFO_2 UserInfo2
;
1261 PUSER_INFO_3 UserInfo3
;
1262 PUSER_INFO_4 UserInfo4
;
1263 PUSER_INFO_22 UserInfo22
;
1264 PUSER_INFO_1003 UserInfo1003
;
1265 PUSER_INFO_1006 UserInfo1006
;
1266 PUSER_INFO_1007 UserInfo1007
;
1267 PUSER_INFO_1008 UserInfo1008
;
1268 PUSER_INFO_1009 UserInfo1009
;
1269 PUSER_INFO_1011 UserInfo1011
;
1270 PUSER_INFO_1012 UserInfo1012
;
1271 PUSER_INFO_1013 UserInfo1013
;
1272 PUSER_INFO_1014 UserInfo1014
;
1273 PUSER_INFO_1017 UserInfo1017
;
1274 PUSER_INFO_1018 UserInfo1018
;
1275 PUSER_INFO_1020 UserInfo1020
;
1276 PUSER_INFO_1024 UserInfo1024
;
1277 PUSER_INFO_1025 UserInfo1025
;
1278 PUSER_INFO_1051 UserInfo1051
;
1279 PUSER_INFO_1052 UserInfo1052
;
1280 PUSER_INFO_1053 UserInfo1053
;
1282 NET_API_STATUS ApiStatus
= NERR_Success
;
1283 NTSTATUS Status
= STATUS_SUCCESS
;
1285 ZeroMemory(&UserAllInfo
, sizeof(USER_ALL_INFORMATION
));
1287 if ((Level
== 1) || (Level
== 2) || (Level
== 3) ||
1288 (Level
== 4) || (Level
== 22) || (Level
== 1008))
1290 ApiStatus
= GetUserDacl(UserHandle
, &Dacl
);
1291 if (ApiStatus
!= NERR_Success
)
1298 UserInfo0
= (PUSER_INFO_0
)UserInfo
;
1300 RtlInitUnicodeString(&UserAllInfo
.UserName
,
1301 UserInfo0
->usri0_name
);
1303 UserAllInfo
.WhichFields
|= USER_ALL_USERNAME
;
1307 UserInfo1
= (PUSER_INFO_1
)UserInfo
;
1309 // usri1_name ignored
1311 if (UserInfo1
->usri1_password
!= NULL
)
1313 RtlInitUnicodeString(&UserAllInfo
.NtPassword
,
1314 UserInfo1
->usri1_password
);
1315 UserAllInfo
.NtPasswordPresent
= TRUE
;
1316 UserAllInfo
.WhichFields
|= USER_ALL_NTPASSWORDPRESENT
;
1319 // usri1_password_age ignored
1321 // UserInfo1->usri1_priv
1323 if (UserInfo1
->usri1_home_dir
!= NULL
)
1325 RtlInitUnicodeString(&UserAllInfo
.HomeDirectory
,
1326 UserInfo1
->usri1_home_dir
);
1327 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORY
;
1330 if (UserInfo1
->usri1_comment
!= NULL
)
1332 RtlInitUnicodeString(&UserAllInfo
.AdminComment
,
1333 UserInfo1
->usri1_comment
);
1334 UserAllInfo
.WhichFields
|= USER_ALL_ADMINCOMMENT
;
1337 ChangeUserDacl(Dacl
, UserInfo1
->usri1_flags
);
1338 UserAllInfo
.UserAccountControl
= GetAccountControl(UserInfo1
->usri1_flags
);
1339 UserAllInfo
.WhichFields
|= USER_ALL_USERACCOUNTCONTROL
;
1341 if (UserInfo1
->usri1_script_path
!= NULL
)
1343 RtlInitUnicodeString(&UserAllInfo
.ScriptPath
,
1344 UserInfo1
->usri1_script_path
);
1345 UserAllInfo
.WhichFields
|= USER_ALL_SCRIPTPATH
;
1350 UserInfo2
= (PUSER_INFO_2
)UserInfo
;
1352 // usri2_name ignored
1354 if (UserInfo2
->usri2_password
!= NULL
)
1356 RtlInitUnicodeString(&UserAllInfo
.NtPassword
,
1357 UserInfo2
->usri2_password
);
1358 UserAllInfo
.NtPasswordPresent
= TRUE
;
1359 UserAllInfo
.WhichFields
|= USER_ALL_NTPASSWORDPRESENT
;
1362 // usri2_password_age ignored
1364 // UserInfo2->usri2_priv;
1366 if (UserInfo2
->usri2_home_dir
!= NULL
)
1368 RtlInitUnicodeString(&UserAllInfo
.HomeDirectory
,
1369 UserInfo2
->usri2_home_dir
);
1370 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORY
;
1373 if (UserInfo2
->usri2_comment
!= NULL
)
1375 RtlInitUnicodeString(&UserAllInfo
.AdminComment
,
1376 UserInfo2
->usri2_comment
);
1377 UserAllInfo
.WhichFields
|= USER_ALL_ADMINCOMMENT
;
1380 ChangeUserDacl(Dacl
, UserInfo2
->usri2_flags
);
1381 UserAllInfo
.UserAccountControl
= GetAccountControl(UserInfo2
->usri2_flags
);
1382 UserAllInfo
.WhichFields
|= USER_ALL_USERACCOUNTCONTROL
;
1384 if (UserInfo2
->usri2_script_path
!= NULL
)
1386 RtlInitUnicodeString(&UserAllInfo
.ScriptPath
,
1387 UserInfo2
->usri2_script_path
);
1388 UserAllInfo
.WhichFields
|= USER_ALL_SCRIPTPATH
;
1391 // UserInfo2->usri2_auth_flags;
1393 if (UserInfo2
->usri2_full_name
!= NULL
)
1395 RtlInitUnicodeString(&UserAllInfo
.FullName
,
1396 UserInfo2
->usri2_full_name
);
1397 UserAllInfo
.WhichFields
|= USER_ALL_FULLNAME
;
1400 if (UserInfo2
->usri2_usr_comment
!= NULL
)
1402 RtlInitUnicodeString(&UserAllInfo
.UserComment
,
1403 UserInfo2
->usri2_usr_comment
);
1404 UserAllInfo
.WhichFields
|= USER_ALL_USERCOMMENT
;
1407 if (UserInfo2
->usri2_parms
!= NULL
)
1409 RtlInitUnicodeString(&UserAllInfo
.Parameters
,
1410 UserInfo2
->usri2_parms
);
1411 UserAllInfo
.WhichFields
|= USER_ALL_PARAMETERS
;
1414 if (UserInfo2
->usri2_workstations
!= NULL
)
1416 RtlInitUnicodeString(&UserAllInfo
.WorkStations
,
1417 UserInfo2
->usri2_workstations
);
1418 UserAllInfo
.WhichFields
|= USER_ALL_WORKSTATIONS
;
1421 // usri2_last_logon ignored
1422 // usri2_last_logoff ignored
1424 if (UserInfo2
->usri2_acct_expires
== TIMEQ_FOREVER
)
1426 UserAllInfo
.AccountExpires
.QuadPart
= MAXLONGLONG
;
1430 RtlSecondsSince1970ToTime(UserInfo2
->usri2_acct_expires
,
1431 &UserAllInfo
.AccountExpires
);
1433 UserAllInfo
.WhichFields
|= USER_ALL_ACCOUNTEXPIRES
;
1435 if (UserInfo2
->usri2_max_storage
!= USER_MAXSTORAGE_UNLIMITED
)
1437 if (parm_err
!= NULL
)
1438 *parm_err
= USER_MAX_STORAGE_PARMNUM
;
1439 ApiStatus
= ERROR_INVALID_PARAMETER
;
1443 if (UserInfo2
->usri2_units_per_week
> USHRT_MAX
)
1445 if (parm_err
!= NULL
)
1446 *parm_err
= USER_UNITS_PER_WEEK_PARMNUM
;
1447 ApiStatus
= ERROR_INVALID_PARAMETER
;
1451 UserAllInfo
.LogonHours
.UnitsPerWeek
= UserInfo2
->usri2_units_per_week
;
1452 UserAllInfo
.LogonHours
.LogonHours
= UserInfo2
->usri2_logon_hours
;
1453 UserAllInfo
.WhichFields
|= USER_ALL_LOGONHOURS
;
1455 // usri2_bad_pw_count ignored
1456 // usri2_num_logons ignored
1457 // usri2_logon_server ignored
1459 UserAllInfo
.CountryCode
= UserInfo2
->usri2_country_code
;
1460 UserAllInfo
.WhichFields
|= USER_ALL_COUNTRYCODE
;
1462 UserAllInfo
.CodePage
= UserInfo2
->usri2_code_page
;
1463 UserAllInfo
.WhichFields
|= USER_ALL_CODEPAGE
;
1467 UserInfo3
= (PUSER_INFO_3
)UserInfo
;
1469 // usri3_name ignored
1471 if (UserInfo3
->usri3_password
!= NULL
)
1473 RtlInitUnicodeString(&UserAllInfo
.NtPassword
,
1474 UserInfo3
->usri3_password
);
1475 UserAllInfo
.NtPasswordPresent
= TRUE
;
1476 UserAllInfo
.WhichFields
|= USER_ALL_NTPASSWORDPRESENT
;
1479 // usri3_password_age ignored
1481 // UserInfo3->usri3_priv;
1483 if (UserInfo3
->usri3_home_dir
!= NULL
)
1485 RtlInitUnicodeString(&UserAllInfo
.HomeDirectory
,
1486 UserInfo3
->usri3_home_dir
);
1487 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORY
;
1490 if (UserInfo3
->usri3_comment
!= NULL
)
1492 RtlInitUnicodeString(&UserAllInfo
.AdminComment
,
1493 UserInfo3
->usri3_comment
);
1494 UserAllInfo
.WhichFields
|= USER_ALL_ADMINCOMMENT
;
1497 ChangeUserDacl(Dacl
, UserInfo3
->usri3_flags
);
1498 UserAllInfo
.UserAccountControl
= GetAccountControl(UserInfo3
->usri3_flags
);
1499 UserAllInfo
.WhichFields
|= USER_ALL_USERACCOUNTCONTROL
;
1501 if (UserInfo3
->usri3_script_path
!= NULL
)
1503 RtlInitUnicodeString(&UserAllInfo
.ScriptPath
,
1504 UserInfo3
->usri3_script_path
);
1505 UserAllInfo
.WhichFields
|= USER_ALL_SCRIPTPATH
;
1508 // UserInfo3->usri3_auth_flags;
1510 if (UserInfo3
->usri3_full_name
!= NULL
)
1512 RtlInitUnicodeString(&UserAllInfo
.FullName
,
1513 UserInfo3
->usri3_full_name
);
1514 UserAllInfo
.WhichFields
|= USER_ALL_FULLNAME
;
1517 if (UserInfo3
->usri3_usr_comment
!= NULL
)
1519 RtlInitUnicodeString(&UserAllInfo
.UserComment
,
1520 UserInfo3
->usri3_usr_comment
);
1521 UserAllInfo
.WhichFields
|= USER_ALL_USERCOMMENT
;
1524 if (UserInfo3
->usri3_parms
!= NULL
)
1526 RtlInitUnicodeString(&UserAllInfo
.Parameters
,
1527 UserInfo3
->usri3_parms
);
1528 UserAllInfo
.WhichFields
|= USER_ALL_PARAMETERS
;
1531 if (UserInfo3
->usri3_workstations
!= NULL
)
1533 RtlInitUnicodeString(&UserAllInfo
.WorkStations
,
1534 UserInfo3
->usri3_workstations
);
1535 UserAllInfo
.WhichFields
|= USER_ALL_WORKSTATIONS
;
1538 // usri3_last_logon ignored
1539 // usri3_last_logoff ignored
1541 if (UserInfo3
->usri3_acct_expires
== TIMEQ_FOREVER
)
1543 UserAllInfo
.AccountExpires
.QuadPart
= MAXLONGLONG
;
1547 RtlSecondsSince1970ToTime(UserInfo3
->usri3_acct_expires
,
1548 &UserAllInfo
.AccountExpires
);
1550 UserAllInfo
.WhichFields
|= USER_ALL_ACCOUNTEXPIRES
;
1552 if (UserInfo3
->usri3_max_storage
!= USER_MAXSTORAGE_UNLIMITED
)
1554 if (parm_err
!= NULL
)
1555 *parm_err
= USER_MAX_STORAGE_PARMNUM
;
1556 ApiStatus
= ERROR_INVALID_PARAMETER
;
1560 if (UserInfo3
->usri3_units_per_week
> USHRT_MAX
)
1562 if (parm_err
!= NULL
)
1563 *parm_err
= USER_UNITS_PER_WEEK_PARMNUM
;
1564 ApiStatus
= ERROR_INVALID_PARAMETER
;
1568 UserAllInfo
.LogonHours
.UnitsPerWeek
= UserInfo3
->usri3_units_per_week
;
1569 UserAllInfo
.LogonHours
.LogonHours
= UserInfo3
->usri3_logon_hours
;
1570 UserAllInfo
.WhichFields
|= USER_ALL_LOGONHOURS
;
1572 // usri3_bad_pw_count ignored
1573 // usri3_num_logons ignored
1574 // usri3_logon_server ignored
1576 UserAllInfo
.CountryCode
= UserInfo3
->usri3_country_code
;
1577 UserAllInfo
.WhichFields
|= USER_ALL_COUNTRYCODE
;
1579 UserAllInfo
.CodePage
= UserInfo3
->usri3_code_page
;
1580 UserAllInfo
.WhichFields
|= USER_ALL_CODEPAGE
;
1582 // usri3_user_id ignored
1584 UserAllInfo
.PrimaryGroupId
= UserInfo3
->usri3_primary_group_id
;
1585 UserAllInfo
.WhichFields
|= USER_ALL_PRIMARYGROUPID
;
1587 if (UserInfo3
->usri3_profile
!= NULL
)
1589 RtlInitUnicodeString(&UserAllInfo
.ProfilePath
,
1590 UserInfo3
->usri3_profile
);
1591 UserAllInfo
.WhichFields
|= USER_ALL_PROFILEPATH
;
1594 if (UserInfo3
->usri3_home_dir_drive
!= NULL
)
1596 RtlInitUnicodeString(&UserAllInfo
.HomeDirectoryDrive
,
1597 UserInfo3
->usri3_home_dir_drive
);
1598 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORYDRIVE
;
1601 UserAllInfo
.PasswordExpired
= (UserInfo3
->usri3_password_expired
!= 0);
1602 UserAllInfo
.WhichFields
|= USER_ALL_PASSWORDEXPIRED
;
1606 UserInfo4
= (PUSER_INFO_4
)UserInfo
;
1608 // usri4_name ignored
1610 if (UserInfo4
->usri4_password
!= NULL
)
1612 RtlInitUnicodeString(&UserAllInfo
.NtPassword
,
1613 UserInfo4
->usri4_password
);
1614 UserAllInfo
.NtPasswordPresent
= TRUE
;
1615 UserAllInfo
.WhichFields
|= USER_ALL_NTPASSWORDPRESENT
;
1618 // usri4_password_age ignored
1620 // UserInfo3->usri4_priv;
1622 if (UserInfo4
->usri4_home_dir
!= NULL
)
1624 RtlInitUnicodeString(&UserAllInfo
.HomeDirectory
,
1625 UserInfo4
->usri4_home_dir
);
1626 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORY
;
1629 if (UserInfo4
->usri4_comment
!= NULL
)
1631 RtlInitUnicodeString(&UserAllInfo
.AdminComment
,
1632 UserInfo4
->usri4_comment
);
1633 UserAllInfo
.WhichFields
|= USER_ALL_ADMINCOMMENT
;
1636 ChangeUserDacl(Dacl
, UserInfo4
->usri4_flags
);
1637 UserAllInfo
.UserAccountControl
= GetAccountControl(UserInfo4
->usri4_flags
);
1638 UserAllInfo
.WhichFields
|= USER_ALL_USERACCOUNTCONTROL
;
1640 if (UserInfo4
->usri4_script_path
!= NULL
)
1642 RtlInitUnicodeString(&UserAllInfo
.ScriptPath
,
1643 UserInfo4
->usri4_script_path
);
1644 UserAllInfo
.WhichFields
|= USER_ALL_SCRIPTPATH
;
1647 // UserInfo4->usri4_auth_flags;
1649 if (UserInfo4
->usri4_full_name
!= NULL
)
1651 RtlInitUnicodeString(&UserAllInfo
.FullName
,
1652 UserInfo4
->usri4_full_name
);
1653 UserAllInfo
.WhichFields
|= USER_ALL_FULLNAME
;
1656 if (UserInfo4
->usri4_usr_comment
!= NULL
)
1658 RtlInitUnicodeString(&UserAllInfo
.UserComment
,
1659 UserInfo4
->usri4_usr_comment
);
1660 UserAllInfo
.WhichFields
|= USER_ALL_USERCOMMENT
;
1663 if (UserInfo4
->usri4_parms
!= NULL
)
1665 RtlInitUnicodeString(&UserAllInfo
.Parameters
,
1666 UserInfo4
->usri4_parms
);
1667 UserAllInfo
.WhichFields
|= USER_ALL_PARAMETERS
;
1670 if (UserInfo4
->usri4_workstations
!= NULL
)
1672 RtlInitUnicodeString(&UserAllInfo
.WorkStations
,
1673 UserInfo4
->usri4_workstations
);
1674 UserAllInfo
.WhichFields
|= USER_ALL_WORKSTATIONS
;
1677 // usri4_last_logon ignored
1678 // usri4_last_logoff ignored
1680 if (UserInfo4
->usri4_acct_expires
== TIMEQ_FOREVER
)
1682 UserAllInfo
.AccountExpires
.QuadPart
= MAXLONGLONG
;
1686 RtlSecondsSince1970ToTime(UserInfo4
->usri4_acct_expires
,
1687 &UserAllInfo
.AccountExpires
);
1689 UserAllInfo
.WhichFields
|= USER_ALL_ACCOUNTEXPIRES
;
1691 if (UserInfo4
->usri4_max_storage
!= USER_MAXSTORAGE_UNLIMITED
)
1693 if (parm_err
!= NULL
)
1694 *parm_err
= USER_MAX_STORAGE_PARMNUM
;
1695 ApiStatus
= ERROR_INVALID_PARAMETER
;
1699 if (UserInfo4
->usri4_units_per_week
> USHRT_MAX
)
1701 if (parm_err
!= NULL
)
1702 *parm_err
= USER_UNITS_PER_WEEK_PARMNUM
;
1703 ApiStatus
= ERROR_INVALID_PARAMETER
;
1707 UserAllInfo
.LogonHours
.UnitsPerWeek
= UserInfo4
->usri4_units_per_week
;
1708 UserAllInfo
.LogonHours
.LogonHours
= UserInfo4
->usri4_logon_hours
;
1709 UserAllInfo
.WhichFields
|= USER_ALL_LOGONHOURS
;
1711 // usri4_bad_pw_count ignored
1712 // usri4_num_logons ignored
1713 // usri4_logon_server ignored
1715 UserAllInfo
.CountryCode
= UserInfo4
->usri4_country_code
;
1716 UserAllInfo
.WhichFields
|= USER_ALL_COUNTRYCODE
;
1718 UserAllInfo
.CodePage
= UserInfo4
->usri4_code_page
;
1719 UserAllInfo
.WhichFields
|= USER_ALL_CODEPAGE
;
1721 // usri4_user_sid ignored
1723 UserAllInfo
.PrimaryGroupId
= UserInfo4
->usri4_primary_group_id
;
1724 UserAllInfo
.WhichFields
|= USER_ALL_PRIMARYGROUPID
;
1726 if (UserInfo4
->usri4_profile
!= NULL
)
1728 RtlInitUnicodeString(&UserAllInfo
.ProfilePath
,
1729 UserInfo4
->usri4_profile
);
1730 UserAllInfo
.WhichFields
|= USER_ALL_PROFILEPATH
;
1733 if (UserInfo4
->usri4_home_dir_drive
!= NULL
)
1735 RtlInitUnicodeString(&UserAllInfo
.HomeDirectoryDrive
,
1736 UserInfo4
->usri4_home_dir_drive
);
1737 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORYDRIVE
;
1740 UserAllInfo
.PasswordExpired
= (UserInfo4
->usri4_password_expired
!= 0);
1741 UserAllInfo
.WhichFields
|= USER_ALL_PASSWORDEXPIRED
;
1748 UserInfo22
= (PUSER_INFO_22
)UserInfo
;
1750 // usri22_name ignored
1752 // UserInfo22->usri22_password[ENCRYPTED_PWLEN];
1754 // usri22_password_age ignored
1756 // UserInfo3->usri3_priv;
1758 if (UserInfo22
->usri22_home_dir
!= NULL
)
1760 RtlInitUnicodeString(&UserAllInfo
.HomeDirectory
,
1761 UserInfo22
->usri22_home_dir
);
1762 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORY
;
1765 if (UserInfo22
->usri22_comment
!= NULL
)
1767 RtlInitUnicodeString(&UserAllInfo
.AdminComment
,
1768 UserInfo22
->usri22_comment
);
1769 UserAllInfo
.WhichFields
|= USER_ALL_ADMINCOMMENT
;
1772 ChangeUserDacl(Dacl
, UserInfo22
->usri22_flags
);
1773 UserAllInfo
.UserAccountControl
= GetAccountControl(UserInfo22
->usri22_flags
);
1774 UserAllInfo
.WhichFields
|= USER_ALL_USERACCOUNTCONTROL
;
1776 if (UserInfo22
->usri22_script_path
!= NULL
)
1778 RtlInitUnicodeString(&UserAllInfo
.ScriptPath
,
1779 UserInfo22
->usri22_script_path
);
1780 UserAllInfo
.WhichFields
|= USER_ALL_SCRIPTPATH
;
1783 // UserInfo22->usri22_auth_flags;
1785 if (UserInfo22
->usri22_full_name
!= NULL
)
1787 RtlInitUnicodeString(&UserAllInfo
.FullName
,
1788 UserInfo22
->usri22_full_name
);
1789 UserAllInfo
.WhichFields
|= USER_ALL_FULLNAME
;
1792 if (UserInfo22
->usri22_usr_comment
!= NULL
)
1794 RtlInitUnicodeString(&UserAllInfo
.UserComment
,
1795 UserInfo22
->usri22_usr_comment
);
1796 UserAllInfo
.WhichFields
|= USER_ALL_USERCOMMENT
;
1799 if (UserInfo22
->usri22_parms
!= NULL
)
1801 RtlInitUnicodeString(&UserAllInfo
.Parameters
,
1802 UserInfo22
->usri22_parms
);
1803 UserAllInfo
.WhichFields
|= USER_ALL_PARAMETERS
;
1806 if (UserInfo22
->usri22_workstations
!= NULL
)
1808 RtlInitUnicodeString(&UserAllInfo
.WorkStations
,
1809 UserInfo22
->usri22_workstations
);
1810 UserAllInfo
.WhichFields
|= USER_ALL_WORKSTATIONS
;
1813 // usri22_last_logon ignored
1814 // usri22_last_logoff ignored
1816 if (UserInfo22
->usri22_acct_expires
== TIMEQ_FOREVER
)
1818 UserAllInfo
.AccountExpires
.QuadPart
= MAXLONGLONG
;
1822 RtlSecondsSince1970ToTime(UserInfo22
->usri22_acct_expires
,
1823 &UserAllInfo
.AccountExpires
);
1825 UserAllInfo
.WhichFields
|= USER_ALL_ACCOUNTEXPIRES
;
1827 if (UserInfo22
->usri22_max_storage
!= USER_MAXSTORAGE_UNLIMITED
)
1829 if (parm_err
!= NULL
)
1830 *parm_err
= USER_MAX_STORAGE_PARMNUM
;
1831 ApiStatus
= ERROR_INVALID_PARAMETER
;
1835 if (UserInfo22
->usri22_units_per_week
> USHRT_MAX
)
1837 if (parm_err
!= NULL
)
1838 *parm_err
= USER_UNITS_PER_WEEK_PARMNUM
;
1839 ApiStatus
= ERROR_INVALID_PARAMETER
;
1843 UserAllInfo
.LogonHours
.UnitsPerWeek
= UserInfo22
->usri22_units_per_week
;
1844 UserAllInfo
.LogonHours
.LogonHours
= UserInfo22
->usri22_logon_hours
;
1845 UserAllInfo
.WhichFields
|= USER_ALL_LOGONHOURS
;
1847 // usri22_bad_pw_count ignored
1848 // usri22_num_logons ignored
1849 // usri22_logon_server ignored
1851 UserAllInfo
.CountryCode
= UserInfo22
->usri22_country_code
;
1852 UserAllInfo
.WhichFields
|= USER_ALL_COUNTRYCODE
;
1854 UserAllInfo
.CodePage
= UserInfo22
->usri22_code_page
;
1855 UserAllInfo
.WhichFields
|= USER_ALL_CODEPAGE
;
1859 UserInfo1003
= (PUSER_INFO_1003
)UserInfo
;
1861 if (UserInfo1003
->usri1003_password
!= NULL
)
1863 RtlInitUnicodeString(&UserAllInfo
.NtPassword
,
1864 UserInfo1003
->usri1003_password
);
1865 UserAllInfo
.NtPasswordPresent
= TRUE
;
1866 UserAllInfo
.WhichFields
|= USER_ALL_NTPASSWORDPRESENT
;
1874 UserInfo1006
= (PUSER_INFO_1006
)UserInfo
;
1876 if (UserInfo1006
->usri1006_home_dir
!= NULL
)
1878 RtlInitUnicodeString(&UserAllInfo
.HomeDirectory
,
1879 UserInfo1006
->usri1006_home_dir
);
1880 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORY
;
1885 UserInfo1007
= (PUSER_INFO_1007
)UserInfo
;
1887 if (UserInfo1007
->usri1007_comment
!= NULL
)
1889 RtlInitUnicodeString(&UserAllInfo
.AdminComment
,
1890 UserInfo1007
->usri1007_comment
);
1891 UserAllInfo
.WhichFields
|= USER_ALL_ADMINCOMMENT
;
1896 UserInfo1008
= (PUSER_INFO_1008
)UserInfo
;
1897 ChangeUserDacl(Dacl
, UserInfo1008
->usri1008_flags
);
1898 UserAllInfo
.UserAccountControl
= GetAccountControl(UserInfo1008
->usri1008_flags
);
1899 UserAllInfo
.WhichFields
|= USER_ALL_USERACCOUNTCONTROL
;
1903 UserInfo1009
= (PUSER_INFO_1009
)UserInfo
;
1905 if (UserInfo1009
->usri1009_script_path
!= NULL
)
1907 RtlInitUnicodeString(&UserAllInfo
.ScriptPath
,
1908 UserInfo1009
->usri1009_script_path
);
1909 UserAllInfo
.WhichFields
|= USER_ALL_SCRIPTPATH
;
1917 UserInfo1011
= (PUSER_INFO_1011
)UserInfo
;
1919 if (UserInfo1011
->usri1011_full_name
!= NULL
)
1921 RtlInitUnicodeString(&UserAllInfo
.FullName
,
1922 UserInfo1011
->usri1011_full_name
);
1923 UserAllInfo
.WhichFields
|= USER_ALL_FULLNAME
;
1928 UserInfo1012
= (PUSER_INFO_1012
)UserInfo
;
1930 if (UserInfo1012
->usri1012_usr_comment
!= NULL
)
1932 RtlInitUnicodeString(&UserAllInfo
.UserComment
,
1933 UserInfo1012
->usri1012_usr_comment
);
1934 UserAllInfo
.WhichFields
|= USER_ALL_USERCOMMENT
;
1939 UserInfo1013
= (PUSER_INFO_1013
)UserInfo
;
1941 if (UserInfo1013
->usri1013_parms
!= NULL
)
1943 RtlInitUnicodeString(&UserAllInfo
.Parameters
,
1944 UserInfo1013
->usri1013_parms
);
1945 UserAllInfo
.WhichFields
|= USER_ALL_PARAMETERS
;
1950 UserInfo1014
= (PUSER_INFO_1014
)UserInfo
;
1952 if (UserInfo1014
->usri1014_workstations
!= NULL
)
1954 RtlInitUnicodeString(&UserAllInfo
.WorkStations
,
1955 UserInfo1014
->usri1014_workstations
);
1956 UserAllInfo
.WhichFields
|= USER_ALL_WORKSTATIONS
;
1961 UserInfo1017
= (PUSER_INFO_1017
)UserInfo
;
1963 if (UserInfo1017
->usri1017_acct_expires
== TIMEQ_FOREVER
)
1965 UserAllInfo
.AccountExpires
.QuadPart
= MAXLONGLONG
;
1969 RtlSecondsSince1970ToTime(UserInfo1017
->usri1017_acct_expires
,
1970 &UserAllInfo
.AccountExpires
);
1972 UserAllInfo
.WhichFields
|= USER_ALL_ACCOUNTEXPIRES
;
1976 UserInfo1018
= (PUSER_INFO_1018
)UserInfo
;
1978 if (UserInfo1018
->usri1018_max_storage
!= USER_MAXSTORAGE_UNLIMITED
)
1980 if (parm_err
!= NULL
)
1981 *parm_err
= USER_MAX_STORAGE_PARMNUM
;
1982 ApiStatus
= ERROR_INVALID_PARAMETER
;
1987 UserInfo1020
= (PUSER_INFO_1020
)UserInfo
;
1989 if (UserInfo1020
->usri1020_units_per_week
> USHRT_MAX
)
1991 if (parm_err
!= NULL
)
1992 *parm_err
= USER_UNITS_PER_WEEK_PARMNUM
;
1993 ApiStatus
= ERROR_INVALID_PARAMETER
;
1997 UserAllInfo
.LogonHours
.UnitsPerWeek
= UserInfo1020
->usri1020_units_per_week
;
1998 UserAllInfo
.LogonHours
.LogonHours
= UserInfo1020
->usri1020_logon_hours
;
1999 UserAllInfo
.WhichFields
|= USER_ALL_LOGONHOURS
;
2003 UserInfo1024
= (PUSER_INFO_1024
)UserInfo
;
2005 UserAllInfo
.CountryCode
= UserInfo1024
->usri1024_country_code
;
2006 UserAllInfo
.WhichFields
|= USER_ALL_COUNTRYCODE
;
2010 UserInfo1025
= (PUSER_INFO_1025
)UserInfo
;
2012 UserAllInfo
.CodePage
= UserInfo1025
->usri1025_code_page
;
2013 UserAllInfo
.WhichFields
|= USER_ALL_CODEPAGE
;
2017 UserInfo1051
= (PUSER_INFO_1051
)UserInfo
;
2019 UserAllInfo
.PrimaryGroupId
= UserInfo1051
->usri1051_primary_group_id
;
2020 UserAllInfo
.WhichFields
|= USER_ALL_PRIMARYGROUPID
;
2024 UserInfo1052
= (PUSER_INFO_1052
)UserInfo
;
2026 if (UserInfo1052
->usri1052_profile
!= NULL
)
2028 RtlInitUnicodeString(&UserAllInfo
.ProfilePath
,
2029 UserInfo1052
->usri1052_profile
);
2030 UserAllInfo
.WhichFields
|= USER_ALL_PROFILEPATH
;
2035 UserInfo1053
= (PUSER_INFO_1053
)UserInfo
;
2037 if (UserInfo1053
->usri1053_home_dir_drive
!= NULL
)
2039 RtlInitUnicodeString(&UserAllInfo
.HomeDirectoryDrive
,
2040 UserInfo1053
->usri1053_home_dir_drive
);
2041 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORYDRIVE
;
2046 if (ApiStatus
!= NERR_Success
)
2049 Status
= SamSetInformationUser(UserHandle
,
2052 if (!NT_SUCCESS(Status
))
2054 ERR("SamSetInformationUser failed (Status %08lx)\n", Status
);
2055 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2061 HeapFree(GetProcessHeap(), 0, Dacl
);
2069 OpenUserByName(SAM_HANDLE DomainHandle
,
2070 PUNICODE_STRING UserName
,
2071 ULONG DesiredAccess
,
2072 PSAM_HANDLE UserHandle
)
2074 PULONG RelativeIds
= NULL
;
2075 PSID_NAME_USE Use
= NULL
;
2076 NET_API_STATUS ApiStatus
= NERR_Success
;
2077 NTSTATUS Status
= STATUS_SUCCESS
;
2079 /* Get the RID for the given user name */
2080 Status
= SamLookupNamesInDomain(DomainHandle
,
2085 if (!NT_SUCCESS(Status
))
2087 ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status
);
2088 return NetpNtStatusToApiStatus(Status
);
2091 /* Fail, if it is not an alias account */
2092 if (Use
[0] != SidTypeUser
)
2094 ERR("Object is not a user!\n");
2095 ApiStatus
= NERR_GroupNotFound
;
2099 /* Open the alias account */
2100 Status
= SamOpenUser(DomainHandle
,
2104 if (!NT_SUCCESS(Status
))
2106 ERR("SamOpenUser failed (Status %08lx)\n", Status
);
2107 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2112 if (RelativeIds
!= NULL
)
2113 SamFreeMemory(RelativeIds
);
2122 /************************************************************
2123 * NetUserAdd (NETAPI32.@)
2127 NetUserAdd(LPCWSTR servername
,
2132 UNICODE_STRING ServerName
;
2133 UNICODE_STRING UserName
;
2134 SAM_HANDLE ServerHandle
= NULL
;
2135 SAM_HANDLE DomainHandle
= NULL
;
2136 SAM_HANDLE UserHandle
= NULL
;
2137 ULONG GrantedAccess
;
2139 NET_API_STATUS ApiStatus
= NERR_Success
;
2140 NTSTATUS Status
= STATUS_SUCCESS
;
2142 TRACE("(%s, %d, %p, %p)\n", debugstr_w(servername
), level
, bufptr
, parm_err
);
2144 if (parm_err
!= NULL
)
2145 *parm_err
= PARM_ERROR_NONE
;
2147 /* Check the info level */
2157 return ERROR_INVALID_LEVEL
;
2160 if (servername
!= NULL
)
2161 RtlInitUnicodeString(&ServerName
, servername
);
2163 /* Connect to the SAM Server */
2164 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
2166 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
2168 if (!NT_SUCCESS(Status
))
2170 ERR("SamConnect failed (Status %08lx)\n", Status
);
2171 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2175 /* Open the Account Domain */
2176 Status
= OpenAccountDomain(ServerHandle
,
2177 (servername
!= NULL
) ? &ServerName
: NULL
,
2178 DOMAIN_CREATE_USER
| DOMAIN_LOOKUP
| DOMAIN_READ_PASSWORD_PARAMETERS
,
2180 if (!NT_SUCCESS(Status
))
2182 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
2183 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2187 /* Initialize the user name string */
2188 RtlInitUnicodeString(&UserName
,
2189 ((PUSER_INFO_1
)bufptr
)->usri1_name
);
2191 /* Create the user account */
2192 Status
= SamCreateUser2InDomain(DomainHandle
,
2194 USER_NORMAL_ACCOUNT
,
2195 USER_ALL_ACCESS
| DELETE
| WRITE_DAC
,
2199 if (!NT_SUCCESS(Status
))
2201 ERR("SamCreateUser2InDomain failed (Status %08lx)\n", Status
);
2202 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2206 /* Set user information */
2207 ApiStatus
= SetUserInfo(UserHandle
,
2211 if (ApiStatus
!= NERR_Success
)
2213 ERR("SetUserInfo failed (Status %lu)\n", ApiStatus
);
2218 if (UserHandle
!= NULL
)
2220 if (ApiStatus
!= NERR_Success
)
2221 SamDeleteUser(UserHandle
);
2223 SamCloseHandle(UserHandle
);
2226 if (DomainHandle
!= NULL
)
2227 SamCloseHandle(DomainHandle
);
2229 if (ServerHandle
!= NULL
)
2230 SamCloseHandle(ServerHandle
);
2236 /******************************************************************************
2237 * NetUserChangePassword (NETAPI32.@)
2239 * domainname [I] Optional. Domain on which the user resides or the logon
2240 * domain of the current user if NULL.
2241 * username [I] Optional. Username to change the password for or the name
2242 * of the current user if NULL.
2243 * oldpassword [I] The user's current password.
2244 * newpassword [I] The password that the user will be changed to using.
2247 * Success: NERR_Success.
2248 * Failure: NERR_* failure code or win error code.
2253 NetUserChangePassword(LPCWSTR domainname
,
2255 LPCWSTR oldpassword
,
2256 LPCWSTR newpassword
)
2258 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer
= NULL
;
2259 PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer
= NULL
;
2260 ULONG RequestBufferSize
;
2261 ULONG ResponseBufferSize
= 0;
2263 ANSI_STRING PackageName
;
2264 ULONG AuthenticationPackage
= 0;
2265 HANDLE LsaHandle
= NULL
;
2266 NET_API_STATUS ApiStatus
= NERR_Success
;
2267 NTSTATUS Status
= STATUS_SUCCESS
;
2268 NTSTATUS ProtocolStatus
;
2270 TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname
), debugstr_w(username
));
2272 /* FIXME: handle null domain or user name */
2274 /* Check the parameters */
2275 if ((oldpassword
== NULL
) ||
2276 (newpassword
== NULL
))
2277 return ERROR_INVALID_PARAMETER
;
2279 /* Connect to the LSA server */
2280 Status
= LsaConnectUntrusted(&LsaHandle
);
2281 if (!NT_SUCCESS(Status
))
2282 return NetpNtStatusToApiStatus(Status
);
2284 /* Get the authentication package ID */
2285 RtlInitAnsiString(&PackageName
,
2286 MSV1_0_PACKAGE_NAME
);
2288 Status
= LsaLookupAuthenticationPackage(LsaHandle
,
2290 &AuthenticationPackage
);
2291 if (!NT_SUCCESS(Status
))
2293 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2297 /* Calculate the request buffer size */
2298 RequestBufferSize
= sizeof(MSV1_0_CHANGEPASSWORD_REQUEST
) +
2299 ((wcslen(domainname
) + 1) * sizeof(WCHAR
)) +
2300 ((wcslen(username
) + 1) * sizeof(WCHAR
)) +
2301 ((wcslen(oldpassword
) + 1) * sizeof(WCHAR
)) +
2302 ((wcslen(newpassword
) + 1) * sizeof(WCHAR
));
2304 /* Allocate the request buffer */
2305 ApiStatus
= NetApiBufferAllocate(RequestBufferSize
,
2306 (PVOID
*)&RequestBuffer
);
2307 if (ApiStatus
!= NERR_Success
)
2310 /* Initialize the request buffer */
2311 RequestBuffer
->MessageType
= MsV1_0ChangePassword
;
2312 RequestBuffer
->Impersonating
= TRUE
;
2314 Ptr
= (LPWSTR
)((ULONG_PTR
)RequestBuffer
+ sizeof(MSV1_0_CHANGEPASSWORD_REQUEST
));
2316 /* Pack the domain name */
2317 RequestBuffer
->DomainName
.Length
= wcslen(domainname
) * sizeof(WCHAR
);
2318 RequestBuffer
->DomainName
.MaximumLength
= RequestBuffer
->DomainName
.Length
+ sizeof(WCHAR
);
2319 RequestBuffer
->DomainName
.Buffer
= Ptr
;
2321 RtlCopyMemory(RequestBuffer
->DomainName
.Buffer
,
2323 RequestBuffer
->DomainName
.MaximumLength
);
2325 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->DomainName
.MaximumLength
);
2327 /* Pack the user name */
2328 RequestBuffer
->AccountName
.Length
= wcslen(username
) * sizeof(WCHAR
);
2329 RequestBuffer
->AccountName
.MaximumLength
= RequestBuffer
->AccountName
.Length
+ sizeof(WCHAR
);
2330 RequestBuffer
->AccountName
.Buffer
= Ptr
;
2332 RtlCopyMemory(RequestBuffer
->AccountName
.Buffer
,
2334 RequestBuffer
->AccountName
.MaximumLength
);
2336 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->AccountName
.MaximumLength
);
2338 /* Pack the old password */
2339 RequestBuffer
->OldPassword
.Length
= wcslen(oldpassword
) * sizeof(WCHAR
);
2340 RequestBuffer
->OldPassword
.MaximumLength
= RequestBuffer
->OldPassword
.Length
+ sizeof(WCHAR
);
2341 RequestBuffer
->OldPassword
.Buffer
= Ptr
;
2343 RtlCopyMemory(RequestBuffer
->OldPassword
.Buffer
,
2345 RequestBuffer
->OldPassword
.MaximumLength
);
2347 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->OldPassword
.MaximumLength
);
2349 /* Pack the new password */
2350 RequestBuffer
->NewPassword
.Length
= wcslen(newpassword
) * sizeof(WCHAR
);
2351 RequestBuffer
->NewPassword
.MaximumLength
= RequestBuffer
->NewPassword
.Length
+ sizeof(WCHAR
);
2352 RequestBuffer
->NewPassword
.Buffer
= Ptr
;
2354 RtlCopyMemory(RequestBuffer
->NewPassword
.Buffer
,
2356 RequestBuffer
->NewPassword
.MaximumLength
);
2358 /* Call the authentication package */
2359 Status
= LsaCallAuthenticationPackage(LsaHandle
,
2360 AuthenticationPackage
,
2363 (PVOID
*)&ResponseBuffer
,
2364 &ResponseBufferSize
,
2366 if (!NT_SUCCESS(Status
))
2368 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2372 if (!NT_SUCCESS(ProtocolStatus
))
2374 ApiStatus
= NetpNtStatusToApiStatus(ProtocolStatus
);
2379 if (RequestBuffer
!= NULL
)
2380 NetApiBufferFree(RequestBuffer
);
2382 if (ResponseBuffer
!= NULL
)
2383 LsaFreeReturnBuffer(ResponseBuffer
);
2385 if (LsaHandle
!= NULL
)
2392 /************************************************************
2393 * NetUserDel (NETAPI32.@)
2397 NetUserDel(LPCWSTR servername
,
2400 UNICODE_STRING ServerName
;
2401 UNICODE_STRING UserName
;
2402 SAM_HANDLE ServerHandle
= NULL
;
2403 SAM_HANDLE DomainHandle
= NULL
;
2404 SAM_HANDLE UserHandle
= NULL
;
2405 NET_API_STATUS ApiStatus
= NERR_Success
;
2406 NTSTATUS Status
= STATUS_SUCCESS
;
2408 TRACE("(%s, %s)\n", debugstr_w(servername
), debugstr_w(username
));
2410 if (servername
!= NULL
)
2411 RtlInitUnicodeString(&ServerName
, servername
);
2413 RtlInitUnicodeString(&UserName
, username
);
2415 /* Connect to the SAM Server */
2416 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
2418 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
2420 if (!NT_SUCCESS(Status
))
2422 ERR("SamConnect failed (Status %08lx)\n", Status
);
2423 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2427 /* Open the Builtin Domain */
2428 Status
= OpenBuiltinDomain(ServerHandle
,
2431 if (!NT_SUCCESS(Status
))
2433 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
2434 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2438 /* Open the user account in the builtin domain */
2439 ApiStatus
= OpenUserByName(DomainHandle
,
2443 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_NONE_MAPPED
)
2445 TRACE("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus
);
2449 if (UserHandle
== NULL
)
2451 if (DomainHandle
!= NULL
)
2453 SamCloseHandle(DomainHandle
);
2454 DomainHandle
= NULL
;
2457 /* Open the Acount Domain */
2458 Status
= OpenAccountDomain(ServerHandle
,
2459 (servername
!= NULL
) ? &ServerName
: NULL
,
2462 if (!NT_SUCCESS(Status
))
2464 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
2465 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2469 /* Open the user account in the account domain */
2470 ApiStatus
= OpenUserByName(DomainHandle
,
2474 if (ApiStatus
!= NERR_Success
)
2476 ERR("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus
);
2477 if (ApiStatus
== ERROR_NONE_MAPPED
)
2478 ApiStatus
= NERR_UserNotFound
;
2483 /* Delete the user */
2484 Status
= SamDeleteUser(UserHandle
);
2485 if (!NT_SUCCESS(Status
))
2487 ERR("SamDeleteUser failed (Status %08lx)\n", Status
);
2488 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2492 /* A successful delete invalidates the handle */
2496 if (UserHandle
!= NULL
)
2497 SamCloseHandle(UserHandle
);
2499 if (DomainHandle
!= NULL
)
2500 SamCloseHandle(DomainHandle
);
2502 if (ServerHandle
!= NULL
)
2503 SamCloseHandle(ServerHandle
);
2509 /************************************************************
2510 * NetUserEnum (NETAPI32.@)
2514 NetUserEnum(LPCWSTR servername
,
2519 LPDWORD entriesread
,
2520 LPDWORD totalentries
,
2521 LPDWORD resume_handle
)
2523 UNICODE_STRING ServerName
;
2524 PSAM_RID_ENUMERATION CurrentUser
;
2525 PENUM_CONTEXT EnumContext
= NULL
;
2526 LPVOID Buffer
= NULL
;
2528 SAM_HANDLE UserHandle
= NULL
;
2529 NET_API_STATUS ApiStatus
= NERR_Success
;
2530 NTSTATUS Status
= STATUS_SUCCESS
;
2532 TRACE("(%s %d 0x%d %p %d %p %p %p)\n", debugstr_w(servername
), level
,
2533 filter
, bufptr
, prefmaxlen
, entriesread
, totalentries
, resume_handle
);
2539 if (servername
!= NULL
)
2540 RtlInitUnicodeString(&ServerName
, servername
);
2542 if (resume_handle
!= NULL
&& *resume_handle
!= 0)
2544 EnumContext
= (PENUM_CONTEXT
)*resume_handle
;
2548 ApiStatus
= NetApiBufferAllocate(sizeof(ENUM_CONTEXT
), (PVOID
*)&EnumContext
);
2549 if (ApiStatus
!= NERR_Success
)
2552 EnumContext
->EnumerationContext
= 0;
2553 EnumContext
->Buffer
= NULL
;
2554 EnumContext
->Count
= 0;
2555 EnumContext
->Index
= 0;
2556 EnumContext
->BuiltinDone
= FALSE
;
2558 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
2559 &EnumContext
->ServerHandle
,
2560 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
2562 if (!NT_SUCCESS(Status
))
2564 ERR("SamConnect failed (Status %08lx)\n", Status
);
2565 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2569 /* Get the Account Domain SID */
2570 Status
= GetAccountDomainSid((servername
!= NULL
) ? &ServerName
: NULL
,
2571 &EnumContext
->AccountDomainSid
);
2572 if (!NT_SUCCESS(Status
))
2574 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status
);
2575 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2579 /* Open the Account Domain */
2580 Status
= SamOpenDomain(EnumContext
->ServerHandle
,
2581 DOMAIN_LIST_ACCOUNTS
| DOMAIN_LOOKUP
,
2582 EnumContext
->AccountDomainSid
,
2583 &EnumContext
->AccountDomainHandle
);
2584 if (!NT_SUCCESS(Status
))
2586 ERR("SamOpenDomain failed (Status %08lx)\n", Status
);
2587 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2591 Status
= OpenBuiltinDomain(EnumContext
->ServerHandle
,
2592 DOMAIN_LIST_ACCOUNTS
| DOMAIN_LOOKUP
,
2593 &EnumContext
->BuiltinDomainHandle
);
2594 if (!NT_SUCCESS(Status
))
2596 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
2597 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2604 TRACE("EnumContext->Index: %lu\n", EnumContext
->Index
);
2605 TRACE("EnumContext->Count: %lu\n", EnumContext
->Count
);
2607 if (EnumContext
->Index
>= EnumContext
->Count
)
2609 // if (EnumContext->BuiltinDone != FALSE)
2611 // ApiStatus = NERR_Success;
2615 TRACE("Calling SamEnumerateUsersInDomain\n");
2616 Status
= SamEnumerateUsersInDomain(EnumContext
->AccountDomainHandle
, //BuiltinDomainHandle,
2617 &EnumContext
->EnumerationContext
,
2619 (PVOID
*)&EnumContext
->Buffer
,
2621 &EnumContext
->Count
);
2623 TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n", Status
);
2624 if (!NT_SUCCESS(Status
))
2626 ERR("SamEnumerateUsersInDomain failed (Status %08lx)\n", Status
);
2627 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2631 if (Status
== STATUS_MORE_ENTRIES
)
2633 ApiStatus
= NERR_BufTooSmall
;
2638 EnumContext
->BuiltinDone
= TRUE
;
2642 TRACE("EnumContext: %lu\n", EnumContext
);
2643 TRACE("EnumContext->Count: %lu\n", EnumContext
->Count
);
2644 TRACE("EnumContext->Buffer: %p\n", EnumContext
->Buffer
);
2646 /* Get a pointer to the current user */
2647 CurrentUser
= &EnumContext
->Buffer
[EnumContext
->Index
];
2649 TRACE("RID: %lu\n", CurrentUser
->RelativeId
);
2651 Status
= SamOpenUser(EnumContext
->AccountDomainHandle
, //BuiltinDomainHandle,
2652 READ_CONTROL
| USER_READ_GENERAL
| USER_READ_PREFERENCES
| USER_READ_LOGON
| USER_READ_ACCOUNT
,
2653 CurrentUser
->RelativeId
,
2655 if (!NT_SUCCESS(Status
))
2657 ERR("SamOpenUser failed (Status %08lx)\n", Status
);
2658 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2662 ApiStatus
= BuildUserInfoBuffer(UserHandle
,
2663 EnumContext
->AccountDomainSid
,
2665 CurrentUser
->RelativeId
,
2667 if (ApiStatus
!= NERR_Success
)
2669 ERR("BuildUserInfoBuffer failed (ApiStatus %lu)\n", ApiStatus
);
2673 SamCloseHandle(UserHandle
);
2676 EnumContext
->Index
++;
2682 if (ApiStatus
== NERR_Success
&& EnumContext
!= NULL
&& EnumContext
->Index
< EnumContext
->Count
)
2683 ApiStatus
= ERROR_MORE_DATA
;
2685 if (EnumContext
!= NULL
)
2686 *totalentries
= EnumContext
->Count
;
2688 if (resume_handle
== NULL
|| ApiStatus
!= ERROR_MORE_DATA
)
2690 if (EnumContext
!= NULL
)
2692 if (EnumContext
->BuiltinDomainHandle
!= NULL
)
2693 SamCloseHandle(EnumContext
->BuiltinDomainHandle
);
2695 if (EnumContext
->AccountDomainHandle
!= NULL
)
2696 SamCloseHandle(EnumContext
->AccountDomainHandle
);
2698 if (EnumContext
->AccountDomainSid
!= NULL
)
2699 RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext
->AccountDomainSid
);
2701 if (EnumContext
->ServerHandle
!= NULL
)
2702 SamCloseHandle(EnumContext
->ServerHandle
);
2704 if (EnumContext
->Buffer
!= NULL
)
2706 for (i
= 0; i
< EnumContext
->Count
; i
++)
2708 SamFreeMemory(EnumContext
->Buffer
[i
].Name
.Buffer
);
2711 SamFreeMemory(EnumContext
->Buffer
);
2714 NetApiBufferFree(EnumContext
);
2719 if (UserHandle
!= NULL
)
2720 SamCloseHandle(UserHandle
);
2722 if (resume_handle
!= NULL
)
2723 *resume_handle
= (DWORD_PTR
)EnumContext
;
2725 *bufptr
= (LPBYTE
)Buffer
;
2727 TRACE("return %lu\n", ApiStatus
);
2733 /************************************************************
2734 * NetUserGetGroups (NETAPI32.@)
2738 NetUserGetGroups(LPCWSTR servername
,
2743 LPDWORD entriesread
,
2744 LPDWORD totalentries
)
2746 UNICODE_STRING ServerName
;
2747 UNICODE_STRING UserName
;
2748 SAM_HANDLE ServerHandle
= NULL
;
2749 SAM_HANDLE AccountDomainHandle
= NULL
;
2750 SAM_HANDLE UserHandle
= NULL
;
2751 PSID AccountDomainSid
= NULL
;
2752 PULONG RelativeIds
= NULL
;
2753 PSID_NAME_USE Use
= NULL
;
2754 PGROUP_MEMBERSHIP GroupMembership
= NULL
;
2757 NET_API_STATUS ApiStatus
= NERR_Success
;
2758 NTSTATUS Status
= STATUS_SUCCESS
;
2760 TRACE("%s %s %d %p %d %p %p stub\n", debugstr_w(servername
),
2761 debugstr_w(username
), level
, bufptr
, prefixmaxlen
, entriesread
,
2764 if (servername
!= NULL
)
2765 RtlInitUnicodeString(&ServerName
, servername
);
2767 RtlInitUnicodeString(&UserName
, username
);
2769 /* Connect to the SAM Server */
2770 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
2772 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
2774 if (!NT_SUCCESS(Status
))
2776 ERR("SamConnect failed (Status %08lx)\n", Status
);
2777 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2781 /* Get the Account Domain SID */
2782 Status
= GetAccountDomainSid((servername
!= NULL
) ? &ServerName
: NULL
,
2784 if (!NT_SUCCESS(Status
))
2786 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status
);
2787 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2791 /* Open the Account Domain */
2792 Status
= SamOpenDomain(ServerHandle
,
2793 DOMAIN_LOOKUP
| DOMAIN_GET_ALIAS_MEMBERSHIP
,
2795 &AccountDomainHandle
);
2796 if (!NT_SUCCESS(Status
))
2798 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
2799 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2803 /* Get the RID for the given user name */
2804 Status
= SamLookupNamesInDomain(AccountDomainHandle
,
2809 if (!NT_SUCCESS(Status
))
2811 ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status
);
2812 if (Status
== STATUS_NONE_MAPPED
)
2813 ApiStatus
= NERR_UserNotFound
;
2815 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2819 /* Fail, if it is not a user account */
2820 if (Use
[0] != SidTypeUser
)
2822 ERR("Account is not a User!\n");
2823 ApiStatus
= NERR_UserNotFound
;
2827 /* Open the user object */
2828 Status
= SamOpenUser(AccountDomainHandle
,
2832 if (!NT_SUCCESS(Status
))
2834 ERR("SamOpenUser failed (Status %08lx)\n", Status
);
2835 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2839 /* Get the group memberships of this user */
2840 Status
= SamGetGroupsForUser(UserHandle
,
2843 if (!NT_SUCCESS(Status
))
2845 ERR("SamGetGroupsForUser failed (Status %08lx)\n", Status
);
2846 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2850 /* If there is no group membership, we're done */
2851 if (GroupCount
== 0)
2853 ApiStatus
= NERR_Success
;
2860 if (GroupMembership
!= NULL
)
2861 SamFreeMemory(GroupMembership
);
2863 if (UserHandle
!= NULL
)
2864 SamCloseHandle(UserHandle
);
2866 if (RelativeIds
!= NULL
)
2867 SamFreeMemory(RelativeIds
);
2872 if (AccountDomainSid
!= NULL
)
2873 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid
);
2875 if (AccountDomainHandle
!= NULL
)
2876 SamCloseHandle(AccountDomainHandle
);
2878 if (ServerHandle
!= NULL
)
2879 SamCloseHandle(ServerHandle
);
2881 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_MORE_DATA
)
2888 // *entriesread = Count;
2889 // *totalentries = Count;
2892 // *bufptr = (LPBYTE)Buffer;
2898 /************************************************************
2899 * NetUserGetInfo (NETAPI32.@)
2903 NetUserGetInfo(LPCWSTR servername
,
2908 UNICODE_STRING ServerName
;
2909 UNICODE_STRING UserName
;
2910 SAM_HANDLE ServerHandle
= NULL
;
2911 SAM_HANDLE AccountDomainHandle
= NULL
;
2912 SAM_HANDLE UserHandle
= NULL
;
2913 PULONG RelativeIds
= NULL
;
2914 PSID_NAME_USE Use
= NULL
;
2915 LPVOID Buffer
= NULL
;
2916 PSID AccountDomainSid
= NULL
;
2917 NET_API_STATUS ApiStatus
= NERR_Success
;
2918 NTSTATUS Status
= STATUS_SUCCESS
;
2920 TRACE("(%s, %s, %d, %p)\n", debugstr_w(servername
),
2921 debugstr_w(username
), level
, bufptr
);
2923 if (servername
!= NULL
)
2924 RtlInitUnicodeString(&ServerName
, servername
);
2926 RtlInitUnicodeString(&UserName
, username
);
2928 /* Connect to the SAM Server */
2929 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
2931 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
2933 if (!NT_SUCCESS(Status
))
2935 ERR("SamConnect failed (Status %08lx)\n", Status
);
2936 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2940 /* Get the Account Domain SID */
2941 Status
= GetAccountDomainSid((servername
!= NULL
) ? &ServerName
: NULL
,
2943 if (!NT_SUCCESS(Status
))
2945 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status
);
2946 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2950 /* Open the Account Domain */
2951 Status
= SamOpenDomain(ServerHandle
,
2952 DOMAIN_LIST_ACCOUNTS
| DOMAIN_LOOKUP
,
2954 &AccountDomainHandle
);
2955 if (!NT_SUCCESS(Status
))
2957 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
2958 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2962 /* Get the RID for the given user name */
2963 Status
= SamLookupNamesInDomain(AccountDomainHandle
,
2968 if (!NT_SUCCESS(Status
))
2970 ERR("SamOpenDomain failed (Status %08lx)\n", Status
);
2971 if (Status
== STATUS_NONE_MAPPED
)
2972 ApiStatus
= NERR_UserNotFound
;
2974 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2978 /* Check if the account is a user account */
2979 if (Use
[0] != SidTypeUser
)
2981 ERR("No user found!\n");
2982 ApiStatus
= NERR_UserNotFound
;
2986 TRACE("RID: %lu\n", RelativeIds
[0]);
2988 /* Open the user object */
2989 Status
= SamOpenUser(AccountDomainHandle
,
2990 READ_CONTROL
| USER_READ_GENERAL
| USER_READ_PREFERENCES
| USER_READ_LOGON
| USER_READ_ACCOUNT
,
2993 if (!NT_SUCCESS(Status
))
2995 ERR("SamOpenUser failed (Status %08lx)\n", Status
);
2996 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3000 ApiStatus
= BuildUserInfoBuffer(UserHandle
,
3005 if (ApiStatus
!= NERR_Success
)
3007 ERR("BuildUserInfoBuffer failed (ApiStatus %08lu)\n", ApiStatus
);
3012 if (UserHandle
!= NULL
)
3013 SamCloseHandle(UserHandle
);
3015 if (RelativeIds
!= NULL
)
3016 SamFreeMemory(RelativeIds
);
3021 if (AccountDomainHandle
!= NULL
)
3022 SamCloseHandle(AccountDomainHandle
);
3024 if (AccountDomainSid
!= NULL
)
3025 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid
);
3027 if (ServerHandle
!= NULL
)
3028 SamCloseHandle(ServerHandle
);
3030 *bufptr
= (LPBYTE
)Buffer
;
3036 /************************************************************
3037 * NetUserGetLocalGroups (NETAPI32.@)
3041 NetUserGetLocalGroups(LPCWSTR servername
,
3047 LPDWORD entriesread
,
3048 LPDWORD totalentries
)
3050 UNICODE_STRING ServerName
;
3051 UNICODE_STRING UserName
;
3052 SAM_HANDLE ServerHandle
= NULL
;
3053 SAM_HANDLE BuiltinDomainHandle
= NULL
;
3054 SAM_HANDLE AccountDomainHandle
= NULL
;
3055 PSID AccountDomainSid
= NULL
;
3056 PSID UserSid
= NULL
;
3057 PULONG RelativeIds
= NULL
;
3058 PSID_NAME_USE Use
= NULL
;
3059 ULONG BuiltinMemberCount
= 0;
3060 ULONG AccountMemberCount
= 0;
3061 PULONG BuiltinAliases
= NULL
;
3062 PULONG AccountAliases
= NULL
;
3063 PUNICODE_STRING BuiltinNames
= NULL
;
3064 PUNICODE_STRING AccountNames
= NULL
;
3065 PLOCALGROUP_USERS_INFO_0 Buffer
= NULL
;
3071 NET_API_STATUS ApiStatus
= NERR_Success
;
3072 NTSTATUS Status
= STATUS_SUCCESS
;
3074 TRACE("(%s, %s, %d, %08x, %p %d, %p, %p) stub!\n",
3075 debugstr_w(servername
), debugstr_w(username
), level
, flags
, bufptr
,
3076 prefmaxlen
, entriesread
, totalentries
);
3079 return ERROR_INVALID_LEVEL
;
3081 if (flags
& ~LG_INCLUDE_INDIRECT
)
3082 return ERROR_INVALID_PARAMETER
;
3084 if (flags
& LG_INCLUDE_INDIRECT
)
3086 WARN("The flag LG_INCLUDE_INDIRECT is not supported yet!\n");
3089 if (servername
!= NULL
)
3090 RtlInitUnicodeString(&ServerName
, servername
);
3092 RtlInitUnicodeString(&UserName
, username
);
3094 /* Connect to the SAM Server */
3095 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
3097 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
3099 if (!NT_SUCCESS(Status
))
3101 ERR("SamConnect failed (Status %08lx)\n", Status
);
3102 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3106 /* Open the Builtin Domain */
3107 Status
= OpenBuiltinDomain(ServerHandle
,
3108 DOMAIN_LOOKUP
| DOMAIN_GET_ALIAS_MEMBERSHIP
,
3109 &BuiltinDomainHandle
);
3110 if (!NT_SUCCESS(Status
))
3112 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
3113 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3117 /* Get the Account Domain SID */
3118 Status
= GetAccountDomainSid((servername
!= NULL
) ? &ServerName
: NULL
,
3120 if (!NT_SUCCESS(Status
))
3122 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status
);
3123 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3127 /* Open the Account Domain */
3128 Status
= SamOpenDomain(ServerHandle
,
3129 DOMAIN_LOOKUP
| DOMAIN_GET_ALIAS_MEMBERSHIP
,
3131 &AccountDomainHandle
);
3132 if (!NT_SUCCESS(Status
))
3134 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
3135 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3139 /* Get the RID for the given user name */
3140 Status
= SamLookupNamesInDomain(AccountDomainHandle
,
3145 if (!NT_SUCCESS(Status
))
3147 ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status
);
3148 if (Status
== STATUS_NONE_MAPPED
)
3149 ApiStatus
= NERR_UserNotFound
;
3151 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3155 /* Fail, if it is not a user account */
3156 if (Use
[0] != SidTypeUser
)
3158 ERR("Account is not a User!\n");
3159 ApiStatus
= NERR_UserNotFound
;
3163 /* Build the User SID from the Account Domain SID and the users RID */
3164 ApiStatus
= BuildSidFromSidAndRid(AccountDomainSid
,
3167 if (ApiStatus
!= NERR_Success
)
3169 ERR("BuildSidFromSidAndRid failed!\n");
3173 /* Get alias memberships in the Builtin Domain */
3174 Status
= SamGetAliasMembership(BuiltinDomainHandle
,
3177 &BuiltinMemberCount
,
3179 if (!NT_SUCCESS(Status
))
3181 ERR("SamGetAliasMembership failed (Status %08lx)\n", Status
);
3182 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3186 if (BuiltinMemberCount
> 0)
3188 /* Get the Names of the builtin alias members */
3189 Status
= SamLookupIdsInDomain(BuiltinDomainHandle
,
3194 if (!NT_SUCCESS(Status
))
3196 ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status
);
3197 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3202 /* Get alias memberships in the Account Domain */
3203 Status
= SamGetAliasMembership(AccountDomainHandle
,
3206 &AccountMemberCount
,
3208 if (!NT_SUCCESS(Status
))
3210 ERR("SamGetAliasMembership failed (Status %08lx)\n", Status
);
3211 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3215 if (AccountMemberCount
> 0)
3217 /* Get the Names of the builtin alias members */
3218 Status
= SamLookupIdsInDomain(AccountDomainHandle
,
3223 if (!NT_SUCCESS(Status
))
3225 ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status
);
3226 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3231 /* Calculate the required buffer size */
3234 for (i
= 0; i
< BuiltinMemberCount
; i
++)
3236 if (BuiltinNames
[i
].Length
> 0)
3238 Size
+= (sizeof(LOCALGROUP_USERS_INFO_0
) + BuiltinNames
[i
].Length
+ sizeof(UNICODE_NULL
));
3243 for (i
= 0; i
< AccountMemberCount
; i
++)
3245 if (AccountNames
[i
].Length
> 0)
3247 Size
+= (sizeof(LOCALGROUP_USERS_INFO_0
) + AccountNames
[i
].Length
+ sizeof(UNICODE_NULL
));
3254 ApiStatus
= NERR_Success
;
3258 /* Allocate buffer */
3259 ApiStatus
= NetApiBufferAllocate(Size
, (LPVOID
*)&Buffer
);
3260 if (ApiStatus
!= NERR_Success
)
3263 ZeroMemory(Buffer
, Size
);
3265 StrPtr
= (LPWSTR
)((INT_PTR
)Buffer
+ Count
* sizeof(LOCALGROUP_USERS_INFO_0
));
3267 /* Copy data to the allocated buffer */
3269 for (i
= 0; i
< BuiltinMemberCount
; i
++)
3271 if (BuiltinNames
[i
].Length
> 0)
3274 BuiltinNames
[i
].Buffer
,
3275 BuiltinNames
[i
].Length
);
3276 Buffer
[Index
].lgrui0_name
= StrPtr
;
3278 StrPtr
= (LPWSTR
)((INT_PTR
)StrPtr
+ BuiltinNames
[i
].Length
+ sizeof(UNICODE_NULL
));
3283 for (i
= 0; i
< AccountMemberCount
; i
++)
3285 if (AccountNames
[i
].Length
> 0)
3288 AccountNames
[i
].Buffer
,
3289 AccountNames
[i
].Length
);
3290 Buffer
[Index
].lgrui0_name
= StrPtr
;
3292 StrPtr
= (LPWSTR
)((INT_PTR
)StrPtr
+ AccountNames
[i
].Length
+ sizeof(UNICODE_NULL
));
3298 if (AccountNames
!= NULL
)
3299 SamFreeMemory(AccountNames
);
3301 if (BuiltinNames
!= NULL
)
3302 SamFreeMemory(BuiltinNames
);
3304 if (AccountAliases
!= NULL
)
3305 SamFreeMemory(AccountAliases
);
3307 if (BuiltinAliases
!= NULL
)
3308 SamFreeMemory(BuiltinAliases
);
3310 if (RelativeIds
!= NULL
)
3311 SamFreeMemory(RelativeIds
);
3316 if (UserSid
!= NULL
)
3317 NetApiBufferFree(UserSid
);
3319 if (AccountDomainSid
!= NULL
)
3320 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid
);
3322 if (AccountDomainHandle
!= NULL
)
3323 SamCloseHandle(AccountDomainHandle
);
3325 if (BuiltinDomainHandle
!= NULL
)
3326 SamCloseHandle(BuiltinDomainHandle
);
3328 if (ServerHandle
!= NULL
)
3329 SamCloseHandle(ServerHandle
);
3331 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_MORE_DATA
)
3338 *entriesread
= Count
;
3339 *totalentries
= Count
;
3342 *bufptr
= (LPBYTE
)Buffer
;
3348 /******************************************************************************
3349 * NetUserModalsGet (NETAPI32.@)
3351 * Retrieves global information for all users and global groups in the security
3355 * servername [I] Specifies the DNS or the NetBIOS name of the remote server
3356 * on which the function is to execute.
3357 * level [I] Information level of the data.
3358 * 0 Return global passwords parameters. bufptr points to a
3359 * USER_MODALS_INFO_0 struct.
3360 * 1 Return logon server and domain controller information. bufptr
3361 * points to a USER_MODALS_INFO_1 struct.
3362 * 2 Return domain name and identifier. bufptr points to a
3363 * USER_MODALS_INFO_2 struct.
3364 * 3 Return lockout information. bufptr points to a USER_MODALS_INFO_3
3366 * bufptr [O] Buffer that receives the data.
3369 * Success: NERR_Success.
3371 * ERROR_ACCESS_DENIED - the user does not have access to the info.
3372 * NERR_InvalidComputer - computer name is invalid.
3376 NetUserModalsGet(LPCWSTR servername
,
3380 UNICODE_STRING ServerName
;
3381 SAM_HANDLE ServerHandle
= NULL
;
3382 SAM_HANDLE DomainHandle
= NULL
;
3383 PSID DomainSid
= NULL
;
3384 PDOMAIN_PASSWORD_INFORMATION PasswordInfo
= NULL
;
3385 PDOMAIN_LOGOFF_INFORMATION LogoffInfo
= NULL
;
3386 PDOMAIN_SERVER_ROLE_INFORMATION ServerRoleInfo
= NULL
;
3387 PDOMAIN_REPLICATION_INFORMATION ReplicationInfo
= NULL
;
3388 PDOMAIN_NAME_INFORMATION NameInfo
= NULL
;
3389 PDOMAIN_LOCKOUT_INFORMATION LockoutInfo
= NULL
;
3390 ULONG DesiredAccess
;
3392 PUSER_MODALS_INFO_0 umi0
;
3393 PUSER_MODALS_INFO_1 umi1
;
3394 PUSER_MODALS_INFO_2 umi2
;
3395 PUSER_MODALS_INFO_3 umi3
;
3396 NET_API_STATUS ApiStatus
= NERR_Success
;
3397 NTSTATUS Status
= STATUS_SUCCESS
;
3399 TRACE("(%s %d %p)\n", debugstr_w(servername
), level
, bufptr
);
3403 if (servername
!= NULL
)
3404 RtlInitUnicodeString(&ServerName
, servername
);
3406 /* Connect to the SAM Server */
3407 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
3409 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
3411 if (!NT_SUCCESS(Status
))
3413 ERR("SamConnect failed (Status %08lx)\n", Status
);
3414 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3418 /* Get the Account Domain SID */
3419 Status
= GetAccountDomainSid((servername
!= NULL
) ? &ServerName
: NULL
,
3421 if (!NT_SUCCESS(Status
))
3423 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status
);
3424 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3431 DesiredAccess
= DOMAIN_READ_OTHER_PARAMETERS
| DOMAIN_READ_PASSWORD_PARAMETERS
;
3435 DesiredAccess
= DOMAIN_READ_OTHER_PARAMETERS
;
3439 DesiredAccess
= DOMAIN_READ_OTHER_PARAMETERS
;
3443 DesiredAccess
= DOMAIN_READ_PASSWORD_PARAMETERS
;
3447 ApiStatus
= ERROR_INVALID_LEVEL
;
3451 /* Open the Account Domain */
3452 Status
= SamOpenDomain(ServerHandle
,
3456 if (!NT_SUCCESS(Status
))
3458 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
3459 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3466 /* return global passwords parameters */
3467 Status
= SamQueryInformationDomain(DomainHandle
,
3468 DomainPasswordInformation
,
3469 (PVOID
*)&PasswordInfo
);
3470 if (!NT_SUCCESS(Status
))
3472 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3476 Status
= SamQueryInformationDomain(DomainHandle
,
3477 DomainLogoffInformation
,
3478 (PVOID
*)&LogoffInfo
);
3479 if (!NT_SUCCESS(Status
))
3481 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3485 BufferSize
= sizeof(USER_MODALS_INFO_0
);
3489 /* return logon server and domain controller info */
3490 Status
= SamQueryInformationDomain(DomainHandle
,
3491 DomainServerRoleInformation
,
3492 (PVOID
*)&ServerRoleInfo
);
3493 if (!NT_SUCCESS(Status
))
3495 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3499 Status
= SamQueryInformationDomain(DomainHandle
,
3500 DomainReplicationInformation
,
3501 (PVOID
*)&ReplicationInfo
);
3502 if (!NT_SUCCESS(Status
))
3504 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3508 BufferSize
= sizeof(USER_MODALS_INFO_1
) +
3509 ReplicationInfo
->ReplicaSourceNodeName
.Length
+ sizeof(WCHAR
);
3513 /* return domain name and identifier */
3514 Status
= SamQueryInformationDomain(DomainHandle
,
3515 DomainNameInformation
,
3517 if (!NT_SUCCESS(Status
))
3519 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3523 BufferSize
= sizeof( USER_MODALS_INFO_2
) +
3524 NameInfo
->DomainName
.Length
+ sizeof(WCHAR
) +
3525 RtlLengthSid(DomainSid
);
3529 /* return lockout information */
3530 Status
= SamQueryInformationDomain(DomainHandle
,
3531 DomainLockoutInformation
,
3532 (PVOID
*)&LockoutInfo
);
3533 if (!NT_SUCCESS(Status
))
3535 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3539 BufferSize
= sizeof(USER_MODALS_INFO_3
);
3543 TRACE("Invalid level %d is specified\n", level
);
3544 ApiStatus
= ERROR_INVALID_LEVEL
;
3549 ApiStatus
= NetApiBufferAllocate(BufferSize
,
3551 if (ApiStatus
!= NERR_Success
)
3553 WARN("NetApiBufferAllocate() failed\n");
3560 umi0
= (PUSER_MODALS_INFO_0
)*bufptr
;
3562 umi0
->usrmod0_min_passwd_len
= PasswordInfo
->MinPasswordLength
;
3563 umi0
->usrmod0_max_passwd_age
= (ULONG
)(-PasswordInfo
->MaxPasswordAge
.QuadPart
/ 10000000);
3564 umi0
->usrmod0_min_passwd_age
=
3565 DeltaTimeToSeconds(PasswordInfo
->MinPasswordAge
);
3566 umi0
->usrmod0_force_logoff
=
3567 DeltaTimeToSeconds(LogoffInfo
->ForceLogoff
);
3568 umi0
->usrmod0_password_hist_len
= PasswordInfo
->PasswordHistoryLength
;
3572 umi1
= (PUSER_MODALS_INFO_1
)*bufptr
;
3574 switch (ServerRoleInfo
->DomainServerRole
)
3576 case DomainServerRolePrimary
:
3577 umi1
->usrmod1_role
= UAS_ROLE_PRIMARY
;
3580 case DomainServerRoleBackup
:
3581 umi1
->usrmod1_role
= UAS_ROLE_BACKUP
;
3585 ApiStatus
= NERR_InternalError
;
3589 umi1
->usrmod1_primary
= (LPWSTR
)(*bufptr
+ sizeof(USER_MODALS_INFO_1
));
3590 RtlCopyMemory(umi1
->usrmod1_primary
,
3591 ReplicationInfo
->ReplicaSourceNodeName
.Buffer
,
3592 ReplicationInfo
->ReplicaSourceNodeName
.Length
);
3593 umi1
->usrmod1_primary
[ReplicationInfo
->ReplicaSourceNodeName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
3597 umi2
= (PUSER_MODALS_INFO_2
)*bufptr
;
3599 umi2
->usrmod2_domain_name
= (LPWSTR
)(*bufptr
+ sizeof(USER_MODALS_INFO_2
));
3600 RtlCopyMemory(umi2
->usrmod2_domain_name
,
3601 NameInfo
->DomainName
.Buffer
,
3602 NameInfo
->DomainName
.Length
);
3603 umi2
->usrmod2_domain_name
[NameInfo
->DomainName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
3605 umi2
->usrmod2_domain_id
= *bufptr
+
3606 sizeof(USER_MODALS_INFO_2
) +
3607 NameInfo
->DomainName
.Length
+ sizeof(WCHAR
);
3608 RtlCopyMemory(umi2
->usrmod2_domain_id
,
3610 RtlLengthSid(DomainSid
));
3614 umi3
= (PUSER_MODALS_INFO_3
)*bufptr
;
3615 umi3
->usrmod3_lockout_duration
=
3616 DeltaTimeToSeconds(LockoutInfo
->LockoutDuration
);
3617 umi3
->usrmod3_lockout_observation_window
=
3618 DeltaTimeToSeconds(LockoutInfo
->LockoutObservationWindow
);
3619 umi3
->usrmod3_lockout_threshold
= LockoutInfo
->LockoutThreshold
;
3624 if (LockoutInfo
!= NULL
)
3625 SamFreeMemory(LockoutInfo
);
3627 if (NameInfo
!= NULL
)
3628 SamFreeMemory(NameInfo
);
3630 if (ReplicationInfo
!= NULL
)
3631 SamFreeMemory(ReplicationInfo
);
3633 if (ServerRoleInfo
!= NULL
)
3634 SamFreeMemory(ServerRoleInfo
);
3636 if (LogoffInfo
!= NULL
)
3637 SamFreeMemory(LogoffInfo
);
3639 if (PasswordInfo
!= NULL
)
3640 SamFreeMemory(PasswordInfo
);
3642 if (DomainSid
!= NULL
)
3643 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid
);
3645 if (DomainHandle
!= NULL
)
3646 SamCloseHandle(DomainHandle
);
3648 if (ServerHandle
!= NULL
)
3649 SamCloseHandle(ServerHandle
);
3655 /******************************************************************************
3656 * NetUserModalsSet (NETAPI32.@)
3660 NetUserModalsSet(IN LPCWSTR servername
,
3663 OUT LPDWORD parm_err
)
3665 FIXME("(%s %d %p %p)\n", debugstr_w(servername
), level
, buf
, parm_err
);
3666 return ERROR_ACCESS_DENIED
;
3670 /******************************************************************************
3671 * NetUserSetGroups (NETAPI32.@)
3675 NetUserSetGroups(LPCWSTR servername
,
3681 FIXME("(%s %s %lu %p %lu)\n",
3682 debugstr_w(servername
), debugstr_w(username
), level
, buf
, num_entries
);
3683 return ERROR_ACCESS_DENIED
;
3687 /******************************************************************************
3688 * NetUserSetInfo (NETAPI32.@)
3692 NetUserSetInfo(LPCWSTR servername
,
3698 UNICODE_STRING ServerName
;
3699 UNICODE_STRING UserName
;
3700 SAM_HANDLE ServerHandle
= NULL
;
3701 SAM_HANDLE AccountDomainHandle
= NULL
;
3702 SAM_HANDLE UserHandle
= NULL
;
3703 NET_API_STATUS ApiStatus
= NERR_Success
;
3704 NTSTATUS Status
= STATUS_SUCCESS
;
3706 TRACE("(%s %s %lu %p %p)\n",
3707 debugstr_w(servername
), debugstr_w(username
), level
, buf
, parm_err
);
3709 if (parm_err
!= NULL
)
3710 *parm_err
= PARM_ERROR_NONE
;
3712 /* Check the info level */
3744 return ERROR_INVALID_LEVEL
;
3747 if (servername
!= NULL
)
3748 RtlInitUnicodeString(&ServerName
, servername
);
3750 RtlInitUnicodeString(&UserName
, username
);
3752 /* Connect to the SAM Server */
3753 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
3755 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
3757 if (!NT_SUCCESS(Status
))
3759 ERR("SamConnect failed (Status %08lx)\n", Status
);
3760 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3764 /* Open the Account Domain */
3765 Status
= OpenAccountDomain(ServerHandle
,
3766 (servername
!= NULL
) ? &ServerName
: NULL
,
3767 DOMAIN_LIST_ACCOUNTS
| DOMAIN_LOOKUP
| DOMAIN_READ_PASSWORD_PARAMETERS
,
3768 &AccountDomainHandle
);
3769 if (!NT_SUCCESS(Status
))
3771 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
3772 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3776 /* Open the User Account */
3777 ApiStatus
= OpenUserByName(AccountDomainHandle
,
3781 if (ApiStatus
!= NERR_Success
)
3783 ERR("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus
);
3787 /* Set user information */
3788 ApiStatus
= SetUserInfo(UserHandle
,
3792 if (ApiStatus
!= NERR_Success
)
3794 ERR("SetUserInfo failed (Status %lu)\n", ApiStatus
);
3798 if (UserHandle
!= NULL
)
3799 SamCloseHandle(UserHandle
);
3801 if (AccountDomainHandle
!= NULL
)
3802 SamCloseHandle(AccountDomainHandle
);
3804 if (ServerHandle
!= NULL
)
3805 SamCloseHandle(ServerHandle
);