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 | { |
