https://git.reactos.org/?p=reactos.git;a=commitdiff;h=56a2c0fec4eb69f898b98…
commit 56a2c0fec4eb69f898b98439bc4a5b0353e6f759
Author: George Bișoc <george.bisoc(a)reactos.org>
AuthorDate: Fri Feb 18 21:42:51 2022 +0100
Commit: George Bișoc <george.bisoc(a)reactos.org>
CommitDate: Fri May 6 10:09:51 2022 +0200
[RPCRT4] Set up a security descriptor for RPC named pipes
rpcrt4_create_pipe_security function will be held in charge to set up security
descriptors specific for each named pipe upon creation in rpcrt4_conn_create_pipe. The
descriptor is then freed after the pipe is no longer needed.
---
dll/win32/rpcrt4/rpc_transport.c | 240 +++++++++++++++++++++++++++++++++++++++
1 file changed, 240 insertions(+)
diff --git a/dll/win32/rpcrt4/rpc_transport.c b/dll/win32/rpcrt4/rpc_transport.c
index 88f027d9990..be0d052bef3 100644
--- a/dll/win32/rpcrt4/rpc_transport.c
+++ b/dll/win32/rpcrt4/rpc_transport.c
@@ -107,23 +107,263 @@ static void release_np_event(RpcConnection_np *connection, HANDLE
event)
CloseHandle(event);
}
+#ifdef __REACTOS__
+/**
+ * @brief
+ * Creates a security descriptor for RPC4 pipe
+ *
+ * @param[out] SecDesc
+ * A pointer to an allocated security descriptor.
+ *
+ * @return
+ * ERROR_SUCCESS is returned if the function has
+ * successfully created the security descriptor,
+ * otherwise a Win32 error code is returned.
+ *
+ * @remarks
+ * Everyone (aka World SID) and anonynous users
+ * are given a subset of rights to access the pipe,
+ * whereas admins are given full power.
+ */
+static DWORD rpcrt4_create_pipe_security(PSECURITY_DESCRIPTOR *SecDesc)
+{
+ DWORD ErrCode;
+ PACL Dacl;
+ ULONG DaclSize, RelSDSize = 0;
+ PSID EveryoneSid = NULL, AnonymousSid = NULL, AdminsSid = NULL;
+ PSECURITY_DESCRIPTOR AbsSD = NULL, RelSD = NULL;
+ static SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
+ static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
+
+ if (!AllocateAndInitializeSid(&WorldAuthority,
+ 1,
+ SECURITY_WORLD_RID,
+ 0, 0, 0, 0, 0, 0, 0,
+ &EveryoneSid))
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to allocate Everyone SID (error
code %d)\n", GetLastError());
+ return GetLastError();
+ }
+
+ if (!AllocateAndInitializeSid(&NtAuthority,
+ 1,
+ SECURITY_ANONYMOUS_LOGON_RID,
+ 0, 0, 0, 0, 0, 0, 0,
+ &AnonymousSid))
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to allocate Anonymous 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))
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to allocate Admins SID (error
code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ AbsSD = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SECURITY_DESCRIPTOR));
+ if (AbsSD == NULL)
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to allocate absolute
SD!\n");
+ ErrCode = ERROR_OUTOFMEMORY;
+ goto Quit;
+ }
+
+ if (!InitializeSecurityDescriptor(AbsSD, SECURITY_DESCRIPTOR_REVISION))
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to create absolute SD (error code
%d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ DaclSize = sizeof(ACL) +
+ sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(EveryoneSid) +
+ sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(AnonymousSid) +
+ sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(AdminsSid);
+
+
+ Dacl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DaclSize);
+ if (Dacl == NULL)
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to allocate DACL!\n");
+ ErrCode = ERROR_OUTOFMEMORY;
+ goto Quit;
+ }
+
+ if (!InitializeAcl(Dacl, DaclSize, ACL_REVISION))
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to create DACL (error code
%d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!AddAccessAllowedAce(Dacl,
+ ACL_REVISION,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE | READ_CONTROL,
+ EveryoneSid))
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to set up ACE for Everyone SID
(error code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!AddAccessAllowedAce(Dacl,
+ ACL_REVISION,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE | READ_CONTROL,
+ AnonymousSid))
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to set up ACE for Anonymous SID
(error code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!AddAccessAllowedAce(Dacl,
+ ACL_REVISION,
+ GENERIC_ALL,
+ AdminsSid))
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to set up ACE for Admins SID
(error code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!SetSecurityDescriptorDacl(AbsSD, TRUE, Dacl, FALSE))
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to set DACL to absolute SD (error
code %d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!SetSecurityDescriptorOwner(AbsSD, AdminsSid, FALSE))
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to set SD owner (error code
%d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!SetSecurityDescriptorGroup(AbsSD, AdminsSid, FALSE))
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to set SD group (error code
%d)\n", GetLastError());
+ ErrCode = GetLastError();
+ goto Quit;
+ }
+
+ if (!MakeSelfRelativeSD(AbsSD, NULL, &RelSDSize) && GetLastError() !=
ERROR_INSUFFICIENT_BUFFER)
+ {
+ ERR("rpcrt4_create_pipe_security(): 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)
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to allocate relative
SD!\n");
+ ErrCode = ERROR_OUTOFMEMORY;
+ goto Quit;
+ }
+
+ if (!MakeSelfRelativeSD(AbsSD, RelSD, &RelSDSize) && GetLastError() ==
ERROR_INSUFFICIENT_BUFFER)
+ {
+ ERR("rpcrt4_create_pipe_security(): Failed to allocate relative SD, buffer
too smal (expected size %lu)\n", RelSDSize);
+ ErrCode = ERROR_INSUFFICIENT_BUFFER;
+ goto Quit;
+ }
+
+ TRACE("rpcrt4_create_pipe_security(): Success!\n");
+ *SecDesc = RelSD;
+ ErrCode = ERROR_SUCCESS;
+
+Quit:
+ if (ErrCode != ERROR_SUCCESS)
+ {
+ if (RelSD != NULL)
+ {
+ HeapFree(GetProcessHeap(), 0, RelSD);
+ }
+ }
+
+ if (EveryoneSid != NULL)
+ {
+ FreeSid(EveryoneSid);
+ }
+
+ if (AnonymousSid != NULL)
+ {
+ FreeSid(AnonymousSid);
+ }
+
+ if (AdminsSid != NULL)
+ {
+ FreeSid(AdminsSid);
+ }
+
+ if (Dacl != NULL)
+ {
+ HeapFree(GetProcessHeap(), 0, Dacl);
+ }
+
+ if (AbsSD != NULL)
+ {
+ HeapFree(GetProcessHeap(), 0, AbsSD);
+ }
+
+ return ErrCode;
+}
+#endif
+
static RPC_STATUS rpcrt4_conn_create_pipe(RpcConnection *conn)
{
RpcConnection_np *connection = (RpcConnection_np *) conn;
+#ifdef __REACTOS__
+ DWORD ErrCode;
+ SECURITY_ATTRIBUTES SecurityAttributes;
+ PSECURITY_DESCRIPTOR PipeSecDesc;
+#endif
TRACE("listening on %s\n", connection->listen_pipe);
+#ifdef __REACTOS__
+ ErrCode = rpcrt4_create_pipe_security(&PipeSecDesc);
+ if (ErrCode != ERROR_SUCCESS)
+ {
+ ERR("rpcrt4_conn_create_pipe(): Pipe security descriptor creation
failed!\n");
+ return RPC_S_CANT_CREATE_ENDPOINT;
+ }
+
+ SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ SecurityAttributes.lpSecurityDescriptor = PipeSecDesc;
+ SecurityAttributes.bInheritHandle = FALSE;
+
+ connection->pipe = CreateNamedPipeA(connection->listen_pipe, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED,
+ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
+ PIPE_UNLIMITED_INSTANCES,
+ RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000,
&SecurityAttributes);
+ HeapFree(GetProcessHeap(), 0, PipeSecDesc);
+#else
connection->pipe = CreateNamedPipeA(connection->listen_pipe, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
PIPE_UNLIMITED_INSTANCES,
RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000,
NULL);
+#endif
if (connection->pipe == INVALID_HANDLE_VALUE)
{
WARN("CreateNamedPipe failed with error %d\n", GetLastError());
if (GetLastError() == ERROR_FILE_EXISTS)
+ {
return RPC_S_DUPLICATE_ENDPOINT;
+ }
else
+ {
return RPC_S_CANT_CREATE_ENDPOINT;
+ }
}
return RPC_S_OK;