aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-09-07 12:58:57 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-09-07 16:18:30 -0400
commit5e6b19901b763f502e62b5fd4f583778df983ce7 (patch)
treef407c8014634062f1f02a7528801dd1b4868e6ba /fs/nfs
parent19e7b8d240702297d837891694f463435910f718 (diff)
NFSv4: Fix security auto-negotiation
NFSv4 security auto-negotiation has been broken since commit 4580a92d44e2b21c2254fa5fef0f1bfb43c82318 (NFS: Use server-recommended security flavor by default (NFSv3)) because nfs4_try_mount() will automatically select AUTH_SYS if it sees no auth flavours. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: Chuck Lever <chuck.lever@oracle.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/internal.h2
-rw-r--r--fs/nfs/nfs4_fs.h2
-rw-r--r--fs/nfs/nfs4client.c19
-rw-r--r--fs/nfs/nfs4getroot.c4
-rw-r--r--fs/nfs/nfs4proc.c17
-rw-r--r--fs/nfs/nfs4super.c4
6 files changed, 30 insertions, 18 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 23ec6e8e8a4d..d388302c005f 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -358,7 +358,7 @@ extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *,
358extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *, 358extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *,
359 const char *); 359 const char *);
360 360
361extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh); 361extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh, bool);
362#endif 362#endif
363 363
364struct nfs_pgio_completion_ops; 364struct nfs_pgio_completion_ops;
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index d2db3ce07d3a..f520a1113b38 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -221,7 +221,7 @@ struct vfsmount *nfs4_submount(struct nfs_server *, struct dentry *,
221/* nfs4proc.c */ 221/* nfs4proc.c */
222extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *); 222extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);
223extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *); 223extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *);
224extern int nfs4_proc_get_rootfh(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 224extern int nfs4_proc_get_rootfh(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *, bool);
225extern int nfs4_proc_bind_conn_to_session(struct nfs_client *, struct rpc_cred *cred); 225extern int nfs4_proc_bind_conn_to_session(struct nfs_client *, struct rpc_cred *cred);
226extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred); 226extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
227extern int nfs4_destroy_clientid(struct nfs_client *clp); 227extern int nfs4_destroy_clientid(struct nfs_client *clp);
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index f798925d8291..cc80085c4de4 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -885,7 +885,7 @@ static void nfs4_session_set_rwsize(struct nfs_server *server)
885} 885}
886 886
887static int nfs4_server_common_setup(struct nfs_server *server, 887static int nfs4_server_common_setup(struct nfs_server *server,
888 struct nfs_fh *mntfh) 888 struct nfs_fh *mntfh, bool auth_probe)
889{ 889{
890 struct nfs_fattr *fattr; 890 struct nfs_fattr *fattr;
891 int error; 891 int error;
@@ -917,7 +917,7 @@ static int nfs4_server_common_setup(struct nfs_server *server,
917 917
918 918
919 /* Probe the root fh to retrieve its FSID and filehandle */ 919 /* Probe the root fh to retrieve its FSID and filehandle */
920 error = nfs4_get_rootfh(server, mntfh); 920 error = nfs4_get_rootfh(server, mntfh, auth_probe);
921 if (error < 0) 921 if (error < 0)
922 goto out; 922 goto out;
923 923
@@ -949,6 +949,7 @@ out:
949static int nfs4_init_server(struct nfs_server *server, 949static int nfs4_init_server(struct nfs_server *server,
950 const struct nfs_parsed_mount_data *data) 950 const struct nfs_parsed_mount_data *data)
951{ 951{
952 rpc_authflavor_t pseudoflavor = RPC_AUTH_UNIX;
952 struct rpc_timeout timeparms; 953 struct rpc_timeout timeparms;
953 int error; 954 int error;
954 955
@@ -961,13 +962,16 @@ static int nfs4_init_server(struct nfs_server *server,
961 server->flags = data->flags; 962 server->flags = data->flags;
962 server->options = data->options; 963 server->options = data->options;
963 964
965 if (data->auth_flavor_len >= 1)
966 pseudoflavor = data->auth_flavors[0];
967
964 /* Get a client record */ 968 /* Get a client record */
965 error = nfs4_set_client(server, 969 error = nfs4_set_client(server,
966 data->nfs_server.hostname, 970 data->nfs_server.hostname,
967 (const struct sockaddr *)&data->nfs_server.address, 971 (const struct sockaddr *)&data->nfs_server.address,
968 data->nfs_server.addrlen, 972 data->nfs_server.addrlen,
969 data->client_address, 973 data->client_address,
970 data->auth_flavors[0], 974 pseudoflavor,
971 data->nfs_server.protocol, 975 data->nfs_server.protocol,
972 &timeparms, 976 &timeparms,
973 data->minorversion, 977 data->minorversion,
@@ -987,7 +991,7 @@ static int nfs4_init_server(struct nfs_server *server,
987 991
988 server->port = data->nfs_server.port; 992 server->port = data->nfs_server.port;
989 993
990 error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]); 994 error = nfs_init_server_rpcclient(server, &timeparms, pseudoflavor);
991 995
992error: 996error:
993 /* Done */ 997 /* Done */
@@ -1005,6 +1009,7 @@ struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info,
1005 struct nfs_subversion *nfs_mod) 1009 struct nfs_subversion *nfs_mod)
1006{ 1010{
1007 struct nfs_server *server; 1011 struct nfs_server *server;
1012 bool auth_probe;
1008 int error; 1013 int error;
1009 1014
1010 dprintk("--> nfs4_create_server()\n"); 1015 dprintk("--> nfs4_create_server()\n");
@@ -1013,12 +1018,14 @@ struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info,
1013 if (!server) 1018 if (!server)
1014 return ERR_PTR(-ENOMEM); 1019 return ERR_PTR(-ENOMEM);
1015 1020
1021 auth_probe = mount_info->parsed->auth_flavor_len < 1;
1022
1016 /* set up the general RPC client */ 1023 /* set up the general RPC client */
1017 error = nfs4_init_server(server, mount_info->parsed); 1024 error = nfs4_init_server(server, mount_info->parsed);
1018 if (error < 0) 1025 if (error < 0)
1019 goto error; 1026 goto error;
1020 1027
1021 error = nfs4_server_common_setup(server, mount_info->mntfh); 1028 error = nfs4_server_common_setup(server, mount_info->mntfh, auth_probe);
1022 if (error < 0) 1029 if (error < 0)
1023 goto error; 1030 goto error;
1024 1031
@@ -1071,7 +1078,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1071 if (error < 0) 1078 if (error < 0)
1072 goto error; 1079 goto error;
1073 1080
1074 error = nfs4_server_common_setup(server, mntfh); 1081 error = nfs4_server_common_setup(server, mntfh, false);
1075 if (error < 0) 1082 if (error < 0)
1076 goto error; 1083 goto error;
1077 1084
diff --git a/fs/nfs/nfs4getroot.c b/fs/nfs/nfs4getroot.c
index 549462e5b9b0..c0b3a16b4a00 100644
--- a/fs/nfs/nfs4getroot.c
+++ b/fs/nfs/nfs4getroot.c
@@ -9,7 +9,7 @@
9 9
10#define NFSDBG_FACILITY NFSDBG_CLIENT 10#define NFSDBG_FACILITY NFSDBG_CLIENT
11 11
12int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh) 12int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh, bool auth_probe)
13{ 13{
14 struct nfs_fsinfo fsinfo; 14 struct nfs_fsinfo fsinfo;
15 int ret = -ENOMEM; 15 int ret = -ENOMEM;
@@ -21,7 +21,7 @@ int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh)
21 goto out; 21 goto out;
22 22
23 /* Start by getting the root filehandle from the server */ 23 /* Start by getting the root filehandle from the server */
24 ret = nfs4_proc_get_rootfh(server, mntfh, &fsinfo); 24 ret = nfs4_proc_get_rootfh(server, mntfh, &fsinfo, auth_probe);
25 if (ret < 0) { 25 if (ret < 0) {
26 dprintk("nfs4_get_rootfh: getroot error = %d\n", -ret); 26 dprintk("nfs4_get_rootfh: getroot error = %d\n", -ret);
27 goto out; 27 goto out;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index cb56102ad40e..68551ea0b673 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2884,18 +2884,27 @@ static int nfs4_do_find_root_sec(struct nfs_server *server,
2884 * @server: initialized nfs_server handle 2884 * @server: initialized nfs_server handle
2885 * @fhandle: we fill in the pseudo-fs root file handle 2885 * @fhandle: we fill in the pseudo-fs root file handle
2886 * @info: we fill in an FSINFO struct 2886 * @info: we fill in an FSINFO struct
2887 * @auth_probe: probe the auth flavours
2887 * 2888 *
2888 * Returns zero on success, or a negative errno. 2889 * Returns zero on success, or a negative errno.
2889 */ 2890 */
2890int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle, 2891int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle,
2891 struct nfs_fsinfo *info) 2892 struct nfs_fsinfo *info,
2893 bool auth_probe)
2892{ 2894{
2893 int status; 2895 int status;
2894 2896
2895 status = nfs4_lookup_root(server, fhandle, info); 2897 switch (auth_probe) {
2896 if ((status == -NFS4ERR_WRONGSEC) && 2898 case false:
2897 !(server->flags & NFS_MOUNT_SECFLAVOUR)) 2899 status = nfs4_lookup_root(server, fhandle, info);
2900 if (status != -NFS4ERR_WRONGSEC)
2901 break;
2902 /* Did user force a 'sec=' mount option? */
2903 if (server->flags & NFS_MOUNT_SECFLAVOUR)
2904 break;
2905 default:
2898 status = nfs4_do_find_root_sec(server, fhandle, info); 2906 status = nfs4_do_find_root_sec(server, fhandle, info);
2907 }
2899 2908
2900 if (status == 0) 2909 if (status == 0)
2901 status = nfs4_server_capabilities(server, fhandle); 2910 status = nfs4_server_capabilities(server, fhandle);
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 4ad837cf4786..e26acdd1a645 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -253,10 +253,6 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name,
253 253
254 dfprintk(MOUNT, "--> nfs4_try_mount()\n"); 254 dfprintk(MOUNT, "--> nfs4_try_mount()\n");
255 255
256 if (data->auth_flavor_len < 1) {
257 data->auth_flavors[0] = RPC_AUTH_UNIX;
258 data->auth_flavor_len = 1;
259 }
260 export_path = data->nfs_server.export_path; 256 export_path = data->nfs_server.export_path;
261 data->nfs_server.export_path = "/"; 257 data->nfs_server.export_path = "/";
262 root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info, 258 root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info,