afs: Detect VIOCPREFETCH special case properly
[openafs.git] / src / afs / afs_pioctl.c
index 1d71bec..1f36540 100644 (file)
@@ -828,7 +828,7 @@ afs_xioctl(afs_proc_t *p, const struct ioctl_args *uap, register_t *retval)
 #if defined(AFS_NBSD50_ENV)
     if ((fd = fd_getfile(SCARG(uap, fd))) == NULL)
        return (EBADF);
-#elif defined(AFS_FBSD100_ENV)
+#elif defined(AFS_FBSD_ENV)
     if ((uap->fd >= fdp->fd_nfiles)
        || ((fd = fdp->fd_ofiles[uap->fd].fde_file) == NULL))
        return EBADF;
@@ -887,11 +887,7 @@ afs_xioctl(afs_proc_t *p, const struct ioctl_args *uap, register_t *retval)
 
     if (!ioctlDone) {
 # if defined(AFS_FBSD_ENV)
-#  if (__FreeBSD_version >= 900044)
        return sys_ioctl(td, uap);
-#  else
-       return ioctl(td, uap);
-#  endif
 # elif defined(AFS_OBSD_ENV)
        code = sys_ioctl(p, uap, retval);
 # elif defined(AFS_NBSD_ENV)
@@ -1123,7 +1119,9 @@ afs_syscall_pioctl(char *path, unsigned int com, caddr_t cmarg, int follow)
 #endif
     }
 #endif /* AFS_NEED_CLIENTCONTEXT */
-    if ((com & 0xff) == 15) {
+
+    /* VIOCPREFETCH */
+    if ((com & 0xff00) >> 8 == 'V' && (com & 0xff) == 15) {
        /* special case prefetch so entire pathname eval occurs in helper process.
         * otherwise, the pioctl call is essentially useless */
 #if    defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
@@ -1258,10 +1256,10 @@ afs_syscall_pioctl(char *path, unsigned int com, caddr_t cmarg, int follow)
        dput(dp);
        AFS_GLOCK();
 #else
-#if defined(AFS_FBSD80_ENV)
+#if defined(AFS_FBSD_ENV)
     if (VOP_ISLOCKED(vp))
        VOP_UNLOCK(vp, 0);
-#endif /* AFS_FBSD80_ENV */
+#endif /* AFS_FBSD_ENV */
        AFS_RELE(vp);           /* put vnode back */
 #endif
     }
@@ -2226,9 +2224,9 @@ DECL_PIOCTL(PNewStatMount)
     tfid.Cell = avc->f.fid.Cell;
     tfid.Fid.Volume = avc->f.fid.Fid.Volume;
     if (!tfid.Fid.Unique && (avc->f.states & CForeign)) {
-       tvc = afs_LookupVCache(&tfid, areq, NULL, avc, bufp);
+       tvc = afs_LookupVCache(&tfid, areq, avc, bufp);
     } else {
-       tvc = afs_GetVCache(&tfid, areq, NULL, NULL);
+       tvc = afs_GetVCache(&tfid, areq);
     }
     if (!tvc) {
        code = EIO;
@@ -3287,9 +3285,9 @@ DECL_PIOCTL(PRemoveMount)
     tfid.Cell = avc->f.fid.Cell;
     tfid.Fid.Volume = avc->f.fid.Fid.Volume;
     if (!tfid.Fid.Unique && (avc->f.states & CForeign)) {
-       tvc = afs_LookupVCache(&tfid, areq, NULL, avc, bufp);
+       tvc = afs_LookupVCache(&tfid, areq, avc, bufp);
     } else {
-       tvc = afs_GetVCache(&tfid, areq, NULL, NULL);
+       tvc = afs_GetVCache(&tfid, areq);
     }
     if (!tvc) {
        code = EIO;
@@ -4621,7 +4619,7 @@ HandleClientContext(struct afs_ioctl *ablob, int *com,
 #ifdef AFS_AIX_ENV
     newcred->cr_ngrps = 2;
 #elif !defined(AFS_LINUX26_ENV) && !defined(AFS_SUN510_ENV)
-# if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_FBSD80_ENV)
+# if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_FBSD_ENV)
     newcred->cr_ngroups = 2;
 # else
     for (i = 2; i < NGROUPS; i++)
@@ -4766,10 +4764,6 @@ DECL_PIOCTL(PSetCPrefs)
 
     if (ainSize < sizeof(struct setspref))
        return EINVAL;
-#if 0                          /* num_servers is unsigned */
-    if (sin->num_servers < 0)
-       return EINVAL;
-#endif
     if (sin->num_servers > AFS_MAX_INTERFACE_ADDR)
        return ENOMEM;
 
@@ -4844,9 +4838,9 @@ DECL_PIOCTL(PFlushMount)
     tfid.Cell = avc->f.fid.Cell;
     tfid.Fid.Volume = avc->f.fid.Fid.Volume;
     if (!tfid.Fid.Unique && (avc->f.states & CForeign)) {
-       tvc = afs_LookupVCache(&tfid, areq, NULL, avc, bufp);
+       tvc = afs_LookupVCache(&tfid, areq, avc, bufp);
     } else {
-       tvc = afs_GetVCache(&tfid, areq, NULL, NULL);
+       tvc = afs_GetVCache(&tfid, areq);
     }
     if (!tvc) {
        code = EIO;
@@ -4982,7 +4976,7 @@ DECL_PIOCTL(PPrefetchFromTape)
     tfid.Fid.Vnode = Fid->Vnode;
     tfid.Fid.Unique = Fid->Unique;
 
-    tvc = afs_GetVCache(&tfid, areq, NULL, NULL);
+    tvc = afs_GetVCache(&tfid, areq);
     if (!tvc) {
        afs_Trace3(afs_iclSetp, CM_TRACE_PREFETCHCMD, ICL_TYPE_POINTER, tvc,
                   ICL_TYPE_FID, &tfid, ICL_TYPE_FID, &avc->f.fid);
@@ -5053,7 +5047,7 @@ DECL_PIOCTL(PFsCmd)
     tfid.Fid.Vnode = Fid->Vnode;
     tfid.Fid.Unique = Fid->Unique;
 
-    tvc = afs_GetVCache(&tfid, areq, NULL, NULL);
+    tvc = afs_GetVCache(&tfid, areq);
     afs_Trace3(afs_iclSetp, CM_TRACE_RESIDCMD, ICL_TYPE_POINTER, tvc,
               ICL_TYPE_INT32, Inputs->command, ICL_TYPE_FID, &tfid);
     if (!tvc)
@@ -5167,7 +5161,7 @@ DECL_PIOCTL(PCallBackAddr)
     if (!afs_resourceinit_flag)        /* afs deamons havn't started yet */
        return EIO;             /* Inappropriate ioctl for device */
 
-    if (!afs_osi_suser(acred))
+    if (!afs_osi_suser(*acred))
        return EACCES;
 
     if (afs_pd_getInt(ain, &addr) != 0)
@@ -5443,6 +5437,26 @@ out:
     return code;
 }
 
+/*!
+ * VIOC_GETTOK2 (7) - Return a user's nth token, or token for a cell by
+ *                     name.
+ *
+ * \ingroup pioctl
+ *
+ * \param[in] ain      EITHER  a string cellname
+ *                     OR      an integer 'iterator' to specify the nth
+ *                             token.
+ *
+ * \param[out] aout    XDR-encoded tokens from the user's tokenJar
+ *
+ * \retval EINVAL      invalid input (bad integer, or invalid string)
+ *                     unable to extract token(s)
+ * \retval ENOMEM      insufficient memory (returned from called routines)
+ * \retval EDOM                (integer) request was out of bounds or the user has no tokens
+ * \retval ENOTCONN    user found but has no valid token(s)
+ * \retval E2BIG       token(s) do not fit in the output buffer
+ *
+ */
 DECL_PIOCTL(PGetTokens2)
 {
     struct cell *cell = NULL;
@@ -5451,6 +5465,7 @@ DECL_PIOCTL(PGetTokens2)
     char *cellName = NULL;
     afs_int32 cellNum;
     int code = 0;
+    int integer_in = 1;                /* assume integer input */
     time_t now;
     XDR xdrs;
     struct ktc_setTokenData tokenSet;
@@ -5462,11 +5477,23 @@ DECL_PIOCTL(PGetTokens2)
     memset(&tokenSet, 0, sizeof(tokenSet));
 
     /* No input data - return tokens for primary cell */
-    /* 4 octets of data is an iterator count */
+    /* 4 octets of data is PROBABLY an iterator count */
     /* Otherwise, treat as string & return tokens for that cell name */
 
     if (afs_pd_remaining(ain) == sizeof(afs_int32)) {
-       /* Integer iterator - return tokens for the n'th cell found for user */
+       char *scratch = afs_pd_where(ain);
+
+       if (scratch[3] == '\0' && strlen(scratch) == 3)
+           integer_in = 0;
+    } else {
+       integer_in = 0;
+    }
+
+    if (integer_in) {
+       /* The misleadingly-named getNthCell actually return the nth valid
+        * token found for the specified user; there can never be a gap
+        * in the ordinals at this level.
+        */
        if (afs_pd_getInt(ain, &iterator) != 0)
            return EINVAL;
        tu = getNthCell(areq->uid, iterator);
@@ -5539,7 +5566,7 @@ DECL_PIOCTL(PNFSNukeCreds)
            return EACCES;
        }
        afs_PutUser(tu, SHARED_LOCK);
-    } else if (!afs_osi_suser(acred)) {
+    } else if (!afs_osi_suser(*acred)) {
        return EACCES;
     }