Skip to content

Commit 56a2c0f

Browse files
committed
[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.
1 parent eccae20 commit 56a2c0f

File tree

1 file changed

+240
-0
lines changed

1 file changed

+240
-0
lines changed

dll/win32/rpcrt4/rpc_transport.c

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,23 +107,263 @@ static void release_np_event(RpcConnection_np *connection, HANDLE event)
107107
CloseHandle(event);
108108
}
109109

110+
#ifdef __REACTOS__
111+
/**
112+
* @brief
113+
* Creates a security descriptor for RPC4 pipe
114+
*
115+
* @param[out] SecDesc
116+
* A pointer to an allocated security descriptor.
117+
*
118+
* @return
119+
* ERROR_SUCCESS is returned if the function has
120+
* successfully created the security descriptor,
121+
* otherwise a Win32 error code is returned.
122+
*
123+
* @remarks
124+
* Everyone (aka World SID) and anonynous users
125+
* are given a subset of rights to access the pipe,
126+
* whereas admins are given full power.
127+
*/
128+
static DWORD rpcrt4_create_pipe_security(PSECURITY_DESCRIPTOR *SecDesc)
129+
{
130+
DWORD ErrCode;
131+
PACL Dacl;
132+
ULONG DaclSize, RelSDSize = 0;
133+
PSID EveryoneSid = NULL, AnonymousSid = NULL, AdminsSid = NULL;
134+
PSECURITY_DESCRIPTOR AbsSD = NULL, RelSD = NULL;
135+
static SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
136+
static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
137+
138+
if (!AllocateAndInitializeSid(&WorldAuthority,
139+
1,
140+
SECURITY_WORLD_RID,
141+
0, 0, 0, 0, 0, 0, 0,
142+
&EveryoneSid))
143+
{
144+
ERR("rpcrt4_create_pipe_security(): Failed to allocate Everyone SID (error code %d)\n", GetLastError());
145+
return GetLastError();
146+
}
147+
148+
if (!AllocateAndInitializeSid(&NtAuthority,
149+
1,
150+
SECURITY_ANONYMOUS_LOGON_RID,
151+
0, 0, 0, 0, 0, 0, 0,
152+
&AnonymousSid))
153+
{
154+
ERR("rpcrt4_create_pipe_security(): Failed to allocate Anonymous SID (error code %d)\n", GetLastError());
155+
ErrCode = GetLastError();
156+
goto Quit;
157+
}
158+
159+
if (!AllocateAndInitializeSid(&NtAuthority,
160+
2,
161+
SECURITY_BUILTIN_DOMAIN_RID,
162+
DOMAIN_ALIAS_RID_ADMINS,
163+
0, 0, 0, 0, 0, 0,
164+
&AdminsSid))
165+
{
166+
ERR("rpcrt4_create_pipe_security(): Failed to allocate Admins SID (error code %d)\n", GetLastError());
167+
ErrCode = GetLastError();
168+
goto Quit;
169+
}
170+
171+
AbsSD = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SECURITY_DESCRIPTOR));
172+
if (AbsSD == NULL)
173+
{
174+
ERR("rpcrt4_create_pipe_security(): Failed to allocate absolute SD!\n");
175+
ErrCode = ERROR_OUTOFMEMORY;
176+
goto Quit;
177+
}
178+
179+
if (!InitializeSecurityDescriptor(AbsSD, SECURITY_DESCRIPTOR_REVISION))
180+
{
181+
ERR("rpcrt4_create_pipe_security(): Failed to create absolute SD (error code %d)\n", GetLastError());
182+
ErrCode = GetLastError();
183+
goto Quit;
184+
}
185+
186+
DaclSize = sizeof(ACL) +
187+
sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(EveryoneSid) +
188+
sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(AnonymousSid) +
189+
sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(AdminsSid);
190+
191+
192+
Dacl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DaclSize);
193+
if (Dacl == NULL)
194+
{
195+
ERR("rpcrt4_create_pipe_security(): Failed to allocate DACL!\n");
196+
ErrCode = ERROR_OUTOFMEMORY;
197+
goto Quit;
198+
}
199+
200+
if (!InitializeAcl(Dacl, DaclSize, ACL_REVISION))
201+
{
202+
ERR("rpcrt4_create_pipe_security(): Failed to create DACL (error code %d)\n", GetLastError());
203+
ErrCode = GetLastError();
204+
goto Quit;
205+
}
206+
207+
if (!AddAccessAllowedAce(Dacl,
208+
ACL_REVISION,
209+
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE | READ_CONTROL,
210+
EveryoneSid))
211+
{
212+
ERR("rpcrt4_create_pipe_security(): Failed to set up ACE for Everyone SID (error code %d)\n", GetLastError());
213+
ErrCode = GetLastError();
214+
goto Quit;
215+
}
216+
217+
if (!AddAccessAllowedAce(Dacl,
218+
ACL_REVISION,
219+
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE | READ_CONTROL,
220+
AnonymousSid))
221+
{
222+
ERR("rpcrt4_create_pipe_security(): Failed to set up ACE for Anonymous SID (error code %d)\n", GetLastError());
223+
ErrCode = GetLastError();
224+
goto Quit;
225+
}
226+
227+
if (!AddAccessAllowedAce(Dacl,
228+
ACL_REVISION,
229+
GENERIC_ALL,
230+
AdminsSid))
231+
{
232+
ERR("rpcrt4_create_pipe_security(): Failed to set up ACE for Admins SID (error code %d)\n", GetLastError());
233+
ErrCode = GetLastError();
234+
goto Quit;
235+
}
236+
237+
if (!SetSecurityDescriptorDacl(AbsSD, TRUE, Dacl, FALSE))
238+
{
239+
ERR("rpcrt4_create_pipe_security(): Failed to set DACL to absolute SD (error code %d)\n", GetLastError());
240+
ErrCode = GetLastError();
241+
goto Quit;
242+
}
243+
244+
if (!SetSecurityDescriptorOwner(AbsSD, AdminsSid, FALSE))
245+
{
246+
ERR("rpcrt4_create_pipe_security(): Failed to set SD owner (error code %d)\n", GetLastError());
247+
ErrCode = GetLastError();
248+
goto Quit;
249+
}
250+
251+
if (!SetSecurityDescriptorGroup(AbsSD, AdminsSid, FALSE))
252+
{
253+
ERR("rpcrt4_create_pipe_security(): Failed to set SD group (error code %d)\n", GetLastError());
254+
ErrCode = GetLastError();
255+
goto Quit;
256+
}
257+
258+
if (!MakeSelfRelativeSD(AbsSD, NULL, &RelSDSize) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
259+
{
260+
ERR("rpcrt4_create_pipe_security(): Unexpected error code (error code %d -- must be ERROR_INSUFFICIENT_BUFFER)\n", GetLastError());
261+
ErrCode = GetLastError();
262+
goto Quit;
263+
}
264+
265+
RelSD = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, RelSDSize);
266+
if (RelSD == NULL)
267+
{
268+
ERR("rpcrt4_create_pipe_security(): Failed to allocate relative SD!\n");
269+
ErrCode = ERROR_OUTOFMEMORY;
270+
goto Quit;
271+
}
272+
273+
if (!MakeSelfRelativeSD(AbsSD, RelSD, &RelSDSize) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
274+
{
275+
ERR("rpcrt4_create_pipe_security(): Failed to allocate relative SD, buffer too smal (expected size %lu)\n", RelSDSize);
276+
ErrCode = ERROR_INSUFFICIENT_BUFFER;
277+
goto Quit;
278+
}
279+
280+
TRACE("rpcrt4_create_pipe_security(): Success!\n");
281+
*SecDesc = RelSD;
282+
ErrCode = ERROR_SUCCESS;
283+
284+
Quit:
285+
if (ErrCode != ERROR_SUCCESS)
286+
{
287+
if (RelSD != NULL)
288+
{
289+
HeapFree(GetProcessHeap(), 0, RelSD);
290+
}
291+
}
292+
293+
if (EveryoneSid != NULL)
294+
{
295+
FreeSid(EveryoneSid);
296+
}
297+
298+
if (AnonymousSid != NULL)
299+
{
300+
FreeSid(AnonymousSid);
301+
}
302+
303+
if (AdminsSid != NULL)
304+
{
305+
FreeSid(AdminsSid);
306+
}
307+
308+
if (Dacl != NULL)
309+
{
310+
HeapFree(GetProcessHeap(), 0, Dacl);
311+
}
312+
313+
if (AbsSD != NULL)
314+
{
315+
HeapFree(GetProcessHeap(), 0, AbsSD);
316+
}
317+
318+
return ErrCode;
319+
}
320+
#endif
321+
110322
static RPC_STATUS rpcrt4_conn_create_pipe(RpcConnection *conn)
111323
{
112324
RpcConnection_np *connection = (RpcConnection_np *) conn;
325+
#ifdef __REACTOS__
326+
DWORD ErrCode;
327+
SECURITY_ATTRIBUTES SecurityAttributes;
328+
PSECURITY_DESCRIPTOR PipeSecDesc;
329+
#endif
113330

114331
TRACE("listening on %s\n", connection->listen_pipe);
115332

333+
#ifdef __REACTOS__
334+
ErrCode = rpcrt4_create_pipe_security(&PipeSecDesc);
335+
if (ErrCode != ERROR_SUCCESS)
336+
{
337+
ERR("rpcrt4_conn_create_pipe(): Pipe security descriptor creation failed!\n");
338+
return RPC_S_CANT_CREATE_ENDPOINT;
339+
}
340+
341+
SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
342+
SecurityAttributes.lpSecurityDescriptor = PipeSecDesc;
343+
SecurityAttributes.bInheritHandle = FALSE;
344+
345+
connection->pipe = CreateNamedPipeA(connection->listen_pipe, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
346+
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
347+
PIPE_UNLIMITED_INSTANCES,
348+
RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000, &SecurityAttributes);
349+
HeapFree(GetProcessHeap(), 0, PipeSecDesc);
350+
#else
116351
connection->pipe = CreateNamedPipeA(connection->listen_pipe, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
117352
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
118353
PIPE_UNLIMITED_INSTANCES,
119354
RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000, NULL);
355+
#endif
120356
if (connection->pipe == INVALID_HANDLE_VALUE)
121357
{
122358
WARN("CreateNamedPipe failed with error %d\n", GetLastError());
123359
if (GetLastError() == ERROR_FILE_EXISTS)
360+
{
124361
return RPC_S_DUPLICATE_ENDPOINT;
362+
}
125363
else
364+
{
126365
return RPC_S_CANT_CREATE_ENDPOINT;
366+
}
127367
}
128368

129369
return RPC_S_OK;

0 commit comments

Comments
 (0)