Author: ekohl Date: Thu Jun 7 10:31:17 2012 New Revision: 56704
URL: http://svn.reactos.org/svn/reactos?rev=56704&view=rev Log: [SAMLIB][SAMSRV] - Implement SamGetMembersInAlias and SamrGetMembersInAlias. - Add registry helper routines SampRegQueryKeyInfo, SampRegEnumerateValue and SampRegSetValue. - Remove unused SAM database code. - Store the name and members key (only for aliases and groups) in the database object.
Modified: trunk/reactos/dll/win32/samlib/samlib.c trunk/reactos/dll/win32/samlib/samlib.spec trunk/reactos/dll/win32/samsrv/database.c trunk/reactos/dll/win32/samsrv/registry.c trunk/reactos/dll/win32/samsrv/samrpc.c trunk/reactos/dll/win32/samsrv/samsrv.h trunk/reactos/include/ddk/ntsam.h
Modified: trunk/reactos/dll/win32/samlib/samlib.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samlib/samlib.c?r... ============================================================================== --- trunk/reactos/dll/win32/samlib/samlib.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samlib/samlib.c [iso-8859-1] Thu Jun 7 10:31:17 2012 @@ -303,6 +303,48 @@
NTSTATUS NTAPI +SamGetMembersInAlias(IN SAM_HANDLE AliasHandle, + OUT PSID **MemberIds, + OUT PULONG MemberCount) +{ + SAMPR_PSID_ARRAY_OUT SidArray; + NTSTATUS Status; + + TRACE("SamGetMembersInAlias(%p %p %p)\n", + AliasHandle, MemberIds, MemberCount); + + if ((MemberIds == NULL) || + (MemberCount == NULL)) + return STATUS_INVALID_PARAMETER; + + *MemberIds = NULL; + *MemberCount = 0; + + SidArray.Sids = NULL; + + RpcTryExcept + { + Status = SamrGetMembersInAlias((SAMPR_HANDLE)AliasHandle, + &SidArray); + if (NT_SUCCESS(Status)) + { + *MemberCount = SidArray.Count; + *MemberIds = (PSID *)(SidArray.Sids); + } + + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + return Status; +} + + +NTSTATUS +NTAPI SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle, IN PUNICODE_STRING Name, OUT PSID *DomainId)
Modified: trunk/reactos/dll/win32/samlib/samlib.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samlib/samlib.spe... ============================================================================== --- trunk/reactos/dll/win32/samlib/samlib.spec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samlib/samlib.spec [iso-8859-1] Thu Jun 7 10:31:17 2012 @@ -23,7 +23,7 @@ @ stub SamGetCompatibilityMode @ stub SamGetDisplayEnumerationIndex @ stub SamGetGroupsForUser -@ stub SamGetMembersInAlias +@ stdcall SamGetMembersInAlias(ptr ptr ptr) @ stub SamGetMembersInGroup @ stdcall SamLookupDomainInSamServer(ptr ptr ptr) @ stub SamLookupIdsInDomain
Modified: trunk/reactos/dll/win32/samsrv/database.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/database.c... ============================================================================== --- trunk/reactos/dll/win32/samsrv/database.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/database.c [iso-8859-1] Thu Jun 7 10:31:17 2012 @@ -44,210 +44,6 @@ return Status; }
-#if 0 -static BOOLEAN -LsapIsDatabaseInstalled(VOID) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyName; - HANDLE KeyHandle; - NTSTATUS Status; - - RtlInitUnicodeString(&KeyName, - L"Policy"); - - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - SecurityKeyHandle, - NULL); - - Status = RtlpNtOpenKey(&KeyHandle, - KEY_READ, - &ObjectAttributes, - 0); - if (!NT_SUCCESS(Status)) - return FALSE; - - NtClose(KeyHandle); - - return TRUE; -} - - -static NTSTATUS -LsapCreateDatabaseKeys(VOID) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyName; - HANDLE PolicyKeyHandle = NULL; - HANDLE AccountsKeyHandle = NULL; - HANDLE DomainsKeyHandle = NULL; - HANDLE SecretsKeyHandle = NULL; - NTSTATUS Status = STATUS_SUCCESS; - - TRACE("LsapInstallDatabase()\n"); - - /* Create the 'Policy' key */ - RtlInitUnicodeString(&KeyName, - L"Policy"); - - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - SecurityKeyHandle, - NULL); - - Status = NtCreateKey(&PolicyKeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - 0, - NULL); - if (!NT_SUCCESS(Status)) - { - ERR("Failed to create the 'Policy' key (Status: 0x%08lx)\n", Status); - goto Done; - } - - /* Create the 'Accounts' key */ - RtlInitUnicodeString(&KeyName, - L"Accounts"); - - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - PolicyKeyHandle, - NULL); - - Status = NtCreateKey(&AccountsKeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - 0, - NULL); - if (!NT_SUCCESS(Status)) - { - ERR("Failed to create the 'Accounts' key (Status: 0x%08lx)\n", Status); - goto Done; - } - - /* Create the 'Domains' key */ - RtlInitUnicodeString(&KeyName, - L"Domains"); - - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - PolicyKeyHandle, - NULL); - - Status = NtCreateKey(&DomainsKeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - 0, - NULL); - if (!NT_SUCCESS(Status)) - { - ERR("Failed to create the 'Domains' key (Status: 0x%08lx)\n", Status); - goto Done; - } - - /* Create the 'Secrets' key */ - RtlInitUnicodeString(&KeyName, - L"Secrets"); - - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - PolicyKeyHandle, - NULL); - - Status = NtCreateKey(&SecretsKeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - 0, - NULL); - if (!NT_SUCCESS(Status)) - { - ERR("Failed to create the 'Secrets' key (Status: 0x%08lx)\n", Status); - goto Done; - } - -Done: - if (SecretsKeyHandle != NULL) - NtClose(SecretsKeyHandle); - - if (DomainsKeyHandle != NULL) - NtClose(DomainsKeyHandle); - - if (AccountsKeyHandle != NULL) - NtClose(AccountsKeyHandle); - - if (PolicyKeyHandle != NULL) - NtClose(PolicyKeyHandle); - - TRACE("LsapInstallDatabase() done (Status: 0x%08lx)\n", Status); - - return Status; -} - - -static NTSTATUS -LsapCreateDatabaseObjects(VOID) -{ - PLSA_DB_OBJECT PolicyObject; - NTSTATUS Status; - - /* Open the 'Policy' object */ - Status = LsapOpenDbObject(NULL, - L"Policy", - LsaDbPolicyObject, - 0, - &PolicyObject); - if (!NT_SUCCESS(Status)) - return Status; - - LsapSetObjectAttribute(PolicyObject, - L"PolPrDmN", - NULL, - 0); - - LsapSetObjectAttribute(PolicyObject, - L"PolPrDmS", - NULL, - 0); - - LsapSetObjectAttribute(PolicyObject, - L"PolAcDmN", - NULL, - 0); - - LsapSetObjectAttribute(PolicyObject, - L"PolAcDmS", - NULL, - 0); - - /* Close the 'Policy' object */ - LsapCloseDbObject(PolicyObject); - - return STATUS_SUCCESS; -} - - -static NTSTATUS -LsapUpdateDatabase(VOID) -{ - return STATUS_SUCCESS; -} -#endif -
NTSTATUS SampInitDatabase(VOID) @@ -310,7 +106,8 @@ UNICODE_STRING KeyName; HANDLE ParentKeyHandle; HANDLE ContainerKeyHandle = NULL; - HANDLE ObjectKeyHandle; + HANDLE ObjectKeyHandle = NULL; + HANDLE MembersKeyHandle = NULL; NTSTATUS Status;
if (DbObject == NULL) @@ -359,6 +156,28 @@ 0, NULL);
+ if ((ObjectType == SamDbAliasObject) || + (ObjectType == SamDbGroupObject)) + { + /* Open the object key */ + RtlInitUnicodeString(&KeyName, + L"Members"); + + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE | OBJ_OPENIF, + ContainerKeyHandle, + NULL); + + Status = NtCreateKey(&MembersKeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + 0, + NULL); + } + NtClose(ContainerKeyHandle);
if (!NT_SUCCESS(Status)) @@ -395,15 +214,32 @@ sizeof(SAM_DB_OBJECT)); if (NewObject == NULL) { + if (MembersKeyHandle != NULL) + NtClose(MembersKeyHandle); NtClose(ObjectKeyHandle); return STATUS_NO_MEMORY; } + + NewObject->Name = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + (wcslen(ObjectName) + 1) * sizeof(WCHAR)); + if (NewObject == NULL) + { + if (MembersKeyHandle != NULL) + NtClose(MembersKeyHandle); + NtClose(ObjectKeyHandle); + RtlFreeHeap(RtlGetProcessHeap(), 0, NewObject); + return STATUS_NO_MEMORY; + } + + wcscpy(NewObject->Name, ObjectName);
NewObject->Signature = SAMP_DB_SIGNATURE; NewObject->RefCount = 1; NewObject->ObjectType = ObjectType; NewObject->Access = DesiredAccess; NewObject->KeyHandle = ObjectKeyHandle; + NewObject->MembersKeyHandle = MembersKeyHandle; NewObject->ParentObject = ParentObject;
if (ParentObject != NULL) @@ -428,7 +264,8 @@ UNICODE_STRING KeyName; HANDLE ParentKeyHandle; HANDLE ContainerKeyHandle = NULL; - HANDLE ObjectKeyHandle; + HANDLE ObjectKeyHandle = NULL; + HANDLE MembersKeyHandle = NULL; NTSTATUS Status;
if (DbObject == NULL) @@ -473,6 +310,28 @@ KEY_ALL_ACCESS, &ObjectAttributes);
+ if ((ObjectType == SamDbAliasObject) || + (ObjectType == SamDbGroupObject)) + { + /* Open the object key */ + RtlInitUnicodeString(&KeyName, + L"Members"); + + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE | OBJ_OPENIF, + ContainerKeyHandle, + NULL); + + Status = NtCreateKey(&MembersKeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + 0, + NULL); + } + NtClose(ContainerKeyHandle);
if (!NT_SUCCESS(Status)) @@ -506,15 +365,31 @@ sizeof(SAM_DB_OBJECT)); if (NewObject == NULL) { + if (MembersKeyHandle != NULL) + NtClose(MembersKeyHandle); NtClose(ObjectKeyHandle); return STATUS_NO_MEMORY; }
+ NewObject->Name = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + (wcslen(ObjectName) + 1) * sizeof(WCHAR)); + if (NewObject == NULL) + { + if (MembersKeyHandle != NULL) + NtClose(MembersKeyHandle); + NtClose(ObjectKeyHandle); + RtlFreeHeap(RtlGetProcessHeap(), 0, NewObject); + return STATUS_NO_MEMORY; + } + + wcscpy(NewObject->Name, ObjectName); NewObject->Signature = SAMP_DB_SIGNATURE; NewObject->RefCount = 1; NewObject->ObjectType = ObjectType; NewObject->Access = DesiredAccess; NewObject->KeyHandle = ObjectKeyHandle; + NewObject->MembersKeyHandle = MembersKeyHandle; NewObject->ParentObject = ParentObject;
if (ParentObject != NULL) @@ -585,8 +460,14 @@ if (DbObject->KeyHandle != NULL) NtClose(DbObject->KeyHandle);
+ if (DbObject->MembersKeyHandle != NULL) + NtClose(DbObject->MembersKeyHandle); + if (DbObject->ParentObject != NULL) ParentObject = DbObject->ParentObject; + + if (DbObject->Name != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject->Name);
RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject);
Modified: trunk/reactos/dll/win32/samsrv/registry.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/registry.c... ============================================================================== --- trunk/reactos/dll/win32/samsrv/registry.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/registry.c [iso-8859-1] Thu Jun 7 10:31:17 2012 @@ -15,6 +15,14 @@
/* FUNCTIONS ***************************************************************/
+static +BOOLEAN +IsStringType(ULONG Type) +{ + return (Type == REG_SZ) || (Type == REG_EXPAND_SZ) || (Type == REG_MULTI_SZ); +} + + NTSTATUS SampRegCloseKey(IN HANDLE KeyHandle) { @@ -132,32 +140,148 @@
NTSTATUS -SampRegSetValue(HANDLE KeyHandle, - LPWSTR ValueName, - ULONG Type, - LPVOID Data, - ULONG DataLength) -{ - UNICODE_STRING Name; - - RtlInitUnicodeString(&Name, - ValueName); - - return ZwSetValueKey(KeyHandle, - &Name, - 0, - Type, - Data, - DataLength); -} - - -NTSTATUS -SampRegQueryValue(HANDLE KeyHandle, - LPWSTR ValueName, - PULONG Type OPTIONAL, - LPVOID Data OPTIONAL, - PULONG DataLength OPTIONAL) +SampRegQueryKeyInfo(IN HANDLE KeyHandle, + OUT PULONG SubKeyCount, + OUT PULONG ValueCount) +{ + KEY_FULL_INFORMATION FullInfoBuffer; + ULONG Length; + NTSTATUS Status; + + FullInfoBuffer.ClassLength = 0; + FullInfoBuffer.ClassOffset = FIELD_OFFSET(KEY_FULL_INFORMATION, Class); + + Status = NtQueryKey(KeyHandle, + KeyFullInformation, + &FullInfoBuffer, + sizeof(KEY_FULL_INFORMATION), + &Length); + TRACE("NtQueryKey() returned status 0x%08lX\n", Status); + if (!NT_SUCCESS(Status)) + return Status; + + if (SubKeyCount != NULL) + *SubKeyCount = FullInfoBuffer.SubKeys; + + if (ValueCount != NULL) + *ValueCount = FullInfoBuffer.Values; + + return Status; +} + + +NTSTATUS +SampRegEnumerateValue(IN HANDLE KeyHandle, + IN ULONG Index, + OUT LPWSTR Name, + IN OUT PULONG NameLength, + OUT PULONG Type OPTIONAL, + OUT PVOID Data OPTIONAL, + IN OUT PULONG DataLength OPTIONAL) +{ + PKEY_VALUE_FULL_INFORMATION ValueInfo = NULL; + ULONG BufferLength = 0; + ULONG ReturnedLength; + NTSTATUS Status; + + TRACE("Index: %lu\n", Index); + + /* Calculate the required buffer length */ + BufferLength = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name); + BufferLength += (MAX_PATH + 1) * sizeof(WCHAR); + if (Data != NULL) + BufferLength += *DataLength; + + /* Allocate the value buffer */ + ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); + if (ValueInfo == NULL) + return STATUS_NO_MEMORY; + + /* Enumerate the value*/ + Status = ZwEnumerateValueKey(KeyHandle, + Index, + KeyValueFullInformation, + ValueInfo, + BufferLength, + &ReturnedLength); + if (NT_SUCCESS(Status)) + { + if (Name != NULL) + { + /* Check if the name fits */ + if (ValueInfo->NameLength < (*NameLength * sizeof(WCHAR))) + { + /* Copy it */ + RtlMoveMemory(Name, + ValueInfo->Name, + ValueInfo->NameLength); + + /* Terminate the string */ + Name[ValueInfo->NameLength / sizeof(WCHAR)] = 0; + } + else + { + /* Otherwise, we ran out of buffer space */ + Status = STATUS_BUFFER_OVERFLOW; + goto done; + } + } + + if (Data != NULL) + { + /* Check if the data fits */ + if (ValueInfo->DataLength <= *DataLength) + { + /* Copy it */ + RtlMoveMemory(Data, + (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset), + ValueInfo->DataLength); + + /* if the type is REG_SZ and data is not 0-terminated + * and there is enough space in the buffer NT appends a \0 */ + if (IsStringType(ValueInfo->Type) && + ValueInfo->DataLength <= *DataLength - sizeof(WCHAR)) + { + WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength); + if ((ptr > (WCHAR *)Data) && ptr[-1]) + *ptr = 0; + } + } + else + { + Status = STATUS_BUFFER_OVERFLOW; + goto done; + } + } + } + +done: + if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW)) + { + if (Type != NULL) + *Type = ValueInfo->Type; + + if (NameLength != NULL) + *NameLength = ValueInfo->NameLength; + + if (DataLength != NULL) + *DataLength = ValueInfo->DataLength; + } + + /* Free the buffer and return status */ + if (ValueInfo) + RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo); + + return Status; +} + + +NTSTATUS +SampRegQueryValue(IN HANDLE KeyHandle, + IN LPWSTR ValueName, + OUT PULONG Type OPTIONAL, + OUT PVOID Data OPTIONAL, + IN OUT PULONG DataLength OPTIONAL) { PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; UNICODE_STRING Name; @@ -200,6 +324,16 @@ RtlMoveMemory(Data, ValueInfo->Data, ValueInfo->DataLength); + + /* if the type is REG_SZ and data is not 0-terminated + * and there is enough space in the buffer NT appends a \0 */ + if (IsStringType(ValueInfo->Type) && + ValueInfo->DataLength <= *DataLength - sizeof(WCHAR)) + { + WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength); + if ((ptr > (WCHAR *)Data) && ptr[-1]) + *ptr = 0; + } }
/* Free the memory and return status */ @@ -210,3 +344,24 @@
return Status; } + + +NTSTATUS +SampRegSetValue(HANDLE KeyHandle, + LPWSTR ValueName, + ULONG Type, + LPVOID Data, + ULONG DataLength) +{ + UNICODE_STRING Name; + + RtlInitUnicodeString(&Name, + ValueName); + + return ZwSetValueKey(KeyHandle, + &Name, + 0, + Type, + Data, + DataLength); +}
Modified: trunk/reactos/dll/win32/samsrv/samrpc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samrpc.c?r... ============================================================================== --- trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] Thu Jun 7 10:31:17 2012 @@ -1186,6 +1186,8 @@ PSAM_DB_OBJECT AliasObject; LPWSTR MemberIdString = NULL; HANDLE MembersKeyHandle = NULL; + HANDLE MemberKeyHandle = NULL; + ULONG MemberIdLength; NTSTATUS Status;
TRACE("SamrAddMemberToAlias(%p %p)\n", @@ -1205,6 +1207,8 @@ ConvertSidToStringSidW(MemberId, &MemberIdString); TRACE("Member SID: %S\n", MemberIdString);
+ MemberIdLength = RtlLengthSid(MemberId); + Status = SampRegCreateKey(AliasObject->KeyHandle, L"Members", KEY_WRITE, @@ -1218,10 +1222,39 @@ Status = SampRegSetValue(MembersKeyHandle, MemberIdString, REG_BINARY, - NULL, - 0); + MemberId, + MemberIdLength); + if (!NT_SUCCESS(Status)) + { + TRACE("SampRegSetValue failed with status 0x%08lx\n", Status); + goto done; + } + + Status = SampRegCreateKey(AliasObject->MembersKeyHandle, + MemberIdString, + KEY_WRITE, + &MemberKeyHandle); + if (!NT_SUCCESS(Status)) + { + TRACE("SampRegCreateKey failed with status 0x%08lx\n", Status); + goto done; + } + + Status = SampRegSetValue(MemberKeyHandle, + AliasObject->Name, + REG_BINARY, + MemberId, + MemberIdLength); + if (!NT_SUCCESS(Status)) + { + TRACE("SampRegSetValue failed with status 0x%08lx\n", Status); + goto done; + }
done: + if (MemberKeyHandle != NULL) + SampRegCloseKey(MemberKeyHandle); + if (MembersKeyHandle != NULL) SampRegCloseKey(MembersKeyHandle);
@@ -1247,8 +1280,129 @@ SamrGetMembersInAlias(IN SAMPR_HANDLE AliasHandle, OUT PSAMPR_PSID_ARRAY_OUT Members) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PSAM_DB_OBJECT AliasObject; + HANDLE MembersKeyHandle = NULL; + PSAMPR_SID_INFORMATION MemberArray = NULL; + ULONG ValueCount = 0; + ULONG DataLength; + ULONG Index; + NTSTATUS Status; + + TRACE("SamrGetMembersInAlias(%p %p %p)\n", + AliasHandle, Members); + + /* Validate the alias handle */ + Status = SampValidateDbObject(AliasHandle, + SamDbAliasObject, + ALIAS_LIST_MEMBERS, + &AliasObject); + if (!NT_SUCCESS(Status)) + { + ERR("failed with status 0x%08lx\n", Status); + return Status; + } + + /* Open the members key of the alias objct */ + Status = SampRegOpenKey(AliasObject->KeyHandle, + L"Members", + KEY_READ, + &MembersKeyHandle); + if (!NT_SUCCESS(Status)) + { + ERR("SampRegOpenKey failed with status 0x%08lx\n", Status); + return Status; + } + + /* Get the number of members */ + Status = SampRegQueryKeyInfo(MembersKeyHandle, + NULL, + &ValueCount); + if (!NT_SUCCESS(Status)) + { + ERR("SampRegQueryKeyInfo failed with status 0x%08lx\n", Status); + goto done; + } + + /* Allocate the member array */ + MemberArray = midl_user_allocate(ValueCount * sizeof(SAMPR_SID_INFORMATION)); + if (MemberArray == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + /* Enumerate the members */ + Index = 0; + while (TRUE) + { + /* Get the size of the next SID */ + DataLength = 0; + Status = SampRegEnumerateValue(MembersKeyHandle, + Index, + NULL, + NULL, + NULL, + NULL, + &DataLength); + if (!NT_SUCCESS(Status)) + { + if (Status == STATUS_NO_MORE_ENTRIES) + Status = STATUS_SUCCESS; + break; + } + + /* Allocate a buffer for the SID */ + MemberArray[Index].SidPointer = midl_user_allocate(DataLength); + if (MemberArray[Index].SidPointer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + /* Read the SID into the buffer */ + Status = SampRegEnumerateValue(MembersKeyHandle, + Index, + NULL, + NULL, + NULL, + (PVOID)MemberArray[Index].SidPointer, + &DataLength); + if (!NT_SUCCESS(Status)) + { + goto done; + } + + Index++; + } + + /* Return the number of members and the member array */ + if (NT_SUCCESS(Status)) + { + Members->Count = ValueCount; + Members->Sids = MemberArray; + } + +done: + /* Clean up the members array and the SID buffers if something failed */ + if (!NT_SUCCESS(Status)) + { + if (MemberArray != NULL) + { + for (Index = 0; Index < ValueCount; Index++) + { + if (MemberArray[Index].SidPointer != NULL) + midl_user_free(MemberArray[Index].SidPointer); + } + + midl_user_free(MemberArray); + } + } + + /* Close the members key */ + if (MembersKeyHandle != NULL) + SampRegCloseKey(MembersKeyHandle); + + return Status; }
/* Function 34 */
Modified: trunk/reactos/dll/win32/samsrv/samsrv.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samsrv.h?r... ============================================================================== --- trunk/reactos/dll/win32/samsrv/samsrv.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/samsrv.h [iso-8859-1] Thu Jun 7 10:31:17 2012 @@ -42,7 +42,9 @@ SAM_DB_OBJECT_TYPE ObjectType; ULONG RefCount; ACCESS_MASK Access; + LPWSTR Name; HANDLE KeyHandle; + HANDLE MembersKeyHandle; // only used by Aliases and Groups struct _SAM_DB_OBJECT *ParentObject; } SAM_DB_OBJECT, *PSAM_DB_OBJECT;
@@ -127,6 +129,20 @@ OUT HANDLE KeyHandle);
NTSTATUS +SampRegQueryKeyInfo(IN HANDLE KeyHandle, + OUT PULONG SubKeyCount, + OUT PULONG ValueCount); + +NTSTATUS +SampRegEnumerateValue(IN HANDLE KeyHandle, + IN ULONG Index, + OUT LPWSTR Name, + IN OUT PULONG NameLength, + OUT PULONG Type OPTIONAL, + OUT PVOID Data OPTIONAL, + IN OUT PULONG DataLength OPTIONAL); + +NTSTATUS SampRegQueryValue(IN HANDLE KeyHandle, IN LPWSTR ValueName, OUT PULONG Type OPTIONAL,
Modified: trunk/reactos/include/ddk/ntsam.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/ntsam.h?rev=567... ============================================================================== --- trunk/reactos/include/ddk/ntsam.h [iso-8859-1] (original) +++ trunk/reactos/include/ddk/ntsam.h [iso-8859-1] Thu Jun 7 10:31:17 2012 @@ -166,6 +166,12 @@
NTSTATUS NTAPI +SamGetMembersInAlias(IN SAM_HANDLE AliasHandle, + OUT PSID **MemberIds, + OUT PULONG MemberCount); + +NTSTATUS +NTAPI SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle, IN PUNICODE_STRING Name, OUT PSID *DomainId);