xref: /linux/fs/nfs/nfs4idmap.c (revision e9a83bd2322035ed9d7dcf35753d3f984d76c6a5)
1 /*
2  * fs/nfs/idmap.c
3  *
4  *  UID and GID to name mapping for clients.
5  *
6  *  Copyright (c) 2002 The Regents of the University of Michigan.
7  *  All rights reserved.
8  *
9  *  Marius Aamodt Eriksen <marius@umich.edu>
10  *
11  *  Redistribution and use in source and binary forms, with or without
12  *  modification, are permitted provided that the following conditions
13  *  are met:
14  *
15  *  1. Redistributions of source code must retain the above copyright
16  *     notice, this list of conditions and the following disclaimer.
17  *  2. Redistributions in binary form must reproduce the above copyright
18  *     notice, this list of conditions and the following disclaimer in the
19  *     documentation and/or other materials provided with the distribution.
20  *  3. Neither the name of the University nor the names of its
21  *     contributors may be used to endorse or promote products derived
22  *     from this software without specific prior written permission.
23  *
24  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
25  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
31  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  */
36 #include <linux/types.h>
37 #include <linux/parser.h>
38 #include <linux/fs.h>
39 #include <net/net_namespace.h>
40 #include <linux/sunrpc/rpc_pipe_fs.h>
41 #include <linux/nfs_fs.h>
42 #include <linux/nfs_fs_sb.h>
43 #include <linux/key.h>
44 #include <linux/keyctl.h>
45 #include <linux/key-type.h>
46 #include <keys/user-type.h>
47 #include <keys/request_key_auth-type.h>
48 #include <linux/module.h>
49 
50 #include "internal.h"
51 #include "netns.h"
52 #include "nfs4idmap.h"
53 #include "nfs4trace.h"
54 
55 #define NFS_UINT_MAXLEN 11
56 
57 static const struct cred *id_resolver_cache;
58 static struct key_type key_type_id_resolver_legacy;
59 
60 struct idmap_legacy_upcalldata {
61 	struct rpc_pipe_msg pipe_msg;
62 	struct idmap_msg idmap_msg;
63 	struct key	*authkey;
64 	struct idmap *idmap;
65 };
66 
67 struct idmap {
68 	struct rpc_pipe_dir_object idmap_pdo;
69 	struct rpc_pipe		*idmap_pipe;
70 	struct idmap_legacy_upcalldata *idmap_upcall_data;
71 	struct mutex		idmap_mutex;
72 	const struct cred	*cred;
73 };
74 
75 static struct key_acl nfs_idmap_key_acl = {
76 	.usage	= REFCOUNT_INIT(1),
77 	.nr_ace	= 2,
78 	.possessor_viewable = true,
79 	.aces = {
80 		KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_SEARCH | KEY_ACE_READ),
81 		KEY_OWNER_ACE(KEY_ACE_VIEW),
82 	}
83 };
84 
85 static struct key_acl nfs_idmap_keyring_acl = {
86 	.usage	= REFCOUNT_INIT(1),
87 	.nr_ace	= 2,
88 	.aces = {
89 		KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_WRITE),
90 		KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ),
91 	}
92 };
93 
94 static struct user_namespace *idmap_userns(const struct idmap *idmap)
95 {
96 	if (idmap && idmap->cred)
97 		return idmap->cred->user_ns;
98 	return &init_user_ns;
99 }
100 
101 /**
102  * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields
103  * @fattr: fully initialised struct nfs_fattr
104  * @owner_name: owner name string cache
105  * @group_name: group name string cache
106  */
107 void nfs_fattr_init_names(struct nfs_fattr *fattr,
108 		struct nfs4_string *owner_name,
109 		struct nfs4_string *group_name)
110 {
111 	fattr->owner_name = owner_name;
112 	fattr->group_name = group_name;
113 }
114 
115 static void nfs_fattr_free_owner_name(struct nfs_fattr *fattr)
116 {
117 	fattr->valid &= ~NFS_ATTR_FATTR_OWNER_NAME;
118 	kfree(fattr->owner_name->data);
119 }
120 
121 static void nfs_fattr_free_group_name(struct nfs_fattr *fattr)
122 {
123 	fattr->valid &= ~NFS_ATTR_FATTR_GROUP_NAME;
124 	kfree(fattr->group_name->data);
125 }
126 
127 static bool nfs_fattr_map_owner_name(struct nfs_server *server, struct nfs_fattr *fattr)
128 {
129 	struct nfs4_string *owner = fattr->owner_name;
130 	kuid_t uid;
131 
132 	if (!(fattr->valid & NFS_ATTR_FATTR_OWNER_NAME))
133 		return false;
134 	if (nfs_map_name_to_uid(server, owner->data, owner->len, &uid) == 0) {
135 		fattr->uid = uid;
136 		fattr->valid |= NFS_ATTR_FATTR_OWNER;
137 	}
138 	return true;
139 }
140 
141 static bool nfs_fattr_map_group_name(struct nfs_server *server, struct nfs_fattr *fattr)
142 {
143 	struct nfs4_string *group = fattr->group_name;
144 	kgid_t gid;
145 
146 	if (!(fattr->valid & NFS_ATTR_FATTR_GROUP_NAME))
147 		return false;
148 	if (nfs_map_group_to_gid(server, group->data, group->len, &gid) == 0) {
149 		fattr->gid = gid;
150 		fattr->valid |= NFS_ATTR_FATTR_GROUP;
151 	}
152 	return true;
153 }
154 
155 /**
156  * nfs_fattr_free_names - free up the NFSv4 owner and group strings
157  * @fattr: a fully initialised nfs_fattr structure
158  */
159 void nfs_fattr_free_names(struct nfs_fattr *fattr)
160 {
161 	if (fattr->valid & NFS_ATTR_FATTR_OWNER_NAME)
162 		nfs_fattr_free_owner_name(fattr);
163 	if (fattr->valid & NFS_ATTR_FATTR_GROUP_NAME)
164 		nfs_fattr_free_group_name(fattr);
165 }
166 
167 /**
168  * nfs_fattr_map_and_free_names - map owner/group strings into uid/gid and free
169  * @server: pointer to the filesystem nfs_server structure
170  * @fattr: a fully initialised nfs_fattr structure
171  *
172  * This helper maps the cached NFSv4 owner/group strings in fattr into
173  * their numeric uid/gid equivalents, and then frees the cached strings.
174  */
175 void nfs_fattr_map_and_free_names(struct nfs_server *server, struct nfs_fattr *fattr)
176 {
177 	if (nfs_fattr_map_owner_name(server, fattr))
178 		nfs_fattr_free_owner_name(fattr);
179 	if (nfs_fattr_map_group_name(server, fattr))
180 		nfs_fattr_free_group_name(fattr);
181 }
182 
183 int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *res)
184 {
185 	unsigned long val;
186 	char buf[16];
187 
188 	if (memchr(name, '@', namelen) != NULL || namelen >= sizeof(buf))
189 		return 0;
190 	memcpy(buf, name, namelen);
191 	buf[namelen] = '\0';
192 	if (kstrtoul(buf, 0, &val) != 0)
193 		return 0;
194 	*res = val;
195 	return 1;
196 }
197 EXPORT_SYMBOL_GPL(nfs_map_string_to_numeric);
198 
199 static int nfs_map_numeric_to_string(__u32 id, char *buf, size_t buflen)
200 {
201 	return snprintf(buf, buflen, "%u", id);
202 }
203 
204 static struct key_type key_type_id_resolver = {
205 	.name		= "id_resolver",
206 	.preparse	= user_preparse,
207 	.free_preparse	= user_free_preparse,
208 	.instantiate	= generic_key_instantiate,
209 	.revoke		= user_revoke,
210 	.destroy	= user_destroy,
211 	.describe	= user_describe,
212 	.read		= user_read,
213 };
214 
215 int nfs_idmap_init(void)
216 {
217 	struct cred *cred;
218 	struct key *keyring;
219 	int ret = 0;
220 
221 	printk(KERN_NOTICE "NFS: Registering the %s key type\n",
222 		key_type_id_resolver.name);
223 
224 	cred = prepare_kernel_cred(NULL);
225 	if (!cred)
226 		return -ENOMEM;
227 
228 	keyring = keyring_alloc(".id_resolver",
229 				GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
230 				&nfs_idmap_keyring_acl,
231 				KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
232 	if (IS_ERR(keyring)) {
233 		ret = PTR_ERR(keyring);
234 		goto failed_put_cred;
235 	}
236 
237 	ret = register_key_type(&key_type_id_resolver);
238 	if (ret < 0)
239 		goto failed_put_key;
240 
241 	ret = register_key_type(&key_type_id_resolver_legacy);
242 	if (ret < 0)
243 		goto failed_reg_legacy;
244 
245 	set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
246 	cred->thread_keyring = keyring;
247 	cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
248 	id_resolver_cache = cred;
249 	return 0;
250 
251 failed_reg_legacy:
252 	unregister_key_type(&key_type_id_resolver);
253 failed_put_key:
254 	key_put(keyring);
255 failed_put_cred:
256 	put_cred(cred);
257 	return ret;
258 }
259 
260 void nfs_idmap_quit(void)
261 {
262 	key_revoke(id_resolver_cache->thread_keyring);
263 	unregister_key_type(&key_type_id_resolver);
264 	unregister_key_type(&key_type_id_resolver_legacy);
265 	put_cred(id_resolver_cache);
266 }
267 
268 /*
269  * Assemble the description to pass to request_key()
270  * This function will allocate a new string and update dest to point
271  * at it.  The caller is responsible for freeing dest.
272  *
273  * On error 0 is returned.  Otherwise, the length of dest is returned.
274  */
275 static ssize_t nfs_idmap_get_desc(const char *name, size_t namelen,
276 				const char *type, size_t typelen, char **desc)
277 {
278 	char *cp;
279 	size_t desclen = typelen + namelen + 2;
280 
281 	*desc = kmalloc(desclen, GFP_KERNEL);
282 	if (!*desc)
283 		return -ENOMEM;
284 
285 	cp = *desc;
286 	memcpy(cp, type, typelen);
287 	cp += typelen;
288 	*cp++ = ':';
289 
290 	memcpy(cp, name, namelen);
291 	cp += namelen;
292 	*cp = '\0';
293 	return desclen;
294 }
295 
296 static struct key *nfs_idmap_request_key(const char *name, size_t namelen,
297 					 const char *type, struct idmap *idmap)
298 {
299 	char *desc;
300 	struct key *rkey = ERR_PTR(-EAGAIN);
301 	ssize_t ret;
302 
303 	ret = nfs_idmap_get_desc(name, namelen, type, strlen(type), &desc);
304 	if (ret < 0)
305 		return ERR_PTR(ret);
306 
307 	if (!idmap->cred || idmap->cred->user_ns == &init_user_ns)
308 		rkey = request_key(&key_type_id_resolver, desc, "",
309 				   &nfs_idmap_key_acl);
310 	if (IS_ERR(rkey)) {
311 		mutex_lock(&idmap->idmap_mutex);
312 		rkey = request_key_with_auxdata(&key_type_id_resolver_legacy,
313 						desc, NULL, "", 0, idmap,
314 						&nfs_idmap_key_acl);
315 		mutex_unlock(&idmap->idmap_mutex);
316 	}
317 	if (!IS_ERR(rkey))
318 		set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags);
319 
320 	kfree(desc);
321 	return rkey;
322 }
323 
324 static ssize_t nfs_idmap_get_key(const char *name, size_t namelen,
325 				 const char *type, void *data,
326 				 size_t data_size, struct idmap *idmap)
327 {
328 	const struct cred *saved_cred;
329 	struct key *rkey;
330 	const struct user_key_payload *payload;
331 	ssize_t ret;
332 
333 	saved_cred = override_creds(id_resolver_cache);
334 	rkey = nfs_idmap_request_key(name, namelen, type, idmap);
335 	revert_creds(saved_cred);
336 
337 	if (IS_ERR(rkey)) {
338 		ret = PTR_ERR(rkey);
339 		goto out;
340 	}
341 
342 	rcu_read_lock();
343 	ret = key_validate(rkey);
344 	if (ret < 0)
345 		goto out_up;
346 
347 	payload = user_key_payload_rcu(rkey);
348 	if (IS_ERR_OR_NULL(payload)) {
349 		ret = PTR_ERR(payload);
350 		goto out_up;
351 	}
352 
353 	ret = payload->datalen;
354 	if (ret > 0 && ret <= data_size)
355 		memcpy(data, payload->data, ret);
356 	else
357 		ret = -EINVAL;
358 
359 out_up:
360 	rcu_read_unlock();
361 	key_put(rkey);
362 out:
363 	return ret;
364 }
365 
366 /* ID -> Name */
367 static ssize_t nfs_idmap_lookup_name(__u32 id, const char *type, char *buf,
368 				     size_t buflen, struct idmap *idmap)
369 {
370 	char id_str[NFS_UINT_MAXLEN];
371 	int id_len;
372 	ssize_t ret;
373 
374 	id_len = nfs_map_numeric_to_string(id, id_str, sizeof(id_str));
375 	ret = nfs_idmap_get_key(id_str, id_len, type, buf, buflen, idmap);
376 	if (ret < 0)
377 		return -EINVAL;
378 	return ret;
379 }
380 
381 /* Name -> ID */
382 static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *type,
383 			       __u32 *id, struct idmap *idmap)
384 {
385 	char id_str[NFS_UINT_MAXLEN];
386 	long id_long;
387 	ssize_t data_size;
388 	int ret = 0;
389 
390 	data_size = nfs_idmap_get_key(name, namelen, type, id_str, NFS_UINT_MAXLEN, idmap);
391 	if (data_size <= 0) {
392 		ret = -EINVAL;
393 	} else {
394 		ret = kstrtol(id_str, 10, &id_long);
395 		if (!ret)
396 			*id = (__u32)id_long;
397 	}
398 	return ret;
399 }
400 
401 /* idmap classic begins here */
402 
403 enum {
404 	Opt_find_uid, Opt_find_gid, Opt_find_user, Opt_find_group, Opt_find_err
405 };
406 
407 static const match_table_t nfs_idmap_tokens = {
408 	{ Opt_find_uid, "uid:%s" },
409 	{ Opt_find_gid, "gid:%s" },
410 	{ Opt_find_user, "user:%s" },
411 	{ Opt_find_group, "group:%s" },
412 	{ Opt_find_err, NULL }
413 };
414 
415 static int nfs_idmap_legacy_upcall(struct key *, void *);
416 static ssize_t idmap_pipe_downcall(struct file *, const char __user *,
417 				   size_t);
418 static void idmap_release_pipe(struct inode *);
419 static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
420 
421 static const struct rpc_pipe_ops idmap_upcall_ops = {
422 	.upcall		= rpc_pipe_generic_upcall,
423 	.downcall	= idmap_pipe_downcall,
424 	.release_pipe	= idmap_release_pipe,
425 	.destroy_msg	= idmap_pipe_destroy_msg,
426 };
427 
428 static struct key_type key_type_id_resolver_legacy = {
429 	.name		= "id_legacy",
430 	.preparse	= user_preparse,
431 	.free_preparse	= user_free_preparse,
432 	.instantiate	= generic_key_instantiate,
433 	.revoke		= user_revoke,
434 	.destroy	= user_destroy,
435 	.describe	= user_describe,
436 	.read		= user_read,
437 	.request_key	= nfs_idmap_legacy_upcall,
438 };
439 
440 static void nfs_idmap_pipe_destroy(struct dentry *dir,
441 		struct rpc_pipe_dir_object *pdo)
442 {
443 	struct idmap *idmap = pdo->pdo_data;
444 	struct rpc_pipe *pipe = idmap->idmap_pipe;
445 
446 	if (pipe->dentry) {
447 		rpc_unlink(pipe->dentry);
448 		pipe->dentry = NULL;
449 	}
450 }
451 
452 static int nfs_idmap_pipe_create(struct dentry *dir,
453 		struct rpc_pipe_dir_object *pdo)
454 {
455 	struct idmap *idmap = pdo->pdo_data;
456 	struct rpc_pipe *pipe = idmap->idmap_pipe;
457 	struct dentry *dentry;
458 
459 	dentry = rpc_mkpipe_dentry(dir, "idmap", idmap, pipe);
460 	if (IS_ERR(dentry))
461 		return PTR_ERR(dentry);
462 	pipe->dentry = dentry;
463 	return 0;
464 }
465 
466 static const struct rpc_pipe_dir_object_ops nfs_idmap_pipe_dir_object_ops = {
467 	.create = nfs_idmap_pipe_create,
468 	.destroy = nfs_idmap_pipe_destroy,
469 };
470 
471 int
472 nfs_idmap_new(struct nfs_client *clp)
473 {
474 	struct idmap *idmap;
475 	struct rpc_pipe *pipe;
476 	int error;
477 
478 	idmap = kzalloc(sizeof(*idmap), GFP_KERNEL);
479 	if (idmap == NULL)
480 		return -ENOMEM;
481 
482 	mutex_init(&idmap->idmap_mutex);
483 	idmap->cred = get_cred(clp->cl_rpcclient->cl_cred);
484 
485 	rpc_init_pipe_dir_object(&idmap->idmap_pdo,
486 			&nfs_idmap_pipe_dir_object_ops,
487 			idmap);
488 
489 	pipe = rpc_mkpipe_data(&idmap_upcall_ops, 0);
490 	if (IS_ERR(pipe)) {
491 		error = PTR_ERR(pipe);
492 		goto err;
493 	}
494 	idmap->idmap_pipe = pipe;
495 
496 	error = rpc_add_pipe_dir_object(clp->cl_net,
497 			&clp->cl_rpcclient->cl_pipedir_objects,
498 			&idmap->idmap_pdo);
499 	if (error)
500 		goto err_destroy_pipe;
501 
502 	clp->cl_idmap = idmap;
503 	return 0;
504 err_destroy_pipe:
505 	rpc_destroy_pipe_data(idmap->idmap_pipe);
506 err:
507 	put_cred(idmap->cred);
508 	kfree(idmap);
509 	return error;
510 }
511 
512 void
513 nfs_idmap_delete(struct nfs_client *clp)
514 {
515 	struct idmap *idmap = clp->cl_idmap;
516 
517 	if (!idmap)
518 		return;
519 	clp->cl_idmap = NULL;
520 	rpc_remove_pipe_dir_object(clp->cl_net,
521 			&clp->cl_rpcclient->cl_pipedir_objects,
522 			&idmap->idmap_pdo);
523 	rpc_destroy_pipe_data(idmap->idmap_pipe);
524 	put_cred(idmap->cred);
525 	kfree(idmap);
526 }
527 
528 static int nfs_idmap_prepare_message(char *desc, struct idmap *idmap,
529 				     struct idmap_msg *im,
530 				     struct rpc_pipe_msg *msg)
531 {
532 	substring_t substr;
533 	int token, ret;
534 
535 	im->im_type = IDMAP_TYPE_GROUP;
536 	token = match_token(desc, nfs_idmap_tokens, &substr);
537 
538 	switch (token) {
539 	case Opt_find_uid:
540 		im->im_type = IDMAP_TYPE_USER;
541 		/* Fall through */
542 	case Opt_find_gid:
543 		im->im_conv = IDMAP_CONV_NAMETOID;
544 		ret = match_strlcpy(im->im_name, &substr, IDMAP_NAMESZ);
545 		break;
546 
547 	case Opt_find_user:
548 		im->im_type = IDMAP_TYPE_USER;
549 		/* Fall through */
550 	case Opt_find_group:
551 		im->im_conv = IDMAP_CONV_IDTONAME;
552 		ret = match_int(&substr, &im->im_id);
553 		if (ret)
554 			goto out;
555 		break;
556 
557 	default:
558 		ret = -EINVAL;
559 		goto out;
560 	}
561 
562 	msg->data = im;
563 	msg->len  = sizeof(struct idmap_msg);
564 
565 out:
566 	return ret;
567 }
568 
569 static bool
570 nfs_idmap_prepare_pipe_upcall(struct idmap *idmap,
571 		struct idmap_legacy_upcalldata *data)
572 {
573 	if (idmap->idmap_upcall_data != NULL) {
574 		WARN_ON_ONCE(1);
575 		return false;
576 	}
577 	idmap->idmap_upcall_data = data;
578 	return true;
579 }
580 
581 static void
582 nfs_idmap_complete_pipe_upcall_locked(struct idmap *idmap, int ret)
583 {
584 	struct key *authkey = idmap->idmap_upcall_data->authkey;
585 
586 	kfree(idmap->idmap_upcall_data);
587 	idmap->idmap_upcall_data = NULL;
588 	complete_request_key(authkey, ret);
589 	key_put(authkey);
590 }
591 
592 static void
593 nfs_idmap_abort_pipe_upcall(struct idmap *idmap, int ret)
594 {
595 	if (idmap->idmap_upcall_data != NULL)
596 		nfs_idmap_complete_pipe_upcall_locked(idmap, ret);
597 }
598 
599 static int nfs_idmap_legacy_upcall(struct key *authkey, void *aux)
600 {
601 	struct idmap_legacy_upcalldata *data;
602 	struct request_key_auth *rka = get_request_key_auth(authkey);
603 	struct rpc_pipe_msg *msg;
604 	struct idmap_msg *im;
605 	struct idmap *idmap = (struct idmap *)aux;
606 	struct key *key = rka->target_key;
607 	int ret = -ENOKEY;
608 
609 	if (!aux)
610 		goto out1;
611 
612 	/* msg and im are freed in idmap_pipe_destroy_msg */
613 	ret = -ENOMEM;
614 	data = kzalloc(sizeof(*data), GFP_KERNEL);
615 	if (!data)
616 		goto out1;
617 
618 	msg = &data->pipe_msg;
619 	im = &data->idmap_msg;
620 	data->idmap = idmap;
621 	data->authkey = key_get(authkey);
622 
623 	ret = nfs_idmap_prepare_message(key->description, idmap, im, msg);
624 	if (ret < 0)
625 		goto out2;
626 
627 	ret = -EAGAIN;
628 	if (!nfs_idmap_prepare_pipe_upcall(idmap, data))
629 		goto out2;
630 
631 	ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
632 	if (ret < 0)
633 		nfs_idmap_abort_pipe_upcall(idmap, ret);
634 
635 	return ret;
636 out2:
637 	kfree(data);
638 out1:
639 	complete_request_key(authkey, ret);
640 	return ret;
641 }
642 
643 static int nfs_idmap_instantiate(struct key *key, struct key *authkey, char *data, size_t datalen)
644 {
645 	return key_instantiate_and_link(key, data, datalen,
646 					id_resolver_cache->thread_keyring,
647 					authkey);
648 }
649 
650 static int nfs_idmap_read_and_verify_message(struct idmap_msg *im,
651 		struct idmap_msg *upcall,
652 		struct key *key, struct key *authkey)
653 {
654 	char id_str[NFS_UINT_MAXLEN];
655 	size_t len;
656 	int ret = -ENOKEY;
657 
658 	/* ret = -ENOKEY */
659 	if (upcall->im_type != im->im_type || upcall->im_conv != im->im_conv)
660 		goto out;
661 	switch (im->im_conv) {
662 	case IDMAP_CONV_NAMETOID:
663 		if (strcmp(upcall->im_name, im->im_name) != 0)
664 			break;
665 		/* Note: here we store the NUL terminator too */
666 		len = 1 + nfs_map_numeric_to_string(im->im_id, id_str,
667 						    sizeof(id_str));
668 		ret = nfs_idmap_instantiate(key, authkey, id_str, len);
669 		break;
670 	case IDMAP_CONV_IDTONAME:
671 		if (upcall->im_id != im->im_id)
672 			break;
673 		len = strlen(im->im_name);
674 		ret = nfs_idmap_instantiate(key, authkey, im->im_name, len);
675 		break;
676 	default:
677 		ret = -EINVAL;
678 	}
679 out:
680 	return ret;
681 }
682 
683 static ssize_t
684 idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
685 {
686 	struct request_key_auth *rka;
687 	struct rpc_inode *rpci = RPC_I(file_inode(filp));
688 	struct idmap *idmap = (struct idmap *)rpci->private;
689 	struct key *authkey;
690 	struct idmap_msg im;
691 	size_t namelen_in;
692 	int ret = -ENOKEY;
693 
694 	/* If instantiation is successful, anyone waiting for key construction
695 	 * will have been woken up and someone else may now have used
696 	 * idmap_key_cons - so after this point we may no longer touch it.
697 	 */
698 	if (idmap->idmap_upcall_data == NULL)
699 		goto out_noupcall;
700 
701 	authkey = idmap->idmap_upcall_data->authkey;
702 	rka = get_request_key_auth(authkey);
703 
704 	if (mlen != sizeof(im)) {
705 		ret = -ENOSPC;
706 		goto out;
707 	}
708 
709 	if (copy_from_user(&im, src, mlen) != 0) {
710 		ret = -EFAULT;
711 		goto out;
712 	}
713 
714 	if (!(im.im_status & IDMAP_STATUS_SUCCESS)) {
715 		ret = -ENOKEY;
716 		goto out;
717 	}
718 
719 	namelen_in = strnlen(im.im_name, IDMAP_NAMESZ);
720 	if (namelen_in == 0 || namelen_in == IDMAP_NAMESZ) {
721 		ret = -EINVAL;
722 		goto out;
723 }
724 
725 	ret = nfs_idmap_read_and_verify_message(&im,
726 			&idmap->idmap_upcall_data->idmap_msg,
727 			rka->target_key, authkey);
728 	if (ret >= 0) {
729 		key_set_timeout(rka->target_key, nfs_idmap_cache_timeout);
730 		ret = mlen;
731 	}
732 
733 out:
734 	nfs_idmap_complete_pipe_upcall_locked(idmap, ret);
735 out_noupcall:
736 	return ret;
737 }
738 
739 static void
740 idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg)
741 {
742 	struct idmap_legacy_upcalldata *data = container_of(msg,
743 			struct idmap_legacy_upcalldata,
744 			pipe_msg);
745 	struct idmap *idmap = data->idmap;
746 
747 	if (msg->errno)
748 		nfs_idmap_abort_pipe_upcall(idmap, msg->errno);
749 }
750 
751 static void
752 idmap_release_pipe(struct inode *inode)
753 {
754 	struct rpc_inode *rpci = RPC_I(inode);
755 	struct idmap *idmap = (struct idmap *)rpci->private;
756 
757 	nfs_idmap_abort_pipe_upcall(idmap, -EPIPE);
758 }
759 
760 int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, kuid_t *uid)
761 {
762 	struct idmap *idmap = server->nfs_client->cl_idmap;
763 	__u32 id = -1;
764 	int ret = 0;
765 
766 	if (!nfs_map_string_to_numeric(name, namelen, &id))
767 		ret = nfs_idmap_lookup_id(name, namelen, "uid", &id, idmap);
768 	if (ret == 0) {
769 		*uid = make_kuid(idmap_userns(idmap), id);
770 		if (!uid_valid(*uid))
771 			ret = -ERANGE;
772 	}
773 	trace_nfs4_map_name_to_uid(name, namelen, id, ret);
774 	return ret;
775 }
776 
777 int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size_t namelen, kgid_t *gid)
778 {
779 	struct idmap *idmap = server->nfs_client->cl_idmap;
780 	__u32 id = -1;
781 	int ret = 0;
782 
783 	if (!nfs_map_string_to_numeric(name, namelen, &id))
784 		ret = nfs_idmap_lookup_id(name, namelen, "gid", &id, idmap);
785 	if (ret == 0) {
786 		*gid = make_kgid(idmap_userns(idmap), id);
787 		if (!gid_valid(*gid))
788 			ret = -ERANGE;
789 	}
790 	trace_nfs4_map_group_to_gid(name, namelen, id, ret);
791 	return ret;
792 }
793 
794 int nfs_map_uid_to_name(const struct nfs_server *server, kuid_t uid, char *buf, size_t buflen)
795 {
796 	struct idmap *idmap = server->nfs_client->cl_idmap;
797 	int ret = -EINVAL;
798 	__u32 id;
799 
800 	id = from_kuid_munged(idmap_userns(idmap), uid);
801 	if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
802 		ret = nfs_idmap_lookup_name(id, "user", buf, buflen, idmap);
803 	if (ret < 0)
804 		ret = nfs_map_numeric_to_string(id, buf, buflen);
805 	trace_nfs4_map_uid_to_name(buf, ret, id, ret);
806 	return ret;
807 }
808 int nfs_map_gid_to_group(const struct nfs_server *server, kgid_t gid, char *buf, size_t buflen)
809 {
810 	struct idmap *idmap = server->nfs_client->cl_idmap;
811 	int ret = -EINVAL;
812 	__u32 id;
813 
814 	id = from_kgid_munged(idmap_userns(idmap), gid);
815 	if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
816 		ret = nfs_idmap_lookup_name(id, "group", buf, buflen, idmap);
817 	if (ret < 0)
818 		ret = nfs_map_numeric_to_string(id, buf, buflen);
819 	trace_nfs4_map_gid_to_group(buf, ret, id, ret);
820 	return ret;
821 }
822