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
.QuadPart
= MAXLONGLONG
;
2561 FixedUserData
.LastBadPasswordTime
.QuadPart
= 0;
2562 FixedUserData
.UserId
= ulRid
;
2563 FixedUserData
.PrimaryGroupId
= DOMAIN_GROUP_RID_USERS
;
2564 FixedUserData
.UserAccountControl
= USER_ACCOUNT_DISABLED
|
2565 USER_PASSWORD_NOT_REQUIRED
|
2566 USER_NORMAL_ACCOUNT
;
2567 FixedUserData
.CountryCode
= 0;
2568 FixedUserData
.CodePage
= 0;
2569 FixedUserData
.BadPasswordCount
= 0;
2570 FixedUserData
.LogonCount
= 0;
2571 FixedUserData
.AdminCount
= 0;
2572 FixedUserData
.OperatorCount
= 0;
2574 /* Set fixed user data attribute */
2575 Status
= SampSetObjectAttribute(UserObject
,
2578 (LPVOID
)&FixedUserData
,
2579 sizeof(SAM_USER_FIXED_DATA
));
2580 if (!NT_SUCCESS(Status
))
2582 TRACE("failed with status 0x%08lx\n", Status
);
2586 /* Set the Name attribute */
2587 Status
= SampSetObjectAttributeString(UserObject
,
2590 if (!NT_SUCCESS(Status
))
2592 TRACE("failed with status 0x%08lx\n", Status
);
2596 /* Set the FullName attribute */
2597 Status
= SampSetObjectAttributeString(UserObject
,
2600 if (!NT_SUCCESS(Status
))
2602 TRACE("failed with status 0x%08lx\n", Status
);
2606 /* Set the HomeDirectory attribute */
2607 Status
= SampSetObjectAttributeString(UserObject
,
2610 if (!NT_SUCCESS(Status
))
2612 TRACE("failed with status 0x%08lx\n", Status
);
2616 /* Set the HomeDirectoryDrive attribute */
2617 Status
= SampSetObjectAttributeString(UserObject
,
2618 L
"HomeDirectoryDrive",
2620 if (!NT_SUCCESS(Status
))
2622 TRACE("failed with status 0x%08lx\n", Status
);
2626 /* Set the ScriptPath attribute */
2627 Status
= SampSetObjectAttributeString(UserObject
,
2630 if (!NT_SUCCESS(Status
))
2632 TRACE("failed with status 0x%08lx\n", Status
);
2636 /* Set the ProfilePath attribute */
2637 Status
= SampSetObjectAttributeString(UserObject
,
2640 if (!NT_SUCCESS(Status
))
2642 TRACE("failed with status 0x%08lx\n", Status
);
2646 /* Set the AdminComment attribute */
2647 Status
= SampSetObjectAttributeString(UserObject
,
2650 if (!NT_SUCCESS(Status
))
2652 TRACE("failed with status 0x%08lx\n", Status
);
2656 /* Set the UserComment attribute */
2657 Status
= SampSetObjectAttributeString(UserObject
,
2660 if (!NT_SUCCESS(Status
))
2662 TRACE("failed with status 0x%08lx\n", Status
);
2666 /* Set the WorkStations attribute */
2667 Status
= SampSetObjectAttributeString(UserObject
,
2670 if (!NT_SUCCESS(Status
))
2672 TRACE("failed with status 0x%08lx\n", Status
);
2676 /* Set the Parameters attribute */
2677 Status
= SampSetObjectAttributeString(UserObject
,
2680 if (!NT_SUCCESS(Status
))
2682 TRACE("failed with status 0x%08lx\n", Status
);
2686 /* Set LogonHours attribute*/
2687 *((PUSHORT
)LogonHours
) = 168;
2688 memset(&(LogonHours
[2]), 0xff, 21);
2690 Status
= SampSetObjectAttribute(UserObject
,
2694 sizeof(LogonHours
));
2695 if (!NT_SUCCESS(Status
))
2697 TRACE("failed with status 0x%08lx\n", Status
);
2701 /* Set Groups attribute*/
2702 GroupMembership
.RelativeId
= DOMAIN_GROUP_RID_USERS
;
2703 GroupMembership
.Attributes
= SE_GROUP_MANDATORY
|
2705 SE_GROUP_ENABLED_BY_DEFAULT
;
2707 Status
= SampSetObjectAttribute(UserObject
,
2711 sizeof(GROUP_MEMBERSHIP
));
2712 if (!NT_SUCCESS(Status
))
2714 TRACE("failed with status 0x%08lx\n", Status
);
2718 /* Set LMPwd attribute*/
2719 Status
= SampSetObjectAttribute(UserObject
,
2723 sizeof(ENCRYPTED_LM_OWF_PASSWORD
));
2724 if (!NT_SUCCESS(Status
))
2726 TRACE("failed with status 0x%08lx\n", Status
);
2730 /* Set NTPwd attribute*/
2731 Status
= SampSetObjectAttribute(UserObject
,
2735 sizeof(ENCRYPTED_NT_OWF_PASSWORD
));
2736 if (!NT_SUCCESS(Status
))
2738 TRACE("failed with status 0x%08lx\n", Status
);
2742 /* Set LMPwdHistory attribute*/
2743 Status
= SampSetObjectAttribute(UserObject
,
2748 if (!NT_SUCCESS(Status
))
2750 TRACE("failed with status 0x%08lx\n", Status
);
2754 /* Set NTPwdHistory attribute*/
2755 Status
= SampSetObjectAttribute(UserObject
,
2760 if (!NT_SUCCESS(Status
))
2762 TRACE("failed with status 0x%08lx\n", Status
);
2766 /* Set the PrivateData attribute */
2767 Status
= SampSetObjectAttributeString(UserObject
,
2770 if (!NT_SUCCESS(Status
))
2772 TRACE("failed with status 0x%08lx\n", Status
);
2776 /* Set the SecDesc attribute*/
2777 Status
= SampSetObjectAttribute(UserObject
,
2782 if (!NT_SUCCESS(Status
))
2784 TRACE("failed with status 0x%08lx\n", Status
);
2788 if (NT_SUCCESS(Status
))
2790 *UserHandle
= (SAMPR_HANDLE
)UserObject
;
2791 *RelativeId
= ulRid
;
2796 RtlFreeHeap(RtlGetProcessHeap(), 0, Sd
);
2798 if (UserSid
!= NULL
)
2799 RtlFreeHeap(RtlGetProcessHeap(), 0, UserSid
);
2801 RtlReleaseResource(&SampResource
);
2803 TRACE("returns with status 0x%08lx\n", Status
);
2812 SamrEnumerateUsersInDomain(IN SAMPR_HANDLE DomainHandle
,
2813 IN OUT
unsigned long *EnumerationContext
,
2814 IN
unsigned long UserAccountControl
,
2815 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
2816 IN
unsigned long PreferedMaximumLength
,
2817 OUT
unsigned long *CountReturned
)
2819 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
2820 PSAM_DB_OBJECT DomainObject
;
2821 HANDLE UsersKeyHandle
= NULL
;
2822 HANDLE NamesKeyHandle
= NULL
;
2825 ULONG EnumCount
= 0;
2826 ULONG RequiredLength
= 0;
2831 BOOLEAN MoreEntries
= FALSE
;
2834 TRACE("SamrEnumerateUsersInDomain(%p %p %lx %p %lu %p)\n",
2835 DomainHandle
, EnumerationContext
, UserAccountControl
, Buffer
,
2836 PreferedMaximumLength
, CountReturned
);
2838 RtlAcquireResourceShared(&SampResource
,
2841 /* Validate the domain handle */
2842 Status
= SampValidateDbObject(DomainHandle
,
2844 DOMAIN_LIST_ACCOUNTS
,
2846 if (!NT_SUCCESS(Status
))
2849 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
2853 if (!NT_SUCCESS(Status
))
2856 Status
= SampRegOpenKey(UsersKeyHandle
,
2860 if (!NT_SUCCESS(Status
))
2865 EnumIndex
= *EnumerationContext
;
2869 NameLength
= 64 * sizeof(WCHAR
);
2870 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2877 if (!NT_SUCCESS(Status
))
2879 if (Status
== STATUS_NO_MORE_ENTRIES
)
2880 Status
= STATUS_SUCCESS
;
2884 TRACE("EnumIndex: %lu\n", EnumIndex
);
2885 TRACE("User name: %S\n", UserName
);
2886 TRACE("Name length: %lu\n", NameLength
);
2888 if ((RequiredLength
+ NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
)) > PreferedMaximumLength
)
2894 RequiredLength
+= (NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
));
2900 TRACE("EnumCount: %lu\n", EnumCount
);
2901 TRACE("RequiredLength: %lu\n", RequiredLength
);
2903 if (!NT_SUCCESS(Status
))
2906 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
2907 if (EnumBuffer
== NULL
)
2909 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2913 EnumBuffer
->EntriesRead
= EnumCount
;
2917 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
2918 if (EnumBuffer
->Buffer
== NULL
)
2920 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2926 EnumIndex
= *EnumerationContext
;
2927 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
2929 NameLength
= 64 * sizeof(WCHAR
);
2930 DataLength
= sizeof(ULONG
);
2931 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2938 if (!NT_SUCCESS(Status
))
2940 if (Status
== STATUS_NO_MORE_ENTRIES
)
2941 Status
= STATUS_SUCCESS
;
2945 TRACE("EnumIndex: %lu\n", EnumIndex
);
2946 TRACE("User name: %S\n", UserName
);
2947 TRACE("Name length: %lu\n", NameLength
);
2948 TRACE("RID: %lu\n", Rid
);
2950 EnumBuffer
->Buffer
[i
].RelativeId
= Rid
;
2952 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)NameLength
;
2953 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)(NameLength
+ sizeof(UNICODE_NULL
));
2955 /* FIXME: Disabled because of bugs in widl and rpcrt4 */
2957 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(EnumBuffer
->Buffer
[i
].Name
.MaximumLength
);
2958 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
2960 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2964 memcpy(EnumBuffer
->Buffer
[i
].Name
.Buffer
,
2966 EnumBuffer
->Buffer
[i
].Name
.Length
);
2971 if (NT_SUCCESS(Status
))
2973 *EnumerationContext
+= EnumCount
;
2974 *Buffer
= EnumBuffer
;
2975 *CountReturned
= EnumCount
;
2979 *EnumerationContext
= 0;
2983 if (EnumBuffer
!= NULL
)
2985 if (EnumBuffer
->Buffer
!= NULL
)
2987 if (EnumBuffer
->EntriesRead
!= 0)
2989 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
2991 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
2992 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
2996 midl_user_free(EnumBuffer
->Buffer
);
2999 midl_user_free(EnumBuffer
);
3003 SampRegCloseKey(&NamesKeyHandle
);
3004 SampRegCloseKey(&UsersKeyHandle
);
3006 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
!= FALSE
))
3007 Status
= STATUS_MORE_ENTRIES
;
3009 RtlReleaseResource(&SampResource
);
3018 SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle
,
3019 IN PRPC_UNICODE_STRING AccountName
,
3020 IN ACCESS_MASK DesiredAccess
,
3021 OUT SAMPR_HANDLE
*AliasHandle
,
3022 OUT
unsigned long *RelativeId
)
3024 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
3025 PSAM_DB_OBJECT DomainObject
;
3026 PSAM_DB_OBJECT AliasObject
;
3027 PSECURITY_DESCRIPTOR Sd
= NULL
;
3034 TRACE("SamrCreateAliasInDomain(%p %p %lx %p %p)\n",
3035 DomainHandle
, AccountName
, DesiredAccess
, AliasHandle
, RelativeId
);
3037 /* Map generic access rights */
3038 RtlMapGenericMask(&DesiredAccess
,
3041 RtlAcquireResourceExclusive(&SampResource
,
3044 /* Validate the domain handle */
3045 Status
= SampValidateDbObject(DomainHandle
,
3047 DOMAIN_CREATE_ALIAS
,
3049 if (!NT_SUCCESS(Status
))
3051 TRACE("failed with status 0x%08lx\n", Status
);
3055 /* Check the alias account name */
3056 Status
= SampCheckAccountName(AccountName
, 256);
3057 if (!NT_SUCCESS(Status
))
3059 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
3063 /* Check if the alias name already exists in the domain */
3064 Status
= SampCheckAccountNameInDomain(DomainObject
,
3065 AccountName
->Buffer
);
3066 if (!NT_SUCCESS(Status
))
3068 TRACE("Alias name \'%S\' already exists in domain (Status 0x%08lx)\n",
3069 AccountName
->Buffer
, Status
);
3073 /* Create the security descriptor */
3074 Status
= SampCreateAliasSD(&Sd
,
3076 if (!NT_SUCCESS(Status
))
3078 TRACE("SampCreateAliasSD failed (Status 0x%08lx)\n", Status
);
3082 /* Get the fixed domain attributes */
3083 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
3084 Status
= SampGetObjectAttribute(DomainObject
,
3087 (PVOID
)&FixedDomainData
,
3089 if (!NT_SUCCESS(Status
))
3091 TRACE("failed with status 0x%08lx\n", Status
);
3095 /* Increment the NextRid attribute */
3096 ulRid
= FixedDomainData
.NextRid
;
3097 FixedDomainData
.NextRid
++;
3099 /* Store the fixed domain attributes */
3100 Status
= SampSetObjectAttribute(DomainObject
,
3105 if (!NT_SUCCESS(Status
))
3107 TRACE("failed with status 0x%08lx\n", Status
);
3111 TRACE("RID: %lx\n", ulRid
);
3113 /* Convert the RID into a string (hex) */
3114 swprintf(szRid
, L
"%08lX", ulRid
);
3116 /* Create the alias object */
3117 Status
= SampCreateDbObject(DomainObject
,
3124 if (!NT_SUCCESS(Status
))
3126 TRACE("failed with status 0x%08lx\n", Status
);
3130 /* Add the account name for the alias object */
3131 Status
= SampSetAccountNameInDomain(DomainObject
,
3133 AccountName
->Buffer
,
3135 if (!NT_SUCCESS(Status
))
3137 TRACE("failed with status 0x%08lx\n", Status
);
3141 /* Set the Name attribute */
3142 Status
= SampSetObjectAttributeString(AliasObject
,
3145 if (!NT_SUCCESS(Status
))
3147 TRACE("failed with status 0x%08lx\n", Status
);
3151 /* Set the Description attribute */
3152 Status
= SampSetObjectAttributeString(AliasObject
,
3155 if (!NT_SUCCESS(Status
))
3157 TRACE("failed with status 0x%08lx\n", Status
);
3161 /* Set the SecDesc attribute*/
3162 Status
= SampSetObjectAttribute(AliasObject
,
3167 if (!NT_SUCCESS(Status
))
3169 TRACE("failed with status 0x%08lx\n", Status
);
3173 if (NT_SUCCESS(Status
))
3175 *AliasHandle
= (SAMPR_HANDLE
)AliasObject
;
3176 *RelativeId
= ulRid
;
3181 RtlFreeHeap(RtlGetProcessHeap(), 0, Sd
);
3183 RtlReleaseResource(&SampResource
);
3185 TRACE("returns with status 0x%08lx\n", Status
);
3194 SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle
,
3195 IN OUT
unsigned long *EnumerationContext
,
3196 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
3197 IN
unsigned long PreferedMaximumLength
,
3198 OUT
unsigned long *CountReturned
)
3200 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
3201 PSAM_DB_OBJECT DomainObject
;
3202 HANDLE AliasesKeyHandle
= NULL
;
3203 HANDLE NamesKeyHandle
= NULL
;
3204 WCHAR AliasName
[64];
3206 ULONG EnumCount
= 0;
3207 ULONG RequiredLength
= 0;
3212 BOOLEAN MoreEntries
= FALSE
;
3215 TRACE("SamrEnumerateAliasesInDomain(%p %p %p %lu %p)\n",
3216 DomainHandle
, EnumerationContext
, Buffer
,
3217 PreferedMaximumLength
, CountReturned
);
3219 RtlAcquireResourceShared(&SampResource
,
3222 /* Validate the domain handle */
3223 Status
= SampValidateDbObject(DomainHandle
,
3225 DOMAIN_LIST_ACCOUNTS
,
3227 if (!NT_SUCCESS(Status
))
3230 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3234 if (!NT_SUCCESS(Status
))
3237 Status
= SampRegOpenKey(AliasesKeyHandle
,
3241 if (!NT_SUCCESS(Status
))
3246 EnumIndex
= *EnumerationContext
;
3250 NameLength
= 64 * sizeof(WCHAR
);
3251 Status
= SampRegEnumerateValue(NamesKeyHandle
,
3258 if (!NT_SUCCESS(Status
))
3260 if (Status
== STATUS_NO_MORE_ENTRIES
)
3261 Status
= STATUS_SUCCESS
;
3265 TRACE("EnumIndex: %lu\n", EnumIndex
);
3266 TRACE("Alias name: %S\n", AliasName
);
3267 TRACE("Name length: %lu\n", NameLength
);
3269 if ((RequiredLength
+ NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
)) > PreferedMaximumLength
)
3275 RequiredLength
+= (NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
));
3281 TRACE("EnumCount: %lu\n", EnumCount
);
3282 TRACE("RequiredLength: %lu\n", RequiredLength
);
3284 if (!NT_SUCCESS(Status
))
3287 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
3288 if (EnumBuffer
== NULL
)
3290 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3294 EnumBuffer
->EntriesRead
= EnumCount
;
3298 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
3299 if (EnumBuffer
->Buffer
== NULL
)
3301 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3307 EnumIndex
= *EnumerationContext
;
3308 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
3310 NameLength
= 64 * sizeof(WCHAR
);
3311 DataLength
= sizeof(ULONG
);
3312 Status
= SampRegEnumerateValue(NamesKeyHandle
,
3319 if (!NT_SUCCESS(Status
))
3321 if (Status
== STATUS_NO_MORE_ENTRIES
)
3322 Status
= STATUS_SUCCESS
;
3326 TRACE("EnumIndex: %lu\n", EnumIndex
);
3327 TRACE("Alias name: %S\n", AliasName
);
3328 TRACE("Name length: %lu\n", NameLength
);
3329 TRACE("RID: %lu\n", Rid
);
3331 EnumBuffer
->Buffer
[i
].RelativeId
= Rid
;
3333 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)NameLength
;
3334 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)(NameLength
+ sizeof(UNICODE_NULL
));
3336 /* FIXME: Disabled because of bugs in widl and rpcrt4 */
3338 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(EnumBuffer
->Buffer
[i
].Name
.MaximumLength
);
3339 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
3341 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3345 memcpy(EnumBuffer
->Buffer
[i
].Name
.Buffer
,
3347 EnumBuffer
->Buffer
[i
].Name
.Length
);
3352 if (NT_SUCCESS(Status
))
3354 *EnumerationContext
+= EnumCount
;
3355 *Buffer
= EnumBuffer
;
3356 *CountReturned
= EnumCount
;
3360 *EnumerationContext
= 0;
3364 if (EnumBuffer
!= NULL
)
3366 if (EnumBuffer
->Buffer
!= NULL
)
3368 if (EnumBuffer
->EntriesRead
!= 0)
3370 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
3372 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
3373 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
3377 midl_user_free(EnumBuffer
->Buffer
);
3380 midl_user_free(EnumBuffer
);
3384 SampRegCloseKey(&NamesKeyHandle
);
3385 SampRegCloseKey(&AliasesKeyHandle
);
3387 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
!= FALSE
))
3388 Status
= STATUS_MORE_ENTRIES
;
3390 RtlReleaseResource(&SampResource
);
3399 SamrGetAliasMembership(IN SAMPR_HANDLE DomainHandle
,
3400 IN PSAMPR_PSID_ARRAY SidArray
,
3401 OUT PSAMPR_ULONG_ARRAY Membership
)
3403 PSAM_DB_OBJECT DomainObject
;
3404 HANDLE AliasesKeyHandle
= NULL
;
3405 HANDLE MembersKeyHandle
= NULL
;
3406 HANDLE MemberKeyHandle
= NULL
;
3407 LPWSTR MemberSidString
= NULL
;
3408 PULONG RidArray
= NULL
;
3409 ULONG MaxSidCount
= 0;
3415 WCHAR NameBuffer
[9];
3417 TRACE("SamrGetAliasMembership(%p %p %p)\n",
3418 DomainHandle
, SidArray
, Membership
);
3420 RtlAcquireResourceShared(&SampResource
,
3423 /* Validate the domain handle */
3424 Status
= SampValidateDbObject(DomainHandle
,
3426 DOMAIN_GET_ALIAS_MEMBERSHIP
,
3428 if (!NT_SUCCESS(Status
))
3431 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3435 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3436 if (!NT_SUCCESS(Status
))
3439 Status
= SampRegOpenKey(AliasesKeyHandle
,
3443 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3445 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3447 Status
= STATUS_SUCCESS
;
3451 if (!NT_SUCCESS(Status
))
3454 for (i
= 0; i
< SidArray
->Count
; i
++)
3456 ConvertSidToStringSid(SidArray
->Sids
[i
].SidPointer
, &MemberSidString
);
3457 TRACE("Open %S\n", MemberSidString
);
3459 Status
= SampRegOpenKey(MembersKeyHandle
,
3463 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3464 if (NT_SUCCESS(Status
))
3466 Status
= SampRegQueryKeyInfo(MemberKeyHandle
,
3469 if (NT_SUCCESS(Status
))
3471 TRACE("Found %lu values\n", ValueCount
);
3472 MaxSidCount
+= ValueCount
;
3475 SampRegCloseKey(&MemberKeyHandle
);
3478 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3479 Status
= STATUS_SUCCESS
;
3481 LocalFree(MemberSidString
);
3484 if (MaxSidCount
== 0)
3486 Status
= STATUS_SUCCESS
;
3490 TRACE("Maximum sid count: %lu\n", MaxSidCount
);
3491 RidArray
= midl_user_allocate(MaxSidCount
* sizeof(ULONG
));
3492 if (RidArray
== NULL
)
3494 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3499 for (i
= 0; i
< SidArray
->Count
; i
++)
3501 ConvertSidToStringSid(SidArray
->Sids
[i
].SidPointer
, &MemberSidString
);
3502 TRACE("Open %S\n", MemberSidString
);
3504 Status
= SampRegOpenKey(MembersKeyHandle
,
3508 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3509 if (NT_SUCCESS(Status
))
3511 Status
= SampRegQueryKeyInfo(MemberKeyHandle
,
3514 if (NT_SUCCESS(Status
))
3516 TRACE("Found %lu values\n", ValueCount
);
3518 for (j
= 0; j
< ValueCount
; j
++)
3520 DataLength
= 9 * sizeof(WCHAR
);
3521 Status
= SampRegEnumerateValue(MemberKeyHandle
,
3528 if (NT_SUCCESS(Status
))
3530 /* FIXME: Do not return each RID more than once. */
3531 RidArray
[RidIndex
] = wcstoul(NameBuffer
, NULL
, 16);
3537 SampRegCloseKey(&MemberKeyHandle
);
3540 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3541 Status
= STATUS_SUCCESS
;
3543 LocalFree(MemberSidString
);
3547 SampRegCloseKey(&MembersKeyHandle
);
3548 SampRegCloseKey(&AliasesKeyHandle
);
3550 if (NT_SUCCESS(Status
))
3552 Membership
->Count
= MaxSidCount
;
3553 Membership
->Element
= RidArray
;
3557 if (RidArray
!= NULL
)
3558 midl_user_free(RidArray
);
3561 RtlReleaseResource(&SampResource
);
3570 SamrLookupNamesInDomain(IN SAMPR_HANDLE DomainHandle
,
3572 IN RPC_UNICODE_STRING Names
[],
3573 OUT PSAMPR_ULONG_ARRAY RelativeIds
,
3574 OUT PSAMPR_ULONG_ARRAY Use
)
3576 PSAM_DB_OBJECT DomainObject
;
3577 HANDLE AccountsKeyHandle
= NULL
;
3578 HANDLE NamesKeyHandle
= NULL
;
3579 ULONG MappedCount
= 0;
3585 TRACE("SamrLookupNamesInDomain(%p %lu %p %p %p)\n",
3586 DomainHandle
, Count
, Names
, RelativeIds
, Use
);
3588 RtlAcquireResourceShared(&SampResource
,
3591 /* Validate the domain handle */
3592 Status
= SampValidateDbObject(DomainHandle
,
3596 if (!NT_SUCCESS(Status
))
3598 TRACE("failed with status 0x%08lx\n", Status
);
3602 RelativeIds
->Count
= 0;
3607 Status
= STATUS_SUCCESS
;
3611 /* Allocate the relative IDs array */
3612 RelativeIds
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
3613 if (RelativeIds
->Element
== NULL
)
3615 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3619 /* Allocate the use array */
3620 Use
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
3621 if (Use
->Element
== NULL
)
3623 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3627 RelativeIds
->Count
= Count
;
3630 for (i
= 0; i
< Count
; i
++)
3632 TRACE("Name: %S\n", Names
[i
].Buffer
);
3636 /* Lookup aliases */
3637 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3640 &AccountsKeyHandle
);
3641 if (NT_SUCCESS(Status
))
3643 Status
= SampRegOpenKey(AccountsKeyHandle
,
3647 if (NT_SUCCESS(Status
))
3649 DataLength
= sizeof(ULONG
);
3650 Status
= SampRegQueryValue(NamesKeyHandle
,
3656 SampRegCloseKey(&NamesKeyHandle
);
3659 SampRegCloseKey(&AccountsKeyHandle
);
3662 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3665 /* Return alias account */
3666 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
3668 TRACE("Rid: %lu\n", RelativeId
);
3669 RelativeIds
->Element
[i
] = RelativeId
;
3670 Use
->Element
[i
] = SidTypeAlias
;
3676 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3679 &AccountsKeyHandle
);
3680 if (NT_SUCCESS(Status
))
3682 Status
= SampRegOpenKey(AccountsKeyHandle
,
3686 if (NT_SUCCESS(Status
))
3688 DataLength
= sizeof(ULONG
);
3689 Status
= SampRegQueryValue(NamesKeyHandle
,
3695 SampRegCloseKey(&NamesKeyHandle
);
3698 SampRegCloseKey(&AccountsKeyHandle
);
3701 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3704 /* Return group account */
3705 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
3707 TRACE("Rid: %lu\n", RelativeId
);
3708 RelativeIds
->Element
[i
] = RelativeId
;
3709 Use
->Element
[i
] = SidTypeGroup
;
3715 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3718 &AccountsKeyHandle
);
3719 if (NT_SUCCESS(Status
))
3721 Status
= SampRegOpenKey(AccountsKeyHandle
,
3725 if (NT_SUCCESS(Status
))
3727 DataLength
= sizeof(ULONG
);
3728 Status
= SampRegQueryValue(NamesKeyHandle
,
3734 SampRegCloseKey(&NamesKeyHandle
);
3737 SampRegCloseKey(&AccountsKeyHandle
);
3740 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3743 /* Return user account */
3744 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
3746 TRACE("Rid: %lu\n", RelativeId
);
3747 RelativeIds
->Element
[i
] = RelativeId
;
3748 Use
->Element
[i
] = SidTypeUser
;
3753 /* Return unknown account */
3754 RelativeIds
->Element
[i
] = 0;
3755 Use
->Element
[i
] = SidTypeUnknown
;
3759 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3760 Status
= STATUS_SUCCESS
;
3762 if (NT_SUCCESS(Status
))
3764 if (MappedCount
== 0)
3765 Status
= STATUS_NONE_MAPPED
;
3766 else if (MappedCount
< Count
)
3767 Status
= STATUS_SOME_NOT_MAPPED
;
3771 if (RelativeIds
->Element
!= NULL
)
3773 midl_user_free(RelativeIds
->Element
);
3774 RelativeIds
->Element
= NULL
;
3777 RelativeIds
->Count
= 0;
3779 if (Use
->Element
!= NULL
)
3781 midl_user_free(Use
->Element
);
3782 Use
->Element
= NULL
;
3788 RtlReleaseResource(&SampResource
);
3790 TRACE("Returned Status %lx\n", Status
);
3799 SamrLookupIdsInDomain(IN SAMPR_HANDLE DomainHandle
,
3801 IN ULONG
*RelativeIds
,
3802 OUT PSAMPR_RETURNED_USTRING_ARRAY Names
,
3803 OUT PSAMPR_ULONG_ARRAY Use
)
3805 PSAM_DB_OBJECT DomainObject
;
3807 HANDLE AccountsKeyHandle
= NULL
;
3808 HANDLE AccountKeyHandle
= NULL
;
3809 ULONG MappedCount
= 0;
3814 TRACE("SamrLookupIdsInDomain(%p %lu %p %p %p)\n",
3815 DomainHandle
, Count
, RelativeIds
, Names
, Use
);
3817 RtlAcquireResourceShared(&SampResource
,
3820 /* Validate the domain handle */
3821 Status
= SampValidateDbObject(DomainHandle
,
3825 if (!NT_SUCCESS(Status
))
3827 TRACE("failed with status 0x%08lx\n", Status
);
3836 Status
= STATUS_SUCCESS
;
3840 /* Allocate the names array */
3841 Names
->Element
= midl_user_allocate(Count
* sizeof(*Names
->Element
));
3842 if (Names
->Element
== NULL
)
3844 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3848 /* Allocate the use array */
3849 Use
->Element
= midl_user_allocate(Count
* sizeof(*Use
->Element
));
3850 if (Use
->Element
== NULL
)
3852 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3856 Names
->Count
= Count
;
3859 for (i
= 0; i
< Count
; i
++)
3861 TRACE("RID: %lu\n", RelativeIds
[i
]);
3863 swprintf(RidString
, L
"%08lx", RelativeIds
[i
]);
3865 /* Lookup aliases */
3866 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3869 &AccountsKeyHandle
);
3870 if (NT_SUCCESS(Status
))
3872 Status
= SampRegOpenKey(AccountsKeyHandle
,
3876 if (NT_SUCCESS(Status
))
3879 Status
= SampRegQueryValue(AccountKeyHandle
,
3884 if (NT_SUCCESS(Status
))
3886 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
3887 if (Names
->Element
[i
].Buffer
== NULL
)
3888 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3890 if (NT_SUCCESS(Status
))
3892 Names
->Element
[i
].MaximumLength
= (USHORT
)DataLength
;
3893 Names
->Element
[i
].Length
= (USHORT
)(DataLength
- sizeof(WCHAR
));
3895 Status
= SampRegQueryValue(AccountKeyHandle
,
3898 Names
->Element
[i
].Buffer
,
3903 SampRegCloseKey(&AccountKeyHandle
);
3906 SampRegCloseKey(&AccountsKeyHandle
);
3909 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3912 /* Return alias account */
3913 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
3915 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
3916 Use
->Element
[i
] = SidTypeAlias
;
3922 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3925 &AccountsKeyHandle
);
3926 if (NT_SUCCESS(Status
))
3928 Status
= SampRegOpenKey(AccountsKeyHandle
,
3932 if (NT_SUCCESS(Status
))
3935 Status
= SampRegQueryValue(AccountKeyHandle
,
3940 if (NT_SUCCESS(Status
))
3942 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
3943 if (Names
->Element
[i
].Buffer
== NULL
)
3944 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3946 if (NT_SUCCESS(Status
))
3948 Names
->Element
[i
].MaximumLength
= (USHORT
)DataLength
;
3949 Names
->Element
[i
].Length
= (USHORT
)(DataLength
- sizeof(WCHAR
));
3951 Status
= SampRegQueryValue(AccountKeyHandle
,
3954 Names
->Element
[i
].Buffer
,
3959 SampRegCloseKey(&AccountKeyHandle
);
3962 SampRegCloseKey(&AccountsKeyHandle
);
3965 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3968 /* Return group account */
3969 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
3971 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
3972 Use
->Element
[i
] = SidTypeGroup
;
3978 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3981 &AccountsKeyHandle
);
3982 if (NT_SUCCESS(Status
))
3984 Status
= SampRegOpenKey(AccountsKeyHandle
,
3988 if (NT_SUCCESS(Status
))
3991 Status
= SampRegQueryValue(AccountKeyHandle
,
3996 if (NT_SUCCESS(Status
))
3998 TRACE("DataLength: %lu\n", DataLength
);
4000 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
4001 if (Names
->Element
[i
].Buffer
== NULL
)
4002 Status
= STATUS_INSUFFICIENT_RESOURCES
;
4004 if (NT_SUCCESS(Status
))
4006 Names
->Element
[i
].MaximumLength
= (USHORT
)DataLength
;
4007 Names
->Element
[i
].Length
= (USHORT
)(DataLength
- sizeof(WCHAR
));
4009 Status
= SampRegQueryValue(AccountKeyHandle
,
4012 Names
->Element
[i
].Buffer
,
4017 SampRegCloseKey(&AccountKeyHandle
);
4020 SampRegCloseKey(&AccountsKeyHandle
);
4023 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
4026 /* Return user account */
4027 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
4029 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
4030 Use
->Element
[i
] = SidTypeUser
;
4035 /* Return unknown account */
4036 Use
->Element
[i
] = SidTypeUnknown
;
4040 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
4041 Status
= STATUS_SUCCESS
;
4043 if (NT_SUCCESS(Status
))
4045 if (MappedCount
== 0)
4046 Status
= STATUS_NONE_MAPPED
;
4047 else if (MappedCount
< Count
)
4048 Status
= STATUS_SOME_NOT_MAPPED
;
4052 if (Names
->Element
!= NULL
)
4054 for (i
= 0; i
< Count
; i
++)
4056 if (Names
->Element
[i
].Buffer
!= NULL
)
4057 midl_user_free(Names
->Element
[i
].Buffer
);
4060 midl_user_free(Names
->Element
);
4061 Names
->Element
= NULL
;
4066 if (Use
->Element
!= NULL
)
4068 midl_user_free(Use
->Element
);
4069 Use
->Element
= NULL
;
4075 RtlReleaseResource(&SampResource
);
4084 SamrOpenGroup(IN SAMPR_HANDLE DomainHandle
,
4085 IN ACCESS_MASK DesiredAccess
,
4086 IN
unsigned long GroupId
,
4087 OUT SAMPR_HANDLE
*GroupHandle
)
4089 PSAM_DB_OBJECT DomainObject
;
4090 PSAM_DB_OBJECT GroupObject
;
4094 TRACE("SamrOpenGroup(%p %lx %lx %p)\n",
4095 DomainHandle
, DesiredAccess
, GroupId
, GroupHandle
);
4097 /* Map generic access rights */
4098 RtlMapGenericMask(&DesiredAccess
,
4101 RtlAcquireResourceShared(&SampResource
,
4104 /* Validate the domain handle */
4105 Status
= SampValidateDbObject(DomainHandle
,
4109 if (!NT_SUCCESS(Status
))
4111 TRACE("failed with status 0x%08lx\n", Status
);
4115 /* Convert the RID into a string (hex) */
4116 swprintf(szRid
, L
"%08lX", GroupId
);
4118 /* Create the group object */
4119 Status
= SampOpenDbObject(DomainObject
,
4126 if (!NT_SUCCESS(Status
))
4128 TRACE("failed with status 0x%08lx\n", Status
);
4132 *GroupHandle
= (SAMPR_HANDLE
)GroupObject
;
4135 RtlReleaseResource(&SampResource
);
4142 SampQueryGroupGeneral(PSAM_DB_OBJECT GroupObject
,
4143 PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
4145 PSAMPR_GROUP_INFO_BUFFER InfoBuffer
= NULL
;
4146 SAM_GROUP_FIXED_DATA FixedData
;
4147 ULONG MembersLength
= 0;
4153 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_GROUP_INFO_BUFFER
));
4154 if (InfoBuffer
== NULL
)
4155 return STATUS_INSUFFICIENT_RESOURCES
;
4157 Status
= SampGetObjectAttributeString(GroupObject
,
4159 &InfoBuffer
->General
.Name
);
4160 if (!NT_SUCCESS(Status
))
4162 TRACE("Status 0x%08lx\n", Status
);
4166 Status
= SampGetObjectAttributeString(GroupObject
,
4168 &InfoBuffer
->General
.AdminComment
);
4169 if (!NT_SUCCESS(Status
))
4171 TRACE("Status 0x%08lx\n", Status
);
4175 Length
= sizeof(SAM_GROUP_FIXED_DATA
);
4176 Status
= SampGetObjectAttribute(GroupObject
,
4181 if (!NT_SUCCESS(Status
))
4184 InfoBuffer
->General
.Attributes
= FixedData
.Attributes
;
4186 Status
= SampGetObjectAttribute(GroupObject
,
4191 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
4194 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
4195 InfoBuffer
->General
.MemberCount
= 0;
4197 InfoBuffer
->General
.MemberCount
= MembersLength
/ sizeof(ULONG
);
4199 *Buffer
= InfoBuffer
;
4202 if (!NT_SUCCESS(Status
))
4204 if (InfoBuffer
!= NULL
)
4206 if (InfoBuffer
->General
.Name
.Buffer
!= NULL
)
4207 midl_user_free(InfoBuffer
->General
.Name
.Buffer
);
4209 if (InfoBuffer
->General
.AdminComment
.Buffer
!= NULL
)
4210 midl_user_free(InfoBuffer
->General
.AdminComment
.Buffer
);
4212 midl_user_free(InfoBuffer
);
4221 SampQueryGroupName(PSAM_DB_OBJECT GroupObject
,
4222 PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
4224 PSAMPR_GROUP_INFO_BUFFER InfoBuffer
= NULL
;
4229 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_GROUP_INFO_BUFFER
));
4230 if (InfoBuffer
== NULL
)
4231 return STATUS_INSUFFICIENT_RESOURCES
;
4233 Status
= SampGetObjectAttributeString(GroupObject
,
4235 &InfoBuffer
->Name
.Name
);
4236 if (!NT_SUCCESS(Status
))
4238 TRACE("Status 0x%08lx\n", Status
);
4242 *Buffer
= InfoBuffer
;
4245 if (!NT_SUCCESS(Status
))
4247 if (InfoBuffer
!= NULL
)
4249 if (InfoBuffer
->Name
.Name
.Buffer
!= NULL
)
4250 midl_user_free(InfoBuffer
->Name
.Name
.Buffer
);
4252 midl_user_free(InfoBuffer
);
4261 SampQueryGroupAttribute(PSAM_DB_OBJECT GroupObject
,
4262 PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
4264 PSAMPR_GROUP_INFO_BUFFER InfoBuffer
= NULL
;
4265 SAM_GROUP_FIXED_DATA FixedData
;
4271 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_GROUP_INFO_BUFFER
));
4272 if (InfoBuffer
== NULL
)
4273 return STATUS_INSUFFICIENT_RESOURCES
;
4275 Length
= sizeof(SAM_GROUP_FIXED_DATA
);
4276 Status
= SampGetObjectAttribute(GroupObject
,
4281 if (!NT_SUCCESS(Status
))
4284 InfoBuffer
->Attribute
.Attributes
= FixedData
.Attributes
;
4286 *Buffer
= InfoBuffer
;
4289 if (!NT_SUCCESS(Status
))
4291 if (InfoBuffer
!= NULL
)
4293 midl_user_free(InfoBuffer
);
4302 SampQueryGroupAdminComment(PSAM_DB_OBJECT GroupObject
,
4303 PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
4305 PSAMPR_GROUP_INFO_BUFFER InfoBuffer
= NULL
;
4310 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_GROUP_INFO_BUFFER
));
4311 if (InfoBuffer
== NULL
)
4312 return STATUS_INSUFFICIENT_RESOURCES
;
4314 Status
= SampGetObjectAttributeString(GroupObject
,
4316 &InfoBuffer
->AdminComment
.AdminComment
);
4317 if (!NT_SUCCESS(Status
))
4319 TRACE("Status 0x%08lx\n", Status
);
4323 *Buffer
= InfoBuffer
;
4326 if (!NT_SUCCESS(Status
))
4328 if (InfoBuffer
!= NULL
)
4330 if (InfoBuffer
->AdminComment
.AdminComment
.Buffer
!= NULL
)
4331 midl_user_free(InfoBuffer
->AdminComment
.AdminComment
.Buffer
);
4333 midl_user_free(InfoBuffer
);
4344 SamrQueryInformationGroup(IN SAMPR_HANDLE GroupHandle
,
4345 IN GROUP_INFORMATION_CLASS GroupInformationClass
,
4346 OUT PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
4348 PSAM_DB_OBJECT GroupObject
;
4351 TRACE("SamrQueryInformationGroup(%p %lu %p)\n",
4352 GroupHandle
, GroupInformationClass
, Buffer
);
4354 RtlAcquireResourceShared(&SampResource
,
4357 /* Validate the group handle */
4358 Status
= SampValidateDbObject(GroupHandle
,
4360 GROUP_READ_INFORMATION
,
4362 if (!NT_SUCCESS(Status
))
4365 switch (GroupInformationClass
)
4367 case GroupGeneralInformation
:
4368 Status
= SampQueryGroupGeneral(GroupObject
,
4372 case GroupNameInformation
:
4373 Status
= SampQueryGroupName(GroupObject
,
4377 case GroupAttributeInformation
:
4378 Status
= SampQueryGroupAttribute(GroupObject
,
4382 case GroupAdminCommentInformation
:
4383 Status
= SampQueryGroupAdminComment(GroupObject
,
4388 Status
= STATUS_INVALID_INFO_CLASS
;
4393 RtlReleaseResource(&SampResource
);
4400 SampSetGroupName(PSAM_DB_OBJECT GroupObject
,
4401 PSAMPR_GROUP_INFO_BUFFER Buffer
)
4403 UNICODE_STRING OldGroupName
= {0, 0, NULL
};
4404 UNICODE_STRING NewGroupName
;
4407 Status
= SampGetObjectAttributeString(GroupObject
,
4409 (PRPC_UNICODE_STRING
)&OldGroupName
);
4410 if (!NT_SUCCESS(Status
))
4412 TRACE("SampGetObjectAttributeString failed (Status 0x%08lx)\n", Status
);
4416 /* Check the new account name */
4417 Status
= SampCheckAccountName(&Buffer
->Name
.Name
, 256);
4418 if (!NT_SUCCESS(Status
))
4420 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
4424 NewGroupName
.Length
= Buffer
->Name
.Name
.Length
;
4425 NewGroupName
.MaximumLength
= Buffer
->Name
.Name
.MaximumLength
;
4426 NewGroupName
.Buffer
= Buffer
->Name
.Name
.Buffer
;
4428 if (!RtlEqualUnicodeString(&OldGroupName
, &NewGroupName
, TRUE
))
4430 Status
= SampCheckAccountNameInDomain(GroupObject
->ParentObject
,
4431 NewGroupName
.Buffer
);
4432 if (!NT_SUCCESS(Status
))
4434 TRACE("Group name \'%S\' already exists in domain (Status 0x%08lx)\n",
4435 NewGroupName
.Buffer
, Status
);
4440 Status
= SampSetAccountNameInDomain(GroupObject
->ParentObject
,
4442 NewGroupName
.Buffer
,
4443 GroupObject
->RelativeId
);
4444 if (!NT_SUCCESS(Status
))
4446 TRACE("SampSetAccountNameInDomain failed (Status 0x%08lx)\n", Status
);
4450 Status
= SampRemoveAccountNameFromDomain(GroupObject
->ParentObject
,
4452 OldGroupName
.Buffer
);
4453 if (!NT_SUCCESS(Status
))
4455 TRACE("SampRemoveAccountNameFromDomain failed (Status 0x%08lx)\n", Status
);
4459 Status
= SampSetObjectAttributeString(GroupObject
,
4461 (PRPC_UNICODE_STRING
)&NewGroupName
);
4462 if (!NT_SUCCESS(Status
))
4464 TRACE("SampSetObjectAttribute failed (Status 0x%08lx)\n", Status
);
4468 if (OldGroupName
.Buffer
!= NULL
)
4469 midl_user_free(OldGroupName
.Buffer
);
4476 SampSetGroupAttribute(PSAM_DB_OBJECT GroupObject
,
4477 PSAMPR_GROUP_INFO_BUFFER Buffer
)
4479 SAM_GROUP_FIXED_DATA FixedData
;
4483 Length
= sizeof(SAM_GROUP_FIXED_DATA
);
4484 Status
= SampGetObjectAttribute(GroupObject
,
4489 if (!NT_SUCCESS(Status
))
4492 FixedData
.Attributes
= Buffer
->Attribute
.Attributes
;
4494 Status
= SampSetObjectAttribute(GroupObject
,
4508 SamrSetInformationGroup(IN SAMPR_HANDLE GroupHandle
,
4509 IN GROUP_INFORMATION_CLASS GroupInformationClass
,
4510 IN PSAMPR_GROUP_INFO_BUFFER Buffer
)
4512 PSAM_DB_OBJECT GroupObject
;
4515 TRACE("SamrSetInformationGroup(%p %lu %p)\n",
4516 GroupHandle
, GroupInformationClass
, Buffer
);
4518 RtlAcquireResourceExclusive(&SampResource
,
4521 /* Validate the group handle */
4522 Status
= SampValidateDbObject(GroupHandle
,
4524 GROUP_WRITE_ACCOUNT
,
4526 if (!NT_SUCCESS(Status
))
4529 switch (GroupInformationClass
)
4531 case GroupNameInformation
:
4532 Status
= SampSetGroupName(GroupObject
,
4536 case GroupAttributeInformation
:
4537 Status
= SampSetGroupAttribute(GroupObject
,
4541 case GroupAdminCommentInformation
:
4542 Status
= SampSetObjectAttributeString(GroupObject
,
4544 &Buffer
->AdminComment
.AdminComment
);
4548 Status
= STATUS_INVALID_INFO_CLASS
;
4553 RtlReleaseResource(&SampResource
);
4562 SamrAddMemberToGroup(IN SAMPR_HANDLE GroupHandle
,
4563 IN
unsigned long MemberId
,
4564 IN
unsigned long Attributes
)
4566 PSAM_DB_OBJECT GroupObject
;
4567 PSAM_DB_OBJECT UserObject
= NULL
;
4570 TRACE("(%p %lu %lx)\n",
4571 GroupHandle
, MemberId
, Attributes
);
4573 RtlAcquireResourceExclusive(&SampResource
,
4576 /* Validate the group handle */
4577 Status
= SampValidateDbObject(GroupHandle
,
4581 if (!NT_SUCCESS(Status
))
4584 /* Open the user object in the same domain */
4585 Status
= SampOpenUserObject(GroupObject
->ParentObject
,
4589 if (!NT_SUCCESS(Status
))
4591 TRACE("SampOpenUserObject() failed (Status 0x%08lx)\n", Status
);
4595 /* Add group membership to the user object */
4596 Status
= SampAddGroupMembershipToUser(UserObject
,
4597 GroupObject
->RelativeId
,
4599 if (!NT_SUCCESS(Status
))
4601 TRACE("SampAddGroupMembershipToUser() failed (Status 0x%08lx)\n", Status
);
4605 /* Add the member to the group object */
4606 Status
= SampAddMemberToGroup(GroupObject
,
4608 if (!NT_SUCCESS(Status
))
4610 TRACE("SampAddMemberToGroup() failed (Status 0x%08lx)\n", Status
);
4615 SampCloseDbObject(UserObject
);
4617 RtlReleaseResource(&SampResource
);
4626 SamrDeleteGroup(IN OUT SAMPR_HANDLE
*GroupHandle
)
4628 PSAM_DB_OBJECT GroupObject
;
4632 TRACE("(%p)\n", GroupHandle
);
4634 RtlAcquireResourceExclusive(&SampResource
,
4637 /* Validate the group handle */
4638 Status
= SampValidateDbObject(*GroupHandle
,
4642 if (!NT_SUCCESS(Status
))
4644 TRACE("SampValidateDbObject() failed (Status 0x%08lx)\n", Status
);
4648 /* Fail, if the group is built-in */
4649 if (GroupObject
->RelativeId
< 1000)
4651 TRACE("You can not delete a special account!\n");
4652 Status
= STATUS_SPECIAL_ACCOUNT
;
4656 /* Get the length of the Members attribute */
4657 SampGetObjectAttribute(GroupObject
,
4663 /* Fail, if the group has members */
4666 TRACE("There are still members in the group!\n");
4667 Status
= STATUS_MEMBER_IN_GROUP
;
4671 /* FIXME: Remove the group from all aliases */
4673 /* Delete the group from the database */
4674 Status
= SampDeleteAccountDbObject(GroupObject
);
4675 if (!NT_SUCCESS(Status
))
4677 TRACE("SampDeleteAccountDbObject() failed (Status 0x%08lx)\n", Status
);
4681 /* Invalidate the handle */
4682 *GroupHandle
= NULL
;
4685 RtlReleaseResource(&SampResource
);
4694 SamrRemoveMemberFromGroup(IN SAMPR_HANDLE GroupHandle
,
4695 IN
unsigned long MemberId
)
4697 PSAM_DB_OBJECT GroupObject
;
4698 PSAM_DB_OBJECT UserObject
= NULL
;
4702 GroupHandle
, MemberId
);
4704 RtlAcquireResourceExclusive(&SampResource
,
4707 /* Validate the group handle */
4708 Status
= SampValidateDbObject(GroupHandle
,
4710 GROUP_REMOVE_MEMBER
,
4712 if (!NT_SUCCESS(Status
))
4715 /* Open the user object in the same domain */
4716 Status
= SampOpenUserObject(GroupObject
->ParentObject
,
4720 if (!NT_SUCCESS(Status
))
4722 ERR("SampOpenUserObject() failed (Status 0x%08lx)\n", Status
);
4726 /* Remove group membership from the user object */
4727 Status
= SampRemoveGroupMembershipFromUser(UserObject
,
4728 GroupObject
->RelativeId
);
4729 if (!NT_SUCCESS(Status
))
4731 ERR("SampAddGroupMembershipToUser() failed (Status 0x%08lx)\n", Status
);
4735 /* Remove the member from the group object */
4736 Status
= SampRemoveMemberFromGroup(GroupObject
,
4738 if (!NT_SUCCESS(Status
))
4740 ERR("SampRemoveMemberFromGroup() failed (Status 0x%08lx)\n", Status
);
4745 SampCloseDbObject(UserObject
);
4747 RtlReleaseResource(&SampResource
);
4756 SamrGetMembersInGroup(IN SAMPR_HANDLE GroupHandle
,
4757 OUT PSAMPR_GET_MEMBERS_BUFFER
*Members
)
4759 PSAMPR_GET_MEMBERS_BUFFER MembersBuffer
= NULL
;
4760 PSAM_DB_OBJECT GroupObject
;
4765 RtlAcquireResourceShared(&SampResource
,
4768 /* Validate the group handle */
4769 Status
= SampValidateDbObject(GroupHandle
,
4773 if (!NT_SUCCESS(Status
))
4776 MembersBuffer
= midl_user_allocate(sizeof(SAMPR_GET_MEMBERS_BUFFER
));
4777 if (MembersBuffer
== NULL
)
4779 Status
= STATUS_INSUFFICIENT_RESOURCES
;
4783 SampGetObjectAttribute(GroupObject
,
4791 MembersBuffer
->MemberCount
= 0;
4792 MembersBuffer
->Members
= NULL
;
4793 MembersBuffer
->Attributes
= NULL
;
4795 *Members
= MembersBuffer
;
4797 Status
= STATUS_SUCCESS
;
4801 MembersBuffer
->Members
= midl_user_allocate(Length
);
4802 if (MembersBuffer
->Members
== NULL
)
4804 Status
= STATUS_INSUFFICIENT_RESOURCES
;
4808 MembersBuffer
->Attributes
= midl_user_allocate(Length
);
4809 if (MembersBuffer
->Attributes
== NULL
)
4811 Status
= STATUS_INSUFFICIENT_RESOURCES
;
4815 Status
= SampGetObjectAttribute(GroupObject
,
4818 MembersBuffer
->Members
,
4820 if (!NT_SUCCESS(Status
))
4822 TRACE("SampGetObjectAttributes() failed (Status 0x%08lx)\n", Status
);
4826 MembersBuffer
->MemberCount
= Length
/ sizeof(ULONG
);
4828 for (i
= 0; i
< MembersBuffer
->MemberCount
; i
++)
4830 Status
= SampGetUserGroupAttributes(GroupObject
->ParentObject
,
4831 MembersBuffer
->Members
[i
],
4832 GroupObject
->RelativeId
,
4833 &(MembersBuffer
->Attributes
[i
]));
4834 if (!NT_SUCCESS(Status
))
4836 TRACE("SampGetUserGroupAttributes() failed (Status 0x%08lx)\n", Status
);
4841 *Members
= MembersBuffer
;
4844 if (!NT_SUCCESS(Status
))
4846 if (MembersBuffer
!= NULL
)
4848 if (MembersBuffer
->Members
!= NULL
)
4849 midl_user_free(MembersBuffer
->Members
);
4851 if (MembersBuffer
->Attributes
!= NULL
)
4852 midl_user_free(MembersBuffer
->Attributes
);
4854 midl_user_free(MembersBuffer
);
4858 RtlReleaseResource(&SampResource
);
4867 SamrSetMemberAttributesOfGroup(IN SAMPR_HANDLE GroupHandle
,
4868 IN
unsigned long MemberId
,
4869 IN
unsigned long Attributes
)
4871 PSAM_DB_OBJECT GroupObject
;
4874 RtlAcquireResourceExclusive(&SampResource
,
4877 /* Validate the group handle */
4878 Status
= SampValidateDbObject(GroupHandle
,
4882 if (!NT_SUCCESS(Status
))
4884 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
4888 Status
= SampSetUserGroupAttributes(GroupObject
->ParentObject
,
4890 GroupObject
->RelativeId
,
4892 if (!NT_SUCCESS(Status
))
4894 TRACE("SampSetUserGroupAttributes failed with status 0x%08lx\n", Status
);
4898 RtlReleaseResource(&SampResource
);
4907 SamrOpenAlias(IN SAMPR_HANDLE DomainHandle
,
4908 IN ACCESS_MASK DesiredAccess
,
4910 OUT SAMPR_HANDLE
*AliasHandle
)
4912 PSAM_DB_OBJECT DomainObject
;
4913 PSAM_DB_OBJECT AliasObject
;
4917 TRACE("SamrOpenAlias(%p %lx %lx %p)\n",
4918 DomainHandle
, DesiredAccess
, AliasId
, AliasHandle
);
4920 /* Map generic access rights */
4921 RtlMapGenericMask(&DesiredAccess
,
4924 RtlAcquireResourceShared(&SampResource
,
4927 /* Validate the domain handle */
4928 Status
= SampValidateDbObject(DomainHandle
,
4932 if (!NT_SUCCESS(Status
))
4934 TRACE("failed with status 0x%08lx\n", Status
);
4938 /* Convert the RID into a string (hex) */
4939 swprintf(szRid
, L
"%08lX", AliasId
);
4941 /* Create the alias object */
4942 Status
= SampOpenDbObject(DomainObject
,
4949 if (!NT_SUCCESS(Status
))
4951 TRACE("failed with status 0x%08lx\n", Status
);
4955 *AliasHandle
= (SAMPR_HANDLE
)AliasObject
;
4958 RtlReleaseResource(&SampResource
);
4965 SampQueryAliasGeneral(PSAM_DB_OBJECT AliasObject
,
4966 PSAMPR_ALIAS_INFO_BUFFER
*Buffer
)
4968 PSAMPR_ALIAS_INFO_BUFFER InfoBuffer
= NULL
;
4969 HANDLE MembersKeyHandle
= NULL
;
4974 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_ALIAS_INFO_BUFFER
));
4975 if (InfoBuffer
== NULL
)
4976 return STATUS_INSUFFICIENT_RESOURCES
;
4978 Status
= SampGetObjectAttributeString(AliasObject
,
4980 &InfoBuffer
->General
.Name
);
4981 if (!NT_SUCCESS(Status
))
4983 TRACE("Status 0x%08lx\n", Status
);
4987 Status
= SampGetObjectAttributeString(AliasObject
,
4989 &InfoBuffer
->General
.AdminComment
);
4990 if (!NT_SUCCESS(Status
))
4992 TRACE("Status 0x%08lx\n", Status
);
4996 /* Open the Members subkey */
4997 Status
= SampRegOpenKey(AliasObject
->KeyHandle
,
5001 if (NT_SUCCESS(Status
))
5003 /* Retrieve the number of members of the alias */
5004 Status
= SampRegQueryKeyInfo(MembersKeyHandle
,
5006 &InfoBuffer
->General
.MemberCount
);
5007 if (!NT_SUCCESS(Status
))
5009 TRACE("Status 0x%08lx\n", Status
);
5013 else if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
5015 InfoBuffer
->General
.MemberCount
= 0;
5016 Status
= STATUS_SUCCESS
;
5020 TRACE("Status 0x%08lx\n", Status
);
5024 *Buffer
= InfoBuffer
;
5027 SampRegCloseKey(&MembersKeyHandle
);
5029 if (!NT_SUCCESS(Status
))
5031 if (InfoBuffer
!= NULL
)
5033 if (InfoBuffer
->General
.Name
.Buffer
!= NULL
)
5034 midl_user_free(InfoBuffer
->General
.Name
.Buffer
);
5036 if (InfoBuffer
->General
.AdminComment
.Buffer
!= NULL
)
5037 midl_user_free(InfoBuffer
->General
.AdminComment
.Buffer
);
5039 midl_user_free(InfoBuffer
);
5048 SampQueryAliasName(PSAM_DB_OBJECT AliasObject
,
5049 PSAMPR_ALIAS_INFO_BUFFER
*Buffer
)
5051 PSAMPR_ALIAS_INFO_BUFFER InfoBuffer
= NULL
;
5056 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_ALIAS_INFO_BUFFER
));
5057 if (InfoBuffer
== NULL
)
5058 return STATUS_INSUFFICIENT_RESOURCES
;
5060 Status
= SampGetObjectAttributeString(AliasObject
,
5062 &InfoBuffer
->Name
.Name
);
5063 if (!NT_SUCCESS(Status
))
5065 TRACE("Status 0x%08lx\n", Status
);
5069 *Buffer
= InfoBuffer
;
5072 if (!NT_SUCCESS(Status
))
5074 if (InfoBuffer
!= NULL
)
5076 if (InfoBuffer
->Name
.Name
.Buffer
!= NULL
)
5077 midl_user_free(InfoBuffer
->Name
.Name
.Buffer
);
5079 midl_user_free(InfoBuffer
);
5088 SampQueryAliasAdminComment(PSAM_DB_OBJECT AliasObject
,
5089 PSAMPR_ALIAS_INFO_BUFFER
*Buffer
)
5091 PSAMPR_ALIAS_INFO_BUFFER InfoBuffer
= NULL
;
5096 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_ALIAS_INFO_BUFFER
));
5097 if (InfoBuffer
== NULL
)
5098 return STATUS_INSUFFICIENT_RESOURCES
;
5100 Status
= SampGetObjectAttributeString(AliasObject
,
5102 &InfoBuffer
->AdminComment
.AdminComment
);
5103 if (!NT_SUCCESS(Status
))
5105 TRACE("Status 0x%08lx\n", Status
);
5109 *Buffer
= InfoBuffer
;
5112 if (!NT_SUCCESS(Status
))
5114 if (InfoBuffer
!= NULL
)
5116 if (InfoBuffer
->AdminComment
.AdminComment
.Buffer
!= NULL
)
5117 midl_user_free(InfoBuffer
->AdminComment
.AdminComment
.Buffer
);
5119 midl_user_free(InfoBuffer
);
5130 SamrQueryInformationAlias(IN SAMPR_HANDLE AliasHandle
,
5131 IN ALIAS_INFORMATION_CLASS AliasInformationClass
,
5132 OUT PSAMPR_ALIAS_INFO_BUFFER
*Buffer
)
5134 PSAM_DB_OBJECT AliasObject
;
5137 TRACE("SamrQueryInformationAlias(%p %lu %p)\n",
5138 AliasHandle
, AliasInformationClass
, Buffer
);
5140 RtlAcquireResourceShared(&SampResource
,
5143 /* Validate the alias handle */
5144 Status
= SampValidateDbObject(AliasHandle
,
5146 ALIAS_READ_INFORMATION
,
5148 if (!NT_SUCCESS(Status
))
5151 switch (AliasInformationClass
)
5153 case AliasGeneralInformation
:
5154 Status
= SampQueryAliasGeneral(AliasObject
,
5158 case AliasNameInformation
:
5159 Status
= SampQueryAliasName(AliasObject
,
5163 case AliasAdminCommentInformation
:
5164 Status
= SampQueryAliasAdminComment(AliasObject
,
5169 Status
= STATUS_INVALID_INFO_CLASS
;
5174 RtlReleaseResource(&SampResource
);
5181 SampSetAliasName(PSAM_DB_OBJECT AliasObject
,
5182 PSAMPR_ALIAS_INFO_BUFFER Buffer
)
5184 UNICODE_STRING OldAliasName
= {0, 0, NULL
};
5185 UNICODE_STRING NewAliasName
;
5188 Status
= SampGetObjectAttributeString(AliasObject
,
5190 (PRPC_UNICODE_STRING
)&OldAliasName
);
5191 if (!NT_SUCCESS(Status
))
5193 TRACE("SampGetObjectAttributeString failed (Status 0x%08lx)\n", Status
);
5197 /* Check the new account name */
5198 Status
= SampCheckAccountName(&Buffer
->Name
.Name
, 256);
5199 if (!NT_SUCCESS(Status
))
5201 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
5205 NewAliasName
.Length
= Buffer
->Name
.Name
.Length
;
5206 NewAliasName
.MaximumLength
= Buffer
->Name
.Name
.MaximumLength
;
5207 NewAliasName
.Buffer
= Buffer
->Name
.Name
.Buffer
;
5209 if (!RtlEqualUnicodeString(&OldAliasName
, &NewAliasName
, TRUE
))
5211 Status
= SampCheckAccountNameInDomain(AliasObject
->ParentObject
,
5212 NewAliasName
.Buffer
);
5213 if (!NT_SUCCESS(Status
))
5215 TRACE("Alias name \'%S\' already exists in domain (Status 0x%08lx)\n",
5216 NewAliasName
.Buffer
, Status
);
5221 Status
= SampSetAccountNameInDomain(AliasObject
->ParentObject
,
5223 NewAliasName
.Buffer
,
5224 AliasObject
->RelativeId
);
5225 if (!NT_SUCCESS(Status
))
5227 TRACE("SampSetAccountNameInDomain failed (Status 0x%08lx)\n", Status
);
5231 Status
= SampRemoveAccountNameFromDomain(AliasObject
->ParentObject
,
5233 OldAliasName
.Buffer
);
5234 if (!NT_SUCCESS(Status
))
5236 TRACE("SampRemoveAccountNameFromDomain failed (Status 0x%08lx)\n", Status
);
5240 Status
= SampSetObjectAttributeString(AliasObject
,
5242 (PRPC_UNICODE_STRING
)&NewAliasName
);
5243 if (!NT_SUCCESS(Status
))
5245 TRACE("SampSetObjectAttribute failed (Status 0x%08lx)\n", Status
);
5249 if (OldAliasName
.Buffer
!= NULL
)
5250 midl_user_free(OldAliasName
.Buffer
);
5259 SamrSetInformationAlias(IN SAMPR_HANDLE AliasHandle
,
5260 IN ALIAS_INFORMATION_CLASS AliasInformationClass
,
5261 IN PSAMPR_ALIAS_INFO_BUFFER Buffer
)
5263 PSAM_DB_OBJECT AliasObject
;
5266 TRACE("SamrSetInformationAlias(%p %lu %p)\n",
5267 AliasHandle
, AliasInformationClass
, Buffer
);
5269 RtlAcquireResourceExclusive(&SampResource
,
5272 /* Validate the alias handle */
5273 Status
= SampValidateDbObject(AliasHandle
,
5275 ALIAS_WRITE_ACCOUNT
,
5277 if (!NT_SUCCESS(Status
))
5280 switch (AliasInformationClass
)
5282 case AliasNameInformation
:
5283 Status
= SampSetAliasName(AliasObject
,
5287 case AliasAdminCommentInformation
:
5288 Status
= SampSetObjectAttributeString(AliasObject
,
5290 &Buffer
->AdminComment
.AdminComment
);
5294 Status
= STATUS_INVALID_INFO_CLASS
;
5299 RtlReleaseResource(&SampResource
);
5308 SamrDeleteAlias(IN OUT SAMPR_HANDLE
*AliasHandle
)
5310 PSAM_DB_OBJECT AliasObject
;
5313 RtlAcquireResourceExclusive(&SampResource
,
5316 /* Validate the alias handle */
5317 Status
= SampValidateDbObject(*AliasHandle
,
5321 if (!NT_SUCCESS(Status
))
5323 TRACE("SampValidateDbObject failed (Status 0x%08lx)\n", Status
);
5327 /* Fail, if the alias is built-in */
5328 if (AliasObject
->RelativeId
< 1000)
5330 TRACE("You can not delete a special account!\n");
5331 Status
= STATUS_SPECIAL_ACCOUNT
;
5335 /* Remove all members from the alias */
5336 Status
= SampRemoveAllMembersFromAlias(AliasObject
);
5337 if (!NT_SUCCESS(Status
))
5339 TRACE("SampRemoveAllMembersFromAlias() failed (Status 0x%08lx)\n", Status
);
5343 /* Delete the alias from the database */
5344 Status
= SampDeleteAccountDbObject(AliasObject
);
5345 if (!NT_SUCCESS(Status
))
5347 TRACE("SampDeleteAccountDbObject() failed (Status 0x%08lx)\n", Status
);
5351 /* Invalidate the handle */
5352 *AliasHandle
= NULL
;
5355 RtlReleaseResource(&SampResource
);
5364 SamrAddMemberToAlias(IN SAMPR_HANDLE AliasHandle
,
5365 IN PRPC_SID MemberId
)
5367 PSAM_DB_OBJECT AliasObject
;
5370 TRACE("(%p %p)\n", AliasHandle
, MemberId
);
5372 RtlAcquireResourceExclusive(&SampResource
,
5375 /* Validate the alias handle */
5376 Status
= SampValidateDbObject(AliasHandle
,
5380 if (!NT_SUCCESS(Status
))
5382 TRACE("failed with status 0x%08lx\n", Status
);
5386 Status
= SampAddMemberToAlias(AliasObject
,
5388 if (!NT_SUCCESS(Status
))
5390 TRACE("failed with status 0x%08lx\n", Status
);
5394 RtlReleaseResource(&SampResource
);
5403 SamrRemoveMemberFromAlias(IN SAMPR_HANDLE AliasHandle
,
5404 IN PRPC_SID MemberId
)
5406 PSAM_DB_OBJECT AliasObject
;
5409 TRACE("(%p %p)\n", AliasHandle
, MemberId
);
5411 RtlAcquireResourceExclusive(&SampResource
,
5414 /* Validate the alias handle */
5415 Status
= SampValidateDbObject(AliasHandle
,
5417 ALIAS_REMOVE_MEMBER
,
5419 if (!NT_SUCCESS(Status
))
5421 TRACE("failed with status 0x%08lx\n", Status
);
5425 Status
= SampRemoveMemberFromAlias(AliasObject
,
5427 if (!NT_SUCCESS(Status
))
5429 TRACE("failed with status 0x%08lx\n", Status
);
5433 RtlReleaseResource(&SampResource
);
5442 SamrGetMembersInAlias(IN SAMPR_HANDLE AliasHandle
,
5443 OUT PSAMPR_PSID_ARRAY_OUT Members
)
5445 PSAM_DB_OBJECT AliasObject
;
5446 PSAMPR_SID_INFORMATION MemberArray
= NULL
;
5447 ULONG MemberCount
= 0;
5451 TRACE("SamrGetMembersInAlias(%p %p %p)\n",
5452 AliasHandle
, Members
);
5454 RtlAcquireResourceShared(&SampResource
,
5457 /* Validate the alias handle */
5458 Status
= SampValidateDbObject(AliasHandle
,
5462 if (!NT_SUCCESS(Status
))
5464 ERR("failed with status 0x%08lx\n", Status
);
5468 Status
= SampGetMembersInAlias(AliasObject
,
5472 /* Return the number of members and the member array */
5473 if (NT_SUCCESS(Status
))
5475 Members
->Count
= MemberCount
;
5476 Members
->Sids
= MemberArray
;
5480 /* Clean up the members array and the SID buffers if something failed */
5481 if (!NT_SUCCESS(Status
))
5483 if (MemberArray
!= NULL
)
5485 for (Index
= 0; Index
< MemberCount
; Index
++)
5487 if (MemberArray
[Index
].SidPointer
!= NULL
)
5488 midl_user_free(MemberArray
[Index
].SidPointer
);
5491 midl_user_free(MemberArray
);
5495 RtlReleaseResource(&SampResource
);
5504 SamrOpenUser(IN SAMPR_HANDLE DomainHandle
,
5505 IN ACCESS_MASK DesiredAccess
,
5506 IN
unsigned long UserId
,
5507 OUT SAMPR_HANDLE
*UserHandle
)
5509 PSAM_DB_OBJECT DomainObject
;
5510 PSAM_DB_OBJECT UserObject
;
5514 TRACE("SamrOpenUser(%p %lx %lx %p)\n",
5515 DomainHandle
, DesiredAccess
, UserId
, UserHandle
);
5517 /* Map generic access rights */
5518 RtlMapGenericMask(&DesiredAccess
,
5521 RtlAcquireResourceShared(&SampResource
,
5524 /* Validate the domain handle */
5525 Status
= SampValidateDbObject(DomainHandle
,
5529 if (!NT_SUCCESS(Status
))
5531 TRACE("failed with status 0x%08lx\n", Status
);
5535 /* Convert the RID into a string (hex) */
5536 swprintf(szRid
, L
"%08lX", UserId
);
5538 /* Create the user object */
5539 Status
= SampOpenDbObject(DomainObject
,
5546 if (!NT_SUCCESS(Status
))
5548 TRACE("failed with status 0x%08lx\n", Status
);
5552 *UserHandle
= (SAMPR_HANDLE
)UserObject
;
5555 RtlReleaseResource(&SampResource
);
5564 SamrDeleteUser(IN OUT SAMPR_HANDLE
*UserHandle
)
5566 PSAM_DB_OBJECT UserObject
;
5569 TRACE("(%p)\n", UserHandle
);
5571 RtlAcquireResourceExclusive(&SampResource
,
5574 /* Validate the user handle */
5575 Status
= SampValidateDbObject(*UserHandle
,
5579 if (!NT_SUCCESS(Status
))
5581 TRACE("SampValidateDbObject() failed (Status 0x%08lx)\n", Status
);
5585 /* Fail, if the user is built-in */
5586 if (UserObject
->RelativeId
< 1000)
5588 TRACE("You can not delete a special account!\n");
5589 Status
= STATUS_SPECIAL_ACCOUNT
;
5593 /* Remove the user from all groups */
5594 Status
= SampRemoveUserFromAllGroups(UserObject
);
5595 if (!NT_SUCCESS(Status
))
5597 TRACE("SampRemoveUserFromAllGroups() failed (Status 0x%08lx)\n", Status
);
5601 /* Remove the user from all aliases */
5602 Status
= SampRemoveUserFromAllAliases(UserObject
);
5603 if (!NT_SUCCESS(Status
))
5605 TRACE("SampRemoveUserFromAllAliases() failed (Status 0x%08lx)\n", Status
);
5609 /* Delete the user from the database */
5610 Status
= SampDeleteAccountDbObject(UserObject
);
5611 if (!NT_SUCCESS(Status
))
5613 TRACE("SampDeleteAccountDbObject() failed (Status 0x%08lx)\n", Status
);
5617 /* Invalidate the handle */
5621 RtlReleaseResource(&SampResource
);
5629 SampQueryUserGeneral(PSAM_DB_OBJECT UserObject
,
5630 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5632 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5633 SAM_USER_FIXED_DATA FixedData
;
5639 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5640 if (InfoBuffer
== NULL
)
5641 return STATUS_INSUFFICIENT_RESOURCES
;
5643 Length
= sizeof(SAM_USER_FIXED_DATA
);
5644 Status
= SampGetObjectAttribute(UserObject
,
5649 if (!NT_SUCCESS(Status
))
5652 InfoBuffer
->General
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
5654 /* Get the Name string */
5655 Status
= SampGetObjectAttributeString(UserObject
,
5657 &InfoBuffer
->General
.UserName
);
5658 if (!NT_SUCCESS(Status
))
5660 TRACE("Status 0x%08lx\n", Status
);
5664 /* Get the FullName string */
5665 Status
= SampGetObjectAttributeString(UserObject
,
5667 &InfoBuffer
->General
.FullName
);
5668 if (!NT_SUCCESS(Status
))
5670 TRACE("Status 0x%08lx\n", Status
);
5674 /* Get the AdminComment string */
5675 Status
= SampGetObjectAttributeString(UserObject
,
5677 &InfoBuffer
->General
.AdminComment
);
5678 if (!NT_SUCCESS(Status
))
5680 TRACE("Status 0x%08lx\n", Status
);
5684 /* Get the UserComment string */
5685 Status
= SampGetObjectAttributeString(UserObject
,
5687 &InfoBuffer
->General
.UserComment
);
5688 if (!NT_SUCCESS(Status
))
5690 TRACE("Status 0x%08lx\n", Status
);
5694 *Buffer
= InfoBuffer
;
5697 if (!NT_SUCCESS(Status
))
5699 if (InfoBuffer
!= NULL
)
5701 if (InfoBuffer
->General
.UserName
.Buffer
!= NULL
)
5702 midl_user_free(InfoBuffer
->General
.UserName
.Buffer
);
5704 if (InfoBuffer
->General
.FullName
.Buffer
!= NULL
)
5705 midl_user_free(InfoBuffer
->General
.FullName
.Buffer
);
5707 if (InfoBuffer
->General
.AdminComment
.Buffer
!= NULL
)
5708 midl_user_free(InfoBuffer
->General
.AdminComment
.Buffer
);
5710 if (InfoBuffer
->General
.UserComment
.Buffer
!= NULL
)
5711 midl_user_free(InfoBuffer
->General
.UserComment
.Buffer
);
5713 midl_user_free(InfoBuffer
);
5723 SampQueryUserPreferences(PSAM_DB_OBJECT UserObject
,
5724 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5726 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5727 SAM_USER_FIXED_DATA FixedData
;
5733 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5734 if (InfoBuffer
== NULL
)
5735 return STATUS_INSUFFICIENT_RESOURCES
;
5737 Length
= sizeof(SAM_USER_FIXED_DATA
);
5738 Status
= SampGetObjectAttribute(UserObject
,
5743 if (!NT_SUCCESS(Status
))
5746 InfoBuffer
->Preferences
.CountryCode
= FixedData
.CountryCode
;
5747 InfoBuffer
->Preferences
.CodePage
= FixedData
.CodePage
;
5749 /* Get the UserComment string */
5750 Status
= SampGetObjectAttributeString(UserObject
,
5752 &InfoBuffer
->Preferences
.UserComment
);
5753 if (!NT_SUCCESS(Status
))
5755 TRACE("Status 0x%08lx\n", Status
);
5759 *Buffer
= InfoBuffer
;
5762 if (!NT_SUCCESS(Status
))
5764 if (InfoBuffer
!= NULL
)
5766 if (InfoBuffer
->Preferences
.UserComment
.Buffer
!= NULL
)
5767 midl_user_free(InfoBuffer
->Preferences
.UserComment
.Buffer
);
5769 midl_user_free(InfoBuffer
);
5779 SampQueryUserLogon(PSAM_DB_OBJECT UserObject
,
5780 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5782 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5783 SAM_DOMAIN_FIXED_DATA DomainFixedData
;
5784 SAM_USER_FIXED_DATA FixedData
;
5785 LARGE_INTEGER PasswordCanChange
;
5786 LARGE_INTEGER PasswordMustChange
;
5792 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5793 if (InfoBuffer
== NULL
)
5794 return STATUS_INSUFFICIENT_RESOURCES
;
5796 /* Get the fixed size domain data */
5797 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
5798 Status
= SampGetObjectAttribute(UserObject
->ParentObject
,
5801 (PVOID
)&DomainFixedData
,
5803 if (!NT_SUCCESS(Status
))
5806 /* Get the fixed size user data */
5807 Length
= sizeof(SAM_USER_FIXED_DATA
);
5808 Status
= SampGetObjectAttribute(UserObject
,
5813 if (!NT_SUCCESS(Status
))
5816 InfoBuffer
->Logon
.UserId
= FixedData
.UserId
;
5817 InfoBuffer
->Logon
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
5818 InfoBuffer
->Logon
.LastLogon
.LowPart
= FixedData
.LastLogon
.LowPart
;
5819 InfoBuffer
->Logon
.LastLogon
.HighPart
= FixedData
.LastLogon
.HighPart
;
5820 InfoBuffer
->Logon
.LastLogoff
.LowPart
= FixedData
.LastLogoff
.LowPart
;
5821 InfoBuffer
->Logon
.LastLogoff
.HighPart
= FixedData
.LastLogoff
.HighPart
;
5822 InfoBuffer
->Logon
.PasswordLastSet
.LowPart
= FixedData
.PasswordLastSet
.LowPart
;
5823 InfoBuffer
->Logon
.PasswordLastSet
.HighPart
= FixedData
.PasswordLastSet
.HighPart
;
5824 InfoBuffer
->Logon
.BadPasswordCount
= FixedData
.BadPasswordCount
;
5825 InfoBuffer
->Logon
.LogonCount
= FixedData
.LogonCount
;
5826 InfoBuffer
->Logon
.UserAccountControl
= FixedData
.UserAccountControl
;
5828 PasswordCanChange
= SampAddRelativeTimeToTime(FixedData
.PasswordLastSet
,
5829 DomainFixedData
.MinPasswordAge
);
5830 InfoBuffer
->Logon
.PasswordCanChange
.LowPart
= PasswordCanChange
.LowPart
;
5831 InfoBuffer
->Logon
.PasswordCanChange
.HighPart
= PasswordCanChange
.HighPart
;
5833 PasswordMustChange
= SampAddRelativeTimeToTime(FixedData
.PasswordLastSet
,
5834 DomainFixedData
.MaxPasswordAge
);
5835 InfoBuffer
->Logon
.PasswordMustChange
.LowPart
= PasswordMustChange
.LowPart
;
5836 InfoBuffer
->Logon
.PasswordMustChange
.HighPart
= PasswordMustChange
.HighPart
;
5838 /* Get the Name string */
5839 Status
= SampGetObjectAttributeString(UserObject
,
5841 &InfoBuffer
->Logon
.UserName
);
5842 if (!NT_SUCCESS(Status
))
5844 TRACE("Status 0x%08lx\n", Status
);
5848 /* Get the FullName string */
5849 Status
= SampGetObjectAttributeString(UserObject
,
5851 &InfoBuffer
->Logon
.FullName
);
5852 if (!NT_SUCCESS(Status
))
5854 TRACE("Status 0x%08lx\n", Status
);
5858 /* Get the HomeDirectory string */
5859 Status
= SampGetObjectAttributeString(UserObject
,
5861 &InfoBuffer
->Logon
.HomeDirectory
);
5862 if (!NT_SUCCESS(Status
))
5864 TRACE("Status 0x%08lx\n", Status
);
5868 /* Get the HomeDirectoryDrive string */
5869 Status
= SampGetObjectAttributeString(UserObject
,
5870 L
"HomeDirectoryDrive",
5871 &InfoBuffer
->Logon
.HomeDirectoryDrive
);
5872 if (!NT_SUCCESS(Status
))
5874 TRACE("Status 0x%08lx\n", Status
);
5878 /* Get the ScriptPath string */
5879 Status
= SampGetObjectAttributeString(UserObject
,
5881 &InfoBuffer
->Logon
.ScriptPath
);
5882 if (!NT_SUCCESS(Status
))
5884 TRACE("Status 0x%08lx\n", Status
);
5888 /* Get the ProfilePath string */
5889 Status
= SampGetObjectAttributeString(UserObject
,
5891 &InfoBuffer
->Logon
.ProfilePath
);
5892 if (!NT_SUCCESS(Status
))
5894 TRACE("Status 0x%08lx\n", Status
);
5898 /* Get the WorkStations string */
5899 Status
= SampGetObjectAttributeString(UserObject
,
5901 &InfoBuffer
->Logon
.WorkStations
);
5902 if (!NT_SUCCESS(Status
))
5904 TRACE("Status 0x%08lx\n", Status
);
5908 /* Get the LogonHours attribute */
5909 Status
= SampGetLogonHoursAttribute(UserObject
,
5910 &InfoBuffer
->Logon
.LogonHours
);
5911 if (!NT_SUCCESS(Status
))
5913 TRACE("Status 0x%08lx\n", Status
);
5917 *Buffer
= InfoBuffer
;
5920 if (!NT_SUCCESS(Status
))
5922 if (InfoBuffer
!= NULL
)
5924 if (InfoBuffer
->Logon
.UserName
.Buffer
!= NULL
)
5925 midl_user_free(InfoBuffer
->Logon
.UserName
.Buffer
);
5927 if (InfoBuffer
->Logon
.FullName
.Buffer
!= NULL
)
5928 midl_user_free(InfoBuffer
->Logon
.FullName
.Buffer
);
5930 if (InfoBuffer
->Logon
.HomeDirectory
.Buffer
!= NULL
)
5931 midl_user_free(InfoBuffer
->Logon
.HomeDirectory
.Buffer
);
5933 if (InfoBuffer
->Logon
.HomeDirectoryDrive
.Buffer
!= NULL
)
5934 midl_user_free(InfoBuffer
->Logon
.HomeDirectoryDrive
.Buffer
);
5936 if (InfoBuffer
->Logon
.ScriptPath
.Buffer
!= NULL
)
5937 midl_user_free(InfoBuffer
->Logon
.ScriptPath
.Buffer
);
5939 if (InfoBuffer
->Logon
.ProfilePath
.Buffer
!= NULL
)
5940 midl_user_free(InfoBuffer
->Logon
.ProfilePath
.Buffer
);
5942 if (InfoBuffer
->Logon
.WorkStations
.Buffer
!= NULL
)
5943 midl_user_free(InfoBuffer
->Logon
.WorkStations
.Buffer
);
5945 if (InfoBuffer
->Logon
.LogonHours
.LogonHours
!= NULL
)
5946 midl_user_free(InfoBuffer
->Logon
.LogonHours
.LogonHours
);
5948 midl_user_free(InfoBuffer
);
5958 SampQueryUserAccount(PSAM_DB_OBJECT UserObject
,
5959 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5961 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5962 SAM_USER_FIXED_DATA FixedData
;
5968 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5969 if (InfoBuffer
== NULL
)
5970 return STATUS_INSUFFICIENT_RESOURCES
;
5972 Length
= sizeof(SAM_USER_FIXED_DATA
);
5973 Status
= SampGetObjectAttribute(UserObject
,
5978 if (!NT_SUCCESS(Status
))
5981 InfoBuffer
->Account
.UserId
= FixedData
.UserId
;
5982 InfoBuffer
->Account
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
5983 InfoBuffer
->Account
.LastLogon
.LowPart
= FixedData
.LastLogon
.LowPart
;
5984 InfoBuffer
->Account
.LastLogon
.HighPart
= FixedData
.LastLogon
.HighPart
;
5985 InfoBuffer
->Account
.LastLogoff
.LowPart
= FixedData
.LastLogoff
.LowPart
;
5986 InfoBuffer
->Account
.LastLogoff
.HighPart
= FixedData
.LastLogoff
.HighPart
;
5987 InfoBuffer
->Account
.PasswordLastSet
.LowPart
= FixedData
.PasswordLastSet
.LowPart
;
5988 InfoBuffer
->Account
.PasswordLastSet
.HighPart
= FixedData
.PasswordLastSet
.HighPart
;
5989 InfoBuffer
->Account
.AccountExpires
.LowPart
= FixedData
.AccountExpires
.LowPart
;
5990 InfoBuffer
->Account
.AccountExpires
.HighPart
= FixedData
.AccountExpires
.HighPart
;
5991 InfoBuffer
->Account
.BadPasswordCount
= FixedData
.BadPasswordCount
;
5992 InfoBuffer
->Account
.LogonCount
= FixedData
.LogonCount
;
5993 InfoBuffer
->Account
.UserAccountControl
= FixedData
.UserAccountControl
;
5995 /* Get the Name string */
5996 Status
= SampGetObjectAttributeString(UserObject
,
5998 &InfoBuffer
->Account
.UserName
);
5999 if (!NT_SUCCESS(Status
))
6001 TRACE("Status 0x%08lx\n", Status
);
6005 /* Get the FullName string */
6006 Status
= SampGetObjectAttributeString(UserObject
,
6008 &InfoBuffer
->Account
.FullName
);
6009 if (!NT_SUCCESS(Status
))
6011 TRACE("Status 0x%08lx\n", Status
);
6015 /* Get the HomeDirectory string */
6016 Status
= SampGetObjectAttributeString(UserObject
,
6018 &InfoBuffer
->Account
.HomeDirectory
);
6019 if (!NT_SUCCESS(Status
))
6021 TRACE("Status 0x%08lx\n", Status
);
6025 /* Get the HomeDirectoryDrive string */
6026 Status
= SampGetObjectAttributeString(UserObject
,
6027 L
"HomeDirectoryDrive",
6028 &InfoBuffer
->Account
.HomeDirectoryDrive
);
6029 if (!NT_SUCCESS(Status
))
6031 TRACE("Status 0x%08lx\n", Status
);
6035 /* Get the ScriptPath string */
6036 Status
= SampGetObjectAttributeString(UserObject
,
6038 &InfoBuffer
->Account
.ScriptPath
);
6039 if (!NT_SUCCESS(Status
))
6041 TRACE("Status 0x%08lx\n", Status
);
6045 /* Get the ProfilePath string */
6046 Status
= SampGetObjectAttributeString(UserObject
,
6048 &InfoBuffer
->Account
.ProfilePath
);
6049 if (!NT_SUCCESS(Status
))
6051 TRACE("Status 0x%08lx\n", Status
);
6055 /* Get the AdminComment string */
6056 Status
= SampGetObjectAttributeString(UserObject
,
6058 &InfoBuffer
->Account
.AdminComment
);
6059 if (!NT_SUCCESS(Status
))
6061 TRACE("Status 0x%08lx\n", Status
);
6065 /* Get the WorkStations string */
6066 Status
= SampGetObjectAttributeString(UserObject
,
6068 &InfoBuffer
->Account
.WorkStations
);
6069 if (!NT_SUCCESS(Status
))
6071 TRACE("Status 0x%08lx\n", Status
);
6075 /* Get the LogonHours attribute */
6076 Status
= SampGetLogonHoursAttribute(UserObject
,
6077 &InfoBuffer
->Account
.LogonHours
);
6078 if (!NT_SUCCESS(Status
))
6080 TRACE("Status 0x%08lx\n", Status
);
6084 *Buffer
= InfoBuffer
;
6087 if (!NT_SUCCESS(Status
))
6089 if (InfoBuffer
!= NULL
)
6091 if (InfoBuffer
->Account
.UserName
.Buffer
!= NULL
)
6092 midl_user_free(InfoBuffer
->Account
.UserName
.Buffer
);
6094 if (InfoBuffer
->Account
.FullName
.Buffer
!= NULL
)
6095 midl_user_free(InfoBuffer
->Account
.FullName
.Buffer
);
6097 if (InfoBuffer
->Account
.HomeDirectory
.Buffer
!= NULL
)
6098 midl_user_free(InfoBuffer
->Account
.HomeDirectory
.Buffer
);
6100 if (InfoBuffer
->Account
.HomeDirectoryDrive
.Buffer
!= NULL
)
6101 midl_user_free(InfoBuffer
->Account
.HomeDirectoryDrive
.Buffer
);
6103 if (InfoBuffer
->Account
.ScriptPath
.Buffer
!= NULL
)
6104 midl_user_free(InfoBuffer
->Account
.ScriptPath
.Buffer
);
6106 if (InfoBuffer
->Account
.ProfilePath
.Buffer
!= NULL
)
6107 midl_user_free(InfoBuffer
->Account
.ProfilePath
.Buffer
);
6109 if (InfoBuffer
->Account
.AdminComment
.Buffer
!= NULL
)
6110 midl_user_free(InfoBuffer
->Account
.AdminComment
.Buffer
);
6112 if (InfoBuffer
->Account
.WorkStations
.Buffer
!= NULL
)
6113 midl_user_free(InfoBuffer
->Account
.WorkStations
.Buffer
);
6115 if (InfoBuffer
->Account
.LogonHours
.LogonHours
!= NULL
)
6116 midl_user_free(InfoBuffer
->Account
.LogonHours
.LogonHours
);
6118 midl_user_free(InfoBuffer
);
6128 SampQueryUserLogonHours(PSAM_DB_OBJECT UserObject
,
6129 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6131 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6134 TRACE("(%p %p)\n", UserObject
, Buffer
);
6138 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6139 if (InfoBuffer
== NULL
)
6141 TRACE("Failed to allocate InfoBuffer!\n");
6142 return STATUS_INSUFFICIENT_RESOURCES
;
6145 Status
= SampGetLogonHoursAttribute(UserObject
,
6146 &InfoBuffer
->LogonHours
.LogonHours
);
6147 if (!NT_SUCCESS(Status
))
6149 TRACE("SampGetLogonHoursAttribute failed (Status 0x%08lx)\n", Status
);
6153 *Buffer
= InfoBuffer
;
6156 if (!NT_SUCCESS(Status
))
6158 if (InfoBuffer
!= NULL
)
6160 if (InfoBuffer
->LogonHours
.LogonHours
.LogonHours
!= NULL
)
6161 midl_user_free(InfoBuffer
->LogonHours
.LogonHours
.LogonHours
);
6163 midl_user_free(InfoBuffer
);
6173 SampQueryUserName(PSAM_DB_OBJECT UserObject
,
6174 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6176 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6181 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6182 if (InfoBuffer
== NULL
)
6183 return STATUS_INSUFFICIENT_RESOURCES
;
6185 /* Get the Name string */
6186 Status
= SampGetObjectAttributeString(UserObject
,
6188 &InfoBuffer
->Name
.UserName
);
6189 if (!NT_SUCCESS(Status
))
6191 TRACE("Status 0x%08lx\n", Status
);
6195 /* Get the FullName string */
6196 Status
= SampGetObjectAttributeString(UserObject
,
6198 &InfoBuffer
->Name
.FullName
);
6199 if (!NT_SUCCESS(Status
))
6201 TRACE("Status 0x%08lx\n", Status
);
6205 *Buffer
= InfoBuffer
;
6208 if (!NT_SUCCESS(Status
))
6210 if (InfoBuffer
!= NULL
)
6212 if (InfoBuffer
->Name
.UserName
.Buffer
!= NULL
)
6213 midl_user_free(InfoBuffer
->Name
.UserName
.Buffer
);
6215 if (InfoBuffer
->Name
.FullName
.Buffer
!= NULL
)
6216 midl_user_free(InfoBuffer
->Name
.FullName
.Buffer
);
6218 midl_user_free(InfoBuffer
);
6227 SampQueryUserAccountName(PSAM_DB_OBJECT UserObject
,
6228 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6230 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6235 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6236 if (InfoBuffer
== NULL
)
6237 return STATUS_INSUFFICIENT_RESOURCES
;
6239 /* Get the Name string */
6240 Status
= SampGetObjectAttributeString(UserObject
,
6242 &InfoBuffer
->AccountName
.UserName
);
6243 if (!NT_SUCCESS(Status
))
6245 TRACE("Status 0x%08lx\n", Status
);
6249 *Buffer
= InfoBuffer
;
6252 if (!NT_SUCCESS(Status
))
6254 if (InfoBuffer
!= NULL
)
6256 if (InfoBuffer
->AccountName
.UserName
.Buffer
!= NULL
)
6257 midl_user_free(InfoBuffer
->AccountName
.UserName
.Buffer
);
6259 midl_user_free(InfoBuffer
);
6268 SampQueryUserFullName(PSAM_DB_OBJECT UserObject
,
6269 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6271 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6276 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6277 if (InfoBuffer
== NULL
)
6278 return STATUS_INSUFFICIENT_RESOURCES
;
6280 /* Get the FullName string */
6281 Status
= SampGetObjectAttributeString(UserObject
,
6283 &InfoBuffer
->FullName
.FullName
);
6284 if (!NT_SUCCESS(Status
))
6286 TRACE("Status 0x%08lx\n", Status
);
6290 *Buffer
= InfoBuffer
;
6293 if (!NT_SUCCESS(Status
))
6295 if (InfoBuffer
!= NULL
)
6297 if (InfoBuffer
->FullName
.FullName
.Buffer
!= NULL
)
6298 midl_user_free(InfoBuffer
->FullName
.FullName
.Buffer
);
6300 midl_user_free(InfoBuffer
);
6310 SampQueryUserPrimaryGroup(PSAM_DB_OBJECT UserObject
,
6311 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6313 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6314 SAM_USER_FIXED_DATA FixedData
;
6320 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6321 if (InfoBuffer
== NULL
)
6322 return STATUS_INSUFFICIENT_RESOURCES
;
6324 Length
= sizeof(SAM_USER_FIXED_DATA
);
6325 Status
= SampGetObjectAttribute(UserObject
,
6330 if (!NT_SUCCESS(Status
))
6333 InfoBuffer
->PrimaryGroup
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
6335 *Buffer
= InfoBuffer
;
6338 if (!NT_SUCCESS(Status
))
6340 if (InfoBuffer
!= NULL
)
6342 midl_user_free(InfoBuffer
);
6351 SampQueryUserHome(PSAM_DB_OBJECT UserObject
,
6352 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6354 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6359 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6360 if (InfoBuffer
== NULL
)
6361 return STATUS_INSUFFICIENT_RESOURCES
;
6363 /* Get the HomeDirectory string */
6364 Status
= SampGetObjectAttributeString(UserObject
,
6366 &InfoBuffer
->Home
.HomeDirectory
);
6367 if (!NT_SUCCESS(Status
))
6369 TRACE("Status 0x%08lx\n", Status
);
6373 /* Get the HomeDirectoryDrive string */
6374 Status
= SampGetObjectAttributeString(UserObject
,
6375 L
"HomeDirectoryDrive",
6376 &InfoBuffer
->Home
.HomeDirectoryDrive
);
6377 if (!NT_SUCCESS(Status
))
6379 TRACE("Status 0x%08lx\n", Status
);
6383 *Buffer
= InfoBuffer
;
6386 if (!NT_SUCCESS(Status
))
6388 if (InfoBuffer
!= NULL
)
6390 if (InfoBuffer
->Home
.HomeDirectory
.Buffer
!= NULL
)
6391 midl_user_free(InfoBuffer
->Home
.HomeDirectory
.Buffer
);
6393 if (InfoBuffer
->Home
.HomeDirectoryDrive
.Buffer
!= NULL
)
6394 midl_user_free(InfoBuffer
->Home
.HomeDirectoryDrive
.Buffer
);
6396 midl_user_free(InfoBuffer
);
6405 SampQueryUserScript(PSAM_DB_OBJECT UserObject
,
6406 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6408 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6413 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6414 if (InfoBuffer
== NULL
)
6415 return STATUS_INSUFFICIENT_RESOURCES
;
6417 /* Get the ScriptPath string */
6418 Status
= SampGetObjectAttributeString(UserObject
,
6420 &InfoBuffer
->Script
.ScriptPath
);
6421 if (!NT_SUCCESS(Status
))
6423 TRACE("Status 0x%08lx\n", Status
);
6427 *Buffer
= InfoBuffer
;
6430 if (!NT_SUCCESS(Status
))
6432 if (InfoBuffer
!= NULL
)
6434 if (InfoBuffer
->Script
.ScriptPath
.Buffer
!= NULL
)
6435 midl_user_free(InfoBuffer
->Script
.ScriptPath
.Buffer
);
6437 midl_user_free(InfoBuffer
);
6446 SampQueryUserProfile(PSAM_DB_OBJECT UserObject
,
6447 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6449 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6454 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6455 if (InfoBuffer
== NULL
)
6456 return STATUS_INSUFFICIENT_RESOURCES
;
6458 /* Get the ProfilePath string */
6459 Status
= SampGetObjectAttributeString(UserObject
,
6461 &InfoBuffer
->Profile
.ProfilePath
);
6462 if (!NT_SUCCESS(Status
))
6464 TRACE("Status 0x%08lx\n", Status
);
6468 *Buffer
= InfoBuffer
;
6471 if (!NT_SUCCESS(Status
))
6473 if (InfoBuffer
!= NULL
)
6475 if (InfoBuffer
->Profile
.ProfilePath
.Buffer
!= NULL
)
6476 midl_user_free(InfoBuffer
->Profile
.ProfilePath
.Buffer
);
6478 midl_user_free(InfoBuffer
);
6487 SampQueryUserAdminComment(PSAM_DB_OBJECT UserObject
,
6488 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6490 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6495 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6496 if (InfoBuffer
== NULL
)
6497 return STATUS_INSUFFICIENT_RESOURCES
;
6499 /* Get the AdminComment string */
6500 Status
= SampGetObjectAttributeString(UserObject
,
6502 &InfoBuffer
->AdminComment
.AdminComment
);
6503 if (!NT_SUCCESS(Status
))
6505 TRACE("Status 0x%08lx\n", Status
);
6509 *Buffer
= InfoBuffer
;
6512 if (!NT_SUCCESS(Status
))
6514 if (InfoBuffer
!= NULL
)
6516 if (InfoBuffer
->AdminComment
.AdminComment
.Buffer
!= NULL
)
6517 midl_user_free(InfoBuffer
->AdminComment
.AdminComment
.Buffer
);
6519 midl_user_free(InfoBuffer
);
6528 SampQueryUserWorkStations(PSAM_DB_OBJECT UserObject
,
6529 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6531 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6536 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6537 if (InfoBuffer
== NULL
)
6538 return STATUS_INSUFFICIENT_RESOURCES
;
6540 /* Get the WorkStations string */
6541 Status
= SampGetObjectAttributeString(UserObject
,
6543 &InfoBuffer
->WorkStations
.WorkStations
);
6544 if (!NT_SUCCESS(Status
))
6546 TRACE("Status 0x%08lx\n", Status
);
6550 *Buffer
= InfoBuffer
;
6553 if (!NT_SUCCESS(Status
))
6555 if (InfoBuffer
!= NULL
)
6557 if (InfoBuffer
->WorkStations
.WorkStations
.Buffer
!= NULL
)
6558 midl_user_free(InfoBuffer
->WorkStations
.WorkStations
.Buffer
);
6560 midl_user_free(InfoBuffer
);
6570 SampQueryUserControl(PSAM_DB_OBJECT UserObject
,
6571 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6573 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6574 SAM_USER_FIXED_DATA FixedData
;
6580 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6581 if (InfoBuffer
== NULL
)
6582 return STATUS_INSUFFICIENT_RESOURCES
;
6584 Length
= sizeof(SAM_USER_FIXED_DATA
);
6585 Status
= SampGetObjectAttribute(UserObject
,
6590 if (!NT_SUCCESS(Status
))
6593 InfoBuffer
->Control
.UserAccountControl
= FixedData
.UserAccountControl
;
6595 *Buffer
= InfoBuffer
;
6598 if (!NT_SUCCESS(Status
))
6600 if (InfoBuffer
!= NULL
)
6602 midl_user_free(InfoBuffer
);
6612 SampQueryUserExpires(PSAM_DB_OBJECT UserObject
,
6613 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6615 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6616 SAM_USER_FIXED_DATA FixedData
;
6622 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6623 if (InfoBuffer
== NULL
)
6624 return STATUS_INSUFFICIENT_RESOURCES
;
6626 Length
= sizeof(SAM_USER_FIXED_DATA
);
6627 Status
= SampGetObjectAttribute(UserObject
,
6632 if (!NT_SUCCESS(Status
))
6635 InfoBuffer
->Expires
.AccountExpires
.LowPart
= FixedData
.AccountExpires
.LowPart
;
6636 InfoBuffer
->Expires
.AccountExpires
.HighPart
= FixedData
.AccountExpires
.HighPart
;
6638 *Buffer
= InfoBuffer
;
6641 if (!NT_SUCCESS(Status
))
6643 if (InfoBuffer
!= NULL
)
6645 midl_user_free(InfoBuffer
);
6655 SampQueryUserInternal1(PSAM_DB_OBJECT UserObject
,
6656 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6658 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6660 NTSTATUS Status
= STATUS_SUCCESS
;
6662 /* Fail, if the caller is not a trusted caller */
6663 if (UserObject
->Trusted
== FALSE
)
6664 return STATUS_INVALID_INFO_CLASS
;
6668 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6669 if (InfoBuffer
== NULL
)
6670 return STATUS_INSUFFICIENT_RESOURCES
;
6672 InfoBuffer
->Internal1
.LmPasswordPresent
= FALSE
;
6673 InfoBuffer
->Internal1
.NtPasswordPresent
= FALSE
;
6675 /* Get the NT password */
6677 SampGetObjectAttribute(UserObject
,
6683 if (Length
== sizeof(ENCRYPTED_NT_OWF_PASSWORD
))
6685 Status
= SampGetObjectAttribute(UserObject
,
6688 (PVOID
)&InfoBuffer
->Internal1
.EncryptedNtOwfPassword
,
6690 if (!NT_SUCCESS(Status
))
6693 if (memcmp(&InfoBuffer
->Internal1
.EncryptedNtOwfPassword
,
6695 sizeof(ENCRYPTED_NT_OWF_PASSWORD
)))
6696 InfoBuffer
->Internal1
.NtPasswordPresent
= TRUE
;
6700 /* Get the LM password */
6702 SampGetObjectAttribute(UserObject
,
6708 if (Length
== sizeof(ENCRYPTED_LM_OWF_PASSWORD
))
6710 Status
= SampGetObjectAttribute(UserObject
,
6713 (PVOID
)&InfoBuffer
->Internal1
.EncryptedLmOwfPassword
,
6715 if (!NT_SUCCESS(Status
))
6718 if (memcmp(&InfoBuffer
->Internal1
.EncryptedLmOwfPassword
,
6720 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
6721 InfoBuffer
->Internal1
.LmPasswordPresent
= TRUE
;
6724 InfoBuffer
->Internal1
.PasswordExpired
= FALSE
;
6726 *Buffer
= InfoBuffer
;
6729 if (!NT_SUCCESS(Status
))
6731 if (InfoBuffer
!= NULL
)
6733 midl_user_free(InfoBuffer
);
6742 SampQueryUserParameters(PSAM_DB_OBJECT UserObject
,
6743 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6745 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6750 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6751 if (InfoBuffer
== NULL
)
6752 return STATUS_INSUFFICIENT_RESOURCES
;
6754 /* Get the Parameters string */
6755 Status
= SampGetObjectAttributeString(UserObject
,
6757 &InfoBuffer
->Parameters
.Parameters
);
6758 if (!NT_SUCCESS(Status
))
6760 TRACE("Status 0x%08lx\n", Status
);
6764 *Buffer
= InfoBuffer
;
6767 if (!NT_SUCCESS(Status
))
6769 if (InfoBuffer
!= NULL
)
6771 if (InfoBuffer
->Parameters
.Parameters
.Buffer
!= NULL
)
6772 midl_user_free(InfoBuffer
->Parameters
.Parameters
.Buffer
);
6774 midl_user_free(InfoBuffer
);
6783 SampQueryUserAll(PSAM_DB_OBJECT UserObject
,
6784 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6786 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6787 SAM_DOMAIN_FIXED_DATA DomainFixedData
;
6788 SAM_USER_FIXED_DATA FixedData
;
6789 LARGE_INTEGER PasswordCanChange
;
6790 LARGE_INTEGER PasswordMustChange
;
6796 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6797 if (InfoBuffer
== NULL
)
6798 return STATUS_INSUFFICIENT_RESOURCES
;
6800 /* Get the fixed size domain data */
6801 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
6802 Status
= SampGetObjectAttribute(UserObject
->ParentObject
,
6805 (PVOID
)&DomainFixedData
,
6807 if (!NT_SUCCESS(Status
))
6810 /* Get the fixed size user data */
6811 Length
= sizeof(SAM_USER_FIXED_DATA
);
6812 Status
= SampGetObjectAttribute(UserObject
,
6817 if (!NT_SUCCESS(Status
))
6820 /* Set the fields to be returned */
6821 if (UserObject
->Trusted
)
6823 InfoBuffer
->All
.WhichFields
= USER_ALL_READ_GENERAL_MASK
|
6824 USER_ALL_READ_LOGON_MASK
|
6825 USER_ALL_READ_ACCOUNT_MASK
|
6826 USER_ALL_READ_PREFERENCES_MASK
|
6827 USER_ALL_READ_TRUSTED_MASK
;
6831 InfoBuffer
->All
.WhichFields
= 0;
6833 if (UserObject
->Access
& USER_READ_GENERAL
)
6834 InfoBuffer
->All
.WhichFields
|= USER_ALL_READ_GENERAL_MASK
;
6836 if (UserObject
->Access
& USER_READ_LOGON
)
6837 InfoBuffer
->All
.WhichFields
|= USER_ALL_READ_LOGON_MASK
;
6839 if (UserObject
->Access
& USER_READ_ACCOUNT
)
6840 InfoBuffer
->All
.WhichFields
|= USER_ALL_READ_ACCOUNT_MASK
;
6842 if (UserObject
->Access
& USER_READ_PREFERENCES
)
6843 InfoBuffer
->All
.WhichFields
|= USER_ALL_READ_PREFERENCES_MASK
;
6846 /* Fail, if no fields are to be returned */
6847 if (InfoBuffer
->All
.WhichFields
== 0)
6849 Status
= STATUS_ACCESS_DENIED
;
6853 /* Get the UserName attribute */
6854 if (InfoBuffer
->All
.WhichFields
& USER_ALL_USERNAME
)
6856 Status
= SampGetObjectAttributeString(UserObject
,
6858 &InfoBuffer
->All
.UserName
);
6859 if (!NT_SUCCESS(Status
))
6861 TRACE("Status 0x%08lx\n", Status
);
6866 /* Get the FullName attribute */
6867 if (InfoBuffer
->All
.WhichFields
& USER_ALL_FULLNAME
)
6869 Status
= SampGetObjectAttributeString(UserObject
,
6871 &InfoBuffer
->All
.FullName
);
6872 if (!NT_SUCCESS(Status
))
6874 TRACE("Status 0x%08lx\n", Status
);
6879 /* Get the UserId attribute */
6880 if (InfoBuffer
->All
.WhichFields
& USER_ALL_USERID
)
6882 InfoBuffer
->All
.UserId
= FixedData
.UserId
;
6885 /* Get the PrimaryGroupId attribute */
6886 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PRIMARYGROUPID
)
6888 InfoBuffer
->All
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
6891 /* Get the AdminComment attribute */
6892 if (InfoBuffer
->All
.WhichFields
& USER_ALL_ADMINCOMMENT
)
6894 Status
= SampGetObjectAttributeString(UserObject
,
6896 &InfoBuffer
->All
.AdminComment
);
6897 if (!NT_SUCCESS(Status
))
6899 TRACE("Status 0x%08lx\n", Status
);
6904 /* Get the UserComment attribute */
6905 if (InfoBuffer
->All
.WhichFields
& USER_ALL_USERCOMMENT
)
6907 Status
= SampGetObjectAttributeString(UserObject
,
6909 &InfoBuffer
->All
.UserComment
);
6910 if (!NT_SUCCESS(Status
))
6912 TRACE("Status 0x%08lx\n", Status
);
6917 /* Get the HomeDirectory attribute */
6918 if (InfoBuffer
->All
.WhichFields
& USER_ALL_HOMEDIRECTORY
)
6920 Status
= SampGetObjectAttributeString(UserObject
,
6922 &InfoBuffer
->All
.HomeDirectory
);
6923 if (!NT_SUCCESS(Status
))
6925 TRACE("Status 0x%08lx\n", Status
);
6930 /* Get the HomeDirectoryDrive attribute */
6931 if (InfoBuffer
->All
.WhichFields
& USER_ALL_HOMEDIRECTORYDRIVE
)
6933 Status
= SampGetObjectAttributeString(UserObject
,
6934 L
"HomeDirectoryDrive",
6935 &InfoBuffer
->Home
.HomeDirectoryDrive
);
6936 if (!NT_SUCCESS(Status
))
6938 TRACE("Status 0x%08lx\n", Status
);
6943 /* Get the ScriptPath attribute */
6944 if (InfoBuffer
->All
.WhichFields
& USER_ALL_SCRIPTPATH
)
6946 Status
= SampGetObjectAttributeString(UserObject
,
6948 &InfoBuffer
->All
.ScriptPath
);
6949 if (!NT_SUCCESS(Status
))
6951 TRACE("Status 0x%08lx\n", Status
);
6956 /* Get the ProfilePath attribute */
6957 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PROFILEPATH
)
6959 Status
= SampGetObjectAttributeString(UserObject
,
6961 &InfoBuffer
->All
.ProfilePath
);
6962 if (!NT_SUCCESS(Status
))
6964 TRACE("Status 0x%08lx\n", Status
);
6969 /* Get the WorkStations attribute */
6970 if (InfoBuffer
->All
.WhichFields
& USER_ALL_WORKSTATIONS
)
6972 Status
= SampGetObjectAttributeString(UserObject
,
6974 &InfoBuffer
->All
.WorkStations
);
6975 if (!NT_SUCCESS(Status
))
6977 TRACE("Status 0x%08lx\n", Status
);
6982 /* Get the LastLogon attribute */
6983 if (InfoBuffer
->All
.WhichFields
& USER_ALL_LASTLOGON
)
6985 InfoBuffer
->All
.LastLogon
.LowPart
= FixedData
.LastLogon
.LowPart
;
6986 InfoBuffer
->All
.LastLogon
.HighPart
= FixedData
.LastLogon
.HighPart
;
6989 /* Get the LastLogoff attribute */
6990 if (InfoBuffer
->All
.WhichFields
& USER_ALL_LASTLOGOFF
)
6992 InfoBuffer
->All
.LastLogoff
.LowPart
= FixedData
.LastLogoff
.LowPart
;
6993 InfoBuffer
->All
.LastLogoff
.HighPart
= FixedData
.LastLogoff
.HighPart
;
6996 /* Get the LogonHours attribute */
6997 if (InfoBuffer
->All
.WhichFields
& USER_ALL_LOGONHOURS
)
6999 Status
= SampGetLogonHoursAttribute(UserObject
,
7000 &InfoBuffer
->All
.LogonHours
);
7001 if (!NT_SUCCESS(Status
))
7003 TRACE("Status 0x%08lx\n", Status
);
7008 /* Get the BadPasswordCount attribute */
7009 if (InfoBuffer
->All
.WhichFields
& USER_ALL_BADPASSWORDCOUNT
)
7011 InfoBuffer
->All
.BadPasswordCount
= FixedData
.BadPasswordCount
;
7014 /* Get the LogonCount attribute */
7015 if (InfoBuffer
->All
.WhichFields
& USER_ALL_LOGONCOUNT
)
7017 InfoBuffer
->All
.LogonCount
= FixedData
.LogonCount
;
7020 /* Get the PasswordCanChange attribute */
7021 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PASSWORDCANCHANGE
)
7023 PasswordCanChange
= SampAddRelativeTimeToTime(FixedData
.PasswordLastSet
,
7024 DomainFixedData
.MinPasswordAge
);
7025 InfoBuffer
->All
.PasswordCanChange
.LowPart
= PasswordCanChange
.LowPart
;
7026 InfoBuffer
->All
.PasswordCanChange
.HighPart
= PasswordCanChange
.HighPart
;
7029 /* Get the PasswordMustChange attribute */
7030 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PASSWORDMUSTCHANGE
)
7032 PasswordMustChange
= SampAddRelativeTimeToTime(FixedData
.PasswordLastSet
,
7033 DomainFixedData
.MaxPasswordAge
);
7034 InfoBuffer
->All
.PasswordMustChange
.LowPart
= PasswordMustChange
.LowPart
;
7035 InfoBuffer
->All
.PasswordMustChange
.HighPart
= PasswordMustChange
.HighPart
;
7038 /* Get the PasswordLastSet attribute */
7039 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PASSWORDLASTSET
)
7041 InfoBuffer
->All
.PasswordLastSet
.LowPart
= FixedData
.PasswordLastSet
.LowPart
;
7042 InfoBuffer
->All
.PasswordLastSet
.HighPart
= FixedData
.PasswordLastSet
.HighPart
;
7045 /* Get the AccountExpires attribute */
7046 if (InfoBuffer
->All
.WhichFields
& USER_ALL_ACCOUNTEXPIRES
)
7048 InfoBuffer
->All
.AccountExpires
.LowPart
= FixedData
.AccountExpires
.LowPart
;
7049 InfoBuffer
->All
.AccountExpires
.HighPart
= FixedData
.AccountExpires
.HighPart
;
7052 /* Get the UserAccountControl attribute */
7053 if (InfoBuffer
->All
.WhichFields
& USER_ALL_USERACCOUNTCONTROL
)
7055 InfoBuffer
->All
.UserAccountControl
= FixedData
.UserAccountControl
;
7058 /* Get the Parameters attribute */
7059 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PARAMETERS
)
7061 Status
= SampGetObjectAttributeString(UserObject
,
7063 &InfoBuffer
->All
.Parameters
);
7064 if (!NT_SUCCESS(Status
))
7066 TRACE("Status 0x%08lx\n", Status
);
7071 /* Get the CountryCode attribute */
7072 if (InfoBuffer
->All
.WhichFields
& USER_ALL_COUNTRYCODE
)
7074 InfoBuffer
->All
.CountryCode
= FixedData
.CountryCode
;
7077 /* Get the CodePage attribute */
7078 if (InfoBuffer
->All
.WhichFields
& USER_ALL_CODEPAGE
)
7080 InfoBuffer
->All
.CodePage
= FixedData
.CodePage
;
7083 /* Get the LmPassword and NtPassword attributes */
7084 if (InfoBuffer
->All
.WhichFields
& (USER_ALL_NTPASSWORDPRESENT
| USER_ALL_LMPASSWORDPRESENT
))
7086 InfoBuffer
->All
.LmPasswordPresent
= FALSE
;
7087 InfoBuffer
->All
.NtPasswordPresent
= FALSE
;
7089 /* Get the NT password */
7091 SampGetObjectAttribute(UserObject
,
7097 if (Length
== sizeof(ENCRYPTED_NT_OWF_PASSWORD
))
7099 InfoBuffer
->All
.NtOwfPassword
.Buffer
= midl_user_allocate(sizeof(ENCRYPTED_NT_OWF_PASSWORD
));
7100 if (InfoBuffer
->All
.NtOwfPassword
.Buffer
== NULL
)
7102 Status
= STATUS_INSUFFICIENT_RESOURCES
;
7106 InfoBuffer
->All
.NtOwfPassword
.Length
= sizeof(ENCRYPTED_NT_OWF_PASSWORD
);
7107 InfoBuffer
->All
.NtOwfPassword
.MaximumLength
= sizeof(ENCRYPTED_NT_OWF_PASSWORD
);
7109 Status
= SampGetObjectAttribute(UserObject
,
7112 (PVOID
)InfoBuffer
->All
.NtOwfPassword
.Buffer
,
7114 if (!NT_SUCCESS(Status
))
7117 if (memcmp(InfoBuffer
->All
.NtOwfPassword
.Buffer
,
7119 sizeof(ENCRYPTED_NT_OWF_PASSWORD
)))
7120 InfoBuffer
->All
.NtPasswordPresent
= TRUE
;
7123 /* Get the LM password */
7125 SampGetObjectAttribute(UserObject
,
7131 if (Length
== sizeof(ENCRYPTED_LM_OWF_PASSWORD
))
7133 InfoBuffer
->All
.LmOwfPassword
.Buffer
= midl_user_allocate(sizeof(ENCRYPTED_LM_OWF_PASSWORD
));
7134 if (InfoBuffer
->All
.LmOwfPassword
.Buffer
== NULL
)
7136 Status
= STATUS_INSUFFICIENT_RESOURCES
;
7140 InfoBuffer
->All
.LmOwfPassword
.Length
= sizeof(ENCRYPTED_LM_OWF_PASSWORD
);
7141 InfoBuffer
->All
.LmOwfPassword
.MaximumLength
= sizeof(ENCRYPTED_LM_OWF_PASSWORD
);
7143 Status
= SampGetObjectAttribute(UserObject
,
7146 (PVOID
)InfoBuffer
->All
.LmOwfPassword
.Buffer
,
7148 if (!NT_SUCCESS(Status
))
7151 if (memcmp(InfoBuffer
->All
.LmOwfPassword
.Buffer
,
7153 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
7154 InfoBuffer
->All
.LmPasswordPresent
= TRUE
;
7158 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PRIVATEDATA
)
7160 Status
= SampGetObjectAttributeString(UserObject
,
7162 &InfoBuffer
->All
.PrivateData
);
7163 if (!NT_SUCCESS(Status
))
7165 TRACE("Status 0x%08lx\n", Status
);
7170 if (InfoBuffer
->All
.WhichFields
& USER_ALL_PASSWORDEXPIRED
)
7175 if (InfoBuffer
->All
.WhichFields
& USER_ALL_SECURITYDESCRIPTOR
)
7178 SampGetObjectAttribute(UserObject
,
7186 InfoBuffer
->All
.SecurityDescriptor
.SecurityDescriptor
= midl_user_allocate(Length
);
7187 if (InfoBuffer
->All
.SecurityDescriptor
.SecurityDescriptor
== NULL
)
7189 Status
= STATUS_INSUFFICIENT_RESOURCES
;
7193 InfoBuffer
->All
.SecurityDescriptor
.Length
= Length
;
7195 Status
= SampGetObjectAttribute(UserObject
,
7198 (PVOID
)InfoBuffer
->All
.SecurityDescriptor
.SecurityDescriptor
,
7200 if (!NT_SUCCESS(Status
))
7205 *Buffer
= InfoBuffer
;
7208 if (!NT_SUCCESS(Status
))
7210 if (InfoBuffer
!= NULL
)
7212 if (InfoBuffer
->All
.UserName
.Buffer
!= NULL
)
7213 midl_user_free(InfoBuffer
->All
.UserName
.Buffer
);
7215 if (InfoBuffer
->All
.FullName
.Buffer
!= NULL
)
7216 midl_user_free(InfoBuffer
->All
.FullName
.Buffer
);
7218 if (InfoBuffer
->All
.AdminComment
.Buffer
!= NULL
)
7219 midl_user_free(InfoBuffer
->All
.AdminComment
.Buffer
);
7221 if (InfoBuffer
->All
.UserComment
.Buffer
!= NULL
)
7222 midl_user_free(InfoBuffer
->All
.UserComment
.Buffer
);
7224 if (InfoBuffer
->All
.HomeDirectory
.Buffer
!= NULL
)
7225 midl_user_free(InfoBuffer
->All
.HomeDirectory
.Buffer
);
7227 if (InfoBuffer
->All
.HomeDirectoryDrive
.Buffer
!= NULL
)
7228 midl_user_free(InfoBuffer
->All
.HomeDirectoryDrive
.Buffer
);
7230 if (InfoBuffer
->All
.ScriptPath
.Buffer
!= NULL
)
7231 midl_user_free(InfoBuffer
->All
.ScriptPath
.Buffer
);
7233 if (InfoBuffer
->All
.ProfilePath
.Buffer
!= NULL
)
7234 midl_user_free(InfoBuffer
->All
.ProfilePath
.Buffer
);
7236 if (InfoBuffer
->All
.WorkStations
.Buffer
!= NULL
)
7237 midl_user_free(InfoBuffer
->All
.WorkStations
.Buffer
);
7239 if (InfoBuffer
->All
.LogonHours
.LogonHours
!= NULL
)
7240 midl_user_free(InfoBuffer
->All
.LogonHours
.LogonHours
);
7242 if (InfoBuffer
->All
.Parameters
.Buffer
!= NULL
)
7243 midl_user_free(InfoBuffer
->All
.Parameters
.Buffer
);
7245 if (InfoBuffer
->All
.LmOwfPassword
.Buffer
!= NULL
)
7246 midl_user_free(InfoBuffer
->All
.LmOwfPassword
.Buffer
);
7248 if (InfoBuffer
->All
.NtOwfPassword
.Buffer
!= NULL
)
7249 midl_user_free(InfoBuffer
->All
.NtOwfPassword
.Buffer
);
7251 if (InfoBuffer
->All
.PrivateData
.Buffer
!= NULL
)
7252 midl_user_free(InfoBuffer
->All
.PrivateData
.Buffer
);
7254 if (InfoBuffer
->All
.SecurityDescriptor
.SecurityDescriptor
!= NULL
)
7255 midl_user_free(InfoBuffer
->All
.SecurityDescriptor
.SecurityDescriptor
);
7257 midl_user_free(InfoBuffer
);
7268 SamrQueryInformationUser(IN SAMPR_HANDLE UserHandle
,
7269 IN USER_INFORMATION_CLASS UserInformationClass
,
7270 OUT PSAMPR_USER_INFO_BUFFER
*Buffer
)
7272 PSAM_DB_OBJECT UserObject
;
7273 ACCESS_MASK DesiredAccess
;
7276 TRACE("SamrQueryInformationUser(%p %lu %p)\n",
7277 UserHandle
, UserInformationClass
, Buffer
);
7279 switch (UserInformationClass
)
7281 case UserGeneralInformation
:
7282 case UserNameInformation
:
7283 case UserAccountNameInformation
:
7284 case UserFullNameInformation
:
7285 case UserPrimaryGroupInformation
:
7286 case UserAdminCommentInformation
:
7287 DesiredAccess
= USER_READ_GENERAL
;
7290 case UserLogonHoursInformation
:
7291 case UserHomeInformation
:
7292 case UserScriptInformation
:
7293 case UserProfileInformation
:
7294 case UserWorkStationsInformation
:
7295 DesiredAccess
= USER_READ_LOGON
;
7298 case UserControlInformation
:
7299 case UserExpiresInformation
:
7300 case UserParametersInformation
:
7301 DesiredAccess
= USER_READ_ACCOUNT
;
7304 case UserPreferencesInformation
:
7305 DesiredAccess
= USER_READ_GENERAL
|
7306 USER_READ_PREFERENCES
;
7309 case UserLogonInformation
:
7310 case UserAccountInformation
:
7311 DesiredAccess
= USER_READ_GENERAL
|
7312 USER_READ_PREFERENCES
|
7317 case UserInternal1Information
:
7318 case UserAllInformation
:
7323 return STATUS_INVALID_INFO_CLASS
;
7326 RtlAcquireResourceShared(&SampResource
,
7329 /* Validate the domain handle */
7330 Status
= SampValidateDbObject(UserHandle
,
7334 if (!NT_SUCCESS(Status
))
7336 TRACE("failed with status 0x%08lx\n", Status
);
7340 switch (UserInformationClass
)
7342 case UserGeneralInformation
:
7343 Status
= SampQueryUserGeneral(UserObject
,
7347 case UserPreferencesInformation
:
7348 Status
= SampQueryUserPreferences(UserObject
,
7352 case UserLogonInformation
:
7353 Status
= SampQueryUserLogon(UserObject
,
7357 case UserLogonHoursInformation
:
7358 Status
= SampQueryUserLogonHours(UserObject
,
7362 case UserAccountInformation
:
7363 Status
= SampQueryUserAccount(UserObject
,
7367 case UserNameInformation
:
7368 Status
= SampQueryUserName(UserObject
,
7372 case UserAccountNameInformation
:
7373 Status
= SampQueryUserAccountName(UserObject
,
7377 case UserFullNameInformation
:
7378 Status
= SampQueryUserFullName(UserObject
,
7382 case UserPrimaryGroupInformation
:
7383 Status
= SampQueryUserPrimaryGroup(UserObject
,
7387 case UserHomeInformation
:
7388 Status
= SampQueryUserHome(UserObject
,
7391 case UserScriptInformation
:
7392 Status
= SampQueryUserScript(UserObject
,
7396 case UserProfileInformation
:
7397 Status
= SampQueryUserProfile(UserObject
,
7401 case UserAdminCommentInformation
:
7402 Status
= SampQueryUserAdminComment(UserObject
,
7406 case UserWorkStationsInformation
:
7407 Status
= SampQueryUserWorkStations(UserObject
,
7411 case UserControlInformation
:
7412 Status
= SampQueryUserControl(UserObject
,
7416 case UserExpiresInformation
:
7417 Status
= SampQueryUserExpires(UserObject
,
7421 case UserInternal1Information
:
7422 Status
= SampQueryUserInternal1(UserObject
,
7426 case UserParametersInformation
:
7427 Status
= SampQueryUserParameters(UserObject
,
7431 case UserAllInformation
:
7432 Status
= SampQueryUserAll(UserObject
,
7436 // case UserInternal4Information:
7437 // case UserInternal5Information:
7438 // case UserInternal4InformationNew:
7439 // case UserInternal5InformationNew:
7442 Status
= STATUS_INVALID_INFO_CLASS
;
7446 RtlReleaseResource(&SampResource
);
7453 SampSetUserName(PSAM_DB_OBJECT UserObject
,
7454 PRPC_UNICODE_STRING NewUserName
)
7456 UNICODE_STRING OldUserName
= {0, 0, NULL
};
7459 /* Check the account name */
7460 Status
= SampCheckAccountName(NewUserName
, 20);
7461 if (!NT_SUCCESS(Status
))
7463 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
7467 Status
= SampGetObjectAttributeString(UserObject
,
7469 (PRPC_UNICODE_STRING
)&OldUserName
);
7470 if (!NT_SUCCESS(Status
))
7472 TRACE("SampGetObjectAttributeString failed (Status 0x%08lx)\n", Status
);
7476 if (!RtlEqualUnicodeString(&OldUserName
, (PCUNICODE_STRING
)NewUserName
, TRUE
))
7478 Status
= SampCheckAccountNameInDomain(UserObject
->ParentObject
,
7479 NewUserName
->Buffer
);
7480 if (!NT_SUCCESS(Status
))
7482 TRACE("User name \'%S\' already exists in domain (Status 0x%08lx)\n",
7483 NewUserName
->Buffer
, Status
);
7488 Status
= SampSetAccountNameInDomain(UserObject
->ParentObject
,
7490 NewUserName
->Buffer
,
7491 UserObject
->RelativeId
);
7492 if (!NT_SUCCESS(Status
))
7494 TRACE("SampSetAccountNameInDomain failed (Status 0x%08lx)\n", Status
);
7498 Status
= SampRemoveAccountNameFromDomain(UserObject
->ParentObject
,
7500 OldUserName
.Buffer
);
7501 if (!NT_SUCCESS(Status
))
7503 TRACE("SampRemoveAccountNameFromDomain failed (Status 0x%08lx)\n", Status
);
7507 Status
= SampSetObjectAttributeString(UserObject
,
7510 if (!NT_SUCCESS(Status
))
7512 TRACE("SampSetObjectAttribute failed (Status 0x%08lx)\n", Status
);
7516 if (OldUserName
.Buffer
!= NULL
)
7517 midl_user_free(OldUserName
.Buffer
);
7524 SampSetUserGeneral(PSAM_DB_OBJECT UserObject
,
7525 PSAMPR_USER_INFO_BUFFER Buffer
)
7527 SAM_USER_FIXED_DATA FixedData
;
7531 Length
= sizeof(SAM_USER_FIXED_DATA
);
7532 Status
= SampGetObjectAttribute(UserObject
,
7537 if (!NT_SUCCESS(Status
))
7540 FixedData
.PrimaryGroupId
= Buffer
->General
.PrimaryGroupId
;
7542 Status
= SampSetObjectAttribute(UserObject
,
7547 if (!NT_SUCCESS(Status
))
7550 Status
= SampSetUserName(UserObject
,
7551 &Buffer
->General
.UserName
);
7552 if (!NT_SUCCESS(Status
))
7555 Status
= SampSetObjectAttributeString(UserObject
,
7557 &Buffer
->General
.FullName
);
7558 if (!NT_SUCCESS(Status
))
7561 Status
= SampSetObjectAttributeString(UserObject
,
7563 &Buffer
->General
.AdminComment
);
7564 if (!NT_SUCCESS(Status
))
7567 Status
= SampSetObjectAttributeString(UserObject
,
7569 &Buffer
->General
.UserComment
);
7577 SampSetUserPreferences(PSAM_DB_OBJECT UserObject
,
7578 PSAMPR_USER_INFO_BUFFER Buffer
)
7580 SAM_USER_FIXED_DATA FixedData
;
7584 Length
= sizeof(SAM_USER_FIXED_DATA
);
7585 Status
= SampGetObjectAttribute(UserObject
,
7590 if (!NT_SUCCESS(Status
))
7593 FixedData
.CountryCode
= Buffer
->Preferences
.CountryCode
;
7594 FixedData
.CodePage
= Buffer
->Preferences
.CodePage
;
7596 Status
= SampSetObjectAttribute(UserObject
,
7601 if (!NT_SUCCESS(Status
))
7604 Status
= SampSetObjectAttributeString(UserObject
,
7606 &Buffer
->Preferences
.UserComment
);
7614 SampSetUserPrimaryGroup(PSAM_DB_OBJECT UserObject
,
7615 PSAMPR_USER_INFO_BUFFER Buffer
)
7617 SAM_USER_FIXED_DATA FixedData
;
7621 Length
= sizeof(SAM_USER_FIXED_DATA
);
7622 Status
= SampGetObjectAttribute(UserObject
,
7627 if (!NT_SUCCESS(Status
))
7630 FixedData
.PrimaryGroupId
= Buffer
->PrimaryGroup
.PrimaryGroupId
;
7632 Status
= SampSetObjectAttribute(UserObject
,
7644 SampSetUserControl(PSAM_DB_OBJECT UserObject
,
7645 PSAMPR_USER_INFO_BUFFER Buffer
)
7647 SAM_USER_FIXED_DATA FixedData
;
7651 Length
= sizeof(SAM_USER_FIXED_DATA
);
7652 Status
= SampGetObjectAttribute(UserObject
,
7657 if (!NT_SUCCESS(Status
))
7660 FixedData
.UserAccountControl
= Buffer
->Control
.UserAccountControl
;
7662 Status
= SampSetObjectAttribute(UserObject
,
7674 SampSetUserExpires(PSAM_DB_OBJECT UserObject
,
7675 PSAMPR_USER_INFO_BUFFER Buffer
)
7677 SAM_USER_FIXED_DATA FixedData
;
7681 Length
= sizeof(SAM_USER_FIXED_DATA
);
7682 Status
= SampGetObjectAttribute(UserObject
,
7687 if (!NT_SUCCESS(Status
))
7690 FixedData
.AccountExpires
.LowPart
= Buffer
->Expires
.AccountExpires
.LowPart
;
7691 FixedData
.AccountExpires
.HighPart
= Buffer
->Expires
.AccountExpires
.HighPart
;
7693 Status
= SampSetObjectAttribute(UserObject
,
7705 SampSetUserInternal1(PSAM_DB_OBJECT UserObject
,
7706 PSAMPR_USER_INFO_BUFFER Buffer
)
7708 SAM_USER_FIXED_DATA FixedData
;
7710 NTSTATUS Status
= STATUS_SUCCESS
;
7712 /* FIXME: Decrypt NT password */
7713 /* FIXME: Decrypt LM password */
7715 Status
= SampSetUserPassword(UserObject
,
7716 &Buffer
->Internal1
.EncryptedNtOwfPassword
,
7717 Buffer
->Internal1
.NtPasswordPresent
,
7718 &Buffer
->Internal1
.EncryptedLmOwfPassword
,
7719 Buffer
->Internal1
.LmPasswordPresent
);
7720 if (!NT_SUCCESS(Status
))
7723 /* Get the fixed user attributes */
7724 Length
= sizeof(SAM_USER_FIXED_DATA
);
7725 Status
= SampGetObjectAttribute(UserObject
,
7730 if (!NT_SUCCESS(Status
))
7733 if (Buffer
->Internal1
.PasswordExpired
)
7735 /* The password was last set ages ago */
7736 FixedData
.PasswordLastSet
.LowPart
= 0;
7737 FixedData
.PasswordLastSet
.HighPart
= 0;
7741 /* The password was last set right now */
7742 Status
= NtQuerySystemTime(&FixedData
.PasswordLastSet
);
7743 if (!NT_SUCCESS(Status
))
7747 /* Set the fixed user attributes */
7748 Status
= SampSetObjectAttribute(UserObject
,
7760 SampSetUserAll(PSAM_DB_OBJECT UserObject
,
7761 PSAMPR_USER_INFO_BUFFER Buffer
)
7763 SAM_USER_FIXED_DATA FixedData
;
7766 PENCRYPTED_NT_OWF_PASSWORD NtPassword
= NULL
;
7767 PENCRYPTED_LM_OWF_PASSWORD LmPassword
= NULL
;
7768 BOOLEAN NtPasswordPresent
= FALSE
;
7769 BOOLEAN LmPasswordPresent
= FALSE
;
7770 BOOLEAN WriteFixedData
= FALSE
;
7771 NTSTATUS Status
= STATUS_SUCCESS
;
7773 WhichFields
= Buffer
->All
.WhichFields
;
7775 /* Get the fixed size attributes */
7776 Length
= sizeof(SAM_USER_FIXED_DATA
);
7777 Status
= SampGetObjectAttribute(UserObject
,
7782 if (!NT_SUCCESS(Status
))
7785 if (WhichFields
& USER_ALL_USERNAME
)
7787 Status
= SampSetUserName(UserObject
,
7788 &Buffer
->All
.UserName
);
7789 if (!NT_SUCCESS(Status
))
7793 if (WhichFields
& USER_ALL_FULLNAME
)
7795 Status
= SampSetObjectAttributeString(UserObject
,
7797 &Buffer
->All
.FullName
);
7798 if (!NT_SUCCESS(Status
))
7802 if (WhichFields
& USER_ALL_ADMINCOMMENT
)
7804 Status
= SampSetObjectAttributeString(UserObject
,
7806 &Buffer
->All
.AdminComment
);
7807 if (!NT_SUCCESS(Status
))
7811 if (WhichFields
& USER_ALL_USERCOMMENT
)
7813 Status
= SampSetObjectAttributeString(UserObject
,
7815 &Buffer
->All
.UserComment
);
7816 if (!NT_SUCCESS(Status
))
7820 if (WhichFields
& USER_ALL_HOMEDIRECTORY
)
7822 Status
= SampSetObjectAttributeString(UserObject
,
7824 &Buffer
->All
.HomeDirectory
);
7825 if (!NT_SUCCESS(Status
))
7829 if (WhichFields
& USER_ALL_HOMEDIRECTORYDRIVE
)
7831 Status
= SampSetObjectAttributeString(UserObject
,
7832 L
"HomeDirectoryDrive",
7833 &Buffer
->All
.HomeDirectoryDrive
);
7834 if (!NT_SUCCESS(Status
))
7838 if (WhichFields
& USER_ALL_SCRIPTPATH
)
7840 Status
= SampSetObjectAttributeString(UserObject
,
7842 &Buffer
->All
.ScriptPath
);
7843 if (!NT_SUCCESS(Status
))
7847 if (WhichFields
& USER_ALL_PROFILEPATH
)
7849 Status
= SampSetObjectAttributeString(UserObject
,
7851 &Buffer
->All
.ProfilePath
);
7852 if (!NT_SUCCESS(Status
))
7856 if (WhichFields
& USER_ALL_WORKSTATIONS
)
7858 Status
= SampSetObjectAttributeString(UserObject
,
7860 &Buffer
->All
.WorkStations
);
7861 if (!NT_SUCCESS(Status
))
7865 if (WhichFields
& USER_ALL_PARAMETERS
)
7867 Status
= SampSetObjectAttributeString(UserObject
,
7869 &Buffer
->All
.Parameters
);
7870 if (!NT_SUCCESS(Status
))
7874 if (WhichFields
& USER_ALL_LOGONHOURS
)
7876 Status
= SampSetLogonHoursAttribute(UserObject
,
7877 &Buffer
->All
.LogonHours
);
7878 if (!NT_SUCCESS(Status
))
7882 if (WhichFields
& USER_ALL_PRIMARYGROUPID
)
7884 FixedData
.PrimaryGroupId
= Buffer
->All
.PrimaryGroupId
;
7885 WriteFixedData
= TRUE
;
7888 if (WhichFields
& USER_ALL_ACCOUNTEXPIRES
)
7890 FixedData
.AccountExpires
.LowPart
= Buffer
->All
.AccountExpires
.LowPart
;
7891 FixedData
.AccountExpires
.HighPart
= Buffer
->All
.AccountExpires
.HighPart
;
7892 WriteFixedData
= TRUE
;
7895 if (WhichFields
& USER_ALL_USERACCOUNTCONTROL
)
7897 FixedData
.UserAccountControl
= Buffer
->All
.UserAccountControl
;
7898 WriteFixedData
= TRUE
;
7901 if (WhichFields
& USER_ALL_COUNTRYCODE
)
7903 FixedData
.CountryCode
= Buffer
->All
.CountryCode
;
7904 WriteFixedData
= TRUE
;
7907 if (WhichFields
& USER_ALL_CODEPAGE
)
7909 FixedData
.CodePage
= Buffer
->All
.CodePage
;
7910 WriteFixedData
= TRUE
;
7913 if (WhichFields
& (USER_ALL_NTPASSWORDPRESENT
|
7914 USER_ALL_LMPASSWORDPRESENT
))
7916 if (WhichFields
& USER_ALL_NTPASSWORDPRESENT
)
7918 NtPassword
= (PENCRYPTED_NT_OWF_PASSWORD
)Buffer
->All
.NtOwfPassword
.Buffer
;
7919 NtPasswordPresent
= Buffer
->All
.NtPasswordPresent
;
7922 if (WhichFields
& USER_ALL_LMPASSWORDPRESENT
)
7924 LmPassword
= (PENCRYPTED_LM_OWF_PASSWORD
)Buffer
->All
.LmOwfPassword
.Buffer
;
7925 LmPasswordPresent
= Buffer
->All
.LmPasswordPresent
;
7928 Status
= SampSetUserPassword(UserObject
,
7933 if (!NT_SUCCESS(Status
))
7936 /* The password has just been set */
7937 Status
= NtQuerySystemTime(&FixedData
.PasswordLastSet
);
7938 if (!NT_SUCCESS(Status
))
7941 WriteFixedData
= TRUE
;
7944 if (WhichFields
& USER_ALL_PRIVATEDATA
)
7946 Status
= SampSetObjectAttributeString(UserObject
,
7948 &Buffer
->All
.PrivateData
);
7949 if (!NT_SUCCESS(Status
))
7953 if (WhichFields
& USER_ALL_PASSWORDEXPIRED
)
7955 if (Buffer
->All
.PasswordExpired
)
7957 /* The password was last set ages ago */
7958 FixedData
.PasswordLastSet
.LowPart
= 0;
7959 FixedData
.PasswordLastSet
.HighPart
= 0;
7963 /* The password was last set right now */
7964 Status
= NtQuerySystemTime(&FixedData
.PasswordLastSet
);
7965 if (!NT_SUCCESS(Status
))
7969 WriteFixedData
= TRUE
;
7972 if (WhichFields
& USER_ALL_SECURITYDESCRIPTOR
)
7974 Status
= SampSetObjectAttribute(UserObject
,
7977 Buffer
->All
.SecurityDescriptor
.SecurityDescriptor
,
7978 Buffer
->All
.SecurityDescriptor
.Length
);
7981 if (WriteFixedData
!= FALSE
)
7983 Status
= SampSetObjectAttribute(UserObject
,
7988 if (!NT_SUCCESS(Status
))
8000 SamrSetInformationUser(IN SAMPR_HANDLE UserHandle
,
8001 IN USER_INFORMATION_CLASS UserInformationClass
,
8002 IN PSAMPR_USER_INFO_BUFFER Buffer
)
8004 PSAM_DB_OBJECT UserObject
;
8005 ACCESS_MASK DesiredAccess
;
8008 TRACE("SamrSetInformationUser(%p %lu %p)\n",
8009 UserHandle
, UserInformationClass
, Buffer
);
8011 switch (UserInformationClass
)
8013 case UserLogonHoursInformation
:
8014 case UserNameInformation
:
8015 case UserAccountNameInformation
:
8016 case UserFullNameInformation
:
8017 case UserPrimaryGroupInformation
:
8018 case UserHomeInformation
:
8019 case UserScriptInformation
:
8020 case UserProfileInformation
:
8021 case UserAdminCommentInformation
:
8022 case UserWorkStationsInformation
:
8023 case UserControlInformation
:
8024 case UserExpiresInformation
:
8025 case UserParametersInformation
:
8026 DesiredAccess
= USER_WRITE_ACCOUNT
;
8029 case UserGeneralInformation
:
8030 DesiredAccess
= USER_WRITE_ACCOUNT
|
8031 USER_WRITE_PREFERENCES
;
8034 case UserPreferencesInformation
:
8035 DesiredAccess
= USER_WRITE_PREFERENCES
;
8038 case UserSetPasswordInformation
:
8039 case UserInternal1Information
:
8040 DesiredAccess
= USER_FORCE_PASSWORD_CHANGE
;
8043 case UserAllInformation
:
8044 DesiredAccess
= 0; /* FIXME */
8048 return STATUS_INVALID_INFO_CLASS
;
8051 RtlAcquireResourceExclusive(&SampResource
,
8054 /* Validate the domain handle */
8055 Status
= SampValidateDbObject(UserHandle
,
8059 if (!NT_SUCCESS(Status
))
8061 TRACE("failed with status 0x%08lx\n", Status
);
8065 switch (UserInformationClass
)
8067 case UserGeneralInformation
:
8068 Status
= SampSetUserGeneral(UserObject
,
8072 case UserPreferencesInformation
:
8073 Status
= SampSetUserPreferences(UserObject
,
8077 case UserLogonHoursInformation
:
8078 Status
= SampSetLogonHoursAttribute(UserObject
,
8079 &Buffer
->LogonHours
.LogonHours
);
8082 case UserNameInformation
:
8083 Status
= SampSetUserName(UserObject
,
8084 &Buffer
->Name
.UserName
);
8085 if (!NT_SUCCESS(Status
))
8088 Status
= SampSetObjectAttributeString(UserObject
,
8090 &Buffer
->Name
.FullName
);
8093 case UserAccountNameInformation
:
8094 Status
= SampSetUserName(UserObject
,
8095 &Buffer
->AccountName
.UserName
);
8098 case UserFullNameInformation
:
8099 Status
= SampSetObjectAttributeString(UserObject
,
8101 &Buffer
->FullName
.FullName
);
8104 case UserPrimaryGroupInformation
:
8105 Status
= SampSetUserPrimaryGroup(UserObject
,
8109 case UserHomeInformation
:
8110 Status
= SampSetObjectAttributeString(UserObject
,
8112 &Buffer
->Home
.HomeDirectory
);
8113 if (!NT_SUCCESS(Status
))
8116 Status
= SampSetObjectAttributeString(UserObject
,
8117 L
"HomeDirectoryDrive",
8118 &Buffer
->Home
.HomeDirectoryDrive
);
8121 case UserScriptInformation
:
8122 Status
= SampSetObjectAttributeString(UserObject
,
8124 &Buffer
->Script
.ScriptPath
);
8127 case UserProfileInformation
:
8128 Status
= SampSetObjectAttributeString(UserObject
,
8130 &Buffer
->Profile
.ProfilePath
);
8133 case UserAdminCommentInformation
:
8134 Status
= SampSetObjectAttributeString(UserObject
,
8136 &Buffer
->AdminComment
.AdminComment
);
8139 case UserWorkStationsInformation
:
8140 Status
= SampSetObjectAttributeString(UserObject
,
8142 &Buffer
->WorkStations
.WorkStations
);
8145 case UserSetPasswordInformation
:
8146 TRACE("Password: %S\n", Buffer
->SetPassword
.Password
.Buffer
);
8147 TRACE("PasswordExpired: %d\n", Buffer
->SetPassword
.PasswordExpired
);
8149 Status
= SampSetObjectAttributeString(UserObject
,
8151 &Buffer
->SetPassword
.Password
);
8154 case UserControlInformation
:
8155 Status
= SampSetUserControl(UserObject
,
8159 case UserExpiresInformation
:
8160 Status
= SampSetUserExpires(UserObject
,
8164 case UserInternal1Information
:
8165 Status
= SampSetUserInternal1(UserObject
,
8169 case UserParametersInformation
:
8170 Status
= SampSetObjectAttributeString(UserObject
,
8172 &Buffer
->Parameters
.Parameters
);
8175 case UserAllInformation
:
8176 Status
= SampSetUserAll(UserObject
,
8180 // case UserInternal4Information:
8181 // case UserInternal5Information:
8182 // case UserInternal4InformationNew:
8183 // case UserInternal5InformationNew:
8186 Status
= STATUS_INVALID_INFO_CLASS
;
8190 RtlReleaseResource(&SampResource
);
8199 SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle
,
8200 IN
unsigned char LmPresent
,
8201 IN PENCRYPTED_LM_OWF_PASSWORD OldLmEncryptedWithNewLm
,
8202 IN PENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithOldLm
,
8203 IN
unsigned char NtPresent
,
8204 IN PENCRYPTED_NT_OWF_PASSWORD OldNtEncryptedWithNewNt
,
8205 IN PENCRYPTED_NT_OWF_PASSWORD NewNtEncryptedWithOldNt
,
8206 IN
unsigned char NtCrossEncryptionPresent
,
8207 IN PENCRYPTED_NT_OWF_PASSWORD NewNtEncryptedWithNewLm
,
8208 IN
unsigned char LmCrossEncryptionPresent
,
8209 IN PENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithNewNt
)
8211 ENCRYPTED_LM_OWF_PASSWORD StoredLmPassword
;
8212 ENCRYPTED_NT_OWF_PASSWORD StoredNtPassword
;
8213 LM_OWF_PASSWORD OldLmPassword
;
8214 LM_OWF_PASSWORD NewLmPassword
;
8215 NT_OWF_PASSWORD OldNtPassword
;
8216 NT_OWF_PASSWORD NewNtPassword
;
8217 BOOLEAN StoredLmPresent
= FALSE
;
8218 BOOLEAN StoredNtPresent
= FALSE
;
8219 BOOLEAN StoredLmEmpty
= TRUE
;
8220 BOOLEAN StoredNtEmpty
= TRUE
;
8221 PSAM_DB_OBJECT UserObject
;
8223 SAM_USER_FIXED_DATA UserFixedData
;
8224 SAM_DOMAIN_FIXED_DATA DomainFixedData
;
8225 LARGE_INTEGER SystemTime
;
8228 DBG_UNREFERENCED_LOCAL_VARIABLE(StoredLmPresent
);
8229 DBG_UNREFERENCED_LOCAL_VARIABLE(StoredNtPresent
);
8230 DBG_UNREFERENCED_LOCAL_VARIABLE(StoredLmEmpty
);
8232 TRACE("(%p %u %p %p %u %p %p %u %p %u %p)\n",
8233 UserHandle
, LmPresent
, OldLmEncryptedWithNewLm
, NewLmEncryptedWithOldLm
,
8234 NtPresent
, OldNtEncryptedWithNewNt
, NewNtEncryptedWithOldNt
, NtCrossEncryptionPresent
,
8235 NewNtEncryptedWithNewLm
, LmCrossEncryptionPresent
, NewLmEncryptedWithNewNt
);
8237 RtlAcquireResourceExclusive(&SampResource
,
8240 /* Validate the user handle */
8241 Status
= SampValidateDbObject(UserHandle
,
8243 USER_CHANGE_PASSWORD
,
8245 if (!NT_SUCCESS(Status
))
8247 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
8251 /* Get the current time */
8252 Status
= NtQuerySystemTime(&SystemTime
);
8253 if (!NT_SUCCESS(Status
))
8255 TRACE("NtQuerySystemTime failed (Status 0x%08lx)\n", Status
);
8259 /* Retrieve the LM password */
8260 Length
= sizeof(ENCRYPTED_LM_OWF_PASSWORD
);
8261 Status
= SampGetObjectAttribute(UserObject
,
8266 if (NT_SUCCESS(Status
))
8268 if (Length
== sizeof(ENCRYPTED_LM_OWF_PASSWORD
))
8270 StoredLmPresent
= TRUE
;
8271 if (!RtlEqualMemory(&StoredLmPassword
,
8273 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
8274 StoredLmEmpty
= FALSE
;
8278 /* Retrieve the NT password */
8279 Length
= sizeof(ENCRYPTED_NT_OWF_PASSWORD
);
8280 Status
= SampGetObjectAttribute(UserObject
,
8285 if (NT_SUCCESS(Status
))
8287 if (Length
== sizeof(ENCRYPTED_NT_OWF_PASSWORD
))
8289 StoredNtPresent
= TRUE
;
8290 if (!RtlEqualMemory(&StoredNtPassword
,
8292 sizeof(ENCRYPTED_NT_OWF_PASSWORD
)))
8293 StoredNtEmpty
= FALSE
;
8297 /* Retrieve the fixed size user data */
8298 Length
= sizeof(SAM_USER_FIXED_DATA
);
8299 Status
= SampGetObjectAttribute(UserObject
,
8304 if (!NT_SUCCESS(Status
))
8306 TRACE("SampGetObjectAttribute failed to retrieve the fixed user data (Status 0x%08lx)\n", Status
);
8310 /* Check if we can change the password at this time */
8311 if ((StoredLmEmpty
== FALSE
) || (StoredNtEmpty
== FALSE
))
8313 /* Get fixed domain data */
8314 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
8315 Status
= SampGetObjectAttribute(UserObject
->ParentObject
,
8320 if (!NT_SUCCESS(Status
))
8322 TRACE("SampGetObjectAttribute failed to retrieve the fixed domain data (Status 0x%08lx)\n", Status
);
8326 if (DomainFixedData
.MinPasswordAge
.QuadPart
> 0)
8328 if (SystemTime
.QuadPart
< (UserFixedData
.PasswordLastSet
.QuadPart
+ DomainFixedData
.MinPasswordAge
.QuadPart
))
8330 Status
= STATUS_ACCOUNT_RESTRICTION
;
8336 /* Decrypt the LM passwords, if present */
8339 Status
= SystemFunction013((const BYTE
*)NewLmEncryptedWithOldLm
,
8340 (const BYTE
*)&StoredLmPassword
,
8341 (LPBYTE
)&NewLmPassword
);
8342 if (!NT_SUCCESS(Status
))
8344 TRACE("SystemFunction013 failed (Status 0x%08lx)\n", Status
);
8348 Status
= SystemFunction013((const BYTE
*)OldLmEncryptedWithNewLm
,
8349 (const BYTE
*)&NewLmPassword
,
8350 (LPBYTE
)&OldLmPassword
);
8351 if (!NT_SUCCESS(Status
))
8353 TRACE("SystemFunction013 failed (Status 0x%08lx)\n", Status
);
8358 /* Decrypt the NT passwords, if present */
8361 Status
= SystemFunction013((const BYTE
*)NewNtEncryptedWithOldNt
,
8362 (const BYTE
*)&StoredNtPassword
,
8363 (LPBYTE
)&NewNtPassword
);
8364 if (!NT_SUCCESS(Status
))
8366 TRACE("SystemFunction013 failed (Status 0x%08lx)\n", Status
);
8370 Status
= SystemFunction013((const BYTE
*)OldNtEncryptedWithNewNt
,
8371 (const BYTE
*)&NewNtPassword
,
8372 (LPBYTE
)&OldNtPassword
);
8373 if (!NT_SUCCESS(Status
))
8375 TRACE("SystemFunction013 failed (Status 0x%08lx)\n", Status
);
8380 /* Check if the old passwords match the stored ones */
8385 if (!RtlEqualMemory(&StoredLmPassword
,
8387 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
8389 TRACE("Old LM Password does not match!\n");
8390 Status
= STATUS_WRONG_PASSWORD
;
8394 if (!RtlEqualMemory(&StoredNtPassword
,
8396 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
8398 TRACE("Old NT Password does not match!\n");
8399 Status
= STATUS_WRONG_PASSWORD
;
8405 if (!RtlEqualMemory(&StoredNtPassword
,
8407 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
8409 TRACE("Old NT Password does not match!\n");
8410 Status
= STATUS_WRONG_PASSWORD
;
8418 if (!RtlEqualMemory(&StoredLmPassword
,
8420 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
8422 TRACE("Old LM Password does not match!\n");
8423 Status
= STATUS_WRONG_PASSWORD
;
8428 Status
= STATUS_INVALID_PARAMETER
;
8432 /* Store the new password hashes */
8433 if (NT_SUCCESS(Status
))
8435 Status
= SampSetUserPassword(UserObject
,
8440 if (NT_SUCCESS(Status
))
8442 /* Update PasswordLastSet */
8443 UserFixedData
.PasswordLastSet
.QuadPart
= SystemTime
.QuadPart
;
8445 /* Set the fixed size user data */
8446 Length
= sizeof(SAM_USER_FIXED_DATA
);
8447 Status
= SampSetObjectAttribute(UserObject
,
8455 if (Status
== STATUS_WRONG_PASSWORD
)
8457 /* Update BadPasswordCount and LastBadPasswordTime */
8458 UserFixedData
.BadPasswordCount
++;
8459 UserFixedData
.LastBadPasswordTime
.QuadPart
= SystemTime
.QuadPart
;
8461 /* Set the fixed size user data */
8462 Length
= sizeof(SAM_USER_FIXED_DATA
);
8463 Status
= SampSetObjectAttribute(UserObject
,
8471 RtlReleaseResource(&SampResource
);
8480 SamrGetGroupsForUser(IN SAMPR_HANDLE UserHandle
,
8481 OUT PSAMPR_GET_GROUPS_BUFFER
*Groups
)
8483 PSAMPR_GET_GROUPS_BUFFER GroupsBuffer
= NULL
;
8484 PSAM_DB_OBJECT UserObject
;
8488 TRACE("SamrGetGroupsForUser(%p %p)\n",
8489 UserHandle
, Groups
);
8491 RtlAcquireResourceShared(&SampResource
,
8494 /* Validate the user handle */
8495 Status
= SampValidateDbObject(UserHandle
,
8499 if (!NT_SUCCESS(Status
))
8501 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
8505 /* Allocate the groups buffer */
8506 GroupsBuffer
= midl_user_allocate(sizeof(SAMPR_GET_GROUPS_BUFFER
));
8507 if (GroupsBuffer
== NULL
)
8509 Status
= STATUS_INSUFFICIENT_RESOURCES
;
8514 * Get the size of the Groups attribute.
8515 * Do not check the status code because in case of an error
8516 * Length will be 0. And that is all we need.
8518 SampGetObjectAttribute(UserObject
,
8524 /* If there is no Groups attribute, return a groups buffer without an array */
8527 GroupsBuffer
->MembershipCount
= 0;
8528 GroupsBuffer
->Groups
= NULL
;
8530 *Groups
= GroupsBuffer
;
8532 Status
= STATUS_SUCCESS
;
8536 /* Allocate a buffer for the Groups attribute */
8537 GroupsBuffer
->Groups
= midl_user_allocate(Length
);
8538 if (GroupsBuffer
->Groups
== NULL
)
8540 Status
= STATUS_INSUFFICIENT_RESOURCES
;
8544 /* Retrieve the Grous attribute */
8545 Status
= SampGetObjectAttribute(UserObject
,
8548 GroupsBuffer
->Groups
,
8550 if (!NT_SUCCESS(Status
))
8552 TRACE("SampGetObjectAttribute failed with status 0x%08lx\n", Status
);
8556 /* Calculate the membership count */
8557 GroupsBuffer
->MembershipCount
= Length
/ sizeof(GROUP_MEMBERSHIP
);
8559 /* Return the groups buffer to the caller */
8560 *Groups
= GroupsBuffer
;
8563 if (!NT_SUCCESS(Status
))
8565 if (GroupsBuffer
!= NULL
)
8567 if (GroupsBuffer
->Groups
!= NULL
)
8568 midl_user_free(GroupsBuffer
->Groups
);
8570 midl_user_free(GroupsBuffer
);
8574 RtlReleaseResource(&SampResource
);
8583 SamrQueryDisplayInformation(IN SAMPR_HANDLE DomainHandle
,
8584 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
8585 IN
unsigned long Index
,
8586 IN
unsigned long EntryCount
,
8587 IN
unsigned long PreferredMaximumLength
,
8588 OUT
unsigned long *TotalAvailable
,
8589 OUT
unsigned long *TotalReturned
,
8590 OUT PSAMPR_DISPLAY_INFO_BUFFER Buffer
)
8593 return STATUS_NOT_IMPLEMENTED
;
8599 SamrGetDisplayEnumerationIndex(IN SAMPR_HANDLE DomainHandle
,
8600 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
8601 IN PRPC_UNICODE_STRING Prefix
,
8602 OUT
unsigned long *Index
)
8605 return STATUS_NOT_IMPLEMENTED
;
8611 SamrTestPrivateFunctionsDomain(IN SAMPR_HANDLE DomainHandle
)
8614 return STATUS_NOT_IMPLEMENTED
;
8620 SamrTestPrivateFunctionsUser(IN SAMPR_HANDLE UserHandle
)
8623 return STATUS_NOT_IMPLEMENTED
;
8630 SamrGetUserDomainPasswordInformation(IN SAMPR_HANDLE UserHandle
,
8631 OUT PUSER_DOMAIN_PASSWORD_INFORMATION PasswordInformation
)
8633 SAM_DOMAIN_FIXED_DATA DomainFixedData
;
8634 SAM_USER_FIXED_DATA UserFixedData
;
8635 PSAM_DB_OBJECT DomainObject
;
8636 PSAM_DB_OBJECT UserObject
;
8641 UserHandle
, PasswordInformation
);
8643 RtlAcquireResourceShared(&SampResource
,
8646 /* Validate the user handle */
8647 Status
= SampValidateDbObject(UserHandle
,
8651 if (!NT_SUCCESS(Status
))
8653 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
8657 /* Validate the domain object */
8658 Status
= SampValidateDbObject((SAMPR_HANDLE
)UserObject
->ParentObject
,
8660 DOMAIN_READ_PASSWORD_PARAMETERS
,
8662 if (!NT_SUCCESS(Status
))
8664 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
8668 /* Get fixed user data */
8669 Length
= sizeof(SAM_USER_FIXED_DATA
);
8670 Status
= SampGetObjectAttribute(UserObject
,
8673 (PVOID
)&UserFixedData
,
8675 if (!NT_SUCCESS(Status
))
8677 TRACE("SampGetObjectAttribute failed with status 0x%08lx\n", Status
);
8681 if ((UserObject
->RelativeId
== DOMAIN_USER_RID_KRBTGT
) ||
8682 (UserFixedData
.UserAccountControl
& (USER_INTERDOMAIN_TRUST_ACCOUNT
|
8683 USER_WORKSTATION_TRUST_ACCOUNT
|
8684 USER_SERVER_TRUST_ACCOUNT
)))
8686 PasswordInformation
->MinPasswordLength
= 0;
8687 PasswordInformation
->PasswordProperties
= 0;
8691 /* Get fixed domain data */
8692 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
8693 Status
= SampGetObjectAttribute(DomainObject
,
8696 (PVOID
)&DomainFixedData
,
8698 if (!NT_SUCCESS(Status
))
8700 TRACE("SampGetObjectAttribute failed with status 0x%08lx\n", Status
);
8704 PasswordInformation
->MinPasswordLength
= DomainFixedData
.MinPasswordLength
;
8705 PasswordInformation
->PasswordProperties
= DomainFixedData
.PasswordProperties
;
8709 RtlReleaseResource(&SampResource
);
8711 return STATUS_SUCCESS
;
8718 SamrRemoveMemberFromForeignDomain(IN SAMPR_HANDLE DomainHandle
,
8719 IN PRPC_SID MemberSid
)
8721 PSAM_DB_OBJECT DomainObject
;
8726 DomainHandle
, MemberSid
);
8728 RtlAcquireResourceExclusive(&SampResource
,
8731 /* Validate the domain object */
8732 Status
= SampValidateDbObject(DomainHandle
,
8736 if (!NT_SUCCESS(Status
))
8738 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
8742 /* Retrieve the RID from the MemberSID */
8743 Status
= SampGetRidFromSid((PSID
)MemberSid
,
8745 if (!NT_SUCCESS(Status
))
8747 TRACE("SampGetRidFromSid failed with status 0x%08lx\n", Status
);
8751 /* Fail, if the RID represents a special account */
8754 TRACE("Cannot remove a special account (RID: %lu)\n", Rid
);
8755 Status
= STATUS_SPECIAL_ACCOUNT
;
8759 /* Remove the member from all aliases in the domain */
8760 Status
= SampRemoveMemberFromAllAliases(DomainObject
,
8762 if (!NT_SUCCESS(Status
))
8764 TRACE("SampRemoveMemberFromAllAliases failed with status 0x%08lx\n", Status
);
8768 RtlReleaseResource(&SampResource
);
8777 SamrQueryInformationDomain2(IN SAMPR_HANDLE DomainHandle
,
8778 IN DOMAIN_INFORMATION_CLASS DomainInformationClass
,
8779 OUT PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
8781 TRACE("(%p %lu %p)\n", DomainHandle
, DomainInformationClass
, Buffer
);
8783 return SamrQueryInformationDomain(DomainHandle
,
8784 DomainInformationClass
,
8792 SamrQueryInformationUser2(IN SAMPR_HANDLE UserHandle
,
8793 IN USER_INFORMATION_CLASS UserInformationClass
,
8794 OUT PSAMPR_USER_INFO_BUFFER
*Buffer
)
8796 TRACE("(%p %lu %p)\n", UserHandle
, UserInformationClass
, Buffer
);
8798 return SamrQueryInformationUser(UserHandle
,
8799 UserInformationClass
,
8807 SamrQueryDisplayInformation2(IN SAMPR_HANDLE DomainHandle
,
8808 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
8809 IN
unsigned long Index
,
8810 IN
unsigned long EntryCount
,
8811 IN
unsigned long PreferredMaximumLength
,
8812 OUT
unsigned long *TotalAvailable
,
8813 OUT
unsigned long *TotalReturned
,
8814 OUT PSAMPR_DISPLAY_INFO_BUFFER Buffer
)
8816 TRACE("%p %lu %lu %lu %lu %p %p %p\n",
8817 DomainHandle
, DisplayInformationClass
, Index
,
8818 EntryCount
, PreferredMaximumLength
, TotalAvailable
,
8819 TotalReturned
, Buffer
);
8821 return SamrQueryDisplayInformation(DomainHandle
,
8822 DisplayInformationClass
,
8825 PreferredMaximumLength
,
8835 SamrGetDisplayEnumerationIndex2(IN SAMPR_HANDLE DomainHandle
,
8836 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
8837 IN PRPC_UNICODE_STRING Prefix
,
8838 OUT
unsigned long *Index
)
8840 TRACE("(%p %lu %p %p)\n",
8841 DomainHandle
, DisplayInformationClass
, Prefix
, Index
);
8843 return SamrGetDisplayEnumerationIndex(DomainHandle
,
8844 DisplayInformationClass
,
8853 SamrCreateUser2InDomain(IN SAMPR_HANDLE DomainHandle
,
8854 IN PRPC_UNICODE_STRING Name
,
8855 IN
unsigned long AccountType
,
8856 IN ACCESS_MASK DesiredAccess
,
8857 OUT SAMPR_HANDLE
*UserHandle
,
8858 OUT
unsigned long *GrantedAccess
,
8859 OUT
unsigned long *RelativeId
)
8861 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
8862 SAM_USER_FIXED_DATA FixedUserData
;
8863 PSAM_DB_OBJECT DomainObject
;
8864 PSAM_DB_OBJECT UserObject
;
8865 GROUP_MEMBERSHIP GroupMembership
;
8866 UCHAR LogonHours
[23];
8870 PSECURITY_DESCRIPTOR Sd
= NULL
;
8872 PSID UserSid
= NULL
;
8875 TRACE("SamrCreateUserInDomain(%p %p %lx %p %p)\n",
8876 DomainHandle
, Name
, DesiredAccess
, UserHandle
, RelativeId
);
8879 Name
->Length
== 0 ||
8880 Name
->Buffer
== NULL
||
8881 UserHandle
== NULL
||
8883 return STATUS_INVALID_PARAMETER
;
8885 /* Check for valid account type */
8886 if (AccountType
!= USER_NORMAL_ACCOUNT
&&
8887 AccountType
!= USER_WORKSTATION_TRUST_ACCOUNT
&&
8888 AccountType
!= USER_INTERDOMAIN_TRUST_ACCOUNT
&&
8889 AccountType
!= USER_SERVER_TRUST_ACCOUNT
&&
8890 AccountType
!= USER_TEMP_DUPLICATE_ACCOUNT
)
8891 return STATUS_INVALID_PARAMETER
;
8893 /* Map generic access rights */
8894 RtlMapGenericMask(&DesiredAccess
,
8897 RtlAcquireResourceExclusive(&SampResource
,
8900 /* Validate the domain handle */
8901 Status
= SampValidateDbObject(DomainHandle
,
8905 if (!NT_SUCCESS(Status
))
8907 TRACE("failed with status 0x%08lx\n", Status
);
8911 /* Check the user account name */
8912 Status
= SampCheckAccountName(Name
, 20);
8913 if (!NT_SUCCESS(Status
))
8915 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
8919 /* Check if the user name already exists in the domain */
8920 Status
= SampCheckAccountNameInDomain(DomainObject
,
8922 if (!NT_SUCCESS(Status
))
8924 TRACE("User name \'%S\' already exists in domain (Status 0x%08lx)\n",
8925 Name
->Buffer
, Status
);
8929 /* Get the fixed domain attributes */
8930 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
8931 Status
= SampGetObjectAttribute(DomainObject
,
8934 (PVOID
)&FixedDomainData
,
8936 if (!NT_SUCCESS(Status
))
8938 TRACE("failed with status 0x%08lx\n", Status
);
8942 /* Increment the NextRid attribute */
8943 ulRid
= FixedDomainData
.NextRid
;
8944 FixedDomainData
.NextRid
++;
8946 TRACE("RID: %lx\n", ulRid
);
8948 /* Create the user SID */
8949 Status
= SampCreateAccountSid(DomainObject
,
8952 if (!NT_SUCCESS(Status
))
8954 TRACE("SampCreateAccountSid failed (Status 0x%08lx)\n", Status
);
8958 /* Create the security descriptor */
8959 Status
= SampCreateUserSD(UserSid
,
8962 if (!NT_SUCCESS(Status
))
8964 TRACE("SampCreateUserSD failed (Status 0x%08lx)\n", Status
);
8968 /* Store the fixed domain attributes */
8969 Status
= SampSetObjectAttribute(DomainObject
,
8974 if (!NT_SUCCESS(Status
))
8976 TRACE("failed with status 0x%08lx\n", Status
);
8980 /* Convert the RID into a string (hex) */
8981 swprintf(szRid
, L
"%08lX", ulRid
);
8983 /* Create the user object */
8984 Status
= SampCreateDbObject(DomainObject
,
8991 if (!NT_SUCCESS(Status
))
8993 TRACE("failed with status 0x%08lx\n", Status
);
8997 /* Add the account name for the user object */
8998 Status
= SampSetAccountNameInDomain(DomainObject
,
9002 if (!NT_SUCCESS(Status
))
9004 TRACE("failed with status 0x%08lx\n", Status
);
9008 /* Initialize fixed user data */
9009 FixedUserData
.Version
= 1;
9010 FixedUserData
.Reserved
= 0;
9011 FixedUserData
.LastLogon
.QuadPart
= 0;
9012 FixedUserData
.LastLogoff
.QuadPart
= 0;
9013 FixedUserData
.PasswordLastSet
.QuadPart
= 0;
9014 FixedUserData
.AccountExpires
.LowPart
= MAXULONG
;
9015 FixedUserData
.AccountExpires
.HighPart
= MAXLONG
;
9016 FixedUserData
.LastBadPasswordTime
.QuadPart
= 0;
9017 FixedUserData
.UserId
= ulRid
;
9018 FixedUserData
.PrimaryGroupId
= DOMAIN_GROUP_RID_USERS
;
9019 FixedUserData
.UserAccountControl
= USER_ACCOUNT_DISABLED
|
9020 USER_PASSWORD_NOT_REQUIRED
|
9022 FixedUserData
.CountryCode
= 0;
9023 FixedUserData
.CodePage
= 0;
9024 FixedUserData
.BadPasswordCount
= 0;
9025 FixedUserData
.LogonCount
= 0;
9026 FixedUserData
.AdminCount
= 0;
9027 FixedUserData
.OperatorCount
= 0;
9029 /* Set fixed user data attribute */
9030 Status
= SampSetObjectAttribute(UserObject
,
9033 (LPVOID
)&FixedUserData
,
9034 sizeof(SAM_USER_FIXED_DATA
));
9035 if (!NT_SUCCESS(Status
))
9037 TRACE("failed with status 0x%08lx\n", Status
);
9041 /* Set the Name attribute */
9042 Status
= SampSetObjectAttributeString(UserObject
,
9045 if (!NT_SUCCESS(Status
))
9047 TRACE("failed with status 0x%08lx\n", Status
);
9051 /* Set the FullName attribute */
9052 Status
= SampSetObjectAttributeString(UserObject
,
9055 if (!NT_SUCCESS(Status
))
9057 TRACE("failed with status 0x%08lx\n", Status
);
9061 /* Set the HomeDirectory attribute */
9062 Status
= SampSetObjectAttributeString(UserObject
,
9065 if (!NT_SUCCESS(Status
))
9067 TRACE("failed with status 0x%08lx\n", Status
);
9071 /* Set the HomeDirectoryDrive attribute */
9072 Status
= SampSetObjectAttributeString(UserObject
,
9073 L
"HomeDirectoryDrive",
9075 if (!NT_SUCCESS(Status
))
9077 TRACE("failed with status 0x%08lx\n", Status
);
9081 /* Set the ScriptPath attribute */
9082 Status
= SampSetObjectAttributeString(UserObject
,
9085 if (!NT_SUCCESS(Status
))
9087 TRACE("failed with status 0x%08lx\n", Status
);
9091 /* Set the ProfilePath attribute */
9092 Status
= SampSetObjectAttributeString(UserObject
,
9095 if (!NT_SUCCESS(Status
))
9097 TRACE("failed with status 0x%08lx\n", Status
);
9101 /* Set the AdminComment attribute */
9102 Status
= SampSetObjectAttributeString(UserObject
,
9105 if (!NT_SUCCESS(Status
))
9107 TRACE("failed with status 0x%08lx\n", Status
);
9111 /* Set the UserComment attribute */
9112 Status
= SampSetObjectAttributeString(UserObject
,
9115 if (!NT_SUCCESS(Status
))
9117 TRACE("failed with status 0x%08lx\n", Status
);
9121 /* Set the WorkStations attribute */
9122 Status
= SampSetObjectAttributeString(UserObject
,
9125 if (!NT_SUCCESS(Status
))
9127 TRACE("failed with status 0x%08lx\n", Status
);
9131 /* Set the Parameters attribute */
9132 Status
= SampSetObjectAttributeString(UserObject
,
9135 if (!NT_SUCCESS(Status
))
9137 TRACE("failed with status 0x%08lx\n", Status
);
9141 /* Set LogonHours attribute*/
9142 *((PUSHORT
)LogonHours
) = 168;
9143 memset(&(LogonHours
[2]), 0xff, 21);
9145 Status
= SampSetObjectAttribute(UserObject
,
9149 sizeof(LogonHours
));
9150 if (!NT_SUCCESS(Status
))
9152 TRACE("failed with status 0x%08lx\n", Status
);
9156 /* Set Groups attribute*/
9157 GroupMembership
.RelativeId
= DOMAIN_GROUP_RID_USERS
;
9158 GroupMembership
.Attributes
= SE_GROUP_MANDATORY
|
9160 SE_GROUP_ENABLED_BY_DEFAULT
;
9162 Status
= SampSetObjectAttribute(UserObject
,
9166 sizeof(GROUP_MEMBERSHIP
));
9167 if (!NT_SUCCESS(Status
))
9169 TRACE("failed with status 0x%08lx\n", Status
);
9173 /* Set LMPwd attribute*/
9174 Status
= SampSetObjectAttribute(UserObject
,
9179 if (!NT_SUCCESS(Status
))
9181 TRACE("failed with status 0x%08lx\n", Status
);
9185 /* Set NTPwd attribute*/
9186 Status
= SampSetObjectAttribute(UserObject
,
9191 if (!NT_SUCCESS(Status
))
9193 TRACE("failed with status 0x%08lx\n", Status
);
9197 /* Set LMPwdHistory attribute*/
9198 Status
= SampSetObjectAttribute(UserObject
,
9203 if (!NT_SUCCESS(Status
))
9205 TRACE("failed with status 0x%08lx\n", Status
);
9209 /* Set NTPwdHistory attribute*/
9210 Status
= SampSetObjectAttribute(UserObject
,
9215 if (!NT_SUCCESS(Status
))
9217 TRACE("failed with status 0x%08lx\n", Status
);
9221 /* Set the PrivateData attribute */
9222 Status
= SampSetObjectAttributeString(UserObject
,
9225 if (!NT_SUCCESS(Status
))
9227 TRACE("failed with status 0x%08lx\n", Status
);
9231 /* Set the SecDesc attribute*/
9232 Status
= SampSetObjectAttribute(UserObject
,
9237 if (!NT_SUCCESS(Status
))
9239 TRACE("failed with status 0x%08lx\n", Status
);
9243 if (NT_SUCCESS(Status
))
9245 *UserHandle
= (SAMPR_HANDLE
)UserObject
;
9246 *RelativeId
= ulRid
;
9247 *GrantedAccess
= UserObject
->Access
;
9252 RtlFreeHeap(RtlGetProcessHeap(), 0, Sd
);
9254 if (UserSid
!= NULL
)
9255 RtlFreeHeap(RtlGetProcessHeap(), 0, UserSid
);
9257 RtlReleaseResource(&SampResource
);
9259 TRACE("returns with status 0x%08lx\n", Status
);
9268 SamrQueryDisplayInformation3(IN SAMPR_HANDLE DomainHandle
,
9269 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
9270 IN
unsigned long Index
,
9271 IN
unsigned long EntryCount
,
9272 IN
unsigned long PreferredMaximumLength
,
9273 OUT
unsigned long *TotalAvailable
,
9274 OUT
unsigned long *TotalReturned
,
9275 OUT PSAMPR_DISPLAY_INFO_BUFFER Buffer
)
9277 TRACE("%p %lu %lu %lu %lu %p %p %p\n",
9278 DomainHandle
, DisplayInformationClass
, Index
,
9279 EntryCount
, PreferredMaximumLength
, TotalAvailable
,
9280 TotalReturned
, Buffer
);
9282 return SamrQueryDisplayInformation(DomainHandle
,
9283 DisplayInformationClass
,
9286 PreferredMaximumLength
,
9296 SamrAddMultipleMembersToAlias(IN SAMPR_HANDLE AliasHandle
,
9297 IN PSAMPR_PSID_ARRAY MembersBuffer
)
9300 NTSTATUS Status
= STATUS_SUCCESS
;
9302 TRACE("SamrAddMultipleMembersToAlias(%p %p)\n",
9303 AliasHandle
, MembersBuffer
);
9305 for (i
= 0; i
< MembersBuffer
->Count
; i
++)
9307 Status
= SamrAddMemberToAlias(AliasHandle
,
9308 ((PSID
*)MembersBuffer
->Sids
)[i
]);
9310 if (Status
== STATUS_MEMBER_IN_ALIAS
)
9311 Status
= STATUS_SUCCESS
;
9313 if (!NT_SUCCESS(Status
))
9324 SamrRemoveMultipleMembersFromAlias(IN SAMPR_HANDLE AliasHandle
,
9325 IN PSAMPR_PSID_ARRAY MembersBuffer
)
9328 NTSTATUS Status
= STATUS_SUCCESS
;
9330 TRACE("SamrRemoveMultipleMembersFromAlias(%p %p)\n",
9331 AliasHandle
, MembersBuffer
);
9333 for (i
= 0; i
< MembersBuffer
->Count
; i
++)
9335 Status
= SamrRemoveMemberFromAlias(AliasHandle
,
9336 ((PSID
*)MembersBuffer
->Sids
)[i
]);
9338 if (Status
== STATUS_MEMBER_IN_ALIAS
)
9339 Status
= STATUS_SUCCESS
;
9341 if (!NT_SUCCESS(Status
))
9352 SamrOemChangePasswordUser2(IN handle_t BindingHandle
,
9353 IN PRPC_STRING ServerName
,
9354 IN PRPC_STRING UserName
,
9355 IN PSAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldLm
,
9356 IN PENCRYPTED_LM_OWF_PASSWORD OldLmOwfPasswordEncryptedWithNewLm
)
9359 return STATUS_NOT_IMPLEMENTED
;
9365 SamrUnicodeChangePasswordUser2(IN handle_t BindingHandle
,
9366 IN PRPC_UNICODE_STRING ServerName
,
9367 IN PRPC_UNICODE_STRING UserName
,
9368 IN PSAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldNt
,
9369 IN PENCRYPTED_NT_OWF_PASSWORD OldNtOwfPasswordEncryptedWithNewNt
,
9370 IN
unsigned char LmPresent
,
9371 IN PSAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldLm
,
9372 IN PENCRYPTED_LM_OWF_PASSWORD OldLmOwfPasswordEncryptedWithNewNt
)
9375 return STATUS_NOT_IMPLEMENTED
;
9382 SamrGetDomainPasswordInformation(IN handle_t BindingHandle
,
9383 IN PRPC_UNICODE_STRING Unused
,
9384 OUT PUSER_DOMAIN_PASSWORD_INFORMATION PasswordInformation
)
9386 SAMPR_HANDLE ServerHandle
= NULL
;
9387 PSAM_DB_OBJECT DomainObject
= NULL
;
9388 SAM_DOMAIN_FIXED_DATA FixedData
;
9392 TRACE("(%p %p %p)\n", BindingHandle
, Unused
, PasswordInformation
);
9394 Status
= SamrConnect(NULL
,
9396 SAM_SERVER_LOOKUP_DOMAIN
);
9397 if (!NT_SUCCESS(Status
))
9399 TRACE("SamrConnect() failed (Status 0x%08lx)\n", Status
);
9403 Status
= SampOpenDbObject((PSAM_DB_OBJECT
)ServerHandle
,
9408 DOMAIN_READ_PASSWORD_PARAMETERS
,
9410 if (!NT_SUCCESS(Status
))
9412 TRACE("SampOpenDbObject() failed (Status 0x%08lx)\n", Status
);
9416 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
9417 Status
= SampGetObjectAttribute(DomainObject
,
9422 if (!NT_SUCCESS(Status
))
9424 TRACE("SampGetObjectAttribute() failed (Status 0x%08lx)\n", Status
);
9428 PasswordInformation
->MinPasswordLength
= FixedData
.MinPasswordLength
;
9429 PasswordInformation
->PasswordProperties
= FixedData
.PasswordProperties
;
9432 if (DomainObject
!= NULL
)
9433 SampCloseDbObject(DomainObject
);
9435 if (ServerHandle
!= NULL
)
9436 SamrCloseHandle(ServerHandle
);
9445 SamrConnect2(IN PSAMPR_SERVER_NAME ServerName
,
9446 OUT SAMPR_HANDLE
*ServerHandle
,
9447 IN ACCESS_MASK DesiredAccess
)
9449 TRACE("(%p %p %lx)\n", ServerName
, ServerHandle
, DesiredAccess
);
9451 return SamrConnect(ServerName
,
9460 SamrSetInformationUser2(IN SAMPR_HANDLE UserHandle
,
9461 IN USER_INFORMATION_CLASS UserInformationClass
,
9462 IN PSAMPR_USER_INFO_BUFFER Buffer
)
9464 TRACE("(%p %lu %p)\n", UserHandle
, UserInformationClass
, Buffer
);
9466 return SamrSetInformationUser(UserHandle
,
9467 UserInformationClass
,
9475 SamrSetBootKeyInformation(IN handle_t BindingHandle
) /* FIXME */
9478 return STATUS_NOT_IMPLEMENTED
;
9484 SamrGetBootKeyInformation(IN handle_t BindingHandle
) /* FIXME */
9487 return STATUS_NOT_IMPLEMENTED
;
9493 SamrConnect3(IN handle_t BindingHandle
) /* FIXME */
9496 return STATUS_NOT_IMPLEMENTED
;
9502 SamrConnect4(IN PSAMPR_SERVER_NAME ServerName
,
9503 OUT SAMPR_HANDLE
*ServerHandle
,
9504 IN
unsigned long ClientRevision
,
9505 IN ACCESS_MASK DesiredAccess
)
9508 return STATUS_NOT_IMPLEMENTED
;
9514 SamrUnicodeChangePasswordUser3(IN handle_t BindingHandle
) /* FIXME */
9517 return STATUS_NOT_IMPLEMENTED
;
9523 SamrConnect5(IN PSAMPR_SERVER_NAME ServerName
,
9524 IN ACCESS_MASK DesiredAccess
,
9525 IN
unsigned long InVersion
,
9526 IN SAMPR_REVISION_INFO
*InRevisionInfo
,
9527 OUT
unsigned long *OutVersion
,
9528 OUT SAMPR_REVISION_INFO
*OutRevisionInfo
,
9529 OUT SAMPR_HANDLE
*ServerHandle
)
9532 return STATUS_NOT_IMPLEMENTED
;
9538 SamrRidToSid(IN SAMPR_HANDLE ObjectHandle
,
9539 IN
unsigned long Rid
,
9543 return STATUS_NOT_IMPLEMENTED
;
9549 SamrSetDSRMPassword(IN handle_t BindingHandle
,
9550 IN PRPC_UNICODE_STRING Unused
,
9551 IN
unsigned long UserId
,
9552 IN PENCRYPTED_NT_OWF_PASSWORD EncryptedNtOwfPassword
)
9555 return STATUS_NOT_IMPLEMENTED
;
9561 SamrValidatePassword(IN handle_t Handle
,
9562 IN PASSWORD_POLICY_VALIDATION_TYPE ValidationType
,
9563 IN PSAM_VALIDATE_INPUT_ARG InputArg
,
9564 OUT PSAM_VALIDATE_OUTPUT_ARG
*OutputArg
)
9567 return STATUS_NOT_IMPLEMENTED
;