From 42f3cd76ad85e4edb3888f98f39639d4176b04ec Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 23 Jun 2013 14:26:18 +0000 Subject: [PATCH] [SAMSRV] Create and store a security descriptor for the server object. svn path=/trunk/; revision=59317 --- reactos/dll/win32/samsrv/CMakeLists.txt | 1 + reactos/dll/win32/samsrv/samsrv.h | 7 + reactos/dll/win32/samsrv/security.c | 286 ++++++++++++++++++++++++ reactos/dll/win32/samsrv/setup.c | 19 ++ 4 files changed, 313 insertions(+) create mode 100644 reactos/dll/win32/samsrv/security.c diff --git a/reactos/dll/win32/samsrv/CMakeLists.txt b/reactos/dll/win32/samsrv/CMakeLists.txt index c8fb5722d5d..83cacc1a542 100644 --- a/reactos/dll/win32/samsrv/CMakeLists.txt +++ b/reactos/dll/win32/samsrv/CMakeLists.txt @@ -15,6 +15,7 @@ list(APPEND SOURCE registry.c samrpc.c samsrv.c + security.c setup.c user.c utils.c diff --git a/reactos/dll/win32/samsrv/samsrv.h b/reactos/dll/win32/samsrv/samsrv.h index 8d942fa7a56..a9508cef8e5 100644 --- a/reactos/dll/win32/samsrv/samsrv.h +++ b/reactos/dll/win32/samsrv/samsrv.h @@ -300,6 +300,13 @@ VOID SampStartRpcServer(VOID); +/* security.c */ + +NTSTATUS +SampCreateServerSD(OUT PSECURITY_DESCRIPTOR *ServerSd, + OUT PULONG Size); + + /* setup.c */ BOOL diff --git a/reactos/dll/win32/samsrv/security.c b/reactos/dll/win32/samsrv/security.c new file mode 100644 index 00000000000..b26175fa0f7 --- /dev/null +++ b/reactos/dll/win32/samsrv/security.c @@ -0,0 +1,286 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: Security Account Manager (SAM) Server + * FILE: reactos/dll/win32/samsrv/security.c + * PURPOSE: Seccurity descriptor functions + * + * PROGRAMMERS: Eric Kohl + */ + +/* INCLUDES ****************************************************************/ + +#include "samsrv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(samsrv); + + +/* GLOBALS *****************************************************************/ + +static SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; +static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; + + +/* FUNCTIONS ***************************************************************/ + +NTSTATUS +SampCreateServerSD(OUT PSECURITY_DESCRIPTOR *ServerSd, + OUT PULONG Size) +{ + PSECURITY_DESCRIPTOR AbsSD = NULL; + PSECURITY_DESCRIPTOR RelSD = NULL; + PSID EveryoneSid = NULL; + PSID AnonymousSid = NULL; + PSID AdministratorsSid = NULL; + PACL Dacl = NULL; + PACL Sacl = NULL; + ULONG DaclSize; + ULONG SaclSize; + ULONG RelSDSize = 0; + NTSTATUS Status = STATUS_SUCCESS; + + + /* Create the Everyone SID */ + Status = RtlAllocateAndInitializeSid(&WorldAuthority, + 1, + SECURITY_WORLD_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &EveryoneSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Anonymous SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 1, + SECURITY_ANONYMOUS_LOGON_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &AnonymousSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Administrators SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, + 0, + 0, + 0, + 0, + 0, + &AdministratorsSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + + /* Allocate a buffer for the absolute SD */ + AbsSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(SECURITY_DESCRIPTOR)); + if (AbsSD == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + /* Create the absolute SD */ + Status = RtlCreateSecurityDescriptor(AbsSD, + SECURITY_DESCRIPTOR_REVISION); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* allocate and create the DACL */ + DaclSize = sizeof(ACL) + + 2 * sizeof(ACE) + + RtlLengthSid(EveryoneSid) + + RtlLengthSid(AdministratorsSid); + + Dacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Dacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + Status = RtlCreateAcl(Dacl, + DaclSize, + ACL_REVISION); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + SAM_SERVER_READ | SAM_SERVER_EXECUTE, + EveryoneSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + SAM_SERVER_ALL_ACCESS, + AdministratorsSid); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the DACL */ + Status = RtlSetDaclSecurityDescriptor(AbsSD, + TRUE, + Dacl, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* allocate and create the SACL */ + SaclSize = sizeof(ACL) + + 2 * sizeof(ACE) + + RtlLengthSid(EveryoneSid) + + RtlLengthSid(AnonymousSid); + + Sacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Sacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + Status = RtlCreateAcl(Sacl, + SaclSize, + ACL_REVISION); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAuditAccessAce(Sacl, + ACL_REVISION, + ACCESS_SYSTEM_SECURITY | WRITE_DAC | DELETE | + SAM_SERVER_CREATE_DOMAIN | SAM_SERVER_INITIALIZE | + SAM_SERVER_SHUTDOWN, + EveryoneSid, + TRUE, + TRUE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAuditAccessAce(Sacl, + ACL_REVISION, + STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, + AnonymousSid, + TRUE, + TRUE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the SACL */ + Status = RtlSetSaclSecurityDescriptor(AbsSD, + TRUE, + Sacl, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the owner SID */ + Status = RtlSetOwnerSecurityDescriptor(AbsSD, + AdministratorsSid, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the group SID */ + Status = RtlSetGroupSecurityDescriptor(AbsSD, + AdministratorsSid, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Get the reqired buffer size for the self-relative SD */ + Status = RtlAbsoluteToSelfRelativeSD(AbsSD, + NULL, + &RelSDSize); + if (Status != STATUS_BUFFER_TOO_SMALL) + goto done; + + /* Allocate a buffer for the self-relative SD */ + RelSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + RelSDSize); + if (RelSD == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + /* Convert the absolute SD to self-relative format */ + Status = RtlAbsoluteToSelfRelativeSD(AbsSD, + RelSD, + &RelSDSize); + if (Status == STATUS_BUFFER_TOO_SMALL) + { + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + *ServerSd = RelSD; + *Size = RelSDSize; + +done: + if (!NT_SUCCESS(Status)) + { + if (RelSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, RelSD); + } + + if (EveryoneSid != NULL) + RtlFreeSid(EveryoneSid); + + if (AnonymousSid != NULL) + RtlFreeSid(AnonymousSid); + + if (AdministratorsSid != NULL) + RtlFreeSid(AdministratorsSid); + + if (Dacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl); + + if (Sacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sacl); + + if (AbsSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, AbsSD); + + return Status; +} + +/* EOF */ diff --git a/reactos/dll/win32/samsrv/setup.c b/reactos/dll/win32/samsrv/setup.c index b6e9268974a..76a262f5a8c 100644 --- a/reactos/dll/win32/samsrv/setup.c +++ b/reactos/dll/win32/samsrv/setup.c @@ -722,6 +722,8 @@ SampSetupCreateServer(IN HANDLE hSamKey, { HANDLE hServerKey = NULL; HANDLE hDomainsKey = NULL; + PSECURITY_DESCRIPTOR Sd = NULL; + ULONG SdSize = 0; NTSTATUS Status; Status = SampRegCreateKey(hSamKey, @@ -738,11 +740,28 @@ SampSetupCreateServer(IN HANDLE hSamKey, if (!NT_SUCCESS(Status)) goto done; + /* Create the server SD */ + Status = SampCreateServerSD(&Sd, + &SdSize); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set SecDesc attribute*/ + Status = SampRegSetValue(hServerKey, + L"SecDesc", + REG_BINARY, + Sd, + SdSize); + if (!NT_SUCCESS(Status)) + goto done; + SampRegCloseKey(hDomainsKey); *lpServerKey = hServerKey; done: + if (Sd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sd); return Status; }