void smb_InitIoctl(void)
{
+ int i;
+ for (i=0; i<SMB_IOCTL_MAXPROCS; i++)
+ smb_ioctlProcsp[i] = NULL;
+
smb_ioctlProcsp[VIOCGETAL] = cm_IoctlGetACL;
smb_ioctlProcsp[VIOC_FILE_CELL_NAME] = cm_IoctlGetFileCellName;
smb_ioctlProcsp[VIOCSETAL] = cm_IoctlSetACL;
#endif
smb_ioctlProcsp[VIOC_TRACEMEMDUMP] = cm_IoctlMemoryDump;
smb_ioctlProcsp[VIOC_ISSYMLINK] = cm_IoctlIslink;
+ smb_ioctlProcsp[VIOC_FLUSHALL] = cm_IoctlFlushAllVolumes;
+ smb_ioctlProcsp[VIOCGETFID] = cm_IoctlGetFid;
+ smb_ioctlProcsp[VIOCGETOWNER] = cm_IoctlGetOwner;
+ smb_ioctlProcsp[VIOC_RXSTAT_PROC] = cm_IoctlRxStatProcess;
+ smb_ioctlProcsp[VIOC_RXSTAT_PEER] = cm_IoctlRxStatPeer;
}
/* called to make a fid structure into an IOCTL fid structure */
void smb_SetupIoctlFid(smb_fid_t *fidp, cm_space_t *prefix)
{
- smb_ioctl_t *iop;
- cm_space_t *copyPrefix;
-
- lock_ObtainMutex(&fidp->mx);
- fidp->flags |= SMB_FID_IOCTL;
- fidp->scp = &cm_fakeSCache;
- if (fidp->ioctlp == NULL) {
- iop = malloc(sizeof(*iop));
- memset(iop, 0, sizeof(*iop));
- fidp->ioctlp = iop;
- iop->fidp = fidp;
- }
- if (prefix) {
- copyPrefix = cm_GetSpace();
- strcpy(copyPrefix->data, prefix->data);
- fidp->ioctlp->prefix = copyPrefix;
- }
- lock_ReleaseMutex(&fidp->mx);
+ smb_ioctl_t *iop;
+ cm_space_t *copyPrefix;
+
+ lock_ObtainMutex(&fidp->mx);
+ fidp->flags |= SMB_FID_IOCTL;
+ fidp->scp = &cm_data.fakeSCache;
+ cm_HoldSCache(fidp->scp);
+ if (fidp->ioctlp == NULL) {
+ iop = malloc(sizeof(*iop));
+ memset(iop, 0, sizeof(*iop));
+ fidp->ioctlp = iop;
+ iop->fidp = fidp;
+ }
+ if (prefix) {
+ copyPrefix = cm_GetSpace();
+ strcpy(copyPrefix->data, prefix->data);
+ fidp->ioctlp->prefix = copyPrefix;
+ }
+ lock_ReleaseMutex(&fidp->mx);
}
/* called when we receive a read call, does the send of the received data if
*/
smb_IoctlPrepareRead(smb_fid_t *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp)
{
- long opcode;
- smb_ioctlProc_t *procp;
- long code;
+ long opcode;
+ smb_ioctlProc_t *procp = NULL;
+ long code;
- if (ioctlp->flags & SMB_IOCTLFLAG_DATAIN) {
- ioctlp->flags &= ~SMB_IOCTLFLAG_DATAIN;
-
- /* do the call now, or fail if we didn't get an opcode, or
- * enough of an opcode.
- */
- if (ioctlp->inCopied < sizeof(long)) return CM_ERROR_INVAL;
- memcpy(&opcode, ioctlp->inDatap, sizeof(long));
- ioctlp->inDatap += sizeof(long);
-
- osi_Log1(afsd_logp, "Ioctl opcode %d", opcode);
-
- /* check for opcode out of bounds */
- if (opcode < 0 || opcode >= SMB_IOCTL_MAXPROCS)
- return CM_ERROR_TOOBIG;
-
- /* check for no such proc */
- procp = smb_ioctlProcsp[opcode];
- if (procp == NULL) return CM_ERROR_BADOP;
-
- /* otherwise, make the call */
- ioctlp->outDatap += sizeof(long); /* reserve room for return code */
- code = (*procp)(ioctlp, userp);
-
- osi_Log1(afsd_logp, "Ioctl return code %d", code);
-
- /* copy in return code */
- memcpy(ioctlp->outAllocp, &code, sizeof(long));
- }
- return 0;
+ if (ioctlp->flags & SMB_IOCTLFLAG_DATAIN) {
+ ioctlp->flags &= ~SMB_IOCTLFLAG_DATAIN;
+
+ /* do the call now, or fail if we didn't get an opcode, or
+ * enough of an opcode.
+ */
+ if (ioctlp->inCopied < sizeof(long))
+ return CM_ERROR_INVAL;
+ memcpy(&opcode, ioctlp->inDatap, sizeof(long));
+ ioctlp->inDatap += sizeof(long);
+
+ osi_Log1(afsd_logp, "Ioctl opcode 0x%x", opcode);
+
+ /* check for opcode out of bounds */
+ if (opcode < 0 || opcode >= SMB_IOCTL_MAXPROCS)
+ return CM_ERROR_TOOBIG;
+
+ /* check for no such proc */
+ if (fidp->flags & SMB_FID_IOCTL)
+ procp = smb_ioctlProcsp[opcode];
+ else
+ procp = NULL;
+
+ if (procp == NULL)
+ return CM_ERROR_BADOP;
+
+ /* otherwise, make the call */
+ ioctlp->outDatap += sizeof(long); /* reserve room for return code */
+ code = (*procp)(ioctlp, userp);
+
+ osi_Log1(afsd_logp, "Ioctl return code 0x%x", code);
+
+ /* copy in return code */
+ memcpy(ioctlp->outAllocp, &code, sizeof(long));
+ }
+ return 0;
}
/* called when we receive a write call. If this is the first write call after
iop = fidp->ioctlp;
count = smb_GetSMBParm(inp, 1);
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
/* Identify tree */
- iop->tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid);
+ code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
+ if(code) {
+ cm_ReleaseUser(userp);
+ return CM_ERROR_NOSUCHPATH;
+ }
/* turn the connection around, if required */
code = smb_IoctlPrepareRead(fidp, iop, userp);
return code;
}
- leftToCopy = (iop->outDatap - iop->outAllocp) - iop->outCopied;
+ leftToCopy = (long)((iop->outDatap - iop->outAllocp) - iop->outCopied);
if (count > leftToCopy) count = leftToCopy;
/* now set the parms for a read of count bytes */
op = smb_GetSMBData(outp, NULL);
*op++ = 1;
- *op++ = count & 0xff;
- *op++ = (count >> 8) & 0xff;
+ *op++ = (char)(count & 0xff);
+ *op++ = (char)((count >> 8) & 0xff);
/* now copy the data into the response packet */
memcpy(op, iop->outCopied + iop->outAllocp, count);
iop->outCopied += count;
cm_ReleaseUser(userp);
- smb_ReleaseFID(fidp);
return 0;
}
smb_SetSMBDataLength(outp, 0);
}
- smb_ReleaseFID(fidp);
return code;
}
-/* called from V3 read to handle IOCTL descriptor reads */
-long smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
+/* called from smb_ReceiveV3WriteX when we receive a write call on the IOCTL
+ * file descriptor.
+ */
+long smb_IoctlV3Write(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
smb_ioctl_t *iop;
long count;
long code;
- long leftToCopy;
char *op;
- cm_user_t *userp;
+ int inDataBlockCount;
+ code = 0;
+ count = smb_GetSMBParm(inp, 10);
iop = fidp->ioctlp;
- count = smb_GetSMBParm(inp, 5);
-
- userp = smb_GetUser(vcp, inp);
-
- {
- smb_user_t *uidp;
-
- uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
- if (uidp && uidp->unp)
- osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
- uidp->userID, userp,
- osi_LogSaveString(afsd_logp, uidp->unp->name));
- else {
- if (uidp)
- osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
- uidp->userID, userp);
- else
- osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
- userp);
- }
- smb_ReleaseUID(uidp);
- }
+
+ smb_IoctlPrepareWrite(fidp, iop);
- iop->tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid);
+ op = inp->data + smb_GetSMBParm(inp, 11);
+ inDataBlockCount = count;
+
+ if (count + iop->inCopied > SMB_IOCTL_MAXDATA) {
+ code = CM_ERROR_TOOBIG;
+ goto done;
+ }
+
+ /* copy data */
+ memcpy(iop->inDatap + iop->inCopied, op, count);
+
+ /* adjust counts */
+ iop->inCopied += count;
- code = smb_IoctlPrepareRead(fidp, iop, userp);
- if (code) {
- cm_ReleaseUser(userp);
- smb_ReleaseFID(fidp);
- return code;
+done:
+ /* return # of bytes written */
+ if (code == 0) {
+ smb_SetSMBParm(outp, 2, count);
+ smb_SetSMBParm(outp, 3, 0); /* reserved */
+ smb_SetSMBParm(outp, 4, 0); /* reserved */
+ smb_SetSMBParm(outp, 5, 0); /* reserved */
+ smb_SetSMBDataLength(outp, 0);
}
- leftToCopy = (iop->outDatap - iop->outAllocp) - iop->outCopied;
- if (count > leftToCopy) count = leftToCopy;
+ return code;
+}
+
+
+/* called from V3 read to handle IOCTL descriptor reads */
+long smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
+{
+ smb_ioctl_t *iop;
+ long count;
+ long code;
+ long leftToCopy;
+ char *op;
+ cm_user_t *userp;
+ smb_user_t *uidp;
+
+ iop = fidp->ioctlp;
+ count = smb_GetSMBParm(inp, 5);
+
+ uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
+ userp = smb_GetUserFromUID(uidp);
+ osi_assert(userp != 0);
+ iop->uidp = uidp;
+ if (uidp && uidp->unp) {
+ osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
+ uidp->userID, userp,
+ osi_LogSaveString(afsd_logp, uidp->unp->name));
+ } else {
+ if (uidp)
+ osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
+ uidp->userID, userp);
+ else
+ osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
+ userp);
+ }
+
+ code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
+ if (code) {
+ if (uidp)
+ smb_ReleaseUID(uidp);
+ cm_ReleaseUser(userp);
+ return CM_ERROR_NOSUCHPATH;
+ }
+
+ code = smb_IoctlPrepareRead(fidp, iop, userp);
+ if (uidp) {
+ iop->uidp = 0;
+ smb_ReleaseUID(uidp);
+ }
+ if (code) {
+ cm_ReleaseUser(userp);
+ return code;
+ }
+
+ leftToCopy = (long)((iop->outDatap - iop->outAllocp) - iop->outCopied);
+ if (count > leftToCopy) count = leftToCopy;
- /* 0 and 1 are reserved for request chaining, were setup by our caller,
- * and will be further filled in after we return.
- */
- smb_SetSMBParm(outp, 2, 0); /* remaining bytes, for pipes */
- smb_SetSMBParm(outp, 3, 0); /* resvd */
- smb_SetSMBParm(outp, 4, 0); /* resvd */
- smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */
- /* fill in #6 when we have all the parameters' space reserved */
- smb_SetSMBParm(outp, 7, 0); /* resv'd */
- smb_SetSMBParm(outp, 8, 0); /* resv'd */
- smb_SetSMBParm(outp, 9, 0); /* resv'd */
- smb_SetSMBParm(outp, 10, 0); /* resv'd */
- smb_SetSMBParm(outp, 11, 0); /* reserved */
-
- /* get op ptr after putting in the last parm, since otherwise we don't
- * know where the data really is.
- */
- op = smb_GetSMBData(outp, NULL);
+ /* 0 and 1 are reserved for request chaining, were setup by our caller,
+ * and will be further filled in after we return.
+ */
+ smb_SetSMBParm(outp, 2, 0); /* remaining bytes, for pipes */
+ smb_SetSMBParm(outp, 3, 0); /* resvd */
+ smb_SetSMBParm(outp, 4, 0); /* resvd */
+ smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */
+ /* fill in #6 when we have all the parameters' space reserved */
+ smb_SetSMBParm(outp, 7, 0); /* resv'd */
+ smb_SetSMBParm(outp, 8, 0); /* resv'd */
+ smb_SetSMBParm(outp, 9, 0); /* resv'd */
+ smb_SetSMBParm(outp, 10, 0); /* resv'd */
+ smb_SetSMBParm(outp, 11, 0); /* reserved */
+
+ /* get op ptr after putting in the last parm, since otherwise we don't
+ * know where the data really is.
+ */
+ op = smb_GetSMBData(outp, NULL);
- /* now fill in offset from start of SMB header to first data byte (to op) */
- smb_SetSMBParm(outp, 6, ((int) (op - outp->data)));
+ /* now fill in offset from start of SMB header to first data byte (to op) */
+ smb_SetSMBParm(outp, 6, ((int) (op - outp->data)));
- /* set the packet data length the count of the # of bytes */
- smb_SetSMBDataLength(outp, count);
+ /* set the packet data length the count of the # of bytes */
+ smb_SetSMBDataLength(outp, count);
- /* now copy the data into the response packet */
- memcpy(op, iop->outCopied + iop->outAllocp, count);
+ /* now copy the data into the response packet */
+ memcpy(op, iop->outCopied + iop->outAllocp, count);
- /* and adjust the counters */
- iop->outCopied += count;
-
- /* and cleanup things */
- cm_ReleaseUser(userp);
- smb_ReleaseFID(fidp);
+ /* and adjust the counters */
+ iop->outCopied += count;
- return 0;
-}
+ /* and cleanup things */
+ cm_ReleaseUser(userp);
+
+ return 0;
+}
/* called from Read Raw to handle IOCTL descriptor reads */
long smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
- smb_packet_t *outp
+ smb_packet_t *outp
#ifdef DJGPP
-, dos_ptr rawBuf
+ , dos_ptr rawBuf
#endif /* DJGPP */
-)
+ )
{
- smb_ioctl_t *iop;
- long leftToCopy;
- NCB *ncbp;
- long code;
- cm_user_t *userp;
+ smb_ioctl_t *iop;
+ long leftToCopy;
+ NCB *ncbp;
+ long code;
+ cm_user_t *userp;
#ifdef DJGPP
- dos_ptr dos_ncb;
+ dos_ptr dos_ncb;
- if (rawBuf == 0)
- {
- osi_Log0(afsd_logp, "Failed to get raw buf for smb_IoctlReadRaw");
- return -1;
- }
+ if (rawBuf == 0)
+ {
+ osi_Log0(afsd_logp, "Failed to get raw buf for smb_IoctlReadRaw");
+ return -1;
+ }
#endif /* DJGPP */
- iop = fidp->ioctlp;
-
- userp = smb_GetUser(vcp, inp);
-
- {
- smb_user_t *uidp;
-
- uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
- if (uidp && uidp->unp)
- osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
- uidp->userID, userp,
- osi_LogSaveString(afsd_logp, uidp->unp->name));
- else
- osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
- uidp->userID, userp);
- smb_ReleaseUID(uidp);
+ iop = fidp->ioctlp;
+
+ userp = smb_GetUserFromVCP(vcp, inp);
+
+ /* Log the user */
+ {
+ smb_user_t *uidp;
+
+ uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
+ if (uidp && uidp->unp) {
+ osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
+ uidp->userID, userp,
+ osi_LogSaveString(afsd_logp, uidp->unp->name));
+ } else if (uidp) {
+ osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
+ uidp->userID, userp);
+ } else {
+ osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
+ userp);
}
+ if (uidp)
+ smb_ReleaseUID(uidp);
+ }
- iop->tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid);
+ code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
+ if (code) {
+ cm_ReleaseUser(userp);
+ return CM_ERROR_NOSUCHPATH;
+ }
- code = smb_IoctlPrepareRead(fidp, iop, userp);
- if (code) {
- cm_ReleaseUser(userp);
- smb_ReleaseFID(fidp);
- return code;
- }
+ code = smb_IoctlPrepareRead(fidp, iop, userp);
+ if (code) {
+ cm_ReleaseUser(userp);
+ return code;
+ }
- leftToCopy = (iop->outDatap - iop->outAllocp) - iop->outCopied;
+ leftToCopy = (long)((iop->outDatap - iop->outAllocp) - iop->outCopied);
- ncbp = outp->ncbp;
- memset((char *)ncbp, 0, sizeof(NCB));
+ ncbp = outp->ncbp;
+ memset((char *)ncbp, 0, sizeof(NCB));
- ncbp->ncb_length = (unsigned short) leftToCopy;
- ncbp->ncb_lsn = (unsigned char) vcp->lsn;
- ncbp->ncb_command = NCBSEND;
+ ncbp->ncb_length = (unsigned short) leftToCopy;
+ ncbp->ncb_lsn = (unsigned char) vcp->lsn;
+ ncbp->ncb_command = NCBSEND;
/*ncbp->ncb_lana_num = smb_LANadapter;*/
- ncbp->ncb_lana_num = vcp->lana;
+ ncbp->ncb_lana_num = vcp->lana;
#ifndef DJGPP
- ncbp->ncb_buffer = iop->outCopied + iop->outAllocp;
- code = Netbios(ncbp);
+ ncbp->ncb_buffer = iop->outCopied + iop->outAllocp;
+ code = Netbios(ncbp);
#else /* DJGPP */
- dosmemput(iop->outCopied + iop->outAllocp, ncbp->ncb_length, rawBuf);
- ncbp->ncb_buffer = rawBuf;
- dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
- code = Netbios(ncbp, dos_ncb);
+ dosmemput(iop->outCopied + iop->outAllocp, ncbp->ncb_length, rawBuf);
+ ncbp->ncb_buffer = rawBuf;
+ dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
+ code = Netbios(ncbp, dos_ncb);
#endif /* !DJGPP */
- if (code != 0)
- osi_Log1(afsd_logp, "ReadRaw send failure code %d", code);
+ if (code != 0)
+ osi_Log1(afsd_logp, "ReadRaw send failure code %d", code);
- cm_ReleaseUser(userp);
- smb_ReleaseFID(fidp);
+ cm_ReleaseUser(userp);
- return 0;
+ return 0;
}