]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Windows: check perms before RXAFS_GetVolumeStatus
authorJeffrey Altman <jaltman@your-file-system.com>
Fri, 22 Jun 2012 04:25:26 +0000 (00:25 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Tue, 3 Jul 2012 16:28:06 +0000 (09:28 -0700)
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 <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>
src/WINNT/afsd/cm_ioctl.c
src/WINNT/afsd/cm_vnodeops.c
src/WINNT/afsd/cm_volume.c
src/WINNT/afsrdr/user/RDRFunction.c

index 1fc3abf6e6ca05751710a6dfb98559609841ceff..990ebfcaaf4cc6a67831447d60f7f635c94350e7 100644 (file)
@@ -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)
index cd9996935e63cf042294677a360aa7fea6a7aaec..1706b3b31f92bbd4279d32eeb1dee7b4c4acb6b2 100644 (file)
@@ -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);
index 00960360d4609a977ac73a4c08cb7111ac0e056b..1c181209cf132cc34e1dadbb5d8e5bcf61186b5a 100644 (file)
@@ -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);
index 849bd1465e36ea22ee059fea4476bc057108fedf..4eddf0115e45434156827481beb7171483fdd888 100644 (file)
@@ -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);