auth: make PGetTokens2 work with 3-char cellnames 99/13599/4
authorMark Vitale <mvitale@sinenomine.net>
Thu, 23 May 2019 02:50:00 +0000 (22:50 -0400)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 5 Jul 2019 20:05:23 +0000 (16:05 -0400)
PGetTokens2 accepts two different types of input:
- an integer 'iterator' to request the nth token set for a user
- a string cellname to request the user's token set for that cell

Unfortunately, it distinguishes between these by assuming if the input
length is sizeof(afs_int32) (4 bytes), it must be an integer.  This
assumption is incorrect if the cellname is three (3) characters long
plus a nul terminator.

The result is that the cellname string is interpreted as a very large
"n"; the subsequent search for the user's "very-large-nth-token" fails,
making it appear that the user has no valid token for this cell.

Improve on this heuristic by double-checking any putative integer input.
If it is actually a 3-character string, then process the input as a
cellname instead.

Introduced by commit 5ec5ad5dcca84e99e5f55987cc4f787cd482fdde 'New
GetToken pioctl'.

While here, add doxygen comments.

Change-Id: Ifa226fa1c35b95bc32642870f73359f97a9f1d61
Reviewed-on: https://gerrit.openafs.org/13599
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>

src/afs/afs_pioctl.c

index 1d71bec..cd6907f 100644 (file)
@@ -5443,6 +5443,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 +5471,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 +5483,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);