diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-09-07 12:58:57 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-09-07 16:18:30 -0400 |
commit | 5e6b19901b763f502e62b5fd4f583778df983ce7 (patch) | |
tree | f407c8014634062f1f02a7528801dd1b4868e6ba /fs/nfs | |
parent | 19e7b8d240702297d837891694f463435910f718 (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.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4_fs.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4client.c | 19 | ||||
-rw-r--r-- | fs/nfs/nfs4getroot.c | 4 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 17 | ||||
-rw-r--r-- | fs/nfs/nfs4super.c | 4 |
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 *, | |||
358 | extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *, | 358 | extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *, |
359 | const char *); | 359 | const char *); |
360 | 360 | ||
361 | extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh); | 361 | extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh, bool); |
362 | #endif | 362 | #endif |
363 | 363 | ||
364 | struct nfs_pgio_completion_ops; | 364 | struct 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 */ |
222 | extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *); | 222 | extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *); |
223 | extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *); | 223 | extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *); |
224 | extern int nfs4_proc_get_rootfh(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); | 224 | extern int nfs4_proc_get_rootfh(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *, bool); |
225 | extern int nfs4_proc_bind_conn_to_session(struct nfs_client *, struct rpc_cred *cred); | 225 | extern int nfs4_proc_bind_conn_to_session(struct nfs_client *, struct rpc_cred *cred); |
226 | extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred); | 226 | extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred); |
227 | extern int nfs4_destroy_clientid(struct nfs_client *clp); | 227 | extern 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 | ||
887 | static int nfs4_server_common_setup(struct nfs_server *server, | 887 | static 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: | |||
949 | static int nfs4_init_server(struct nfs_server *server, | 949 | static 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 | ||
992 | error: | 996 | error: |
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 | ||
12 | int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh) | 12 | int 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 | */ |
2890 | int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle, | 2891 | int 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, |