2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: Security Account Manager (SAM) Server
4 * FILE: reactos/dll/win32/samsrv/samrpc.c
5 * PURPOSE: RPC interface functions
7 * PROGRAMMERS: Eric Kohl
12 /* GLOBALS *******************************************************************/
14 static SID_IDENTIFIER_AUTHORITY NtSidAuthority
= {SECURITY_NT_AUTHORITY
};
16 static GENERIC_MAPPING ServerMapping
=
24 static GENERIC_MAPPING DomainMapping
=
32 static GENERIC_MAPPING AliasMapping
=
40 static GENERIC_MAPPING GroupMapping
=
48 static GENERIC_MAPPING UserMapping
=
56 PGENERIC_MAPPING pServerMapping
= &ServerMapping
;
59 /* FUNCTIONS *****************************************************************/
63 SampAddRelativeTimeToTime(IN LARGE_INTEGER AbsoluteTime
,
64 IN LARGE_INTEGER RelativeTime
)
66 LARGE_INTEGER NewTime
;
68 NewTime
.QuadPart
= AbsoluteTime
.QuadPart
- RelativeTime
.QuadPart
;
70 if (NewTime
.QuadPart
< 0)
78 SampStartRpcServer(VOID
)
82 TRACE("SampStartRpcServer() called\n");
84 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
85 RPC_C_PROTSEQ_MAX_REQS_DEFAULT
,
88 if (Status
!= RPC_S_OK
)
90 WARN("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
94 Status
= RpcServerRegisterIf(samr_v1_0_s_ifspec
,
97 if (Status
!= RPC_S_OK
)
99 WARN("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
103 Status
= RpcServerListen(1, 20, TRUE
);
104 if (Status
!= RPC_S_OK
)
106 WARN("RpcServerListen() failed (Status %lx)\n", Status
);
110 TRACE("SampStartRpcServer() done\n");
114 void __RPC_FAR
* __RPC_USER
midl_user_allocate(SIZE_T len
)
116 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
120 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
122 HeapFree(GetProcessHeap(), 0, ptr
);
126 void __RPC_USER
SAMPR_HANDLE_rundown(SAMPR_HANDLE hHandle
)
134 SamrConnect(IN PSAMPR_SERVER_NAME ServerName
,
135 OUT SAMPR_HANDLE
*ServerHandle
,
136 IN ACCESS_MASK DesiredAccess
)
138 PSAM_DB_OBJECT ServerObject
;
141 TRACE("SamrConnect(%p %p %lx)\n",
142 ServerName
, ServerHandle
, DesiredAccess
);
144 RtlAcquireResourceShared(&SampResource
,
147 /* Map generic access rights */
148 RtlMapGenericMask(&DesiredAccess
,
151 /* Open the Server Object */
152 Status
= SampOpenDbObject(NULL
,
159 if (NT_SUCCESS(Status
))
160 *ServerHandle
= (SAMPR_HANDLE
)ServerObject
;
162 RtlReleaseResource(&SampResource
);
164 TRACE("SamrConnect done (Status 0x%08lx)\n", Status
);
173 SamrCloseHandle(IN OUT SAMPR_HANDLE
*SamHandle
)
175 PSAM_DB_OBJECT DbObject
;
176 NTSTATUS Status
= STATUS_SUCCESS
;
178 TRACE("SamrCloseHandle(%p)\n", SamHandle
);
180 RtlAcquireResourceShared(&SampResource
,
183 Status
= SampValidateDbObject(*SamHandle
,
187 if (Status
== STATUS_SUCCESS
)
189 Status
= SampCloseDbObject(DbObject
);
193 RtlReleaseResource(&SampResource
);
195 TRACE("SamrCloseHandle done (Status 0x%08lx)\n", Status
);
204 SamrSetSecurityObject(IN SAMPR_HANDLE ObjectHandle
,
205 IN SECURITY_INFORMATION SecurityInformation
,
206 IN PSAMPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor
)
208 PSAM_DB_OBJECT DbObject
= NULL
;
209 ACCESS_MASK DesiredAccess
= 0;
210 PSECURITY_DESCRIPTOR RelativeSd
= NULL
;
211 ULONG RelativeSdSize
= 0;
212 HANDLE TokenHandle
= NULL
;
213 PGENERIC_MAPPING Mapping
;
216 TRACE("SamrSetSecurityObject(%p %lx %p)\n",
217 ObjectHandle
, SecurityInformation
, SecurityDescriptor
);
219 if ((SecurityDescriptor
== NULL
) ||
220 (SecurityDescriptor
->SecurityDescriptor
== NULL
) ||
221 !RtlValidSecurityDescriptor((PSECURITY_DESCRIPTOR
)SecurityDescriptor
->SecurityDescriptor
))
222 return ERROR_INVALID_PARAMETER
;
224 if (SecurityInformation
== 0 ||
225 SecurityInformation
& ~(OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
226 | DACL_SECURITY_INFORMATION
| SACL_SECURITY_INFORMATION
))
227 return ERROR_INVALID_PARAMETER
;
229 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
230 DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
232 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
233 DesiredAccess
|= WRITE_DAC
;
235 if (SecurityInformation
& (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
236 DesiredAccess
|= WRITE_OWNER
;
238 if ((SecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
239 (((PISECURITY_DESCRIPTOR
)SecurityDescriptor
)->Owner
== NULL
))
240 return ERROR_INVALID_PARAMETER
;
242 if ((SecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
243 (((PISECURITY_DESCRIPTOR
)SecurityDescriptor
)->Group
== NULL
))
244 return ERROR_INVALID_PARAMETER
;
246 /* Validate the server handle */
247 Status
= SampValidateDbObject(ObjectHandle
,
251 if (!NT_SUCCESS(Status
))
254 /* Get the mapping for the object type */
255 switch (DbObject
->ObjectType
)
257 case SamDbServerObject
:
258 Mapping
= &ServerMapping
;
261 case SamDbDomainObject
:
262 Mapping
= &DomainMapping
;
265 case SamDbAliasObject
:
266 Mapping
= &AliasMapping
;
269 case SamDbGroupObject
:
270 Mapping
= &GroupMapping
;
273 case SamDbUserObject
:
274 Mapping
= &UserMapping
;
278 return STATUS_INVALID_HANDLE
;
281 /* Get the size of the SD */
282 Status
= SampGetObjectAttribute(DbObject
,
287 if (!NT_SUCCESS(Status
))
290 /* Allocate a buffer for the SD */
291 RelativeSd
= RtlAllocateHeap(RtlGetProcessHeap(), 0, RelativeSdSize
);
292 if (RelativeSd
== NULL
)
293 return STATUS_INSUFFICIENT_RESOURCES
;
296 Status
= SampGetObjectAttribute(DbObject
,
301 if (!NT_SUCCESS(Status
))
304 /* Build the new security descriptor */
305 Status
= RtlSetSecurityObject(SecurityInformation
,
306 (PSECURITY_DESCRIPTOR
)SecurityDescriptor
->SecurityDescriptor
,
310 if (!NT_SUCCESS(Status
))
312 ERR("RtlSetSecurityObject failed (Status 0x%08lx)\n", Status
);
316 /* Set the modified SD */
317 Status
= SampSetObjectAttribute(DbObject
,
321 RtlLengthSecurityDescriptor(RelativeSd
));
322 if (!NT_SUCCESS(Status
))
324 ERR("SampSetObjectAttribute failed (Status 0x%08lx)\n", Status
);
328 if (TokenHandle
!= NULL
)
329 NtClose(TokenHandle
);
331 if (RelativeSd
!= NULL
)
332 RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSd
);
341 SamrQuerySecurityObject(IN SAMPR_HANDLE ObjectHandle
,
342 IN SECURITY_INFORMATION SecurityInformation
,
343 OUT PSAMPR_SR_SECURITY_DESCRIPTOR
*SecurityDescriptor
)
345 PSAM_DB_OBJECT SamObject
;
346 PSAMPR_SR_SECURITY_DESCRIPTOR SdData
= NULL
;
347 PSECURITY_DESCRIPTOR RelativeSd
= NULL
;
348 PSECURITY_DESCRIPTOR ResultSd
= NULL
;
349 ACCESS_MASK DesiredAccess
= 0;
350 ULONG RelativeSdSize
= 0;
351 ULONG ResultSdSize
= 0;
354 TRACE("(%p %lx %p)\n",
355 ObjectHandle
, SecurityInformation
, SecurityDescriptor
);
357 *SecurityDescriptor
= NULL
;
359 RtlAcquireResourceShared(&SampResource
,
362 if (SecurityInformation
& (DACL_SECURITY_INFORMATION
|
363 OWNER_SECURITY_INFORMATION
|
364 GROUP_SECURITY_INFORMATION
))
365 DesiredAccess
|= READ_CONTROL
;
367 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
368 DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
370 /* Validate the server handle */
371 Status
= SampValidateDbObject(ObjectHandle
,
375 if (!NT_SUCCESS(Status
))
378 /* Get the size of the SD */
379 Status
= SampGetObjectAttribute(SamObject
,
384 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_OVERFLOW
)
386 TRACE("Status 0x%08lx\n", Status
);
390 /* Allocate a buffer for the SD */
391 RelativeSd
= midl_user_allocate(RelativeSdSize
);
392 if (RelativeSd
== NULL
)
394 Status
= STATUS_INSUFFICIENT_RESOURCES
;
399 Status
= SampGetObjectAttribute(SamObject
,
404 if (!NT_SUCCESS(Status
))
406 TRACE("Status 0x%08lx\n", Status
);
410 /* Invalidate the SD information that was not requested */
411 if (!(SecurityInformation
& OWNER_SECURITY_INFORMATION
))
412 ((PISECURITY_DESCRIPTOR
)RelativeSd
)->Owner
= NULL
;
414 if (!(SecurityInformation
& GROUP_SECURITY_INFORMATION
))
415 ((PISECURITY_DESCRIPTOR
)RelativeSd
)->Group
= NULL
;
417 if (!(SecurityInformation
& DACL_SECURITY_INFORMATION
))
418 ((PISECURITY_DESCRIPTOR
)RelativeSd
)->Control
&= ~SE_DACL_PRESENT
;
420 if (!(SecurityInformation
& SACL_SECURITY_INFORMATION
))
421 ((PISECURITY_DESCRIPTOR
)RelativeSd
)->Control
&= ~SE_SACL_PRESENT
;
423 /* Calculate the required SD size */
424 Status
= RtlMakeSelfRelativeSD(RelativeSd
,
427 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
430 /* Allocate a buffer for the new SD */
431 ResultSd
= MIDL_user_allocate(ResultSdSize
);
432 if (ResultSd
== NULL
)
434 Status
= STATUS_INSUFFICIENT_RESOURCES
;
438 /* Build the new SD */
439 Status
= RtlMakeSelfRelativeSD(RelativeSd
,
442 if (!NT_SUCCESS(Status
))
445 /* Allocate the SD data buffer */
446 SdData
= midl_user_allocate(sizeof(SAMPR_SR_SECURITY_DESCRIPTOR
));
449 Status
= STATUS_INSUFFICIENT_RESOURCES
;
453 /* Fill the SD data buffer and return it to the caller */
454 SdData
->Length
= RelativeSdSize
;
455 SdData
->SecurityDescriptor
= (PBYTE
)ResultSd
;
457 *SecurityDescriptor
= SdData
;
460 RtlReleaseResource(&SampResource
);
462 if (!NT_SUCCESS(Status
))
464 if (ResultSd
!= NULL
)
465 MIDL_user_free(ResultSd
);
468 if (RelativeSd
!= NULL
)
469 MIDL_user_free(RelativeSd
);
478 SamrShutdownSamServer(IN SAMPR_HANDLE ServerHandle
)
480 PSAM_DB_OBJECT ServerObject
;
483 TRACE("(%p)\n", ServerHandle
);
485 RtlAcquireResourceShared(&SampResource
,
488 /* Validate the server handle */
489 Status
= SampValidateDbObject(ServerHandle
,
494 RtlReleaseResource(&SampResource
);
496 if (!NT_SUCCESS(Status
))
499 /* Shut the server down */
500 RpcMgmtStopServerListening(0);
502 return STATUS_SUCCESS
;
509 SamrLookupDomainInSamServer(IN SAMPR_HANDLE ServerHandle
,
510 IN PRPC_UNICODE_STRING Name
,
511 OUT PRPC_SID
*DomainId
)
513 PSAM_DB_OBJECT ServerObject
;
514 HANDLE DomainsKeyHandle
= NULL
;
515 HANDLE DomainKeyHandle
= NULL
;
516 WCHAR DomainKeyName
[64];
518 WCHAR DomainNameString
[MAX_COMPUTERNAME_LENGTH
+ 1];
519 UNICODE_STRING DomainName
;
524 TRACE("SamrLookupDomainInSamServer(%p %p %p)\n",
525 ServerHandle
, Name
, DomainId
);
527 RtlAcquireResourceShared(&SampResource
,
530 /* Validate the server handle */
531 Status
= SampValidateDbObject(ServerHandle
,
533 SAM_SERVER_LOOKUP_DOMAIN
,
535 if (!NT_SUCCESS(Status
))
540 Status
= SampRegOpenKey(ServerObject
->KeyHandle
,
544 if (!NT_SUCCESS(Status
))
548 while (Found
== FALSE
)
550 Status
= SampRegEnumerateSubKey(DomainsKeyHandle
,
554 if (!NT_SUCCESS(Status
))
556 if (Status
== STATUS_NO_MORE_ENTRIES
)
557 Status
= STATUS_NO_SUCH_DOMAIN
;
561 TRACE("Domain key name: %S\n", DomainKeyName
);
563 Status
= SampRegOpenKey(DomainsKeyHandle
,
567 if (NT_SUCCESS(Status
))
569 Length
= (MAX_COMPUTERNAME_LENGTH
+ 1) * sizeof(WCHAR
);
570 Status
= SampRegQueryValue(DomainKeyHandle
,
573 (PVOID
)&DomainNameString
,
575 if (NT_SUCCESS(Status
))
577 TRACE("Domain name: %S\n", DomainNameString
);
579 RtlInitUnicodeString(&DomainName
,
581 if (RtlEqualUnicodeString(&DomainName
, (PUNICODE_STRING
)Name
, TRUE
))
583 TRACE("Found it!\n");
586 Status
= SampRegQueryValue(DomainKeyHandle
,
591 if (NT_SUCCESS(Status
))
593 *DomainId
= midl_user_allocate(Length
);
595 SampRegQueryValue(DomainKeyHandle
,
601 Status
= STATUS_SUCCESS
;
607 SampRegCloseKey(&DomainKeyHandle
);
614 SampRegCloseKey(&DomainKeyHandle
);
615 SampRegCloseKey(&DomainsKeyHandle
);
617 RtlReleaseResource(&SampResource
);
626 SamrEnumerateDomainsInSamServer(IN SAMPR_HANDLE ServerHandle
,
627 IN OUT
unsigned long *EnumerationContext
,
628 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
629 IN ULONG PreferedMaximumLength
,
630 OUT PULONG CountReturned
)
632 PSAM_DB_OBJECT ServerObject
;
633 WCHAR DomainKeyName
[64];
634 HANDLE DomainsKeyHandle
= NULL
;
635 HANDLE DomainKeyHandle
= NULL
;
638 ULONG RequiredLength
;
641 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
644 TRACE("SamrEnumerateDomainsInSamServer(%p %p %p %lu %p)\n",
645 ServerHandle
, EnumerationContext
, Buffer
, PreferedMaximumLength
,
648 RtlAcquireResourceShared(&SampResource
,
651 /* Validate the server handle */
652 Status
= SampValidateDbObject(ServerHandle
,
654 SAM_SERVER_ENUMERATE_DOMAINS
,
656 if (!NT_SUCCESS(Status
))
659 Status
= SampRegOpenKey(ServerObject
->KeyHandle
,
663 if (!NT_SUCCESS(Status
))
666 EnumIndex
= *EnumerationContext
;
672 Status
= SampRegEnumerateSubKey(DomainsKeyHandle
,
676 if (!NT_SUCCESS(Status
))
679 TRACE("EnumIndex: %lu\n", EnumIndex
);
680 TRACE("Domain key name: %S\n", DomainKeyName
);
682 Status
= SampRegOpenKey(DomainsKeyHandle
,
686 TRACE("SampRegOpenKey returned %08lX\n", Status
);
687 if (NT_SUCCESS(Status
))
690 Status
= SampRegQueryValue(DomainKeyHandle
,
695 TRACE("SampRegQueryValue returned %08lX\n", Status
);
696 if (NT_SUCCESS(Status
))
698 TRACE("Data length: %lu\n", DataLength
);
700 if ((RequiredLength
+ DataLength
+ sizeof(UNICODE_STRING
)) > PreferedMaximumLength
)
703 RequiredLength
+= (DataLength
+ sizeof(UNICODE_STRING
));
707 SampRegCloseKey(&DomainKeyHandle
);
713 TRACE("EnumCount: %lu\n", EnumCount
);
714 TRACE("RequiredLength: %lu\n", RequiredLength
);
716 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
717 if (EnumBuffer
== NULL
)
719 Status
= STATUS_INSUFFICIENT_RESOURCES
;
723 EnumBuffer
->EntriesRead
= EnumCount
;
724 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
725 if (EnumBuffer
->Buffer
== NULL
)
727 Status
= STATUS_INSUFFICIENT_RESOURCES
;
731 EnumIndex
= *EnumerationContext
;
732 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
734 Status
= SampRegEnumerateSubKey(DomainsKeyHandle
,
738 if (!NT_SUCCESS(Status
))
741 TRACE("EnumIndex: %lu\n", EnumIndex
);
742 TRACE("Domain key name: %S\n", DomainKeyName
);
744 Status
= SampRegOpenKey(DomainsKeyHandle
,
748 TRACE("SampRegOpenKey returned %08lX\n", Status
);
749 if (NT_SUCCESS(Status
))
752 Status
= SampRegQueryValue(DomainKeyHandle
,
757 TRACE("SampRegQueryValue returned %08lX\n", Status
);
758 if (NT_SUCCESS(Status
))
760 EnumBuffer
->Buffer
[i
].RelativeId
= 0;
761 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)DataLength
- sizeof(WCHAR
);
762 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)DataLength
;
763 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(DataLength
);
764 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
766 SampRegCloseKey(&DomainKeyHandle
);
767 Status
= STATUS_INSUFFICIENT_RESOURCES
;
771 Status
= SampRegQueryValue(DomainKeyHandle
,
774 EnumBuffer
->Buffer
[i
].Name
.Buffer
,
776 TRACE("SampRegQueryValue returned %08lX\n", Status
);
777 if (NT_SUCCESS(Status
))
779 TRACE("Domain name: %S\n", EnumBuffer
->Buffer
[i
].Name
.Buffer
);
783 SampRegCloseKey(&DomainKeyHandle
);
785 if (!NT_SUCCESS(Status
))
790 if (NT_SUCCESS(Status
))
792 *EnumerationContext
+= EnumCount
;
793 *Buffer
= EnumBuffer
;
794 *CountReturned
= EnumCount
;
798 SampRegCloseKey(&DomainKeyHandle
);
799 SampRegCloseKey(&DomainsKeyHandle
);
801 if (!NT_SUCCESS(Status
))
803 *EnumerationContext
= 0;
807 if (EnumBuffer
!= NULL
)
809 if (EnumBuffer
->Buffer
!= NULL
)
811 if (EnumBuffer
->EntriesRead
!= 0)
813 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
815 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
816 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
820 midl_user_free(EnumBuffer
->Buffer
);
823 midl_user_free(EnumBuffer
);
827 RtlReleaseResource(&SampResource
);
836 SamrOpenDomain(IN SAMPR_HANDLE ServerHandle
,
837 IN ACCESS_MASK DesiredAccess
,
838 IN PRPC_SID DomainId
,
839 OUT SAMPR_HANDLE
*DomainHandle
)
841 PSAM_DB_OBJECT ServerObject
;
842 PSAM_DB_OBJECT DomainObject
;
845 TRACE("SamrOpenDomain(%p %lx %p %p)\n",
846 ServerHandle
, DesiredAccess
, DomainId
, DomainHandle
);
848 /* Map generic access rights */
849 RtlMapGenericMask(&DesiredAccess
,
852 RtlAcquireResourceShared(&SampResource
,
855 /* Validate the server handle */
856 Status
= SampValidateDbObject(ServerHandle
,
858 SAM_SERVER_LOOKUP_DOMAIN
,
860 if (!NT_SUCCESS(Status
))
863 /* Validate the Domain SID */
864 if ((DomainId
->Revision
!= SID_REVISION
) ||
865 (DomainId
->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
) ||
866 (memcmp(&DomainId
->IdentifierAuthority
, &NtSidAuthority
, sizeof(SID_IDENTIFIER_AUTHORITY
)) != 0))
867 return STATUS_INVALID_PARAMETER
;
869 /* Open the domain object */
870 if ((DomainId
->SubAuthorityCount
== 1) &&
871 (DomainId
->SubAuthority
[0] == SECURITY_BUILTIN_DOMAIN_RID
))
873 /* Builtin domain object */
874 TRACE("Opening the builtin domain object.\n");
876 Status
= SampOpenDbObject(ServerObject
,
884 else if ((DomainId
->SubAuthorityCount
== 4) &&
885 (DomainId
->SubAuthority
[0] == SECURITY_NT_NON_UNIQUE
))
887 /* Account domain object */
888 TRACE("Opening the account domain object.\n");
890 /* FIXME: Check the account domain sub authorities!!! */
892 Status
= SampOpenDbObject(ServerObject
,
902 /* No valid domain SID */
903 Status
= STATUS_INVALID_PARAMETER
;
906 if (NT_SUCCESS(Status
))
907 *DomainHandle
= (SAMPR_HANDLE
)DomainObject
;
909 RtlReleaseResource(&SampResource
);
911 TRACE("SamrOpenDomain done (Status 0x%08lx)\n", Status
);
918 SampQueryDomainPassword(PSAM_DB_OBJECT DomainObject
,
919 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
921 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
922 SAM_DOMAIN_FIXED_DATA FixedData
;
928 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
929 if (InfoBuffer
== NULL
)
930 return STATUS_INSUFFICIENT_RESOURCES
;
932 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
933 Status
= SampGetObjectAttribute(DomainObject
,
938 if (!NT_SUCCESS(Status
))
941 InfoBuffer
->Password
.MinPasswordLength
= FixedData
.MinPasswordLength
;
942 InfoBuffer
->Password
.PasswordHistoryLength
= FixedData
.PasswordHistoryLength
;
943 InfoBuffer
->Password
.PasswordProperties
= FixedData
.PasswordProperties
;
944 InfoBuffer
->Password
.MaxPasswordAge
.LowPart
= FixedData
.MaxPasswordAge
.LowPart
;
945 InfoBuffer
->Password
.MaxPasswordAge
.HighPart
= FixedData
.MaxPasswordAge
.HighPart
;
946 InfoBuffer
->Password
.MinPasswordAge
.LowPart
= FixedData
.MinPasswordAge
.LowPart
;
947 InfoBuffer
->Password
.MinPasswordAge
.HighPart
= FixedData
.MinPasswordAge
.HighPart
;
949 *Buffer
= InfoBuffer
;
952 if (!NT_SUCCESS(Status
))
954 if (InfoBuffer
!= NULL
)
956 midl_user_free(InfoBuffer
);
965 SampGetNumberOfAccounts(PSAM_DB_OBJECT DomainObject
,
969 HANDLE AccountKeyHandle
= NULL
;
970 HANDLE NamesKeyHandle
= NULL
;
975 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
979 if (!NT_SUCCESS(Status
))
982 Status
= SampRegOpenKey(AccountKeyHandle
,
986 if (!NT_SUCCESS(Status
))
989 Status
= SampRegQueryKeyInfo(NamesKeyHandle
,
994 SampRegCloseKey(&NamesKeyHandle
);
995 SampRegCloseKey(&AccountKeyHandle
);
1002 SampQueryDomainGeneral(PSAM_DB_OBJECT DomainObject
,
1003 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1005 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1006 SAM_DOMAIN_FIXED_DATA FixedData
;
1012 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1013 if (InfoBuffer
== NULL
)
1014 return STATUS_INSUFFICIENT_RESOURCES
;
1016 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1017 Status
= SampGetObjectAttribute(DomainObject
,
1022 if (!NT_SUCCESS(Status
))
1025 InfoBuffer
->General
.ForceLogoff
.LowPart
= FixedData
.ForceLogoff
.LowPart
;
1026 InfoBuffer
->General
.ForceLogoff
.HighPart
= FixedData
.ForceLogoff
.HighPart
;
1027 InfoBuffer
->General
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
1028 InfoBuffer
->General
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
1029 InfoBuffer
->General
.DomainServerState
= FixedData
.DomainServerState
;
1030 InfoBuffer
->General
.DomainServerRole
= FixedData
.DomainServerRole
;
1031 InfoBuffer
->General
.UasCompatibilityRequired
= FixedData
.UasCompatibilityRequired
;
1033 /* Get the OemInformation string */
1034 Status
= SampGetObjectAttributeString(DomainObject
,
1036 &InfoBuffer
->General
.OemInformation
);
1037 if (!NT_SUCCESS(Status
))
1039 TRACE("Status 0x%08lx\n", Status
);
1043 /* Get the Name string */
1044 Status
= SampGetObjectAttributeString(DomainObject
,
1046 &InfoBuffer
->General
.DomainName
);
1047 if (!NT_SUCCESS(Status
))
1049 TRACE("Status 0x%08lx\n", Status
);
1053 /* Get the ReplicaSourceNodeName string */
1054 Status
= SampGetObjectAttributeString(DomainObject
,
1055 L
"ReplicaSourceNodeName",
1056 &InfoBuffer
->General
.ReplicaSourceNodeName
);
1057 if (!NT_SUCCESS(Status
))
1059 TRACE("Status 0x%08lx\n", Status
);
1063 /* Get the number of Users in the Domain */
1064 Status
= SampGetNumberOfAccounts(DomainObject
,
1066 &InfoBuffer
->General
.UserCount
);
1067 if (!NT_SUCCESS(Status
))
1069 TRACE("Status 0x%08lx\n", Status
);
1073 /* Get the number of Groups in the Domain */
1074 Status
= SampGetNumberOfAccounts(DomainObject
,
1076 &InfoBuffer
->General
.GroupCount
);
1077 if (!NT_SUCCESS(Status
))
1079 TRACE("Status 0x%08lx\n", Status
);
1083 /* Get the number of Aliases in the Domain */
1084 Status
= SampGetNumberOfAccounts(DomainObject
,
1086 &InfoBuffer
->General
.AliasCount
);
1087 if (!NT_SUCCESS(Status
))
1089 TRACE("Status 0x%08lx\n", Status
);
1093 *Buffer
= InfoBuffer
;
1096 if (!NT_SUCCESS(Status
))
1098 if (InfoBuffer
!= NULL
)
1100 if (InfoBuffer
->General
.OemInformation
.Buffer
!= NULL
)
1101 midl_user_free(InfoBuffer
->General
.OemInformation
.Buffer
);
1103 if (InfoBuffer
->General
.DomainName
.Buffer
!= NULL
)
1104 midl_user_free(InfoBuffer
->General
.DomainName
.Buffer
);
1106 if (InfoBuffer
->General
.ReplicaSourceNodeName
.Buffer
!= NULL
)
1107 midl_user_free(InfoBuffer
->General
.ReplicaSourceNodeName
.Buffer
);
1109 midl_user_free(InfoBuffer
);
1118 SampQueryDomainLogoff(PSAM_DB_OBJECT DomainObject
,
1119 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1121 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1122 SAM_DOMAIN_FIXED_DATA FixedData
;
1128 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1129 if (InfoBuffer
== NULL
)
1130 return STATUS_INSUFFICIENT_RESOURCES
;
1132 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1133 Status
= SampGetObjectAttribute(DomainObject
,
1138 if (!NT_SUCCESS(Status
))
1141 InfoBuffer
->Logoff
.ForceLogoff
.LowPart
= FixedData
.ForceLogoff
.LowPart
;
1142 InfoBuffer
->Logoff
.ForceLogoff
.HighPart
= FixedData
.ForceLogoff
.HighPart
;
1144 *Buffer
= InfoBuffer
;
1147 if (!NT_SUCCESS(Status
))
1149 if (InfoBuffer
!= NULL
)
1151 midl_user_free(InfoBuffer
);
1160 SampQueryDomainOem(PSAM_DB_OBJECT DomainObject
,
1161 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1163 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1168 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1169 if (InfoBuffer
== NULL
)
1170 return STATUS_INSUFFICIENT_RESOURCES
;
1172 /* Get the OemInformation string */
1173 Status
= SampGetObjectAttributeString(DomainObject
,
1175 &InfoBuffer
->Oem
.OemInformation
);
1176 if (!NT_SUCCESS(Status
))
1178 TRACE("Status 0x%08lx\n", Status
);
1182 *Buffer
= InfoBuffer
;
1185 if (!NT_SUCCESS(Status
))
1187 if (InfoBuffer
!= NULL
)
1189 if (InfoBuffer
->Oem
.OemInformation
.Buffer
!= NULL
)
1190 midl_user_free(InfoBuffer
->Oem
.OemInformation
.Buffer
);
1192 midl_user_free(InfoBuffer
);
1201 SampQueryDomainName(PSAM_DB_OBJECT DomainObject
,
1202 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1204 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1209 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1210 if (InfoBuffer
== NULL
)
1211 return STATUS_INSUFFICIENT_RESOURCES
;
1213 /* Get the Name string */
1214 Status
= SampGetObjectAttributeString(DomainObject
,
1216 &InfoBuffer
->Name
.DomainName
);
1217 if (!NT_SUCCESS(Status
))
1219 TRACE("Status 0x%08lx\n", Status
);
1223 *Buffer
= InfoBuffer
;
1226 if (!NT_SUCCESS(Status
))
1228 if (InfoBuffer
!= NULL
)
1230 if (InfoBuffer
->Name
.DomainName
.Buffer
!= NULL
)
1231 midl_user_free(InfoBuffer
->Name
.DomainName
.Buffer
);
1233 midl_user_free(InfoBuffer
);
1242 SampQueryDomainReplication(PSAM_DB_OBJECT DomainObject
,
1243 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1245 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1250 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1251 if (InfoBuffer
== NULL
)
1252 return STATUS_INSUFFICIENT_RESOURCES
;
1254 /* Get the ReplicaSourceNodeName string */
1255 Status
= SampGetObjectAttributeString(DomainObject
,
1256 L
"ReplicaSourceNodeName",
1257 &InfoBuffer
->Replication
.ReplicaSourceNodeName
);
1258 if (!NT_SUCCESS(Status
))
1260 TRACE("Status 0x%08lx\n", Status
);
1264 *Buffer
= InfoBuffer
;
1267 if (!NT_SUCCESS(Status
))
1269 if (InfoBuffer
!= NULL
)
1271 if (InfoBuffer
->Replication
.ReplicaSourceNodeName
.Buffer
!= NULL
)
1272 midl_user_free(InfoBuffer
->Replication
.ReplicaSourceNodeName
.Buffer
);
1274 midl_user_free(InfoBuffer
);
1283 SampQueryDomainServerRole(PSAM_DB_OBJECT DomainObject
,
1284 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1286 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1287 SAM_DOMAIN_FIXED_DATA FixedData
;
1293 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1294 if (InfoBuffer
== NULL
)
1295 return STATUS_INSUFFICIENT_RESOURCES
;
1297 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1298 Status
= SampGetObjectAttribute(DomainObject
,
1303 if (!NT_SUCCESS(Status
))
1306 InfoBuffer
->Role
.DomainServerRole
= FixedData
.DomainServerRole
;
1308 *Buffer
= InfoBuffer
;
1311 if (!NT_SUCCESS(Status
))
1313 if (InfoBuffer
!= NULL
)
1315 midl_user_free(InfoBuffer
);
1324 SampQueryDomainModified(PSAM_DB_OBJECT DomainObject
,
1325 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1327 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1328 SAM_DOMAIN_FIXED_DATA FixedData
;
1334 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1335 if (InfoBuffer
== NULL
)
1336 return STATUS_INSUFFICIENT_RESOURCES
;
1338 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1339 Status
= SampGetObjectAttribute(DomainObject
,
1344 if (!NT_SUCCESS(Status
))
1347 InfoBuffer
->Modified
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
1348 InfoBuffer
->Modified
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
1349 InfoBuffer
->Modified
.CreationTime
.LowPart
= FixedData
.CreationTime
.LowPart
;
1350 InfoBuffer
->Modified
.CreationTime
.HighPart
= FixedData
.CreationTime
.HighPart
;
1352 *Buffer
= InfoBuffer
;
1355 if (!NT_SUCCESS(Status
))
1357 if (InfoBuffer
!= NULL
)
1359 midl_user_free(InfoBuffer
);
1368 SampQueryDomainState(PSAM_DB_OBJECT DomainObject
,
1369 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1371 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1372 SAM_DOMAIN_FIXED_DATA FixedData
;
1378 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1379 if (InfoBuffer
== NULL
)
1380 return STATUS_INSUFFICIENT_RESOURCES
;
1382 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1383 Status
= SampGetObjectAttribute(DomainObject
,
1388 if (!NT_SUCCESS(Status
))
1391 InfoBuffer
->State
.DomainServerState
= FixedData
.DomainServerState
;
1393 *Buffer
= InfoBuffer
;
1396 if (!NT_SUCCESS(Status
))
1398 if (InfoBuffer
!= NULL
)
1400 midl_user_free(InfoBuffer
);
1409 SampQueryDomainGeneral2(PSAM_DB_OBJECT DomainObject
,
1410 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1412 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1413 SAM_DOMAIN_FIXED_DATA FixedData
;
1419 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1420 if (InfoBuffer
== NULL
)
1421 return STATUS_INSUFFICIENT_RESOURCES
;
1423 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1424 Status
= SampGetObjectAttribute(DomainObject
,
1429 if (!NT_SUCCESS(Status
))
1432 InfoBuffer
->General2
.I1
.ForceLogoff
.LowPart
= FixedData
.ForceLogoff
.LowPart
;
1433 InfoBuffer
->General2
.I1
.ForceLogoff
.HighPart
= FixedData
.ForceLogoff
.HighPart
;
1434 InfoBuffer
->General2
.I1
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
1435 InfoBuffer
->General2
.I1
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
1436 InfoBuffer
->General2
.I1
.DomainServerState
= FixedData
.DomainServerState
;
1437 InfoBuffer
->General2
.I1
.DomainServerRole
= FixedData
.DomainServerRole
;
1438 InfoBuffer
->General2
.I1
.UasCompatibilityRequired
= FixedData
.UasCompatibilityRequired
;
1440 InfoBuffer
->General2
.LockoutDuration
= FixedData
.LockoutDuration
;
1441 InfoBuffer
->General2
.LockoutObservationWindow
= FixedData
.LockoutObservationWindow
;
1442 InfoBuffer
->General2
.LockoutThreshold
= FixedData
.LockoutThreshold
;
1444 /* Get the OemInformation string */
1445 Status
= SampGetObjectAttributeString(DomainObject
,
1447 &InfoBuffer
->General2
.I1
.OemInformation
);
1448 if (!NT_SUCCESS(Status
))
1450 TRACE("Status 0x%08lx\n", Status
);
1454 /* Get the Name string */
1455 Status
= SampGetObjectAttributeString(DomainObject
,
1457 &InfoBuffer
->General2
.I1
.DomainName
);
1458 if (!NT_SUCCESS(Status
))
1460 TRACE("Status 0x%08lx\n", Status
);
1464 /* Get the ReplicaSourceNodeName string */
1465 Status
= SampGetObjectAttributeString(DomainObject
,
1466 L
"ReplicaSourceNodeName",
1467 &InfoBuffer
->General2
.I1
.ReplicaSourceNodeName
);
1468 if (!NT_SUCCESS(Status
))
1470 TRACE("Status 0x%08lx\n", Status
);
1474 /* Get the number of Users in the Domain */
1475 Status
= SampGetNumberOfAccounts(DomainObject
,
1477 &InfoBuffer
->General2
.I1
.UserCount
);
1478 if (!NT_SUCCESS(Status
))
1480 TRACE("Status 0x%08lx\n", Status
);
1484 /* Get the number of Groups in the Domain */
1485 Status
= SampGetNumberOfAccounts(DomainObject
,
1487 &InfoBuffer
->General2
.I1
.GroupCount
);
1488 if (!NT_SUCCESS(Status
))
1490 TRACE("Status 0x%08lx\n", Status
);
1494 /* Get the number of Aliases in the Domain */
1495 Status
= SampGetNumberOfAccounts(DomainObject
,
1497 &InfoBuffer
->General2
.I1
.AliasCount
);
1498 if (!NT_SUCCESS(Status
))
1500 TRACE("Status 0x%08lx\n", Status
);
1504 *Buffer
= InfoBuffer
;
1507 if (!NT_SUCCESS(Status
))
1509 if (InfoBuffer
!= NULL
)
1511 if (InfoBuffer
->General2
.I1
.OemInformation
.Buffer
!= NULL
)
1512 midl_user_free(InfoBuffer
->General2
.I1
.OemInformation
.Buffer
);
1514 if (InfoBuffer
->General2
.I1
.DomainName
.Buffer
!= NULL
)
1515 midl_user_free(InfoBuffer
->General2
.I1
.DomainName
.Buffer
);
1517 if (InfoBuffer
->General2
.I1
.ReplicaSourceNodeName
.Buffer
!= NULL
)
1518 midl_user_free(InfoBuffer
->General2
.I1
.ReplicaSourceNodeName
.Buffer
);
1520 midl_user_free(InfoBuffer
);
1529 SampQueryDomainLockout(PSAM_DB_OBJECT DomainObject
,
1530 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1532 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1533 SAM_DOMAIN_FIXED_DATA FixedData
;
1539 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1540 if (InfoBuffer
== NULL
)
1541 return STATUS_INSUFFICIENT_RESOURCES
;
1543 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1544 Status
= SampGetObjectAttribute(DomainObject
,
1549 if (!NT_SUCCESS(Status
))
1552 InfoBuffer
->Lockout
.LockoutDuration
= FixedData
.LockoutDuration
;
1553 InfoBuffer
->Lockout
.LockoutObservationWindow
= FixedData
.LockoutObservationWindow
;
1554 InfoBuffer
->Lockout
.LockoutThreshold
= FixedData
.LockoutThreshold
;
1556 *Buffer
= InfoBuffer
;
1559 if (!NT_SUCCESS(Status
))
1561 if (InfoBuffer
!= NULL
)
1563 midl_user_free(InfoBuffer
);
1572 SampQueryDomainModified2(PSAM_DB_OBJECT DomainObject
,
1573 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1575 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1576 SAM_DOMAIN_FIXED_DATA FixedData
;
1582 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1583 if (InfoBuffer
== NULL
)
1584 return STATUS_INSUFFICIENT_RESOURCES
;
1586 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1587 Status
= SampGetObjectAttribute(DomainObject
,
1592 if (!NT_SUCCESS(Status
))
1595 InfoBuffer
->Modified2
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
1596 InfoBuffer
->Modified2
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
1597 InfoBuffer
->Modified2
.CreationTime
.LowPart
= FixedData
.CreationTime
.LowPart
;
1598 InfoBuffer
->Modified2
.CreationTime
.HighPart
= FixedData
.CreationTime
.HighPart
;
1599 InfoBuffer
->Modified2
.ModifiedCountAtLastPromotion
.LowPart
= FixedData
.ModifiedCountAtLastPromotion
.LowPart
;
1600 InfoBuffer
->Modified2
.ModifiedCountAtLastPromotion
.HighPart
= FixedData
.ModifiedCountAtLastPromotion
.HighPart
;
1602 *Buffer
= InfoBuffer
;
1605 if (!NT_SUCCESS(Status
))
1607 if (InfoBuffer
!= NULL
)
1609 midl_user_free(InfoBuffer
);
1620 SamrQueryInformationDomain(IN SAMPR_HANDLE DomainHandle
,
1621 IN DOMAIN_INFORMATION_CLASS DomainInformationClass
,
1622 OUT PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1624 PSAM_DB_OBJECT DomainObject
;
1625 ACCESS_MASK DesiredAccess
;
1628 TRACE("SamrQueryInformationDomain(%p %lu %p)\n",
1629 DomainHandle
, DomainInformationClass
, Buffer
);
1631 switch (DomainInformationClass
)
1633 case DomainPasswordInformation
:
1634 case DomainLockoutInformation
:
1635 DesiredAccess
= DOMAIN_READ_PASSWORD_PARAMETERS
;
1638 case DomainGeneralInformation
:
1639 case DomainLogoffInformation
:
1640 case DomainOemInformation
:
1641 case DomainNameInformation
:
1642 case DomainReplicationInformation
:
1643 case DomainServerRoleInformation
:
1644 case DomainModifiedInformation
:
1645 case DomainStateInformation
:
1646 case DomainModifiedInformation2
:
1647 DesiredAccess
= DOMAIN_READ_OTHER_PARAMETERS
;
1650 case DomainGeneralInformation2
:
1651 DesiredAccess
= DOMAIN_READ_PASSWORD_PARAMETERS
|
1652 DOMAIN_READ_OTHER_PARAMETERS
;
1656 return STATUS_INVALID_INFO_CLASS
;
1659 RtlAcquireResourceShared(&SampResource
,
1662 /* Validate the server handle */
1663 Status
= SampValidateDbObject(DomainHandle
,
1667 if (!NT_SUCCESS(Status
))
1670 switch (DomainInformationClass
)
1672 case DomainPasswordInformation
:
1673 Status
= SampQueryDomainPassword(DomainObject
,
1677 case DomainGeneralInformation
:
1678 Status
= SampQueryDomainGeneral(DomainObject
,
1682 case DomainLogoffInformation
:
1683 Status
= SampQueryDomainLogoff(DomainObject
,
1687 case DomainOemInformation
:
1688 Status
= SampQueryDomainOem(DomainObject
,
1692 case DomainNameInformation
:
1693 Status
= SampQueryDomainName(DomainObject
,
1697 case DomainReplicationInformation
:
1698 Status
= SampQueryDomainReplication(DomainObject
,
1702 case DomainServerRoleInformation
:
1703 Status
= SampQueryDomainServerRole(DomainObject
,
1707 case DomainModifiedInformation
:
1708 Status
= SampQueryDomainModified(DomainObject
,
1712 case DomainStateInformation
:
1713 Status
= SampQueryDomainState(DomainObject
,
1717 case DomainGeneralInformation2
:
1718 Status
= SampQueryDomainGeneral2(DomainObject
,
1722 case DomainLockoutInformation
:
1723 Status
= SampQueryDomainLockout(DomainObject
,
1727 case DomainModifiedInformation2
:
1728 Status
= SampQueryDomainModified2(DomainObject
,
1733 Status
= STATUS_NOT_IMPLEMENTED
;
1737 RtlReleaseResource(&SampResource
);
1744 SampSetDomainPassword(PSAM_DB_OBJECT DomainObject
,
1745 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1747 SAM_DOMAIN_FIXED_DATA FixedData
;
1751 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1752 Status
= SampGetObjectAttribute(DomainObject
,
1757 if (!NT_SUCCESS(Status
))
1760 FixedData
.MinPasswordLength
= Buffer
->Password
.MinPasswordLength
;
1761 FixedData
.PasswordHistoryLength
= Buffer
->Password
.PasswordHistoryLength
;
1762 FixedData
.PasswordProperties
= Buffer
->Password
.PasswordProperties
;
1763 FixedData
.MaxPasswordAge
.LowPart
= Buffer
->Password
.MaxPasswordAge
.LowPart
;
1764 FixedData
.MaxPasswordAge
.HighPart
= Buffer
->Password
.MaxPasswordAge
.HighPart
;
1765 FixedData
.MinPasswordAge
.LowPart
= Buffer
->Password
.MinPasswordAge
.LowPart
;
1766 FixedData
.MinPasswordAge
.HighPart
= Buffer
->Password
.MinPasswordAge
.HighPart
;
1768 Status
= SampSetObjectAttribute(DomainObject
,
1780 SampSetDomainLogoff(PSAM_DB_OBJECT DomainObject
,
1781 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1783 SAM_DOMAIN_FIXED_DATA FixedData
;
1787 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1788 Status
= SampGetObjectAttribute(DomainObject
,
1793 if (!NT_SUCCESS(Status
))
1796 FixedData
.ForceLogoff
.LowPart
= Buffer
->Logoff
.ForceLogoff
.LowPart
;
1797 FixedData
.ForceLogoff
.HighPart
= Buffer
->Logoff
.ForceLogoff
.HighPart
;
1799 Status
= SampSetObjectAttribute(DomainObject
,
1811 SampSetDomainServerRole(PSAM_DB_OBJECT DomainObject
,
1812 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1814 SAM_DOMAIN_FIXED_DATA FixedData
;
1818 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1819 Status
= SampGetObjectAttribute(DomainObject
,
1824 if (!NT_SUCCESS(Status
))
1827 FixedData
.DomainServerRole
= Buffer
->Role
.DomainServerRole
;
1829 Status
= SampSetObjectAttribute(DomainObject
,
1841 SampSetDomainState(PSAM_DB_OBJECT DomainObject
,
1842 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1844 SAM_DOMAIN_FIXED_DATA FixedData
;
1848 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1849 Status
= SampGetObjectAttribute(DomainObject
,
1854 if (!NT_SUCCESS(Status
))
1857 FixedData
.DomainServerState
= Buffer
->State
.DomainServerState
;
1859 Status
= SampSetObjectAttribute(DomainObject
,
1871 SampSetDomainLockout(PSAM_DB_OBJECT DomainObject
,
1872 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1874 SAM_DOMAIN_FIXED_DATA FixedData
;
1878 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1879 Status
= SampGetObjectAttribute(DomainObject
,
1884 if (!NT_SUCCESS(Status
))
1887 FixedData
.LockoutDuration
= Buffer
->Lockout
.LockoutDuration
;
1888 FixedData
.LockoutObservationWindow
= Buffer
->Lockout
.LockoutObservationWindow
;
1889 FixedData
.LockoutThreshold
= Buffer
->Lockout
.LockoutThreshold
;
1891 Status
= SampSetObjectAttribute(DomainObject
,
1905 SamrSetInformationDomain(IN SAMPR_HANDLE DomainHandle
,
1906 IN DOMAIN_INFORMATION_CLASS DomainInformationClass
,
1907 IN PSAMPR_DOMAIN_INFO_BUFFER DomainInformation
)
1909 PSAM_DB_OBJECT DomainObject
;
1910 ACCESS_MASK DesiredAccess
;
1913 TRACE("SamrSetInformationDomain(%p %lu %p)\n",
1914 DomainHandle
, DomainInformationClass
, DomainInformation
);
1916 switch (DomainInformationClass
)
1918 case DomainPasswordInformation
:
1919 case DomainLockoutInformation
:
1920 DesiredAccess
= DOMAIN_WRITE_PASSWORD_PARAMS
;
1923 case DomainLogoffInformation
:
1924 case DomainOemInformation
:
1925 case DomainNameInformation
:
1926 DesiredAccess
= DOMAIN_WRITE_OTHER_PARAMETERS
;
1929 case DomainReplicationInformation
:
1930 case DomainServerRoleInformation
:
1931 case DomainStateInformation
:
1932 DesiredAccess
= DOMAIN_ADMINISTER_SERVER
;
1936 return STATUS_INVALID_INFO_CLASS
;
1939 RtlAcquireResourceExclusive(&SampResource
,
1942 /* Validate the server handle */
1943 Status
= SampValidateDbObject(DomainHandle
,
1947 if (!NT_SUCCESS(Status
))
1950 switch (DomainInformationClass
)
1952 case DomainPasswordInformation
:
1953 Status
= SampSetDomainPassword(DomainObject
,
1957 case DomainLogoffInformation
:
1958 Status
= SampSetDomainLogoff(DomainObject
,
1962 case DomainOemInformation
:
1963 Status
= SampSetObjectAttributeString(DomainObject
,
1965 &DomainInformation
->Oem
.OemInformation
);
1968 case DomainNameInformation
:
1969 Status
= SampSetObjectAttributeString(DomainObject
,
1971 &DomainInformation
->Name
.DomainName
);
1974 case DomainReplicationInformation
:
1975 Status
= SampSetObjectAttributeString(DomainObject
,
1976 L
"ReplicaSourceNodeName",
1977 &DomainInformation
->Replication
.ReplicaSourceNodeName
);
1980 case DomainServerRoleInformation
:
1981 Status
= SampSetDomainServerRole(DomainObject
,
1985 case DomainStateInformation
:
1986 Status
= SampSetDomainState(DomainObject
,
1990 case DomainLockoutInformation
:
1991 Status
= SampSetDomainLockout(DomainObject
,
1996 Status
= STATUS_NOT_IMPLEMENTED
;
2000 RtlReleaseResource(&SampResource
);
2009 SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle
,
2010 IN PRPC_UNICODE_STRING Name
,
2011 IN ACCESS_MASK DesiredAccess
,
2012 OUT SAMPR_HANDLE
*GroupHandle
,
2013 OUT
unsigned long *RelativeId
)
2015 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
2016 SAM_GROUP_FIXED_DATA FixedGroupData
;
2017 PSAM_DB_OBJECT DomainObject
;
2018 PSAM_DB_OBJECT GroupObject
;
2019 PSECURITY_DESCRIPTOR Sd
= NULL
;
2026 TRACE("SamrCreateGroupInDomain(%p %p %lx %p %p)\n",
2027 DomainHandle
, Name
, DesiredAccess
, GroupHandle
, RelativeId
);
2029 /* Map generic access rights */
2030 RtlMapGenericMask(&DesiredAccess
,
2033 RtlAcquireResourceExclusive(&SampResource
,
2036 /* Validate the domain handle */
2037 Status
= SampValidateDbObject(DomainHandle
,
2039 DOMAIN_CREATE_GROUP
,
2041 if (!NT_SUCCESS(Status
))
2043 TRACE("failed with status 0x%08lx\n", Status
);
2047 /* Check the group account name */
2048 Status
= SampCheckAccountName(Name
, 256);
2049 if (!NT_SUCCESS(Status
))
2051 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
2055 /* Check if the group name already exists in the domain */
2056 Status
= SampCheckAccountNameInDomain(DomainObject
,
2058 if (!NT_SUCCESS(Status
))
2060 TRACE("Group name \'%S\' already exists in domain (Status 0x%08lx)\n",
2061 Name
->Buffer
, Status
);
2065 /* Create the security descriptor */
2066 Status
= SampCreateGroupSD(&Sd
,
2068 if (!NT_SUCCESS(Status
))
2070 TRACE("SampCreateGroupSD failed (Status 0x%08lx)\n", Status
);
2074 /* Get the fixed domain attributes */
2075 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
2076 Status
= SampGetObjectAttribute(DomainObject
,
2079 (PVOID
)&FixedDomainData
,
2081 if (!NT_SUCCESS(Status
))
2083 TRACE("failed with status 0x%08lx\n", Status
);
2087 /* Increment the NextRid attribute */
2088 ulRid
= FixedDomainData
.NextRid
;
2089 FixedDomainData
.NextRid
++;
2091 /* Store the fixed domain attributes */
2092 Status
= SampSetObjectAttribute(DomainObject
,
2097 if (!NT_SUCCESS(Status
))
2099 TRACE("failed with status 0x%08lx\n", Status
);
2103 TRACE("RID: %lx\n", ulRid
);
2105 /* Convert the RID into a string (hex) */
2106 swprintf(szRid
, L
"%08lX", ulRid
);
2108 /* Create the group object */
2109 Status
= SampCreateDbObject(DomainObject
,
2116 if (!NT_SUCCESS(Status
))
2118 TRACE("failed with status 0x%08lx\n", Status
);
2122 /* Add the account name of the user object */
2123 Status
= SampSetAccountNameInDomain(DomainObject
,
2127 if (!NT_SUCCESS(Status
))
2129 TRACE("failed with status 0x%08lx\n", Status
);
2133 /* Initialize fixed user data */
2134 memset(&FixedGroupData
, 0, sizeof(SAM_GROUP_FIXED_DATA
));
2135 FixedGroupData
.Version
= 1;
2136 FixedGroupData
.GroupId
= ulRid
;
2138 /* Set fixed user data attribute */
2139 Status
= SampSetObjectAttribute(GroupObject
,
2142 (LPVOID
)&FixedGroupData
,
2143 sizeof(SAM_GROUP_FIXED_DATA
));
2144 if (!NT_SUCCESS(Status
))
2146 TRACE("failed with status 0x%08lx\n", Status
);
2150 /* Set the Name attribute */
2151 Status
= SampSetObjectAttributeString(GroupObject
,
2154 if (!NT_SUCCESS(Status
))
2156 TRACE("failed with status 0x%08lx\n", Status
);
2160 /* Set the AdminComment attribute */
2161 Status
= SampSetObjectAttributeString(GroupObject
,
2164 if (!NT_SUCCESS(Status
))
2166 TRACE("failed with status 0x%08lx\n", Status
);
2170 /* Set the SecDesc attribute*/
2171 Status
= SampSetObjectAttribute(GroupObject
,
2176 if (!NT_SUCCESS(Status
))
2178 TRACE("failed with status 0x%08lx\n", Status
);
2182 if (NT_SUCCESS(Status
))
2184 *GroupHandle
= (SAMPR_HANDLE
)GroupObject
;
2185 *RelativeId
= ulRid
;
2190 RtlFreeHeap(RtlGetProcessHeap(), 0, Sd
);
2192 RtlReleaseResource(&SampResource
);
2194 TRACE("returns with status 0x%08lx\n", Status
);
2203 SamrEnumerateGroupsInDomain(IN SAMPR_HANDLE DomainHandle
,
2204 IN OUT
unsigned long *EnumerationContext
,
2205 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
2206 IN
unsigned long PreferedMaximumLength
,
2207 OUT
unsigned long *CountReturned
)
2209 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
2210 PSAM_DB_OBJECT DomainObject
;
2211 HANDLE GroupsKeyHandle
= NULL
;
2212 HANDLE NamesKeyHandle
= NULL
;
2213 WCHAR GroupName
[64];
2215 ULONG EnumCount
= 0;
2216 ULONG RequiredLength
= 0;
2221 BOOLEAN MoreEntries
= FALSE
;
2224 TRACE("SamrEnumerateUsersInDomain(%p %p %p %lu %p)\n",
2225 DomainHandle
, EnumerationContext
, Buffer
,
2226 PreferedMaximumLength
, CountReturned
);
2228 RtlAcquireResourceShared(&SampResource
,
2231 /* Validate the domain handle */
2232 Status
= SampValidateDbObject(DomainHandle
,
2234 DOMAIN_LIST_ACCOUNTS
,
2236 if (!NT_SUCCESS(Status
))
2239 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
2243 if (!NT_SUCCESS(Status
))
2246 Status
= SampRegOpenKey(GroupsKeyHandle
,
2250 if (!NT_SUCCESS(Status
))
2255 EnumIndex
= *EnumerationContext
;
2259 NameLength
= 64 * sizeof(WCHAR
);
2260 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2267 if (!NT_SUCCESS(Status
))
2269 if (Status
== STATUS_NO_MORE_ENTRIES
)
2270 Status
= STATUS_SUCCESS
;
2274 TRACE("EnumIndex: %lu\n", EnumIndex
);
2275 TRACE("Group name: %S\n", GroupName
);
2276 TRACE("Name length: %lu\n", NameLength
);
2278 if ((RequiredLength
+ NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
)) > PreferedMaximumLength
)
2284 RequiredLength
+= (NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
));
2290 TRACE("EnumCount: %lu\n", EnumCount
);
2291 TRACE("RequiredLength: %lu\n", RequiredLength
);
2293 if (!NT_SUCCESS(Status
))
2296 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
2297 if (EnumBuffer
== NULL
)
2299 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2303 EnumBuffer
->EntriesRead
= EnumCount
;
2307 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
2308 if (EnumBuffer
->Buffer
== NULL
)
2310 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2316 EnumIndex
= *EnumerationContext
;
2317 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
2319 NameLength
= 64 * sizeof(WCHAR
);
2320 DataLength
= sizeof(ULONG
);
2321 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2328 if (!NT_SUCCESS(Status
))
2330 if (Status
== STATUS_NO_MORE_ENTRIES
)
2331 Status
= STATUS_SUCCESS
;
2335 TRACE("EnumIndex: %lu\n", EnumIndex
);
2336 TRACE("Group name: %S\n", GroupName
);
2337 TRACE("Name length: %lu\n", NameLength
);
2338 TRACE("RID: %lu\n", Rid
);
2340 EnumBuffer
->Buffer
[i
].RelativeId
= Rid
;
2342 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)NameLength
;
2343 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)(NameLength
+ sizeof(UNICODE_NULL
));
2345 /* FIXME: Disabled because of bugs in widl and rpcrt4 */
2347 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(EnumBuffer
->Buffer
[i
].Name
.MaximumLength
);
2348 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
2350 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2354 memcpy(EnumBuffer
->Buffer
[i
].Name
.Buffer
,
2356 EnumBuffer
->Buffer
[i
].Name
.Length
);
2361 if (NT_SUCCESS(Status
))
2363 *EnumerationContext
+= EnumCount
;
2364 *Buffer
= EnumBuffer
;
2365 *CountReturned
= EnumCount
;
2369 *EnumerationContext
= 0;
2373 if (EnumBuffer
!= NULL
)
2375 if (EnumBuffer
->Buffer
!= NULL
)
2377 if (EnumBuffer
->EntriesRead
!= 0)
2379 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
2381 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
2382 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
2386 midl_user_free(EnumBuffer
->Buffer
);
2389 midl_user_free(EnumBuffer
);
2393 SampRegCloseKey(&NamesKeyHandle
);
2394 SampRegCloseKey(&GroupsKeyHandle
);
2396 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
!= FALSE
))
2397 Status
= STATUS_MORE_ENTRIES
;
2399 RtlReleaseResource(&SampResource
);
2408 SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle
,
2409 IN PRPC_UNICODE_STRING Name
,
2410 IN ACCESS_MASK DesiredAccess
,
2411 OUT SAMPR_HANDLE
*UserHandle
,
2412 OUT
unsigned long *RelativeId
)
2414 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
2415 SAM_USER_FIXED_DATA FixedUserData
;
2416 PSAM_DB_OBJECT DomainObject
;
2417 PSAM_DB_OBJECT UserObject
;
2418 GROUP_MEMBERSHIP GroupMembership
;
2419 UCHAR LogonHours
[23];
2423 PSECURITY_DESCRIPTOR Sd
= NULL
;
2425 PSID UserSid
= NULL
;
2428 TRACE("SamrCreateUserInDomain(%p %p %lx %p %p)\n",
2429 DomainHandle
, Name
, DesiredAccess
, UserHandle
, RelativeId
);
2432 Name
->Length
== 0 ||
2433 Name
->Buffer
== NULL
||
2434 UserHandle
== NULL
||
2436 return STATUS_INVALID_PARAMETER
;
2438 /* Map generic access rights */
2439 RtlMapGenericMask(&DesiredAccess
,
2442 RtlAcquireResourceExclusive(&SampResource
,
2445 /* Validate the domain handle */
2446 Status
= SampValidateDbObject(DomainHandle
,
2450 if (!NT_SUCCESS(Status
))
2452 TRACE("failed with status 0x%08lx\n", Status
);
2456 /* Check the user account name */
2457 Status
= SampCheckAccountName(Name
, 20);
2458 if (!NT_SUCCESS(Status
))
2460 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
2464 /* Check if the user name already exists in the domain */
2465 Status
= SampCheckAccountNameInDomain(DomainObject
,
2467 if (!NT_SUCCESS(Status
))
2469 TRACE("User name \'%S\' already exists in domain (Status 0x%08lx)\n",
2470 Name
->Buffer
, Status
);
2474 /* Get the fixed domain attributes */
2475 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
2476 Status
= SampGetObjectAttribute(DomainObject
,
2479 (PVOID
)&FixedDomainData
,
2481 if (!NT_SUCCESS(Status
))
2483 TRACE("failed with status 0x%08lx\n", Status
);
2487 /* Increment the NextRid attribute */
2488 ulRid
= FixedDomainData
.NextRid
;
2489 FixedDomainData
.NextRid
++;
2491 TRACE("RID: %lx\n", ulRid
);
2493 /* Create the user SID */
2494 Status
= SampCreateAccountSid(DomainObject
,
2497 if (!NT_SUCCESS(Status
))
2499 TRACE("SampCreateAccountSid failed (Status 0x%08lx)\n", Status
);
2503 /* Create the security descriptor */
2504 Status
= SampCreateUserSD(UserSid
,
2507 if (!NT_SUCCESS(Status
))
2509 TRACE("SampCreateUserSD failed (Status 0x%08lx)\n", Status
);
2513 /* Store the fixed domain attributes */
2514 Status
= SampSetObjectAttribute(DomainObject
,
2519 if (!NT_SUCCESS(Status
))
2521 TRACE("failed with status 0x%08lx\n", Status
);
2525 /* Convert the RID into a string (hex) */
2526 swprintf(szRid
, L
"%08lX", ulRid
);
2528 /* Create the user object */
2529 Status
= SampCreateDbObject(DomainObject
,
2536 if (!NT_SUCCESS(Status
))
2538 TRACE("failed with status 0x%08lx\n", Status
);
2542 /* Add the account name for the user object */
2543 Status
= SampSetAccountNameInDomain(DomainObject
,
2547 if (!NT_SUCCESS(Status
))
2549 TRACE("failed with status 0x%08lx\n", Status
);
2553 /* Initialize fixed user data */
2554 memset(&FixedUserData
, 0, sizeof(SAM_USER_FIXED_DATA
));
2555 FixedUserData
.Version
= 1;
2556 FixedUserData
.Reserved
= 0;
2557 FixedUserData
.LastLogon
.QuadPart
= 0;
2558 FixedUserData
.LastLogoff
.QuadPart
= 0;
2559 FixedUserData
.PasswordLastSet
.QuadPart
= 0;
2560 FixedUserData
.AccountExpires
.LowPart
= MAXULONG
;
2561 FixedUserData
.AccountExpires
.HighPart
= MAXLONG
;
2562 FixedUserData
.LastBadPasswordTime
.QuadPart
= 0;
2563 FixedUserData
.UserId
= ulRid
;
2564 FixedUserData
.PrimaryGroupId
= DOMAIN_GROUP_RID_USERS
;
2565 FixedUserData
.UserAccountControl
= USER_ACCOUNT_DISABLED
|
2566 USER_PASSWORD_NOT_REQUIRED
|
2567 USER_NORMAL_ACCOUNT
;
2568 FixedUserData
.CountryCode
= 0;
2569 FixedUserData
.CodePage
= 0;
2570 FixedUserData
.BadPasswordCount
= 0;
2571 FixedUserData
.LogonCount
= 0;
2572 FixedUserData
.AdminCount
= 0;
2573 FixedUserData
.OperatorCount
= 0;
2575 /* Set fixed user data attribute */
2576 Status
= SampSetObjectAttribute(UserObject
,
2579 (LPVOID
)&FixedUserData
,
2580 sizeof(SAM_USER_FIXED_DATA
));
2581 if (!NT_SUCCESS(Status
))
2583 TRACE("failed with status 0x%08lx\n", Status
);
2587 /* Set the Name attribute */
2588 Status
= SampSetObjectAttributeString(UserObject
,
2591 if (!NT_SUCCESS(Status
))
2593 TRACE("failed with status 0x%08lx\n", Status
);
2597 /* Set the FullName attribute */
2598 Status
= SampSetObjectAttributeString(UserObject
,
2601 if (!NT_SUCCESS(Status
))
2603 TRACE("failed with status 0x%08lx\n", Status
);
2607 /* Set the HomeDirectory attribute */
2608 Status
= SampSetObjectAttributeString(UserObject
,
2611 if (!NT_SUCCESS(Status
))
2613 TRACE("failed with status 0x%08lx\n", Status
);
2617 /* Set the HomeDirectoryDrive attribute */
2618 Status
= SampSetObjectAttributeString(UserObject
,
2619 L
"HomeDirectoryDrive",
2621 if (!NT_SUCCESS(Status
))
2623 TRACE("failed with status 0x%08lx\n", Status
);
2627 /* Set the ScriptPath attribute */
2628 Status
= SampSetObjectAttributeString(UserObject
,
2631 if (!NT_SUCCESS(Status
))
2633 TRACE("failed with status 0x%08lx\n", Status
);
2637 /* Set the ProfilePath attribute */
2638 Status
= SampSetObjectAttributeString(UserObject
,
2641 if (!NT_SUCCESS(Status
))
2643 TRACE("failed with status 0x%08lx\n", Status
);
2647 /* Set the AdminComment attribute */
2648 Status
= SampSetObjectAttributeString(UserObject
,
2651 if (!NT_SUCCESS(Status
))
2653 TRACE("failed with status 0x%08lx\n", Status
);
2657 /* Set the UserComment attribute */
2658 Status
= SampSetObjectAttributeString(UserObject
,
2661 if (!NT_SUCCESS(Status
))
2663 TRACE("failed with status 0x%08lx\n", Status
);
2667 /* Set the WorkStations attribute */
2668 Status
= SampSetObjectAttributeString(UserObject
,
2671 if (!NT_SUCCESS(Status
))
2673 TRACE("failed with status 0x%08lx\n", Status
);
2677 /* Set the Parameters attribute */
2678 Status
= SampSetObjectAttributeString(UserObject
,
2681 if (!NT_SUCCESS(Status
))
2683 TRACE("failed with status 0x%08lx\n", Status
);
2687 /* Set LogonHours attribute*/
2688 *((PUSHORT
)LogonHours
) = 168;
2689 memset(&(LogonHours
[2]), 0xff, 21);
2691 Status
= SampSetObjectAttribute(UserObject
,
2695 sizeof(LogonHours
));
2696 if (!NT_SUCCESS(Status
))
2698 TRACE("failed with status 0x%08lx\n", Status
);
2702 /* Set Groups attribute*/
2703 GroupMembership
.RelativeId
= DOMAIN_GROUP_RID_USERS
;
2704 GroupMembership
.Attributes
= SE_GROUP_MANDATORY
|
2706 SE_GROUP_ENABLED_BY_DEFAULT
;
2708 Status
= SampSetObjectAttribute(UserObject
,
2712 sizeof(GROUP_MEMBERSHIP
));
2713 if (!NT_SUCCESS(Status
))
2715 TRACE("failed with status 0x%08lx\n", Status
);
2719 /* Set LMPwd attribute*/
2720 Status
= SampSetObjectAttribute(UserObject
,
2724 sizeof(ENCRYPTED_LM_OWF_PASSWORD
));
2725 if (!NT_SUCCESS(Status
))
2727 TRACE("failed with status 0x%08lx\n", Status
);
2731 /* Set NTPwd attribute*/
2732 Status
= SampSetObjectAttribute(UserObject
,
2736 sizeof(ENCRYPTED_NT_OWF_PASSWORD
));
2737 if (!NT_SUCCESS(Status
))
2739 TRACE("failed with status 0x%08lx\n", Status
);
2743 /* Set LMPwdHistory attribute*/
2744 Status
= SampSetObjectAttribute(UserObject
,
2749 if (!NT_SUCCESS(Status
))
2751 TRACE("failed with status 0x%08lx\n", Status
);
2755 /* Set NTPwdHistory attribute*/
2756 Status
= SampSetObjectAttribute(UserObject
,
2761 if (!NT_SUCCESS(Status
))
2763 TRACE("failed with status 0x%08lx\n", Status
);
2767 /* Set the PrivateData attribute */
2768 Status
= SampSetObjectAttributeString(UserObject
,
2771 if (!NT_SUCCESS(Status
))
2773 TRACE("failed with status 0x%08lx\n", Status
);
2777 /* Set the SecDesc attribute*/
2778 Status
= SampSetObjectAttribute(UserObject
,
2783 if (!NT_SUCCESS(Status
))
2785 TRACE("failed with status 0x%08lx\n", Status
);
2789 if (NT_SUCCESS(Status
))
2791 *UserHandle
= (SAMPR_HANDLE
)UserObject
;
2792 *RelativeId
= ulRid
;
2797 RtlFreeHeap(RtlGetProcessHeap(), 0, Sd
);
2799 if (UserSid
!= NULL
)
2800 RtlFreeHeap(RtlGetProcessHeap(), 0, UserSid
);
2802 RtlReleaseResource(&SampResource
);
2804 TRACE("returns with status 0x%08lx\n", Status
);
2813 SamrEnumerateUsersInDomain(IN SAMPR_HANDLE DomainHandle
,
2814 IN OUT
unsigned long *EnumerationContext
,
2815 IN
unsigned long UserAccountControl
,
2816 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
2817 IN
unsigned long PreferedMaximumLength
,
2818 OUT
unsigned long *CountReturned
)
2820 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
2821 PSAM_DB_OBJECT DomainObject
;
2822 HANDLE UsersKeyHandle
= NULL
;
2823 HANDLE NamesKeyHandle
= NULL
;
2826 ULONG EnumCount
= 0;
2827 ULONG RequiredLength
= 0;
2832 BOOLEAN MoreEntries
= FALSE
;
2835 TRACE("SamrEnumerateUsersInDomain(%p %p %lx %p %lu %p)\n",
2836 DomainHandle
, EnumerationContext
, UserAccountControl
, Buffer
,
2837 PreferedMaximumLength
, CountReturned
);
2839 RtlAcquireResourceShared(&SampResource
,
2842 /* Validate the domain handle */
2843 Status
= SampValidateDbObject(DomainHandle
,
2845 DOMAIN_LIST_ACCOUNTS
,
2847 if (!NT_SUCCESS(Status
))
2850 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
2854 if (!NT_SUCCESS(Status
))
2857 Status
= SampRegOpenKey(UsersKeyHandle
,
2861 if (!NT_SUCCESS(Status
))
2866 EnumIndex
= *EnumerationContext
;
2870 NameLength
= 64 * sizeof(WCHAR
);
2871 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2878 if (!NT_SUCCESS(Status
))
2880 if (Status
== STATUS_NO_MORE_ENTRIES
)
2881 Status
= STATUS_SUCCESS
;
2885 TRACE("EnumIndex: %lu\n", EnumIndex
);
2886 TRACE("User name: %S\n", UserName
);
2887 TRACE("Name length: %lu\n", NameLength
);
2889 if ((RequiredLength
+ NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
)) > PreferedMaximumLength
)
2895 RequiredLength
+= (NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
));
2901 TRACE("EnumCount: %lu\n", EnumCount
);
2902 TRACE("RequiredLength: %lu\n", RequiredLength
);
2904 if (!NT_SUCCESS(Status
))
2907 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
2908 if (EnumBuffer
== NULL
)
2910 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2914 EnumBuffer
->EntriesRead
= EnumCount
;
2918 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
2919 if (EnumBuffer
->Buffer
== NULL
)
2921 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2927 EnumIndex
= *EnumerationContext
;
2928 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
2930 NameLength
= 64 * sizeof(WCHAR
);
2931 DataLength
= sizeof(ULONG
);
2932 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2939 if (!NT_SUCCESS(Status
))
2941 if (Status
== STATUS_NO_MORE_ENTRIES
)
2942 Status
= STATUS_SUCCESS
;
2946 TRACE("EnumIndex: %lu\n", EnumIndex
);
2947 TRACE("User name: %S\n", UserName
);
2948 TRACE("Name length: %lu\n", NameLength
);
2949 TRACE("RID: %lu\n", Rid
);
2951 EnumBuffer
->Buffer
[i
].RelativeId
= Rid
;
2953 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)NameLength
;
2954 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)(NameLength
+ sizeof(UNICODE_NULL
));
2956 /* FIXME: Disabled because of bugs in widl and rpcrt4 */
2958 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(EnumBuffer
->Buffer
[i
].Name
.MaximumLength
);
2959 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
2961 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2965 memcpy(EnumBuffer
->Buffer
[i
].Name
.Buffer
,
2967 EnumBuffer
->Buffer
[i
].Name
.Length
);
2972 if (NT_SUCCESS(Status
))
2974 *EnumerationContext
+= EnumCount
;
2975 *Buffer
= EnumBuffer
;
2976 *CountReturned
= EnumCount
;
2980 *EnumerationContext
= 0;
2984 if (EnumBuffer
!= NULL
)
2986 if (EnumBuffer
->Buffer
!= NULL
)
2988 if (EnumBuffer
->EntriesRead
!= 0)
2990 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
2992 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
2993 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
2997 midl_user_free(EnumBuffer
->Buffer
);
3000 midl_user_free(EnumBuffer
);
3004 SampRegCloseKey(&NamesKeyHandle
);
3005 SampRegCloseKey(&UsersKeyHandle
);
3007 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
!= FALSE
))
3008 Status
= STATUS_MORE_ENTRIES
;
3010 RtlReleaseResource(&SampResource
);
3019 SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle
,
3020 IN PRPC_UNICODE_STRING AccountName
,
3021 IN ACCESS_MASK DesiredAccess
,
3022 OUT SAMPR_HANDLE
*AliasHandle
,
3023 OUT
unsigned long *RelativeId
)
3025 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
3026 PSAM_DB_OBJECT DomainObject
;
3027 PSAM_DB_OBJECT AliasObject
;
3028 PSECURITY_DESCRIPTOR Sd
= NULL
;
3035 TRACE("SamrCreateAliasInDomain(%p %p %lx %p %p)\n",
3036 DomainHandle
, AccountName
, DesiredAccess
, AliasHandle
, RelativeId
);
3038 /* Map generic access rights */
3039 RtlMapGenericMask(&DesiredAccess
,
3042 RtlAcquireResourceExclusive(&SampResource
,
3045 /* Validate the domain handle */
3046 Status
= SampValidateDbObject(DomainHandle
,
3048 DOMAIN_CREATE_ALIAS
,
3050 if (!NT_SUCCESS(Status
))
3052 TRACE("failed with status 0x%08lx\n", Status
);
3056 /* Check the alias account name */
3057 Status
= SampCheckAccountName(AccountName
, 256);
3058 if (!NT_SUCCESS(Status
))
3060 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
3064 /* Check if the alias name already exists in the domain */
3065 Status
= SampCheckAccountNameInDomain(DomainObject
,
3066 AccountName
->Buffer
);
3067 if (!NT_SUCCESS(Status
))
3069 TRACE("Alias name \'%S\' already exists in domain (Status 0x%08lx)\n",
3070 AccountName
->Buffer
, Status
);
3074 /* Create the security descriptor */
3075 Status
= SampCreateAliasSD(&Sd
,
3077 if (!NT_SUCCESS(Status
))
3079 TRACE("SampCreateAliasSD failed (Status 0x%08lx)\n", Status
);
3083 /* Get the fixed domain attributes */
3084 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
3085 Status
= SampGetObjectAttribute(DomainObject
,
3088 (PVOID
)&FixedDomainData
,
3090 if (!NT_SUCCESS(Status
))
3092 TRACE("failed with status 0x%08lx\n", Status
);
3096 /* Increment the NextRid attribute */
3097 ulRid
= FixedDomainData
.NextRid
;
3098 FixedDomainData
.NextRid
++;
3100 /* Store the fixed domain attributes */
3101 Status
= SampSetObjectAttribute(DomainObject
,
3106 if (!NT_SUCCESS(Status
))
3108 TRACE("failed with status 0x%08lx\n", Status
);
3112 TRACE("RID: %lx\n", ulRid
);
3114 /* Convert the RID into a string (hex) */
3115 swprintf(szRid
, L
"%08lX", ulRid
);
3117 /* Create the alias object */
3118 Status
= SampCreateDbObject(DomainObject
,
3125 if (!NT_SUCCESS(Status
))
3127 TRACE("failed with status 0x%08lx\n", Status
);
3131 /* Add the account name for the alias object */
3132 Status
= SampSetAccountNameInDomain(DomainObject
,
3134 AccountName
->Buffer
,
3136 if (!NT_SUCCESS(Status
))
3138 TRACE("failed with status 0x%08lx\n", Status
);
3142 /* Set the Name attribute */
3143 Status
= SampSetObjectAttributeString(AliasObject
,
3146 if (!NT_SUCCESS(Status
))
3148 TRACE("failed with status 0x%08lx\n", Status
);
3152 /* Set the Description attribute */
3153 Status
= SampSetObjectAttributeString(AliasObject
,
3156 if (!NT_SUCCESS(Status
))
3158 TRACE("failed with status 0x%08lx\n", Status
);
3162 /* Set the SecDesc attribute*/
3163 Status
= SampSetObjectAttribute(AliasObject
,
3168 if (!NT_SUCCESS(Status
))
3170 TRACE("failed with status 0x%08lx\n", Status
);
3174 if (NT_SUCCESS(Status
))
3176 *AliasHandle
= (SAMPR_HANDLE
)AliasObject
;
3177 *RelativeId
= ulRid
;
3182 RtlFreeHeap(RtlGetProcessHeap(), 0, Sd
);
3184 RtlReleaseResource(&SampResource
);
3186 TRACE("returns with status 0x%08lx\n", Status
);
3195 SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle
,
3196 IN OUT
unsigned long *EnumerationContext
,
3197 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
3198 IN
unsigned long PreferedMaximumLength
,
3199 OUT
unsigned long *CountReturned
)
3201 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
3202 PSAM_DB_OBJECT DomainObject
;
3203 HANDLE AliasesKeyHandle
= NULL
;
3204 HANDLE NamesKeyHandle
= NULL
;
3205 WCHAR AliasName
[64];
3207 ULONG EnumCount
= 0;
3208 ULONG RequiredLength
= 0;
3213 BOOLEAN MoreEntries
= FALSE
;
3216 TRACE("SamrEnumerateAliasesInDomain(%p %p %p %lu %p)\n",
3217 DomainHandle
, EnumerationContext
, Buffer
,
3218 PreferedMaximumLength
, CountReturned
);
3220 RtlAcquireResourceShared(&SampResource
,
3223 /* Validate the domain handle */
3224 Status
= SampValidateDbObject(DomainHandle
,
3226 DOMAIN_LIST_ACCOUNTS
,
3228 if (!NT_SUCCESS(Status
))
3231 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3235 if (!NT_SUCCESS(Status
))
3238 Status
= SampRegOpenKey(AliasesKeyHandle
,
3242 if (!NT_SUCCESS(Status
))
3247 EnumIndex
= *EnumerationContext
;
3251 NameLength
= 64 * sizeof(WCHAR
);
3252 Status
= SampRegEnumerateValue(NamesKeyHandle
,
3259 if (!NT_SUCCESS(Status
))
3261 if (Status
== STATUS_NO_MORE_ENTRIES
)
3262 Status
= STATUS_SUCCESS
;
3266 TRACE("EnumIndex: %lu\n", EnumIndex
);
3267 TRACE("Alias name: %S\n", AliasName
);
3268 TRACE("Name length: %lu\n", NameLength
);
3270 if ((RequiredLength
+ NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
)) > PreferedMaximumLength
)
3276 RequiredLength
+= (NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
));
3282 TRACE("EnumCount: %lu\n", EnumCount
);
3283 TRACE("RequiredLength: %lu\n", RequiredLength
);
3285 if (!NT_SUCCESS(Status
))
3288 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
3289 if (EnumBuffer
== NULL
)
3291 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3295 EnumBuffer
->EntriesRead
= EnumCount
;
3299 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
3300 if (EnumBuffer
->Buffer
== NULL
)
3302 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3308 EnumIndex
= *EnumerationContext
;
3309 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
3311 NameLength
= 64 * sizeof(WCHAR
);
3312 DataLength
= sizeof(ULONG
);
3313 Status
= SampRegEnumerateValue(NamesKeyHandle
,
3320 if (!NT_SUCCESS(Status
))
3322 if (Status
== STATUS_NO_MORE_ENTRIES
)
3323 Status
= STATUS_SUCCESS
;
3327 TRACE("EnumIndex: %lu\n", EnumIndex
);
3328 TRACE("Alias name: %S\n", AliasName
);
3329 TRACE("Name length: %lu\n", NameLength
);
3330 TRACE("RID: %lu\n", Rid
);
3332 EnumBuffer
->Buffer
[i
].RelativeId
= Rid
;
3334 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)NameLength
;
3335 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)(NameLength
+ sizeof(UNICODE_NULL
));
3337 /* FIXME: Disabled because of bugs in widl and rpcrt4 */
3339 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(EnumBuffer
->Buffer
[i
].Name
.MaximumLength
);
3340 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
3342 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3346 memcpy(EnumBuffer
->Buffer
[i
].Name
.Buffer
,
3348 EnumBuffer
->Buffer
[i
].Name
.Length
);
3353 if (NT_SUCCESS(Status
))
3355 *EnumerationContext
+= EnumCount
;
3356 *Buffer
= EnumBuffer
;
3357 *CountReturned
= EnumCount
;
3361 *EnumerationContext
= 0;
3365 if (EnumBuffer
!= NULL
)
3367 if (EnumBuffer
->Buffer
!= NULL
)
3369 if (EnumBuffer
->EntriesRead
!= 0)
3371 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
3373 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
3374 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
3378 midl_user_free(EnumBuffer
->Buffer
);
3381 midl_user_free(EnumBuffer
);
3385 SampRegCloseKey(&NamesKeyHandle
);
3386 SampRegCloseKey(&AliasesKeyHandle
);
3388 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
!= FALSE
))
3389 Status
= STATUS_MORE_ENTRIES
;
3391 RtlReleaseResource(&SampResource
);
3400 SamrGetAliasMembership(IN SAMPR_HANDLE DomainHandle
,
3401 IN PSAMPR_PSID_ARRAY SidArray
,
3402 OUT PSAMPR_ULONG_ARRAY Membership
)
3404 PSAM_DB_OBJECT DomainObject
;
3405 HANDLE AliasesKeyHandle
= NULL
;
3406 HANDLE MembersKeyHandle
= NULL
;
3407 HANDLE MemberKeyHandle
= NULL
;
3408 LPWSTR MemberSidString
= NULL
;
3409 PULONG RidArray
= NULL
;
3410 ULONG MaxSidCount
= 0;
3416 WCHAR NameBuffer
[9];
3418 TRACE("SamrGetAliasMembership(%p %p %p)\n",
3419 DomainHandle
, SidArray
, Membership
);
3421 RtlAcquireResourceShared(&SampResource
,
3424 /* Validate the domain handle */
3425 Status
= SampValidateDbObject(DomainHandle
,
3427 DOMAIN_GET_ALIAS_MEMBERSHIP
,
3429 if (!NT_SUCCESS(Status
))
3432 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3436 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3437 if (!NT_SUCCESS(Status
))
3440 Status
= SampRegOpenKey(AliasesKeyHandle
,
3444 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3446 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3448 Status
= STATUS_SUCCESS
;
3452 if (!NT_SUCCESS(Status
))
3455 for (i
= 0; i
< SidArray
->Count
; i
++)
3457 ConvertSidToStringSid(SidArray
->Sids
[i
].SidPointer
, &MemberSidString
);
3458 TRACE("Open %S\n", MemberSidString
);
3460 Status
= SampRegOpenKey(MembersKeyHandle
,
3464 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3465 if (NT_SUCCESS(Status
))
3467 Status
= SampRegQueryKeyInfo(MemberKeyHandle
,
3470 if (NT_SUCCESS(Status
))
3472 TRACE("Found %lu values\n", ValueCount
);
3473 MaxSidCount
+= ValueCount
;
3476 SampRegCloseKey(&MemberKeyHandle
);
3479 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3480 Status
= STATUS_SUCCESS
;
3482 LocalFree(MemberSidString
);
3485 if (MaxSidCount
== 0)
3487 Status
= STATUS_SUCCESS
;
3491 TRACE("Maximum sid count: %lu\n", MaxSidCount
);
3492 RidArray
= midl_user_allocate(MaxSidCount
* sizeof(ULONG
));
3493 if (RidArray
== NULL
)
3495 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3500 for (i
= 0; i
< SidArray
->Count
; i
++)
3502 ConvertSidToStringSid(SidArray
->Sids
[i
].SidPointer
, &MemberSidString
);
3503 TRACE("Open %S\n", MemberSidString
);
3505 Status
= SampRegOpenKey(MembersKeyHandle
,
3509 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3510 if (NT_SUCCESS(Status
))
3512 Status
= SampRegQueryKeyInfo(MemberKeyHandle
,
3515 if (NT_SUCCESS(Status
))
3517 TRACE("Found %lu values\n", ValueCount
);
3519 for (j
= 0; j
< ValueCount
; j
++)
3521 DataLength
= 9 * sizeof(WCHAR
);
3522 Status
= SampRegEnumerateValue(MemberKeyHandle
,
3529 if (NT_SUCCESS(Status
))
3531 /* FIXME: Do not return each RID more than once. */
3532 RidArray
[RidIndex
] = wcstoul(NameBuffer
, NULL
, 16);
3538 SampRegCloseKey(&MemberKeyHandle
);
3541 LocalFree(MemberSidString
);
3545 SampRegCloseKey(&MembersKeyHandle
);
3546 SampRegCloseKey(&AliasesKeyHandle
);
3548 if (NT_SUCCESS(Status
))
3550 Membership
->Count
= MaxSidCount
;
3551 Membership
->Element
= RidArray
;
3555 if (RidArray
!= NULL
)
3556 midl_user_free(RidArray
);
3559 RtlReleaseResource(&SampResource
);
3568 SamrLookupNamesInDomain(IN SAMPR_HANDLE DomainHandle
,
3570 IN RPC_UNICODE_STRING Names
[],
3571 OUT PSAMPR_ULONG_ARRAY RelativeIds
,
3572 OUT PSAMPR_ULONG_ARRAY Use
)
3574 PSAM_DB_OBJECT DomainObject
;
3575 HANDLE AccountsKeyHandle
= NULL
;
3576 HANDLE NamesKeyHandle
= NULL
;
3577 ULONG MappedCount
= 0;
3583 TRACE("SamrLookupNamesInDomain(%p %lu %p %p %p)\n",
3584 DomainHandle
, Count
, Names
, RelativeIds
, Use
);
3586 RtlAcquireResourceShared(&SampResource
,
3589 /* Validate the domain handle */
3590 Status
= SampValidateDbObject(DomainHandle
,
3594 if (!NT_SUCCESS(Status
))
3596 TRACE("failed with status 0x%08lx\n", Status
);
3600 RelativeIds
->Count
= 0;
3605 Status
= STATUS_SUCCESS
;
3609 /* Allocate the relative IDs array */
3610 RelativeIds
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
3611 if (RelativeIds
->Element
== NULL
)
3613 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3617 /* Allocate the use array */
3618 Use
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
3619 if (Use
->Element
== NULL
)
3621 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3625 RelativeIds
->Count
= Count
;
3628 for (i
= 0; i
< Count
; i
++)
3630 TRACE("Name: %S\n", Names
[i
].Buffer
);
3634 /* Lookup aliases */
3635 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3638 &AccountsKeyHandle
);
3639 if (NT_SUCCESS(Status
))
3641 Status
= SampRegOpenKey(AccountsKeyHandle
,
3645 if (NT_SUCCESS(Status
))
3647 DataLength
= sizeof(ULONG
);
3648 Status
= SampRegQueryValue(NamesKeyHandle
,
3654 SampRegCloseKey(&NamesKeyHandle
);
3657 SampRegCloseKey(&AccountsKeyHandle
);
3660 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3663 /* Return alias account */
3664 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
3666 TRACE("Rid: %lu\n", RelativeId
);
3667 RelativeIds
->Element
[i
] = RelativeId
;
3668 Use
->Element
[i
] = SidTypeAlias
;
3674 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3677 &AccountsKeyHandle
);
3678 if (NT_SUCCESS(Status
))
3680 Status
= SampRegOpenKey(AccountsKeyHandle
,
3684 if (NT_SUCCESS(Status
))
3686 DataLength
= sizeof(ULONG
);
3687 Status
= SampRegQueryValue(NamesKeyHandle
,
3693 SampRegCloseKey(&NamesKeyHandle
);
3696 SampRegCloseKey(&AccountsKeyHandle
);
3699 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3702 /* Return group account */
3703 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
3705 TRACE("Rid: %lu\n", RelativeId
);
3706 RelativeIds
->Element
[i
] = RelativeId
;
3707 Use
->Element
[i
] = SidTypeGroup
;
3713 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3716 &AccountsKeyHandle
);
3717 if (NT_SUCCESS(Status
))
3719 Status
= SampRegOpenKey(AccountsKeyHandle
,
3723 if (NT_SUCCESS(Status
))
3725 DataLength
= sizeof(ULONG
);
3726 Status
= SampRegQueryValue(NamesKeyHandle
,
3732 SampRegCloseKey(&NamesKeyHandle
);
3735 SampRegCloseKey(&AccountsKeyHandle
);
3738 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3741 /* Return user account */
3742 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
3744 TRACE("Rid: %lu\n", RelativeId
);
3745 RelativeIds
->Element
[i
] = RelativeId
;
3746 Use
->Element
[i
] = SidTypeUser
;
3751 /* Return unknown account */
3752 RelativeIds
->Element
[i
] = 0;
3753 Use
->Element
[i
] = SidTypeUnknown
;
3757 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3758 Status
= STATUS_SUCCESS
;
3760 if (NT_SUCCESS(Status
))
3762 if (MappedCount
== 0)
3763 Status
= STATUS_NONE_MAPPED
;
3764 else if (MappedCount
< Count
)
3765 Status
= STATUS_SOME_NOT_MAPPED
;
3769 if (RelativeIds
->Element
!= NULL
)
3771 midl_user_free(RelativeIds
->Element
);
3772 RelativeIds
->Element
= NULL
;
3775 RelativeIds
->Count
= 0;
3777 if (Use
->Element
!= NULL
)
3779 midl_user_free(Use
->Element
);
3780 Use
->Element
= NULL
;
3786 RtlReleaseResource(&SampResource
);
3788 TRACE("Returned Status %lx\n", Status
);
3797 SamrLookupIdsInDomain(IN SAMPR_HANDLE DomainHandle
,
3799 IN ULONG
*RelativeIds
,
3800 OUT PSAMPR_RETURNED_USTRING_ARRAY Names
,
3801 OUT PSAMPR_ULONG_ARRAY Use
)
3803 PSAM_DB_OBJECT DomainObject
;
3805 HANDLE AccountsKeyHandle
= NULL
;
3806 HANDLE AccountKeyHandle
= NULL
;
3807 ULONG MappedCount
= 0;
3812 TRACE("SamrLookupIdsInDomain(%p %lu %p %p %p)\n",
3813 DomainHandle
, Count
, RelativeIds
, Names
, Use
);
3815 RtlAcquireResourceShared(&SampResource
,
3818 /* Validate the domain handle */
3819 Status
= SampValidateDbObject(DomainHandle
,
3823 if (!NT_SUCCESS(Status
))
3825 TRACE("failed with status 0x%08lx\n", Status
);
3834 Status
= STATUS_SUCCESS
;
3838 /* Allocate the names array */
3839 Names
->Element
= midl_user_allocate(Count
* sizeof(*Names
->Element
));
3840 if (Names
->Element
== NULL
)
3842 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3846 /* Allocate the use array */
3847 Use
->Element
= midl_user_allocate(Count
* sizeof(*Use
->Element
));
3848 if (Use
->Element
== NULL
)
3850 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3854 Names
->Count
= Count
;
3857 for (i
= 0; i
< Count
; i
++)
3859 TRACE("RID: %lu\n", RelativeIds
[i
]);
3861 swprintf(RidString
, L
"%08lx", RelativeIds
[i
]);
3863 /* Lookup aliases */
3864 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3867 &AccountsKeyHandle
);
3868 if (NT_SUCCESS(Status
))
3870 Status
= SampRegOpenKey(AccountsKeyHandle
,
3874 if (NT_SUCCESS(Status
))
3877 Status
= SampRegQueryValue(AccountKeyHandle
,
3882 if (NT_SUCCESS(Status
))
3884 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
3885 if (Names
->Element
[i
].Buffer
== NULL
)
3886 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3888 if (NT_SUCCESS(Status
))
3890 Names
->Element
[i
].MaximumLength
= (USHORT
)DataLength
;
3891 Names
->Element
[i
].Length
= (USHORT
)(DataLength
- sizeof(WCHAR
));
3893 Status
= SampRegQueryValue(AccountKeyHandle
,
3896 Names
->Element
[i
].Buffer
,
3901 SampRegCloseKey(&AccountKeyHandle
);
3904 SampRegCloseKey(&AccountsKeyHandle
);
3907 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3910 /* Return alias account */
3911 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
3913 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
3914 Use
->Element
[i
] = SidTypeAlias
;
3920 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3923 &AccountsKeyHandle
);
3924 if (NT_SUCCESS(Status
))
3926 Status
= SampRegOpenKey(AccountsKeyHandle
,
3930 if (NT_SUCCESS(Status
))
3933 Status
= SampRegQueryValue(AccountKeyHandle
,
3938 if (NT_SUCCESS(Status
))
3940 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
3941 if (Names
->Element
[i
].Buffer
== NULL
)
3942 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3944 if (NT_SUCCESS(Status
))
3946 Names
->Element
[i
].MaximumLength
= (USHORT
)DataLength
;
3947 Names
->Element
[i
].Length
= (USHORT
)(DataLength
- sizeof(WCHAR
));
3949 Status
= SampRegQueryValue(AccountKeyHandle
,
3952 Names
->Element
[i
].Buffer
,
3957 SampRegCloseKey(&AccountKeyHandle
);
3960 SampRegCloseKey(&AccountsKeyHandle
);
3963 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3966 /* Return group account */
3967 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
3969 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
3970 Use
->Element
[i
] = SidTypeGroup
;
3976 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3979 &AccountsKeyHandle
);
3980 if (NT_SUCCESS(Status
))
3982 Status
= SampRegOpenKey(AccountsKeyHandle
,
3986 if (NT_SUCCESS(Status
))
3989 Status
= SampRegQueryValue(AccountKeyHandle
,
3994 if (NT_SUCCESS(Status
))
3996 TRACE("DataLength: %lu\n", DataLength
);
3998 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
3999 if (Names
->Element
[i
].Buffer
== NULL
)
4000 Status
= STATUS_INSUFFICIENT_RESOURCES
;
4002 if (NT_SUCCESS(Status
))
4004 Names
->Element
[i
].MaximumLength
= (USHORT
)DataLength
;
4005 Names
->Element
[i
].Length
= (USHORT
)(DataLength
- sizeof(WCHAR
));
4007 Status
= SampRegQueryValue(AccountKeyHandle
,
4010 Names
->Element
[i
].Buffer
,
4015 SampRegCloseKey(&AccountKeyHandle
);
4018 SampRegCloseKey(&AccountsKeyHandle
);
4021 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
4024 /* Return user account */
4025 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
4027 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
4028 Use
->Element
[i
] = SidTypeUser
;
4033 /* Return unknown account */
4034 Use
->Element
[i
] = SidTypeUnknown
;
4038 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
4039 Status
= STATUS_SUCCESS
;
4041 if (NT_SUCCESS(Status
))
4043 if (MappedCount
== 0)
4044 Status
= STATUS_NONE_MAPPED
;
4045 else if (MappedCount
< Count
)
4046 Status
= STATUS_SOME_NOT_MAPPED
;
4050 if (Names
->Element
!= NULL
)
4052 for (i
= 0; i
< Count
; i
++)
4054 if (Names
->Element
[i
].Buffer
!= NULL
)
4055 midl_user_free(Names
->Element
[i
].Buffer
);
4058 midl_user_free(Names
->Element
);
4059 Names
->Element
= NULL
;
4064 if (Use
->Element
!= NULL
)
4066 midl_user_free(Use
->Element
);
4067 Use
->Element
= NULL
;
4073 RtlReleaseResource(&SampResource
);
4082 SamrOpenGroup(IN SAMPR_HANDLE DomainHandle
,
4083 IN ACCESS_MASK DesiredAccess
,
4084 IN
unsigned long GroupId
,
4085 OUT SAMPR_HANDLE
*GroupHandle
)
4087 PSAM_DB_OBJECT DomainObject
;
4088 PSAM_DB_OBJECT GroupObject
;
4092 TRACE("SamrOpenGroup(%p %lx %lx %p)\n",
4093 DomainHandle
, DesiredAccess
, GroupId
, GroupHandle
);
4095 /* Map generic access rights */
4096 RtlMapGenericMask(&DesiredAccess
,
4099 RtlAcquireResourceShared(&SampResource
,
4102 /* Validate the domain handle */
4103 Status
= SampValidateDbObject(DomainHandle
,
4107 if (!NT_SUCCESS(Status
))
4109 TRACE("failed with status 0x%08lx\n", Status
);
4113 /* Convert the RID into a string (hex) */
4114 swprintf(szRid
, L
"%08lX", GroupId
);
4116 /* Create the group object */
4117 Status
= SampOpenDbObject(DomainObject
,
4124 if (!NT_SUCCESS(Status
))
4126 TRACE("failed with status 0x%08lx\n", Status
);
4130 *GroupHandle
= (SAMPR_HANDLE
)GroupObject
;
4133 RtlReleaseResource(&SampResource
);
4140 SampQueryGroupGeneral(PSAM_DB_OBJECT GroupObject
,
4141 PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
4143 PSAMPR_GROUP_INFO_BUFFER InfoBuffer
= NULL
;
4144 SAM_GROUP_FIXED_DATA FixedData
;
4145 ULONG MembersLength
= 0;
4151 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_GROUP_INFO_BUFFER
));
4152 if (InfoBuffer
== NULL
)
4153 return STATUS_INSUFFICIENT_RESOURCES
;
4155 Status
= SampGetObjectAttributeString(GroupObject
,
4157 &InfoBuffer
->General
.Name
);
4158 if (!NT_SUCCESS(Status
))
4160 TRACE("Status 0x%08lx\n", Status
);
4164 Status
= SampGetObjectAttributeString(GroupObject
,
4166 &InfoBuffer
->General
.AdminComment
);
4167 if (!NT_SUCCESS(Status
))
4169 TRACE("Status 0x%08lx\n", Status
);
4173 Length
= sizeof(SAM_GROUP_FIXED_DATA
);
4174 Status
= SampGetObjectAttribute(GroupObject
,
4179 if (!NT_SUCCESS(Status
))
4182 InfoBuffer
->General
.Attributes
= FixedData
.Attributes
;
4184 Status
= SampGetObjectAttribute(GroupObject
,
4189 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
4192 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
4193 InfoBuffer
->General
.MemberCount
= 0;
4195 InfoBuffer
->General
.MemberCount
= MembersLength
/ sizeof(ULONG
);
4197 *Buffer
= InfoBuffer
;
4200 if (!NT_SUCCESS(Status
))
4202 if (InfoBuffer
!= NULL
)
4204 if (InfoBuffer
->General
.Name
.Buffer
!= NULL
)
4205 midl_user_free(InfoBuffer
->General
.Name
.Buffer
);
4207 if (InfoBuffer
->General
.AdminComment
.Buffer
!= NULL
)
4208 midl_user_free(InfoBuffer
->General
.AdminComment
.Buffer
);
4210 midl_user_free(InfoBuffer
);
4219 SampQueryGroupName(PSAM_DB_OBJECT GroupObject
,
4220 PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
4222 PSAMPR_GROUP_INFO_BUFFER InfoBuffer
= NULL
;
4227 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_GROUP_INFO_BUFFER
));
4228 if (InfoBuffer
== NULL
)
4229 return STATUS_INSUFFICIENT_RESOURCES
;
4231 Status
= SampGetObjectAttributeString(GroupObject
,
4233 &InfoBuffer
->Name
.Name
);
4234 if (!NT_SUCCESS(Status
))
4236 TRACE("Status 0x%08lx\n", Status
);
4240 *Buffer
= InfoBuffer
;
4243 if (!NT_SUCCESS(Status
))
4245 if (InfoBuffer
!= NULL
)
4247 if (InfoBuffer
->Name
.Name
.Buffer
!= NULL
)
4248 midl_user_free(InfoBuffer
->Name
.Name
.Buffer
);
4250 midl_user_free(InfoBuffer
);
4259 SampQueryGroupAttribute(PSAM_DB_OBJECT GroupObject
,
4260 PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
4262 PSAMPR_GROUP_INFO_BUFFER InfoBuffer
= NULL
;
4263 SAM_GROUP_FIXED_DATA FixedData
;
4269 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_GROUP_INFO_BUFFER
));
4270 if (InfoBuffer
== NULL
)
4271 return STATUS_INSUFFICIENT_RESOURCES
;
4273 Length
= sizeof(SAM_GROUP_FIXED_DATA
);
4274 Status
= SampGetObjectAttribute(GroupObject
,
4279 if (!NT_SUCCESS(Status
))
4282 InfoBuffer
->Attribute
.Attributes
= FixedData
.Attributes
;
4284 *Buffer
= InfoBuffer
;
4287 if (!NT_SUCCESS(Status
))
4289 if (InfoBuffer
!= NULL
)
4291 midl_user_free(InfoBuffer
);
4300 SampQueryGroupAdminComment(PSAM_DB_OBJECT GroupObject
,
4301 PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
4303 PSAMPR_GROUP_INFO_BUFFER InfoBuffer
= NULL
;
4308 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_GROUP_INFO_BUFFER
));
4309 if (InfoBuffer
== NULL
)
4310 return STATUS_INSUFFICIENT_RESOURCES
;
4312 Status
= SampGetObjectAttributeString(GroupObject
,
4314 &InfoBuffer
->AdminComment
.AdminComment
);
4315 if (!NT_SUCCESS(Status
))
4317 TRACE("Status 0x%08lx\n", Status
);
4321 *Buffer
= InfoBuffer
;
4324 if (!NT_SUCCESS(Status
))
4326 if (InfoBuffer
!= NULL
)
4328 if (InfoBuffer
->AdminComment
.AdminComment
.Buffer
!= NULL
)
4329 midl_user_free(InfoBuffer
->AdminComment
.AdminComment
.Buffer
);
4331 midl_user_free(InfoBuffer
);
4342 SamrQueryInformationGroup(IN SAMPR_HANDLE GroupHandle
,
4343 IN GROUP_INFORMATION_CLASS GroupInformationClass
,
4344 OUT PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
4346 PSAM_DB_OBJECT GroupObject
;
4349 TRACE("SamrQueryInformationGroup(%p %lu %p)\n",
4350 GroupHandle
, GroupInformationClass
, Buffer
);
4352 RtlAcquireResourceShared(&SampResource
,
4355 /* Validate the group handle */
4356 Status
= SampValidateDbObject(GroupHandle
,
4358 GROUP_READ_INFORMATION
,
4360 if (!NT_SUCCESS(Status
))
4363 switch (GroupInformationClass
)
4365 case GroupGeneralInformation
:
4366 Status
= SampQueryGroupGeneral(GroupObject
,
4370 case GroupNameInformation
:
4371 Status
= SampQueryGroupName(GroupObject
,
4375 case GroupAttributeInformation
:
4376 Status
= SampQueryGroupAttribute(GroupObject
,
4380 case GroupAdminCommentInformation
:
4381 Status
= SampQueryGroupAdminComment(GroupObject
,
4386 Status
= STATUS_INVALID_INFO_CLASS
;
4391 RtlReleaseResource(&SampResource
);
4398 SampSetGroupName(PSAM_DB_OBJECT GroupObject
,
4399 PSAMPR_GROUP_INFO_BUFFER Buffer
)
4401 UNICODE_STRING OldGroupName
= {0, 0, NULL
};
4402 UNICODE_STRING NewGroupName
;
4405 Status
= SampGetObjectAttributeString(GroupObject
,
4407 (PRPC_UNICODE_STRING
)&OldGroupName
);
4408 if (!NT_SUCCESS(Status
))
4410 TRACE("SampGetObjectAttributeString failed (Status 0x%08lx)\n", Status
);
4414 /* Check the new account name */
4415 Status
= SampCheckAccountName(&Buffer
->Name
.Name
, 256);
4416 if (!NT_SUCCESS(Status
))
4418 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
4422 NewGroupName
.Length
= Buffer
->Name
.Name
.Length
;
4423 NewGroupName
.MaximumLength
= Buffer
->Name
.Name
.MaximumLength
;
4424 NewGroupName
.Buffer
= Buffer
->Name
.Name
.Buffer
;
4426 if (!RtlEqualUnicodeString(&OldGroupName
, &NewGroupName
, TRUE
))
4428 Status
= SampCheckAccountNameInDomain(GroupObject
->ParentObject
,
4429 NewGroupName
.Buffer
);
4430 if (!NT_SUCCESS(Status
))
4432 TRACE("Group name \'%S\' already exists in domain (Status 0x%08lx)\n",
4433 NewGroupName
.Buffer
, Status
);
4438 Status
= SampSetAccountNameInDomain(GroupObject
->ParentObject
,
4440 NewGroupName
.Buffer
,
4441 GroupObject
->RelativeId
);
4442 if (!NT_SUCCESS(Status
))
4444 TRACE("SampSetAccountNameInDomain failed (Status 0x%08lx)\n", Status
);
4448 Status
= SampRemoveAccountNameFromDomain(GroupObject
->ParentObject
,
4450 OldGroupName
.Buffer
);
4451 if (!NT_SUCCESS(Status
))
4453 TRACE("SampRemoveAccountNameFromDomain failed (Status 0x%08lx)\n", Status
);
4457 Status
= SampSetObjectAttributeString(GroupObject
,
4459 (PRPC_UNICODE_STRING
)&NewGroupName
);
4460 if (!NT_SUCCESS(Status
))
4462 TRACE("SampSetObjectAttribute failed (Status 0x%08lx)\n", Status
);
4466 if (OldGroupName
.Buffer
!= NULL
)
4467 midl_user_free(OldGroupName
.Buffer
);
4474 SampSetGroupAttribute(PSAM_DB_OBJECT GroupObject
,
4475 PSAMPR_GROUP_INFO_BUFFER Buffer
)
4477 SAM_GROUP_FIXED_DATA FixedData
;
4481 Length
= sizeof(SAM_GROUP_FIXED_DATA
);
4482 Status
= SampGetObjectAttribute(GroupObject
,
4487 if (!NT_SUCCESS(Status
))
4490 FixedData
.Attributes
= Buffer
->Attribute
.Attributes
;
4492 Status
= SampSetObjectAttribute(GroupObject
,
4506 SamrSetInformationGroup(IN SAMPR_HANDLE GroupHandle
,
4507 IN GROUP_INFORMATION_CLASS GroupInformationClass
,
4508 IN PSAMPR_GROUP_INFO_BUFFER Buffer
)
4510 PSAM_DB_OBJECT GroupObject
;
4513 TRACE("SamrSetInformationGroup(%p %lu %p)\n",
4514 GroupHandle
, GroupInformationClass
, Buffer
);
4516 RtlAcquireResourceExclusive(&SampResource
,
4519 /* Validate the group handle */
4520 Status
= SampValidateDbObject(GroupHandle
,
4522 GROUP_WRITE_ACCOUNT
,
4524 if (!NT_SUCCESS(Status
))
4527 switch (GroupInformationClass
)
4529 case GroupNameInformation
:
4530 Status
= SampSetGroupName(GroupObject
,
4534 case GroupAttributeInformation
:
4535 Status
= SampSetGroupAttribute(GroupObject
,
4539 case GroupAdminCommentInformation
:
4540 Status
= SampSetObjectAttributeString(GroupObject
,
4542 &Buffer
->AdminComment
.AdminComment
);
4546 Status
= STATUS_INVALID_INFO_CLASS
;
4551 RtlReleaseResource(&SampResource
);
4560 SamrAddMemberToGroup(IN SAMPR_HANDLE GroupHandle
,
4561 IN
unsigned long MemberId
,
4562 IN
unsigned long Attributes
)
4564 PSAM_DB_OBJECT GroupObject
;
4565 PSAM_DB_OBJECT UserObject
= NULL
;
4568 TRACE("(%p %lu %lx)\n",
4569 GroupHandle
, MemberId
, Attributes
);
4571 RtlAcquireResourceExclusive(&SampResource
,
4574 /* Validate the group handle */
4575 Status
= SampValidateDbObject(GroupHandle
,
4579 if (!NT_SUCCESS(Status
))
4582 /* Open the user object in the same domain */
4583 Status
= SampOpenUserObject(GroupObject
->ParentObject
,
4587 if (!NT_SUCCESS(Status
))
4589 TRACE("SampOpenUserObject() failed (Status 0x%08lx)\n", Status
);
4593 /* Add group membership to the user object */
4594 Status
= SampAddGroupMembershipToUser(UserObject
,
4595 GroupObject
->RelativeId
,
4597 if (!NT_SUCCESS(Status
))
4599 TRACE("SampAddGroupMembershipToUser() failed (Status 0x%08lx)\n", Status
);
4603 /* Add the member to the group object */
4604 Status
= SampAddMemberToGroup(GroupObject
,
4606 if (!NT_SUCCESS(Status
))
4608 TRACE("SampAddMemberToGroup() failed (Status 0x%08lx)\n", Status
);
4613 SampCloseDbObject(UserObject
);
4615 RtlReleaseResource(&SampResource
);
4624 SamrDeleteGroup(IN OUT SAMPR_HANDLE
*GroupHandle
)
4626 PSAM_DB_OBJECT GroupObject
;
4630 TRACE("(%p)\n", GroupHandle
);
4632 RtlAcquireResourceExclusive(&SampResource
,
4635 /* Validate the group handle */
4636 Status
= SampValidateDbObject(*GroupHandle
,
4640 if (!NT_SUCCESS(Status
))
4642 TRACE("SampValidateDbObject() failed (Status 0x%08lx)\n", Status
);
4646 /* Fail, if the group is built-in */
4647 if (GroupObject
->RelativeId
< 1000)
4649 TRACE("You can not delete a special account!\n");
4650 Status
= STATUS_SPECIAL_ACCOUNT
;
4654 /* Get the length of the Members attribute */
4655 SampGetObjectAttribute(GroupObject
,
4661 /* Fail, if the group has members */
4664 TRACE("There are still members in the group!\n");
4665 Status
= STATUS_MEMBER_IN_GROUP
;
4669 /* FIXME: Remove the group from all aliases */
4671 /* Delete the group from the database */
4672 Status
= SampDeleteAccountDbObject(GroupObject
);
4673 if (!NT_SUCCESS(Status
))
4675 TRACE("SampDeleteAccountDbObject() failed (Status 0x%08lx)\n", Status
);
4679 /* Invalidate the handle */
4680 *GroupHandle
= NULL
;
4683 RtlReleaseResource(&SampResource
);
4692 SamrRemoveMemberFromGroup(IN SAMPR_HANDLE GroupHandle
,
4693 IN
unsigned long MemberId
)
4695 PSAM_DB_OBJECT GroupObject
;
4696 PSAM_DB_OBJECT UserObject
= NULL
;
4700 GroupHandle
, MemberId
);
4702 RtlAcquireResourceExclusive(&SampResource
,
4705 /* Validate the group handle */
4706 Status
= SampValidateDbObject(GroupHandle
,
4708 GROUP_REMOVE_MEMBER
,
4710 if (!NT_SUCCESS(Status
))
4713 /* Open the user object in the same domain */
4714 Status
= SampOpenUserObject(GroupObject
->ParentObject
,
4718 if (!NT_SUCCESS(Status
))
4720 ERR("SampOpenUserObject() failed (Status 0x%08lx)\n", Status
);
4724 /* Remove group membership from the user object */
4725 Status
= SampRemoveGroupMembershipFromUser(UserObject
,
4726 GroupObject
->RelativeId
);
4727 if (!NT_SUCCESS(Status
))
4729 ERR("SampAddGroupMembershipToUser() failed (Status 0x%08lx)\n", Status
);
4733 /* Remove the member from the group object */
4734 Status
= SampRemoveMemberFromGroup(GroupObject
,
4736 if (!NT_SUCCESS(Status
))
4738 ERR("SampRemoveMemberFromGroup() failed (Status 0x%08lx)\n", Status
);
4743 SampCloseDbObject(UserObject
);
4745 RtlReleaseResource(&SampResource
);
4754 SamrGetMembersInGroup(IN SAMPR_HANDLE GroupHandle
,
4755 OUT PSAMPR_GET_MEMBERS_BUFFER
*Members
)
4757 PSAMPR_GET_MEMBERS_BUFFER MembersBuffer
= NULL
;
4758 PSAM_DB_OBJECT GroupObject
;
4763 RtlAcquireResourceShared(&SampResource
,
4766 /* Validate the group handle */
4767 Status
= SampValidateDbObject(GroupHandle
,
4771 if (!NT_SUCCESS(Status
))
4774 MembersBuffer
= midl_user_allocate(sizeof(SAMPR_GET_MEMBERS_BUFFER
));
4775 if (MembersBuffer
== NULL
)
4777 Status
= STATUS_INSUFFICIENT_RESOURCES
;
4781 SampGetObjectAttribute(GroupObject
,
4789 MembersBuffer
->MemberCount
= 0;
4790 MembersBuffer
->Members
= NULL
;
4791 MembersBuffer
->Attributes
= NULL
;
4793 *Members
= MembersBuffer
;
4795 Status
= STATUS_SUCCESS
;
4799 MembersBuffer
->Members
= midl_user_allocate(Length
);
4800 if (MembersBuffer
->Members
== NULL
)
4802 Status
= STATUS_INSUFFICIENT_RESOURCES
;
4806 MembersBuffer
->Attributes
= midl_user_allocate(Length
);
4807 if (MembersBuffer
->Attributes
== NULL
)
4809 Status
= STATUS_INSUFFICIENT_RESOURCES
;
4813 Status
= SampGetObjectAttribute(GroupObject
,
4816 MembersBuffer
->Members
,
4818 if (!NT_SUCCESS(Status
))
4820 TRACE("SampGetObjectAttributes() failed (Status 0x%08lx)\n", Status
);
4824 MembersBuffer
->MemberCount
= Length
/ sizeof(ULONG
);
4826 for (i
= 0; i
< MembersBuffer
->MemberCount
; i
++)
4828 Status
= SampGetUserGroupAttributes(GroupObject
->ParentObject
,
4829 MembersBuffer
->Members
[i
],
4830 GroupObject
->RelativeId
,
4831 &(MembersBuffer
->Attributes
[i
]));
4832 if (!NT_SUCCESS(Status
))
4834 TRACE("SampGetUserGroupAttributes() failed (Status 0x%08lx)\n", Status
);
4839 *Members
= MembersBuffer
;
4842 if (!NT_SUCCESS(Status
))
4844 if (MembersBuffer
!= NULL
)
4846 if (MembersBuffer
->Members
!= NULL
)
4847 midl_user_free(MembersBuffer
->Members
);
4849 if (MembersBuffer
->Attributes
!= NULL
)
4850 midl_user_free(MembersBuffer
->Attributes
);
4852 midl_user_free(MembersBuffer
);
4856 RtlReleaseResource(&SampResource
);
4865 SamrSetMemberAttributesOfGroup(IN SAMPR_HANDLE GroupHandle
,
4866 IN
unsigned long MemberId
,
4867 IN
unsigned long Attributes
)
4869 PSAM_DB_OBJECT GroupObject
;
4872 RtlAcquireResourceExclusive(&SampResource
,
4875 /* Validate the group handle */
4876 Status
= SampValidateDbObject(GroupHandle
,
4880 if (!NT_SUCCESS(Status
))
4882 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
4886 Status
= SampSetUserGroupAttributes(GroupObject
->ParentObject
,
4888 GroupObject
->RelativeId
,
4890 if (!NT_SUCCESS(Status
))
4892 TRACE("SampSetUserGroupAttributes failed with status 0x%08lx\n", Status
);
4896 RtlReleaseResource(&SampResource
);
4905 SamrOpenAlias(IN SAMPR_HANDLE DomainHandle
,
4906 IN ACCESS_MASK DesiredAccess
,
4908 OUT SAMPR_HANDLE
*AliasHandle
)
4910 PSAM_DB_OBJECT DomainObject
;
4911 PSAM_DB_OBJECT AliasObject
;
4915 TRACE("SamrOpenAlias(%p %lx %lx %p)\n",
4916 DomainHandle
, DesiredAccess
, AliasId
, AliasHandle
);
4918 /* Map generic access rights */
4919 RtlMapGenericMask(&DesiredAccess
,
4922 RtlAcquireResourceShared(&SampResource
,
4925 /* Validate the domain handle */
4926 Status
= SampValidateDbObject(DomainHandle
,
4930 if (!NT_SUCCESS(Status
))
4932 TRACE("failed with status 0x%08lx\n", Status
);
4936 /* Convert the RID into a string (hex) */
4937 swprintf(szRid
, L
"%08lX", AliasId
);
4939 /* Create the alias object */
4940 Status
= SampOpenDbObject(DomainObject
,
4947 if (!NT_SUCCESS(Status
))
4949 TRACE("failed with status 0x%08lx\n", Status
);
4953 *AliasHandle
= (SAMPR_HANDLE
)AliasObject
;
4956 RtlReleaseResource(&SampResource
);
4963 SampQueryAliasGeneral(PSAM_DB_OBJECT AliasObject
,
4964 PSAMPR_ALIAS_INFO_BUFFER
*Buffer
)
4966 PSAMPR_ALIAS_INFO_BUFFER InfoBuffer
= NULL
;
4967 HANDLE MembersKeyHandle
= NULL
;
4972 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_ALIAS_INFO_BUFFER
));
4973 if (InfoBuffer
== NULL
)
4974 return STATUS_INSUFFICIENT_RESOURCES
;
4976 Status
= SampGetObjectAttributeString(AliasObject
,
4978 &InfoBuffer
->General
.Name
);
4979 if (!NT_SUCCESS(Status
))
4981 TRACE("Status 0x%08lx\n", Status
);
4985 Status
= SampGetObjectAttributeString(AliasObject
,
4987 &InfoBuffer
->General
.AdminComment
);
4988 if (!NT_SUCCESS(Status
))
4990 TRACE("Status 0x%08lx\n", Status
);
4994 /* Open the Members subkey */
4995 Status
= SampRegOpenKey(AliasObject
->KeyHandle
,
4999 if (NT_SUCCESS(Status
))
5001 /* Retrieve the number of members of the alias */
5002 Status
= SampRegQueryKeyInfo(MembersKeyHandle
,
5004 &InfoBuffer
->General
.MemberCount
);
5005 if (!NT_SUCCESS(Status
))
5007 TRACE("Status 0x%08lx\n", Status
);
5011 else if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
5013 InfoBuffer
->General
.MemberCount
= 0;
5014 Status
= STATUS_SUCCESS
;
5018 TRACE("Status 0x%08lx\n", Status
);
5022 *Buffer
= InfoBuffer
;
5025 SampRegCloseKey(&MembersKeyHandle
);
5027 if (!NT_SUCCESS(Status
))
5029 if (InfoBuffer
!= NULL
)
5031 if (InfoBuffer
->General
.Name
.Buffer
!= NULL
)
5032 midl_user_free(InfoBuffer
->General
.Name
.Buffer
);
5034 if (InfoBuffer
->General
.AdminComment
.Buffer
!= NULL
)
5035 midl_user_free(InfoBuffer
->General
.AdminComment
.Buffer
);
5037 midl_user_free(InfoBuffer
);
5046 SampQueryAliasName(PSAM_DB_OBJECT AliasObject
,
5047 PSAMPR_ALIAS_INFO_BUFFER
*Buffer
)
5049 PSAMPR_ALIAS_INFO_BUFFER InfoBuffer
= NULL
;
5054 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_ALIAS_INFO_BUFFER
));
5055 if (InfoBuffer
== NULL
)
5056 return STATUS_INSUFFICIENT_RESOURCES
;
5058 Status
= SampGetObjectAttributeString(AliasObject
,
5060 &InfoBuffer
->Name
.Name
);
5061 if (!NT_SUCCESS(Status
))
5063 TRACE("Status 0x%08lx\n", Status
);
5067 *Buffer
= InfoBuffer
;
5070 if (!NT_SUCCESS(Status
))
5072 if (InfoBuffer
!= NULL
)
5074 if (InfoBuffer
->Name
.Name
.Buffer
!= NULL
)
5075 midl_user_free(InfoBuffer
->Name
.Name
.Buffer
);
5077 midl_user_free(InfoBuffer
);
5086 SampQueryAliasAdminComment(PSAM_DB_OBJECT AliasObject
,
5087 PSAMPR_ALIAS_INFO_BUFFER
*Buffer
)
5089 PSAMPR_ALIAS_INFO_BUFFER InfoBuffer
= NULL
;
5094 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_ALIAS_INFO_BUFFER
));
5095 if (InfoBuffer
== NULL
)
5096 return STATUS_INSUFFICIENT_RESOURCES
;
5098 Status
= SampGetObjectAttributeString(AliasObject
,
5100 &InfoBuffer
->AdminComment
.AdminComment
);
5101 if (!NT_SUCCESS(Status
))
5103 TRACE("Status 0x%08lx\n", Status
);
5107 *Buffer
= InfoBuffer
;
5110 if (!NT_SUCCESS(Status
))
5112 if (InfoBuffer
!= NULL
)
5114 if (InfoBuffer
->AdminComment
.AdminComment
.Buffer
!= NULL
)
5115 midl_user_free(InfoBuffer
->AdminComment
.AdminComment
.Buffer
);
5117 midl_user_free(InfoBuffer
);
5128 SamrQueryInformationAlias(IN SAMPR_HANDLE AliasHandle
,
5129 IN ALIAS_INFORMATION_CLASS AliasInformationClass
,
5130 OUT PSAMPR_ALIAS_INFO_BUFFER
*Buffer
)
5132 PSAM_DB_OBJECT AliasObject
;
5135 TRACE("SamrQueryInformationAlias(%p %lu %p)\n",
5136 AliasHandle
, AliasInformationClass
, Buffer
);
5138 RtlAcquireResourceShared(&SampResource
,
5141 /* Validate the alias handle */
5142 Status
= SampValidateDbObject(AliasHandle
,
5144 ALIAS_READ_INFORMATION
,
5146 if (!NT_SUCCESS(Status
))
5149 switch (AliasInformationClass
)
5151 case AliasGeneralInformation
:
5152 Status
= SampQueryAliasGeneral(AliasObject
,
5156 case AliasNameInformation
:
5157 Status
= SampQueryAliasName(AliasObject
,
5161 case AliasAdminCommentInformation
:
5162 Status
= SampQueryAliasAdminComment(AliasObject
,
5167 Status
= STATUS_INVALID_INFO_CLASS
;
5172 RtlReleaseResource(&SampResource
);
5179 SampSetAliasName(PSAM_DB_OBJECT AliasObject
,
5180 PSAMPR_ALIAS_INFO_BUFFER Buffer
)
5182 UNICODE_STRING OldAliasName
= {0, 0, NULL
};
5183 UNICODE_STRING NewAliasName
;
5186 Status
= SampGetObjectAttributeString(AliasObject
,
5188 (PRPC_UNICODE_STRING
)&OldAliasName
);
5189 if (!NT_SUCCESS(Status
))
5191 TRACE("SampGetObjectAttributeString failed (Status 0x%08lx)\n", Status
);
5195 /* Check the new account name */
5196 Status
= SampCheckAccountName(&Buffer
->Name
.Name
, 256);
5197 if (!NT_SUCCESS(Status
))
5199 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
5203 NewAliasName
.Length
= Buffer
->Name
.Name
.Length
;
5204 NewAliasName
.MaximumLength
= Buffer
->Name
.Name
.MaximumLength
;
5205 NewAliasName
.Buffer
= Buffer
->Name
.Name
.Buffer
;
5207 if (!RtlEqualUnicodeString(&OldAliasName
, &NewAliasName
, TRUE
))
5209 Status
= SampCheckAccountNameInDomain(AliasObject
->ParentObject
,
5210 NewAliasName
.Buffer
);
5211 if (!NT_SUCCESS(Status
))
5213 TRACE("Alias name \'%S\' already exists in domain (Status 0x%08lx)\n",
5214 NewAliasName
.Buffer
, Status
);
5219 Status
= SampSetAccountNameInDomain(AliasObject
->ParentObject
,
5221 NewAliasName
.Buffer
,
5222 AliasObject
->RelativeId
);
5223 if (!NT_SUCCESS(Status
))
5225 TRACE("SampSetAccountNameInDomain failed (Status 0x%08lx)\n", Status
);
5229 Status
= SampRemoveAccountNameFromDomain(AliasObject
->ParentObject
,
5231 OldAliasName
.Buffer
);
5232 if (!NT_SUCCESS(Status
))
5234 TRACE("SampRemoveAccountNameFromDomain failed (Status 0x%08lx)\n", Status
);
5238 Status
= SampSetObjectAttributeString(AliasObject
,
5240 (PRPC_UNICODE_STRING
)&NewAliasName
);
5241 if (!NT_SUCCESS(Status
))
5243 TRACE("SampSetObjectAttribute failed (Status 0x%08lx)\n", Status
);
5247 if (OldAliasName
.Buffer
!= NULL
)
5248 midl_user_free(OldAliasName
.Buffer
);
5257 SamrSetInformationAlias(IN SAMPR_HANDLE AliasHandle
,
5258 IN ALIAS_INFORMATION_CLASS AliasInformationClass
,
5259 IN PSAMPR_ALIAS_INFO_BUFFER Buffer
)
5261 PSAM_DB_OBJECT AliasObject
;
5264 TRACE("SamrSetInformationAlias(%p %lu %p)\n",
5265 AliasHandle
, AliasInformationClass
, Buffer
);
5267 RtlAcquireResourceExclusive(&SampResource
,
5270 /* Validate the alias handle */
5271 Status
= SampValidateDbObject(AliasHandle
,
5273 ALIAS_WRITE_ACCOUNT
,
5275 if (!NT_SUCCESS(Status
))
5278 switch (AliasInformationClass
)
5280 case AliasNameInformation
:
5281 Status
= SampSetAliasName(AliasObject
,
5285 case AliasAdminCommentInformation
:
5286 Status
= SampSetObjectAttributeString(AliasObject
,
5288 &Buffer
->AdminComment
.AdminComment
);
5292 Status
= STATUS_INVALID_INFO_CLASS
;
5297 RtlReleaseResource(&SampResource
);
5306 SamrDeleteAlias(IN OUT SAMPR_HANDLE
*AliasHandle
)
5308 PSAM_DB_OBJECT AliasObject
;
5311 RtlAcquireResourceExclusive(&SampResource
,
5314 /* Validate the alias handle */
5315 Status
= SampValidateDbObject(*AliasHandle
,
5319 if (!NT_SUCCESS(Status
))
5321 TRACE("SampValidateDbObject failed (Status 0x%08lx)\n", Status
);
5325 /* Fail, if the alias is built-in */
5326 if (AliasObject
->RelativeId
< 1000)
5328 TRACE("You can not delete a special account!\n");
5329 Status
= STATUS_SPECIAL_ACCOUNT
;
5333 /* Remove all members from the alias */
5334 Status
= SampRemoveAllMembersFromAlias(AliasObject
);
5335 if (!NT_SUCCESS(Status
))
5337 TRACE("SampRemoveAllMembersFromAlias() failed (Status 0x%08lx)\n", Status
);
5341 /* Delete the alias from the database */
5342 Status
= SampDeleteAccountDbObject(AliasObject
);
5343 if (!NT_SUCCESS(Status
))
5345 TRACE("SampDeleteAccountDbObject() failed (Status 0x%08lx)\n", Status
);
5349 /* Invalidate the handle */
5350 *AliasHandle
= NULL
;
5353 RtlReleaseResource(&SampResource
);
5362 SamrAddMemberToAlias(IN SAMPR_HANDLE AliasHandle
,
5363 IN PRPC_SID MemberId
)
5365 PSAM_DB_OBJECT AliasObject
;
5368 TRACE("(%p %p)\n", AliasHandle
, MemberId
);
5370 RtlAcquireResourceExclusive(&SampResource
,
5373 /* Validate the alias handle */
5374 Status
= SampValidateDbObject(AliasHandle
,
5378 if (!NT_SUCCESS(Status
))
5380 TRACE("failed with status 0x%08lx\n", Status
);
5384 Status
= SampAddMemberToAlias(AliasObject
,
5386 if (!NT_SUCCESS(Status
))
5388 TRACE("failed with status 0x%08lx\n", Status
);
5392 RtlReleaseResource(&SampResource
);
5401 SamrRemoveMemberFromAlias(IN SAMPR_HANDLE AliasHandle
,
5402 IN PRPC_SID MemberId
)
5404 PSAM_DB_OBJECT AliasObject
;
5407 TRACE("(%p %p)\n", AliasHandle
, MemberId
);
5409 RtlAcquireResourceExclusive(&SampResource
,
5412 /* Validate the alias handle */
5413 Status
= SampValidateDbObject(AliasHandle
,
5415 ALIAS_REMOVE_MEMBER
,
5417 if (!NT_SUCCESS(Status
))
5419 TRACE("failed with status 0x%08lx\n", Status
);
5423 Status
= SampRemoveMemberFromAlias(AliasObject
,
5425 if (!NT_SUCCESS(Status
))
5427 TRACE("failed with status 0x%08lx\n", Status
);
5431 RtlReleaseResource(&SampResource
);
5440 SamrGetMembersInAlias(IN SAMPR_HANDLE AliasHandle
,
5441 OUT PSAMPR_PSID_ARRAY_OUT Members
)
5443 PSAM_DB_OBJECT AliasObject
;
5444 PSAMPR_SID_INFORMATION MemberArray
= NULL
;
5445 ULONG MemberCount
= 0;
5449 TRACE("SamrGetMembersInAlias(%p %p %p)\n",
5450 AliasHandle
, Members
);
5452 RtlAcquireResourceShared(&SampResource
,
5455 /* Validate the alias handle */
5456 Status
= SampValidateDbObject(AliasHandle
,
5460 if (!NT_SUCCESS(Status
))
5462 ERR("failed with status 0x%08lx\n", Status
);
5466 Status
= SampGetMembersInAlias(AliasObject
,
5470 /* Return the number of members and the member array */
5471 if (NT_SUCCESS(Status
))
5473 Members
->Count
= MemberCount
;
5474 Members
->Sids
= MemberArray
;
5478 /* Clean up the members array and the SID buffers if something failed */
5479 if (!NT_SUCCESS(Status
))
5481 if (MemberArray
!= NULL
)
5483 for (Index
= 0; Index
< MemberCount
; Index
++)
5485 if (MemberArray
[Index
].SidPointer
!= NULL
)
5486 midl_user_free(MemberArray
[Index
].SidPointer
);
5489 midl_user_free(MemberArray
);
5493 RtlReleaseResource(&SampResource
);
5502 SamrOpenUser(IN SAMPR_HANDLE DomainHandle
,
5503 IN ACCESS_MASK DesiredAccess
,
5504 IN
unsigned long UserId
,
5505 OUT SAMPR_HANDLE
*UserHandle
)
5507 PSAM_DB_OBJECT DomainObject
;
5508 PSAM_DB_OBJECT UserObject
;
5512 TRACE("SamrOpenUser(%p %lx %lx %p)\n",
5513 DomainHandle
, DesiredAccess
, UserId
, UserHandle
);
5515 /* Map generic access rights */
5516 RtlMapGenericMask(&DesiredAccess
,
5519 RtlAcquireResourceShared(&SampResource
,
5522 /* Validate the domain handle */
5523 Status
= SampValidateDbObject(DomainHandle
,
5527 if (!NT_SUCCESS(Status
))
5529 TRACE("failed with status 0x%08lx\n", Status
);
5533 /* Convert the RID into a string (hex) */
5534 swprintf(szRid
, L
"%08lX", UserId
);
5536 /* Create the user object */
5537 Status
= SampOpenDbObject(DomainObject
,
5544 if (!NT_SUCCESS(Status
))
5546 TRACE("failed with status 0x%08lx\n", Status
);
5550 *UserHandle
= (SAMPR_HANDLE
)UserObject
;
5553 RtlReleaseResource(&SampResource
);
5562 SamrDeleteUser(IN OUT SAMPR_HANDLE
*UserHandle
)
5564 PSAM_DB_OBJECT UserObject
;
5567 TRACE("(%p)\n", UserHandle
);
5569 RtlAcquireResourceExclusive(&SampResource
,
5572 /* Validate the user handle */
5573 Status
= SampValidateDbObject(*UserHandle
,
5577 if (!NT_SUCCESS(Status
))
5579 TRACE("SampValidateDbObject() failed (Status 0x%08lx)\n", Status
);
5583 /* Fail, if the user is built-in */
5584 if (UserObject
->RelativeId
< 1000)
5586 TRACE("You can not delete a special account!\n");
5587 Status
= STATUS_SPECIAL_ACCOUNT
;
5591 /* Remove the user from all groups */
5592 Status
= SampRemoveUserFromAllGroups(UserObject
);
5593 if (!NT_SUCCESS(Status
))
5595 TRACE("SampRemoveUserFromAllGroups() failed (Status 0x%08lx)\n", Status
);
5599 /* Remove the user from all aliases */
5600 Status
= SampRemoveUserFromAllAliases(UserObject
);
5601 if (!NT_SUCCESS(Status
))
5603 TRACE("SampRemoveUserFromAllAliases() failed (Status 0x%08lx)\n", Status
);
5607 /* Delete the user from the database */
5608 Status
= SampDeleteAccountDbObject(UserObject
);
5609 if (!NT_SUCCESS(Status
))
5611 TRACE("SampDeleteAccountDbObject() failed (Status 0x%08lx)\n", Status
);
5615 /* Invalidate the handle */
5619 RtlReleaseResource(&SampResource
);
5627 SampQueryUserGeneral(PSAM_DB_OBJECT UserObject
,
5628 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5630 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5631 SAM_USER_FIXED_DATA FixedData
;
5637 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5638 if (InfoBuffer
== NULL
)
5639 return STATUS_INSUFFICIENT_RESOURCES
;
5641 Length
= sizeof(SAM_USER_FIXED_DATA
);
5642 Status
= SampGetObjectAttribute(UserObject
,
5647 if (!NT_SUCCESS(Status
))
5650 InfoBuffer
->General
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
5652 /* Get the Name string */
5653 Status
= SampGetObjectAttributeString(UserObject
,
5655 &InfoBuffer
->General
.UserName
);
5656 if (!NT_SUCCESS(Status
))
5658 TRACE("Status 0x%08lx\n", Status
);
5662 /* Get the FullName string */
5663 Status
= SampGetObjectAttributeString(UserObject
,
5665 &InfoBuffer
->General
.FullName
);
5666 if (!NT_SUCCESS(Status
))
5668 TRACE("Status 0x%08lx\n", Status
);
5672 /* Get the AdminComment string */
5673 Status
= SampGetObjectAttributeString(UserObject
,
5675 &InfoBuffer
->General
.AdminComment
);
5676 if (!NT_SUCCESS(Status
))
5678 TRACE("Status 0x%08lx\n", Status
);
5682 /* Get the UserComment string */
5683 Status
= SampGetObjectAttributeString(UserObject
,
5685 &InfoBuffer
->General
.UserComment
);
5686 if (!NT_SUCCESS(Status
))
5688 TRACE("Status 0x%08lx\n", Status
);
5692 *Buffer
= InfoBuffer
;
5695 if (!NT_SUCCESS(Status
))
5697 if (InfoBuffer
!= NULL
)
5699 if (InfoBuffer
->General
.UserName
.Buffer
!= NULL
)
5700 midl_user_free(InfoBuffer
->General
.UserName
.Buffer
);
5702 if (InfoBuffer
->General
.FullName
.Buffer
!= NULL
)
5703 midl_user_free(InfoBuffer
->General
.FullName
.Buffer
);
5705 if (InfoBuffer
->General
.AdminComment
.Buffer
!= NULL
)
5706 midl_user_free(InfoBuffer
->General
.AdminComment
.Buffer
);
5708 if (InfoBuffer
->General
.UserComment
.Buffer
!= NULL
)
5709 midl_user_free(InfoBuffer
->General
.UserComment
.Buffer
);
5711 midl_user_free(InfoBuffer
);
5721 SampQueryUserPreferences(PSAM_DB_OBJECT UserObject
,
5722 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5724 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5725 SAM_USER_FIXED_DATA FixedData
;
5731 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5732 if (InfoBuffer
== NULL
)
5733 return STATUS_INSUFFICIENT_RESOURCES
;
5735 Length
= sizeof(SAM_USER_FIXED_DATA
);
5736 Status
= SampGetObjectAttribute(UserObject
,
5741 if (!NT_SUCCESS(Status
))
5744 InfoBuffer
->Preferences
.CountryCode
= FixedData
.CountryCode
;
5745 InfoBuffer
->Preferences
.CodePage
= FixedData
.CodePage
;
5747 /* Get the UserComment string */
5748 Status
= SampGetObjectAttributeString(UserObject
,
5750 &InfoBuffer
->Preferences
.UserComment
);
5751 if (!NT_SUCCESS(Status
))
5753 TRACE("Status 0x%08lx\n", Status
);
5757 *Buffer
= InfoBuffer
;
5760 if (!NT_SUCCESS(Status
))
5762 if (InfoBuffer
!= NULL
)
5764 if (InfoBuffer
->Preferences
.UserComment
.Buffer
!= NULL
)
5765 midl_user_free(InfoBuffer
->Preferences
.UserComment
.Buffer
);
5767 midl_user_free(InfoBuffer
);
5777 SampQueryUserLogon(PSAM_DB_OBJECT UserObject
,
5778 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5780 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5781 SAM_DOMAIN_FIXED_DATA DomainFixedData
;
5782 SAM_USER_FIXED_DATA FixedData
;
5783 LARGE_INTEGER PasswordCanChange
;
5784 LARGE_INTEGER PasswordMustChange
;
5790 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5791 if (InfoBuffer
== NULL
)
5792 return STATUS_INSUFFICIENT_RESOURCES
;
5794 /* Get the fixed size domain data */
5795 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
5796 Status
= SampGetObjectAttribute(UserObject
->ParentObject
,
5799 (PVOID
)&DomainFixedData
,
5801 if (!NT_SUCCESS(Status
))
5804 /* Get the fixed size user data */
5805 Length
= sizeof(SAM_USER_FIXED_DATA
);
5806 Status
= SampGetObjectAttribute(UserObject
,
5811 if (!NT_SUCCESS(Status
))
5814 InfoBuffer
->Logon
.UserId
= FixedData
.UserId
;
5815 InfoBuffer
->Logon
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
5816 InfoBuffer
->Logon
.LastLogon
.LowPart
= FixedData
.LastLogon
.LowPart
;
5817 InfoBuffer
->Logon
.LastLogon
.HighPart
= FixedData
.LastLogon
.HighPart
;
5818 InfoBuffer
->Logon
.LastLogoff
.LowPart
= FixedData
.LastLogoff
.LowPart
;
5819 InfoBuffer
->Logon
.LastLogoff
.HighPart
= FixedData
.LastLogoff
.HighPart
;
5820 InfoBuffer
->Logon
.PasswordLastSet
.LowPart
= FixedData
.PasswordLastSet
.LowPart
;
5821 InfoBuffer
->Logon
.PasswordLastSet
.HighPart
= FixedData
.PasswordLastSet
.HighPart
;
5822 InfoBuffer
->Logon
.BadPasswordCount
= FixedData
.BadPasswordCount
;
5823 InfoBuffer
->Logon
.LogonCount
= FixedData
.LogonCount
;
5824 InfoBuffer
->Logon
.UserAccountControl
= FixedData
.UserAccountControl
;
5826 PasswordCanChange
= SampAddRelativeTimeToTime(FixedData
.PasswordLastSet
,
5827 DomainFixedData
.MinPasswordAge
);
5828 InfoBuffer
->Logon
.PasswordCanChange
.LowPart
= PasswordCanChange
.LowPart
;
5829 InfoBuffer
->Logon
.PasswordCanChange
.HighPart
= PasswordCanChange
.HighPart
;
5831 PasswordMustChange
= SampAddRelativeTimeToTime(FixedData
.PasswordLastSet
,
5832 DomainFixedData
.MaxPasswordAge
);
5833 InfoBuffer
->Logon
.PasswordMustChange
.LowPart
= PasswordMustChange
.LowPart
;
5834 InfoBuffer
->Logon
.PasswordMustChange
.HighPart
= PasswordMustChange
.HighPart
;
5836 /* Get the Name string */
5837 Status
= SampGetObjectAttributeString(UserObject
,
5839 &InfoBuffer
->Logon
.UserName
);
5840 if (!NT_SUCCESS(Status
))
5842 TRACE("Status 0x%08lx\n", Status
);
5846 /* Get the FullName string */
5847 Status
= SampGetObjectAttributeString(UserObject
,
5849 &InfoBuffer
->Logon
.FullName
);
5850 if (!NT_SUCCESS(Status
))
5852 TRACE("Status 0x%08lx\n", Status
);
5856 /* Get the HomeDirectory string */
5857 Status
= SampGetObjectAttributeString(UserObject
,
5859 &InfoBuffer
->Logon
.HomeDirectory
);
5860 if (!NT_SUCCESS(Status
))
5862 TRACE("Status 0x%08lx\n", Status
);
5866 /* Get the HomeDirectoryDrive string */
5867 Status
= SampGetObjectAttributeString(UserObject
,
5868 L
"HomeDirectoryDrive",
5869 &InfoBuffer
->Logon
.HomeDirectoryDrive
);
5870 if (!NT_SUCCESS(Status
))
5872 TRACE("Status 0x%08lx\n", Status
);
5876 /* Get the ScriptPath string */
5877 Status
= SampGetObjectAttributeString(UserObject
,
5879 &InfoBuffer
->Logon
.ScriptPath
);
5880 if (!NT_SUCCESS(Status
))
5882 TRACE("Status 0x%08lx\n", Status
);
5886 /* Get the ProfilePath string */
5887 Status
= SampGetObjectAttributeString(UserObject
,
5889 &InfoBuffer
->Logon
.ProfilePath
);
5890 if (!NT_SUCCESS(Status
))
5892 TRACE("Status 0x%08lx\n", Status
);
5896 /* Get the WorkStations string */
5897 Status
= SampGetObjectAttributeString(UserObject
,
5899 &InfoBuffer
->Logon
.WorkStations
);
5900 if (!NT_SUCCESS(Status
))
5902 TRACE("Status 0x%08lx\n", Status
);
5906 /* Get the LogonHours attribute */
5907 Status
= SampGetLogonHoursAttribute(UserObject
,
5908 &InfoBuffer
->Logon
.LogonHours
);
5909 if (!NT_SUCCESS(Status
))
5911 TRACE("Status 0x%08lx\n", Status
);
5915 *Buffer
= InfoBuffer
;
5918 if (!NT_SUCCESS(Status
))
5920 if (InfoBuffer
!= NULL
)
5922 if (InfoBuffer
->Logon
.UserName
.Buffer
!= NULL
)
5923 midl_user_free(InfoBuffer
->Logon
.UserName
.Buffer
);
5925 if (InfoBuffer
->Logon
.FullName
.Buffer
!= NULL
)
5926 midl_user_free(InfoBuffer
->Logon
.FullName
.Buffer
);
5928 if (InfoBuffer
->Logon
.HomeDirectory
.Buffer
!= NULL
)
5929 midl_user_free(InfoBuffer
->Logon
.HomeDirectory
.Buffer
);
5931 if (InfoBuffer
->Logon
.HomeDirectoryDrive
.Buffer
!= NULL
)
5932 midl_user_free(InfoBuffer
->Logon
.HomeDirectoryDrive
.Buffer
);
5934 if (InfoBuffer
->Logon
.ScriptPath
.Buffer
!= NULL
)
5935 midl_user_free(InfoBuffer
->Logon
.ScriptPath
.Buffer
);
5937 if (InfoBuffer
->Logon
.ProfilePath
.Buffer
!= NULL
)
5938 midl_user_free(InfoBuffer
->Logon
.ProfilePath
.Buffer
);
5940 if (InfoBuffer
->Logon
.WorkStations
.Buffer
!= NULL
)
5941 midl_user_free(InfoBuffer
->Logon
.WorkStations
.Buffer
);
5943 if (InfoBuffer
->Logon
.LogonHours
.LogonHours
!= NULL
)
5944 midl_user_free(InfoBuffer
->Logon
.LogonHours
.LogonHours
);
5946 midl_user_free(InfoBuffer
);
5956 SampQueryUserAccount(PSAM_DB_OBJECT UserObject
,
5957 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5959 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5960 SAM_USER_FIXED_DATA FixedData
;
5966 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5967 if (InfoBuffer
== NULL
)
5968 return STATUS_INSUFFICIENT_RESOURCES
;
5970 Length
= sizeof(SAM_USER_FIXED_DATA
);
5971 Status
= SampGetObjectAttribute(UserObject
,
5976 if (!NT_SUCCESS(Status
))
5979 InfoBuffer
->Account
.UserId
= FixedData
.UserId
;
5980 InfoBuffer
->Account
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
5981 InfoBuffer
->Account
.LastLogon
.LowPart
= FixedData
.LastLogon
.LowPart
;
5982 InfoBuffer
->Account
.LastLogon
.HighPart
= FixedData
.LastLogon
.HighPart
;
5983 InfoBuffer
->Account
.LastLogoff
.LowPart
= FixedData
.LastLogoff
.LowPart
;
5984 InfoBuffer
->Account
.LastLogoff
.HighPart
= FixedData
.LastLogoff
.HighPart
;
5985 InfoBuffer
->Account
.PasswordLastSet
.LowPart
= FixedData
.PasswordLastSet
.LowPart
;
5986 InfoBuffer
->Account
.PasswordLastSet
.HighPart
= FixedData
.PasswordLastSet
.HighPart
;
5987 InfoBuffer
->Account
.AccountExpires
.LowPart
= FixedData
.AccountExpires
.LowPart
;
5988 InfoBuffer
->Account
.AccountExpires
.HighPart
= FixedData
.AccountExpires
.HighPart
;
5989 InfoBuffer
->Account
.BadPasswordCount
= FixedData
.BadPasswordCount
;
5990 InfoBuffer
->Account
.LogonCount
= FixedData
.LogonCount
;
5991 InfoBuffer
->Account
.UserAccountControl
= FixedData
.UserAccountControl
;
5993 /* Get the Name string */
5994 Status
= SampGetObjectAttributeString(UserObject
,
5996 &InfoBuffer
->Account
.UserName
);
5997 if (!NT_SUCCESS(Status
))
5999 TRACE("Status 0x%08lx\n", Status
);
6003 /* Get the FullName string */
6004 Status
= SampGetObjectAttributeString(UserObject
,
6006 &InfoBuffer
->Account
.FullName
);
6007 if (!NT_SUCCESS(Status
))
6009 TRACE("Status 0x%08lx\n", Status
);
6013 /* Get the HomeDirectory string */
6014 Status
= SampGetObjectAttributeString(UserObject
,
6016 &InfoBuffer
->Account
.HomeDirectory
);
6017 if (!NT_SUCCESS(Status
))
6019 TRACE("Status 0x%08lx\n", Status
);
6023 /* Get the HomeDirectoryDrive string */
6024 Status
= SampGetObjectAttributeString(UserObject
,
6025 L
"HomeDirectoryDrive",
6026 &InfoBuffer
->Account
.HomeDirectoryDrive
);
6027 if (!NT_SUCCESS(Status
))
6029 TRACE("Status 0x%08lx\n", Status
);
6033 /* Get the ScriptPath string */
6034 Status
= SampGetObjectAttributeString(UserObject
,
6036 &InfoBuffer
->Account
.ScriptPath
);
6037 if (!NT_SUCCESS(Status
))
6039 TRACE("Status 0x%08lx\n", Status
);
6043 /* Get the ProfilePath string */
6044 Status
= SampGetObjectAttributeString(UserObject
,
6046 &InfoBuffer
->Account
.ProfilePath
);
6047 if (!NT_SUCCESS(Status
))
6049 TRACE("Status 0x%08lx\n", Status
);
6053 /* Get the AdminComment string */
6054 Status
= SampGetObjectAttributeString(UserObject
,
6056 &InfoBuffer
->Account
.AdminComment
);
6057 if (!NT_SUCCESS(Status
))
6059 TRACE("Status 0x%08lx\n", Status
);
6063 /* Get the WorkStations string */
6064 Status
= SampGetObjectAttributeString(UserObject
,
6066 &InfoBuffer
->Account
.WorkStations
);
6067 if (!NT_SUCCESS(Status
))
6069 TRACE("Status 0x%08lx\n", Status
);
6073 /* Get the LogonHours attribute */
6074 Status
= SampGetLogonHoursAttribute(UserObject
,
6075 &InfoBuffer
->Account
.LogonHours
);
6076 if (!NT_SUCCESS(Status
))
6078 TRACE("Status 0x%08lx\n", Status
);
6082 *Buffer
= InfoBuffer
;
6085 if (!NT_SUCCESS(Status
))
6087 if (InfoBuffer
!= NULL
)
6089 if (InfoBuffer
->Account
.UserName
.Buffer
!= NULL
)
6090 midl_user_free(InfoBuffer
->Account
.UserName
.Buffer
);
6092 if (InfoBuffer
->Account
.FullName
.Buffer
!= NULL
)
6093 midl_user_free(InfoBuffer
->Account
.FullName
.Buffer
);
6095 if (InfoBuffer
->Account
.HomeDirectory
.Buffer
!= NULL
)
6096 midl_user_free(InfoBuffer
->Account
.HomeDirectory
.Buffer
);
6098 if (InfoBuffer
->Account
.HomeDirectoryDrive
.Buffer
!= NULL
)
6099 midl_user_free(InfoBuffer
->Account
.HomeDirectoryDrive
.Buffer
);
6101 if (InfoBuffer
->Account
.ScriptPath
.Buffer
!= NULL
)
6102 midl_user_free(InfoBuffer
->Account
.ScriptPath
.Buffer
);
6104 if (InfoBuffer
->Account
.ProfilePath
.Buffer
!= NULL
)
6105 midl_user_free(InfoBuffer
->Account
.ProfilePath
.Buffer
);
6107 if (InfoBuffer
->Account
.AdminComment
.Buffer
!= NULL
)
6108 midl_user_free(InfoBuffer
->Account
.AdminComment
.Buffer
);
6110 if (InfoBuffer
->Account
.WorkStations
.Buffer
!= NULL
)
6111 midl_user_free(InfoBuffer
->Account
.WorkStations
.Buffer
);
6113 if (InfoBuffer
->Account
.LogonHours
.LogonHours
!= NULL
)
6114 midl_user_free(InfoBuffer
->Account
.LogonHours
.LogonHours
);
6116 midl_user_free(InfoBuffer
);
6126 SampQueryUserLogonHours(PSAM_DB_OBJECT UserObject
,
6127 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6129 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6132 TRACE("(%p %p)\n", UserObject
, Buffer
);
6136 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6137 if (InfoBuffer
== NULL
)
6139 TRACE("Failed to allocate InfoBuffer!\n");
6140 return STATUS_INSUFFICIENT_RESOURCES
;
6143 Status
= SampGetLogonHoursAttribute(UserObject
,
6144 &InfoBuffer
->LogonHours
.LogonHours
);
6145 if (!NT_SUCCESS(Status
))
6147 TRACE("SampGetLogonHoursAttribute failed (Status 0x%08lx)\n", Status
);
6151 *Buffer
= InfoBuffer
;
6154 if (!NT_SUCCESS(Status
))
6156 if (InfoBuffer
!= NULL
)
6158 if (InfoBuffer
->LogonHours
.LogonHours
.LogonHours
!= NULL
)
6159 midl_user_free(InfoBuffer
->LogonHours
.LogonHours
.LogonHours
);
6161 midl_user_free(InfoBuffer
);
6171 SampQueryUserName(PSAM_DB_OBJECT UserObject
,
6172 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6174 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6179 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6180 if (InfoBuffer
== NULL
)
6181 return STATUS_INSUFFICIENT_RESOURCES
;
6183 /* Get the Name string */
6184 Status
= SampGetObjectAttributeString(UserObject
,
6186 &InfoBuffer
->Name
.UserName
);
6187 if (!NT_SUCCESS(Status
))
6189 TRACE("Status 0x%08lx\n", Status
);
6193 /* Get the FullName string */
6194 Status
= SampGetObjectAttributeString(UserObject
,
6196 &InfoBuffer
->Name
.FullName
);
6197 if (!NT_SUCCESS(Status
))
6199 TRACE("Status 0x%08lx\n", Status
);
6203 *Buffer
= InfoBuffer
;
6206 if (!NT_SUCCESS(Status
))
6208 if (InfoBuffer
!= NULL
)
6210 if (InfoBuffer
->Name
.UserName
.Buffer
!= NULL
)
6211 midl_user_free(InfoBuffer
->Name
.UserName
.Buffer
);
6213 if (InfoBuffer
->Name
.FullName
.Buffer
!= NULL
)
6214 midl_user_free(InfoBuffer
->Name
.FullName
.Buffer
);
6216 midl_user_free(InfoBuffer
);
6225 SampQueryUserAccountName(PSAM_DB_OBJECT UserObject
,
6226 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6228 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6233 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6234 if (InfoBuffer
== NULL
)
6235 return STATUS_INSUFFICIENT_RESOURCES
;
6237 /* Get the Name string */
6238 Status
= SampGetObjectAttributeString(UserObject
,
6240 &InfoBuffer
->AccountName
.UserName
);
6241 if (!NT_SUCCESS(Status
))
6243 TRACE("Status 0x%08lx\n", Status
);
6247 *Buffer
= InfoBuffer
;
6250 if (!NT_SUCCESS(Status
))
6252 if (InfoBuffer
!= NULL
)
6254 if (InfoBuffer
->AccountName
.UserName
.Buffer
!= NULL
)
6255 midl_user_free(InfoBuffer
->AccountName
.UserName
.Buffer
);
6257 midl_user_free(InfoBuffer
);
6266 SampQueryUserFullName(PSAM_DB_OBJECT UserObject
,
6267 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6269 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6274 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6275 if (InfoBuffer
== NULL
)
6276 return STATUS_INSUFFICIENT_RESOURCES
;
6278 /* Get the FullName string */
6279 Status
= SampGetObjectAttributeString(UserObject
,
6281 &InfoBuffer
->FullName
.FullName
);
6282 if (!NT_SUCCESS(Status
))
6284 TRACE("Status 0x%08lx\n", Status
);
6288 *Buffer
= InfoBuffer
;
6291 if (!NT_SUCCESS(Status
))
6293 if (InfoBuffer
!= NULL
)
6295 if (InfoBuffer
->FullName
.FullName
.Buffer
!= NULL
)
6296 midl_user_free(InfoBuffer
->FullName
.FullName
.Buffer
);
6298 midl_user_free(InfoBuffer
);
6308 SampQueryUserPrimaryGroup(PSAM_DB_OBJECT UserObject
,
6309 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6311 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6312 SAM_USER_FIXED_DATA FixedData
;
6318 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6319 if (InfoBuffer
== NULL
)
6320 return STATUS_INSUFFICIENT_RESOURCES
;
6322 Length
= sizeof(SAM_USER_FIXED_DATA
);
6323 Status
= SampGetObjectAttribute(UserObject
,
6328 if (!NT_SUCCESS(Status
))
6331 InfoBuffer
->PrimaryGroup
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
6333 *Buffer
= InfoBuffer
;
6336 if (!NT_SUCCESS(Status
))
6338 if (InfoBuffer
!= NULL
)
6340 midl_user_free(InfoBuffer
);
6349 SampQueryUserHome(PSAM_DB_OBJECT UserObject
,
6350 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6352 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6357 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6358 if (InfoBuffer
== NULL
)
6359 return STATUS_INSUFFICIENT_RESOURCES
;
6361 /* Get the HomeDirectory string */
6362 Status
= SampGetObjectAttributeString(UserObject
,
6364 &InfoBuffer
->Home
.HomeDirectory
);
6365 if (!NT_SUCCESS(Status
))
6367 TRACE("Status 0x%08lx\n", Status
);
6371 /* Get the HomeDirectoryDrive string */
6372 Status
= SampGetObjectAttributeString(UserObject
,
6373 L
"HomeDirectoryDrive",
6374 &InfoBuffer
->Home
.HomeDirectoryDrive
);
6375 if (!NT_SUCCESS(Status
))
6377 TRACE("Status 0x%08lx\n", Status
);
6381 *Buffer
= InfoBuffer
;
6384 if (!NT_SUCCESS(Status
))
6386 if (InfoBuffer
!= NULL
)
6388 if (InfoBuffer
->Home
.HomeDirectory
.Buffer
!= NULL
)
6389 midl_user_free(InfoBuffer
->Home
.HomeDirectory
.Buffer
);
6391 if (InfoBuffer
->Home
.HomeDirectoryDrive
.Buffer
!= NULL
)
6392 midl_user_free(InfoBuffer
->Home
.HomeDirectoryDrive
.Buffer
);
6394 midl_user_free(InfoBuffer
);
6403 SampQueryUserScript(PSAM_DB_OBJECT UserObject
,
6404 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6406 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6411 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6412 if (InfoBuffer
== NULL
)
6413 return STATUS_INSUFFICIENT_RESOURCES
;
6415 /* Get the ScriptPath string */
6416 Status
= SampGetObjectAttributeString(UserObject
,
6418 &InfoBuffer
->Script
.ScriptPath
);
6419 if (!NT_SUCCESS(Status
))
6421 TRACE("Status 0x%08lx\n", Status
);
6425 *Buffer
= InfoBuffer
;
6428 if (!NT_SUCCESS(Status
))
6430 if (InfoBuffer
!= NULL
)
6432 if (InfoBuffer
->Script
.ScriptPath
.Buffer
!= NULL
)
6433 midl_user_free(InfoBuffer
->Script
.ScriptPath
.Buffer
);
6435 midl_user_free(InfoBuffer
);
6444 SampQueryUserProfile(PSAM_DB_OBJECT UserObject
,
6445 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6447 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6452 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6453 if (InfoBuffer
== NULL
)
6454 return STATUS_INSUFFICIENT_RESOURCES
;
6456 /* Get the ProfilePath string */
6457 Status
= SampGetObjectAttributeString(UserObject
,
6459 &InfoBuffer
->Profile
.ProfilePath
);
6460 if (!NT_SUCCESS(Status
))
6462 TRACE("Status 0x%08lx\n", Status
);
6466 *Buffer
= InfoBuffer
;
6469 if (!NT_SUCCESS(Status
))
6471 if (InfoBuffer
!= NULL
)
6473 if (InfoBuffer
->Profile
.ProfilePath
.Buffer
!= NULL
)
6474 midl_user_free(InfoBuffer
->Profile
.ProfilePath
.Buffer
);
6476 midl_user_free(InfoBuffer
);
6485 SampQueryUserAdminComment(PSAM_DB_OBJECT UserObject
,
6486 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6488 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6493 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6494 if (InfoBuffer
== NULL
)
6495 return STATUS_INSUFFICIENT_RESOURCES
;
6497 /* Get the AdminComment string */
6498 Status
= SampGetObjectAttributeString(UserObject
,
6500 &InfoBuffer
->AdminComment
.AdminComment
);
6501 if (!NT_SUCCESS(Status
))
6503 TRACE("Status 0x%08lx\n", Status
);
6507 *Buffer
= InfoBuffer
;
6510 if (!NT_SUCCESS(Status
))
6512 if (InfoBuffer
!= NULL
)
6514 if (InfoBuffer
->AdminComment
.AdminComment
.Buffer
!= NULL
)
6515 midl_user_free(InfoBuffer
->AdminComment
.AdminComment
.Buffer
);
6517 midl_user_free(InfoBuffer
);
6526 SampQueryUserWorkStations(PSAM_DB_OBJECT UserObject
,
6527 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6529 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6534 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6535 if (InfoBuffer
== NULL
)
6536 return STATUS_INSUFFICIENT_RESOURCES
;
6538 /* Get the WorkStations string */
6539 Status
= SampGetObjectAttributeString(UserObject
,
6541 &InfoBuffer
->WorkStations
.WorkStations
);
6542 if (!NT_SUCCESS(Status
))
6544 TRACE("Status 0x%08lx\n", Status
);
6548 *Buffer
= InfoBuffer
;
6551 if (!NT_SUCCESS(Status
))
6553 if (InfoBuffer
!= NULL
)
6555 if (InfoBuffer
->WorkStations
.WorkStations
.Buffer
!= NULL
)
6556 midl_user_free(InfoBuffer
->WorkStations
.WorkStations
.Buffer
);
6558 midl_user_free(InfoBuffer
);
6568 SampQueryUserControl(PSAM_DB_OBJECT UserObject
,
6569 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6571 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6572 SAM_USER_FIXED_DATA FixedData
;
6578 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6579 if (InfoBuffer
== NULL
)
6580 return STATUS_INSUFFICIENT_RESOURCES
;
6582 Length
= sizeof(SAM_USER_FIXED_DATA
);
6583 Status
= SampGetObjectAttribute(UserObject
,
6588 if (!NT_SUCCESS(Status
))
6591 InfoBuffer
->Control
.UserAccountControl
= FixedData
.UserAccountControl
;
6593 *Buffer
= InfoBuffer
;
6596 if (!NT_SUCCESS(Status
))
6598 if (InfoBuffer
!= NULL
)
6600 midl_user_free(InfoBuffer
);
6610 SampQueryUserExpires(PSAM_DB_OBJECT UserObject
,
6611 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6613 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6614 SAM_USER_FIXED_DATA FixedData
;
6620 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6621 if (InfoBuffer
== NULL
)
6622 return STATUS_INSUFFICIENT_RESOURCES
;
6624 Length
= sizeof(SAM_USER_FIXED_DATA
);
6625 Status
= SampGetObjectAttribute(UserObject
,
6630 if (!NT_SUCCESS(Status
))
6633 InfoBuffer
->Expires
.AccountExpires
.LowPart
= FixedData
.AccountExpires
.LowPart
;
6634 InfoBuffer
->Expires
.AccountExpires
.HighPart
= FixedData
.AccountExpires
.HighPart
;
6636 *Buffer
= InfoBuffer
;
6639 if (!NT_SUCCESS(Status
))
6641 if (InfoBuffer
!= NULL
)
6643 midl_user_free(InfoBuffer
);
6653 SampQueryUserInternal1(PSAM_DB_OBJECT UserObject
,
6654 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6656 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6658 NTSTATUS Status
= STATUS_SUCCESS
;
6660 /* Fail, if the caller is not a trusted caller */
6661 if (UserObject
->Trusted
== FALSE
)
6662 return STATUS_INVALID_INFO_CLASS
;
6666 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6667 if (InfoBuffer
== NULL
)
6668 return STATUS_INSUFFICIENT_RESOURCES
;
6670 InfoBuffer
->Internal1
.LmPasswordPresent
= FALSE
;
6671 InfoBuffer
->Internal1
.NtPasswordPresent
= FALSE
;
6673 /* Get the NT password */
6675 SampGetObjectAttribute(UserObject
,
6681 if (Length
== sizeof(ENCRYPTED_NT_OWF_PASSWORD
))
6683 Status
= SampGetObjectAttribute(UserObject
,
6686 (PVOID
)&InfoBuffer
->Internal1
.EncryptedNtOwfPassword
,
6688 if (!NT_SUCCESS(Status
))
6691 if (memcmp(&InfoBuffer
->Internal1
.EncryptedNtOwfPassword
,
6693 sizeof(ENCRYPTED_NT_OWF_PASSWORD
)))
6694 InfoBuffer
->Internal1
.NtPasswordPresent
= TRUE
;
6698 /* Get the LM password */
6700 SampGetObjectAttribute(UserObject
,
6706 if (Length
== sizeof(ENCRYPTED_LM_OWF_PASSWORD
))
6708 Status
= SampGetObjectAttribute(UserObject
,
6711 (PVOID
)&InfoBuffer
->Internal1
.EncryptedLmOwfPassword
,
6713 if (!NT_SUCCESS(Status
))
6716 if (memcmp(&InfoBuffer
->Internal1
.EncryptedLmOwfPassword
,
6718 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
6719 InfoBuffer
->Internal1
.LmPasswordPresent
= TRUE
;
6722 InfoBuffer
->Internal1
.PasswordExpired
= FALSE
;
6724 *Buffer
= InfoBuffer
;
6727 if (!NT_SUCCESS(Status
))
6729 if (InfoBuffer
!= NULL
)
6731 midl_user_free(InfoBuffer
);
6740 SampQueryUserParameters(PSAM_DB_OBJECT UserObject
,
6741 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6743 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6748 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6749 if (InfoBuffer
== NULL
)
6750 return STATUS_INSUFFICIENT_RESOURCES
;
6752 /* Get the Parameters string */
6753 Status
= SampGetObjectAttributeString(UserObject
,
6755 &InfoBuffer
->Parameters
.Parameters
);
6756 if (!NT_SUCCESS(Status
))
6758 TRACE("Status 0x%08lx\n", Status
);
6762 *Buffer
= InfoBuffer
;
6765 if (!NT_SUCCESS(Status
))
6767 if (InfoBuffer
!= NULL
)
6769 if (InfoBuffer
->Parameters
.Parameters
.Buffer
!= NULL
)
6770 midl_user_free(InfoBuffer
->Parameters
.Parameters
.Buffer
);
6772 midl_user_free(InfoBuffer
);
6781 SampQueryUserAll(PSAM_DB_OBJECT UserObject
,
6782 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6784 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6785 SAM_DOMAIN_FIXED_DATA DomainFixedData
;
6786 SAM_USER_FIXED_DATA FixedData
;
6787 LARGE_INTEGER PasswordCanChange
;
6788 LARGE_INTEGER PasswordMustChange
;
6794 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6795 if (InfoBuffer
== NULL
)
6796 return STATUS_INSUFFICIENT_RESOURCES
;
6798 /* Get the fixed size domain data */
6799 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
6800 Status
= SampGetObjectAttribute(UserObject
->ParentObject
,
6803 (PVOID
)&DomainFixedData
,
6805 if (!NT_SUCCESS(Status
))
6808 /* Get the fixed size user data */
6809 Length
= sizeof(SAM_USER_FIXED_DATA
);
6810 Status
= SampGetObjectAttribute(UserObject
,
6815 if (!NT_SUCCESS(Status
))
6818 /* Set the fields to be returned */
6819 if (UserObject
->Trusted
)
6821 InfoBuffer
->All
.WhichFields
= USER_ALL_READ_GENERAL_MASK
|
6822 USER_ALL_READ_LOGON_MASK
|
6823 USER_ALL_READ_ACCOUNT_MASK
|
6824 USER_ALL_READ_PREFERENCES_MASK
|
6825 USER_ALL_READ_TRUSTED_MASK
;
6829 InfoBuffer
->All
.WhichFields
= 0;
6831 if (UserObject
->Access
& USER_READ_GENERAL
)
6832 InfoBuffer
->All
.WhichFields
|= USER_ALL_READ_GENERAL_MASK
;
6834 if (UserObject
->Access
& USER_READ_LOGON
)
6835 InfoBuffer
->All
.WhichFields
|= USER_ALL_READ_LOGON_MASK
;
6837 if (UserObject
->Access
& USER_READ_ACCOUNT
)
6838 InfoBuffer
->All
.WhichFields
|= USER_ALL_READ_ACCOUNT_MASK
;
6840 if (UserObject
->Access
& USER_READ_PREFERENCES
)
6841 InfoBuffer
->All
.WhichFields
|= USER_ALL_READ_PREFERENCES_MASK
;
6844 /* Fail, if no fields are to be returned */
6845 if (InfoBuffer
->All
.WhichFields
== 0)
6847 Status
= STATUS_ACCESS_DENIED
;
6851 /* Get the UserName attribute */
6852 if (InfoBuffer
->All
.WhichFields
& USER_ALL_USERNAME
)
6854 Status
= SampGetObjectAttributeString(UserObject
,
6856 &InfoBuffer
->All
.UserName
);
6857 if (!NT_SUCCESS(Status
))
6859 TRACE("Status 0x%08lx\n", Status
);
6864 /* Get the FullName attribute */
6865 if (InfoBuffer
->All
.WhichFields
& USER_ALL_FULLNAME
)
6867 Status
= SampGetObjectAttributeString(UserObject
,
6869 &InfoBuffer
->All
.FullName
);
6870 if (!NT_SUCCESS(Status
))
6872 TRACE("Status 0x%08lx\n", Status
);
6877 /* Get the UserId attribute */
6878 if (InfoBuffer
->All
.WhichFields
& USER_ALL_USERID
)
6880 InfoBuffer
->All
.UserId
= FixedData
.UserId
;
6883 /* Get the PrimaryGroupId attribute */
6884 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PRIMARYGROUPID
)
6886 InfoBuffer
->All
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
6889 /* Get the AdminComment attribute */
6890 if (InfoBuffer
->All
.WhichFields
& USER_ALL_ADMINCOMMENT
)
6892 Status
= SampGetObjectAttributeString(UserObject
,
6894 &InfoBuffer
->All
.AdminComment
);
6895 if (!NT_SUCCESS(Status
))
6897 TRACE("Status 0x%08lx\n", Status
);
6902 /* Get the UserComment attribute */
6903 if (InfoBuffer
->All
.WhichFields
& USER_ALL_USERCOMMENT
)
6905 Status
= SampGetObjectAttributeString(UserObject
,
6907 &InfoBuffer
->All
.UserComment
);
6908 if (!NT_SUCCESS(Status
))
6910 TRACE("Status 0x%08lx\n", Status
);
6915 /* Get the HomeDirectory attribute */
6916 if (InfoBuffer
->All
.WhichFields
& USER_ALL_HOMEDIRECTORY
)
6918 Status
= SampGetObjectAttributeString(UserObject
,
6920 &InfoBuffer
->All
.HomeDirectory
);
6921 if (!NT_SUCCESS(Status
))
6923 TRACE("Status 0x%08lx\n", Status
);
6928 /* Get the HomeDirectoryDrive attribute */
6929 if (InfoBuffer
->All
.WhichFields
& USER_ALL_HOMEDIRECTORYDRIVE
)
6931 Status
= SampGetObjectAttributeString(UserObject
,
6932 L
"HomeDirectoryDrive",
6933 &InfoBuffer
->Home
.HomeDirectoryDrive
);
6934 if (!NT_SUCCESS(Status
))
6936 TRACE("Status 0x%08lx\n", Status
);
6941 /* Get the ScriptPath attribute */
6942 if (InfoBuffer
->All
.WhichFields
& USER_ALL_SCRIPTPATH
)
6944 Status
= SampGetObjectAttributeString(UserObject
,
6946 &InfoBuffer
->All
.ScriptPath
);
6947 if (!NT_SUCCESS(Status
))
6949 TRACE("Status 0x%08lx\n", Status
);
6954 /* Get the ProfilePath attribute */
6955 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PROFILEPATH
)
6957 Status
= SampGetObjectAttributeString(UserObject
,
6959 &InfoBuffer
->All
.ProfilePath
);
6960 if (!NT_SUCCESS(Status
))
6962 TRACE("Status 0x%08lx\n", Status
);
6967 /* Get the WorkStations attribute */
6968 if (InfoBuffer
->All
.WhichFields
& USER_ALL_WORKSTATIONS
)
6970 Status
= SampGetObjectAttributeString(UserObject
,
6972 &InfoBuffer
->All
.WorkStations
);
6973 if (!NT_SUCCESS(Status
))
6975 TRACE("Status 0x%08lx\n", Status
);
6980 /* Get the LastLogon attribute */
6981 if (InfoBuffer
->All
.WhichFields
& USER_ALL_LASTLOGON
)
6983 InfoBuffer
->All
.LastLogon
.LowPart
= FixedData
.LastLogon
.LowPart
;
6984 InfoBuffer
->All
.LastLogon
.HighPart
= FixedData
.LastLogon
.HighPart
;
6987 /* Get the LastLogoff attribute */
6988 if (InfoBuffer
->All
.WhichFields
& USER_ALL_LASTLOGOFF
)
6990 InfoBuffer
->All
.LastLogoff
.LowPart
= FixedData
.LastLogoff
.LowPart
;
6991 InfoBuffer
->All
.LastLogoff
.HighPart
= FixedData
.LastLogoff
.HighPart
;
6994 /* Get the LogonHours attribute */
6995 if (InfoBuffer
->All
.WhichFields
& USER_ALL_LOGONHOURS
)
6997 Status
= SampGetLogonHoursAttribute(UserObject
,
6998 &InfoBuffer
->All
.LogonHours
);
6999 if (!NT_SUCCESS(Status
))
7001 TRACE("Status 0x%08lx\n", Status
);
7006 /* Get the BadPasswordCount attribute */
7007 if (InfoBuffer
->All
.WhichFields
& USER_ALL_BADPASSWORDCOUNT
)
7009 InfoBuffer
->All
.BadPasswordCount
= FixedData
.BadPasswordCount
;
7012 /* Get the LogonCount attribute */
7013 if (InfoBuffer
->All
.WhichFields
& USER_ALL_LOGONCOUNT
)
7015 InfoBuffer
->All
.LogonCount
= FixedData
.LogonCount
;
7018 /* Get the PasswordCanChange attribute */
7019 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PASSWORDCANCHANGE
)
7021 PasswordCanChange
= SampAddRelativeTimeToTime(FixedData
.PasswordLastSet
,
7022 DomainFixedData
.MinPasswordAge
);
7023 InfoBuffer
->All
.PasswordCanChange
.LowPart
= PasswordCanChange
.LowPart
;
7024 InfoBuffer
->All
.PasswordCanChange
.HighPart
= PasswordCanChange
.HighPart
;
7027 /* Get the PasswordMustChange attribute */
7028 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PASSWORDMUSTCHANGE
)
7030 PasswordMustChange
= SampAddRelativeTimeToTime(FixedData
.PasswordLastSet
,
7031 DomainFixedData
.MaxPasswordAge
);
7032 InfoBuffer
->All
.PasswordMustChange
.LowPart
= PasswordMustChange
.LowPart
;
7033 InfoBuffer
->All
.PasswordMustChange
.HighPart
= PasswordMustChange
.HighPart
;
7036 /* Get the PasswordLastSet attribute */
7037 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PASSWORDLASTSET
)
7039 InfoBuffer
->All
.PasswordLastSet
.LowPart
= FixedData
.PasswordLastSet
.LowPart
;
7040 InfoBuffer
->All
.PasswordLastSet
.HighPart
= FixedData
.PasswordLastSet
.HighPart
;
7043 /* Get the AccountExpires attribute */
7044 if (InfoBuffer
->All
.WhichFields
& USER_ALL_ACCOUNTEXPIRES
)
7046 InfoBuffer
->All
.AccountExpires
.LowPart
= FixedData
.AccountExpires
.LowPart
;
7047 InfoBuffer
->All
.AccountExpires
.HighPart
= FixedData
.AccountExpires
.HighPart
;
7050 /* Get the UserAccountControl attribute */
7051 if (InfoBuffer
->All
.WhichFields
& USER_ALL_USERACCOUNTCONTROL
)
7053 InfoBuffer
->All
.UserAccountControl
= FixedData
.UserAccountControl
;
7056 /* Get the Parameters attribute */
7057 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PARAMETERS
)
7059 Status
= SampGetObjectAttributeString(UserObject
,
7061 &InfoBuffer
->All
.Parameters
);
7062 if (!NT_SUCCESS(Status
))
7064 TRACE("Status 0x%08lx\n", Status
);
7069 /* Get the CountryCode attribute */
7070 if (InfoBuffer
->All
.WhichFields
& USER_ALL_COUNTRYCODE
)
7072 InfoBuffer
->All
.CountryCode
= FixedData
.CountryCode
;
7075 /* Get the CodePage attribute */
7076 if (InfoBuffer
->All
.WhichFields
& USER_ALL_CODEPAGE
)
7078 InfoBuffer
->All
.CodePage
= FixedData
.CodePage
;
7081 /* Get the LmPassword and NtPassword attributes */
7082 if (InfoBuffer
->All
.WhichFields
& (USER_ALL_NTPASSWORDPRESENT
| USER_ALL_LMPASSWORDPRESENT
))
7084 InfoBuffer
->All
.LmPasswordPresent
= FALSE
;
7085 InfoBuffer
->All
.NtPasswordPresent
= FALSE
;
7087 /* Get the NT password */
7089 SampGetObjectAttribute(UserObject
,
7095 if (Length
== sizeof(ENCRYPTED_NT_OWF_PASSWORD
))
7097 InfoBuffer
->All
.NtOwfPassword
.Buffer
= midl_user_allocate(sizeof(ENCRYPTED_NT_OWF_PASSWORD
));
7098 if (InfoBuffer
->All
.NtOwfPassword
.Buffer
== NULL
)
7100 Status
= STATUS_INSUFFICIENT_RESOURCES
;
7104 InfoBuffer
->All
.NtOwfPassword
.Length
= sizeof(ENCRYPTED_NT_OWF_PASSWORD
);
7105 InfoBuffer
->All
.NtOwfPassword
.MaximumLength
= sizeof(ENCRYPTED_NT_OWF_PASSWORD
);
7107 Status
= SampGetObjectAttribute(UserObject
,
7110 (PVOID
)InfoBuffer
->All
.NtOwfPassword
.Buffer
,
7112 if (!NT_SUCCESS(Status
))
7115 if (memcmp(InfoBuffer
->All
.NtOwfPassword
.Buffer
,
7117 sizeof(ENCRYPTED_NT_OWF_PASSWORD
)))
7118 InfoBuffer
->All
.NtPasswordPresent
= TRUE
;
7121 /* Get the LM password */
7123 SampGetObjectAttribute(UserObject
,
7129 if (Length
== sizeof(ENCRYPTED_LM_OWF_PASSWORD
))
7131 InfoBuffer
->All
.LmOwfPassword
.Buffer
= midl_user_allocate(sizeof(ENCRYPTED_LM_OWF_PASSWORD
));
7132 if (InfoBuffer
->All
.LmOwfPassword
.Buffer
== NULL
)
7134 Status
= STATUS_INSUFFICIENT_RESOURCES
;
7138 InfoBuffer
->All
.LmOwfPassword
.Length
= sizeof(ENCRYPTED_LM_OWF_PASSWORD
);
7139 InfoBuffer
->All
.LmOwfPassword
.MaximumLength
= sizeof(ENCRYPTED_LM_OWF_PASSWORD
);
7141 Status
= SampGetObjectAttribute(UserObject
,
7144 (PVOID
)InfoBuffer
->All
.LmOwfPassword
.Buffer
,
7146 if (!NT_SUCCESS(Status
))
7149 if (memcmp(InfoBuffer
->All
.LmOwfPassword
.Buffer
,
7151 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
7152 InfoBuffer
->All
.LmPasswordPresent
= TRUE
;
7156 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PRIVATEDATA
)
7158 Status
= SampGetObjectAttributeString(UserObject
,
7160 &InfoBuffer
->All
.PrivateData
);
7161 if (!NT_SUCCESS(Status
))
7163 TRACE("Status 0x%08lx\n", Status
);
7168 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PASSWORDEXPIRED
)
7173 if (InfoBuffer
->All
.WhichFields
& USER_ALL_SECURITYDESCRIPTOR
)
7176 SampGetObjectAttribute(UserObject
,
7184 InfoBuffer
->All
.SecurityDescriptor
.SecurityDescriptor
= midl_user_allocate(Length
);
7185 if (InfoBuffer
->All
.SecurityDescriptor
.SecurityDescriptor
== NULL
)
7187 Status
= STATUS_INSUFFICIENT_RESOURCES
;
7191 InfoBuffer
->All
.SecurityDescriptor
.Length
= Length
;
7193 Status
= SampGetObjectAttribute(UserObject
,
7196 (PVOID
)InfoBuffer
->All
.SecurityDescriptor
.SecurityDescriptor
,
7198 if (!NT_SUCCESS(Status
))
7203 *Buffer
= InfoBuffer
;
7206 if (!NT_SUCCESS(Status
))
7208 if (InfoBuffer
!= NULL
)
7210 if (InfoBuffer
->All
.UserName
.Buffer
!= NULL
)
7211 midl_user_free(InfoBuffer
->All
.UserName
.Buffer
);
7213 if (InfoBuffer
->All
.FullName
.Buffer
!= NULL
)
7214 midl_user_free(InfoBuffer
->All
.FullName
.Buffer
);
7216 if (InfoBuffer
->All
.AdminComment
.Buffer
!= NULL
)
7217 midl_user_free(InfoBuffer
->All
.AdminComment
.Buffer
);
7219 if (InfoBuffer
->All
.UserComment
.Buffer
!= NULL
)
7220 midl_user_free(InfoBuffer
->All
.UserComment
.Buffer
);
7222 if (InfoBuffer
->All
.HomeDirectory
.Buffer
!= NULL
)
7223 midl_user_free(InfoBuffer
->All
.HomeDirectory
.Buffer
);
7225 if (InfoBuffer
->All
.HomeDirectoryDrive
.Buffer
!= NULL
)
7226 midl_user_free(InfoBuffer
->All
.HomeDirectoryDrive
.Buffer
);
7228 if (InfoBuffer
->All
.ScriptPath
.Buffer
!= NULL
)
7229 midl_user_free(InfoBuffer
->All
.ScriptPath
.Buffer
);
7231 if (InfoBuffer
->All
.ProfilePath
.Buffer
!= NULL
)
7232 midl_user_free(InfoBuffer
->All
.ProfilePath
.Buffer
);
7234 if (InfoBuffer
->All
.WorkStations
.Buffer
!= NULL
)
7235 midl_user_free(InfoBuffer
->All
.WorkStations
.Buffer
);
7237 if (InfoBuffer
->All
.LogonHours
.LogonHours
!= NULL
)
7238 midl_user_free(InfoBuffer
->All
.LogonHours
.LogonHours
);
7240 if (InfoBuffer
->All
.Parameters
.Buffer
!= NULL
)
7241 midl_user_free(InfoBuffer
->All
.Parameters
.Buffer
);
7243 if (InfoBuffer
->All
.LmOwfPassword
.Buffer
!= NULL
)
7244 midl_user_free(InfoBuffer
->All
.LmOwfPassword
.Buffer
);
7246 if (InfoBuffer
->All
.NtOwfPassword
.Buffer
!= NULL
)
7247 midl_user_free(InfoBuffer
->All
.NtOwfPassword
.Buffer
);
7249 if (InfoBuffer
->All
.PrivateData
.Buffer
!= NULL
)
7250 midl_user_free(InfoBuffer
->All
.PrivateData
.Buffer
);
7252 if (InfoBuffer
->All
.SecurityDescriptor
.SecurityDescriptor
!= NULL
)
7253 midl_user_free(InfoBuffer
->All
.SecurityDescriptor
.SecurityDescriptor
);
7255 midl_user_free(InfoBuffer
);
7266 SamrQueryInformationUser(IN SAMPR_HANDLE UserHandle
,
7267 IN USER_INFORMATION_CLASS UserInformationClass
,
7268 OUT PSAMPR_USER_INFO_BUFFER
*Buffer
)
7270 PSAM_DB_OBJECT UserObject
;
7271 ACCESS_MASK DesiredAccess
;
7274 TRACE("SamrQueryInformationUser(%p %lu %p)\n",
7275 UserHandle
, UserInformationClass
, Buffer
);
7277 switch (UserInformationClass
)
7279 case UserGeneralInformation
:
7280 case UserNameInformation
:
7281 case UserAccountNameInformation
:
7282 case UserFullNameInformation
:
7283 case UserPrimaryGroupInformation
:
7284 case UserAdminCommentInformation
:
7285 DesiredAccess
= USER_READ_GENERAL
;
7288 case UserLogonHoursInformation
:
7289 case UserHomeInformation
:
7290 case UserScriptInformation
:
7291 case UserProfileInformation
:
7292 case UserWorkStationsInformation
:
7293 DesiredAccess
= USER_READ_LOGON
;
7296 case UserControlInformation
:
7297 case UserExpiresInformation
:
7298 case UserParametersInformation
:
7299 DesiredAccess
= USER_READ_ACCOUNT
;
7302 case UserPreferencesInformation
:
7303 DesiredAccess
= USER_READ_GENERAL
|
7304 USER_READ_PREFERENCES
;
7307 case UserLogonInformation
:
7308 case UserAccountInformation
:
7309 DesiredAccess
= USER_READ_GENERAL
|
7310 USER_READ_PREFERENCES
|
7315 case UserInternal1Information
:
7316 case UserAllInformation
:
7321 return STATUS_INVALID_INFO_CLASS
;
7324 RtlAcquireResourceShared(&SampResource
,
7327 /* Validate the domain handle */
7328 Status
= SampValidateDbObject(UserHandle
,
7332 if (!NT_SUCCESS(Status
))
7334 TRACE("failed with status 0x%08lx\n", Status
);
7338 switch (UserInformationClass
)
7340 case UserGeneralInformation
:
7341 Status
= SampQueryUserGeneral(UserObject
,
7345 case UserPreferencesInformation
:
7346 Status
= SampQueryUserPreferences(UserObject
,
7350 case UserLogonInformation
:
7351 Status
= SampQueryUserLogon(UserObject
,
7355 case UserLogonHoursInformation
:
7356 Status
= SampQueryUserLogonHours(UserObject
,
7360 case UserAccountInformation
:
7361 Status
= SampQueryUserAccount(UserObject
,
7365 case UserNameInformation
:
7366 Status
= SampQueryUserName(UserObject
,
7370 case UserAccountNameInformation
:
7371 Status
= SampQueryUserAccountName(UserObject
,
7375 case UserFullNameInformation
:
7376 Status
= SampQueryUserFullName(UserObject
,
7380 case UserPrimaryGroupInformation
:
7381 Status
= SampQueryUserPrimaryGroup(UserObject
,
7385 case UserHomeInformation
:
7386 Status
= SampQueryUserHome(UserObject
,
7389 case UserScriptInformation
:
7390 Status
= SampQueryUserScript(UserObject
,
7394 case UserProfileInformation
:
7395 Status
= SampQueryUserProfile(UserObject
,
7399 case UserAdminCommentInformation
:
7400 Status
= SampQueryUserAdminComment(UserObject
,
7404 case UserWorkStationsInformation
:
7405 Status
= SampQueryUserWorkStations(UserObject
,
7409 case UserControlInformation
:
7410 Status
= SampQueryUserControl(UserObject
,
7414 case UserExpiresInformation
:
7415 Status
= SampQueryUserExpires(UserObject
,
7419 case UserInternal1Information
:
7420 Status
= SampQueryUserInternal1(UserObject
,
7424 case UserParametersInformation
:
7425 Status
= SampQueryUserParameters(UserObject
,
7429 case UserAllInformation
:
7430 Status
= SampQueryUserAll(UserObject
,
7434 // case UserInternal4Information:
7435 // case UserInternal5Information:
7436 // case UserInternal4InformationNew:
7437 // case UserInternal5InformationNew:
7440 Status
= STATUS_INVALID_INFO_CLASS
;
7444 RtlReleaseResource(&SampResource
);
7451 SampSetUserName(PSAM_DB_OBJECT UserObject
,
7452 PRPC_UNICODE_STRING NewUserName
)
7454 UNICODE_STRING OldUserName
= {0, 0, NULL
};
7457 /* Check the account name */
7458 Status
= SampCheckAccountName(NewUserName
, 20);
7459 if (!NT_SUCCESS(Status
))
7461 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
7465 Status
= SampGetObjectAttributeString(UserObject
,
7467 (PRPC_UNICODE_STRING
)&OldUserName
);
7468 if (!NT_SUCCESS(Status
))
7470 TRACE("SampGetObjectAttributeString failed (Status 0x%08lx)\n", Status
);
7474 if (!RtlEqualUnicodeString(&OldUserName
, (PCUNICODE_STRING
)NewUserName
, TRUE
))
7476 Status
= SampCheckAccountNameInDomain(UserObject
->ParentObject
,
7477 NewUserName
->Buffer
);
7478 if (!NT_SUCCESS(Status
))
7480 TRACE("User name \'%S\' already exists in domain (Status 0x%08lx)\n",
7481 NewUserName
->Buffer
, Status
);
7486 Status
= SampSetAccountNameInDomain(UserObject
->ParentObject
,
7488 NewUserName
->Buffer
,
7489 UserObject
->RelativeId
);
7490 if (!NT_SUCCESS(Status
))
7492 TRACE("SampSetAccountNameInDomain failed (Status 0x%08lx)\n", Status
);
7496 Status
= SampRemoveAccountNameFromDomain(UserObject
->ParentObject
,
7498 OldUserName
.Buffer
);
7499 if (!NT_SUCCESS(Status
))
7501 TRACE("SampRemoveAccountNameFromDomain failed (Status 0x%08lx)\n", Status
);
7505 Status
= SampSetObjectAttributeString(UserObject
,
7508 if (!NT_SUCCESS(Status
))
7510 TRACE("SampSetObjectAttribute failed (Status 0x%08lx)\n", Status
);
7514 if (OldUserName
.Buffer
!= NULL
)
7515 midl_user_free(OldUserName
.Buffer
);
7522 SampSetUserGeneral(PSAM_DB_OBJECT UserObject
,
7523 PSAMPR_USER_INFO_BUFFER Buffer
)
7525 SAM_USER_FIXED_DATA FixedData
;
7529 Length
= sizeof(SAM_USER_FIXED_DATA
);
7530 Status
= SampGetObjectAttribute(UserObject
,
7535 if (!NT_SUCCESS(Status
))
7538 FixedData
.PrimaryGroupId
= Buffer
->General
.PrimaryGroupId
;
7540 Status
= SampSetObjectAttribute(UserObject
,
7545 if (!NT_SUCCESS(Status
))
7548 Status
= SampSetUserName(UserObject
,
7549 &Buffer
->General
.UserName
);
7550 if (!NT_SUCCESS(Status
))
7553 Status
= SampSetObjectAttributeString(UserObject
,
7555 &Buffer
->General
.FullName
);
7556 if (!NT_SUCCESS(Status
))
7559 Status
= SampSetObjectAttributeString(UserObject
,
7561 &Buffer
->General
.AdminComment
);
7562 if (!NT_SUCCESS(Status
))
7565 Status
= SampSetObjectAttributeString(UserObject
,
7567 &Buffer
->General
.UserComment
);
7575 SampSetUserPreferences(PSAM_DB_OBJECT UserObject
,
7576 PSAMPR_USER_INFO_BUFFER Buffer
)
7578 SAM_USER_FIXED_DATA FixedData
;
7582 Length
= sizeof(SAM_USER_FIXED_DATA
);
7583 Status
= SampGetObjectAttribute(UserObject
,
7588 if (!NT_SUCCESS(Status
))
7591 FixedData
.CountryCode
= Buffer
->Preferences
.CountryCode
;
7592 FixedData
.CodePage
= Buffer
->Preferences
.CodePage
;
7594 Status
= SampSetObjectAttribute(UserObject
,
7599 if (!NT_SUCCESS(Status
))
7602 Status
= SampSetObjectAttributeString(UserObject
,
7604 &Buffer
->Preferences
.UserComment
);
7612 SampSetUserPrimaryGroup(PSAM_DB_OBJECT UserObject
,
7613 PSAMPR_USER_INFO_BUFFER Buffer
)
7615 SAM_USER_FIXED_DATA FixedData
;
7619 Length
= sizeof(SAM_USER_FIXED_DATA
);
7620 Status
= SampGetObjectAttribute(UserObject
,
7625 if (!NT_SUCCESS(Status
))
7628 FixedData
.PrimaryGroupId
= Buffer
->PrimaryGroup
.PrimaryGroupId
;
7630 Status
= SampSetObjectAttribute(UserObject
,
7642 SampSetUserControl(PSAM_DB_OBJECT UserObject
,
7643 PSAMPR_USER_INFO_BUFFER Buffer
)
7645 SAM_USER_FIXED_DATA FixedData
;
7649 Length
= sizeof(SAM_USER_FIXED_DATA
);
7650 Status
= SampGetObjectAttribute(UserObject
,
7655 if (!NT_SUCCESS(Status
))
7658 FixedData
.UserAccountControl
= Buffer
->Control
.UserAccountControl
;
7660 Status
= SampSetObjectAttribute(UserObject
,
7672 SampSetUserExpires(PSAM_DB_OBJECT UserObject
,
7673 PSAMPR_USER_INFO_BUFFER Buffer
)
7675 SAM_USER_FIXED_DATA FixedData
;
7679 Length
= sizeof(SAM_USER_FIXED_DATA
);
7680 Status
= SampGetObjectAttribute(UserObject
,
7685 if (!NT_SUCCESS(Status
))
7688 FixedData
.AccountExpires
.LowPart
= Buffer
->Expires
.AccountExpires
.LowPart
;
7689 FixedData
.AccountExpires
.HighPart
= Buffer
->Expires
.AccountExpires
.HighPart
;
7691 Status
= SampSetObjectAttribute(UserObject
,
7703 SampSetUserInternal1(PSAM_DB_OBJECT UserObject
,
7704 PSAMPR_USER_INFO_BUFFER Buffer
)
7706 SAM_USER_FIXED_DATA FixedData
;
7708 NTSTATUS Status
= STATUS_SUCCESS
;
7710 /* FIXME: Decrypt NT password */
7711 /* FIXME: Decrypt LM password */
7713 Status
= SampSetUserPassword(UserObject
,
7714 &Buffer
->Internal1
.EncryptedNtOwfPassword
,
7715 Buffer
->Internal1
.NtPasswordPresent
,
7716 &Buffer
->Internal1
.EncryptedLmOwfPassword
,
7717 Buffer
->Internal1
.LmPasswordPresent
);
7718 if (!NT_SUCCESS(Status
))
7721 /* Get the fixed user attributes */
7722 Length
= sizeof(SAM_USER_FIXED_DATA
);
7723 Status
= SampGetObjectAttribute(UserObject
,
7728 if (!NT_SUCCESS(Status
))
7731 if (Buffer
->Internal1
.PasswordExpired
)
7733 /* The password was last set ages ago */
7734 FixedData
.PasswordLastSet
.LowPart
= 0;
7735 FixedData
.PasswordLastSet
.HighPart
= 0;
7739 /* The password was last set right now */
7740 Status
= NtQuerySystemTime(&FixedData
.PasswordLastSet
);
7741 if (!NT_SUCCESS(Status
))
7745 /* Set the fixed user attributes */
7746 Status
= SampSetObjectAttribute(UserObject
,
7758 SampSetUserAll(PSAM_DB_OBJECT UserObject
,
7759 PSAMPR_USER_INFO_BUFFER Buffer
)
7761 SAM_USER_FIXED_DATA FixedData
;
7764 PENCRYPTED_NT_OWF_PASSWORD NtPassword
= NULL
;
7765 PENCRYPTED_LM_OWF_PASSWORD LmPassword
= NULL
;
7766 BOOLEAN NtPasswordPresent
= FALSE
;
7767 BOOLEAN LmPasswordPresent
= FALSE
;
7768 BOOLEAN WriteFixedData
= FALSE
;
7769 NTSTATUS Status
= STATUS_SUCCESS
;
7771 WhichFields
= Buffer
->All
.WhichFields
;
7773 /* Get the fixed size attributes */
7774 Length
= sizeof(SAM_USER_FIXED_DATA
);
7775 Status
= SampGetObjectAttribute(UserObject
,
7780 if (!NT_SUCCESS(Status
))
7783 if (WhichFields
& USER_ALL_USERNAME
)
7785 Status
= SampSetUserName(UserObject
,
7786 &Buffer
->All
.UserName
);
7787 if (!NT_SUCCESS(Status
))
7791 if (WhichFields
& USER_ALL_FULLNAME
)
7793 Status
= SampSetObjectAttributeString(UserObject
,
7795 &Buffer
->All
.FullName
);
7796 if (!NT_SUCCESS(Status
))
7800 if (WhichFields
& USER_ALL_ADMINCOMMENT
)
7802 Status
= SampSetObjectAttributeString(UserObject
,
7804 &Buffer
->All
.AdminComment
);
7805 if (!NT_SUCCESS(Status
))
7809 if (WhichFields
& USER_ALL_USERCOMMENT
)
7811 Status
= SampSetObjectAttributeString(UserObject
,
7813 &Buffer
->All
.UserComment
);
7814 if (!NT_SUCCESS(Status
))
7818 if (WhichFields
& USER_ALL_HOMEDIRECTORY
)
7820 Status
= SampSetObjectAttributeString(UserObject
,
7822 &Buffer
->All
.HomeDirectory
);
7823 if (!NT_SUCCESS(Status
))
7827 if (WhichFields
& USER_ALL_HOMEDIRECTORYDRIVE
)
7829 Status
= SampSetObjectAttributeString(UserObject
,
7830 L
"HomeDirectoryDrive",
7831 &Buffer
->All
.HomeDirectoryDrive
);
7832 if (!NT_SUCCESS(Status
))
7836 if (WhichFields
& USER_ALL_SCRIPTPATH
)
7838 Status
= SampSetObjectAttributeString(UserObject
,
7840 &Buffer
->All
.ScriptPath
);
7841 if (!NT_SUCCESS(Status
))
7845 if (WhichFields
& USER_ALL_PROFILEPATH
)
7847 Status
= SampSetObjectAttributeString(UserObject
,
7849 &Buffer
->All
.ProfilePath
);
7850 if (!NT_SUCCESS(Status
))
7854 if (WhichFields
& USER_ALL_WORKSTATIONS
)
7856 Status
= SampSetObjectAttributeString(UserObject
,
7858 &Buffer
->All
.WorkStations
);
7859 if (!NT_SUCCESS(Status
))
7863 if (WhichFields
& USER_ALL_PARAMETERS
)
7865 Status
= SampSetObjectAttributeString(UserObject
,
7867 &Buffer
->All
.Parameters
);
7868 if (!NT_SUCCESS(Status
))
7872 if (WhichFields
& USER_ALL_LOGONHOURS
)
7874 Status
= SampSetLogonHoursAttribute(UserObject
,
7875 &Buffer
->All
.LogonHours
);
7876 if (!NT_SUCCESS(Status
))
7880 if (WhichFields
& USER_ALL_PRIMARYGROUPID
)
7882 FixedData
.PrimaryGroupId
= Buffer
->All
.PrimaryGroupId
;
7883 WriteFixedData
= TRUE
;
7886 if (WhichFields
& USER_ALL_ACCOUNTEXPIRES
)
7888 FixedData
.AccountExpires
.LowPart
= Buffer
->All
.AccountExpires
.LowPart
;
7889 FixedData
.AccountExpires
.HighPart
= Buffer
->All
.AccountExpires
.HighPart
;
7890 WriteFixedData
= TRUE
;
7893 if (WhichFields
& USER_ALL_USERACCOUNTCONTROL
)
7895 FixedData
.UserAccountControl
= Buffer
->All
.UserAccountControl
;
7896 WriteFixedData
= TRUE
;
7899 if (WhichFields
& USER_ALL_COUNTRYCODE
)
7901 FixedData
.CountryCode
= Buffer
->All
.CountryCode
;
7902 WriteFixedData
= TRUE
;
7905 if (WhichFields
& USER_ALL_CODEPAGE
)
7907 FixedData
.CodePage
= Buffer
->All
.CodePage
;
7908 WriteFixedData
= TRUE
;
7911 if (WhichFields
& (USER_ALL_NTPASSWORDPRESENT
|
7912 USER_ALL_LMPASSWORDPRESENT
))
7914 if (WhichFields
& USER_ALL_NTPASSWORDPRESENT
)
7916 NtPassword
= (PENCRYPTED_NT_OWF_PASSWORD
)Buffer
->All
.NtOwfPassword
.Buffer
;
7917 NtPasswordPresent
= Buffer
->All
.NtPasswordPresent
;
7920 if (WhichFields
& USER_ALL_LMPASSWORDPRESENT
)
7922 LmPassword
= (PENCRYPTED_LM_OWF_PASSWORD
)Buffer
->All
.LmOwfPassword
.Buffer
;
7923 LmPasswordPresent
= Buffer
->All
.LmPasswordPresent
;
7926 Status
= SampSetUserPassword(UserObject
,
7931 if (!NT_SUCCESS(Status
))
7934 /* The password has just been set */
7935 Status
= NtQuerySystemTime(&FixedData
.PasswordLastSet
);
7936 if (!NT_SUCCESS(Status
))
7939 WriteFixedData
= TRUE
;
7942 if (WhichFields
& USER_ALL_PRIVATEDATA
)
7944 Status
= SampSetObjectAttributeString(UserObject
,
7946 &Buffer
->All
.PrivateData
);
7947 if (!NT_SUCCESS(Status
))
7951 if (WhichFields
& USER_ALL_PASSWORDEXPIRED
)
7953 if (Buffer
->All
.PasswordExpired
)
7955 /* The password was last set ages ago */
7956 FixedData
.PasswordLastSet
.LowPart
= 0;
7957 FixedData
.PasswordLastSet
.HighPart
= 0;
7961 /* The password was last set right now */
7962 Status
= NtQuerySystemTime(&FixedData
.PasswordLastSet
);
7963 if (!NT_SUCCESS(Status
))
7967 WriteFixedData
= TRUE
;
7970 if (WhichFields
& USER_ALL_SECURITYDESCRIPTOR
)
7972 Status
= SampSetObjectAttribute(UserObject
,
7975 Buffer
->All
.SecurityDescriptor
.SecurityDescriptor
,
7976 Buffer
->All
.SecurityDescriptor
.Length
);
7979 if (WriteFixedData
!= FALSE
)
7981 Status
= SampSetObjectAttribute(UserObject
,
7986 if (!NT_SUCCESS(Status
))
7998 SamrSetInformationUser(IN SAMPR_HANDLE UserHandle
,
7999 IN USER_INFORMATION_CLASS UserInformationClass
,
8000 IN PSAMPR_USER_INFO_BUFFER Buffer
)
8002 PSAM_DB_OBJECT UserObject
;
8003 ACCESS_MASK DesiredAccess
;
8006 TRACE("SamrSetInformationUser(%p %lu %p)\n",
8007 UserHandle
, UserInformationClass
, Buffer
);
8009 switch (UserInformationClass
)
8011 case UserLogonHoursInformation
:
8012 case UserNameInformation
:
8013 case UserAccountNameInformation
:
8014 case UserFullNameInformation
:
8015 case UserPrimaryGroupInformation
:
8016 case UserHomeInformation
:
8017 case UserScriptInformation
:
8018 case UserProfileInformation
:
8019 case UserAdminCommentInformation
:
8020 case UserWorkStationsInformation
:
8021 case UserControlInformation
:
8022 case UserExpiresInformation
:
8023 case UserParametersInformation
:
8024 DesiredAccess
= USER_WRITE_ACCOUNT
;
8027 case UserGeneralInformation
:
8028 DesiredAccess
= USER_WRITE_ACCOUNT
|
8029 USER_WRITE_PREFERENCES
;
8032 case UserPreferencesInformation
:
8033 DesiredAccess
= USER_WRITE_PREFERENCES
;
8036 case UserSetPasswordInformation
:
8037 case UserInternal1Information
:
8038 DesiredAccess
= USER_FORCE_PASSWORD_CHANGE
;
8041 case UserAllInformation
:
8042 DesiredAccess
= 0; /* FIXME */
8046 return STATUS_INVALID_INFO_CLASS
;
8049 RtlAcquireResourceExclusive(&SampResource
,
8052 /* Validate the domain handle */
8053 Status
= SampValidateDbObject(UserHandle
,
8057 if (!NT_SUCCESS(Status
))
8059 TRACE("failed with status 0x%08lx\n", Status
);
8063 switch (UserInformationClass
)
8065 case UserGeneralInformation
:
8066 Status
= SampSetUserGeneral(UserObject
,
8070 case UserPreferencesInformation
:
8071 Status
= SampSetUserPreferences(UserObject
,
8075 case UserLogonHoursInformation
:
8076 Status
= SampSetLogonHoursAttribute(UserObject
,
8077 &Buffer
->LogonHours
.LogonHours
);
8080 case UserNameInformation
:
8081 Status
= SampSetUserName(UserObject
,
8082 &Buffer
->Name
.UserName
);
8083 if (!NT_SUCCESS(Status
))
8086 Status
= SampSetObjectAttributeString(UserObject
,
8088 &Buffer
->Name
.FullName
);
8091 case UserAccountNameInformation
:
8092 Status
= SampSetUserName(UserObject
,
8093 &Buffer
->AccountName
.UserName
);
8096 case UserFullNameInformation
:
8097 Status
= SampSetObjectAttributeString(UserObject
,
8099 &Buffer
->FullName
.FullName
);
8102 case UserPrimaryGroupInformation
:
8103 Status
= SampSetUserPrimaryGroup(UserObject
,
8107 case UserHomeInformation
:
8108 Status
= SampSetObjectAttributeString(UserObject
,
8110 &Buffer
->Home
.HomeDirectory
);
8111 if (!NT_SUCCESS(Status
))
8114 Status
= SampSetObjectAttributeString(UserObject
,
8115 L
"HomeDirectoryDrive",
8116 &Buffer
->Home
.HomeDirectoryDrive
);
8119 case UserScriptInformation
:
8120 Status
= SampSetObjectAttributeString(UserObject
,
8122 &Buffer
->Script
.ScriptPath
);
8125 case UserProfileInformation
:
8126 Status
= SampSetObjectAttributeString(UserObject
,
8128 &Buffer
->Profile
.ProfilePath
);
8131 case UserAdminCommentInformation
:
8132 Status
= SampSetObjectAttributeString(UserObject
,
8134 &Buffer
->AdminComment
.AdminComment
);
8137 case UserWorkStationsInformation
:
8138 Status
= SampSetObjectAttributeString(UserObject
,
8140 &Buffer
->WorkStations
.WorkStations
);
8143 case UserSetPasswordInformation
:
8144 TRACE("Password: %S\n", Buffer
->SetPassword
.Password
.Buffer
);
8145 TRACE("PasswordExpired: %d\n", Buffer
->SetPassword
.PasswordExpired
);
8147 Status
= SampSetObjectAttributeString(UserObject
,
8149 &Buffer
->SetPassword
.Password
);
8152 case UserControlInformation
:
8153 Status
= SampSetUserControl(UserObject
,
8157 case UserExpiresInformation
:
8158 Status
= SampSetUserExpires(UserObject
,
8162 case UserInternal1Information
:
8163 Status
= SampSetUserInternal1(UserObject
,
8167 case UserParametersInformation
:
8168 Status
= SampSetObjectAttributeString(UserObject
,
8170 &Buffer
->Parameters
.Parameters
);
8173 case UserAllInformation
:
8174 Status
= SampSetUserAll(UserObject
,
8178 // case UserInternal4Information:
8179 // case UserInternal5Information:
8180 // case UserInternal4InformationNew:
8181 // case UserInternal5InformationNew:
8184 Status
= STATUS_INVALID_INFO_CLASS
;
8188 RtlReleaseResource(&SampResource
);
8197 SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle
,
8198 IN
unsigned char LmPresent
,
8199 IN PENCRYPTED_LM_OWF_PASSWORD OldLmEncryptedWithNewLm
,
8200 IN PENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithOldLm
,
8201 IN
unsigned char NtPresent
,
8202 IN PENCRYPTED_NT_OWF_PASSWORD OldNtEncryptedWithNewNt
,
8203 IN PENCRYPTED_NT_OWF_PASSWORD NewNtEncryptedWithOldNt
,
8204 IN
unsigned char NtCrossEncryptionPresent
,
8205 IN PENCRYPTED_NT_OWF_PASSWORD NewNtEncryptedWithNewLm
,
8206 IN
unsigned char LmCrossEncryptionPresent
,
8207 IN PENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithNewNt
)
8209 ENCRYPTED_LM_OWF_PASSWORD StoredLmPassword
;
8210 ENCRYPTED_NT_OWF_PASSWORD StoredNtPassword
;
8211 LM_OWF_PASSWORD OldLmPassword
;
8212 LM_OWF_PASSWORD NewLmPassword
;
8213 NT_OWF_PASSWORD OldNtPassword
;
8214 NT_OWF_PASSWORD NewNtPassword
;
8215 BOOLEAN StoredLmPresent
= FALSE
;
8216 BOOLEAN StoredNtPresent
= FALSE
;
8217 BOOLEAN StoredLmEmpty
= TRUE
;
8218 BOOLEAN StoredNtEmpty
= TRUE
;
8219 PSAM_DB_OBJECT UserObject
;
8221 SAM_USER_FIXED_DATA UserFixedData
;
8222 SAM_DOMAIN_FIXED_DATA DomainFixedData
;
8223 LARGE_INTEGER SystemTime
;
8226 DBG_UNREFERENCED_LOCAL_VARIABLE(StoredLmPresent
);
8227 DBG_UNREFERENCED_LOCAL_VARIABLE(StoredNtPresent
);
8228 DBG_UNREFERENCED_LOCAL_VARIABLE(StoredLmEmpty
);
8230 TRACE("(%p %u %p %p %u %p %p %u %p %u %p)\n",
8231 UserHandle
, LmPresent
, OldLmEncryptedWithNewLm
, NewLmEncryptedWithOldLm
,
8232 NtPresent
, OldNtEncryptedWithNewNt
, NewNtEncryptedWithOldNt
, NtCrossEncryptionPresent
,
8233 NewNtEncryptedWithNewLm
, LmCrossEncryptionPresent
, NewLmEncryptedWithNewNt
);
8235 RtlAcquireResourceExclusive(&SampResource
,
8238 /* Validate the user handle */
8239 Status
= SampValidateDbObject(UserHandle
,
8241 USER_CHANGE_PASSWORD
,
8243 if (!NT_SUCCESS(Status
))
8245 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
8249 /* Get the current time */
8250 Status
= NtQuerySystemTime(&SystemTime
);
8251 if (!NT_SUCCESS(Status
))
8253 TRACE("NtQuerySystemTime failed (Status 0x%08lx)\n", Status
);
8257 /* Retrieve the LM password */
8258 Length
= sizeof(ENCRYPTED_LM_OWF_PASSWORD
);
8259 Status
= SampGetObjectAttribute(UserObject
,
8264 if (NT_SUCCESS(Status
))
8266 if (Length
== sizeof(ENCRYPTED_LM_OWF_PASSWORD
))
8268 StoredLmPresent
= TRUE
;
8269 if (!RtlEqualMemory(&StoredLmPassword
,
8271 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
8272 StoredLmEmpty
= FALSE
;
8276 /* Retrieve the NT password */
8277 Length
= sizeof(ENCRYPTED_NT_OWF_PASSWORD
);
8278 Status
= SampGetObjectAttribute(UserObject
,
8283 if (NT_SUCCESS(Status
))
8285 if (Length
== sizeof(ENCRYPTED_NT_OWF_PASSWORD
))
8287 StoredNtPresent
= TRUE
;
8288 if (!RtlEqualMemory(&StoredNtPassword
,
8290 sizeof(ENCRYPTED_NT_OWF_PASSWORD
)))
8291 StoredNtEmpty
= FALSE
;
8295 /* Retrieve the fixed size user data */
8296 Length
= sizeof(SAM_USER_FIXED_DATA
);
8297 Status
= SampGetObjectAttribute(UserObject
,
8302 if (!NT_SUCCESS(Status
))
8304 TRACE("SampGetObjectAttribute failed to retrieve the fixed user data (Status 0x%08lx)\n", Status
);
8308 /* Check if we can change the password at this time */
8309 if ((StoredLmEmpty
== FALSE
) || (StoredNtEmpty
== FALSE
))
8311 /* Get fixed domain data */
8312 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
8313 Status
= SampGetObjectAttribute(UserObject
->ParentObject
,
8318 if (!NT_SUCCESS(Status
))
8320 TRACE("SampGetObjectAttribute failed to retrieve the fixed domain data (Status 0x%08lx)\n", Status
);
8324 if (DomainFixedData
.MinPasswordAge
.QuadPart
> 0)
8326 if (SystemTime
.QuadPart
< (UserFixedData
.PasswordLastSet
.QuadPart
+ DomainFixedData
.MinPasswordAge
.QuadPart
))
8328 Status
= STATUS_ACCOUNT_RESTRICTION
;
8334 /* Decrypt the LM passwords, if present */
8337 Status
= SystemFunction013((const BYTE
*)NewLmEncryptedWithOldLm
,
8338 (const BYTE
*)&StoredLmPassword
,
8339 (LPBYTE
)&NewLmPassword
);
8340 if (!NT_SUCCESS(Status
))
8342 TRACE("SystemFunction013 failed (Status 0x%08lx)\n", Status
);
8346 Status
= SystemFunction013((const BYTE
*)OldLmEncryptedWithNewLm
,
8347 (const BYTE
*)&NewLmPassword
,
8348 (LPBYTE
)&OldLmPassword
);
8349 if (!NT_SUCCESS(Status
))
8351 TRACE("SystemFunction013 failed (Status 0x%08lx)\n", Status
);
8356 /* Decrypt the NT passwords, if present */
8359 Status
= SystemFunction013((const BYTE
*)NewNtEncryptedWithOldNt
,
8360 (const BYTE
*)&StoredNtPassword
,
8361 (LPBYTE
)&NewNtPassword
);
8362 if (!NT_SUCCESS(Status
))
8364 TRACE("SystemFunction013 failed (Status 0x%08lx)\n", Status
);
8368 Status
= SystemFunction013((const BYTE
*)OldNtEncryptedWithNewNt
,
8369 (const BYTE
*)&NewNtPassword
,
8370 (LPBYTE
)&OldNtPassword
);
8371 if (!NT_SUCCESS(Status
))
8373 TRACE("SystemFunction013 failed (Status 0x%08lx)\n", Status
);
8378 /* Check if the old passwords match the stored ones */
8383 if (!RtlEqualMemory(&StoredLmPassword
,
8385 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
8387 TRACE("Old LM Password does not match!\n");
8388 Status
= STATUS_WRONG_PASSWORD
;
8392 if (!RtlEqualMemory(&StoredNtPassword
,
8394 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
8396 TRACE("Old NT Password does not match!\n");
8397 Status
= STATUS_WRONG_PASSWORD
;
8403 if (!RtlEqualMemory(&StoredNtPassword
,
8405 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
8407 TRACE("Old NT Password does not match!\n");
8408 Status
= STATUS_WRONG_PASSWORD
;
8416 if (!RtlEqualMemory(&StoredLmPassword
,
8418 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
8420 TRACE("Old LM Password does not match!\n");
8421 Status
= STATUS_WRONG_PASSWORD
;
8426 Status
= STATUS_INVALID_PARAMETER
;
8430 /* Store the new password hashes */
8431 if (NT_SUCCESS(Status
))
8433 Status
= SampSetUserPassword(UserObject
,
8438 if (NT_SUCCESS(Status
))
8440 /* Update PasswordLastSet */
8441 UserFixedData
.PasswordLastSet
.QuadPart
= SystemTime
.QuadPart
;
8443 /* Set the fixed size user data */
8444 Length
= sizeof(SAM_USER_FIXED_DATA
);
8445 Status
= SampSetObjectAttribute(UserObject
,
8453 if (Status
== STATUS_WRONG_PASSWORD
)
8455 /* Update BadPasswordCount and LastBadPasswordTime */
8456 UserFixedData
.BadPasswordCount
++;
8457 UserFixedData
.LastBadPasswordTime
.QuadPart
= SystemTime
.QuadPart
;
8459 /* Set the fixed size user data */
8460 Length
= sizeof(SAM_USER_FIXED_DATA
);
8461 Status
= SampSetObjectAttribute(UserObject
,
8469 RtlReleaseResource(&SampResource
);
8478 SamrGetGroupsForUser(IN SAMPR_HANDLE UserHandle
,
8479 OUT PSAMPR_GET_GROUPS_BUFFER
*Groups
)
8481 PSAMPR_GET_GROUPS_BUFFER GroupsBuffer
= NULL
;
8482 PSAM_DB_OBJECT UserObject
;
8486 TRACE("SamrGetGroupsForUser(%p %p)\n",
8487 UserHandle
, Groups
);
8489 RtlAcquireResourceShared(&SampResource
,
8492 /* Validate the user handle */
8493 Status
= SampValidateDbObject(UserHandle
,
8497 if (!NT_SUCCESS(Status
))
8499 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
8503 /* Allocate the groups buffer */
8504 GroupsBuffer
= midl_user_allocate(sizeof(SAMPR_GET_GROUPS_BUFFER
));
8505 if (GroupsBuffer
== NULL
)
8507 Status
= STATUS_INSUFFICIENT_RESOURCES
;
8512 * Get the size of the Groups attribute.
8513 * Do not check the status code because in case of an error
8514 * Length will be 0. And that is all we need.
8516 SampGetObjectAttribute(UserObject
,
8522 /* If there is no Groups attribute, return a groups buffer without an array */
8525 GroupsBuffer
->MembershipCount
= 0;
8526 GroupsBuffer
->Groups
= NULL
;
8528 *Groups
= GroupsBuffer
;
8530 Status
= STATUS_SUCCESS
;
8534 /* Allocate a buffer for the Groups attribute */
8535 GroupsBuffer
->Groups
= midl_user_allocate(Length
);
8536 if (GroupsBuffer
->Groups
== NULL
)
8538 Status
= STATUS_INSUFFICIENT_RESOURCES
;
8542 /* Retrieve the Grous attribute */
8543 Status
= SampGetObjectAttribute(UserObject
,
8546 GroupsBuffer
->Groups
,
8548 if (!NT_SUCCESS(Status
))
8550 TRACE("SampGetObjectAttribute failed with status 0x%08lx\n", Status
);
8554 /* Calculate the membership count */
8555 GroupsBuffer
->MembershipCount
= Length
/ sizeof(GROUP_MEMBERSHIP
);
8557 /* Return the groups buffer to the caller */
8558 *Groups
= GroupsBuffer
;
8561 if (!NT_SUCCESS(Status
))
8563 if (GroupsBuffer
!= NULL
)
8565 if (GroupsBuffer
->Groups
!= NULL
)
8566 midl_user_free(GroupsBuffer
->Groups
);
8568 midl_user_free(GroupsBuffer
);
8572 RtlReleaseResource(&SampResource
);
8581 SamrQueryDisplayInformation(IN SAMPR_HANDLE DomainHandle
,
8582 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
8583 IN
unsigned long Index
,
8584 IN
unsigned long EntryCount
,
8585 IN
unsigned long PreferredMaximumLength
,
8586 OUT
unsigned long *TotalAvailable
,
8587 OUT
unsigned long *TotalReturned
,
8588 OUT PSAMPR_DISPLAY_INFO_BUFFER Buffer
)
8591 return STATUS_NOT_IMPLEMENTED
;
8597 SamrGetDisplayEnumerationIndex(IN SAMPR_HANDLE DomainHandle
,
8598 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
8599 IN PRPC_UNICODE_STRING Prefix
,
8600 OUT
unsigned long *Index
)
8603 return STATUS_NOT_IMPLEMENTED
;
8609 SamrTestPrivateFunctionsDomain(IN SAMPR_HANDLE DomainHandle
)
8612 return STATUS_NOT_IMPLEMENTED
;
8618 SamrTestPrivateFunctionsUser(IN SAMPR_HANDLE UserHandle
)
8621 return STATUS_NOT_IMPLEMENTED
;
8628 SamrGetUserDomainPasswordInformation(IN SAMPR_HANDLE UserHandle
,
8629 OUT PUSER_DOMAIN_PASSWORD_INFORMATION PasswordInformation
)
8631 SAM_DOMAIN_FIXED_DATA DomainFixedData
;
8632 SAM_USER_FIXED_DATA UserFixedData
;
8633 PSAM_DB_OBJECT DomainObject
;
8634 PSAM_DB_OBJECT UserObject
;
8639 UserHandle
, PasswordInformation
);
8641 RtlAcquireResourceShared(&SampResource
,
8644 /* Validate the user handle */
8645 Status
= SampValidateDbObject(UserHandle
,
8649 if (!NT_SUCCESS(Status
))
8651 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
8655 /* Validate the domain object */
8656 Status
= SampValidateDbObject((SAMPR_HANDLE
)UserObject
->ParentObject
,
8658 DOMAIN_READ_PASSWORD_PARAMETERS
,
8660 if (!NT_SUCCESS(Status
))
8662 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
8666 /* Get fixed user data */
8667 Length
= sizeof(SAM_USER_FIXED_DATA
);
8668 Status
= SampGetObjectAttribute(UserObject
,
8671 (PVOID
)&UserFixedData
,
8673 if (!NT_SUCCESS(Status
))
8675 TRACE("SampGetObjectAttribute failed with status 0x%08lx\n", Status
);
8679 if ((UserObject
->RelativeId
== DOMAIN_USER_RID_KRBTGT
) ||
8680 (UserFixedData
.UserAccountControl
& (USER_INTERDOMAIN_TRUST_ACCOUNT
|
8681 USER_WORKSTATION_TRUST_ACCOUNT
|
8682 USER_SERVER_TRUST_ACCOUNT
)))
8684 PasswordInformation
->MinPasswordLength
= 0;
8685 PasswordInformation
->PasswordProperties
= 0;
8689 /* Get fixed domain data */
8690 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
8691 Status
= SampGetObjectAttribute(DomainObject
,
8694 (PVOID
)&DomainFixedData
,
8696 if (!NT_SUCCESS(Status
))
8698 TRACE("SampGetObjectAttribute failed with status 0x%08lx\n", Status
);
8702 PasswordInformation
->MinPasswordLength
= DomainFixedData
.MinPasswordLength
;
8703 PasswordInformation
->PasswordProperties
= DomainFixedData
.PasswordProperties
;
8707 RtlReleaseResource(&SampResource
);
8709 return STATUS_SUCCESS
;
8716 SamrRemoveMemberFromForeignDomain(IN SAMPR_HANDLE DomainHandle
,
8717 IN PRPC_SID MemberSid
)
8719 PSAM_DB_OBJECT DomainObject
;
8724 DomainHandle
, MemberSid
);
8726 RtlAcquireResourceExclusive(&SampResource
,
8729 /* Validate the domain object */
8730 Status
= SampValidateDbObject(DomainHandle
,
8734 if (!NT_SUCCESS(Status
))
8736 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
8740 /* Retrieve the RID from the MemberSID */
8741 Status
= SampGetRidFromSid((PSID
)MemberSid
,
8743 if (!NT_SUCCESS(Status
))
8745 TRACE("SampGetRidFromSid failed with status 0x%08lx\n", Status
);
8749 /* Fail, if the RID represents a special account */
8752 TRACE("Cannot remove a special account (RID: %lu)\n", Rid
);
8753 Status
= STATUS_SPECIAL_ACCOUNT
;
8757 /* Remove the member from all aliases in the domain */
8758 Status
= SampRemoveMemberFromAllAliases(DomainObject
,
8760 if (!NT_SUCCESS(Status
))
8762 TRACE("SampRemoveMemberFromAllAliases failed with status 0x%08lx\n", Status
);
8766 RtlReleaseResource(&SampResource
);
8775 SamrQueryInformationDomain2(IN SAMPR_HANDLE DomainHandle
,
8776 IN DOMAIN_INFORMATION_CLASS DomainInformationClass
,
8777 OUT PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
8779 TRACE("(%p %lu %p)\n", DomainHandle
, DomainInformationClass
, Buffer
);
8781 return SamrQueryInformationDomain(DomainHandle
,
8782 DomainInformationClass
,
8790 SamrQueryInformationUser2(IN SAMPR_HANDLE UserHandle
,
8791 IN USER_INFORMATION_CLASS UserInformationClass
,
8792 OUT PSAMPR_USER_INFO_BUFFER
*Buffer
)
8794 TRACE("(%p %lu %p)\n", UserHandle
, UserInformationClass
, Buffer
);
8796 return SamrQueryInformationUser(UserHandle
,
8797 UserInformationClass
,
8805 SamrQueryDisplayInformation2(IN SAMPR_HANDLE DomainHandle
,
8806 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
8807 IN
unsigned long Index
,
8808 IN
unsigned long EntryCount
,
8809 IN
unsigned long PreferredMaximumLength
,
8810 OUT
unsigned long *TotalAvailable
,
8811 OUT
unsigned long *TotalReturned
,
8812 OUT PSAMPR_DISPLAY_INFO_BUFFER Buffer
)
8814 TRACE("%p %lu %lu %lu %lu %p %p %p\n",
8815 DomainHandle
, DisplayInformationClass
, Index
,
8816 EntryCount
, PreferredMaximumLength
, TotalAvailable
,
8817 TotalReturned
, Buffer
);
8819 return SamrQueryDisplayInformation(DomainHandle
,
8820 DisplayInformationClass
,
8823 PreferredMaximumLength
,
8833 SamrGetDisplayEnumerationIndex2(IN SAMPR_HANDLE DomainHandle
,
8834 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
8835 IN PRPC_UNICODE_STRING Prefix
,
8836 OUT
unsigned long *Index
)
8838 TRACE("(%p %lu %p %p)\n",
8839 DomainHandle
, DisplayInformationClass
, Prefix
, Index
);
8841 return SamrGetDisplayEnumerationIndex(DomainHandle
,
8842 DisplayInformationClass
,
8851 SamrCreateUser2InDomain(IN SAMPR_HANDLE DomainHandle
,
8852 IN PRPC_UNICODE_STRING Name
,
8853 IN
unsigned long AccountType
,
8854 IN ACCESS_MASK DesiredAccess
,
8855 OUT SAMPR_HANDLE
*UserHandle
,
8856 OUT
unsigned long *GrantedAccess
,
8857 OUT
unsigned long *RelativeId
)
8859 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
8860 SAM_USER_FIXED_DATA FixedUserData
;
8861 PSAM_DB_OBJECT DomainObject
;
8862 PSAM_DB_OBJECT UserObject
;
8863 GROUP_MEMBERSHIP GroupMembership
;
8864 UCHAR LogonHours
[23];
8868 PSECURITY_DESCRIPTOR Sd
= NULL
;
8870 PSID UserSid
= NULL
;
8873 TRACE("SamrCreateUserInDomain(%p %p %lx %p %p)\n",
8874 DomainHandle
, Name
, DesiredAccess
, UserHandle
, RelativeId
);
8877 Name
->Length
== 0 ||
8878 Name
->Buffer
== NULL
||
8879 UserHandle
== NULL
||
8881 return STATUS_INVALID_PARAMETER
;
8883 /* Check for valid account type */
8884 if (AccountType
!= USER_NORMAL_ACCOUNT
&&
8885 AccountType
!= USER_WORKSTATION_TRUST_ACCOUNT
&&
8886 AccountType
!= USER_INTERDOMAIN_TRUST_ACCOUNT
&&
8887 AccountType
!= USER_SERVER_TRUST_ACCOUNT
&&
8888 AccountType
!= USER_TEMP_DUPLICATE_ACCOUNT
)
8889 return STATUS_INVALID_PARAMETER
;
8891 /* Map generic access rights */
8892 RtlMapGenericMask(&DesiredAccess
,
8895 RtlAcquireResourceExclusive(&SampResource
,
8898 /* Validate the domain handle */
8899 Status
= SampValidateDbObject(DomainHandle
,
8903 if (!NT_SUCCESS(Status
))
8905 TRACE("failed with status 0x%08lx\n", Status
);
8909 /* Check the user account name */
8910 Status
= SampCheckAccountName(Name
, 20);
8911 if (!NT_SUCCESS(Status
))
8913 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
8917 /* Check if the user name already exists in the domain */
8918 Status
= SampCheckAccountNameInDomain(DomainObject
,
8920 if (!NT_SUCCESS(Status
))
8922 TRACE("User name \'%S\' already exists in domain (Status 0x%08lx)\n",
8923 Name
->Buffer
, Status
);
8927 /* Get the fixed domain attributes */
8928 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
8929 Status
= SampGetObjectAttribute(DomainObject
,
8932 (PVOID
)&FixedDomainData
,
8934 if (!NT_SUCCESS(Status
))
8936 TRACE("failed with status 0x%08lx\n", Status
);
8940 /* Increment the NextRid attribute */
8941 ulRid
= FixedDomainData
.NextRid
;
8942 FixedDomainData
.NextRid
++;
8944 TRACE("RID: %lx\n", ulRid
);
8946 /* Create the user SID */
8947 Status
= SampCreateAccountSid(DomainObject
,
8950 if (!NT_SUCCESS(Status
))
8952 TRACE("SampCreateAccountSid failed (Status 0x%08lx)\n", Status
);
8956 /* Create the security descriptor */
8957 Status
= SampCreateUserSD(UserSid
,
8960 if (!NT_SUCCESS(Status
))
8962 TRACE("SampCreateUserSD failed (Status 0x%08lx)\n", Status
);
8966 /* Store the fixed domain attributes */
8967 Status
= SampSetObjectAttribute(DomainObject
,
8972 if (!NT_SUCCESS(Status
))
8974 TRACE("failed with status 0x%08lx\n", Status
);
8978 /* Convert the RID into a string (hex) */
8979 swprintf(szRid
, L
"%08lX", ulRid
);
8981 /* Create the user object */
8982 Status
= SampCreateDbObject(DomainObject
,
8989 if (!NT_SUCCESS(Status
))
8991 TRACE("failed with status 0x%08lx\n", Status
);
8995 /* Add the account name for the user object */
8996 Status
= SampSetAccountNameInDomain(DomainObject
,
9000 if (!NT_SUCCESS(Status
))
9002 TRACE("failed with status 0x%08lx\n", Status
);
9006 /* Initialize fixed user data */
9007 FixedUserData
.Version
= 1;
9008 FixedUserData
.Reserved
= 0;
9009 FixedUserData
.LastLogon
.QuadPart
= 0;
9010 FixedUserData
.LastLogoff
.QuadPart
= 0;
9011 FixedUserData
.PasswordLastSet
.QuadPart
= 0;
9012 FixedUserData
.AccountExpires
.LowPart
= MAXULONG
;
9013 FixedUserData
.AccountExpires
.HighPart
= MAXLONG
;
9014 FixedUserData
.LastBadPasswordTime
.QuadPart
= 0;
9015 FixedUserData
.UserId
= ulRid
;
9016 FixedUserData
.PrimaryGroupId
= DOMAIN_GROUP_RID_USERS
;
9017 FixedUserData
.UserAccountControl
= USER_ACCOUNT_DISABLED
|
9018 USER_PASSWORD_NOT_REQUIRED
|
9020 FixedUserData
.CountryCode
= 0;
9021 FixedUserData
.CodePage
= 0;
9022 FixedUserData
.BadPasswordCount
= 0;
9023 FixedUserData
.LogonCount
= 0;
9024 FixedUserData
.AdminCount
= 0;
9025 FixedUserData
.OperatorCount
= 0;
9027 /* Set fixed user data attribute */
9028 Status
= SampSetObjectAttribute(UserObject
,
9031 (LPVOID
)&FixedUserData
,
9032 sizeof(SAM_USER_FIXED_DATA
));
9033 if (!NT_SUCCESS(Status
))
9035 TRACE("failed with status 0x%08lx\n", Status
);
9039 /* Set the Name attribute */
9040 Status
= SampSetObjectAttributeString(UserObject
,
9043 if (!NT_SUCCESS(Status
))
9045 TRACE("failed with status 0x%08lx\n", Status
);
9049 /* Set the FullName attribute */
9050 Status
= SampSetObjectAttributeString(UserObject
,
9053 if (!NT_SUCCESS(Status
))
9055 TRACE("failed with status 0x%08lx\n", Status
);
9059 /* Set the HomeDirectory attribute */
9060 Status
= SampSetObjectAttributeString(UserObject
,
9063 if (!NT_SUCCESS(Status
))
9065 TRACE("failed with status 0x%08lx\n", Status
);
9069 /* Set the HomeDirectoryDrive attribute */
9070 Status
= SampSetObjectAttributeString(UserObject
,
9071 L
"HomeDirectoryDrive",
9073 if (!NT_SUCCESS(Status
))
9075 TRACE("failed with status 0x%08lx\n", Status
);
9079 /* Set the ScriptPath attribute */
9080 Status
= SampSetObjectAttributeString(UserObject
,
9083 if (!NT_SUCCESS(Status
))
9085 TRACE("failed with status 0x%08lx\n", Status
);
9089 /* Set the ProfilePath attribute */
9090 Status
= SampSetObjectAttributeString(UserObject
,
9093 if (!NT_SUCCESS(Status
))
9095 TRACE("failed with status 0x%08lx\n", Status
);
9099 /* Set the AdminComment attribute */
9100 Status
= SampSetObjectAttributeString(UserObject
,
9103 if (!NT_SUCCESS(Status
))
9105 TRACE("failed with status 0x%08lx\n", Status
);
9109 /* Set the UserComment attribute */
9110 Status
= SampSetObjectAttributeString(UserObject
,
9113 if (!NT_SUCCESS(Status
))
9115 TRACE("failed with status 0x%08lx\n", Status
);
9119 /* Set the WorkStations attribute */
9120 Status
= SampSetObjectAttributeString(UserObject
,
9123 if (!NT_SUCCESS(Status
))
9125 TRACE("failed with status 0x%08lx\n", Status
);
9129 /* Set the Parameters attribute */
9130 Status
= SampSetObjectAttributeString(UserObject
,
9133 if (!NT_SUCCESS(Status
))
9135 TRACE("failed with status 0x%08lx\n", Status
);
9139 /* Set LogonHours attribute*/
9140 *((PUSHORT
)LogonHours
) = 168;
9141 memset(&(LogonHours
[2]), 0xff, 21);
9143 Status
= SampSetObjectAttribute(UserObject
,
9147 sizeof(LogonHours
));
9148 if (!NT_SUCCESS(Status
))
9150 TRACE("failed with status 0x%08lx\n", Status
);
9154 /* Set Groups attribute*/
9155 GroupMembership
.RelativeId
= DOMAIN_GROUP_RID_USERS
;
9156 GroupMembership
.Attributes
= SE_GROUP_MANDATORY
|
9158 SE_GROUP_ENABLED_BY_DEFAULT
;
9160 Status
= SampSetObjectAttribute(UserObject
,
9164 sizeof(GROUP_MEMBERSHIP
));
9165 if (!NT_SUCCESS(Status
))
9167 TRACE("failed with status 0x%08lx\n", Status
);
9171 /* Set LMPwd attribute*/
9172 Status
= SampSetObjectAttribute(UserObject
,
9177 if (!NT_SUCCESS(Status
))
9179 TRACE("failed with status 0x%08lx\n", Status
);
9183 /* Set NTPwd attribute*/
9184 Status
= SampSetObjectAttribute(UserObject
,
9189 if (!NT_SUCCESS(Status
))
9191 TRACE("failed with status 0x%08lx\n", Status
);
9195 /* Set LMPwdHistory attribute*/
9196 Status
= SampSetObjectAttribute(UserObject
,
9201 if (!NT_SUCCESS(Status
))
9203 TRACE("failed with status 0x%08lx\n", Status
);
9207 /* Set NTPwdHistory attribute*/
9208 Status
= SampSetObjectAttribute(UserObject
,
9213 if (!NT_SUCCESS(Status
))
9215 TRACE("failed with status 0x%08lx\n", Status
);
9219 /* Set the PrivateData attribute */
9220 Status
= SampSetObjectAttributeString(UserObject
,
9223 if (!NT_SUCCESS(Status
))
9225 TRACE("failed with status 0x%08lx\n", Status
);
9229 /* Set the SecDesc attribute*/
9230 Status
= SampSetObjectAttribute(UserObject
,
9235 if (!NT_SUCCESS(Status
))
9237 TRACE("failed with status 0x%08lx\n", Status
);
9241 if (NT_SUCCESS(Status
))
9243 *UserHandle
= (SAMPR_HANDLE
)UserObject
;
9244 *RelativeId
= ulRid
;
9245 *GrantedAccess
= UserObject
->Access
;
9250 RtlFreeHeap(RtlGetProcessHeap(), 0, Sd
);
9252 if (UserSid
!= NULL
)
9253 RtlFreeHeap(RtlGetProcessHeap(), 0, UserSid
);
9255 RtlReleaseResource(&SampResource
);
9257 TRACE("returns with status 0x%08lx\n", Status
);
9266 SamrQueryDisplayInformation3(IN SAMPR_HANDLE DomainHandle
,
9267 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
9268 IN
unsigned long Index
,
9269 IN
unsigned long EntryCount
,
9270 IN
unsigned long PreferredMaximumLength
,
9271 OUT
unsigned long *TotalAvailable
,
9272 OUT
unsigned long *TotalReturned
,
9273 OUT PSAMPR_DISPLAY_INFO_BUFFER Buffer
)
9275 TRACE("%p %lu %lu %lu %lu %p %p %p\n",
9276 DomainHandle
, DisplayInformationClass
, Index
,
9277 EntryCount
, PreferredMaximumLength
, TotalAvailable
,
9278 TotalReturned
, Buffer
);
9280 return SamrQueryDisplayInformation(DomainHandle
,
9281 DisplayInformationClass
,
9284 PreferredMaximumLength
,
9294 SamrAddMultipleMembersToAlias(IN SAMPR_HANDLE AliasHandle
,
9295 IN PSAMPR_PSID_ARRAY MembersBuffer
)
9298 NTSTATUS Status
= STATUS_SUCCESS
;
9300 TRACE("SamrAddMultipleMembersToAlias(%p %p)\n",
9301 AliasHandle
, MembersBuffer
);
9303 for (i
= 0; i
< MembersBuffer
->Count
; i
++)
9305 Status
= SamrAddMemberToAlias(AliasHandle
,
9306 ((PSID
*)MembersBuffer
->Sids
)[i
]);
9308 if (Status
== STATUS_MEMBER_IN_ALIAS
)
9309 Status
= STATUS_SUCCESS
;
9311 if (!NT_SUCCESS(Status
))
9322 SamrRemoveMultipleMembersFromAlias(IN SAMPR_HANDLE AliasHandle
,
9323 IN PSAMPR_PSID_ARRAY MembersBuffer
)
9326 NTSTATUS Status
= STATUS_SUCCESS
;
9328 TRACE("SamrRemoveMultipleMembersFromAlias(%p %p)\n",
9329 AliasHandle
, MembersBuffer
);
9331 for (i
= 0; i
< MembersBuffer
->Count
; i
++)
9333 Status
= SamrRemoveMemberFromAlias(AliasHandle
,
9334 ((PSID
*)MembersBuffer
->Sids
)[i
]);
9336 if (Status
== STATUS_MEMBER_IN_ALIAS
)
9337 Status
= STATUS_SUCCESS
;
9339 if (!NT_SUCCESS(Status
))
9350 SamrOemChangePasswordUser2(IN handle_t BindingHandle
,
9351 IN PRPC_STRING ServerName
,
9352 IN PRPC_STRING UserName
,
9353 IN PSAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldLm
,
9354 IN PENCRYPTED_LM_OWF_PASSWORD OldLmOwfPasswordEncryptedWithNewLm
)
9357 return STATUS_NOT_IMPLEMENTED
;
9363 SamrUnicodeChangePasswordUser2(IN handle_t BindingHandle
,
9364 IN PRPC_UNICODE_STRING ServerName
,
9365 IN PRPC_UNICODE_STRING UserName
,
9366 IN PSAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldNt
,
9367 IN PENCRYPTED_NT_OWF_PASSWORD OldNtOwfPasswordEncryptedWithNewNt
,
9368 IN
unsigned char LmPresent
,
9369 IN PSAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldLm
,
9370 IN PENCRYPTED_LM_OWF_PASSWORD OldLmOwfPasswordEncryptedWithNewNt
)
9373 return STATUS_NOT_IMPLEMENTED
;
9380 SamrGetDomainPasswordInformation(IN handle_t BindingHandle
,
9381 IN PRPC_UNICODE_STRING Unused
,
9382 OUT PUSER_DOMAIN_PASSWORD_INFORMATION PasswordInformation
)
9384 SAMPR_HANDLE ServerHandle
= NULL
;
9385 PSAM_DB_OBJECT DomainObject
= NULL
;
9386 SAM_DOMAIN_FIXED_DATA FixedData
;
9390 TRACE("(%p %p %p)\n", BindingHandle
, Unused
, PasswordInformation
);
9392 Status
= SamrConnect(NULL
,
9394 SAM_SERVER_LOOKUP_DOMAIN
);
9395 if (!NT_SUCCESS(Status
))
9397 TRACE("SamrConnect() failed (Status 0x%08lx)\n", Status
);
9401 Status
= SampOpenDbObject((PSAM_DB_OBJECT
)ServerHandle
,
9406 DOMAIN_READ_PASSWORD_PARAMETERS
,
9408 if (!NT_SUCCESS(Status
))
9410 TRACE("SampOpenDbObject() failed (Status 0x%08lx)\n", Status
);
9414 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
9415 Status
= SampGetObjectAttribute(DomainObject
,
9420 if (!NT_SUCCESS(Status
))
9422 TRACE("SampGetObjectAttribute() failed (Status 0x%08lx)\n", Status
);
9426 PasswordInformation
->MinPasswordLength
= FixedData
.MinPasswordLength
;
9427 PasswordInformation
->PasswordProperties
= FixedData
.PasswordProperties
;
9430 if (DomainObject
!= NULL
)
9431 SampCloseDbObject(DomainObject
);
9433 if (ServerHandle
!= NULL
)
9434 SamrCloseHandle(ServerHandle
);
9443 SamrConnect2(IN PSAMPR_SERVER_NAME ServerName
,
9444 OUT SAMPR_HANDLE
*ServerHandle
,
9445 IN ACCESS_MASK DesiredAccess
)
9447 TRACE("(%p %p %lx)\n", ServerName
, ServerHandle
, DesiredAccess
);
9449 return SamrConnect(ServerName
,
9458 SamrSetInformationUser2(IN SAMPR_HANDLE UserHandle
,
9459 IN USER_INFORMATION_CLASS UserInformationClass
,
9460 IN PSAMPR_USER_INFO_BUFFER Buffer
)
9462 TRACE("(%p %lu %p)\n", UserHandle
, UserInformationClass
, Buffer
);
9464 return SamrSetInformationUser(UserHandle
,
9465 UserInformationClass
,
9473 SamrSetBootKeyInformation(IN handle_t BindingHandle
) /* FIXME */
9476 return STATUS_NOT_IMPLEMENTED
;
9482 SamrGetBootKeyInformation(IN handle_t BindingHandle
) /* FIXME */
9485 return STATUS_NOT_IMPLEMENTED
;
9491 SamrConnect3(IN handle_t BindingHandle
) /* FIXME */
9494 return STATUS_NOT_IMPLEMENTED
;
9500 SamrConnect4(IN PSAMPR_SERVER_NAME ServerName
,
9501 OUT SAMPR_HANDLE
*ServerHandle
,
9502 IN
unsigned long ClientRevision
,
9503 IN ACCESS_MASK DesiredAccess
)
9506 return STATUS_NOT_IMPLEMENTED
;
9512 SamrUnicodeChangePasswordUser3(IN handle_t BindingHandle
) /* FIXME */
9515 return STATUS_NOT_IMPLEMENTED
;
9521 SamrConnect5(IN PSAMPR_SERVER_NAME ServerName
,
9522 IN ACCESS_MASK DesiredAccess
,
9523 IN
unsigned long InVersion
,
9524 IN SAMPR_REVISION_INFO
*InRevisionInfo
,
9525 OUT
unsigned long *OutVersion
,
9526 OUT SAMPR_REVISION_INFO
*OutRevisionInfo
,
9527 OUT SAMPR_HANDLE
*ServerHandle
)
9530 return STATUS_NOT_IMPLEMENTED
;
9536 SamrRidToSid(IN SAMPR_HANDLE ObjectHandle
,
9537 IN
unsigned long Rid
,
9541 return STATUS_NOT_IMPLEMENTED
;
9547 SamrSetDSRMPassword(IN handle_t BindingHandle
,
9548 IN PRPC_UNICODE_STRING Unused
,
9549 IN
unsigned long UserId
,
9550 IN PENCRYPTED_NT_OWF_PASSWORD EncryptedNtOwfPassword
)
9553 return STATUS_NOT_IMPLEMENTED
;
9559 SamrValidatePassword(IN handle_t Handle
,
9560 IN PASSWORD_POLICY_VALIDATION_TYPE ValidationType
,
9561 IN PSAM_VALIDATE_INPUT_ARG InputArg
,
9562 OUT PSAM_VALIDATE_OUTPUT_ARG
*OutputArg
)
9565 return STATUS_NOT_IMPLEMENTED
;