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