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 /* Map generic access rights */
149 RtlMapGenericMask(&DesiredAccess
,
152 /* Open the Server Object */
153 Status
= SampOpenDbObject(NULL
,
160 if (NT_SUCCESS(Status
))
161 *ServerHandle
= (SAMPR_HANDLE
)ServerObject
;
163 TRACE("SamrConnect done (Status 0x%08lx)\n", Status
);
172 SamrCloseHandle(IN OUT SAMPR_HANDLE
*SamHandle
)
174 PSAM_DB_OBJECT DbObject
;
175 NTSTATUS Status
= STATUS_SUCCESS
;
177 TRACE("SamrCloseHandle(%p)\n", SamHandle
);
179 Status
= SampValidateDbObject(*SamHandle
,
183 if (Status
== STATUS_SUCCESS
)
185 Status
= SampCloseDbObject(DbObject
);
189 TRACE("SamrCloseHandle done (Status 0x%08lx)\n", Status
);
198 SamrSetSecurityObject(IN SAMPR_HANDLE ObjectHandle
,
199 IN SECURITY_INFORMATION SecurityInformation
,
200 IN PSAMPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor
)
203 return STATUS_NOT_IMPLEMENTED
;
210 SamrQuerySecurityObject(IN SAMPR_HANDLE ObjectHandle
,
211 IN SECURITY_INFORMATION SecurityInformation
,
212 OUT PSAMPR_SR_SECURITY_DESCRIPTOR
*SecurityDescriptor
)
215 return STATUS_NOT_IMPLEMENTED
;
222 SamrShutdownSamServer(IN SAMPR_HANDLE ServerHandle
)
224 PSAM_DB_OBJECT ServerObject
;
227 TRACE("(%p)\n", ServerHandle
);
229 /* Validate the server handle */
230 Status
= SampValidateDbObject(ServerHandle
,
234 if (!NT_SUCCESS(Status
))
237 /* Shut the server down */
238 RpcMgmtStopServerListening(0);
240 return STATUS_SUCCESS
;
247 SamrLookupDomainInSamServer(IN SAMPR_HANDLE ServerHandle
,
248 IN PRPC_UNICODE_STRING Name
,
249 OUT PRPC_SID
*DomainId
)
251 PSAM_DB_OBJECT ServerObject
;
252 HANDLE DomainsKeyHandle
= NULL
;
253 HANDLE DomainKeyHandle
= NULL
;
254 WCHAR DomainKeyName
[64];
256 WCHAR DomainNameString
[MAX_COMPUTERNAME_LENGTH
+ 1];
257 UNICODE_STRING DomainName
;
262 TRACE("SamrLookupDomainInSamServer(%p %p %p)\n",
263 ServerHandle
, Name
, DomainId
);
265 /* Validate the server handle */
266 Status
= SampValidateDbObject(ServerHandle
,
268 SAM_SERVER_LOOKUP_DOMAIN
,
270 if (!NT_SUCCESS(Status
))
275 Status
= SampRegOpenKey(ServerObject
->KeyHandle
,
279 if (!NT_SUCCESS(Status
))
283 while (Found
== FALSE
)
285 Status
= SampRegEnumerateSubKey(DomainsKeyHandle
,
289 if (!NT_SUCCESS(Status
))
291 if (Status
== STATUS_NO_MORE_ENTRIES
)
292 Status
= STATUS_NO_SUCH_DOMAIN
;
296 TRACE("Domain key name: %S\n", DomainKeyName
);
298 Status
= SampRegOpenKey(DomainsKeyHandle
,
302 if (NT_SUCCESS(Status
))
304 Length
= (MAX_COMPUTERNAME_LENGTH
+ 1) * sizeof(WCHAR
);
305 Status
= SampRegQueryValue(DomainKeyHandle
,
308 (PVOID
)&DomainNameString
,
310 if (NT_SUCCESS(Status
))
312 TRACE("Domain name: %S\n", DomainNameString
);
314 RtlInitUnicodeString(&DomainName
,
316 if (RtlEqualUnicodeString(&DomainName
, (PUNICODE_STRING
)Name
, TRUE
))
318 TRACE("Found it!\n");
321 Status
= SampRegQueryValue(DomainKeyHandle
,
326 if (NT_SUCCESS(Status
))
328 *DomainId
= midl_user_allocate(Length
);
330 SampRegQueryValue(DomainKeyHandle
,
336 Status
= STATUS_SUCCESS
;
342 NtClose(DomainKeyHandle
);
348 NtClose(DomainsKeyHandle
);
357 SamrEnumerateDomainsInSamServer(IN SAMPR_HANDLE ServerHandle
,
358 IN OUT
unsigned long *EnumerationContext
,
359 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
360 IN ULONG PreferedMaximumLength
,
361 OUT PULONG CountReturned
)
363 PSAM_DB_OBJECT ServerObject
;
364 WCHAR DomainKeyName
[64];
365 HANDLE DomainsKeyHandle
;
366 HANDLE DomainKeyHandle
;
369 ULONG RequiredLength
;
372 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
375 TRACE("SamrEnumerateDomainsInSamServer(%p %p %p %lu %p)\n",
376 ServerHandle
, EnumerationContext
, Buffer
, PreferedMaximumLength
,
379 /* Validate the server handle */
380 Status
= SampValidateDbObject(ServerHandle
,
382 SAM_SERVER_ENUMERATE_DOMAINS
,
384 if (!NT_SUCCESS(Status
))
387 Status
= SampRegOpenKey(ServerObject
->KeyHandle
,
391 if (!NT_SUCCESS(Status
))
394 EnumIndex
= *EnumerationContext
;
400 Status
= SampRegEnumerateSubKey(DomainsKeyHandle
,
404 if (!NT_SUCCESS(Status
))
407 TRACE("EnumIndex: %lu\n", EnumIndex
);
408 TRACE("Domain key name: %S\n", DomainKeyName
);
410 Status
= SampRegOpenKey(DomainsKeyHandle
,
414 TRACE("SampRegOpenKey returned %08lX\n", Status
);
415 if (NT_SUCCESS(Status
))
418 Status
= SampRegQueryValue(DomainKeyHandle
,
423 TRACE("SampRegQueryValue returned %08lX\n", Status
);
424 if (NT_SUCCESS(Status
))
426 TRACE("Data length: %lu\n", DataLength
);
428 if ((RequiredLength
+ DataLength
+ sizeof(UNICODE_STRING
)) > PreferedMaximumLength
)
431 RequiredLength
+= (DataLength
+ sizeof(UNICODE_STRING
));
435 NtClose(DomainKeyHandle
);
441 TRACE("EnumCount: %lu\n", EnumCount
);
442 TRACE("RequiredLength: %lu\n", RequiredLength
);
444 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
445 if (EnumBuffer
== NULL
)
447 Status
= STATUS_INSUFFICIENT_RESOURCES
;
451 EnumBuffer
->EntriesRead
= EnumCount
;
452 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
453 if (EnumBuffer
->Buffer
== NULL
)
455 Status
= STATUS_INSUFFICIENT_RESOURCES
;
459 EnumIndex
= *EnumerationContext
;
460 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
462 Status
= SampRegEnumerateSubKey(DomainsKeyHandle
,
466 if (!NT_SUCCESS(Status
))
469 TRACE("EnumIndex: %lu\n", EnumIndex
);
470 TRACE("Domain key name: %S\n", DomainKeyName
);
472 Status
= SampRegOpenKey(DomainsKeyHandle
,
476 TRACE("SampRegOpenKey returned %08lX\n", Status
);
477 if (NT_SUCCESS(Status
))
480 Status
= SampRegQueryValue(DomainKeyHandle
,
485 TRACE("SampRegQueryValue returned %08lX\n", Status
);
486 if (NT_SUCCESS(Status
))
488 EnumBuffer
->Buffer
[i
].RelativeId
= 0;
489 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)DataLength
- sizeof(WCHAR
);
490 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)DataLength
;
491 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(DataLength
);
492 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
494 NtClose(DomainKeyHandle
);
495 Status
= STATUS_INSUFFICIENT_RESOURCES
;
499 Status
= SampRegQueryValue(DomainKeyHandle
,
502 EnumBuffer
->Buffer
[i
].Name
.Buffer
,
504 TRACE("SampRegQueryValue returned %08lX\n", Status
);
505 if (NT_SUCCESS(Status
))
507 TRACE("Domain name: %S\n", EnumBuffer
->Buffer
[i
].Name
.Buffer
);
511 NtClose(DomainKeyHandle
);
513 if (!NT_SUCCESS(Status
))
518 if (NT_SUCCESS(Status
))
520 *EnumerationContext
+= EnumCount
;
521 *Buffer
= EnumBuffer
;
522 *CountReturned
= EnumCount
;
526 if (!NT_SUCCESS(Status
))
528 *EnumerationContext
= 0;
532 if (EnumBuffer
!= NULL
)
534 if (EnumBuffer
->Buffer
!= NULL
)
536 if (EnumBuffer
->EntriesRead
!= 0)
538 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
540 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
541 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
545 midl_user_free(EnumBuffer
->Buffer
);
548 midl_user_free(EnumBuffer
);
552 NtClose(DomainsKeyHandle
);
561 SamrOpenDomain(IN SAMPR_HANDLE ServerHandle
,
562 IN ACCESS_MASK DesiredAccess
,
563 IN PRPC_SID DomainId
,
564 OUT SAMPR_HANDLE
*DomainHandle
)
566 PSAM_DB_OBJECT ServerObject
;
567 PSAM_DB_OBJECT DomainObject
;
570 TRACE("SamrOpenDomain(%p %lx %p %p)\n",
571 ServerHandle
, DesiredAccess
, DomainId
, DomainHandle
);
573 /* Map generic access rights */
574 RtlMapGenericMask(&DesiredAccess
,
577 /* Validate the server handle */
578 Status
= SampValidateDbObject(ServerHandle
,
580 SAM_SERVER_LOOKUP_DOMAIN
,
582 if (!NT_SUCCESS(Status
))
585 /* Validate the Domain SID */
586 if ((DomainId
->Revision
!= SID_REVISION
) ||
587 (DomainId
->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
) ||
588 (memcmp(&DomainId
->IdentifierAuthority
, &NtSidAuthority
, sizeof(SID_IDENTIFIER_AUTHORITY
)) != 0))
589 return STATUS_INVALID_PARAMETER
;
591 /* Open the domain object */
592 if ((DomainId
->SubAuthorityCount
== 1) &&
593 (DomainId
->SubAuthority
[0] == SECURITY_BUILTIN_DOMAIN_RID
))
595 /* Builtin domain object */
596 TRACE("Opening the builtin domain object.\n");
598 Status
= SampOpenDbObject(ServerObject
,
606 else if ((DomainId
->SubAuthorityCount
== 4) &&
607 (DomainId
->SubAuthority
[0] == SECURITY_NT_NON_UNIQUE
))
609 /* Account domain object */
610 TRACE("Opening the account domain object.\n");
612 /* FIXME: Check the account domain sub authorities!!! */
614 Status
= SampOpenDbObject(ServerObject
,
624 /* No vaild domain SID */
625 Status
= STATUS_INVALID_PARAMETER
;
628 if (NT_SUCCESS(Status
))
629 *DomainHandle
= (SAMPR_HANDLE
)DomainObject
;
631 TRACE("SamrOpenDomain done (Status 0x%08lx)\n", Status
);
638 SampQueryDomainPassword(PSAM_DB_OBJECT DomainObject
,
639 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
641 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
642 SAM_DOMAIN_FIXED_DATA FixedData
;
648 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
649 if (InfoBuffer
== NULL
)
650 return STATUS_INSUFFICIENT_RESOURCES
;
652 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
653 Status
= SampGetObjectAttribute(DomainObject
,
658 if (!NT_SUCCESS(Status
))
661 InfoBuffer
->Password
.MinPasswordLength
= FixedData
.MinPasswordLength
;
662 InfoBuffer
->Password
.PasswordHistoryLength
= FixedData
.PasswordHistoryLength
;
663 InfoBuffer
->Password
.PasswordProperties
= FixedData
.PasswordProperties
;
664 InfoBuffer
->Password
.MaxPasswordAge
.LowPart
= FixedData
.MaxPasswordAge
.LowPart
;
665 InfoBuffer
->Password
.MaxPasswordAge
.HighPart
= FixedData
.MaxPasswordAge
.HighPart
;
666 InfoBuffer
->Password
.MinPasswordAge
.LowPart
= FixedData
.MinPasswordAge
.LowPart
;
667 InfoBuffer
->Password
.MinPasswordAge
.HighPart
= FixedData
.MinPasswordAge
.HighPart
;
669 *Buffer
= InfoBuffer
;
672 if (!NT_SUCCESS(Status
))
674 if (InfoBuffer
!= NULL
)
676 midl_user_free(InfoBuffer
);
685 SampGetNumberOfAccounts(PSAM_DB_OBJECT DomainObject
,
689 HANDLE AccountKeyHandle
= NULL
;
690 HANDLE NamesKeyHandle
= NULL
;
695 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
699 if (!NT_SUCCESS(Status
))
702 Status
= SampRegOpenKey(AccountKeyHandle
,
706 if (!NT_SUCCESS(Status
))
709 Status
= SampRegQueryKeyInfo(NamesKeyHandle
,
713 if (NamesKeyHandle
!= NULL
)
714 SampRegCloseKey(NamesKeyHandle
);
716 if (AccountKeyHandle
!= NULL
)
717 SampRegCloseKey(AccountKeyHandle
);
724 SampQueryDomainGeneral(PSAM_DB_OBJECT DomainObject
,
725 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
727 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
728 SAM_DOMAIN_FIXED_DATA FixedData
;
734 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
735 if (InfoBuffer
== NULL
)
736 return STATUS_INSUFFICIENT_RESOURCES
;
738 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
739 Status
= SampGetObjectAttribute(DomainObject
,
744 if (!NT_SUCCESS(Status
))
747 InfoBuffer
->General
.ForceLogoff
.LowPart
= FixedData
.ForceLogoff
.LowPart
;
748 InfoBuffer
->General
.ForceLogoff
.HighPart
= FixedData
.ForceLogoff
.HighPart
;
749 InfoBuffer
->General
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
750 InfoBuffer
->General
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
751 InfoBuffer
->General
.DomainServerState
= FixedData
.DomainServerState
;
752 InfoBuffer
->General
.DomainServerRole
= FixedData
.DomainServerRole
;
753 InfoBuffer
->General
.UasCompatibilityRequired
= FixedData
.UasCompatibilityRequired
;
755 /* Get the OemInformation string */
756 Status
= SampGetObjectAttributeString(DomainObject
,
758 &InfoBuffer
->General
.OemInformation
);
759 if (!NT_SUCCESS(Status
))
761 TRACE("Status 0x%08lx\n", Status
);
765 /* Get the Name string */
766 Status
= SampGetObjectAttributeString(DomainObject
,
768 &InfoBuffer
->General
.DomainName
);
769 if (!NT_SUCCESS(Status
))
771 TRACE("Status 0x%08lx\n", Status
);
775 /* Get the ReplicaSourceNodeName string */
776 Status
= SampGetObjectAttributeString(DomainObject
,
777 L
"ReplicaSourceNodeName",
778 &InfoBuffer
->General
.ReplicaSourceNodeName
);
779 if (!NT_SUCCESS(Status
))
781 TRACE("Status 0x%08lx\n", Status
);
785 /* Get the number of Users in the Domain */
786 Status
= SampGetNumberOfAccounts(DomainObject
,
788 &InfoBuffer
->General
.UserCount
);
789 if (!NT_SUCCESS(Status
))
791 TRACE("Status 0x%08lx\n", Status
);
795 /* Get the number of Groups in the Domain */
796 Status
= SampGetNumberOfAccounts(DomainObject
,
798 &InfoBuffer
->General
.GroupCount
);
799 if (!NT_SUCCESS(Status
))
801 TRACE("Status 0x%08lx\n", Status
);
805 /* Get the number of Aliases in the Domain */
806 Status
= SampGetNumberOfAccounts(DomainObject
,
808 &InfoBuffer
->General
.AliasCount
);
809 if (!NT_SUCCESS(Status
))
811 TRACE("Status 0x%08lx\n", Status
);
815 *Buffer
= InfoBuffer
;
818 if (!NT_SUCCESS(Status
))
820 if (InfoBuffer
!= NULL
)
822 if (InfoBuffer
->General
.OemInformation
.Buffer
!= NULL
)
823 midl_user_free(InfoBuffer
->General
.OemInformation
.Buffer
);
825 if (InfoBuffer
->General
.DomainName
.Buffer
!= NULL
)
826 midl_user_free(InfoBuffer
->General
.DomainName
.Buffer
);
828 if (InfoBuffer
->General
.ReplicaSourceNodeName
.Buffer
!= NULL
)
829 midl_user_free(InfoBuffer
->General
.ReplicaSourceNodeName
.Buffer
);
831 midl_user_free(InfoBuffer
);
840 SampQueryDomainLogoff(PSAM_DB_OBJECT DomainObject
,
841 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
843 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
844 SAM_DOMAIN_FIXED_DATA FixedData
;
850 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
851 if (InfoBuffer
== NULL
)
852 return STATUS_INSUFFICIENT_RESOURCES
;
854 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
855 Status
= SampGetObjectAttribute(DomainObject
,
860 if (!NT_SUCCESS(Status
))
863 InfoBuffer
->Logoff
.ForceLogoff
.LowPart
= FixedData
.ForceLogoff
.LowPart
;
864 InfoBuffer
->Logoff
.ForceLogoff
.HighPart
= FixedData
.ForceLogoff
.HighPart
;
866 *Buffer
= InfoBuffer
;
869 if (!NT_SUCCESS(Status
))
871 if (InfoBuffer
!= NULL
)
873 midl_user_free(InfoBuffer
);
882 SampQueryDomainOem(PSAM_DB_OBJECT DomainObject
,
883 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
885 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
890 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
891 if (InfoBuffer
== NULL
)
892 return STATUS_INSUFFICIENT_RESOURCES
;
894 /* Get the OemInformation string */
895 Status
= SampGetObjectAttributeString(DomainObject
,
897 &InfoBuffer
->Oem
.OemInformation
);
898 if (!NT_SUCCESS(Status
))
900 TRACE("Status 0x%08lx\n", Status
);
904 *Buffer
= InfoBuffer
;
907 if (!NT_SUCCESS(Status
))
909 if (InfoBuffer
!= NULL
)
911 if (InfoBuffer
->Oem
.OemInformation
.Buffer
!= NULL
)
912 midl_user_free(InfoBuffer
->Oem
.OemInformation
.Buffer
);
914 midl_user_free(InfoBuffer
);
923 SampQueryDomainName(PSAM_DB_OBJECT DomainObject
,
924 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
926 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
931 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
932 if (InfoBuffer
== NULL
)
933 return STATUS_INSUFFICIENT_RESOURCES
;
935 /* Get the Name string */
936 Status
= SampGetObjectAttributeString(DomainObject
,
938 &InfoBuffer
->Name
.DomainName
);
939 if (!NT_SUCCESS(Status
))
941 TRACE("Status 0x%08lx\n", Status
);
945 *Buffer
= InfoBuffer
;
948 if (!NT_SUCCESS(Status
))
950 if (InfoBuffer
!= NULL
)
952 if (InfoBuffer
->Name
.DomainName
.Buffer
!= NULL
)
953 midl_user_free(InfoBuffer
->Name
.DomainName
.Buffer
);
955 midl_user_free(InfoBuffer
);
964 SampQueryDomainReplication(PSAM_DB_OBJECT DomainObject
,
965 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
967 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
972 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
973 if (InfoBuffer
== NULL
)
974 return STATUS_INSUFFICIENT_RESOURCES
;
976 /* Get the ReplicaSourceNodeName string */
977 Status
= SampGetObjectAttributeString(DomainObject
,
978 L
"ReplicaSourceNodeName",
979 &InfoBuffer
->Replication
.ReplicaSourceNodeName
);
980 if (!NT_SUCCESS(Status
))
982 TRACE("Status 0x%08lx\n", Status
);
986 *Buffer
= InfoBuffer
;
989 if (!NT_SUCCESS(Status
))
991 if (InfoBuffer
!= NULL
)
993 if (InfoBuffer
->Replication
.ReplicaSourceNodeName
.Buffer
!= NULL
)
994 midl_user_free(InfoBuffer
->Replication
.ReplicaSourceNodeName
.Buffer
);
996 midl_user_free(InfoBuffer
);
1005 SampQueryDomainServerRole(PSAM_DB_OBJECT DomainObject
,
1006 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1008 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1009 SAM_DOMAIN_FIXED_DATA FixedData
;
1015 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1016 if (InfoBuffer
== NULL
)
1017 return STATUS_INSUFFICIENT_RESOURCES
;
1019 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1020 Status
= SampGetObjectAttribute(DomainObject
,
1025 if (!NT_SUCCESS(Status
))
1028 InfoBuffer
->Role
.DomainServerRole
= FixedData
.DomainServerRole
;
1030 *Buffer
= InfoBuffer
;
1033 if (!NT_SUCCESS(Status
))
1035 if (InfoBuffer
!= NULL
)
1037 midl_user_free(InfoBuffer
);
1046 SampQueryDomainModified(PSAM_DB_OBJECT DomainObject
,
1047 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1049 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1050 SAM_DOMAIN_FIXED_DATA FixedData
;
1056 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1057 if (InfoBuffer
== NULL
)
1058 return STATUS_INSUFFICIENT_RESOURCES
;
1060 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1061 Status
= SampGetObjectAttribute(DomainObject
,
1066 if (!NT_SUCCESS(Status
))
1069 InfoBuffer
->Modified
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
1070 InfoBuffer
->Modified
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
1071 InfoBuffer
->Modified
.CreationTime
.LowPart
= FixedData
.CreationTime
.LowPart
;
1072 InfoBuffer
->Modified
.CreationTime
.HighPart
= FixedData
.CreationTime
.HighPart
;
1074 *Buffer
= InfoBuffer
;
1077 if (!NT_SUCCESS(Status
))
1079 if (InfoBuffer
!= NULL
)
1081 midl_user_free(InfoBuffer
);
1090 SampQueryDomainState(PSAM_DB_OBJECT DomainObject
,
1091 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1093 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1094 SAM_DOMAIN_FIXED_DATA FixedData
;
1100 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1101 if (InfoBuffer
== NULL
)
1102 return STATUS_INSUFFICIENT_RESOURCES
;
1104 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1105 Status
= SampGetObjectAttribute(DomainObject
,
1110 if (!NT_SUCCESS(Status
))
1113 InfoBuffer
->State
.DomainServerState
= FixedData
.DomainServerState
;
1115 *Buffer
= InfoBuffer
;
1118 if (!NT_SUCCESS(Status
))
1120 if (InfoBuffer
!= NULL
)
1122 midl_user_free(InfoBuffer
);
1131 SampQueryDomainGeneral2(PSAM_DB_OBJECT DomainObject
,
1132 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1134 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1135 SAM_DOMAIN_FIXED_DATA FixedData
;
1141 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1142 if (InfoBuffer
== NULL
)
1143 return STATUS_INSUFFICIENT_RESOURCES
;
1145 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1146 Status
= SampGetObjectAttribute(DomainObject
,
1151 if (!NT_SUCCESS(Status
))
1154 InfoBuffer
->General2
.I1
.ForceLogoff
.LowPart
= FixedData
.ForceLogoff
.LowPart
;
1155 InfoBuffer
->General2
.I1
.ForceLogoff
.HighPart
= FixedData
.ForceLogoff
.HighPart
;
1156 InfoBuffer
->General2
.I1
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
1157 InfoBuffer
->General2
.I1
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
1158 InfoBuffer
->General2
.I1
.DomainServerState
= FixedData
.DomainServerState
;
1159 InfoBuffer
->General2
.I1
.DomainServerRole
= FixedData
.DomainServerRole
;
1160 InfoBuffer
->General2
.I1
.UasCompatibilityRequired
= FixedData
.UasCompatibilityRequired
;
1162 InfoBuffer
->General2
.LockoutDuration
= FixedData
.LockoutDuration
;
1163 InfoBuffer
->General2
.LockoutObservationWindow
= FixedData
.LockoutObservationWindow
;
1164 InfoBuffer
->General2
.LockoutThreshold
= FixedData
.LockoutThreshold
;
1166 /* Get the OemInformation string */
1167 Status
= SampGetObjectAttributeString(DomainObject
,
1169 &InfoBuffer
->General2
.I1
.OemInformation
);
1170 if (!NT_SUCCESS(Status
))
1172 TRACE("Status 0x%08lx\n", Status
);
1176 /* Get the Name string */
1177 Status
= SampGetObjectAttributeString(DomainObject
,
1179 &InfoBuffer
->General2
.I1
.DomainName
);
1180 if (!NT_SUCCESS(Status
))
1182 TRACE("Status 0x%08lx\n", Status
);
1186 /* Get the ReplicaSourceNodeName string */
1187 Status
= SampGetObjectAttributeString(DomainObject
,
1188 L
"ReplicaSourceNodeName",
1189 &InfoBuffer
->General2
.I1
.ReplicaSourceNodeName
);
1190 if (!NT_SUCCESS(Status
))
1192 TRACE("Status 0x%08lx\n", Status
);
1196 /* Get the number of Users in the Domain */
1197 Status
= SampGetNumberOfAccounts(DomainObject
,
1199 &InfoBuffer
->General2
.I1
.UserCount
);
1200 if (!NT_SUCCESS(Status
))
1202 TRACE("Status 0x%08lx\n", Status
);
1206 /* Get the number of Groups in the Domain */
1207 Status
= SampGetNumberOfAccounts(DomainObject
,
1209 &InfoBuffer
->General2
.I1
.GroupCount
);
1210 if (!NT_SUCCESS(Status
))
1212 TRACE("Status 0x%08lx\n", Status
);
1216 /* Get the number of Aliases in the Domain */
1217 Status
= SampGetNumberOfAccounts(DomainObject
,
1219 &InfoBuffer
->General2
.I1
.AliasCount
);
1220 if (!NT_SUCCESS(Status
))
1222 TRACE("Status 0x%08lx\n", Status
);
1226 *Buffer
= InfoBuffer
;
1229 if (!NT_SUCCESS(Status
))
1231 if (InfoBuffer
!= NULL
)
1233 if (InfoBuffer
->General2
.I1
.OemInformation
.Buffer
!= NULL
)
1234 midl_user_free(InfoBuffer
->General2
.I1
.OemInformation
.Buffer
);
1236 if (InfoBuffer
->General2
.I1
.DomainName
.Buffer
!= NULL
)
1237 midl_user_free(InfoBuffer
->General2
.I1
.DomainName
.Buffer
);
1239 if (InfoBuffer
->General2
.I1
.ReplicaSourceNodeName
.Buffer
!= NULL
)
1240 midl_user_free(InfoBuffer
->General2
.I1
.ReplicaSourceNodeName
.Buffer
);
1242 midl_user_free(InfoBuffer
);
1251 SampQueryDomainLockout(PSAM_DB_OBJECT DomainObject
,
1252 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1254 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1255 SAM_DOMAIN_FIXED_DATA FixedData
;
1261 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1262 if (InfoBuffer
== NULL
)
1263 return STATUS_INSUFFICIENT_RESOURCES
;
1265 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1266 Status
= SampGetObjectAttribute(DomainObject
,
1271 if (!NT_SUCCESS(Status
))
1274 InfoBuffer
->Lockout
.LockoutDuration
= FixedData
.LockoutDuration
;
1275 InfoBuffer
->Lockout
.LockoutObservationWindow
= FixedData
.LockoutObservationWindow
;
1276 InfoBuffer
->Lockout
.LockoutThreshold
= FixedData
.LockoutThreshold
;
1278 *Buffer
= InfoBuffer
;
1281 if (!NT_SUCCESS(Status
))
1283 if (InfoBuffer
!= NULL
)
1285 midl_user_free(InfoBuffer
);
1294 SampQueryDomainModified2(PSAM_DB_OBJECT DomainObject
,
1295 PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1297 PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer
= NULL
;
1298 SAM_DOMAIN_FIXED_DATA FixedData
;
1304 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER
));
1305 if (InfoBuffer
== NULL
)
1306 return STATUS_INSUFFICIENT_RESOURCES
;
1308 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1309 Status
= SampGetObjectAttribute(DomainObject
,
1314 if (!NT_SUCCESS(Status
))
1317 InfoBuffer
->Modified2
.DomainModifiedCount
.LowPart
= FixedData
.DomainModifiedCount
.LowPart
;
1318 InfoBuffer
->Modified2
.DomainModifiedCount
.HighPart
= FixedData
.DomainModifiedCount
.HighPart
;
1319 InfoBuffer
->Modified2
.CreationTime
.LowPart
= FixedData
.CreationTime
.LowPart
;
1320 InfoBuffer
->Modified2
.CreationTime
.HighPart
= FixedData
.CreationTime
.HighPart
;
1321 InfoBuffer
->Modified2
.ModifiedCountAtLastPromotion
.LowPart
= FixedData
.ModifiedCountAtLastPromotion
.LowPart
;
1322 InfoBuffer
->Modified2
.ModifiedCountAtLastPromotion
.HighPart
= FixedData
.ModifiedCountAtLastPromotion
.HighPart
;
1324 *Buffer
= InfoBuffer
;
1327 if (!NT_SUCCESS(Status
))
1329 if (InfoBuffer
!= NULL
)
1331 midl_user_free(InfoBuffer
);
1342 SamrQueryInformationDomain(IN SAMPR_HANDLE DomainHandle
,
1343 IN DOMAIN_INFORMATION_CLASS DomainInformationClass
,
1344 OUT PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
1346 PSAM_DB_OBJECT DomainObject
;
1347 ACCESS_MASK DesiredAccess
;
1350 TRACE("SamrQueryInformationDomain(%p %lu %p)\n",
1351 DomainHandle
, DomainInformationClass
, Buffer
);
1353 switch (DomainInformationClass
)
1355 case DomainPasswordInformation
:
1356 case DomainLockoutInformation
:
1357 DesiredAccess
= DOMAIN_READ_PASSWORD_PARAMETERS
;
1360 case DomainGeneralInformation
:
1361 case DomainLogoffInformation
:
1362 case DomainOemInformation
:
1363 case DomainNameInformation
:
1364 case DomainReplicationInformation
:
1365 case DomainServerRoleInformation
:
1366 case DomainModifiedInformation
:
1367 case DomainStateInformation
:
1368 case DomainModifiedInformation2
:
1369 DesiredAccess
= DOMAIN_READ_OTHER_PARAMETERS
;
1372 case DomainGeneralInformation2
:
1373 DesiredAccess
= DOMAIN_READ_PASSWORD_PARAMETERS
|
1374 DOMAIN_READ_OTHER_PARAMETERS
;
1378 return STATUS_INVALID_INFO_CLASS
;
1381 /* Validate the server handle */
1382 Status
= SampValidateDbObject(DomainHandle
,
1386 if (!NT_SUCCESS(Status
))
1389 switch (DomainInformationClass
)
1391 case DomainPasswordInformation
:
1392 Status
= SampQueryDomainPassword(DomainObject
,
1396 case DomainGeneralInformation
:
1397 Status
= SampQueryDomainGeneral(DomainObject
,
1401 case DomainLogoffInformation
:
1402 Status
= SampQueryDomainLogoff(DomainObject
,
1406 case DomainOemInformation
:
1407 Status
= SampQueryDomainOem(DomainObject
,
1411 case DomainNameInformation
:
1412 Status
= SampQueryDomainName(DomainObject
,
1416 case DomainReplicationInformation
:
1417 Status
= SampQueryDomainReplication(DomainObject
,
1421 case DomainServerRoleInformation
:
1422 Status
= SampQueryDomainServerRole(DomainObject
,
1426 case DomainModifiedInformation
:
1427 Status
= SampQueryDomainModified(DomainObject
,
1431 case DomainStateInformation
:
1432 Status
= SampQueryDomainState(DomainObject
,
1436 case DomainGeneralInformation2
:
1437 Status
= SampQueryDomainGeneral2(DomainObject
,
1441 case DomainLockoutInformation
:
1442 Status
= SampQueryDomainLockout(DomainObject
,
1446 case DomainModifiedInformation2
:
1447 Status
= SampQueryDomainModified2(DomainObject
,
1452 Status
= STATUS_NOT_IMPLEMENTED
;
1460 SampSetDomainPassword(PSAM_DB_OBJECT DomainObject
,
1461 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1463 SAM_DOMAIN_FIXED_DATA FixedData
;
1467 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1468 Status
= SampGetObjectAttribute(DomainObject
,
1473 if (!NT_SUCCESS(Status
))
1476 FixedData
.MinPasswordLength
= Buffer
->Password
.MinPasswordLength
;
1477 FixedData
.PasswordHistoryLength
= Buffer
->Password
.PasswordHistoryLength
;
1478 FixedData
.PasswordProperties
= Buffer
->Password
.PasswordProperties
;
1479 FixedData
.MaxPasswordAge
.LowPart
= Buffer
->Password
.MaxPasswordAge
.LowPart
;
1480 FixedData
.MaxPasswordAge
.HighPart
= Buffer
->Password
.MaxPasswordAge
.HighPart
;
1481 FixedData
.MinPasswordAge
.LowPart
= Buffer
->Password
.MinPasswordAge
.LowPart
;
1482 FixedData
.MinPasswordAge
.HighPart
= Buffer
->Password
.MinPasswordAge
.HighPart
;
1484 Status
= SampSetObjectAttribute(DomainObject
,
1496 SampSetDomainLogoff(PSAM_DB_OBJECT DomainObject
,
1497 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1499 SAM_DOMAIN_FIXED_DATA FixedData
;
1503 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1504 Status
= SampGetObjectAttribute(DomainObject
,
1509 if (!NT_SUCCESS(Status
))
1512 FixedData
.ForceLogoff
.LowPart
= Buffer
->Logoff
.ForceLogoff
.LowPart
;
1513 FixedData
.ForceLogoff
.HighPart
= Buffer
->Logoff
.ForceLogoff
.HighPart
;
1515 Status
= SampSetObjectAttribute(DomainObject
,
1527 SampSetDomainServerRole(PSAM_DB_OBJECT DomainObject
,
1528 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1530 SAM_DOMAIN_FIXED_DATA FixedData
;
1534 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1535 Status
= SampGetObjectAttribute(DomainObject
,
1540 if (!NT_SUCCESS(Status
))
1543 FixedData
.DomainServerRole
= Buffer
->Role
.DomainServerRole
;
1545 Status
= SampSetObjectAttribute(DomainObject
,
1557 SampSetDomainState(PSAM_DB_OBJECT DomainObject
,
1558 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1560 SAM_DOMAIN_FIXED_DATA FixedData
;
1564 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1565 Status
= SampGetObjectAttribute(DomainObject
,
1570 if (!NT_SUCCESS(Status
))
1573 FixedData
.DomainServerState
= Buffer
->State
.DomainServerState
;
1575 Status
= SampSetObjectAttribute(DomainObject
,
1587 SampSetDomainLockout(PSAM_DB_OBJECT DomainObject
,
1588 PSAMPR_DOMAIN_INFO_BUFFER Buffer
)
1590 SAM_DOMAIN_FIXED_DATA FixedData
;
1594 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1595 Status
= SampGetObjectAttribute(DomainObject
,
1600 if (!NT_SUCCESS(Status
))
1603 FixedData
.LockoutDuration
= Buffer
->Lockout
.LockoutDuration
;
1604 FixedData
.LockoutObservationWindow
= Buffer
->Lockout
.LockoutObservationWindow
;
1605 FixedData
.LockoutThreshold
= Buffer
->Lockout
.LockoutThreshold
;
1607 Status
= SampSetObjectAttribute(DomainObject
,
1621 SamrSetInformationDomain(IN SAMPR_HANDLE DomainHandle
,
1622 IN DOMAIN_INFORMATION_CLASS DomainInformationClass
,
1623 IN PSAMPR_DOMAIN_INFO_BUFFER DomainInformation
)
1625 PSAM_DB_OBJECT DomainObject
;
1626 ACCESS_MASK DesiredAccess
;
1629 TRACE("SamrSetInformationDomain(%p %lu %p)\n",
1630 DomainHandle
, DomainInformationClass
, DomainInformation
);
1632 switch (DomainInformationClass
)
1634 case DomainPasswordInformation
:
1635 case DomainLockoutInformation
:
1636 DesiredAccess
= DOMAIN_WRITE_PASSWORD_PARAMS
;
1639 case DomainLogoffInformation
:
1640 case DomainOemInformation
:
1641 case DomainNameInformation
:
1642 DesiredAccess
= DOMAIN_WRITE_OTHER_PARAMETERS
;
1645 case DomainReplicationInformation
:
1646 case DomainServerRoleInformation
:
1647 case DomainStateInformation
:
1648 DesiredAccess
= DOMAIN_ADMINISTER_SERVER
;
1652 return STATUS_INVALID_INFO_CLASS
;
1655 /* Validate the server handle */
1656 Status
= SampValidateDbObject(DomainHandle
,
1660 if (!NT_SUCCESS(Status
))
1663 switch (DomainInformationClass
)
1665 case DomainPasswordInformation
:
1666 Status
= SampSetDomainPassword(DomainObject
,
1670 case DomainLogoffInformation
:
1671 Status
= SampSetDomainLogoff(DomainObject
,
1675 case DomainOemInformation
:
1676 Status
= SampSetObjectAttribute(DomainObject
,
1679 DomainInformation
->Oem
.OemInformation
.Buffer
,
1680 DomainInformation
->Oem
.OemInformation
.Length
+ sizeof(WCHAR
));
1683 case DomainNameInformation
:
1684 Status
= SampSetObjectAttribute(DomainObject
,
1687 DomainInformation
->Name
.DomainName
.Buffer
,
1688 DomainInformation
->Name
.DomainName
.Length
+ sizeof(WCHAR
));
1691 case DomainReplicationInformation
:
1692 Status
= SampSetObjectAttribute(DomainObject
,
1693 L
"ReplicaSourceNodeName",
1695 DomainInformation
->Replication
.ReplicaSourceNodeName
.Buffer
,
1696 DomainInformation
->Replication
.ReplicaSourceNodeName
.Length
+ sizeof(WCHAR
));
1699 case DomainServerRoleInformation
:
1700 Status
= SampSetDomainServerRole(DomainObject
,
1704 case DomainStateInformation
:
1705 Status
= SampSetDomainState(DomainObject
,
1709 case DomainLockoutInformation
:
1710 Status
= SampSetDomainLockout(DomainObject
,
1715 Status
= STATUS_NOT_IMPLEMENTED
;
1725 SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle
,
1726 IN PRPC_UNICODE_STRING Name
,
1727 IN ACCESS_MASK DesiredAccess
,
1728 OUT SAMPR_HANDLE
*GroupHandle
,
1729 OUT
unsigned long *RelativeId
)
1731 UNICODE_STRING EmptyString
= RTL_CONSTANT_STRING(L
"");
1732 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
1733 SAM_GROUP_FIXED_DATA FixedGroupData
;
1734 PSAM_DB_OBJECT DomainObject
;
1735 PSAM_DB_OBJECT GroupObject
;
1741 TRACE("SamrCreateGroupInDomain(%p %p %lx %p %p)\n",
1742 DomainHandle
, Name
, DesiredAccess
, GroupHandle
, RelativeId
);
1744 /* Map generic access rights */
1745 RtlMapGenericMask(&DesiredAccess
,
1748 /* Validate the domain handle */
1749 Status
= SampValidateDbObject(DomainHandle
,
1751 DOMAIN_CREATE_GROUP
,
1753 if (!NT_SUCCESS(Status
))
1755 TRACE("failed with status 0x%08lx\n", Status
);
1759 /* Check if the group name already exists in the domain */
1760 Status
= SampCheckAccountNameInDomain(DomainObject
,
1762 if (!NT_SUCCESS(Status
))
1764 TRACE("Group name \'%S\' already exists in domain (Status 0x%08lx)\n",
1765 Name
->Buffer
, Status
);
1769 /* Get the fixed domain attributes */
1770 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
1771 Status
= SampGetObjectAttribute(DomainObject
,
1774 (PVOID
)&FixedDomainData
,
1776 if (!NT_SUCCESS(Status
))
1778 TRACE("failed with status 0x%08lx\n", Status
);
1782 /* Increment the NextRid attribute */
1783 ulRid
= FixedDomainData
.NextRid
;
1784 FixedDomainData
.NextRid
++;
1786 /* Store the fixed domain attributes */
1787 Status
= SampSetObjectAttribute(DomainObject
,
1792 if (!NT_SUCCESS(Status
))
1794 TRACE("failed with status 0x%08lx\n", Status
);
1798 TRACE("RID: %lx\n", ulRid
);
1800 /* Convert the RID into a string (hex) */
1801 swprintf(szRid
, L
"%08lX", ulRid
);
1803 /* Create the group object */
1804 Status
= SampCreateDbObject(DomainObject
,
1811 if (!NT_SUCCESS(Status
))
1813 TRACE("failed with status 0x%08lx\n", Status
);
1817 /* Add the account name of the user object */
1818 Status
= SampSetAccountNameInDomain(DomainObject
,
1822 if (!NT_SUCCESS(Status
))
1824 TRACE("failed with status 0x%08lx\n", Status
);
1828 /* Initialize fixed user data */
1829 memset(&FixedGroupData
, 0, sizeof(SAM_GROUP_FIXED_DATA
));
1830 FixedGroupData
.Version
= 1;
1832 FixedGroupData
.GroupId
= ulRid
;
1834 /* Set fixed user data attribute */
1835 Status
= SampSetObjectAttribute(GroupObject
,
1838 (LPVOID
)&FixedGroupData
,
1839 sizeof(SAM_GROUP_FIXED_DATA
));
1840 if (!NT_SUCCESS(Status
))
1842 TRACE("failed with status 0x%08lx\n", Status
);
1846 /* Set the Name attribute */
1847 Status
= SampSetObjectAttribute(GroupObject
,
1850 (LPVOID
)Name
->Buffer
,
1851 Name
->MaximumLength
);
1852 if (!NT_SUCCESS(Status
))
1854 TRACE("failed with status 0x%08lx\n", Status
);
1858 /* Set the AdminComment attribute */
1859 Status
= SampSetObjectAttribute(GroupObject
,
1863 EmptyString
.MaximumLength
);
1864 if (!NT_SUCCESS(Status
))
1866 TRACE("failed with status 0x%08lx\n", Status
);
1870 if (NT_SUCCESS(Status
))
1872 *GroupHandle
= (SAMPR_HANDLE
)GroupObject
;
1873 *RelativeId
= ulRid
;
1876 TRACE("returns with status 0x%08lx\n", Status
);
1885 SamrEnumerateGroupsInDomain(IN SAMPR_HANDLE DomainHandle
,
1886 IN OUT
unsigned long *EnumerationContext
,
1887 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
1888 IN
unsigned long PreferedMaximumLength
,
1889 OUT
unsigned long *CountReturned
)
1891 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
1892 PSAM_DB_OBJECT DomainObject
;
1893 HANDLE GroupsKeyHandle
= NULL
;
1894 HANDLE NamesKeyHandle
= NULL
;
1895 WCHAR GroupName
[64];
1897 ULONG EnumCount
= 0;
1898 ULONG RequiredLength
= 0;
1903 BOOLEAN MoreEntries
= FALSE
;
1906 TRACE("SamrEnumerateUsersInDomain(%p %p %p %lu %p)\n",
1907 DomainHandle
, EnumerationContext
, Buffer
,
1908 PreferedMaximumLength
, CountReturned
);
1910 /* Validate the domain handle */
1911 Status
= SampValidateDbObject(DomainHandle
,
1913 DOMAIN_LIST_ACCOUNTS
,
1915 if (!NT_SUCCESS(Status
))
1918 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
1922 if (!NT_SUCCESS(Status
))
1925 Status
= SampRegOpenKey(GroupsKeyHandle
,
1929 if (!NT_SUCCESS(Status
))
1934 EnumIndex
= *EnumerationContext
;
1938 NameLength
= 64 * sizeof(WCHAR
);
1939 Status
= SampRegEnumerateValue(NamesKeyHandle
,
1946 if (!NT_SUCCESS(Status
))
1948 if (Status
== STATUS_NO_MORE_ENTRIES
)
1949 Status
= STATUS_SUCCESS
;
1953 TRACE("EnumIndex: %lu\n", EnumIndex
);
1954 TRACE("Group name: %S\n", GroupName
);
1955 TRACE("Name length: %lu\n", NameLength
);
1957 if ((RequiredLength
+ NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
)) > PreferedMaximumLength
)
1963 RequiredLength
+= (NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
));
1969 TRACE("EnumCount: %lu\n", EnumCount
);
1970 TRACE("RequiredLength: %lu\n", RequiredLength
);
1972 if (!NT_SUCCESS(Status
))
1975 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
1976 if (EnumBuffer
== NULL
)
1978 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1982 EnumBuffer
->EntriesRead
= EnumCount
;
1986 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
1987 if (EnumBuffer
->Buffer
== NULL
)
1989 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1995 EnumIndex
= *EnumerationContext
;
1996 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
1998 NameLength
= 64 * sizeof(WCHAR
);
1999 DataLength
= sizeof(ULONG
);
2000 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2007 if (!NT_SUCCESS(Status
))
2009 if (Status
== STATUS_NO_MORE_ENTRIES
)
2010 Status
= STATUS_SUCCESS
;
2014 TRACE("EnumIndex: %lu\n", EnumIndex
);
2015 TRACE("Group name: %S\n", GroupName
);
2016 TRACE("Name length: %lu\n", NameLength
);
2017 TRACE("RID: %lu\n", Rid
);
2019 EnumBuffer
->Buffer
[i
].RelativeId
= Rid
;
2021 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)NameLength
;
2022 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)(DataLength
+ sizeof(UNICODE_NULL
));
2024 /* FIXME: Disabled because of bugs in widl and rpcrt4 */
2026 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(EnumBuffer
->Buffer
[i
].Name
.MaximumLength
);
2027 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
2029 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2033 memcpy(EnumBuffer
->Buffer
[i
].Name
.Buffer
,
2035 EnumBuffer
->Buffer
[i
].Name
.Length
);
2040 if (NT_SUCCESS(Status
))
2042 *EnumerationContext
+= EnumCount
;
2043 *Buffer
= EnumBuffer
;
2044 *CountReturned
= EnumCount
;
2048 *EnumerationContext
= 0;
2052 if (EnumBuffer
!= NULL
)
2054 if (EnumBuffer
->Buffer
!= NULL
)
2056 if (EnumBuffer
->EntriesRead
!= 0)
2058 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
2060 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
2061 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
2065 midl_user_free(EnumBuffer
->Buffer
);
2068 midl_user_free(EnumBuffer
);
2072 if (NamesKeyHandle
!= NULL
)
2073 SampRegCloseKey(NamesKeyHandle
);
2075 if (GroupsKeyHandle
!= NULL
)
2076 SampRegCloseKey(GroupsKeyHandle
);
2078 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
== TRUE
))
2079 Status
= STATUS_MORE_ENTRIES
;
2088 SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle
,
2089 IN PRPC_UNICODE_STRING Name
,
2090 IN ACCESS_MASK DesiredAccess
,
2091 OUT SAMPR_HANDLE
*UserHandle
,
2092 OUT
unsigned long *RelativeId
)
2094 UNICODE_STRING EmptyString
= RTL_CONSTANT_STRING(L
"");
2095 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
2096 SAM_USER_FIXED_DATA FixedUserData
;
2097 PSAM_DB_OBJECT DomainObject
;
2098 PSAM_DB_OBJECT UserObject
;
2099 GROUP_MEMBERSHIP GroupMembership
;
2100 UCHAR LogonHours
[23];
2106 TRACE("SamrCreateUserInDomain(%p %p %lx %p %p)\n",
2107 DomainHandle
, Name
, DesiredAccess
, UserHandle
, RelativeId
);
2110 Name
->Length
== 0 ||
2111 Name
->Buffer
== NULL
||
2112 UserHandle
== NULL
||
2114 return STATUS_INVALID_PARAMETER
;
2116 /* Map generic access rights */
2117 RtlMapGenericMask(&DesiredAccess
,
2120 /* Validate the domain handle */
2121 Status
= SampValidateDbObject(DomainHandle
,
2125 if (!NT_SUCCESS(Status
))
2127 TRACE("failed with status 0x%08lx\n", Status
);
2131 /* Check if the user name already exists in the domain */
2132 Status
= SampCheckAccountNameInDomain(DomainObject
,
2134 if (!NT_SUCCESS(Status
))
2136 TRACE("User name \'%S\' already exists in domain (Status 0x%08lx)\n",
2137 Name
->Buffer
, Status
);
2141 /* Get the fixed domain attributes */
2142 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
2143 Status
= SampGetObjectAttribute(DomainObject
,
2146 (PVOID
)&FixedDomainData
,
2148 if (!NT_SUCCESS(Status
))
2150 TRACE("failed with status 0x%08lx\n", Status
);
2154 /* Increment the NextRid attribute */
2155 ulRid
= FixedDomainData
.NextRid
;
2156 FixedDomainData
.NextRid
++;
2158 /* Store the fixed domain attributes */
2159 Status
= SampSetObjectAttribute(DomainObject
,
2164 if (!NT_SUCCESS(Status
))
2166 TRACE("failed with status 0x%08lx\n", Status
);
2170 TRACE("RID: %lx\n", ulRid
);
2172 /* Convert the RID into a string (hex) */
2173 swprintf(szRid
, L
"%08lX", ulRid
);
2175 /* Create the user object */
2176 Status
= SampCreateDbObject(DomainObject
,
2183 if (!NT_SUCCESS(Status
))
2185 TRACE("failed with status 0x%08lx\n", Status
);
2189 /* Add the account name for the user object */
2190 Status
= SampSetAccountNameInDomain(DomainObject
,
2194 if (!NT_SUCCESS(Status
))
2196 TRACE("failed with status 0x%08lx\n", Status
);
2200 /* Initialize fixed user data */
2201 memset(&FixedUserData
, 0, sizeof(SAM_USER_FIXED_DATA
));
2202 FixedUserData
.Version
= 1;
2203 FixedUserData
.Reserved
= 0;
2204 FixedUserData
.LastLogon
.QuadPart
= 0;
2205 FixedUserData
.LastLogoff
.QuadPart
= 0;
2206 FixedUserData
.PasswordLastSet
.QuadPart
= 0;
2207 FixedUserData
.AccountExpires
.LowPart
= MAXULONG
;
2208 FixedUserData
.AccountExpires
.HighPart
= MAXLONG
;
2209 FixedUserData
.LastBadPasswordTime
.QuadPart
= 0;
2210 FixedUserData
.UserId
= ulRid
;
2211 FixedUserData
.PrimaryGroupId
= DOMAIN_GROUP_RID_USERS
;
2212 FixedUserData
.UserAccountControl
= USER_ACCOUNT_DISABLED
|
2213 USER_PASSWORD_NOT_REQUIRED
|
2214 USER_NORMAL_ACCOUNT
;
2215 FixedUserData
.CountryCode
= 0;
2216 FixedUserData
.CodePage
= 0;
2217 FixedUserData
.BadPasswordCount
= 0;
2218 FixedUserData
.LogonCount
= 0;
2219 FixedUserData
.AdminCount
= 0;
2220 FixedUserData
.OperatorCount
= 0;
2222 /* Set fixed user data attribute */
2223 Status
= SampSetObjectAttribute(UserObject
,
2226 (LPVOID
)&FixedUserData
,
2227 sizeof(SAM_USER_FIXED_DATA
));
2228 if (!NT_SUCCESS(Status
))
2230 TRACE("failed with status 0x%08lx\n", Status
);
2234 /* Set the Name attribute */
2235 Status
= SampSetObjectAttribute(UserObject
,
2238 (LPVOID
)Name
->Buffer
,
2239 Name
->MaximumLength
);
2240 if (!NT_SUCCESS(Status
))
2242 TRACE("failed with status 0x%08lx\n", Status
);
2246 /* Set the FullName attribute */
2247 Status
= SampSetObjectAttribute(UserObject
,
2251 EmptyString
.MaximumLength
);
2252 if (!NT_SUCCESS(Status
))
2254 TRACE("failed with status 0x%08lx\n", Status
);
2258 /* Set the HomeDirectory attribute */
2259 Status
= SampSetObjectAttribute(UserObject
,
2263 EmptyString
.MaximumLength
);
2264 if (!NT_SUCCESS(Status
))
2266 TRACE("failed with status 0x%08lx\n", Status
);
2270 /* Set the HomeDirectoryDrive attribute */
2271 Status
= SampSetObjectAttribute(UserObject
,
2272 L
"HomeDirectoryDrive",
2275 EmptyString
.MaximumLength
);
2276 if (!NT_SUCCESS(Status
))
2278 TRACE("failed with status 0x%08lx\n", Status
);
2282 /* Set the ScriptPath attribute */
2283 Status
= SampSetObjectAttribute(UserObject
,
2287 EmptyString
.MaximumLength
);
2288 if (!NT_SUCCESS(Status
))
2290 TRACE("failed with status 0x%08lx\n", Status
);
2294 /* Set the ProfilePath attribute */
2295 Status
= SampSetObjectAttribute(UserObject
,
2299 EmptyString
.MaximumLength
);
2300 if (!NT_SUCCESS(Status
))
2302 TRACE("failed with status 0x%08lx\n", Status
);
2306 /* Set the AdminComment attribute */
2307 Status
= SampSetObjectAttribute(UserObject
,
2311 EmptyString
.MaximumLength
);
2312 if (!NT_SUCCESS(Status
))
2314 TRACE("failed with status 0x%08lx\n", Status
);
2318 /* Set the UserComment attribute */
2319 Status
= SampSetObjectAttribute(UserObject
,
2323 EmptyString
.MaximumLength
);
2324 if (!NT_SUCCESS(Status
))
2326 TRACE("failed with status 0x%08lx\n", Status
);
2330 /* Set the WorkStations attribute */
2331 Status
= SampSetObjectAttribute(UserObject
,
2335 EmptyString
.MaximumLength
);
2336 if (!NT_SUCCESS(Status
))
2338 TRACE("failed with status 0x%08lx\n", Status
);
2342 /* Set the Parameters attribute */
2343 Status
= SampSetObjectAttribute(UserObject
,
2347 EmptyString
.MaximumLength
);
2348 if (!NT_SUCCESS(Status
))
2350 TRACE("failed with status 0x%08lx\n", Status
);
2354 /* Set LogonHours attribute*/
2355 *((PUSHORT
)LogonHours
) = 168;
2356 memset(&(LogonHours
[2]), 0xff, 21);
2358 Status
= SampSetObjectAttribute(UserObject
,
2362 sizeof(LogonHours
));
2363 if (!NT_SUCCESS(Status
))
2365 TRACE("failed with status 0x%08lx\n", Status
);
2369 /* Set Groups attribute*/
2370 GroupMembership
.RelativeId
= DOMAIN_GROUP_RID_USERS
;
2371 GroupMembership
.Attributes
= SE_GROUP_MANDATORY
|
2373 SE_GROUP_ENABLED_BY_DEFAULT
;
2375 Status
= SampSetObjectAttribute(UserObject
,
2379 sizeof(GROUP_MEMBERSHIP
));
2380 if (!NT_SUCCESS(Status
))
2382 TRACE("failed with status 0x%08lx\n", Status
);
2386 /* Set LMPwd attribute*/
2387 Status
= SampSetObjectAttribute(UserObject
,
2391 sizeof(ENCRYPTED_LM_OWF_PASSWORD
));
2392 if (!NT_SUCCESS(Status
))
2394 TRACE("failed with status 0x%08lx\n", Status
);
2398 /* Set NTPwd attribute*/
2399 Status
= SampSetObjectAttribute(UserObject
,
2403 sizeof(ENCRYPTED_NT_OWF_PASSWORD
));
2404 if (!NT_SUCCESS(Status
))
2406 TRACE("failed with status 0x%08lx\n", Status
);
2410 /* Set LMPwdHistory attribute*/
2411 Status
= SampSetObjectAttribute(UserObject
,
2416 if (!NT_SUCCESS(Status
))
2418 TRACE("failed with status 0x%08lx\n", Status
);
2422 /* Set NTPwdHistory attribute*/
2423 Status
= SampSetObjectAttribute(UserObject
,
2428 if (!NT_SUCCESS(Status
))
2430 TRACE("failed with status 0x%08lx\n", Status
);
2434 /* FIXME: Set SecDesc attribute*/
2436 if (NT_SUCCESS(Status
))
2438 *UserHandle
= (SAMPR_HANDLE
)UserObject
;
2439 *RelativeId
= ulRid
;
2442 TRACE("returns with status 0x%08lx\n", Status
);
2451 SamrEnumerateUsersInDomain(IN SAMPR_HANDLE DomainHandle
,
2452 IN OUT
unsigned long *EnumerationContext
,
2453 IN
unsigned long UserAccountControl
,
2454 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
2455 IN
unsigned long PreferedMaximumLength
,
2456 OUT
unsigned long *CountReturned
)
2458 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
2459 PSAM_DB_OBJECT DomainObject
;
2460 HANDLE UsersKeyHandle
= NULL
;
2461 HANDLE NamesKeyHandle
= NULL
;
2464 ULONG EnumCount
= 0;
2465 ULONG RequiredLength
= 0;
2470 BOOLEAN MoreEntries
= FALSE
;
2473 TRACE("SamrEnumerateUsersInDomain(%p %p %lx %p %lu %p)\n",
2474 DomainHandle
, EnumerationContext
, UserAccountControl
, Buffer
,
2475 PreferedMaximumLength
, CountReturned
);
2477 /* Validate the domain handle */
2478 Status
= SampValidateDbObject(DomainHandle
,
2480 DOMAIN_LIST_ACCOUNTS
,
2482 if (!NT_SUCCESS(Status
))
2485 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
2489 if (!NT_SUCCESS(Status
))
2492 Status
= SampRegOpenKey(UsersKeyHandle
,
2496 if (!NT_SUCCESS(Status
))
2501 EnumIndex
= *EnumerationContext
;
2505 NameLength
= 64 * sizeof(WCHAR
);
2506 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2513 if (!NT_SUCCESS(Status
))
2515 if (Status
== STATUS_NO_MORE_ENTRIES
)
2516 Status
= STATUS_SUCCESS
;
2520 TRACE("EnumIndex: %lu\n", EnumIndex
);
2521 TRACE("User name: %S\n", UserName
);
2522 TRACE("Name length: %lu\n", NameLength
);
2524 if ((RequiredLength
+ NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
)) > PreferedMaximumLength
)
2530 RequiredLength
+= (NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
));
2536 TRACE("EnumCount: %lu\n", EnumCount
);
2537 TRACE("RequiredLength: %lu\n", RequiredLength
);
2539 if (!NT_SUCCESS(Status
))
2542 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
2543 if (EnumBuffer
== NULL
)
2545 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2549 EnumBuffer
->EntriesRead
= EnumCount
;
2553 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
2554 if (EnumBuffer
->Buffer
== NULL
)
2556 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2562 EnumIndex
= *EnumerationContext
;
2563 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
2565 NameLength
= 64 * sizeof(WCHAR
);
2566 DataLength
= sizeof(ULONG
);
2567 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2574 if (!NT_SUCCESS(Status
))
2576 if (Status
== STATUS_NO_MORE_ENTRIES
)
2577 Status
= STATUS_SUCCESS
;
2581 TRACE("EnumIndex: %lu\n", EnumIndex
);
2582 TRACE("User name: %S\n", UserName
);
2583 TRACE("Name length: %lu\n", NameLength
);
2584 TRACE("RID: %lu\n", Rid
);
2586 EnumBuffer
->Buffer
[i
].RelativeId
= Rid
;
2588 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)NameLength
;
2589 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)(DataLength
+ sizeof(UNICODE_NULL
));
2591 /* FIXME: Disabled because of bugs in widl and rpcrt4 */
2593 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(EnumBuffer
->Buffer
[i
].Name
.MaximumLength
);
2594 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
2596 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2600 memcpy(EnumBuffer
->Buffer
[i
].Name
.Buffer
,
2602 EnumBuffer
->Buffer
[i
].Name
.Length
);
2607 if (NT_SUCCESS(Status
))
2609 *EnumerationContext
+= EnumCount
;
2610 *Buffer
= EnumBuffer
;
2611 *CountReturned
= EnumCount
;
2615 *EnumerationContext
= 0;
2619 if (EnumBuffer
!= NULL
)
2621 if (EnumBuffer
->Buffer
!= NULL
)
2623 if (EnumBuffer
->EntriesRead
!= 0)
2625 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
2627 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
2628 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
2632 midl_user_free(EnumBuffer
->Buffer
);
2635 midl_user_free(EnumBuffer
);
2639 if (NamesKeyHandle
!= NULL
)
2640 SampRegCloseKey(NamesKeyHandle
);
2642 if (UsersKeyHandle
!= NULL
)
2643 SampRegCloseKey(UsersKeyHandle
);
2645 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
== TRUE
))
2646 Status
= STATUS_MORE_ENTRIES
;
2655 SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle
,
2656 IN PRPC_UNICODE_STRING AccountName
,
2657 IN ACCESS_MASK DesiredAccess
,
2658 OUT SAMPR_HANDLE
*AliasHandle
,
2659 OUT
unsigned long *RelativeId
)
2661 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
2662 PSAM_DB_OBJECT DomainObject
;
2663 PSAM_DB_OBJECT AliasObject
;
2664 UNICODE_STRING EmptyString
= RTL_CONSTANT_STRING(L
"");
2670 TRACE("SamrCreateAliasInDomain(%p %p %lx %p %p)\n",
2671 DomainHandle
, AccountName
, DesiredAccess
, AliasHandle
, RelativeId
);
2673 /* Map generic access rights */
2674 RtlMapGenericMask(&DesiredAccess
,
2677 /* Validate the domain handle */
2678 Status
= SampValidateDbObject(DomainHandle
,
2680 DOMAIN_CREATE_ALIAS
,
2682 if (!NT_SUCCESS(Status
))
2684 TRACE("failed with status 0x%08lx\n", Status
);
2688 /* Check if the alias name already exists in the domain */
2689 Status
= SampCheckAccountNameInDomain(DomainObject
,
2690 AccountName
->Buffer
);
2691 if (!NT_SUCCESS(Status
))
2693 TRACE("Alias name \'%S\' already exists in domain (Status 0x%08lx)\n",
2694 AccountName
->Buffer
, Status
);
2698 /* Get the fixed domain attributes */
2699 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
2700 Status
= SampGetObjectAttribute(DomainObject
,
2703 (PVOID
)&FixedDomainData
,
2705 if (!NT_SUCCESS(Status
))
2707 TRACE("failed with status 0x%08lx\n", Status
);
2711 /* Increment the NextRid attribute */
2712 ulRid
= FixedDomainData
.NextRid
;
2713 FixedDomainData
.NextRid
++;
2715 /* Store the fixed domain attributes */
2716 Status
= SampSetObjectAttribute(DomainObject
,
2721 if (!NT_SUCCESS(Status
))
2723 TRACE("failed with status 0x%08lx\n", Status
);
2727 TRACE("RID: %lx\n", ulRid
);
2729 /* Convert the RID into a string (hex) */
2730 swprintf(szRid
, L
"%08lX", ulRid
);
2732 /* Create the alias object */
2733 Status
= SampCreateDbObject(DomainObject
,
2740 if (!NT_SUCCESS(Status
))
2742 TRACE("failed with status 0x%08lx\n", Status
);
2746 /* Add the account name for the alias object */
2747 Status
= SampSetAccountNameInDomain(DomainObject
,
2749 AccountName
->Buffer
,
2751 if (!NT_SUCCESS(Status
))
2753 TRACE("failed with status 0x%08lx\n", Status
);
2757 /* Set the Name attribute */
2758 Status
= SampSetObjectAttribute(AliasObject
,
2761 (LPVOID
)AccountName
->Buffer
,
2762 AccountName
->MaximumLength
);
2763 if (!NT_SUCCESS(Status
))
2765 TRACE("failed with status 0x%08lx\n", Status
);
2769 /* Set the Description attribute */
2770 Status
= SampSetObjectAttribute(AliasObject
,
2774 EmptyString
.MaximumLength
);
2775 if (!NT_SUCCESS(Status
))
2777 TRACE("failed with status 0x%08lx\n", Status
);
2781 if (NT_SUCCESS(Status
))
2783 *AliasHandle
= (SAMPR_HANDLE
)AliasObject
;
2784 *RelativeId
= ulRid
;
2787 TRACE("returns with status 0x%08lx\n", Status
);
2796 SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle
,
2797 IN OUT
unsigned long *EnumerationContext
,
2798 OUT PSAMPR_ENUMERATION_BUFFER
*Buffer
,
2799 IN
unsigned long PreferedMaximumLength
,
2800 OUT
unsigned long *CountReturned
)
2802 PSAMPR_ENUMERATION_BUFFER EnumBuffer
= NULL
;
2803 PSAM_DB_OBJECT DomainObject
;
2804 HANDLE AliasesKeyHandle
= NULL
;
2805 HANDLE NamesKeyHandle
= NULL
;
2806 WCHAR AliasName
[64];
2808 ULONG EnumCount
= 0;
2809 ULONG RequiredLength
= 0;
2814 BOOLEAN MoreEntries
= FALSE
;
2817 TRACE("SamrEnumerateAliasesInDomain(%p %p %p %lu %p)\n",
2818 DomainHandle
, EnumerationContext
, Buffer
,
2819 PreferedMaximumLength
, CountReturned
);
2821 /* Validate the domain handle */
2822 Status
= SampValidateDbObject(DomainHandle
,
2824 DOMAIN_LIST_ACCOUNTS
,
2826 if (!NT_SUCCESS(Status
))
2829 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
2833 if (!NT_SUCCESS(Status
))
2836 Status
= SampRegOpenKey(AliasesKeyHandle
,
2840 if (!NT_SUCCESS(Status
))
2845 EnumIndex
= *EnumerationContext
;
2849 NameLength
= 64 * sizeof(WCHAR
);
2850 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2857 if (!NT_SUCCESS(Status
))
2859 if (Status
== STATUS_NO_MORE_ENTRIES
)
2860 Status
= STATUS_SUCCESS
;
2864 TRACE("EnumIndex: %lu\n", EnumIndex
);
2865 TRACE("Alias name: %S\n", AliasName
);
2866 TRACE("Name length: %lu\n", NameLength
);
2868 if ((RequiredLength
+ NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
)) > PreferedMaximumLength
)
2874 RequiredLength
+= (NameLength
+ sizeof(UNICODE_NULL
) + sizeof(SAMPR_RID_ENUMERATION
));
2880 TRACE("EnumCount: %lu\n", EnumCount
);
2881 TRACE("RequiredLength: %lu\n", RequiredLength
);
2883 if (!NT_SUCCESS(Status
))
2886 EnumBuffer
= midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER
));
2887 if (EnumBuffer
== NULL
)
2889 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2893 EnumBuffer
->EntriesRead
= EnumCount
;
2897 EnumBuffer
->Buffer
= midl_user_allocate(EnumCount
* sizeof(SAMPR_RID_ENUMERATION
));
2898 if (EnumBuffer
->Buffer
== NULL
)
2900 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2906 EnumIndex
= *EnumerationContext
;
2907 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
2909 NameLength
= 64 * sizeof(WCHAR
);
2910 DataLength
= sizeof(ULONG
);
2911 Status
= SampRegEnumerateValue(NamesKeyHandle
,
2918 if (!NT_SUCCESS(Status
))
2920 if (Status
== STATUS_NO_MORE_ENTRIES
)
2921 Status
= STATUS_SUCCESS
;
2925 TRACE("EnumIndex: %lu\n", EnumIndex
);
2926 TRACE("Alias name: %S\n", AliasName
);
2927 TRACE("Name length: %lu\n", NameLength
);
2928 TRACE("RID: %lu\n", Rid
);
2930 EnumBuffer
->Buffer
[i
].RelativeId
= Rid
;
2932 EnumBuffer
->Buffer
[i
].Name
.Length
= (USHORT
)NameLength
;
2933 EnumBuffer
->Buffer
[i
].Name
.MaximumLength
= (USHORT
)(DataLength
+ sizeof(UNICODE_NULL
));
2935 /* FIXME: Disabled because of bugs in widl and rpcrt4 */
2937 EnumBuffer
->Buffer
[i
].Name
.Buffer
= midl_user_allocate(EnumBuffer
->Buffer
[i
].Name
.MaximumLength
);
2938 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
== NULL
)
2940 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2944 memcpy(EnumBuffer
->Buffer
[i
].Name
.Buffer
,
2946 EnumBuffer
->Buffer
[i
].Name
.Length
);
2951 if (NT_SUCCESS(Status
))
2953 *EnumerationContext
+= EnumCount
;
2954 *Buffer
= EnumBuffer
;
2955 *CountReturned
= EnumCount
;
2959 *EnumerationContext
= 0;
2963 if (EnumBuffer
!= NULL
)
2965 if (EnumBuffer
->Buffer
!= NULL
)
2967 if (EnumBuffer
->EntriesRead
!= 0)
2969 for (i
= 0; i
< EnumBuffer
->EntriesRead
; i
++)
2971 if (EnumBuffer
->Buffer
[i
].Name
.Buffer
!= NULL
)
2972 midl_user_free(EnumBuffer
->Buffer
[i
].Name
.Buffer
);
2976 midl_user_free(EnumBuffer
->Buffer
);
2979 midl_user_free(EnumBuffer
);
2983 if (NamesKeyHandle
!= NULL
)
2984 SampRegCloseKey(NamesKeyHandle
);
2986 if (AliasesKeyHandle
!= NULL
)
2987 SampRegCloseKey(AliasesKeyHandle
);
2989 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
== TRUE
))
2990 Status
= STATUS_MORE_ENTRIES
;
2999 SamrGetAliasMembership(IN SAMPR_HANDLE DomainHandle
,
3000 IN PSAMPR_PSID_ARRAY SidArray
,
3001 OUT PSAMPR_ULONG_ARRAY Membership
)
3003 PSAM_DB_OBJECT DomainObject
;
3004 HANDLE AliasesKeyHandle
= NULL
;
3005 HANDLE MembersKeyHandle
= NULL
;
3006 HANDLE MemberKeyHandle
= NULL
;
3007 LPWSTR MemberSidString
= NULL
;
3008 PULONG RidArray
= NULL
;
3009 ULONG MaxSidCount
= 0;
3014 WCHAR NameBuffer
[9];
3016 TRACE("SamrGetAliasMembership(%p %p %p)\n",
3017 DomainHandle
, SidArray
, Membership
);
3019 /* Validate the domain handle */
3020 Status
= SampValidateDbObject(DomainHandle
,
3022 DOMAIN_GET_ALIAS_MEMBERSHIP
,
3024 if (!NT_SUCCESS(Status
))
3027 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3031 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3032 if (!NT_SUCCESS(Status
))
3035 Status
= SampRegOpenKey(AliasesKeyHandle
,
3039 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3041 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3043 Status
= STATUS_SUCCESS
;
3047 if (!NT_SUCCESS(Status
))
3050 for (i
= 0; i
< SidArray
->Count
; i
++)
3052 ConvertSidToStringSid(SidArray
->Sids
[i
].SidPointer
, &MemberSidString
);
3053 TRACE("Open %S\n", MemberSidString
);
3055 Status
= SampRegOpenKey(MembersKeyHandle
,
3059 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3060 if (NT_SUCCESS(Status
))
3062 Status
= SampRegQueryKeyInfo(MemberKeyHandle
,
3065 if (NT_SUCCESS(Status
))
3067 TRACE("Found %lu values\n", ValueCount
);
3068 MaxSidCount
+= ValueCount
;
3071 NtClose(MemberKeyHandle
);
3074 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3075 Status
= STATUS_SUCCESS
;
3077 LocalFree(MemberSidString
);
3080 if (MaxSidCount
== 0)
3082 Status
= STATUS_SUCCESS
;
3086 TRACE("Maximum sid count: %lu\n", MaxSidCount
);
3087 RidArray
= midl_user_allocate(MaxSidCount
* sizeof(ULONG
));
3088 if (RidArray
== NULL
)
3090 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3094 for (i
= 0; i
< SidArray
->Count
; i
++)
3096 ConvertSidToStringSid(SidArray
->Sids
[i
].SidPointer
, &MemberSidString
);
3097 TRACE("Open %S\n", MemberSidString
);
3099 Status
= SampRegOpenKey(MembersKeyHandle
,
3103 TRACE("SampRegOpenKey returned %08lX\n", Status
);
3104 if (NT_SUCCESS(Status
))
3106 Status
= SampRegQueryKeyInfo(MemberKeyHandle
,
3109 if (NT_SUCCESS(Status
))
3111 TRACE("Found %lu values\n", ValueCount
);
3113 for (j
= 0; j
< ValueCount
; j
++)
3115 DataLength
= 9 * sizeof(WCHAR
);
3116 Status
= SampRegEnumerateValue(MemberKeyHandle
,
3123 if (NT_SUCCESS(Status
))
3125 RidArray
[j
] = wcstoul(NameBuffer
, NULL
, 16);
3130 NtClose(MemberKeyHandle
);
3133 LocalFree(MemberSidString
);
3137 if (NT_SUCCESS(Status
))
3139 Membership
->Count
= MaxSidCount
;
3140 Membership
->Element
= RidArray
;
3144 if (RidArray
!= NULL
)
3145 midl_user_free(RidArray
);
3148 if (MembersKeyHandle
!= NULL
)
3149 NtClose(MembersKeyHandle
);
3151 if (MembersKeyHandle
!= NULL
)
3152 NtClose(MembersKeyHandle
);
3154 if (AliasesKeyHandle
!= NULL
)
3155 NtClose(AliasesKeyHandle
);
3164 SamrLookupNamesInDomain(IN SAMPR_HANDLE DomainHandle
,
3166 IN RPC_UNICODE_STRING Names
[],
3167 OUT PSAMPR_ULONG_ARRAY RelativeIds
,
3168 OUT PSAMPR_ULONG_ARRAY Use
)
3170 PSAM_DB_OBJECT DomainObject
;
3171 HANDLE AccountsKeyHandle
;
3172 HANDLE NamesKeyHandle
;
3173 ULONG MappedCount
= 0;
3179 TRACE("SamrLookupNamesInDomain(%p %lu %p %p %p)\n",
3180 DomainHandle
, Count
, Names
, RelativeIds
, Use
);
3182 /* Validate the domain handle */
3183 Status
= SampValidateDbObject(DomainHandle
,
3187 if (!NT_SUCCESS(Status
))
3189 TRACE("failed with status 0x%08lx\n", Status
);
3193 RelativeIds
->Count
= 0;
3197 return STATUS_SUCCESS
;
3199 /* Allocate the relative IDs array */
3200 RelativeIds
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
3201 if (RelativeIds
->Element
== NULL
)
3203 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3207 /* Allocate the use array */
3208 Use
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
3209 if (Use
->Element
== NULL
)
3211 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3215 RelativeIds
->Count
= Count
;
3218 for (i
= 0; i
< Count
; i
++)
3220 TRACE("Name: %S\n", Names
[i
].Buffer
);
3224 /* Lookup aliases */
3225 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3228 &AccountsKeyHandle
);
3229 if (NT_SUCCESS(Status
))
3231 Status
= SampRegOpenKey(AccountsKeyHandle
,
3235 if (NT_SUCCESS(Status
))
3237 DataLength
= sizeof(ULONG
);
3238 Status
= SampRegQueryValue(NamesKeyHandle
,
3244 SampRegCloseKey(NamesKeyHandle
);
3247 SampRegCloseKey(AccountsKeyHandle
);
3250 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3253 /* Return alias account */
3254 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
3256 TRACE("Rid: %lu\n", RelativeId
);
3257 RelativeIds
->Element
[i
] = RelativeId
;
3258 Use
->Element
[i
] = SidTypeAlias
;
3264 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3267 &AccountsKeyHandle
);
3268 if (NT_SUCCESS(Status
))
3270 Status
= SampRegOpenKey(AccountsKeyHandle
,
3274 if (NT_SUCCESS(Status
))
3276 DataLength
= sizeof(ULONG
);
3277 Status
= SampRegQueryValue(NamesKeyHandle
,
3283 SampRegCloseKey(NamesKeyHandle
);
3286 SampRegCloseKey(AccountsKeyHandle
);
3289 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3292 /* Return group account */
3293 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
3295 TRACE("Rid: %lu\n", RelativeId
);
3296 RelativeIds
->Element
[i
] = RelativeId
;
3297 Use
->Element
[i
] = SidTypeGroup
;
3303 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3306 &AccountsKeyHandle
);
3307 if (NT_SUCCESS(Status
))
3309 Status
= SampRegOpenKey(AccountsKeyHandle
,
3313 if (NT_SUCCESS(Status
))
3315 DataLength
= sizeof(ULONG
);
3316 Status
= SampRegQueryValue(NamesKeyHandle
,
3322 SampRegCloseKey(NamesKeyHandle
);
3325 SampRegCloseKey(AccountsKeyHandle
);
3328 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3331 /* Return user account */
3332 if (NT_SUCCESS(Status
) && RelativeId
!= 0)
3334 TRACE("Rid: %lu\n", RelativeId
);
3335 RelativeIds
->Element
[i
] = RelativeId
;
3336 Use
->Element
[i
] = SidTypeUser
;
3341 /* Return unknown account */
3342 RelativeIds
->Element
[i
] = 0;
3343 Use
->Element
[i
] = SidTypeUnknown
;
3347 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3348 Status
= STATUS_SUCCESS
;
3350 if (NT_SUCCESS(Status
))
3352 if (MappedCount
== 0)
3353 Status
= STATUS_NONE_MAPPED
;
3354 else if (MappedCount
< Count
)
3355 Status
= STATUS_SOME_NOT_MAPPED
;
3359 if (RelativeIds
->Element
!= NULL
)
3361 midl_user_free(RelativeIds
->Element
);
3362 RelativeIds
->Element
= NULL
;
3365 RelativeIds
->Count
= 0;
3367 if (Use
->Element
!= NULL
)
3369 midl_user_free(Use
->Element
);
3370 Use
->Element
= NULL
;
3376 TRACE("Returned Status %lx\n", Status
);
3385 SamrLookupIdsInDomain(IN SAMPR_HANDLE DomainHandle
,
3387 IN ULONG
*RelativeIds
,
3388 OUT PSAMPR_RETURNED_USTRING_ARRAY Names
,
3389 OUT PSAMPR_ULONG_ARRAY Use
)
3391 PSAM_DB_OBJECT DomainObject
;
3393 HANDLE AccountsKeyHandle
;
3394 HANDLE AccountKeyHandle
;
3395 ULONG MappedCount
= 0;
3400 TRACE("SamrLookupIdsInDomain(%p %lu %p %p %p)\n",
3401 DomainHandle
, Count
, RelativeIds
, Names
, Use
);
3403 /* Validate the domain handle */
3404 Status
= SampValidateDbObject(DomainHandle
,
3408 if (!NT_SUCCESS(Status
))
3410 TRACE("failed with status 0x%08lx\n", Status
);
3418 return STATUS_SUCCESS
;
3420 /* Allocate the names array */
3421 Names
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
3422 if (Names
->Element
== NULL
)
3424 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3428 /* Allocate the use array */
3429 Use
->Element
= midl_user_allocate(Count
* sizeof(ULONG
));
3430 if (Use
->Element
== NULL
)
3432 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3436 Names
->Count
= Count
;
3439 for (i
= 0; i
< Count
; i
++)
3441 TRACE("RID: %lu\n", RelativeIds
[i
]);
3443 swprintf(RidString
, L
"%08lx", RelativeIds
[i
]);
3445 /* Lookup aliases */
3446 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3449 &AccountsKeyHandle
);
3450 if (NT_SUCCESS(Status
))
3452 Status
= SampRegOpenKey(AccountsKeyHandle
,
3456 if (NT_SUCCESS(Status
))
3459 Status
= SampRegQueryValue(AccountKeyHandle
,
3464 if (NT_SUCCESS(Status
))
3466 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
3467 if (Names
->Element
[i
].Buffer
== NULL
)
3468 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3470 if (NT_SUCCESS(Status
))
3472 Names
->Element
[i
].MaximumLength
= (USHORT
)DataLength
;
3473 Names
->Element
[i
].Length
= (USHORT
)(DataLength
- sizeof(WCHAR
));
3475 Status
= SampRegQueryValue(AccountKeyHandle
,
3478 Names
->Element
[i
].Buffer
,
3483 SampRegCloseKey(AccountKeyHandle
);
3486 SampRegCloseKey(AccountsKeyHandle
);
3489 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3492 /* Return alias account */
3493 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
3495 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
3496 Use
->Element
[i
] = SidTypeAlias
;
3502 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3505 &AccountsKeyHandle
);
3506 if (NT_SUCCESS(Status
))
3508 Status
= SampRegOpenKey(AccountsKeyHandle
,
3512 if (NT_SUCCESS(Status
))
3515 Status
= SampRegQueryValue(AccountKeyHandle
,
3520 if (NT_SUCCESS(Status
))
3522 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
3523 if (Names
->Element
[i
].Buffer
== NULL
)
3524 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3526 if (NT_SUCCESS(Status
))
3528 Names
->Element
[i
].MaximumLength
= (USHORT
)DataLength
;
3529 Names
->Element
[i
].Length
= (USHORT
)(DataLength
- sizeof(WCHAR
));
3531 Status
= SampRegQueryValue(AccountKeyHandle
,
3534 Names
->Element
[i
].Buffer
,
3539 SampRegCloseKey(AccountKeyHandle
);
3542 SampRegCloseKey(AccountsKeyHandle
);
3545 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3548 /* Return group account */
3549 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
3551 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
3552 Use
->Element
[i
] = SidTypeGroup
;
3558 Status
= SampRegOpenKey(DomainObject
->KeyHandle
,
3561 &AccountsKeyHandle
);
3562 if (NT_SUCCESS(Status
))
3564 Status
= SampRegOpenKey(AccountsKeyHandle
,
3568 if (NT_SUCCESS(Status
))
3571 Status
= SampRegQueryValue(AccountKeyHandle
,
3576 if (NT_SUCCESS(Status
))
3578 TRACE("DataLength: %lu\n", DataLength
);
3580 Names
->Element
[i
].Buffer
= midl_user_allocate(DataLength
);
3581 if (Names
->Element
[i
].Buffer
== NULL
)
3582 Status
= STATUS_INSUFFICIENT_RESOURCES
;
3584 if (NT_SUCCESS(Status
))
3586 Names
->Element
[i
].MaximumLength
= (USHORT
)DataLength
;
3587 Names
->Element
[i
].Length
= (USHORT
)(DataLength
- sizeof(WCHAR
));
3589 Status
= SampRegQueryValue(AccountKeyHandle
,
3592 Names
->Element
[i
].Buffer
,
3597 SampRegCloseKey(AccountKeyHandle
);
3600 SampRegCloseKey(AccountsKeyHandle
);
3603 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3606 /* Return user account */
3607 if (NT_SUCCESS(Status
) && Names
->Element
[i
].Buffer
!= NULL
)
3609 TRACE("Name: %S\n", Names
->Element
[i
].Buffer
);
3610 Use
->Element
[i
] = SidTypeUser
;
3615 /* Return unknown account */
3616 Use
->Element
[i
] = SidTypeUnknown
;
3620 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3621 Status
= STATUS_SUCCESS
;
3623 if (NT_SUCCESS(Status
))
3625 if (MappedCount
== 0)
3626 Status
= STATUS_NONE_MAPPED
;
3627 else if (MappedCount
< Count
)
3628 Status
= STATUS_SOME_NOT_MAPPED
;
3632 if (Names
->Element
!= NULL
)
3634 for (i
= 0; i
< Count
; i
++)
3636 if (Names
->Element
[i
].Buffer
!= NULL
)
3637 midl_user_free(Names
->Element
[i
].Buffer
);
3640 midl_user_free(Names
->Element
);
3641 Names
->Element
= NULL
;
3646 if (Use
->Element
!= NULL
)
3648 midl_user_free(Use
->Element
);
3649 Use
->Element
= NULL
;
3662 SamrOpenGroup(IN SAMPR_HANDLE DomainHandle
,
3663 IN ACCESS_MASK DesiredAccess
,
3664 IN
unsigned long GroupId
,
3665 OUT SAMPR_HANDLE
*GroupHandle
)
3667 PSAM_DB_OBJECT DomainObject
;
3668 PSAM_DB_OBJECT GroupObject
;
3672 TRACE("SamrOpenGroup(%p %lx %lx %p)\n",
3673 DomainHandle
, DesiredAccess
, GroupId
, GroupHandle
);
3675 /* Map generic access rights */
3676 RtlMapGenericMask(&DesiredAccess
,
3679 /* Validate the domain handle */
3680 Status
= SampValidateDbObject(DomainHandle
,
3684 if (!NT_SUCCESS(Status
))
3686 TRACE("failed with status 0x%08lx\n", Status
);
3690 /* Convert the RID into a string (hex) */
3691 swprintf(szRid
, L
"%08lX", GroupId
);
3693 /* Create the group object */
3694 Status
= SampOpenDbObject(DomainObject
,
3701 if (!NT_SUCCESS(Status
))
3703 TRACE("failed with status 0x%08lx\n", Status
);
3707 *GroupHandle
= (SAMPR_HANDLE
)GroupObject
;
3709 return STATUS_SUCCESS
;
3714 SampQueryGroupGeneral(PSAM_DB_OBJECT GroupObject
,
3715 PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
3717 PSAMPR_GROUP_INFO_BUFFER InfoBuffer
= NULL
;
3718 SAM_GROUP_FIXED_DATA FixedData
;
3719 ULONG MembersLength
= 0;
3725 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_GROUP_INFO_BUFFER
));
3726 if (InfoBuffer
== NULL
)
3727 return STATUS_INSUFFICIENT_RESOURCES
;
3729 Status
= SampGetObjectAttributeString(GroupObject
,
3731 &InfoBuffer
->General
.Name
);
3732 if (!NT_SUCCESS(Status
))
3734 TRACE("Status 0x%08lx\n", Status
);
3738 Status
= SampGetObjectAttributeString(GroupObject
,
3740 &InfoBuffer
->General
.AdminComment
);
3741 if (!NT_SUCCESS(Status
))
3743 TRACE("Status 0x%08lx\n", Status
);
3747 Length
= sizeof(SAM_GROUP_FIXED_DATA
);
3748 Status
= SampGetObjectAttribute(GroupObject
,
3753 if (!NT_SUCCESS(Status
))
3756 InfoBuffer
->General
.Attributes
= FixedData
.Attributes
;
3758 Status
= SampGetObjectAttribute(GroupObject
,
3763 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_NOT_FOUND
)
3766 if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
3767 InfoBuffer
->General
.MemberCount
= 0;
3769 InfoBuffer
->General
.MemberCount
= MembersLength
/ sizeof(ULONG
);
3771 *Buffer
= InfoBuffer
;
3774 if (!NT_SUCCESS(Status
))
3776 if (InfoBuffer
!= NULL
)
3778 if (InfoBuffer
->General
.Name
.Buffer
!= NULL
)
3779 midl_user_free(InfoBuffer
->General
.Name
.Buffer
);
3781 if (InfoBuffer
->General
.AdminComment
.Buffer
!= NULL
)
3782 midl_user_free(InfoBuffer
->General
.AdminComment
.Buffer
);
3784 midl_user_free(InfoBuffer
);
3793 SampQueryGroupName(PSAM_DB_OBJECT GroupObject
,
3794 PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
3796 PSAMPR_GROUP_INFO_BUFFER InfoBuffer
= NULL
;
3801 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_GROUP_INFO_BUFFER
));
3802 if (InfoBuffer
== NULL
)
3803 return STATUS_INSUFFICIENT_RESOURCES
;
3805 Status
= SampGetObjectAttributeString(GroupObject
,
3807 &InfoBuffer
->Name
.Name
);
3808 if (!NT_SUCCESS(Status
))
3810 TRACE("Status 0x%08lx\n", Status
);
3814 *Buffer
= InfoBuffer
;
3817 if (!NT_SUCCESS(Status
))
3819 if (InfoBuffer
!= NULL
)
3821 if (InfoBuffer
->Name
.Name
.Buffer
!= NULL
)
3822 midl_user_free(InfoBuffer
->Name
.Name
.Buffer
);
3824 midl_user_free(InfoBuffer
);
3833 SampQueryGroupAttribute(PSAM_DB_OBJECT GroupObject
,
3834 PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
3836 PSAMPR_GROUP_INFO_BUFFER InfoBuffer
= NULL
;
3837 SAM_GROUP_FIXED_DATA FixedData
;
3843 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_GROUP_INFO_BUFFER
));
3844 if (InfoBuffer
== NULL
)
3845 return STATUS_INSUFFICIENT_RESOURCES
;
3847 Length
= sizeof(SAM_GROUP_FIXED_DATA
);
3848 Status
= SampGetObjectAttribute(GroupObject
,
3853 if (!NT_SUCCESS(Status
))
3856 InfoBuffer
->Attribute
.Attributes
= FixedData
.Attributes
;
3858 *Buffer
= InfoBuffer
;
3861 if (!NT_SUCCESS(Status
))
3863 if (InfoBuffer
!= NULL
)
3865 midl_user_free(InfoBuffer
);
3874 SampQueryGroupAdminComment(PSAM_DB_OBJECT GroupObject
,
3875 PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
3877 PSAMPR_GROUP_INFO_BUFFER InfoBuffer
= NULL
;
3882 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_GROUP_INFO_BUFFER
));
3883 if (InfoBuffer
== NULL
)
3884 return STATUS_INSUFFICIENT_RESOURCES
;
3886 Status
= SampGetObjectAttributeString(GroupObject
,
3888 &InfoBuffer
->AdminComment
.AdminComment
);
3889 if (!NT_SUCCESS(Status
))
3891 TRACE("Status 0x%08lx\n", Status
);
3895 *Buffer
= InfoBuffer
;
3898 if (!NT_SUCCESS(Status
))
3900 if (InfoBuffer
!= NULL
)
3902 if (InfoBuffer
->AdminComment
.AdminComment
.Buffer
!= NULL
)
3903 midl_user_free(InfoBuffer
->AdminComment
.AdminComment
.Buffer
);
3905 midl_user_free(InfoBuffer
);
3916 SamrQueryInformationGroup(IN SAMPR_HANDLE GroupHandle
,
3917 IN GROUP_INFORMATION_CLASS GroupInformationClass
,
3918 OUT PSAMPR_GROUP_INFO_BUFFER
*Buffer
)
3920 PSAM_DB_OBJECT GroupObject
;
3923 TRACE("SamrQueryInformationGroup(%p %lu %p)\n",
3924 GroupHandle
, GroupInformationClass
, Buffer
);
3926 /* Validate the group handle */
3927 Status
= SampValidateDbObject(GroupHandle
,
3929 GROUP_READ_INFORMATION
,
3931 if (!NT_SUCCESS(Status
))
3934 switch (GroupInformationClass
)
3936 case GroupGeneralInformation
:
3937 Status
= SampQueryGroupGeneral(GroupObject
,
3941 case GroupNameInformation
:
3942 Status
= SampQueryGroupName(GroupObject
,
3946 case GroupAttributeInformation
:
3947 Status
= SampQueryGroupAttribute(GroupObject
,
3951 case GroupAdminCommentInformation
:
3952 Status
= SampQueryGroupAdminComment(GroupObject
,
3957 Status
= STATUS_INVALID_INFO_CLASS
;
3966 SampSetGroupName(PSAM_DB_OBJECT GroupObject
,
3967 PSAMPR_GROUP_INFO_BUFFER Buffer
)
3969 UNICODE_STRING OldGroupName
= {0, 0, NULL
};
3970 UNICODE_STRING NewGroupName
;
3973 Status
= SampGetObjectAttributeString(GroupObject
,
3975 (PRPC_UNICODE_STRING
)&OldGroupName
);
3976 if (!NT_SUCCESS(Status
))
3978 TRACE("SampGetObjectAttributeString failed (Status 0x%08lx)\n", Status
);
3982 NewGroupName
.Length
= Buffer
->Name
.Name
.Length
;
3983 NewGroupName
.MaximumLength
= Buffer
->Name
.Name
.MaximumLength
;
3984 NewGroupName
.Buffer
= Buffer
->Name
.Name
.Buffer
;
3986 if (!RtlEqualUnicodeString(&OldGroupName
, &NewGroupName
, TRUE
))
3988 Status
= SampCheckAccountNameInDomain(GroupObject
->ParentObject
,
3989 NewGroupName
.Buffer
);
3990 if (!NT_SUCCESS(Status
))
3992 TRACE("Group name \'%S\' already exists in domain (Status 0x%08lx)\n",
3993 NewGroupName
.Buffer
, Status
);
3998 Status
= SampSetAccountNameInDomain(GroupObject
->ParentObject
,
4000 NewGroupName
.Buffer
,
4001 GroupObject
->RelativeId
);
4002 if (!NT_SUCCESS(Status
))
4004 TRACE("SampSetAccountNameInDomain failed (Status 0x%08lx)\n", Status
);
4008 Status
= SampRemoveAccountNameFromDomain(GroupObject
->ParentObject
,
4010 OldGroupName
.Buffer
);
4011 if (!NT_SUCCESS(Status
))
4013 TRACE("SampRemoveAccountNameFromDomain failed (Status 0x%08lx)\n", Status
);
4017 Status
= SampSetObjectAttribute(GroupObject
,
4020 NewGroupName
.Buffer
,
4021 NewGroupName
.Length
+ sizeof(WCHAR
));
4022 if (!NT_SUCCESS(Status
))
4024 TRACE("SampSetObjectAttribute failed (Status 0x%08lx)\n", Status
);
4028 if (OldGroupName
.Buffer
!= NULL
)
4029 midl_user_free(OldGroupName
.Buffer
);
4036 SampSetGroupAttribute(PSAM_DB_OBJECT GroupObject
,
4037 PSAMPR_GROUP_INFO_BUFFER Buffer
)
4039 SAM_GROUP_FIXED_DATA FixedData
;
4043 Length
= sizeof(SAM_GROUP_FIXED_DATA
);
4044 Status
= SampGetObjectAttribute(GroupObject
,
4049 if (!NT_SUCCESS(Status
))
4052 FixedData
.Attributes
= Buffer
->Attribute
.Attributes
;
4054 Status
= SampSetObjectAttribute(GroupObject
,
4068 SamrSetInformationGroup(IN SAMPR_HANDLE GroupHandle
,
4069 IN GROUP_INFORMATION_CLASS GroupInformationClass
,
4070 IN PSAMPR_GROUP_INFO_BUFFER Buffer
)
4072 PSAM_DB_OBJECT GroupObject
;
4075 TRACE("SamrSetInformationGroup(%p %lu %p)\n",
4076 GroupHandle
, GroupInformationClass
, Buffer
);
4078 /* Validate the group handle */
4079 Status
= SampValidateDbObject(GroupHandle
,
4081 GROUP_WRITE_ACCOUNT
,
4083 if (!NT_SUCCESS(Status
))
4086 switch (GroupInformationClass
)
4088 case GroupNameInformation
:
4089 Status
= SampSetGroupName(GroupObject
,
4093 case GroupAttributeInformation
:
4094 Status
= SampSetGroupAttribute(GroupObject
,
4098 case GroupAdminCommentInformation
:
4099 Status
= SampSetObjectAttribute(GroupObject
,
4102 Buffer
->AdminComment
.AdminComment
.Buffer
,
4103 Buffer
->AdminComment
.AdminComment
.Length
+ sizeof(WCHAR
));
4107 Status
= STATUS_INVALID_INFO_CLASS
;
4118 SamrAddMemberToGroup(IN SAMPR_HANDLE GroupHandle
,
4119 IN
unsigned long MemberId
,
4120 IN
unsigned long Attributes
)
4122 PSAM_DB_OBJECT GroupObject
;
4123 PSAM_DB_OBJECT UserObject
= NULL
;
4126 TRACE("(%p %lu %lx)\n",
4127 GroupHandle
, MemberId
, Attributes
);
4129 /* Validate the group handle */
4130 Status
= SampValidateDbObject(GroupHandle
,
4134 if (!NT_SUCCESS(Status
))
4137 /* Open the user object in the same domain */
4138 Status
= SampOpenUserObject(GroupObject
->ParentObject
,
4142 if (!NT_SUCCESS(Status
))
4144 TRACE("SampOpenUserObject() failed (Status 0x%08lx)\n", Status
);
4148 /* Add group membership to the user object */
4149 Status
= SampAddGroupMembershipToUser(UserObject
,
4150 GroupObject
->RelativeId
,
4152 if (!NT_SUCCESS(Status
))
4154 TRACE("SampAddGroupMembershipToUser() failed (Status 0x%08lx)\n", Status
);
4158 /* Add the member to the group object */
4159 Status
= SampAddMemberToGroup(GroupObject
,
4161 if (!NT_SUCCESS(Status
))
4163 TRACE("SampAddMemberToGroup() failed (Status 0x%08lx)\n", Status
);
4168 SampCloseDbObject(UserObject
);
4177 SamrDeleteGroup(IN OUT SAMPR_HANDLE
*GroupHandle
)
4179 PSAM_DB_OBJECT GroupObject
;
4183 TRACE("(%p)\n", GroupHandle
);
4185 /* Validate the group handle */
4186 Status
= SampValidateDbObject(*GroupHandle
,
4190 if (!NT_SUCCESS(Status
))
4192 TRACE("SampValidateDbObject() failed (Status 0x%08lx)\n", Status
);
4196 /* Fail, if the group is built-in */
4197 if (GroupObject
->RelativeId
< 1000)
4199 TRACE("You can not delete a special account!\n");
4200 return STATUS_SPECIAL_ACCOUNT
;
4203 /* Get the length of the Members attribute */
4204 SampGetObjectAttribute(GroupObject
,
4210 /* Fail, if the group has members */
4213 TRACE("There are still members in the group!\n");
4214 return STATUS_MEMBER_IN_GROUP
;
4217 /* FIXME: Remove the group from all aliases */
4219 /* Delete the group from the database */
4220 Status
= SampDeleteAccountDbObject(GroupObject
);
4221 if (!NT_SUCCESS(Status
))
4223 TRACE("SampDeleteAccountDbObject() failed (Status 0x%08lx)\n", Status
);
4227 /* Invalidate the handle */
4228 *GroupHandle
= NULL
;
4230 return STATUS_SUCCESS
;
4237 SamrRemoveMemberFromGroup(IN SAMPR_HANDLE GroupHandle
,
4238 IN
unsigned long MemberId
)
4240 PSAM_DB_OBJECT GroupObject
;
4241 PSAM_DB_OBJECT UserObject
= NULL
;
4245 GroupHandle
, MemberId
);
4247 /* Validate the group handle */
4248 Status
= SampValidateDbObject(GroupHandle
,
4250 GROUP_REMOVE_MEMBER
,
4252 if (!NT_SUCCESS(Status
))
4255 /* Open the user object in the same domain */
4256 Status
= SampOpenUserObject(GroupObject
->ParentObject
,
4260 if (!NT_SUCCESS(Status
))
4262 ERR("SampOpenUserObject() failed (Status 0x%08lx)\n", Status
);
4266 /* Remove group membership from the user object */
4267 Status
= SampRemoveGroupMembershipFromUser(UserObject
,
4268 GroupObject
->RelativeId
);
4269 if (!NT_SUCCESS(Status
))
4271 ERR("SampAddGroupMembershipToUser() failed (Status 0x%08lx)\n", Status
);
4275 /* Remove the member from the group object */
4276 Status
= SampRemoveMemberFromGroup(GroupObject
,
4278 if (!NT_SUCCESS(Status
))
4280 ERR("SampRemoveMemberFromGroup() failed (Status 0x%08lx)\n", Status
);
4285 SampCloseDbObject(UserObject
);
4294 SamrGetMembersInGroup(IN SAMPR_HANDLE GroupHandle
,
4295 OUT PSAMPR_GET_MEMBERS_BUFFER
*Members
)
4297 PSAMPR_GET_MEMBERS_BUFFER MembersBuffer
= NULL
;
4298 PSAM_DB_OBJECT GroupObject
;
4303 /* Validate the group handle */
4304 Status
= SampValidateDbObject(GroupHandle
,
4308 if (!NT_SUCCESS(Status
))
4311 MembersBuffer
= midl_user_allocate(sizeof(SAMPR_GET_MEMBERS_BUFFER
));
4312 if (MembersBuffer
== NULL
)
4313 return STATUS_INSUFFICIENT_RESOURCES
;
4315 SampGetObjectAttribute(GroupObject
,
4323 MembersBuffer
->MemberCount
= 0;
4324 MembersBuffer
->Members
= NULL
;
4325 MembersBuffer
->Attributes
= NULL
;
4327 *Members
= MembersBuffer
;
4329 return STATUS_SUCCESS
;
4332 MembersBuffer
->Members
= midl_user_allocate(Length
);
4333 if (MembersBuffer
->Members
== NULL
)
4335 Status
= STATUS_INSUFFICIENT_RESOURCES
;
4339 MembersBuffer
->Attributes
= midl_user_allocate(Length
);
4340 if (MembersBuffer
->Attributes
== NULL
)
4342 Status
= STATUS_INSUFFICIENT_RESOURCES
;
4346 Status
= SampGetObjectAttribute(GroupObject
,
4349 MembersBuffer
->Members
,
4351 if (!NT_SUCCESS(Status
))
4353 TRACE("SampGetObjectAttributes() failed (Status 0x%08lx)\n", Status
);
4357 MembersBuffer
->MemberCount
= Length
/ sizeof(ULONG
);
4359 for (i
= 0; i
< MembersBuffer
->MemberCount
; i
++)
4361 Status
= SampGetUserGroupAttributes(GroupObject
->ParentObject
,
4362 MembersBuffer
->Members
[i
],
4363 GroupObject
->RelativeId
,
4364 &(MembersBuffer
->Attributes
[i
]));
4365 if (!NT_SUCCESS(Status
))
4367 TRACE("SampGetUserGroupAttributes() failed (Status 0x%08lx)\n", Status
);
4372 *Members
= MembersBuffer
;
4375 if (!NT_SUCCESS(Status
))
4377 if (MembersBuffer
!= NULL
)
4379 if (MembersBuffer
->Members
!= NULL
)
4380 midl_user_free(MembersBuffer
->Members
);
4382 if (MembersBuffer
->Attributes
!= NULL
)
4383 midl_user_free(MembersBuffer
->Attributes
);
4385 midl_user_free(MembersBuffer
);
4396 SamrSetMemberAttributesOfGroup(IN SAMPR_HANDLE GroupHandle
,
4397 IN
unsigned long MemberId
,
4398 IN
unsigned long Attributes
)
4400 PSAM_DB_OBJECT GroupObject
;
4403 /* Validate the group handle */
4404 Status
= SampValidateDbObject(GroupHandle
,
4408 if (!NT_SUCCESS(Status
))
4410 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
4414 Status
= SampSetUserGroupAttributes(GroupObject
->ParentObject
,
4416 GroupObject
->RelativeId
,
4418 if (!NT_SUCCESS(Status
))
4420 TRACE("SampSetUserGroupAttributes failed with status 0x%08lx\n", Status
);
4430 SamrOpenAlias(IN SAMPR_HANDLE DomainHandle
,
4431 IN ACCESS_MASK DesiredAccess
,
4433 OUT SAMPR_HANDLE
*AliasHandle
)
4435 PSAM_DB_OBJECT DomainObject
;
4436 PSAM_DB_OBJECT AliasObject
;
4440 TRACE("SamrOpenAlias(%p %lx %lx %p)\n",
4441 DomainHandle
, DesiredAccess
, AliasId
, AliasHandle
);
4443 /* Map generic access rights */
4444 RtlMapGenericMask(&DesiredAccess
,
4447 /* Validate the domain handle */
4448 Status
= SampValidateDbObject(DomainHandle
,
4452 if (!NT_SUCCESS(Status
))
4454 TRACE("failed with status 0x%08lx\n", Status
);
4458 /* Convert the RID into a string (hex) */
4459 swprintf(szRid
, L
"%08lX", AliasId
);
4461 /* Create the alias object */
4462 Status
= SampOpenDbObject(DomainObject
,
4469 if (!NT_SUCCESS(Status
))
4471 TRACE("failed with status 0x%08lx\n", Status
);
4475 *AliasHandle
= (SAMPR_HANDLE
)AliasObject
;
4477 return STATUS_SUCCESS
;
4482 SampQueryAliasGeneral(PSAM_DB_OBJECT AliasObject
,
4483 PSAMPR_ALIAS_INFO_BUFFER
*Buffer
)
4485 PSAMPR_ALIAS_INFO_BUFFER InfoBuffer
= NULL
;
4486 HANDLE MembersKeyHandle
= NULL
;
4491 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_ALIAS_INFO_BUFFER
));
4492 if (InfoBuffer
== NULL
)
4493 return STATUS_INSUFFICIENT_RESOURCES
;
4495 Status
= SampGetObjectAttributeString(AliasObject
,
4497 &InfoBuffer
->General
.Name
);
4498 if (!NT_SUCCESS(Status
))
4500 TRACE("Status 0x%08lx\n", Status
);
4504 Status
= SampGetObjectAttributeString(AliasObject
,
4506 &InfoBuffer
->General
.AdminComment
);
4507 if (!NT_SUCCESS(Status
))
4509 TRACE("Status 0x%08lx\n", Status
);
4513 /* Open the Members subkey */
4514 Status
= SampRegOpenKey(AliasObject
->KeyHandle
,
4518 if (NT_SUCCESS(Status
))
4520 /* Retrieve the number of members of the alias */
4521 Status
= SampRegQueryKeyInfo(MembersKeyHandle
,
4523 &InfoBuffer
->General
.MemberCount
);
4524 if (!NT_SUCCESS(Status
))
4526 TRACE("Status 0x%08lx\n", Status
);
4530 else if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
4532 InfoBuffer
->General
.MemberCount
= 0;
4533 Status
= STATUS_SUCCESS
;
4537 TRACE("Status 0x%08lx\n", Status
);
4541 *Buffer
= InfoBuffer
;
4544 if (MembersKeyHandle
!= NULL
)
4545 SampRegCloseKey(MembersKeyHandle
);
4547 if (!NT_SUCCESS(Status
))
4549 if (InfoBuffer
!= NULL
)
4551 if (InfoBuffer
->General
.Name
.Buffer
!= NULL
)
4552 midl_user_free(InfoBuffer
->General
.Name
.Buffer
);
4554 if (InfoBuffer
->General
.AdminComment
.Buffer
!= NULL
)
4555 midl_user_free(InfoBuffer
->General
.AdminComment
.Buffer
);
4557 midl_user_free(InfoBuffer
);
4566 SampQueryAliasName(PSAM_DB_OBJECT AliasObject
,
4567 PSAMPR_ALIAS_INFO_BUFFER
*Buffer
)
4569 PSAMPR_ALIAS_INFO_BUFFER InfoBuffer
= NULL
;
4574 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_ALIAS_INFO_BUFFER
));
4575 if (InfoBuffer
== NULL
)
4576 return STATUS_INSUFFICIENT_RESOURCES
;
4578 Status
= SampGetObjectAttributeString(AliasObject
,
4580 &InfoBuffer
->Name
.Name
);
4581 if (!NT_SUCCESS(Status
))
4583 TRACE("Status 0x%08lx\n", Status
);
4587 *Buffer
= InfoBuffer
;
4590 if (!NT_SUCCESS(Status
))
4592 if (InfoBuffer
!= NULL
)
4594 if (InfoBuffer
->Name
.Name
.Buffer
!= NULL
)
4595 midl_user_free(InfoBuffer
->Name
.Name
.Buffer
);
4597 midl_user_free(InfoBuffer
);
4606 SampQueryAliasAdminComment(PSAM_DB_OBJECT AliasObject
,
4607 PSAMPR_ALIAS_INFO_BUFFER
*Buffer
)
4609 PSAMPR_ALIAS_INFO_BUFFER InfoBuffer
= NULL
;
4614 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_ALIAS_INFO_BUFFER
));
4615 if (InfoBuffer
== NULL
)
4616 return STATUS_INSUFFICIENT_RESOURCES
;
4618 Status
= SampGetObjectAttributeString(AliasObject
,
4620 &InfoBuffer
->AdminComment
.AdminComment
);
4621 if (!NT_SUCCESS(Status
))
4623 TRACE("Status 0x%08lx\n", Status
);
4627 *Buffer
= InfoBuffer
;
4630 if (!NT_SUCCESS(Status
))
4632 if (InfoBuffer
!= NULL
)
4634 if (InfoBuffer
->AdminComment
.AdminComment
.Buffer
!= NULL
)
4635 midl_user_free(InfoBuffer
->AdminComment
.AdminComment
.Buffer
);
4637 midl_user_free(InfoBuffer
);
4648 SamrQueryInformationAlias(IN SAMPR_HANDLE AliasHandle
,
4649 IN ALIAS_INFORMATION_CLASS AliasInformationClass
,
4650 OUT PSAMPR_ALIAS_INFO_BUFFER
*Buffer
)
4652 PSAM_DB_OBJECT AliasObject
;
4655 TRACE("SamrQueryInformationAlias(%p %lu %p)\n",
4656 AliasHandle
, AliasInformationClass
, Buffer
);
4658 /* Validate the alias handle */
4659 Status
= SampValidateDbObject(AliasHandle
,
4661 ALIAS_READ_INFORMATION
,
4663 if (!NT_SUCCESS(Status
))
4666 switch (AliasInformationClass
)
4668 case AliasGeneralInformation
:
4669 Status
= SampQueryAliasGeneral(AliasObject
,
4673 case AliasNameInformation
:
4674 Status
= SampQueryAliasName(AliasObject
,
4678 case AliasAdminCommentInformation
:
4679 Status
= SampQueryAliasAdminComment(AliasObject
,
4684 Status
= STATUS_INVALID_INFO_CLASS
;
4693 SampSetAliasName(PSAM_DB_OBJECT AliasObject
,
4694 PSAMPR_ALIAS_INFO_BUFFER Buffer
)
4696 UNICODE_STRING OldAliasName
= {0, 0, NULL
};
4697 UNICODE_STRING NewAliasName
;
4700 Status
= SampGetObjectAttributeString(AliasObject
,
4702 (PRPC_UNICODE_STRING
)&OldAliasName
);
4703 if (!NT_SUCCESS(Status
))
4705 TRACE("SampGetObjectAttributeString failed (Status 0x%08lx)\n", Status
);
4709 NewAliasName
.Length
= Buffer
->Name
.Name
.Length
;
4710 NewAliasName
.MaximumLength
= Buffer
->Name
.Name
.MaximumLength
;
4711 NewAliasName
.Buffer
= Buffer
->Name
.Name
.Buffer
;
4713 if (!RtlEqualUnicodeString(&OldAliasName
, &NewAliasName
, TRUE
))
4715 Status
= SampCheckAccountNameInDomain(AliasObject
->ParentObject
,
4716 NewAliasName
.Buffer
);
4717 if (!NT_SUCCESS(Status
))
4719 TRACE("Alias name \'%S\' already exists in domain (Status 0x%08lx)\n",
4720 NewAliasName
.Buffer
, Status
);
4725 Status
= SampSetAccountNameInDomain(AliasObject
->ParentObject
,
4727 NewAliasName
.Buffer
,
4728 AliasObject
->RelativeId
);
4729 if (!NT_SUCCESS(Status
))
4731 TRACE("SampSetAccountNameInDomain failed (Status 0x%08lx)\n", Status
);
4735 Status
= SampRemoveAccountNameFromDomain(AliasObject
->ParentObject
,
4737 OldAliasName
.Buffer
);
4738 if (!NT_SUCCESS(Status
))
4740 TRACE("SampRemoveAccountNameFromDomain failed (Status 0x%08lx)\n", Status
);
4744 Status
= SampSetObjectAttribute(AliasObject
,
4747 NewAliasName
.Buffer
,
4748 NewAliasName
.Length
+ sizeof(WCHAR
));
4749 if (!NT_SUCCESS(Status
))
4751 TRACE("SampSetObjectAttribute failed (Status 0x%08lx)\n", Status
);
4755 if (OldAliasName
.Buffer
!= NULL
)
4756 midl_user_free(OldAliasName
.Buffer
);
4765 SamrSetInformationAlias(IN SAMPR_HANDLE AliasHandle
,
4766 IN ALIAS_INFORMATION_CLASS AliasInformationClass
,
4767 IN PSAMPR_ALIAS_INFO_BUFFER Buffer
)
4769 PSAM_DB_OBJECT AliasObject
;
4772 TRACE("SamrSetInformationAlias(%p %lu %p)\n",
4773 AliasHandle
, AliasInformationClass
, Buffer
);
4775 /* Validate the alias handle */
4776 Status
= SampValidateDbObject(AliasHandle
,
4778 ALIAS_WRITE_ACCOUNT
,
4780 if (!NT_SUCCESS(Status
))
4783 switch (AliasInformationClass
)
4785 case AliasNameInformation
:
4786 Status
= SampSetAliasName(AliasObject
,
4790 case AliasAdminCommentInformation
:
4791 Status
= SampSetObjectAttribute(AliasObject
,
4794 Buffer
->AdminComment
.AdminComment
.Buffer
,
4795 Buffer
->AdminComment
.AdminComment
.Length
+ sizeof(WCHAR
));
4799 Status
= STATUS_INVALID_INFO_CLASS
;
4810 SamrDeleteAlias(IN OUT SAMPR_HANDLE
*AliasHandle
)
4812 PSAM_DB_OBJECT AliasObject
;
4815 /* Validate the alias handle */
4816 Status
= SampValidateDbObject(*AliasHandle
,
4820 if (!NT_SUCCESS(Status
))
4822 TRACE("SampValidateDbObject failed (Status 0x%08lx)\n", Status
);
4826 /* Fail, if the alias is built-in */
4827 if (AliasObject
->RelativeId
< 1000)
4829 TRACE("You can not delete a special account!\n");
4830 return STATUS_SPECIAL_ACCOUNT
;
4833 /* FIXME: Remove all members from the alias */
4835 /* Delete the alias from the database */
4836 Status
= SampDeleteAccountDbObject(AliasObject
);
4837 if (!NT_SUCCESS(Status
))
4839 TRACE("SampDeleteAccountDbObject() failed (Status 0x%08lx)\n", Status
);
4843 /* Invalidate the handle */
4844 *AliasHandle
= NULL
;
4853 SamrAddMemberToAlias(IN SAMPR_HANDLE AliasHandle
,
4854 IN PRPC_SID MemberId
)
4856 PSAM_DB_OBJECT AliasObject
;
4859 TRACE("(%p %p)\n", AliasHandle
, MemberId
);
4861 /* Validate the alias handle */
4862 Status
= SampValidateDbObject(AliasHandle
,
4866 if (!NT_SUCCESS(Status
))
4868 TRACE("failed with status 0x%08lx\n", Status
);
4872 Status
= SampAddMemberToAlias(AliasObject
,
4874 if (!NT_SUCCESS(Status
))
4876 TRACE("failed with status 0x%08lx\n", Status
);
4886 SamrRemoveMemberFromAlias(IN SAMPR_HANDLE AliasHandle
,
4887 IN PRPC_SID MemberId
)
4889 PSAM_DB_OBJECT AliasObject
;
4892 TRACE("(%p %p)\n", AliasHandle
, MemberId
);
4894 /* Validate the alias handle */
4895 Status
= SampValidateDbObject(AliasHandle
,
4897 ALIAS_REMOVE_MEMBER
,
4899 if (!NT_SUCCESS(Status
))
4901 TRACE("failed with status 0x%08lx\n", Status
);
4905 Status
= SampRemoveMemberFromAlias(AliasObject
,
4907 if (!NT_SUCCESS(Status
))
4909 TRACE("failed with status 0x%08lx\n", Status
);
4919 SamrGetMembersInAlias(IN SAMPR_HANDLE AliasHandle
,
4920 OUT PSAMPR_PSID_ARRAY_OUT Members
)
4922 PSAM_DB_OBJECT AliasObject
;
4923 HANDLE MembersKeyHandle
= NULL
;
4924 PSAMPR_SID_INFORMATION MemberArray
= NULL
;
4925 ULONG ValueCount
= 0;
4930 TRACE("SamrGetMembersInAlias(%p %p %p)\n",
4931 AliasHandle
, Members
);
4933 /* Validate the alias handle */
4934 Status
= SampValidateDbObject(AliasHandle
,
4938 if (!NT_SUCCESS(Status
))
4940 ERR("failed with status 0x%08lx\n", Status
);
4944 /* Open the members key of the alias objct */
4945 Status
= SampRegOpenKey(AliasObject
->KeyHandle
,
4949 if (!NT_SUCCESS(Status
))
4951 ERR("SampRegOpenKey failed with status 0x%08lx\n", Status
);
4955 /* Get the number of members */
4956 Status
= SampRegQueryKeyInfo(MembersKeyHandle
,
4959 if (!NT_SUCCESS(Status
))
4961 ERR("SampRegQueryKeyInfo failed with status 0x%08lx\n", Status
);
4965 /* Allocate the member array */
4966 MemberArray
= midl_user_allocate(ValueCount
* sizeof(SAMPR_SID_INFORMATION
));
4967 if (MemberArray
== NULL
)
4969 Status
= STATUS_INSUFFICIENT_RESOURCES
;
4973 /* Enumerate the members */
4977 /* Get the size of the next SID */
4979 Status
= SampRegEnumerateValue(MembersKeyHandle
,
4986 if (!NT_SUCCESS(Status
))
4988 if (Status
== STATUS_NO_MORE_ENTRIES
)
4989 Status
= STATUS_SUCCESS
;
4993 /* Allocate a buffer for the SID */
4994 MemberArray
[Index
].SidPointer
= midl_user_allocate(DataLength
);
4995 if (MemberArray
[Index
].SidPointer
== NULL
)
4997 Status
= STATUS_INSUFFICIENT_RESOURCES
;
5001 /* Read the SID into the buffer */
5002 Status
= SampRegEnumerateValue(MembersKeyHandle
,
5007 (PVOID
)MemberArray
[Index
].SidPointer
,
5009 if (!NT_SUCCESS(Status
))
5017 /* Return the number of members and the member array */
5018 if (NT_SUCCESS(Status
))
5020 Members
->Count
= ValueCount
;
5021 Members
->Sids
= MemberArray
;
5025 /* Clean up the members array and the SID buffers if something failed */
5026 if (!NT_SUCCESS(Status
))
5028 if (MemberArray
!= NULL
)
5030 for (Index
= 0; Index
< ValueCount
; Index
++)
5032 if (MemberArray
[Index
].SidPointer
!= NULL
)
5033 midl_user_free(MemberArray
[Index
].SidPointer
);
5036 midl_user_free(MemberArray
);
5040 /* Close the members key */
5041 if (MembersKeyHandle
!= NULL
)
5042 SampRegCloseKey(MembersKeyHandle
);
5051 SamrOpenUser(IN SAMPR_HANDLE DomainHandle
,
5052 IN ACCESS_MASK DesiredAccess
,
5053 IN
unsigned long UserId
,
5054 OUT SAMPR_HANDLE
*UserHandle
)
5056 PSAM_DB_OBJECT DomainObject
;
5057 PSAM_DB_OBJECT UserObject
;
5061 TRACE("SamrOpenUser(%p %lx %lx %p)\n",
5062 DomainHandle
, DesiredAccess
, UserId
, UserHandle
);
5064 /* Map generic access rights */
5065 RtlMapGenericMask(&DesiredAccess
,
5068 /* Validate the domain handle */
5069 Status
= SampValidateDbObject(DomainHandle
,
5073 if (!NT_SUCCESS(Status
))
5075 TRACE("failed with status 0x%08lx\n", Status
);
5079 /* Convert the RID into a string (hex) */
5080 swprintf(szRid
, L
"%08lX", UserId
);
5082 /* Create the user object */
5083 Status
= SampOpenDbObject(DomainObject
,
5090 if (!NT_SUCCESS(Status
))
5092 TRACE("failed with status 0x%08lx\n", Status
);
5096 *UserHandle
= (SAMPR_HANDLE
)UserObject
;
5098 return STATUS_SUCCESS
;
5105 SamrDeleteUser(IN OUT SAMPR_HANDLE
*UserHandle
)
5107 PSAM_DB_OBJECT UserObject
;
5110 TRACE("(%p)\n", UserHandle
);
5112 /* Validate the user handle */
5113 Status
= SampValidateDbObject(*UserHandle
,
5117 if (!NT_SUCCESS(Status
))
5119 TRACE("SampValidateDbObject() failed (Status 0x%08lx)\n", Status
);
5123 /* Fail, if the user is built-in */
5124 if (UserObject
->RelativeId
< 1000)
5126 TRACE("You can not delete a special account!\n");
5127 return STATUS_SPECIAL_ACCOUNT
;
5130 /* FIXME: Remove the user from all groups */
5132 /* FIXME: Remove the user from all aliases */
5134 /* Delete the user from the database */
5135 Status
= SampDeleteAccountDbObject(UserObject
);
5136 if (!NT_SUCCESS(Status
))
5138 TRACE("SampDeleteAccountDbObject() failed (Status 0x%08lx)\n", Status
);
5142 /* Invalidate the handle */
5145 return STATUS_SUCCESS
;
5151 SampQueryUserGeneral(PSAM_DB_OBJECT UserObject
,
5152 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5154 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5155 SAM_USER_FIXED_DATA FixedData
;
5161 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5162 if (InfoBuffer
== NULL
)
5163 return STATUS_INSUFFICIENT_RESOURCES
;
5165 Length
= sizeof(SAM_USER_FIXED_DATA
);
5166 Status
= SampGetObjectAttribute(UserObject
,
5171 if (!NT_SUCCESS(Status
))
5174 InfoBuffer
->General
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
5176 /* Get the Name string */
5177 Status
= SampGetObjectAttributeString(UserObject
,
5179 &InfoBuffer
->General
.UserName
);
5180 if (!NT_SUCCESS(Status
))
5182 TRACE("Status 0x%08lx\n", Status
);
5186 /* Get the FullName string */
5187 Status
= SampGetObjectAttributeString(UserObject
,
5189 &InfoBuffer
->General
.FullName
);
5190 if (!NT_SUCCESS(Status
))
5192 TRACE("Status 0x%08lx\n", Status
);
5196 /* Get the AdminComment string */
5197 Status
= SampGetObjectAttributeString(UserObject
,
5199 &InfoBuffer
->General
.AdminComment
);
5200 if (!NT_SUCCESS(Status
))
5202 TRACE("Status 0x%08lx\n", Status
);
5206 /* Get the UserComment string */
5207 Status
= SampGetObjectAttributeString(UserObject
,
5209 &InfoBuffer
->General
.UserComment
);
5210 if (!NT_SUCCESS(Status
))
5212 TRACE("Status 0x%08lx\n", Status
);
5216 *Buffer
= InfoBuffer
;
5219 if (!NT_SUCCESS(Status
))
5221 if (InfoBuffer
!= NULL
)
5223 if (InfoBuffer
->General
.UserName
.Buffer
!= NULL
)
5224 midl_user_free(InfoBuffer
->General
.UserName
.Buffer
);
5226 if (InfoBuffer
->General
.FullName
.Buffer
!= NULL
)
5227 midl_user_free(InfoBuffer
->General
.FullName
.Buffer
);
5229 if (InfoBuffer
->General
.AdminComment
.Buffer
!= NULL
)
5230 midl_user_free(InfoBuffer
->General
.AdminComment
.Buffer
);
5232 if (InfoBuffer
->General
.UserComment
.Buffer
!= NULL
)
5233 midl_user_free(InfoBuffer
->General
.UserComment
.Buffer
);
5235 midl_user_free(InfoBuffer
);
5245 SampQueryUserPreferences(PSAM_DB_OBJECT UserObject
,
5246 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5248 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5249 SAM_USER_FIXED_DATA FixedData
;
5255 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5256 if (InfoBuffer
== NULL
)
5257 return STATUS_INSUFFICIENT_RESOURCES
;
5259 Length
= sizeof(SAM_USER_FIXED_DATA
);
5260 Status
= SampGetObjectAttribute(UserObject
,
5265 if (!NT_SUCCESS(Status
))
5268 InfoBuffer
->Preferences
.CountryCode
= FixedData
.CountryCode
;
5269 InfoBuffer
->Preferences
.CodePage
= FixedData
.CodePage
;
5271 /* Get the UserComment string */
5272 Status
= SampGetObjectAttributeString(UserObject
,
5274 &InfoBuffer
->Preferences
.UserComment
);
5275 if (!NT_SUCCESS(Status
))
5277 TRACE("Status 0x%08lx\n", Status
);
5281 *Buffer
= InfoBuffer
;
5284 if (!NT_SUCCESS(Status
))
5286 if (InfoBuffer
!= NULL
)
5288 if (InfoBuffer
->Preferences
.UserComment
.Buffer
!= NULL
)
5289 midl_user_free(InfoBuffer
->Preferences
.UserComment
.Buffer
);
5291 midl_user_free(InfoBuffer
);
5301 SampQueryUserLogon(PSAM_DB_OBJECT UserObject
,
5302 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5304 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5305 SAM_DOMAIN_FIXED_DATA DomainFixedData
;
5306 SAM_USER_FIXED_DATA FixedData
;
5307 LARGE_INTEGER PasswordCanChange
;
5308 LARGE_INTEGER PasswordMustChange
;
5314 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5315 if (InfoBuffer
== NULL
)
5316 return STATUS_INSUFFICIENT_RESOURCES
;
5318 /* Get the fixed size domain data */
5319 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
5320 Status
= SampGetObjectAttribute(UserObject
->ParentObject
,
5323 (PVOID
)&DomainFixedData
,
5325 if (!NT_SUCCESS(Status
))
5328 /* Get the fixed size user data */
5329 Length
= sizeof(SAM_USER_FIXED_DATA
);
5330 Status
= SampGetObjectAttribute(UserObject
,
5335 if (!NT_SUCCESS(Status
))
5338 InfoBuffer
->Logon
.UserId
= FixedData
.UserId
;
5339 InfoBuffer
->Logon
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
5340 InfoBuffer
->Logon
.LastLogon
.LowPart
= FixedData
.LastLogon
.LowPart
;
5341 InfoBuffer
->Logon
.LastLogon
.HighPart
= FixedData
.LastLogon
.HighPart
;
5342 InfoBuffer
->Logon
.LastLogoff
.LowPart
= FixedData
.LastLogoff
.LowPart
;
5343 InfoBuffer
->Logon
.LastLogoff
.HighPart
= FixedData
.LastLogoff
.HighPart
;
5344 InfoBuffer
->Logon
.PasswordLastSet
.LowPart
= FixedData
.PasswordLastSet
.LowPart
;
5345 InfoBuffer
->Logon
.PasswordLastSet
.HighPart
= FixedData
.PasswordLastSet
.HighPart
;
5346 InfoBuffer
->Logon
.BadPasswordCount
= FixedData
.BadPasswordCount
;
5347 InfoBuffer
->Logon
.LogonCount
= FixedData
.LogonCount
;
5348 InfoBuffer
->Logon
.UserAccountControl
= FixedData
.UserAccountControl
;
5350 PasswordCanChange
= SampAddRelativeTimeToTime(FixedData
.PasswordLastSet
,
5351 DomainFixedData
.MinPasswordAge
);
5352 InfoBuffer
->Logon
.PasswordCanChange
.LowPart
= PasswordCanChange
.LowPart
;
5353 InfoBuffer
->Logon
.PasswordCanChange
.HighPart
= PasswordCanChange
.HighPart
;
5355 PasswordMustChange
= SampAddRelativeTimeToTime(FixedData
.PasswordLastSet
,
5356 DomainFixedData
.MaxPasswordAge
);
5357 InfoBuffer
->Logon
.PasswordMustChange
.LowPart
= PasswordMustChange
.LowPart
;
5358 InfoBuffer
->Logon
.PasswordMustChange
.HighPart
= PasswordMustChange
.HighPart
;
5360 /* Get the Name string */
5361 Status
= SampGetObjectAttributeString(UserObject
,
5363 &InfoBuffer
->Logon
.UserName
);
5364 if (!NT_SUCCESS(Status
))
5366 TRACE("Status 0x%08lx\n", Status
);
5370 /* Get the FullName string */
5371 Status
= SampGetObjectAttributeString(UserObject
,
5373 &InfoBuffer
->Logon
.FullName
);
5374 if (!NT_SUCCESS(Status
))
5376 TRACE("Status 0x%08lx\n", Status
);
5380 /* Get the HomeDirectory string */
5381 Status
= SampGetObjectAttributeString(UserObject
,
5383 &InfoBuffer
->Logon
.HomeDirectory
);
5384 if (!NT_SUCCESS(Status
))
5386 TRACE("Status 0x%08lx\n", Status
);
5390 /* Get the HomeDirectoryDrive string */
5391 Status
= SampGetObjectAttributeString(UserObject
,
5392 L
"HomeDirectoryDrive",
5393 &InfoBuffer
->Logon
.HomeDirectoryDrive
);
5394 if (!NT_SUCCESS(Status
))
5396 TRACE("Status 0x%08lx\n", Status
);
5400 /* Get the ScriptPath string */
5401 Status
= SampGetObjectAttributeString(UserObject
,
5403 &InfoBuffer
->Logon
.ScriptPath
);
5404 if (!NT_SUCCESS(Status
))
5406 TRACE("Status 0x%08lx\n", Status
);
5410 /* Get the ProfilePath string */
5411 Status
= SampGetObjectAttributeString(UserObject
,
5413 &InfoBuffer
->Logon
.ProfilePath
);
5414 if (!NT_SUCCESS(Status
))
5416 TRACE("Status 0x%08lx\n", Status
);
5420 /* Get the WorkStations string */
5421 Status
= SampGetObjectAttributeString(UserObject
,
5423 &InfoBuffer
->Logon
.WorkStations
);
5424 if (!NT_SUCCESS(Status
))
5426 TRACE("Status 0x%08lx\n", Status
);
5430 /* Get the LogonHours attribute */
5431 Status
= SampGetLogonHoursAttrbute(UserObject
,
5432 &InfoBuffer
->Logon
.LogonHours
);
5433 if (!NT_SUCCESS(Status
))
5435 TRACE("Status 0x%08lx\n", Status
);
5439 *Buffer
= InfoBuffer
;
5442 if (!NT_SUCCESS(Status
))
5444 if (InfoBuffer
!= NULL
)
5446 if (InfoBuffer
->Logon
.UserName
.Buffer
!= NULL
)
5447 midl_user_free(InfoBuffer
->Logon
.UserName
.Buffer
);
5449 if (InfoBuffer
->Logon
.FullName
.Buffer
!= NULL
)
5450 midl_user_free(InfoBuffer
->Logon
.FullName
.Buffer
);
5452 if (InfoBuffer
->Logon
.HomeDirectory
.Buffer
!= NULL
)
5453 midl_user_free(InfoBuffer
->Logon
.HomeDirectory
.Buffer
);
5455 if (InfoBuffer
->Logon
.HomeDirectoryDrive
.Buffer
!= NULL
)
5456 midl_user_free(InfoBuffer
->Logon
.HomeDirectoryDrive
.Buffer
);
5458 if (InfoBuffer
->Logon
.ScriptPath
.Buffer
!= NULL
)
5459 midl_user_free(InfoBuffer
->Logon
.ScriptPath
.Buffer
);
5461 if (InfoBuffer
->Logon
.ProfilePath
.Buffer
!= NULL
)
5462 midl_user_free(InfoBuffer
->Logon
.ProfilePath
.Buffer
);
5464 if (InfoBuffer
->Logon
.WorkStations
.Buffer
!= NULL
)
5465 midl_user_free(InfoBuffer
->Logon
.WorkStations
.Buffer
);
5467 if (InfoBuffer
->Logon
.LogonHours
.LogonHours
!= NULL
)
5468 midl_user_free(InfoBuffer
->Logon
.LogonHours
.LogonHours
);
5470 midl_user_free(InfoBuffer
);
5480 SampQueryUserAccount(PSAM_DB_OBJECT UserObject
,
5481 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5483 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5484 SAM_USER_FIXED_DATA FixedData
;
5490 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5491 if (InfoBuffer
== NULL
)
5492 return STATUS_INSUFFICIENT_RESOURCES
;
5494 Length
= sizeof(SAM_USER_FIXED_DATA
);
5495 Status
= SampGetObjectAttribute(UserObject
,
5500 if (!NT_SUCCESS(Status
))
5503 InfoBuffer
->Account
.UserId
= FixedData
.UserId
;
5504 InfoBuffer
->Account
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
5505 InfoBuffer
->Account
.LastLogon
.LowPart
= FixedData
.LastLogon
.LowPart
;
5506 InfoBuffer
->Account
.LastLogon
.HighPart
= FixedData
.LastLogon
.HighPart
;
5507 InfoBuffer
->Account
.LastLogoff
.LowPart
= FixedData
.LastLogoff
.LowPart
;
5508 InfoBuffer
->Account
.LastLogoff
.HighPart
= FixedData
.LastLogoff
.HighPart
;
5509 InfoBuffer
->Account
.PasswordLastSet
.LowPart
= FixedData
.PasswordLastSet
.LowPart
;
5510 InfoBuffer
->Account
.PasswordLastSet
.HighPart
= FixedData
.PasswordLastSet
.HighPart
;
5511 InfoBuffer
->Account
.AccountExpires
.LowPart
= FixedData
.AccountExpires
.LowPart
;
5512 InfoBuffer
->Account
.AccountExpires
.HighPart
= FixedData
.AccountExpires
.HighPart
;
5513 InfoBuffer
->Account
.BadPasswordCount
= FixedData
.BadPasswordCount
;
5514 InfoBuffer
->Account
.LogonCount
= FixedData
.LogonCount
;
5515 InfoBuffer
->Account
.UserAccountControl
= FixedData
.UserAccountControl
;
5517 /* Get the Name string */
5518 Status
= SampGetObjectAttributeString(UserObject
,
5520 &InfoBuffer
->Account
.UserName
);
5521 if (!NT_SUCCESS(Status
))
5523 TRACE("Status 0x%08lx\n", Status
);
5527 /* Get the FullName string */
5528 Status
= SampGetObjectAttributeString(UserObject
,
5530 &InfoBuffer
->Account
.FullName
);
5531 if (!NT_SUCCESS(Status
))
5533 TRACE("Status 0x%08lx\n", Status
);
5537 /* Get the HomeDirectory string */
5538 Status
= SampGetObjectAttributeString(UserObject
,
5540 &InfoBuffer
->Account
.HomeDirectory
);
5541 if (!NT_SUCCESS(Status
))
5543 TRACE("Status 0x%08lx\n", Status
);
5547 /* Get the HomeDirectoryDrive string */
5548 Status
= SampGetObjectAttributeString(UserObject
,
5549 L
"HomeDirectoryDrive",
5550 &InfoBuffer
->Account
.HomeDirectoryDrive
);
5551 if (!NT_SUCCESS(Status
))
5553 TRACE("Status 0x%08lx\n", Status
);
5557 /* Get the ScriptPath string */
5558 Status
= SampGetObjectAttributeString(UserObject
,
5560 &InfoBuffer
->Account
.ScriptPath
);
5561 if (!NT_SUCCESS(Status
))
5563 TRACE("Status 0x%08lx\n", Status
);
5567 /* Get the ProfilePath string */
5568 Status
= SampGetObjectAttributeString(UserObject
,
5570 &InfoBuffer
->Account
.ProfilePath
);
5571 if (!NT_SUCCESS(Status
))
5573 TRACE("Status 0x%08lx\n", Status
);
5577 /* Get the AdminComment string */
5578 Status
= SampGetObjectAttributeString(UserObject
,
5580 &InfoBuffer
->Account
.AdminComment
);
5581 if (!NT_SUCCESS(Status
))
5583 TRACE("Status 0x%08lx\n", Status
);
5587 /* Get the WorkStations string */
5588 Status
= SampGetObjectAttributeString(UserObject
,
5590 &InfoBuffer
->Account
.WorkStations
);
5591 if (!NT_SUCCESS(Status
))
5593 TRACE("Status 0x%08lx\n", Status
);
5597 /* Get the LogonHours attribute */
5598 Status
= SampGetLogonHoursAttrbute(UserObject
,
5599 &InfoBuffer
->Account
.LogonHours
);
5600 if (!NT_SUCCESS(Status
))
5602 TRACE("Status 0x%08lx\n", Status
);
5606 *Buffer
= InfoBuffer
;
5609 if (!NT_SUCCESS(Status
))
5611 if (InfoBuffer
!= NULL
)
5613 if (InfoBuffer
->Account
.UserName
.Buffer
!= NULL
)
5614 midl_user_free(InfoBuffer
->Account
.UserName
.Buffer
);
5616 if (InfoBuffer
->Account
.FullName
.Buffer
!= NULL
)
5617 midl_user_free(InfoBuffer
->Account
.FullName
.Buffer
);
5619 if (InfoBuffer
->Account
.HomeDirectory
.Buffer
!= NULL
)
5620 midl_user_free(InfoBuffer
->Account
.HomeDirectory
.Buffer
);
5622 if (InfoBuffer
->Account
.HomeDirectoryDrive
.Buffer
!= NULL
)
5623 midl_user_free(InfoBuffer
->Account
.HomeDirectoryDrive
.Buffer
);
5625 if (InfoBuffer
->Account
.ScriptPath
.Buffer
!= NULL
)
5626 midl_user_free(InfoBuffer
->Account
.ScriptPath
.Buffer
);
5628 if (InfoBuffer
->Account
.ProfilePath
.Buffer
!= NULL
)
5629 midl_user_free(InfoBuffer
->Account
.ProfilePath
.Buffer
);
5631 if (InfoBuffer
->Account
.AdminComment
.Buffer
!= NULL
)
5632 midl_user_free(InfoBuffer
->Account
.AdminComment
.Buffer
);
5634 if (InfoBuffer
->Account
.WorkStations
.Buffer
!= NULL
)
5635 midl_user_free(InfoBuffer
->Account
.WorkStations
.Buffer
);
5637 if (InfoBuffer
->Account
.LogonHours
.LogonHours
!= NULL
)
5638 midl_user_free(InfoBuffer
->Account
.LogonHours
.LogonHours
);
5640 midl_user_free(InfoBuffer
);
5650 SampQueryUserLogonHours(PSAM_DB_OBJECT UserObject
,
5651 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5653 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5656 TRACE("(%p %p)\n", UserObject
, Buffer
);
5660 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5661 if (InfoBuffer
== NULL
)
5663 TRACE("Failed to allocate InfoBuffer!\n");
5664 return STATUS_INSUFFICIENT_RESOURCES
;
5667 Status
= SampGetLogonHoursAttrbute(UserObject
,
5668 &InfoBuffer
->LogonHours
.LogonHours
);
5669 if (!NT_SUCCESS(Status
))
5671 TRACE("SampGetLogonHoursAttrbute failed (Status 0x%08lx)\n", Status
);
5675 *Buffer
= InfoBuffer
;
5678 if (!NT_SUCCESS(Status
))
5680 if (InfoBuffer
!= NULL
)
5682 if (InfoBuffer
->LogonHours
.LogonHours
.LogonHours
!= NULL
)
5683 midl_user_free(InfoBuffer
->LogonHours
.LogonHours
.LogonHours
);
5685 midl_user_free(InfoBuffer
);
5695 SampQueryUserName(PSAM_DB_OBJECT UserObject
,
5696 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5698 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5703 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5704 if (InfoBuffer
== NULL
)
5705 return STATUS_INSUFFICIENT_RESOURCES
;
5707 /* Get the Name string */
5708 Status
= SampGetObjectAttributeString(UserObject
,
5710 &InfoBuffer
->Name
.UserName
);
5711 if (!NT_SUCCESS(Status
))
5713 TRACE("Status 0x%08lx\n", Status
);
5717 /* Get the FullName string */
5718 Status
= SampGetObjectAttributeString(UserObject
,
5720 &InfoBuffer
->Name
.FullName
);
5721 if (!NT_SUCCESS(Status
))
5723 TRACE("Status 0x%08lx\n", Status
);
5727 *Buffer
= InfoBuffer
;
5730 if (!NT_SUCCESS(Status
))
5732 if (InfoBuffer
!= NULL
)
5734 if (InfoBuffer
->Name
.UserName
.Buffer
!= NULL
)
5735 midl_user_free(InfoBuffer
->Name
.UserName
.Buffer
);
5737 if (InfoBuffer
->Name
.FullName
.Buffer
!= NULL
)
5738 midl_user_free(InfoBuffer
->Name
.FullName
.Buffer
);
5740 midl_user_free(InfoBuffer
);
5749 SampQueryUserAccountName(PSAM_DB_OBJECT UserObject
,
5750 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5752 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5757 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5758 if (InfoBuffer
== NULL
)
5759 return STATUS_INSUFFICIENT_RESOURCES
;
5761 /* Get the Name string */
5762 Status
= SampGetObjectAttributeString(UserObject
,
5764 &InfoBuffer
->AccountName
.UserName
);
5765 if (!NT_SUCCESS(Status
))
5767 TRACE("Status 0x%08lx\n", Status
);
5771 *Buffer
= InfoBuffer
;
5774 if (!NT_SUCCESS(Status
))
5776 if (InfoBuffer
!= NULL
)
5778 if (InfoBuffer
->AccountName
.UserName
.Buffer
!= NULL
)
5779 midl_user_free(InfoBuffer
->AccountName
.UserName
.Buffer
);
5781 midl_user_free(InfoBuffer
);
5790 SampQueryUserFullName(PSAM_DB_OBJECT UserObject
,
5791 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5793 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5798 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5799 if (InfoBuffer
== NULL
)
5800 return STATUS_INSUFFICIENT_RESOURCES
;
5802 /* Get the FullName string */
5803 Status
= SampGetObjectAttributeString(UserObject
,
5805 &InfoBuffer
->FullName
.FullName
);
5806 if (!NT_SUCCESS(Status
))
5808 TRACE("Status 0x%08lx\n", Status
);
5812 *Buffer
= InfoBuffer
;
5815 if (!NT_SUCCESS(Status
))
5817 if (InfoBuffer
!= NULL
)
5819 if (InfoBuffer
->FullName
.FullName
.Buffer
!= NULL
)
5820 midl_user_free(InfoBuffer
->FullName
.FullName
.Buffer
);
5822 midl_user_free(InfoBuffer
);
5832 SampQueryUserPrimaryGroup(PSAM_DB_OBJECT UserObject
,
5833 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5835 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5836 SAM_USER_FIXED_DATA FixedData
;
5842 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5843 if (InfoBuffer
== NULL
)
5844 return STATUS_INSUFFICIENT_RESOURCES
;
5846 Length
= sizeof(SAM_USER_FIXED_DATA
);
5847 Status
= SampGetObjectAttribute(UserObject
,
5852 if (!NT_SUCCESS(Status
))
5855 InfoBuffer
->PrimaryGroup
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
5857 *Buffer
= InfoBuffer
;
5860 if (!NT_SUCCESS(Status
))
5862 if (InfoBuffer
!= NULL
)
5864 midl_user_free(InfoBuffer
);
5873 SampQueryUserHome(PSAM_DB_OBJECT UserObject
,
5874 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5876 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5881 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5882 if (InfoBuffer
== NULL
)
5883 return STATUS_INSUFFICIENT_RESOURCES
;
5885 /* Get the HomeDirectory string */
5886 Status
= SampGetObjectAttributeString(UserObject
,
5888 &InfoBuffer
->Home
.HomeDirectory
);
5889 if (!NT_SUCCESS(Status
))
5891 TRACE("Status 0x%08lx\n", Status
);
5895 /* Get the HomeDirectoryDrive string */
5896 Status
= SampGetObjectAttributeString(UserObject
,
5897 L
"HomeDirectoryDrive",
5898 &InfoBuffer
->Home
.HomeDirectoryDrive
);
5899 if (!NT_SUCCESS(Status
))
5901 TRACE("Status 0x%08lx\n", Status
);
5905 *Buffer
= InfoBuffer
;
5908 if (!NT_SUCCESS(Status
))
5910 if (InfoBuffer
!= NULL
)
5912 if (InfoBuffer
->Home
.HomeDirectory
.Buffer
!= NULL
)
5913 midl_user_free(InfoBuffer
->Home
.HomeDirectory
.Buffer
);
5915 if (InfoBuffer
->Home
.HomeDirectoryDrive
.Buffer
!= NULL
)
5916 midl_user_free(InfoBuffer
->Home
.HomeDirectoryDrive
.Buffer
);
5918 midl_user_free(InfoBuffer
);
5927 SampQueryUserScript(PSAM_DB_OBJECT UserObject
,
5928 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5930 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5935 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5936 if (InfoBuffer
== NULL
)
5937 return STATUS_INSUFFICIENT_RESOURCES
;
5939 /* Get the ScriptPath string */
5940 Status
= SampGetObjectAttributeString(UserObject
,
5942 &InfoBuffer
->Script
.ScriptPath
);
5943 if (!NT_SUCCESS(Status
))
5945 TRACE("Status 0x%08lx\n", Status
);
5949 *Buffer
= InfoBuffer
;
5952 if (!NT_SUCCESS(Status
))
5954 if (InfoBuffer
!= NULL
)
5956 if (InfoBuffer
->Script
.ScriptPath
.Buffer
!= NULL
)
5957 midl_user_free(InfoBuffer
->Script
.ScriptPath
.Buffer
);
5959 midl_user_free(InfoBuffer
);
5968 SampQueryUserProfile(PSAM_DB_OBJECT UserObject
,
5969 PSAMPR_USER_INFO_BUFFER
*Buffer
)
5971 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
5976 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
5977 if (InfoBuffer
== NULL
)
5978 return STATUS_INSUFFICIENT_RESOURCES
;
5980 /* Get the ProfilePath string */
5981 Status
= SampGetObjectAttributeString(UserObject
,
5983 &InfoBuffer
->Profile
.ProfilePath
);
5984 if (!NT_SUCCESS(Status
))
5986 TRACE("Status 0x%08lx\n", Status
);
5990 *Buffer
= InfoBuffer
;
5993 if (!NT_SUCCESS(Status
))
5995 if (InfoBuffer
!= NULL
)
5997 if (InfoBuffer
->Profile
.ProfilePath
.Buffer
!= NULL
)
5998 midl_user_free(InfoBuffer
->Profile
.ProfilePath
.Buffer
);
6000 midl_user_free(InfoBuffer
);
6009 SampQueryUserAdminComment(PSAM_DB_OBJECT UserObject
,
6010 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6012 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6017 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6018 if (InfoBuffer
== NULL
)
6019 return STATUS_INSUFFICIENT_RESOURCES
;
6021 /* Get the AdminComment string */
6022 Status
= SampGetObjectAttributeString(UserObject
,
6024 &InfoBuffer
->AdminComment
.AdminComment
);
6025 if (!NT_SUCCESS(Status
))
6027 TRACE("Status 0x%08lx\n", Status
);
6031 *Buffer
= InfoBuffer
;
6034 if (!NT_SUCCESS(Status
))
6036 if (InfoBuffer
!= NULL
)
6038 if (InfoBuffer
->AdminComment
.AdminComment
.Buffer
!= NULL
)
6039 midl_user_free(InfoBuffer
->AdminComment
.AdminComment
.Buffer
);
6041 midl_user_free(InfoBuffer
);
6050 SampQueryUserWorkStations(PSAM_DB_OBJECT UserObject
,
6051 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6053 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6058 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6059 if (InfoBuffer
== NULL
)
6060 return STATUS_INSUFFICIENT_RESOURCES
;
6062 /* Get the WorkStations string */
6063 Status
= SampGetObjectAttributeString(UserObject
,
6065 &InfoBuffer
->WorkStations
.WorkStations
);
6066 if (!NT_SUCCESS(Status
))
6068 TRACE("Status 0x%08lx\n", Status
);
6072 *Buffer
= InfoBuffer
;
6075 if (!NT_SUCCESS(Status
))
6077 if (InfoBuffer
!= NULL
)
6079 if (InfoBuffer
->WorkStations
.WorkStations
.Buffer
!= NULL
)
6080 midl_user_free(InfoBuffer
->WorkStations
.WorkStations
.Buffer
);
6082 midl_user_free(InfoBuffer
);
6092 SampQueryUserControl(PSAM_DB_OBJECT UserObject
,
6093 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6095 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6096 SAM_USER_FIXED_DATA FixedData
;
6102 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6103 if (InfoBuffer
== NULL
)
6104 return STATUS_INSUFFICIENT_RESOURCES
;
6106 Length
= sizeof(SAM_USER_FIXED_DATA
);
6107 Status
= SampGetObjectAttribute(UserObject
,
6112 if (!NT_SUCCESS(Status
))
6115 InfoBuffer
->Control
.UserAccountControl
= FixedData
.UserAccountControl
;
6117 *Buffer
= InfoBuffer
;
6120 if (!NT_SUCCESS(Status
))
6122 if (InfoBuffer
!= NULL
)
6124 midl_user_free(InfoBuffer
);
6134 SampQueryUserExpires(PSAM_DB_OBJECT UserObject
,
6135 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6137 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6138 SAM_USER_FIXED_DATA FixedData
;
6144 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6145 if (InfoBuffer
== NULL
)
6146 return STATUS_INSUFFICIENT_RESOURCES
;
6148 Length
= sizeof(SAM_USER_FIXED_DATA
);
6149 Status
= SampGetObjectAttribute(UserObject
,
6154 if (!NT_SUCCESS(Status
))
6157 InfoBuffer
->Expires
.AccountExpires
.LowPart
= FixedData
.AccountExpires
.LowPart
;
6158 InfoBuffer
->Expires
.AccountExpires
.HighPart
= FixedData
.AccountExpires
.HighPart
;
6160 *Buffer
= InfoBuffer
;
6163 if (!NT_SUCCESS(Status
))
6165 if (InfoBuffer
!= NULL
)
6167 midl_user_free(InfoBuffer
);
6177 SampQueryUserInternal1(PSAM_DB_OBJECT UserObject
,
6178 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6180 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6182 NTSTATUS Status
= STATUS_SUCCESS
;
6184 /* Fail, if the caller is not a trusted caller */
6185 if (UserObject
->Trusted
== FALSE
)
6186 return STATUS_INVALID_INFO_CLASS
;
6190 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6191 if (InfoBuffer
== NULL
)
6192 return STATUS_INSUFFICIENT_RESOURCES
;
6194 /* Get the NT password */
6196 SampGetObjectAttribute(UserObject
,
6202 if (Length
== sizeof(ENCRYPTED_NT_OWF_PASSWORD
))
6204 Status
= SampGetObjectAttribute(UserObject
,
6207 (PVOID
)&InfoBuffer
->Internal1
.EncryptedNtOwfPassword
,
6209 if (!NT_SUCCESS(Status
))
6213 InfoBuffer
->Internal1
.NtPasswordPresent
= (Length
== sizeof(ENCRYPTED_NT_OWF_PASSWORD
));
6215 /* Get the LM password */
6217 SampGetObjectAttribute(UserObject
,
6223 if (Length
== sizeof(ENCRYPTED_LM_OWF_PASSWORD
))
6225 Status
= SampGetObjectAttribute(UserObject
,
6228 (PVOID
)&InfoBuffer
->Internal1
.EncryptedLmOwfPassword
,
6230 if (!NT_SUCCESS(Status
))
6234 InfoBuffer
->Internal1
.LmPasswordPresent
= (Length
== sizeof(ENCRYPTED_LM_OWF_PASSWORD
));
6236 InfoBuffer
->Internal1
.PasswordExpired
= FALSE
;
6238 *Buffer
= InfoBuffer
;
6241 if (!NT_SUCCESS(Status
))
6243 if (InfoBuffer
!= NULL
)
6245 midl_user_free(InfoBuffer
);
6254 SampQueryUserParameters(PSAM_DB_OBJECT UserObject
,
6255 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6257 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6262 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6263 if (InfoBuffer
== NULL
)
6264 return STATUS_INSUFFICIENT_RESOURCES
;
6266 /* Get the Parameters string */
6267 Status
= SampGetObjectAttributeString(UserObject
,
6269 &InfoBuffer
->Parameters
.Parameters
);
6270 if (!NT_SUCCESS(Status
))
6272 TRACE("Status 0x%08lx\n", Status
);
6276 *Buffer
= InfoBuffer
;
6279 if (!NT_SUCCESS(Status
))
6281 if (InfoBuffer
!= NULL
)
6283 if (InfoBuffer
->Parameters
.Parameters
.Buffer
!= NULL
)
6284 midl_user_free(InfoBuffer
->Parameters
.Parameters
.Buffer
);
6286 midl_user_free(InfoBuffer
);
6295 SampQueryUserAll(PSAM_DB_OBJECT UserObject
,
6296 PSAMPR_USER_INFO_BUFFER
*Buffer
)
6298 PSAMPR_USER_INFO_BUFFER InfoBuffer
= NULL
;
6299 SAM_DOMAIN_FIXED_DATA DomainFixedData
;
6300 SAM_USER_FIXED_DATA FixedData
;
6301 LARGE_INTEGER PasswordCanChange
;
6302 LARGE_INTEGER PasswordMustChange
;
6308 InfoBuffer
= midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER
));
6309 if (InfoBuffer
== NULL
)
6310 return STATUS_INSUFFICIENT_RESOURCES
;
6312 /* Get the fixed size domain data */
6313 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
6314 Status
= SampGetObjectAttribute(UserObject
->ParentObject
,
6317 (PVOID
)&DomainFixedData
,
6319 if (!NT_SUCCESS(Status
))
6322 /* Get the fixed size user data */
6323 Length
= sizeof(SAM_USER_FIXED_DATA
);
6324 Status
= SampGetObjectAttribute(UserObject
,
6329 if (!NT_SUCCESS(Status
))
6332 if (UserObject
->Access
& USER_READ_GENERAL
)
6334 /* Get the Name string */
6335 Status
= SampGetObjectAttributeString(UserObject
,
6337 &InfoBuffer
->All
.UserName
);
6338 if (!NT_SUCCESS(Status
))
6340 TRACE("Status 0x%08lx\n", Status
);
6344 /* Get the FullName string */
6345 Status
= SampGetObjectAttributeString(UserObject
,
6347 &InfoBuffer
->All
.FullName
);
6348 if (!NT_SUCCESS(Status
))
6350 TRACE("Status 0x%08lx\n", Status
);
6354 /* Get the user ID*/
6355 InfoBuffer
->All
.UserId
= FixedData
.UserId
;
6357 /* Get the primary group ID */
6358 InfoBuffer
->All
.PrimaryGroupId
= FixedData
.PrimaryGroupId
;
6360 /* Get the AdminComment string */
6361 Status
= SampGetObjectAttributeString(UserObject
,
6363 &InfoBuffer
->All
.AdminComment
);
6364 if (!NT_SUCCESS(Status
))
6366 TRACE("Status 0x%08lx\n", Status
);
6370 /* Get the UserComment string */
6371 Status
= SampGetObjectAttributeString(UserObject
,
6373 &InfoBuffer
->All
.UserComment
);
6374 if (!NT_SUCCESS(Status
))
6376 TRACE("Status 0x%08lx\n", Status
);
6380 InfoBuffer
->All
.WhichFields
|= USER_ALL_READ_GENERAL_MASK
;
6381 // USER_ALL_USERNAME |
6382 // USER_ALL_FULLNAME |
6383 // USER_ALL_USERID |
6384 // USER_ALL_PRIMARYGROUPID |
6385 // USER_ALL_ADMINCOMMENT |
6386 // USER_ALL_USERCOMMENT;
6389 if (UserObject
->Access
& USER_READ_LOGON
)
6391 /* Get the HomeDirectory string */
6392 Status
= SampGetObjectAttributeString(UserObject
,
6394 &InfoBuffer
->All
.HomeDirectory
);
6395 if (!NT_SUCCESS(Status
))
6397 TRACE("Status 0x%08lx\n", Status
);
6401 /* Get the HomeDirectoryDrive string */
6402 Status
= SampGetObjectAttributeString(UserObject
,
6403 L
"HomeDirectoryDrive",
6404 &InfoBuffer
->Home
.HomeDirectoryDrive
);
6405 if (!NT_SUCCESS(Status
))
6407 TRACE("Status 0x%08lx\n", Status
);
6411 /* Get the ScriptPath string */
6412 Status
= SampGetObjectAttributeString(UserObject
,
6414 &InfoBuffer
->All
.ScriptPath
);
6415 if (!NT_SUCCESS(Status
))
6417 TRACE("Status 0x%08lx\n", Status
);
6421 /* Get the ProfilePath string */
6422 Status
= SampGetObjectAttributeString(UserObject
,
6424 &InfoBuffer
->All
.ProfilePath
);
6425 if (!NT_SUCCESS(Status
))
6427 TRACE("Status 0x%08lx\n", Status
);
6431 /* Get the WorkStations string */
6432 Status
= SampGetObjectAttributeString(UserObject
,
6434 &InfoBuffer
->All
.WorkStations
);
6435 if (!NT_SUCCESS(Status
))
6437 TRACE("Status 0x%08lx\n", Status
);
6441 /* Get the LogonHours attribute */
6442 Status
= SampGetLogonHoursAttrbute(UserObject
,
6443 &InfoBuffer
->All
.LogonHours
);
6444 if (!NT_SUCCESS(Status
))
6446 TRACE("Status 0x%08lx\n", Status
);
6450 InfoBuffer
->All
.LastLogon
.LowPart
= FixedData
.LastLogon
.LowPart
;
6451 InfoBuffer
->All
.LastLogon
.HighPart
= FixedData
.LastLogon
.HighPart
;
6453 InfoBuffer
->All
.LastLogoff
.LowPart
= FixedData
.LastLogoff
.LowPart
;
6454 InfoBuffer
->All
.LastLogoff
.HighPart
= FixedData
.LastLogoff
.HighPart
;
6456 InfoBuffer
->All
.BadPasswordCount
= FixedData
.BadPasswordCount
;
6458 InfoBuffer
->All
.LogonCount
= FixedData
.LogonCount
;
6460 PasswordCanChange
= SampAddRelativeTimeToTime(FixedData
.PasswordLastSet
,
6461 DomainFixedData
.MinPasswordAge
);
6462 InfoBuffer
->All
.PasswordCanChange
.LowPart
= PasswordCanChange
.LowPart
;
6463 InfoBuffer
->All
.PasswordCanChange
.HighPart
= PasswordCanChange
.HighPart
;
6465 PasswordMustChange
= SampAddRelativeTimeToTime(FixedData
.PasswordLastSet
,
6466 DomainFixedData
.MaxPasswordAge
);
6467 InfoBuffer
->All
.PasswordMustChange
.LowPart
= PasswordMustChange
.LowPart
;
6468 InfoBuffer
->All
.PasswordMustChange
.HighPart
= PasswordMustChange
.HighPart
;
6470 InfoBuffer
->All
. WhichFields
|= USER_ALL_READ_LOGON_MASK
;
6472 USER_ALL_HOMEDIRECTORY |
6473 USER_ALL_HOMEDIRECTORYDRIVE |
6474 USER_ALL_SCRIPTPATH |
6475 USER_ALL_PROFILEPATH |
6476 USER_ALL_WORKSTATIONS |
6477 USER_ALL_LASTLOGON |
6478 USER_ALL_LASTLOGOFF |
6479 USER_ALL_LOGONHOURS |
6480 USER_ALL_BADPASSWORDCOUNT |
6481 USER_ALL_LOGONCOUNT;
6482 USER_ALL_PASSWORDCANCHANGE |
6483 USER_ALL_PASSWORDMUSTCHANGE;
6487 if (UserObject
->Access
& USER_READ_ACCOUNT
)
6489 InfoBuffer
->All
.PasswordLastSet
.LowPart
= FixedData
.PasswordLastSet
.LowPart
;
6490 InfoBuffer
->All
.PasswordLastSet
.HighPart
= FixedData
.PasswordLastSet
.HighPart
;
6492 InfoBuffer
->All
.AccountExpires
.LowPart
= FixedData
.AccountExpires
.LowPart
;
6493 InfoBuffer
->All
.AccountExpires
.HighPart
= FixedData
.AccountExpires
.HighPart
;
6495 InfoBuffer
->All
.UserAccountControl
= FixedData
.UserAccountControl
;
6497 /* Get the Parameters string */
6498 Status
= SampGetObjectAttributeString(UserObject
,
6500 &InfoBuffer
->All
.Parameters
);
6501 if (!NT_SUCCESS(Status
))
6503 TRACE("Status 0x%08lx\n", Status
);
6507 InfoBuffer
->All
. WhichFields
|= USER_ALL_READ_ACCOUNT_MASK
;
6508 // USER_ALL_PASSWORDLASTSET |
6509 // USER_ALL_ACCOUNTEXPIRES |
6510 // USER_ALL_USERACCOUNTCONTROL |
6511 // USER_ALL_PARAMETERS;
6514 if (UserObject
->Access
& USER_READ_PREFERENCES
)
6516 InfoBuffer
->All
.CountryCode
= FixedData
.CountryCode
;
6518 InfoBuffer
->All
.CodePage
= FixedData
.CodePage
;
6520 InfoBuffer
->All
. WhichFields
|= USER_ALL_READ_PREFERENCES_MASK
;
6521 // USER_ALL_COUNTRYCODE |
6522 // USER_ALL_CODEPAGE;
6525 *Buffer
= InfoBuffer
;
6528 if (!NT_SUCCESS(Status
))
6530 if (InfoBuffer
!= NULL
)
6532 if (InfoBuffer
->All
.UserName
.Buffer
!= NULL
)
6533 midl_user_free(InfoBuffer
->All
.UserName
.Buffer
);
6535 if (InfoBuffer
->All
.FullName
.Buffer
!= NULL
)
6536 midl_user_free(InfoBuffer
->All
.FullName
.Buffer
);
6538 if (InfoBuffer
->All
.AdminComment
.Buffer
!= NULL
)
6539 midl_user_free(InfoBuffer
->All
.AdminComment
.Buffer
);
6541 if (InfoBuffer
->All
.UserComment
.Buffer
!= NULL
)
6542 midl_user_free(InfoBuffer
->All
.UserComment
.Buffer
);
6544 if (InfoBuffer
->All
.HomeDirectory
.Buffer
!= NULL
)
6545 midl_user_free(InfoBuffer
->All
.HomeDirectory
.Buffer
);
6547 if (InfoBuffer
->All
.HomeDirectoryDrive
.Buffer
!= NULL
)
6548 midl_user_free(InfoBuffer
->All
.HomeDirectoryDrive
.Buffer
);
6550 if (InfoBuffer
->All
.ScriptPath
.Buffer
!= NULL
)
6551 midl_user_free(InfoBuffer
->All
.ScriptPath
.Buffer
);
6553 if (InfoBuffer
->All
.ProfilePath
.Buffer
!= NULL
)
6554 midl_user_free(InfoBuffer
->All
.ProfilePath
.Buffer
);
6556 if (InfoBuffer
->All
.WorkStations
.Buffer
!= NULL
)
6557 midl_user_free(InfoBuffer
->All
.WorkStations
.Buffer
);
6559 if (InfoBuffer
->All
.LogonHours
.LogonHours
!= NULL
)
6560 midl_user_free(InfoBuffer
->All
.LogonHours
.LogonHours
);
6562 if (InfoBuffer
->All
.Parameters
.Buffer
!= NULL
)
6563 midl_user_free(InfoBuffer
->All
.Parameters
.Buffer
);
6565 midl_user_free(InfoBuffer
);
6576 SamrQueryInformationUser(IN SAMPR_HANDLE UserHandle
,
6577 IN USER_INFORMATION_CLASS UserInformationClass
,
6578 OUT PSAMPR_USER_INFO_BUFFER
*Buffer
)
6580 PSAM_DB_OBJECT UserObject
;
6581 ACCESS_MASK DesiredAccess
;
6584 TRACE("SamrQueryInformationUser(%p %lu %p)\n",
6585 UserHandle
, UserInformationClass
, Buffer
);
6587 switch (UserInformationClass
)
6589 case UserGeneralInformation
:
6590 case UserNameInformation
:
6591 case UserAccountNameInformation
:
6592 case UserFullNameInformation
:
6593 case UserPrimaryGroupInformation
:
6594 case UserAdminCommentInformation
:
6595 DesiredAccess
= USER_READ_GENERAL
;
6598 case UserLogonHoursInformation
:
6599 case UserHomeInformation
:
6600 case UserScriptInformation
:
6601 case UserProfileInformation
:
6602 case UserWorkStationsInformation
:
6603 DesiredAccess
= USER_READ_LOGON
;
6606 case UserControlInformation
:
6607 case UserExpiresInformation
:
6608 case UserParametersInformation
:
6609 DesiredAccess
= USER_READ_ACCOUNT
;
6612 case UserPreferencesInformation
:
6613 DesiredAccess
= USER_READ_GENERAL
|
6614 USER_READ_PREFERENCES
;
6617 case UserLogonInformation
:
6618 case UserAccountInformation
:
6619 DesiredAccess
= USER_READ_GENERAL
|
6620 USER_READ_PREFERENCES
|
6625 case UserInternal1Information
:
6626 case UserAllInformation
:
6631 return STATUS_INVALID_INFO_CLASS
;
6634 /* Validate the domain handle */
6635 Status
= SampValidateDbObject(UserHandle
,
6639 if (!NT_SUCCESS(Status
))
6641 TRACE("failed with status 0x%08lx\n", Status
);
6645 switch (UserInformationClass
)
6647 case UserGeneralInformation
:
6648 Status
= SampQueryUserGeneral(UserObject
,
6652 case UserPreferencesInformation
:
6653 Status
= SampQueryUserPreferences(UserObject
,
6657 case UserLogonInformation
:
6658 Status
= SampQueryUserLogon(UserObject
,
6662 case UserLogonHoursInformation
:
6663 Status
= SampQueryUserLogonHours(UserObject
,
6667 case UserAccountInformation
:
6668 Status
= SampQueryUserAccount(UserObject
,
6672 case UserNameInformation
:
6673 Status
= SampQueryUserName(UserObject
,
6677 case UserAccountNameInformation
:
6678 Status
= SampQueryUserAccountName(UserObject
,
6682 case UserFullNameInformation
:
6683 Status
= SampQueryUserFullName(UserObject
,
6687 case UserPrimaryGroupInformation
:
6688 Status
= SampQueryUserPrimaryGroup(UserObject
,
6692 case UserHomeInformation
:
6693 Status
= SampQueryUserHome(UserObject
,
6696 case UserScriptInformation
:
6697 Status
= SampQueryUserScript(UserObject
,
6701 case UserProfileInformation
:
6702 Status
= SampQueryUserProfile(UserObject
,
6706 case UserAdminCommentInformation
:
6707 Status
= SampQueryUserAdminComment(UserObject
,
6711 case UserWorkStationsInformation
:
6712 Status
= SampQueryUserWorkStations(UserObject
,
6716 case UserControlInformation
:
6717 Status
= SampQueryUserControl(UserObject
,
6721 case UserExpiresInformation
:
6722 Status
= SampQueryUserExpires(UserObject
,
6726 case UserInternal1Information
:
6727 Status
= SampQueryUserInternal1(UserObject
,
6731 case UserParametersInformation
:
6732 Status
= SampQueryUserParameters(UserObject
,
6736 case UserAllInformation
:
6737 Status
= SampQueryUserAll(UserObject
,
6741 // case UserInternal4Information:
6742 // case UserInternal5Information:
6743 // case UserInternal4InformationNew:
6744 // case UserInternal5InformationNew:
6747 Status
= STATUS_INVALID_INFO_CLASS
;
6755 SampSetUserName(PSAM_DB_OBJECT UserObject
,
6756 PRPC_UNICODE_STRING NewUserName
)
6758 UNICODE_STRING OldUserName
= {0, 0, NULL
};
6761 Status
= SampGetObjectAttributeString(UserObject
,
6763 (PRPC_UNICODE_STRING
)&OldUserName
);
6764 if (!NT_SUCCESS(Status
))
6766 TRACE("SampGetObjectAttributeString failed (Status 0x%08lx)\n", Status
);
6770 if (!RtlEqualUnicodeString(&OldUserName
, (PCUNICODE_STRING
)NewUserName
, TRUE
))
6772 Status
= SampCheckAccountNameInDomain(UserObject
->ParentObject
,
6773 NewUserName
->Buffer
);
6774 if (!NT_SUCCESS(Status
))
6776 TRACE("User name \'%S\' already exists in domain (Status 0x%08lx)\n",
6777 NewUserName
->Buffer
, Status
);
6782 Status
= SampSetAccountNameInDomain(UserObject
->ParentObject
,
6784 NewUserName
->Buffer
,
6785 UserObject
->RelativeId
);
6786 if (!NT_SUCCESS(Status
))
6788 TRACE("SampSetAccountNameInDomain failed (Status 0x%08lx)\n", Status
);
6792 Status
= SampRemoveAccountNameFromDomain(UserObject
->ParentObject
,
6794 OldUserName
.Buffer
);
6795 if (!NT_SUCCESS(Status
))
6797 TRACE("SampRemoveAccountNameFromDomain failed (Status 0x%08lx)\n", Status
);
6801 Status
= SampSetObjectAttribute(UserObject
,
6804 NewUserName
->Buffer
,
6805 NewUserName
->Length
+ sizeof(WCHAR
));
6806 if (!NT_SUCCESS(Status
))
6808 TRACE("SampSetObjectAttribute failed (Status 0x%08lx)\n", Status
);
6812 if (OldUserName
.Buffer
!= NULL
)
6813 midl_user_free(OldUserName
.Buffer
);
6820 SampSetUserGeneral(PSAM_DB_OBJECT UserObject
,
6821 PSAMPR_USER_INFO_BUFFER Buffer
)
6823 SAM_USER_FIXED_DATA FixedData
;
6827 Length
= sizeof(SAM_USER_FIXED_DATA
);
6828 Status
= SampGetObjectAttribute(UserObject
,
6833 if (!NT_SUCCESS(Status
))
6836 FixedData
.PrimaryGroupId
= Buffer
->General
.PrimaryGroupId
;
6838 Status
= SampSetObjectAttribute(UserObject
,
6843 if (!NT_SUCCESS(Status
))
6846 Status
= SampSetUserName(UserObject
,
6847 &Buffer
->General
.UserName
);
6848 if (!NT_SUCCESS(Status
))
6851 Status
= SampSetObjectAttribute(UserObject
,
6854 Buffer
->General
.FullName
.Buffer
,
6855 Buffer
->General
.FullName
.MaximumLength
);
6856 if (!NT_SUCCESS(Status
))
6859 Status
= SampSetObjectAttribute(UserObject
,
6862 Buffer
->General
.AdminComment
.Buffer
,
6863 Buffer
->General
.AdminComment
.MaximumLength
);
6864 if (!NT_SUCCESS(Status
))
6867 Status
= SampSetObjectAttribute(UserObject
,
6870 Buffer
->General
.UserComment
.Buffer
,
6871 Buffer
->General
.UserComment
.MaximumLength
);
6879 SampSetUserPreferences(PSAM_DB_OBJECT UserObject
,
6880 PSAMPR_USER_INFO_BUFFER Buffer
)
6882 SAM_USER_FIXED_DATA FixedData
;
6886 Length
= sizeof(SAM_USER_FIXED_DATA
);
6887 Status
= SampGetObjectAttribute(UserObject
,
6892 if (!NT_SUCCESS(Status
))
6895 FixedData
.CountryCode
= Buffer
->Preferences
.CountryCode
;
6896 FixedData
.CodePage
= Buffer
->Preferences
.CodePage
;
6898 Status
= SampSetObjectAttribute(UserObject
,
6903 if (!NT_SUCCESS(Status
))
6906 Status
= SampSetObjectAttribute(UserObject
,
6909 Buffer
->Preferences
.UserComment
.Buffer
,
6910 Buffer
->Preferences
.UserComment
.MaximumLength
);
6918 SampSetUserPrimaryGroup(PSAM_DB_OBJECT UserObject
,
6919 PSAMPR_USER_INFO_BUFFER Buffer
)
6921 SAM_USER_FIXED_DATA FixedData
;
6925 Length
= sizeof(SAM_USER_FIXED_DATA
);
6926 Status
= SampGetObjectAttribute(UserObject
,
6931 if (!NT_SUCCESS(Status
))
6934 FixedData
.PrimaryGroupId
= Buffer
->PrimaryGroup
.PrimaryGroupId
;
6936 Status
= SampSetObjectAttribute(UserObject
,
6948 SampSetUserControl(PSAM_DB_OBJECT UserObject
,
6949 PSAMPR_USER_INFO_BUFFER Buffer
)
6951 SAM_USER_FIXED_DATA FixedData
;
6955 Length
= sizeof(SAM_USER_FIXED_DATA
);
6956 Status
= SampGetObjectAttribute(UserObject
,
6961 if (!NT_SUCCESS(Status
))
6964 FixedData
.UserAccountControl
= Buffer
->Control
.UserAccountControl
;
6966 Status
= SampSetObjectAttribute(UserObject
,
6978 SampSetUserExpires(PSAM_DB_OBJECT UserObject
,
6979 PSAMPR_USER_INFO_BUFFER Buffer
)
6981 SAM_USER_FIXED_DATA FixedData
;
6985 Length
= sizeof(SAM_USER_FIXED_DATA
);
6986 Status
= SampGetObjectAttribute(UserObject
,
6991 if (!NT_SUCCESS(Status
))
6994 FixedData
.AccountExpires
.LowPart
= Buffer
->Expires
.AccountExpires
.LowPart
;
6995 FixedData
.AccountExpires
.HighPart
= Buffer
->Expires
.AccountExpires
.HighPart
;
6997 Status
= SampSetObjectAttribute(UserObject
,
7009 SampSetUserInternal1(PSAM_DB_OBJECT UserObject
,
7010 PSAMPR_USER_INFO_BUFFER Buffer
)
7012 SAM_USER_FIXED_DATA FixedData
;
7014 NTSTATUS Status
= STATUS_SUCCESS
;
7016 /* FIXME: Decrypt NT password */
7017 /* FIXME: Decrypt LM password */
7019 Status
= SampSetUserPassword(UserObject
,
7020 &Buffer
->Internal1
.EncryptedNtOwfPassword
,
7021 Buffer
->Internal1
.NtPasswordPresent
,
7022 &Buffer
->Internal1
.EncryptedLmOwfPassword
,
7023 Buffer
->Internal1
.LmPasswordPresent
);
7024 if (!NT_SUCCESS(Status
))
7027 /* Get the fixed user attributes */
7028 Length
= sizeof(SAM_USER_FIXED_DATA
);
7029 Status
= SampGetObjectAttribute(UserObject
,
7034 if (!NT_SUCCESS(Status
))
7037 if (Buffer
->Internal1
.PasswordExpired
)
7039 /* The pasword was last set ages ago */
7040 FixedData
.PasswordLastSet
.LowPart
= 0;
7041 FixedData
.PasswordLastSet
.HighPart
= 0;
7045 /* The pasword was last set right now */
7046 Status
= NtQuerySystemTime(&FixedData
.PasswordLastSet
);
7047 if (!NT_SUCCESS(Status
))
7051 /* Set the fixed user attributes */
7052 Status
= SampSetObjectAttribute(UserObject
,
7064 SampSetUserAll(PSAM_DB_OBJECT UserObject
,
7065 PSAMPR_USER_INFO_BUFFER Buffer
)
7067 SAM_USER_FIXED_DATA FixedData
;
7070 NTSTATUS Status
= STATUS_SUCCESS
;
7072 WhichFields
= Buffer
->All
.WhichFields
;
7074 if (WhichFields
& USER_ALL_USERNAME
)
7076 Status
= SampSetUserName(UserObject
,
7077 &Buffer
->All
.UserName
);
7078 if (!NT_SUCCESS(Status
))
7082 if (WhichFields
& USER_ALL_FULLNAME
)
7084 Status
= SampSetObjectAttribute(UserObject
,
7087 Buffer
->All
.FullName
.Buffer
,
7088 Buffer
->All
.FullName
.MaximumLength
);
7089 if (!NT_SUCCESS(Status
))
7093 if (WhichFields
& USER_ALL_ADMINCOMMENT
)
7095 Status
= SampSetObjectAttribute(UserObject
,
7098 Buffer
->All
.AdminComment
.Buffer
,
7099 Buffer
->All
.AdminComment
.MaximumLength
);
7100 if (!NT_SUCCESS(Status
))
7104 if (WhichFields
& USER_ALL_USERCOMMENT
)
7106 Status
= SampSetObjectAttribute(UserObject
,
7109 Buffer
->All
.UserComment
.Buffer
,
7110 Buffer
->All
.UserComment
.MaximumLength
);
7111 if (!NT_SUCCESS(Status
))
7115 if (WhichFields
& USER_ALL_HOMEDIRECTORY
)
7117 Status
= SampSetObjectAttribute(UserObject
,
7120 Buffer
->All
.HomeDirectory
.Buffer
,
7121 Buffer
->All
.HomeDirectory
.MaximumLength
);
7122 if (!NT_SUCCESS(Status
))
7126 if (WhichFields
& USER_ALL_HOMEDIRECTORYDRIVE
)
7128 Status
= SampSetObjectAttribute(UserObject
,
7129 L
"HomeDirectoryDrive",
7131 Buffer
->All
.HomeDirectoryDrive
.Buffer
,
7132 Buffer
->All
.HomeDirectoryDrive
.MaximumLength
);
7133 if (!NT_SUCCESS(Status
))
7137 if (WhichFields
& USER_ALL_SCRIPTPATH
)
7139 Status
= SampSetObjectAttribute(UserObject
,
7142 Buffer
->All
.ScriptPath
.Buffer
,
7143 Buffer
->All
.ScriptPath
.MaximumLength
);
7144 if (!NT_SUCCESS(Status
))
7148 if (WhichFields
& USER_ALL_PROFILEPATH
)
7150 Status
= SampSetObjectAttribute(UserObject
,
7153 Buffer
->All
.ProfilePath
.Buffer
,
7154 Buffer
->All
.ProfilePath
.MaximumLength
);
7155 if (!NT_SUCCESS(Status
))
7159 if (WhichFields
& USER_ALL_WORKSTATIONS
)
7161 Status
= SampSetObjectAttribute(UserObject
,
7164 Buffer
->All
.WorkStations
.Buffer
,
7165 Buffer
->All
.WorkStations
.MaximumLength
);
7166 if (!NT_SUCCESS(Status
))
7170 if (WhichFields
& USER_ALL_PARAMETERS
)
7172 Status
= SampSetObjectAttribute(UserObject
,
7175 Buffer
->All
.Parameters
.Buffer
,
7176 Buffer
->All
.Parameters
.MaximumLength
);
7177 if (!NT_SUCCESS(Status
))
7181 if (WhichFields
& USER_ALL_LOGONHOURS
)
7183 Status
= SampSetLogonHoursAttrbute(UserObject
,
7184 &Buffer
->All
.LogonHours
);
7185 if (!NT_SUCCESS(Status
))
7189 if (WhichFields
& (USER_ALL_PRIMARYGROUPID
|
7190 USER_ALL_ACCOUNTEXPIRES
|
7191 USER_ALL_USERACCOUNTCONTROL
|
7192 USER_ALL_COUNTRYCODE
|
7195 Length
= sizeof(SAM_USER_FIXED_DATA
);
7196 Status
= SampGetObjectAttribute(UserObject
,
7201 if (!NT_SUCCESS(Status
))
7204 if (WhichFields
& USER_ALL_PRIMARYGROUPID
)
7205 FixedData
.PrimaryGroupId
= Buffer
->All
.PrimaryGroupId
;
7207 if (WhichFields
& USER_ALL_ACCOUNTEXPIRES
)
7209 FixedData
.AccountExpires
.LowPart
= Buffer
->All
.AccountExpires
.LowPart
;
7210 FixedData
.AccountExpires
.HighPart
= Buffer
->All
.AccountExpires
.HighPart
;
7213 if (WhichFields
& USER_ALL_USERACCOUNTCONTROL
)
7214 FixedData
.UserAccountControl
= Buffer
->All
.UserAccountControl
;
7216 if (WhichFields
& USER_ALL_COUNTRYCODE
)
7217 FixedData
.CountryCode
= Buffer
->Preferences
.CountryCode
;
7219 if (WhichFields
& USER_ALL_CODEPAGE
)
7220 FixedData
.CodePage
= Buffer
->Preferences
.CodePage
;
7222 Status
= SampSetObjectAttribute(UserObject
,
7227 if (!NT_SUCCESS(Status
))
7233 USER_ALL_NTPASSWORDPRESENT
7234 USER_ALL_LMPASSWORDPRESENT
7235 USER_ALL_PASSWORDEXPIRED
7247 SamrSetInformationUser(IN SAMPR_HANDLE UserHandle
,
7248 IN USER_INFORMATION_CLASS UserInformationClass
,
7249 IN PSAMPR_USER_INFO_BUFFER Buffer
)
7251 PSAM_DB_OBJECT UserObject
;
7252 ACCESS_MASK DesiredAccess
;
7255 TRACE("SamrSetInformationUser(%p %lu %p)\n",
7256 UserHandle
, UserInformationClass
, Buffer
);
7258 switch (UserInformationClass
)
7260 case UserLogonHoursInformation
:
7261 case UserNameInformation
:
7262 case UserAccountNameInformation
:
7263 case UserFullNameInformation
:
7264 case UserPrimaryGroupInformation
:
7265 case UserHomeInformation
:
7266 case UserScriptInformation
:
7267 case UserProfileInformation
:
7268 case UserAdminCommentInformation
:
7269 case UserWorkStationsInformation
:
7270 case UserControlInformation
:
7271 case UserExpiresInformation
:
7272 case UserParametersInformation
:
7273 DesiredAccess
= USER_WRITE_ACCOUNT
;
7276 case UserGeneralInformation
:
7277 DesiredAccess
= USER_WRITE_ACCOUNT
|
7278 USER_WRITE_PREFERENCES
;
7281 case UserPreferencesInformation
:
7282 DesiredAccess
= USER_WRITE_PREFERENCES
;
7285 case UserSetPasswordInformation
:
7286 case UserInternal1Information
:
7287 DesiredAccess
= USER_FORCE_PASSWORD_CHANGE
;
7290 case UserAllInformation
:
7291 DesiredAccess
= 0; /* FIXME */
7295 return STATUS_INVALID_INFO_CLASS
;
7298 /* Validate the domain handle */
7299 Status
= SampValidateDbObject(UserHandle
,
7303 if (!NT_SUCCESS(Status
))
7305 TRACE("failed with status 0x%08lx\n", Status
);
7309 switch (UserInformationClass
)
7311 case UserGeneralInformation
:
7312 Status
= SampSetUserGeneral(UserObject
,
7316 case UserPreferencesInformation
:
7317 Status
= SampSetUserPreferences(UserObject
,
7321 case UserLogonHoursInformation
:
7322 Status
= SampSetLogonHoursAttrbute(UserObject
,
7323 &Buffer
->LogonHours
.LogonHours
);
7326 case UserNameInformation
:
7327 Status
= SampSetUserName(UserObject
,
7328 &Buffer
->Name
.UserName
);
7329 if (!NT_SUCCESS(Status
))
7332 Status
= SampSetObjectAttribute(UserObject
,
7335 Buffer
->Name
.FullName
.Buffer
,
7336 Buffer
->Name
.FullName
.MaximumLength
);
7339 case UserAccountNameInformation
:
7340 Status
= SampSetUserName(UserObject
,
7341 &Buffer
->AccountName
.UserName
);
7344 case UserFullNameInformation
:
7345 Status
= SampSetObjectAttribute(UserObject
,
7348 Buffer
->FullName
.FullName
.Buffer
,
7349 Buffer
->FullName
.FullName
.MaximumLength
);
7352 case UserPrimaryGroupInformation
:
7353 Status
= SampSetUserPrimaryGroup(UserObject
,
7357 case UserHomeInformation
:
7358 Status
= SampSetObjectAttribute(UserObject
,
7361 Buffer
->Home
.HomeDirectory
.Buffer
,
7362 Buffer
->Home
.HomeDirectory
.MaximumLength
);
7363 if (!NT_SUCCESS(Status
))
7366 Status
= SampSetObjectAttribute(UserObject
,
7367 L
"HomeDirectoryDrive",
7369 Buffer
->Home
.HomeDirectoryDrive
.Buffer
,
7370 Buffer
->Home
.HomeDirectoryDrive
.MaximumLength
);
7373 case UserScriptInformation
:
7374 Status
= SampSetObjectAttribute(UserObject
,
7377 Buffer
->Script
.ScriptPath
.Buffer
,
7378 Buffer
->Script
.ScriptPath
.MaximumLength
);
7381 case UserProfileInformation
:
7382 Status
= SampSetObjectAttribute(UserObject
,
7385 Buffer
->Profile
.ProfilePath
.Buffer
,
7386 Buffer
->Profile
.ProfilePath
.MaximumLength
);
7389 case UserAdminCommentInformation
:
7390 Status
= SampSetObjectAttribute(UserObject
,
7393 Buffer
->AdminComment
.AdminComment
.Buffer
,
7394 Buffer
->AdminComment
.AdminComment
.MaximumLength
);
7397 case UserWorkStationsInformation
:
7398 Status
= SampSetObjectAttribute(UserObject
,
7401 Buffer
->WorkStations
.WorkStations
.Buffer
,
7402 Buffer
->WorkStations
.WorkStations
.MaximumLength
);
7405 case UserSetPasswordInformation
:
7406 TRACE("Password: %S\n", Buffer
->SetPassword
.Password
.Buffer
);
7407 TRACE("PasswordExpired: %d\n", Buffer
->SetPassword
.PasswordExpired
);
7409 Status
= SampSetObjectAttribute(UserObject
,
7412 Buffer
->SetPassword
.Password
.Buffer
,
7413 Buffer
->SetPassword
.Password
.MaximumLength
);
7416 case UserControlInformation
:
7417 Status
= SampSetUserControl(UserObject
,
7421 case UserExpiresInformation
:
7422 Status
= SampSetUserExpires(UserObject
,
7426 case UserInternal1Information
:
7427 Status
= SampSetUserInternal1(UserObject
,
7431 case UserParametersInformation
:
7432 Status
= SampSetObjectAttribute(UserObject
,
7435 Buffer
->Parameters
.Parameters
.Buffer
,
7436 Buffer
->Parameters
.Parameters
.MaximumLength
);
7439 case UserAllInformation
:
7440 Status
= SampSetUserAll(UserObject
,
7444 // case UserInternal4Information:
7445 // case UserInternal5Information:
7446 // case UserInternal4InformationNew:
7447 // case UserInternal5InformationNew:
7450 Status
= STATUS_INVALID_INFO_CLASS
;
7460 SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle
,
7461 IN
unsigned char LmPresent
,
7462 IN PENCRYPTED_LM_OWF_PASSWORD OldLmEncryptedWithNewLm
,
7463 IN PENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithOldLm
,
7464 IN
unsigned char NtPresent
,
7465 IN PENCRYPTED_NT_OWF_PASSWORD OldNtEncryptedWithNewNt
,
7466 IN PENCRYPTED_NT_OWF_PASSWORD NewNtEncryptedWithOldNt
,
7467 IN
unsigned char NtCrossEncryptionPresent
,
7468 IN PENCRYPTED_NT_OWF_PASSWORD NewNtEncryptedWithNewLm
,
7469 IN
unsigned char LmCrossEncryptionPresent
,
7470 IN PENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithNewNt
)
7472 ENCRYPTED_LM_OWF_PASSWORD StoredLmPassword
;
7473 ENCRYPTED_NT_OWF_PASSWORD StoredNtPassword
;
7474 PENCRYPTED_LM_OWF_PASSWORD OldLmPassword
;
7475 PENCRYPTED_LM_OWF_PASSWORD NewLmPassword
;
7476 PENCRYPTED_NT_OWF_PASSWORD OldNtPassword
;
7477 PENCRYPTED_NT_OWF_PASSWORD NewNtPassword
;
7478 PSAM_DB_OBJECT UserObject
;
7482 TRACE("(%p %u %p %p %u %p %p %u %p %u %p)\n",
7483 UserHandle
, LmPresent
, OldLmEncryptedWithNewLm
, NewLmEncryptedWithOldLm
,
7484 NtPresent
, OldNtEncryptedWithNewNt
, NewNtEncryptedWithOldNt
, NtCrossEncryptionPresent
,
7485 NewNtEncryptedWithNewLm
, LmCrossEncryptionPresent
, NewLmEncryptedWithNewNt
);
7487 /* Validate the user handle */
7488 Status
= SampValidateDbObject(UserHandle
,
7490 USER_CHANGE_PASSWORD
,
7492 if (!NT_SUCCESS(Status
))
7494 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
7498 /* Retrieve the LM password */
7499 Length
= sizeof(ENCRYPTED_LM_OWF_PASSWORD
);
7500 Status
= SampGetObjectAttribute(UserObject
,
7505 if (!NT_SUCCESS(Status
))
7510 /* Retrieve the NT password */
7511 Length
= sizeof(ENCRYPTED_NT_OWF_PASSWORD
);
7512 Status
= SampGetObjectAttribute(UserObject
,
7517 if (!NT_SUCCESS(Status
))
7522 /* FIXME: Decrypt passwords */
7523 OldLmPassword
= OldLmEncryptedWithNewLm
;
7524 NewLmPassword
= NewLmEncryptedWithOldLm
;
7525 OldNtPassword
= OldNtEncryptedWithNewNt
;
7526 NewNtPassword
= NewNtEncryptedWithOldNt
;
7528 /* Check if the old passwords match the stored ones */
7533 if (!RtlEqualMemory(&StoredLmPassword
,
7535 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
7537 TRACE("Old LM Password does not match!\n");
7538 Status
= STATUS_WRONG_PASSWORD
;
7542 if (!RtlEqualMemory(&StoredNtPassword
,
7544 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
7546 TRACE("Old NT Password does not match!\n");
7547 Status
= STATUS_WRONG_PASSWORD
;
7553 if (!RtlEqualMemory(&StoredNtPassword
,
7555 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
7557 TRACE("Old NT Password does not match!\n");
7558 Status
= STATUS_WRONG_PASSWORD
;
7566 if (!RtlEqualMemory(&StoredLmPassword
,
7568 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
7570 TRACE("Old LM Password does not match!\n");
7571 Status
= STATUS_WRONG_PASSWORD
;
7576 Status
= STATUS_INVALID_PARAMETER
;
7580 /* Store the new LM password */
7581 if (NT_SUCCESS(Status
))
7585 Length
= sizeof(ENCRYPTED_LM_OWF_PASSWORD
);
7586 Status
= SampSetObjectAttribute(UserObject
,
7591 if (!NT_SUCCESS(Status
))
7597 /* Store the new NT password */
7600 Length
= sizeof(ENCRYPTED_NT_OWF_PASSWORD
);
7601 Status
= SampSetObjectAttribute(UserObject
,
7606 if (!NT_SUCCESS(Status
))
7622 SamrGetGroupsForUser(IN SAMPR_HANDLE UserHandle
,
7623 OUT PSAMPR_GET_GROUPS_BUFFER
*Groups
)
7625 PSAMPR_GET_GROUPS_BUFFER GroupsBuffer
= NULL
;
7626 PSAM_DB_OBJECT UserObject
;
7630 TRACE("SamrGetGroupsForUser(%p %p)\n",
7631 UserHandle
, Groups
);
7633 /* Validate the user handle */
7634 Status
= SampValidateDbObject(UserHandle
,
7638 if (!NT_SUCCESS(Status
))
7640 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
7644 /* Allocate the groups buffer */
7645 GroupsBuffer
= midl_user_allocate(sizeof(SAMPR_GET_GROUPS_BUFFER
));
7646 if (GroupsBuffer
== NULL
)
7647 return STATUS_INSUFFICIENT_RESOURCES
;
7650 * Get the size of the Groups attribute.
7651 * Do not check the status code because in case of an error
7652 * Length will be 0. And that is all we need.
7654 SampGetObjectAttribute(UserObject
,
7660 /* If there is no Groups attribute, return a groups buffer without an array */
7663 GroupsBuffer
->MembershipCount
= 0;
7664 GroupsBuffer
->Groups
= NULL
;
7666 *Groups
= GroupsBuffer
;
7668 return STATUS_SUCCESS
;
7671 /* Allocate a buffer for the Groups attribute */
7672 GroupsBuffer
->Groups
= midl_user_allocate(Length
);
7673 if (GroupsBuffer
->Groups
== NULL
)
7675 Status
= STATUS_INSUFFICIENT_RESOURCES
;
7679 /* Retrieve the Grous attribute */
7680 Status
= SampGetObjectAttribute(UserObject
,
7683 GroupsBuffer
->Groups
,
7685 if (!NT_SUCCESS(Status
))
7687 TRACE("SampGetObjectAttribute failed with status 0x%08lx\n", Status
);
7691 /* Calculate the membership count */
7692 GroupsBuffer
->MembershipCount
= Length
/ sizeof(GROUP_MEMBERSHIP
);
7694 /* Return the groups buffer to the caller */
7695 *Groups
= GroupsBuffer
;
7698 if (!NT_SUCCESS(Status
))
7700 if (GroupsBuffer
!= NULL
)
7702 if (GroupsBuffer
->Groups
!= NULL
)
7703 midl_user_free(GroupsBuffer
->Groups
);
7705 midl_user_free(GroupsBuffer
);
7716 SamrQueryDisplayInformation(IN SAMPR_HANDLE DomainHandle
,
7717 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
7718 IN
unsigned long Index
,
7719 IN
unsigned long EntryCount
,
7720 IN
unsigned long PreferredMaximumLength
,
7721 OUT
unsigned long *TotalAvailable
,
7722 OUT
unsigned long *TotalReturned
,
7723 OUT PSAMPR_DISPLAY_INFO_BUFFER Buffer
)
7726 return STATUS_NOT_IMPLEMENTED
;
7732 SamrGetDisplayEnumerationIndex(IN SAMPR_HANDLE DomainHandle
,
7733 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
7734 IN PRPC_UNICODE_STRING Prefix
,
7735 OUT
unsigned long *Index
)
7738 return STATUS_NOT_IMPLEMENTED
;
7744 SamrTestPrivateFunctionsDomain(IN SAMPR_HANDLE DomainHandle
)
7747 return STATUS_NOT_IMPLEMENTED
;
7753 SamrTestPrivateFunctionsUser(IN SAMPR_HANDLE UserHandle
)
7756 return STATUS_NOT_IMPLEMENTED
;
7763 SamrGetUserDomainPasswordInformation(IN SAMPR_HANDLE UserHandle
,
7764 OUT PUSER_DOMAIN_PASSWORD_INFORMATION PasswordInformation
)
7766 SAM_DOMAIN_FIXED_DATA DomainFixedData
;
7767 SAM_USER_FIXED_DATA UserFixedData
;
7768 PSAM_DB_OBJECT DomainObject
;
7769 PSAM_DB_OBJECT UserObject
;
7774 UserHandle
, PasswordInformation
);
7776 /* Validate the user handle */
7777 Status
= SampValidateDbObject(UserHandle
,
7781 if (!NT_SUCCESS(Status
))
7783 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
7787 /* Validate the domain object */
7788 Status
= SampValidateDbObject((SAMPR_HANDLE
)UserObject
->ParentObject
,
7790 DOMAIN_READ_PASSWORD_PARAMETERS
,
7792 if (!NT_SUCCESS(Status
))
7794 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
7798 /* Get fixed user data */
7799 Length
= sizeof(SAM_USER_FIXED_DATA
);
7800 Status
= SampGetObjectAttribute(UserObject
,
7803 (PVOID
)&UserFixedData
,
7805 if (!NT_SUCCESS(Status
))
7807 TRACE("SampGetObjectAttribute failed with status 0x%08lx\n", Status
);
7811 if ((UserObject
->RelativeId
== DOMAIN_USER_RID_KRBTGT
) ||
7812 (UserFixedData
.UserAccountControl
& (USER_INTERDOMAIN_TRUST_ACCOUNT
|
7813 USER_WORKSTATION_TRUST_ACCOUNT
|
7814 USER_SERVER_TRUST_ACCOUNT
)))
7816 PasswordInformation
->MinPasswordLength
= 0;
7817 PasswordInformation
->PasswordProperties
= 0;
7821 /* Get fixed domain data */
7822 Length
= sizeof(SAM_DOMAIN_FIXED_DATA
);
7823 Status
= SampGetObjectAttribute(DomainObject
,
7826 (PVOID
)&DomainFixedData
,
7828 if (!NT_SUCCESS(Status
))
7830 TRACE("SampGetObjectAttribute failed with status 0x%08lx\n", Status
);
7834 PasswordInformation
->MinPasswordLength
= DomainFixedData
.MinPasswordLength
;
7835 PasswordInformation
->PasswordProperties
= DomainFixedData
.PasswordProperties
;
7838 return STATUS_SUCCESS
;
7845 SamrRemoveMemberFromForeignDomain(IN SAMPR_HANDLE DomainHandle
,
7846 IN PRPC_SID MemberSid
)
7848 PSAM_DB_OBJECT DomainObject
;
7853 DomainHandle
, MemberSid
);
7855 /* Validate the domain object */
7856 Status
= SampValidateDbObject(DomainHandle
,
7860 if (!NT_SUCCESS(Status
))
7862 TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status
);
7866 /* Retrieve the RID from the MemberSID */
7867 Status
= SampGetRidFromSid((PSID
)MemberSid
,
7869 if (!NT_SUCCESS(Status
))
7871 TRACE("SampGetRidFromSid failed with status 0x%08lx\n", Status
);
7875 /* Fail, if the RID represents a special account */
7878 TRACE("Cannot remove a special account (RID: %lu)\n", Rid
);
7879 return STATUS_SPECIAL_ACCOUNT
;
7882 /* Remove the member from all aliases in the domain */
7883 Status
= SampRemoveMemberFromAllAliases(DomainObject
,
7885 if (!NT_SUCCESS(Status
))
7887 TRACE("SampRemoveMemberFromAllAliases failed with status 0x%08lx\n", Status
);
7897 SamrQueryInformationDomain2(IN SAMPR_HANDLE DomainHandle
,
7898 IN DOMAIN_INFORMATION_CLASS DomainInformationClass
,
7899 OUT PSAMPR_DOMAIN_INFO_BUFFER
*Buffer
)
7901 TRACE("(%p %lu %p)\n", DomainHandle
, DomainInformationClass
, Buffer
);
7903 return SamrQueryInformationDomain(DomainHandle
,
7904 DomainInformationClass
,
7912 SamrQueryInformationUser2(IN SAMPR_HANDLE UserHandle
,
7913 IN USER_INFORMATION_CLASS UserInformationClass
,
7914 OUT PSAMPR_USER_INFO_BUFFER
*Buffer
)
7916 TRACE("(%p %lu %p)\n", UserHandle
, UserInformationClass
, Buffer
);
7918 return SamrQueryInformationUser(UserHandle
,
7919 UserInformationClass
,
7927 SamrQueryDisplayInformation2(IN SAMPR_HANDLE DomainHandle
,
7928 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
7929 IN
unsigned long Index
,
7930 IN
unsigned long EntryCount
,
7931 IN
unsigned long PreferredMaximumLength
,
7932 OUT
unsigned long *TotalAvailable
,
7933 OUT
unsigned long *TotalReturned
,
7934 OUT PSAMPR_DISPLAY_INFO_BUFFER Buffer
)
7936 TRACE("%p %lu %lu %lu %lu %p %p %p\n",
7937 DomainHandle
, DisplayInformationClass
, Index
,
7938 EntryCount
, PreferredMaximumLength
, TotalAvailable
,
7939 TotalReturned
, Buffer
);
7941 return SamrQueryDisplayInformation(DomainHandle
,
7942 DisplayInformationClass
,
7945 PreferredMaximumLength
,
7955 SamrGetDisplayEnumerationIndex2(IN SAMPR_HANDLE DomainHandle
,
7956 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
7957 IN PRPC_UNICODE_STRING Prefix
,
7958 OUT
unsigned long *Index
)
7960 TRACE("(%p %lu %p %p)\n",
7961 DomainHandle
, DisplayInformationClass
, Prefix
, Index
);
7963 return SamrGetDisplayEnumerationIndex(DomainHandle
,
7964 DisplayInformationClass
,
7973 SamrCreateUser2InDomain(IN SAMPR_HANDLE DomainHandle
,
7974 IN PRPC_UNICODE_STRING Name
,
7975 IN
unsigned long AccountType
,
7976 IN ACCESS_MASK DesiredAccess
,
7977 OUT SAMPR_HANDLE
*UserHandle
,
7978 OUT
unsigned long *GrantedAccess
,
7979 OUT
unsigned long *RelativeId
)
7981 UNICODE_STRING EmptyString
= RTL_CONSTANT_STRING(L
"");
7982 SAM_DOMAIN_FIXED_DATA FixedDomainData
;
7983 SAM_USER_FIXED_DATA FixedUserData
;
7984 PSAM_DB_OBJECT DomainObject
;
7985 PSAM_DB_OBJECT UserObject
;
7986 GROUP_MEMBERSHIP GroupMembership
;
7987 UCHAR LogonHours
[23];
7993 TRACE("SamrCreateUserInDomain(%p %p %lx %p %p)\n",
7994 DomainHandle
, Name
, DesiredAccess
, UserHandle
, RelativeId
);
7997 Name
->Length
== 0 ||
7998 Name
->Buffer
== NULL
||
7999 UserHandle
== NULL
||
8001 return STATUS_INVALID_PARAMETER
;
8003 /* Check for valid account type */
8004 if (AccountType
!= USER_NORMAL_ACCOUNT
&&
8005 AccountType
!= USER_WORKSTATION_TRUST_ACCOUNT
&&
8006 AccountType
!= USER_INTERDOMAIN_TRUST_ACCOUNT
&&
8007 AccountType
!= USER_SERVER_TRUST_ACCOUNT
&&
8008 AccountType
!= USER_TEMP_DUPLICATE_ACCOUNT
)
8009 return STATUS_INVALID_PARAMETER
;
8011 /* Map generic access rights */
8012 RtlMapGenericMask(&DesiredAccess
,
8015 /* Validate the domain handle */
8016 Status
= SampValidateDbObject(DomainHandle
,
8020 if (!NT_SUCCESS(Status
))
8022 TRACE("failed with status 0x%08lx\n", Status
);
8026 /* Check if the user name already exists in the domain */
8027 Status
= SampCheckAccountNameInDomain(DomainObject
,
8029 if (!NT_SUCCESS(Status
))
8031 TRACE("User name \'%S\' already exists in domain (Status 0x%08lx)\n",
8032 Name
->Buffer
, Status
);
8036 /* Get the fixed domain attributes */
8037 ulSize
= sizeof(SAM_DOMAIN_FIXED_DATA
);
8038 Status
= SampGetObjectAttribute(DomainObject
,
8041 (PVOID
)&FixedDomainData
,
8043 if (!NT_SUCCESS(Status
))
8045 TRACE("failed with status 0x%08lx\n", Status
);
8049 /* Increment the NextRid attribute */
8050 ulRid
= FixedDomainData
.NextRid
;
8051 FixedDomainData
.NextRid
++;
8053 /* Store the fixed domain attributes */
8054 Status
= SampSetObjectAttribute(DomainObject
,
8059 if (!NT_SUCCESS(Status
))
8061 TRACE("failed with status 0x%08lx\n", Status
);
8065 TRACE("RID: %lx\n", ulRid
);
8067 /* Convert the RID into a string (hex) */
8068 swprintf(szRid
, L
"%08lX", ulRid
);
8070 /* Create the user object */
8071 Status
= SampCreateDbObject(DomainObject
,
8078 if (!NT_SUCCESS(Status
))
8080 TRACE("failed with status 0x%08lx\n", Status
);
8084 /* Add the account name for the user object */
8085 Status
= SampSetAccountNameInDomain(DomainObject
,
8089 if (!NT_SUCCESS(Status
))
8091 TRACE("failed with status 0x%08lx\n", Status
);
8095 /* Initialize fixed user data */
8096 FixedUserData
.Version
= 1;
8097 FixedUserData
.Reserved
= 0;
8098 FixedUserData
.LastLogon
.QuadPart
= 0;
8099 FixedUserData
.LastLogoff
.QuadPart
= 0;
8100 FixedUserData
.PasswordLastSet
.QuadPart
= 0;
8101 FixedUserData
.AccountExpires
.LowPart
= MAXULONG
;
8102 FixedUserData
.AccountExpires
.HighPart
= MAXLONG
;
8103 FixedUserData
.LastBadPasswordTime
.QuadPart
= 0;
8104 FixedUserData
.UserId
= ulRid
;
8105 FixedUserData
.PrimaryGroupId
= DOMAIN_GROUP_RID_USERS
;
8106 FixedUserData
.UserAccountControl
= USER_ACCOUNT_DISABLED
|
8107 USER_PASSWORD_NOT_REQUIRED
|
8109 FixedUserData
.CountryCode
= 0;
8110 FixedUserData
.CodePage
= 0;
8111 FixedUserData
.BadPasswordCount
= 0;
8112 FixedUserData
.LogonCount
= 0;
8113 FixedUserData
.AdminCount
= 0;
8114 FixedUserData
.OperatorCount
= 0;
8116 /* Set fixed user data attribute */
8117 Status
= SampSetObjectAttribute(UserObject
,
8120 (LPVOID
)&FixedUserData
,
8121 sizeof(SAM_USER_FIXED_DATA
));
8122 if (!NT_SUCCESS(Status
))
8124 TRACE("failed with status 0x%08lx\n", Status
);
8128 /* Set the Name attribute */
8129 Status
= SampSetObjectAttribute(UserObject
,
8132 (LPVOID
)Name
->Buffer
,
8133 Name
->MaximumLength
);
8134 if (!NT_SUCCESS(Status
))
8136 TRACE("failed with status 0x%08lx\n", Status
);
8140 /* Set the FullName attribute */
8141 Status
= SampSetObjectAttribute(UserObject
,
8145 EmptyString
.MaximumLength
);
8146 if (!NT_SUCCESS(Status
))
8148 TRACE("failed with status 0x%08lx\n", Status
);
8152 /* Set the HomeDirectory attribute */
8153 Status
= SampSetObjectAttribute(UserObject
,
8157 EmptyString
.MaximumLength
);
8158 if (!NT_SUCCESS(Status
))
8160 TRACE("failed with status 0x%08lx\n", Status
);
8164 /* Set the HomeDirectoryDrive attribute */
8165 Status
= SampSetObjectAttribute(UserObject
,
8166 L
"HomeDirectoryDrive",
8169 EmptyString
.MaximumLength
);
8170 if (!NT_SUCCESS(Status
))
8172 TRACE("failed with status 0x%08lx\n", Status
);
8176 /* Set the ScriptPath attribute */
8177 Status
= SampSetObjectAttribute(UserObject
,
8181 EmptyString
.MaximumLength
);
8182 if (!NT_SUCCESS(Status
))
8184 TRACE("failed with status 0x%08lx\n", Status
);
8188 /* Set the ProfilePath attribute */
8189 Status
= SampSetObjectAttribute(UserObject
,
8193 EmptyString
.MaximumLength
);
8194 if (!NT_SUCCESS(Status
))
8196 TRACE("failed with status 0x%08lx\n", Status
);
8200 /* Set the AdminComment attribute */
8201 Status
= SampSetObjectAttribute(UserObject
,
8205 EmptyString
.MaximumLength
);
8206 if (!NT_SUCCESS(Status
))
8208 TRACE("failed with status 0x%08lx\n", Status
);
8212 /* Set the UserComment attribute */
8213 Status
= SampSetObjectAttribute(UserObject
,
8217 EmptyString
.MaximumLength
);
8218 if (!NT_SUCCESS(Status
))
8220 TRACE("failed with status 0x%08lx\n", Status
);
8224 /* Set the WorkStations attribute */
8225 Status
= SampSetObjectAttribute(UserObject
,
8229 EmptyString
.MaximumLength
);
8230 if (!NT_SUCCESS(Status
))
8232 TRACE("failed with status 0x%08lx\n", Status
);
8236 /* Set the Parameters attribute */
8237 Status
= SampSetObjectAttribute(UserObject
,
8241 EmptyString
.MaximumLength
);
8242 if (!NT_SUCCESS(Status
))
8244 TRACE("failed with status 0x%08lx\n", Status
);
8248 /* Set LogonHours attribute*/
8249 *((PUSHORT
)LogonHours
) = 168;
8250 memset(&(LogonHours
[2]), 0xff, 21);
8252 Status
= SampSetObjectAttribute(UserObject
,
8256 sizeof(LogonHours
));
8257 if (!NT_SUCCESS(Status
))
8259 TRACE("failed with status 0x%08lx\n", Status
);
8263 /* Set Groups attribute*/
8264 GroupMembership
.RelativeId
= DOMAIN_GROUP_RID_USERS
;
8265 GroupMembership
.Attributes
= SE_GROUP_MANDATORY
|
8267 SE_GROUP_ENABLED_BY_DEFAULT
;
8269 Status
= SampSetObjectAttribute(UserObject
,
8273 sizeof(GROUP_MEMBERSHIP
));
8274 if (!NT_SUCCESS(Status
))
8276 TRACE("failed with status 0x%08lx\n", Status
);
8280 /* Set LMPwd attribute*/
8281 Status
= SampSetObjectAttribute(UserObject
,
8286 if (!NT_SUCCESS(Status
))
8288 TRACE("failed with status 0x%08lx\n", Status
);
8292 /* Set NTPwd attribute*/
8293 Status
= SampSetObjectAttribute(UserObject
,
8298 if (!NT_SUCCESS(Status
))
8300 TRACE("failed with status 0x%08lx\n", Status
);
8304 /* Set LMPwdHistory attribute*/
8305 Status
= SampSetObjectAttribute(UserObject
,
8310 if (!NT_SUCCESS(Status
))
8312 TRACE("failed with status 0x%08lx\n", Status
);
8316 /* Set NTPwdHistory attribute*/
8317 Status
= SampSetObjectAttribute(UserObject
,
8322 if (!NT_SUCCESS(Status
))
8324 TRACE("failed with status 0x%08lx\n", Status
);
8328 /* FIXME: Set SecDesc attribute*/
8330 if (NT_SUCCESS(Status
))
8332 *UserHandle
= (SAMPR_HANDLE
)UserObject
;
8333 *RelativeId
= ulRid
;
8334 *GrantedAccess
= UserObject
->Access
;
8337 TRACE("returns with status 0x%08lx\n", Status
);
8346 SamrQueryDisplayInformation3(IN SAMPR_HANDLE DomainHandle
,
8347 IN DOMAIN_DISPLAY_INFORMATION DisplayInformationClass
,
8348 IN
unsigned long Index
,
8349 IN
unsigned long EntryCount
,
8350 IN
unsigned long PreferredMaximumLength
,
8351 OUT
unsigned long *TotalAvailable
,
8352 OUT
unsigned long *TotalReturned
,
8353 OUT PSAMPR_DISPLAY_INFO_BUFFER Buffer
)
8355 TRACE("%p %lu %lu %lu %lu %p %p %p\n",
8356 DomainHandle
, DisplayInformationClass
, Index
,
8357 EntryCount
, PreferredMaximumLength
, TotalAvailable
,
8358 TotalReturned
, Buffer
);
8360 return SamrQueryDisplayInformation(DomainHandle
,
8361 DisplayInformationClass
,
8364 PreferredMaximumLength
,
8374 SamrAddMultipleMembersToAlias(IN SAMPR_HANDLE AliasHandle
,
8375 IN PSAMPR_PSID_ARRAY MembersBuffer
)
8378 NTSTATUS Status
= STATUS_SUCCESS
;
8380 TRACE("SamrAddMultipleMembersToAlias(%p %p)\n",
8381 AliasHandle
, MembersBuffer
);
8383 for (i
= 0; i
< MembersBuffer
->Count
; i
++)
8385 Status
= SamrAddMemberToAlias(AliasHandle
,
8386 ((PSID
*)MembersBuffer
->Sids
)[i
]);
8388 if (Status
== STATUS_MEMBER_IN_ALIAS
)
8389 Status
= STATUS_SUCCESS
;
8391 if (!NT_SUCCESS(Status
))
8402 SamrRemoveMultipleMembersFromAlias(IN SAMPR_HANDLE AliasHandle
,
8403 IN PSAMPR_PSID_ARRAY MembersBuffer
)
8406 NTSTATUS Status
= STATUS_SUCCESS
;
8408 TRACE("SamrRemoveMultipleMembersFromAlias(%p %p)\n",
8409 AliasHandle
, MembersBuffer
);
8411 for (i
= 0; i
< MembersBuffer
->Count
; i
++)
8413 Status
= SamrRemoveMemberFromAlias(AliasHandle
,
8414 ((PSID
*)MembersBuffer
->Sids
)[i
]);
8416 if (Status
== STATUS_MEMBER_IN_ALIAS
)
8417 Status
= STATUS_SUCCESS
;
8419 if (!NT_SUCCESS(Status
))
8430 SamrOemChangePasswordUser2(IN handle_t BindingHandle
,
8431 IN PRPC_STRING ServerName
,
8432 IN PRPC_STRING UserName
,
8433 IN PSAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldLm
,
8434 IN PENCRYPTED_LM_OWF_PASSWORD OldLmOwfPasswordEncryptedWithNewLm
)
8437 return STATUS_NOT_IMPLEMENTED
;
8443 SamrUnicodeChangePasswordUser2(IN handle_t BindingHandle
,
8444 IN PRPC_UNICODE_STRING ServerName
,
8445 IN PRPC_UNICODE_STRING UserName
,
8446 IN PSAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldNt
,
8447 IN PENCRYPTED_NT_OWF_PASSWORD OldNtOwfPasswordEncryptedWithNewNt
,
8448 IN
unsigned char LmPresent
,
8449 IN PSAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldLm
,
8450 IN PENCRYPTED_LM_OWF_PASSWORD OldLmOwfPasswordEncryptedWithNewNt
)
8453 return STATUS_NOT_IMPLEMENTED
;
8459 SamrGetDomainPasswordInformation(IN handle_t BindingHandle
,
8460 IN PRPC_UNICODE_STRING Unused
,
8461 OUT PUSER_DOMAIN_PASSWORD_INFORMATION PasswordInformation
)
8464 return STATUS_NOT_IMPLEMENTED
;
8471 SamrConnect2(IN PSAMPR_SERVER_NAME ServerName
,
8472 OUT SAMPR_HANDLE
*ServerHandle
,
8473 IN ACCESS_MASK DesiredAccess
)
8475 TRACE("(%p %p %lx)\n", ServerName
, ServerHandle
, DesiredAccess
);
8477 return SamrConnect(ServerName
,
8486 SamrSetInformationUser2(IN SAMPR_HANDLE UserHandle
,
8487 IN USER_INFORMATION_CLASS UserInformationClass
,
8488 IN PSAMPR_USER_INFO_BUFFER Buffer
)
8490 TRACE("(%p %lu %p)\n", UserHandle
, UserInformationClass
, Buffer
);
8492 return SamrSetInformationUser(UserHandle
,
8493 UserInformationClass
,
8501 SamrSetBootKeyInformation(IN handle_t BindingHandle
) /* FIXME */
8504 return STATUS_NOT_IMPLEMENTED
;
8510 SamrGetBootKeyInformation(IN handle_t BindingHandle
) /* FIXME */
8513 return STATUS_NOT_IMPLEMENTED
;
8519 SamrConnect3(IN handle_t BindingHandle
) /* FIXME */
8522 return STATUS_NOT_IMPLEMENTED
;
8528 SamrConnect4(IN PSAMPR_SERVER_NAME ServerName
,
8529 OUT SAMPR_HANDLE
*ServerHandle
,
8530 IN
unsigned long ClientRevision
,
8531 IN ACCESS_MASK DesiredAccess
)
8534 return STATUS_NOT_IMPLEMENTED
;
8540 SamrUnicodeChangePasswordUser3(IN handle_t BindingHandle
) /* FIXME */
8543 return STATUS_NOT_IMPLEMENTED
;
8549 SamrConnect5(IN PSAMPR_SERVER_NAME ServerName
,
8550 IN ACCESS_MASK DesiredAccess
,
8551 IN
unsigned long InVersion
,
8552 IN SAMPR_REVISION_INFO
*InRevisionInfo
,
8553 OUT
unsigned long *OutVersion
,
8554 OUT SAMPR_REVISION_INFO
*OutRevisionInfo
,
8555 OUT SAMPR_HANDLE
*ServerHandle
)
8558 return STATUS_NOT_IMPLEMENTED
;
8564 SamrRidToSid(IN SAMPR_HANDLE ObjectHandle
,
8565 IN
unsigned long Rid
,
8569 return STATUS_NOT_IMPLEMENTED
;
8575 SamrSetDSRMPassword(IN handle_t BindingHandle
,
8576 IN PRPC_UNICODE_STRING Unused
,
8577 IN
unsigned long UserId
,
8578 IN PENCRYPTED_NT_OWF_PASSWORD EncryptedNtOwfPassword
)
8581 return STATUS_NOT_IMPLEMENTED
;
8587 SamrValidatePassword(IN handle_t Handle
,
8588 IN PASSWORD_POLICY_VALIDATION_TYPE ValidationType
,
8589 IN PSAM_VALIDATE_INPUT_ARG InputArg
,
8590 OUT PSAM_VALIDATE_OUTPUT_ARG
*OutputArg
)
8593 return STATUS_NOT_IMPLEMENTED
;