From 05ac74528b30d36c195ff8f4df343fa72082a213 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Fri, 22 Jun 2012 00:25:26 -0400 Subject: [PATCH] Windows: check perms before RXAFS_GetVolumeStatus Instead of calling RXAFS_GetVolumeStatus naked, perform a read permission check using RXAFS_FetchStatus first. This permits EACCES caching to prevent unnecessary requests. Regardless of which FileId is queried, always use the root vnode FileId for the permission check. The file server performs its permission check using the root vnode. Change-Id: I3260bf0061beed5d95aae1d40e25d17be1811271 Reviewed-on: http://gerrit.openafs.org/7641 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsd/cm_ioctl.c | 48 ++++++++++++++++++++--------- src/WINNT/afsd/cm_vnodeops.c | 42 +++++++++++++++++-------- src/WINNT/afsd/cm_volume.c | 40 ++++++++++++++++-------- src/WINNT/afsrdr/user/RDRFunction.c | 13 ++++---- 4 files changed, 97 insertions(+), 46 deletions(-) diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index 1fc3abf6e..990ebfcaa 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -774,20 +774,40 @@ cm_IoctlGetVolumeStatus(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scach } else #endif { - Name = volName; - OfflineMsg = offLineMsg; - MOTD = motd; - do { - code = cm_ConnFromFID(&scp->fid, userp, reqp, &connp); - if (code) continue; - - rxconnp = cm_GetRxConn(connp); - code = RXAFS_GetVolumeStatus(rxconnp, scp->fid.volume, - &volStat, &Name, &OfflineMsg, &MOTD); - rx_PutConnection(rxconnp); - - } while (cm_Analyze(connp, userp, reqp, &scp->fid, NULL, 0, NULL, NULL, NULL, code)); - code = cm_MapRPCError(code, reqp); + cm_fid_t vfid; + cm_scache_t *vscp; + + cm_SetFid(&vfid, scp->fid.cell, scp->fid.volume, 1, 1); + code = cm_GetSCache(&vfid, NULL, &vscp, userp, reqp); + if (code) + return code; + + lock_ObtainWrite(&vscp->rw); + code = cm_SyncOp(vscp, NULL, userp, reqp, PRSFS_READ, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + lock_ReleaseWrite(&vscp->rw); + if (code) + return code; + + Name = volName; + OfflineMsg = offLineMsg; + MOTD = motd; + do { + code = cm_ConnFromFID(&vfid, userp, reqp, &connp); + if (code) continue; + + rxconnp = cm_GetRxConn(connp); + code = RXAFS_GetVolumeStatus(rxconnp, vfid.volume, + &volStat, &Name, &OfflineMsg, &MOTD); + rx_PutConnection(rxconnp); + + } while (cm_Analyze(connp, userp, reqp, &vfid, NULL, 0, NULL, NULL, NULL, code)); + code = cm_MapRPCError(code, reqp); + + lock_ObtainWrite(&vscp->rw); + cm_SyncOpDone(vscp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + lock_ReleaseWrite(&vscp->rw); + cm_ReleaseSCache(vscp); } if (code) diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index cd9996935..1706b3b31 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -2674,6 +2674,8 @@ cm_IsSpaceAvailable(cm_fid_t * fidp, osi_hyper_t *sizep, cm_user_t *userp, cm_re char offLineMsg[256]="server temporarily inaccessible"; char motd[256]="server temporarily inaccessible"; osi_hyper_t freespace; + cm_fid_t vfid; + cm_scache_t *vscp; if (fidp->cell==AFS_FAKE_ROOT_CELL_ID && fidp->volume==AFS_FAKE_ROOT_VOL_ID) @@ -2692,21 +2694,37 @@ cm_IsSpaceAvailable(cm_fid_t * fidp, osi_hyper_t *sizep, cm_user_t *userp, cm_re goto _done; } - Name = volName; - OfflineMsg = offLineMsg; - MOTD = motd; + cm_SetFid(&vfid, fidp->cell, fidp->volume, 1, 1); + code = cm_GetSCache(&vfid, NULL, &vscp, userp, reqp); + if (code == 0) { + lock_ObtainWrite(&vscp->rw); + code = cm_SyncOp(vscp, NULL, userp, reqp, PRSFS_READ, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + lock_ReleaseWrite(&vscp->rw); + if (code == 0) { + Name = volName; + OfflineMsg = offLineMsg; + MOTD = motd; - do { - code = cm_ConnFromFID(fidp, userp, reqp, &connp); - if (code) continue; + do { + code = cm_ConnFromFID(&vfid, userp, reqp, &connp); + if (code) continue; - rxconnp = cm_GetRxConn(connp); - code = RXAFS_GetVolumeStatus(rxconnp, fidp->volume, - &volStat, &Name, &OfflineMsg, &MOTD); - rx_PutConnection(rxconnp); + rxconnp = cm_GetRxConn(connp); + code = RXAFS_GetVolumeStatus(rxconnp, fidp->volume, + &volStat, &Name, &OfflineMsg, &MOTD); + rx_PutConnection(rxconnp); + + } while (cm_Analyze(connp, userp, reqp, &vfid, NULL, 0, NULL, NULL, NULL, code)); + code = cm_MapRPCError(code, reqp); + } + + lock_ObtainWrite(&vscp->rw); + cm_SyncOpDone(vscp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + lock_ReleaseWrite(&vscp->rw); + cm_ReleaseSCache(vscp); + } - } while (cm_Analyze(connp, userp, reqp, fidp, NULL, 0, NULL, NULL, NULL, code)); - code = cm_MapRPCError(code, reqp); if (code == 0) { if (volStat.MaxQuota) { freespace.QuadPart = 1024 * (afs_int64)min(volStat.MaxQuota - volStat.BlocksInUse, volStat.PartBlocksAvail); diff --git a/src/WINNT/afsd/cm_volume.c b/src/WINNT/afsd/cm_volume.c index 00960360d..1c181209c 100644 --- a/src/WINNT/afsd/cm_volume.c +++ b/src/WINNT/afsd/cm_volume.c @@ -1264,7 +1264,8 @@ cm_CheckOfflineVolumeState(cm_volume_t *volp, cm_vol_state_t *statep, afs_uint32 char motd[256]; long alldown, alldeleted; cm_serverRef_t *serversp; - cm_fid_t fid; + cm_fid_t vfid; + cm_scache_t *vscp = NULL; Name = volName; OfflineMsg = offLineMsg; @@ -1272,7 +1273,7 @@ cm_CheckOfflineVolumeState(cm_volume_t *volp, cm_vol_state_t *statep, afs_uint32 if (statep->ID != 0 && (!volID || volID == statep->ID)) { /* create fid for volume root so that VNOVOL and VMOVED errors can be processed */ - cm_SetFid(&fid, volp->cellp->cellID, statep->ID, 1, 1); + cm_SetFid(&vfid, volp->cellp->cellID, statep->ID, 1, 1); if (!statep->serversp && !(*volumeUpdatedp)) { cm_InitReq(&req); @@ -1308,20 +1309,33 @@ cm_CheckOfflineVolumeState(cm_volume_t *volp, cm_vol_state_t *statep, afs_uint32 (!alldown && statep->state == vl_alldown)) { cm_InitReq(&req); req.flags |= CM_REQ_OFFLINE_VOL_CHK; - lock_ReleaseWrite(&volp->rw); - do { - code = cm_ConnFromVolume(volp, statep->ID, cm_rootUserp, &req, &connp); - if (code) - continue; - rxconnp = cm_GetRxConn(connp); - code = RXAFS_GetVolumeStatus(rxconnp, statep->ID, - &volStat, &Name, &OfflineMsg, &MOTD); - rx_PutConnection(rxconnp); - } while (cm_Analyze(connp, cm_rootUserp, &req, &fid, NULL, 0, NULL, NULL, NULL, code)); - code = cm_MapRPCError(code, &req); + code = cm_GetSCache(&vfid, NULL, &vscp, cm_rootUserp, &req); + if (code = 0) { + lock_ObtainWrite(&vscp->rw); + code = cm_SyncOp(vscp, NULL, cm_rootUserp, &req, PRSFS_READ, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + lock_ReleaseWrite(&vscp->rw); + if (code == 0) { + do { + code = cm_ConnFromVolume(volp, statep->ID, cm_rootUserp, &req, &connp); + if (code) + continue; + + rxconnp = cm_GetRxConn(connp); + code = RXAFS_GetVolumeStatus(rxconnp, statep->ID, + &volStat, &Name, &OfflineMsg, &MOTD); + rx_PutConnection(rxconnp); + } while (cm_Analyze(connp, cm_rootUserp, &req, &vfid, NULL, 0, NULL, NULL, NULL, code)); + code = cm_MapRPCError(code, &req); + } + lock_ObtainWrite(&vscp->rw); + cm_SyncOpDone(vscp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + lock_ReleaseWrite(&vscp->rw); + cm_ReleaseSCache(vscp); + } lock_ObtainWrite(&volp->rw); if (code == 0 && volStat.Online) { cm_VolumeStatusNotification(volp, statep->ID, statep->state, vl_online); diff --git a/src/WINNT/afsrdr/user/RDRFunction.c b/src/WINNT/afsrdr/user/RDRFunction.c index 849bd1465..4eddf0115 100644 --- a/src/WINNT/afsrdr/user/RDRFunction.c +++ b/src/WINNT/afsrdr/user/RDRFunction.c @@ -5018,7 +5018,7 @@ RDR_GetVolumeInfo( IN cm_user_t *userp, } lock_ObtainWrite(&scp->rw); - code = cm_SyncOp(scp, NULL, userp, &req, 0, + code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_READ, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); if (code) { lock_ReleaseWrite(&scp->rw); @@ -5107,11 +5107,10 @@ RDR_GetVolumeInfo( IN cm_user_t *userp, } else { pResultCB->TotalAllocationUnits.QuadPart = 0x7FFFFFFF; pResultCB->AvailableAllocationUnits.QuadPart = (volType == ROVOL || volType == BACKVOL) ? 0 : 0x3F000000; - - pResultCB->VolumeLabelLength = cm_Utf8ToUtf16( volp->namep, -1, pResultCB->VolumeLabel, - (sizeof(pResultCB->VolumeLabel) / sizeof(WCHAR)) + 1); - code = 0; } + + pResultCB->VolumeLabelLength = cm_Utf8ToUtf16( volp->namep, -1, pResultCB->VolumeLabel, + (sizeof(pResultCB->VolumeLabel) / sizeof(WCHAR)) + 1); if ( pResultCB->VolumeLabelLength ) pResultCB->VolumeLabelLength--; @@ -5204,8 +5203,8 @@ RDR_GetVolumeSizeInfo( IN cm_user_t *userp, } lock_ObtainWrite(&scp->rw); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_READ, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); if (code) { lock_ReleaseWrite(&scp->rw); smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE); -- 2.39.5