Skip to content

Commit eccae20

Browse files
committed
[DHCPCSVC] Set up a security descriptor for DHCP named pipe
1 parent d862fa6 commit eccae20

File tree

1 file changed

+252
-1
lines changed
  • base/services/dhcpcsvc/dhcp

1 file changed

+252
-1
lines changed

base/services/dhcpcsvc/dhcp/pipe.c

Lines changed: 252 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,243 @@ DWORD PipeSend( HANDLE CommPipe, COMM_DHCP_REPLY *Reply ) {
3636
return Success ? Written : -1;
3737
}
3838

39+
/**
40+
* @brief
41+
* Creates a security descriptor for the DHCP pipe
42+
* service.
43+
*
44+
* @param[out] SecurityDescriptor
45+
* A pointer to an allocated security descriptor
46+
* for the DHCP pipe.
47+
*
48+
* @return
49+
* ERROR_SUCCESS is returned if the function has
50+
* successfully created the descriptor otherwise
51+
* a Win32 error code is returned.
52+
*
53+
* @remarks
54+
* Both admins and local system are given full power
55+
* over the DHCP pipe whereas authenticated users
56+
* and network operators can only read over this pipe.
57+
* They can also execute it.
58+
*/
59+
DWORD CreateDhcpPipeSecurity( PSECURITY_DESCRIPTOR *SecurityDescriptor ) {
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;
65+
static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
66+
67+
if (!AllocateAndInitializeSid(&NtAuthority,
68+
1,
69+
SECURITY_AUTHENTICATED_USER_RID,
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+
77+
if (!AllocateAndInitializeSid(&NtAuthority,
78+
2,
79+
SECURITY_BUILTIN_DOMAIN_RID,
80+
DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS,
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+
89+
if (!AllocateAndInitializeSid(&NtAuthority,
90+
2,
91+
SECURITY_BUILTIN_DOMAIN_RID,
92+
DOMAIN_ALIAS_RID_ADMINS,
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+
101+
if (!AllocateAndInitializeSid(&NtAuthority,
102+
1,
103+
SECURITY_LOCAL_SYSTEM_RID,
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+
112+
AbsSD = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SECURITY_DESCRIPTOR));
113+
if (!AbsSD)
114+
{
115+
DPRINT1("CreateDhcpPipeSecurity(): Failed to allocate absolute security descriptor!\n");
116+
ErrCode = ERROR_OUTOFMEMORY;
117+
goto Quit;
118+
}
119+
120+
if (!InitializeSecurityDescriptor(AbsSD, SECURITY_DESCRIPTOR_REVISION))
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+
133+
Dacl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DaclSize);
134+
if (!Dacl)
135+
{
136+
DPRINT1("CreateDhcpPipeSecurity(): Failed to allocate DACL!\n");
137+
ErrCode = ERROR_OUTOFMEMORY;
138+
goto Quit;
139+
}
140+
141+
if (!InitializeAcl(Dacl, DaclSize, ACL_REVISION))
142+
{
143+
DPRINT1("CreateDhcpPipeSecurity(): Failed to initialize DACL (error code %d)\n", GetLastError());
144+
ErrCode = GetLastError();
145+
goto Quit;
146+
}
147+
148+
if (!AddAccessAllowedAce(Dacl,
149+
ACL_REVISION,
150+
GENERIC_READ | GENERIC_EXECUTE,
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+
158+
if (!AddAccessAllowedAce(Dacl,
159+
ACL_REVISION,
160+
GENERIC_READ | GENERIC_EXECUTE,
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+
168+
if (!AddAccessAllowedAce(Dacl,
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+
178+
if (!AddAccessAllowedAce(Dacl,
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+
{
265+
HeapFree(GetProcessHeap(), 0, Dacl);
266+
}
267+
268+
if (AbsSD)
269+
{
270+
HeapFree(GetProcessHeap(), 0, AbsSD);
271+
}
272+
273+
return ErrCode;
274+
}
275+
39276
DWORD WINAPI PipeThreadProc( LPVOID Parameter ) {
40277
DWORD BytesRead;
41278
COMM_DHCP_REQ Req;
@@ -45,9 +282,22 @@ DWORD WINAPI PipeThreadProc( LPVOID Parameter ) {
45282
HANDLE CommPipe;
46283
OVERLAPPED Overlapped = {0};
47284
DWORD dwError;
285+
SECURITY_ATTRIBUTES SecurityAttributes;
286+
PSECURITY_DESCRIPTOR DhcpPipeSD = NULL;
48287

49288
DPRINT("PipeThreadProc(%p)\n", Parameter);
50289

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+
51301
CommPipe = CreateNamedPipeW
52302
( DHCP_PIPE_NAME,
53303
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
@@ -56,7 +306,8 @@ DWORD WINAPI PipeThreadProc( LPVOID Parameter ) {
56306
COMM_PIPE_OUTPUT_BUFFER,
57307
COMM_PIPE_INPUT_BUFFER,
58308
COMM_PIPE_DEFAULT_TIMEOUT,
59-
NULL );
309+
&SecurityAttributes );
310+
HeapFree(GetProcessHeap(), 0, DhcpPipeSD);
60311
if (CommPipe == INVALID_HANDLE_VALUE)
61312
{
62313
DbgPrint("DHCP: Could not create named pipe\n");

0 commit comments

Comments
 (0)