- 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
This commit is contained in:
Eric Kohl 2012-10-06 19:37:10 +00:00
parent 39cb83bab8
commit d59abae163
3 changed files with 298 additions and 148 deletions

View file

@ -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;
}

View file

@ -192,6 +192,9 @@ LsarpEnumeratePrivileges(DWORD *EnumerationContext,
NTSTATUS
LsapInitSids(VOID);
ULONG
LsapGetRelativeIdFromSid(PSID Sid);
NTSTATUS
LsapLookupNames(DWORD Count,
PRPC_UNICODE_STRING Names,

View file

@ -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))
{