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
10 /* INCLUDES ******************************************************************/
14 WINE_DEFAULT_DEBUG_CHANNEL(samsrv
);
16 /* GLOBALS *******************************************************************/
18 static SID_IDENTIFIER_AUTHORITY NtSidAuthority
= {SECURITY_NT_AUTHORITY
};
20 static GENERIC_MAPPING ServerMapping
=
28 static GENERIC_MAPPING DomainMapping
=
36 static GENERIC_MAPPING AliasMapping
=
44 static GENERIC_MAPPING GroupMapping
=
52 static GENERIC_MAPPING UserMapping
=
60 PGENERIC_MAPPING pServerMapping
= &ServerMapping
;
63 /* FUNCTIONS *****************************************************************/
67 SampAddRelativeTimeToTime(IN LARGE_INTEGER AbsoluteTime
,
68 IN LARGE_INTEGER RelativeTime
)
70 LARGE_INTEGER NewTime
;
72 NewTime
.QuadPart
= AbsoluteTime
.QuadPart
- RelativeTime
.QuadPart
;
74 if (NewTime
.QuadPart
< 0)
82 SampStartRpcServer(VOID
)
86 TRACE("SampStartRpcServer() called\n");
88 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
92 if (Status
!= RPC_S_OK
)
94 WARN("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
98 Status
= RpcServerRegisterIf(samr_v1_0_s_ifspec
,
101 if (Status
!= RPC_S_OK
)
103 WARN("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
107 Status
= RpcServerListen(1, 20, TRUE
);
108 if (Status
!= RPC_S_OK
)
110 WARN("RpcServerListen() failed (Status %lx)\n", Status
);
114 TRACE("SampStartRpcServer() done\n");
118 void __RPC_FAR
* __RPC_USER
midl_user_allocate(SIZE_T len
)
120 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
124 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
126 HeapFree(GetProcessHeap(), 0, ptr
);
130 void __RPC_USER
SAMPR_HANDLE_rundown(SAMPR_HANDLE hHandle
)
138 SamrConnect(IN PSAMPR_SERVER_NAME ServerName
,
139 OUT SAMPR_HANDLE
*ServerHandle
,
140 IN ACCESS_MASK DesiredAccess
)
142 PSAM_DB_OBJECT ServerObject
;
145 TRACE("SamrConnect(%p %p %lx)\n",
146 ServerName
, ServerHandle
, DesiredAccess
);
148 RtlAcquireResourceShared(&SampResource
,
151 /* Map generic access rights */
152 RtlMapGenericMask(&DesiredAccess
,
155 /* Open the Server Object */
156 Status
= SampOpenDbObject(NULL
,
163 if (NT_SUCCESS(Status
))
164 *ServerHandle
= (SAMPR_HANDLE
)ServerObject
;
166 RtlReleaseResource(&SampResource
);
168 TRACE("SamrConnect done (Status 0x%08lx)\n", Status
);
177 SamrCloseHandle(IN OUT SAMPR_HANDLE
*SamHandle
)
179 PSAM_DB_OBJECT DbObject
;
180 NTSTATUS Status
= STATUS_SUCCESS
;
182 TRACE("SamrCloseHandle(%p)\n", SamHandle
);
184 RtlAcquireResourceShared(&SampResource
,
187 Status
= SampValidateDbObject(*SamHandle
,
191 if (Status
== STATUS_SUCCESS
)
193 Status
= SampCloseDbObject(DbObject
);
197 RtlReleaseResource(&SampResource
);
199 TRACE("SamrCloseHandle done (Status 0x%08lx)\n", Status
);
208 SamrSetSecurityObject(IN SAMPR_HANDLE ObjectHandle
,
209 IN SECURITY_INFORMATION SecurityInformation
,
210 IN PSAMPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor
)
213 return STATUS_NOT_IMPLEMENTED
;
220 SamrQuerySecurityObject(IN SAMPR_HANDLE ObjectHandle
,
221 IN SECURITY_INFORMATION SecurityInformation
,
222 OUT PSAMPR_SR_SECURITY_DESCRIPTOR
*SecurityDescriptor
)
225 return STATUS_NOT_IMPLEMENTED
;
232 SamrShutdownSamServer(IN SAMPR_HANDLE ServerHandle
)
234 PSAM_DB_OBJECT ServerObject
;
237 TRACE("(%p)\n", ServerHandle
);
239 RtlAcquireResourceShared(&SampResource
,
242 /* Validate the server handle */
243 Status
= SampValidateDbObject(ServerHandle
,
248 RtlReleaseResource(&SampResource
);
250 if (!NT_SUCCESS(Status
))
253 /* Shut the server down */
254 RpcMgmtStopServerListening(0);
256 return STATUS_SUCCESS
;
263 SamrLookupDomainInSamServer(IN SAMPR_HANDLE ServerHandle
,
264 IN PRPC_UNICODE_STRING Name
,
265 OUT PRPC_SID
*DomainId
)
267 PSAM_DB_OBJECT ServerObject
;
268 HANDLE DomainsKeyHandle
= NULL
;
269 HANDLE DomainKeyHandle
= NULL
;
270 WCHAR DomainKeyName
[64];
272 WCHAR DomainNameString
[MAX_COMPUTERNAME_LENGTH
+ 1];
273 UNICODE_STRING DomainName
;
278 TRACE("SamrLookupDomainInSamServer(%p %p %p)\n",
279 ServerHandle
, Name
, DomainId
);
281 RtlAcquireResourceShared(&SampResource
,
284 /* Validate the server handle */
285 Status
= SampValidateDbObject(ServerHandle
,
287 SAM_SERVER_LOOKUP_DOMAIN
,
289 if (!NT_SUCCESS(Status
))
294 Status
= SampRegOpenKey(ServerObject
->KeyHandle
,
298 if (!NT_SUCCESS(Status
))
302 while (Found
== FALSE
)
304 Status
= SampRegEnumerateSubKey(DomainsKeyHandle
,
308 if (!NT_SUCCESS(Status
))
310 if (Status
== STATUS_NO_MORE_ENTRIES
)
311 Status
= STATUS_NO_SUCH_DOMAIN
;
315 TRACE("Domain key name: %S\n", DomainKeyName
);
317 Status
= SampRegOpenKey(DomainsKeyHandle
,
321 if (NT_SUCCESS(Status
))
323 Length
= (MAX_COMPUTERNAME_LENGTH
+ 1) * sizeof(WCHAR
);
324 Status
= SampRegQueryValue(DomainKeyHandle
,
327 (PVOID
)&DomainNameString
,
329 if (NT_SUCCESS(Status
))
331 TRACE("Domain name: %S\n", DomainNameString
);
333 RtlInitUnicodeString(&DomainName
,
335 if (RtlEqualUnicodeString(&DomainName
, (PUNICODE_STRING
)Name
, TRUE
))
337 TRACE("Found it!\n");
340 Status
= SampRegQueryValue(DomainKeyHandle
,
345 if (NT_SUCCESS(Status
))
347 *DomainId
= midl_user_allocate(Length
);
349 SampRegQueryValue(DomainKeyHandle
,
355 Status
= STATUS_SUCCESS
;
361 SampRegCloseKey(&DomainKeyHandle
);
368 SampRegCloseKey(&DomainKeyHandle
);
369 SampRegCloseKey(&DomainsKeyHandle
);
371 RtlReleaseResource(&SampResource
);
380 SamrEnumerateDomainsInSamServer(IN SAMPR_HANDLE ServerHandle
,
381 IN OUT
unsigned long *EnumerationContext
,
382 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
383 IN ULONG PreferedMaximumLength
,
384 OUT PULONG CountReturned
)
386 PSAM_DB_OBJECT ServerObject
;
387 WCHAR DomainKeyName
[64];
388 HANDLE DomainsKeyHandle
= NULL
;
389 HANDLE DomainKeyHandle
= NULL
;
392 ULONG RequiredLength
;
395 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
398 TRACE("SamrEnumerateDomainsInSamServer(%p %p %p %lu %p)\n",
399 ServerHandle
, EnumerationContext
, Buffer
, PreferedMaximumLength
,
402 RtlAcquireResourceShared(&SampResource
,
405 /* Validate the server handle */
406 Status
= SampValidateDbObject(ServerHandle
,
408 SAM_SERVER_ENUMERATE_DOMAINS
,
410 if (!NT_SUCCESS(Status
))
413 Status
= SampRegOpenKey(ServerObject
->KeyHandle
,
417 if (!NT_SUCCESS(Status
))
420 EnumIndex
= *EnumerationContext
;
426 Status
= SampRegEnumerateSubKey(DomainsKeyHandle
,
430 if (!NT_SUCCESS(Status
))
433 TRACE("EnumIndex: %lu\n", EnumIndex
);
434 TRACE("Domain key name: %S\n", DomainKeyName
);
436 Status
= SampRegOpenKey(DomainsKeyHandle
,
440 TRACE("SampRegOpenKey returned %08lX\n", Status
);
441 if (NT_SUCCESS(Status
))
444 Status
= SampRegQueryValue(DomainKeyHandle
,
449 TRACE("SampRegQueryValue returned %08lX\n", Status
);
450 if (NT_SUCCESS(Status
))
452 TRACE("Data length: %lu\n", DataLength
);
454 if ((RequiredLength
+ DataLength
+ sizeof(UNICODE_STRING
)) > PreferedMaximumLength
)
457 RequiredLength
+= (DataLength
+ sizeof(UNICODE_STRING
));
461 SampRegCloseKey(&DomainKeyHandle
);
467 TRACE("EnumCount: %lu\n", EnumCount
);
468 TRACE("RequiredLength: %lu\n", RequiredLength
);
470 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
471 if (EnumBuffer
== NULL
)
473 Status
= STATUS_INSUFFICIENT_RESOURCES
;
477 EnumBuffer
->EntriesRead
= EnumCount
;
478 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
479 if (EnumBuffer
->Buffer
== NULL
)
481 Status
= STATUS_INSUFFICIENT_RESOURCES
;
485 EnumIndex
= *EnumerationContext
;
486 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
488 Status
= SampRegEnumerateSubKey(DomainsKeyHandle
,
492 if (!NT_SUCCESS(Status
))
495 TRACE("EnumIndex: %lu\n", EnumIndex
);
496 TRACE("Domain key name: %S\n", DomainKeyName
);
498 Status
= SampRegOpenKey(DomainsKeyHandle
,
502 TRACE("SampRegOpenKey returned %08lX\n", Status
);
503 if (NT_SUCCESS(Status
))
506 Status
= SampRegQueryValue(DomainKeyHandle
,
511 TRACE("SampRegQueryValue returned %08lX\n", Status
);
512 if (NT_SUCCESS(Status
))
514 EnumBuffer
->Buffer
[i
].RelativeId
= 0;
515 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)DataLength
- sizeof(WCHAR
);
516 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)DataLength
;
517 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(DataLength
);
518 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
520 SampRegCloseKey(&DomainKeyHandle
);
521 Status
= STATUS_INSUFFICIENT_RESOURCES
;
525 Status
= SampRegQueryValue(DomainKeyHandle
,
528 EnumBuffer
->Buffer
[i
].Name
.Buffer
,
530 TRACE("SampRegQueryValue returned %08lX\n", Status
);
531 if (NT_SUCCESS(Status
))
533 TRACE("Domain name: %S\n", EnumBuffer
->Buffer
[i
].Name
.Buffer
);
537 SampRegCloseKey(&DomainKeyHandle
);
539 if (!NT_SUCCESS(Status
))
544 if (NT_SUCCESS(Status
))
546 *EnumerationContext
+= EnumCount
;
547 *Buffer
= EnumBuffer
;
548 *CountReturned
= EnumCount
;
552 SampRegCloseKey(&DomainKeyHandle
);
553 SampRegCloseKey(&DomainsKeyHandle
);
555 if (!NT_SUCCESS(Status
))
557 *EnumerationContext
= 0;
561 if (EnumBuffer
!= NULL
)
563 if (EnumBuffer
->Buffer
!= NULL
)
565 if (EnumBuffer
->EntriesRead
!= 0)
567 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
569 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
570 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
574 midl_user_free(EnumBuffer
->Buffer
);
577 midl_user_free(EnumBuffer
);
581 RtlReleaseResource(&SampResource
);
590 SamrOpenDomain(IN SAMPR_HANDLE ServerHandle
,
591 IN ACCESS_MASK DesiredAccess
,
592 IN PRPC_SID DomainId
,
593 OUT SAMPR_HANDLE
*DomainHandle
)
595 PSAM_DB_OBJECT ServerObject
;
596 PSAM_DB_OBJECT DomainObject
;
599 TRACE("SamrOpenDomain(%p %lx %p %p)\n",
600 ServerHandle
, DesiredAccess
, DomainId
, DomainHandle
);
602 /* Map generic access rights */
603 RtlMapGenericMask(&DesiredAccess
,
606 RtlAcquireResourceShared(&SampResource
,
609 /* Validate the server handle */
610 Status
= SampValidateDbObject(ServerHandle
,
612 SAM_SERVER_LOOKUP_DOMAIN
,
614 if (!NT_SUCCESS(Status
))
617 /* Validate the Domain SID */
618 if ((DomainId
->Revision
!= SID_REVISION
) ||
619 (DomainId
->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
) ||
620 (memcmp(&DomainId
->IdentifierAuthority
, &NtSidAuthority
, sizeof(SID_IDENTIFIER_AUTHORITY
)) != 0))
621 return STATUS_INVALID_PARAMETER
;
623 /* Open the domain object */
624 if ((DomainId
->SubAuthorityCount
== 1) &&
625 (DomainId
->SubAuthority
[0] == SECURITY_BUILTIN_DOMAIN_RID
))
627 /* Builtin domain object */
628 TRACE("Opening the builtin domain object.\n");
630 Status
= SampOpenDbObject(ServerObject
,
638 else if ((DomainId
->SubAuthorityCount
== 4) &&
639 (DomainId
->SubAuthority
[0] == SECURITY_NT_NON_UNIQUE
))
641 /* Account domain object */
642 TRACE("Opening the account domain object.\n");
644 /* FIXME: Check the account domain sub authorities!!! */
646 Status
= SampOpenDbObject(ServerObject
,
656 /* No vaild domain SID */
657 Status
= STATUS_INVALID_PARAMETER
;
660 if (NT_SUCCESS(Status
))
661 *DomainHandle
= (SAMPR_HANDLE
)DomainObject
;
663 RtlReleaseResource(&SampResource
);
665 TRACE("SamrOpenDomain done (Status 0x%08lx)\n", Status
);
672 SampQueryDomainPassword(PSAM_DB_OBJECT DomainObject
,
673 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
675 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
676 SAM_DOMAIN_FIXED_DATA FixedData
;
682 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
683 if (InfoBuffer
== NULL
)
684 return STATUS_INSUFFICIENT_RESOURCES
;
686 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
687 Status
= SampGetObjectAttribute(DomainObject
,
692 if (!NT_SUCCESS(Status
))
695 InfoBuffer
->Password
.MinPasswordLength
= FixedData
.MinPasswordLength
;
696 InfoBuffer
->Password
.PasswordHistoryLength
= FixedData
.PasswordHistoryLength
;
697 InfoBuffer
->Password
.PasswordProperties
= FixedData
.PasswordProperties
;
698 InfoBuffer
->Password
.MaxPasswordAge
.LowPart
= FixedData
.MaxPasswordAge
.LowPart
;
699 InfoBuffer
->Password
.MaxPasswordAge
.HighPart
= FixedData
.MaxPasswordAge
.HighPart
;
700 InfoBuffer
->Password
.MinPasswordAge
.LowPart
= FixedData
.MinPasswordAge
.LowPart
;
701 InfoBuffer
->Password
.MinPasswordAge
.HighPart
= FixedData
.MinPasswordAge
.HighPart
;
703 *Buffer
= InfoBuffer
;
706 if (!NT_SUCCESS(Status
))
708 if (InfoBuffer
!= NULL
)
710 midl_user_free(InfoBuffer
);
719 SampGetNumberOfAccounts(PSAM_DB_OBJECT DomainObject
,
723 HANDLE AccountKeyHandle
= NULL
;
724 HANDLE NamesKeyHandle
= NULL
;
729 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
733 if (!NT_SUCCESS(Status
))
736 Status
= SampRegOpenKey(AccountKeyHandle
,
740 if (!NT_SUCCESS(Status
))
743 Status
= SampRegQueryKeyInfo(NamesKeyHandle
,
748 SampRegCloseKey(&NamesKeyHandle
);
749 SampRegCloseKey(&AccountKeyHandle
);
756 SampQueryDomainGeneral(PSAM_DB_OBJECT DomainObject
,
757 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
759 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
760 SAM_DOMAIN_FIXED_DATA FixedData
;
766 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
767 if (InfoBuffer
== NULL
)
768 return STATUS_INSUFFICIENT_RESOURCES
;
770 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
771 Status
= SampGetObjectAttribute(DomainObject
,
776 if (!NT_SUCCESS(Status
))
779 InfoBuffer
->General
.ForceLogoff
.LowPart
= FixedData
.ForceLogoff
.LowPart
;
780 InfoBuffer
->General
.ForceLogoff
.HighPart
= FixedData
.ForceLogoff
.HighPart
;
781 InfoBuffer
->General
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
782 InfoBuffer
->General
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
783 InfoBuffer
->General
.DomainServerState
= FixedData
.DomainServerState
;
784 InfoBuffer
->General
.DomainServerRole
= FixedData
.DomainServerRole
;
785 InfoBuffer
->General
.UasCompatibilityRequired
= FixedData
.UasCompatibilityRequired
;
787 /* Get the OemInformation string */
788 Status
= SampGetObjectAttributeString(DomainObject
,
790 &InfoBuffer
->General
.OemInformation
);
791 if (!NT_SUCCESS(Status
))
793 TRACE("Status 0x%08lx\n", Status
);
797 /* Get the Name string */
798 Status
= SampGetObjectAttributeString(DomainObject
,
800 &InfoBuffer
->General
.DomainName
);
801 if (!NT_SUCCESS(Status
))
803 TRACE("Status 0x%08lx\n", Status
);
807 /* Get the ReplicaSourceNodeName string */
808 Status
= SampGetObjectAttributeString(DomainObject
,
809 L
"ReplicaSourceNodeName",
810 &InfoBuffer
->General
.ReplicaSourceNodeName
);
811 if (!NT_SUCCESS(Status
))
813 TRACE("Status 0x%08lx\n", Status
);
817 /* Get the number of Users in the Domain */
818 Status
= SampGetNumberOfAccounts(DomainObject
,
820 &InfoBuffer
->General
.UserCount
);
821 if (!NT_SUCCESS(Status
))
823 TRACE("Status 0x%08lx\n", Status
);
827 /* Get the number of Groups in the Domain */
828 Status
= SampGetNumberOfAccounts(DomainObject
,
830 &InfoBuffer
->General
.GroupCount
);
831 if (!NT_SUCCESS(Status
))
833 TRACE("Status 0x%08lx\n", Status
);
837 /* Get the number of Aliases in the Domain */
838 Status
= SampGetNumberOfAccounts(DomainObject
,
840 &InfoBuffer
->General
.AliasCount
);
841 if (!NT_SUCCESS(Status
))
843 TRACE("Status 0x%08lx\n", Status
);
847 *Buffer
= InfoBuffer
;
850 if (!NT_SUCCESS(Status
))
852 if (InfoBuffer
!= NULL
)
854 if (InfoBuffer
->General
.OemInformation
.Buffer
!= NULL
)
855 midl_user_free(InfoBuffer
->General
.OemInformation
.Buffer
);
857 if (InfoBuffer
->General
.DomainName
.Buffer
!= NULL
)
858 midl_user_free(InfoBuffer
->General
.DomainName
.Buffer
);
860 if (InfoBuffer
->General
.ReplicaSourceNodeName
.Buffer
!= NULL
)
861 midl_user_free(InfoBuffer
->General
.ReplicaSourceNodeName
.Buffer
);
863 midl_user_free(InfoBuffer
);
872 SampQueryDomainLogoff(PSAM_DB_OBJECT DomainObject
,
873 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
875 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
876 SAM_DOMAIN_FIXED_DATA FixedData
;
882 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
883 if (InfoBuffer
== NULL
)
884 return STATUS_INSUFFICIENT_RESOURCES
;
886 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
887 Status
= SampGetObjectAttribute(DomainObject
,
892 if (!NT_SUCCESS(Status
))
895 InfoBuffer
->Logoff
.ForceLogoff
.LowPart
= FixedData
.ForceLogoff
.LowPart
;
896 InfoBuffer
->Logoff
.ForceLogoff
.HighPart
= FixedData
.ForceLogoff
.HighPart
;
898 *Buffer
= InfoBuffer
;
901 if (!NT_SUCCESS(Status
))
903 if (InfoBuffer
!= NULL
)
905 midl_user_free(InfoBuffer
);
914 SampQueryDomainOem(PSAM_DB_OBJECT DomainObject
,
915 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
917 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
922 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
923 if (InfoBuffer
== NULL
)
924 return STATUS_INSUFFICIENT_RESOURCES
;
926 /* Get the OemInformation string */
927 Status
= SampGetObjectAttributeString(DomainObject
,
929 &InfoBuffer
->Oem
.OemInformation
);
930 if (!NT_SUCCESS(Status
))
932 TRACE("Status 0x%08lx\n", Status
);
936 *Buffer
= InfoBuffer
;
939 if (!NT_SUCCESS(Status
))
941 if (InfoBuffer
!= NULL
)
943 if (InfoBuffer
->Oem
.OemInformation
.Buffer
!= NULL
)
944 midl_user_free(InfoBuffer
->Oem
.OemInformation
.Buffer
);
946 midl_user_free(InfoBuffer
);
955 SampQueryDomainName(PSAM_DB_OBJECT DomainObject
,
956 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
958 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
963 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
964 if (InfoBuffer
== NULL
)
965 return STATUS_INSUFFICIENT_RESOURCES
;
967 /* Get the Name string */
968 Status
= SampGetObjectAttributeString(DomainObject
,
970 &InfoBuffer
->Name
.DomainName
);
971 if (!NT_SUCCESS(Status
))
973 TRACE("Status 0x%08lx\n", Status
);
977 *Buffer
= InfoBuffer
;
980 if (!NT_SUCCESS(Status
))
982 if (InfoBuffer
!= NULL
)
984 if (InfoBuffer
->Name
.DomainName
.Buffer
!= NULL
)
985 midl_user_free(InfoBuffer
->Name
.DomainName
.Buffer
);
987 midl_user_free(InfoBuffer
);
996 SampQueryDomainReplication(PSAM_DB_OBJECT DomainObject
,
997 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
999 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1004 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1005 if (InfoBuffer
== NULL
)
1006 return STATUS_INSUFFICIENT_RESOURCES
;
1008 /* Get the ReplicaSourceNodeName string */
1009 Status
= SampGetObjectAttributeString(DomainObject
,
1010 L
"ReplicaSourceNodeName",
1011 &InfoBuffer
->Replication
.ReplicaSourceNodeName
);
1012 if (!NT_SUCCESS(Status
))
1014 TRACE("Status 0x%08lx\n", Status
);
1018 *Buffer
= InfoBuffer
;
1021 if (!NT_SUCCESS(Status
))
1023 if (InfoBuffer
!= NULL
)
1025 if (InfoBuffer
->Replication
.ReplicaSourceNodeName
.Buffer
!= NULL
)
1026 midl_user_free(InfoBuffer
->Replication
.ReplicaSourceNodeName
.Buffer
);
1028 midl_user_free(InfoBuffer
);
1037 SampQueryDomainServerRole(PSAM_DB_OBJECT DomainObject
,
1038 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1040 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1041 SAM_DOMAIN_FIXED_DATA FixedData
;
1047 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1048 if (InfoBuffer
== NULL
)
1049 return STATUS_INSUFFICIENT_RESOURCES
;
1051 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1052 Status
= SampGetObjectAttribute(DomainObject
,
1057 if (!NT_SUCCESS(Status
))
1060 InfoBuffer
->Role
.DomainServerRole
= FixedData
.DomainServerRole
;
1062 *Buffer
= InfoBuffer
;
1065 if (!NT_SUCCESS(Status
))
1067 if (InfoBuffer
!= NULL
)
1069 midl_user_free(InfoBuffer
);
1078 SampQueryDomainModified(PSAM_DB_OBJECT DomainObject
,
1079 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1081 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1082 SAM_DOMAIN_FIXED_DATA FixedData
;
1088 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1089 if (InfoBuffer
== NULL
)
1090 return STATUS_INSUFFICIENT_RESOURCES
;
1092 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1093 Status
= SampGetObjectAttribute(DomainObject
,
1098 if (!NT_SUCCESS(Status
))
1101 InfoBuffer
->Modified
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
1102 InfoBuffer
->Modified
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
1103 InfoBuffer
->Modified
.CreationTime
.LowPart
= FixedData
.CreationTime
.LowPart
;
1104 InfoBuffer
->Modified
.CreationTime
.HighPart
= FixedData
.CreationTime
.HighPart
;
1106 *Buffer
= InfoBuffer
;
1109 if (!NT_SUCCESS(Status
))
1111 if (InfoBuffer
!= NULL
)
1113 midl_user_free(InfoBuffer
);
1122 SampQueryDomainState(PSAM_DB_OBJECT DomainObject
,
1123 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1125 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1126 SAM_DOMAIN_FIXED_DATA FixedData
;
1132 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1133 if (InfoBuffer
== NULL
)
1134 return STATUS_INSUFFICIENT_RESOURCES
;
1136 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1137 Status
= SampGetObjectAttribute(DomainObject
,
1142 if (!NT_SUCCESS(Status
))
1145 InfoBuffer
->State
.DomainServerState
= FixedData
.DomainServerState
;
1147 *Buffer
= InfoBuffer
;
1150 if (!NT_SUCCESS(Status
))
1152 if (InfoBuffer
!= NULL
)
1154 midl_user_free(InfoBuffer
);
1163 SampQueryDomainGeneral2(PSAM_DB_OBJECT DomainObject
,
1164 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1166 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1167 SAM_DOMAIN_FIXED_DATA FixedData
;
1173 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1174 if (InfoBuffer
== NULL
)
1175 return STATUS_INSUFFICIENT_RESOURCES
;
1177 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1178 Status
= SampGetObjectAttribute(DomainObject
,
1183 if (!NT_SUCCESS(Status
))
1186 InfoBuffer
->General2
.I1
.ForceLogoff
.LowPart
= FixedData
.ForceLogoff
.LowPart
;
1187 InfoBuffer
->General2
.I1
.ForceLogoff
.HighPart
= FixedData
.ForceLogoff
.HighPart
;
1188 InfoBuffer
->General2
.I1
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
1189 InfoBuffer
->General2
.I1
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
1190 InfoBuffer
->General2
.I1
.DomainServerState
= FixedData
.DomainServerState
;
1191 InfoBuffer
->General2
.I1
.DomainServerRole
= FixedData
.DomainServerRole
;
1192 InfoBuffer
->General2
.I1
.UasCompatibilityRequired
= FixedData
.UasCompatibilityRequired
;
1194 InfoBuffer
->General2
.LockoutDuration
= FixedData
.LockoutDuration
;
1195 InfoBuffer
->General2
.LockoutObservationWindow
= FixedData
.LockoutObservationWindow
;
1196 InfoBuffer
->General2
.LockoutThreshold
= FixedData
.LockoutThreshold
;
1198 /* Get the OemInformation string */
1199 Status
= SampGetObjectAttributeString(DomainObject
,
1201 &InfoBuffer
->General2
.I1
.OemInformation
);
1202 if (!NT_SUCCESS(Status
))
1204 TRACE("Status 0x%08lx\n", Status
);
1208 /* Get the Name string */
1209 Status
= SampGetObjectAttributeString(DomainObject
,
1211 &InfoBuffer
->General2
.I1
.DomainName
);
1212 if (!NT_SUCCESS(Status
))
1214 TRACE("Status 0x%08lx\n", Status
);
1218 /* Get the ReplicaSourceNodeName string */
1219 Status
= SampGetObjectAttributeString(DomainObject
,
1220 L
"ReplicaSourceNodeName",
1221 &InfoBuffer
->General2
.I1
.ReplicaSourceNodeName
);
1222 if (!NT_SUCCESS(Status
))
1224 TRACE("Status 0x%08lx\n", Status
);
1228 /* Get the number of Users in the Domain */
1229 Status
= SampGetNumberOfAccounts(DomainObject
,
1231 &InfoBuffer
->General2
.I1
.UserCount
);
1232 if (!NT_SUCCESS(Status
))
1234 TRACE("Status 0x%08lx\n", Status
);
1238 /* Get the number of Groups in the Domain */
1239 Status
= SampGetNumberOfAccounts(DomainObject
,
1241 &InfoBuffer
->General2
.I1
.GroupCount
);
1242 if (!NT_SUCCESS(Status
))
1244 TRACE("Status 0x%08lx\n", Status
);
1248 /* Get the number of Aliases in the Domain */
1249 Status
= SampGetNumberOfAccounts(DomainObject
,
1251 &InfoBuffer
->General2
.I1
.AliasCount
);
1252 if (!NT_SUCCESS(Status
))
1254 TRACE("Status 0x%08lx\n", Status
);
1258 *Buffer
= InfoBuffer
;
1261 if (!NT_SUCCESS(Status
))
1263 if (InfoBuffer
!= NULL
)
1265 if (InfoBuffer
->General2
.I1
.OemInformation
.Buffer
!= NULL
)
1266 midl_user_free(InfoBuffer
->General2
.I1
.OemInformation
.Buffer
);
1268 if (InfoBuffer
->General2
.I1
.DomainName
.Buffer
!= NULL
)
1269 midl_user_free(InfoBuffer
->General2
.I1
.DomainName
.Buffer
);
1271 if (InfoBuffer
->General2
.I1
.ReplicaSourceNodeName
.Buffer
!= NULL
)
1272 midl_user_free(InfoBuffer
->General2
.I1
.ReplicaSourceNodeName
.Buffer
);
1274 midl_user_free(InfoBuffer
);
1283 SampQueryDomainLockout(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
->Lockout
.LockoutDuration
= FixedData
.LockoutDuration
;
1307 InfoBuffer
->Lockout
.LockoutObservationWindow
= FixedData
.LockoutObservationWindow
;
1308 InfoBuffer
->Lockout
.LockoutThreshold
= FixedData
.LockoutThreshold
;
1310 *Buffer
= InfoBuffer
;
1313 if (!NT_SUCCESS(Status
))
1315 if (InfoBuffer
!= NULL
)
1317 midl_user_free(InfoBuffer
);
1326 SampQueryDomainModified2(PSAM_DB_OBJECT DomainObject
,
1327 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1329 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1330 SAM_DOMAIN_FIXED_DATA FixedData
;
1336 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1337 if (InfoBuffer
== NULL
)
1338 return STATUS_INSUFFICIENT_RESOURCES
;
1340 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1341 Status
= SampGetObjectAttribute(DomainObject
,
1346 if (!NT_SUCCESS(Status
))
1349 InfoBuffer
->Modified2
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
1350 InfoBuffer
->Modified2
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
1351 InfoBuffer
->Modified2
.CreationTime
.LowPart
= FixedData
.CreationTime
.LowPart
;
1352 InfoBuffer
->Modified2
.CreationTime
.HighPart
= FixedData
.CreationTime
.HighPart
;
1353 InfoBuffer
->Modified2
.ModifiedCountAtLastPromotion
.LowPart
= FixedData
.ModifiedCountAtLastPromotion
.LowPart
;
1354 InfoBuffer
->Modified2
.ModifiedCountAtLastPromotion
.HighPart
= FixedData
.ModifiedCountAtLastPromotion
.HighPart
;
1356 *Buffer
= InfoBuffer
;
1359 if (!NT_SUCCESS(Status
))
1361 if (InfoBuffer
!= NULL
)
1363 midl_user_free(InfoBuffer
);
1374 SamrQueryInformationDomain(IN SAMPR_HANDLE DomainHandle
,
1375 IN DOMAIN_INFORMATION_CLASS DomainInformationClass
,
1376 OUT PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1378 PSAM_DB_OBJECT DomainObject
;
1379 ACCESS_MASK DesiredAccess
;
1382 TRACE("SamrQueryInformationDomain(%p %lu %p)\n",
1383 DomainHandle
, DomainInformationClass
, Buffer
);
1385 switch (DomainInformationClass
)
1387 case DomainPasswordInformation
:
1388 case DomainLockoutInformation
:
1389 DesiredAccess
= DOMAIN_READ_PASSWORD_PARAMETERS
;
1392 case DomainGeneralInformation
:
1393 case DomainLogoffInformation
:
1394 case DomainOemInformation
:
1395 case DomainNameInformation
:
1396 case DomainReplicationInformation
:
1397 case DomainServerRoleInformation
:
1398 case DomainModifiedInformation
:
1399 case DomainStateInformation
:
1400 case DomainModifiedInformation2
:
1401 DesiredAccess
= DOMAIN_READ_OTHER_PARAMETERS
;
1404 case DomainGeneralInformation2
:
1405 DesiredAccess
= DOMAIN_READ_PASSWORD_PARAMETERS
|
1406 DOMAIN_READ_OTHER_PARAMETERS
;
1410 return STATUS_INVALID_INFO_CLASS
;
1413 RtlAcquireResourceShared(&SampResource
,
1416 /* Validate the server handle */
1417 Status
= SampValidateDbObject(DomainHandle
,
1421 if (!NT_SUCCESS(Status
))
1424 switch (DomainInformationClass
)
1426 case DomainPasswordInformation
:
1427 Status
= SampQueryDomainPassword(DomainObject
,
1431 case DomainGeneralInformation
:
1432 Status
= SampQueryDomainGeneral(DomainObject
,
1436 case DomainLogoffInformation
:
1437 Status
= SampQueryDomainLogoff(DomainObject
,
1441 case DomainOemInformation
:
1442 Status
= SampQueryDomainOem(DomainObject
,
1446 case DomainNameInformation
:
1447 Status
= SampQueryDomainName(DomainObject
,
1451 case DomainReplicationInformation
:
1452 Status
= SampQueryDomainReplication(DomainObject
,
1456 case DomainServerRoleInformation
:
1457 Status
= SampQueryDomainServerRole(DomainObject
,
1461 case DomainModifiedInformation
:
1462 Status
= SampQueryDomainModified(DomainObject
,
1466 case DomainStateInformation
:
1467 Status
= SampQueryDomainState(DomainObject
,
1471 case DomainGeneralInformation2
:
1472 Status
= SampQueryDomainGeneral2(DomainObject
,
1476 case DomainLockoutInformation
:
1477 Status
= SampQueryDomainLockout(DomainObject
,
1481 case DomainModifiedInformation2
:
1482 Status
= SampQueryDomainModified2(DomainObject
,
1487 Status
= STATUS_NOT_IMPLEMENTED
;
1491 RtlReleaseResource(&SampResource
);
1498 SampSetDomainPassword(PSAM_DB_OBJECT DomainObject
,
1499 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1501 SAM_DOMAIN_FIXED_DATA FixedData
;
1505 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1506 Status
= SampGetObjectAttribute(DomainObject
,
1511 if (!NT_SUCCESS(Status
))
1514 FixedData
.MinPasswordLength
= Buffer
->Password
.MinPasswordLength
;
1515 FixedData
.PasswordHistoryLength
= Buffer
->Password
.PasswordHistoryLength
;
1516 FixedData
.PasswordProperties
= Buffer
->Password
.PasswordProperties
;
1517 FixedData
.MaxPasswordAge
.LowPart
= Buffer
->Password
.MaxPasswordAge
.LowPart
;
1518 FixedData
.MaxPasswordAge
.HighPart
= Buffer
->Password
.MaxPasswordAge
.HighPart
;
1519 FixedData
.MinPasswordAge
.LowPart
= Buffer
->Password
.MinPasswordAge
.LowPart
;
1520 FixedData
.MinPasswordAge
.HighPart
= Buffer
->Password
.MinPasswordAge
.HighPart
;
1522 Status
= SampSetObjectAttribute(DomainObject
,
1534 SampSetDomainLogoff(PSAM_DB_OBJECT DomainObject
,
1535 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1537 SAM_DOMAIN_FIXED_DATA FixedData
;
1541 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1542 Status
= SampGetObjectAttribute(DomainObject
,
1547 if (!NT_SUCCESS(Status
))
1550 FixedData
.ForceLogoff
.LowPart
= Buffer
->Logoff
.ForceLogoff
.LowPart
;
1551 FixedData
.ForceLogoff
.HighPart
= Buffer
->Logoff
.ForceLogoff
.HighPart
;
1553 Status
= SampSetObjectAttribute(DomainObject
,
1565 SampSetDomainServerRole(PSAM_DB_OBJECT DomainObject
,
1566 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1568 SAM_DOMAIN_FIXED_DATA FixedData
;
1572 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1573 Status
= SampGetObjectAttribute(DomainObject
,
1578 if (!NT_SUCCESS(Status
))
1581 FixedData
.DomainServerRole
= Buffer
->Role
.DomainServerRole
;
1583 Status
= SampSetObjectAttribute(DomainObject
,
1595 SampSetDomainState(PSAM_DB_OBJECT DomainObject
,
1596 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1598 SAM_DOMAIN_FIXED_DATA FixedData
;
1602 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1603 Status
= SampGetObjectAttribute(DomainObject
,
1608 if (!NT_SUCCESS(Status
))
1611 FixedData
.DomainServerState
= Buffer
->State
.DomainServerState
;
1613 Status
= SampSetObjectAttribute(DomainObject
,
1625 SampSetDomainLockout(PSAM_DB_OBJECT DomainObject
,
1626 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1628 SAM_DOMAIN_FIXED_DATA FixedData
;
1632 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1633 Status
= SampGetObjectAttribute(DomainObject
,
1638 if (!NT_SUCCESS(Status
))
1641 FixedData
.LockoutDuration
= Buffer
->Lockout
.LockoutDuration
;
1642 FixedData
.LockoutObservationWindow
= Buffer
->Lockout
.LockoutObservationWindow
;
1643 FixedData
.LockoutThreshold
= Buffer
->Lockout
.LockoutThreshold
;
1645 Status
= SampSetObjectAttribute(DomainObject
,
1659 SamrSetInformationDomain(IN SAMPR_HANDLE DomainHandle
,
1660 IN DOMAIN_INFORMATION_CLASS DomainInformationClass
,
1661 IN PSAMPR_DOMAIN_INFO_BUFFER DomainInformation
)
1663 PSAM_DB_OBJECT DomainObject
;
1664 ACCESS_MASK DesiredAccess
;
1667 TRACE("SamrSetInformationDomain(%p %lu %p)\n",
1668 DomainHandle
, DomainInformationClass
, DomainInformation
);
1670 switch (DomainInformationClass
)
1672 case DomainPasswordInformation
:
1673 case DomainLockoutInformation
:
1674 DesiredAccess
= DOMAIN_WRITE_PASSWORD_PARAMS
;
1677 case DomainLogoffInformation
:
1678 case DomainOemInformation
:
1679 case DomainNameInformation
:
1680 DesiredAccess
= DOMAIN_WRITE_OTHER_PARAMETERS
;
1683 case DomainReplicationInformation
:
1684 case DomainServerRoleInformation
:
1685 case DomainStateInformation
:
1686 DesiredAccess
= DOMAIN_ADMINISTER_SERVER
;
1690 return STATUS_INVALID_INFO_CLASS
;
1693 RtlAcquireResourceExclusive(&SampResource
,
1696 /* Validate the server handle */
1697 Status
= SampValidateDbObject(DomainHandle
,
1701 if (!NT_SUCCESS(Status
))
1704 switch (DomainInformationClass
)
1706 case DomainPasswordInformation
:
1707 Status
= SampSetDomainPassword(DomainObject
,
1711 case DomainLogoffInformation
:
1712 Status
= SampSetDomainLogoff(DomainObject
,
1716 case DomainOemInformation
:
1717 Status
= SampSetObjectAttribute(DomainObject
,
1720 DomainInformation
->Oem
.OemInformation
.Buffer
,
1721 DomainInformation
->Oem
.OemInformation
.Length
+ sizeof(WCHAR
));
1724 case DomainNameInformation
:
1725 Status
= SampSetObjectAttribute(DomainObject
,
1728 DomainInformation
->Name
.DomainName
.Buffer
,
1729 DomainInformation
->Name
.DomainName
.Length
+ sizeof(WCHAR
));
1732 case DomainReplicationInformation
:
1733 Status
= SampSetObjectAttribute(DomainObject
,
1734 L
"ReplicaSourceNodeName",
1736 DomainInformation
->Replication
.ReplicaSourceNodeName
.Buffer
,
1737 DomainInformation
->Replication
.ReplicaSourceNodeName
.Length
+ sizeof(WCHAR
));
1740 case DomainServerRoleInformation
:
1741 Status
= SampSetDomainServerRole(DomainObject
,
1745 case DomainStateInformation
:
1746 Status
= SampSetDomainState(DomainObject
,
1750 case DomainLockoutInformation
:
1751 Status
= SampSetDomainLockout(DomainObject
,
1756 Status
= STATUS_NOT_IMPLEMENTED
;
1760 RtlReleaseResource(&SampResource
);
1769 SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle
,
1770 IN PRPC_UNICODE_STRING Name
,
1771 IN ACCESS_MASK DesiredAccess
,
1772 OUT SAMPR_HANDLE
*GroupHandle
,
1773 OUT
unsigned long *RelativeId
)
1775 UNICODE_STRING EmptyString
= RTL_CONSTANT_STRING(L
"");
1776 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
1777 SAM_GROUP_FIXED_DATA FixedGroupData
;
1778 PSAM_DB_OBJECT DomainObject
;
1779 PSAM_DB_OBJECT GroupObject
;
1785 TRACE("SamrCreateGroupInDomain(%p %p %lx %p %p)\n",
1786 DomainHandle
, Name
, DesiredAccess
, GroupHandle
, RelativeId
);
1788 /* Map generic access rights */
1789 RtlMapGenericMask(&DesiredAccess
,
1792 RtlAcquireResourceExclusive(&SampResource
,
1795 /* Validate the domain handle */
1796 Status
= SampValidateDbObject(DomainHandle
,
1798 DOMAIN_CREATE_GROUP
,
1800 if (!NT_SUCCESS(Status
))
1802 TRACE("failed with status 0x%08lx\n", Status
);
1806 /* Check the group account name */
1807 Status
= SampCheckAccountName(Name
, 256);
1808 if (!NT_SUCCESS(Status
))
1810 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
1814 /* Check if the group name already exists in the domain */
1815 Status
= SampCheckAccountNameInDomain(DomainObject
,
1817 if (!NT_SUCCESS(Status
))
1819 TRACE("Group name \'%S\' already exists in domain (Status 0x%08lx)\n",
1820 Name
->Buffer
, Status
);
1824 /* Get the fixed domain attributes */
1825 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1826 Status
= SampGetObjectAttribute(DomainObject
,
1829 (PVOID
)&FixedDomainData
,
1831 if (!NT_SUCCESS(Status
))
1833 TRACE("failed with status 0x%08lx\n", Status
);
1837 /* Increment the NextRid attribute */
1838 ulRid
= FixedDomainData
.NextRid
;
1839 FixedDomainData
.NextRid
++;
1841 /* Store the fixed domain attributes */
1842 Status
= SampSetObjectAttribute(DomainObject
,
1847 if (!NT_SUCCESS(Status
))
1849 TRACE("failed with status 0x%08lx\n", Status
);
1853 TRACE("RID: %lx\n", ulRid
);
1855 /* Convert the RID into a string (hex) */
1856 swprintf(szRid
, L
"%08lX", ulRid
);
1858 /* Create the group object */
1859 Status
= SampCreateDbObject(DomainObject
,
1866 if (!NT_SUCCESS(Status
))
1868 TRACE("failed with status 0x%08lx\n", Status
);
1872 /* Add the account name of the user object */
1873 Status
= SampSetAccountNameInDomain(DomainObject
,
1877 if (!NT_SUCCESS(Status
))
1879 TRACE("failed with status 0x%08lx\n", Status
);
1883 /* Initialize fixed user data */
1884 memset(&FixedGroupData
, 0, sizeof(SAM_GROUP_FIXED_DATA
));
1885 FixedGroupData
.Version
= 1;
1886 FixedGroupData
.GroupId
= ulRid
;
1888 /* Set fixed user data attribute */
1889 Status
= SampSetObjectAttribute(GroupObject
,
1892 (LPVOID
)&FixedGroupData
,
1893 sizeof(SAM_GROUP_FIXED_DATA
));
1894 if (!NT_SUCCESS(Status
))
1896 TRACE("failed with status 0x%08lx\n", Status
);
1900 /* Set the Name attribute */
1901 Status
= SampSetObjectAttribute(GroupObject
,
1904 (LPVOID
)Name
->Buffer
,
1905 Name
->MaximumLength
);
1906 if (!NT_SUCCESS(Status
))
1908 TRACE("failed with status 0x%08lx\n", Status
);
1912 /* Set the AdminComment attribute */
1913 Status
= SampSetObjectAttribute(GroupObject
,
1917 EmptyString
.MaximumLength
);
1918 if (!NT_SUCCESS(Status
))
1920 TRACE("failed with status 0x%08lx\n", Status
);
1924 if (NT_SUCCESS(Status
))
1926 *GroupHandle
= (SAMPR_HANDLE
)GroupObject
;
1927 *RelativeId
= ulRid
;
1931 RtlReleaseResource(&SampResource
);
1933 TRACE("returns with status 0x%08lx\n", Status
);
1942 SamrEnumerateGroupsInDomain(IN SAMPR_HANDLE DomainHandle
,
1943 IN OUT
unsigned long *EnumerationContext
,
1944 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
1945 IN
unsigned long PreferedMaximumLength
,
1946 OUT
unsigned long *CountReturned
)
1948 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
1949 PSAM_DB_OBJECT DomainObject
;
1950 HANDLE GroupsKeyHandle
= NULL
;
1951 HANDLE NamesKeyHandle
= NULL
;
1952 WCHAR GroupName
[64];
1954 ULONG EnumCount
= 0;
1955 ULONG RequiredLength
= 0;
1960 BOOLEAN MoreEntries
= FALSE
;
1963 TRACE("SamrEnumerateUsersInDomain(%p %p %p %lu %p)\n",
1964 DomainHandle
, EnumerationContext
, Buffer
,
1965 PreferedMaximumLength
, CountReturned
);
1967 RtlAcquireResourceShared(&SampResource
,
1970 /* Validate the domain handle */
1971 Status
= SampValidateDbObject(DomainHandle
,
1973 DOMAIN_LIST_ACCOUNTS
,
1975 if (!NT_SUCCESS(Status
))
1978 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
1982 if (!NT_SUCCESS(Status
))
1985 Status
= SampRegOpenKey(GroupsKeyHandle
,
1989 if (!NT_SUCCESS(Status
))
1994 EnumIndex
= *EnumerationContext
;
1998 NameLength
= 64 * sizeof(WCHAR
);
1999 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2006 if (!NT_SUCCESS(Status
))
2008 if (Status
== STATUS_NO_MORE_ENTRIES
)
2009 Status
= STATUS_SUCCESS
;
2013 TRACE("EnumIndex: %lu\n", EnumIndex
);
2014 TRACE("Group name: %S\n", GroupName
);
2015 TRACE("Name length: %lu\n", NameLength
);
2017 if ((RequiredLength
+ NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
)) > PreferedMaximumLength
)
2023 RequiredLength
+= (NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
));
2029 TRACE("EnumCount: %lu\n", EnumCount
);
2030 TRACE("RequiredLength: %lu\n", RequiredLength
);
2032 if (!NT_SUCCESS(Status
))
2035 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
2036 if (EnumBuffer
== NULL
)
2038 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2042 EnumBuffer
->EntriesRead
= EnumCount
;
2046 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
2047 if (EnumBuffer
->Buffer
== NULL
)
2049 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2055 EnumIndex
= *EnumerationContext
;
2056 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
2058 NameLength
= 64 * sizeof(WCHAR
);
2059 DataLength
= sizeof(ULONG
);
2060 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2067 if (!NT_SUCCESS(Status
))
2069 if (Status
== STATUS_NO_MORE_ENTRIES
)
2070 Status
= STATUS_SUCCESS
;
2074 TRACE("EnumIndex: %lu\n", EnumIndex
);
2075 TRACE("Group name: %S\n", GroupName
);
2076 TRACE("Name length: %lu\n", NameLength
);
2077 TRACE("RID: %lu\n", Rid
);
2079 EnumBuffer
->Buffer
[i
].RelativeId
= Rid
;
2081 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)NameLength
;
2082 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)(DataLength
+ sizeof(UNICODE_NULL
));
2084 /* FIXME: Disabled because of bugs in widl and rpcrt4 */
2086 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(EnumBuffer
->Buffer
[i
].Name
.MaximumLength
);
2087 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
2089 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2093 memcpy(EnumBuffer
->Buffer
[i
].Name
.Buffer
,
2095 EnumBuffer
->Buffer
[i
].Name
.Length
);
2100 if (NT_SUCCESS(Status
))
2102 *EnumerationContext
+= EnumCount
;
2103 *Buffer
= EnumBuffer
;
2104 *CountReturned
= EnumCount
;
2108 *EnumerationContext
= 0;
2112 if (EnumBuffer
!= NULL
)
2114 if (EnumBuffer
->Buffer
!= NULL
)
2116 if (EnumBuffer
->EntriesRead
!= 0)
2118 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
2120 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
2121 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
2125 midl_user_free(EnumBuffer
->Buffer
);
2128 midl_user_free(EnumBuffer
);
2132 SampRegCloseKey(&NamesKeyHandle
);
2133 SampRegCloseKey(&GroupsKeyHandle
);
2135 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
== TRUE
))
2136 Status
= STATUS_MORE_ENTRIES
;
2138 RtlReleaseResource(&SampResource
);
2147 SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle
,
2148 IN PRPC_UNICODE_STRING Name
,
2149 IN ACCESS_MASK DesiredAccess
,
2150 OUT SAMPR_HANDLE
*UserHandle
,
2151 OUT
unsigned long *RelativeId
)
2153 UNICODE_STRING EmptyString
= RTL_CONSTANT_STRING(L
"");
2154 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
2155 SAM_USER_FIXED_DATA FixedUserData
;
2156 PSAM_DB_OBJECT DomainObject
;
2157 PSAM_DB_OBJECT UserObject
;
2158 GROUP_MEMBERSHIP GroupMembership
;
2159 UCHAR LogonHours
[23];
2165 TRACE("SamrCreateUserInDomain(%p %p %lx %p %p)\n",
2166 DomainHandle
, Name
, DesiredAccess
, UserHandle
, RelativeId
);
2169 Name
->Length
== 0 ||
2170 Name
->Buffer
== NULL
||
2171 UserHandle
== NULL
||
2173 return STATUS_INVALID_PARAMETER
;
2175 /* Map generic access rights */
2176 RtlMapGenericMask(&DesiredAccess
,
2179 RtlAcquireResourceExclusive(&SampResource
,
2182 /* Validate the domain handle */
2183 Status
= SampValidateDbObject(DomainHandle
,
2187 if (!NT_SUCCESS(Status
))
2189 TRACE("failed with status 0x%08lx\n", Status
);
2193 /* Check the user account name */
2194 Status
= SampCheckAccountName(Name
, 20);
2195 if (!NT_SUCCESS(Status
))
2197 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
2201 /* Check if the user name already exists in the domain */
2202 Status
= SampCheckAccountNameInDomain(DomainObject
,
2204 if (!NT_SUCCESS(Status
))
2206 TRACE("User name \'%S\' already exists in domain (Status 0x%08lx)\n",
2207 Name
->Buffer
, Status
);
2211 /* Get the fixed domain attributes */
2212 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
2213 Status
= SampGetObjectAttribute(DomainObject
,
2216 (PVOID
)&FixedDomainData
,
2218 if (!NT_SUCCESS(Status
))
2220 TRACE("failed with status 0x%08lx\n", Status
);
2224 /* Increment the NextRid attribute */
2225 ulRid
= FixedDomainData
.NextRid
;
2226 FixedDomainData
.NextRid
++;
2228 /* Store the fixed domain attributes */
2229 Status
= SampSetObjectAttribute(DomainObject
,
2234 if (!NT_SUCCESS(Status
))
2236 TRACE("failed with status 0x%08lx\n", Status
);
2240 TRACE("RID: %lx\n", ulRid
);
2242 /* Convert the RID into a string (hex) */
2243 swprintf(szRid
, L
"%08lX", ulRid
);
2245 /* Create the user object */
2246 Status
= SampCreateDbObject(DomainObject
,
2253 if (!NT_SUCCESS(Status
))
2255 TRACE("failed with status 0x%08lx\n", Status
);
2259 /* Add the account name for the user object */
2260 Status
= SampSetAccountNameInDomain(DomainObject
,
2264 if (!NT_SUCCESS(Status
))
2266 TRACE("failed with status 0x%08lx\n", Status
);
2270 /* Initialize fixed user data */
2271 memset(&FixedUserData
, 0, sizeof(SAM_USER_FIXED_DATA
));
2272 FixedUserData
.Version
= 1;
2273 FixedUserData
.Reserved
= 0;
2274 FixedUserData
.LastLogon
.QuadPart
= 0;
2275 FixedUserData
.LastLogoff
.QuadPart
= 0;
2276 FixedUserData
.PasswordLastSet
.QuadPart
= 0;
2277 FixedUserData
.AccountExpires
.LowPart
= MAXULONG
;
2278 FixedUserData
.AccountExpires
.HighPart
= MAXLONG
;
2279 FixedUserData
.LastBadPasswordTime
.QuadPart
= 0;
2280 FixedUserData
.UserId
= ulRid
;
2281 FixedUserData
.PrimaryGroupId
= DOMAIN_GROUP_RID_USERS
;
2282 FixedUserData
.UserAccountControl
= USER_ACCOUNT_DISABLED
|
2283 USER_PASSWORD_NOT_REQUIRED
|
2284 USER_NORMAL_ACCOUNT
;
2285 FixedUserData
.CountryCode
= 0;
2286 FixedUserData
.CodePage
= 0;
2287 FixedUserData
.BadPasswordCount
= 0;
2288 FixedUserData
.LogonCount
= 0;
2289 FixedUserData
.AdminCount
= 0;
2290 FixedUserData
.OperatorCount
= 0;
2292 /* Set fixed user data attribute */
2293 Status
= SampSetObjectAttribute(UserObject
,
2296 (LPVOID
)&FixedUserData
,
2297 sizeof(SAM_USER_FIXED_DATA
));
2298 if (!NT_SUCCESS(Status
))
2300 TRACE("failed with status 0x%08lx\n", Status
);
2304 /* Set the Name attribute */
2305 Status
= SampSetObjectAttribute(UserObject
,
2308 (LPVOID
)Name
->Buffer
,
2309 Name
->MaximumLength
);
2310 if (!NT_SUCCESS(Status
))
2312 TRACE("failed with status 0x%08lx\n", Status
);
2316 /* Set the FullName attribute */
2317 Status
= SampSetObjectAttribute(UserObject
,
2321 EmptyString
.MaximumLength
);
2322 if (!NT_SUCCESS(Status
))
2324 TRACE("failed with status 0x%08lx\n", Status
);
2328 /* Set the HomeDirectory attribute */
2329 Status
= SampSetObjectAttribute(UserObject
,
2333 EmptyString
.MaximumLength
);
2334 if (!NT_SUCCESS(Status
))
2336 TRACE("failed with status 0x%08lx\n", Status
);
2340 /* Set the HomeDirectoryDrive attribute */
2341 Status
= SampSetObjectAttribute(UserObject
,
2342 L
"HomeDirectoryDrive",
2345 EmptyString
.MaximumLength
);
2346 if (!NT_SUCCESS(Status
))
2348 TRACE("failed with status 0x%08lx\n", Status
);
2352 /* Set the ScriptPath attribute */
2353 Status
= SampSetObjectAttribute(UserObject
,
2357 EmptyString
.MaximumLength
);
2358 if (!NT_SUCCESS(Status
))
2360 TRACE("failed with status 0x%08lx\n", Status
);
2364 /* Set the ProfilePath attribute */
2365 Status
= SampSetObjectAttribute(UserObject
,
2369 EmptyString
.MaximumLength
);
2370 if (!NT_SUCCESS(Status
))
2372 TRACE("failed with status 0x%08lx\n", Status
);
2376 /* Set the AdminComment attribute */
2377 Status
= SampSetObjectAttribute(UserObject
,
2381 EmptyString
.MaximumLength
);
2382 if (!NT_SUCCESS(Status
))
2384 TRACE("failed with status 0x%08lx\n", Status
);
2388 /* Set the UserComment attribute */
2389 Status
= SampSetObjectAttribute(UserObject
,
2393 EmptyString
.MaximumLength
);
2394 if (!NT_SUCCESS(Status
))
2396 TRACE("failed with status 0x%08lx\n", Status
);
2400 /* Set the WorkStations attribute */
2401 Status
= SampSetObjectAttribute(UserObject
,
2405 EmptyString
.MaximumLength
);
2406 if (!NT_SUCCESS(Status
))
2408 TRACE("failed with status 0x%08lx\n", Status
);
2412 /* Set the Parameters attribute */
2413 Status
= SampSetObjectAttribute(UserObject
,
2417 EmptyString
.MaximumLength
);
2418 if (!NT_SUCCESS(Status
))
2420 TRACE("failed with status 0x%08lx\n", Status
);
2424 /* Set LogonHours attribute*/
2425 *((PUSHORT
)LogonHours
) = 168;
2426 memset(&(LogonHours
[2]), 0xff, 21);
2428 Status
= SampSetObjectAttribute(UserObject
,
2432 sizeof(LogonHours
));
2433 if (!NT_SUCCESS(Status
))
2435 TRACE("failed with status 0x%08lx\n", Status
);
2439 /* Set Groups attribute*/
2440 GroupMembership
.RelativeId
= DOMAIN_GROUP_RID_USERS
;
2441 GroupMembership
.Attributes
= SE_GROUP_MANDATORY
|
2443 SE_GROUP_ENABLED_BY_DEFAULT
;
2445 Status
= SampSetObjectAttribute(UserObject
,
2449 sizeof(GROUP_MEMBERSHIP
));
2450 if (!NT_SUCCESS(Status
))
2452 TRACE("failed with status 0x%08lx\n", Status
);
2456 /* Set LMPwd attribute*/
2457 Status
= SampSetObjectAttribute(UserObject
,
2461 sizeof(ENCRYPTED_LM_OWF_PASSWORD
));
2462 if (!NT_SUCCESS(Status
))
2464 TRACE("failed with status 0x%08lx\n", Status
);
2468 /* Set NTPwd attribute*/
2469 Status
= SampSetObjectAttribute(UserObject
,
2473 sizeof(ENCRYPTED_NT_OWF_PASSWORD
));
2474 if (!NT_SUCCESS(Status
))
2476 TRACE("failed with status 0x%08lx\n", Status
);
2480 /* Set LMPwdHistory attribute*/
2481 Status
= SampSetObjectAttribute(UserObject
,
2486 if (!NT_SUCCESS(Status
))
2488 TRACE("failed with status 0x%08lx\n", Status
);
2492 /* Set NTPwdHistory attribute*/
2493 Status
= SampSetObjectAttribute(UserObject
,
2498 if (!NT_SUCCESS(Status
))
2500 TRACE("failed with status 0x%08lx\n", Status
);
2504 /* FIXME: Set SecDesc attribute*/
2506 if (NT_SUCCESS(Status
))
2508 *UserHandle
= (SAMPR_HANDLE
)UserObject
;
2509 *RelativeId
= ulRid
;
2513 RtlReleaseResource(&SampResource
);
2515 TRACE("returns with status 0x%08lx\n", Status
);
2524 SamrEnumerateUsersInDomain(IN SAMPR_HANDLE DomainHandle
,
2525 IN OUT
unsigned long *EnumerationContext
,
2526 IN
unsigned long UserAccountControl
,
2527 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
2528 IN
unsigned long PreferedMaximumLength
,
2529 OUT
unsigned long *CountReturned
)
2531 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
2532 PSAM_DB_OBJECT DomainObject
;
2533 HANDLE UsersKeyHandle
= NULL
;
2534 HANDLE NamesKeyHandle
= NULL
;
2537 ULONG EnumCount
= 0;
2538 ULONG RequiredLength
= 0;
2543 BOOLEAN MoreEntries
= FALSE
;
2546 TRACE("SamrEnumerateUsersInDomain(%p %p %lx %p %lu %p)\n",
2547 DomainHandle
, EnumerationContext
, UserAccountControl
, Buffer
,
2548 PreferedMaximumLength
, CountReturned
);
2550 RtlAcquireResourceShared(&SampResource
,
2553 /* Validate the domain handle */
2554 Status
= SampValidateDbObject(DomainHandle
,
2556 DOMAIN_LIST_ACCOUNTS
,
2558 if (!NT_SUCCESS(Status
))
2561 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
2565 if (!NT_SUCCESS(Status
))
2568 Status
= SampRegOpenKey(UsersKeyHandle
,
2572 if (!NT_SUCCESS(Status
))
2577 EnumIndex
= *EnumerationContext
;
2581 NameLength
= 64 * sizeof(WCHAR
);
2582 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2589 if (!NT_SUCCESS(Status
))
2591 if (Status
== STATUS_NO_MORE_ENTRIES
)
2592 Status
= STATUS_SUCCESS
;
2596 TRACE("EnumIndex: %lu\n", EnumIndex
);
2597 TRACE("User name: %S\n", UserName
);
2598 TRACE("Name length: %lu\n", NameLength
);
2600 if ((RequiredLength
+ NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
)) > PreferedMaximumLength
)
2606 RequiredLength
+= (NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
));
2612 TRACE("EnumCount: %lu\n", EnumCount
);
2613 TRACE("RequiredLength: %lu\n", RequiredLength
);
2615 if (!NT_SUCCESS(Status
))
2618 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
2619 if (EnumBuffer
== NULL
)
2621 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2625 EnumBuffer
->EntriesRead
= EnumCount
;
2629 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
2630 if (EnumBuffer
->Buffer
== NULL
)
2632 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2638 EnumIndex
= *EnumerationContext
;
2639 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
2641 NameLength
= 64 * sizeof(WCHAR
);
2642 DataLength
= sizeof(ULONG
);
2643 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2650 if (!NT_SUCCESS(Status
))
2652 if (Status
== STATUS_NO_MORE_ENTRIES
)
2653 Status
= STATUS_SUCCESS
;
2657 TRACE("EnumIndex: %lu\n", EnumIndex
);
2658 TRACE("User name: %S\n", UserName
);
2659 TRACE("Name length: %lu\n", NameLength
);
2660 TRACE("RID: %lu\n", Rid
);
2662 EnumBuffer
->Buffer
[i
].RelativeId
= Rid
;
2664 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)NameLength
;
2665 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)(DataLength
+ sizeof(UNICODE_NULL
));
2667 /* FIXME: Disabled because of bugs in widl and rpcrt4 */
2669 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(EnumBuffer
->Buffer
[i
].Name
.MaximumLength
);
2670 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
2672 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2676 memcpy(EnumBuffer
->Buffer
[i
].Name
.Buffer
,
2678 EnumBuffer
->Buffer
[i
].Name
.Length
);
2683 if (NT_SUCCESS(Status
))
2685 *EnumerationContext
+= EnumCount
;
2686 *Buffer
= EnumBuffer
;
2687 *CountReturned
= EnumCount
;
2691 *EnumerationContext
= 0;
2695 if (EnumBuffer
!= NULL
)
2697 if (EnumBuffer
->Buffer
!= NULL
)
2699 if (EnumBuffer
->EntriesRead
!= 0)
2701 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
2703 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
2704 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
2708 midl_user_free(EnumBuffer
->Buffer
);
2711 midl_user_free(EnumBuffer
);
2715 SampRegCloseKey(&NamesKeyHandle
);
2716 SampRegCloseKey(&UsersKeyHandle
);
2718 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
== TRUE
))
2719 Status
= STATUS_MORE_ENTRIES
;
2721 RtlReleaseResource(&SampResource
);
2730 SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle
,
2731 IN PRPC_UNICODE_STRING AccountName
,
2732 IN ACCESS_MASK DesiredAccess
,
2733 OUT SAMPR_HANDLE
*AliasHandle
,
2734 OUT
unsigned long *RelativeId
)
2736 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
2737 PSAM_DB_OBJECT DomainObject
;
2738 PSAM_DB_OBJECT AliasObject
;
2739 UNICODE_STRING EmptyString
= RTL_CONSTANT_STRING(L
"");
2745 TRACE("SamrCreateAliasInDomain(%p %p %lx %p %p)\n",
2746 DomainHandle
, AccountName
, DesiredAccess
, AliasHandle
, RelativeId
);
2748 /* Map generic access rights */
2749 RtlMapGenericMask(&DesiredAccess
,
2752 RtlAcquireResourceExclusive(&SampResource
,
2755 /* Validate the domain handle */
2756 Status
= SampValidateDbObject(DomainHandle
,
2758 DOMAIN_CREATE_ALIAS
,
2760 if (!NT_SUCCESS(Status
))
2762 TRACE("failed with status 0x%08lx\n", Status
);
2766 /* Check the alias acoount name */
2767 Status
= SampCheckAccountName(AccountName
, 256);
2768 if (!NT_SUCCESS(Status
))
2770 TRACE("SampCheckAccountName failed (Status 0x%08lx)\n", Status
);
2774 /* Check if the alias name already exists in the domain */
2775 Status
= SampCheckAccountNameInDomain(DomainObject
,
2776 AccountName
->Buffer
);
2777 if (!NT_SUCCESS(Status
))
2779 TRACE("Alias name \'%S\' already exists in domain (Status 0x%08lx)\n",
2780 AccountName
->Buffer
, Status
);
2784 /* Get the fixed domain attributes */
2785 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
2786 Status
= SampGetObjectAttribute(DomainObject
,
2789 (PVOID
)&FixedDomainData
,
2791 if (!NT_SUCCESS(Status
))
2793 TRACE("failed with status 0x%08lx\n", Status
);
2797 /* Increment the NextRid attribute */
2798 ulRid
= FixedDomainData
.NextRid
;
2799 FixedDomainData
.NextRid
++;
2801 /* Store the fixed domain attributes */
2802 Status
= SampSetObjectAttribute(DomainObject
,
2807 if (!NT_SUCCESS(Status
))
2809 TRACE("failed with status 0x%08lx\n", Status
);
2813 TRACE("RID: %lx\n", ulRid
);
2815 /* Convert the RID into a string (hex) */
2816 swprintf(szRid
, L
"%08lX", ulRid
);
2818 /* Create the alias object */
2819 Status
= SampCreateDbObject(DomainObject
,
2826 if (!NT_SUCCESS(Status
))
2828 TRACE("failed with status 0x%08lx\n", Status
);
2832 /* Add the account name for the alias object */
2833 Status
= SampSetAccountNameInDomain(DomainObject
,
2835 AccountName
->Buffer
,
2837 if (!NT_SUCCESS(Status
))
2839 TRACE("failed with status 0x%08lx\n", Status
);
2843 /* Set the Name attribute */
2844 Status
= SampSetObjectAttribute(AliasObject
,
2847 (LPVOID
)AccountName
->Buffer
,
2848 AccountName
->MaximumLength
);
2849 if (!NT_SUCCESS(Status
))
2851 TRACE("failed with status 0x%08lx\n", Status
);
2855 /* Set the Description attribute */
2856 Status
= SampSetObjectAttribute(AliasObject
,
2860 EmptyString
.MaximumLength
);
2861 if (!NT_SUCCESS(Status
))
2863 TRACE("failed with status 0x%08lx\n", Status
);
2867 if (NT_SUCCESS(Status
))
2869 *AliasHandle
= (SAMPR_HANDLE
)AliasObject
;
2870 *RelativeId
= ulRid
;
2874 RtlReleaseResource(&SampResource
);
2876 TRACE("returns with status 0x%08lx\n", Status
);
2885 SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle
,
2886 IN OUT
unsigned long *EnumerationContext
,
2887 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
2888 IN
unsigned long PreferedMaximumLength
,
2889 OUT
unsigned long *CountReturned
)
2891 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
2892 PSAM_DB_OBJECT DomainObject
;
2893 HANDLE AliasesKeyHandle
= NULL
;
2894 HANDLE NamesKeyHandle
= NULL
;
2895 WCHAR AliasName
[64];
2897 ULONG EnumCount
= 0;
2898 ULONG RequiredLength
= 0;
2903 BOOLEAN MoreEntries
= FALSE
;
2906 TRACE("SamrEnumerateAliasesInDomain(%p %p %p %lu %p)\n",
2907 DomainHandle
, EnumerationContext
, Buffer
,
2908 PreferedMaximumLength
, CountReturned
);
2910 RtlAcquireResourceShared(&SampResource
,
2913 /* Validate the domain handle */
2914 Status
= SampValidateDbObject(DomainHandle
,
2916 DOMAIN_LIST_ACCOUNTS
,
2918 if (!NT_SUCCESS(Status
))
2921 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
2925 if (!NT_SUCCESS(Status
))
2928 Status
= SampRegOpenKey(AliasesKeyHandle
,
2932 if (!NT_SUCCESS(Status
))
2937 EnumIndex
= *EnumerationContext
;
2941 NameLength
= 64 * sizeof(WCHAR
);
2942 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2949 if (!NT_SUCCESS(Status
))
2951 if (Status
== STATUS_NO_MORE_ENTRIES
)
2952 Status
= STATUS_SUCCESS
;
2956 TRACE("EnumIndex: %lu\n", EnumIndex
);
2957 TRACE("Alias name: %S\n", AliasName
);
2958 TRACE("Name length: %lu\n", NameLength
);
2960 if ((RequiredLength
+ NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
)) > PreferedMaximumLength
)
2966 RequiredLength
+= (NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
));
2972 TRACE("EnumCount: %lu\n", EnumCount
);
2973 TRACE("RequiredLength: %lu\n", RequiredLength
);
2975 if (!NT_SUCCESS(Status
))
2978 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
2979 if (EnumBuffer
== NULL
)
2981 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2985 EnumBuffer
->EntriesRead
= EnumCount
;
2989 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
2990 if (EnumBuffer
->Buffer
== NULL
)
2992 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2998 EnumIndex
= *EnumerationContext
;
2999 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
3001 NameLength
= 64 * sizeof(WCHAR
);
3002 DataLength
= sizeof(ULONG
);
3003 Status
= SampRegEnumerateValue(NamesKeyHandle
,
3010 if (!NT_SUCCESS(Status
))
3012 if (Status
== STATUS_NO_MORE_ENTRIES
)
3013 Status
= STATUS_SUCCESS
;
3017 TRACE("EnumIndex: %lu\n", EnumIndex
);
3018 TRACE("Alias name: %S\n", AliasName
);
3019 TRACE("Name length: %lu\n", NameLength
);
3020 TRACE("RID: %lu\n", Rid
);
3022 EnumBuffer
->Buffer
[i
].RelativeId
= Rid
;
3024 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)NameLength
;
3025 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)(DataLength
+ sizeof(UNICODE_NULL
));
3027 /* FIXME: Disabled because of bugs in widl and rpcrt4 */
3029 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(EnumBuffer
->Buffer
[i
].Name
.MaximumLength
);
3030 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
3032 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3036 memcpy(EnumBuffer
->Buffer
[i
].Name
.Buffer
,
3038 EnumBuffer
->Buffer
[i
].Name
.Length
);
3043 if (NT_SUCCESS(Status
))
3045 *EnumerationContext
+= EnumCount
;
3046 *Buffer
= EnumBuffer
;
3047 *CountReturned
= EnumCount
;
3051 *EnumerationContext
= 0;
3055 if (EnumBuffer
!= NULL
)
3057 if (EnumBuffer
->Buffer
!= NULL
)
3059 if (EnumBuffer
->EntriesRead
!= 0)
3061 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
3063 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
3064 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
3068 midl_user_free(EnumBuffer
->Buffer
);
3071 midl_user_free(EnumBuffer
);
3075 SampRegCloseKey(&NamesKeyHandle
);
3076 SampRegCloseKey(&AliasesKeyHandle
);
3078 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
== TRUE
))
3079 Status
= STATUS_MORE_ENTRIES
;
3081 RtlReleaseResource(&SampResource
);
3090 SamrGetAliasMembership(IN SAMPR_HANDLE DomainHandle
,
3091 IN PSAMPR_PSID_ARRAY SidArray
,
3092 OUT PSAMPR_ULONG_ARRAY Membership
)
3094 PSAM_DB_OBJECT DomainObject
;
3095 HANDLE AliasesKeyHandle
= NULL
;
3096 HANDLE MembersKeyHandle
= NULL
;
3097 HANDLE MemberKeyHandle
= NULL
;
3098 LPWSTR MemberSidString
= NULL
;
3099 PULONG RidArray
= NULL
;
3100 ULONG MaxSidCount
= 0;
3105 WCHAR NameBuffer
[9];
3107 TRACE("SamrGetAliasMembership(%p %p %p)\n",
3108 DomainHandle
, SidArray
, Membership
);
3110 RtlAcquireResourceShared(&SampResource
,
3113 /* Validate the domain handle */
3114 Status
= SampValidateDbObject(DomainHandle
,
3116 DOMAIN_GET_ALIAS_MEMBERSHIP
,
3118 if (!NT_SUCCESS(Status
))
3121 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3125 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3126 if (!NT_SUCCESS(Status
))
3129 Status
= SampRegOpenKey(AliasesKeyHandle
,
3133 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3135 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3137 Status
= STATUS_SUCCESS
;
3141 if (!NT_SUCCESS(Status
))
3144 for (i
= 0; i
< SidArray
->Count
; i
++)
3146 ConvertSidToStringSid(SidArray
->Sids
[i
].SidPointer
, &MemberSidString
);
3147 TRACE("Open %S\n", MemberSidString
);
3149 Status
= SampRegOpenKey(MembersKeyHandle
,
3153 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3154 if (NT_SUCCESS(Status
))
3156 Status
= SampRegQueryKeyInfo(MemberKeyHandle
,
3159 if (NT_SUCCESS(Status
))
3161 TRACE("Found %lu values\n", ValueCount
);
3162 MaxSidCount
+= ValueCount
;
3165 SampRegCloseKey(&MemberKeyHandle
);
3168 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3169 Status
= STATUS_SUCCESS
;
3171 LocalFree(MemberSidString
);
3174 if (MaxSidCount
== 0)
3176 Status
= STATUS_SUCCESS
;
3180 TRACE("Maximum sid count: %lu\n", MaxSidCount
);
3181 RidArray
= midl_user_allocate(MaxSidCount
* sizeof(ULONG
));
3182 if (RidArray
== NULL
)
3184 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3188 for (i
= 0; i
< SidArray
->Count
; i
++)
3190 ConvertSidToStringSid(SidArray
->Sids
[i
].SidPointer
, &MemberSidString
);
3191 TRACE("Open %S\n", MemberSidString
);
3193 Status
= SampRegOpenKey(MembersKeyHandle
,
3197 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3198 if (NT_SUCCESS(Status
))
3200 Status
= SampRegQueryKeyInfo(MemberKeyHandle
,
3203 if (NT_SUCCESS(Status
))
3205 TRACE("Found %lu values\n", ValueCount
);
3207 for (j
= 0; j
< ValueCount
; j
++)
3209 DataLength
= 9 * sizeof(WCHAR
);
3210 Status
= SampRegEnumerateValue(MemberKeyHandle
,
3217 if (NT_SUCCESS(Status
))
3219 RidArray
[j
] = wcstoul(NameBuffer
, NULL
, 16);
3224 SampRegCloseKey(&MemberKeyHandle
);
3227 LocalFree(MemberSidString
);
3231 SampRegCloseKey(&MembersKeyHandle
);
3232 SampRegCloseKey(&MembersKeyHandle
);
3233 SampRegCloseKey(&AliasesKeyHandle
);
3235 if (NT_SUCCESS(Status
))
3237 Membership
->Count
= MaxSidCount
;
3238 Membership
->Element
= RidArray
;
3242 if (RidArray
!= NULL
)
3243 midl_user_free(RidArray
);
3246 RtlReleaseResource(&SampResource
);
3255 SamrLookupNamesInDomain(IN SAMPR_HANDLE DomainHandle
,
3257 IN RPC_UNICODE_STRING Names
[],
3258 OUT PSAMPR_ULONG_ARRAY RelativeIds
,
3259 OUT PSAMPR_ULONG_ARRAY Use
)
3261 PSAM_DB_OBJECT DomainObject
;
3262 HANDLE AccountsKeyHandle
= NULL
;
3263 HANDLE NamesKeyHandle
= NULL
;
3264 ULONG MappedCount
= 0;
3270 TRACE("SamrLookupNamesInDomain(%p %lu %p %p %p)\n",
3271 DomainHandle
, Count
, Names
, RelativeIds
, Use
);
3273 RtlAcquireResourceShared(&SampResource
,
3276 /* Validate the domain handle */
3277 Status
= SampValidateDbObject(DomainHandle
,
3281 if (!NT_SUCCESS(Status
))
3283 TRACE("failed with status 0x%08lx\n", Status
);
3287 RelativeIds
->Count
= 0;
3292 Status
= STATUS_SUCCESS
;
3296 /* Allocate the relative IDs array */
3297 RelativeIds
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
3298 if (RelativeIds
->Element
== NULL
)
3300 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3304 /* Allocate the use array */
3305 Use
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
3306 if (Use
->Element
== NULL
)
3308 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3312 RelativeIds
->Count
= Count
;
3315 for (i
= 0; i
< Count
; i
++)
3317 TRACE("Name: %S\n", Names
[i
].Buffer
);
3321 /* Lookup aliases */
3322 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3325 &AccountsKeyHandle
);
3326 if (NT_SUCCESS(Status
))
3328 Status
= SampRegOpenKey(AccountsKeyHandle
,
3332 if (NT_SUCCESS(Status
))
3334 DataLength
= sizeof(ULONG
);
3335 Status
= SampRegQueryValue(NamesKeyHandle
,
3341 SampRegCloseKey(&NamesKeyHandle
);
3344 SampRegCloseKey(&AccountsKeyHandle
);
3347 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3350 /* Return alias account */
3351 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
3353 TRACE("Rid: %lu\n", RelativeId
);
3354 RelativeIds
->Element
[i
] = RelativeId
;
3355 Use
->Element
[i
] = SidTypeAlias
;
3361 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3364 &AccountsKeyHandle
);
3365 if (NT_SUCCESS(Status
))
3367 Status
= SampRegOpenKey(AccountsKeyHandle
,
3371 if (NT_SUCCESS(Status
))
3373 DataLength
= sizeof(ULONG
);
3374 Status
= SampRegQueryValue(NamesKeyHandle
,
3380 SampRegCloseKey(&NamesKeyHandle
);
3383 SampRegCloseKey(&AccountsKeyHandle
);
3386 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3389 /* Return group account */
3390 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
3392 TRACE("Rid: %lu\n", RelativeId
);
3393 RelativeIds
->Element
[i
] = RelativeId
;
3394 Use
->Element
[i
] = SidTypeGroup
;
3400 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3403 &AccountsKeyHandle
);
3404 if (NT_SUCCESS(Status
))
3406 Status
= SampRegOpenKey(AccountsKeyHandle
,
3410 if (NT_SUCCESS(Status
))
3412 DataLength
= sizeof(ULONG
);
3413 Status
= SampRegQueryValue(NamesKeyHandle
,
3419 SampRegCloseKey(&NamesKeyHandle
);
3422 SampRegCloseKey(&AccountsKeyHandle
);
3425 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3428 /* Return user account */
3429 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
3431 TRACE("Rid: %lu\n", RelativeId
);
3432 RelativeIds
->Element
[i
] = RelativeId
;
3433 Use
->Element
[i
] = SidTypeUser
;
3438 /* Return unknown account */
3439 RelativeIds
->Element
[i
] = 0;
3440 Use
->Element
[i
] = SidTypeUnknown
;
3444 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3445 Status
= STATUS_SUCCESS
;
3447 if (NT_SUCCESS(Status
))
3449 if (MappedCount
== 0)
3450 Status
= STATUS_NONE_MAPPED
;
3451 else if (MappedCount
< Count
)
3452 Status
= STATUS_SOME_NOT_MAPPED
;
3456 if (RelativeIds
->Element
!= NULL
)
3458 midl_user_free(RelativeIds
->Element
);
3459 RelativeIds
->Element
= NULL
;
3462 RelativeIds
->Count
= 0;
3464 if (Use
->Element
!= NULL
)
3466 midl_user_free(Use
->Element
);
3467 Use
->Element
= NULL
;
3473 RtlReleaseResource(&SampResource
);
3475 TRACE("Returned Status %lx\n", Status
);
3484 SamrLookupIdsInDomain(IN SAMPR_HANDLE DomainHandle
,
3486 IN ULONG
*RelativeIds
,
3487 OUT PSAMPR_RETURNED_USTRING_ARRAY Names
,
3488 OUT PSAMPR_ULONG_ARRAY Use
)
3490 PSAM_DB_OBJECT DomainObject
;
3492 HANDLE AccountsKeyHandle
= NULL
;
3493 HANDLE AccountKeyHandle
= NULL
;
3494 ULONG MappedCount
= 0;
3499 TRACE("SamrLookupIdsInDomain(%p %lu %p %p %p)\n",
3500 DomainHandle
, Count
, RelativeIds
, Names
, Use
);
3502 RtlAcquireResourceShared(&SampResource
,
3505 /* Validate the domain handle */
3506 Status
= SampValidateDbObject(DomainHandle
,
3510 if (!NT_SUCCESS(Status
))
3512 TRACE("failed with status 0x%08lx\n", Status
);
3521 Status
= STATUS_SUCCESS
;
3525 /* Allocate the names array */
3526 Names
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
3527 if (Names
->Element
== NULL
)
3529 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3533 /* Allocate the use array */
3534 Use
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
3535 if (Use
->Element
== NULL
)
3537 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3541 Names
->Count
= Count
;
3544 for (i
= 0; i
< Count
; i
++)
3546 TRACE("RID: %lu\n", RelativeIds
[i
]);
3548 swprintf(RidString
, L
"%08lx", RelativeIds
[i
]);
3550 /* Lookup aliases */
3551 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3554 &AccountsKeyHandle
);
3555 if (NT_SUCCESS(Status
))
3557 Status
= SampRegOpenKey(AccountsKeyHandle
,
3561 if (NT_SUCCESS(Status
))
3564 Status
= SampRegQueryValue(AccountKeyHandle
,
3569 if (NT_SUCCESS(Status
))
3571 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
3572 if (Names
->Element
[i
].Buffer
== NULL
)
3573 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3575 if (NT_SUCCESS(Status
))
3577 Names
->Element
[i
].MaximumLength
= (USHORT
)DataLength
;
3578 Names
->Element
[i
].Length
= (USHORT
)(DataLength
- sizeof(WCHAR
));
3580 Status
= SampRegQueryValue(AccountKeyHandle
,
3583 Names
->Element
[i
].Buffer
,
3588 SampRegCloseKey(&AccountKeyHandle
);
3591 SampRegCloseKey(&AccountsKeyHandle
);
3594 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3597 /* Return alias account */
3598 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
3600 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
3601 Use
->Element
[i
] = SidTypeAlias
;
3607 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3610 &AccountsKeyHandle
);
3611 if (NT_SUCCESS(Status
))
3613 Status
= SampRegOpenKey(AccountsKeyHandle
,
3617 if (NT_SUCCESS(Status
))
3620 Status
= SampRegQueryValue(AccountKeyHandle
,
3625 if (NT_SUCCESS(Status
))
3627 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
3628 if (Names
->Element
[i
].Buffer
== NULL
)
3629 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3631 if (NT_SUCCESS(Status
))
3633 Names
->Element
[i
].MaximumLength
= (USHORT
)DataLength
;
3634 Names
->Element
[i
].Length
= (USHORT
)(DataLength
- sizeof(WCHAR
));
3636 Status
= SampRegQueryValue(AccountKeyHandle
,
3639 Names
->Element
[i
].Buffer
,
3644 SampRegCloseKey(&AccountKeyHandle
);
3647 SampRegCloseKey(&AccountsKeyHandle
);
3650 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3653 /* Return group account */
3654 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
3656 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
3657 Use
->Element
[i
] = SidTypeGroup
;
3663 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3666 &AccountsKeyHandle
);
3667 if (NT_SUCCESS(Status
))
3669 Status
= SampRegOpenKey(AccountsKeyHandle
,
3673 if (NT_SUCCESS(Status
))
3676 Status
= SampRegQueryValue(AccountKeyHandle
,
3681 if (NT_SUCCESS(Status
))
3683 TRACE("DataLength: %lu\n", DataLength
);
3685 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
3686 if (Names
->Element
[i
].Buffer
== NULL
)
3687 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3689 if (NT_SUCCESS(Status
))
3691 Names
->Element
[i
].MaximumLength
= (USHORT
)DataLength
;
3692 Names
->Element
[i
].Length
= (USHORT
)(DataLength
- sizeof(WCHAR
));
3694 Status
= SampRegQueryValue(AccountKeyHandle
,
3697 Names
->Element
[i
].Buffer
,
3702 SampRegCloseKey(&AccountKeyHandle
);
3705 SampRegCloseKey(&AccountsKeyHandle
);
3708 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3711 /* Return user account */
3712 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
3714 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
3715 Use
->Element
[i
] = SidTypeUser
;
3720 /* Return unknown account */
3721 Use
->Element
[i
] = SidTypeUnknown
;
3725 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3726 Status
= STATUS_SUCCESS
;
3728 if (NT_SUCCESS(Status
))
3730 if (MappedCount
== 0)
3731 Status
= STATUS_NONE_MAPPED
;
3732 else if (MappedCount
< Count
)
3733 Status
= STATUS_SOME_NOT_MAPPED
;
3737 if (Names
->Element
!= NULL
)
3739 for (i
= 0; i
< Count
; i
++)
3741 if (Names
->Element
[i
].Buffer
!= NULL
)
3742 midl_user_free(Names
->Element
[i
].Buffer
);
3745 midl_user_free(Names
->Element
);
3746 Names
->Element
= NULL
;
3751 if (Use
->Element
!= NULL
)
3753 midl_user_free(Use
->Element
);
3754 Use
->Element
= NULL
;
3760 RtlReleaseResource(&SampResource
);
3769 SamrOpenGroup(IN SAMPR_HANDLE DomainHandle
,
3770 IN ACCESS_MASK DesiredAccess
,
3771 IN
unsigned long GroupId
,
3772 OUT SAMPR_HANDLE
*GroupHandle
)
3774 PSAM_DB_OBJECT DomainObject
;
3775 PSAM_DB_OBJECT GroupObject
;
3779 TRACE("SamrOpenGroup(%p %lx %lx %p)\n",
3780 DomainHandle
, DesiredAccess
, GroupId
, GroupHandle
);
3782 /* Map generic access rights */
3783 RtlMapGenericMask(&DesiredAccess
,
3786 RtlAcquireResourceShared(&SampResource
,
3789 /* Validate the domain handle */
3790 Status
= SampValidateDbObject(DomainHandle
,
3794 if (!NT_SUCCESS(Status
))
3796 TRACE("failed with status 0x%08lx\n", Status
);
3800 /* Convert the RID into a string (hex) */
3801 swprintf(szRid
, L
"%08lX", GroupId
);
3803 /* Create the group object */
3804 Status
= SampOpenDbObject(DomainObject
,
3811 if (!NT_SUCCESS(Status
))
3813 TRACE("failed with status 0x%08lx\n", Status
);
3817 *GroupHandle
= (SAMPR_HANDLE
)GroupObject
;
3820 RtlReleaseResource(&SampResource
);
3827 SampQueryGroupGeneral(PSAM_DB_OBJECT GroupObject
,
3828 PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
3830 PSAMPR_GROUP_INFO_BUFFER InfoBuffer
= NULL
;
3831 SAM_GROUP_FIXED_DATA FixedData
;
3832 ULONG MembersLength
= 0;
3838 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_GROUP_INFO_BUFFER
));
3839 if (InfoBuffer
== NULL
)
3840 return STATUS_INSUFFICIENT_RESOURCES
;
3842 Status
= SampGetObjectAttributeString(GroupObject
,
3844 &InfoBuffer
->General
.Name
);
3845 if (!NT_SUCCESS(Status
))
3847 TRACE("Status 0x%08lx\n", Status
);
3851 Status
= SampGetObjectAttributeString(GroupObject
,
3853 &InfoBuffer
->General
.AdminComment
);
3854 if (!NT_SUCCESS(Status
))
3856 TRACE("Status 0x%08lx\n", Status
);
3860 Length
= sizeof(SAM_GROUP_FIXED_DATA
);
3861 Status
= SampGetObjectAttribute(GroupObject
,