2012-11-19 21:33:07 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: Local Security Authority Server DLL
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
|
|
* FILE: dll/win32/lsasrv/security.c
|
|
|
|
* PURPOSE: LSA object security functions
|
|
|
|
* COPYRIGHT: Copyright 2012 Eric Kohl
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "lsasrv.h"
|
|
|
|
|
|
|
|
/* FUNCTIONS ***************************************************************/
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
LsapCreatePolicySd(PSECURITY_DESCRIPTOR *PolicySd,
|
|
|
|
PULONG PolicySdSize)
|
|
|
|
{
|
|
|
|
SECURITY_DESCRIPTOR AbsoluteSd;
|
|
|
|
PSECURITY_DESCRIPTOR RelativeSd = NULL;
|
|
|
|
ULONG RelativeSdSize = 0;
|
|
|
|
PSID AnonymousSid = NULL;
|
|
|
|
PSID AdministratorsSid = NULL;
|
|
|
|
PSID EveryoneSid = NULL;
|
|
|
|
PSID LocalServiceSid = NULL;
|
|
|
|
PSID NetworkServiceSid = NULL;
|
|
|
|
PSID LocalSystemSid = NULL;
|
|
|
|
PACL Dacl = NULL;
|
|
|
|
ULONG DaclSize;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
if (PolicySd == NULL || PolicySdSize == NULL)
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
*PolicySd = NULL;
|
|
|
|
*PolicySdSize = 0;
|
|
|
|
|
|
|
|
/* Initialize the SD */
|
|
|
|
Status = RtlCreateSecurityDescriptor(&AbsoluteSd,
|
|
|
|
SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
1,
|
|
|
|
SECURITY_ANONYMOUS_LOGON_RID,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&AnonymousSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
2,
|
|
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&AdministratorsSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(&WorldSidAuthority,
|
|
|
|
1,
|
|
|
|
SECURITY_WORLD_RID,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&EveryoneSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
1,
|
|
|
|
SECURITY_LOCAL_SERVICE_RID,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&LocalServiceSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
1,
|
|
|
|
SECURITY_NETWORK_SERVICE_RID,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&NetworkServiceSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
1,
|
|
|
|
SECURITY_LOCAL_SYSTEM_RID,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&LocalSystemSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Allocate and initialize the DACL */
|
|
|
|
DaclSize = sizeof(ACL) +
|
2016-11-14 16:17:42 +00:00
|
|
|
sizeof(ACCESS_DENIED_ACE) - sizeof(ULONG) + RtlLengthSid(AnonymousSid) +
|
2012-11-19 21:33:07 +00:00
|
|
|
sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(AdministratorsSid) +
|
|
|
|
sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(EveryoneSid) +
|
|
|
|
sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(AnonymousSid) +
|
|
|
|
sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(LocalServiceSid) +
|
|
|
|
sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(NetworkServiceSid);
|
|
|
|
|
|
|
|
Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
DaclSize);
|
|
|
|
if (Dacl == NULL)
|
|
|
|
{
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = RtlCreateAcl(Dacl,
|
|
|
|
DaclSize,
|
|
|
|
ACL_REVISION);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAddAccessDeniedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
POLICY_LOOKUP_NAMES,
|
|
|
|
AnonymousSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
POLICY_ALL_ACCESS | POLICY_NOTIFICATION,
|
|
|
|
AdministratorsSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
POLICY_EXECUTE,
|
|
|
|
EveryoneSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
POLICY_LOOKUP_NAMES | POLICY_VIEW_LOCAL_INFORMATION,
|
|
|
|
AnonymousSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
POLICY_NOTIFICATION,
|
|
|
|
LocalServiceSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
POLICY_NOTIFICATION,
|
|
|
|
NetworkServiceSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlSetDaclSecurityDescriptor(&AbsoluteSd,
|
|
|
|
TRUE,
|
|
|
|
Dacl,
|
|
|
|
FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlSetGroupSecurityDescriptor(&AbsoluteSd,
|
|
|
|
LocalSystemSid,
|
|
|
|
FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlSetOwnerSecurityDescriptor(&AbsoluteSd,
|
|
|
|
AdministratorsSid,
|
|
|
|
FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
|
|
|
|
RelativeSd,
|
|
|
|
&RelativeSdSize);
|
|
|
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
RelativeSd = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
RelativeSdSize);
|
|
|
|
if (RelativeSd == NULL)
|
|
|
|
{
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
|
|
|
|
RelativeSd,
|
|
|
|
&RelativeSdSize);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
*PolicySd = RelativeSd;
|
|
|
|
*PolicySdSize = RelativeSdSize;
|
|
|
|
|
|
|
|
done:
|
|
|
|
if (Dacl != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
|
|
|
|
|
|
|
|
if (AnonymousSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, AnonymousSid);
|
|
|
|
|
|
|
|
if (AdministratorsSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, AdministratorsSid);
|
|
|
|
|
|
|
|
if (EveryoneSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, EveryoneSid);
|
|
|
|
|
|
|
|
if (LocalServiceSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, LocalServiceSid);
|
|
|
|
|
|
|
|
if (NetworkServiceSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, NetworkServiceSid);
|
|
|
|
|
|
|
|
if (LocalSystemSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSystemSid);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (RelativeSd != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSd);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
LsapCreateAccountSd(PSECURITY_DESCRIPTOR *AccountSd,
|
|
|
|
PULONG AccountSdSize)
|
|
|
|
{
|
|
|
|
SECURITY_DESCRIPTOR AbsoluteSd;
|
|
|
|
PSECURITY_DESCRIPTOR RelativeSd = NULL;
|
|
|
|
ULONG RelativeSdSize = 0;
|
|
|
|
PSID AdministratorsSid = NULL;
|
|
|
|
PSID EveryoneSid = NULL;
|
|
|
|
PSID LocalSystemSid = NULL;
|
|
|
|
PACL Dacl = NULL;
|
|
|
|
ULONG DaclSize;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
if (AccountSd == NULL || AccountSdSize == NULL)
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
*AccountSd = NULL;
|
|
|
|
*AccountSdSize = 0;
|
|
|
|
|
|
|
|
/* Initialize the SD */
|
|
|
|
Status = RtlCreateSecurityDescriptor(&AbsoluteSd,
|
|
|
|
SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
2,
|
|
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&AdministratorsSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(&WorldSidAuthority,
|
|
|
|
1,
|
|
|
|
SECURITY_WORLD_RID,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&EveryoneSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
1,
|
|
|
|
SECURITY_LOCAL_SYSTEM_RID,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&LocalSystemSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Allocate and initialize the DACL */
|
|
|
|
DaclSize = sizeof(ACL) +
|
|
|
|
sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(AdministratorsSid) +
|
|
|
|
sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(EveryoneSid);
|
|
|
|
|
|
|
|
Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
DaclSize);
|
|
|
|
if (Dacl == NULL)
|
|
|
|
{
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = RtlCreateAcl(Dacl,
|
|
|
|
DaclSize,
|
|
|
|
ACL_REVISION);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
ACCOUNT_ALL_ACCESS,
|
|
|
|
AdministratorsSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
ACCOUNT_EXECUTE,
|
|
|
|
EveryoneSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlSetDaclSecurityDescriptor(&AbsoluteSd,
|
|
|
|
TRUE,
|
|
|
|
Dacl,
|
|
|
|
FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlSetGroupSecurityDescriptor(&AbsoluteSd,
|
|
|
|
LocalSystemSid,
|
|
|
|
FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlSetOwnerSecurityDescriptor(&AbsoluteSd,
|
|
|
|
AdministratorsSid,
|
|
|
|
FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
|
|
|
|
RelativeSd,
|
|
|
|
&RelativeSdSize);
|
|
|
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
RelativeSd = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
RelativeSdSize);
|
|
|
|
if (RelativeSd == NULL)
|
|
|
|
{
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
|
|
|
|
RelativeSd,
|
|
|
|
&RelativeSdSize);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
*AccountSd = RelativeSd;
|
|
|
|
*AccountSdSize = RelativeSdSize;
|
|
|
|
|
|
|
|
done:
|
|
|
|
if (Dacl != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
|
|
|
|
|
|
|
|
if (AdministratorsSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, AdministratorsSid);
|
|
|
|
|
|
|
|
if (EveryoneSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, EveryoneSid);
|
|
|
|
|
|
|
|
if (LocalSystemSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSystemSid);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (RelativeSd != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSd);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2012-11-20 22:34:00 +00:00
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
LsapCreateSecretSd(PSECURITY_DESCRIPTOR *SecretSd,
|
|
|
|
PULONG SecretSdSize)
|
|
|
|
{
|
|
|
|
SECURITY_DESCRIPTOR AbsoluteSd;
|
|
|
|
PSECURITY_DESCRIPTOR RelativeSd = NULL;
|
|
|
|
ULONG RelativeSdSize = 0;
|
|
|
|
PSID AdministratorsSid = NULL;
|
|
|
|
PSID EveryoneSid = NULL;
|
|
|
|
PSID LocalSystemSid = NULL;
|
|
|
|
PACL Dacl = NULL;
|
|
|
|
ULONG DaclSize;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
if (SecretSd == NULL || SecretSdSize == NULL)
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
*SecretSd = NULL;
|
|
|
|
*SecretSdSize = 0;
|
|
|
|
|
|
|
|
/* Initialize the SD */
|
|
|
|
Status = RtlCreateSecurityDescriptor(&AbsoluteSd,
|
|
|
|
SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
2,
|
|
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&AdministratorsSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(&WorldSidAuthority,
|
|
|
|
1,
|
|
|
|
SECURITY_WORLD_RID,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&EveryoneSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
1,
|
|
|
|
SECURITY_LOCAL_SYSTEM_RID,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&LocalSystemSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Allocate and initialize the DACL */
|
|
|
|
DaclSize = sizeof(ACL) +
|
|
|
|
sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(AdministratorsSid) +
|
|
|
|
sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(EveryoneSid);
|
|
|
|
|
|
|
|
Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
DaclSize);
|
|
|
|
if (Dacl == NULL)
|
|
|
|
{
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = RtlCreateAcl(Dacl,
|
|
|
|
DaclSize,
|
|
|
|
ACL_REVISION);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
SECRET_ALL_ACCESS,
|
|
|
|
AdministratorsSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
SECRET_EXECUTE,
|
|
|
|
EveryoneSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlSetDaclSecurityDescriptor(&AbsoluteSd,
|
|
|
|
TRUE,
|
|
|
|
Dacl,
|
|
|
|
FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlSetGroupSecurityDescriptor(&AbsoluteSd,
|
|
|
|
LocalSystemSid,
|
|
|
|
FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlSetOwnerSecurityDescriptor(&AbsoluteSd,
|
|
|
|
AdministratorsSid,
|
|
|
|
FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
|
|
|
|
RelativeSd,
|
|
|
|
&RelativeSdSize);
|
|
|
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
RelativeSd = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
RelativeSdSize);
|
|
|
|
if (RelativeSd == NULL)
|
|
|
|
{
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
|
|
|
|
RelativeSd,
|
|
|
|
&RelativeSdSize);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
*SecretSd = RelativeSd;
|
|
|
|
*SecretSdSize = RelativeSdSize;
|
|
|
|
|
|
|
|
done:
|
|
|
|
if (Dacl != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
|
|
|
|
|
|
|
|
if (AdministratorsSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, AdministratorsSid);
|
|
|
|
|
|
|
|
if (EveryoneSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, EveryoneSid);
|
|
|
|
|
|
|
|
if (LocalSystemSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSystemSid);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (RelativeSd != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSd);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2022-02-28 17:35:53 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* Creates a security descriptor for the token
|
|
|
|
* object.
|
|
|
|
*
|
|
|
|
* @param[in] User
|
|
|
|
* A primary user to be given to the function.
|
|
|
|
* This user represents the owner that is in
|
|
|
|
* charge of this object.
|
|
|
|
*
|
|
|
|
* @param[out] TokenSd
|
|
|
|
* A pointer to an allocated security descriptor
|
|
|
|
* for the token object.
|
|
|
|
*
|
|
|
|
* @param[out] TokenSdSize
|
|
|
|
* A pointer to a returned size of the descriptor.
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
* STATUS_SUCCESS is returned if the function has
|
|
|
|
* successfully created the security descriptor.
|
|
|
|
* STATUS_INVALID_PARAMETER is returned if one of the
|
|
|
|
* parameters are not valid. STATUS_INSUFFICIENT_RESOURCES
|
|
|
|
* is returned if memory heap allocation for specific
|
|
|
|
* security buffers couldn't be done. A NTSTATUS status
|
|
|
|
* code is returned otherwise.
|
|
|
|
*
|
|
|
|
* @remarks
|
|
|
|
* Bot the local system and user are given full access rights
|
|
|
|
* for the token (they can open it, read and write into it, etc.)
|
|
|
|
* whereas admins can only read from the token. This security
|
|
|
|
* descriptor is TO NOT BE confused with the default DACL of the
|
|
|
|
* token which is another thing that serves different purpose.
|
|
|
|
*/
|
|
|
|
NTSTATUS
|
|
|
|
LsapCreateTokenSd(
|
|
|
|
_In_ const TOKEN_USER *User,
|
|
|
|
_Outptr_ PSECURITY_DESCRIPTOR *TokenSd,
|
|
|
|
_Out_ PULONG TokenSdSize)
|
|
|
|
{
|
|
|
|
SECURITY_DESCRIPTOR AbsoluteSd;
|
|
|
|
PSECURITY_DESCRIPTOR RelativeSd = NULL;
|
|
|
|
ULONG RelativeSdSize = 0;
|
|
|
|
PSID AdministratorsSid = NULL;
|
|
|
|
PSID LocalSystemSid = NULL;
|
|
|
|
PACL Dacl = NULL;
|
|
|
|
ULONG DaclSize;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
if (TokenSd == NULL || TokenSdSize == NULL)
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
*TokenSd = NULL;
|
|
|
|
*TokenSdSize = 0;
|
|
|
|
|
|
|
|
/* Initialize the SD */
|
|
|
|
Status = RtlCreateSecurityDescriptor(&AbsoluteSd,
|
|
|
|
SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
1,
|
|
|
|
SECURITY_LOCAL_SYSTEM_RID,
|
|
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
|
|
&LocalSystemSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
2,
|
|
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
|
|
0, 0, 0, 0, 0, 0,
|
|
|
|
&AdministratorsSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Allocate and initialize the DACL */
|
|
|
|
DaclSize = sizeof(ACL) +
|
|
|
|
sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(LocalSystemSid) +
|
|
|
|
sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(AdministratorsSid) +
|
|
|
|
sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(User->User.Sid);
|
|
|
|
|
|
|
|
Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
DaclSize);
|
|
|
|
if (Dacl == NULL)
|
|
|
|
{
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = RtlCreateAcl(Dacl,
|
|
|
|
DaclSize,
|
|
|
|
ACL_REVISION);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
TOKEN_ALL_ACCESS,
|
|
|
|
LocalSystemSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
TOKEN_READ,
|
|
|
|
AdministratorsSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
TOKEN_ALL_ACCESS,
|
|
|
|
User->User.Sid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlSetDaclSecurityDescriptor(&AbsoluteSd,
|
|
|
|
TRUE,
|
|
|
|
Dacl,
|
|
|
|
FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlSetOwnerSecurityDescriptor(&AbsoluteSd,
|
|
|
|
AdministratorsSid,
|
|
|
|
FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
|
|
|
|
RelativeSd,
|
|
|
|
&RelativeSdSize);
|
|
|
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
RelativeSd = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
RelativeSdSize);
|
|
|
|
if (RelativeSd == NULL)
|
|
|
|
{
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd,
|
|
|
|
RelativeSd,
|
|
|
|
&RelativeSdSize);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
*TokenSd = RelativeSd;
|
|
|
|
*TokenSdSize = RelativeSdSize;
|
|
|
|
|
|
|
|
done:
|
|
|
|
if (Dacl != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
|
|
|
|
|
|
|
|
if (AdministratorsSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, AdministratorsSid);
|
|
|
|
|
|
|
|
if (LocalSystemSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSystemSid);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (RelativeSd != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSd);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2012-11-19 21:33:07 +00:00
|
|
|
/* EOF */
|