aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2019-04-24 17:46:47 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2019-04-26 17:10:53 -0400
commit58002399da65c53f00987623d9ff7c3c2773a0d9 (patch)
tree37b2f2e5f8449f33996fcffaede37654bde31a04 /fs/nfs
parent264d948ce7d0b99cbe1aae704bbef8d951602eec (diff)
NFSv4: Convert the NFS client idmapper to use the container user namespace
When mapping NFS identities using the NFSv4 idmapper, we want to substitute for the uids and gids that would normally go on the wire as part of a NFSv3 request. So we use the same mapping in the NFSv4 upcall as we use in the NFSv3 RPC call (i.e. the mapping stored in the rpc_clnt cred). Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4idmap.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c
index bf34ddaa2ad7..4884fdae28fb 100644
--- a/fs/nfs/nfs4idmap.c
+++ b/fs/nfs/nfs4idmap.c
@@ -69,8 +69,16 @@ struct idmap {
69 struct rpc_pipe *idmap_pipe; 69 struct rpc_pipe *idmap_pipe;
70 struct idmap_legacy_upcalldata *idmap_upcall_data; 70 struct idmap_legacy_upcalldata *idmap_upcall_data;
71 struct mutex idmap_mutex; 71 struct mutex idmap_mutex;
72 const struct cred *cred;
72}; 73};
73 74
75static struct user_namespace *idmap_userns(const struct idmap *idmap)
76{
77 if (idmap && idmap->cred)
78 return idmap->cred->user_ns;
79 return &init_user_ns;
80}
81
74/** 82/**
75 * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields 83 * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields
76 * @fattr: fully initialised struct nfs_fattr 84 * @fattr: fully initialised struct nfs_fattr
@@ -271,14 +279,15 @@ static struct key *nfs_idmap_request_key(const char *name, size_t namelen,
271 const char *type, struct idmap *idmap) 279 const char *type, struct idmap *idmap)
272{ 280{
273 char *desc; 281 char *desc;
274 struct key *rkey; 282 struct key *rkey = ERR_PTR(-EAGAIN);
275 ssize_t ret; 283 ssize_t ret;
276 284
277 ret = nfs_idmap_get_desc(name, namelen, type, strlen(type), &desc); 285 ret = nfs_idmap_get_desc(name, namelen, type, strlen(type), &desc);
278 if (ret < 0) 286 if (ret < 0)
279 return ERR_PTR(ret); 287 return ERR_PTR(ret);
280 288
281 rkey = request_key(&key_type_id_resolver, desc, ""); 289 if (!idmap->cred || idmap->cred->user_ns == &init_user_ns)
290 rkey = request_key(&key_type_id_resolver, desc, "");
282 if (IS_ERR(rkey)) { 291 if (IS_ERR(rkey)) {
283 mutex_lock(&idmap->idmap_mutex); 292 mutex_lock(&idmap->idmap_mutex);
284 rkey = request_key_with_auxdata(&key_type_id_resolver_legacy, 293 rkey = request_key_with_auxdata(&key_type_id_resolver_legacy,
@@ -452,6 +461,9 @@ nfs_idmap_new(struct nfs_client *clp)
452 if (idmap == NULL) 461 if (idmap == NULL)
453 return -ENOMEM; 462 return -ENOMEM;
454 463
464 mutex_init(&idmap->idmap_mutex);
465 idmap->cred = get_cred(clp->cl_rpcclient->cl_cred);
466
455 rpc_init_pipe_dir_object(&idmap->idmap_pdo, 467 rpc_init_pipe_dir_object(&idmap->idmap_pdo,
456 &nfs_idmap_pipe_dir_object_ops, 468 &nfs_idmap_pipe_dir_object_ops,
457 idmap); 469 idmap);
@@ -462,7 +474,6 @@ nfs_idmap_new(struct nfs_client *clp)
462 goto err; 474 goto err;
463 } 475 }
464 idmap->idmap_pipe = pipe; 476 idmap->idmap_pipe = pipe;
465 mutex_init(&idmap->idmap_mutex);
466 477
467 error = rpc_add_pipe_dir_object(clp->cl_net, 478 error = rpc_add_pipe_dir_object(clp->cl_net,
468 &clp->cl_rpcclient->cl_pipedir_objects, 479 &clp->cl_rpcclient->cl_pipedir_objects,
@@ -475,6 +486,7 @@ nfs_idmap_new(struct nfs_client *clp)
475err_destroy_pipe: 486err_destroy_pipe:
476 rpc_destroy_pipe_data(idmap->idmap_pipe); 487 rpc_destroy_pipe_data(idmap->idmap_pipe);
477err: 488err:
489 put_cred(idmap->cred);
478 kfree(idmap); 490 kfree(idmap);
479 return error; 491 return error;
480} 492}
@@ -491,6 +503,7 @@ nfs_idmap_delete(struct nfs_client *clp)
491 &clp->cl_rpcclient->cl_pipedir_objects, 503 &clp->cl_rpcclient->cl_pipedir_objects,
492 &idmap->idmap_pdo); 504 &idmap->idmap_pdo);
493 rpc_destroy_pipe_data(idmap->idmap_pipe); 505 rpc_destroy_pipe_data(idmap->idmap_pipe);
506 put_cred(idmap->cred);
494 kfree(idmap); 507 kfree(idmap);
495} 508}
496 509
@@ -735,7 +748,7 @@ int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_
735 if (!nfs_map_string_to_numeric(name, namelen, &id)) 748 if (!nfs_map_string_to_numeric(name, namelen, &id))
736 ret = nfs_idmap_lookup_id(name, namelen, "uid", &id, idmap); 749 ret = nfs_idmap_lookup_id(name, namelen, "uid", &id, idmap);
737 if (ret == 0) { 750 if (ret == 0) {
738 *uid = make_kuid(&init_user_ns, id); 751 *uid = make_kuid(idmap_userns(idmap), id);
739 if (!uid_valid(*uid)) 752 if (!uid_valid(*uid))
740 ret = -ERANGE; 753 ret = -ERANGE;
741 } 754 }
@@ -752,7 +765,7 @@ int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size
752 if (!nfs_map_string_to_numeric(name, namelen, &id)) 765 if (!nfs_map_string_to_numeric(name, namelen, &id))
753 ret = nfs_idmap_lookup_id(name, namelen, "gid", &id, idmap); 766 ret = nfs_idmap_lookup_id(name, namelen, "gid", &id, idmap);
754 if (ret == 0) { 767 if (ret == 0) {
755 *gid = make_kgid(&init_user_ns, id); 768 *gid = make_kgid(idmap_userns(idmap), id);
756 if (!gid_valid(*gid)) 769 if (!gid_valid(*gid))
757 ret = -ERANGE; 770 ret = -ERANGE;
758 } 771 }
@@ -766,7 +779,7 @@ int nfs_map_uid_to_name(const struct nfs_server *server, kuid_t uid, char *buf,
766 int ret = -EINVAL; 779 int ret = -EINVAL;
767 __u32 id; 780 __u32 id;
768 781
769 id = from_kuid(&init_user_ns, uid); 782 id = from_kuid_munged(idmap_userns(idmap), uid);
770 if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) 783 if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
771 ret = nfs_idmap_lookup_name(id, "user", buf, buflen, idmap); 784 ret = nfs_idmap_lookup_name(id, "user", buf, buflen, idmap);
772 if (ret < 0) 785 if (ret < 0)
@@ -780,7 +793,7 @@ int nfs_map_gid_to_group(const struct nfs_server *server, kgid_t gid, char *buf,
780 int ret = -EINVAL; 793 int ret = -EINVAL;
781 __u32 id; 794 __u32 id;
782 795
783 id = from_kgid(&init_user_ns, gid); 796 id = from_kgid_munged(idmap_userns(idmap), gid);
784 if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) 797 if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
785 ret = nfs_idmap_lookup_name(id, "group", buf, buflen, idmap); 798 ret = nfs_idmap_lookup_name(id, "group", buf, buflen, idmap);
786 if (ret < 0) 799 if (ret < 0)