aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-04-08 14:47:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-04-08 14:47:35 -0400
commit94c8a984ae2adbd9a9626fb42e0f2faf3e36e86f (patch)
treea4beddd64501ef00ad41c8fd5974340bec2fcf73 /fs
parentf9fa0bc1fabe1d861e46d80ecbe7e85da359195c (diff)
parent37adb89fadd65ce47f7e5cfd564938a76b351948 (diff)
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"
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/namespace.c58
-rw-r--r--fs/nfs/nfs4proc.c4
2 files changed, 26 insertions, 36 deletions
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 9166fcb66da..89fc160fd5b 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,
148 return pseudoflavor; 148 return pseudoflavor;
149} 149}
150 150
151static rpc_authflavor_t nfs_negotiate_security(const struct dentry *parent, const struct dentry *dentry) 151static int nfs_negotiate_security(const struct dentry *parent,
152 const struct dentry *dentry,
153 rpc_authflavor_t *flavor)
152{ 154{
153 int status = 0;
154 struct page *page; 155 struct page *page;
155 struct nfs4_secinfo_flavors *flavors; 156 struct nfs4_secinfo_flavors *flavors;
156 int (*secinfo)(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); 157 int (*secinfo)(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *);
157 rpc_authflavor_t flavor = RPC_AUTH_UNIX; 158 int ret = -EPERM;
158 159
159 secinfo = NFS_PROTO(parent->d_inode)->secinfo; 160 secinfo = NFS_PROTO(parent->d_inode)->secinfo;
160 if (secinfo != NULL) { 161 if (secinfo != NULL) {
161 page = alloc_page(GFP_KERNEL); 162 page = alloc_page(GFP_KERNEL);
162 if (!page) { 163 if (!page) {
163 status = -ENOMEM; 164 ret = -ENOMEM;
164 goto out; 165 goto out;
165 } 166 }
166 flavors = page_address(page); 167 flavors = page_address(page);
167 status = secinfo(parent->d_inode, &dentry->d_name, flavors); 168 ret = secinfo(parent->d_inode, &dentry->d_name, flavors);
168 flavor = nfs_find_best_sec(flavors, dentry->d_inode); 169 *flavor = nfs_find_best_sec(flavors, dentry->d_inode);
169 put_page(page); 170 put_page(page);
170 } 171 }
171 172
172 return flavor;
173
174out: 173out:
175 status = -ENOMEM; 174 return ret;
176 return status;
177} 175}
178 176
179static rpc_authflavor_t nfs_lookup_with_sec(struct nfs_server *server, struct dentry *parent, 177static int nfs_lookup_with_sec(struct nfs_server *server, struct dentry *parent,
180 struct dentry *dentry, struct path *path, 178 struct dentry *dentry, struct path *path,
181 struct nfs_fh *fh, struct nfs_fattr *fattr) 179 struct nfs_fh *fh, struct nfs_fattr *fattr,
180 rpc_authflavor_t *flavor)
182{ 181{
183 rpc_authflavor_t flavor;
184 struct rpc_clnt *clone; 182 struct rpc_clnt *clone;
185 struct rpc_auth *auth; 183 struct rpc_auth *auth;
186 int err; 184 int err;
187 185
188 flavor = nfs_negotiate_security(parent, path->dentry); 186 err = nfs_negotiate_security(parent, path->dentry, flavor);
189 if (flavor < 0) 187 if (err < 0)
190 goto out; 188 goto out;
191 clone = rpc_clone_client(server->client); 189 clone = rpc_clone_client(server->client);
192 auth = rpcauth_create(flavor, clone); 190 auth = rpcauth_create(*flavor, clone);
193 if (!auth) { 191 if (!auth) {
194 flavor = -EIO; 192 err = -EIO;
195 goto out_shutdown; 193 goto out_shutdown;
196 } 194 }
197 err = server->nfs_client->rpc_ops->lookup(clone, parent->d_inode, 195 err = server->nfs_client->rpc_ops->lookup(clone, parent->d_inode,
198 &path->dentry->d_name, 196 &path->dentry->d_name,
199 fh, fattr); 197 fh, fattr);
200 if (err < 0)
201 flavor = err;
202out_shutdown: 198out_shutdown:
203 rpc_shutdown_client(clone); 199 rpc_shutdown_client(clone);
204out: 200out:
205 return flavor; 201 return err;
206} 202}
207#else /* CONFIG_NFS_V4 */ 203#else /* CONFIG_NFS_V4 */
208static inline rpc_authflavor_t nfs_lookup_with_sec(struct nfs_server *server, 204static inline int nfs_lookup_with_sec(struct nfs_server *server,
209 struct dentry *parent, struct dentry *dentry, 205 struct dentry *parent, struct dentry *dentry,
210 struct path *path, struct nfs_fh *fh, 206 struct path *path, struct nfs_fh *fh,
211 struct nfs_fattr *fattr) 207 struct nfs_fattr *fattr,
208 rpc_authflavor_t *flavor)
212{ 209{
213 return -EPERM; 210 return -EPERM;
214} 211}
@@ -234,7 +231,7 @@ struct vfsmount *nfs_d_automount(struct path *path)
234 struct nfs_fh *fh = NULL; 231 struct nfs_fh *fh = NULL;
235 struct nfs_fattr *fattr = NULL; 232 struct nfs_fattr *fattr = NULL;
236 int err; 233 int err;
237 rpc_authflavor_t flavor = 1; 234 rpc_authflavor_t flavor = RPC_AUTH_UNIX;
238 235
239 dprintk("--> nfs_d_automount()\n"); 236 dprintk("--> nfs_d_automount()\n");
240 237
@@ -255,13 +252,8 @@ struct vfsmount *nfs_d_automount(struct path *path)
255 err = server->nfs_client->rpc_ops->lookup(server->client, parent->d_inode, 252 err = server->nfs_client->rpc_ops->lookup(server->client, parent->d_inode,
256 &path->dentry->d_name, 253 &path->dentry->d_name,
257 fh, fattr); 254 fh, fattr);
258 if (err == -EPERM) { 255 if (err == -EPERM && NFS_PROTO(parent->d_inode)->secinfo != NULL)
259 flavor = nfs_lookup_with_sec(server, parent, path->dentry, path, fh, fattr); 256 err = nfs_lookup_with_sec(server, parent, path->dentry, path, fh, fattr, &flavor);
260 if (flavor < 0)
261 err = flavor;
262 else
263 err = 0;
264 }
265 dput(parent); 257 dput(parent);
266 if (err != 0) { 258 if (err != 0) {
267 mnt = ERR_PTR(err); 259 mnt = ERR_PTR(err);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index dfd1e6d7e6c..9bf41eab3e4 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
2204 goto out; 2204 goto out;
2205 } 2205 }
2206 ret = nfs4_lookup_root(server, fhandle, info); 2206 ret = nfs4_lookup_root(server, fhandle, info);
2207 if (ret < 0)
2208 ret = -EAGAIN;
2209out: 2207out:
2210 return ret; 2208 return ret;
2211} 2209}
@@ -2226,7 +2224,7 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
2226 2224
2227 for (i = 0; i < len; i++) { 2225 for (i = 0; i < len; i++) {
2228 status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]); 2226 status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]);
2229 if (status == 0) 2227 if (status != -EPERM)
2230 break; 2228 break;
2231 } 2229 }
2232 if (status == 0) 2230 if (status == 0)