mirror of
https://github.com/reactos/reactos.git
synced 2025-01-02 12:32:47 +00:00
[LSASRV]
Implement lookup of accounts in the account domain of the SAM database. The advapi32 security winetest shows proper domain and account names for the administrator and guest SIDs. svn path=/trunk/; revision=57517
This commit is contained in:
parent
3c50db37b6
commit
6097ae49f8
3 changed files with 233 additions and 21 deletions
|
@ -27,7 +27,7 @@ add_library(lsasrv SHARED ${SOURCE})
|
||||||
set_module_type(lsasrv win32dll ENTRYPOINT 0 UNICODE)
|
set_module_type(lsasrv win32dll ENTRYPOINT 0 UNICODE)
|
||||||
|
|
||||||
target_link_libraries(lsasrv wine ${PSEH_LIB})
|
target_link_libraries(lsasrv wine ${PSEH_LIB})
|
||||||
add_importlibs(lsasrv rpcrt4 msvcrt kernel32 advapi32 ntdll)
|
add_importlibs(lsasrv samsrv rpcrt4 msvcrt kernel32 advapi32 ntdll)
|
||||||
add_pch(lsasrv lsasrv.h)
|
add_pch(lsasrv lsasrv.h)
|
||||||
add_dependencies(lsasrv psdk)
|
add_dependencies(lsasrv psdk)
|
||||||
add_cd_file(TARGET lsasrv DESTINATION reactos/system32 FOR all)
|
add_cd_file(TARGET lsasrv DESTINATION reactos/system32 FOR all)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <ndk/rtlfuncs.h>
|
#include <ndk/rtlfuncs.h>
|
||||||
#include <ndk/setypes.h>
|
#include <ndk/setypes.h>
|
||||||
|
|
||||||
|
#include <ntsam.h>
|
||||||
#include <ntlsa.h>
|
#include <ntlsa.h>
|
||||||
#include <ntsecapi.h>
|
#include <ntsecapi.h>
|
||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
|
|
|
@ -10,6 +10,55 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
|
WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
|
||||||
|
|
||||||
|
typedef wchar_t *PSAMPR_SERVER_NAME;
|
||||||
|
typedef void *SAMPR_HANDLE;
|
||||||
|
|
||||||
|
typedef struct _SAMPR_RETURNED_USTRING_ARRAY
|
||||||
|
{
|
||||||
|
unsigned long Count;
|
||||||
|
PRPC_UNICODE_STRING Element;
|
||||||
|
} SAMPR_RETURNED_USTRING_ARRAY, *PSAMPR_RETURNED_USTRING_ARRAY;
|
||||||
|
|
||||||
|
typedef struct _SAMPR_ULONG_ARRAY
|
||||||
|
{
|
||||||
|
unsigned long Count;
|
||||||
|
unsigned long *Element;
|
||||||
|
} SAMPR_ULONG_ARRAY, *PSAMPR_ULONG_ARRAY;
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
SamIFree_SAMPR_RETURNED_USTRING_ARRAY(PSAMPR_RETURNED_USTRING_ARRAY Ptr);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
SamIFree_SAMPR_ULONG_ARRAY(PSAMPR_ULONG_ARRAY Ptr);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
SamrConnect(IN PSAMPR_SERVER_NAME ServerName,
|
||||||
|
OUT SAMPR_HANDLE *ServerHandle,
|
||||||
|
IN ACCESS_MASK DesiredAccess);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
SamrCloseHandle(IN OUT SAMPR_HANDLE *SamHandle);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
SamrOpenDomain(IN SAMPR_HANDLE ServerHandle,
|
||||||
|
IN ACCESS_MASK DesiredAccess,
|
||||||
|
IN PRPC_SID DomainId,
|
||||||
|
OUT SAMPR_HANDLE *DomainHandle);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
SamrLookupIdsInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||||
|
IN ULONG Count,
|
||||||
|
IN ULONG *RelativeIds,
|
||||||
|
OUT PSAMPR_RETURNED_USTRING_ARRAY Names,
|
||||||
|
OUT PSAMPR_ULONG_ARRAY Use);
|
||||||
|
|
||||||
|
|
||||||
typedef struct _WELL_KNOWN_SID
|
typedef struct _WELL_KNOWN_SID
|
||||||
{
|
{
|
||||||
|
@ -800,6 +849,40 @@ LsapAddDomainToDomainsList(PLSAPR_REFERENCED_DOMAIN_LIST ReferencedDomains,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static BOOLEAN
|
||||||
|
LsapIsPrefixSid(IN PSID PrefixSid,
|
||||||
|
IN PSID Sid)
|
||||||
|
{
|
||||||
|
PISID Sid1 = PrefixSid, Sid2 = Sid;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
if (Sid1->Revision != Sid2->Revision)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ((Sid1->IdentifierAuthority.Value[0] != Sid2->IdentifierAuthority.Value[0]) ||
|
||||||
|
(Sid1->IdentifierAuthority.Value[1] != Sid2->IdentifierAuthority.Value[1]) ||
|
||||||
|
(Sid1->IdentifierAuthority.Value[2] != Sid2->IdentifierAuthority.Value[2]) ||
|
||||||
|
(Sid1->IdentifierAuthority.Value[3] != Sid2->IdentifierAuthority.Value[3]) ||
|
||||||
|
(Sid1->IdentifierAuthority.Value[4] != Sid2->IdentifierAuthority.Value[4]) ||
|
||||||
|
(Sid1->IdentifierAuthority.Value[5] != Sid2->IdentifierAuthority.Value[5]))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (Sid1->SubAuthorityCount >= Sid2->SubAuthorityCount)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (Sid1->SubAuthorityCount == 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
for (i = 0; i < Sid1->SubAuthorityCount; i++)
|
||||||
|
{
|
||||||
|
if (Sid1->SubAuthority[i] != Sid2->SubAuthority[i])
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
LsapGetRelativeIdFromSid(PSID Sid_)
|
LsapGetRelativeIdFromSid(PSID Sid_)
|
||||||
{
|
{
|
||||||
|
@ -1150,7 +1233,7 @@ LsapLookupWellKnownSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString);
|
ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString);
|
||||||
TRACE("Unmapped SID: %S\n", SidString);
|
TRACE("Mapping SID: %S\n", SidString);
|
||||||
LocalFree(SidString);
|
LocalFree(SidString);
|
||||||
SidString = NULL;
|
SidString = NULL;
|
||||||
|
|
||||||
|
@ -1172,8 +1255,10 @@ LsapLookupWellKnownSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
||||||
&ptr2->Name,
|
&ptr2->Name,
|
||||||
ptr2->Sid,
|
ptr2->Sid,
|
||||||
&DomainIndex);
|
&DomainIndex);
|
||||||
if (NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
NamesBuffer[i].DomainIndex = DomainIndex;
|
goto done;
|
||||||
|
|
||||||
|
NamesBuffer[i].DomainIndex = DomainIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
|
TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
|
||||||
|
@ -1182,18 +1267,45 @@ LsapLookupWellKnownSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
LsapLookupLocalDomainSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
LsapLookupAccountDomainSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
||||||
PLSAPR_TRANSLATED_NAME_EX NamesBuffer,
|
PLSAPR_TRANSLATED_NAME_EX NamesBuffer,
|
||||||
PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
|
PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
|
||||||
PULONG Mapped)
|
PULONG Mapped)
|
||||||
{
|
{
|
||||||
|
SAMPR_HANDLE ServerHandle = NULL;
|
||||||
|
SAMPR_HANDLE DomainHandle = NULL;
|
||||||
|
SAMPR_RETURNED_USTRING_ARRAY Names = {0, NULL};
|
||||||
|
SAMPR_ULONG_ARRAY Use = {0, NULL};
|
||||||
LPWSTR SidString = NULL;
|
LPWSTR SidString = NULL;
|
||||||
|
ULONG DomainIndex;
|
||||||
|
ULONG RelativeIds[1];
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
Status = SamrConnect(NULL,
|
||||||
|
&ServerHandle,
|
||||||
|
SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
TRACE("SamrConnect failed (Status %08lx)\n", Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = SamrOpenDomain(ServerHandle,
|
||||||
|
DOMAIN_LOOKUP,
|
||||||
|
AccountDomainSid,
|
||||||
|
&DomainHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
TRACE("SamOpenDomain failed (Status %08lx)\n", Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < SidEnumBuffer->Entries; i++)
|
for (i = 0; i < SidEnumBuffer->Entries; i++)
|
||||||
{
|
{
|
||||||
|
@ -1202,12 +1314,103 @@ LsapLookupLocalDomainSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString);
|
ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString);
|
||||||
TRACE("Unmapped SID: %S\n", SidString);
|
TRACE("Mapping SID: %S\n", SidString);
|
||||||
LocalFree(SidString);
|
LocalFree(SidString);
|
||||||
SidString = NULL;
|
SidString = NULL;
|
||||||
|
|
||||||
|
if (RtlEqualSid(AccountDomainSid, SidEnumBuffer->SidInfo[i].Sid))
|
||||||
|
{
|
||||||
|
TRACE("Found account domain!\n");
|
||||||
|
|
||||||
|
NamesBuffer[i].Use = SidTypeDomain;
|
||||||
|
NamesBuffer[i].Flags = 0;
|
||||||
|
|
||||||
|
NamesBuffer[i].Name.Length = AccountDomainName.Length;
|
||||||
|
NamesBuffer[i].Name.MaximumLength = AccountDomainName.MaximumLength;
|
||||||
|
NamesBuffer[i].Name.Buffer = MIDL_user_allocate(AccountDomainName.MaximumLength);
|
||||||
|
if (NamesBuffer[i].Name.Buffer == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlCopyMemory(NamesBuffer[i].Name.Buffer, AccountDomainName.Buffer, AccountDomainName.MaximumLength);
|
||||||
|
|
||||||
|
Status = LsapAddDomainToDomainsList(DomainsBuffer,
|
||||||
|
&AccountDomainName,
|
||||||
|
AccountDomainSid,
|
||||||
|
&DomainIndex);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
NamesBuffer[i].DomainIndex = DomainIndex;
|
||||||
|
|
||||||
|
TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
|
||||||
|
|
||||||
|
(*Mapped)++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (LsapIsPrefixSid(AccountDomainSid, SidEnumBuffer->SidInfo[i].Sid))
|
||||||
|
{
|
||||||
|
TRACE("Found account domain account!\n");
|
||||||
|
|
||||||
|
RelativeIds[0] = LsapGetRelativeIdFromSid(SidEnumBuffer->SidInfo[i].Sid);
|
||||||
|
|
||||||
|
Status = SamrLookupIdsInDomain(DomainHandle,
|
||||||
|
1,
|
||||||
|
RelativeIds,
|
||||||
|
&Names,
|
||||||
|
&Use);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
TRACE("SamLookupIdsInDomain failed (Status %08lx)\n", Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
NamesBuffer[i].Use = Use.Element[0]; //SidTypeUser;
|
||||||
|
NamesBuffer[i].Flags = 0;
|
||||||
|
|
||||||
|
NamesBuffer[i].Name.Length = Names.Element[0].Length; //TestName.Length;
|
||||||
|
NamesBuffer[i].Name.MaximumLength = Names.Element[0].MaximumLength; //TestName.MaximumLength;
|
||||||
|
NamesBuffer[i].Name.Buffer = MIDL_user_allocate(Names.Element[0].MaximumLength);
|
||||||
|
if (NamesBuffer[i].Name.Buffer == NULL)
|
||||||
|
{
|
||||||
|
SamIFree_SAMPR_RETURNED_USTRING_ARRAY(&Names);
|
||||||
|
SamIFree_SAMPR_ULONG_ARRAY(&Use);
|
||||||
|
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlCopyMemory(NamesBuffer[i].Name.Buffer, Names.Element[0].Buffer, Names.Element[0].MaximumLength);
|
||||||
|
|
||||||
|
SamIFree_SAMPR_RETURNED_USTRING_ARRAY(&Names);
|
||||||
|
SamIFree_SAMPR_ULONG_ARRAY(&Use);
|
||||||
|
|
||||||
|
Status = LsapAddDomainToDomainsList(DomainsBuffer,
|
||||||
|
&AccountDomainName,
|
||||||
|
AccountDomainSid,
|
||||||
|
&DomainIndex);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
NamesBuffer[i].DomainIndex = DomainIndex;
|
||||||
|
|
||||||
|
TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
|
||||||
|
|
||||||
|
(*Mapped)++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
done:
|
||||||
|
if (DomainHandle != NULL)
|
||||||
|
SamrCloseHandle(DomainHandle);
|
||||||
|
|
||||||
|
if (ServerHandle != NULL)
|
||||||
|
SamrCloseHandle(ServerHandle);
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1218,8 +1421,8 @@ LsapLookupUnknownSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
||||||
PULONG Mapped)
|
PULONG Mapped)
|
||||||
{
|
{
|
||||||
SID_IDENTIFIER_AUTHORITY IdentifierAuthority = {SECURITY_NT_AUTHORITY};
|
SID_IDENTIFIER_AUTHORITY IdentifierAuthority = {SECURITY_NT_AUTHORITY};
|
||||||
static const UNICODE_STRING DomainName = RTL_CONSTANT_STRING(L"DOMAIN");
|
static const UNICODE_STRING DomainName = RTL_CONSTANT_STRING(L"UNKNOWN");
|
||||||
static const UNICODE_STRING AdminName = RTL_CONSTANT_STRING(L"Administrator");
|
static const UNICODE_STRING AdminName = RTL_CONSTANT_STRING(L"Test");
|
||||||
PSID AdminsSid = NULL;
|
PSID AdminsSid = NULL;
|
||||||
LPWSTR SidString = NULL;
|
LPWSTR SidString = NULL;
|
||||||
ULONG SidLength;
|
ULONG SidLength;
|
||||||
|
@ -1246,7 +1449,7 @@ LsapLookupUnknownSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
||||||
|
|
||||||
|
|
||||||
ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString);
|
ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString);
|
||||||
TRACE("Unmapped SID: %S\n", SidString);
|
TRACE("Mapping SID: %S\n", SidString);
|
||||||
LocalFree(SidString);
|
LocalFree(SidString);
|
||||||
SidString = NULL;
|
SidString = NULL;
|
||||||
|
|
||||||
|
@ -1257,14 +1460,22 @@ LsapLookupUnknownSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
||||||
NamesBuffer[i].Name.Length = AdminName.Length;
|
NamesBuffer[i].Name.Length = AdminName.Length;
|
||||||
NamesBuffer[i].Name.MaximumLength = AdminName.MaximumLength;
|
NamesBuffer[i].Name.MaximumLength = AdminName.MaximumLength;
|
||||||
NamesBuffer[i].Name.Buffer = MIDL_user_allocate(AdminName.MaximumLength);
|
NamesBuffer[i].Name.Buffer = MIDL_user_allocate(AdminName.MaximumLength);
|
||||||
|
if (NamesBuffer[i].Name.Buffer == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
RtlCopyMemory(NamesBuffer[i].Name.Buffer, AdminName.Buffer, AdminName.MaximumLength);
|
RtlCopyMemory(NamesBuffer[i].Name.Buffer, AdminName.Buffer, AdminName.MaximumLength);
|
||||||
|
|
||||||
Status = LsapAddDomainToDomainsList(DomainsBuffer,
|
Status = LsapAddDomainToDomainsList(DomainsBuffer,
|
||||||
(PUNICODE_STRING)&DomainName,
|
(PUNICODE_STRING)&DomainName,
|
||||||
AdminsSid,
|
AdminsSid,
|
||||||
&DomainIndex);
|
&DomainIndex);
|
||||||
if (NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
NamesBuffer[i].DomainIndex = DomainIndex;
|
goto done;
|
||||||
|
|
||||||
|
NamesBuffer[i].DomainIndex = DomainIndex;
|
||||||
|
|
||||||
TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
|
TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
|
||||||
|
|
||||||
|
@ -1331,7 +1542,7 @@ LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
||||||
NamesBuffer[i].Flags = 0;
|
NamesBuffer[i].Flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look-up all well-known SIDs */
|
/* Look-up well-known SIDs */
|
||||||
Status = LsapLookupWellKnownSids(SidEnumBuffer,
|
Status = LsapLookupWellKnownSids(SidEnumBuffer,
|
||||||
NamesBuffer,
|
NamesBuffer,
|
||||||
DomainsBuffer,
|
DomainsBuffer,
|
||||||
|
@ -1342,11 +1553,11 @@ LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
||||||
if (Mapped == SidEnumBuffer->Entries)
|
if (Mapped == SidEnumBuffer->Entries)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Look-up all Domain SIDs */
|
/* Look-up account domain SIDs */
|
||||||
Status = LsapLookupLocalDomainSids(SidEnumBuffer,
|
Status = LsapLookupAccountDomainSids(SidEnumBuffer,
|
||||||
NamesBuffer,
|
NamesBuffer,
|
||||||
DomainsBuffer,
|
DomainsBuffer,
|
||||||
&Mapped);
|
&Mapped);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue