- Move LsapCreatePolicySd into a separate file.
- Create and set a security descriptor to newly created accounts.

svn path=/trunk/; revision=57737
This commit is contained in:
Eric Kohl 2012-11-19 21:33:07 +00:00
parent 4874b78fd4
commit bf98c11bae
5 changed files with 471 additions and 254 deletions

View file

@ -18,6 +18,7 @@ list(APPEND SOURCE
lsasrv.c
policy.c
privileges.c
security.c
lsasrv.rc
${CMAKE_CURRENT_BINARY_DIR}/lsasrv_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/lsasrv.def

View file

@ -233,260 +233,6 @@ LsapCreateRandomDomainSid(OUT PSID *Sid)
}
static 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) +
sizeof(ACCESS_DENIED_ACE) - sizeof(ULONG) + RtlLengthSid(AnonymousSid) +
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;
}
static NTSTATUS
LsapCreateDatabaseObjects(VOID)
{

View file

@ -513,6 +513,8 @@ NTSTATUS WINAPI LsarCreateAccount(
PLSA_DB_OBJECT PolicyObject;
PLSA_DB_OBJECT AccountObject = NULL;
LPWSTR SidString = NULL;
PSECURITY_DESCRIPTOR AccountSd = NULL;
ULONG AccountSdSize;
NTSTATUS Status = STATUS_SUCCESS;
/* Validate the AccountSid */
@ -539,6 +541,15 @@ NTSTATUS WINAPI LsarCreateAccount(
goto done;
}
/* Create a security descriptor for the account */
Status = LsapCreateAccountSd(&AccountSd,
&AccountSdSize);
if (!NT_SUCCESS(Status))
{
ERR("LsapCreateAccountSd returned 0x%08lx\n", Status);
return Status;
}
/* Create the Account object */
Status = LsapCreateDbObject(PolicyObject,
L"Accounts",
@ -557,11 +568,22 @@ NTSTATUS WINAPI LsarCreateAccount(
L"Sid",
(PVOID)AccountSid,
GetLengthSid(AccountSid));
if (!NT_SUCCESS(Status))
goto done;
/* Set the SecDesc attribute */
Status = LsapSetObjectAttribute(AccountObject,
L"SecDesc",
AccountSd,
AccountSdSize);
done:
if (SidString != NULL)
LocalFree(SidString);
if (AccountSd != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, AccountSd);
if (!NT_SUCCESS(Status))
{
if (AccountObject != NULL)

View file

@ -227,4 +227,13 @@ LsarpEnumeratePrivileges(DWORD *EnumerationContext,
PLSAPR_PRIVILEGE_ENUM_BUFFER EnumerationBuffer,
DWORD PreferedMaximumLength);
/* security.c */
NTSTATUS
LsapCreatePolicySd(PSECURITY_DESCRIPTOR *PolicySd,
PULONG PolicySdSize);
NTSTATUS
LsapCreateAccountSd(PSECURITY_DESCRIPTOR *AccountSd,
PULONG AccountSdSize);
/* EOF */

View file

@ -0,0 +1,439 @@
/*
* 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
*/
/* INCLUDES ****************************************************************/
#include "lsasrv.h"
WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
/* 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) +
sizeof(ACCESS_DENIED_ACE) - sizeof(ULONG) + RtlLengthSid(AnonymousSid) +
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;
}
/* EOF */