From d59abae16377468ce0a955a016a0084c7cd55ba1 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 6 Oct 2012 19:37:10 +0000 Subject: [PATCH] [LSASRV] - Make LsarLookupNames, LsarLookupNames2 and LsarLookupNames4 call LsapLookupNames and convert the results where this is needed. - Split the lookup code in LsapLookupSids into separate functions. svn path=/trunk/; revision=57503 --- reactos/dll/win32/lsasrv/lsarpc.c | 185 ++++++++++++--------- reactos/dll/win32/lsasrv/lsasrv.h | 3 + reactos/dll/win32/lsasrv/sids.c | 258 +++++++++++++++++++++--------- 3 files changed, 298 insertions(+), 148 deletions(-) diff --git a/reactos/dll/win32/lsasrv/lsarpc.c b/reactos/dll/win32/lsasrv/lsarpc.c index fdfb250b434..ac4c86b5ee0 100644 --- a/reactos/dll/win32/lsasrv/lsarpc.c +++ b/reactos/dll/win32/lsasrv/lsarpc.c @@ -550,89 +550,53 @@ NTSTATUS WINAPI LsarLookupNames( LSAP_LOOKUP_LEVEL LookupLevel, DWORD *MappedCount) { - SID_IDENTIFIER_AUTHORITY IdentifierAuthority = {SECURITY_NT_AUTHORITY}; - static const UNICODE_STRING DomainName = RTL_CONSTANT_STRING(L"DOMAIN"); - PLSAPR_REFERENCED_DOMAIN_LIST OutputDomains = NULL; - PLSA_TRANSLATED_SID OutputSids = NULL; - ULONG OutputSidsLength; + LSAPR_TRANSLATED_SIDS_EX2 TranslatedSidsEx2; ULONG i; - PSID Sid; - ULONG SidLength; NTSTATUS Status; - TRACE("LsarLookupNames(%p, %lu, %p, %p, %p, %d, %p)\n", + TRACE("(%p %lu %p %p %p %d %p)\n", PolicyHandle, Count, Names, ReferencedDomains, TranslatedSids, LookupLevel, MappedCount); - TranslatedSids->Entries = Count; + TranslatedSids->Entries = 0; TranslatedSids->Sids = NULL; *ReferencedDomains = NULL; - OutputSidsLength = Count * sizeof(LSA_TRANSLATED_SID); - OutputSids = MIDL_user_allocate(OutputSidsLength); - if (OutputSids == NULL) - { - return STATUS_INSUFFICIENT_RESOURCES; - } + if (Count == 0) + return STATUS_NONE_MAPPED; - RtlZeroMemory(OutputSids, OutputSidsLength); + TranslatedSidsEx2.Entries = 0; + TranslatedSidsEx2.Sids = NULL; - OutputDomains = MIDL_user_allocate(sizeof(LSAPR_REFERENCED_DOMAIN_LIST)); - if (OutputDomains == NULL) - { - MIDL_user_free(OutputSids); - return STATUS_INSUFFICIENT_RESOURCES; - } - - OutputDomains->Entries = Count; - OutputDomains->Domains = MIDL_user_allocate(Count * sizeof(LSA_TRUST_INFORMATION)); - if (OutputDomains->Domains == NULL) - { - MIDL_user_free(OutputDomains); - MIDL_user_free(OutputSids); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Status = RtlAllocateAndInitializeSid(&IdentifierAuthority, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, - 0, 0, 0, 0, 0, 0, - &Sid); + Status = LsapLookupNames(Count, + Names, + ReferencedDomains, + &TranslatedSidsEx2, + LookupLevel, + MappedCount, + 0, + 0); if (!NT_SUCCESS(Status)) - { - MIDL_user_free(OutputDomains->Domains); - MIDL_user_free(OutputDomains); - MIDL_user_free(OutputSids); return Status; - } - SidLength = RtlLengthSid(Sid); - - for (i = 0; i < Count; i++) + TranslatedSids->Entries = TranslatedSidsEx2.Entries; + TranslatedSids->Sids = MIDL_user_allocate(TranslatedSids->Entries * sizeof(LSA_TRANSLATED_SID)); + if (TranslatedSids->Sids == NULL) { - OutputDomains->Domains[i].Sid = MIDL_user_allocate(SidLength); - RtlCopyMemory(OutputDomains->Domains[i].Sid, Sid, SidLength); - - OutputDomains->Domains[i].Name.Buffer = MIDL_user_allocate(DomainName.MaximumLength); - OutputDomains->Domains[i].Name.Length = DomainName.Length; - OutputDomains->Domains[i].Name.MaximumLength = DomainName.MaximumLength; - RtlCopyMemory(OutputDomains->Domains[i].Name.Buffer, DomainName.Buffer, DomainName.MaximumLength); + MIDL_user_free(TranslatedSidsEx2.Sids); + MIDL_user_free(*ReferencedDomains); + *ReferencedDomains = NULL; + return STATUS_INSUFFICIENT_RESOURCES; } - for (i = 0; i < Count; i++) + for (i = 0; i < TranslatedSidsEx2.Entries; i++) { - OutputSids[i].Use = SidTypeWellKnownGroup; - OutputSids[i].RelativeId = DOMAIN_USER_RID_ADMIN; //DOMAIN_ALIAS_RID_ADMINS; - OutputSids[i].DomainIndex = i; + TranslatedSids->Sids[i].Use = TranslatedSidsEx2.Sids[i].Use; + TranslatedSids->Sids[i].RelativeId = LsapGetRelativeIdFromSid(TranslatedSidsEx2.Sids[i].Sid); + TranslatedSids->Sids[i].DomainIndex = TranslatedSidsEx2.Sids[i].DomainIndex; } - *ReferencedDomains = OutputDomains; - - *MappedCount = Count; - - TranslatedSids->Entries = Count; - TranslatedSids->Sids = OutputSids; + MIDL_user_free(TranslatedSidsEx2.Sids); return STATUS_SUCCESS; } @@ -658,14 +622,11 @@ NTSTATUS WINAPI LsarLookupSids( /* FIXME: Fail, if there is an invalid SID in the SidEnumBuffer */ TranslatedNames->Entries = SidEnumBuffer->Entries; - TranslatedNames->Names = MIDL_user_allocate(SidEnumBuffer->Entries * sizeof(LSAPR_TRANSLATED_NAME)); - if (TranslatedNames->Names == NULL) - return STATUS_INSUFFICIENT_RESOURCES; - + TranslatedNames->Names = NULL; *ReferencedDomains = NULL; TranslatedNamesEx.Entries = SidEnumBuffer->Entries; - TranslatedNamesEx.Names = NULL;; + TranslatedNamesEx.Names = NULL; Status = LsapLookupSids(SidEnumBuffer, ReferencedDomains, @@ -675,9 +636,16 @@ NTSTATUS WINAPI LsarLookupSids( 0, 0); if (!NT_SUCCESS(Status)) + return Status; + + TranslatedNames->Entries = SidEnumBuffer->Entries; + TranslatedNames->Names = MIDL_user_allocate(SidEnumBuffer->Entries * sizeof(LSAPR_TRANSLATED_NAME)); + if (TranslatedNames->Names == NULL) { MIDL_user_free(TranslatedNamesEx.Names); - return Status; + MIDL_user_free(*ReferencedDomains); + *ReferencedDomains = NULL; + return STATUS_INSUFFICIENT_RESOURCES; } for (i = 0; i < TranslatedNamesEx.Entries; i++) @@ -1977,8 +1945,56 @@ NTSTATUS WINAPI LsarLookupNames2( DWORD LookupOptions, DWORD ClientRevision) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + LSAPR_TRANSLATED_SIDS_EX2 TranslatedSidsEx2; + ULONG i; + NTSTATUS Status; + + TRACE("(%p %lu %p %p %p %d %p %lu %lu)\n", + PolicyHandle, Count, Names, ReferencedDomains, TranslatedSids, + LookupLevel, MappedCount, LookupOptions, ClientRevision); + + TranslatedSids->Entries = 0; + TranslatedSids->Sids = NULL; + *ReferencedDomains = NULL; + + if (Count == 0) + return STATUS_NONE_MAPPED; + + TranslatedSidsEx2.Entries = 0; + TranslatedSidsEx2.Sids = NULL; + + Status = LsapLookupNames(Count, + Names, + ReferencedDomains, + &TranslatedSidsEx2, + LookupLevel, + MappedCount, + LookupOptions, + ClientRevision); + if (!NT_SUCCESS(Status)) + return Status; + + TranslatedSids->Entries = TranslatedSidsEx2.Entries; + TranslatedSids->Sids = MIDL_user_allocate(TranslatedSids->Entries * sizeof(LSA_TRANSLATED_SID)); + if (TranslatedSids->Sids == NULL) + { + MIDL_user_free(TranslatedSidsEx2.Sids); + MIDL_user_free(*ReferencedDomains); + *ReferencedDomains = NULL; + return STATUS_INSUFFICIENT_RESOURCES; + } + + for (i = 0; i < TranslatedSidsEx2.Entries; i++) + { + TranslatedSids->Sids[i].Use = TranslatedSidsEx2.Sids[i].Use; + TranslatedSids->Sids[i].RelativeId = LsapGetRelativeIdFromSid(TranslatedSidsEx2.Sids[i].Sid); + TranslatedSids->Sids[i].DomainIndex = TranslatedSidsEx2.Sids[i].DomainIndex; + TranslatedSids->Sids[i].Flags = TranslatedSidsEx2.Sids[i].Flags; + } + + MIDL_user_free(TranslatedSidsEx2.Sids); + + return STATUS_SUCCESS; } @@ -2081,7 +2097,7 @@ NTSTATUS WINAPI LsarLookupNames3( { NTSTATUS Status; - TRACE("LsarLookupNames3(%p, %lu, %p, %p, %p, %d, %p, %lu, %lu)\n", + TRACE("(%p %lu %p %p %p %d %p %lu %lu)\n", PolicyHandle, Count, Names, ReferencedDomains, TranslatedSids, LookupLevel, MappedCount, LookupOptions, ClientRevision); @@ -2223,8 +2239,29 @@ NTSTATUS WINAPI LsarLookupNames4( DWORD LookupOptions, DWORD ClientRevision) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + + TRACE("(%p %lu %p %p %p %d %p %lu %lu)\n", + RpcHandle, Count, Names, ReferencedDomains, TranslatedSids, + LookupLevel, MappedCount, LookupOptions, ClientRevision); + + TranslatedSids->Entries = 0; + TranslatedSids->Sids = NULL; + *ReferencedDomains = NULL; + + if (Count == 0) + return STATUS_NONE_MAPPED; + + Status = LsapLookupNames(Count, + Names, + ReferencedDomains, + TranslatedSids, + LookupLevel, + MappedCount, + LookupOptions, + ClientRevision); + + return Status; } diff --git a/reactos/dll/win32/lsasrv/lsasrv.h b/reactos/dll/win32/lsasrv/lsasrv.h index 25fdf21aba5..e66bb667d98 100644 --- a/reactos/dll/win32/lsasrv/lsasrv.h +++ b/reactos/dll/win32/lsasrv/lsasrv.h @@ -192,6 +192,9 @@ LsarpEnumeratePrivileges(DWORD *EnumerationContext, NTSTATUS LsapInitSids(VOID); +ULONG +LsapGetRelativeIdFromSid(PSID Sid); + NTSTATUS LsapLookupNames(DWORD Count, PRPC_UNICODE_STRING Names, diff --git a/reactos/dll/win32/lsasrv/sids.c b/reactos/dll/win32/lsasrv/sids.c index af14d8a12de..71374a002b0 100644 --- a/reactos/dll/win32/lsasrv/sids.c +++ b/reactos/dll/win32/lsasrv/sids.c @@ -808,6 +808,18 @@ LsapAddDomainToDomainsList(PLSAPR_REFERENCED_DOMAIN_LIST ReferencedDomains, } +ULONG +LsapGetRelativeIdFromSid(PSID Sid_) +{ + PISID Sid = Sid_; + + if (Sid->SubAuthorityCount != 0) + return Sid->SubAuthority[Sid->SubAuthorityCount - 1]; + + return 0; +} + + NTSTATUS LsapLookupNames(DWORD Count, PRPC_UNICODE_STRING Names, @@ -824,10 +836,6 @@ LsapLookupNames(DWORD Count, PRPC_UNICODE_STRING AccountNames = NULL; ULONG SidsBufferLength; ULONG DomainIndex; -// ULONG DomainSidLength; -// ULONG AccountSidLength; -// PSID DomainSid; -// PSID AccountSid; ULONG i; ULONG Mapped = 0; NTSTATUS Status = STATUS_SUCCESS; @@ -1006,6 +1014,154 @@ done: } +static NTSTATUS +LsapLookupWellKnownSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer, + PLSAPR_TRANSLATED_NAME_EX NamesBuffer, + PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer, + PULONG Mapped) +{ + PWELL_KNOWN_SID ptr, ptr2; + LPWSTR SidString = NULL; + ULONG DomainIndex; + ULONG i; + NTSTATUS Status = STATUS_SUCCESS; + + for (i = 0; i < SidEnumBuffer->Entries; i++) + { + /* Ignore SIDs which are already mapped */ + if (NamesBuffer[i].Use != SidTypeUnknown) + continue; + + ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString); + TRACE("Unmapped SID: %S\n", SidString); + LocalFree(SidString); + SidString = NULL; + + ptr = LsapLookupWellKnownSid(SidEnumBuffer->SidInfo[i].Sid); + if (ptr != NULL) + { + NamesBuffer[i].Use = ptr->Use; + NamesBuffer[i].Flags = 0; + + NamesBuffer[i].Name.Buffer = MIDL_user_allocate(ptr->Name.MaximumLength); + NamesBuffer[i].Name.Length = ptr->Name.Length; + NamesBuffer[i].Name.MaximumLength = ptr->Name.MaximumLength; + RtlCopyMemory(NamesBuffer[i].Name.Buffer, ptr->Name.Buffer, ptr->Name.MaximumLength); + + ptr2= LsapLookupWellKnownName(&ptr->Domain); + if (ptr2 != NULL) + { + Status = LsapAddDomainToDomainsList(DomainsBuffer, + &ptr2->Name, + ptr2->Sid, + &DomainIndex); + if (NT_SUCCESS(Status)) + NamesBuffer[i].DomainIndex = DomainIndex; + } + + TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name); + + (*Mapped)++; + } + } + + return Status; +} + + +static NTSTATUS +LsapLookupLocalDomainSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer, + PLSAPR_TRANSLATED_NAME_EX NamesBuffer, + PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer, + PULONG Mapped) +{ + LPWSTR SidString = NULL; + ULONG i; + + for (i = 0; i < SidEnumBuffer->Entries; i++) + { + /* Ignore SIDs which are already mapped */ + if (NamesBuffer[i].Use != SidTypeUnknown) + continue; + + ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString); + TRACE("Unmapped SID: %S\n", SidString); + LocalFree(SidString); + SidString = NULL; + } + + return STATUS_SUCCESS; +} + + +static NTSTATUS +LsapLookupUnknownSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer, + PLSAPR_TRANSLATED_NAME_EX NamesBuffer, + PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer, + PULONG Mapped) +{ + SID_IDENTIFIER_AUTHORITY IdentifierAuthority = {SECURITY_NT_AUTHORITY}; + static const UNICODE_STRING DomainName = RTL_CONSTANT_STRING(L"DOMAIN"); + static const UNICODE_STRING AdminName = RTL_CONSTANT_STRING(L"Administrator"); + PSID AdminsSid = NULL; + LPWSTR SidString = NULL; + ULONG SidLength; + ULONG DomainIndex; + ULONG i; + NTSTATUS Status; + + Status = RtlAllocateAndInitializeSid(&IdentifierAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &AdminsSid); + if (!NT_SUCCESS(Status)) + goto done; + + SidLength = RtlLengthSid(AdminsSid); + + for (i = 0; i < SidEnumBuffer->Entries; i++) + { + /* Ignore SIDs which are already mapped */ + if (NamesBuffer[i].Use != SidTypeUnknown) + continue; + + + ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString); + TRACE("Unmapped SID: %S\n", SidString); + LocalFree(SidString); + SidString = NULL; + + + /* Hack: Map the SID to the Admin Account if it is not a well-known SID */ + NamesBuffer[i].Use = SidTypeUser; + NamesBuffer[i].Flags = 0; + NamesBuffer[i].Name.Length = AdminName.Length; + NamesBuffer[i].Name.MaximumLength = AdminName.MaximumLength; + NamesBuffer[i].Name.Buffer = MIDL_user_allocate(AdminName.MaximumLength); + RtlCopyMemory(NamesBuffer[i].Name.Buffer, AdminName.Buffer, AdminName.MaximumLength); + + Status = LsapAddDomainToDomainsList(DomainsBuffer, + (PUNICODE_STRING)&DomainName, + AdminsSid, + &DomainIndex); + if (NT_SUCCESS(Status)) + NamesBuffer[i].DomainIndex = DomainIndex; + + TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name); + + (*Mapped)++; + } + +done: + if (AdminsSid != NULL) + RtlFreeSid(AdminsSid); + + return Status; +} + + NTSTATUS LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer, PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains, @@ -1018,20 +1174,10 @@ LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer, PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer = NULL; PLSAPR_TRANSLATED_NAME_EX NamesBuffer = NULL; ULONG NamesBufferLength; - ULONG DomainIndex; ULONG i; ULONG Mapped = 0; NTSTATUS Status = STATUS_SUCCESS; - PWELL_KNOWN_SID ptr, ptr2; - - SID_IDENTIFIER_AUTHORITY IdentifierAuthority = {SECURITY_NT_AUTHORITY}; - static const UNICODE_STRING DomainName = RTL_CONSTANT_STRING(L"DOMAIN"); - static const UNICODE_STRING AdminName = RTL_CONSTANT_STRING(L"Administrator"); - PSID AdminsSid = NULL; - ULONG SidLength; - - NamesBufferLength = SidEnumBuffer->Entries * sizeof(LSAPR_TRANSLATED_NAME_EX); NamesBuffer = MIDL_user_allocate(NamesBufferLength); if (NamesBuffer == NULL) @@ -1068,74 +1214,38 @@ LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer, NamesBuffer[i].Flags = 0; } - - Status = RtlAllocateAndInitializeSid(&IdentifierAuthority, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, - 0, 0, 0, 0, 0, 0, - &AdminsSid); + /* Look-up all well-known SIDs */ + Status = LsapLookupWellKnownSids(SidEnumBuffer, + NamesBuffer, + DomainsBuffer, + &Mapped); if (!NT_SUCCESS(Status)) goto done; + if (Mapped == SidEnumBuffer->Entries) + goto done; - SidLength = RtlLengthSid(AdminsSid); + /* Look-up all Domain SIDs */ + Status = LsapLookupLocalDomainSids(SidEnumBuffer, + NamesBuffer, + DomainsBuffer, + &Mapped); + if (!NT_SUCCESS(Status)) + goto done; + if (Mapped == SidEnumBuffer->Entries) + goto done; - for (i = 0; i < SidEnumBuffer->Entries; i++) - { - ptr = LsapLookupWellKnownSid(SidEnumBuffer->SidInfo[i].Sid); - if (ptr != NULL) - { - NamesBuffer[i].Use = ptr->Use; - NamesBuffer[i].Flags = 0; - - NamesBuffer[i].Name.Buffer = MIDL_user_allocate(ptr->Name.MaximumLength); - NamesBuffer[i].Name.Length = ptr->Name.Length; - NamesBuffer[i].Name.MaximumLength = ptr->Name.MaximumLength; - RtlCopyMemory(NamesBuffer[i].Name.Buffer, ptr->Name.Buffer, ptr->Name.MaximumLength); - - ptr2= LsapLookupWellKnownName(&ptr->Domain); - if (ptr2 != NULL) - { - Status = LsapAddDomainToDomainsList(DomainsBuffer, - &ptr2->Name, - ptr2->Sid, - &DomainIndex); - if (NT_SUCCESS(Status)) - NamesBuffer[i].DomainIndex = DomainIndex; - } - - Mapped++; - continue; - } - - - /* Hack: Map the SID to the Admin Account if it is not a well-known SID */ - NamesBuffer[i].Use = SidTypeWellKnownGroup; - NamesBuffer[i].Flags = 0; - NamesBuffer[i].Name.Length = AdminName.Length; - NamesBuffer[i].Name.MaximumLength = AdminName.MaximumLength; - NamesBuffer[i].Name.Buffer = MIDL_user_allocate(AdminName.MaximumLength); - RtlCopyMemory(NamesBuffer[i].Name.Buffer, AdminName.Buffer, AdminName.MaximumLength); - - Status = LsapAddDomainToDomainsList(DomainsBuffer, - (PUNICODE_STRING)&DomainName, - AdminsSid, - &DomainIndex); - if (NT_SUCCESS(Status)) - NamesBuffer[i].DomainIndex = DomainIndex; - - Mapped++; - continue; - - - } + /* Map unknown SIDs */ + Status = LsapLookupUnknownSids(SidEnumBuffer, + NamesBuffer, + DomainsBuffer, + &Mapped); + if (!NT_SUCCESS(Status)) + goto done; done: - if (AdminsSid != NULL) - RtlFreeSid(AdminsSid); - + TRACE("done Status: %lx Mapped: %lu\n", Status, Mapped); if (!NT_SUCCESS(Status)) {