diff --git a/reactos/dll/win32/samsrv/samrpc.c b/reactos/dll/win32/samsrv/samrpc.c index 826bdc7f7f2..fc885fd02b1 100644 --- a/reactos/dll/win32/samsrv/samrpc.c +++ b/reactos/dll/win32/samsrv/samrpc.c @@ -7,18 +7,18 @@ * PROGRAMMERS: Eric Kohl */ -/* INCLUDES ****************************************************************/ +/* INCLUDES ******************************************************************/ #include "samsrv.h" WINE_DEFAULT_DEBUG_CHANNEL(samsrv); -/* GLOBALS ********************************************************************/ +/* GLOBALS *******************************************************************/ static SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY}; -/* FUNCTIONS ***************************************************************/ +/* FUNCTIONS *****************************************************************/ VOID SampStartRpcServer(VOID) @@ -4187,10 +4187,126 @@ NTAPI SamrRemoveMemberFromAlias(IN SAMPR_HANDLE AliasHandle, IN PRPC_SID MemberId) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PSAM_DB_OBJECT AliasObject; + LPWSTR MemberIdString = NULL; + HANDLE MembersKeyHandle = NULL; + HANDLE MemberKeyHandle = NULL; + ULONG ulValueCount; + NTSTATUS Status; + + TRACE("SamrRemoveMemberFromAlias(%p %p)\n", + AliasHandle, MemberId); + + /* Validate the alias handle */ + Status = SampValidateDbObject(AliasHandle, + SamDbAliasObject, + ALIAS_REMOVE_MEMBER, + &AliasObject); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + + ConvertSidToStringSidW(MemberId, &MemberIdString); + TRACE("Member SID: %S\n", MemberIdString); + + Status = SampRegOpenKey(AliasObject->MembersKeyHandle, + MemberIdString, + KEY_WRITE | KEY_QUERY_VALUE, + &MemberKeyHandle); + if (!NT_SUCCESS(Status)) + { + TRACE("SampRegOpenKey failed with status 0x%08lx\n", Status); + goto done; + } + + Status = SampRegDeleteValue(MemberKeyHandle, + AliasObject->Name); + if (!NT_SUCCESS(Status)) + { + TRACE("SampRegDeleteValue failed with status 0x%08lx\n", Status); + goto done; + } + + Status = SampRegQueryKeyInfo(MemberKeyHandle, + NULL, + &ulValueCount); + if (!NT_SUCCESS(Status)) + { + TRACE("SampRegQueryKeyInfo failed with status 0x%08lx\n", Status); + goto done; + } + + if (ulValueCount == 0) + { + SampRegCloseKey(MemberKeyHandle); + MemberKeyHandle = NULL; + + Status = SampRegDeleteKey(AliasObject->MembersKeyHandle, + MemberIdString); + if (!NT_SUCCESS(Status)) + { + TRACE("SampRegDeleteKey failed with status 0x%08lx\n", Status); + goto done; + } + } + + Status = SampRegOpenKey(AliasObject->KeyHandle, + L"Members", + KEY_WRITE | KEY_QUERY_VALUE, + &MembersKeyHandle); + if (!NT_SUCCESS(Status)) + { + TRACE("SampRegOpenKey failed with status 0x%08lx\n", Status); + goto done; + } + + Status = SampRegDeleteValue(MembersKeyHandle, + MemberIdString); + if (!NT_SUCCESS(Status)) + { + TRACE("SampRegDeleteValue failed with status 0x%08lx\n", Status); + goto done; + } + + Status = SampRegQueryKeyInfo(MembersKeyHandle, + NULL, + &ulValueCount); + if (!NT_SUCCESS(Status)) + { + TRACE("SampRegQueryKeyInfo failed with status 0x%08lx\n", Status); + goto done; + } + + if (ulValueCount == 0) + { + SampRegCloseKey(MembersKeyHandle); + MembersKeyHandle = NULL; + + Status = SampRegDeleteKey(AliasObject->KeyHandle, + L"Members"); + if (!NT_SUCCESS(Status)) + { + TRACE("SampRegDeleteKey failed with status 0x%08lx\n", Status); + goto done; + } + } + +done: + if (MemberKeyHandle != NULL) + SampRegCloseKey(MemberKeyHandle); + + if (MembersKeyHandle != NULL) + SampRegCloseKey(MembersKeyHandle); + + if (MemberIdString != NULL) + LocalFree(MemberIdString); + + return Status; } + /* Function 33 */ NTSTATUS NTAPI @@ -6338,10 +6454,28 @@ NTAPI SamrRemoveMultipleMembersFromAlias(IN SAMPR_HANDLE AliasHandle, IN PSAMPR_PSID_ARRAY MembersBuffer) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + ULONG i; + NTSTATUS Status = STATUS_SUCCESS; + + TRACE("SamrRemoveMultipleMembersFromAlias(%p %p)\n", + AliasHandle, MembersBuffer); + + for (i = 0; i < MembersBuffer->Count; i++) + { + Status = SamrRemoveMemberFromAlias(AliasHandle, + ((PSID *)MembersBuffer->Sids)[i]); + + if (Status == STATUS_MEMBER_IN_ALIAS) + Status = STATUS_SUCCESS; + + if (!NT_SUCCESS(Status)) + break; + } + + return Status; } + /* Function 54 */ NTSTATUS NTAPI