ACLs on Sockets

A friend from Foundstone sent me an email asking how to set ACLs on sockets in Windows. He'd heard that we'd added the capability recently. Yup, it's true, ACL support for sockets was added to Windows Server 2003 SP1, and is in current builds of Windows Vista too.

Here's how you do it (I could explain it, but I guess code is best :)

    SOCKET listen_socket = WSASocket(AF_INET, DEFAULT_PROTO, 0, NULL, 0, 0);
if (listen_socket == INVALID_SOCKET){
printf("socket() failed with error %d\n",WSAGetLastError());
WSACleanup();
}

    PSECURITY_DESCRIPTOR psD = NULL;
if (!ConvertStringSecurityDescriptorToSecurityDescriptor (
"D:(A;;GA;;;LS)(A;;GA;;;BA)", // Only local admins and local service can bind
SECURITY_DESCRIPTOR_REVISION,
&psD,
NULL
) )
printf("Convert Failed \n");

    if (!SetKernelObjectSecurity (
(HANDLE)listen_socket,
DACL_SECURITY_INFORMATION,
psD))
printf ("SetKernelObjectSecurity failed %d",GetLastError());

If another application attempts to bind to the socket, and the process is not running as an admin or local service account, it'll get the dreaded Err=5 :)

In Windows Vista we also added SACL support, so you can audit who attempts to bind, you

just need to create an SDDL ACL that looks like this:

D:(A;;GA;;;LS)(A;;GA;;;BA)S:(AU;SAFA;GA;;;WD)

See how the SACL (S:) follows the DACL (D:)

If you setting a SACL you will need to assert the SeSecurityPrivilege privilege first.

PS: Yes, we'll update the text for SetKernelObjectSecurity on MSDN to reflect sockets are ACL-able!