ReactOS  0.4.15-dev-4914-g2220e56
pipe.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * FILE: subsys/system/dhcp/pipe.c
5  * PURPOSE: DHCP client pipe
6  * PROGRAMMER: arty
7  */
8 
9 #include <rosdhcp.h>
10 
11 #define NDEBUG
12 #include <reactos/debug.h>
13 
14 #define COMM_PIPE_OUTPUT_BUFFER sizeof(COMM_DHCP_REQ)
15 #define COMM_PIPE_INPUT_BUFFER sizeof(COMM_DHCP_REPLY)
16 #define COMM_PIPE_DEFAULT_TIMEOUT 1000
17 
18 DWORD PipeSend( HANDLE CommPipe, COMM_DHCP_REPLY *Reply ) {
19  DWORD Written = 0;
20  OVERLAPPED Overlapped = {0};
21  BOOL Success =
22  WriteFile( CommPipe,
23  Reply,
24  sizeof(*Reply),
25  &Written,
26  &Overlapped);
27  if (!Success)
28  {
29  WaitForSingleObject(CommPipe, INFINITE);
30  Success = GetOverlappedResult(CommPipe,
31  &Overlapped,
32  &Written,
33  TRUE);
34  }
35 
36  return Success ? Written : -1;
37 }
38 
60  DWORD ErrCode;
61  PACL Dacl;
62  ULONG DaclSize, RelSDSize = 0;
63  PSECURITY_DESCRIPTOR AbsSD = NULL, RelSD = NULL;
64  PSID AuthenticatedUsersSid = NULL, NetworkOpsSid = NULL, AdminsSid = NULL, SystemSid = NULL;
66 
68  1,
70  0, 0, 0, 0, 0, 0, 0,
71  &AuthenticatedUsersSid))
72  {
73  DPRINT1("CreateDhcpPipeSecurity(): Failed to create Authenticated Users SID (error code %d)\n", GetLastError());
74  return GetLastError();
75  }
76 
78  2,
81  0, 0, 0, 0, 0, 0,
82  &NetworkOpsSid))
83  {
84  DPRINT1("CreateDhcpPipeSecurity(): Failed to create Network Ops SID (error code %d)\n", GetLastError());
85  ErrCode = GetLastError();
86  goto Quit;
87  }
88 
90  2,
93  0, 0, 0, 0, 0, 0,
94  &AdminsSid))
95  {
96  DPRINT1("CreateDhcpPipeSecurity(): Failed to create Admins SID (error code %d)\n", GetLastError());
97  ErrCode = GetLastError();
98  goto Quit;
99  }
100 
102  1,
104  0, 0, 0, 0, 0, 0, 0,
105  &SystemSid))
106  {
107  DPRINT1("CreateDhcpPipeSecurity(): Failed to create Local System SID (error code %d)\n", GetLastError());
108  ErrCode = GetLastError();
109  goto Quit;
110  }
111 
113  if (!AbsSD)
114  {
115  DPRINT1("CreateDhcpPipeSecurity(): Failed to allocate absolute security descriptor!\n");
116  ErrCode = ERROR_OUTOFMEMORY;
117  goto Quit;
118  }
119 
121  {
122  DPRINT1("CreateDhcpPipeSecurity(): Failed to initialize absolute security descriptor (error code %d)\n", GetLastError());
123  ErrCode = GetLastError();
124  goto Quit;
125  }
126 
127  DaclSize = sizeof(ACL) +
128  sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(AuthenticatedUsersSid) +
129  sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(NetworkOpsSid) +
130  sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(AdminsSid) +
131  sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(SystemSid);
132 
134  if (!Dacl)
135  {
136  DPRINT1("CreateDhcpPipeSecurity(): Failed to allocate DACL!\n");
137  ErrCode = ERROR_OUTOFMEMORY;
138  goto Quit;
139  }
140 
142  {
143  DPRINT1("CreateDhcpPipeSecurity(): Failed to initialize DACL (error code %d)\n", GetLastError());
144  ErrCode = GetLastError();
145  goto Quit;
146  }
147 
149  ACL_REVISION,
151  AuthenticatedUsersSid))
152  {
153  DPRINT1("CreateDhcpPipeSecurity(): Failed to set up ACE for Authenticated Users SID (error code %d)\n", GetLastError());
154  ErrCode = GetLastError();
155  goto Quit;
156  }
157 
159  ACL_REVISION,
161  NetworkOpsSid))
162  {
163  DPRINT1("CreateDhcpPipeSecurity(): Failed to set up ACE for Network Ops SID (error code %d)\n", GetLastError());
164  ErrCode = GetLastError();
165  goto Quit;
166  }
167 
169  ACL_REVISION,
170  GENERIC_ALL,
171  AdminsSid))
172  {
173  DPRINT1("CreateDhcpPipeSecurity(): Failed to set up ACE for Admins SID (error code %d)\n", GetLastError());
174  ErrCode = GetLastError();
175  goto Quit;
176  }
177 
179  ACL_REVISION,
180  GENERIC_ALL,
181  SystemSid))
182  {
183  DPRINT1("CreateDhcpPipeSecurity(): Failed to set up ACE for Local System SID (error code %d)\n", GetLastError());
184  ErrCode = GetLastError();
185  goto Quit;
186  }
187 
188  if (!SetSecurityDescriptorDacl(AbsSD, TRUE, Dacl, FALSE))
189  {
190  DPRINT1("CreateDhcpPipeSecurity(): Failed to set up DACL to absolute security descriptor (error code %d)\n", GetLastError());
191  ErrCode = GetLastError();
192  goto Quit;
193  }
194 
195  if (!SetSecurityDescriptorOwner(AbsSD, AdminsSid, FALSE))
196  {
197  DPRINT1("CreateDhcpPipeSecurity(): Failed to set up owner to absolute security descriptor (error code %d)\n", GetLastError());
198  ErrCode = GetLastError();
199  goto Quit;
200  }
201 
202  if (!SetSecurityDescriptorGroup(AbsSD, SystemSid, FALSE))
203  {
204  DPRINT1("CreateDhcpPipeSecurity(): Failed to set up group to absolute security descriptor (error code %d)\n", GetLastError());
205  ErrCode = GetLastError();
206  goto Quit;
207  }
208 
209  if (!MakeSelfRelativeSD(AbsSD, NULL, &RelSDSize) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
210  {
211  DPRINT1("CreateDhcpPipeSecurity(): Unexpected error code (error code %d -- must be ERROR_INSUFFICIENT_BUFFER)\n", GetLastError());
212  ErrCode = GetLastError();
213  goto Quit;
214  }
215 
216  RelSD = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, RelSDSize);
217  if (RelSD == NULL)
218  {
219  DPRINT1("CreateDhcpPipeSecurity(): Failed to allocate relative SD!\n");
220  ErrCode = ERROR_OUTOFMEMORY;
221  goto Quit;
222  }
223 
224  if (!MakeSelfRelativeSD(AbsSD, RelSD, &RelSDSize) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
225  {
226  DPRINT1("CreateDhcpPipeSecurity(): Failed to allocate relative SD, buffer too smal (expected size %lu)\n", RelSDSize);
227  ErrCode = ERROR_INSUFFICIENT_BUFFER;
228  goto Quit;
229  }
230 
231  *SecurityDescriptor = RelSD;
232  ErrCode = ERROR_SUCCESS;
233 
234 Quit:
235  if (ErrCode != ERROR_SUCCESS)
236  {
237  if (RelSD)
238  {
239  HeapFree(GetProcessHeap(), 0, RelSD);
240  }
241  }
242 
243  if (AuthenticatedUsersSid)
244  {
245  FreeSid(AuthenticatedUsersSid);
246  }
247 
248  if (NetworkOpsSid)
249  {
250  FreeSid(NetworkOpsSid);
251  }
252 
253  if (AdminsSid)
254  {
255  FreeSid(AdminsSid);
256  }
257 
258  if (SystemSid)
259  {
260  FreeSid(SystemSid);
261  }
262 
263  if (Dacl)
264  {
266  }
267 
268  if (AbsSD)
269  {
270  HeapFree(GetProcessHeap(), 0, AbsSD);
271  }
272 
273  return ErrCode;
274 }
275 
278  COMM_DHCP_REQ Req;
279  COMM_DHCP_REPLY Reply;
280  BOOL Result, Connected;
281  HANDLE Events[2];
282  HANDLE CommPipe;
283  OVERLAPPED Overlapped = {0};
284  DWORD dwError;
285  SECURITY_ATTRIBUTES SecurityAttributes;
286  PSECURITY_DESCRIPTOR DhcpPipeSD = NULL;
287 
288  DPRINT("PipeThreadProc(%p)\n", Parameter);
289 
290  dwError = CreateDhcpPipeSecurity(&DhcpPipeSD);
291  if (dwError != ERROR_SUCCESS)
292  {
293  DbgPrint("DHCP: Could not create security descriptor for pipe\n");
294  return FALSE;
295  }
296 
297  SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
298  SecurityAttributes.lpSecurityDescriptor = DhcpPipeSD;
299  SecurityAttributes.bInheritHandle = FALSE;
300 
301  CommPipe = CreateNamedPipeW
302  ( DHCP_PIPE_NAME,
305  1,
309  &SecurityAttributes );
310  HeapFree(GetProcessHeap(), 0, DhcpPipeSD);
311  if (CommPipe == INVALID_HANDLE_VALUE)
312  {
313  DbgPrint("DHCP: Could not create named pipe\n");
314  return FALSE;
315  }
316 
317  Events[0] = (HANDLE)Parameter;
318  Events[1] = CommPipe;
319 
320  while( TRUE )
321  {
322  Connected = ConnectNamedPipe(CommPipe, &Overlapped);
323  if (!Connected)
324  {
325  dwError = GetLastError();
326  if (dwError == ERROR_IO_PENDING)
327  {
329  DPRINT("WaitForMultipleObjects() returned %lu\n", dwError);
330  if (dwError == WAIT_OBJECT_0 + 1)
331  {
332  Connected = GetOverlappedResult(CommPipe,
333  &Overlapped,
334  &BytesRead,
335  TRUE);
336  }
337  else if (dwError == WAIT_OBJECT_0)
338  {
339  CancelIo(CommPipe);
340  CloseHandle(CommPipe);
341  CommPipe = INVALID_HANDLE_VALUE;
342  break;
343  }
344  }
345  }
346 
347  if (!Connected) {
348  DbgPrint("DHCP: Could not connect named pipe\n");
349  CloseHandle( CommPipe );
350  CommPipe = INVALID_HANDLE_VALUE;
351  break;
352  }
353 
354  Result = ReadFile(CommPipe, &Req, sizeof(Req), &BytesRead, &Overlapped);
355  if (!Result)
356  {
357  dwError = GetLastError();
358  if (dwError == ERROR_IO_PENDING)
359  {
361  DPRINT("WaitForMultipleObjects() returned %lu\n", dwError);
362  if (dwError == WAIT_OBJECT_0 + 1)
363  {
364  Result = GetOverlappedResult(CommPipe,
365  &Overlapped,
366  &BytesRead,
367  TRUE);
368  }
369  else if (dwError == WAIT_OBJECT_0)
370  {
371  CancelIo(CommPipe);
372  DisconnectNamedPipe( CommPipe );
373  CloseHandle(CommPipe);
374  CommPipe = INVALID_HANDLE_VALUE;
375  break;
376  }
377  }
378  }
379 
380  if( Result ) {
381  switch( Req.Type ) {
382  case DhcpReqQueryHWInfo:
383  DSQueryHWInfo( PipeSend, CommPipe, &Req );
384  break;
385 
387  DSLeaseIpAddress( PipeSend, CommPipe, &Req );
388  break;
389 
391  DSReleaseIpAddressLease( PipeSend, CommPipe, &Req );
392  break;
393 
395  DSRenewIpAddressLease( PipeSend, CommPipe, &Req );
396  break;
397 
399  DSStaticRefreshParams( PipeSend, CommPipe, &Req );
400  break;
401 
403  DSGetAdapterInfo( PipeSend, CommPipe, &Req );
404  break;
405 
406  default:
407  DPRINT1("Unrecognized request type %d\n", Req.Type);
408  ZeroMemory( &Reply, sizeof( COMM_DHCP_REPLY ) );
409  Reply.Reply = 0;
410  PipeSend(CommPipe, &Reply );
411  break;
412  }
413  }
414  DisconnectNamedPipe( CommPipe );
415  }
416 
417  DPRINT("Pipe thread stopped!\n");
418 
419  return TRUE;
420 }
421 
423 {
425 }
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
#define SECURITY_AUTHENTICATED_USER_RID
Definition: setypes.h:568
#define GENERIC_ALL
Definition: nt_native.h:92
#define SECURITY_LOCAL_SYSTEM_RID
Definition: setypes.h:574
#define COMM_PIPE_DEFAULT_TIMEOUT
Definition: pipe.c:16
DWORD WINAPI PipeThreadProc(LPVOID Parameter)
Definition: pipe.c:276
#define CloseHandle
Definition: compat.h:598
BOOL WINAPI MakeSelfRelativeSD(PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor, PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor, LPDWORD lpdwBufferLength)
Definition: sec.c:214
BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bDaclPresent, PACL pDacl, BOOL bDaclDefaulted)
Definition: sec.c:262
#define ERROR_SUCCESS
Definition: deptool.c:10
#define DbgPrint
Definition: hal.h:12
BOOL WINAPI InitializeAcl(PACL pAcl, DWORD nAclLength, DWORD dwAclRevision)
Definition: security.c:1008
#define PIPE_TYPE_MESSAGE
Definition: winbase.h:168
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:221
#define TRUE
Definition: types.h:120
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD dwRevision)
Definition: security.c:931
BOOL WINAPI AddAccessAllowedAce(PACL pAcl, DWORD dwAceRevision, DWORD AccessMask, PSID pSid)
Definition: security.c:1041
#define PIPE_WAIT
Definition: winbase.h:171
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define ZeroMemory
Definition: winbase.h:1667
struct _ACCESS_ALLOWED_ACE ACCESS_ALLOWED_ACE
DWORD DSReleaseIpAddressLease(PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req)
Definition: api.c:90
_In_ PVOID Parameter
Definition: ldrtypes.h:241
#define ERROR_IO_PENDING
Definition: dderror.h:15
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:859
BOOL WINAPI SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID pOwner, BOOL bOwnerDefaulted)
Definition: sec.c:312
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
PVOID WINAPI FreeSid(PSID pSid)
Definition: security.c:700
HANDLE hStopEvent
Definition: dhcpcsvc.c:19
DWORD PipeSend(HANDLE CommPipe, COMM_DHCP_REPLY *Reply)
Definition: pipe.c:18
BOOL WINAPI CancelIo(IN HANDLE hFile)
Definition: deviceio.c:290
BOOL WINAPI SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID pGroup, BOOL bGroupDefaulted)
Definition: sec.c:288
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
struct _ACL ACL
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define COMM_PIPE_INPUT_BUFFER
Definition: pipe.c:15
#define FILE_FLAG_FIRST_PIPE_INSTANCE
Definition: piperead.cpp:20
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
HANDLE Events[3]
Definition: schedsvc.c:40
DWORD DSLeaseIpAddress(PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req)
Definition: api.c:36
#define WAIT_OBJECT_0
Definition: winbase.h:403
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
DWORD WINAPI GetLengthSid(PSID pSid)
Definition: security.c:921
#define PIPE_ACCESS_DUPLEX
Definition: winbase.h:164
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
HANDLE PipeInit(HANDLE hStopEvent)
Definition: pipe.c:422
#define COMM_PIPE_OUTPUT_BUFFER
Definition: pipe.c:14
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1579
static SID_IDENTIFIER_AUTHORITY NtAuthority
Definition: security.c:40
static HANDLE(WINAPI *pOpenThread)(DWORD dwDesiredAccess
BOOL WINAPI DisconnectNamedPipe(HANDLE hNamedPipe)
Definition: npipe.c:961
DWORD DSQueryHWInfo(PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req)
Definition: api.c:68
#define GENERIC_READ
Definition: compat.h:135
#define PIPE_READMODE_MESSAGE
Definition: winbase.h:170
DWORD DSRenewIpAddressLease(PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req)
Definition: api.c:129
DWORD CreateDhcpPipeSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor)
Creates a security descriptor for the DHCP pipe service.
Definition: pipe.c:59
DWORD DSStaticRefreshParams(PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req)
Definition: api.c:165
#define DHCP_PIPE_NAME
LPVOID lpSecurityDescriptor
Definition: compat.h:193
DWORD DSGetAdapterInfo(PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req)
Definition: api.c:209
#define ReadFile(a, b, c, d, e)
Definition: compat.h:601
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define DPRINT1
Definition: precomp.h:8
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG DaclSize
Definition: rtlfuncs.h:1579
#define ACL_REVISION
Definition: setypes.h:39
unsigned int ULONG
Definition: retypes.h:1
#define DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS
Definition: setypes.h:666
#define DPRINT
Definition: sndvol32.h:71
HANDLE WINAPI CreateNamedPipeW(LPCWSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: npipe.c:246
#define FILE_FLAG_OVERLAPPED
Definition: disk.h:46
#define INFINITE
Definition: serial.h:102
#define GENERIC_EXECUTE
Definition: nt_native.h:91
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652
BOOL WINAPI ConnectNamedPipe(IN HANDLE hNamedPipe, IN LPOVERLAPPED lpOverlapped)
Definition: npipe.c:701
#define HeapFree(x, y, z)
Definition: compat.h:594
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
BOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, BYTE nSubAuthorityCount, DWORD nSubAuthority0, DWORD nSubAuthority1, DWORD nSubAuthority2, DWORD nSubAuthority3, DWORD nSubAuthority4, DWORD nSubAuthority5, DWORD nSubAuthority6, DWORD nSubAuthority7, PSID *pSid)
Definition: security.c:676
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10