windows-do-not-discard-badtickets-20080218
[openafs.git] / src / WINNT / afsd / smb.c
index 7c82cc1..c4a2534 100644 (file)
@@ -93,6 +93,7 @@ EVENT_HANDLE NCBavails[NCB_MAX], NCBevents[NCB_MAX];
 EVENT_HANDLE **NCBreturns;
 EVENT_HANDLE **NCBShutdown;
 EVENT_HANDLE *smb_ServerShutdown;
+EVENT_HANDLE ListenerShutdown[256];
 DWORD NCBsessions[NCB_MAX];
 NCB *NCBs[NCB_MAX];
 struct smb_packet *bufs[NCB_MAX];
@@ -103,7 +104,6 @@ unsigned short LSNs[SESSION_MAX];
 int lanas[SESSION_MAX];
 BOOL dead_sessions[SESSION_MAX];
 LANA_ENUM lana_list;
-
 /* for raw I/O */
 osi_mutex_t smb_RawBufLock;
 char *smb_RawBufs;
@@ -1644,6 +1644,8 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName,
     }
 
     if (_stricmp(shareName, "IPC$") == 0 ||
+        _stricmp(shareName, "srvsvc") == 0 ||
+        _stricmp(shareName, "wkssvc") == 0 ||
         _stricmp(shareName, SMB_IOCTL_FILENAME_NOSLASH) == 0 ||
         _stricmp(shareName, "DESKTOP.INI") == 0
          ) {
@@ -2580,11 +2582,7 @@ void smb_MapNTError(long code, unsigned long *NTStatusp)
         NTStatus = 0xC09820FBL;        /* SMB use standard */
     }
     else if (code == CM_ERROR_QUOTA) {
-#ifdef COMMENT
         NTStatus = 0xC0000044L;        /* Quota exceeded */
-#else
-        NTStatus = 0xC000007FL;        /* Disk full */
-#endif
     }
     else if (code == CM_ERROR_SPACE) {
         NTStatus = 0xC000007FL;        /* Disk full */
@@ -2638,12 +2636,16 @@ void smb_MapNTError(long code, unsigned long *NTStatusp)
     else if (code == CM_ERROR_ALLOFFLINE || code == CM_ERROR_ALLDOWN) {
         NTStatus = 0xC00000BEL; /* Bad Network Path */
     } 
-    else if (code == RXKADUNKNOWNKEY) {
-       NTStatus = 0xC0000322L; /* Bad Kerberos key */
+    else if (code >= ERROR_TABLE_BASE_RXK && code < ERROR_TABLE_BASE_RXK + 256) {
+       NTStatus = 0xC0000322L; /* No Kerberos key */
     } 
     else if (code == CM_ERROR_BAD_LEVEL) {
        NTStatus = 0xC0000148L; /* Invalid Level */
-    } else {
+    } 
+    else if (code == CM_ERROR_RANGE_NOT_LOCKED) {
+       NTStatus = 0xC000007EL; /* Range Not Locked */
+    } 
+    else {
         NTStatus = 0xC0982001L;        /* SMB non-specific error */
     }
 
@@ -8059,6 +8061,12 @@ void smb_Listener(void *parmp)
     char cname[MAX_COMPUTERNAME_LENGTH+1];
     int cnamelen = MAX_COMPUTERNAME_LENGTH+1;
     INT_PTR lana = (INT_PTR) parmp;
+    char eventName[MAX_PATH];
+
+    sprintf(eventName,"smb_Listener_lana_%d", (char)lana);
+    ListenerShutdown[lana] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName);
+    if ( GetLastError() == ERROR_ALREADY_EXISTS )
+        thrd_ResetEvent(ListenerShutdown[lana]);
 
     ncbp = GetNCB();
 
@@ -8086,25 +8094,36 @@ void smb_Listener(void *parmp)
 
         code = Netbios(ncbp);
 
-       if (code == NRC_BRIDGE) {
-           int lanaRemaining = 0;
+        if (code == NRC_NAMERR) {
+         /* An smb shutdown or Vista resume must have taken place */
+         osi_Log2(smb_logp,
+                  "NCBLISTEN lana=%d failed with NRC_NAMERR.",
+                  ncbp->ncb_lana_num, code);
 
-           lock_ObtainMutex(&smb_StartedLock);
-           if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1) {
+            if (lock_TryMutex(&smb_StartedLock)) {
+                lana_list.lana[i] = LANA_INVALID;
                lock_ReleaseMutex(&smb_StartedLock);
-               ExitThread(1);
            }
+            break;
+        } else if (code ==  NRC_BRIDGE || code != 0) {
+            int lanaRemaining = 0;
 
-           osi_Log2(smb_logp,
-                     "NCBLISTEN lana=%d failed with NRC_BRIDGE.  Listener thread exiting.",
-                     ncbp->ncb_lana_num, code);
+            while (!lock_TryMutex(&smb_StartedLock)) {
+                if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1)
+                    goto exit_thread;
+                Sleep(50);
+            }
+            osi_Log2(smb_logp,
+                      "NCBLISTEN lana=%d failed with %s.  Listener thread exiting.",
+                      ncbp->ncb_lana_num, ncb_error_string(code));
 
            for (i = 0; i < lana_list.length; i++) {
-               if (lana_list.lana[i] == ncbp->ncb_lana_num) {
-                   smb_StopListener(ncbp, lana_list.lana[i]);
-                   lana_list.lana[i] = 255;
+               if (lana_list.lana[i] == lana) {
+                   smb_StopListener(ncbp, lana_list.lana[i], FALSE);
+                   lana_list.lana[i] = LANA_INVALID;
                }
-               if (lana_list.lana[i] != 255)
+               if (lana_list.lana[i] != LANA_INVALID)
                    lanaRemaining++;
            }
 
@@ -8118,15 +8137,18 @@ void smb_Listener(void *parmp)
                smb_LANadapter = LANA_INVALID;
                lana_list.length = 0;
            }
-           FreeNCB(ncbp);
             lock_ReleaseMutex(&smb_StartedLock);
-           return;
-       } else if (code != 0) {
+           break;
+       }
+#if 0
+        else if (code != 0) {
             char tbuffer[AFSPATHMAX];
 
             /* terminate silently if shutdown flag is set */
-            if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1) {
-                ExitThread(1);
+            while (!lock_TryMutex(&smb_StartedLock)) {
+                if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1)
+                    goto exit_thread;
+                Sleep(50);
             }
 
             osi_Log3(smb_logp, 
@@ -8143,7 +8165,11 @@ void smb_Listener(void *parmp)
                 code = (*smb_MBfunc)(NULL, tbuffer, "AFS Client Service: Fatal Error",
                                       MB_OK|MB_SERVICE_NOTIFICATION);
             osi_panic(tbuffer, __FILE__, __LINE__);
+
+            lock_ReleaseMutex(&smb_StartedLock);
+            break;
         }
+#endif /* 0 */
 
         /* check for remote conns */
         /* first get remote name and insert null terminator */
@@ -8323,12 +8349,37 @@ void smb_Listener(void *parmp)
         lock_ReleaseMutex(&smb_ListenerLock);
     }  /* dispatch while loop */
 
+exit_thread:
     FreeNCB(ncbp);
+    thrd_SetEvent(ListenerShutdown[lana]);
+    return;
+}
+
+static void
+smb_LanAdapterChangeThread(void *param)
+{
+    /* 
+     * Give the IPAddrDaemon thread a chance
+     * to block before we trigger.
+     */
+    Sleep(30000);
+    smb_LanAdapterChange(0);
 }
 
 void smb_SetLanAdapterChangeDetected(void)
 {
+    int lpid;
+    thread_t phandle;
+
     lock_ObtainMutex(&smb_StartedLock);
+
+    if (!powerStateSuspended) {
+        phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_LanAdapterChangeThread,
+                              NULL, 0, &lpid, "smb_LanAdapterChange");
+        osi_assertx(phandle != NULL, "smb_LanAdapterChangeThread thread creation failure");
+        thrd_CloseHandle(phandle);
+    }
+
     smb_LanAdapterChangeDetected = 1;
     lock_ReleaseMutex(&smb_StartedLock);
 }
@@ -8352,10 +8403,9 @@ void smb_LanAdapterChange(int locked) {
 
     if (!powerStateSuspended && 
         SUCCEEDED(lana_GetUncServerNameEx(NetbiosName, &lanaNum, &bGateway, 
-                                          LANA_NETBIOS_NAME_FULL))) {
-
-        if ( lanaNum != LANA_INVALID && smb_LANadapter != lanaNum ||
-             isGateway != bGateway ||
+                                          LANA_NETBIOS_NAME_FULL)) &&
+        lanaNum != LANA_INVALID && smb_LANadapter != lanaNum) {
+        if ( isGateway != bGateway ||
              strcmp(cm_NetbiosName, NetbiosName) ) {
             change = 1;
         } else {
@@ -8470,7 +8520,7 @@ int smb_NetbiosInit(int locked)
             code = ncbp->ncb_retcode;
         if (code != 0) {
             afsi_log("Netbios NCBRESET lana %d error code %d", lana_list.lana[i], code);
-            lana_list.lana[i] = 255;  /* invalid lana */
+            lana_list.lana[i] = LANA_INVALID;  /* invalid lana */
         } else {
             afsi_log("Netbios NCBRESET lana %d succeeded", lana_list.lana[i]);
         }
@@ -8510,7 +8560,7 @@ int smb_NetbiosInit(int locked)
         else {
             afsi_log("Netbios NCBADDNAME lana %d error code %d", lana, code);
             if (code == NRC_BRIDGE) {    /* invalid LANA num */
-                lana_list.lana[l] = 255;
+                lana_list.lana[l] = LANA_INVALID;
                 continue;
             }
             else if (code == NRC_DUPNAME) {
@@ -8526,7 +8576,7 @@ int smb_NetbiosInit(int locked)
                     afsi_log("Netbios NCBDELNAME lana %d error code %d\n", lana, code);
                 }
                 if (code != 0 || delname_tried) {
-                    lana_list.lana[l] = 255;
+                    lana_list.lana[l] = LANA_INVALID;
                 }
                 else if (code == 0) {
                     if (!delname_tried) {
@@ -8538,7 +8588,7 @@ int smb_NetbiosInit(int locked)
             }
             else {
                 afsi_log("Netbios NCBADDNAME lana %d error code %d", lana, code);
-                lana_list.lana[l] = 255;  /* invalid lana */
+                lana_list.lana[l] = LANA_INVALID;  /* invalid lana */
             }
         }
         if (code == 0) {
@@ -8597,7 +8647,7 @@ void smb_StartListeners(int locked)
                                   );
 
     for (i = 0; i < lana_list.length; i++) {
-        if (lana_list.lana[i] == 255) 
+        if (lana_list.lana[i] == LANA_INVALID) 
             continue;
         phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_Listener,
                                (void*)lana_list.lana[i], 0, &lpid, "smb_Listener");
@@ -8613,8 +8663,10 @@ void smb_RestartListeners(int locked)
     if (!locked)
         lock_ObtainMutex(&smb_StartedLock);
 
+    if (powerStateSuspended)
+        afsi_log("smb_RestartListeners called while suspended");
+
     if (!powerStateSuspended && smb_ListenerState != SMB_LISTENER_UNINITIALIZED) {
-        afsi_log("smb_RestartListeners");
        if (smb_ListenerState == SMB_LISTENER_STOPPED) {
             if (smb_NetbiosInit(1))
                 smb_StartListeners(1);
@@ -8626,7 +8678,7 @@ void smb_RestartListeners(int locked)
         lock_ReleaseMutex(&smb_StartedLock);
 }
 
-void smb_StopListener(NCB *ncbp, int lana)
+void smb_StopListener(NCB *ncbp, int lana, int wait)
 {
     long code;
 
@@ -8652,6 +8704,9 @@ void smb_StopListener(NCB *ncbp, int lana)
     } else {
        afsi_log("Netbios NCBRESET lana %d succeeded", lana);
     }
+
+    if (wait)
+        thrd_WaitForSingleObject_Event(ListenerShutdown[lana], INFINITE);
 }
 
 void smb_StopListeners(int locked)
@@ -8682,11 +8737,11 @@ void smb_StopListeners(int locked)
     for (l = 0; l < lana_list.length; l++) {
         lana = lana_list.lana[l];
 
-       if (lana != 255) {
-           smb_StopListener(ncbp, lana);
+       if (lana != LANA_INVALID) {
+           smb_StopListener(ncbp, lana, TRUE);
 
            /* mark the adapter invalid */
-           lana_list.lana[l] = 255;  /* invalid lana */
+           lana_list.lana[l] = LANA_INVALID;  /* invalid lana */
        }
     }
 
@@ -8696,7 +8751,6 @@ void smb_StopListeners(int locked)
     FreeNCB(ncbp);
     if (!locked)
         lock_ReleaseMutex(&smb_StartedLock);
-    Sleep(1000);       /* give the listener threads a chance to exit */
 }
 
 void smb_Init(osi_log_t *logp, int useV3,
@@ -9037,7 +9091,7 @@ void smb_Init(osi_log_t *logp, int useV3,
 
     phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_ClientWaiter,
                           NULL, 0, &lpid, "smb_ClientWaiter");
-    osi_assertx(phandle != NULL, , "smb_ClientWaiter thread creation failure");
+    osi_assertx(phandle != NULL, "smb_ClientWaiter thread creation failure");
     thrd_CloseHandle(phandle);
 
     phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_ServerWaiter,
@@ -9122,7 +9176,7 @@ void smb_Shutdown(void)
     /* Delete Netbios name */
     memset((char *)ncbp, 0, sizeof(NCB));
     for (i = 0; i < lana_list.length; i++) {
-        if (lana_list.lana[i] == 255) continue;
+        if (lana_list.lana[i] == LANA_INVALID) continue;
         ncbp->ncb_command = NCBDELNAME;
         ncbp->ncb_lana_num = lana_list.lana[i];
         memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ);