]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE14-windows-digital-sigs-and-more-20041130
authorJeffrey Altman <jaltman@mit.edu>
Tue, 7 Dec 2004 06:01:41 +0000 (06:01 +0000)
committerDerrick Brashear <shadow@dementia.org>
Tue, 7 Dec 2004 06:01:41 +0000 (06:01 +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.

(cherry picked from commit 852a0518624c13e45a4d0f2561b171687e07b9cc)

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 56e6199c0bf75b9b7b87afa25ccf82b61387c85c..9af81d55c84a7f062eba5c82a02196d8432c44c6 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 1e3a7571ea2851952607d76d08fcdc1e66079697..495e2ba14f96d44a96cdd4cb24d46afb0820becb 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 c01f2140ecaef69318c79d28edeff3d49ec037d1..506c8640baab60f3e16849b2e7a9bf53a6489384 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 5f4ac80db7ee16cef56687db2c5391663412d1b8..8abbf431fab7f9a0d8505347bc73ccb0f7bd7b7e 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 3acc6f19e5d50bd96b533536bd9c7622aff912c9..8be706b8e3c5d2f10afddc29838e1f7832635301 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 94985039927bcc2fd733051ba250cdb77b055b4c..38b6ee69bb4cfaba0b2ea58c3014626a6890b761 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 ae8a2cde1ba59c47d660a3434536f52e40d31396..551fb9bcaf11617f296f81c5b20596ef6cb53632 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 28ce1a9f351f46b385b324d778180b213ba0b83a..852f86c7ba11bc9246e1411e05d3c63e33485d28 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 effeb9ee6aea0f3ccbb37f20e247d98e34c36e82..d0fcc78a0f5938409881ae1772dbeaa311322a4b 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 04f251e4f2ea877b24bc81396d7bd7be2087a63d..a162bb9aecddc158083974560f4d3de7cce86ea4 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 c238f22d04304c0345a9bdf4381219af5c131f52..af73b6242aa6c65a84928d7838016724688034c0 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 9271bcb4ce0fc9f78c472177075826bfa21547d1..e742bcf77b76a959cb62e07a2de3f8fc95c74f6c 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"