if ( smb_ExecutableExtensions == NULL || name == NULL)
return 0;
- len = strlen(name);
+ len = (int)strlen(name);
for ( i=0; smb_ExecutableExtensions[i]; i++) {
- j = len - strlen(smb_ExecutableExtensions[i]);
+ j = len - (int)strlen(smb_ExecutableExtensions[i]);
if (_stricmp(smb_ExecutableExtensions[i], &name[j]) == 0)
return 1;
}
for (i=0;i<len;i++) {
if(!(i%16)) {
if(i) {
- osi_Log0(smb_logp, osi_LogSaveString(smb_logp, buf));
+ osi_Log1(smb_logp, "%s", osi_LogSaveString(smb_logp, buf));
strcat(buf,"\r\n");
OutputDebugString(buf);
}
buf[j] = (k>32 && k<127)?k:'.';
}
if(i) {
- osi_Log0(smb_logp, osi_LogSaveString(smb_logp, buf));
+ osi_Log1(smb_logp, "%s", osi_LogSaveString(smb_logp, buf));
strcat(buf,"\r\n");
OutputDebugString(buf);
}
if (!shareFound) {
if (uidp)
smb_ReleaseUID(uidp);
- smb_ReleaseTID(tidp);
+ smb_ReleaseTID(tidp, FALSE);
return CM_ERROR_BADSHARENAME;
}
if (vcp->flags & SMB_VCFLAG_USENT)
{
int policy = smb_FindShareCSCPolicy(shareName);
+ HKEY parmKey;
+ DWORD code;
+ DWORD dwAdvertiseDFS = 0, dwSize = sizeof(DWORD);
+
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ code = RegQueryValueEx(parmKey, "AdvertiseDFS", NULL, NULL,
+ (BYTE *)&dwAdvertiseDFS, &dwSize);
+ if (code != ERROR_SUCCESS)
+ dwAdvertiseDFS = 0;
+ RegCloseKey (parmKey);
+ }
smb_SetSMBParm(outp, 2, SMB_SUPPORT_SEARCH_BITS |
-#ifdef DFS_SUPPORT
- SMB_SHARE_IS_IN_DFS |
-#endif
+ (dwAdvertiseDFS ? SMB_SHARE_IS_IN_DFS : 0) |
(policy << 2));
}
} else {
if (ipc)
tidp->flags |= SMB_TIDFLAG_IPC;
lock_ReleaseMutex(&tidp->mx);
- smb_ReleaseTID(tidp);
+ smb_ReleaseTID(tidp, FALSE);
((smb_t *)outp)->tid = newTid;
((smb_t *)inp)->tid = newTid;
} smb_rap_share_info_1_t;
typedef struct smb_rap_share_info_2 {
- char shi2_netname[13];
- char shi2_pad;
+ char shi2_netname[13];
+ char shi2_pad;
unsigned short shi2_type;
- DWORD shi2_remark; /* char *shi2_remark; data offset */
+ DWORD shi2_remark; /* char *shi2_remark; data offset */
unsigned short shi2_permissions;
unsigned short shi2_max_uses;
unsigned short shi2_current_uses;
- DWORD shi2_path; /* char *shi2_path; data offset */
+ DWORD shi2_path; /* char *shi2_path; data offset */
unsigned short shi2_passwd[9];
unsigned short shi2_pad2;
} smb_rap_share_info_2_t;
DWORD allSubmount;
LONG rv;
long code = 0;
+ cm_scache_t *scp = NULL;
+ cm_user_t *userp;
+ cm_req_t req;
+
+ cm_InitReq(&req);
tp = p->parmsp + 1; /* skip over function number (always 1) */
(void) smb_ParseString( (char *) tp, (char **) &tp); /* skip over param descriptor */
else
return CM_ERROR_INVAL;
- outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParam, totalData);
-
if(!stricmp(shareName,"all") || !strcmp(shareName,"*.")) {
rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, 0,
KEY_QUERY_VALUE, &hkParam);
shareFound = TRUE;
} else {
- rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY "\\Submounts", 0,
- KEY_QUERY_VALUE, &hkSubmount);
- if (rv == ERROR_SUCCESS) {
- rv = RegQueryValueEx(hkSubmount, shareName, NULL, NULL, NULL, NULL);
+ userp = smb_GetTran2User(vcp, p);
+ if (!userp) {
+ osi_Log1(smb_logp,"ReceiveTran2GetDfsReferral unable to resolve user [%d]", p->uid);
+ return CM_ERROR_BADSMB;
+ }
+ code = cm_NameI(cm_data.rootSCachep, shareName,
+ CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD | CM_FLAG_DFS_REFERRAL,
+ userp, NULL, &req, &scp);
+ if (code == 0) {
+ cm_ReleaseSCache(scp);
+ shareFound = TRUE;
+ } else {
+ rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY "\\Submounts", 0,
+ KEY_QUERY_VALUE, &hkSubmount);
if (rv == ERROR_SUCCESS) {
- shareFound = TRUE;
+ rv = RegQueryValueEx(hkSubmount, shareName, NULL, NULL, NULL, NULL);
+ if (rv == ERROR_SUCCESS) {
+ shareFound = TRUE;
+ }
+ RegCloseKey(hkSubmount);
}
- RegCloseKey(hkSubmount);
}
}
- if (!shareFound) {
- smb_FreeTran2Packet(outp);
+ if (!shareFound)
return CM_ERROR_BADSHARENAME;
- }
+ outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParam, totalData);
memset(outp->datap, 0, totalData);
outp->parmsp[0] = 0;
spacep = cm_GetSpace();
smb_StripLastComponent(spacep->data, &lastNamep, pathp);
- if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) {
+ if (lastNamep &&
+ (stricmp(lastNamep, SMB_IOCTL_FILENAME) == 0 ||
+ stricmp(lastNamep, "\\srvsvc") == 0 ||
+ stricmp(lastNamep, "\\wkssvc") == 0 ||
+ stricmp(lastNamep, "\\ipc$") == 0)) {
/* special case magic file name for receiving IOCTL requests
* (since IOCTL calls themselves aren't getting through).
*/
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
smb_FreeTran2Packet(outp);
- if ( WANTS_DFS_PATHNAMES(p) )
+ if ( WANTS_DFS_PATHNAMES(p) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
} else {
#ifdef DFS_SUPPORT
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, lastNamep);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_FreeTran2Packet(outp);
- if ( WANTS_DFS_PATHNAMES(p) )
+ if ( WANTS_DFS_PATHNAMES(p) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
/* save a pointer to the vnode */
osi_Log2(smb_logp,"smb_ReceiveTran2Open fidp 0x%p scp 0x%p", fidp, scp);
fidp->scp = scp;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
/* and the user */
fidp->userp = userp;
/* copy out remainder of the parms */
parmSlot = 0;
outp->parmsp[parmSlot++] = fidp->fid;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
if (extraInfo) {
outp->parmsp[parmSlot++] = smb_Attributes(scp);
smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
outp->parmsp[parmSlot++] = 0;
outp->parmsp[parmSlot++] = 0;
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
outp->totalData = 0; /* total # of data bytes */
outp->totalParms = parmSlot * 2; /* shorts are two bytes */
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
+ DebugBreak();
return CM_ERROR_PATH_NOT_COVERED;
}
#endif /* DFS_SUPPORT */
if (code == 0) {
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
- if ( WANTS_DFS_PATHNAMES(p) )
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
+ if ( WANTS_DFS_PATHNAMES(p) || pnc )
code = CM_ERROR_PATH_NOT_COVERED;
else
code = CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, pathp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(p) )
+ if ( WANTS_DFS_PATHNAMES(p) || pnc )
code = CM_ERROR_PATH_NOT_COVERED;
else
code = CM_ERROR_BADSHARENAME;
}
#endif /* DFS_SUPPORT */
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
scp_mx_held = 1;
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ConvertWToR(&scp->rw);
+
/* now we have the status in the cache entry, and everything is locked.
* Marshall the output data.
*/
goto done;
}
else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) {
- len = strlen(lastComp);
+ len = (unsigned int)strlen(lastComp);
qpi.u.QPfileNameInfo.fileNameLength = (len + 1) * 2;
mbstowcs((unsigned short *)qpi.u.QPfileNameInfo.fileName, lastComp, len + 1);
qpi.u.QPfileStandardInfo.reserved = 0;
if (fidp) {
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
scp_mx_held = 0;
lock_ObtainMutex(&fidp->mx);
delonclose = fidp->flags & SMB_FID_DELONCLOSE;
qpi.u.QPfileAllInfo.currentByteOffset.LowPart = 0;
qpi.u.QPfileAllInfo.mode = 0;
qpi.u.QPfileAllInfo.alignmentRequirement = 0;
- len = strlen(lastComp);
+ len = (unsigned int)strlen(lastComp);
qpi.u.QPfileAllInfo.fileNameLength = (len + 1) * 2;
mbstowcs((unsigned short *)qpi.u.QPfileAllInfo.fileName, lastComp, len + 1);
}
/* send and free the packets */
done:
if (scp_mx_held)
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
if (code == 0) {
infoLevel != SMB_INFO_QUERY_ALL_EAS) {
osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
p->opcode, infoLevel);
- smb_SendTran2Error(vcp, p, opx, CM_ERROR_BAD_LEVEL);
+ smb_SendTran2Error(vcp, p, opx,
+ infoLevel == SMB_INFO_QUERY_ALL_EAS ? CM_ERROR_EAS_NOT_SUPPORTED : CM_ERROR_BAD_LEVEL);
return 0;
}
if (code == 0) {
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
- if ( WANTS_DFS_PATHNAMES(p) )
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
+ if ( WANTS_DFS_PATHNAMES(p) || pnc )
code = CM_ERROR_PATH_NOT_COVERED;
else
code = CM_ERROR_BADSHARENAME;
/* lock the vnode with a callback; we need the current status
* to determine what the new status is, in some cases.
*/
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
goto done;
}
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&fidp->mx);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
/* prepare for setattr call */
attr.mask = CM_ATTRMASK_LENGTH;
attr.unixModeBits = scp->unixModeBits | 0222;
}
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
lock_ReleaseMutex(&fidp->mx);
/* call setattr */
}
else if (infoLevel == SMB_INFO_QUERY_ALL_EAS) {
/* we don't support EAs */
- code = CM_ERROR_INVAL;
+ code = CM_ERROR_EAS_NOT_SUPPORTED;
}
done:
cm_scache_t *scp;
smb_tran2QFileInfo_t qfi;
long code = 0;
+ int readlock = 0;
cm_req_t req;
cm_InitReq(&req);
osi_Log2(smb_logp,"smb_ReleaseTran2QFileInfo fidp 0x%p scp 0x%p", fidp, scp);
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ConvertWToR(&scp->rw);
+ readlock = 1;
+
/* now we have the status in the cache entry, and everything is locked.
* Marshall the output data.
*/
unsigned long len;
char *name;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
lock_ObtainMutex(&fidp->mx);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
if (fidp->NTopen_wholepathp)
name = fidp->NTopen_wholepathp;
else
/* send and free the packets */
done:
- lock_ReleaseMutex(&scp->mx);
+ if (readlock)
+ lock_ReleaseRead(&scp->rw);
+ else
+ lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
/* lock the vnode with a callback; we need the current status
* to determine what the new status is, in some cases.
*/
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
goto done;
}
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&fidp->mx);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
/* prepare for setattr call */
attr.mask = 0;
attr.unixModeBits = scp->unixModeBits | 0222;
}
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
lock_ReleaseMutex(&fidp->mx);
/* call setattr */
long code = 0;
int maxReferralLevel = 0;
char requestFileName[1024] = "";
+ char referralPath[1024] = "";
smb_tran2Packet_t *outp = 0;
cm_user_t *userp = 0;
+ cm_scache_t *scp = 0;
+ cm_scache_t *dscp = 0;
cm_req_t req;
CPINFO CodePageInfo;
- int i, nbnLen, reqLen;
+ int i, nbnLen, reqLen, refLen;
int idx;
cm_InitReq(&req);
osi_Log2(smb_logp,"ReceiveTran2GetDfsReferral [%d][%s]",
maxReferralLevel, osi_LogSaveString(smb_logp, requestFileName));
- nbnLen = strlen(cm_NetbiosName);
- reqLen = strlen(requestFileName);
+ nbnLen = (int)strlen(cm_NetbiosName);
+ reqLen = (int)strlen(requestFileName);
- if (reqLen == nbnLen + 5 &&
- requestFileName[0] == '\\' &&
+ if (reqLen > nbnLen + 2 && requestFileName[0] == '\\' &&
!_strnicmp(cm_NetbiosName,&requestFileName[1],nbnLen) &&
- requestFileName[nbnLen+1] == '\\' &&
- (!_strnicmp("all",&requestFileName[nbnLen+2],3) ||
- !_strnicmp("*.",&requestFileName[nbnLen+2],2)))
+ requestFileName[nbnLen+1] == '\\')
{
- USHORT * sp;
- struct smb_v2_referral * v2ref;
- outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, 2 * (reqLen + 8));
-
- sp = (USHORT *)outp->datap;
- idx = 0;
- sp[idx++] = reqLen; /* path consumed */
- sp[idx++] = 1; /* number of referrals */
- sp[idx++] = 0x03; /* flags */
+ int found = 0;
+
+ if (!_strnicmp("all",&requestFileName[nbnLen+2],3) ||
+ !_strnicmp("*.",&requestFileName[nbnLen+2],2))
+ {
+ found = 1;
+ strcpy(referralPath, requestFileName);
+ refLen = reqLen;
+ } else {
+ userp = smb_GetTran2User(vcp, p);
+ if (!userp) {
+ osi_Log1(smb_logp,"ReceiveTran2GetDfsReferral unable to resolve user [%d]", p->uid);
+ code = CM_ERROR_BADSMB;
+ goto done;
+ }
+
+ /*
+ * We have a requested path. Check to see if it is something
+ * we know about.
+ *
+ * But be careful because the name that we might be searching
+ * for might be a known name with the final character stripped
+ * off. If we
+ */
+ code = cm_NameI(cm_data.rootSCachep, &requestFileName[nbnLen+2],
+ CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD | CM_FLAG_DFS_REFERRAL,
+ userp, NULL, &req, &scp);
+ if (code == 0) {
+ /* Yes it is. */
+ found = 1;
+ strcpy(referralPath, requestFileName);
+ refLen = reqLen;
+ } else if (code == CM_ERROR_PATH_NOT_COVERED ) {
+ char temp[1024];
+ char pathName[1024];
+ char *lastComponent;
+ /*
+ * we have a msdfs link somewhere in the path
+ * we should figure out where in the path the link is.
+ * and return it.
+ */
+ osi_Log1(smb_logp,"ReceiveTran2GetDfsReferral PATH_NOT_COVERED [%s]", requestFileName);
+
+ strcpy(temp, &requestFileName[nbnLen+2]);
+
+ do {
+ if (dscp) {
+ cm_ReleaseSCache(dscp);
+ dscp = 0;
+ }
+ if (scp) {
+ cm_ReleaseSCache(scp);
+ scp = 0;
+ }
+ smb_StripLastComponent(pathName, &lastComponent, temp);
+
+ code = cm_NameI(cm_data.rootSCachep, pathName,
+ CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
+ userp, NULL, &req, &dscp);
+ if (code == 0) {
+ code = cm_NameI(dscp, ++lastComponent,
+ CM_FLAG_CASEFOLD,
+ userp, NULL, &req, &scp);
+ if (code == 0 && scp->fileType == CM_SCACHETYPE_DFSLINK)
+ break;
+ }
+ } while (code == CM_ERROR_PATH_NOT_COVERED);
+
+ /* scp should now be the DfsLink we are looking for */
+ if (scp) {
+ /* figure out how much of the input path was used */
+ reqLen = (int)(nbnLen+2 + strlen(pathName) + 1 + strlen(lastComponent));
+
+ strcpy(referralPath, &scp->mountPointStringp[strlen("msdfs:")]);
+ refLen = (int)strlen(referralPath);
+ found = 1;
+ }
+ } else {
+ char shareName[MAX_PATH + 1];
+ char *p, *q;
+ /* we may have a sharename that is a volume reference */
+
+ for (p = &requestFileName[nbnLen+2], q = shareName; *p && *p != '\\'; p++, q++)
+ {
+ *q = *p;
+ }
+ *q = '\0';
+
+ if (smb_FindShare(vcp, vcp->usersp, shareName, &p)) {
+ code = cm_NameI(cm_data.rootSCachep, "",
+ CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ userp, p, &req, &scp);
+ free(p);
+
+ if (code == 0) {
+ found = 1;
+ strcpy(referralPath, requestFileName);
+ refLen = reqLen;
+ }
+ }
+ }
+ }
+
+ if (found)
+ {
+ USHORT * sp;
+ struct smb_v2_referral * v2ref;
+ outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, 2 * (refLen + 8));
+
+ sp = (USHORT *)outp->datap;
+ idx = 0;
+ sp[idx++] = reqLen; /* path consumed */
+ sp[idx++] = 1; /* number of referrals */
+ sp[idx++] = 0x03; /* flags */
#ifdef DFS_VERSION_1
- sp[idx++] = 1; /* Version Number */
- sp[idx++] = reqLen + 4; /* Referral Size */
- sp[idx++] = 1; /* Type = SMB Server */
- sp[idx++] = 0; /* Do not strip path consumed */
- for ( i=0;i<=reqLen; i++ )
- sp[i+idx] = requestFileName[i];
+ sp[idx++] = 1; /* Version Number */
+ sp[idx++] = refLen + 4; /* Referral Size */
+ sp[idx++] = 1; /* Type = SMB Server */
+ sp[idx++] = 0; /* Do not strip path consumed */
+ for ( i=0;i<=refLen; i++ )
+ sp[i+idx] = referralPath[i];
#else /* DFS_VERSION_2 */
- sp[idx++] = 2; /* Version Number */
- sp[idx++] = sizeof(struct smb_v2_referral); /* Referral Size */
- idx += (sizeof(struct smb_v2_referral) / 2);
- v2ref = (struct smb_v2_referral *) &sp[5];
- v2ref->ServerType = 1; /* SMB Server */
- v2ref->ReferralFlags = 0x03;
- v2ref->Proximity = 0; /* closest */
- v2ref->TimeToLive = 3600; /* seconds */
- v2ref->DfsPathOffset = idx * 2;
- v2ref->DfsAlternativePathOffset = idx * 2;
- v2ref->NetworkAddressOffset = 0;
- for ( i=0;i<=reqLen; i++ )
- sp[i+idx] = requestFileName[i];
+ sp[idx++] = 2; /* Version Number */
+ sp[idx++] = sizeof(struct smb_v2_referral); /* Referral Size */
+ idx += (sizeof(struct smb_v2_referral) / 2);
+ v2ref = (struct smb_v2_referral *) &sp[5];
+ v2ref->ServerType = 1; /* SMB Server */
+ v2ref->ReferralFlags = 0x03;
+ v2ref->Proximity = 0; /* closest */
+ v2ref->TimeToLive = 3600; /* seconds */
+ v2ref->DfsPathOffset = idx * 2;
+ v2ref->DfsAlternativePathOffset = idx * 2;
+ v2ref->NetworkAddressOffset = 0;
+ for ( i=0;i<=refLen; i++ )
+ sp[i+idx] = referralPath[i];
#endif
+ }
} else {
- userp = smb_GetTran2User(vcp, p);
- if (!userp) {
- osi_Log1(smb_logp,"ReceiveTran2GetDfsReferral unable to resolve user [%d]", p->uid);
- code = CM_ERROR_BADSMB;
- goto done;
- }
-
- /* not done yet */
code = CM_ERROR_NOSUCHPATH;
}
-
+
done:
+ if (dscp)
+ cm_ReleaseSCache(dscp);
+ if (scp)
+ cm_ReleaseSCache(scp);
if (userp)
cm_ReleaseUser(userp);
if (code == 0)
return 0;
#else /* DFS_SUPPORT */
osi_Log0(smb_logp,"ReceiveTran2GetDfsReferral - NOT_SUPPORTED");
- return CM_ERROR_BADOP;
+ return CM_ERROR_NOSUCHDEVICE;
#endif /* DFS_SUPPORT */
}
return CM_ERROR_BADOP;
}
-long
-smb_ApplyV3DirListPatches(cm_scache_t *dscp,
- smb_dirListPatch_t **dirPatchespp, int infoLevel, cm_user_t *userp,
- cm_req_t *reqp)
+static long
+smb_ApplyV3DirListPatches(cm_scache_t *dscp,smb_dirListPatch_t **dirPatchespp,
+ char * tidPathp, char * relPathp,
+ int infoLevel, cm_user_t *userp,
+ cm_req_t *reqp)
{
long code = 0;
cm_scache_t *scp;
smb_dirListPatch_t *npatchp;
afs_uint32 rights;
afs_int32 mustFake = 0;
+ char path[AFSPATHMAX];
code = cm_FindACLCache(dscp, userp, &rights);
if (code == 0 && !(rights & PRSFS_READ))
mustFake = 1;
else if (code == -1) {
- lock_ObtainMutex(&dscp->mx);
+ lock_ObtainWrite(&dscp->rw);
code = cm_SyncOp(dscp, NULL, userp, reqp, PRSFS_READ,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- lock_ReleaseMutex(&dscp->mx);
+ lock_ReleaseWrite(&dscp->rw);
if (code == CM_ERROR_NOACCESS) {
mustFake = 1;
code = 0;
for(patchp = *dirPatchespp; patchp; patchp =
(smb_dirListPatch_t *) osi_QNext(&patchp->q)) {
+ snprintf(path, AFSPATHMAX, "%s\\%s", relPathp ? relPathp : "", patchp->dep->name);
+ reqp->relPathp = path;
+ reqp->tidPathp = tidPathp;
+
code = cm_GetSCache(&patchp->fid, &scp, userp, reqp);
+ reqp->relPathp = reqp->tidPathp = NULL;
if (code)
continue;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
if (mustFake == 0)
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (mustFake || code) {
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
dptr = patchp->dptr;
/* now watch for a symlink */
code = 0;
while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
+ snprintf(path, AFSPATHMAX, "%s\\%s", relPathp ? relPathp : "", patchp->dep->name);
+ reqp->relPathp = path;
+ reqp->tidPathp = tidPathp;
code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, reqp);
+ reqp->relPathp = reqp->tidPathp = NULL;
if (code == 0) {
/* we have a more accurate file to use (the
* target of the symbolic link). Otherwise,
cm_ReleaseSCache(scp);
scp = targetScp;
}
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
}
+ lock_ConvertWToR(&scp->rw);
+
dptr = patchp->dptr;
if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) {
/* Copy attributes */
lattr = smb_ExtAttributes(scp);
- if (code == CM_ERROR_NOSUCHPATH && scp->fileType == CM_SCACHETYPE_SYMLINK) {
+ if (code == CM_ERROR_NOSUCHPATH && scp->fileType == CM_SCACHETYPE_SYMLINK ||
+ code == CM_ERROR_PATH_NOT_COVERED && scp->fileType == CM_SCACHETYPE_DFSLINK) {
if (lattr == SMB_ATTR_NORMAL)
lattr = SMB_ATTR_DIRECTORY;
else
*dptr++ = (attr >> 8) & 0xff;
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
cm_ReleaseSCache(scp);
}
int attribute;
long nextCookie;
long code = 0, code2 = 0;
- char *pathp;
+ char *pathp = 0;
int maxCount;
smb_dirListPatch_t *dirListPatchesp;
smb_dirListPatch_t *curPatchp;
int searchFlags;
int eos;
smb_tran2Packet_t *outp; /* response packet */
- char *tidPathp;
+ char *tidPathp = 0;
int align;
char shortName[13]; /* 8.3 name if needed */
int NeedShortName;
char *shortNameEnd;
+ cm_dirEntry_t * dep = NULL;
cm_req_t req;
char * s;
#ifdef DFS_SUPPORT_BUT_NOT_FIND_FIRST
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, spacep->data);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(p) )
+ if ( WANTS_DFS_PATHNAMES(p) || pnc )
code = CM_ERROR_PATH_NOT_COVERED;
else
code = CM_ERROR_BADSHARENAME;
ohbytes += 4; /* EASIZE */
/* add header to name & term. null */
- onbytes = strlen(maskp);
+ onbytes = (int)strlen(maskp);
orbytes = ohbytes + onbytes + 1;
/* now, we round up the record to a 4 byte alignment, and we make
curPatchp->flags = 0;
}
- curPatchp->fid.cell = targetscp->fid.cell;
- curPatchp->fid.volume = targetscp->fid.volume;
- curPatchp->fid.vnode = targetscp->fid.vnode;
- curPatchp->fid.unique = targetscp->fid.unique;
+ cm_SetFid(&curPatchp->fid, targetscp->fid.cell, targetscp->fid.volume, targetscp->fid.vnode, targetscp->fid.unique);
/* temp */
- curPatchp->dep = NULL;
+ dep = (cm_dirEntry_t *)malloc(sizeof(cm_dirEntry_t)+strlen(maskp));
+ strcpy(dep->name, maskp);
+ dep->fid.vnode = targetscp->fid.vnode;
+ dep->fid.unique = targetscp->fid.unique;
+ curPatchp->dep = dep;
}
if (searchFlags & TRAN2_FIND_FLAG_RETURN_RESUME_KEYS) {
}
/* apply the patches */
- code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, infoLevel, userp, &req);
+ code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, tidPathp, spacep->data, infoLevel, userp, &req);
outp->parmsp[0] = 0;
outp->parmsp[1] = 1; /* number of names returned */
skip_file:
smb_FreeTran2Packet(outp);
+ if (dep)
+ free(dep);
+ if (scp)
cm_ReleaseSCache(scp);
cm_ReleaseSCache(targetscp);
cm_ReleaseUser(userp);
char *tp;
long code = 0, code2 = 0;
char *pathp;
- cm_dirEntry_t *dep;
+ cm_dirEntry_t *dep = 0;
int maxCount;
- smb_dirListPatch_t *dirListPatchesp;
- smb_dirListPatch_t *curPatchp;
+ smb_dirListPatch_t *dirListPatchesp = 0;
+ smb_dirListPatch_t *curPatchp = 0;
cm_buf_t *bufferp;
long temp;
long orbytes; /* # of bytes in this output record */
smb_ReleaseDirSearch(dsp);
return 0;
}
+
+ strcpy(dsp->tidPath, tidPathp ? tidPathp : "/");
+ strcpy(dsp->relPath, spacep->data);
+
code = cm_NameI(cm_data.rootSCachep, spacep->data,
CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
userp, tidPathp, &req, &scp);
if (code == 0) {
#ifdef DFS_SUPPORT_BUT_NOT_FIND_FIRST
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, spacep->data);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(p) )
+ if ( WANTS_DFS_PATHNAMES(p) || pnc )
code = CM_ERROR_PATH_NOT_COVERED;
else
code = CM_ERROR_BADSHARENAME;
* and so we do another hold now.
*/
cm_HoldSCache(scp);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 &&
LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) {
scp->flags |= CM_SCACHEFLAG_BULKSTATTING;
dsp->flags |= SMB_DIRSEARCH_BULKST;
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
}
}
lock_ReleaseMutex(&dsp->mx);
}
/* get the directory size */
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_FreeTran2Packet(outp);
buf_Release(bufferp);
bufferp = NULL;
}
- lock_ReleaseMutex(&scp->mx);
- lock_ObtainRead(&scp->bufCreateLock);
+ lock_ReleaseWrite(&scp->rw);
code = buf_Get(scp, &thyper, &bufferp);
- lock_ReleaseRead(&scp->bufCreateLock);
lock_ObtainMutex(&dsp->mx);
/* now, if we're doing a star match, do bulk fetching
* of all of the status info for files in the dir.
*/
if (starPattern) {
- smb_ApplyV3DirListPatches(scp, &dirListPatchesp,
- infoLevel, userp,
- &req);
- lock_ObtainMutex(&scp->mx);
+ code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, dsp->tidPath, dsp->relPath, infoLevel, userp, &req);
+
+ lock_ObtainWrite(&scp->rw);
if ((dsp->flags & SMB_DIRSEARCH_BULKST) &&
LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) {
/* Don't bulk stat if risking timeout */
code = cm_TryBulkStat(scp, &thyper, userp, &req);
}
} else {
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
}
lock_ReleaseMutex(&dsp->mx);
if (code) {
if (!(dsp->attribute & SMB_ATTR_DIRECTORY)) /* no directories */
{
/* We have already done the cm_TryBulkStat above */
- fid.cell = scp->fid.cell;
- fid.volume = scp->fid.volume;
- fid.vnode = ntohl(dep->fid.vnode);
- fid.unique = ntohl(dep->fid.unique);
+ cm_SetFid(&fid, scp->fid.cell, scp->fid.volume, ntohl(dep->fid.vnode), ntohl(dep->fid.unique));
fileType = cm_FindFileType(&fid);
/* osi_Log2(smb_logp, "smb_ReceiveTran2SearchDir: file %s "
* "has filetype %d", dep->name, fileType);
else
curPatchp->flags = 0;
- curPatchp->fid.cell = scp->fid.cell;
- curPatchp->fid.volume = scp->fid.volume;
- curPatchp->fid.vnode = ntohl(dep->fid.vnode);
- curPatchp->fid.unique = ntohl(dep->fid.unique);
+ cm_SetFid(&curPatchp->fid, scp->fid.cell, scp->fid.volume, ntohl(dep->fid.vnode), ntohl(dep->fid.unique));
/* temp */
curPatchp->dep = dep;
}
/* release the mutex */
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
if (bufferp) {
buf_Release(bufferp);
bufferp = NULL;
/* apply and free last set of patches; if not doing a star match, this
* will be empty, but better safe (and freeing everything) than sorry.
*/
- code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, infoLevel, userp, &req);
-
+ code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, dsp->tidPath,
+ dsp->relPath, infoLevel, userp, &req);
+
/* now put out the final parameters */
if (returnedNames == 0)
eos = 1;
spacep = inp->spacep;
smb_StripLastComponent(spacep->data, &lastNamep, pathp);
- if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) {
+ if (lastNamep &&
+ (stricmp(lastNamep, SMB_IOCTL_FILENAME) == 0 ||
+ stricmp(lastNamep, "\\srvsvc") == 0 ||
+ stricmp(lastNamep, "\\wkssvc") == 0 ||
+ stricmp(lastNamep, "ipc$") == 0)) {
/* special case magic file name for receiving IOCTL requests
* (since IOCTL calls themselves aren't getting through).
*/
#ifdef DFS_SUPPORT
if (code == 0 && scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, pathp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
osi_Log2(smb_logp,"smb_ReceiveV3OpenX fidp 0x%p scp 0x%p", fidp, scp);
/* also the user */
fidp->userp = userp;
/* copy out remainder of the parms */
parmSlot = 2;
smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
if (extraInfo) {
smb_SetSMBParm(outp, parmSlot, smb_Attributes(scp)); parmSlot++;
smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime);
smb_SetSMBParm(outp, parmSlot, scp->fid.vnode & 0xffff); parmSlot++;
smb_SetSMBParm(outp, parmSlot, scp->fid.volume & 0xffff); parmSlot++;
smb_SetSMBParm(outp, parmSlot, 0); parmSlot++;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
smb_SetSMBDataLength(outp, 0);
osi_Log1(smb_logp, "SMB OpenX opening fid %d", fidp->fid);
cm_scache_t *scp;
unsigned char LockType;
unsigned short NumberOfUnlocks, NumberOfLocks;
- long Timeout;
+ afs_uint32 Timeout;
char *op;
char *op_locks;
LARGE_INTEGER LOffset, LLength;
userp = smb_GetUserFromVCP(vcp, inp);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK
| CM_SCACHESYNC_GETSTATUS
LockType |= LOCKING_ANDX_SHARED_LOCK;
}
- if ((LockType & LOCKING_ANDX_CANCEL_LOCK) ||
- (LockType & LOCKING_ANDX_CHANGE_LOCKTYPE)) {
-
- /* We don't support these requests. Apparently, we can safely
- not deal with them too. */
- osi_Log1(smb_logp, "smb_ReceiveV3Locking received unsupported request [%s]",
- ((LockType & LOCKING_ANDX_CANCEL_LOCK)?
- "LOCKING_ANDX_CANCEL_LOCK":
- "LOCKING_ANDX_CHANGE_LOCKTYPE"));
- /* No need to call osi_LogSaveString since these are string
- constants.*/
-
+ if (LockType & LOCKING_ANDX_CHANGE_LOCKTYPE) {
+ /* AFS does not support atomic changes of lock types from read or write and vice-versa */
+ osi_Log0(smb_logp, "smb_ReceiveV3Locking received unsupported request [LOCKING_ANDX_CHANGE_LOCKTYPE]");
code = CM_ERROR_BADOP;
goto done;
op = smb_GetSMBData(inp, NULL);
+ if (LockType & LOCKING_ANDX_CANCEL_LOCK) {
+ /* Cancel outstanding lock requests */
+ smb_waitingLock_t * wl;
+
+ for (i=0; i<NumberOfLocks; i++) {
+ smb_GetLockParams(LockType, &op, &pid, &LOffset, &LLength);
+
+ key = cm_GenerateKey(vcp->vcID, pid, fidp->fid);
+
+ lock_ObtainWrite(&smb_globalLock);
+ for (wlRequest = smb_allWaitingLocks; wlRequest; wlRequest = (smb_waitingLockRequest_t *) osi_QNext(&wlRequest->q))
+ {
+ for (wl = wlRequest->locks; wl; wl = (smb_waitingLock_t *) osi_QNext(&wl->q)) {
+ if (wl->key == key && LargeIntegerEqualTo(wl->LOffset, LOffset) &&
+ LargeIntegerEqualTo(wl->LLength, LLength)) {
+ wl->state = SMB_WAITINGLOCKSTATE_CANCELLED;
+ goto found_lock_request;
+ }
+ }
+ }
+ found_lock_request:
+ lock_ReleaseWrite(&smb_globalLock);
+ }
+ code = 0;
+ smb_SetSMBDataLength(outp, 0);
+ goto done;
+ }
+
+
for (i=0; i<NumberOfUnlocks; i++) {
smb_GetLockParams(LockType, &op, &pid, &LOffset, &LLength);
wlRequest->inp = smb_CopyPacket(inp);
wlRequest->outp = smb_CopyPacket(outp);
wlRequest->lockType = LockType;
- wlRequest->timeRemaining = Timeout;
+ wlRequest->msTimeout = Timeout;
+ wlRequest->start_t = osi_Time();
wlRequest->locks = NULL;
/* The waiting lock request needs to have enough
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
doneSync:
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
afs_uint32 searchTime;
cm_user_t *userp;
cm_req_t req;
+ int readlock = 0;
cm_InitReq(&req);
/* otherwise, stat the file */
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ConvertWToR(&scp->rw);
+
/* decode times. We need a search time, but the response to this
* call provides the date first, not the time, as returned in the
* searchTime variable. So we take the high-order bits first.
code = 0;
done:
- lock_ReleaseMutex(&scp->mx);
+ if (readlock)
+ lock_ReleaseRead(&scp->rw);
+ else
+ lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
unsigned short fd;
unsigned pid;
smb_fid_t *fidp;
+ smb_t *smbp = (smb_t*) inp;
long code = 0;
cm_user_t *userp;
char *op;
LARGE_INTEGER LLength;
cm_scache_t * scp;
- pid = ((smb_t *) inp)->pid;
+ pid = smbp->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
LOffset.HighPart = offset.HighPart;
LLength.LowPart = count;
scp = fidp->scp;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_LockCheckWrite(scp, LOffset, LLength, key);
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
if (code)
goto done;
written = 0;
}
- done_writing:
-
/* slots 0 and 1 are reserved for request chaining and will be
filled in when we return. */
smb_SetSMBParm(outp, 2, total_written);
unsigned short fd;
unsigned pid;
smb_fid_t *fidp;
+ smb_t *smbp = (smb_t*) inp;
long code = 0;
cm_user_t *userp;
cm_key_t key;
return CM_ERROR_NOSUCHFILE;
}
- pid = ((smb_t *) inp)->pid;
+ pid = smbp->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
{
LARGE_INTEGER LOffset, LLength;
LLength.LowPart = count;
scp = fidp->scp;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_LockCheckRead(scp, LOffset, LLength, key);
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
}
if (code) {
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_LogSaveString(smb_logp,(lastNamep?lastNamep:"null")));
- if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) {
+ if (lastNamep &&
+ (stricmp(lastNamep, SMB_IOCTL_FILENAME) == 0 ||
+ stricmp(lastNamep, "\\srvsvc") == 0 ||
+ stricmp(lastNamep, "\\wkssvc") == 0 ||
+ stricmp(lastNamep, "ipc$") == 0)) {
/* special case magic file name for receiving IOCTL requests
* (since IOCTL calls themselves aren't getting through).
*/
fidflags = 0;
if (desiredAccess & DELETE)
fidflags |= SMB_FID_OPENDELETE;
- if (desiredAccess & AFS_ACCESS_READ)
+ if (desiredAccess & (AFS_ACCESS_READ|AFS_ACCESS_EXECUTE))
fidflags |= SMB_FID_OPENREAD_LISTDIR;
if (desiredAccess & AFS_ACCESS_WRITE)
fidflags |= SMB_FID_OPENWRITE;
if (code == 0) {
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
if (baseFidp)
smb_ReleaseFID(baseFidp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
userp, tidPathp, &req, &scp);
#ifdef DFS_SUPPORT
if (code == 0 && scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, realPathp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
free(realPathp);
if (baseFidp)
smb_ReleaseFID(baseFidp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (code == 0 && dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
if (scp)
cm_ReleaseSCache(scp);
cm_ReleaseSCache(dscp);
free(realPathp);
if (baseFidp)
smb_ReleaseFID(baseFidp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
LLength.LowPart = SMB_FID_QLOCK_LENGTH;
/* If we are not opening the file for writing, then we don't
- try to get an exclusive lock. Noone else should be able to
+ try to get an exclusive lock. No one else should be able to
get an exclusive lock on the file anyway, although someone
else can get a shared lock. */
if ((fidflags & SMB_FID_SHARE_READ) ||
key = cm_GenerateKey(vcp->vcID, SMB_FID_QLOCK_PID, fidp->fid);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_Lock(scp, sLockType, LOffset, LLength, key, 0, userp, &req, NULL);
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
if (code) {
if (ldp)
lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp; /* Hold transfered to fidp->scp and no longer needed */
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
osi_Log2(smb_logp,"smb_ReceiveNTCreateX fidp 0x%p scp 0x%p", fidp, scp);
fidp->flags = fidflags;
/* out parms */
parmSlot = 2;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */
smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
smb_SetSMBParmLong(outp, parmSlot, openAction); parmSlot += 2;
fidp->scp->length.LowPart, fidp->scp->length.HighPart,
userp);
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
osi_Log2(smb_logp, "SMB NT CreateX opening fid %d path %s", fidp->fid,
osi_LogSaveString(smb_logp, realPathp));
fidflags = 0;
if (desiredAccess & DELETE)
fidflags |= SMB_FID_OPENDELETE;
- if (desiredAccess & AFS_ACCESS_READ)
+ if (desiredAccess & (AFS_ACCESS_READ|AFS_ACCESS_EXECUTE))
fidflags |= SMB_FID_OPENREAD_LISTDIR;
if (desiredAccess & AFS_ACCESS_WRITE)
fidflags |= SMB_FID_OPENWRITE;
if (code == 0) {
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
if (baseFidp)
smb_ReleaseFID(baseFidp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
userp, tidPathp, &req, &scp);
#ifdef DFS_SUPPORT
if (code == 0 && scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, realPathp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
free(realPathp);
if (baseFidp)
smb_ReleaseFID(baseFidp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
userp, tidPathp, &req, &dscp);
#ifdef DFS_SUPPORT
if (code == 0 && dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
if (baseFidp)
smb_ReleaseFID(baseFidp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
key = cm_GenerateKey(vcp->vcID, SMB_FID_QLOCK_PID, fidp->fid);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_Lock(scp, sLockType, LOffset, LLength, key, 0, userp, &req, NULL);
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
if (code) {
if (ldp)
lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
osi_Log2(smb_logp,"smb_ReceiveNTTranCreate fidp 0x%p scp 0x%p", fidp, scp);
fidp->flags = fidflags;
smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */
smb_SetSMBDataLength(outp, 70);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
outData = smb_GetSMBData(outp, NULL);
outData++; /* round to get to parmOffset */
*outData = 0; outData++; /* oplock */
scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0);
outData += 2; /* is a dir? */
- lock_ReleaseMutex(&scp->mx);
} else {
/* out parms */
parmOffset = 8*4 + 39;
smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */
smb_SetSMBDataLength(outp, 105);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
outData = smb_GetSMBData(outp, NULL);
outData++; /* round to get to parmOffset */
*outData = 0; outData++; /* oplock */
memset(outData,0,24); outData += 24; /* Volume ID and file ID */
*((ULONG *)outData) = 0x001f01ffL; outData += 4; /* Maxmimal access rights */
*((ULONG *)outData) = 0; outData += 4; /* Guest Access rights */
- lock_ReleaseMutex(&scp->mx);
}
- lock_ObtainMutex(&scp->mx);
if ((fidp->flags & SMB_FID_EXECUTABLE) &&
LargeIntegerGreaterThanZero(fidp->scp->length) &&
!(scp->flags & CM_SCACHEFLAG_PREFETCHING)) {
fidp->scp->length.LowPart, fidp->scp->length.HighPart,
userp);
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
osi_Log1(smb_logp, "SMB NTTranCreate opening fid %d", fidp->fid);
if (filter & FILE_NOTIFY_CHANGE_STREAM_WRITE)
osi_Log0(smb_logp, " Notify Change Stream Write");
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
if (watchtree)
scp->flags |= CM_SCACHEFLAG_WATCHEDSUBTREE;
else
scp->flags |= CM_SCACHEFLAG_WATCHED;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
smb_ReleaseFID(fidp);
outp->flags |= SMB_PACKETFLAG_NOSEND;
break;
case 6:
return smb_ReceiveNTTranQuerySecurityDesc(vcp, inp, outp);
+ case 7:
+ osi_Log0(smb_logp, "SMB NT Transact Query Quota - not implemented");
+ break;
+ case 8:
+ osi_Log0(smb_logp, "SMB NT Transact Set Quota - not implemented");
+ break;
}
return CM_ERROR_INVAL;
}
lastWatch->nextp = nextWatch;
/* Turn off WATCHED flag in dscp */
- lock_ObtainMutex(&dscp->mx);
+ lock_ObtainWrite(&dscp->rw);
if (wtree)
dscp->flags &= ~CM_SCACHEFLAG_WATCHEDSUBTREE;
else
dscp->flags &= ~CM_SCACHEFLAG_WATCHED;
- lock_ReleaseMutex(&dscp->mx);
+ lock_ReleaseWrite(&dscp->rw);
/* Convert to response packet */
((smb_t *) watch)->reb = SMB_FLAGS_SERVER_TO_CLIENT;
scp = fidp->scp;
osi_Log2(smb_logp,"smb_ReceiveNTCancel fidp 0x%p scp 0x%p", fidp, scp);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
if (watchtree)
scp->flags &= ~CM_SCACHEFLAG_WATCHEDSUBTREE;
else
scp->flags &= ~CM_SCACHEFLAG_WATCHED;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
smb_ReleaseFID(fidp);
} else {
osi_Log2(smb_logp,"NTCancel unable to resolve fid [%d] in vcp[%x]", fid,vcp);