#include <WINNT\afsreg.h>
#include "smb.h"
+#include "msrpc.h"
#include <strsafe.h>
extern osi_hyper_t hzero;
cm_req_t req;
int created = 0;
BOOL is_rpc = FALSE;
+ BOOL is_ipc = FALSE;
smb_InitReq(&req);
outp = smb_GetTran2ResponsePacket(vcp, p, op, 40, 0);
+ code = smb_LookupTIDPath(vcp, p->tid, &tidPathp);
+ if (code == CM_ERROR_TIDIPC) {
+ is_ipc = TRUE;
+ osi_Log0(smb_logp, "Tran2Open received IPC TID");
+ }
+
spacep = cm_GetSpace();
+ /* smb_StripLastComponent will strip "::$DATA" if present */
smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
- /* The 'is_rpc' assignment to TRUE is intentional */
- if (lastNamep &&
+ if (lastNamep &&
+
+ /* special case magic file name for receiving IOCTL requests
+ * (since IOCTL calls themselves aren't getting through).
+ */
(cm_ClientStrCmpI(lastNamep, _C(SMB_IOCTL_FILENAME)) == 0 ||
- ((cm_ClientStrCmpI(lastNamep, _C("\\srvsvc")) == 0 ||
- cm_ClientStrCmpI(lastNamep, _C("\\wkssvc")) == 0 ||
- cm_ClientStrCmpI(lastNamep, _C("\\spoolss")) == 0 ||
- cm_ClientStrCmpI(lastNamep, _C("\\winreg")) == 0 ||
- cm_ClientStrCmpI(lastNamep, _C("\\ipc$")) == 0) && (is_rpc = TRUE)))) {
+
+ /* Or an RPC endpoint (is_rpc = TRUE assignment is intentional)*/
+ (is_ipc && MSRPC_IsWellKnownService(lastNamep) && (is_rpc = TRUE)))) {
unsigned short file_type = 0;
unsigned short device_state = 0;
- /* special case magic file name for receiving IOCTL requests
- * (since IOCTL calls themselves aren't getting through).
- */
fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
if (is_rpc) {
code = smb_SetupRPCFid(fidp, lastNamep, &file_type, &device_state);
osi_Log2(smb_logp, "smb_ReceiveTran2Open Creating RPC Fid [%d] code [%d]",
fidp->fid, code);
+ if (code) {
+ smb_ReleaseFID(fidp);
+ smb_FreeTran2Packet(outp);
+ osi_Log1(smb_logp, "smb_SetupRPCFid() failure code [%d]", code);
+ return code;
+ }
} else {
smb_SetupIoctlFid(fidp, spacep);
osi_Log1(smb_logp, "smb_ReceiveTran2Open Creating IOCTL Fid [%d]", fidp->fid);
return 0;
}
+#ifndef DFS_SUPPORT
+ if (is_ipc) {
+ osi_Log0(smb_logp, "Tran2Open rejecting IPC TID");
+ smb_FreeTran2Packet(outp);
+ return CM_ERROR_BADFD;
+ }
+#endif
+
if (!cm_IsValidClientString(pathp)) {
#ifdef DEBUG
clientchar_t * hexp;
return CM_ERROR_BADSMB;
}
- code = smb_LookupTIDPath(vcp, p->tid, &tidPathp);
- if (code == CM_ERROR_TIDIPC) {
- /* Attempt to use a TID allocated for IPC. The client
- * is probably looking for DCE RPC end points which we
- * don't support OR it could be looking to make a DFS
- * referral request.
- */
- osi_Log0(smb_logp, "Tran2Open received IPC TID");
-#ifndef DFS_SUPPORT
- cm_ReleaseUser(userp);
- smb_FreeTran2Packet(outp);
- return CM_ERROR_NOSUCHPATH;
-#endif
- }
-
dscp = NULL;
code = cm_NameI(cm_data.rootSCachep, pathp,
CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
return code;
}
} else {
+ /* macintosh is expensive to program for it */
+ cm_FreeSpace(spacep);
+
#ifdef DFS_SUPPORT
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, lastNamep);
return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
-
- /* macintosh is expensive to program for it */
- cm_FreeSpace(spacep);
}
/* if we get here, if code is 0, the file exists and is represented by
osi_assertx(dscp != NULL && scp == NULL, "null dsc || non-null sc");
openAction = 2; /* created file */
setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
- smb_UnixTimeFromSearchTime(&setAttr.clientModTime, dosTime);
+ cm_UnixTimeFromSearchTime(&setAttr.clientModTime, dosTime);
code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp,
&req);
if (code == 0) {
lock_ObtainRead(&scp->rw);
if (extraInfo) {
outp->parmsp[parmSlot++] = smb_Attributes(scp);
- smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
+ cm_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
outp->parmsp[parmSlot++] = (unsigned short)(dosTime & 0xffff);
outp->parmsp[parmSlot++] = (unsigned short)((dosTime>>16) & 0xffff);
outp->parmsp[parmSlot++] = (unsigned short) (scp->length.LowPart & 0xffff);
osi_hyper_t thyper;
spacep = cm_GetSpace();
+ /* smb_StripLastComponent will strip "::$DATA" if present */
smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
code = cm_NameI(cm_data.rootSCachep, spacep->wdata,
responseSize = sizeof(qpi.u.QPfileAllInfo);
else if (infoLevel == SMB_QUERY_FILE_ALT_NAME_INFO)
responseSize = sizeof(qpi.u.QPfileAltNameInfo);
+ else if (infoLevel == SMB_QUERY_FILE_STREAM_INFO)
+ responseSize = sizeof(qpi.u.QPfileStreamInfo);
else {
- osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
+ osi_Log2(smb_logp, "Bad Tran2QPathInfo op 0x%x infolevel 0x%x",
p->opcode, infoLevel);
smb_SendTran2Error(vcp, p, opx, CM_ERROR_BAD_LEVEL);
return 0;
}
+ memset(&qpi, 0, sizeof(qpi));
pathp = smb_ParseStringT2Parm(p, (char *) (&p->parmsp[3]), NULL, SMB_STRF_ANSIPATH);
osi_Log2(smb_logp, "T2 QPathInfo type 0x%x path %S", infoLevel,
outp->totalParms = 2;
else
outp->totalParms = 0;
- outp->totalData = responseSize;
/* now, if we're at infoLevel 6, we're only being asked to check
* the syntax, so we just OK things now. In particular, we're *not*
*/
if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) {
spacep = cm_GetSpace();
+ /* smb_StripLastComponent will strip "::$DATA" if present */
smb_StripLastComponent(spacep->wdata, &lastComp, pathp);
#ifndef SPECIAL_FOLDERS
/* Make sure that lastComp is not NULL */
smb_UnparseString(opx, qpi.u.QPfileAltNameInfo.fileName, shortName, &len, SMB_STRF_IGNORENUL);
qpi.u.QPfileAltNameInfo.fileNameLength = len;
-
- goto done;
+ responseSize = sizeof(unsigned long) + len;
}
else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) {
smb_UnparseString(opx, qpi.u.QPfileNameInfo.fileName, lastComp, &len, SMB_STRF_IGNORENUL);
qpi.u.QPfileNameInfo.fileNameLength = len;
-
- goto done;
+ responseSize = sizeof(unsigned long) + len;
}
else if (infoLevel == SMB_INFO_STANDARD || infoLevel == SMB_INFO_QUERY_EA_SIZE) {
- smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
+ cm_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
qpi.u.QPstandardInfo.creationDateTime = dosTime;
qpi.u.QPstandardInfo.lastAccessDateTime = dosTime;
qpi.u.QPstandardInfo.lastWriteDateTime = dosTime;
qpi.u.QPstandardInfo.eaSize = 0;
}
else if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) {
- smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
+ cm_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
qpi.u.QPfileBasicInfo.creationTime = ft;
qpi.u.QPfileBasicInfo.lastAccessTime = ft;
qpi.u.QPfileBasicInfo.lastWriteTime = ft;
qpi.u.QPfileEaInfo.eaSize = 0;
}
else if (infoLevel == SMB_QUERY_FILE_ALL_INFO) {
- smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
+ smb_fid_t * fidp;
+
+ lock_ReleaseRead(&scp->rw);
+ scp_rw_held = 0;
+ fidp = smb_FindFIDByScache(vcp, scp);
+
+ cm_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
qpi.u.QPfileAllInfo.creationTime = ft;
qpi.u.QPfileAllInfo.lastAccessTime = ft;
qpi.u.QPfileAllInfo.lastWriteTime = ft;
((scp->fileType == CM_SCACHETYPE_DIRECTORY ||
scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0);
- qpi.u.QPfileAllInfo.indexNumber.HighPart = scp->fid.cell;
- qpi.u.QPfileAllInfo.indexNumber.LowPart = scp->fid.volume;
+ qpi.u.QPfileAllInfo.indexNumber.HighPart = scp->fid.vnode;
+ qpi.u.QPfileAllInfo.indexNumber.LowPart = scp->fid.unique;
qpi.u.QPfileAllInfo.eaSize = 0;
- qpi.u.QPfileAllInfo.accessFlags = 0;
- qpi.u.QPfileAllInfo.indexNumber2.HighPart = scp->fid.vnode;
- qpi.u.QPfileAllInfo.indexNumber2.LowPart = scp->fid.unique;
+ qpi.u.QPfileAllInfo.accessFlags = 0;
+ if (fidp) {
+ lock_ObtainMutex(&fidp->mx);
+ if (fidp->flags & SMB_FID_OPENDELETE)
+ qpi.u.QPfileAllInfo.accessFlags |= DELETE;
+ if (fidp->flags & SMB_FID_OPENREAD_LISTDIR)
+ qpi.u.QPfileAllInfo.accessFlags |= AFS_ACCESS_READ|AFS_ACCESS_EXECUTE;
+ if (fidp->flags & SMB_FID_OPENWRITE)
+ qpi.u.QPfileAllInfo.accessFlags |= AFS_ACCESS_WRITE;
+ if (fidp->flags & SMB_FID_DELONCLOSE)
+ qpi.u.QPfileAllInfo.deletePending = 1;
+ lock_ReleaseMutex(&fidp->mx);
+ smb_ReleaseFID(fidp);
+ }
+ qpi.u.QPfileAllInfo.indexNumber2.HighPart = scp->fid.cell;
+ qpi.u.QPfileAllInfo.indexNumber2.LowPart = scp->fid.volume;
qpi.u.QPfileAllInfo.currentByteOffset.HighPart = 0;
qpi.u.QPfileAllInfo.currentByteOffset.LowPart = 0;
qpi.u.QPfileAllInfo.mode = 0;
smb_UnparseString(opx, qpi.u.QPfileAllInfo.fileName, lastComp, &len, SMB_STRF_IGNORENUL);
qpi.u.QPfileAllInfo.fileNameLength = len;
+ responseSize -= (sizeof(qpi.u.QPfileAllInfo.fileName) - len);
+ }
+ else if (infoLevel == SMB_QUERY_FILE_STREAM_INFO) {
+ size_t len = 0;
+ /* For now we have no streams */
+ qpi.u.QPfileStreamInfo.nextEntryOffset = 0;
+ qpi.u.QPfileStreamInfo.streamSize = scp->length;
+ qpi.u.QPfileStreamInfo.streamAllocationSize = scp->length;
+ smb_UnparseString(opx, qpi.u.QPfileStreamInfo.fileName, L"::$DATA", &len, SMB_STRF_IGNORENUL);
+ qpi.u.QPfileStreamInfo.streamNameLength = len;
+ responseSize -= (sizeof(qpi.u.QPfileStreamInfo.fileName) - len);
}
+ outp->totalData = responseSize;
/* send and free the packets */
done:
if (infoLevel != SMB_INFO_STANDARD &&
infoLevel != SMB_INFO_QUERY_EA_SIZE &&
infoLevel != SMB_INFO_QUERY_ALL_EAS) {
- osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
+ osi_Log2(smb_logp, "Bad Tran2SetPathInfo op 0x%x infolevel 0x%x",
p->opcode, infoLevel);
smb_SendTran2Error(vcp, p, opx,
infoLevel == SMB_INFO_QUERY_ALL_EAS ? CM_ERROR_EAS_NOT_SUPPORTED : CM_ERROR_BAD_LEVEL);
*/
if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) {
spacep = cm_GetSpace();
+ /* smb_StripLastComponent will strip "::$DATA" if present */
smb_StripLastComponent(spacep->wdata, &lastComp, pathp);
#ifndef SPECIAL_FOLDERS
/* Make sure that lastComp is not NULL */
attr.length.HighPart = 0;
if (spi->u.QPstandardInfo.lastWriteDateTime != 0) {
- smb_UnixTimeFromSearchTime(&attr.clientModTime, spi->u.QPstandardInfo.lastWriteDateTime);
+ cm_UnixTimeFromSearchTime(&attr.clientModTime, spi->u.QPstandardInfo.lastWriteDateTime);
attr.mask |= CM_ATTRMASK_CLIENTMODTIME;
}
responseSize = sizeof(qfi.u.QFeaInfo);
else if (infoLevel == SMB_QUERY_FILE_NAME_INFO)
responseSize = sizeof(qfi.u.QFfileNameInfo);
+ else if (infoLevel == SMB_QUERY_FILE_STREAM_INFO)
+ responseSize = sizeof(qfi.u.QFfileStreamInfo);
else {
- osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
+ osi_Log2(smb_logp, "Bad Tran2QFileInfo op 0x%x infolevel 0x%x",
p->opcode, infoLevel);
smb_SendTran2Error(vcp, p, opx, CM_ERROR_BAD_LEVEL);
smb_ReleaseFID(fidp);
return 0;
}
osi_Log2(smb_logp, "T2 QFileInfo type 0x%x fid %d", infoLevel, fid);
+ memset(&qfi, 0, sizeof(qfi));
outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, responseSize);
outp->totalParms = 2;
else
outp->totalParms = 0;
- outp->totalData = responseSize;
userp = smb_GetTran2User(vcp, p);
if (!userp) {
* Marshall the output data.
*/
if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) {
- smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
+ cm_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
qfi.u.QFbasicInfo.creationTime = ft;
qfi.u.QFbasicInfo.lastAccessTime = ft;
qfi.u.QFbasicInfo.lastWriteTime = ft;
lock_ReleaseMutex(&fidp->mx);
smb_UnparseString(opx, qfi.u.QFfileNameInfo.fileName, name, &len, SMB_STRF_IGNORENUL);
- outp->totalData = len + 4; /* this is actually what we want to return */
+ responseSize = len + 4; /* this is actually what we want to return */
qfi.u.QFfileNameInfo.fileNameLength = len;
}
+ else if (infoLevel == SMB_QUERY_FILE_STREAM_INFO) {
+ size_t len = 0;
+ /* For now we have no streams */
+ qfi.u.QFfileStreamInfo.nextEntryOffset = 0;
+ qfi.u.QFfileStreamInfo.streamSize = scp->length;
+ qfi.u.QFfileStreamInfo.streamAllocationSize = scp->length;
+ smb_UnparseString(opx, qfi.u.QFfileStreamInfo.fileName, L"::$DATA", &len, SMB_STRF_IGNORENUL);
+ qfi.u.QFfileStreamInfo.streamNameLength = len;
+ responseSize -= (sizeof(qfi.u.QFfileStreamInfo.fileName) - len);
+ }
+ outp->totalData = responseSize;
/* send and free the packets */
done:
infoLevel = p->parmsp[1];
osi_Log2(smb_logp,"ReceiveTran2SetFileInfo type 0x%x fid %d", infoLevel, fid);
if (infoLevel > SMB_SET_FILE_END_OF_FILE_INFO || infoLevel < SMB_SET_FILE_BASIC_INFO) {
- osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
+ osi_Log2(smb_logp, "Bad Tran2SetFileInfo op 0x%x infolevel 0x%x",
p->opcode, infoLevel);
smb_SendTran2Error(vcp, p, opx, CM_ERROR_BAD_LEVEL);
smb_ReleaseFID(fidp);
if (LargeIntegerNotEqualToZero(*((LARGE_INTEGER *)&lastMod)) &&
lastMod.dwLowDateTime != -1 && lastMod.dwHighDateTime != -1) {
attr.mask |= CM_ATTRMASK_CLIENTMODTIME;
- smb_UnixTimeFromLargeSearchTime(&attr.clientModTime, &lastMod);
+ cm_UnixTimeFromLargeSearchTime(&attr.clientModTime, &lastMod);
fidp->flags |= SMB_FID_MTIMESETDONE;
}
cm_ReleaseSCache(scp);
scp = 0;
}
+ /* smb_StripLastComponent will strip "::$DATA" if present */
smb_StripLastComponent(pathName, &lastComponent, temp);
code = cm_NameI(cm_data.rootSCachep, pathName,
smb_V3FileAttrsLong * fa = (smb_V3FileAttrsLong *) patchp->dptr;
/* get filetime */
- smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
+ cm_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
fa->creationTime = ft;
fa->lastAccessTime = ft;
smb_V3FileAttrsShort * fa = (smb_V3FileAttrsShort *) patchp->dptr;
/* get dos time */
- smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
+ cm_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
fa->creationDateTime = MAKELONG(HIWORD(dosTime), LOWORD(dosTime));
fa->lastAccessDateTime = fa->creationDateTime;
/* try to get the vnode for the path name next */
spacep = cm_GetSpace();
+ /* smb_StripLastComponent will strip "::$DATA" if present */
smb_StripLastComponent(spacep->wdata, NULL, pathp);
code = smb_LookupTIDPath(vcp, p->tid, &tidPathp);
if (code) {
code = 0;
} else {
spacep = cm_GetSpace();
+ /* smb_StripLastComponent will strip "::$DATA" if present */
smb_StripLastComponent(spacep->wdata, NULL, pathp);
code = smb_LookupTIDPath(vcp, p->tid, &tidPathp);
if (code) {
cm_req_t req;
int created = 0;
BOOL is_rpc = FALSE;
+ BOOL is_ipc = FALSE;
smb_InitReq(&req);
if (!pathp)
return CM_ERROR_BADSMB;
+ code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
+ if (code) {
+ if (code == CM_ERROR_TIDIPC) {
+ is_ipc = TRUE;
+ } else {
+ return CM_ERROR_NOSUCHPATH;
+ }
+ }
+
spacep = inp->spacep;
+ /* smb_StripLastComponent will strip "::$DATA" if present */
smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
- /* The 'is_rpc' assignment to TRUE is intentional */
if (lastNamep &&
- (cm_ClientStrCmpIA(lastNamep, _C(SMB_IOCTL_FILENAME)) == 0 ||
- ((cm_ClientStrCmpIA(lastNamep, _C("\\srvsvc")) == 0 ||
- cm_ClientStrCmpIA(lastNamep, _C("\\wkssvc")) == 0 ||
- cm_ClientStrCmpIA(lastNamep, _C("\\spoolss")) == 0 ||
- cm_ClientStrCmpIA(lastNamep, _C("\\winreg")) == 0 ||
- cm_ClientStrCmpIA(lastNamep, _C("ipc$")) == 0) && (is_rpc = TRUE)))) {
-
- unsigned short file_type = 0;
- unsigned short device_state = 0;
/* special case magic file name for receiving IOCTL requests
* (since IOCTL calls themselves aren't getting through).
*/
-#ifdef NOTSERVICE
- osi_Log0(smb_logp, "IOCTL Open");
-#endif
+ (cm_ClientStrCmpIA(lastNamep, _C(SMB_IOCTL_FILENAME)) == 0 ||
+
+ /* Or an RPC endpoint (is_rpc = TRUE assignment is intentional) */
+ (is_ipc && MSRPC_IsWellKnownService(lastNamep) && (is_rpc = TRUE)))) {
+
+ unsigned short file_type = 0;
+ unsigned short device_state = 0;
fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
if (is_rpc) {
- smb_SetupRPCFid(fidp, lastNamep, &file_type, &device_state);
+ code = smb_SetupRPCFid(fidp, lastNamep, &file_type, &device_state);
osi_Log1(smb_logp, "OpenAndX Setting up RPC on fid[%d]", fidp->fid);
+ if (code) {
+ osi_Log1(smb_logp, "smb_SetupRPCFid failure code [%d]", code);
+ smb_ReleaseFID(fidp);
+ return code;
+ }
} else {
smb_SetupIoctlFid(fidp, spacep);
osi_Log1(smb_logp, "OpenAndX Setting up IOCTL on fid[%d]", fidp->fid);
return 0;
}
+#ifndef DFS_SUPPORT
+ if (is_ipc) {
+ osi_Log0(smb_logp, "NTOpenX rejecting IPC TID");
+ return CM_ERROR_BADFD;
+ }
+#endif
+
if (!cm_IsValidClientString(pathp)) {
#ifdef DEBUG
clientchar_t * hexp;
userp = smb_GetUserFromVCP(vcp, inp);
dscp = NULL;
- code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
- if (code) {
- cm_ReleaseUser(userp);
- return CM_ERROR_NOSUCHPATH;
- }
code = cm_NameI(cm_data.rootSCachep, pathp,
CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
userp, tidPathp, &req, &scp);
* call provides the date first, not the time, as returned in the
* searchTime variable. So we take the high-order bits first.
*/
- smb_SearchTimeFromUnixTime(&searchTime, scp->clientModTime);
+ cm_SearchTimeFromUnixTime(&searchTime, scp->clientModTime);
smb_SetSMBParm(outp, 0, (searchTime >> 16) & 0xffff); /* ctime */
smb_SetSMBParm(outp, 1, searchTime & 0xffff);
smb_SetSMBParm(outp, 2, (searchTime >> 16) & 0xffff); /* atime */
searchTime = smb_GetSMBParm(inp, 5) | (smb_GetSMBParm(inp, 6) << 16);
if (searchTime != 0) {
- smb_UnixTimeFromSearchTime(&unixTime, searchTime);
+ cm_UnixTimeFromSearchTime(&unixTime, searchTime);
if ( unixTime != -1 ) {
attrs.mask = CM_ATTRMASK_CLIENTMODTIME;
osi_Log1(smb_logp, "SMB receive V3SetAttributes [fid=%ld]", fid);
} else {
- osi_Log1(smb_logp, "**smb_UnixTimeFromSearchTime failed searchTime=%ld", searchTime);
+ osi_Log1(smb_logp, "**cm_UnixTimeFromSearchTime failed searchTime=%ld", searchTime);
}
}
else
int checkDoneRequired = 0;
cm_lock_data_t *ldp = NULL;
BOOL is_rpc = FALSE;
+ BOOL is_ipc = FALSE;
smb_InitReq(&req);
realPathp[nameLength/sizeof(clientchar_t)] = 0;
spacep = inp->spacep;
+ /* smb_StripLastComponent will strip "::$DATA" if present */
smb_StripLastComponent(spacep->wdata, &lastNamep, realPathp);
osi_Log1(smb_logp,"NTCreateX for [%S]",osi_LogSaveClientString(smb_logp,realPathp));
osi_Log4(smb_logp,"... da=[%x] ea=[%x] cd=[%x] co=[%x]", desiredAccess, extAttributes, createDisp, createOptions);
osi_Log3(smb_logp,"... share=[%x] flags=[%x] lastNamep=[%S]", shareAccess, flags, osi_LogSaveClientString(smb_logp,(lastNamep?lastNamep:_C("null"))));
- /* The 'is_rpc' assignment to TRUE is intentional */
+ if (baseFid == 0) {
+ baseFidp = NULL;
+ baseDirp = cm_data.rootSCachep;
+ code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
+ if (code == CM_ERROR_TIDIPC) {
+ /* Attempt to use a TID allocated for IPC. The client
+ * is probably looking for DCE RPC end points which we
+ * don't support OR it could be looking to make a DFS
+ * referral request.
+ */
+ osi_Log0(smb_logp, "NTCreateX received IPC TID");
+ is_ipc = TRUE;
+ }
+ }
+
+ osi_Log1(smb_logp, "NTCreateX tidPathp=[%S]", (tidPathp==NULL)?_C("null"): osi_LogSaveClientString(smb_logp,tidPathp));
+
if (lastNamep &&
- (((cm_ClientStrCmpIA(lastNamep, _C("\\srvsvc")) == 0 ||
- cm_ClientStrCmpIA(lastNamep, _C("\\wkssvc")) == 0 ||
- cm_ClientStrCmpIA(lastNamep, _C("\\spoolss")) == 0 ||
- cm_ClientStrCmpIA(lastNamep, _C("\\winreg")) == 0 ||
- cm_ClientStrCmpIA(lastNamep, _C("ipc$")) == 0) && (is_rpc = TRUE)) ||
+
+ ((is_ipc && MSRPC_IsWellKnownService(lastNamep) && (is_rpc = TRUE)) ||
/* special case magic file name for receiving IOCTL requests
* (since IOCTL calls themselves aren't getting through).
fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
if (is_rpc) {
- smb_SetupRPCFid(fidp, lastNamep, &file_type, &device_state);
+ code = smb_SetupRPCFid(fidp, lastNamep, &file_type, &device_state);
osi_Log1(smb_logp, "NTCreateX Setting up RPC on fid[%d]", fidp->fid);
+ if (code) {
+ osi_Log1(smb_logp, "smb_SetupRPCFid() failure code [%d]", code);
+ smb_ReleaseFID(fidp);
+ free(realPathp);
+ return code;
+ }
} else {
smb_SetupIoctlFid(fidp, spacep);
osi_Log1(smb_logp, "NTCreateX Setting up IOCTL on fid[%d]", fidp->fid);
return 0;
}
+#ifndef DFS_SUPPORT
+ if (is_ipc) {
+ osi_Log0(smb_logp, "NTCreateX rejecting IPC TID");
+ free(realPathp);
+ return CM_ERROR_BADFD;
+ }
+#endif
+
if (!cm_IsValidClientString(realPathp)) {
#ifdef DEBUG
clientchar_t * hexp;
osi_Log1(smb_logp, "NTCreateX rejecting invalid name. [%S]",
osi_LogSaveClientString(smb_logp, hexp));
if (hexp)
- free(hexp);
+ free(hexp);
#else
osi_Log0(smb_logp, "NTCreateX rejecting invalid name");
#endif
return CM_ERROR_INVAL;
}
- if (baseFid == 0) {
- baseFidp = NULL;
- baseDirp = cm_data.rootSCachep;
- code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
- if (code == CM_ERROR_TIDIPC) {
- /* Attempt to use a TID allocated for IPC. The client
- * is probably looking for DCE RPC end points which we
- * don't support OR it could be looking to make a DFS
- * referral request.
- */
- osi_Log0(smb_logp, "NTCreateX received IPC TID");
-#ifndef DFS_SUPPORT
- free(realPathp);
- cm_ReleaseUser(userp);
- return CM_ERROR_NOSUCHFILE;
-#endif /* DFS_SUPPORT */
- }
- } else {
+ if (baseFidp != 0) {
baseFidp = smb_FindFID(vcp, baseFid, 0);
if (!baseFidp) {
osi_Log1(smb_logp, "NTCreateX Invalid base fid [%d]", baseFid);
+ cm_ReleaseUser(userp);
free(realPathp);
- cm_ReleaseUser(userp);
return CM_ERROR_INVAL;
- }
+ }
if (baseFidp->scp && (baseFidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
free(realPathp);
- cm_ReleaseUser(userp);
smb_CloseFID(vcp, baseFidp, NULL, 0);
smb_ReleaseFID(baseFidp);
+ cm_ReleaseUser(userp);
return CM_ERROR_NOSUCHPATH;
}
tidPathp = NULL;
}
- osi_Log1(smb_logp, "NTCreateX tidPathp=[%S]", (tidPathp==NULL)?_C("null"): osi_LogSaveClientString(smb_logp,tidPathp));
-
/* compute open mode */
fidflags = 0;
if (desiredAccess & DELETE)
/* set inp->fid so that later read calls in same msg can find fid */
inp->fid = fidp->fid;
- /* out parms */
- parmSlot = 2;
lock_ObtainRead(&scp->rw);
- smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */
- smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
- smb_SetSMBParmLong(outp, parmSlot, openAction); parmSlot += 2;
- smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
- smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
- smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
- smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
- smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
- smb_SetSMBParmLong(outp, parmSlot, smb_ExtAttributes(scp));
- parmSlot += 2;
- smb_SetSMBParmDouble(outp, parmSlot, (char *)&scp->length); parmSlot += 4;
- smb_SetSMBParmDouble(outp, parmSlot, (char *)&scp->length); parmSlot += 4;
- smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* filetype */
- smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* dev state */
- smb_SetSMBParmByte(outp, parmSlot,
- (scp->fileType == CM_SCACHETYPE_DIRECTORY ||
- scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
- scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0); /* is a dir? */
- smb_SetSMBDataLength(outp, 0);
+
+ /* check whether we are required to send an extended response */
+ if (!extendedRespRequired) {
+ /* out parms */
+ parmSlot = 2;
+ smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */
+ smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
+ smb_SetSMBParmLong(outp, parmSlot, openAction); parmSlot += 2;
+ cm_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
+ smb_SetSMBParmLong(outp, parmSlot, smb_ExtAttributes(scp));
+ parmSlot += 2;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&scp->length); parmSlot += 4;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&scp->length); parmSlot += 4;
+ smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* filetype */
+ smb_SetSMBParm(outp, parmSlot, NO_REPARSETAG|NO_SUBSTREAMS|NO_EAS);
+ parmSlot++; /* dev state */
+ smb_SetSMBParmByte(outp, parmSlot,
+ (scp->fileType == CM_SCACHETYPE_DIRECTORY ||
+ scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
+ scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0); /* is a dir? */
+ smb_SetSMBDataLength(outp, 70);
+ } else {
+ /* out parms */
+ parmSlot = 2;
+ smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */
+ smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
+ smb_SetSMBParmLong(outp, parmSlot, openAction); parmSlot += 2;
+ cm_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
+ smb_SetSMBParmLong(outp, parmSlot, smb_ExtAttributes(scp));
+ parmSlot += 2;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&scp->length); parmSlot += 4;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&scp->length); parmSlot += 4;
+ smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* filetype */
+ smb_SetSMBParm(outp, parmSlot, NO_REPARSETAG|NO_SUBSTREAMS|NO_EAS);
+ parmSlot++; /* dev state */
+ smb_SetSMBParmByte(outp, parmSlot,
+ (scp->fileType == CM_SCACHETYPE_DIRECTORY ||
+ scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
+ scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0); /* is a dir? */
+ /* Setting the GUID results in a failure with cygwin */
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ /* Maxmimal access rights */
+ smb_SetSMBParmLong(outp, parmSlot, 0x001f01ff); parmSlot += 2;
+ /* Guest access rights */
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ smb_SetSMBDataLength(outp, 105);
+ }
if ((fidp->flags & SMB_FID_EXECUTABLE) &&
LargeIntegerGreaterThanZero(scp->length) &&
memcpy(realPathp, pathp, nameLength);
realPathp[nameLength/sizeof(clientchar_t)] = 0;
spacep = cm_GetSpace();
+ /* smb_StripLastComponent will strip "::$DATA" if present */
smb_StripLastComponent(spacep->wdata, &lastNamep, realPathp);
osi_Log1(smb_logp,"NTTranCreate %S",osi_LogSaveStringW(smb_logp,realPathp));
*((USHORT *)outData) = fidp->fid; outData += 2; /* fid */
*((ULONG *)outData) = openAction; outData += 4;
*((ULONG *)outData) = 0; outData += 4; /* EA error offset */
- smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
+ cm_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
*((FILETIME *)outData) = ft; outData += 8; /* creation time */
*((FILETIME *)outData) = ft; outData += 8; /* last access time */
*((FILETIME *)outData) = ft; outData += 8; /* last write time */
*((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* alloc sz */
*((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* EOF */
*((USHORT *)outData) = 0; outData += 2; /* filetype */
- *((USHORT *)outData) = 0; outData += 2; /* dev state */
+ *((USHORT *)outData) = NO_REPARSETAG|NO_SUBSTREAMS|NO_EAS;
+ outData += 2; /* dev state */
*((USHORT *)outData) = ((scp->fileType == CM_SCACHETYPE_DIRECTORY ||
scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0);
*((USHORT *)outData) = fidp->fid; outData += 2; /* fid */
*((ULONG *)outData) = openAction; outData += 4;
*((ULONG *)outData) = 0; outData += 4; /* EA error offset */
- smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
+ cm_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
*((FILETIME *)outData) = ft; outData += 8; /* creation time */
*((FILETIME *)outData) = ft; outData += 8; /* last access time */
*((FILETIME *)outData) = ft; outData += 8; /* last write time */
*((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* alloc sz */
*((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* EOF */
*((USHORT *)outData) = 0; outData += 2; /* filetype */
- *((USHORT *)outData) = 0; outData += 2; /* dev state */
+ *((USHORT *)outData) = NO_REPARSETAG|NO_SUBSTREAMS|NO_EAS;
+ outData += 2; /* dev state */
*((USHORT *)outData) = ((scp->fileType == CM_SCACHETYPE_DIRECTORY ||
scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0);
outData += 1; /* is a dir? */
- memset(outData,0,24); outData += 24; /* Volume ID and file ID */
+ /* Setting the GUID results in failures with cygwin */
+ memset(outData,0,24); outData += 24; /* GUID */
*((ULONG *)outData) = 0x001f01ffL; outData += 4; /* Maxmimal access rights */
*((ULONG *)outData) = 0; outData += 4; /* Guest Access rights */
}
osi_Log0(smb_logp, "SMB NT Transact Set Quota - not implemented");
break;
}
- return CM_ERROR_INVAL;
+ return CM_ERROR_BADOP;
}
/*