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 /* FUNCTIONS ***************************************************************/
23 SampStartRpcServer(VOID
)
27 TRACE("SampStartRpcServer() called\n");
29 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
33 if (Status
!= RPC_S_OK
)
35 WARN("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
39 Status
= RpcServerRegisterIf(samr_v1_0_s_ifspec
,
42 if (Status
!= RPC_S_OK
)
44 WARN("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
48 Status
= RpcServerListen(1, 20, TRUE
);
49 if (Status
!= RPC_S_OK
)
51 WARN("RpcServerListen() failed (Status %lx)\n", Status
);
55 TRACE("SampStartRpcServer() done\n");
59 void __RPC_FAR
* __RPC_USER
midl_user_allocate(SIZE_T len
)
61 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
65 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
67 HeapFree(GetProcessHeap(), 0, ptr
);
70 void __RPC_USER
SAMPR_HANDLE_rundown(SAMPR_HANDLE hHandle
)
77 SamrConnect(IN PSAMPR_SERVER_NAME ServerName
,
78 OUT SAMPR_HANDLE
*ServerHandle
,
79 IN ACCESS_MASK DesiredAccess
)
81 PSAM_DB_OBJECT ServerObject
;
84 TRACE("SamrConnect(%p %p %lx)\n",
85 ServerName
, ServerHandle
, DesiredAccess
);
87 Status
= SampOpenDbObject(NULL
,
93 if (NT_SUCCESS(Status
))
94 *ServerHandle
= (SAMPR_HANDLE
)ServerObject
;
96 TRACE("SamrConnect done (Status 0x%08lx)\n", Status
);
104 SamrCloseHandle(IN OUT SAMPR_HANDLE
*SamHandle
)
106 PSAM_DB_OBJECT DbObject
;
107 NTSTATUS Status
= STATUS_SUCCESS
;
109 TRACE("SamrCloseHandle(%p)\n", SamHandle
);
111 Status
= SampValidateDbObject(*SamHandle
,
115 if (Status
== STATUS_SUCCESS
)
117 Status
= SampCloseDbObject(DbObject
);
121 TRACE("SamrCloseHandle done (Status 0x%08lx)\n", Status
);
129 SamrSetSecurityObject(IN SAMPR_HANDLE ObjectHandle
,
130 IN SECURITY_INFORMATION SecurityInformation
,
131 IN PSAMPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor
)
134 return STATUS_NOT_IMPLEMENTED
;
140 SamrQuerySecurityObject(IN SAMPR_HANDLE ObjectHandle
,
141 IN SECURITY_INFORMATION SecurityInformation
,
142 OUT PSAMPR_SR_SECURITY_DESCRIPTOR
* SecurityDescriptor
)
145 return STATUS_NOT_IMPLEMENTED
;
151 SamrShutdownSamServer(IN SAMPR_HANDLE ServerHandle
)
154 return STATUS_NOT_IMPLEMENTED
;
160 SamrLookupDomainInSamServer(IN SAMPR_HANDLE ServerHandle
,
161 IN PRPC_UNICODE_STRING Name
,
162 OUT PRPC_SID
*DomainId
)
164 PSAM_DB_OBJECT ServerObject
;
165 HANDLE DomainsKeyHandle
= NULL
;
166 HANDLE DomainKeyHandle
= NULL
;
167 WCHAR DomainKeyName
[64];
169 WCHAR DomainNameString
[MAX_COMPUTERNAME_LENGTH
+ 1];
170 UNICODE_STRING DomainName
;
175 TRACE("SamrLookupDomainInSamServer(%p %p %p)\n",
176 ServerHandle
, Name
, DomainId
);
178 /* Validate the server handle */
179 Status
= SampValidateDbObject(ServerHandle
,
181 SAM_SERVER_LOOKUP_DOMAIN
,
183 if (!NT_SUCCESS(Status
))
188 Status
= SampRegOpenKey(ServerObject
->KeyHandle
,
192 if (!NT_SUCCESS(Status
))
196 while (Found
== FALSE
)
198 Status
= SampRegEnumerateSubKey(DomainsKeyHandle
,
202 if (!NT_SUCCESS(Status
))
204 if (Status
== STATUS_NO_MORE_ENTRIES
)
205 Status
= STATUS_NO_SUCH_DOMAIN
;
209 TRACE("Domain key name: %S\n", DomainKeyName
);
211 Status
= SampRegOpenKey(DomainsKeyHandle
,
215 if (NT_SUCCESS(Status
))
217 Length
= (MAX_COMPUTERNAME_LENGTH
+ 1) * sizeof(WCHAR
);
218 Status
= SampRegQueryValue(DomainKeyHandle
,
221 (PVOID
)&DomainNameString
,
223 if (NT_SUCCESS(Status
))
225 TRACE("Domain name: %S\n", DomainNameString
);
227 RtlInitUnicodeString(&DomainName
,
229 if (RtlEqualUnicodeString(&DomainName
, (PUNICODE_STRING
)Name
, TRUE
))
231 TRACE("Found it!\n");
234 Status
= SampRegQueryValue(DomainKeyHandle
,
239 if (NT_SUCCESS(Status
))
241 *DomainId
= midl_user_allocate(Length
);
243 SampRegQueryValue(DomainKeyHandle
,
249 Status
= STATUS_SUCCESS
;
255 NtClose(DomainKeyHandle
);
261 NtClose(DomainsKeyHandle
);
269 SamrEnumerateDomainsInSamServer(IN SAMPR_HANDLE ServerHandle
,
270 IN OUT
unsigned long *EnumerationContext
,
271 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
272 IN ULONG PreferedMaximumLength
,
273 OUT PULONG CountReturned
)
275 PSAM_DB_OBJECT ServerObject
;
276 WCHAR DomainKeyName
[64];
277 HANDLE DomainsKeyHandle
;
278 HANDLE DomainKeyHandle
;
281 ULONG RequiredLength
;
284 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
287 TRACE("SamrEnumerateDomainsInSamServer(%p %p %p %lu %p)\n",
288 ServerHandle
, EnumerationContext
, Buffer
, PreferedMaximumLength
,
291 /* Validate the server handle */
292 Status
= SampValidateDbObject(ServerHandle
,
294 SAM_SERVER_ENUMERATE_DOMAINS
,
296 if (!NT_SUCCESS(Status
))
299 Status
= SampRegOpenKey(ServerObject
->KeyHandle
,
303 if (!NT_SUCCESS(Status
))
306 EnumIndex
= *EnumerationContext
;
312 Status
= SampRegEnumerateSubKey(DomainsKeyHandle
,
316 if (!NT_SUCCESS(Status
))
319 TRACE("EnumIndex: %lu\n", EnumIndex
);
320 TRACE("Domain key name: %S\n", DomainKeyName
);
322 Status
= SampRegOpenKey(DomainsKeyHandle
,
326 TRACE("SampRegOpenKey returned %08lX\n", Status
);
327 if (NT_SUCCESS(Status
))
330 Status
= SampRegQueryValue(DomainKeyHandle
,
335 TRACE("SampRegQueryValue returned %08lX\n", Status
);
336 if (NT_SUCCESS(Status
))
338 TRACE("Data length: %lu\n", DataLength
);
340 if ((RequiredLength
+ DataLength
+ sizeof(UNICODE_STRING
)) > PreferedMaximumLength
)
343 RequiredLength
+= (DataLength
+ sizeof(UNICODE_STRING
));
347 NtClose(DomainKeyHandle
);
353 TRACE("EnumCount: %lu\n", EnumCount
);
354 TRACE("RequiredLength: %lu\n", RequiredLength
);
356 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
357 if (EnumBuffer
== NULL
)
359 Status
= STATUS_INSUFFICIENT_RESOURCES
;
363 EnumBuffer
->EntriesRead
= EnumCount
;
364 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
365 if (EnumBuffer
->Buffer
== NULL
)
367 Status
= STATUS_INSUFFICIENT_RESOURCES
;
371 EnumIndex
= *EnumerationContext
;
372 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
374 Status
= SampRegEnumerateSubKey(DomainsKeyHandle
,
378 if (!NT_SUCCESS(Status
))
381 TRACE("EnumIndex: %lu\n", EnumIndex
);
382 TRACE("Domain key name: %S\n", DomainKeyName
);
384 Status
= SampRegOpenKey(DomainsKeyHandle
,
388 TRACE("SampRegOpenKey returned %08lX\n", Status
);
389 if (NT_SUCCESS(Status
))
392 Status
= SampRegQueryValue(DomainKeyHandle
,
397 TRACE("SampRegQueryValue returned %08lX\n", Status
);
398 if (NT_SUCCESS(Status
))
400 EnumBuffer
->Buffer
[i
].RelativeId
= 0;
401 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)DataLength
- sizeof(WCHAR
);
402 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)DataLength
;
403 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(DataLength
);
404 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
406 NtClose(DomainKeyHandle
);
407 Status
= STATUS_INSUFFICIENT_RESOURCES
;
411 Status
= SampRegQueryValue(DomainKeyHandle
,
414 EnumBuffer
->Buffer
[i
].Name
.Buffer
,
416 TRACE("SampRegQueryValue returned %08lX\n", Status
);
417 if (NT_SUCCESS(Status
))
419 TRACE("Domain name: %S\n", EnumBuffer
->Buffer
[i
].Name
.Buffer
);
423 NtClose(DomainKeyHandle
);
425 if (!NT_SUCCESS(Status
))
430 if (NT_SUCCESS(Status
))
432 *EnumerationContext
+= EnumCount
;
433 *Buffer
= EnumBuffer
;
434 *CountReturned
= EnumCount
;
438 if (!NT_SUCCESS(Status
))
440 *EnumerationContext
= 0;
444 if (EnumBuffer
!= NULL
)
446 if (EnumBuffer
->Buffer
!= NULL
)
448 if (EnumBuffer
->EntriesRead
!= 0)
450 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
452 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
453 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
457 midl_user_free(EnumBuffer
->Buffer
);
460 midl_user_free(EnumBuffer
);
464 NtClose(DomainsKeyHandle
);
472 SamrOpenDomain(IN SAMPR_HANDLE ServerHandle
,
473 IN ACCESS_MASK DesiredAccess
,
474 IN PRPC_SID DomainId
,
475 OUT SAMPR_HANDLE
*DomainHandle
)
477 PSAM_DB_OBJECT ServerObject
;
478 PSAM_DB_OBJECT DomainObject
;
481 TRACE("SamrOpenDomain(%p %lx %p %p)\n",
482 ServerHandle
, DesiredAccess
, DomainId
, DomainHandle
);
484 /* Validate the server handle */
485 Status
= SampValidateDbObject(ServerHandle
,
487 SAM_SERVER_LOOKUP_DOMAIN
,
489 if (!NT_SUCCESS(Status
))
492 /* Validate the Domain SID */
493 if ((DomainId
->Revision
!= SID_REVISION
) ||
494 (DomainId
->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
) ||
495 (memcmp(&DomainId
->IdentifierAuthority
, &NtSidAuthority
, sizeof(SID_IDENTIFIER_AUTHORITY
)) != 0))
496 return STATUS_INVALID_PARAMETER
;
498 /* Open the domain object */
499 if ((DomainId
->SubAuthorityCount
== 1) &&
500 (DomainId
->SubAuthority
[0] == SECURITY_BUILTIN_DOMAIN_RID
))
502 /* Builtin domain object */
503 TRACE("Opening the builtin domain object.\n");
505 Status
= SampOpenDbObject(ServerObject
,
512 else if ((DomainId
->SubAuthorityCount
== 4) &&
513 (DomainId
->SubAuthority
[0] == SECURITY_NT_NON_UNIQUE
))
515 /* Account domain object */
516 TRACE("Opening the account domain object.\n");
518 /* FIXME: Check the account domain sub authorities!!! */
520 Status
= SampOpenDbObject(ServerObject
,
529 /* No vaild domain SID */
530 Status
= STATUS_INVALID_PARAMETER
;
533 if (NT_SUCCESS(Status
))
534 *DomainHandle
= (SAMPR_HANDLE
)DomainObject
;
536 TRACE("SamrOpenDomain done (Status 0x%08lx)\n", Status
);
543 SampQueryDomainPassword(PSAM_DB_OBJECT DomainObject
,
544 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
546 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
547 SAM_DOMAIN_FIXED_DATA FixedData
;
553 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
554 if (InfoBuffer
== NULL
)
555 return STATUS_INSUFFICIENT_RESOURCES
;
557 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
558 Status
= SampGetObjectAttribute(DomainObject
,
563 if (!NT_SUCCESS(Status
))
566 InfoBuffer
->Password
.MinPasswordLength
= FixedData
.MinPasswordLength
;
567 InfoBuffer
->Password
.PasswordHistoryLength
= FixedData
.PasswordHistoryLength
;
568 InfoBuffer
->Password
.PasswordProperties
= FixedData
.PasswordProperties
;
569 InfoBuffer
->Password
.MaxPasswordAge
.LowPart
= FixedData
.MaxPasswordAge
.LowPart
;
570 InfoBuffer
->Password
.MaxPasswordAge
.HighPart
= FixedData
.MaxPasswordAge
.HighPart
;
571 InfoBuffer
->Password
.MinPasswordAge
.LowPart
= FixedData
.MinPasswordAge
.LowPart
;
572 InfoBuffer
->Password
.MinPasswordAge
.HighPart
= FixedData
.MinPasswordAge
.HighPart
;
574 *Buffer
= InfoBuffer
;
577 if (!NT_SUCCESS(Status
))
579 if (InfoBuffer
!= NULL
)
581 midl_user_free(InfoBuffer
);
590 SampQueryDomainGeneral(PSAM_DB_OBJECT DomainObject
,
591 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
593 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
594 SAM_DOMAIN_FIXED_DATA FixedData
;
600 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
601 if (InfoBuffer
== NULL
)
602 return STATUS_INSUFFICIENT_RESOURCES
;
604 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
605 Status
= SampGetObjectAttribute(DomainObject
,
610 if (!NT_SUCCESS(Status
))
613 InfoBuffer
->General
.ForceLogoff
.LowPart
= FixedData
.ForceLogoff
.LowPart
;
614 InfoBuffer
->General
.ForceLogoff
.HighPart
= FixedData
.ForceLogoff
.HighPart
;
615 InfoBuffer
->General
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
616 InfoBuffer
->General
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
617 InfoBuffer
->General
.DomainServerState
= FixedData
.DomainServerState
;
618 InfoBuffer
->General
.DomainServerRole
= FixedData
.DomainServerRole
;
619 InfoBuffer
->General
.UasCompatibilityRequired
= FixedData
.UasCompatibilityRequired
;
621 /* Get the OemInformation string */
622 Status
= SampGetObjectAttributeString(DomainObject
,
624 &InfoBuffer
->General
.OemInformation
);
625 if (!NT_SUCCESS(Status
))
627 TRACE("Status 0x%08lx\n", Status
);
631 /* Get the Name string */
632 Status
= SampGetObjectAttributeString(DomainObject
,
634 &InfoBuffer
->General
.DomainName
);
635 if (!NT_SUCCESS(Status
))
637 TRACE("Status 0x%08lx\n", Status
);
641 /* Get the ReplicaSourceNodeName string */
642 Status
= SampGetObjectAttributeString(DomainObject
,
643 L
"ReplicaSourceNodeName",
644 &InfoBuffer
->General
.ReplicaSourceNodeName
);
645 if (!NT_SUCCESS(Status
))
647 TRACE("Status 0x%08lx\n", Status
);
651 InfoBuffer
->General
.UserCount
= 0; /* FIXME */
652 InfoBuffer
->General
.GroupCount
= 0; /* FIXME */
653 InfoBuffer
->General
.AliasCount
= 0; /* FIXME */
655 *Buffer
= InfoBuffer
;
658 if (!NT_SUCCESS(Status
))
660 if (InfoBuffer
!= NULL
)
662 if (InfoBuffer
->General
.OemInformation
.Buffer
!= NULL
)
663 midl_user_free(InfoBuffer
->General
.OemInformation
.Buffer
);
665 if (InfoBuffer
->General
.DomainName
.Buffer
!= NULL
)
666 midl_user_free(InfoBuffer
->General
.DomainName
.Buffer
);
668 if (InfoBuffer
->General
.ReplicaSourceNodeName
.Buffer
!= NULL
)
669 midl_user_free(InfoBuffer
->General
.ReplicaSourceNodeName
.Buffer
);
671 midl_user_free(InfoBuffer
);
680 SampQueryDomainLogoff(PSAM_DB_OBJECT DomainObject
,
681 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
683 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
684 SAM_DOMAIN_FIXED_DATA FixedData
;
690 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
691 if (InfoBuffer
== NULL
)
692 return STATUS_INSUFFICIENT_RESOURCES
;
694 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
695 Status
= SampGetObjectAttribute(DomainObject
,
700 if (!NT_SUCCESS(Status
))
703 InfoBuffer
->Logoff
.ForceLogoff
.LowPart
= FixedData
.ForceLogoff
.LowPart
;
704 InfoBuffer
->Logoff
.ForceLogoff
.HighPart
= FixedData
.ForceLogoff
.HighPart
;
706 *Buffer
= InfoBuffer
;
709 if (!NT_SUCCESS(Status
))
711 if (InfoBuffer
!= NULL
)
713 midl_user_free(InfoBuffer
);
722 SampQueryDomainOem(PSAM_DB_OBJECT DomainObject
,
723 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
725 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
730 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
731 if (InfoBuffer
== NULL
)
732 return STATUS_INSUFFICIENT_RESOURCES
;
734 /* Get the OemInformation string */
735 Status
= SampGetObjectAttributeString(DomainObject
,
737 &InfoBuffer
->Oem
.OemInformation
);
738 if (!NT_SUCCESS(Status
))
740 TRACE("Status 0x%08lx\n", Status
);
744 *Buffer
= InfoBuffer
;
747 if (!NT_SUCCESS(Status
))
749 if (InfoBuffer
!= NULL
)
751 if (InfoBuffer
->Oem
.OemInformation
.Buffer
!= NULL
)
752 midl_user_free(InfoBuffer
->Oem
.OemInformation
.Buffer
);
754 midl_user_free(InfoBuffer
);
763 SampQueryDomainName(PSAM_DB_OBJECT DomainObject
,
764 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
766 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
771 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
772 if (InfoBuffer
== NULL
)
773 return STATUS_INSUFFICIENT_RESOURCES
;
775 /* Get the Name string */
776 Status
= SampGetObjectAttributeString(DomainObject
,
778 &InfoBuffer
->Name
.DomainName
);
779 if (!NT_SUCCESS(Status
))
781 TRACE("Status 0x%08lx\n", Status
);
785 *Buffer
= InfoBuffer
;
788 if (!NT_SUCCESS(Status
))
790 if (InfoBuffer
!= NULL
)
792 if (InfoBuffer
->Name
.DomainName
.Buffer
!= NULL
)
793 midl_user_free(InfoBuffer
->Name
.DomainName
.Buffer
);
795 midl_user_free(InfoBuffer
);
804 SampQueryDomainReplication(PSAM_DB_OBJECT DomainObject
,
805 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
807 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
812 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
813 if (InfoBuffer
== NULL
)
814 return STATUS_INSUFFICIENT_RESOURCES
;
816 /* Get the ReplicaSourceNodeName string */
817 Status
= SampGetObjectAttributeString(DomainObject
,
818 L
"ReplicaSourceNodeName",
819 &InfoBuffer
->Replication
.ReplicaSourceNodeName
);
820 if (!NT_SUCCESS(Status
))
822 TRACE("Status 0x%08lx\n", Status
);
826 *Buffer
= InfoBuffer
;
829 if (!NT_SUCCESS(Status
))
831 if (InfoBuffer
!= NULL
)
833 if (InfoBuffer
->Replication
.ReplicaSourceNodeName
.Buffer
!= NULL
)
834 midl_user_free(InfoBuffer
->Replication
.ReplicaSourceNodeName
.Buffer
);
836 midl_user_free(InfoBuffer
);
845 SampQueryDomainServerRole(PSAM_DB_OBJECT DomainObject
,
846 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
848 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
849 SAM_DOMAIN_FIXED_DATA FixedData
;
855 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
856 if (InfoBuffer
== NULL
)
857 return STATUS_INSUFFICIENT_RESOURCES
;
859 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
860 Status
= SampGetObjectAttribute(DomainObject
,
865 if (!NT_SUCCESS(Status
))
868 InfoBuffer
->Role
.DomainServerRole
= FixedData
.DomainServerRole
;
870 *Buffer
= InfoBuffer
;
873 if (!NT_SUCCESS(Status
))
875 if (InfoBuffer
!= NULL
)
877 midl_user_free(InfoBuffer
);
886 SampQueryDomainModified(PSAM_DB_OBJECT DomainObject
,
887 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
889 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
890 SAM_DOMAIN_FIXED_DATA FixedData
;
896 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
897 if (InfoBuffer
== NULL
)
898 return STATUS_INSUFFICIENT_RESOURCES
;
900 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
901 Status
= SampGetObjectAttribute(DomainObject
,
906 if (!NT_SUCCESS(Status
))
909 InfoBuffer
->Modified
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
910 InfoBuffer
->Modified
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
911 InfoBuffer
->Modified
.CreationTime
.LowPart
= FixedData
.CreationTime
.LowPart
;
912 InfoBuffer
->Modified
.CreationTime
.HighPart
= FixedData
.CreationTime
.HighPart
;
914 *Buffer
= InfoBuffer
;
917 if (!NT_SUCCESS(Status
))
919 if (InfoBuffer
!= NULL
)
921 midl_user_free(InfoBuffer
);
930 SampQueryDomainState(PSAM_DB_OBJECT DomainObject
,
931 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
933 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
934 SAM_DOMAIN_FIXED_DATA FixedData
;
940 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
941 if (InfoBuffer
== NULL
)
942 return STATUS_INSUFFICIENT_RESOURCES
;
944 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
945 Status
= SampGetObjectAttribute(DomainObject
,
950 if (!NT_SUCCESS(Status
))
953 InfoBuffer
->State
.DomainServerState
= FixedData
.DomainServerState
;
955 *Buffer
= InfoBuffer
;
958 if (!NT_SUCCESS(Status
))
960 if (InfoBuffer
!= NULL
)
962 midl_user_free(InfoBuffer
);
971 SampQueryDomainGeneral2(PSAM_DB_OBJECT DomainObject
,
972 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
974 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
975 SAM_DOMAIN_FIXED_DATA FixedData
;
981 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
982 if (InfoBuffer
== NULL
)
983 return STATUS_INSUFFICIENT_RESOURCES
;
985 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
986 Status
= SampGetObjectAttribute(DomainObject
,
991 if (!NT_SUCCESS(Status
))
994 InfoBuffer
->General2
.I1
.ForceLogoff
.LowPart
= FixedData
.ForceLogoff
.LowPart
;
995 InfoBuffer
->General2
.I1
.ForceLogoff
.HighPart
= FixedData
.ForceLogoff
.HighPart
;
996 InfoBuffer
->General2
.I1
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
997 InfoBuffer
->General2
.I1
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
998 InfoBuffer
->General2
.I1
.DomainServerState
= FixedData
.DomainServerState
;
999 InfoBuffer
->General2
.I1
.DomainServerRole
= FixedData
.DomainServerRole
;
1000 InfoBuffer
->General2
.I1
.UasCompatibilityRequired
= FixedData
.UasCompatibilityRequired
;
1002 InfoBuffer
->General2
.LockoutDuration
= FixedData
.LockoutDuration
;
1003 InfoBuffer
->General2
.LockoutObservationWindow
= FixedData
.LockoutObservationWindow
;
1004 InfoBuffer
->General2
.LockoutThreshold
= FixedData
.LockoutThreshold
;
1006 /* Get the OemInformation string */
1007 Status
= SampGetObjectAttributeString(DomainObject
,
1009 &InfoBuffer
->General2
.I1
.OemInformation
);
1010 if (!NT_SUCCESS(Status
))
1012 TRACE("Status 0x%08lx\n", Status
);
1016 /* Get the Name string */
1017 Status
= SampGetObjectAttributeString(DomainObject
,
1019 &InfoBuffer
->General2
.I1
.DomainName
);
1020 if (!NT_SUCCESS(Status
))
1022 TRACE("Status 0x%08lx\n", Status
);
1026 /* Get the ReplicaSourceNodeName string */
1027 Status
= SampGetObjectAttributeString(DomainObject
,
1028 L
"ReplicaSourceNodeName",
1029 &InfoBuffer
->General2
.I1
.ReplicaSourceNodeName
);
1030 if (!NT_SUCCESS(Status
))
1032 TRACE("Status 0x%08lx\n", Status
);
1036 InfoBuffer
->General2
.I1
.UserCount
= 0; /* FIXME */
1037 InfoBuffer
->General2
.I1
.GroupCount
= 0; /* FIXME */
1038 InfoBuffer
->General2
.I1
.AliasCount
= 0; /* FIXME */
1040 *Buffer
= InfoBuffer
;
1043 if (!NT_SUCCESS(Status
))
1045 if (InfoBuffer
!= NULL
)
1047 if (InfoBuffer
->General2
.I1
.OemInformation
.Buffer
!= NULL
)
1048 midl_user_free(InfoBuffer
->General2
.I1
.OemInformation
.Buffer
);
1050 if (InfoBuffer
->General2
.I1
.DomainName
.Buffer
!= NULL
)
1051 midl_user_free(InfoBuffer
->General2
.I1
.DomainName
.Buffer
);
1053 if (InfoBuffer
->General2
.I1
.ReplicaSourceNodeName
.Buffer
!= NULL
)
1054 midl_user_free(InfoBuffer
->General2
.I1
.ReplicaSourceNodeName
.Buffer
);
1056 midl_user_free(InfoBuffer
);
1065 SampQueryDomainLockout(PSAM_DB_OBJECT DomainObject
,
1066 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1068 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1069 SAM_DOMAIN_FIXED_DATA FixedData
;
1075 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1076 if (InfoBuffer
== NULL
)
1077 return STATUS_INSUFFICIENT_RESOURCES
;
1079 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1080 Status
= SampGetObjectAttribute(DomainObject
,
1085 if (!NT_SUCCESS(Status
))
1088 InfoBuffer
->Lockout
.LockoutDuration
= FixedData
.LockoutDuration
;
1089 InfoBuffer
->Lockout
.LockoutObservationWindow
= FixedData
.LockoutObservationWindow
;
1090 InfoBuffer
->Lockout
.LockoutThreshold
= FixedData
.LockoutThreshold
;
1092 *Buffer
= InfoBuffer
;
1095 if (!NT_SUCCESS(Status
))
1097 if (InfoBuffer
!= NULL
)
1099 midl_user_free(InfoBuffer
);
1108 SampQueryDomainModified2(PSAM_DB_OBJECT DomainObject
,
1109 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1111 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1112 SAM_DOMAIN_FIXED_DATA FixedData
;
1118 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1119 if (InfoBuffer
== NULL
)
1120 return STATUS_INSUFFICIENT_RESOURCES
;
1122 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1123 Status
= SampGetObjectAttribute(DomainObject
,
1128 if (!NT_SUCCESS(Status
))
1131 InfoBuffer
->Modified2
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
1132 InfoBuffer
->Modified2
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
1133 InfoBuffer
->Modified2
.CreationTime
.LowPart
= FixedData
.CreationTime
.LowPart
;
1134 InfoBuffer
->Modified2
.CreationTime
.HighPart
= FixedData
.CreationTime
.HighPart
;
1135 InfoBuffer
->Modified2
.ModifiedCountAtLastPromotion
.LowPart
= FixedData
.ModifiedCountAtLastPromotion
.LowPart
;
1136 InfoBuffer
->Modified2
.ModifiedCountAtLastPromotion
.HighPart
= FixedData
.ModifiedCountAtLastPromotion
.HighPart
;
1138 *Buffer
= InfoBuffer
;
1141 if (!NT_SUCCESS(Status
))
1143 if (InfoBuffer
!= NULL
)
1145 midl_user_free(InfoBuffer
);
1156 SamrQueryInformationDomain(IN SAMPR_HANDLE DomainHandle
,
1157 IN DOMAIN_INFORMATION_CLASS DomainInformationClass
,
1158 OUT PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1160 PSAM_DB_OBJECT DomainObject
;
1161 ACCESS_MASK DesiredAccess
;
1164 TRACE("SamrQueryInformationDomain(%p %lu %p)\n",
1165 DomainHandle
, DomainInformationClass
, Buffer
);
1167 switch (DomainInformationClass
)
1169 case DomainPasswordInformation
:
1170 case DomainLockoutInformation
:
1171 DesiredAccess
= DOMAIN_READ_PASSWORD_PARAMETERS
;
1174 case DomainGeneralInformation
:
1175 case DomainLogoffInformation
:
1176 case DomainOemInformation
:
1177 case DomainNameInformation
:
1178 case DomainReplicationInformation
:
1179 case DomainServerRoleInformation
:
1180 case DomainModifiedInformation
:
1181 case DomainStateInformation
:
1182 case DomainModifiedInformation2
:
1183 DesiredAccess
= DOMAIN_READ_OTHER_PARAMETERS
;
1186 case DomainGeneralInformation2
:
1187 DesiredAccess
= DOMAIN_READ_PASSWORD_PARAMETERS
|
1188 DOMAIN_READ_OTHER_PARAMETERS
;
1192 return STATUS_INVALID_INFO_CLASS
;
1195 /* Validate the server handle */
1196 Status
= SampValidateDbObject(DomainHandle
,
1200 if (!NT_SUCCESS(Status
))
1203 switch (DomainInformationClass
)
1205 case DomainPasswordInformation
:
1206 Status
= SampQueryDomainPassword(DomainObject
,
1210 case DomainGeneralInformation
:
1211 Status
= SampQueryDomainGeneral(DomainObject
,
1215 case DomainLogoffInformation
:
1216 Status
= SampQueryDomainLogoff(DomainObject
,
1220 case DomainOemInformation
:
1221 Status
= SampQueryDomainOem(DomainObject
,
1225 case DomainNameInformation
:
1226 Status
= SampQueryDomainName(DomainObject
,
1230 case DomainReplicationInformation
:
1231 Status
= SampQueryDomainReplication(DomainObject
,
1235 case DomainServerRoleInformation
:
1236 Status
= SampQueryDomainServerRole(DomainObject
,
1240 case DomainModifiedInformation
:
1241 Status
= SampQueryDomainModified(DomainObject
,
1245 case DomainStateInformation
:
1246 Status
= SampQueryDomainState(DomainObject
,
1250 case DomainGeneralInformation2
:
1251 Status
= SampQueryDomainGeneral2(DomainObject
,
1255 case DomainLockoutInformation
:
1256 Status
= SampQueryDomainLockout(DomainObject
,
1260 case DomainModifiedInformation2
:
1261 Status
= SampQueryDomainModified2(DomainObject
,
1266 Status
= STATUS_NOT_IMPLEMENTED
;
1274 SampSetDomainPassword(PSAM_DB_OBJECT DomainObject
,
1275 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1277 SAM_DOMAIN_FIXED_DATA FixedData
;
1281 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1282 Status
= SampGetObjectAttribute(DomainObject
,
1287 if (!NT_SUCCESS(Status
))
1290 FixedData
.MinPasswordLength
= Buffer
->Password
.MinPasswordLength
;
1291 FixedData
.PasswordHistoryLength
= Buffer
->Password
.PasswordHistoryLength
;
1292 FixedData
.PasswordProperties
= Buffer
->Password
.PasswordProperties
;
1293 FixedData
.MaxPasswordAge
.LowPart
= Buffer
->Password
.MaxPasswordAge
.LowPart
;
1294 FixedData
.MaxPasswordAge
.HighPart
= Buffer
->Password
.MaxPasswordAge
.HighPart
;
1295 FixedData
.MinPasswordAge
.LowPart
= Buffer
->Password
.MinPasswordAge
.LowPart
;
1296 FixedData
.MinPasswordAge
.HighPart
= Buffer
->Password
.MinPasswordAge
.HighPart
;
1298 Status
= SampSetObjectAttribute(DomainObject
,
1310 SampSetDomainLogoff(PSAM_DB_OBJECT DomainObject
,
1311 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1313 SAM_DOMAIN_FIXED_DATA FixedData
;
1317 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1318 Status
= SampGetObjectAttribute(DomainObject
,
1323 if (!NT_SUCCESS(Status
))
1326 FixedData
.ForceLogoff
.LowPart
= Buffer
->Logoff
.ForceLogoff
.LowPart
;
1327 FixedData
.ForceLogoff
.HighPart
= Buffer
->Logoff
.ForceLogoff
.HighPart
;
1329 Status
= SampSetObjectAttribute(DomainObject
,
1341 SampSetDomainServerRole(PSAM_DB_OBJECT DomainObject
,
1342 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1344 SAM_DOMAIN_FIXED_DATA FixedData
;
1348 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1349 Status
= SampGetObjectAttribute(DomainObject
,
1354 if (!NT_SUCCESS(Status
))
1357 FixedData
.DomainServerRole
= Buffer
->Role
.DomainServerRole
;
1359 Status
= SampSetObjectAttribute(DomainObject
,
1371 SampSetDomainState(PSAM_DB_OBJECT DomainObject
,
1372 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1374 SAM_DOMAIN_FIXED_DATA FixedData
;
1378 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1379 Status
= SampGetObjectAttribute(DomainObject
,
1384 if (!NT_SUCCESS(Status
))
1387 FixedData
.DomainServerState
= Buffer
->State
.DomainServerState
;
1389 Status
= SampSetObjectAttribute(DomainObject
,
1401 SampSetDomainLockout(PSAM_DB_OBJECT DomainObject
,
1402 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1404 SAM_DOMAIN_FIXED_DATA FixedData
;
1408 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1409 Status
= SampGetObjectAttribute(DomainObject
,
1414 if (!NT_SUCCESS(Status
))
1417 FixedData
.LockoutDuration
= Buffer
->Lockout
.LockoutDuration
;
1418 FixedData
.LockoutObservationWindow
= Buffer
->Lockout
.LockoutObservationWindow
;
1419 FixedData
.LockoutThreshold
= Buffer
->Lockout
.LockoutThreshold
;
1421 Status
= SampSetObjectAttribute(DomainObject
,
1435 SamrSetInformationDomain(IN SAMPR_HANDLE DomainHandle
,
1436 IN DOMAIN_INFORMATION_CLASS DomainInformationClass
,
1437 IN PSAMPR_DOMAIN_INFO_BUFFER DomainInformation
)
1439 PSAM_DB_OBJECT DomainObject
;
1440 ACCESS_MASK DesiredAccess
;
1443 TRACE("SamrSetInformationDomain(%p %lu %p)\n",
1444 DomainHandle
, DomainInformationClass
, DomainInformation
);
1446 switch (DomainInformationClass
)
1448 case DomainPasswordInformation
:
1449 case DomainLockoutInformation
:
1450 DesiredAccess
= DOMAIN_WRITE_PASSWORD_PARAMS
;
1453 case DomainLogoffInformation
:
1454 case DomainOemInformation
:
1455 case DomainNameInformation
:
1456 DesiredAccess
= DOMAIN_WRITE_OTHER_PARAMETERS
;
1459 case DomainReplicationInformation
:
1460 case DomainServerRoleInformation
:
1461 case DomainStateInformation
:
1462 DesiredAccess
= DOMAIN_ADMINISTER_SERVER
;
1466 return STATUS_INVALID_INFO_CLASS
;
1469 /* Validate the server handle */
1470 Status
= SampValidateDbObject(DomainHandle
,
1474 if (!NT_SUCCESS(Status
))
1477 switch (DomainInformationClass
)
1479 case DomainPasswordInformation
:
1480 Status
= SampSetDomainPassword(DomainObject
,
1484 case DomainLogoffInformation
:
1485 Status
= SampSetDomainLogoff(DomainObject
,
1489 case DomainOemInformation
:
1490 Status
= SampSetObjectAttribute(DomainObject
,
1493 DomainInformation
->Oem
.OemInformation
.Buffer
,
1494 DomainInformation
->Oem
.OemInformation
.Length
+ sizeof(WCHAR
));
1497 case DomainNameInformation
:
1498 Status
= SampSetObjectAttribute(DomainObject
,
1501 DomainInformation
->Name
.DomainName
.Buffer
,
1502 DomainInformation
->Name
.DomainName
.Length
+ sizeof(WCHAR
));
1505 case DomainReplicationInformation
:
1506 Status
= SampSetObjectAttribute(DomainObject
,
1507 L
"ReplicaSourceNodeName",
1509 DomainInformation
->Replication
.ReplicaSourceNodeName
.Buffer
,
1510 DomainInformation
->Replication
.ReplicaSourceNodeName
.Length
+ sizeof(WCHAR
));
1513 case DomainServerRoleInformation
:
1514 Status
= SampSetDomainServerRole(DomainObject
,
1518 case DomainStateInformation
:
1519 Status
= SampSetDomainState(DomainObject
,
1523 case DomainLockoutInformation
:
1524 Status
= SampSetDomainLockout(DomainObject
,
1529 Status
= STATUS_NOT_IMPLEMENTED
;
1538 SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle
,
1539 IN PRPC_UNICODE_STRING Name
,
1540 IN ACCESS_MASK DesiredAccess
,
1541 OUT SAMPR_HANDLE
*GroupHandle
,
1542 OUT
unsigned long *RelativeId
)
1544 UNICODE_STRING EmptyString
= RTL_CONSTANT_STRING(L
"");
1545 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
1546 SAM_GROUP_FIXED_DATA FixedGroupData
;
1547 PSAM_DB_OBJECT DomainObject
;
1548 PSAM_DB_OBJECT GroupObject
;
1554 TRACE("SamrCreateGroupInDomain(%p %p %lx %p %p)\n",
1555 DomainHandle
, Name
, DesiredAccess
, GroupHandle
, RelativeId
);
1557 /* Validate the domain handle */
1558 Status
= SampValidateDbObject(DomainHandle
,
1560 DOMAIN_CREATE_GROUP
,
1562 if (!NT_SUCCESS(Status
))
1564 TRACE("failed with status 0x%08lx\n", Status
);
1568 /* Check if the group name already exists in the domain */
1569 Status
= SampCheckAccountNameInDomain(DomainObject
,
1571 if (!NT_SUCCESS(Status
))
1573 TRACE("Group name \'%S\' already exists in domain (Status 0x%08lx)\n",
1574 Name
->Buffer
, Status
);
1578 /* Get the fixed domain attributes */
1579 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1580 Status
= SampGetObjectAttribute(DomainObject
,
1583 (PVOID
)&FixedDomainData
,
1585 if (!NT_SUCCESS(Status
))
1587 TRACE("failed with status 0x%08lx\n", Status
);
1591 /* Increment the NextRid attribute */
1592 ulRid
= FixedDomainData
.NextRid
;
1593 FixedDomainData
.NextRid
++;
1595 /* Store the fixed domain attributes */
1596 Status
= SampSetObjectAttribute(DomainObject
,
1601 if (!NT_SUCCESS(Status
))
1603 TRACE("failed with status 0x%08lx\n", Status
);
1607 TRACE("RID: %lx\n", ulRid
);
1609 /* Convert the RID into a string (hex) */
1610 swprintf(szRid
, L
"%08lX", ulRid
);
1612 /* Create the group object */
1613 Status
= SampCreateDbObject(DomainObject
,
1619 if (!NT_SUCCESS(Status
))
1621 TRACE("failed with status 0x%08lx\n", Status
);
1625 /* Add the account name of the user object */
1626 Status
= SampSetAccountNameInDomain(DomainObject
,
1630 if (!NT_SUCCESS(Status
))
1632 TRACE("failed with status 0x%08lx\n", Status
);
1636 /* Initialize fixed user data */
1637 memset(&FixedGroupData
, 0, sizeof(SAM_GROUP_FIXED_DATA
));
1638 FixedGroupData
.Version
= 1;
1640 FixedGroupData
.GroupId
= ulRid
;
1642 /* Set fixed user data attribute */
1643 Status
= SampSetObjectAttribute(GroupObject
,
1646 (LPVOID
)&FixedGroupData
,
1647 sizeof(SAM_GROUP_FIXED_DATA
));
1648 if (!NT_SUCCESS(Status
))
1650 TRACE("failed with status 0x%08lx\n", Status
);
1654 /* Set the Name attribute */
1655 Status
= SampSetObjectAttribute(GroupObject
,
1658 (LPVOID
)Name
->Buffer
,
1659 Name
->MaximumLength
);
1660 if (!NT_SUCCESS(Status
))
1662 TRACE("failed with status 0x%08lx\n", Status
);
1666 /* Set the AdminComment attribute */
1667 Status
= SampSetObjectAttribute(GroupObject
,
1671 EmptyString
.MaximumLength
);
1672 if (!NT_SUCCESS(Status
))
1674 TRACE("failed with status 0x%08lx\n", Status
);
1678 if (NT_SUCCESS(Status
))
1680 *GroupHandle
= (SAMPR_HANDLE
)GroupObject
;
1681 *RelativeId
= ulRid
;
1684 TRACE("returns with status 0x%08lx\n", Status
);
1693 SamrEnumerateGroupsInDomain(IN SAMPR_HANDLE DomainHandle
,
1694 IN OUT
unsigned long *EnumerationContext
,
1695 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
1696 IN
unsigned long PreferedMaximumLength
,
1697 OUT
unsigned long *CountReturned
)
1699 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
1700 PSAM_DB_OBJECT DomainObject
;
1701 HANDLE GroupsKeyHandle
= NULL
;
1702 HANDLE NamesKeyHandle
= NULL
;
1703 WCHAR GroupName
[64];
1705 ULONG EnumCount
= 0;
1706 ULONG RequiredLength
= 0;
1711 BOOLEAN MoreEntries
= FALSE
;
1714 TRACE("SamrEnumerateUsersInDomain(%p %p %p %lu %p)\n",
1715 DomainHandle
, EnumerationContext
, Buffer
,
1716 PreferedMaximumLength
, CountReturned
);
1718 /* Validate the domain handle */
1719 Status
= SampValidateDbObject(DomainHandle
,
1721 DOMAIN_LIST_ACCOUNTS
,
1723 if (!NT_SUCCESS(Status
))
1726 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
1730 if (!NT_SUCCESS(Status
))
1733 Status
= SampRegOpenKey(GroupsKeyHandle
,
1737 if (!NT_SUCCESS(Status
))
1742 EnumIndex
= *EnumerationContext
;
1746 NameLength
= 64 * sizeof(WCHAR
);
1747 Status
= SampRegEnumerateValue(NamesKeyHandle
,
1754 if (!NT_SUCCESS(Status
))
1756 if (Status
== STATUS_NO_MORE_ENTRIES
)
1757 Status
= STATUS_SUCCESS
;
1761 TRACE("EnumIndex: %lu\n", EnumIndex
);
1762 TRACE("Group name: %S\n", GroupName
);
1763 TRACE("Name length: %lu\n", NameLength
);
1765 if ((RequiredLength
+ NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
)) > PreferedMaximumLength
)
1771 RequiredLength
+= (NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
));
1777 TRACE("EnumCount: %lu\n", EnumCount
);
1778 TRACE("RequiredLength: %lu\n", RequiredLength
);
1780 if (!NT_SUCCESS(Status
))
1783 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
1784 if (EnumBuffer
== NULL
)
1786 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1790 EnumBuffer
->EntriesRead
= EnumCount
;
1794 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
1795 if (EnumBuffer
->Buffer
== NULL
)
1797 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1803 EnumIndex
= *EnumerationContext
;
1804 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
1806 NameLength
= 64 * sizeof(WCHAR
);
1807 DataLength
= sizeof(ULONG
);
1808 Status
= SampRegEnumerateValue(NamesKeyHandle
,
1815 if (!NT_SUCCESS(Status
))
1817 if (Status
== STATUS_NO_MORE_ENTRIES
)
1818 Status
= STATUS_SUCCESS
;
1822 TRACE("EnumIndex: %lu\n", EnumIndex
);
1823 TRACE("Group name: %S\n", GroupName
);
1824 TRACE("Name length: %lu\n", NameLength
);
1825 TRACE("RID: %lu\n", Rid
);
1827 EnumBuffer
->Buffer
[i
].RelativeId
= Rid
;
1829 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)NameLength
;
1830 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)(DataLength
+ sizeof(UNICODE_NULL
));
1832 /* FIXME: Disabled because of bugs in widl and rpcrt4 */
1834 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(EnumBuffer
->Buffer
[i
].Name
.MaximumLength
);
1835 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
1837 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1841 memcpy(EnumBuffer
->Buffer
[i
].Name
.Buffer
,
1843 EnumBuffer
->Buffer
[i
].Name
.Length
);
1848 if (NT_SUCCESS(Status
))
1850 *EnumerationContext
+= EnumCount
;
1851 *Buffer
= EnumBuffer
;
1852 *CountReturned
= EnumCount
;
1856 *EnumerationContext
= 0;
1860 if (EnumBuffer
!= NULL
)
1862 if (EnumBuffer
->Buffer
!= NULL
)
1864 if (EnumBuffer
->EntriesRead
!= 0)
1866 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
1868 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
1869 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
1873 midl_user_free(EnumBuffer
->Buffer
);
1876 midl_user_free(EnumBuffer
);
1880 if (NamesKeyHandle
!= NULL
)
1881 SampRegCloseKey(NamesKeyHandle
);
1883 if (GroupsKeyHandle
!= NULL
)
1884 SampRegCloseKey(GroupsKeyHandle
);
1886 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
== TRUE
))
1887 Status
= STATUS_MORE_ENTRIES
;
1896 SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle
,
1897 IN PRPC_UNICODE_STRING Name
,
1898 IN ACCESS_MASK DesiredAccess
,
1899 OUT SAMPR_HANDLE
*UserHandle
,
1900 OUT
unsigned long *RelativeId
)
1902 UNICODE_STRING EmptyString
= RTL_CONSTANT_STRING(L
"");
1903 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
1904 SAM_USER_FIXED_DATA FixedUserData
;
1905 PSAM_DB_OBJECT DomainObject
;
1906 PSAM_DB_OBJECT UserObject
;
1912 TRACE("SamrCreateUserInDomain(%p %p %lx %p %p)\n",
1913 DomainHandle
, Name
, DesiredAccess
, UserHandle
, RelativeId
);
1916 Name
->Length
== 0 ||
1917 Name
->Buffer
== NULL
||
1918 UserHandle
== NULL
||
1920 return STATUS_INVALID_PARAMETER
;
1922 /* Validate the domain handle */
1923 Status
= SampValidateDbObject(DomainHandle
,
1927 if (!NT_SUCCESS(Status
))
1929 TRACE("failed with status 0x%08lx\n", Status
);
1933 /* Check if the user name already exists in the domain */
1934 Status
= SampCheckAccountNameInDomain(DomainObject
,
1936 if (!NT_SUCCESS(Status
))
1938 TRACE("User name \'%S\' already exists in domain (Status 0x%08lx)\n",
1939 Name
->Buffer
, Status
);
1943 /* Get the fixed domain attributes */
1944 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1945 Status
= SampGetObjectAttribute(DomainObject
,
1948 (PVOID
)&FixedDomainData
,
1950 if (!NT_SUCCESS(Status
))
1952 TRACE("failed with status 0x%08lx\n", Status
);
1956 /* Increment the NextRid attribute */
1957 ulRid
= FixedDomainData
.NextRid
;
1958 FixedDomainData
.NextRid
++;
1960 /* Store the fixed domain attributes */
1961 Status
= SampSetObjectAttribute(DomainObject
,
1966 if (!NT_SUCCESS(Status
))
1968 TRACE("failed with status 0x%08lx\n", Status
);
1972 TRACE("RID: %lx\n", ulRid
);
1974 /* Convert the RID into a string (hex) */
1975 swprintf(szRid
, L
"%08lX", ulRid
);
1977 /* Create the user object */
1978 Status
= SampCreateDbObject(DomainObject
,
1984 if (!NT_SUCCESS(Status
))
1986 TRACE("failed with status 0x%08lx\n", Status
);
1990 /* Add the account name for the user object */
1991 Status
= SampSetAccountNameInDomain(DomainObject
,
1995 if (!NT_SUCCESS(Status
))
1997 TRACE("failed with status 0x%08lx\n", Status
);
2001 /* Initialize fixed user data */
2002 memset(&FixedUserData
, 0, sizeof(SAM_USER_FIXED_DATA
));
2003 FixedUserData
.Version
= 1;
2004 FixedUserData
.LastLogon
.QuadPart
= 0;
2005 FixedUserData
.LastLogoff
.QuadPart
= 0;
2006 FixedUserData
.PasswordLastSet
.QuadPart
= 0;
2007 FixedUserData
.AccountExpires
.LowPart
= MAXULONG
;
2008 FixedUserData
.AccountExpires
.HighPart
= MAXLONG
;
2009 FixedUserData
.LastBadPasswordTime
.QuadPart
= 0;
2010 FixedUserData
.UserId
= ulRid
;
2011 FixedUserData
.PrimaryGroupId
= DOMAIN_GROUP_RID_USERS
;
2012 FixedUserData
.UserAccountControl
= USER_ACCOUNT_DISABLED
|
2013 USER_PASSWORD_NOT_REQUIRED
|
2014 USER_NORMAL_ACCOUNT
;
2016 /* Set fixed user data attribute */
2017 Status
= SampSetObjectAttribute(UserObject
,
2020 (LPVOID
)&FixedUserData
,
2021 sizeof(SAM_USER_FIXED_DATA
));
2022 if (!NT_SUCCESS(Status
))
2024 TRACE("failed with status 0x%08lx\n", Status
);
2028 /* Set the Name attribute */
2029 Status
= SampSetObjectAttribute(UserObject
,
2032 (LPVOID
)Name
->Buffer
,
2033 Name
->MaximumLength
);
2034 if (!NT_SUCCESS(Status
))
2036 TRACE("failed with status 0x%08lx\n", Status
);
2040 /* Set the FullName attribute */
2041 Status
= SampSetObjectAttribute(UserObject
,
2045 EmptyString
.MaximumLength
);
2046 if (!NT_SUCCESS(Status
))
2048 TRACE("failed with status 0x%08lx\n", Status
);
2052 /* Set the HomeDirectory attribute */
2053 Status
= SampSetObjectAttribute(UserObject
,
2057 EmptyString
.MaximumLength
);
2058 if (!NT_SUCCESS(Status
))
2060 TRACE("failed with status 0x%08lx\n", Status
);
2064 /* Set the HomeDirectoryDrive attribute */
2065 Status
= SampSetObjectAttribute(UserObject
,
2066 L
"HomeDirectoryDrive",
2069 EmptyString
.MaximumLength
);
2070 if (!NT_SUCCESS(Status
))
2072 TRACE("failed with status 0x%08lx\n", Status
);
2076 /* Set the ScriptPath attribute */
2077 Status
= SampSetObjectAttribute(UserObject
,
2081 EmptyString
.MaximumLength
);
2082 if (!NT_SUCCESS(Status
))
2084 TRACE("failed with status 0x%08lx\n", Status
);
2088 /* Set the ProfilePath attribute */
2089 Status
= SampSetObjectAttribute(UserObject
,
2093 EmptyString
.MaximumLength
);
2094 if (!NT_SUCCESS(Status
))
2096 TRACE("failed with status 0x%08lx\n", Status
);
2100 /* Set the AdminComment attribute */
2101 Status
= SampSetObjectAttribute(UserObject
,
2105 EmptyString
.MaximumLength
);
2106 if (!NT_SUCCESS(Status
))
2108 TRACE("failed with status 0x%08lx\n", Status
);
2112 /* Set the UserComment attribute */
2113 Status
= SampSetObjectAttribute(UserObject
,
2117 EmptyString
.MaximumLength
);
2118 if (!NT_SUCCESS(Status
))
2120 TRACE("failed with status 0x%08lx\n", Status
);
2124 /* Set the WorkStations attribute */
2125 Status
= SampSetObjectAttribute(UserObject
,
2129 EmptyString
.MaximumLength
);
2130 if (!NT_SUCCESS(Status
))
2132 TRACE("failed with status 0x%08lx\n", Status
);
2136 /* FIXME: Set default user attributes */
2138 if (NT_SUCCESS(Status
))
2140 *UserHandle
= (SAMPR_HANDLE
)UserObject
;
2141 *RelativeId
= ulRid
;
2144 TRACE("returns with status 0x%08lx\n", Status
);
2153 SamrEnumerateUsersInDomain(IN SAMPR_HANDLE DomainHandle
,
2154 IN OUT
unsigned long *EnumerationContext
,
2155 IN
unsigned long UserAccountControl
,
2156 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
2157 IN
unsigned long PreferedMaximumLength
,
2158 OUT
unsigned long *CountReturned
)
2160 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
2161 PSAM_DB_OBJECT DomainObject
;
2162 HANDLE UsersKeyHandle
= NULL
;
2163 HANDLE NamesKeyHandle
= NULL
;
2166 ULONG EnumCount
= 0;
2167 ULONG RequiredLength
= 0;
2172 BOOLEAN MoreEntries
= FALSE
;
2175 TRACE("SamrEnumerateUsersInDomain(%p %p %lx %p %lu %p)\n",
2176 DomainHandle
, EnumerationContext
, UserAccountControl
, Buffer
,
2177 PreferedMaximumLength
, CountReturned
);
2179 /* Validate the domain handle */
2180 Status
= SampValidateDbObject(DomainHandle
,
2182 DOMAIN_LIST_ACCOUNTS
,
2184 if (!NT_SUCCESS(Status
))
2187 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
2191 if (!NT_SUCCESS(Status
))
2194 Status
= SampRegOpenKey(UsersKeyHandle
,
2198 if (!NT_SUCCESS(Status
))
2203 EnumIndex
= *EnumerationContext
;
2207 NameLength
= 64 * sizeof(WCHAR
);
2208 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2215 if (!NT_SUCCESS(Status
))
2217 if (Status
== STATUS_NO_MORE_ENTRIES
)
2218 Status
= STATUS_SUCCESS
;
2222 TRACE("EnumIndex: %lu\n", EnumIndex
);
2223 TRACE("User name: %S\n", UserName
);
2224 TRACE("Name length: %lu\n", NameLength
);
2226 if ((RequiredLength
+ NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
)) > PreferedMaximumLength
)
2232 RequiredLength
+= (NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
));
2238 TRACE("EnumCount: %lu\n", EnumCount
);
2239 TRACE("RequiredLength: %lu\n", RequiredLength
);
2241 if (!NT_SUCCESS(Status
))
2244 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
2245 if (EnumBuffer
== NULL
)
2247 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2251 EnumBuffer
->EntriesRead
= EnumCount
;
2255 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
2256 if (EnumBuffer
->Buffer
== NULL
)
2258 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2264 EnumIndex
= *EnumerationContext
;
2265 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
2267 NameLength
= 64 * sizeof(WCHAR
);
2268 DataLength
= sizeof(ULONG
);
2269 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2276 if (!NT_SUCCESS(Status
))
2278 if (Status
== STATUS_NO_MORE_ENTRIES
)
2279 Status
= STATUS_SUCCESS
;
2283 TRACE("EnumIndex: %lu\n", EnumIndex
);
2284 TRACE("User name: %S\n", UserName
);
2285 TRACE("Name length: %lu\n", NameLength
);
2286 TRACE("RID: %lu\n", Rid
);
2288 EnumBuffer
->Buffer
[i
].RelativeId
= Rid
;
2290 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)NameLength
;
2291 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)(DataLength
+ sizeof(UNICODE_NULL
));
2293 /* FIXME: Disabled because of bugs in widl and rpcrt4 */
2295 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(EnumBuffer
->Buffer
[i
].Name
.MaximumLength
);
2296 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
2298 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2302 memcpy(EnumBuffer
->Buffer
[i
].Name
.Buffer
,
2304 EnumBuffer
->Buffer
[i
].Name
.Length
);
2309 if (NT_SUCCESS(Status
))
2311 *EnumerationContext
+= EnumCount
;
2312 *Buffer
= EnumBuffer
;
2313 *CountReturned
= EnumCount
;
2317 *EnumerationContext
= 0;
2321 if (EnumBuffer
!= NULL
)
2323 if (EnumBuffer
->Buffer
!= NULL
)
2325 if (EnumBuffer
->EntriesRead
!= 0)
2327 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
2329 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
2330 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
2334 midl_user_free(EnumBuffer
->Buffer
);
2337 midl_user_free(EnumBuffer
);
2341 if (NamesKeyHandle
!= NULL
)
2342 SampRegCloseKey(NamesKeyHandle
);
2344 if (UsersKeyHandle
!= NULL
)
2345 SampRegCloseKey(UsersKeyHandle
);
2347 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
== TRUE
))
2348 Status
= STATUS_MORE_ENTRIES
;
2357 SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle
,
2358 IN PRPC_UNICODE_STRING AccountName
,
2359 IN ACCESS_MASK DesiredAccess
,
2360 OUT SAMPR_HANDLE
*AliasHandle
,
2361 OUT
unsigned long *RelativeId
)
2363 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
2364 PSAM_DB_OBJECT DomainObject
;
2365 PSAM_DB_OBJECT AliasObject
;
2366 UNICODE_STRING EmptyString
= RTL_CONSTANT_STRING(L
"");
2372 TRACE("SamrCreateAliasInDomain(%p %p %lx %p %p)\n",
2373 DomainHandle
, AccountName
, DesiredAccess
, AliasHandle
, RelativeId
);
2375 /* Validate the domain handle */
2376 Status
= SampValidateDbObject(DomainHandle
,
2378 DOMAIN_CREATE_ALIAS
,
2380 if (!NT_SUCCESS(Status
))
2382 TRACE("failed with status 0x%08lx\n", Status
);
2386 /* Check if the alias name already exists in the domain */
2387 Status
= SampCheckAccountNameInDomain(DomainObject
,
2388 AccountName
->Buffer
);
2389 if (!NT_SUCCESS(Status
))
2391 TRACE("Alias name \'%S\' already exists in domain (Status 0x%08lx)\n",
2392 AccountName
->Buffer
, Status
);
2396 /* Get the fixed domain attributes */
2397 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
2398 Status
= SampGetObjectAttribute(DomainObject
,
2401 (PVOID
)&FixedDomainData
,
2403 if (!NT_SUCCESS(Status
))
2405 TRACE("failed with status 0x%08lx\n", Status
);
2409 /* Increment the NextRid attribute */
2410 ulRid
= FixedDomainData
.NextRid
;
2411 FixedDomainData
.NextRid
++;
2413 /* Store the fixed domain attributes */
2414 Status
= SampSetObjectAttribute(DomainObject
,
2419 if (!NT_SUCCESS(Status
))
2421 TRACE("failed with status 0x%08lx\n", Status
);
2425 TRACE("RID: %lx\n", ulRid
);
2427 /* Convert the RID into a string (hex) */
2428 swprintf(szRid
, L
"%08lX", ulRid
);
2430 /* Create the alias object */
2431 Status
= SampCreateDbObject(DomainObject
,
2437 if (!NT_SUCCESS(Status
))
2439 TRACE("failed with status 0x%08lx\n", Status
);
2443 /* Add the account name for the alias object */
2444 Status
= SampSetAccountNameInDomain(DomainObject
,
2446 AccountName
->Buffer
,
2448 if (!NT_SUCCESS(Status
))
2450 TRACE("failed with status 0x%08lx\n", Status
);
2454 /* Set the Name attribute */
2455 Status
= SampSetObjectAttribute(AliasObject
,
2458 (LPVOID
)AccountName
->Buffer
,
2459 AccountName
->MaximumLength
);
2460 if (!NT_SUCCESS(Status
))
2462 TRACE("failed with status 0x%08lx\n", Status
);
2466 /* Set the Description attribute */
2467 Status
= SampSetObjectAttribute(AliasObject
,
2471 EmptyString
.MaximumLength
);
2472 if (!NT_SUCCESS(Status
))
2474 TRACE("failed with status 0x%08lx\n", Status
);
2478 if (NT_SUCCESS(Status
))
2480 *AliasHandle
= (SAMPR_HANDLE
)AliasObject
;
2481 *RelativeId
= ulRid
;
2484 TRACE("returns with status 0x%08lx\n", Status
);
2493 SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle
,
2494 IN OUT
unsigned long *EnumerationContext
,
2495 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
2496 IN
unsigned long PreferedMaximumLength
,
2497 OUT
unsigned long *CountReturned
)
2499 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
2500 PSAM_DB_OBJECT DomainObject
;
2501 HANDLE AliasesKeyHandle
= NULL
;
2502 HANDLE NamesKeyHandle
= NULL
;
2503 WCHAR AliasName
[64];
2505 ULONG EnumCount
= 0;
2506 ULONG RequiredLength
= 0;
2511 BOOLEAN MoreEntries
= FALSE
;
2514 TRACE("SamrEnumerateAliasesInDomain(%p %p %p %lu %p)\n",
2515 DomainHandle
, EnumerationContext
, Buffer
,
2516 PreferedMaximumLength
, CountReturned
);
2518 /* Validate the domain handle */
2519 Status
= SampValidateDbObject(DomainHandle
,
2521 DOMAIN_LIST_ACCOUNTS
,
2523 if (!NT_SUCCESS(Status
))
2526 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
2530 if (!NT_SUCCESS(Status
))
2533 Status
= SampRegOpenKey(AliasesKeyHandle
,
2537 if (!NT_SUCCESS(Status
))
2542 EnumIndex
= *EnumerationContext
;
2546 NameLength
= 64 * sizeof(WCHAR
);
2547 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2554 if (!NT_SUCCESS(Status
))
2556 if (Status
== STATUS_NO_MORE_ENTRIES
)
2557 Status
= STATUS_SUCCESS
;
2561 TRACE("EnumIndex: %lu\n", EnumIndex
);
2562 TRACE("Alias name: %S\n", AliasName
);
2563 TRACE("Name length: %lu\n", NameLength
);
2565 if ((RequiredLength
+ NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
)) > PreferedMaximumLength
)
2571 RequiredLength
+= (NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
));
2577 TRACE("EnumCount: %lu\n", EnumCount
);
2578 TRACE("RequiredLength: %lu\n", RequiredLength
);
2580 if (!NT_SUCCESS(Status
))
2583 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
2584 if (EnumBuffer
== NULL
)
2586 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2590 EnumBuffer
->EntriesRead
= EnumCount
;
2594 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
2595 if (EnumBuffer
->Buffer
== NULL
)
2597 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2603 EnumIndex
= *EnumerationContext
;
2604 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
2606 NameLength
= 64 * sizeof(WCHAR
);
2607 DataLength
= sizeof(ULONG
);
2608 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2615 if (!NT_SUCCESS(Status
))
2617 if (Status
== STATUS_NO_MORE_ENTRIES
)
2618 Status
= STATUS_SUCCESS
;
2622 TRACE("EnumIndex: %lu\n", EnumIndex
);
2623 TRACE("Alias name: %S\n", AliasName
);
2624 TRACE("Name length: %lu\n", NameLength
);
2625 TRACE("RID: %lu\n", Rid
);
2627 EnumBuffer
->Buffer
[i
].RelativeId
= Rid
;
2629 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)NameLength
;
2630 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)(DataLength
+ sizeof(UNICODE_NULL
));
2632 /* FIXME: Disabled because of bugs in widl and rpcrt4 */
2634 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(EnumBuffer
->Buffer
[i
].Name
.MaximumLength
);
2635 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
2637 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2641 memcpy(EnumBuffer
->Buffer
[i
].Name
.Buffer
,
2643 EnumBuffer
->Buffer
[i
].Name
.Length
);
2648 if (NT_SUCCESS(Status
))
2650 *EnumerationContext
+= EnumCount
;
2651 *Buffer
= EnumBuffer
;
2652 *CountReturned
= EnumCount
;
2656 *EnumerationContext
= 0;
2660 if (EnumBuffer
!= NULL
)
2662 if (EnumBuffer
->Buffer
!= NULL
)
2664 if (EnumBuffer
->EntriesRead
!= 0)
2666 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
2668 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
2669 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
2673 midl_user_free(EnumBuffer
->Buffer
);
2676 midl_user_free(EnumBuffer
);
2680 if (NamesKeyHandle
!= NULL
)
2681 SampRegCloseKey(NamesKeyHandle
);
2683 if (AliasesKeyHandle
!= NULL
)
2684 SampRegCloseKey(AliasesKeyHandle
);
2686 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
== TRUE
))
2687 Status
= STATUS_MORE_ENTRIES
;
2696 SamrGetAliasMembership(IN SAMPR_HANDLE DomainHandle
,
2697 IN PSAMPR_PSID_ARRAY SidArray
,
2698 OUT PSAMPR_ULONG_ARRAY Membership
)
2700 PSAM_DB_OBJECT DomainObject
;
2701 HANDLE AliasesKeyHandle
= NULL
;
2702 HANDLE MembersKeyHandle
= NULL
;
2703 HANDLE MemberKeyHandle
= NULL
;
2704 LPWSTR MemberSidString
= NULL
;
2705 PULONG RidArray
= NULL
;
2706 ULONG MaxSidCount
= 0;
2712 TRACE("SamrGetAliasMembership(%p %p %p)\n",
2713 DomainHandle
, SidArray
, Membership
);
2715 /* Validate the domain handle */
2716 Status
= SampValidateDbObject(DomainHandle
,
2720 if (!NT_SUCCESS(Status
))
2723 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
2727 TRACE("SampRegOpenKey returned %08lX\n", Status
);
2728 if (!NT_SUCCESS(Status
))
2731 Status
= SampRegOpenKey(AliasesKeyHandle
,
2735 TRACE("SampRegOpenKey returned %08lX\n", Status
);
2736 if (!NT_SUCCESS(Status
))
2739 for (i
= 0; i
< SidArray
->Count
; i
++)
2741 ConvertSidToStringSid(SidArray
->Sids
[i
].SidPointer
, &MemberSidString
);
2742 TRACE("Open %S\n", MemberSidString
);
2744 Status
= SampRegOpenKey(MembersKeyHandle
,
2748 TRACE("SampRegOpenKey returned %08lX\n", Status
);
2749 if (NT_SUCCESS(Status
))
2751 Status
= SampRegQueryKeyInfo(MemberKeyHandle
,
2754 if (NT_SUCCESS(Status
))
2756 TRACE("Found %lu values\n", ValueCount
);
2757 MaxSidCount
+= ValueCount
;
2761 NtClose(MemberKeyHandle
);
2764 LocalFree(MemberSidString
);
2767 TRACE("Maximum sid count: %lu\n", MaxSidCount
);
2768 RidArray
= midl_user_allocate(MaxSidCount
* sizeof(ULONG
));
2769 if (RidArray
== NULL
)
2771 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2775 for (i
= 0; i
< SidArray
->Count
; i
++)
2777 ConvertSidToStringSid(SidArray
->Sids
[i
].SidPointer
, &MemberSidString
);
2778 TRACE("Open %S\n", MemberSidString
);
2780 Status
= SampRegOpenKey(MembersKeyHandle
,
2784 TRACE("SampRegOpenKey returned %08lX\n", Status
);
2785 if (NT_SUCCESS(Status
))
2787 Status
= SampRegQueryKeyInfo(MemberKeyHandle
,
2790 if (NT_SUCCESS(Status
))
2792 TRACE("Found %lu values\n", ValueCount
);
2794 for (j
= 0; j
< ValueCount
; j
++)
2796 DataLength
= sizeof(ULONG
);
2797 Status
= SampRegEnumerateValue(MemberKeyHandle
,
2802 (PVOID
)&RidArray
[j
],
2807 NtClose(MemberKeyHandle
);
2810 LocalFree(MemberSidString
);
2815 if (NT_SUCCESS(Status
))
2817 Membership
->Count
= MaxSidCount
;
2818 Membership
->Element
= RidArray
;
2822 if (RidArray
!= NULL
)
2823 midl_user_free(RidArray
);
2826 if (MembersKeyHandle
!= NULL
)
2827 NtClose(MembersKeyHandle
);
2829 if (MembersKeyHandle
!= NULL
)
2830 NtClose(MembersKeyHandle
);
2832 if (AliasesKeyHandle
!= NULL
)
2833 NtClose(AliasesKeyHandle
);
2842 SamrLookupNamesInDomain(IN SAMPR_HANDLE DomainHandle
,
2844 IN RPC_UNICODE_STRING Names
[],
2845 OUT PSAMPR_ULONG_ARRAY RelativeIds
,
2846 OUT PSAMPR_ULONG_ARRAY Use
)
2848 PSAM_DB_OBJECT DomainObject
;
2849 HANDLE AccountsKeyHandle
;
2850 HANDLE NamesKeyHandle
;
2851 ULONG MappedCount
= 0;
2857 TRACE("SamrLookupNamesInDomain(%p %lu %p %p %p)\n",
2858 DomainHandle
, Count
, Names
, RelativeIds
, Use
);
2860 /* Validate the domain handle */
2861 Status
= SampValidateDbObject(DomainHandle
,
2865 if (!NT_SUCCESS(Status
))
2867 TRACE("failed with status 0x%08lx\n", Status
);
2871 RelativeIds
->Count
= 0;
2875 return STATUS_SUCCESS
;
2877 /* Allocate the relative IDs array */
2878 RelativeIds
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
2879 if (RelativeIds
->Element
== NULL
)
2881 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2885 /* Allocate the use array */
2886 Use
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
2887 if (Use
->Element
== NULL
)
2889 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2893 RelativeIds
->Count
= Count
;
2896 for (i
= 0; i
< Count
; i
++)
2898 TRACE("Name: %S\n", Names
[i
].Buffer
);
2902 /* Lookup aliases */
2903 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
2906 &AccountsKeyHandle
);
2907 if (NT_SUCCESS(Status
))
2909 Status
= SampRegOpenKey(AccountsKeyHandle
,
2913 if (NT_SUCCESS(Status
))
2915 DataLength
= sizeof(ULONG
);
2916 Status
= SampRegQueryValue(NamesKeyHandle
,
2922 SampRegCloseKey(NamesKeyHandle
);
2925 SampRegCloseKey(AccountsKeyHandle
);
2928 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
2931 /* Return alias account */
2932 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
2934 TRACE("Rid: %lu\n", RelativeId
);
2935 RelativeIds
->Element
[i
] = RelativeId
;
2936 Use
->Element
[i
] = SidTypeAlias
;
2942 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
2945 &AccountsKeyHandle
);
2946 if (NT_SUCCESS(Status
))
2948 Status
= SampRegOpenKey(AccountsKeyHandle
,
2952 if (NT_SUCCESS(Status
))
2954 DataLength
= sizeof(ULONG
);
2955 Status
= SampRegQueryValue(NamesKeyHandle
,
2961 SampRegCloseKey(NamesKeyHandle
);
2964 SampRegCloseKey(AccountsKeyHandle
);
2967 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
2970 /* Return group account */
2971 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
2973 TRACE("Rid: %lu\n", RelativeId
);
2974 RelativeIds
->Element
[i
] = RelativeId
;
2975 Use
->Element
[i
] = SidTypeGroup
;
2981 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
2984 &AccountsKeyHandle
);
2985 if (NT_SUCCESS(Status
))
2987 Status
= SampRegOpenKey(AccountsKeyHandle
,
2991 if (NT_SUCCESS(Status
))
2993 DataLength
= sizeof(ULONG
);
2994 Status
= SampRegQueryValue(NamesKeyHandle
,
3000 SampRegCloseKey(NamesKeyHandle
);
3003 SampRegCloseKey(AccountsKeyHandle
);
3006 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3009 /* Return user account */
3010 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
3012 TRACE("Rid: %lu\n", RelativeId
);
3013 RelativeIds
->Element
[i
] = RelativeId
;
3014 Use
->Element
[i
] = SidTypeUser
;
3019 /* Return unknown account */
3020 RelativeIds
->Element
[i
] = 0;
3021 Use
->Element
[i
] = SidTypeUnknown
;
3025 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3026 Status
= STATUS_SUCCESS
;
3028 if (NT_SUCCESS(Status
))
3030 if (MappedCount
== 0)
3031 Status
= STATUS_NONE_MAPPED
;
3032 else if (MappedCount
< Count
)
3033 Status
= STATUS_SOME_NOT_MAPPED
;
3037 if (RelativeIds
->Element
!= NULL
)
3039 midl_user_free(RelativeIds
->Element
);
3040 RelativeIds
->Element
= NULL
;
3043 RelativeIds
->Count
= 0;
3045 if (Use
->Element
!= NULL
)
3047 midl_user_free(Use
->Element
);
3048 Use
->Element
= NULL
;
3061 SamrLookupIdsInDomain(IN SAMPR_HANDLE DomainHandle
,
3063 IN ULONG
*RelativeIds
,
3064 OUT PSAMPR_RETURNED_USTRING_ARRAY Names
,
3065 OUT PSAMPR_ULONG_ARRAY Use
)
3067 PSAM_DB_OBJECT DomainObject
;
3069 HANDLE AccountsKeyHandle
;
3070 HANDLE AccountKeyHandle
;
3071 ULONG MappedCount
= 0;
3076 TRACE("SamrLookupIdsInDomain(%p %lu %p %p %p)\n",
3077 DomainHandle
, Count
, RelativeIds
, Names
, Use
);
3079 /* Validate the domain handle */
3080 Status
= SampValidateDbObject(DomainHandle
,
3084 if (!NT_SUCCESS(Status
))
3086 TRACE("failed with status 0x%08lx\n", Status
);
3094 return STATUS_SUCCESS
;
3096 /* Allocate the names array */
3097 Names
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
3098 if (Names
->Element
== NULL
)
3100 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3104 /* Allocate the use array */
3105 Use
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
3106 if (Use
->Element
== NULL
)
3108 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3112 Names
->Count
= Count
;
3115 for (i
= 0; i
< Count
; i
++)
3117 TRACE("RID: %lu\n", RelativeIds
[i
]);
3119 swprintf(RidString
, L
"%08lx", RelativeIds
[i
]);
3121 /* Lookup aliases */
3122 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3125 &AccountsKeyHandle
);
3126 if (NT_SUCCESS(Status
))
3128 Status
= SampRegOpenKey(AccountsKeyHandle
,
3132 if (NT_SUCCESS(Status
))
3135 Status
= SampRegQueryValue(AccountKeyHandle
,
3140 if (NT_SUCCESS(Status
))
3142 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
3143 if (Names
->Element
[i
].Buffer
== NULL
)
3144 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3146 if (NT_SUCCESS(Status
))
3148 Names
->Element
[i
].MaximumLength
= DataLength
;
3149 Names
->Element
[i
].Length
= DataLength
- sizeof(WCHAR
);
3151 Status
= SampRegQueryValue(AccountKeyHandle
,
3154 Names
->Element
[i
].Buffer
,
3159 SampRegCloseKey(AccountKeyHandle
);
3162 SampRegCloseKey(AccountsKeyHandle
);
3165 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3168 /* Return alias account */
3169 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
3171 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
3172 Use
->Element
[i
] = SidTypeAlias
;
3178 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3181 &AccountsKeyHandle
);
3182 if (NT_SUCCESS(Status
))
3184 Status
= SampRegOpenKey(AccountsKeyHandle
,
3188 if (NT_SUCCESS(Status
))
3191 Status
= SampRegQueryValue(AccountKeyHandle
,
3196 if (NT_SUCCESS(Status
))
3198 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
3199 if (Names
->Element
[i
].Buffer
== NULL
)
3200 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3202 if (NT_SUCCESS(Status
))
3204 Names
->Element
[i
].MaximumLength
= DataLength
;
3205 Names
->Element
[i
].Length
= DataLength
- sizeof(WCHAR
);
3207 Status
= SampRegQueryValue(AccountKeyHandle
,
3210 Names
->Element
[i
].Buffer
,
3215 SampRegCloseKey(AccountKeyHandle
);
3218 SampRegCloseKey(AccountsKeyHandle
);
3221 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3224 /* Return group account */
3225 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
3227 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
3228 Use
->Element
[i
] = SidTypeGroup
;
3234 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3237 &AccountsKeyHandle
);
3238 if (NT_SUCCESS(Status
))
3240 Status
= SampRegOpenKey(AccountsKeyHandle
,
3244 if (NT_SUCCESS(Status
))
3247 Status
= SampRegQueryValue(AccountKeyHandle
,
3252 if (NT_SUCCESS(Status
))
3254 TRACE("DataLength: %lu\n", DataLength
);
3256 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
3257 if (Names
->Element
[i
].Buffer
== NULL
)
3258 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3260 if (NT_SUCCESS(Status
))
3262 Names
->Element
[i
].MaximumLength
= DataLength
;
3263 Names
->Element
[i
].Length
= DataLength
- sizeof(WCHAR
);
3265 Status
= SampRegQueryValue(AccountKeyHandle
,
3268 Names
->Element
[i
].Buffer
,
3273 SampRegCloseKey(AccountKeyHandle
);
3276 SampRegCloseKey(AccountsKeyHandle
);
3279 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3282 /* Return user account */
3283 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
3285 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
3286 Use
->Element
[i
] = SidTypeUser
;
3291 /* Return unknown account */
3292 Use
->Element
[i
] = SidTypeUnknown
;
3296 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3297 Status
= STATUS_SUCCESS
;
3299 if (NT_SUCCESS(Status
))