auth: Fix GetNthIdentityOrUser EOF return code
authorAndrew Deason <adeason@sinenomine.net>
Tue, 14 Oct 2014 22:02:55 +0000 (17:02 -0500)
committerD Brashear <shadow@your-file-system.com>
Wed, 5 Nov 2014 13:32:40 +0000 (08:32 -0500)
Before commit 0af17e7e, afsconf_GetNthUser always returned 1 on
failure, to indicate to the caller that they should stop traversing
over the list. After commit 0af17e7e, when reaching the end of the
list, we return EIO or -1. This causes 'bos listusers' invocations to
always fail, since 'bos' clients expect to get the code 1 when
reaching the end of the SUsers list.

To fix this, make GetNthIdentityOrUser always return -1 when searching
beyond the end of the list. For the newer interface
afsconf_GetNthIdentity, we return this as-is, to have a separate
return code specifically for EOF, but still allowing us to return any
positive error code in case of an error.

For the older interface afsconf_GetNthUser, return 1 in this
situation, to retain compatibility with the old interface (both at the
libauth level and on the wire).

Change-Id: I2db4760440d7846dc290a05fa24e24ec97a02f12
Reviewed-on: http://gerrit.openafs.org/7377
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Reviewed-by: D Brashear <shadow@your-file-system.com>

src/auth/userok.c

index 2a258df..90d6333 100644 (file)
@@ -294,6 +294,7 @@ afsconf_DeleteUser(struct afsconf_dir *adir, char *name)
  * GetNthIdentity or GetNthUser. The parameter 'id' indicates
  * whether we are counting all identities (if true), or just
  * ones which can be represented by the old-style interfaces
+ * We return -1 for EOF, 0 for success, and >0 for all errors.
  */
 static int
 GetNthIdentityOrUser(struct afsconf_dir *dir, int count,
@@ -314,12 +315,14 @@ GetNthIdentityOrUser(struct afsconf_dir *dir, int count,
     if (!bp) {
        UNLOCK_GLOBAL_MUTEX;
        free(tbuffer);
-       return EIO;
+       return -1;
     }
     while (1) {
        code = BufioGets(bp, tbuffer, AFSDIR_PATH_MAX);
-       if (code < 0)
+       if (code < 0) {
+           code = -1;
            break;
+       }
 
        code = ParseLine(tbuffer, &fileUser);
        if (code != 0)
@@ -356,7 +359,10 @@ GetNthIdentityOrUser(struct afsconf_dir *dir, int count,
  * @param[out] identity
  *     A pointer to the Nth identity
  * @returns
- *     0 on success, non-zero on failure
+ *      status code
+ * @retval 0 Success
+ * @retval -1 We have searched beyond the end of the list.
+ * @retval >0 Error
  */
 
 int
@@ -384,11 +390,17 @@ afsconf_GetNthIdentity(struct afsconf_dir *dir, int count,
  * @param abufferLen
  *     The length of the buffer passed in abuffer
  * @returns
- *     0 on success, non-zero on failure
+ *      status code
+ * @retval 0 Success
+ * @retval 1 Either an EPERM error, or we have searched beyond the end of the
+ *           list.
+ * @retval >1 All other errors.
  *
  * This function is deprecated, all new callers should use
  * GetNthIdentity instead. This function is particularly dangerous
- * as it will hide any new-style identities from callers.
+ * as it will hide any new-style identities from callers. It is also
+ * impossible to distinguish an EPERM error from a normal end-of-file
+ * condition with this function.
  */
 
 int
@@ -403,6 +415,11 @@ afsconf_GetNthUser(struct afsconf_dir *adir, afs_int32 an, char *abuffer,
        strlcpy(abuffer, identity->displayName, abufferLen);
        rx_identity_free(&identity);
     }
+    if (code == -1) {
+       /* The new functions use -1 to indicate EOF, but the old interface
+        * uses 1 to indicate EOF. */
+       code = 1;
+    }
     return code;
 }