#define CM_IOCTLFLAG_DATAIN 1 /* reading data from client to server */
#define CM_IOCTLFLAG_LOGON 2 /* got tokens from integrated logon */
#define CM_IOCTLFLAG_USEUTF8 4 /* this request is using UTF-8 strings */
+#define CM_IOCTLFLAG_DATAOUT 8 /* sending data from server to client */
/*
smb_fid_t *fidp;
int newFid = 0;
- if (fid == 0 && !(flags & SMB_FLAG_CREATE))
- return NULL;
-
- lock_ObtainWrite(&smb_rctLock);
- /* figure out if we need to allocate a new file ID */
if (fid == 0) {
+ if (!(flags & SMB_FLAG_CREATE))
+ return NULL;
newFid = 1;
- fid = vcp->fidCounter;
}
+ lock_ObtainWrite(&smb_rctLock);
+ if (newFid)
+ fid = vcp->fidCounter;
retry:
+
for(fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q)) {
if (fidp->refCount == 0 && fidp->deleteOk) {
fidp->refCount++;
lock_ReleaseWrite(&smb_rctLock);
smb_ReleaseFID(fidp);
lock_ObtainWrite(&smb_rctLock);
+ /*
+ * We dropped the smb_rctLock so the fid value we are using
+ * may now be used by another thread. Start over with the
+ * current vcp->fidCounter.
+ */
+ if (newFid)
+ fid = vcp->fidCounter;
goto retry;
}
if (fid == fidp->fid) {
if (newFid) {
+ osi_Log1(smb_logp, "smb_FindFID New Fid Requested. fid %d found -- retrying ...", fid);
fid++;
if (fid == 0xFFFF) {
osi_Log1(smb_logp,
if (!fidp && (flags & SMB_FLAG_CREATE)) {
char eventName[MAX_PATH];
EVENT_HANDLE event;
+
+ if (!newFid)
+ osi_Log1(smb_logp, "smb_FindFID New Fid Not Requested, Fid %d Not Found and CREATE flag set.", fid);
+ else
+ osi_Log1(smb_logp, "smb_FindFID New Fid Requested. Creating fid %d", fid);
+
sprintf(eventName,"fid_t event vcp=%d fid=%d", vcp->vcID, fid);
event = thrd_CreateEvent(NULL, FALSE, TRUE, eventName);
if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
smbp = (smb_t *) inp;
osi_Log5(smb_logp,"Dispatch %s mid 0x%x vcp 0x%p lana %d lsn %d",
- opName, smbp->mid, vcp,vcp->lana,vcp->lsn);
+ opName, smbp->mid, vcp, vcp->lana, vcp->lsn);
if (inp->inCom == 0x1d) {
/* Raw Write */
code = smb_ReceiveCoreWriteRaw (vcp, inp, outp, rwcp);
code = (*(dp->procp)) (vcp, inp, outp);
}
osi_Log5(smb_logp,"Dispatch return code 0x%x mid 0x%x vcp 0x%p lana %d lsn %d",
- code, smbp->mid, vcp,vcp->lana,vcp->lsn);
+ code, smbp->mid, vcp, vcp->lana, vcp->lsn);
newTime = GetTickCount();
osi_Log3(smb_logp, "Dispatch %s mid 0x%x duration %d ms",
osi_Log0(smb_logp, "smb_ReceiveV3WriteX offset requires largefile support");
/* we shouldn't have received this op if we didn't specify
largefile support */
- return CM_ERROR_BADOP;
+ return CM_ERROR_INVAL;
}
#endif
}
if (ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAIN) {
ioctlp->ioctl.flags &= ~CM_IOCTLFLAG_DATAIN;
+ ioctlp->ioctl.flags |= CM_IOCTLFLAG_DATAOUT;
/* do the call now, or fail if we didn't get an opcode, or
* enough of an opcode.
memcpy(&opcode, ioctlp->ioctl.inDatap, sizeof(afs_int32));
ioctlp->ioctl.inDatap += sizeof(afs_int32);
- osi_Log1(afsd_logp, "Ioctl opcode 0x%x", opcode);
-
+ osi_Log1(afsd_logp, "smb_IoctlPrepareRead opcode 0x%x", opcode);
/* check for opcode out of bounds */
- if (opcode < 0 || opcode >= SMB_IOCTL_MAXPROCS)
+ if (opcode < 0 || opcode >= SMB_IOCTL_MAXPROCS) {
+ osi_Log0(afsd_logp, "smb_IoctlPrepareRead - invalid opcode");
return CM_ERROR_TOOBIG;
+ }
/* check for no such proc */
procp = smb_ioctlProcsp[opcode];
- if (procp == NULL)
- return CM_ERROR_BADOP;
-
+ if (procp == NULL) {
+ osi_Log0(afsd_logp, "smb_IoctlPrepareRead - unassigned opcode");
+ return CM_ERROR_INVAL;
+ }
/* otherwise, make the call */
ioctlp->ioctl.outDatap += sizeof(afs_int32); /* reserve room for return code */
code = (*procp)(ioctlp, userp);
-
- osi_Log1(afsd_logp, "Ioctl return code 0x%x", code);
+ osi_Log1(afsd_logp, "smb_IoctlPrepareRead operation returns code 0x%x", code);
/* copy in return code */
memcpy(ioctlp->ioctl.outAllocp, &code, sizeof(afs_int32));
+ } else if (!(ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAOUT)) {
+ osi_Log0(afsd_logp, "Ioctl invalid state - dataout expected");
+ return CM_ERROR_INVAL;
}
+
return 0;
}
ioctlp->ioctl.inDatap = ioctlp->ioctl.inAllocp;
ioctlp->ioctl.outDatap = ioctlp->ioctl.outAllocp;
ioctlp->ioctl.flags |= CM_IOCTLFLAG_DATAIN;
+ ioctlp->ioctl.flags &= ~CM_IOCTLFLAG_DATAOUT;
}
}
}
leftToCopy = (afs_int32)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
+ if (leftToCopy < 0) {
+ osi_Log0(afsd_logp, "smb_IoctlRead leftToCopy went negative");
+ cm_ReleaseUser(userp);
+ return CM_ERROR_INVAL;
+ }
if (count > leftToCopy)
count = leftToCopy;
smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
smb_ioctl_t *iop;
- long count;
+ unsigned short count;
afs_int32 code;
long leftToCopy;
char *op;
}
leftToCopy = (long)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
+ if (leftToCopy < 0) {
+ osi_Log0(afsd_logp, "smb_IoctlV3Read leftToCopy went negative");
+ cm_ReleaseUser(userp);
+ return CM_ERROR_INVAL;
+ }
if (count > leftToCopy)
- count = leftToCopy;
+ count = (unsigned short)leftToCopy;
/* 0 and 1 are reserved for request chaining, were setup by our caller,
* and will be further filled in after we return.
}
leftToCopy = (long)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
+ if (leftToCopy < 0) {
+ osi_Log0(afsd_logp, "smb_IoctlReadRaw leftToCopy went negative");
+ code = CM_ERROR_INVAL;
+ goto done;
+ }
ncbp = outp->ncbp;
memset((char *)ncbp, 0, sizeof(NCB));