diff options
-rw-r--r-- | fs/nfs/nfs4proc.c | 33 | ||||
-rw-r--r-- | include/linux/sunrpc/gss_api.h | 3 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_mech_switch.c | 16 |
3 files changed, 50 insertions, 2 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 563463777d9d..f9150f03d640 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/string.h> | 41 | #include <linux/string.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/sunrpc/clnt.h> | 43 | #include <linux/sunrpc/clnt.h> |
44 | #include <linux/sunrpc/gss_api.h> | ||
44 | #include <linux/nfs.h> | 45 | #include <linux/nfs.h> |
45 | #include <linux/nfs4.h> | 46 | #include <linux/nfs4.h> |
46 | #include <linux/nfs_fs.h> | 47 | #include <linux/nfs_fs.h> |
@@ -2191,15 +2192,43 @@ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, | |||
2191 | return err; | 2192 | return err; |
2192 | } | 2193 | } |
2193 | 2194 | ||
2195 | static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandle, | ||
2196 | struct nfs_fsinfo *info, rpc_authflavor_t flavor) | ||
2197 | { | ||
2198 | struct rpc_auth *auth; | ||
2199 | int ret; | ||
2200 | |||
2201 | auth = rpcauth_create(flavor, server->client); | ||
2202 | if (!auth) { | ||
2203 | ret = -EIO; | ||
2204 | goto out; | ||
2205 | } | ||
2206 | ret = nfs4_lookup_root(server, fhandle, info); | ||
2207 | if (ret < 0) | ||
2208 | ret = -EAGAIN; | ||
2209 | out: | ||
2210 | return ret; | ||
2211 | } | ||
2212 | |||
2194 | /* | 2213 | /* |
2195 | * get the file handle for the "/" directory on the server | 2214 | * get the file handle for the "/" directory on the server |
2196 | */ | 2215 | */ |
2197 | static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, | 2216 | static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, |
2198 | struct nfs_fsinfo *info) | 2217 | struct nfs_fsinfo *info) |
2199 | { | 2218 | { |
2200 | int status; | 2219 | int i, len, status = 0; |
2220 | rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS + 2]; | ||
2201 | 2221 | ||
2202 | status = nfs4_lookup_root(server, fhandle, info); | 2222 | flav_array[0] = RPC_AUTH_UNIX; |
2223 | len = gss_mech_list_pseudoflavors(&flav_array[1]); | ||
2224 | flav_array[1+len] = RPC_AUTH_NULL; | ||
2225 | len += 2; | ||
2226 | |||
2227 | for (i = 0; i < len; i++) { | ||
2228 | status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]); | ||
2229 | if (status == 0) | ||
2230 | break; | ||
2231 | } | ||
2203 | if (status == 0) | 2232 | if (status == 0) |
2204 | status = nfs4_server_capabilities(server, fhandle); | 2233 | status = nfs4_server_capabilities(server, fhandle); |
2205 | if (status == 0) | 2234 | if (status == 0) |
diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h index 5d8048beb051..332da61cf8b7 100644 --- a/include/linux/sunrpc/gss_api.h +++ b/include/linux/sunrpc/gss_api.h | |||
@@ -126,6 +126,9 @@ struct gss_api_mech *gss_mech_get_by_name(const char *); | |||
126 | /* Similar, but get by pseudoflavor. */ | 126 | /* Similar, but get by pseudoflavor. */ |
127 | struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32); | 127 | struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32); |
128 | 128 | ||
129 | /* Fill in an array with a list of supported pseudoflavors */ | ||
130 | int gss_mech_list_pseudoflavors(u32 *); | ||
131 | |||
129 | /* Just increments the mechanism's reference count and returns its input: */ | 132 | /* Just increments the mechanism's reference count and returns its input: */ |
130 | struct gss_api_mech * gss_mech_get(struct gss_api_mech *); | 133 | struct gss_api_mech * gss_mech_get(struct gss_api_mech *); |
131 | 134 | ||
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index 6c844b01a1d1..e3c36a274412 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c | |||
@@ -215,6 +215,22 @@ gss_mech_get_by_pseudoflavor(u32 pseudoflavor) | |||
215 | 215 | ||
216 | EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor); | 216 | EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor); |
217 | 217 | ||
218 | int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr) | ||
219 | { | ||
220 | struct gss_api_mech *pos = NULL; | ||
221 | int i = 0; | ||
222 | |||
223 | spin_lock(®istered_mechs_lock); | ||
224 | list_for_each_entry(pos, ®istered_mechs, gm_list) { | ||
225 | array_ptr[i] = pos->gm_pfs->pseudoflavor; | ||
226 | i++; | ||
227 | } | ||
228 | spin_unlock(®istered_mechs_lock); | ||
229 | return i; | ||
230 | } | ||
231 | |||
232 | EXPORT_SYMBOL_GPL(gss_mech_list_pseudoflavors); | ||
233 | |||
218 | u32 | 234 | u32 |
219 | gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service) | 235 | gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service) |
220 | { | 236 | { |