windows-digital-sigs-and-more-20041130
authorJeffrey Altman <jaltman@mit.edu>
Mon, 29 Nov 2004 21:05:26 +0000 (21:05 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 29 Nov 2004 21:05:26 +0000 (21:05 +0000)
Switch the Trust Provider used to verify the validity of executables
and libraries to the Software Publisher Trust Provider.

Add code (with Asanka's help) to extract the certificate details and
log them to afsd_init.log.  Ensure that if files are signed that all
of the files are signed by the same entity.

Add a number of missing prototypes

Correct conversions from time_t to long or short.

12 files changed:
src/WINNT/afsd/NTMakefile
src/WINNT/afsd/afsd.h
src/WINNT/afsd/afsd_service.c
src/WINNT/afsd/cm_buf.c
src/WINNT/afsd/cm_callback.h
src/WINNT/afsd/cm_config.c
src/WINNT/afsd/cm_config.h
src/WINNT/afsd/cm_freelance.c
src/WINNT/afsd/cm_freelance.h
src/WINNT/afsd/cm_scache.h
src/WINNT/afsd/smb.c
src/WINNT/afsd/smb.h

index 56e6199..9af81d5 100644 (file)
@@ -349,7 +349,9 @@ AFSD_SDKLIBS =\
         secur32.lib \
         ole32.lib \
         oleaut32.lib \
-        psapi.lib wintrust.lib
+        psapi.lib \
+        wintrust.lib \
+        crypt32.lib
 
 AFSD_EXELIBS =\
        $(DESTDIR)\lib\libosi.lib \
index 1e3a757..495e2ba 100644 (file)
@@ -62,6 +62,7 @@ BOOL APIENTRY About(HWND, unsigned int, unsigned int, long);
 #include "cm_buf.h"
 #include "cm_freelance.h"
 #include "smb_ioctl.h"
+#include "afsd_init.h"
 #ifdef DJGPP
 #include "afs/afsmsg95.h"
 #endif
index c01f214..506c864 100644 (file)
@@ -96,7 +96,9 @@ static void afsd_notifier(char *msgp, char *filep, long line)
     smb_DumpVCP(afsi_file, "a");                       
     afsi_log("--- end   dump ---");
     
+#ifdef DEBUG
     DebugBreak();      
+#endif
 
     SetEvent(WaitToTerminate);
 
@@ -490,12 +492,111 @@ GetVersionInfo( CHAR * filename, CHAR * szOutput, DWORD dwOutput )
     return retval;
 }
 
+#define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
+
+PCCERT_CONTEXT GetCertCtx(CHAR * filename)
+{
+    wchar_t wfilename[260];
+    BOOL fResult;
+    DWORD dwEncoding;
+    DWORD dwContentType;
+    DWORD dwFormatType;
+    DWORD dwSignerInfo;
+    HCERTSTORE hStore = NULL;
+    HCRYPTMSG hMsg = NULL;
+    PCMSG_SIGNER_INFO pSignerInfo = NULL;
+    PCCERT_CONTEXT pCertContext = NULL;
+    CERT_INFO CertInfo;
+
+    ZeroMemory(&CertInfo, sizeof(CertInfo));
+    mbstowcs(wfilename, filename, 260);
+
+    fResult = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
+                              wfilename,
+                              CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
+                              CERT_QUERY_FORMAT_FLAG_BINARY,
+                              0,
+                              &dwEncoding,
+                              &dwContentType,
+                              &dwFormatType,
+                              &hStore,
+                              &hMsg,
+                              NULL);
+
+    if (!fResult) {
+        afsi_log("CryptQueryObject failed for [%s] with error 0x%x",
+                filename,
+                GetLastError());
+       goto __exit;
+    }
+
+    fResult = CryptMsgGetParam(hMsg,
+                              CMSG_SIGNER_INFO_PARAM,
+                              0,
+                              NULL,
+                              &dwSignerInfo);
+
+    if (!fResult) {
+        afsi_log("CryptMsgGetParam failed for [%s] with error 0x%x",
+                filename,
+                GetLastError());
+       goto __exit;
+    }
+
+    pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo);
+
+    fResult = CryptMsgGetParam(hMsg,
+                              CMSG_SIGNER_INFO_PARAM,
+                              0,
+                              (PVOID)pSignerInfo,
+                              &dwSignerInfo);
+    
+    if (!fResult) {
+        afsi_log("CryptMsgGetParam failed for [%s] with error 0x%x",
+                filename,
+                GetLastError());
+       goto __exit;
+    }
+
+    CertInfo.Issuer = pSignerInfo->Issuer;
+    CertInfo.SerialNumber = pSignerInfo->SerialNumber;
+
+    pCertContext = CertFindCertificateInStore(hStore,
+                                             ENCODING,
+                                             0,
+                                             CERT_FIND_SUBJECT_CERT,
+                                             (PVOID) &CertInfo,
+                                             NULL);
+
+    if (!pCertContext) {
+      afsi_log("CertFindCertificateInStore for file [%s] failed with 0x%x",
+              filename,
+              GetLastError());
+      goto __exit;
+    }
+
+  __exit:
+    if (pSignerInfo)
+      LocalFree(pSignerInfo);
+
+    /*    if (pCertContext)
+         CertFreeCertificateContext(pCertContext);*/
+
+    if (hStore)
+      CertCloseStore(hStore,0);
+
+    if (hMsg)
+      CryptMsgClose(hMsg);
+
+    return pCertContext;
+}
+
 BOOL VerifyTrust(CHAR * filename)
 {
-    WINTRUST_DATA fTrust;
-    WINTRUST_FILE_INFO finfo;
-    GUID trustAction = WINTRUST_ACTION_GENERIC_VERIFY_V2;
-    GUID subject = WIN_TRUST_SUBJTYPE_RAW_FILEEX;
+    WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT fContextWSubject;
+    WIN_TRUST_SUBJECT_FILE fSubjectFile;
+    GUID trustAction = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE;
+    GUID subject = WIN_TRUST_SUBJTYPE_PE_IMAGE;
     wchar_t wfilename[260];
     LONG ret;
 
@@ -504,25 +605,20 @@ BOOL VerifyTrust(CHAR * filename)
 
     mbstowcs(wfilename, filename, 260);
 
-    finfo.cbStruct = sizeof(finfo);
-    finfo.pcwszFilePath= wfilename;
-    finfo.hFile = INVALID_HANDLE_VALUE;
-    finfo.pgKnownSubject = &subject;
-
-    fTrust.cbStruct = sizeof(fTrust);
-    fTrust.pPolicyCallbackData = NULL;
-    fTrust.pSIPClientData = NULL;
-    fTrust.dwUIChoice = WTD_UI_NONE;
-    fTrust.fdwRevocationChecks = WTD_REVOKE_NONE;
-    fTrust.dwUnionChoice = WTD_CHOICE_FILE;
-    fTrust.pFile = &finfo;
-    fTrust.dwStateAction = WTD_STATEACTION_IGNORE;
-    fTrust.hWVTStateData = NULL;
-    fTrust.pwszURLReference = NULL;
-    fTrust.dwProvFlags = WTD_SAFER_FLAG | WTD_REVOCATION_CHECK_NONE;
-    fTrust.dwUIContext = WTD_UICONTEXT_EXECUTE;
-    
-    ret = WinVerifyTrust(INVALID_HANDLE_VALUE, &trustAction, &fTrust);
+    fSubjectFile.hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
+                             0, NULL);
+    fSubjectFile.lpPath = wfilename;
+    fContextWSubject.hClientToken = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
+                                                FALSE, GetCurrentProcessId());
+    fContextWSubject.SubjectType = &subject;
+    fContextWSubject.Subject = &fSubjectFile;
+
+    ret = WinVerifyTrust(INVALID_HANDLE_VALUE, &trustAction, &fContextWSubject);
+
+    if ( fSubjectFile.hFile != INVALID_HANDLE_VALUE )
+        CloseHandle( fSubjectFile.hFile );
+    if ( fContextWSubject.hClientToken != INVALID_HANDLE_VALUE )
+        CloseHandle( fContextWSubject.hClientToken );
 
     if (ret == ERROR_SUCCESS) {
         return TRUE;
@@ -551,6 +647,74 @@ BOOL VerifyTrust(CHAR * filename)
     }
 }
 
+void LogCertCtx(PCCERT_CONTEXT pCtx) {
+    DWORD dwData;
+    LPTSTR szName = NULL;
+
+    // Get Issuer name size.
+    if (!(dwData = CertGetNameString(pCtx,
+                                    CERT_NAME_SIMPLE_DISPLAY_TYPE,
+                                    CERT_NAME_ISSUER_FLAG,
+                                    NULL,
+                                    NULL,
+                                    0))) {
+        afsi_log("CertGetNameString failed: 0x%x", GetLastError());
+       goto __exit;
+    }
+
+    // Allocate memory for Issuer name.
+    szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR));
+
+    // Get Issuer name.
+    if (!(CertGetNameString(pCtx,
+                           CERT_NAME_SIMPLE_DISPLAY_TYPE,
+                           CERT_NAME_ISSUER_FLAG,
+                           NULL,
+                           szName,
+                           dwData))) {
+        afsi_log("CertGetNameString failed: 0x%x", GetLastError());
+       goto __exit;
+    }
+
+    // print Issuer name.
+    afsi_log("Issuer Name: %s", szName);
+    LocalFree(szName);
+    szName = NULL;
+
+    // Get Subject name size.
+    if (!(dwData = CertGetNameString(pCtx,
+                                    CERT_NAME_SIMPLE_DISPLAY_TYPE,
+                                    0,
+                                    NULL,
+                                    NULL,
+                                    0))) {
+        afsi_log("CertGetNameString failed: 0x%x", GetLastError());
+       goto __exit;
+    }
+
+    // Allocate memory for subject name.
+    szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR));
+
+    // Get subject name.
+    if (!(CertGetNameString(pCtx,
+                           CERT_NAME_SIMPLE_DISPLAY_TYPE,
+                           0,
+                           NULL,
+                           szName,
+                           dwData))) {
+        afsi_log("CertGetNameString failed: 0x%x", GetLastError());
+       goto __exit;
+    }
+
+    // Print Subject Name.
+    afsi_log("Subject Name: %s", szName);
+
+  __exit:
+
+    if (szName)
+        LocalFree(szName);
+}
+
 BOOL AFSModulesVerify(void)
 {
     CHAR filename[1024];
@@ -563,6 +727,7 @@ BOOL AFSModulesVerify(void)
     DWORD cbNeeded;
     unsigned int i;
     BOOL success = TRUE;
+    PCCERT_CONTEXT pCtxService = NULL;
 
     if (!GetModuleFileName(NULL, filename, sizeof(filename)))
         return FALSE;
@@ -574,6 +739,13 @@ BOOL AFSModulesVerify(void)
 
     trustVerified = VerifyTrust(filename);
 
+    if (trustVerified) {
+        // get a certificate context for the signer of afsd_service.
+        pCtxService = GetCertCtx(filename);
+        if (pCtxService)
+            LogCertCtx(pCtxService);
+    }
+
     // Get a list of all the modules in this process.
     hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                            FALSE, GetCurrentProcessId());
@@ -608,15 +780,36 @@ BOOL AFSModulesVerify(void)
                         afsi_log("Version mismatch: %s", szModName);
                         success = FALSE;
                     }
-                    if ( trustVerified && !VerifyTrust(szModName) ) {
-                        afsi_log("Signature Verification failed: %s", szModName);
-                        success = FALSE;
+                    if ( trustVerified ) {
+                        if ( !VerifyTrust(szModName) ) {
+                            afsi_log("Signature Verification failed: %s", szModName);
+                            success = FALSE;
+                        } 
+                        else if (pCtxService) {
+                            PCCERT_CONTEXT pCtx = GetCertCtx(szModName);
+
+                            if (!pCtx || !CertCompareCertificate(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+                                                                  pCtxService->pCertInfo,
+                                                                  pCtx->pCertInfo)) {
+                                afsi_log("Certificate mismatch: %s", szModName);
+                                if (pCtx)
+                                    LogCertCtx(pCtx);
+                                
+                                success = FALSE;
+                            }
+                            
+                            if (pCtx)
+                                CertFreeCertificateContext(pCtx);
+                        }
                     }
                 }
             }
         }
     }
 
+    if (pCtxService)
+        CertFreeCertificateContext(pCtxService);
+
     CloseHandle(hProcess);
     return success;
 }
index 5f4ac80..8abbf43 100644 (file)
@@ -339,6 +339,7 @@ long buf_Init(cm_buf_ops_t *opsp)
                               0, 0,   
                               buf_nbuffers * buf_bufferSize);
         if (data == NULL) {
+            afsi_log("Error mapping view of file: 0x%X", GetLastError());
             if (hf != INVALID_HANDLE_VALUE)
                 CloseHandle(hf);
             CloseHandle(hm);
index 3acc6f1..8be706b 100644 (file)
@@ -66,4 +66,6 @@ extern void cm_CheckCBExpiration(void);
 
 extern osi_rwlock_t cm_callbackLock;
 
+extern void cm_CallbackNotifyChange(cm_scache_t *scp);
+
 #endif /*  _CM_CALLBACK_H_ENV__ */
index 9498503..38b6ee6 100644 (file)
@@ -738,7 +738,7 @@ long cm_CloseCellFile(cm_configFile_t *filep)
 
 void cm_GetConfigDir(char *dir)
 {
-       char wdir[256];
+    char wdir[256];
     int tlen;
 #ifdef AFS_WIN95_ENV
     char *afsconf_path;
index ae8a2cd..551fb9b 100644 (file)
@@ -55,6 +55,8 @@ extern long cm_CloseCellFile(cm_configFile_t *filep);
 
 extern long cm_GetCellServDB(char *cellNamep);
 
+extern void cm_GetConfigDir(char *dir);
+
 #endif /* __CM_CONFIG_INTERFACES_ONLY__ */
 
 #endif /* __CONFIG_H_ENV_ */
index 28ce1a9..852f86c 100644 (file)
@@ -332,7 +332,7 @@ int cm_FakeRootFid(cm_fid_t *fidp)
   
 /* called directly from ioctl */
 /* called while not holding freelance lock */
-int cm_noteLocalMountPointChange() {
+int cm_noteLocalMountPointChange(void) {
     lock_ObtainMutex(&cm_Freelance_Lock);
     cm_fakeDirVersion++;
     cm_localMountPointChangeFlag = 1;
@@ -640,7 +640,7 @@ long cm_InitLocalMountPoints() {
 #endif
 
     if (!fp) {
-#if !defined(DJGPP);
+#if !defined(DJGPP)
         RegCloseKey(hkFreelance);
 #endif
         rootCellName[0] = '.';
@@ -1141,11 +1141,8 @@ long cm_FreelanceRemoveMount(char *toremove)
 
 long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp)
 {
-    FILE *fp;
-    char hfile[120];
     char line[512];
     char fullname[200];
-    int n;
     int alias = 0;
 #if !defined(DJGPP)
     HKEY hkFreelanceSymlinks = 0;
@@ -1252,12 +1249,9 @@ long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp)
 
 long cm_FreelanceRemoveSymlink(char *toremove)
 {
-    int i, n;
     char* cp;
     char line[512];
     char shortname[200];
-    char hfile[120], hfile2[120];
-    FILE *fp1, *fp2;
     int found=0;
 #if !defined(DJGPP)
     HKEY hkFreelanceSymlinks = 0;
index effeb9e..d0fcc78 100644 (file)
@@ -14,6 +14,7 @@ extern long cm_InitLocalMountPoints();
 extern int cm_getLocalMountPointChange();
 extern int cm_reInitLocalMountPoints();
 extern void cm_InitFreelance();
+extern int cm_noteLocalMountPointChange(void);
 extern long cm_FreelanceRemoveMount(char *toremove);
 extern long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw, cm_fid_t *fidp);
 extern long cm_FreelanceRemoveSymlink(char *toremove);
index 04f251e..a162bb9 100644 (file)
@@ -260,4 +260,6 @@ extern cm_scache_t **cm_hashTablep;
 
 extern void cm_DiscardSCache(cm_scache_t *scp);
 
+extern int cm_FindFileType(cm_fid_t *fidp);
+
 #endif /*  __CM_SCACHE_H_ENV__ */
index c238f22..af73b62 100644 (file)
@@ -157,7 +157,7 @@ extern HANDLE WaitToTerminate;
  * Time in Unix format of midnight, 1/1/1970 local time.
  * When added to dosUTime, gives Unix (AFS) time.
  */
-long smb_localZero = 0;
+time_t smb_localZero = 0;
 
 /* Time difference for converting to kludge-GMT */
 int smb_NowTZ;
@@ -706,7 +706,7 @@ void smb_UnixTimeFromLargeSearchTime(time_t *unixTimep, FILETIME *largeTimep)
 }       
 #endif /* !DJGPP */
 
-void smb_SearchTimeFromUnixTime(long *dosTimep, time_t unixTime)
+void smb_SearchTimeFromUnixTime(time_t *dosTimep, time_t unixTime)
 {
     struct tm *ltp;
     int dosDate;
@@ -738,8 +738,8 @@ void smb_UnixTimeFromSearchTime(time_t *unixTimep, time_t searchTime)
     unsigned short dosTime;
     struct tm localTm;
         
-    dosDate = searchTime & 0xffff;
-    dosTime = (searchTime >> 16) & 0xffff;
+    dosDate = (unsigned short) (searchTime & 0xffff);
+    dosTime = (unsigned short) ((searchTime >> 16) & 0xffff);
 
     localTm.tm_year = 80 + ((dosDate>>9) & 0x3f);
     localTm.tm_mon = ((dosDate >> 5) & 0xf) - 1;       /* January is 0 in localTm */
@@ -2867,7 +2867,7 @@ void smb_Daemon(void *parmp)
         thrd_Sleep(10000);
         if ((count % 72) == 0) {       /* every five minutes */
             struct tm myTime;
-            long old_localZero = smb_localZero;
+            time_t old_localZero = smb_localZero;
                 
             /* Initialize smb_localZero */
             myTime.tm_isdst = -1;              /* compute whether on DST or not */
@@ -3262,12 +3262,12 @@ long smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp,
         smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
                 
         /* copy out time */
-        shortTemp = dosTime & 0xffff;
+        shortTemp = (unsigned short) (dosTime & 0xffff);
         *((u_short *)dptr) = shortTemp;
         dptr += 2;
 
         /* and copy out date */
-        shortTemp = (dosTime>>16) & 0xffff;
+        shortTemp = (unsigned short) ((dosTime>>16) & 0xffff);
         *((u_short *)dptr) = shortTemp;
         dptr += 2;
                 
@@ -4074,8 +4074,8 @@ long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack
     smb_SetSMBParm(outp, 0, attrs);
         
     smb_DosUTimeFromUnixTime(&dosTime, newScp->clientModTime);
-    smb_SetSMBParm(outp, 1, dosTime & 0xffff);
-    smb_SetSMBParm(outp, 2, (dosTime>>16) & 0xffff);
+    smb_SetSMBParm(outp, 1, (unsigned int)(dosTime & 0xffff));
+    smb_SetSMBParm(outp, 2, (unsigned int)((dosTime>>16) & 0xffff));
     smb_SetSMBParm(outp, 3, newScp->length.LowPart & 0xffff);
     smb_SetSMBParm(outp, 4, (newScp->length.LowPart >> 16) & 0xffff);
     smb_SetSMBParm(outp, 5, 0);
@@ -4218,8 +4218,8 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     smb_SetSMBParm(outp, 0, fidp->fid);
     smb_SetSMBParm(outp, 1, smb_Attributes(scp));
     smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime);
-    smb_SetSMBParm(outp, 2, dosTime & 0xffff);
-    smb_SetSMBParm(outp, 3, (dosTime >> 16) & 0xffff);
+    smb_SetSMBParm(outp, 2, (unsigned int)(dosTime & 0xffff));
+    smb_SetSMBParm(outp, 3, (unsigned int)((dosTime >> 16) & 0xffff));
     smb_SetSMBParm(outp, 4, scp->length.LowPart & 0xffff);
     smb_SetSMBParm(outp, 5, (scp->length.LowPart >> 16) & 0xffff);
     /* pass the open mode back; XXXX add access checks */
@@ -5444,7 +5444,7 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
                             writeBackOffset.HighPart, cm_chunkSize, 0, userp);
     }
 
-    osi_Log2(smb_logp, "smb_WriteData fid %d returns %d written %d",
+    osi_Log3(smb_logp, "smb_WriteData fid %d returns %d written %d",
               fidp->fid, code, *writtenp);
     return code;
 }
@@ -6459,8 +6459,12 @@ void smb_ClientWaiter(void *parmp)
     while (1) {
         code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBevents,
                                                  FALSE, INFINITE);
-        if (code == WAIT_OBJECT_0)
-            continue;
+        if (code == WAIT_OBJECT_0) {
+            if (smbShutdownFlag == 1)
+                break;
+            else
+                continue;
+        }
 
         /* error checking */
         if (code >= WAIT_ABANDONED_0 && code < (WAIT_ABANDONED_0 + numNCBs))
@@ -6518,8 +6522,12 @@ void smb_ServerWaiter(void *parmp)
         /* Get a session */
         code = thrd_WaitForMultipleObjects_Event(numSessions, SessionEvents,
                                                  FALSE, INFINITE);
-        if (code == WAIT_OBJECT_0)
-            continue;
+        if (code == WAIT_OBJECT_0) {
+            if ( smbShutdownFlag == 1 )
+                break;
+            else
+                continue;
+        }
 
         if (code >= WAIT_ABANDONED_0 && code < (WAIT_ABANDONED_0 + numSessions))
         {
@@ -6557,8 +6565,12 @@ void smb_ServerWaiter(void *parmp)
       NCBretry:
         code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBavails,
                                                  FALSE, INFINITE);
-        if (code == WAIT_OBJECT_0)
-            goto NCBretry;
+        if (code == WAIT_OBJECT_0) {
+            if ( smbShutdownFlag == 1 ) 
+                break;
+            else
+                goto NCBretry;
+        }
 
         /* error checking */
         if (code >= WAIT_ABANDONED_0 && code < (WAIT_ABANDONED_0 + numNCBs))
@@ -6598,9 +6610,6 @@ void smb_ServerWaiter(void *parmp)
 
         /* Fire it up */
         ncbp = NCBs[idx_NCB];
-#ifdef DJGPP
-        dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
-#endif /* DJGPP */
         ncbp->ncb_lsn = (unsigned char) LSNs[idx_session];
         ncbp->ncb_command = NCBRECV | ASYNCH;
         ncbp->ncb_lana_num = lanas[idx_session];
@@ -6614,6 +6623,7 @@ void smb_ServerWaiter(void *parmp)
         ((smb_ncb_t*)ncbp)->orig_pkt = bufs[idx_NCB];
         ncbp->ncb_event = NCBreturns[0][idx_NCB];
         ncbp->ncb_length = SMB_PACKETSIZE;
+        dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
         Netbios(ncbp, dos_ncb);
 #endif /* !DJGPP */
     }
@@ -6652,8 +6662,13 @@ void smb_Server(VOID *parmp)
     while (1) {
         code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBreturns[myIdx],
                                                  FALSE, INFINITE);
+
+        /* terminate silently if shutdown flag is set */
         if (code == WAIT_OBJECT_0) {
-            continue;
+            if (smbShutdownFlag == 1)
+                break;
+            else
+                continue;
         }
 
         /* error checking */
@@ -6819,7 +6834,7 @@ void smb_Server(VOID *parmp)
          * Either way, we can't do anything with this packet.
          * Log, sleep and resume.
          */
-        if(!vcp) {
+        if (!vcp) {
             HANDLE h;
             char buf[1000];
             char *ptbuf[1];
@@ -6838,7 +6853,7 @@ void smb_Server(VOID *parmp)
             ptbuf[0] = buf;
 
             h = RegisterEventSource(NULL,AFS_DAEMON_EVENT_NAME);
-            if(h) {
+            if (h) {
                 ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1001, NULL,1,sizeof(*ncbp),ptbuf,(void*)ncbp);
                 DeregisterEventSource(h);
             }
@@ -7784,7 +7799,7 @@ void smb_Shutdown(void)
 #ifndef DJGPP
         code = Netbios(ncbp);
 #else
-               code = Netbios(ncbp, dos_ncb);
+        code = Netbios(ncbp, dos_ncb);
 #endif
         /*fprintf(stderr, "returned from NCBHANGUP session %d LSN %d\n", i, LSNs[i]);*/
         if (code == 0) code = ncbp->ncb_retcode;
@@ -7814,6 +7829,15 @@ void smb_Shutdown(void)
         }       
         fflush(stderr);
     }
+
+    /* Trigger the shutdown of all SMB threads */
+    for (i = 0; i < numSessions; i++)
+        thrd_SetEvent(NCBreturns[i][0]);
+
+    thrd_SetEvent(NCBevents[0]);
+    thrd_SetEvent(SessionEvents[0]);
+    thrd_SetEvent(NCBavails[0]);
+    thrd_Sleep(1000);
 }
 
 /* Get the UNC \\<servername>\<sharename> prefix. */
index 9271bcb..e742bcf 100644 (file)
@@ -569,6 +569,8 @@ extern BOOL smb_IsLegalFilename(char *filename);
 
 extern char *smb_GetSharename(void);
 
+extern DWORD smb_ServerExceptionFilter(void);
+
 /* include other include files */
 #include "smb3.h"
 #include "smb_ioctl.h"