aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4proc.c33
-rw-r--r--include/linux/sunrpc/gss_api.h3
-rw-r--r--net/sunrpc/auth_gss/gss_mech_switch.c16
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
2195static 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;
2209out:
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 */
2197static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, 2216static 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. */
127struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32); 127struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32);
128 128
129/* Fill in an array with a list of supported pseudoflavors */
130int 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: */
130struct gss_api_mech * gss_mech_get(struct gss_api_mech *); 133struct 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
216EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor); 216EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor);
217 217
218int 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(&registered_mechs_lock);
224 list_for_each_entry(pos, &registered_mechs, gm_list) {
225 array_ptr[i] = pos->gm_pfs->pseudoflavor;
226 i++;
227 }
228 spin_unlock(&registered_mechs_lock);
229 return i;
230}
231
232EXPORT_SYMBOL_GPL(gss_mech_list_pseudoflavors);
233
218u32 234u32
219gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service) 235gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service)
220{ 236{