reactos/dll/win32/netapi32/utils.c

249 lines
5.9 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: NetAPI DLL
* FILE: reactos/dll/win32/netapi32/utils.c
* PURPOSE: Helper functions
*
* PROGRAMMERS: Eric Kohl
*/
/* INCLUDES ******************************************************************/
#include "netapi32.h"
WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
/* GLOBALS *******************************************************************/
static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
/* FUNCTIONS *****************************************************************/
NTSTATUS
GetAccountDomainSid(IN PUNICODE_STRING ServerName,
OUT PSID *AccountDomainSid)
{
PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo = NULL;
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
LSA_HANDLE PolicyHandle = NULL;
ULONG Length = 0;
NTSTATUS Status;
memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
Status = LsaOpenPolicy(ServerName,
&ObjectAttributes,
POLICY_VIEW_LOCAL_INFORMATION,
&PolicyHandle);
if (!NT_SUCCESS(Status))
{
ERR("LsaOpenPolicy failed (Status %08lx)\n", Status);
return Status;
}
Status = LsaQueryInformationPolicy(PolicyHandle,
PolicyAccountDomainInformation,
(PVOID *)&AccountDomainInfo);
if (!NT_SUCCESS(Status))
{
ERR("LsaQueryInformationPolicy failed (Status %08lx)\n", Status);
goto done;
}
Length = RtlLengthSid(AccountDomainInfo->DomainSid);
*AccountDomainSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
if (*AccountDomainSid == NULL)
{
ERR("Failed to allocate SID\n");
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
memcpy(*AccountDomainSid, AccountDomainInfo->DomainSid, Length);
done:
if (AccountDomainInfo != NULL)
LsaFreeMemory(AccountDomainInfo);
LsaClose(PolicyHandle);
return Status;
}
NTSTATUS
GetBuiltinDomainSid(OUT PSID *BuiltinDomainSid)
{
PSID Sid = NULL;
PULONG Ptr;
NTSTATUS Status = STATUS_SUCCESS;
*BuiltinDomainSid = NULL;
Sid = RtlAllocateHeap(RtlGetProcessHeap(),
0,
RtlLengthRequiredSid(1));
if (Sid == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Status = RtlInitializeSid(Sid,
&NtAuthority,
1);
if (!NT_SUCCESS(Status))
goto done;
Ptr = RtlSubAuthoritySid(Sid, 0);
*Ptr = SECURITY_BUILTIN_DOMAIN_RID;
*BuiltinDomainSid = Sid;
done:
if (!NT_SUCCESS(Status))
{
if (Sid != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, Sid);
}
return Status;
}
NTSTATUS
OpenAccountDomain(IN SAM_HANDLE ServerHandle,
IN PUNICODE_STRING ServerName,
IN ULONG DesiredAccess,
OUT PSAM_HANDLE DomainHandle)
{
PSID DomainSid = NULL;
NTSTATUS Status;
Status = GetAccountDomainSid(ServerName,
&DomainSid);
if (!NT_SUCCESS(Status))
{
ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
return Status;
}
Status = SamOpenDomain(ServerHandle,
DesiredAccess,
DomainSid,
DomainHandle);
RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
if (!NT_SUCCESS(Status))
{
ERR("SamOpenDomain failed (Status %08lx)\n", Status);
}
return Status;
}
NTSTATUS
OpenBuiltinDomain(IN SAM_HANDLE ServerHandle,
IN ULONG DesiredAccess,
OUT PSAM_HANDLE DomainHandle)
{
PSID DomainSid = NULL;
NTSTATUS Status;
Status = GetBuiltinDomainSid(&DomainSid);
if (!NT_SUCCESS(Status))
{
ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status);
return Status;
}
Status = SamOpenDomain(ServerHandle,
DesiredAccess,
DomainSid,
DomainHandle);
RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
if (!NT_SUCCESS(Status))
{
ERR("SamOpenDomain failed (Status %08lx)\n", Status);
}
return Status;
}
NET_API_STATUS
BuildSidFromSidAndRid(IN PSID SrcSid,
IN ULONG RelativeId,
OUT PSID *DestSid)
{
UCHAR RidCount;
PSID DstSid;
ULONG i;
ULONG DstSidSize;
PULONG p, q;
NET_API_STATUS ApiStatus = NERR_Success;
RidCount = *RtlSubAuthorityCountSid(SrcSid);
if (RidCount >= 8)
return ERROR_INVALID_PARAMETER;
DstSidSize = RtlLengthRequiredSid(RidCount + 1);
ApiStatus = NetApiBufferAllocate(DstSidSize,
&DstSid);
if (ApiStatus != NERR_Success)
return ApiStatus;
RtlInitializeSid(DstSid,
RtlIdentifierAuthoritySid(SrcSid),
RidCount + 1);
for (i = 0; i < (ULONG)RidCount; i++)
{
p = RtlSubAuthoritySid(SrcSid, i);
q = RtlSubAuthoritySid(DstSid, i);
*q = *p;
}
q = RtlSubAuthoritySid(DstSid, (ULONG)RidCount);
*q = RelativeId;
*DestSid = DstSid;
return NERR_Success;
}
VOID
CopySidFromSidAndRid(
_Out_ PSID DstSid,
_In_ PSID SrcSid,
_In_ ULONG RelativeId)
{
UCHAR RidCount;
ULONG i;
PULONG p, q;
RidCount = *RtlSubAuthorityCountSid(SrcSid);
if (RidCount >= 8)
return;
RtlInitializeSid(DstSid,
RtlIdentifierAuthoritySid(SrcSid),
RidCount + 1);
for (i = 0; i < (ULONG)RidCount; i++)
{
p = RtlSubAuthoritySid(SrcSid, i);
q = RtlSubAuthoritySid(DstSid, i);
*q = *p;
}
q = RtlSubAuthoritySid(DstSid, (ULONG)RidCount);
*q = RelativeId;
}
/* EOF */