Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.5 811 lines 20 kB view raw
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 <linux/nfs_idmap.h> 40#include <net/net_namespace.h> 41#include <linux/sunrpc/rpc_pipe_fs.h> 42#include <linux/nfs_fs.h> 43#include <linux/nfs_fs_sb.h> 44#include <linux/key.h> 45#include <linux/keyctl.h> 46#include <linux/key-type.h> 47#include <keys/user-type.h> 48#include <linux/module.h> 49 50#include "internal.h" 51#include "netns.h" 52 53#define NFS_UINT_MAXLEN 11 54 55/* Default cache timeout is 10 minutes */ 56unsigned int nfs_idmap_cache_timeout = 600; 57static const struct cred *id_resolver_cache; 58static struct key_type key_type_id_resolver_legacy; 59 60struct idmap { 61 struct rpc_pipe *idmap_pipe; 62 struct key_construction *idmap_key_cons; 63 struct mutex idmap_mutex; 64}; 65 66/** 67 * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields 68 * @fattr: fully initialised struct nfs_fattr 69 * @owner_name: owner name string cache 70 * @group_name: group name string cache 71 */ 72void nfs_fattr_init_names(struct nfs_fattr *fattr, 73 struct nfs4_string *owner_name, 74 struct nfs4_string *group_name) 75{ 76 fattr->owner_name = owner_name; 77 fattr->group_name = group_name; 78} 79 80static void nfs_fattr_free_owner_name(struct nfs_fattr *fattr) 81{ 82 fattr->valid &= ~NFS_ATTR_FATTR_OWNER_NAME; 83 kfree(fattr->owner_name->data); 84} 85 86static void nfs_fattr_free_group_name(struct nfs_fattr *fattr) 87{ 88 fattr->valid &= ~NFS_ATTR_FATTR_GROUP_NAME; 89 kfree(fattr->group_name->data); 90} 91 92static bool nfs_fattr_map_owner_name(struct nfs_server *server, struct nfs_fattr *fattr) 93{ 94 struct nfs4_string *owner = fattr->owner_name; 95 __u32 uid; 96 97 if (!(fattr->valid & NFS_ATTR_FATTR_OWNER_NAME)) 98 return false; 99 if (nfs_map_name_to_uid(server, owner->data, owner->len, &uid) == 0) { 100 fattr->uid = uid; 101 fattr->valid |= NFS_ATTR_FATTR_OWNER; 102 } 103 return true; 104} 105 106static bool nfs_fattr_map_group_name(struct nfs_server *server, struct nfs_fattr *fattr) 107{ 108 struct nfs4_string *group = fattr->group_name; 109 __u32 gid; 110 111 if (!(fattr->valid & NFS_ATTR_FATTR_GROUP_NAME)) 112 return false; 113 if (nfs_map_group_to_gid(server, group->data, group->len, &gid) == 0) { 114 fattr->gid = gid; 115 fattr->valid |= NFS_ATTR_FATTR_GROUP; 116 } 117 return true; 118} 119 120/** 121 * nfs_fattr_free_names - free up the NFSv4 owner and group strings 122 * @fattr: a fully initialised nfs_fattr structure 123 */ 124void nfs_fattr_free_names(struct nfs_fattr *fattr) 125{ 126 if (fattr->valid & NFS_ATTR_FATTR_OWNER_NAME) 127 nfs_fattr_free_owner_name(fattr); 128 if (fattr->valid & NFS_ATTR_FATTR_GROUP_NAME) 129 nfs_fattr_free_group_name(fattr); 130} 131 132/** 133 * nfs_fattr_map_and_free_names - map owner/group strings into uid/gid and free 134 * @server: pointer to the filesystem nfs_server structure 135 * @fattr: a fully initialised nfs_fattr structure 136 * 137 * This helper maps the cached NFSv4 owner/group strings in fattr into 138 * their numeric uid/gid equivalents, and then frees the cached strings. 139 */ 140void nfs_fattr_map_and_free_names(struct nfs_server *server, struct nfs_fattr *fattr) 141{ 142 if (nfs_fattr_map_owner_name(server, fattr)) 143 nfs_fattr_free_owner_name(fattr); 144 if (nfs_fattr_map_group_name(server, fattr)) 145 nfs_fattr_free_group_name(fattr); 146} 147 148static int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *res) 149{ 150 unsigned long val; 151 char buf[16]; 152 153 if (memchr(name, '@', namelen) != NULL || namelen >= sizeof(buf)) 154 return 0; 155 memcpy(buf, name, namelen); 156 buf[namelen] = '\0'; 157 if (strict_strtoul(buf, 0, &val) != 0) 158 return 0; 159 *res = val; 160 return 1; 161} 162 163static int nfs_map_numeric_to_string(__u32 id, char *buf, size_t buflen) 164{ 165 return snprintf(buf, buflen, "%u", id); 166} 167 168static struct key_type key_type_id_resolver = { 169 .name = "id_resolver", 170 .instantiate = user_instantiate, 171 .match = user_match, 172 .revoke = user_revoke, 173 .destroy = user_destroy, 174 .describe = user_describe, 175 .read = user_read, 176}; 177 178static int nfs_idmap_init_keyring(void) 179{ 180 struct cred *cred; 181 struct key *keyring; 182 int ret = 0; 183 184 printk(KERN_NOTICE "NFS: Registering the %s key type\n", 185 key_type_id_resolver.name); 186 187 cred = prepare_kernel_cred(NULL); 188 if (!cred) 189 return -ENOMEM; 190 191 keyring = key_alloc(&key_type_keyring, ".id_resolver", 0, 0, cred, 192 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 193 KEY_USR_VIEW | KEY_USR_READ, 194 KEY_ALLOC_NOT_IN_QUOTA); 195 if (IS_ERR(keyring)) { 196 ret = PTR_ERR(keyring); 197 goto failed_put_cred; 198 } 199 200 ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL); 201 if (ret < 0) 202 goto failed_put_key; 203 204 ret = register_key_type(&key_type_id_resolver); 205 if (ret < 0) 206 goto failed_put_key; 207 208 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); 209 cred->thread_keyring = keyring; 210 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 211 id_resolver_cache = cred; 212 return 0; 213 214failed_put_key: 215 key_put(keyring); 216failed_put_cred: 217 put_cred(cred); 218 return ret; 219} 220 221static void nfs_idmap_quit_keyring(void) 222{ 223 key_revoke(id_resolver_cache->thread_keyring); 224 unregister_key_type(&key_type_id_resolver); 225 put_cred(id_resolver_cache); 226} 227 228/* 229 * Assemble the description to pass to request_key() 230 * This function will allocate a new string and update dest to point 231 * at it. The caller is responsible for freeing dest. 232 * 233 * On error 0 is returned. Otherwise, the length of dest is returned. 234 */ 235static ssize_t nfs_idmap_get_desc(const char *name, size_t namelen, 236 const char *type, size_t typelen, char **desc) 237{ 238 char *cp; 239 size_t desclen = typelen + namelen + 2; 240 241 *desc = kmalloc(desclen, GFP_KERNEL); 242 if (!*desc) 243 return -ENOMEM; 244 245 cp = *desc; 246 memcpy(cp, type, typelen); 247 cp += typelen; 248 *cp++ = ':'; 249 250 memcpy(cp, name, namelen); 251 cp += namelen; 252 *cp = '\0'; 253 return desclen; 254} 255 256static ssize_t nfs_idmap_request_key(struct key_type *key_type, 257 const char *name, size_t namelen, 258 const char *type, void *data, 259 size_t data_size, struct idmap *idmap) 260{ 261 const struct cred *saved_cred; 262 struct key *rkey; 263 char *desc; 264 struct user_key_payload *payload; 265 ssize_t ret; 266 267 ret = nfs_idmap_get_desc(name, namelen, type, strlen(type), &desc); 268 if (ret <= 0) 269 goto out; 270 271 saved_cred = override_creds(id_resolver_cache); 272 if (idmap) 273 rkey = request_key_with_auxdata(key_type, desc, "", 0, idmap); 274 else 275 rkey = request_key(&key_type_id_resolver, desc, ""); 276 revert_creds(saved_cred); 277 278 kfree(desc); 279 if (IS_ERR(rkey)) { 280 ret = PTR_ERR(rkey); 281 goto out; 282 } 283 284 rcu_read_lock(); 285 rkey->perm |= KEY_USR_VIEW; 286 287 ret = key_validate(rkey); 288 if (ret < 0) 289 goto out_up; 290 291 payload = rcu_dereference(rkey->payload.data); 292 if (IS_ERR_OR_NULL(payload)) { 293 ret = PTR_ERR(payload); 294 goto out_up; 295 } 296 297 ret = payload->datalen; 298 if (ret > 0 && ret <= data_size) 299 memcpy(data, payload->data, ret); 300 else 301 ret = -EINVAL; 302 303out_up: 304 rcu_read_unlock(); 305 key_put(rkey); 306out: 307 return ret; 308} 309 310static ssize_t nfs_idmap_get_key(const char *name, size_t namelen, 311 const char *type, void *data, 312 size_t data_size, struct idmap *idmap) 313{ 314 ssize_t ret = nfs_idmap_request_key(&key_type_id_resolver, 315 name, namelen, type, data, 316 data_size, NULL); 317 if (ret < 0) { 318 mutex_lock(&idmap->idmap_mutex); 319 ret = nfs_idmap_request_key(&key_type_id_resolver_legacy, 320 name, namelen, type, data, 321 data_size, idmap); 322 mutex_unlock(&idmap->idmap_mutex); 323 } 324 return ret; 325} 326 327/* ID -> Name */ 328static ssize_t nfs_idmap_lookup_name(__u32 id, const char *type, char *buf, 329 size_t buflen, struct idmap *idmap) 330{ 331 char id_str[NFS_UINT_MAXLEN]; 332 int id_len; 333 ssize_t ret; 334 335 id_len = snprintf(id_str, sizeof(id_str), "%u", id); 336 ret = nfs_idmap_get_key(id_str, id_len, type, buf, buflen, idmap); 337 if (ret < 0) 338 return -EINVAL; 339 return ret; 340} 341 342/* Name -> ID */ 343static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *type, 344 __u32 *id, struct idmap *idmap) 345{ 346 char id_str[NFS_UINT_MAXLEN]; 347 long id_long; 348 ssize_t data_size; 349 int ret = 0; 350 351 data_size = nfs_idmap_get_key(name, namelen, type, id_str, NFS_UINT_MAXLEN, idmap); 352 if (data_size <= 0) { 353 ret = -EINVAL; 354 } else { 355 ret = strict_strtol(id_str, 10, &id_long); 356 *id = (__u32)id_long; 357 } 358 return ret; 359} 360 361/* idmap classic begins here */ 362module_param(nfs_idmap_cache_timeout, int, 0644); 363 364enum { 365 Opt_find_uid, Opt_find_gid, Opt_find_user, Opt_find_group, Opt_find_err 366}; 367 368static const match_table_t nfs_idmap_tokens = { 369 { Opt_find_uid, "uid:%s" }, 370 { Opt_find_gid, "gid:%s" }, 371 { Opt_find_user, "user:%s" }, 372 { Opt_find_group, "group:%s" }, 373 { Opt_find_err, NULL } 374}; 375 376static int nfs_idmap_legacy_upcall(struct key_construction *, const char *, void *); 377static ssize_t idmap_pipe_downcall(struct file *, const char __user *, 378 size_t); 379static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *); 380 381static const struct rpc_pipe_ops idmap_upcall_ops = { 382 .upcall = rpc_pipe_generic_upcall, 383 .downcall = idmap_pipe_downcall, 384 .destroy_msg = idmap_pipe_destroy_msg, 385}; 386 387static struct key_type key_type_id_resolver_legacy = { 388 .name = "id_resolver", 389 .instantiate = user_instantiate, 390 .match = user_match, 391 .revoke = user_revoke, 392 .destroy = user_destroy, 393 .describe = user_describe, 394 .read = user_read, 395 .request_key = nfs_idmap_legacy_upcall, 396}; 397 398static void __nfs_idmap_unregister(struct rpc_pipe *pipe) 399{ 400 if (pipe->dentry) 401 rpc_unlink(pipe->dentry); 402} 403 404static int __nfs_idmap_register(struct dentry *dir, 405 struct idmap *idmap, 406 struct rpc_pipe *pipe) 407{ 408 struct dentry *dentry; 409 410 dentry = rpc_mkpipe_dentry(dir, "idmap", idmap, pipe); 411 if (IS_ERR(dentry)) 412 return PTR_ERR(dentry); 413 pipe->dentry = dentry; 414 return 0; 415} 416 417static void nfs_idmap_unregister(struct nfs_client *clp, 418 struct rpc_pipe *pipe) 419{ 420 struct net *net = clp->cl_net; 421 struct super_block *pipefs_sb; 422 423 pipefs_sb = rpc_get_sb_net(net); 424 if (pipefs_sb) { 425 __nfs_idmap_unregister(pipe); 426 rpc_put_sb_net(net); 427 } 428} 429 430static int nfs_idmap_register(struct nfs_client *clp, 431 struct idmap *idmap, 432 struct rpc_pipe *pipe) 433{ 434 struct net *net = clp->cl_net; 435 struct super_block *pipefs_sb; 436 int err = 0; 437 438 pipefs_sb = rpc_get_sb_net(net); 439 if (pipefs_sb) { 440 if (clp->cl_rpcclient->cl_dentry) 441 err = __nfs_idmap_register(clp->cl_rpcclient->cl_dentry, 442 idmap, pipe); 443 rpc_put_sb_net(net); 444 } 445 return err; 446} 447 448int 449nfs_idmap_new(struct nfs_client *clp) 450{ 451 struct idmap *idmap; 452 struct rpc_pipe *pipe; 453 int error; 454 455 BUG_ON(clp->cl_idmap != NULL); 456 457 idmap = kzalloc(sizeof(*idmap), GFP_KERNEL); 458 if (idmap == NULL) 459 return -ENOMEM; 460 461 pipe = rpc_mkpipe_data(&idmap_upcall_ops, 0); 462 if (IS_ERR(pipe)) { 463 error = PTR_ERR(pipe); 464 kfree(idmap); 465 return error; 466 } 467 error = nfs_idmap_register(clp, idmap, pipe); 468 if (error) { 469 rpc_destroy_pipe_data(pipe); 470 kfree(idmap); 471 return error; 472 } 473 idmap->idmap_pipe = pipe; 474 mutex_init(&idmap->idmap_mutex); 475 476 clp->cl_idmap = idmap; 477 return 0; 478} 479 480void 481nfs_idmap_delete(struct nfs_client *clp) 482{ 483 struct idmap *idmap = clp->cl_idmap; 484 485 if (!idmap) 486 return; 487 nfs_idmap_unregister(clp, idmap->idmap_pipe); 488 rpc_destroy_pipe_data(idmap->idmap_pipe); 489 clp->cl_idmap = NULL; 490 kfree(idmap); 491} 492 493static int __rpc_pipefs_event(struct nfs_client *clp, unsigned long event, 494 struct super_block *sb) 495{ 496 int err = 0; 497 498 switch (event) { 499 case RPC_PIPEFS_MOUNT: 500 BUG_ON(clp->cl_rpcclient->cl_dentry == NULL); 501 err = __nfs_idmap_register(clp->cl_rpcclient->cl_dentry, 502 clp->cl_idmap, 503 clp->cl_idmap->idmap_pipe); 504 break; 505 case RPC_PIPEFS_UMOUNT: 506 if (clp->cl_idmap->idmap_pipe) { 507 struct dentry *parent; 508 509 parent = clp->cl_idmap->idmap_pipe->dentry->d_parent; 510 __nfs_idmap_unregister(clp->cl_idmap->idmap_pipe); 511 /* 512 * Note: This is a dirty hack. SUNRPC hook has been 513 * called already but simple_rmdir() call for the 514 * directory returned with error because of idmap pipe 515 * inside. Thus now we have to remove this directory 516 * here. 517 */ 518 if (rpc_rmdir(parent)) 519 printk(KERN_ERR "NFS: %s: failed to remove " 520 "clnt dir!\n", __func__); 521 } 522 break; 523 default: 524 printk(KERN_ERR "NFS: %s: unknown event: %ld\n", __func__, 525 event); 526 return -ENOTSUPP; 527 } 528 return err; 529} 530 531static struct nfs_client *nfs_get_client_for_event(struct net *net, int event) 532{ 533 struct nfs_net *nn = net_generic(net, nfs_net_id); 534 struct dentry *cl_dentry; 535 struct nfs_client *clp; 536 int err; 537 538restart: 539 spin_lock(&nn->nfs_client_lock); 540 list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) { 541 /* Wait for initialisation to finish */ 542 if (clp->cl_cons_state == NFS_CS_INITING) { 543 atomic_inc(&clp->cl_count); 544 spin_unlock(&nn->nfs_client_lock); 545 err = nfs_wait_client_init_complete(clp); 546 nfs_put_client(clp); 547 if (err) 548 return NULL; 549 goto restart; 550 } 551 /* Skip nfs_clients that failed to initialise */ 552 if (clp->cl_cons_state < 0) 553 continue; 554 smp_rmb(); 555 if (clp->rpc_ops != &nfs_v4_clientops) 556 continue; 557 cl_dentry = clp->cl_idmap->idmap_pipe->dentry; 558 if (((event == RPC_PIPEFS_MOUNT) && cl_dentry) || 559 ((event == RPC_PIPEFS_UMOUNT) && !cl_dentry)) 560 continue; 561 atomic_inc(&clp->cl_count); 562 spin_unlock(&nn->nfs_client_lock); 563 return clp; 564 } 565 spin_unlock(&nn->nfs_client_lock); 566 return NULL; 567} 568 569static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event, 570 void *ptr) 571{ 572 struct super_block *sb = ptr; 573 struct nfs_client *clp; 574 int error = 0; 575 576 if (!try_module_get(THIS_MODULE)) 577 return 0; 578 579 while ((clp = nfs_get_client_for_event(sb->s_fs_info, event))) { 580 error = __rpc_pipefs_event(clp, event, sb); 581 nfs_put_client(clp); 582 if (error) 583 break; 584 } 585 module_put(THIS_MODULE); 586 return error; 587} 588 589#define PIPEFS_NFS_PRIO 1 590 591static struct notifier_block nfs_idmap_block = { 592 .notifier_call = rpc_pipefs_event, 593 .priority = SUNRPC_PIPEFS_NFS_PRIO, 594}; 595 596int nfs_idmap_init(void) 597{ 598 int ret; 599 ret = nfs_idmap_init_keyring(); 600 if (ret != 0) 601 goto out; 602 ret = rpc_pipefs_notifier_register(&nfs_idmap_block); 603 if (ret != 0) 604 nfs_idmap_quit_keyring(); 605out: 606 return ret; 607} 608 609void nfs_idmap_quit(void) 610{ 611 rpc_pipefs_notifier_unregister(&nfs_idmap_block); 612 nfs_idmap_quit_keyring(); 613} 614 615static int nfs_idmap_prepare_message(char *desc, struct idmap_msg *im, 616 struct rpc_pipe_msg *msg) 617{ 618 substring_t substr; 619 int token, ret; 620 621 memset(im, 0, sizeof(*im)); 622 memset(msg, 0, sizeof(*msg)); 623 624 im->im_type = IDMAP_TYPE_GROUP; 625 token = match_token(desc, nfs_idmap_tokens, &substr); 626 627 switch (token) { 628 case Opt_find_uid: 629 im->im_type = IDMAP_TYPE_USER; 630 case Opt_find_gid: 631 im->im_conv = IDMAP_CONV_NAMETOID; 632 ret = match_strlcpy(im->im_name, &substr, IDMAP_NAMESZ); 633 break; 634 635 case Opt_find_user: 636 im->im_type = IDMAP_TYPE_USER; 637 case Opt_find_group: 638 im->im_conv = IDMAP_CONV_IDTONAME; 639 ret = match_int(&substr, &im->im_id); 640 break; 641 642 default: 643 ret = -EINVAL; 644 goto out; 645 } 646 647 msg->data = im; 648 msg->len = sizeof(struct idmap_msg); 649 650out: 651 return ret; 652} 653 654static int nfs_idmap_legacy_upcall(struct key_construction *cons, 655 const char *op, 656 void *aux) 657{ 658 struct rpc_pipe_msg *msg; 659 struct idmap_msg *im; 660 struct idmap *idmap = (struct idmap *)aux; 661 struct key *key = cons->key; 662 int ret = -ENOMEM; 663 664 /* msg and im are freed in idmap_pipe_destroy_msg */ 665 msg = kmalloc(sizeof(*msg), GFP_KERNEL); 666 if (!msg) 667 goto out0; 668 669 im = kmalloc(sizeof(*im), GFP_KERNEL); 670 if (!im) 671 goto out1; 672 673 ret = nfs_idmap_prepare_message(key->description, im, msg); 674 if (ret < 0) 675 goto out2; 676 677 idmap->idmap_key_cons = cons; 678 679 ret = rpc_queue_upcall(idmap->idmap_pipe, msg); 680 if (ret < 0) 681 goto out2; 682 683 return ret; 684 685out2: 686 kfree(im); 687out1: 688 kfree(msg); 689out0: 690 key_revoke(cons->key); 691 key_revoke(cons->authkey); 692 return ret; 693} 694 695static int nfs_idmap_instantiate(struct key *key, struct key *authkey, char *data) 696{ 697 return key_instantiate_and_link(key, data, strlen(data) + 1, 698 id_resolver_cache->thread_keyring, 699 authkey); 700} 701 702static int nfs_idmap_read_message(struct idmap_msg *im, struct key *key, struct key *authkey) 703{ 704 char id_str[NFS_UINT_MAXLEN]; 705 int ret = -EINVAL; 706 707 switch (im->im_conv) { 708 case IDMAP_CONV_NAMETOID: 709 sprintf(id_str, "%d", im->im_id); 710 ret = nfs_idmap_instantiate(key, authkey, id_str); 711 break; 712 case IDMAP_CONV_IDTONAME: 713 ret = nfs_idmap_instantiate(key, authkey, im->im_name); 714 break; 715 } 716 717 return ret; 718} 719 720static ssize_t 721idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) 722{ 723 struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode); 724 struct idmap *idmap = (struct idmap *)rpci->private; 725 struct key_construction *cons = idmap->idmap_key_cons; 726 struct idmap_msg im; 727 size_t namelen_in; 728 int ret; 729 730 if (mlen != sizeof(im)) { 731 ret = -ENOSPC; 732 goto out; 733 } 734 735 if (copy_from_user(&im, src, mlen) != 0) { 736 ret = -EFAULT; 737 goto out; 738 } 739 740 if (!(im.im_status & IDMAP_STATUS_SUCCESS)) { 741 ret = mlen; 742 complete_request_key(idmap->idmap_key_cons, -ENOKEY); 743 goto out_incomplete; 744 } 745 746 namelen_in = strnlen(im.im_name, IDMAP_NAMESZ); 747 if (namelen_in == 0 || namelen_in == IDMAP_NAMESZ) { 748 ret = -EINVAL; 749 goto out; 750 } 751 752 ret = nfs_idmap_read_message(&im, cons->key, cons->authkey); 753 if (ret >= 0) { 754 key_set_timeout(cons->key, nfs_idmap_cache_timeout); 755 ret = mlen; 756 } 757 758out: 759 complete_request_key(idmap->idmap_key_cons, ret); 760out_incomplete: 761 return ret; 762} 763 764static void 765idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg) 766{ 767 /* Free memory allocated in nfs_idmap_legacy_upcall() */ 768 kfree(msg->data); 769 kfree(msg); 770} 771 772int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid) 773{ 774 struct idmap *idmap = server->nfs_client->cl_idmap; 775 776 if (nfs_map_string_to_numeric(name, namelen, uid)) 777 return 0; 778 return nfs_idmap_lookup_id(name, namelen, "uid", uid, idmap); 779} 780 781int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *gid) 782{ 783 struct idmap *idmap = server->nfs_client->cl_idmap; 784 785 if (nfs_map_string_to_numeric(name, namelen, gid)) 786 return 0; 787 return nfs_idmap_lookup_id(name, namelen, "gid", gid, idmap); 788} 789 790int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen) 791{ 792 struct idmap *idmap = server->nfs_client->cl_idmap; 793 int ret = -EINVAL; 794 795 if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) 796 ret = nfs_idmap_lookup_name(uid, "user", buf, buflen, idmap); 797 if (ret < 0) 798 ret = nfs_map_numeric_to_string(uid, buf, buflen); 799 return ret; 800} 801int nfs_map_gid_to_group(const struct nfs_server *server, __u32 gid, char *buf, size_t buflen) 802{ 803 struct idmap *idmap = server->nfs_client->cl_idmap; 804 int ret = -EINVAL; 805 806 if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) 807 ret = nfs_idmap_lookup_name(gid, "group", buf, buflen, idmap); 808 if (ret < 0) 809 ret = nfs_map_numeric_to_string(gid, buf, buflen); 810 return ret; 811}