diff options
author | Weston Andros Adamson <dros@netapp.com> | 2013-10-18 15:15:19 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-10-28 15:38:02 -0400 |
commit | 4d4b69dd847a098cdca341c45326f6c6f61b8691 (patch) | |
tree | fdd1d7204d48f7af1f93f06844ee507e36dc917b /fs/nfs | |
parent | 5837f6dfcb00f764976ddc178933e612702cbf54 (diff) |
NFS: add support for multiple sec= mount options
This patch adds support for multiple security options which can be
specified using a colon-delimited list of security flavors (the same
syntax as nfsd's exports file).
This is useful, for instance, when NFSv4.x mounts cross SECINFO
boundaries. With this patch a user can use "sec=krb5i,krb5p"
to mount a remote filesystem using krb5i, but can still cross
into krb5p-only exports.
New mounts will try all security options before failing. NFSv4.x
SECINFO results will be compared against the sec= flavors to
find the first flavor in both lists or if no match is found will
return -EPERM.
Signed-off-by: Weston Andros Adamson <dros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/internal.h | 1 | ||||
-rw-r--r-- | fs/nfs/nfs4client.c | 3 | ||||
-rw-r--r-- | fs/nfs/nfs4namespace.c | 17 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 32 | ||||
-rw-r--r-- | fs/nfs/super.c | 160 |
5 files changed, 143 insertions, 70 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index c8cd044f0982..bca6a3e3c49c 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -326,6 +326,7 @@ extern struct file_system_type nfs_xdev_fs_type; | |||
326 | extern struct file_system_type nfs4_xdev_fs_type; | 326 | extern struct file_system_type nfs4_xdev_fs_type; |
327 | extern struct file_system_type nfs4_referral_fs_type; | 327 | extern struct file_system_type nfs4_referral_fs_type; |
328 | #endif | 328 | #endif |
329 | bool nfs_auth_info_match(const struct nfs_auth_info *, rpc_authflavor_t); | ||
329 | struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *, | 330 | struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *, |
330 | struct nfs_subversion *); | 331 | struct nfs_subversion *); |
331 | void nfs_initialise_sb(struct super_block *); | 332 | void nfs_initialise_sb(struct super_block *); |
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index f6cc77c7d802..b4a160a405ce 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c | |||
@@ -964,6 +964,9 @@ static int nfs4_init_server(struct nfs_server *server, | |||
964 | server->options = data->options; | 964 | server->options = data->options; |
965 | server->auth_info = data->auth_info; | 965 | server->auth_info = data->auth_info; |
966 | 966 | ||
967 | /* Use the first specified auth flavor. If this flavor isn't | ||
968 | * allowed by the server, use the SECINFO path to try the | ||
969 | * other specified flavors */ | ||
967 | if (data->auth_info.flavor_len >= 1) | 970 | if (data->auth_info.flavor_len >= 1) |
968 | data->selected_flavor = data->auth_info.flavors[0]; | 971 | data->selected_flavor = data->auth_info.flavors[0]; |
969 | else | 972 | else |
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index b947054f0ca1..c08cbf40c59e 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c | |||
@@ -137,6 +137,7 @@ static size_t nfs_parse_server_name(char *string, size_t len, | |||
137 | 137 | ||
138 | /** | 138 | /** |
139 | * nfs_find_best_sec - Find a security mechanism supported locally | 139 | * nfs_find_best_sec - Find a security mechanism supported locally |
140 | * @server: NFS server struct | ||
140 | * @flavors: List of security tuples returned by SECINFO procedure | 141 | * @flavors: List of security tuples returned by SECINFO procedure |
141 | * | 142 | * |
142 | * Return the pseudoflavor of the first security mechanism in | 143 | * Return the pseudoflavor of the first security mechanism in |
@@ -145,7 +146,8 @@ static size_t nfs_parse_server_name(char *string, size_t len, | |||
145 | * is searched in the order returned from the server, per RFC 3530 | 146 | * is searched in the order returned from the server, per RFC 3530 |
146 | * recommendation. | 147 | * recommendation. |
147 | */ | 148 | */ |
148 | static rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors) | 149 | static rpc_authflavor_t nfs_find_best_sec(struct nfs_server *server, |
150 | struct nfs4_secinfo_flavors *flavors) | ||
149 | { | 151 | { |
150 | rpc_authflavor_t pseudoflavor; | 152 | rpc_authflavor_t pseudoflavor; |
151 | struct nfs4_secinfo4 *secinfo; | 153 | struct nfs4_secinfo4 *secinfo; |
@@ -160,12 +162,19 @@ static rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors) | |||
160 | case RPC_AUTH_GSS: | 162 | case RPC_AUTH_GSS: |
161 | pseudoflavor = rpcauth_get_pseudoflavor(secinfo->flavor, | 163 | pseudoflavor = rpcauth_get_pseudoflavor(secinfo->flavor, |
162 | &secinfo->flavor_info); | 164 | &secinfo->flavor_info); |
163 | if (pseudoflavor != RPC_AUTH_MAXFLAVOR) | 165 | /* make sure pseudoflavor matches sec= mount opt */ |
166 | if (pseudoflavor != RPC_AUTH_MAXFLAVOR && | ||
167 | nfs_auth_info_match(&server->auth_info, | ||
168 | pseudoflavor)) | ||
164 | return pseudoflavor; | 169 | return pseudoflavor; |
165 | break; | 170 | break; |
166 | } | 171 | } |
167 | } | 172 | } |
168 | 173 | ||
174 | /* if there were any sec= options then nothing matched */ | ||
175 | if (server->auth_info.flavor_len > 0) | ||
176 | return -EPERM; | ||
177 | |||
169 | return RPC_AUTH_UNIX; | 178 | return RPC_AUTH_UNIX; |
170 | } | 179 | } |
171 | 180 | ||
@@ -187,7 +196,7 @@ static rpc_authflavor_t nfs4_negotiate_security(struct inode *inode, struct qstr | |||
187 | goto out; | 196 | goto out; |
188 | } | 197 | } |
189 | 198 | ||
190 | flavor = nfs_find_best_sec(flavors); | 199 | flavor = nfs_find_best_sec(NFS_SERVER(inode), flavors); |
191 | 200 | ||
192 | out: | 201 | out: |
193 | put_page(page); | 202 | put_page(page); |
@@ -390,7 +399,7 @@ struct vfsmount *nfs4_submount(struct nfs_server *server, struct dentry *dentry, | |||
390 | 399 | ||
391 | if (client->cl_auth->au_flavor != flavor) | 400 | if (client->cl_auth->au_flavor != flavor) |
392 | flavor = client->cl_auth->au_flavor; | 401 | flavor = client->cl_auth->au_flavor; |
393 | else if (server->auth_info.flavor_len == 0) { | 402 | else { |
394 | rpc_authflavor_t new = nfs4_negotiate_security(dir, name); | 403 | rpc_authflavor_t new = nfs4_negotiate_security(dir, name); |
395 | if ((int)new >= 0) | 404 | if ((int)new >= 0) |
396 | flavor = new; | 405 | flavor = new; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 0eb8dc5792da..b02c4cc7b0a9 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2873,11 +2873,24 @@ static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle, | |||
2873 | int status = -EPERM; | 2873 | int status = -EPERM; |
2874 | size_t i; | 2874 | size_t i; |
2875 | 2875 | ||
2876 | for (i = 0; i < ARRAY_SIZE(flav_array); i++) { | 2876 | if (server->auth_info.flavor_len > 0) { |
2877 | status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]); | 2877 | /* try each flavor specified by user */ |
2878 | if (status == -NFS4ERR_WRONGSEC || status == -EACCES) | 2878 | for (i = 0; i < server->auth_info.flavor_len; i++) { |
2879 | continue; | 2879 | status = nfs4_lookup_root_sec(server, fhandle, info, |
2880 | break; | 2880 | server->auth_info.flavors[i]); |
2881 | if (status == -NFS4ERR_WRONGSEC || status == -EACCES) | ||
2882 | continue; | ||
2883 | break; | ||
2884 | } | ||
2885 | } else { | ||
2886 | /* no flavors specified by user, try default list */ | ||
2887 | for (i = 0; i < ARRAY_SIZE(flav_array); i++) { | ||
2888 | status = nfs4_lookup_root_sec(server, fhandle, info, | ||
2889 | flav_array[i]); | ||
2890 | if (status == -NFS4ERR_WRONGSEC || status == -EACCES) | ||
2891 | continue; | ||
2892 | break; | ||
2893 | } | ||
2881 | } | 2894 | } |
2882 | 2895 | ||
2883 | /* | 2896 | /* |
@@ -2919,9 +2932,6 @@ int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle, | |||
2919 | status = nfs4_lookup_root(server, fhandle, info); | 2932 | status = nfs4_lookup_root(server, fhandle, info); |
2920 | if (status != -NFS4ERR_WRONGSEC) | 2933 | if (status != -NFS4ERR_WRONGSEC) |
2921 | break; | 2934 | break; |
2922 | /* Did user force a 'sec=' mount option? */ | ||
2923 | if (server->auth_info.flavor_len > 0) | ||
2924 | break; | ||
2925 | default: | 2935 | default: |
2926 | status = nfs4_do_find_root_sec(server, fhandle, info); | 2936 | status = nfs4_do_find_root_sec(server, fhandle, info); |
2927 | } | 2937 | } |
@@ -3179,9 +3189,6 @@ static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir, | |||
3179 | err = -EPERM; | 3189 | err = -EPERM; |
3180 | if (client != *clnt) | 3190 | if (client != *clnt) |
3181 | goto out; | 3191 | goto out; |
3182 | /* No security negotiation if the user specified 'sec=' */ | ||
3183 | if (NFS_SERVER(dir)->auth_info.flavor_len > 0) | ||
3184 | goto out; | ||
3185 | client = nfs4_create_sec_client(client, dir, name); | 3192 | client = nfs4_create_sec_client(client, dir, name); |
3186 | if (IS_ERR(client)) | 3193 | if (IS_ERR(client)) |
3187 | return PTR_ERR(client); | 3194 | return PTR_ERR(client); |
@@ -7942,6 +7949,9 @@ nfs41_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle, | |||
7942 | break; | 7949 | break; |
7943 | } | 7950 | } |
7944 | 7951 | ||
7952 | if (!nfs_auth_info_match(&server->auth_info, flavor)) | ||
7953 | flavor = RPC_AUTH_MAXFLAVOR; | ||
7954 | |||
7945 | if (flavor != RPC_AUTH_MAXFLAVOR) { | 7955 | if (flavor != RPC_AUTH_MAXFLAVOR) { |
7946 | err = nfs4_lookup_root_sec(server, fhandle, | 7956 | err = nfs4_lookup_root_sec(server, fhandle, |
7947 | info, flavor); | 7957 | info, flavor); |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 3a4f8bf5e5a5..317d6fc2160e 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -497,7 +497,8 @@ static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour) | |||
497 | static const struct { | 497 | static const struct { |
498 | rpc_authflavor_t flavour; | 498 | rpc_authflavor_t flavour; |
499 | const char *str; | 499 | const char *str; |
500 | } sec_flavours[] = { | 500 | } sec_flavours[NFS_AUTH_INFO_MAX_FLAVORS] = { |
501 | /* update NFS_AUTH_INFO_MAX_FLAVORS when this list changes! */ | ||
501 | { RPC_AUTH_NULL, "null" }, | 502 | { RPC_AUTH_NULL, "null" }, |
502 | { RPC_AUTH_UNIX, "sys" }, | 503 | { RPC_AUTH_UNIX, "sys" }, |
503 | { RPC_AUTH_GSS_KRB5, "krb5" }, | 504 | { RPC_AUTH_GSS_KRB5, "krb5" }, |
@@ -1019,6 +1020,52 @@ static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt) | |||
1019 | } | 1020 | } |
1020 | 1021 | ||
1021 | /* | 1022 | /* |
1023 | * Add 'flavor' to 'auth_info' if not already present. | ||
1024 | * Returns true if 'flavor' ends up in the list, false otherwise | ||
1025 | */ | ||
1026 | static bool nfs_auth_info_add(struct nfs_auth_info *auth_info, | ||
1027 | rpc_authflavor_t flavor) | ||
1028 | { | ||
1029 | unsigned int i; | ||
1030 | unsigned int max_flavor_len = (sizeof(auth_info->flavors) / | ||
1031 | sizeof(auth_info->flavors[0])); | ||
1032 | |||
1033 | /* make sure this flavor isn't already in the list */ | ||
1034 | for (i = 0; i < auth_info->flavor_len; i++) { | ||
1035 | if (flavor == auth_info->flavors[i]) | ||
1036 | return true; | ||
1037 | } | ||
1038 | |||
1039 | if (auth_info->flavor_len + 1 >= max_flavor_len) { | ||
1040 | dfprintk(MOUNT, "NFS: too many sec= flavors\n"); | ||
1041 | return false; | ||
1042 | } | ||
1043 | |||
1044 | auth_info->flavors[auth_info->flavor_len++] = flavor; | ||
1045 | return true; | ||
1046 | } | ||
1047 | |||
1048 | /* | ||
1049 | * Return true if 'match' is in auth_info or auth_info is empty. | ||
1050 | * Return false otherwise. | ||
1051 | */ | ||
1052 | bool nfs_auth_info_match(const struct nfs_auth_info *auth_info, | ||
1053 | rpc_authflavor_t match) | ||
1054 | { | ||
1055 | int i; | ||
1056 | |||
1057 | if (!auth_info->flavor_len) | ||
1058 | return true; | ||
1059 | |||
1060 | for (i = 0; i < auth_info->flavor_len; i++) { | ||
1061 | if (auth_info->flavors[i] == match) | ||
1062 | return true; | ||
1063 | } | ||
1064 | return false; | ||
1065 | } | ||
1066 | EXPORT_SYMBOL_GPL(nfs_auth_info_match); | ||
1067 | |||
1068 | /* | ||
1022 | * Parse the value of the 'sec=' option. | 1069 | * Parse the value of the 'sec=' option. |
1023 | */ | 1070 | */ |
1024 | static int nfs_parse_security_flavors(char *value, | 1071 | static int nfs_parse_security_flavors(char *value, |
@@ -1026,49 +1073,55 @@ static int nfs_parse_security_flavors(char *value, | |||
1026 | { | 1073 | { |
1027 | substring_t args[MAX_OPT_ARGS]; | 1074 | substring_t args[MAX_OPT_ARGS]; |
1028 | rpc_authflavor_t pseudoflavor; | 1075 | rpc_authflavor_t pseudoflavor; |
1076 | char *p; | ||
1029 | 1077 | ||
1030 | dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value); | 1078 | dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value); |
1031 | 1079 | ||
1032 | switch (match_token(value, nfs_secflavor_tokens, args)) { | 1080 | while ((p = strsep(&value, ":")) != NULL) { |
1033 | case Opt_sec_none: | 1081 | switch (match_token(p, nfs_secflavor_tokens, args)) { |
1034 | pseudoflavor = RPC_AUTH_NULL; | 1082 | case Opt_sec_none: |
1035 | break; | 1083 | pseudoflavor = RPC_AUTH_NULL; |
1036 | case Opt_sec_sys: | 1084 | break; |
1037 | pseudoflavor = RPC_AUTH_UNIX; | 1085 | case Opt_sec_sys: |
1038 | break; | 1086 | pseudoflavor = RPC_AUTH_UNIX; |
1039 | case Opt_sec_krb5: | 1087 | break; |
1040 | pseudoflavor = RPC_AUTH_GSS_KRB5; | 1088 | case Opt_sec_krb5: |
1041 | break; | 1089 | pseudoflavor = RPC_AUTH_GSS_KRB5; |
1042 | case Opt_sec_krb5i: | 1090 | break; |
1043 | pseudoflavor = RPC_AUTH_GSS_KRB5I; | 1091 | case Opt_sec_krb5i: |
1044 | break; | 1092 | pseudoflavor = RPC_AUTH_GSS_KRB5I; |
1045 | case Opt_sec_krb5p: | 1093 | break; |
1046 | pseudoflavor = RPC_AUTH_GSS_KRB5P; | 1094 | case Opt_sec_krb5p: |
1047 | break; | 1095 | pseudoflavor = RPC_AUTH_GSS_KRB5P; |
1048 | case Opt_sec_lkey: | 1096 | break; |
1049 | pseudoflavor = RPC_AUTH_GSS_LKEY; | 1097 | case Opt_sec_lkey: |
1050 | break; | 1098 | pseudoflavor = RPC_AUTH_GSS_LKEY; |
1051 | case Opt_sec_lkeyi: | 1099 | break; |
1052 | pseudoflavor = RPC_AUTH_GSS_LKEYI; | 1100 | case Opt_sec_lkeyi: |
1053 | break; | 1101 | pseudoflavor = RPC_AUTH_GSS_LKEYI; |
1054 | case Opt_sec_lkeyp: | 1102 | break; |
1055 | pseudoflavor = RPC_AUTH_GSS_LKEYP; | 1103 | case Opt_sec_lkeyp: |
1056 | break; | 1104 | pseudoflavor = RPC_AUTH_GSS_LKEYP; |
1057 | case Opt_sec_spkm: | 1105 | break; |
1058 | pseudoflavor = RPC_AUTH_GSS_SPKM; | 1106 | case Opt_sec_spkm: |
1059 | break; | 1107 | pseudoflavor = RPC_AUTH_GSS_SPKM; |
1060 | case Opt_sec_spkmi: | 1108 | break; |
1061 | pseudoflavor = RPC_AUTH_GSS_SPKMI; | 1109 | case Opt_sec_spkmi: |
1062 | break; | 1110 | pseudoflavor = RPC_AUTH_GSS_SPKMI; |
1063 | case Opt_sec_spkmp: | 1111 | break; |
1064 | pseudoflavor = RPC_AUTH_GSS_SPKMP; | 1112 | case Opt_sec_spkmp: |
1065 | break; | 1113 | pseudoflavor = RPC_AUTH_GSS_SPKMP; |
1066 | default: | 1114 | break; |
1067 | return 0; | 1115 | default: |
1116 | dfprintk(MOUNT, | ||
1117 | "NFS: sec= option '%s' not recognized\n", p); | ||
1118 | return 0; | ||
1119 | } | ||
1120 | |||
1121 | if (!nfs_auth_info_add(&mnt->auth_info, pseudoflavor)) | ||
1122 | return 0; | ||
1068 | } | 1123 | } |
1069 | 1124 | ||
1070 | mnt->auth_info.flavors[0] = pseudoflavor; | ||
1071 | mnt->auth_info.flavor_len = 1; | ||
1072 | return 1; | 1125 | return 1; |
1073 | } | 1126 | } |
1074 | 1127 | ||
@@ -1615,12 +1668,14 @@ out_security_failure: | |||
1615 | } | 1668 | } |
1616 | 1669 | ||
1617 | /* | 1670 | /* |
1618 | * Ensure that the specified authtype in args->auth_info is supported by | 1671 | * Ensure that a specified authtype in args->auth_info is supported by |
1619 | * the server. Returns 0 if it's ok, and -EACCES if not. | 1672 | * the server. Returns 0 and sets args->selected_flavor if it's ok, and |
1673 | * -EACCES if not. | ||
1620 | */ | 1674 | */ |
1621 | static int nfs_verify_authflavor(struct nfs_parsed_mount_data *args, | 1675 | static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args, |
1622 | rpc_authflavor_t *server_authlist, unsigned int count) | 1676 | rpc_authflavor_t *server_authlist, unsigned int count) |
1623 | { | 1677 | { |
1678 | rpc_authflavor_t flavor = RPC_AUTH_MAXFLAVOR; | ||
1624 | unsigned int i; | 1679 | unsigned int i; |
1625 | 1680 | ||
1626 | /* | 1681 | /* |
@@ -1632,17 +1687,19 @@ static int nfs_verify_authflavor(struct nfs_parsed_mount_data *args, | |||
1632 | * can be used. | 1687 | * can be used. |
1633 | */ | 1688 | */ |
1634 | for (i = 0; i < count; i++) { | 1689 | for (i = 0; i < count; i++) { |
1635 | if (args->auth_info.flavors[0] == server_authlist[i] || | 1690 | flavor = server_authlist[i]; |
1636 | server_authlist[i] == RPC_AUTH_NULL) | 1691 | |
1692 | if (nfs_auth_info_match(&args->auth_info, flavor) || | ||
1693 | flavor == RPC_AUTH_NULL) | ||
1637 | goto out; | 1694 | goto out; |
1638 | } | 1695 | } |
1639 | 1696 | ||
1640 | dfprintk(MOUNT, "NFS: auth flavor %u not supported by server\n", | 1697 | dfprintk(MOUNT, |
1641 | args->auth_info.flavors[0]); | 1698 | "NFS: specified auth flavors not supported by server\n"); |
1642 | return -EACCES; | 1699 | return -EACCES; |
1643 | 1700 | ||
1644 | out: | 1701 | out: |
1645 | args->selected_flavor = args->auth_info.flavors[0]; | 1702 | args->selected_flavor = flavor; |
1646 | dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->selected_flavor); | 1703 | dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->selected_flavor); |
1647 | return 0; | 1704 | return 0; |
1648 | } | 1705 | } |
@@ -1732,7 +1789,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf | |||
1732 | * whether the server supports it, and then just try to use it if so. | 1789 | * whether the server supports it, and then just try to use it if so. |
1733 | */ | 1790 | */ |
1734 | if (args->auth_info.flavor_len > 0) { | 1791 | if (args->auth_info.flavor_len > 0) { |
1735 | status = nfs_verify_authflavor(args, authlist, authlist_len); | 1792 | status = nfs_verify_authflavors(args, authlist, authlist_len); |
1736 | dfprintk(MOUNT, "NFS: using auth flavor %u\n", | 1793 | dfprintk(MOUNT, "NFS: using auth flavor %u\n", |
1737 | args->selected_flavor); | 1794 | args->selected_flavor); |
1738 | if (status) | 1795 | if (status) |
@@ -2102,9 +2159,6 @@ static int nfs_validate_text_mount_data(void *options, | |||
2102 | 2159 | ||
2103 | nfs_set_port(sap, &args->nfs_server.port, port); | 2160 | nfs_set_port(sap, &args->nfs_server.port, port); |
2104 | 2161 | ||
2105 | if (args->auth_info.flavor_len > 1) | ||
2106 | goto out_bad_auth; | ||
2107 | |||
2108 | return nfs_parse_devname(dev_name, | 2162 | return nfs_parse_devname(dev_name, |
2109 | &args->nfs_server.hostname, | 2163 | &args->nfs_server.hostname, |
2110 | max_namelen, | 2164 | max_namelen, |
@@ -2124,10 +2178,6 @@ out_invalid_transport_udp: | |||
2124 | out_no_address: | 2178 | out_no_address: |
2125 | dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n"); | 2179 | dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n"); |
2126 | return -EINVAL; | 2180 | return -EINVAL; |
2127 | |||
2128 | out_bad_auth: | ||
2129 | dfprintk(MOUNT, "NFS: Too many RPC auth flavours specified\n"); | ||
2130 | return -EINVAL; | ||
2131 | } | 2181 | } |
2132 | 2182 | ||
2133 | static int | 2183 | static int |