windows-volume-status-plugin-20070705
[openafs.git] / src / WINNT / afsd / smb.c
index 71f327f..fddacf1 100644 (file)
@@ -60,6 +60,8 @@ osi_mutex_t  smb_ListenerLock;
 char smb_LANadapter;
 unsigned char smb_sharename[NCBNAMSZ+1] = {0};
 
+BOOL isGateway = FALSE;
+
 /* for debugging */
 long smb_maxObsConcurrentCalls=0;
 long smb_concurrentCalls=0;
@@ -1632,6 +1634,36 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName,
         return 0;
     }
 
+    /* Check for volume references
+     * 
+     * They look like <cell>{%,#}<volume>
+     */
+    if (strchr(shareName, '%') != NULL ||
+        strchr(shareName, '#') != NULL) {
+        char pathstr[CELL_MAXNAMELEN + VL_MAXNAMELEN + 1 + CM_PREFIX_VOL_CCH];
+                                /* make room for '/@vol:' + mountchar + NULL terminator*/
+
+        osi_Log1(smb_logp, "smb_FindShare found volume reference [%s]",
+                 osi_LogSaveString(smb_logp, shareName));
+
+        snprintf(pathstr, sizeof(pathstr)/sizeof(char),
+                 "/" CM_PREFIX_VOL "%s", shareName);
+        pathstr[sizeof(pathstr)/sizeof(char) - 1] = '\0';
+        len = strlen(pathstr) + 1;
+
+        *pathNamep = malloc(len);
+        if (*pathNamep) {
+            strcpy(*pathNamep, pathstr);
+            strlwr(*pathNamep);
+            osi_Log1(smb_logp, "   returning pathname [%s]",
+                     osi_LogSaveString(smb_logp, *pathNamep));
+
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
     code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
                          0, KEY_QUERY_VALUE, &parmKey);
     if (code == ERROR_SUCCESS) {
@@ -2598,6 +2630,9 @@ void smb_MapNTError(long code, unsigned long *NTStatusp)
 #endif
     else if (code == RXKADUNKNOWNKEY) {
        NTStatus = 0xC0000322L; /* Bad Kerberos key */
+    } 
+    else if (code == CM_ERROR_BAD_LEVEL) {
+       NTStatus = 0xC0000148L; /* Invalid Level */
     } else {
         NTStatus = 0xC0982001L;        /* SMB non-specific error */
     }
@@ -4202,6 +4237,7 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou
                          "has filetype %d", osi_LogSaveString(smb_logp, dep->name),
                           fileType);
                 if (fileType == CM_SCACHETYPE_DIRECTORY ||
+                    fileType == CM_SCACHETYPE_MOUNTPOINT ||
                     fileType == CM_SCACHETYPE_DFSLINK ||
                     fileType == CM_SCACHETYPE_INVALID)
                     osi_Log0(smb_logp, "SMB search dir skipping directory or bad link");
@@ -4828,11 +4864,11 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
 
     lock_ObtainMutex(&fidp->mx);
     if ((share & 0xf) == 0)
-        fidp->flags |= SMB_FID_OPENREAD;
+        fidp->flags |= SMB_FID_OPENREAD_LISTDIR;
     else if ((share & 0xf) == 1)
         fidp->flags |= SMB_FID_OPENWRITE;
     else 
-        fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE);
+        fidp->flags |= (SMB_FID_OPENREAD_LISTDIR | SMB_FID_OPENWRITE);
     lock_ReleaseMutex(&fidp->mx);
 
     lock_ObtainMutex(&scp->mx);
@@ -6406,7 +6442,7 @@ long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
 
         offset = LargeIntegerAdd(offset,
                                  ConvertLongToLargeInteger(written));
-        count -= written;
+        count -= (unsigned short)written;
         total_written += written;
         written = 0;
     }
@@ -7032,7 +7068,7 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
 
     lock_ObtainMutex(&fidp->mx);
     /* always create it open for read/write */
-    fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE);
+    fidp->flags |= (SMB_FID_OPENREAD_LISTDIR | SMB_FID_OPENWRITE);
 
     /* remember that the file was newly created */
     if (created)
@@ -7933,6 +7969,11 @@ void smb_Listener(void *parmp)
            }
 
            if (lanaRemaining == 0) {
+                cm_VolStatus_Network_Stopped(cm_NetbiosName
+#ifdef _WIN64
+                                             ,cm_NetbiosName
+#endif
+                                              );
                smb_ListenerState = SMB_LISTENER_STOPPED;
                smb_LANadapter = -1;
                lana_list.length = 0;
@@ -8153,10 +8194,40 @@ int smb_NetbiosInit(void)
     int delname_tried=0;
     int len;
     int lana_found = 0;
+    lana_number_t lanaNum;
 
     /* setup the NCB system */
     ncbp = GetNCB();
 
+    /* Call lanahelper to get Netbios name, lan adapter number and gateway flag */
+    if (SUCCEEDED(code = lana_GetUncServerNameEx(cm_NetbiosName, &lanaNum, &isGateway, LANA_NETBIOS_NAME_FULL))) {
+        smb_LANadapter = (lanaNum == LANA_INVALID)? -1: lanaNum;
+
+        if (smb_LANadapter != -1)
+           afsi_log("LAN adapter number %d", smb_LANadapter);
+        else
+           afsi_log("LAN adapter number not determined");
+
+        if (isGateway)
+           afsi_log("Set for gateway service");
+
+        afsi_log("Using >%s< as SMB server name", cm_NetbiosName);
+    } else {
+        /* something went horribly wrong.  We can't proceed without a netbios name */
+        char buf[128];
+        StringCbPrintfA(buf,sizeof(buf),"Netbios name could not be determined: %li", code);
+        osi_panic(buf, __FILE__, __LINE__);
+    }
+
+    /* remember the name */
+    len = (int)strlen(cm_NetbiosName);
+    if (smb_localNamep)
+        free(smb_localNamep);
+    smb_localNamep = malloc(len+1);
+    strcpy(smb_localNamep, cm_NetbiosName);
+    afsi_log("smb_localNamep is >%s<", smb_localNamep);
+
+
     if (smb_LANadapter == -1) {
         ncbp->ncb_command = NCBENUM;
         ncbp->ncb_buffer = (PUCHAR)&lana_list;
@@ -8267,6 +8338,11 @@ int smb_NetbiosInit(void)
        lana_list.length = 0;
        smb_LANadapter = -1;
        smb_ListenerState = SMB_LISTENER_STOPPED;
+        cm_VolStatus_Network_Stopped(cm_NetbiosName
+#ifdef _WIN64
+                                      ,cm_NetbiosName
+#endif
+                                      );
     }
         
     /* we're done with the NCB now */
@@ -8285,6 +8361,11 @@ void smb_StartListeners()
        return;
     
     smb_ListenerState = SMB_LISTENER_STARTED;
+    cm_VolStatus_Network_Started(cm_NetbiosName
+#ifdef _WIN64
+                                  , cm_NetbiosName
+#endif
+                                  );
 
     for (i = 0; i < lana_list.length; i++) {
         if (lana_list.lana[i] == 255) 
@@ -8341,6 +8422,11 @@ void smb_StopListeners(void)
        return;
 
     smb_ListenerState = SMB_LISTENER_STOPPED;
+    cm_VolStatus_Network_Stopped(cm_NetbiosName
+#ifdef _WIN64
+                                  , cm_NetbiosName
+#endif
+                                  );
 
     ncbp = GetNCB();
 
@@ -8363,7 +8449,7 @@ void smb_StopListeners(void)
     Sleep(1000);       /* give the listener threads a chance to exit */
 }
 
-void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt,
+void smb_Init(osi_log_t *logp, int useV3,
               int nThreads
               , void *aMBfunc
   )
@@ -8372,7 +8458,6 @@ void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt,
     thread_t phandle;
     int lpid;
     INT_PTR i;
-    int len;
     struct tm myTime;
     EVENT_HANDLE retHandle;
     char eventName[MAX_PATH];
@@ -8382,7 +8467,6 @@ void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt,
     smb_MBfunc = aMBfunc;
 
     smb_useV3 = useV3;
-    smb_LANadapter = LANadapt;
 
     /* Initialize smb_localZero */
     myTime.tm_isdst = -1;              /* compute whether on DST or not */
@@ -8406,12 +8490,6 @@ void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt,
     /* initialize the remote debugging log */
     smb_logp = logp;
         
-    /* remember the name */
-    len = (int)strlen(snamep);
-    smb_localNamep = malloc(len+1);
-    strcpy(smb_localNamep, snamep);
-    afsi_log("smb_localNamep is >%s<", smb_localNamep);
-
     /* and the global lock */
     lock_InitializeRWLock(&smb_globalLock, "smb global lock");
     lock_InitializeRWLock(&smb_rctLock, "smb refct and tree struct lock");
@@ -8942,97 +9020,72 @@ int smb_DumpVCP(FILE *outputFile, char *cookie, int lock)
     if (lock)
         lock_ObtainRead(&smb_rctLock);
   
-    sprintf(output, "begin dumping smb_vc_t\n");
+    sprintf(output, "begin dumping smb_vc_t\r\n");
     WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
 
     for (vcp = smb_allVCsp; vcp; vcp=vcp->nextp) 
     {
         smb_fid_t *fidp;
       
-        sprintf(output, "%s vcp=0x%p, refCount=%d, flags=%d, vcID=%d, lsn=%d, uidCounter=%d, tidCounter=%d, fidCounter=%d\n",
+        sprintf(output, "%s vcp=0x%p, refCount=%d, flags=%d, vcID=%d, lsn=%d, uidCounter=%d, tidCounter=%d, fidCounter=%d\r\n",
                  cookie, vcp, vcp->refCount, vcp->flags, vcp->vcID, vcp->lsn, vcp->uidCounter, vcp->tidCounter, vcp->fidCounter);
         WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
       
-        sprintf(output, "begin dumping smb_fid_t\n");
+        sprintf(output, "begin dumping smb_fid_t\r\n");
         WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
 
         for (fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q))
         {
-            sprintf(output, "%s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, ioctlp=0x%p, NTopen_pathp=%s, NTopen_wholepathp=%s\n", 
+            sprintf(output, "%s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, ioctlp=0x%p, NTopen_pathp=%s, NTopen_wholepathp=%s\r\n", 
                      cookie, fidp, fidp->refCount, fidp->fid, fidp->vcp, fidp->scp, fidp->ioctlp, 
                      fidp->NTopen_pathp ? fidp->NTopen_pathp : "NULL", 
                      fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : "NULL");
             WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
         }
       
-        sprintf(output, "done dumping smb_fid_t\n");
+        sprintf(output, "done dumping smb_fid_t\r\n");
         WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
     }
 
-    sprintf(output, "done dumping smb_vc_t\n");
+    sprintf(output, "done dumping smb_vc_t\r\n");
     WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
   
-    sprintf(output, "begin dumping DEAD smb_vc_t\n");
+    sprintf(output, "begin dumping DEAD smb_vc_t\r\n");
     WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
 
     for (vcp = smb_deadVCsp; vcp; vcp=vcp->nextp) 
     {
         smb_fid_t *fidp;
       
-        sprintf(output, "%s vcp=0x%p, refCount=%d, flags=%d, vcID=%d, lsn=%d, uidCounter=%d, tidCounter=%d, fidCounter=%d\n",
+        sprintf(output, "%s vcp=0x%p, refCount=%d, flags=%d, vcID=%d, lsn=%d, uidCounter=%d, tidCounter=%d, fidCounter=%d\r\n",
                  cookie, vcp, vcp->refCount, vcp->flags, vcp->vcID, vcp->lsn, vcp->uidCounter, vcp->tidCounter, vcp->fidCounter);
         WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
       
-        sprintf(output, "begin dumping smb_fid_t\n");
+        sprintf(output, "begin dumping smb_fid_t\r\n");
         WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
 
         for (fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q))
         {
-            sprintf(output, "%s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, ioctlp=0x%p, NTopen_pathp=%s, NTopen_wholepathp=%s\n", 
+            sprintf(output, "%s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, ioctlp=0x%p, NTopen_pathp=%s, NTopen_wholepathp=%s\r\n", 
                      cookie, fidp, fidp->refCount, fidp->fid, fidp->vcp, fidp->scp, fidp->ioctlp, 
                      fidp->NTopen_pathp ? fidp->NTopen_pathp : "NULL", 
                      fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : "NULL");
             WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
         }
       
-        sprintf(output, "done dumping smb_fid_t\n");
+        sprintf(output, "done dumping smb_fid_t\r\n");
         WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
     }
 
-    sprintf(output, "done dumping DEAD smb_vc_t\n");
-    WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
-  
-    sprintf(output, "begin dumping DEAD smb_vc_t\n");
-    WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
-
-    for (vcp = smb_deadVCsp; vcp; vcp=vcp->nextp) 
-    {
-        smb_fid_t *fidp;
-      
-        sprintf(output, "%s vcp=0x%p, refCount=%d, flags=%d, vcID=%d, lsn=%d, uidCounter=%d, tidCounter=%d, fidCounter=%d\n",
-                 cookie, vcp, vcp->refCount, vcp->flags, vcp->vcID, vcp->lsn, vcp->uidCounter, vcp->tidCounter, vcp->fidCounter);
-        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
-      
-        sprintf(output, "begin dumping smb_fid_t\n");
-        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
-
-        for (fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q))
-        {
-            sprintf(output, "%s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, ioctlp=0x%p, NTopen_pathp=%s, NTopen_wholepathp=%s\n", 
-                     cookie, fidp, fidp->refCount, fidp->fid, fidp->vcp, fidp->scp, fidp->ioctlp, 
-                     fidp->NTopen_pathp ? fidp->NTopen_pathp : "NULL", 
-                     fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : "NULL");
-            WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
-        }
-      
-        sprintf(output, "done dumping smb_fid_t\n");
-        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
-    }
-
-    sprintf(output, "done dumping DEAD smb_vc_t\n");
+    sprintf(output, "done dumping DEAD smb_vc_t\r\n");
     WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
   
     if (lock)
         lock_ReleaseRead(&smb_rctLock);
     return 0;
 }
+
+long smb_IsNetworkStarted(void)
+{
+    return (smb_ListenerState == SMB_LISTENER_STARTED && smbShutdownFlag == 0);
+}