smb_ioctlProcsp[VIOC_GETFILETYPE] = smb_IoctlGetFileType;
smb_ioctlProcsp[VIOC_VOLSTAT_TEST] = smb_IoctlVolStatTest;
smb_ioctlProcsp[VIOC_UNICODECTL] = smb_IoctlUnicodeControl;
+ smb_ioctlProcsp[VIOC_SETOWNER] = smb_IoctlSetOwner;
+ smb_ioctlProcsp[VIOC_SETGROUP] = smb_IoctlSetGroup;
+ smb_ioctlProcsp[VIOCNEWCELL2] = smb_IoctlNewCell2;
}
/* called to make a fid structure into an IOCTL fid structure */
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;
count = smb_GetSMBParm(inp, 5);
uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
+ if (!uidp)
+ return CM_ERROR_BADSMB;
userp = smb_GetUserFromUID(uidp);
osi_assertx(userp != NULL, "null cm_user_t");
iop->uidp = uidp;
}
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));
+ memset(ncbp, 0, sizeof(NCB));
ncbp->ncb_length = (unsigned short) leftToCopy;
ncbp->ncb_lsn = (unsigned char) vcp->lsn;
ioctlp->ioctl.flags |= CM_IOCTLFLAG_LOGON;
}
- cm_ResetACLCache(userp);
+ cm_ResetACLCache(cellp, userp);
done:
if (release_userp)
int cch;
cch = cm_ClientStringToUtf8(uidp->unp->name,
- cm_ClientStrLen(uidp->unp->name),
-
+ -1,
ioctlp->ioctl.outDatap,
(SMB_IOCTL_MAXDATA -
(ioctlp->ioctl.outDatap - ioctlp->ioctl.outAllocp))
} else {
code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
}
+
if (code)
return code;
}
afs_int32
+smb_IoctlNewCell2(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlNewCell2(&ioctlp->ioctl, userp);
+}
+
+afs_int32
smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
return cm_IoctlVolStatTest(&ioctlp->ioctl, userp, &req);
}
+
+/*
+ * VIOC_SETOWNER
+ *
+ * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
+ *
+ */
+afs_int32
+smb_IoctlSetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ smb_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp) {
+ if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
+ }
+
+ code = cm_IoctlSetOwner(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+
+/*
+ * VIOC_GETOWNER
+ *
+ * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
+ *
+ */
+afs_int32
+smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ smb_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp) {
+ if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
+ }
+
+ code = cm_IoctlSetGroup(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+
+
+