Windows: RDR Dynamic root Freelance only
[openafs.git] / src / WINNT / afsrdr / user / RDRIoctl.c
index bb2f6a0..ed7e43f 100644 (file)
@@ -74,6 +74,14 @@ static osi_rwlock_t  RDR_globalIoctlLock;
 
 extern wchar_t       RDR_UNCName[];
 
+static afs_int32
+RDR_ParseIoctlPath(RDR_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
+                   cm_scache_t **scpp, afs_uint32 flags);
+
+static afs_int32
+RDR_ParseIoctlParent(RDR_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
+                     cm_scache_t **scpp, wchar_t *leafp);
+
 void
 RDR_InitIoctl(void)
 {
@@ -141,6 +149,7 @@ RDR_InitIoctl(void)
     RDR_ioctlProcsp[VIOC_SETUNIXMODE] = RDR_IoctlSetUnixMode;
     RDR_ioctlProcsp[VIOC_GETVERIFYDATA] = RDR_IoctlGetVerifyData;
     RDR_ioctlProcsp[VIOC_SETVERIFYDATA] = RDR_IoctlSetVerifyData;
+    RDR_ioctlProcsp[VIOC_GETCALLERACCESS] = RDR_IoctlGetCallerAccess;
 }
 
 void
@@ -151,12 +160,9 @@ RDR_ShutdownIoctl(void)
 
 /* called to make a fid structure into an IOCTL fid structure */
 void
-RDR_SetupIoctl(ULONG index, cm_fid_t *parentFid, cm_fid_t *rootFid, cm_user_t *userp)
+RDR_SetupIoctl(ULONG index, cm_fid_t *parentFid, cm_fid_t *rootFid, cm_user_t *userp, cm_req_t *reqp)
 {
     RDR_ioctl_t *iop;
-    cm_req_t req;
-
-    cm_InitReq(&req);
 
     lock_ObtainWrite(&RDR_globalIoctlLock);
     for ( iop=RDR_allIoctls; iop; iop=iop->next) {
@@ -166,6 +172,7 @@ RDR_SetupIoctl(ULONG index, cm_fid_t *parentFid, cm_fid_t *rootFid, cm_user_t *u
 
     if (iop) {
         iop->flags = 0;
+        iop->req = *reqp;
 
         /* we are reusing a previous ioctl */
         if (cm_FidCmp(&iop->parentFid, parentFid)) {
@@ -174,7 +181,7 @@ RDR_SetupIoctl(ULONG index, cm_fid_t *parentFid, cm_fid_t *rootFid, cm_user_t *u
                 cm_ReleaseSCache(iop->parentScp);
                 iop->parentScp = NULL;
             }
-            cm_GetSCache(parentFid, NULL, &iop->parentScp, userp, &req);
+            cm_GetSCache(parentFid, NULL, &iop->parentScp, userp, reqp);
             iop->rootFid = *rootFid;
         }
     } else {
@@ -189,13 +196,14 @@ RDR_SetupIoctl(ULONG index, cm_fid_t *parentFid, cm_fid_t *rootFid, cm_user_t *u
             RDR_allIoctlsLast = iop;
         }
         iop->index = index;
+        iop->req = *reqp;
         if (parentFid->cell == 0) {
             iop->parentFid = cm_data.rootFid;
-            iop->parentScp = cm_RootSCachep(userp, &req);
+            iop->parentScp = cm_RootSCachep(userp, reqp);
             cm_HoldSCache(iop->parentScp);
         } else {
             iop->parentFid = *parentFid;
-            cm_GetSCache(parentFid, NULL, &iop->parentScp, userp, &req);
+            cm_GetSCache(parentFid, NULL, &iop->parentScp, userp, reqp);
         }
         if (rootFid->cell == 0) {
             iop->rootFid = cm_data.rootFid;
@@ -365,7 +373,7 @@ RDR_ReleaseIoctl(RDR_ioctl_t * iop)
 
 /* called from RDR_ReceiveCoreRead when we receive a read on the ioctl fid */
 afs_int32
-RDR_IoctlRead(cm_user_t *userp, ULONG RequestId, ULONG BufferLength, void *MappedBuffer, ULONG *pBytesProcessed, cm_req_t *reqp, afs_uint32 pflags)
+RDR_IoctlRead(cm_user_t *userp, ULONG RequestId, ULONG BufferLength, void *MappedBuffer, ULONG *pBytesProcessed, afs_uint32 pflags)
 {
     RDR_ioctl_t *iop;
     afs_uint32 count;
@@ -396,11 +404,11 @@ RDR_IoctlRead(cm_user_t *userp, ULONG RequestId, ULONG BufferLength, void *Mappe
     return code;
 }
 
-/* called from RDR_PioctWRite when we receive a write call on the IOCTL
+/* called from RDR_PioctWrite when we receive a write call on the IOCTL
  * file descriptor.
  */
 afs_int32
-RDR_IoctlWrite(cm_user_t *userp, ULONG RequestId, ULONG BufferLength, void *MappedBuffer, cm_req_t *reqp)
+RDR_IoctlWrite(cm_user_t *userp, ULONG RequestId, ULONG BufferLength, void *MappedBuffer)
 {
     afs_int32 code = 0;
     RDR_ioctl_t *iop;
@@ -433,7 +441,7 @@ RDR_IoctlWrite(cm_user_t *userp, ULONG RequestId, ULONG BufferLength, void *Mapp
  */
 #define CM_PARSE_FLAG_LITERAL 1
 
-afs_int32
+static afs_int32
 RDR_ParseIoctlPath(RDR_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
                    cm_scache_t **scpp, afs_uint32 flags)
 {
@@ -677,13 +685,11 @@ RDR_ParseIoctlPath(RDR_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
     return 0;
 }
 
-
-
 #define LEAF_SIZE 256
 /* parse the passed-in file name and do a namei on its parent.  If we fail,
  * return an error code, otherwise return the vnode located in *scpp.
  */
-afs_int32
+static afs_int32
 RDR_ParseIoctlParent(RDR_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
                      cm_scache_t **scpp, wchar_t *leafp)
 {
@@ -1100,12 +1106,9 @@ RDR_IoctlGetACL(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
 {
     cm_scache_t *scp;
     afs_int32 code;
-    cm_req_t req;
     cm_ioctlQueryOptions_t *optionsp;
     afs_uint32 flags = 0;
 
-    cm_InitReq(&req);
-
     optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
     if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
         flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
@@ -1115,14 +1118,14 @@ RDR_IoctlGetACL(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
         cm_SkipIoctlPath(&ioctlp->ioctl);
         cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
                   optionsp->fid.vnode, optionsp->fid.unique);
-        code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
+        code = cm_GetSCache(&fid, NULL, &scp, userp, &ioctlp->req);
     } else {
-        code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+        code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
     }
     if (code)
         return code;
 
-    code = cm_IoctlGetACL(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlGetACL(&ioctlp->ioctl, userp, scp, &ioctlp->req);
 
     cm_ReleaseSCache(scp);
     return code;
@@ -1133,17 +1136,14 @@ RDR_IoctlSetACL(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
 {
     cm_scache_t *scp;
     afs_int32 code;
-    cm_req_t req;
 
     afs_uint32 flags = 0;
 
-    cm_InitReq(&req);
-
-    code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+    code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
     if (code)
         return code;
 
-    code = cm_IoctlSetACL(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlSetACL(&ioctlp->ioctl, userp, scp, &ioctlp->req);
 
     cm_ReleaseSCache(scp);
     return code;
@@ -1154,12 +1154,9 @@ RDR_IoctlGetFileCellName(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_ui
 {
     afs_int32 code;
     cm_scache_t *scp;
-    cm_req_t req;
     cm_ioctlQueryOptions_t *optionsp;
     afs_uint32 flags = 0;
 
-    cm_InitReq(&req);
-
     optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
     if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
         flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
@@ -1169,14 +1166,14 @@ RDR_IoctlGetFileCellName(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_ui
         cm_SkipIoctlPath(&ioctlp->ioctl);
         cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
                   optionsp->fid.vnode, optionsp->fid.unique);
-        code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
+        code = cm_GetSCache(&fid, NULL, &scp, userp, &ioctlp->req);
     } else {
-        code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+        code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
     }
     if (code)
         return code;
 
-    code = cm_IoctlGetFileCellName(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlGetFileCellName(&ioctlp->ioctl, userp, scp, &ioctlp->req);
 
     cm_ReleaseSCache(scp);
 
@@ -1186,13 +1183,9 @@ RDR_IoctlGetFileCellName(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_ui
 afs_int32
 RDR_IoctlFlushAllVolumes(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
-    cm_req_t req;
-
-    cm_InitReq(&req);
-
     cm_SkipIoctlPath(&ioctlp->ioctl);  /* we don't care about the path */
 
-    return cm_IoctlFlushAllVolumes(&ioctlp->ioctl, userp, &req);
+    return cm_IoctlFlushAllVolumes(&ioctlp->ioctl, userp, &ioctlp->req);
 }
 
 afs_int32
@@ -1200,12 +1193,9 @@ RDR_IoctlFlushVolume(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32
 {
     afs_int32 code;
     cm_scache_t *scp;
-    cm_req_t req;
     cm_ioctlQueryOptions_t *optionsp;
     afs_uint32 flags = 0;
 
-    cm_InitReq(&req);
-
     optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
     if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
         flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
@@ -1215,14 +1205,14 @@ RDR_IoctlFlushVolume(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32
         cm_SkipIoctlPath(&ioctlp->ioctl);
         cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
                   optionsp->fid.vnode, optionsp->fid.unique);
-        code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
+        code = cm_GetSCache(&fid, NULL, &scp, userp, &ioctlp->req);
     } else {
-        code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+        code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
     }
     if (code)
         return code;
 
-    code = cm_IoctlFlushVolume(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlFlushVolume(&ioctlp->ioctl, userp, scp, &ioctlp->req);
 
     cm_ReleaseSCache(scp);
 
@@ -1234,12 +1224,9 @@ RDR_IoctlFlushFile(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 p
 {
     afs_int32 code;
     cm_scache_t *scp;
-    cm_req_t req;
     cm_ioctlQueryOptions_t *optionsp;
     afs_uint32 flags = 0;
 
-    cm_InitReq(&req);
-
     optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
     if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
         flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
@@ -1249,14 +1236,14 @@ RDR_IoctlFlushFile(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 p
         cm_SkipIoctlPath(&ioctlp->ioctl);
        cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
                   optionsp->fid.vnode, optionsp->fid.unique);
-        code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
+        code = cm_GetSCache(&fid, NULL, &scp, userp, &ioctlp->req);
     } else {
-        code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+        code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
     }
     if (code)
         return code;
 
-    code = cm_IoctlFlushFile(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlFlushFile(&ioctlp->ioctl, userp, scp, &ioctlp->req);
 
     cm_ReleaseSCache(scp);
     return code;
@@ -1267,14 +1254,11 @@ RDR_IoctlSetVolumeStatus(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_ui
 {
     afs_int32 code;
     cm_scache_t *scp;
-    cm_req_t req;
 
-    cm_InitReq(&req);
-
-    code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, 0);
+    code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, 0);
     if (code) return code;
 
-    code = cm_IoctlSetVolumeStatus(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlSetVolumeStatus(&ioctlp->ioctl, userp, scp, &ioctlp->req);
     cm_ReleaseSCache(scp);
 
     return code;
@@ -1287,9 +1271,6 @@ RDR_IoctlGetVolumeStatus(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_ui
     cm_scache_t *scp;
     cm_ioctlQueryOptions_t *optionsp;
     afs_uint32 flags = 0;
-    cm_req_t req;
-
-    cm_InitReq(&req);
 
     optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
     if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
@@ -1300,14 +1281,14 @@ RDR_IoctlGetVolumeStatus(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_ui
         cm_SkipIoctlPath(&ioctlp->ioctl);
         cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
                   optionsp->fid.vnode, optionsp->fid.unique);
-        code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
+        code = cm_GetSCache(&fid, NULL, &scp, userp, &ioctlp->req);
     } else {
-        code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+        code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
     }
     if (code)
         return code;
 
-    code = cm_IoctlGetVolumeStatus(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlGetVolumeStatus(&ioctlp->ioctl, userp, scp, &ioctlp->req);
 
     cm_ReleaseSCache(scp);
 
@@ -1319,21 +1300,18 @@ RDR_IoctlGetFid(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pfla
 {
     afs_int32 code;
     cm_scache_t *scp;
-    cm_req_t req;
     cm_ioctlQueryOptions_t * optionsp;
     afs_uint32 flags = 0;
 
-    cm_InitReq(&req);
-
     optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
     if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
         flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
 
-    code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+    code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
     if (code)
         return code;
 
-    code = cm_IoctlGetFid(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlGetFid(&ioctlp->ioctl, userp, scp, &ioctlp->req);
 
     cm_ReleaseSCache(scp);
 
@@ -1345,12 +1323,9 @@ RDR_IoctlGetFileType(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32
 {
     afs_int32 code;
     cm_scache_t *scp;
-    cm_req_t req;
     cm_ioctlQueryOptions_t * optionsp;
     afs_uint32 flags = 0;
 
-    cm_InitReq(&req);
-
     optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
     if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
         flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
@@ -1360,14 +1335,14 @@ RDR_IoctlGetFileType(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32
         cm_SkipIoctlPath(&ioctlp->ioctl);
         cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
                   optionsp->fid.vnode, optionsp->fid.unique);
-        code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
+        code = cm_GetSCache(&fid, NULL, &scp, userp, &ioctlp->req);
     } else {
-        code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+        code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
     }
     if (code)
         return code;
 
-    code = cm_IoctlGetFileType(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlGetFileType(&ioctlp->ioctl, userp, scp, &ioctlp->req);
 
     cm_ReleaseSCache(scp);
 
@@ -1379,12 +1354,9 @@ RDR_IoctlGetOwner(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pf
 {
     afs_int32 code;
     cm_scache_t *scp;
-    cm_req_t req;
     cm_ioctlQueryOptions_t *optionsp;
     afs_uint32 flags = 0;
 
-    cm_InitReq(&req);
-
     optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
     if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
         flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
@@ -1394,14 +1366,14 @@ RDR_IoctlGetOwner(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pf
         cm_SkipIoctlPath(&ioctlp->ioctl);
         cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
                   optionsp->fid.vnode, optionsp->fid.unique);
-        code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
+        code = cm_GetSCache(&fid, NULL, &scp, userp, &ioctlp->req);
     } else {
-        code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+        code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
     }
     if (code)
         return code;
 
-    code = cm_IoctlGetOwner(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlGetOwner(&ioctlp->ioctl, userp, scp, &ioctlp->req);
 
     cm_ReleaseSCache(scp);
 
@@ -1413,12 +1385,9 @@ RDR_IoctlWhereIs(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pfl
 {
     afs_int32 code;
     cm_scache_t *scp;
-    cm_req_t req;
     cm_ioctlQueryOptions_t *optionsp;
     afs_uint32 flags = 0;
 
-    cm_InitReq(&req);
-
     optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
     if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
         flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
@@ -1428,14 +1397,14 @@ RDR_IoctlWhereIs(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pfl
         cm_SkipIoctlPath(&ioctlp->ioctl);
         cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
                   optionsp->fid.vnode, optionsp->fid.unique);
-        code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
+        code = cm_GetSCache(&fid, NULL, &scp, userp, &ioctlp->req);
     } else {
-        code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+        code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
     }
     if (code)
         return code;
 
-    code = cm_IoctlWhereIs(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlWhereIs(&ioctlp->ioctl, userp, scp, &ioctlp->req);
 
     cm_ReleaseSCache(scp);
 
@@ -1448,15 +1417,12 @@ RDR_IoctlStatMountPoint(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uin
 {
     afs_int32 code;
     cm_scache_t *dscp;
-    cm_req_t req;
 
-    cm_InitReq(&req);
-
-    code = RDR_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
+    code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &dscp, 0);
     if (code)
         return code;
 
-    code = cm_IoctlStatMountPoint(&ioctlp->ioctl, userp, dscp, &req);
+    code = cm_IoctlStatMountPoint(&ioctlp->ioctl, userp, dscp, &ioctlp->req);
 
     cm_ReleaseSCache(dscp);
 
@@ -1468,15 +1434,12 @@ RDR_IoctlDeleteMountPoint(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_u
 {
     afs_int32 code;
     cm_scache_t *dscp;
-    cm_req_t req;
-
-    cm_InitReq(&req);
 
-    code = RDR_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
+    code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &dscp, 0);
     if (code)
         return code;
 
-    code = cm_IoctlDeleteMountPoint(&ioctlp->ioctl, userp, dscp, &req);
+    code = cm_IoctlDeleteMountPoint(&ioctlp->ioctl, userp, dscp, &ioctlp->req);
 
     cm_ReleaseSCache(dscp);
 
@@ -1617,15 +1580,12 @@ RDR_IoctlCreateMountPoint(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_u
     afs_int32 code;
     cm_scache_t *dscp;
     wchar_t leaf[LEAF_SIZE];
-    cm_req_t req;
 
-    cm_InitReq(&req);
-
-    code = RDR_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
+    code = RDR_ParseIoctlParent(ioctlp, userp, &ioctlp->req, &dscp, leaf);
     if (code)
         return code;
 
-    code = cm_IoctlCreateMountPoint(&ioctlp->ioctl, userp, dscp, &req, leaf);
+    code = cm_IoctlCreateMountPoint(&ioctlp->ioctl, userp, dscp, &ioctlp->req, leaf);
 
     cm_ReleaseSCache(dscp);
     return code;
@@ -1637,14 +1597,11 @@ RDR_IoctlSymlink(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pfl
     afs_int32 code;
     cm_scache_t *dscp;
     wchar_t leaf[LEAF_SIZE];
-    cm_req_t req;
-
-    cm_InitReq(&req);
 
-    code = RDR_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
+    code = RDR_ParseIoctlParent(ioctlp, userp, &ioctlp->req, &dscp, leaf);
     if (code) return code;
 
-    code = cm_IoctlSymlink(&ioctlp->ioctl, userp, dscp, &req, leaf);
+    code = cm_IoctlSymlink(&ioctlp->ioctl, userp, dscp, &ioctlp->req, leaf);
 
     cm_ReleaseSCache(dscp);
 
@@ -1656,14 +1613,11 @@ RDR_IoctlListlink(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pf
 {
     afs_int32 code;
     cm_scache_t *dscp;
-    cm_req_t req;
 
-    cm_InitReq(&req);
-
-    code = RDR_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
+    code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &dscp, 0);
     if (code) return code;
 
-    code = cm_IoctlListlink(&ioctlp->ioctl, userp, dscp, &req);
+    code = cm_IoctlListlink(&ioctlp->ioctl, userp, dscp, &ioctlp->req);
 
     cm_ReleaseSCache(dscp);
     return code;
@@ -1674,14 +1628,11 @@ RDR_IoctlIslink(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pfla
 {/*CHECK FOR VALID SYMLINK*/
     afs_int32 code;
     cm_scache_t *dscp;
-    cm_req_t req;
-
-    cm_InitReq(&req);
 
-    code = RDR_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
+    code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &dscp, 0);
     if (code) return code;
 
-    code = cm_IoctlIslink(&ioctlp->ioctl, userp, dscp, &req);
+    code = cm_IoctlIslink(&ioctlp->ioctl, userp, dscp, &ioctlp->req);
 
     cm_ReleaseSCache(dscp);
 
@@ -1693,14 +1644,11 @@ RDR_IoctlDeletelink(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32
 {
     afs_int32 code;
     cm_scache_t *dscp;
-    cm_req_t req;
 
-    cm_InitReq(&req);
-
-    code = RDR_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
+    code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &dscp, 0);
     if (code) return code;
 
-    code = cm_IoctlDeletelink(&ioctlp->ioctl, userp, dscp, &req);
+    code = cm_IoctlDeletelink(&ioctlp->ioctl, userp, dscp, &ioctlp->req);
 
     cm_ReleaseSCache(dscp);
 
@@ -1813,12 +1761,9 @@ RDR_IoctlPathAvailability(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_u
 {
     afs_int32 code;
     cm_scache_t *scp;
-    cm_req_t req;
     cm_ioctlQueryOptions_t *optionsp;
     afs_uint32 flags = 0;
 
-    cm_InitReq(&req);
-
     optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
     if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
         flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
@@ -1828,14 +1773,14 @@ RDR_IoctlPathAvailability(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_u
         cm_SkipIoctlPath(&ioctlp->ioctl);
         cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
                   optionsp->fid.vnode, optionsp->fid.unique);
-        code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
+        code = cm_GetSCache(&fid, NULL, &scp, userp, &ioctlp->req);
     } else {
-        code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+        code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
     }
     if (code)
         return code;
 
-    code = cm_IoctlPathAvailability(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlPathAvailability(&ioctlp->ioctl, userp, scp, &ioctlp->req);
     cm_ReleaseSCache(scp);
     return code;
 }
@@ -1843,13 +1788,9 @@ RDR_IoctlPathAvailability(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_u
 afs_int32
 RDR_IoctlVolStatTest(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
-    cm_req_t req;
-
-    cm_InitReq(&req);
-
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
-    return cm_IoctlVolStatTest(&ioctlp->ioctl, userp, &req);
+    return cm_IoctlVolStatTest(&ioctlp->ioctl, userp, &ioctlp->req);
 }
 
 /*
@@ -1863,12 +1804,9 @@ RDR_IoctlSetOwner(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pf
 {
     afs_int32 code;
     cm_scache_t *scp;
-    cm_req_t req;
     cm_ioctlQueryOptions_t *optionsp;
     afs_uint32 flags = 0;
 
-    smb_InitReq(&req);
-
     optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
     if (optionsp) {
         if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
@@ -1879,9 +1817,9 @@ RDR_IoctlSetOwner(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pf
             cm_SkipIoctlPath(&ioctlp->ioctl);
             cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
                        optionsp->fid.vnode, optionsp->fid.unique);
-            code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
+            code = cm_GetSCache(&fid, NULL, &scp, userp, &ioctlp->req);
         } else {
-            code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+            code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
         }
         if (code)
             return code;
@@ -1889,7 +1827,7 @@ RDR_IoctlSetOwner(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pf
         cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
     }
 
-    code = cm_IoctlSetOwner(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlSetOwner(&ioctlp->ioctl, userp, scp, &ioctlp->req);
 
     cm_ReleaseSCache(scp);
 
@@ -1907,12 +1845,9 @@ RDR_IoctlSetGroup(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pf
 {
     afs_int32 code;
     cm_scache_t *scp;
-    cm_req_t req;
     cm_ioctlQueryOptions_t *optionsp;
     afs_uint32 flags = 0;
 
-    smb_InitReq(&req);
-
     optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
     if (optionsp) {
         if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
@@ -1923,9 +1858,9 @@ RDR_IoctlSetGroup(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pf
             cm_SkipIoctlPath(&ioctlp->ioctl);
             cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
                        optionsp->fid.vnode, optionsp->fid.unique);
-            code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
+            code = cm_GetSCache(&fid, NULL, &scp, userp, &ioctlp->req);
         } else {
-            code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+            code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
         }
         if (code)
             return code;
@@ -1933,7 +1868,7 @@ RDR_IoctlSetGroup(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pf
         cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
     }
 
-    code = cm_IoctlSetGroup(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlSetGroup(&ioctlp->ioctl, userp, scp, &ioctlp->req);
 
     cm_ReleaseSCache(scp);
 
@@ -1945,12 +1880,9 @@ RDR_IoctlGetUnixMode(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32
 {
     afs_int32 code;
     cm_scache_t *scp;
-    cm_req_t req;
     cm_ioctlQueryOptions_t *optionsp;
     afs_uint32 flags = 0;
 
-    cm_InitReq(&req);
-
     optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
     if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
         flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
@@ -1960,14 +1892,14 @@ RDR_IoctlGetUnixMode(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32
         cm_SkipIoctlPath(&ioctlp->ioctl);
         cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
                   optionsp->fid.vnode, optionsp->fid.unique);
-        code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
+        code = cm_GetSCache(&fid, NULL, &scp, userp, &ioctlp->req);
     } else {
-        code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+        code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
     }
     if (code)
         return code;
 
-    code = cm_IoctlGetUnixMode(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlGetUnixMode(&ioctlp->ioctl, userp, scp, &ioctlp->req);
 
     cm_ReleaseSCache(scp);
 
@@ -1985,12 +1917,9 @@ RDR_IoctlSetUnixMode(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32
 {
     afs_int32 code;
     cm_scache_t *scp;
-    cm_req_t req;
     cm_ioctlQueryOptions_t *optionsp;
     afs_uint32 flags = 0;
 
-    smb_InitReq(&req);
-
     optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
     if (optionsp) {
         if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
@@ -2001,9 +1930,9 @@ RDR_IoctlSetUnixMode(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32
             cm_SkipIoctlPath(&ioctlp->ioctl);
             cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
                        optionsp->fid.vnode, optionsp->fid.unique);
-            code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
+            code = cm_GetSCache(&fid, NULL, &scp, userp, &ioctlp->req);
         } else {
-            code = RDR_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+            code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
         }
         if (code)
             return code;
@@ -2011,7 +1940,7 @@ RDR_IoctlSetUnixMode(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32
         cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
     }
 
-    code = cm_IoctlSetUnixMode(&ioctlp->ioctl, userp, scp, &req);
+    code = cm_IoctlSetUnixMode(&ioctlp->ioctl, userp, scp, &ioctlp->req);
 
     cm_ReleaseSCache(scp);
 
@@ -2033,3 +1962,34 @@ RDR_IoctlSetVerifyData(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint
 
     return cm_IoctlSetVerifyData(&ioctlp->ioctl);
 }
+
+afs_int32
+RDR_IoctlGetCallerAccess(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
+{
+    afs_int32 code;
+    cm_scache_t *scp;
+    cm_ioctlQueryOptions_t * optionsp;
+    afs_uint32 flags = 0;
+
+    optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+    if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+        flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+    if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+        cm_fid_t fid;
+        cm_SkipIoctlPath(&ioctlp->ioctl);
+        cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+                  optionsp->fid.vnode, optionsp->fid.unique);
+        code = cm_GetSCache(&fid, NULL, &scp, userp, &ioctlp->req);
+    } else {
+        code = RDR_ParseIoctlPath(ioctlp, userp, &ioctlp->req, &scp, flags);
+    }
+    if (code)
+        return code;
+
+    code = cm_IoctlGetCallerAccess(&ioctlp->ioctl, userp, scp, &ioctlp->req);
+
+    cm_ReleaseSCache(scp);
+
+    return code;
+}