[PATCH 2/2] nfs: allow NFSv3 to fall back to using AUTH_UNIX automatically if available

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Currently, when using NFSv3 the mount will fail if the server happens to
have AUTH_GSS flavors in the returned authlist before AUTH_UNIX. This
seems to have been a deliberate change in commit 4580a92 (NFS: Use
server-recommended security flavor by default (NFSv3)).

While the workarounds are fine, I think we can do better here and allow
this to keep "just working". Allow the client to fall back to
automatically trying AUTH_UNIX under if the following are all true:

    - the server return -EACCES from ->create_server call
    - the client had to do a MNT request (i.e. no binary options)
    - we didn't just try to use AUTH_UNIX
    - the admin did not explcitly specify a sec= option

At that point, try to use AUTH_UNIX, if the server listed it.

Cc: Chuck Lever <chuck.lever@xxxxxxxxxx>
Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
---
 fs/nfs/super.c | 39 +++++++++++++++++++++++++++++++--------
 1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 5538bcc..6df327e 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1701,10 +1701,10 @@ out_err:
  * corresponding to the provided path.
  */
 static int nfs_request_mount(struct nfs_parsed_mount_data *args,
-			     struct nfs_fh *root_fh)
+			     struct nfs_fh *root_fh,
+			     unsigned int *server_authlist_len,
+			     rpc_authflavor_t *server_authlist)
 {
-	rpc_authflavor_t server_authlist[NFS_MAX_SECFLAVORS];
-	unsigned int server_authlist_len = ARRAY_SIZE(server_authlist);
 	struct nfs_mount_request request = {
 		.sap		= (struct sockaddr *)
 						&args->mount_server.address,
@@ -1712,7 +1712,7 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
 		.protocol	= args->mount_server.protocol,
 		.fh		= root_fh,
 		.noresvport	= args->flags & NFS_MOUNT_NORESVPORT,
-		.auth_flav_len	= &server_authlist_len,
+		.auth_flav_len	= server_authlist_len,
 		.auth_flavs	= server_authlist,
 		.net		= args->net,
 	};
@@ -1756,7 +1756,7 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
 		return status;
 	}
 
-	return nfs_select_flavor(args, server_authlist_len, server_authlist);
+	return 0;
 }
 
 struct dentry *nfs_try_mount(int flags, const char *dev_name,
@@ -1765,17 +1765,40 @@ struct dentry *nfs_try_mount(int flags, const char *dev_name,
 {
 	int status;
 	struct nfs_server *server;
+	struct nfs_parsed_mount_data *args = mount_info->parsed;
+	rpc_authflavor_t requested_authflavor = args->auth_flavors[0];
+	rpc_authflavor_t server_authlist[NFS_MAX_SECFLAVORS];
+	unsigned int server_authlist_len = ARRAY_SIZE(server_authlist);
 
-	if (mount_info->parsed->need_mount) {
-		status = nfs_request_mount(mount_info->parsed, mount_info->mntfh);
+	if (args->need_mount) {
+		status = nfs_request_mount(args, mount_info->mntfh,
+					&server_authlist_len, server_authlist);
+		if (status)
+			return ERR_PTR(status);
+retry:
+		status = nfs_select_flavor(args, server_authlist_len,
+						server_authlist);
 		if (status)
 			return ERR_PTR(status);
 	}
 
 	/* Get a volume representation */
 	server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
-	if (IS_ERR(server))
+	if (IS_ERR(server)) {
+		/*
+		 * If the initial attempt fails with -EACCES, then that likely
+		 * means that we couldn't get proper credentials to talk to the
+		 * server. If an authflavor wasn't specified in the options,
+		 * and we didn't try to use it already, then try AUTH_UNIX.
+		 */
+		if (PTR_ERR(server) == -EACCES && args->need_mount &&
+		    args->auth_flavors[0] != RPC_AUTH_UNIX &&
+		    requested_authflavor == RPC_AUTH_MAXFLAVOR) {
+			args->auth_flavors[0] = RPC_AUTH_UNIX;
+			goto retry;
+		}
 		return ERR_CAST(server);
+	}
 
 	return nfs_fs_mount_common(server, flags, dev_name, mount_info, nfs_mod);
 }
-- 
1.8.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux