#include <time.h>
#include <osi.h>
+#include <rx\rx.h>
+#include <rx/rx_prototypes.h>
#include "afsd.h"
#include <WINNT\afsreg.h>
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:
*/
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;
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,
#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 */
*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.
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;
SystemTimeToFileTime(&stm, largeTimep);
}
+#endif /* USE_NUMERIC_TIME_CONV */
#else /* DJGPP */
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;
*unixTimep = mktime(<);
_timezone = save_timezone;
}
+#endif /* USE_NUMERIC_TIME_CONV */
#else /* DJGPP */
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;
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;
*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;
}
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;
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.
*/
break;
}
}
+
if (!fidp && (flags & SMB_FLAG_CREATE)) {
char eventName[MAX_PATH];
EVENT_HANDLE event;
vcp->fidCounter = 1;
}
}
+
lock_ReleaseWrite(&smb_rctLock);
return fidp;
}
/* 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);
}
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)
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;
}
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);
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 */
}
else if (code == CM_ERROR_READONLY) {
NTStatus = 0xC00000A2L; /* Write protected */
- }
+ }
else if (code == CM_ERROR_NOSUCHFILE) {
NTStatus = 0xC000000FL; /* No such file */
}
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 */
}
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 */
}
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 */
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;
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 */
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",
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();
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;
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;
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();
/* 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 */
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);
}
}
long code = 0;
cm_scache_t *scp;
char *dptr;
- time_t dosTime;
+ afs_uint32 dosTime;
u_short shortTemp;
char attr;
smb_dirListPatch_t *patchp;
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;
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;
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;
else
code = CM_ERROR_EXISTS;
cm_ReleaseSCache(tmpscp2);
- tmpscp2 = NULL;
+ tmpscp2 = NULL;
} else {
code = CM_ERROR_NOSUCHFILE;
}
unsigned short fid;
smb_fid_t *fidp;
cm_user_t *userp;
- long dosTime;
+ afs_uint32 dosTime;
long code = 0;
cm_req_t req;
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;
}
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,
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;
/* 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;
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;
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;
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
*
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);
osi_hyper_t offset;
long count, finalCount;
unsigned short fd;
+ unsigned pid;
smb_fid_t *fidp;
long code = 0;
cm_user_t *userp;
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);
int attributes;
char *lastNamep;
int caseFold;
- long dosTime;
+ afs_uint32 dosTime;
char *tidPathp;
cm_req_t req;
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 )
dos_ptr dos_ncb;
#endif /* DJGPP */
+ rx_StartClientThread();
+
outncbp = GetNCB();
outbufp = GetPacket();
outbufp->ncbp = outncbp;
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);
}
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);
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);
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);
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:
* 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;
}
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 */
}
}
- /* 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 */
}
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__);
}
}
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
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++) {
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;
#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);
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;
}
}
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__);
}
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();
);
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 */
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