From 467ac5e32d5d57056e6e19a47bb69b9d8ac0ba2d Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 7 Aug 2008 06:35:36 +0000 Subject: [PATCH] windows-misc-20080806 LICENSE MIT Return CM_ERROR_READONLY if the caller wants PRSFS_DELETE and the volume is readonly. In cm_CheckNTDelete() do not call cm_SyncOpDone if cm_SyncOp failed Do not force the use of fake directory data if the user does not have PRSFS_READ on the directory. Let the bulkstatus call take place now that it is actually being used efficiently. In ApplyV3SearchDirPatches, use cm_SyncOp(CM_SCACHESYNC_GETSTATUS) to obtain the status info for Freelance entries instead of the bulkstatus call. Fix the truncation of 8.3 names in directory search responses. --- src/WINNT/afsd/cm_scache.c | 2 +- src/WINNT/afsd/cm_vnodeops.c | 3 ++- src/WINNT/afsd/smb.c | 4 +--- src/WINNT/afsd/smb3.c | 31 +++++++++++++++++++++---------- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index 1d44ec7..8b582c7 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -1245,7 +1245,7 @@ long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *userp, cm_req_t *req /* can't check access rights without a callback */ osi_assertx(flags & CM_SCACHESYNC_NEEDCALLBACK, "!CM_SCACHESYNC_NEEDCALLBACK"); - if ((rights & PRSFS_WRITE) && (scp->flags & CM_SCACHEFLAG_RO)) + if ((rights & (PRSFS_WRITE|PRSFS_DELETE)) && (scp->flags & CM_SCACHEFLAG_RO)) return CM_ERROR_READONLY; if (cm_HaveAccessRights(scp, userp, rights, &outRights) || !getAccessRights) { diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 0ba90ca..f8c9ba4 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -341,7 +341,8 @@ long cm_CheckNTDelete(cm_scache_t *dscp, cm_scache_t *scp, cm_user_t *userp, lock_ObtainWrite(&scp->rw); code = cm_SyncOp(scp, NULL, userp, reqp, PRSFS_DELETE, CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); - cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (!code) + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); lock_ReleaseWrite(&scp->rw); if (code) return code; diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index d0cff27..0b0ead2 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -4288,9 +4288,7 @@ smb_ApplyDirListPatches(cm_scache_t * dscp, smb_dirListPatch_t **dirPatchespp, afs_int32 mustFake = 0; code = cm_FindACLCache(dscp, userp, &rights); - if (code == 0 && !(rights & PRSFS_READ)) - mustFake = 1; - else if (code == -1) { + if (code == -1) { lock_ObtainWrite(&dscp->rw); code = cm_SyncOp(dscp, NULL, userp, reqp, PRSFS_READ, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 12fbfba..26b1650 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -4007,9 +4007,7 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp, smb_dirListPatch_t **dirPatchespp, clientchar_t path[AFSPATHMAX]; code = cm_FindACLCache(dscp, userp, &rights); - if (code == 0 && !(rights & PRSFS_READ)) - mustFake = 1; - else if (code == -1) { + if (code == -1) { lock_ObtainWrite(&dscp->rw); code = cm_SyncOp(dscp, NULL, userp, reqp, PRSFS_READ, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); @@ -4031,12 +4029,25 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp, smb_dirListPatch_t **dirPatchespp, for (patchp = *dirPatchespp, count=0; patchp; patchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q)) { - cm_scache_t *tscp = cm_FindSCache(&patchp->fid); + cm_scache_t *tscp = NULL; int i; - - if (tscp) { + + code = cm_GetSCache(&patchp->fid, &tscp, userp, reqp); + if (code == 0) { if (lock_TryWrite(&tscp->rw)) { /* we have an entry that we can look at */ +#ifdef AFS_FREELANCE_CLIENT + if (dscp->fid.cell == AFS_FAKE_ROOT_CELL_ID && dscp->fid.volume == AFS_FAKE_ROOT_VOL_ID) { + code = cm_SyncOp(tscp, NULL, userp, reqp, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code == 0) + cm_SyncOpDone(tscp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + + lock_ReleaseWrite(&tscp->rw); + cm_ReleaseSCache(tscp); + continue; + } +#endif /* AFS_FREELANCE_CLIENT */ if (!(tscp->flags & CM_SCACHEFLAG_EACCESS) && cm_HaveCallback(tscp)) { /* we have a callback on it. Don't bother * fetching this stat entry, since we're happy @@ -4617,11 +4628,11 @@ long smb_T2SearchDirSingle(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op #ifdef SMB_UNICODE int nchars; - nchars = cm_ClientStringToUtf16(shortName, -1, + nchars = cm_ClientStringToUtf16(shortName, cm_ClientStrLen(shortName), fp->u.FfileBothDirectoryInfo.shortName, sizeof(fp->u.FfileBothDirectoryInfo.shortName)/sizeof(wchar_t)); if (nchars > 0) - fp->u.FfileBothDirectoryInfo.shortNameLength = (nchars - 1)*sizeof(wchar_t); + fp->u.FfileBothDirectoryInfo.shortNameLength = nchars*sizeof(wchar_t); else fp->u.FfileBothDirectoryInfo.shortNameLength = 0; fp->u.FfileBothDirectoryInfo.reserved = 0; @@ -5315,11 +5326,11 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t #ifdef SMB_UNICODE int nchars; - nchars = cm_ClientStringToUtf16(shortName, -1, + nchars = cm_ClientStringToUtf16(shortName, cm_ClientStrLen(shortName), fp->u.FfileBothDirectoryInfo.shortName, sizeof(fp->u.FfileBothDirectoryInfo.shortName)/sizeof(wchar_t)); if (nchars > 0) - fp->u.FfileBothDirectoryInfo.shortNameLength = (nchars - 1)*sizeof(wchar_t); + fp->u.FfileBothDirectoryInfo.shortNameLength = nchars*sizeof(wchar_t); else fp->u.FfileBothDirectoryInfo.shortNameLength = 0; fp->u.FfileBothDirectoryInfo.reserved = 0; -- 1.9.4