From cd98a20f1c9e89eb44ef5c5349337292bd3ba243 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 17 Oct 2005 20:31:31 +0000 Subject: [PATCH] windows-firewall-configuration-20051016 Windows Firewall Policy cannot be accessed by a service unless from the Service Manager thread nor until the service is in a RUNNING state. Firewall configuration moved to cm_Daemon() thread. --- src/WINNT/afsd/afsd_init.c | 26 +-- src/WINNT/afsd/afsicf.cpp | 408 +++++++++++++++++++------------------ src/WINNT/afsd/cm_daemon.c | 25 ++- 3 files changed, 248 insertions(+), 211 deletions(-) diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index c9076d1b61..5f3c85625b 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -32,7 +32,6 @@ #include "cm_rpc.h" #include "lanahelper.h" #include -#include "afsicf.h" #include "cm_memmap.h" extern int RXAFSCB_ExecuteRequest(struct rx_call *z_call); @@ -1066,20 +1065,6 @@ int afsd_InitCM(char **reasonP) cm_initParams.setTime = 0; cm_initParams.memCache = 1; - /* Set RX parameters before initializing RX */ - if ( rx_nojumbo ) { - rx_SetNoJumbo(); - afsi_log("rx_SetNoJumbo successful"); - } - - if ( rx_mtu != -1 ) { - rx_SetMaxMTU(rx_mtu); - afsi_log("rx_SetMaxMTU %d successful", rx_mtu); - } - - /* Open Microsoft Firewall to allow in port 7001 */ - icf_CheckAndAddAFSPorts(AFS_PORTSET_CLIENT); - /* Ensure the AFS Netbios Name is registered to allow loopback access */ configureBackConnectionHostNames(); @@ -1111,6 +1096,17 @@ int afsd_InitCM(char **reasonP) #endif #endif + /* Set RX parameters before initializing RX */ + if ( rx_nojumbo ) { + rx_SetNoJumbo(); + afsi_log("rx_SetNoJumbo successful"); + } + + if ( rx_mtu != -1 ) { + rx_SetMaxMTU(rx_mtu); + afsi_log("rx_SetMaxMTU %d successful", rx_mtu); + } + /* initialize RX, and tell it to listen to port 7001, which is used for * callback RPC messages. */ diff --git a/src/WINNT/afsd/afsicf.cpp b/src/WINNT/afsd/afsicf.cpp index 5aec746317..190ff8d69a 100644 --- a/src/WINNT/afsd/afsicf.cpp +++ b/src/WINNT/afsd/afsicf.cpp @@ -30,50 +30,70 @@ SOFTWARE. #include #include "afsicf.h" -//#define TESTMAIN - #ifdef TESTMAIN #include #pragma comment(lib,"ole32.lib") #pragma comment(lib,"oleaut32.lib") -#define DEBUGOUT(x) printf x +#define DEBUGOUT(x) printf(x) +#define DEBUGOUTW(x) wprintf(x) #else -#define DEBUGOUT(x) +#define DEBUGOUT(x) OutputDebugString(x) +#define DEBUGOUTW(x) OutputDebugStringW(x) #endif /* an IPv4, enabled port with global scope */ struct global_afs_port_type { LPWSTR name; - LONG port; - NET_FW_IP_PROTOCOL protocol; + LONG port; + NET_FW_IP_PROTOCOL protocol; }; typedef struct global_afs_port_type global_afs_port_t; global_afs_port_t afs_clientPorts[] = { - { L"AFS CacheManager Callback (UDP)", 7001, NET_FW_IP_PROTOCOL_UDP }, - { L"AFS CacheManager Callback (TCP)", 7001, NET_FW_IP_PROTOCOL_TCP } + { L"AFS CacheManager Callback (UDP)", 7001, NET_FW_IP_PROTOCOL_UDP } +#ifdef AFS_TCP +, { L"AFS CacheManager Callback (TCP)", 7001, NET_FW_IP_PROTOCOL_TCP } +#endif }; global_afs_port_t afs_serverPorts[] = { - { L"AFS File Server (UDP)", 7000, NET_FW_IP_PROTOCOL_UDP }, - { L"AFS File Server (TCP)", 7000, NET_FW_IP_PROTOCOL_TCP }, - { L"AFS User & Group Database (UDP)", 7002, NET_FW_IP_PROTOCOL_UDP }, - { L"AFS User & Group Database (TCP)", 7002, NET_FW_IP_PROTOCOL_TCP }, - { L"AFS Volume Location Database (UDP)", 7003, NET_FW_IP_PROTOCOL_UDP }, - { L"AFS Volume Location Database (TCP)", 7003, NET_FW_IP_PROTOCOL_TCP }, - { L"AFS/Kerberos Authentication (UDP)", 7004, NET_FW_IP_PROTOCOL_UDP }, - { L"AFS/Kerberos Authentication (TCP)", 7004, NET_FW_IP_PROTOCOL_TCP }, - { L"AFS Volume Mangement (UDP)", 7005, NET_FW_IP_PROTOCOL_UDP }, - { L"AFS Volume Mangement (TCP)", 7005, NET_FW_IP_PROTOCOL_TCP }, - { L"AFS Error Interpretation (UDP)", 7006, NET_FW_IP_PROTOCOL_UDP }, - { L"AFS Error Interpretation (TCP)", 7006, NET_FW_IP_PROTOCOL_TCP }, - { L"AFS Basic Overseer (UDP)", 7007, NET_FW_IP_PROTOCOL_UDP }, - { L"AFS Basic Overseer (TCP)", 7007, NET_FW_IP_PROTOCOL_TCP }, - { L"AFS Server-to-server Updater (UDP)", 7008, NET_FW_IP_PROTOCOL_UDP }, - { L"AFS Server-to-server Updater (TCP)", 7008, NET_FW_IP_PROTOCOL_TCP }, - { L"AFS Remote Cache Manager (UDP)", 7009, NET_FW_IP_PROTOCOL_UDP }, - { L"AFS Remote Cache Manager (TCP)", 7009, NET_FW_IP_PROTOCOL_TCP } + { L"AFS File Server (UDP)", 7000, NET_FW_IP_PROTOCOL_UDP }, +#ifdef AFS_TCP + { L"AFS File Server (TCP)", 7000, NET_FW_IP_PROTOCOL_TCP }, +#endif + { L"AFS User & Group Database (UDP)", 7002, NET_FW_IP_PROTOCOL_UDP }, +#ifdef AFS_TCP + { L"AFS User & Group Database (TCP)", 7002, NET_FW_IP_PROTOCOL_TCP }, +#endif + { L"AFS Volume Location Database (UDP)", 7003, NET_FW_IP_PROTOCOL_UDP }, +#ifdef AFS_TCP + { L"AFS Volume Location Database (TCP)", 7003, NET_FW_IP_PROTOCOL_TCP }, +#endif + { L"AFS/Kerberos Authentication (UDP)", 7004, NET_FW_IP_PROTOCOL_UDP }, +#ifdef AFS_TCP + { L"AFS/Kerberos Authentication (TCP)", 7004, NET_FW_IP_PROTOCOL_TCP }, +#endif + { L"AFS Volume Mangement (UDP)", 7005, NET_FW_IP_PROTOCOL_UDP }, +#ifdef AFS_TCP + { L"AFS Volume Mangement (TCP)", 7005, NET_FW_IP_PROTOCOL_TCP }, +#endif + { L"AFS Error Interpretation (UDP)", 7006, NET_FW_IP_PROTOCOL_UDP }, +#ifdef AFS_TCP + { L"AFS Error Interpretation (TCP)", 7006, NET_FW_IP_PROTOCOL_TCP }, +#endif + { L"AFS Basic Overseer (UDP)", 7007, NET_FW_IP_PROTOCOL_UDP }, +#ifdef AFS_TCP + { L"AFS Basic Overseer (TCP)", 7007, NET_FW_IP_PROTOCOL_TCP }, +#endif + { L"AFS Server-to-server Updater (UDP)", 7008, NET_FW_IP_PROTOCOL_UDP }, +#ifdef AFS_TCP + { L"AFS Server-to-server Updater (TCP)", 7008, NET_FW_IP_PROTOCOL_TCP }, +#endif + { L"AFS Remote Cache Manager (UDP)", 7009, NET_FW_IP_PROTOCOL_UDP } +#ifdef AFS_TCP +, { L"AFS Remote Cache Manager (TCP)", 7009, NET_FW_IP_PROTOCOL_TCP } +#endif }; HRESULT icf_OpenFirewallProfile(INetFwProfile ** fwProfile) { @@ -93,7 +113,7 @@ HRESULT icf_OpenFirewallProfile(INetFwProfile ** fwProfile) { ); if (FAILED(hr)) { - DEBUGOUT(("Can't create fwMgr\n")); + DEBUGOUT(("Can't create fwMgr\n")); goto error; } @@ -101,7 +121,7 @@ HRESULT icf_OpenFirewallProfile(INetFwProfile ** fwProfile) { hr = fwMgr->get_LocalPolicy(&fwPolicy); if (FAILED(hr)) { - DEBUGOUT(("Cant get local policy\n")); + DEBUGOUT(("Cant get local policy\n")); goto error; } @@ -109,11 +129,11 @@ HRESULT icf_OpenFirewallProfile(INetFwProfile ** fwProfile) { hr = fwPolicy->get_CurrentProfile(fwProfile); if (FAILED(hr)) { - DEBUGOUT(("Can't get current profile\n")); + DEBUGOUT(("Can't get current profile\n")); goto error; } -error: + error: // Release the local firewall policy. if (fwPolicy != NULL) @@ -131,197 +151,195 @@ error: } HRESULT icf_CheckAndAddPorts(INetFwProfile * fwProfile, global_afs_port_t * ports, int nPorts) { - INetFwOpenPorts * fwPorts = NULL; - INetFwOpenPort * fwPort = NULL; - HRESULT hr; - HRESULT rhr = S_OK; /* return value */ - int i = 0; + INetFwOpenPorts * fwPorts = NULL; + INetFwOpenPort * fwPort = NULL; + HRESULT hr; + HRESULT rhr = S_OK; /* return value */ + int i = 0; - hr = fwProfile->get_GloballyOpenPorts(&fwPorts); - if (FAILED(hr)) { - // Abort! - DEBUGOUT(("Can't get globallyOpenPorts\n")); - rhr = hr; - goto cleanup; + hr = fwProfile->get_GloballyOpenPorts(&fwPorts); + if (FAILED(hr)) { + // Abort! + DEBUGOUT(("Can't get globallyOpenPorts\n")); + rhr = hr; + goto cleanup; + } + + // go through the supplied ports + for (i=0; iItem(ports[i].port, ports[i].protocol, &fwPort); + if (SUCCEEDED(hr)) { + DEBUGOUTW((L"Found port for %S\n",ports[i].name)); + hr = fwPort->get_Enabled(&vbEnabled); + if (SUCCEEDED(hr)) { + if ( vbEnabled == VARIANT_FALSE ) { + hr = fwPort->put_Enabled(VARIANT_TRUE); + if (FAILED(hr)) { + // failed. Mark as failure. Don't try to create the port either. + rhr = hr; + } + } // else we are fine + } else { + // Something is wrong with the port. + // We try to create a new one thus overriding this faulty one. + bCreate = TRUE; + } + fwPort->Release(); + fwPort = NULL; + } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { + DEBUGOUTW((L"Port not found for %S\n", ports[i].name)); + bCreate = TRUE; } - // go through the supplied ports - for (i=0; i + (static_cast(&fwPort)) + ); - hr = fwPorts->Item(ports[i].port, ports[i].protocol, &fwPort); - if (SUCCEEDED(hr)) { - DEBUGOUT(("Found port for %S\n",ports[i].name)); - hr = fwPort->get_Enabled(&vbEnabled); - if (SUCCEEDED(hr)) { - if ( vbEnabled == VARIANT_FALSE ) { - hr = fwPort->put_Enabled(VARIANT_TRUE); - if (FAILED(hr)) { - // failed. Mark as failure. Don't try to create the port either. - rhr = hr; - } - } // else we are fine - } else { - // Something is wrong with the port. - // We try to create a new one thus overriding this faulty one. - bCreate = TRUE; - } - fwPort->Release(); - fwPort = NULL; - } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { - DEBUGOUT(("Port not found for %S\n", ports[i].name)); - bCreate = TRUE; - } - - if (bCreate) { - DEBUGOUT(("Trying to create port %S\n",ports[i].name)); - hr = CoCreateInstance( - __uuidof(NetFwOpenPort), - NULL, - CLSCTX_INPROC_SERVER, - __uuidof(INetFwOpenPort), - reinterpret_cast - (static_cast(&fwPort)) - ); - - if (FAILED(hr)) { - DEBUGOUT(("Can't create port\n")); + if (FAILED(hr)) { + DEBUGOUT(("Can't create port\n")); rhr = hr; - } else { - DEBUGOUT(("Created port\n")); - hr = fwPort->put_IpVersion( NET_FW_IP_VERSION_ANY ); - if (FAILED(hr)) { - DEBUGOUT(("Can't set IpVersion\n")); - rhr = hr; - goto abandon_port; - } - - hr = fwPort->put_Port( ports[i].port ); - if (FAILED(hr)) { - DEBUGOUT(("Can't set Port\n")); - rhr = hr; - goto abandon_port; - } - - hr = fwPort->put_Protocol( ports[i].protocol ); - if (FAILED(hr)) { - DEBUGOUT(("Can't set Protocol\n")); - rhr = hr; - goto abandon_port; - } - - hr = fwPort->put_Scope( NET_FW_SCOPE_ALL ); - if (FAILED(hr)) { - DEBUGOUT(("Can't set Scope\n")); - rhr = hr; - goto abandon_port; - } - - bstName = SysAllocString( ports[i].name ); - - if (SysStringLen(bstName) == 0) { - rhr = E_OUTOFMEMORY; - } else { - hr = fwPort->put_Name( bstName ); - if (FAILED(hr)) { - DEBUGOUT(("Can't set Name\n")); - rhr = hr; - SysFreeString( bstName ); - goto abandon_port; - } - } - - SysFreeString( bstName ); - - hr = fwPorts->Add( fwPort ); - if (FAILED(hr)) { - DEBUGOUT(("Can't add port\n")); - rhr = hr; - } else - DEBUGOUT(("Added port\n")); - -abandon_port: - fwPort->Release(); - } + } else { + DEBUGOUT(("Created port\n")); + hr = fwPort->put_IpVersion( NET_FW_IP_VERSION_ANY ); + if (FAILED(hr)) { + DEBUGOUT(("Can't set IpVersion\n")); + rhr = hr; + goto abandon_port; } - } // loop through ports + hr = fwPort->put_Port( ports[i].port ); + if (FAILED(hr)) { + DEBUGOUT(("Can't set Port\n")); + rhr = hr; + goto abandon_port; + } + + hr = fwPort->put_Protocol( ports[i].protocol ); + if (FAILED(hr)) { + DEBUGOUT(("Can't set Protocol\n")); + rhr = hr; + goto abandon_port; + } + + hr = fwPort->put_Scope( NET_FW_SCOPE_ALL ); + if (FAILED(hr)) { + DEBUGOUT(("Can't set Scope\n")); + rhr = hr; + goto abandon_port; + } + + bstName = SysAllocString( ports[i].name ); + + if (SysStringLen(bstName) == 0) { + rhr = E_OUTOFMEMORY; + } else { + hr = fwPort->put_Name( bstName ); + if (FAILED(hr)) { + DEBUGOUT(("Can't set Name\n")); + rhr = hr; + SysFreeString( bstName ); + goto abandon_port; + } + } + + SysFreeString( bstName ); + + hr = fwPorts->Add( fwPort ); + if (FAILED(hr)) { + DEBUGOUT(("Can't add port\n")); + rhr = hr; + } else + DEBUGOUT(("Added port\n")); + + abandon_port: + fwPort->Release(); + } + } + } // loop through ports + + fwPorts->Release(); + + cleanup: + + if (fwPorts != NULL) fwPorts->Release(); -cleanup: - - if (fwPorts != NULL) - fwPorts->Release(); - - return rhr; -} + return rhr; +} long icf_CheckAndAddAFSPorts(int portset) { - HRESULT hr; - BOOL coInitialized = FALSE; - INetFwProfile * fwProfile = NULL; - global_afs_port_t * ports; - int nports; - long code = 0; + HRESULT hr; + BOOL coInitialized = FALSE; + INetFwProfile * fwProfile = NULL; + global_afs_port_t * ports; + int nports; + long code = 0; - if (portset == AFS_PORTSET_CLIENT) { - ports = afs_clientPorts; - nports = sizeof(afs_clientPorts) / sizeof(*afs_clientPorts); - } else if (portset == AFS_PORTSET_SERVER) { - ports = afs_serverPorts; - nports = sizeof(afs_serverPorts) / sizeof(*afs_serverPorts); - } else - return 1; /* Invalid port set */ + if (portset == AFS_PORTSET_CLIENT) { + ports = afs_clientPorts; + nports = sizeof(afs_clientPorts) / sizeof(*afs_clientPorts); + } else if (portset == AFS_PORTSET_SERVER) { + ports = afs_serverPorts; + nports = sizeof(afs_serverPorts) / sizeof(*afs_serverPorts); + } else + return 1; /* Invalid port set */ - hr = CoInitializeEx( - NULL, - COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE - ); + hr = CoInitializeEx( NULL, + COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE + ); - if (SUCCEEDED(hr) || RPC_E_CHANGED_MODE == hr) + if (SUCCEEDED(hr) || RPC_E_CHANGED_MODE == hr) { coInitialized = TRUE; } - // not necessarily catastrophic if the call failed. We'll try to - // continue as if it succeeded. + // not necessarily catastrophic if the call failed. We'll try to + // continue as if it succeeded. hr = icf_OpenFirewallProfile(&fwProfile); - if (FAILED(hr)) { - // Ok. That didn't work. This could be because the machine we - // are running on doesn't have Windows Firewall. We'll return - // a failure to the caller, which shouldn't be taken to mean - // it's catastrophic. - DEBUGOUT(("Can't open Firewall profile\n")); - code = 1; - goto cleanup; - } + if (FAILED(hr)) { + // Ok. That didn't work. This could be because the machine we + // are running on doesn't have Windows Firewall. We'll return + // a failure to the caller, which shouldn't be taken to mean + // it's catastrophic. + DEBUGOUT(("Can't open Firewall profile\n")); + code = 2; + goto cleanup; + } - // Now that we have a firewall profile, we can start checking - // and adding the ports that we want. - hr = icf_CheckAndAddPorts(fwProfile, ports, nports); - if (FAILED(hr)) - code = 1; + // Now that we have a firewall profile, we can start checking + // and adding the ports that we want. + hr = icf_CheckAndAddPorts(fwProfile, ports, nports); + if (FAILED(hr)) + code = 3; -cleanup: - if (coInitialized) { - CoUninitialize(); - } + cleanup: + if (coInitialized) { + CoUninitialize(); + } - return code; + return code; } #ifdef TESTMAIN int main(int argc, char **argv) { - printf("Starting...\n"); + printf("Starting...\n"); if (icf_CheckAndAddAFSPorts(AFS_PORTSET_CLIENT)) - printf("Failed\n"); - else - printf("Succeeded\n"); - printf("Done\n"); - return 0; -} + printf("Failed\n"); + else + printf("Succeeded\n"); + printf("Done\n"); + return 0; +} #endif \ No newline at end of file diff --git a/src/WINNT/afsd/cm_daemon.c b/src/WINNT/afsd/cm_daemon.c index ab796a6e2a..3fc2b03a79 100644 --- a/src/WINNT/afsd/cm_daemon.c +++ b/src/WINNT/afsd/cm_daemon.c @@ -24,6 +24,7 @@ #include #include "afsd.h" +#include "afsicf.h" long cm_daemonCheckInterval = 30; long cm_daemonTokenCheckInterval = 180; @@ -113,6 +114,7 @@ void cm_Daemon(long parm) unsigned long code; struct hostent *thp; HMODULE hHookDll; + int firewallConfigured = 0; /* ping all file servers, up or down, with unauthenticated connection, * to find out whether we have all our callbacks from the server still. @@ -142,10 +144,31 @@ void cm_Daemon(long parm) lastTokenCacheCheck = now - cm_daemonTokenCheckInterval/2 + (rand() % cm_daemonTokenCheckInterval); while (daemon_ShutdownFlag == 0) { - thrd_Sleep(30 * 1000); /* sleep 30 seconds */ + thrd_Sleep(30 * 1000); /* sleep 30 seconds */ if (daemon_ShutdownFlag == 1) return; + if (!firewallConfigured) { + /* Open Microsoft Firewall to allow in port 7001 */ + switch (icf_CheckAndAddAFSPorts(AFS_PORTSET_CLIENT)) { + case 0: + afsi_log("Windows Firewall Configuration succeeded"); + firewallConfigured = 1; + break; + case 1: + afsi_log("Invalid Windows Firewall Port Set"); + break; + case 2: + afsi_log("Unable to open Windows Firewall Profile"); + break; + case 3: + afsi_log("Unable to create/modify Windows Firewall Port entries"); + break; + default: + afsi_log("Unknown Windows Firewall Configuration error"); + } + } + /* find out what time it is */ now = osi_Time();