From f3c4bbd41a06aeced5536f55e949767169b906d2 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Wed, 31 Jan 2007 17:02:02 +0000 Subject: [PATCH] windows-delete-test-file-not-dir-20070131 the cm_CheckNTDelete function was testing the permissions of the directory and not the permissions of the file being deleted. This resulted in inconsistencies between the attributes of the file and the ability to delete it. this patch also adds a large amount of trace log entries as there was none in this section of the code before. --- src/WINNT/afsd/cm_access.c | 25 ++++++++++++++++++------- src/WINNT/afsd/cm_scache.c | 4 ++-- src/WINNT/afsd/cm_vnodeops.c | 8 ++++---- src/WINNT/afsd/smb3.c | 20 +++++++++++++++++++- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/WINNT/afsd/cm_access.c b/src/WINNT/afsd/cm_access.c index 5b9d6bd88f..3b16c101e5 100644 --- a/src/WINNT/afsd/cm_access.c +++ b/src/WINNT/afsd/cm_access.c @@ -88,13 +88,24 @@ int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *userp, afs_uint32 *outRightsp = trights; } - /* check mode bits */ - if (!(scp->unixModeBits & 0400)) - *outRightsp &= ~PRSFS_READ; - if (!(scp->unixModeBits & 0200) && !(rights == (PRSFS_WRITE | PRSFS_LOCK))) - *outRightsp &= ~PRSFS_WRITE; - if (!(scp->unixModeBits & 0200) && !cm_deleteReadOnly) - *outRightsp &= ~PRSFS_DELETE; + if (scp->fileType != CM_SCACHETYPE_DIRECTORY) { + /* check mode bits */ + if ((scp->unixModeBits & 0400) == 0) { + osi_Log2(afsd_logp,"cm_HaveAccessRights UnixMode removing READ scp 0x%p unix 0x%x", + scp, scp->unixModeBits); + *outRightsp &= ~PRSFS_READ; + } + if ((scp->unixModeBits & 0200) == 0 && (rights != (PRSFS_WRITE | PRSFS_LOCK))) { + osi_Log2(afsd_logp,"cm_HaveAccessRights UnixMode removing WRITE scp 0x%p unix 0%o", + scp, scp->unixModeBits); + *outRightsp &= ~PRSFS_WRITE; + } + if ((scp->unixModeBits & 0200) == 0 && !cm_deleteReadOnly) { + osi_Log2(afsd_logp,"cm_HaveAccessRights UnixMode removing DELETE scp 0x%p unix 0%o", + scp, scp->unixModeBits); + *outRightsp &= ~PRSFS_DELETE; + } + } /* if the user can obtain a write-lock, read-locks are implied */ if (*outRightsp & PRSFS_WRITE) diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index 459b2a9a31..d678e54edb 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -653,7 +653,7 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, lock_ReleaseMutex(&cm_Freelance_Lock); scp->owner=0x0; - scp->unixModeBits=0x1ff; + scp->unixModeBits=0777; scp->clientModTime=FakeFreelanceModTime; scp->serverModTime=FakeFreelanceModTime; scp->parentUnique = 0x1; @@ -1298,7 +1298,7 @@ void cm_MergeStatus(cm_scache_t *scp, AFSFetchStatus *statusp, AFSVolSync *volp, statusp->Owner = 0x0; statusp->CallerAccess = 0x9; statusp->AnonymousAccess = 0x9; - statusp->UnixModeBits = 0x1ff; + statusp->UnixModeBits = 0777; statusp->ParentVnode = 0x1; statusp->ParentUnique = 0x1; statusp->ResidencyMask = 0; diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 509fe4f37d..9d0432237f 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -479,11 +479,11 @@ long cm_CheckNTDelete(cm_scache_t *dscp, cm_scache_t *scp, cm_user_t *userp, int BeyondPage = 0, HaveDot = 0, HaveDotDot = 0; /* First check permissions */ - lock_ObtainMutex(&dscp->mx); - code = cm_SyncOp(dscp, NULL, userp, reqp, PRSFS_DELETE, + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, reqp, PRSFS_DELETE, CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); - cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - lock_ReleaseMutex(&dscp->mx); + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + lock_ReleaseMutex(&scp->mx); if (code) return code; diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 83cd3366b0..12295da3fc 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -3311,7 +3311,10 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet } lock_ObtainMutex(&fidp->mx); - if (infoLevel == SMB_SET_FILE_DISPOSITION_INFO && !(fidp->flags & SMB_FID_OPENDELETE)) { + if (infoLevel == SMB_SET_FILE_DISPOSITION_INFO && + !(fidp->flags & SMB_FID_OPENDELETE)) { + osi_Log3(smb_logp,"smb_ReceiveTran2SetFileInfo !SMB_FID_OPENDELETE fidp 0x%p scp 0x%p fidp->flags 0x%x", + fidp, scp, fidp->flags); lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOACCESS); @@ -3320,6 +3323,8 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet if ((infoLevel == SMB_SET_FILE_ALLOCATION_INFO || infoLevel == SMB_SET_FILE_END_OF_FILE_INFO) && !(fidp->flags & SMB_FID_OPENWRITE)) { + osi_Log3(smb_logp,"smb_ReceiveTran2SetFileInfo !SMB_FID_OPENWRITE fidp 0x%p scp 0x%p fidp->flags 0x%x", + fidp, scp, fidp->flags); lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOACCESS); @@ -3409,6 +3414,9 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet code = 0; } else if (infoLevel == SMB_SET_FILE_DISPOSITION_INFO) { + int delflag = *((char *)(p->datap)); + osi_Log3(smb_logp,"smb_ReceiveTran2SetFileInfo Delete? %d fidp 0x%p scp 0x%p", + delflag, fidp, scp); if (*((char *)(p->datap))) { /* File is Deleted */ code = cm_CheckNTDelete(fidp->NTopen_dscp, scp, userp, &req); @@ -3416,6 +3424,9 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet lock_ObtainMutex(&fidp->mx); fidp->flags |= SMB_FID_DELONCLOSE; lock_ReleaseMutex(&fidp->mx); + } else { + osi_Log3(smb_logp,"smb_ReceiveTran2SetFileInfo CheckNTDelete fidp 0x%p scp 0x%p code 0x%x", + fidp, scp, code); } } else { @@ -5751,6 +5762,13 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) code = cm_Lock(scp, LockType, LOffset, LLength, key, (Timeout != 0), userp, &req, &lockp); + if (code == CM_ERROR_NOACCESS && LockType == LockWrite && + (fidp->flags & (SMB_FID_OPENREAD_LISTDIR | SMB_FID_OPENWRITE)) == SMB_FID_OPENREAD_LISTDIR) + { + code = cm_Lock(scp, LockRead, LOffset, LLength, key, (Timeout != 0), + userp, &req, &lockp); + } + if (code == CM_ERROR_WOULDBLOCK && Timeout != 0) { smb_waitingLock_t * wLock;