root/fs/nfs/nfs4idmap.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. idmap_userns
  2. nfs_fattr_init_names
  3. nfs_fattr_free_owner_name
  4. nfs_fattr_free_group_name
  5. nfs_fattr_map_owner_name
  6. nfs_fattr_map_group_name
  7. nfs_fattr_free_names
  8. nfs_fattr_map_and_free_names
  9. nfs_map_string_to_numeric
  10. nfs_map_numeric_to_string
  11. nfs_idmap_init
  12. nfs_idmap_quit
  13. nfs_idmap_get_desc
  14. nfs_idmap_request_key
  15. nfs_idmap_get_key
  16. nfs_idmap_lookup_name
  17. nfs_idmap_lookup_id
  18. nfs_idmap_pipe_destroy
  19. nfs_idmap_pipe_create
  20. nfs_idmap_new
  21. nfs_idmap_delete
  22. nfs_idmap_prepare_message
  23. nfs_idmap_prepare_pipe_upcall
  24. nfs_idmap_complete_pipe_upcall_locked
  25. nfs_idmap_abort_pipe_upcall
  26. nfs_idmap_legacy_upcall
  27. nfs_idmap_instantiate
  28. nfs_idmap_read_and_verify_message
  29. idmap_pipe_downcall
  30. idmap_pipe_destroy_msg
  31. idmap_release_pipe
  32. nfs_map_name_to_uid
  33. nfs_map_group_to_gid
  34. nfs_map_uid_to_name
  35. nfs_map_gid_to_group

   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 }

/* [<][>][^][v][top][bottom][index][help] */