knfsd: nfsd4: secinfo handling without secinfo= option
We could return some sort of error in the case where someone asks for secinfo on an export without the secinfo= option set--that'd be no worse than what we've been doing. But it's not really correct. So, hack up an approximate secinfo response in that case--it may not be complete, but it'll tell the client at least one acceptable security flavor. Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
dcb488a3b7
commit
4796f45740
3 changed files with 37 additions and 3 deletions
|
@ -57,6 +57,7 @@
|
||||||
#include <linux/nfs4.h>
|
#include <linux/nfs4.h>
|
||||||
#include <linux/nfs4_acl.h>
|
#include <linux/nfs4_acl.h>
|
||||||
#include <linux/sunrpc/gss_api.h>
|
#include <linux/sunrpc/gss_api.h>
|
||||||
|
#include <linux/sunrpc/svcauth_gss.h>
|
||||||
|
|
||||||
#define NFSDDBG_FACILITY NFSDDBG_XDR
|
#define NFSDDBG_FACILITY NFSDDBG_XDR
|
||||||
|
|
||||||
|
@ -2454,15 +2455,38 @@ nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, int nfserr,
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
struct svc_export *exp = secinfo->si_exp;
|
struct svc_export *exp = secinfo->si_exp;
|
||||||
|
u32 nflavs;
|
||||||
|
struct exp_flavor_info *flavs;
|
||||||
|
struct exp_flavor_info def_flavs[2];
|
||||||
ENCODE_HEAD;
|
ENCODE_HEAD;
|
||||||
|
|
||||||
if (nfserr)
|
if (nfserr)
|
||||||
goto out;
|
goto out;
|
||||||
|
if (exp->ex_nflavors) {
|
||||||
|
flavs = exp->ex_flavors;
|
||||||
|
nflavs = exp->ex_nflavors;
|
||||||
|
} else { /* Handling of some defaults in absence of real secinfo: */
|
||||||
|
flavs = def_flavs;
|
||||||
|
if (exp->ex_client->flavour->flavour == RPC_AUTH_UNIX) {
|
||||||
|
nflavs = 2;
|
||||||
|
flavs[0].pseudoflavor = RPC_AUTH_UNIX;
|
||||||
|
flavs[1].pseudoflavor = RPC_AUTH_NULL;
|
||||||
|
} else if (exp->ex_client->flavour->flavour == RPC_AUTH_GSS) {
|
||||||
|
nflavs = 1;
|
||||||
|
flavs[0].pseudoflavor
|
||||||
|
= svcauth_gss_flavor(exp->ex_client);
|
||||||
|
} else {
|
||||||
|
nflavs = 1;
|
||||||
|
flavs[0].pseudoflavor
|
||||||
|
= exp->ex_client->flavour->flavour;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RESERVE_SPACE(4);
|
RESERVE_SPACE(4);
|
||||||
WRITE32(exp->ex_nflavors);
|
WRITE32(nflavs);
|
||||||
ADJUST_ARGS();
|
ADJUST_ARGS();
|
||||||
for (i = 0; i < exp->ex_nflavors; i++) {
|
for (i = 0; i < nflavs; i++) {
|
||||||
u32 flav = exp->ex_flavors[i].pseudoflavor;
|
u32 flav = flavs[i].pseudoflavor;
|
||||||
struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav);
|
struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav);
|
||||||
|
|
||||||
if (gm) {
|
if (gm) {
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
int gss_svc_init(void);
|
int gss_svc_init(void);
|
||||||
void gss_svc_shutdown(void);
|
void gss_svc_shutdown(void);
|
||||||
int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
|
int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
|
||||||
|
u32 svcauth_gss_flavor(struct auth_domain *dom);
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
#endif /* _LINUX_SUNRPC_SVCAUTH_GSS_H */
|
#endif /* _LINUX_SUNRPC_SVCAUTH_GSS_H */
|
||||||
|
|
|
@ -743,6 +743,15 @@ find_gss_auth_domain(struct gss_ctx *ctx, u32 svc)
|
||||||
|
|
||||||
static struct auth_ops svcauthops_gss;
|
static struct auth_ops svcauthops_gss;
|
||||||
|
|
||||||
|
u32 svcauth_gss_flavor(struct auth_domain *dom)
|
||||||
|
{
|
||||||
|
struct gss_domain *gd = container_of(dom, struct gss_domain, h);
|
||||||
|
|
||||||
|
return gd->pseudoflavor;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(svcauth_gss_flavor);
|
||||||
|
|
||||||
int
|
int
|
||||||
svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
|
svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue