diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-02-22 18:44:32 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-03-11 15:39:27 -0500 |
commit | b064eca2cf6440bf9d5843b24cc4010624031694 (patch) | |
tree | f1024db40bf0afb7b764d6ee825d24cd715d1cc5 /fs/nfs | |
parent | 3ddeb7c5c61d0d6bfd837487d3454ffdb788bb91 (diff) |
NFSv4: Send unmapped uid/gids to the server when using auth_sys
The new behaviour is enabled using the new module parameter
'nfs4_disable_idmapping'.
Note that if the server rejects an unmapped uid or gid, then
the client will automatically switch back to using the idmapper.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/client.c | 16 | ||||
-rw-r--r-- | fs/nfs/idmap.c | 24 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 15 |
3 files changed, 46 insertions, 9 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 6dd50ac5b545..139be9647d80 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -82,6 +82,11 @@ retry: | |||
82 | #endif /* CONFIG_NFS_V4 */ | 82 | #endif /* CONFIG_NFS_V4 */ |
83 | 83 | ||
84 | /* | 84 | /* |
85 | * Turn off NFSv4 uid/gid mapping when using AUTH_SYS | ||
86 | */ | ||
87 | static int nfs4_disable_idmapping = 0; | ||
88 | |||
89 | /* | ||
85 | * RPC cruft for NFS | 90 | * RPC cruft for NFS |
86 | */ | 91 | */ |
87 | static struct rpc_version *nfs_version[5] = { | 92 | static struct rpc_version *nfs_version[5] = { |
@@ -1567,6 +1572,13 @@ static int nfs4_init_server(struct nfs_server *server, | |||
1567 | if (error < 0) | 1572 | if (error < 0) |
1568 | goto error; | 1573 | goto error; |
1569 | 1574 | ||
1575 | /* | ||
1576 | * Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower | ||
1577 | * authentication. | ||
1578 | */ | ||
1579 | if (nfs4_disable_idmapping && data->auth_flavors[0] == RPC_AUTH_UNIX) | ||
1580 | server->caps |= NFS_CAP_UIDGID_NOMAP; | ||
1581 | |||
1570 | if (data->rsize) | 1582 | if (data->rsize) |
1571 | server->rsize = nfs_block_size(data->rsize, NULL); | 1583 | server->rsize = nfs_block_size(data->rsize, NULL); |
1572 | if (data->wsize) | 1584 | if (data->wsize) |
@@ -1984,3 +1996,7 @@ void nfs_fs_proc_exit(void) | |||
1984 | } | 1996 | } |
1985 | 1997 | ||
1986 | #endif /* CONFIG_PROC_FS */ | 1998 | #endif /* CONFIG_PROC_FS */ |
1999 | |||
2000 | module_param(nfs4_disable_idmapping, bool, 0644); | ||
2001 | MODULE_PARM_DESC(nfs4_disable_idmapping, | ||
2002 | "Turn off NFSv4 idmapping when using 'sec=sys'"); | ||
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index e2d579d458f1..79664a1025af 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
@@ -61,6 +61,9 @@ static int nfs_map_numeric_to_string(__u32 id, char *buf, size_t buflen) | |||
61 | 61 | ||
62 | #include <linux/slab.h> | 62 | #include <linux/slab.h> |
63 | #include <linux/cred.h> | 63 | #include <linux/cred.h> |
64 | #include <linux/sunrpc/sched.h> | ||
65 | #include <linux/nfs4.h> | ||
66 | #include <linux/nfs_fs_sb.h> | ||
64 | #include <linux/nfs_idmap.h> | 67 | #include <linux/nfs_idmap.h> |
65 | #include <linux/keyctl.h> | 68 | #include <linux/keyctl.h> |
66 | #include <linux/key-type.h> | 69 | #include <linux/key-type.h> |
@@ -257,17 +260,20 @@ int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size | |||
257 | 260 | ||
258 | int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen) | 261 | int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen) |
259 | { | 262 | { |
260 | int ret; | 263 | int ret = -EINVAL; |
261 | ret = nfs_idmap_lookup_name(uid, "user", buf, buflen); | 264 | |
265 | if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) | ||
266 | ret = nfs_idmap_lookup_name(uid, "user", buf, buflen); | ||
262 | if (ret < 0) | 267 | if (ret < 0) |
263 | ret = nfs_map_numeric_to_string(uid, buf, buflen); | 268 | ret = nfs_map_numeric_to_string(uid, buf, buflen); |
264 | return ret; | 269 | return ret; |
265 | } | 270 | } |
266 | int nfs_map_gid_to_group(const struct nfs_server *server, __u32 gid, char *buf, size_t buflen) | 271 | int nfs_map_gid_to_group(const struct nfs_server *server, __u32 gid, char *buf, size_t buflen) |
267 | { | 272 | { |
268 | int ret; | 273 | int ret = -EINVAL; |
269 | 274 | ||
270 | ret = nfs_idmap_lookup_name(gid, "group", buf, buflen); | 275 | if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) |
276 | ret = nfs_idmap_lookup_name(gid, "group", buf, buflen); | ||
271 | if (ret < 0) | 277 | if (ret < 0) |
272 | ret = nfs_map_numeric_to_string(gid, buf, buflen); | 278 | ret = nfs_map_numeric_to_string(gid, buf, buflen); |
273 | return ret; | 279 | return ret; |
@@ -750,9 +756,10 @@ int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size | |||
750 | int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen) | 756 | int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen) |
751 | { | 757 | { |
752 | struct idmap *idmap = server->nfs_client->cl_idmap; | 758 | struct idmap *idmap = server->nfs_client->cl_idmap; |
753 | int ret; | 759 | int ret = -EINVAL; |
754 | 760 | ||
755 | ret = nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf); | 761 | if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) |
762 | ret = nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf); | ||
756 | if (ret < 0) | 763 | if (ret < 0) |
757 | ret = nfs_map_numeric_to_string(uid, buf, buflen); | 764 | ret = nfs_map_numeric_to_string(uid, buf, buflen); |
758 | return ret; | 765 | return ret; |
@@ -760,9 +767,10 @@ int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, s | |||
760 | int nfs_map_gid_to_group(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen) | 767 | int nfs_map_gid_to_group(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen) |
761 | { | 768 | { |
762 | struct idmap *idmap = server->nfs_client->cl_idmap; | 769 | struct idmap *idmap = server->nfs_client->cl_idmap; |
763 | int ret; | 770 | int ret = -EINVAL; |
764 | 771 | ||
765 | ret = nfs_idmap_name(idmap, &idmap->idmap_group_hash, uid, buf); | 772 | if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) |
773 | ret = nfs_idmap_name(idmap, &idmap->idmap_group_hash, uid, buf); | ||
766 | if (ret < 0) | 774 | if (ret < 0) |
767 | ret = nfs_map_numeric_to_string(uid, buf, buflen); | 775 | ret = nfs_map_numeric_to_string(uid, buf, buflen); |
768 | return ret; | 776 | return ret; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 8f3ada04ea19..1d84e7088af9 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -244,7 +244,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout) | |||
244 | /* This is the error handling routine for processes that are allowed | 244 | /* This is the error handling routine for processes that are allowed |
245 | * to sleep. | 245 | * to sleep. |
246 | */ | 246 | */ |
247 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception) | 247 | static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception) |
248 | { | 248 | { |
249 | struct nfs_client *clp = server->nfs_client; | 249 | struct nfs_client *clp = server->nfs_client; |
250 | struct nfs4_state *state = exception->state; | 250 | struct nfs4_state *state = exception->state; |
@@ -296,6 +296,19 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, | |||
296 | break; | 296 | break; |
297 | case -NFS4ERR_OLD_STATEID: | 297 | case -NFS4ERR_OLD_STATEID: |
298 | exception->retry = 1; | 298 | exception->retry = 1; |
299 | break; | ||
300 | case -NFS4ERR_BADOWNER: | ||
301 | /* The following works around a Linux server bug! */ | ||
302 | case -NFS4ERR_BADNAME: | ||
303 | if (server->caps & NFS_CAP_UIDGID_NOMAP) { | ||
304 | server->caps &= ~NFS_CAP_UIDGID_NOMAP; | ||
305 | exception->retry = 1; | ||
306 | printk(KERN_WARNING "NFS: v4 server %s " | ||
307 | "does not accept raw " | ||
308 | "uid/gids. " | ||
309 | "Reenabling the idmapper.\n", | ||
310 | server->nfs_client->cl_hostname); | ||
311 | } | ||
299 | } | 312 | } |
300 | /* We failed to handle the error */ | 313 | /* We failed to handle the error */ |
301 | return nfs4_map_errors(ret); | 314 | return nfs4_map_errors(ret); |