windows-smb-registry-config-20090407
authorJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 7 Apr 2009 15:05:30 +0000 (15:05 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 7 Apr 2009 15:05:30 +0000 (15:05 +0000)
LICENSE MIT

Move configureBackConnectionHostNames() to smb_StartListeners()
so that when the NetbiosName changes while the service is running
the new values can be set.

Add configureExtendedSMBSessionTimeouts() which configures new
SMB functionality added in a Win2003 post-SP2 hot fix.

src/WINNT/afsd/afsd_init.c
src/WINNT/afsd/smb.c

index ec603a2..032e589 100644 (file)
@@ -86,8 +86,8 @@ char cm_HostName[200];
 long cm_HostAddr;
 unsigned short cm_callbackport = CM_DEFAULT_CALLBACKPORT;
 
-char cm_NetbiosName[MAX_NB_NAME_LENGTH] = "";
-clientchar_t cm_NetbiosNameC[MAX_NB_NAME_LENGTH] = _C("");
+char cm_NetbiosName[MAX_NB_NAME_LENGTH] = "NOT.YET.SET";
+clientchar_t cm_NetbiosNameC[MAX_NB_NAME_LENGTH] = _C("NOT.YET.SET");
 
 char cm_CachePath[MAX_PATH];
 DWORD cm_ValidateCache = 1;
@@ -240,159 +240,6 @@ void afsd_ForceTrace(BOOL flush)
     CloseHandle(handle);
 }
 
-static void
-configureBackConnectionHostNames(void)
-{
-    /* On Windows XP SP2, Windows 2003 SP1, and all future Windows operating systems
-     * there is a restriction on the use of SMB authentication on loopback connections.
-     * There are two work arounds available:
-     * 
-     *   (1) We can disable the check for matching host names.  This does not
-     *   require a reboot:
-     *   [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa]
-     *     "DisableLoopbackCheck"=dword:00000001
-     *
-     *   (2) We can add the AFS SMB/CIFS service name to an approved list.  This
-     *   does require a reboot:
-     *   [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0]
-     *     "BackConnectionHostNames"=multi-sz
-     *
-     * The algorithm will be:
-     *   (1) Check to see if cm_NetbiosName exists in the BackConnectionHostNames list
-     *   (2a) If not, add it to the list.  (This will not take effect until the next reboot.)
-     *   (2b1)    and check to see if DisableLoopbackCheck is set.
-     *   (2b2)    If not set, set the DisableLoopbackCheck value to 0x1 
-     *   (2b3)                and create HKLM\SOFTWARE\OpenAFS\Client  UnsetDisableLoopbackCheck
-     *   (2c) else If cm_NetbiosName exists in the BackConnectionHostNames list,
-     *             check for the UnsetDisableLoopbackCheck value.  
-     *             If set, set the DisableLoopbackCheck flag to 0x0 
-     *             and delete the UnsetDisableLoopbackCheck value
-     *
-     * Starting in Longhorn Beta 1, an entry in the BackConnectionHostNames value will
-     * force Windows to use the loopback authentication mechanism for the specified 
-     * services.
-     */
-    HKEY hkLsa;
-    HKEY hkMSV10;
-    HKEY hkClient;
-    DWORD dwType;
-    DWORD dwSize, dwAllocSize;
-    DWORD dwValue;
-    PBYTE pHostNames = NULL, pName = NULL;
-    BOOL  bNameFound = FALSE;   
-
-    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, 
-                       "SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0",
-                       0,
-                       KEY_READ|KEY_WRITE,
-                       &hkMSV10) == ERROR_SUCCESS )
-    {
-        if ((RegQueryValueEx( hkMSV10, "BackConnectionHostNames", 0, 
-                            &dwType, NULL, &dwAllocSize) == ERROR_SUCCESS) &&
-            (dwType == REG_MULTI_SZ)) 
-        {
-           dwAllocSize += 1 /* in case the source string is not nul terminated */
-               + strlen(cm_NetbiosName) + 2;
-           pHostNames = malloc(dwAllocSize);
-           dwSize = dwAllocSize;
-            if (RegQueryValueEx( hkMSV10, "BackConnectionHostNames", 0, &dwType, 
-                                pHostNames, &dwSize) == ERROR_SUCCESS) 
-            {
-               for (pName = pHostNames; 
-                    (pName - pHostNames < (int) dwSize) && *pName ; 
-                    pName += strlen(pName) + 1)
-               {
-                   if ( !stricmp(pName, cm_NetbiosName) ) {
-                       bNameFound = TRUE;
-                       break;
-                   }   
-               }
-           }
-        }
-             
-        if ( !bNameFound ) {
-            size_t size = strlen(cm_NetbiosName) + 2;
-            if ( !pHostNames ) {
-                pHostNames = malloc(size);
-               pName = pHostNames;
-            }
-            StringCbCopyA(pName, size, cm_NetbiosName);
-            pName += size - 1;
-            *pName = '\0';  /* add a second nul terminator */
-
-            dwType = REG_MULTI_SZ;
-           dwSize = pName - pHostNames + 1;
-            RegSetValueEx( hkMSV10, "BackConnectionHostNames", 0, dwType, pHostNames, dwSize);
-
-            if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, 
-                               "SYSTEM\\CurrentControlSet\\Control\\Lsa",
-                               0,
-                               KEY_READ|KEY_WRITE,
-                               &hkLsa) == ERROR_SUCCESS )
-            {
-                dwSize = sizeof(DWORD);
-                if ( RegQueryValueEx( hkLsa, "DisableLoopbackCheck", 0, &dwType, (LPBYTE)&dwValue, &dwSize) != ERROR_SUCCESS ||
-                     dwValue == 0 ) {
-                    dwType = REG_DWORD;
-                    dwSize = sizeof(DWORD);
-                    dwValue = 1;
-                    RegSetValueEx( hkLsa, "DisableLoopbackCheck", 0, dwType, (LPBYTE)&dwValue, dwSize);
-
-                    if (RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
-                                        AFSREG_CLT_OPENAFS_SUBKEY,
-                                        0,
-                                        NULL,
-                                        REG_OPTION_NON_VOLATILE,
-                                        KEY_READ|KEY_WRITE,
-                                        NULL,
-                                        &hkClient,
-                                        NULL) == ERROR_SUCCESS) {
-
-                        dwType = REG_DWORD;
-                        dwSize = sizeof(DWORD);
-                        dwValue = 1;
-                        RegSetValueEx( hkClient, "RemoveDisableLoopbackCheck", 0, dwType, (LPBYTE)&dwValue, dwSize);
-                        RegCloseKey(hkClient);
-                    }
-                    RegCloseKey(hkLsa);
-                }
-            }
-        } else {
-            if (RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
-                                AFSREG_CLT_OPENAFS_SUBKEY,
-                                0,
-                                NULL,
-                                REG_OPTION_NON_VOLATILE,
-                                KEY_READ|KEY_WRITE,
-                                NULL,
-                                &hkClient,
-                                NULL) == ERROR_SUCCESS) {
-
-                dwSize = sizeof(DWORD);
-                if ( RegQueryValueEx( hkClient, "RemoveDisableLoopbackCheck", 0, &dwType, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS &&
-                     dwValue == 1 ) {
-                    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, 
-                                       "SYSTEM\\CurrentControlSet\\Control\\Lsa",
-                                       0,
-                                       KEY_READ|KEY_WRITE,
-                                       &hkLsa) == ERROR_SUCCESS )
-                    {
-                        RegDeleteValue(hkLsa, "DisableLoopbackCheck");
-                        RegCloseKey(hkLsa);
-                    }
-                }
-                RegDeleteValue(hkClient, "RemoveDisableLoopbackCheck");
-                RegCloseKey(hkClient);
-            }
-        }
-        RegCloseKey(hkMSV10);
-    }
-
-    if (pHostNames)
-       free(pHostNames);
-}
-
-
 static void afsd_InitServerPreferences(void)
 {
     HKEY hkPrefs = 0;
@@ -900,15 +747,15 @@ int afsd_InitCM(char **reasonP)
                             (LPBYTE) cm_mountRootC, &cm_mountRootCLen);
     if (code == ERROR_SUCCESS) {
         afsi_log("Mount root %S", cm_mountRootC);
-        cm_mountRootCLen = cm_ClientStrLen(cm_mountRootC);
+        cm_mountRootCLen = (DWORD)cm_ClientStrLen(cm_mountRootC);
     } else {
         cm_ClientStrCpy(cm_mountRootC, lengthof(cm_mountRootC), _C("/afs"));
-        cm_mountRootCLen = cm_ClientStrLen(cm_mountRootC);
+        cm_mountRootCLen = (DWORD)cm_ClientStrLen(cm_mountRootC);
         /* Don't log */
     }
 
     cm_ClientStringToFsString(cm_mountRootC, -1, cm_mountRoot, lengthof(cm_mountRoot));
-    cm_mountRootLen = cm_FsStrLen(cm_mountRoot);
+    cm_mountRootLen = (DWORD)cm_FsStrLen(cm_mountRoot);
 
     dummyLen = sizeof(buf);
     code = RegQueryValueEx(parmKey, "CachePath", NULL, &regType,
@@ -1327,9 +1174,6 @@ int afsd_InitCM(char **reasonP)
     cm_initParams.setTime = 0;
     cm_initParams.memCache = 1;
 
-    /* Ensure the AFS Netbios Name is registered to allow loopback access */
-    configureBackConnectionHostNames();
-
     /* init user daemon, and other packages */
     cm_InitUser();
 
index 357df62..6d34102 100644 (file)
@@ -9409,6 +9409,290 @@ exit_thread:
 }
 
 static void
+configureBackConnectionHostNames(void)
+{
+    /* On Windows XP SP2, Windows 2003 SP1, and all future Windows operating systems
+     * there is a restriction on the use of SMB authentication on loopback connections.
+     * There are two work arounds available:
+     * 
+     *   (1) We can disable the check for matching host names.  This does not
+     *   require a reboot:
+     *   [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa]
+     *     "DisableLoopbackCheck"=dword:00000001
+     *
+     *   (2) We can add the AFS SMB/CIFS service name to an approved list.  This
+     *   does require a reboot:
+     *   [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0]
+     *     "BackConnectionHostNames"=multi-sz
+     *
+     * The algorithm will be:
+     *   (1) Check to see if cm_NetbiosName exists in the BackConnectionHostNames list
+     *   (2a) If not, add it to the list.  (This will not take effect until the next reboot.)
+     *   (2b1)    and check to see if DisableLoopbackCheck is set.
+     *   (2b2)    If not set, set the DisableLoopbackCheck value to 0x1 
+     *   (2b3)                and create HKLM\SOFTWARE\OpenAFS\Client  UnsetDisableLoopbackCheck
+     *   (2c) else If cm_NetbiosName exists in the BackConnectionHostNames list,
+     *             check for the UnsetDisableLoopbackCheck value.  
+     *             If set, set the DisableLoopbackCheck flag to 0x0 
+     *             and delete the UnsetDisableLoopbackCheck value
+     *
+     * Starting in Longhorn Beta 1, an entry in the BackConnectionHostNames value will
+     * force Windows to use the loopback authentication mechanism for the specified 
+     * services.
+     */
+    HKEY hkLsa;
+    HKEY hkMSV10;
+    HKEY hkClient;
+    DWORD dwType;
+    DWORD dwSize, dwAllocSize;
+    DWORD dwValue;
+    PBYTE pHostNames = NULL, pName = NULL;
+    BOOL  bNameFound = FALSE;   
+
+    /* BackConnectionHostNames and DisableLoopbackCheck */
+    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, 
+                       "SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0",
+                       0,
+                       KEY_READ|KEY_WRITE,
+                       &hkMSV10) == ERROR_SUCCESS )
+    {
+        if ((RegQueryValueEx( hkMSV10, "BackConnectionHostNames", 0, 
+                            &dwType, NULL, &dwAllocSize) == ERROR_SUCCESS) &&
+            (dwType == REG_MULTI_SZ)) 
+        {
+           dwAllocSize += 1 /* in case the source string is not nul terminated */
+               + (DWORD)strlen(cm_NetbiosName) + 2;
+           pHostNames = malloc(dwAllocSize);
+           dwSize = dwAllocSize;
+            if (RegQueryValueEx( hkMSV10, "BackConnectionHostNames", 0, &dwType, 
+                                pHostNames, &dwSize) == ERROR_SUCCESS) 
+            {
+               for (pName = pHostNames; 
+                    (pName - pHostNames < (int) dwSize) && *pName ; 
+                    pName += strlen(pName) + 1)
+               {
+                   if ( !stricmp(pName, cm_NetbiosName) ) {
+                       bNameFound = TRUE;
+                       break;
+                   }   
+               }
+           }
+        }
+             
+        if ( !bNameFound ) {
+            size_t size = strlen(cm_NetbiosName) + 2;
+            if ( !pHostNames ) {
+                pHostNames = malloc(size);
+               pName = pHostNames;
+            }
+            StringCbCopyA(pName, size, cm_NetbiosName);
+            pName += size - 1;
+            *pName = '\0';  /* add a second nul terminator */
+
+            dwType = REG_MULTI_SZ;
+           dwSize = (DWORD)(pName - pHostNames + 1);
+            RegSetValueEx( hkMSV10, "BackConnectionHostNames", 0, dwType, pHostNames, dwSize);
+
+            if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, 
+                               "SYSTEM\\CurrentControlSet\\Control\\Lsa",
+                               0,
+                               KEY_READ|KEY_WRITE,
+                               &hkLsa) == ERROR_SUCCESS )
+            {
+                dwSize = sizeof(DWORD);
+                if ( RegQueryValueEx( hkLsa, "DisableLoopbackCheck", 0, &dwType, (LPBYTE)&dwValue, &dwSize) != ERROR_SUCCESS ||
+                     dwValue == 0 ) {
+                    dwType = REG_DWORD;
+                    dwSize = sizeof(DWORD);
+                    dwValue = 1;
+                    RegSetValueEx( hkLsa, "DisableLoopbackCheck", 0, dwType, (LPBYTE)&dwValue, dwSize);
+
+                    if (RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
+                                        AFSREG_CLT_OPENAFS_SUBKEY,
+                                        0,
+                                        NULL,
+                                        REG_OPTION_NON_VOLATILE,
+                                        KEY_READ|KEY_WRITE,
+                                        NULL,
+                                        &hkClient,
+                                        NULL) == ERROR_SUCCESS) {
+
+                        dwType = REG_DWORD;
+                        dwSize = sizeof(DWORD);
+                        dwValue = 1;
+                        RegSetValueEx( hkClient, "RemoveDisableLoopbackCheck", 0, dwType, (LPBYTE)&dwValue, dwSize);
+                        RegCloseKey(hkClient);
+                    }
+                    RegCloseKey(hkLsa);
+                }
+            }
+        } else {
+            if (RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
+                                AFSREG_CLT_OPENAFS_SUBKEY,
+                                0,
+                                NULL,
+                                REG_OPTION_NON_VOLATILE,
+                                KEY_READ|KEY_WRITE,
+                                NULL,
+                                &hkClient,
+                                NULL) == ERROR_SUCCESS) {
+
+                dwSize = sizeof(DWORD);
+                if ( RegQueryValueEx( hkClient, "RemoveDisableLoopbackCheck", 0, &dwType, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS &&
+                     dwValue == 1 ) {
+                    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, 
+                                       "SYSTEM\\CurrentControlSet\\Control\\Lsa",
+                                       0,
+                                       KEY_READ|KEY_WRITE,
+                                       &hkLsa) == ERROR_SUCCESS )
+                    {
+                        RegDeleteValue(hkLsa, "DisableLoopbackCheck");
+                        RegCloseKey(hkLsa);
+                    }
+                }
+                RegDeleteValue(hkClient, "RemoveDisableLoopbackCheck");
+                RegCloseKey(hkClient);
+            }
+        }
+
+        if (pHostNames) {
+            free(pHostNames);
+            pHostNames = NULL;
+        }
+
+        RegCloseKey(hkMSV10);
+    }
+}
+
+
+static void
+configureExtendedSMBSessionTimeouts(void)
+{
+    /*
+     * In a Hot Fix to Windows 2003 SP2, the smb redirector was given the following
+     * new functionality:
+     *
+     *  [HKLM\SYSTEM\CurrentControlSet\Services\LanManWorkstation\Parameters]
+     *   "ReconnectableServers"            REG_MULTI_SZ
+     *   "ExtendedSessTimeout"             REG_DWORD  (seconds)
+     *   "ServersWithExtendedSessTimeout"  REG_MULTI_SZ 
+     *  
+     * These values can be used to prevent the smb redirector from timing out
+     * smb connection to the afs smb server prematurely.
+     */
+    HKEY hkLanMan;
+    DWORD dwType;
+    DWORD dwSize, dwAllocSize;
+    DWORD dwValue;
+    PBYTE pHostNames = NULL, pName = NULL;
+    BOOL  bNameFound = FALSE;   
+
+    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, 
+                       "SYSTEM\\CurrentControlSet\\Services\\LanManWorkstation\\Parameters",
+                       0,
+                       KEY_READ|KEY_WRITE,
+                       &hkLanMan) == ERROR_SUCCESS )
+    {
+        if ((RegQueryValueEx( hkLanMan, "ReconnectableServers", 0, 
+                            &dwType, NULL, &dwAllocSize) == ERROR_SUCCESS) &&
+            (dwType == REG_MULTI_SZ)) 
+        {
+           dwAllocSize += 1 /* in case the source string is not nul terminated */
+               + (DWORD)strlen(cm_NetbiosName) + 2;
+           pHostNames = malloc(dwAllocSize);
+           dwSize = dwAllocSize;
+            if (RegQueryValueEx( hkLanMan, "ReconnectableServers", 0, &dwType, 
+                                pHostNames, &dwSize) == ERROR_SUCCESS) 
+            {
+               for (pName = pHostNames; 
+                    (pName - pHostNames < (int) dwSize) && *pName ; 
+                    pName += strlen(pName) + 1)
+               {
+                   if ( !stricmp(pName, cm_NetbiosName) ) {
+                       bNameFound = TRUE;
+                       break;
+                   }   
+               }
+           }
+        }
+             
+        if ( !bNameFound ) {
+            size_t size = strlen(cm_NetbiosName) + 2;
+            if ( !pHostNames ) {
+                pHostNames = malloc(size);
+               pName = pHostNames;
+            }
+            StringCbCopyA(pName, size, cm_NetbiosName);
+            pName += size - 1;
+            *pName = '\0';  /* add a second nul terminator */
+
+            dwType = REG_MULTI_SZ;
+           dwSize = (DWORD)(pName - pHostNames + 1);
+            RegSetValueEx( hkLanMan, "ReconnectableServers", 0, dwType, pHostNames, dwSize);
+        }
+
+        if (pHostNames) {
+            free(pHostNames);
+            pHostNames = NULL;
+        }
+        
+        if ((RegQueryValueEx( hkLanMan, "ServersWithExtendedSessTimeout", 0, 
+                            &dwType, NULL, &dwAllocSize) == ERROR_SUCCESS) &&
+            (dwType == REG_MULTI_SZ)) 
+        {
+           dwAllocSize += 1 /* in case the source string is not nul terminated */
+               + (DWORD)strlen(cm_NetbiosName) + 2;
+           pHostNames = malloc(dwAllocSize);
+           dwSize = dwAllocSize;
+            if (RegQueryValueEx( hkLanMan, "ServersWithExtendedSessTimeout", 0, &dwType, 
+                                pHostNames, &dwSize) == ERROR_SUCCESS) 
+            {
+               for (pName = pHostNames; 
+                    (pName - pHostNames < (int) dwSize) && *pName ; 
+                    pName += strlen(pName) + 1)
+               {
+                   if ( !stricmp(pName, cm_NetbiosName) ) {
+                       bNameFound = TRUE;
+                       break;
+                   }   
+               }
+           }
+        }
+             
+        if ( !bNameFound ) {
+            size_t size = strlen(cm_NetbiosName) + 2;
+            if ( !pHostNames ) {
+                pHostNames = malloc(size);
+               pName = pHostNames;
+            }
+            StringCbCopyA(pName, size, cm_NetbiosName);
+            pName += size - 1;
+            *pName = '\0';  /* add a second nul terminator */
+
+            dwType = REG_MULTI_SZ;
+           dwSize = (DWORD)(pName - pHostNames + 1);
+            RegSetValueEx( hkLanMan, "ServersWithExtendedSessTimeout", 0, dwType, pHostNames, dwSize);
+        }
+
+        if (pHostNames) {
+            free(pHostNames);
+            pHostNames = NULL;
+        }
+
+        if ((RegQueryValueEx( hkLanMan, "ExtendedSessTimeout", 0, 
+                              &dwType, (LPBYTE)&dwValue, &dwAllocSize) != ERROR_SUCCESS) ||
+             (dwType != REG_DWORD)) 
+        {
+            dwType = REG_DWORD;
+           dwSize = sizeof(dwValue);
+            dwValue = 600;      /* 10 minutes */
+            RegSetValueEx( hkLanMan, "ExtendedSessTimeout", 0, dwType, (const BYTE *)&dwValue, dwSize);
+        }
+        RegCloseKey(hkLanMan);
+    }
+}
+
+static void
 smb_LanAdapterChangeThread(void *param)
 {
     /* 
@@ -9702,6 +9986,12 @@ void smb_StartListeners(int locked)
     }
 
     afsi_log("smb_StartListeners");
+    /* Ensure the AFS Netbios Name is registered to allow loopback access */
+    configureBackConnectionHostNames();
+
+    /* Configure Extended SMB Session Timeouts */
+    configureExtendedSMBSessionTimeouts();
+
     smb_ListenerState = SMB_LISTENER_STARTED;
     cm_VolStatus_Network_Started(cm_NetbiosName
 #ifdef _WIN64