diff options
Diffstat (limited to 'fs/nfsd/nfs4idmap.c')
-rw-r--r-- | fs/nfsd/nfs4idmap.c | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index 4832fd819f88..c0dfde68742e 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c | |||
@@ -551,27 +551,46 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen | |||
551 | return 0; | 551 | return 0; |
552 | } | 552 | } |
553 | 553 | ||
554 | static int | 554 | static __be32 encode_ascii_id(u32 id, __be32 **p, int *buflen) |
555 | idmap_id_to_name(struct svc_rqst *rqstp, int type, u32 id, char *name) | 555 | { |
556 | char buf[11]; | ||
557 | int len; | ||
558 | int bytes; | ||
559 | |||
560 | len = sprintf(buf, "%u", id); | ||
561 | bytes = 4 + (XDR_QUADLEN(len) << 2); | ||
562 | if (bytes > *buflen) | ||
563 | return nfserr_resource; | ||
564 | *p = xdr_encode_opaque(*p, buf, len); | ||
565 | *buflen -= bytes; | ||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | static __be32 idmap_id_to_name(struct svc_rqst *rqstp, int type, u32 id, __be32 **p, int *buflen) | ||
556 | { | 570 | { |
557 | struct ent *item, key = { | 571 | struct ent *item, key = { |
558 | .id = id, | 572 | .id = id, |
559 | .type = type, | 573 | .type = type, |
560 | }; | 574 | }; |
561 | int ret; | 575 | int ret; |
576 | int bytes; | ||
562 | struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); | 577 | struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); |
563 | 578 | ||
564 | strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); | 579 | strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); |
565 | ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item); | 580 | ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item); |
566 | if (ret == -ENOENT) | 581 | if (ret == -ENOENT) |
567 | return sprintf(name, "%u", id); | 582 | return encode_ascii_id(id, p, buflen); |
568 | if (ret) | 583 | if (ret) |
569 | return ret; | 584 | return nfserrno(ret); |
570 | ret = strlen(item->name); | 585 | ret = strlen(item->name); |
571 | BUG_ON(ret > IDMAP_NAMESZ); | 586 | WARN_ON_ONCE(ret > IDMAP_NAMESZ); |
572 | memcpy(name, item->name, ret); | 587 | bytes = 4 + (XDR_QUADLEN(ret) << 2); |
588 | if (bytes > *buflen) | ||
589 | return nfserr_resource; | ||
590 | *p = xdr_encode_opaque(*p, item->name, ret); | ||
591 | *buflen -= bytes; | ||
573 | cache_put(&item->h, nn->idtoname_cache); | 592 | cache_put(&item->h, nn->idtoname_cache); |
574 | return ret; | 593 | return 0; |
575 | } | 594 | } |
576 | 595 | ||
577 | static bool | 596 | static bool |
@@ -603,12 +622,11 @@ do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u | |||
603 | return idmap_name_to_id(rqstp, type, name, namelen, id); | 622 | return idmap_name_to_id(rqstp, type, name, namelen, id); |
604 | } | 623 | } |
605 | 624 | ||
606 | static int | 625 | static __be32 encode_name_from_id(struct svc_rqst *rqstp, int type, u32 id, __be32 **p, int *buflen) |
607 | do_id_to_name(struct svc_rqst *rqstp, int type, u32 id, char *name) | ||
608 | { | 626 | { |
609 | if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS) | 627 | if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS) |
610 | return sprintf(name, "%u", id); | 628 | return encode_ascii_id(id, p, buflen); |
611 | return idmap_id_to_name(rqstp, type, id, name); | 629 | return idmap_id_to_name(rqstp, type, id, p, buflen); |
612 | } | 630 | } |
613 | 631 | ||
614 | __be32 | 632 | __be32 |
@@ -637,16 +655,14 @@ nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen, | |||
637 | return status; | 655 | return status; |
638 | } | 656 | } |
639 | 657 | ||
640 | int | 658 | __be32 nfsd4_encode_user(struct svc_rqst *rqstp, kuid_t uid, __be32 **p, int *buflen) |
641 | nfsd_map_uid_to_name(struct svc_rqst *rqstp, kuid_t uid, char *name) | ||
642 | { | 659 | { |
643 | u32 id = from_kuid(&init_user_ns, uid); | 660 | u32 id = from_kuid(&init_user_ns, uid); |
644 | return do_id_to_name(rqstp, IDMAP_TYPE_USER, id, name); | 661 | return encode_name_from_id(rqstp, IDMAP_TYPE_USER, id, p, buflen); |
645 | } | 662 | } |
646 | 663 | ||
647 | int | 664 | __be32 nfsd4_encode_group(struct svc_rqst *rqstp, kgid_t gid, __be32 **p, int *buflen) |
648 | nfsd_map_gid_to_name(struct svc_rqst *rqstp, kgid_t gid, char *name) | ||
649 | { | 665 | { |
650 | u32 id = from_kgid(&init_user_ns, gid); | 666 | u32 id = from_kgid(&init_user_ns, gid); |
651 | return do_id_to_name(rqstp, IDMAP_TYPE_GROUP, id, name); | 667 | return encode_name_from_id(rqstp, IDMAP_TYPE_GROUP, id, p, buflen); |
652 | } | 668 | } |