summary refs log tree commit diff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-04-08 11:47:35 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-04-08 11:47:35 -0700
commit94c8a984ae2adbd9a9626fb42e0f2faf3e36e86f (patch)
treea4beddd64501ef00ad41c8fd5974340bec2fcf73
parentf9fa0bc1fabe1d861e46d80ecbe7e85da359195c (diff)
parent37adb89fadd65ce47f7e5cfd564938a76b351948 (diff)
downloadlinux-94c8a984ae2adbd9a9626fb42e0f2faf3e36e86f.tar.gz
Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6:
  NFS: Change initial mount authflavor only when server returns NFS4ERR_WRONGSEC
  NFS: Fix a signed vs. unsigned secinfo bug
  Revert "net/sunrpc: Use static const char arrays"
-rw-r--r--fs/nfs/namespace.c58
-rw-r--r--fs/nfs/nfs4proc.c4
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c2
3 files changed, 27 insertions, 37 deletions
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 9166fcb66da2..89fc160fd5b0 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -148,67 +148,64 @@ static rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors,
 	return pseudoflavor;
 }
 
-static rpc_authflavor_t nfs_negotiate_security(const struct dentry *parent, const struct dentry *dentry)
+static int nfs_negotiate_security(const struct dentry *parent,
+				  const struct dentry *dentry,
+				  rpc_authflavor_t *flavor)
 {
-	int status = 0;
 	struct page *page;
 	struct nfs4_secinfo_flavors *flavors;
 	int (*secinfo)(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *);
-	rpc_authflavor_t flavor = RPC_AUTH_UNIX;
+	int ret = -EPERM;
 
 	secinfo = NFS_PROTO(parent->d_inode)->secinfo;
 	if (secinfo != NULL) {
 		page = alloc_page(GFP_KERNEL);
 		if (!page) {
-			status = -ENOMEM;
+			ret = -ENOMEM;
 			goto out;
 		}
 		flavors = page_address(page);
-		status = secinfo(parent->d_inode, &dentry->d_name, flavors);
-		flavor = nfs_find_best_sec(flavors, dentry->d_inode);
+		ret = secinfo(parent->d_inode, &dentry->d_name, flavors);
+		*flavor = nfs_find_best_sec(flavors, dentry->d_inode);
 		put_page(page);
 	}
 
-	return flavor;
-
 out:
-	status = -ENOMEM;
-	return status;
+	return ret;
 }
 
-static rpc_authflavor_t nfs_lookup_with_sec(struct nfs_server *server, struct dentry *parent,
-				     struct dentry *dentry, struct path *path,
-				     struct nfs_fh *fh, struct nfs_fattr *fattr)
+static int nfs_lookup_with_sec(struct nfs_server *server, struct dentry *parent,
+			       struct dentry *dentry, struct path *path,
+			       struct nfs_fh *fh, struct nfs_fattr *fattr,
+			       rpc_authflavor_t *flavor)
 {
-	rpc_authflavor_t flavor;
 	struct rpc_clnt *clone;
 	struct rpc_auth *auth;
 	int err;
 
-	flavor = nfs_negotiate_security(parent, path->dentry);
-	if (flavor < 0)
+	err = nfs_negotiate_security(parent, path->dentry, flavor);
+	if (err < 0)
 		goto out;
 	clone  = rpc_clone_client(server->client);
-	auth   = rpcauth_create(flavor, clone);
+	auth   = rpcauth_create(*flavor, clone);
 	if (!auth) {
-		flavor = -EIO;
+		err = -EIO;
 		goto out_shutdown;
 	}
 	err = server->nfs_client->rpc_ops->lookup(clone, parent->d_inode,
 						  &path->dentry->d_name,
 						  fh, fattr);
-	if (err < 0)
-		flavor = err;
 out_shutdown:
 	rpc_shutdown_client(clone);
 out:
-	return flavor;
+	return err;
 }
 #else /* CONFIG_NFS_V4 */
-static inline rpc_authflavor_t nfs_lookup_with_sec(struct nfs_server *server,
-				     struct dentry *parent, struct dentry *dentry,
-				     struct path *path, struct nfs_fh *fh,
-				     struct nfs_fattr *fattr)
+static inline int nfs_lookup_with_sec(struct nfs_server *server,
+				      struct dentry *parent, struct dentry *dentry,
+				      struct path *path, struct nfs_fh *fh,
+				      struct nfs_fattr *fattr,
+				      rpc_authflavor_t *flavor)
 {
 	return -EPERM;
 }
@@ -234,7 +231,7 @@ struct vfsmount *nfs_d_automount(struct path *path)
 	struct nfs_fh *fh = NULL;
 	struct nfs_fattr *fattr = NULL;
 	int err;
-	rpc_authflavor_t flavor = 1;
+	rpc_authflavor_t flavor = RPC_AUTH_UNIX;
 
 	dprintk("--> nfs_d_automount()\n");
 
@@ -255,13 +252,8 @@ struct vfsmount *nfs_d_automount(struct path *path)
 	err = server->nfs_client->rpc_ops->lookup(server->client, parent->d_inode,
 						  &path->dentry->d_name,
 						  fh, fattr);
-	if (err == -EPERM) {
-		flavor = nfs_lookup_with_sec(server, parent, path->dentry, path, fh, fattr);
-		if (flavor < 0)
-			err = flavor;
-		else
-			err = 0;
-	}
+	if (err == -EPERM && NFS_PROTO(parent->d_inode)->secinfo != NULL)
+		err = nfs_lookup_with_sec(server, parent, path->dentry, path, fh, fattr, &flavor);
 	dput(parent);
 	if (err != 0) {
 		mnt = ERR_PTR(err);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index dfd1e6d7e6c3..9bf41eab3e46 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2204,8 +2204,6 @@ static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandl
 		goto out;
 	}
 	ret = nfs4_lookup_root(server, fhandle, info);
-	if (ret < 0)
-		ret = -EAGAIN;
 out:
 	return ret;
 }
@@ -2226,7 +2224,7 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
 
 	for (i = 0; i < len; i++) {
 		status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]);
-		if (status == 0)
+		if (status != -EPERM)
 			break;
 	}
 	if (status == 0)
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 9022f0a6503e..0a9a2ec2e469 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -427,7 +427,7 @@ static int
 context_derive_keys_rc4(struct krb5_ctx *ctx)
 {
 	struct crypto_hash *hmac;
-	static const char sigkeyconstant[] = "signaturekey";
+	char sigkeyconstant[] = "signaturekey";
 	int slen = strlen(sigkeyconstant) + 1;	/* include null terminator */
 	struct hash_desc desc;
 	struct scatterlist sg[1];