windows-byte-range-locks-20050816
[openafs.git] / src / WINNT / afsd / smb.c
index 22657df..7f62f59 100644 (file)
@@ -25,6 +25,8 @@
 #include <time.h>
 
 #include <osi.h>
+#include <rx\rx.h>
+#include <rx/rx_prototypes.h>
 
 #include "afsd.h"
 #include <WINNT\afsreg.h>
@@ -152,7 +154,6 @@ int smb_useV3;              /* try to negotiate V3 */
 static showErrors = 1;
 /* MessageBox or something like it */
 int (_stdcall *smb_MBfunc)(HWND, LPCTSTR, LPCTSTR, UINT) = NULL;
-extern HANDLE WaitToTerminate;
 #endif /* DJGPP */
 
 /* GMT time info:
@@ -161,8 +162,12 @@ extern HANDLE WaitToTerminate;
  */
 time_t smb_localZero = 0;
 
+#define USE_NUMERIC_TIME_CONV 1
+
+#ifndef USE_NUMERIC_TIME_CONV
 /* Time difference for converting to kludge-GMT */
-int smb_NowTZ;
+afs_uint32 smb_NowTZ;
+#endif /* USE_NUMERIC_TIME_CONV */
 
 char *smb_localNamep = NULL;
 
@@ -170,7 +175,7 @@ smb_vc_t *smb_allVCsp;
 
 smb_username_t *usernamesp = NULL;
 
-smb_waitingLock_t *smb_allWaitingLocks;
+smb_waitingLockRequest_t *smb_allWaitingLocks;
 
 /* forward decl */
 void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp,
@@ -543,7 +548,7 @@ void GetTimeZoneInfo(BOOL *pDST, LONG *pDstBias, LONG *pBias)
 #endif /* DJGPP */
  
 
-void CompensateForSmbClientLastWriteTimeBugs(long *pLastWriteTime)
+void CompensateForSmbClientLastWriteTimeBugs(afs_uint32 *pLastWriteTime)
 {
     BOOL dst;       /* Will be TRUE if observing DST */
     LONG dstBias;   /* Offset from local time if observing DST */
@@ -579,6 +584,7 @@ void CompensateForSmbClientLastWriteTimeBugs(long *pLastWriteTime)
         *pLastWriteTime -= (-bias * 60);        /* Convert bias to seconds */
 }                      
 
+#ifndef USE_NUMERIC_TIME_CONV
 /*
  * Calculate the difference (in seconds) between local time and GMT.
  * This enables us to convert file times to kludge-GMT.
@@ -595,21 +601,26 @@ smb_CalculateNowTZ()
     local_tm = *(localtime(&t));
 
     days = local_tm.tm_yday - gmt_tm.tm_yday;
-    hours = 24 * days + local_tm.tm_hour - gmt_tm.tm_hour
-#ifdef COMMENT
-        /* There is a problem with DST immediately after the time change
-        * which may continue to exist until the machine is rebooted
-         */
-        - (local_tm.tm_isdst ? 1 : 0)
-#endif /* COMMENT */
-            ;
+    hours = 24 * days + local_tm.tm_hour - gmt_tm.tm_hour;
     minutes = 60 * hours + local_tm.tm_min - gmt_tm.tm_min; 
     seconds = 60 * minutes + local_tm.tm_sec - gmt_tm.tm_sec;
 
     smb_NowTZ = seconds;
 }
+#endif /* USE_NUMERIC_TIME_CONV */
 
 #ifndef DJGPP
+#ifdef USE_NUMERIC_TIME_CONV
+void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, time_t unixTime)
+{
+    // Note that LONGLONG is a 64-bit value
+    LONGLONG ll;
+
+    ll = Int32x32To64(unixTime, 10000000) + 116444736000000000;
+    largeTimep->dwLowDateTime = (DWORD)(ll & 0xFFFFFFFF);
+    largeTimep->dwHighDateTime = (DWORD)(ll >> 32);
+}
+#else
 void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, time_t unixTime)
 {
     struct tm *ltp;
@@ -649,6 +660,7 @@ void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, time_t unixTime)
 
     SystemTimeToFileTime(&stm, largeTimep);
 }
+#endif /* USE_NUMERIC_TIME_CONV */
 #else /* DJGPP */
 void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, time_t unixTime)
 {
@@ -672,6 +684,22 @@ void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, time_t unixTime)
 #endif /* !DJGPP */
 
 #ifndef DJGPP
+#ifdef USE_NUMERIC_TIME_CONV
+void smb_UnixTimeFromLargeSearchTime(time_t *unixTimep, FILETIME *largeTimep)
+{
+    // Note that LONGLONG is a 64-bit value
+    LONGLONG ll;
+
+    ll = largeTimep->dwHighDateTime;
+    ll <<= 32;
+    ll += largeTimep->dwLowDateTime;
+
+    ll -= 116444736000000000;
+    ll /= 10000000;
+
+    *unixTimep = (DWORD)ll;
+}
+#else /* USE_NUMERIC_TIME_CONV */
 void smb_UnixTimeFromLargeSearchTime(time_t *unixTimep, FILETIME *largeTimep)
 {
     SYSTEMTIME stm;
@@ -694,6 +722,7 @@ void smb_UnixTimeFromLargeSearchTime(time_t *unixTimep, FILETIME *largeTimep)
     *unixTimep = mktime(&lt);
     _timezone = save_timezone;
 }       
+#endif /* USE_NUMERIC_TIME_CONV */
 #else /* DJGPP */
 void smb_UnixTimeFromLargeSearchTime(time_t *unixTimep, FILETIME *largeTimep)
 {
@@ -716,7 +745,7 @@ void smb_UnixTimeFromLargeSearchTime(time_t *unixTimep, FILETIME *largeTimep)
 }       
 #endif /* !DJGPP */
 
-void smb_SearchTimeFromUnixTime(time_t *dosTimep, time_t unixTime)
+void smb_SearchTimeFromUnixTime(afs_uint32 *searchTimep, time_t unixTime)
 {
     struct tm *ltp;
     int dosDate;
@@ -739,10 +768,10 @@ void smb_SearchTimeFromUnixTime(time_t *dosTimep, time_t unixTime)
 
     dosDate = ((ltp->tm_year-80)<<9) | ((ltp->tm_mon+1) << 5) | (ltp->tm_mday);
     dosTime = (ltp->tm_hour<<11) | (ltp->tm_min << 5) | (ltp->tm_sec / 2);
-    *dosTimep = (dosDate<<16) | dosTime;
+    *searchTimep = (dosDate<<16) | dosTime;
 }      
 
-void smb_UnixTimeFromSearchTime(time_t *unixTimep, time_t searchTime)
+void smb_UnixTimeFromSearchTime(time_t *unixTimep, afs_uint32 searchTime)
 {
     unsigned short dosDate;
     unsigned short dosTime;
@@ -762,12 +791,12 @@ void smb_UnixTimeFromSearchTime(time_t *unixTimep, time_t searchTime)
     *unixTimep = mktime(&localTm);
 }
 
-void smb_DosUTimeFromUnixTime(time_t *dosUTimep, time_t unixTime)
+void smb_DosUTimeFromUnixTime(afs_uint32 *dosUTimep, time_t unixTime)
 {
     *dosUTimep = unixTime - smb_localZero;
 }
 
-void smb_UnixTimeFromDosUTime(time_t *unixTimep, time_t dosTime)
+void smb_UnixTimeFromDosUTime(time_t *unixTimep, afs_uint32 dosTime)
 {
 #ifndef DJGPP
     *unixTimep = dosTime + smb_localZero;
@@ -831,6 +860,11 @@ smb_vc_t *smb_FindVC(unsigned short lsn, int flags, int lana)
         }
         else
             memset(vcp->encKey, 0, MSV1_0_CHALLENGE_LENGTH);
+
+        if (numVCs >= CM_SESSION_RESERVED) {
+            numVCs = 0;
+            osi_Log0(smb_logp, "WARNING: numVCs wrapping around");
+        }
     }
     lock_ReleaseWrite(&smb_rctLock);
     return vcp;
@@ -1112,7 +1146,7 @@ int smb_SUser(cm_user_t *userp)
     return 1;
 }
 
-/* find a file ID.  If we pass in 0 we select an used File ID.
+/* find a file ID.  If we pass in 0 we select an unused File ID.
  * If the SMB_FLAG_CREATE flag is set, we allocate a new  
  * smb_fid_t data structure if desired File ID cannot be found.
  */
@@ -1144,6 +1178,7 @@ smb_fid_t *smb_FindFID(smb_vc_t *vcp, unsigned short fid, int flags)
             break;
         }
     }
+
     if (!fidp && (flags & SMB_FLAG_CREATE)) {
         char eventName[MAX_PATH];
         EVENT_HANDLE event;
@@ -1174,6 +1209,7 @@ smb_fid_t *smb_FindFID(smb_vc_t *vcp, unsigned short fid, int flags)
                 vcp->fidCounter = 1;
         }
     }
+
     lock_ReleaseWrite(&smb_rctLock);
     return fidp;
 }
@@ -1517,7 +1553,7 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName,
         /* Get the full name for this cell */
         code = cm_SearchCellFile(p, temp, 0, 0);
 #ifdef AFS_AFSDB_ENV
-               if (code && cm_dnsEnabled) {
+        if (code && cm_dnsEnabled) {
             int ttl;
             code = cm_SearchCellByDNS(p, temp, &ttl, 0, 0);
         }
@@ -1651,7 +1687,8 @@ void smb_ReleaseDirSearchNoLock(smb_dirSearch_t *dsp)
         lock_ReleaseMutex(&dsp->mx);
     }
     /* do this now to avoid spurious locking hierarchy creation */
-    if (scp) cm_ReleaseSCache(scp);
+    if (scp) 
+        cm_ReleaseSCache(scp);
 }       
 
 void smb_ReleaseDirSearch(smb_dirSearch_t *dsp)
@@ -1841,7 +1878,8 @@ smb_packet_t *smb_CopyPacket(smb_packet_t *pkt)
     tbp = GetPacket();
     memcpy(tbp, pkt, sizeof(smb_packet_t));
     tbp->wctp = tbp->data + ((unsigned int)pkt->wctp - (unsigned int)pkt->data);
-    smb_HoldVC(tbp->vcp);
+       if (tbp->vcp)
+               smb_HoldVC(tbp->vcp);
     return tbp;
 }
 
@@ -2219,8 +2257,51 @@ void smb_SendPacket(smb_vc_t *vcp, smb_packet_t *inp)
     code = Netbios(ncbp, dos_ncb);
 #endif /* !DJGPP */
         
-    if (code != 0)
-        osi_Log1(smb_logp, "SendPacket failure code %d", code);
+    if (code != 0) {
+        char * s;
+        switch ( code ) {
+        case 0x01: s = "llegal buffer length                     "; break; 
+        case 0x03: s = "illegal command                          "; break; 
+        case 0x05: s = "command timed out                        "; break; 
+        case 0x06: s = "message incomplete, issue another command"; break; 
+        case 0x07: s = "illegal buffer address                   "; break; 
+        case 0x08: s = "session number out of range              "; break; 
+        case 0x09: s = "no resource available                    "; break; 
+        case 0x0a: s = "session closed                           "; break; 
+        case 0x0b: s = "command cancelled                        "; break; 
+        case 0x0d: s = "duplicate name                           "; break; 
+        case 0x0e: s = "name table full                          "; break; 
+        case 0x0f: s = "no deletions, name has active sessions   "; break; 
+        case 0x11: s = "local session table full                 "; break; 
+        case 0x12: s = "remote session table full                "; break; 
+        case 0x13: s = "illegal name number                      "; break; 
+        case 0x14: s = "no callname                              "; break; 
+        case 0x15: s = "cannot put * in NCB_NAME                 "; break; 
+        case 0x16: s = "name in use on remote adapter            "; break; 
+        case 0x17: s = "name deleted                             "; break; 
+        case 0x18: s = "session ended abnormally                 "; break; 
+        case 0x19: s = "name conflict detected                   "; break; 
+        case 0x21: s = "interface busy, IRET before retrying     "; break; 
+        case 0x22: s = "too many commands outstanding, retry later"; break;
+        case 0x23: s = "ncb_lana_num field invalid               "; break; 
+        case 0x24: s = "command completed while cancel occurring "; break; 
+        case 0x26: s = "command not valid to cancel              "; break; 
+        case 0x30: s = "name defined by anther local process     "; break; 
+        case 0x34: s = "environment undefined. RESET required    "; break; 
+        case 0x35: s = "required OS resources exhausted          "; break; 
+        case 0x36: s = "max number of applications exceeded      "; break; 
+        case 0x37: s = "no saps available for netbios            "; break; 
+        case 0x38: s = "requested resources are not available    "; break; 
+        case 0x39: s = "invalid ncb address or length > segment  "; break; 
+        case 0x3B: s = "invalid NCB DDID                         "; break; 
+        case 0x3C: s = "lock of user area failed                 "; break; 
+        case 0x3f: s = "NETBIOS not loaded                       "; break; 
+        case 0x40: s = "system error                             "; break;                 
+        default:
+            s = "unknown error";
+        }
+        osi_Log2(smb_logp, "SendPacket failure code %d \"%s\"", code, s);
+    }
 
     if (localNCB)
         FreeNCB(ncbp);
@@ -2239,7 +2320,11 @@ void smb_MapNTError(long code, unsigned long *NTStatusp)
         NTStatus = 0xC000000FL;        /* No such file */
     }
     else if (code == CM_ERROR_TIMEDOUT) {
+#ifdef COMMENT
         NTStatus = 0xC00000CFL;        /* Sharing Paused */
+#else
+        NTStatus = 0x00000102L; /* Timeout */
+#endif
     }
     else if (code == CM_ERROR_RETRY) {
         NTStatus = 0xC000022DL;        /* Retry */
@@ -2249,7 +2334,7 @@ void smb_MapNTError(long code, unsigned long *NTStatusp)
     }
     else if (code == CM_ERROR_READONLY) {
         NTStatus = 0xC00000A2L;        /* Write protected */
-    }  
+    }
     else if (code == CM_ERROR_NOSUCHFILE) {
         NTStatus = 0xC000000FL;        /* No such file */
     }
@@ -2329,6 +2414,12 @@ void smb_MapNTError(long code, unsigned long *NTStatusp)
     else if (code == CM_ERROR_WOULDBLOCK) {
         NTStatus = 0xC0000055L;        /* Lock not granted */
     }
+    else if (code == CM_ERROR_SHARING_VIOLATION) {
+        NTStatus = 0xC0000043L; /* Sharing violation */
+    }
+    else if (code == CM_ERROR_LOCK_CONFLICT) {
+        NTStatus = 0xC0000054L; /* Lock conflict */
+    }
     else if (code == CM_ERROR_PARTIALWRITE) {
         NTStatus = 0xC000007FL;        /* Disk full */
     }
@@ -2357,9 +2448,23 @@ void smb_MapNTError(long code, unsigned long *NTStatusp)
     else if (code == CM_ERROR_PATH_NOT_COVERED) {
         NTStatus = 0xC0000257L; /* Path Not Covered */
     } 
+#ifdef COMMENT
     else if (code == CM_ERROR_ALLBUSY) {
         NTStatus = 0xC00000BFL; /* Network Busy */
-    } else {
+    } 
+    else if (code == CM_ERROR_ALLOFFLINE) {
+        NTStatus = 0xC0000350L; /* Remote Host Down */
+    } 
+#else
+    /* we do not want to be telling the SMB/CIFS client that
+     * the AFS Client Service is busy or down.  
+     */
+    else if (code == CM_ERROR_ALLBUSY || 
+             code == CM_ERROR_ALLOFFLINE) {
+        NTStatus = 0xC00000BEL; /* Bad Network Path */
+    }
+#endif
+    else {
         NTStatus = 0xC0982001L;        /* SMB non-specific error */
     }
 
@@ -2502,6 +2607,14 @@ void smb_MapCoreError(long code, smb_vc_t *vcp, unsigned short *scodep,
         class = 1;
         error = 33;    /* lock conflict */
     }
+    else if (code == CM_ERROR_LOCK_CONFLICT) {
+        class = 1;
+        error = 33;     /* lock conflict */
+    }
+    else if (code == CM_ERROR_SHARING_VIOLATION) {
+        class = 1;
+        error = 33;     /* lock conflict */
+    }
     else if (code == CM_ERROR_NOFILES) {
         class = 1;
         error = 18;    /* no files in search */
@@ -2560,6 +2673,7 @@ long smb_ReceiveCoreReadRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp
     osi_hyper_t offset;
     long count, minCount, finalCount;
     unsigned short fd;
+    unsigned pid;
     smb_fid_t *fidp;
     long code = 0;
     cm_user_t *userp = NULL;
@@ -2588,6 +2702,26 @@ long smb_ReceiveCoreReadRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp
     if (!fidp)
         goto send1;
 
+    pid = ((smb_t *) inp)->pid;
+    {
+        LARGE_INTEGER LOffset, LLength;
+        cm_key_t key;
+
+        key = cm_GenerateKey(vcp->vcID, pid, fd);
+
+        LOffset.HighPart = 0;
+        LOffset.LowPart = offset.LowPart;
+        LLength.HighPart = 0;
+        LLength.LowPart = count;
+
+        lock_ObtainMutex(&fidp->scp->mx);
+        code = cm_LockCheckRead(fidp->scp, LOffset, LLength, key);
+        lock_ReleaseMutex(&fidp->scp->mx);
+    }    
+    if (code) {
+        goto send1a;
+    }
+
     lock_ObtainMutex(&smb_RawBufLock);
     if (smb_RawBufs) {
         /* Get a raw buf, from head of list */
@@ -2711,7 +2845,7 @@ long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     char protocol_array[10][1024];  /* protocol signature of the client */
     int caps;                       /* capabilities */
     time_t unixTime;
-    time_t dosTime;
+    afs_uint32 dosTime;
     TIME_ZONE_INFORMATION tzi;
 
     osi_Log1(smb_logp, "SMB receive negotiate; %d + 1 ongoing ops",
@@ -2951,8 +3085,9 @@ void smb_Daemon(void *parmp)
             myTime.tm_sec = 0;
             smb_localZero = mktime(&myTime);
 
+#ifndef USE_NUMERIC_TIME_CONV
             smb_CalculateNowTZ();
-
+#endif /* USE_NUMERIC_TIME_CONV */
 #ifdef AFS_FREELANCE
             if ( smb_localZero != old_localZero )
                 cm_noteLocalMountPointChange();
@@ -2964,7 +3099,8 @@ void smb_Daemon(void *parmp)
 
 void smb_WaitingLocksDaemon()
 {
-    smb_waitingLock_t *wL, *nwL;
+    smb_waitingLockRequest_t *wlRequest, *nwlRequest;
+    smb_waitingLock_t *wl, *wlNext;
     int first;
     smb_vc_t *vcp;
     smb_packet_t *inp, *outp;
@@ -2973,8 +3109,8 @@ void smb_WaitingLocksDaemon()
 
     while (smbShutdownFlag == 0) {
         lock_ObtainWrite(&smb_globalLock);
-        nwL = smb_allWaitingLocks;
-        if (nwL == NULL) {
+        nwlRequest = smb_allWaitingLocks;
+        if (nwlRequest == NULL) {
             osi_SleepW((long)&smb_allWaitingLocks, &smb_globalLock);
             thrd_Sleep(1000);
             continue;
@@ -2986,23 +3122,76 @@ void smb_WaitingLocksDaemon()
                 first = 0;
             else
                 lock_ObtainWrite(&smb_globalLock);
-            wL = nwL;
-            nwL = (smb_waitingLock_t *) osi_QNext(&wL->q);
+
+            wlRequest = nwlRequest;
+            nwlRequest = (smb_waitingLockRequest_t *) osi_QNext(&wlRequest->q);
             lock_ReleaseWrite(&smb_globalLock);
-            code = cm_RetryLock((cm_file_lock_t *) wL->lockp,
-                                 wL->vcp->flags & SMB_VCFLAG_ALREADYDEAD);
+
+            code = 0;
+
+            for (wl = wlRequest->locks; wl; wl = (smb_waitingLock_t *) osi_QNext(&wl->q)) {
+                if (wl->state == SMB_WAITINGLOCKSTATE_DONE)
+                    continue;
+                
+                /* wl->state is either _DONE or _WAITING.  _ERROR
+                   would no longer be on the queue. */
+                code = cm_RetryLock( wl->lockp,
+                                     !!(wlRequest->vcp->flags & SMB_VCFLAG_ALREADYDEAD) );
+
+                if (code == 0) {
+                    wl->state = SMB_WAITINGLOCKSTATE_DONE;
+                } else if (code != CM_ERROR_WOULDBLOCK) {
+                    wl->state = SMB_WAITINGLOCKSTATE_ERROR;
+                    break;
+                }
+            }
+
             if (code == CM_ERROR_WOULDBLOCK) {
+
                 /* no progress */
-                if (wL->timeRemaining != 0xffffffff
-                     && (wL->timeRemaining -= 1000) < 0)
+                if (wlRequest->timeRemaining != 0xffffffff
+                     && (wlRequest->timeRemaining -= 1000) < 0)
                     goto endWait;
+
                 continue;
             }
 
           endWait:
-            vcp = wL->vcp;
-            inp = wL->inp;
-            outp = wL->outp;
+
+            if (code != 0) {
+                cm_scache_t * scp;
+                cm_req_t req;
+
+                scp = wlRequest->scp;
+
+                cm_InitReq(&req);
+
+                lock_ObtainMutex(&scp->mx);
+
+                for (wl = wlRequest->locks; wl; wl = wlNext) {
+                    wlNext = (smb_waitingLock_t *) osi_QNext(&wl->q);
+                    
+                    cm_Unlock(scp, wlRequest->lockType, wl->LOffset, 
+                              wl->LLength, wl->key, NULL, &req);
+
+                    osi_QRemove((osi_queue_t **) &wlRequest->locks, &wl->q);
+
+                    free(wl);
+                }
+                
+                lock_ReleaseMutex(&scp->mx);
+
+            } else {
+                for (wl = wlRequest->locks; wl; wl = wlNext) {
+                    wlNext = (smb_waitingLock_t *) osi_QNext(&wl->q);
+                    osi_QRemove((osi_queue_t **) &wlRequest->locks, &wl->q);
+                    free(wl);
+                }
+            }
+
+            vcp = wlRequest->vcp;
+            inp = wlRequest->inp;
+            outp = wlRequest->outp;
             ncbp = GetNCB();
             ncbp->ncb_length = inp->ncb_length;
             inp->spacep = cm_GetSpace();
@@ -3010,7 +3199,7 @@ void smb_WaitingLocksDaemon()
             /* Remove waitingLock from list */
             lock_ObtainWrite(&smb_globalLock);
             osi_QRemove((osi_queue_t **)&smb_allWaitingLocks,
-                         &wL->q);
+                         &wlRequest->q);
             lock_ReleaseWrite(&smb_globalLock);
 
             /* Resume packet processing */
@@ -3026,9 +3215,10 @@ void smb_WaitingLocksDaemon()
             smb_FreePacket(inp);
             smb_FreePacket(outp);
             smb_ReleaseVC(vcp);
+            cm_ReleaseSCache(wlRequest->scp);
             FreeNCB(ncbp);
-            free(wL);
-        } while (nwL && smbShutdownFlag == 0);
+            free(wlRequest);
+        } while (nwlRequest && smbShutdownFlag == 0);
         thrd_Sleep(1000);
     }
 }
@@ -3303,7 +3493,7 @@ long smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp,
     long code = 0;
     cm_scache_t *scp;
     char *dptr;
-    time_t dosTime;
+    afs_uint32 dosTime;
     u_short shortTemp;
     char attr;
     smb_dirListPatch_t *patchp;
@@ -3990,7 +4180,7 @@ long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack
     unsigned short attribute;
     cm_attr_t attr;
     cm_scache_t *newScp;
-    time_t dosTime;
+    afs_uint32 dosTime;
     cm_user_t *userp;
     int caseFold;
     char *tidPathp;
@@ -4100,7 +4290,7 @@ long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack
     long code = 0;
     cm_scache_t *rootScp;
     cm_scache_t *newScp, *dscp;
-    time_t dosTime;
+    afs_uint32 dosTime;
     int attrs;
     cm_user_t *userp;
     int caseFold;
@@ -4282,7 +4472,7 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     long code = 0;
     cm_user_t *userp;
     cm_scache_t *scp;
-    time_t dosTime;
+    afs_uint32 dosTime;
     int caseFold;
     cm_space_t *spacep;
     char *tidPathp;
@@ -4749,7 +4939,7 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i
                 else 
                     code = CM_ERROR_EXISTS;
                 cm_ReleaseSCache(tmpscp2);
-                               tmpscp2 = NULL;
+                tmpscp2 = NULL;
             } else {
                 code = CM_ERROR_NOSUCHFILE;
             }
@@ -5207,7 +5397,7 @@ long smb_ReceiveCoreClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     unsigned short fid;
     smb_fid_t *fidp;
     cm_user_t *userp;
-    long dosTime;
+    afs_uint32 dosTime;
     long code = 0;
     cm_req_t req;
 
@@ -5252,6 +5442,40 @@ long smb_ReceiveCoreClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     else 
         code = 0;
 
+    /* unlock any pending locks */
+    if (!(fidp->flags & SMB_FID_IOCTL) && fidp->scp &&
+        fidp->scp->fileType == CM_SCACHETYPE_FILE) {
+        cm_key_t key;
+        unsigned pid;
+        cm_scache_t * scp;
+        long tcode;
+
+        pid = ((smb_t *) inp)->pid;
+        key = cm_GenerateKey(vcp->vcID, pid, fid);
+        scp = fidp->scp;
+        cm_HoldSCache(scp);
+        lock_ObtainMutex(&scp->mx);
+
+        tcode = cm_SyncOp(scp, NULL, userp, &req, 0,
+                          CM_SCACHESYNC_NEEDCALLBACK
+                          | CM_SCACHESYNC_GETSTATUS
+                          | CM_SCACHESYNC_LOCK);
+
+        if (tcode) {
+            osi_Log1(smb_logp, "smb CoreClose SyncOp failure code 0x%x", tcode);
+            goto post_syncopdone;
+        }
+
+        cm_UnlockByKey(scp, key, CM_UNLOCK_BY_FID, userp, &req);
+
+        cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
+
+    post_syncopdone:
+
+        lock_ReleaseMutex(&scp->mx);
+        cm_ReleaseSCache(scp);
+    }
+
     if (fidp->flags & SMB_FID_DELONCLOSE) {
         cm_scache_t *dscp = fidp->NTopen_dscp;
         char *pathp = fidp->NTopen_pathp;
@@ -5330,7 +5554,7 @@ long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
         }
         if (fidp->curr_chunk == fidp->prev_chunk + 1)
             sequential = 1;
-    }       
+    }
 
     /* start by looking up the file's end */
     code = cm_SyncOp(scp, NULL, userp, &req, 0,
@@ -5487,14 +5711,10 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
     lock_ObtainMutex(&scp->mx);
 
     /* start by looking up the file's end */
-    osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp NEEDCALLBACK|SETSTATUS|GETSTATUS",
-              fidp->fid);
     code = cm_SyncOp(scp, NULL, userp, &req, 0,
                       CM_SCACHESYNC_NEEDCALLBACK
                       | CM_SCACHESYNC_SETSTATUS
                       | CM_SCACHESYNC_GETSTATUS);
-    osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp NEEDCALLBACK|SETSTATUS|GETSTATUS returns %d",
-              fidp->fid,code);
     if (code) 
         goto done;
         
@@ -5574,14 +5794,10 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
 
             /* now get the data in the cache */
             while (1) {
-                osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp NEEDCALLBACK|WRITE|BUFLOCKED",
-                          fidp->fid);
                 code = cm_SyncOp(scp, bufferp, userp, &req, 0,
                                   CM_SCACHESYNC_NEEDCALLBACK
                                   | CM_SCACHESYNC_WRITE
                                   | CM_SCACHESYNC_BUFLOCKED);
-                osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp NEEDCALLBACK|WRITE|BUFLOCKED returns %d",
-                          fidp->fid,code);
                 if (code) 
                     goto done;
 
@@ -5704,6 +5920,7 @@ long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     osi_hyper_t offset;
     long count, written = 0, total_written = 0;
     unsigned short fd;
+    unsigned pid;
     smb_fid_t *fidp;
     long code = 0;
     cm_user_t *userp;
@@ -5733,7 +5950,7 @@ long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         
     userp = smb_GetUser(vcp, inp);
 
-       /* special case: 0 bytes transferred means truncate to this position */
+    /* special case: 0 bytes transferred means truncate to this position */
     if (count == 0) {
         cm_req_t req;
 
@@ -5751,6 +5968,27 @@ long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         goto done;
     }
 
+    {
+        cm_key_t key;
+        LARGE_INTEGER LOffset;
+        LARGE_INTEGER LLength;
+
+        pid = ((smb_t *) inp)->pid;
+        key = cm_GenerateKey(vcp->vcID, pid, fd);
+
+        LOffset.HighPart = offset.HighPart;
+        LOffset.LowPart = offset.LowPart;
+        LLength.HighPart = 0;
+        LLength.LowPart = count;
+
+        lock_ObtainMutex(&fidp->scp->mx);
+        code = cm_LockCheckWrite(fidp->scp, LOffset, LLength, key);
+        lock_ReleaseMutex(&fidp->scp->mx);
+
+        if (code)
+            goto done;
+    }
+
     /*
      * Work around bug in NT client
      *
@@ -5902,6 +6140,30 @@ long smb_ReceiveCoreWriteRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
     if (!fidp) {
         return CM_ERROR_BADFD;
     }
+
+    {
+        unsigned pid;
+        cm_key_t key;
+        LARGE_INTEGER LOffset;
+        LARGE_INTEGER LLength;
+
+        pid = ((smb_t *) inp)->pid;
+        key = cm_GenerateKey(vcp->vcID, pid, fd);
+
+        LOffset.HighPart = offset.HighPart;
+        LOffset.LowPart = offset.LowPart;
+        LLength.HighPart = 0;
+        LLength.LowPart = count;
+
+        lock_ObtainMutex(&fidp->scp->mx);
+        code = cm_LockCheckWrite(fidp->scp, LOffset, LLength, key);
+        lock_ReleaseMutex(&fidp->scp->mx);
+
+        if (code) {
+            smb_ReleaseFID(fidp);
+            return code;
+        }
+    }
         
     userp = smb_GetUser(vcp, inp);
 
@@ -5996,6 +6258,7 @@ long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     osi_hyper_t offset;
     long count, finalCount;
     unsigned short fd;
+    unsigned pid;
     smb_fid_t *fidp;
     long code = 0;
     cm_user_t *userp;
@@ -6018,6 +6281,27 @@ long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     if (fidp->flags & SMB_FID_IOCTL) {
         return smb_IoctlRead(fidp, vcp, inp, outp);
     }
+
+    {
+        LARGE_INTEGER LOffset, LLength;
+        cm_key_t key;
+
+        pid = ((smb_t *) inp)->pid;
+        key = cm_GenerateKey(vcp->vcID, pid, fd);
+
+        LOffset.HighPart = 0;
+        LOffset.LowPart = offset.LowPart;
+        LLength.HighPart = 0;
+        LLength.LowPart = count;
+        
+        lock_ObtainMutex(&fidp->scp->mx);
+        code = cm_LockCheckRead(fidp->scp, LOffset, LLength, key);
+        lock_ReleaseMutex(&fidp->scp->mx);
+    }
+    if (code) {
+        smb_ReleaseFID(fidp);
+        return code;
+    }
         
     userp = smb_GetUser(vcp, inp);
 
@@ -6193,7 +6477,7 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     int attributes;
     char *lastNamep;
     int caseFold;
-    long dosTime;
+    afs_uint32 dosTime;
     char *tidPathp;
     cm_req_t req;
 
@@ -6518,11 +6802,11 @@ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp,
                 code = smb_ReceiveCoreWriteRaw (vcp, inp, outp,
                                                  rwcp);
             else {
-                osi_LogEvent("AFS Dispatch %s",(myCrt_Dispatch(inp->inCom)),"vcp[%x] lana[%d] lsn[%d]",(int)vcp,vcp->lana,vcp->lsn);
-                osi_Log4(smb_logp,"Dispatch %s vcp[%x] lana[%d] lsn[%d]",myCrt_Dispatch(inp->inCom),vcp,vcp->lana,vcp->lsn);
+                osi_LogEvent("AFS Dispatch %s",(myCrt_Dispatch(inp->inCom)),"vcp 0x%x lana %d lsn %d",(int)vcp,vcp->lana,vcp->lsn);
+                osi_Log4(smb_logp,"Dispatch %s vcp 0x%x lana %d lsn %d",myCrt_Dispatch(inp->inCom),vcp,vcp->lana,vcp->lsn);
                 code = (*(dp->procp)) (vcp, inp, outp);
-                osi_LogEvent("AFS Dispatch return",NULL,"Code[%d]",(code==0)?0:code-CM_ERROR_BASE);
-                osi_Log1(smb_logp,"Dispatch return  code[%d]",(code==0)?0:code-CM_ERROR_BASE);
+                osi_LogEvent("AFS Dispatch return",NULL,"Code 0x%x",(code==0)?0:code-CM_ERROR_BASE);
+                osi_Log4(smb_logp,"Dispatch return  code 0x%x vcp 0x%x lana %d lsn %d",(code==0)?0:code-CM_ERROR_BASE,vcp,vcp->lana,vcp->lsn);
 #ifdef LOG_PACKET
                 if ( code == CM_ERROR_BADSMB ||
                      code == CM_ERROR_BADOP )
@@ -6926,6 +7210,8 @@ void smb_Server(VOID *parmp)
     dos_ptr dos_ncb;
 #endif /* DJGPP */
 
+    rx_StartClientThread();
+
     outncbp = GetNCB();
     outbufp = GetPacket();
     outbufp->ncbp = outncbp;
@@ -6972,7 +7258,7 @@ void smb_Server(VOID *parmp)
         if (idx_NCB < 0 || idx_NCB > (sizeof(NCBs) / sizeof(NCBs[0])))
         {
             /* this is fatal - log as much as possible */
-            osi_Log1(smb_logp, "Fatal: idx_NCB [ %d ] out of range.\n", idx_NCB);
+            osi_Log1(smb_logp, "Fatal: idx_NCB %d out of range.\n", idx_NCB);
             osi_assert(0);
         }
 
@@ -7001,13 +7287,13 @@ void smb_Server(VOID *parmp)
                 osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: illegal buffer address", ncbp->ncb_lsn, idx_session);
                 break;
             case 0x08:
-                osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: lsn %d session number out of range", ncbp->ncb_lsn, idx_session);
+                osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: session number out of range", ncbp->ncb_lsn, idx_session);
                 break;
             case 0x09:
                 osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: no resource available", ncbp->ncb_lsn, idx_session);
                 break;
             case 0x0a:
-                osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: lsn %d session closed", ncbp->ncb_lsn, idx_session);
+                osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: session closed", ncbp->ncb_lsn, idx_session);
                 break;
             case 0x0b:
                 osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: command cancelled", ncbp->ncb_lsn, idx_session);
@@ -7022,10 +7308,10 @@ void smb_Server(VOID *parmp)
                 osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: no deletions, name has active lsn %d sessions", ncbp->ncb_lsn, idx_session);
                 break;
             case 0x11:
-                osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: local lsn %d session table full", ncbp->ncb_lsn, idx_session);
+                osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: local session table full", ncbp->ncb_lsn, idx_session);
                 break;
             case 0x12:
-                osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: remote lsn %d session table full", ncbp->ncb_lsn, idx_session);
+                osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: remote session table full", ncbp->ncb_lsn, idx_session);
                 break;
             case 0x13:
                 osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: illegal name number", ncbp->ncb_lsn, idx_session);
@@ -7043,7 +7329,7 @@ void smb_Server(VOID *parmp)
                 osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: name deleted", ncbp->ncb_lsn, idx_session);
                 break;
             case 0x18:
-                osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: lsn %d session ended abnormally", ncbp->ncb_lsn, idx_session);
+                osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: session ended abnormally", ncbp->ncb_lsn, idx_session);
                 break;
             case 0x19:
                 osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: name conflict detected", ncbp->ncb_lsn, idx_session);
@@ -7107,9 +7393,8 @@ void smb_Server(VOID *parmp)
             break;
 
         case NRC_PENDING:
-            /* Can this happen? Or is it just my
-             * UNIX paranoia? 
-             */
+            /* Can this happen? Or is it just my UNIX paranoia? */
+            osi_Log2(smb_logp, "NCBRECV pending lsn %d session %d", ncbp->ncb_lsn, idx_session);
             continue;
 
         case NRC_SCLOSED:
@@ -7127,15 +7412,17 @@ void smb_Server(VOID *parmp)
              * also cleanup after dead vcp 
              */
             if (vcp) {
-                if (dead_vcp)
-                    osi_Log1(smb_logp,
-                             "dead_vcp already set, %x",
-                             dead_vcp);
+                if (dead_vcp == vcp)
+                    osi_Log1(smb_logp, "dead_vcp already set, 0x%x", dead_vcp);
                 else if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
-                    osi_Log2(smb_logp,
-                             "setting dead_vcp %x, user struct %x",
+                    osi_Log2(smb_logp, "setting dead_vcp 0x%x, user struct 0x%x",
                              vcp, vcp->usersp);
                     smb_HoldVC(vcp);
+                    if (dead_vcp) {
+                        smb_ReleaseVC(dead_vcp);
+                        osi_Log1(smb_logp,
+                                  "Previous dead_vcp %x", dead_vcp);
+                    }
                     dead_vcp = vcp;
                     vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
                 }
@@ -7551,7 +7838,6 @@ void smb_Listener(void *parmp)
         vcp = smb_FindVC(ncbp->ncb_lsn, SMB_FLAG_CREATE, ncbp->ncb_lana_num);
         vcp->flags |= flags;
         strcpy(vcp->rname, rname);
-        smb_ReleaseVC(vcp);
 
         /* Allocate slot in session arrays */
         /* Re-use dead session if possible, otherwise add one more */
@@ -7564,43 +7850,82 @@ void smb_Listener(void *parmp)
             }
         }
 
-        /* assert that we do not exceed the maximum number of sessions or NCBs.
-         * we should probably want to wait for a session to be freed in case
-         * we run out.
-         */
+        if (i >= Sessionmax - 1  || numNCBs >= NCBmax - 1) {
+            unsigned long code = CM_ERROR_ALLBUSY;
+            smb_packet_t * outp = GetPacket();
+            unsigned char *outWctp;
+            smb_t *smbp;
+            
+            outp->ncbp = ncbp;
 
-        osi_assert(i < Sessionmax - 1);
-        osi_assert(numNCBs < NCBmax - 1);   /* if we pass this test we can allocate one more */
+            if (vcp->flags & SMB_VCFLAG_STATUS32) {
+                unsigned long NTStatus;
+                smb_MapNTError(code, &NTStatus);
+                outWctp = outp->wctp;
+                smbp = (smb_t *) &outp->data;
+                *outWctp++ = 0;
+                *outWctp++ = 0;
+                *outWctp++ = 0;
+                smbp->rcls = (unsigned char) (NTStatus & 0xff);
+                smbp->reh = (unsigned char) ((NTStatus >> 8) & 0xff);
+                smbp->errLow = (unsigned char) ((NTStatus >> 16) & 0xff);
+                smbp->errHigh = (unsigned char) ((NTStatus >> 24) & 0xff);
+                smbp->flg2 |= SMB_FLAGS2_32BIT_STATUS;
+            } else {
+                unsigned short errCode;
+                unsigned char errClass;
+                smb_MapCoreError(code, vcp, &errCode, &errClass);
+                outWctp = outp->wctp;
+                smbp = (smb_t *) &outp->data;
+                *outWctp++ = 0;
+                *outWctp++ = 0;
+                *outWctp++ = 0;
+                smbp->errLow = (unsigned char) (errCode & 0xff);
+                smbp->errHigh = (unsigned char) ((errCode >> 8) & 0xff);
+                smbp->rcls = errClass;
+            }
+            smb_SendPacket(vcp, outp);
+            smb_FreePacket(outp);
+        } else {
+            /* assert that we do not exceed the maximum number of sessions or NCBs.
+            * we should probably want to wait for a session to be freed in case
+            * we run out.
+            */
+            osi_assert(i < Sessionmax - 1);
+            osi_assert(numNCBs < NCBmax - 1);   /* if we pass this test we can allocate one more */
 
-        LSNs[i] = ncbp->ncb_lsn;
-        lanas[i] = ncbp->ncb_lana_num;
+            LSNs[i] = ncbp->ncb_lsn;
+            lanas[i] = ncbp->ncb_lana_num;
                
-        if (i == numSessions) {
-            /* Add new NCB for new session */
-            char eventName[MAX_PATH];
-
-            osi_Log1(smb_logp, "smb_Listener creating new session %d", i);
-
-            InitNCBslot(numNCBs);
-            numNCBs++;
-            thrd_SetEvent(NCBavails[0]);
-            thrd_SetEvent(NCBevents[0]);
-            for (j = 0; j < smb_NumServerThreads; j++)
-                thrd_SetEvent(NCBreturns[j][0]);
-            /* Also add new session event */
-            sprintf(eventName, "SessionEvents[%d]", i);
-            SessionEvents[i] = thrd_CreateEvent(NULL, FALSE, TRUE, eventName);
-            if ( GetLastError() == ERROR_ALREADY_EXISTS )
-                osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName));
-            numSessions++;
-            osi_Log2(smb_logp, "increasing numNCBs [ %d ] numSessions [ %d ]", numNCBs, numSessions);
-            thrd_SetEvent(SessionEvents[0]);
-        } else {
-            thrd_SetEvent(SessionEvents[i]);
+            if (i == numSessions) {
+                /* Add new NCB for new session */
+                char eventName[MAX_PATH];
+
+                osi_Log1(smb_logp, "smb_Listener creating new session %d", i);
+
+                InitNCBslot(numNCBs);
+                numNCBs++;
+                thrd_SetEvent(NCBavails[0]);
+                thrd_SetEvent(NCBevents[0]);
+                for (j = 0; j < smb_NumServerThreads; j++)
+                    thrd_SetEvent(NCBreturns[j][0]);
+                /* Also add new session event */
+                sprintf(eventName, "SessionEvents[%d]", i);
+                SessionEvents[i] = thrd_CreateEvent(NULL, FALSE, TRUE, eventName);
+                if ( GetLastError() == ERROR_ALREADY_EXISTS )
+                    osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName));
+                numSessions++;
+                osi_Log2(smb_logp, "increasing numNCBs [ %d ] numSessions [ %d ]", numNCBs, numSessions);
+                thrd_SetEvent(SessionEvents[0]);
+            } else {
+                thrd_SetEvent(SessionEvents[i]);
+            }
         }
+        
+        smb_ReleaseVC(vcp);
+
         /* unlock */
         lock_ReleaseMutex(&smb_ListenerLock);
-
     }  /* dispatch while loop */
 }
 
@@ -7636,7 +7961,7 @@ void smb_NetbiosInit()
         ncbp->ncb_length = sizeof(lana_list);
         code = Netbios(ncbp);
         if (code != 0) {
-            osi_Log1(smb_logp, "Netbios NCBENUM error code %d", code);
+            afsi_log("Netbios NCBENUM error code %d", code);
             osi_panic(s, __FILE__, __LINE__);
         }
     }
@@ -7657,10 +7982,10 @@ void smb_NetbiosInit()
         if (code == 0) 
             code = ncbp->ncb_retcode;
         if (code != 0) {
-            osi_Log2(smb_logp, "Netbios NCBRESET lana %d error code %d", lana_list.lana[i], code);
+            afsi_log("Netbios NCBRESET lana %d error code %d", lana_list.lana[i], code);
             lana_list.lana[i] = 255;  /* invalid lana */
         } else {
-            osi_Log1(smb_logp, "Netbios NCBRESET lana %d succeeded", lana_list.lana[i]);
+            afsi_log("Netbios NCBRESET lana %d succeeded", lana_list.lana[i]);
         }
     }
 #else
@@ -7682,7 +8007,7 @@ void smb_NetbiosInit()
     len=lstrlen(smb_localNamep);
     memset(smb_sharename,' ',NCBNAMSZ);
     memcpy(smb_sharename,smb_localNamep,len);
-    osi_Log1(smb_logp, "lana_list.length %d", lana_list.length);
+    afsi_log("lana_list.length %d", lana_list.length);
 
     /* Keep the name so we can unregister it later */
     for (l = 0; l < lana_list.length; l++) {
@@ -7697,18 +8022,18 @@ void smb_NetbiosInit()
         code = Netbios(ncbp, dos_ncb);
 #endif /* !DJGPP */
           
-        osi_Log4(smb_logp, "Netbios NCBADDNAME lana=%d code=%d retcode=%d complete=%d",
+        afsi_log("Netbios NCBADDNAME lana=%d code=%d retcode=%d complete=%d",
                  lana, code, ncbp->ncb_retcode, ncbp->ncb_cmd_cplt);
         {
             char name[NCBNAMSZ+1];
             name[NCBNAMSZ]=0;
             memcpy(name,ncbp->ncb_name,NCBNAMSZ);
-            osi_Log1(smb_logp, "Netbios NCBADDNAME added new name >%s<",osi_LogSaveString(smb_logp, name));
+            afsi_log("Netbios NCBADDNAME added new name >%s<",name);
         }
 
         if (code == 0) code = ncbp->ncb_retcode;
         if (code == 0) {
-            osi_Log1(smb_logp, "Netbios NCBADDNAME succeeded on lana %d\n", lana);
+            afsi_log("Netbios NCBADDNAME succeeded on lana %d\n", lana);
 #ifdef DJGPP
             /* we only use one LANA with djgpp */
             lana_list.lana[0] = lana;
@@ -7716,13 +8041,13 @@ void smb_NetbiosInit()
 #endif   
         }
         else {
-            osi_Log2(smb_logp, "Netbios NCBADDNAME lana %d error code %d", lana, code);
+            afsi_log("Netbios NCBADDNAME lana %d error code %d", lana, code);
             if (code == NRC_BRIDGE) {    /* invalid LANA num */
                 lana_list.lana[l] = 255;
                 continue;
             }
             else if (code == NRC_DUPNAME) {
-                osi_Log0(smb_logp, "Name already exists; try to delete it");
+                afsi_log("Name already exists; try to delete it");
                 memset(ncbp, 0, sizeof(*ncbp));
                 ncbp->ncb_command = NCBDELNAME;
                 memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ);
@@ -7735,7 +8060,7 @@ void smb_NetbiosInit()
                 if (code == 0) 
                     code = ncbp->ncb_retcode;
                 else {
-                    osi_Log2(smb_logp, "Netbios NCBDELNAME lana %d error code %d\n", lana, code);
+                    afsi_log("Netbios NCBDELNAME lana %d error code %d\n", lana, code);
                 }
                 if (code != 0 || delname_tried) {
                     lana_list.lana[l] = 255;
@@ -7749,7 +8074,7 @@ void smb_NetbiosInit()
                 }
             }
             else {
-                osi_Log2(smb_logp, "Netbios NCBADDNAME lana %d error code %d", lana, code);
+                afsi_log("Netbios NCBADDNAME lana %d error code %d", lana, code);
                 lana_list.lana[l] = 255;  /* invalid lana */
                 osi_panic(s, __FILE__, __LINE__);
             }
@@ -7808,9 +8133,10 @@ void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt,
     myTime.tm_sec = 0;
     smb_localZero = mktime(&myTime);
 
+#ifndef USE_NUMERIC_TIME_CONV
     /* Initialize kludge-GMT */
     smb_CalculateNowTZ();
-
+#endif /* USE_NUMERIC_TIME_CONV */
 #ifdef AFS_FREELANCE_CLIENT
     /* Make sure the root.afs volume has the correct time */
     cm_noteLocalMountPointChange();
@@ -8075,13 +8401,14 @@ void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt,
                                                     );
 
                 if (nts != STATUS_SUCCESS && ntsEx != STATUS_SUCCESS) {
-                    osi_Log2(smb_logp,"MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x",
-                              nts, ntsEx);
-                    OutputDebugString("MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x",
+                    char message[256];
+                    sprintf(message,"MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x",
                                        nts, ntsEx);
+                    OutputDebugString(message);
+                    afsi_log(message);
                 } else {
-                    osi_Log0(smb_logp,"MsV1_0SetProcessOption success");
                     OutputDebugString("MsV1_0SetProcessOption success");
+                    afsi_log("MsV1_0SetProcessOption success");
                 }
                 /* END - code from Larry */
 
@@ -8090,18 +8417,23 @@ void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt,
                 smb_lsaLogonOrigin.MaximumLength = smb_lsaLogonOrigin.Length + 1;
             } else {
                 afsi_log("Can't determine security package name for NTLM!! NTSTATUS=[%l]",nts);
+
+                /* something went wrong. We report the error and revert back to no authentication
+                because we can't perform any auth requests without a successful lsa handle
+                or sec package id. */
+                afsi_log("Reverting to NO SMB AUTH");
+                smb_authType = SMB_AUTH_NONE;
             }
         } else {
             afsi_log("Can't register logon process!! NTSTATUS=[%l]",nts);
-        }
 
-        if (nts != STATUS_SUCCESS) {
             /* something went wrong. We report the error and revert back to no authentication
             because we can't perform any auth requests without a successful lsa handle
             or sec package id. */
             afsi_log("Reverting to NO SMB AUTH");
             smb_authType = SMB_AUTH_NONE;
-        } 
+        }
+
 #ifdef COMMENT
         /* Don't fallback to SMB_AUTH_NTLM.  Apparently, allowing SPNEGO to be used each
          * time prevents the failure of authentication when logged into Windows with an