https://git.reactos.org/?p=reactos.git;a=commitdiff;h=eccae203e09d88f0b589a…
commit eccae203e09d88f0b589a690315582e63d362eae
Author: George Bișoc <george.bisoc(a)reactos.org>
AuthorDate: Sun Feb 20 20:31:33 2022 +0100
Commit: George Bișoc <george.bisoc(a)reactos.org>
CommitDate: Fri May 6 10:09:50 2022 +0200
[DHCPCSVC] Set up a security descriptor for DHCP named pipe
---
base/services/dhcpcsvc/dhcp/pipe.c | 253 ++++++++++++++++++++++++++++++++++++-
1 file changed, 252 insertions(+), 1 deletion(-)
diff --git a/base/services/dhcpcsvc/dhcp/pipe.c b/base/services/dhcpcsvc/dhcp/pipe.c
index a323d171ebd..899b2322cf1 100644
--- a/base/services/dhcpcsvc/dhcp/pipe.c
+++ b/base/services/dhcpcsvc/dhcp/pipe.c
@@ -36,6 +36,243 @@ DWORD PipeSend( HANDLE CommPipe, COMM_DHCP_REPLY *Reply ) {
return Success ? Written : -1;
}
+/**
+ * @brief
+ * Creates a security descriptor for the DHCP pipe
+ * service.
+ *
+ * @param[out] SecurityDescriptor
+ * A pointer to an allocated security descriptor
+ * for the DHCP pipe.
+ *
+ * @return
+ * ERROR_SUCCESS is returned if the function has
+ * successfully created the descriptor otherwise
+ * a Win32 error code is returned.
+ *
+ * @remarks
+ * Both admins and local system are given full power
+ * over the DHCP pipe whereas authenticated users
+ * and network operators can only read over this pipe.
+ * They can also execute it.
+ */
+DWORD CreateDhcpPipeSecurity( PSECURITY_DESCRIPTOR *SecurityDescriptor ) {
+ DWORD ErrCode;
+ PACL Dacl;
+ ULONG DaclSize, RelSDSize = 0;
+ PSECURITY_DESCRIPTOR AbsSD = NULL, RelSD = NULL;
+ PSID AuthenticatedUsersSid = NULL, NetworkOpsSid = NULL, AdminsSid = NULL, SystemSid
= NULL;
+ static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
+
+ if (!AllocateAndInitializeSid(&NtAuthority,
+ 1,
+ SECURITY_AUTHENTICATED_USER_RID,
+ 0, 0, 0, 0, 0, 0, 0,
+ &AuthenticatedUsersSid))
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to create Authenticated Users SID
(error code %d)\n", GetLastError());
+ return GetLastError();
+ }
+
+ if (!AllocateAndInitializeSid(&NtAuthority,
+ 2,
+ SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS,
+ 0, 0, 0, 0, 0, 0,
+ &NetworkOpsSid))
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to create Network Ops SID (error
code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!AllocateAndInitializeSid(&NtAuthority,
+ 2,
+ SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS,
+ 0, 0, 0, 0, 0, 0,
+ &AdminsSid))
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to create Admins SID (error code
%d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!AllocateAndInitializeSid(&NtAuthority,
+ 1,
+ SECURITY_LOCAL_SYSTEM_RID,
+ 0, 0, 0, 0, 0, 0, 0,
+ &SystemSid))
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to create Local System SID (error
code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ AbsSD = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SECURITY_DESCRIPTOR));
+ if (!AbsSD)
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to allocate absolute security
descriptor!\n");
+ ErrCode = ERROR_OUTOFMEMORY;
+ goto Quit;
+ }
+
+ if (!InitializeSecurityDescriptor(AbsSD, SECURITY_DESCRIPTOR_REVISION))
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to initialize absolute security
descriptor (error code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ DaclSize = sizeof(ACL) +
+ sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(AuthenticatedUsersSid) +
+ sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(NetworkOpsSid) +
+ sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(AdminsSid) +
+ sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(SystemSid);
+
+ Dacl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DaclSize);
+ if (!Dacl)
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to allocate DACL!\n");
+ ErrCode = ERROR_OUTOFMEMORY;
+ goto Quit;
+ }
+
+ if (!InitializeAcl(Dacl, DaclSize, ACL_REVISION))
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to initialize DACL (error code
%d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!AddAccessAllowedAce(Dacl,
+ ACL_REVISION,
+ GENERIC_READ | GENERIC_EXECUTE,
+ AuthenticatedUsersSid))
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to set up ACE for Authenticated
Users SID (error code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!AddAccessAllowedAce(Dacl,
+ ACL_REVISION,
+ GENERIC_READ | GENERIC_EXECUTE,
+ NetworkOpsSid))
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to set up ACE for Network Ops SID
(error code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!AddAccessAllowedAce(Dacl,
+ ACL_REVISION,
+ GENERIC_ALL,
+ AdminsSid))
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to set up ACE for Admins SID
(error code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!AddAccessAllowedAce(Dacl,
+ ACL_REVISION,
+ GENERIC_ALL,
+ SystemSid))
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to set up ACE for Local System SID
(error code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!SetSecurityDescriptorDacl(AbsSD, TRUE, Dacl, FALSE))
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to set up DACL to absolute
security descriptor (error code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!SetSecurityDescriptorOwner(AbsSD, AdminsSid, FALSE))
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to set up owner to absolute
security descriptor (error code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!SetSecurityDescriptorGroup(AbsSD, SystemSid, FALSE))
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to set up group to absolute
security descriptor (error code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!MakeSelfRelativeSD(AbsSD, NULL, &RelSDSize) && GetLastError() !=
ERROR_INSUFFICIENT_BUFFER)
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Unexpected error code (error code %d --
must be ERROR_INSUFFICIENT_BUFFER)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ RelSD = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, RelSDSize);
+ if (RelSD == NULL)
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to allocate relative
SD!\n");
+ ErrCode = ERROR_OUTOFMEMORY;
+ goto Quit;
+ }
+
+ if (!MakeSelfRelativeSD(AbsSD, RelSD, &RelSDSize) && GetLastError() ==
ERROR_INSUFFICIENT_BUFFER)
+ {
+ DPRINT1("CreateDhcpPipeSecurity(): Failed to allocate relative SD, buffer
too smal (expected size %lu)\n", RelSDSize);
+ ErrCode = ERROR_INSUFFICIENT_BUFFER;
+ goto Quit;
+ }
+
+ *SecurityDescriptor = RelSD;
+ ErrCode = ERROR_SUCCESS;
+
+Quit:
+ if (ErrCode != ERROR_SUCCESS)
+ {
+ if (RelSD)
+ {
+ HeapFree(GetProcessHeap(), 0, RelSD);
+ }
+ }
+
+ if (AuthenticatedUsersSid)
+ {
+ FreeSid(AuthenticatedUsersSid);
+ }
+
+ if (NetworkOpsSid)
+ {
+ FreeSid(NetworkOpsSid);
+ }
+
+ if (AdminsSid)
+ {
+ FreeSid(AdminsSid);
+ }
+
+ if (SystemSid)
+ {
+ FreeSid(SystemSid);
+ }
+
+ if (Dacl)
+ {
+ HeapFree(GetProcessHeap(), 0, Dacl);
+ }
+
+ if (AbsSD)
+ {
+ HeapFree(GetProcessHeap(), 0, AbsSD);
+ }
+
+ return ErrCode;
+}
+
DWORD WINAPI PipeThreadProc( LPVOID Parameter ) {
DWORD BytesRead;
COMM_DHCP_REQ Req;
@@ -45,9 +282,22 @@ DWORD WINAPI PipeThreadProc( LPVOID Parameter ) {
HANDLE CommPipe;
OVERLAPPED Overlapped = {0};
DWORD dwError;
+ SECURITY_ATTRIBUTES SecurityAttributes;
+ PSECURITY_DESCRIPTOR DhcpPipeSD = NULL;
DPRINT("PipeThreadProc(%p)\n", Parameter);
+ dwError = CreateDhcpPipeSecurity(&DhcpPipeSD);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DbgPrint("DHCP: Could not create security descriptor for pipe\n");
+ return FALSE;
+ }
+
+ SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ SecurityAttributes.lpSecurityDescriptor = DhcpPipeSD;
+ SecurityAttributes.bInheritHandle = FALSE;
+
CommPipe = CreateNamedPipeW
( DHCP_PIPE_NAME,
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
@@ -56,7 +306,8 @@ DWORD WINAPI PipeThreadProc( LPVOID Parameter ) {
COMM_PIPE_OUTPUT_BUFFER,
COMM_PIPE_INPUT_BUFFER,
COMM_PIPE_DEFAULT_TIMEOUT,
- NULL );
+ &SecurityAttributes );
+ HeapFree(GetProcessHeap(), 0, DhcpPipeSD);
if (CommPipe == INVALID_HANDLE_VALUE)
{
DbgPrint("DHCP: Could not create named pipe\n");