nfs4idmap.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. /*
  2. * Mapping of UID/GIDs to name and vice versa.
  3. *
  4. * Copyright (c) 2002, 2003 The Regents of the University of
  5. * Michigan. All rights reserved.
  6. *
  7. * Marius Aamodt Eriksen <marius@umich.edu>
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. *
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. * 3. Neither the name of the University nor the names of its
  19. * contributors may be used to endorse or promote products derived
  20. * from this software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  23. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  24. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  25. * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  29. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  30. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  31. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include <linux/module.h>
  35. #include <linux/seq_file.h>
  36. #include <linux/sched.h>
  37. #include <linux/slab.h>
  38. #include <linux/sunrpc/svc_xprt.h>
  39. #include <net/net_namespace.h>
  40. #include "idmap.h"
  41. #include "nfsd.h"
  42. #include "netns.h"
  43. /*
  44. * Turn off idmapping when using AUTH_SYS.
  45. */
  46. static bool nfs4_disable_idmapping = true;
  47. module_param(nfs4_disable_idmapping, bool, 0644);
  48. MODULE_PARM_DESC(nfs4_disable_idmapping,
  49. "Turn off server's NFSv4 idmapping when using 'sec=sys'");
  50. /*
  51. * Cache entry
  52. */
  53. /*
  54. * XXX we know that IDMAP_NAMESZ < PAGE_SIZE, but it's ugly to rely on
  55. * that.
  56. */
  57. struct ent {
  58. struct cache_head h;
  59. int type; /* User / Group */
  60. u32 id;
  61. char name[IDMAP_NAMESZ];
  62. char authname[IDMAP_NAMESZ];
  63. struct rcu_head rcu_head;
  64. };
  65. /* Common entry handling */
  66. #define ENT_HASHBITS 8
  67. #define ENT_HASHMAX (1 << ENT_HASHBITS)
  68. static void
  69. ent_init(struct cache_head *cnew, struct cache_head *citm)
  70. {
  71. struct ent *new = container_of(cnew, struct ent, h);
  72. struct ent *itm = container_of(citm, struct ent, h);
  73. new->id = itm->id;
  74. new->type = itm->type;
  75. strlcpy(new->name, itm->name, sizeof(new->name));
  76. strlcpy(new->authname, itm->authname, sizeof(new->name));
  77. }
  78. static void
  79. ent_put(struct kref *ref)
  80. {
  81. struct ent *map = container_of(ref, struct ent, h.ref);
  82. kfree_rcu(map, rcu_head);
  83. }
  84. static struct cache_head *
  85. ent_alloc(void)
  86. {
  87. struct ent *e = kmalloc(sizeof(*e), GFP_KERNEL);
  88. if (e)
  89. return &e->h;
  90. else
  91. return NULL;
  92. }
  93. /*
  94. * ID -> Name cache
  95. */
  96. static uint32_t
  97. idtoname_hash(struct ent *ent)
  98. {
  99. uint32_t hash;
  100. hash = hash_str(ent->authname, ENT_HASHBITS);
  101. hash = hash_long(hash ^ ent->id, ENT_HASHBITS);
  102. /* Flip LSB for user/group */
  103. if (ent->type == IDMAP_TYPE_GROUP)
  104. hash ^= 1;
  105. return hash;
  106. }
  107. static void
  108. idtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
  109. int *blen)
  110. {
  111. struct ent *ent = container_of(ch, struct ent, h);
  112. char idstr[11];
  113. qword_add(bpp, blen, ent->authname);
  114. snprintf(idstr, sizeof(idstr), "%u", ent->id);
  115. qword_add(bpp, blen, ent->type == IDMAP_TYPE_GROUP ? "group" : "user");
  116. qword_add(bpp, blen, idstr);
  117. (*bpp)[-1] = '\n';
  118. }
  119. static int
  120. idtoname_match(struct cache_head *ca, struct cache_head *cb)
  121. {
  122. struct ent *a = container_of(ca, struct ent, h);
  123. struct ent *b = container_of(cb, struct ent, h);
  124. return (a->id == b->id && a->type == b->type &&
  125. strcmp(a->authname, b->authname) == 0);
  126. }
  127. static int
  128. idtoname_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h)
  129. {
  130. struct ent *ent;
  131. if (h == NULL) {
  132. seq_puts(m, "#domain type id [name]\n");
  133. return 0;
  134. }
  135. ent = container_of(h, struct ent, h);
  136. seq_printf(m, "%s %s %u", ent->authname,
  137. ent->type == IDMAP_TYPE_GROUP ? "group" : "user",
  138. ent->id);
  139. if (test_bit(CACHE_VALID, &h->flags))
  140. seq_printf(m, " %s", ent->name);
  141. seq_printf(m, "\n");
  142. return 0;
  143. }
  144. static void
  145. warn_no_idmapd(struct cache_detail *detail, int has_died)
  146. {
  147. printk("nfsd: nfsv4 idmapping failing: has idmapd %s?\n",
  148. has_died ? "died" : "not been started");
  149. }
  150. static int idtoname_parse(struct cache_detail *, char *, int);
  151. static struct ent *idtoname_lookup(struct cache_detail *, struct ent *);
  152. static struct ent *idtoname_update(struct cache_detail *, struct ent *,
  153. struct ent *);
  154. static const struct cache_detail idtoname_cache_template = {
  155. .owner = THIS_MODULE,
  156. .hash_size = ENT_HASHMAX,
  157. .name = "nfs4.idtoname",
  158. .cache_put = ent_put,
  159. .cache_request = idtoname_request,
  160. .cache_parse = idtoname_parse,
  161. .cache_show = idtoname_show,
  162. .warn_no_listener = warn_no_idmapd,
  163. .match = idtoname_match,
  164. .init = ent_init,
  165. .update = ent_init,
  166. .alloc = ent_alloc,
  167. };
  168. static int
  169. idtoname_parse(struct cache_detail *cd, char *buf, int buflen)
  170. {
  171. struct ent ent, *res;
  172. char *buf1, *bp;
  173. int len;
  174. int error = -EINVAL;
  175. if (buf[buflen - 1] != '\n')
  176. return (-EINVAL);
  177. buf[buflen - 1]= '\0';
  178. buf1 = kmalloc(PAGE_SIZE, GFP_KERNEL);
  179. if (buf1 == NULL)
  180. return (-ENOMEM);
  181. memset(&ent, 0, sizeof(ent));
  182. /* Authentication name */
  183. len = qword_get(&buf, buf1, PAGE_SIZE);
  184. if (len <= 0 || len >= IDMAP_NAMESZ)
  185. goto out;
  186. memcpy(ent.authname, buf1, sizeof(ent.authname));
  187. /* Type */
  188. if (qword_get(&buf, buf1, PAGE_SIZE) <= 0)
  189. goto out;
  190. ent.type = strcmp(buf1, "user") == 0 ?
  191. IDMAP_TYPE_USER : IDMAP_TYPE_GROUP;
  192. /* ID */
  193. if (qword_get(&buf, buf1, PAGE_SIZE) <= 0)
  194. goto out;
  195. ent.id = simple_strtoul(buf1, &bp, 10);
  196. if (bp == buf1)
  197. goto out;
  198. /* expiry */
  199. ent.h.expiry_time = get_expiry(&buf);
  200. if (ent.h.expiry_time == 0)
  201. goto out;
  202. error = -ENOMEM;
  203. res = idtoname_lookup(cd, &ent);
  204. if (!res)
  205. goto out;
  206. /* Name */
  207. error = -EINVAL;
  208. len = qword_get(&buf, buf1, PAGE_SIZE);
  209. if (len < 0 || len >= IDMAP_NAMESZ)
  210. goto out;
  211. if (len == 0)
  212. set_bit(CACHE_NEGATIVE, &ent.h.flags);
  213. else
  214. memcpy(ent.name, buf1, sizeof(ent.name));
  215. error = -ENOMEM;
  216. res = idtoname_update(cd, &ent, res);
  217. if (res == NULL)
  218. goto out;
  219. cache_put(&res->h, cd);
  220. error = 0;
  221. out:
  222. kfree(buf1);
  223. return error;
  224. }
  225. static struct ent *
  226. idtoname_lookup(struct cache_detail *cd, struct ent *item)
  227. {
  228. struct cache_head *ch = sunrpc_cache_lookup_rcu(cd, &item->h,
  229. idtoname_hash(item));
  230. if (ch)
  231. return container_of(ch, struct ent, h);
  232. else
  233. return NULL;
  234. }
  235. static struct ent *
  236. idtoname_update(struct cache_detail *cd, struct ent *new, struct ent *old)
  237. {
  238. struct cache_head *ch = sunrpc_cache_update(cd, &new->h, &old->h,
  239. idtoname_hash(new));
  240. if (ch)
  241. return container_of(ch, struct ent, h);
  242. else
  243. return NULL;
  244. }
  245. /*
  246. * Name -> ID cache
  247. */
  248. static inline int
  249. nametoid_hash(struct ent *ent)
  250. {
  251. return hash_str(ent->name, ENT_HASHBITS);
  252. }
  253. static void
  254. nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
  255. int *blen)
  256. {
  257. struct ent *ent = container_of(ch, struct ent, h);
  258. qword_add(bpp, blen, ent->authname);
  259. qword_add(bpp, blen, ent->type == IDMAP_TYPE_GROUP ? "group" : "user");
  260. qword_add(bpp, blen, ent->name);
  261. (*bpp)[-1] = '\n';
  262. }
  263. static int
  264. nametoid_match(struct cache_head *ca, struct cache_head *cb)
  265. {
  266. struct ent *a = container_of(ca, struct ent, h);
  267. struct ent *b = container_of(cb, struct ent, h);
  268. return (a->type == b->type && strcmp(a->name, b->name) == 0 &&
  269. strcmp(a->authname, b->authname) == 0);
  270. }
  271. static int
  272. nametoid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h)
  273. {
  274. struct ent *ent;
  275. if (h == NULL) {
  276. seq_puts(m, "#domain type name [id]\n");
  277. return 0;
  278. }
  279. ent = container_of(h, struct ent, h);
  280. seq_printf(m, "%s %s %s", ent->authname,
  281. ent->type == IDMAP_TYPE_GROUP ? "group" : "user",
  282. ent->name);
  283. if (test_bit(CACHE_VALID, &h->flags))
  284. seq_printf(m, " %u", ent->id);
  285. seq_printf(m, "\n");
  286. return 0;
  287. }
  288. static struct ent *nametoid_lookup(struct cache_detail *, struct ent *);
  289. static struct ent *nametoid_update(struct cache_detail *, struct ent *,
  290. struct ent *);
  291. static int nametoid_parse(struct cache_detail *, char *, int);
  292. static const struct cache_detail nametoid_cache_template = {
  293. .owner = THIS_MODULE,
  294. .hash_size = ENT_HASHMAX,
  295. .name = "nfs4.nametoid",
  296. .cache_put = ent_put,
  297. .cache_request = nametoid_request,
  298. .cache_parse = nametoid_parse,
  299. .cache_show = nametoid_show,
  300. .warn_no_listener = warn_no_idmapd,
  301. .match = nametoid_match,
  302. .init = ent_init,
  303. .update = ent_init,
  304. .alloc = ent_alloc,
  305. };
  306. static int
  307. nametoid_parse(struct cache_detail *cd, char *buf, int buflen)
  308. {
  309. struct ent ent, *res;
  310. char *buf1;
  311. int len, error = -EINVAL;
  312. if (buf[buflen - 1] != '\n')
  313. return (-EINVAL);
  314. buf[buflen - 1]= '\0';
  315. buf1 = kmalloc(PAGE_SIZE, GFP_KERNEL);
  316. if (buf1 == NULL)
  317. return (-ENOMEM);
  318. memset(&ent, 0, sizeof(ent));
  319. /* Authentication name */
  320. len = qword_get(&buf, buf1, PAGE_SIZE);
  321. if (len <= 0 || len >= IDMAP_NAMESZ)
  322. goto out;
  323. memcpy(ent.authname, buf1, sizeof(ent.authname));
  324. /* Type */
  325. if (qword_get(&buf, buf1, PAGE_SIZE) <= 0)
  326. goto out;
  327. ent.type = strcmp(buf1, "user") == 0 ?
  328. IDMAP_TYPE_USER : IDMAP_TYPE_GROUP;
  329. /* Name */
  330. len = qword_get(&buf, buf1, PAGE_SIZE);
  331. if (len <= 0 || len >= IDMAP_NAMESZ)
  332. goto out;
  333. memcpy(ent.name, buf1, sizeof(ent.name));
  334. /* expiry */
  335. ent.h.expiry_time = get_expiry(&buf);
  336. if (ent.h.expiry_time == 0)
  337. goto out;
  338. /* ID */
  339. error = get_int(&buf, &ent.id);
  340. if (error == -EINVAL)
  341. goto out;
  342. if (error == -ENOENT)
  343. set_bit(CACHE_NEGATIVE, &ent.h.flags);
  344. error = -ENOMEM;
  345. res = nametoid_lookup(cd, &ent);
  346. if (res == NULL)
  347. goto out;
  348. res = nametoid_update(cd, &ent, res);
  349. if (res == NULL)
  350. goto out;
  351. cache_put(&res->h, cd);
  352. error = 0;
  353. out:
  354. kfree(buf1);
  355. return (error);
  356. }
  357. static struct ent *
  358. nametoid_lookup(struct cache_detail *cd, struct ent *item)
  359. {
  360. struct cache_head *ch = sunrpc_cache_lookup_rcu(cd, &item->h,
  361. nametoid_hash(item));
  362. if (ch)
  363. return container_of(ch, struct ent, h);
  364. else
  365. return NULL;
  366. }
  367. static struct ent *
  368. nametoid_update(struct cache_detail *cd, struct ent *new, struct ent *old)
  369. {
  370. struct cache_head *ch = sunrpc_cache_update(cd, &new->h, &old->h,
  371. nametoid_hash(new));
  372. if (ch)
  373. return container_of(ch, struct ent, h);
  374. else
  375. return NULL;
  376. }
  377. /*
  378. * Exported API
  379. */
  380. int
  381. nfsd_idmap_init(struct net *net)
  382. {
  383. int rv;
  384. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  385. nn->idtoname_cache = cache_create_net(&idtoname_cache_template, net);
  386. if (IS_ERR(nn->idtoname_cache))
  387. return PTR_ERR(nn->idtoname_cache);
  388. rv = cache_register_net(nn->idtoname_cache, net);
  389. if (rv)
  390. goto destroy_idtoname_cache;
  391. nn->nametoid_cache = cache_create_net(&nametoid_cache_template, net);
  392. if (IS_ERR(nn->nametoid_cache)) {
  393. rv = PTR_ERR(nn->nametoid_cache);
  394. goto unregister_idtoname_cache;
  395. }
  396. rv = cache_register_net(nn->nametoid_cache, net);
  397. if (rv)
  398. goto destroy_nametoid_cache;
  399. return 0;
  400. destroy_nametoid_cache:
  401. cache_destroy_net(nn->nametoid_cache, net);
  402. unregister_idtoname_cache:
  403. cache_unregister_net(nn->idtoname_cache, net);
  404. destroy_idtoname_cache:
  405. cache_destroy_net(nn->idtoname_cache, net);
  406. return rv;
  407. }
  408. void
  409. nfsd_idmap_shutdown(struct net *net)
  410. {
  411. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  412. cache_unregister_net(nn->idtoname_cache, net);
  413. cache_unregister_net(nn->nametoid_cache, net);
  414. cache_destroy_net(nn->idtoname_cache, net);
  415. cache_destroy_net(nn->nametoid_cache, net);
  416. }
  417. static int
  418. idmap_lookup(struct svc_rqst *rqstp,
  419. struct ent *(*lookup_fn)(struct cache_detail *, struct ent *),
  420. struct ent *key, struct cache_detail *detail, struct ent **item)
  421. {
  422. int ret;
  423. *item = lookup_fn(detail, key);
  424. if (!*item)
  425. return -ENOMEM;
  426. retry:
  427. ret = cache_check(detail, &(*item)->h, &rqstp->rq_chandle);
  428. if (ret == -ETIMEDOUT) {
  429. struct ent *prev_item = *item;
  430. *item = lookup_fn(detail, key);
  431. if (*item != prev_item)
  432. goto retry;
  433. cache_put(&(*item)->h, detail);
  434. }
  435. return ret;
  436. }
  437. static char *
  438. rqst_authname(struct svc_rqst *rqstp)
  439. {
  440. struct auth_domain *clp;
  441. clp = rqstp->rq_gssclient ? rqstp->rq_gssclient : rqstp->rq_client;
  442. return clp->name;
  443. }
  444. static __be32
  445. idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen,
  446. u32 *id)
  447. {
  448. struct ent *item, key = {
  449. .type = type,
  450. };
  451. int ret;
  452. struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
  453. if (namelen + 1 > sizeof(key.name))
  454. return nfserr_badowner;
  455. memcpy(key.name, name, namelen);
  456. key.name[namelen] = '\0';
  457. strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
  458. ret = idmap_lookup(rqstp, nametoid_lookup, &key, nn->nametoid_cache, &item);
  459. if (ret == -ENOENT)
  460. return nfserr_badowner;
  461. if (ret)
  462. return nfserrno(ret);
  463. *id = item->id;
  464. cache_put(&item->h, nn->nametoid_cache);
  465. return 0;
  466. }
  467. static __be32 encode_ascii_id(struct xdr_stream *xdr, u32 id)
  468. {
  469. char buf[11];
  470. int len;
  471. __be32 *p;
  472. len = sprintf(buf, "%u", id);
  473. p = xdr_reserve_space(xdr, len + 4);
  474. if (!p)
  475. return nfserr_resource;
  476. p = xdr_encode_opaque(p, buf, len);
  477. return 0;
  478. }
  479. static __be32 idmap_id_to_name(struct xdr_stream *xdr,
  480. struct svc_rqst *rqstp, int type, u32 id)
  481. {
  482. struct ent *item, key = {
  483. .id = id,
  484. .type = type,
  485. };
  486. __be32 *p;
  487. int ret;
  488. struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
  489. strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
  490. ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item);
  491. if (ret == -ENOENT)
  492. return encode_ascii_id(xdr, id);
  493. if (ret)
  494. return nfserrno(ret);
  495. ret = strlen(item->name);
  496. WARN_ON_ONCE(ret > IDMAP_NAMESZ);
  497. p = xdr_reserve_space(xdr, ret + 4);
  498. if (!p)
  499. return nfserr_resource;
  500. p = xdr_encode_opaque(p, item->name, ret);
  501. cache_put(&item->h, nn->idtoname_cache);
  502. return 0;
  503. }
  504. static bool
  505. numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u32 *id)
  506. {
  507. int ret;
  508. char buf[11];
  509. if (namelen + 1 > sizeof(buf))
  510. /* too long to represent a 32-bit id: */
  511. return false;
  512. /* Just to make sure it's null-terminated: */
  513. memcpy(buf, name, namelen);
  514. buf[namelen] = '\0';
  515. ret = kstrtouint(buf, 10, id);
  516. return ret == 0;
  517. }
  518. static __be32
  519. do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u32 *id)
  520. {
  521. if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
  522. if (numeric_name_to_id(rqstp, type, name, namelen, id))
  523. return 0;
  524. /*
  525. * otherwise, fall through and try idmapping, for
  526. * backwards compatibility with clients sending names:
  527. */
  528. return idmap_name_to_id(rqstp, type, name, namelen, id);
  529. }
  530. static __be32 encode_name_from_id(struct xdr_stream *xdr,
  531. struct svc_rqst *rqstp, int type, u32 id)
  532. {
  533. if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
  534. return encode_ascii_id(xdr, id);
  535. return idmap_id_to_name(xdr, rqstp, type, id);
  536. }
  537. __be32
  538. nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen,
  539. kuid_t *uid)
  540. {
  541. __be32 status;
  542. u32 id = -1;
  543. if (name == NULL || namelen == 0)
  544. return nfserr_inval;
  545. status = do_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, &id);
  546. *uid = make_kuid(&init_user_ns, id);
  547. if (!uid_valid(*uid))
  548. status = nfserr_badowner;
  549. return status;
  550. }
  551. __be32
  552. nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen,
  553. kgid_t *gid)
  554. {
  555. __be32 status;
  556. u32 id = -1;
  557. if (name == NULL || namelen == 0)
  558. return nfserr_inval;
  559. status = do_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, &id);
  560. *gid = make_kgid(&init_user_ns, id);
  561. if (!gid_valid(*gid))
  562. status = nfserr_badowner;
  563. return status;
  564. }
  565. __be32 nfsd4_encode_user(struct xdr_stream *xdr, struct svc_rqst *rqstp,
  566. kuid_t uid)
  567. {
  568. u32 id = from_kuid(&init_user_ns, uid);
  569. return encode_name_from_id(xdr, rqstp, IDMAP_TYPE_USER, id);
  570. }
  571. __be32 nfsd4_encode_group(struct xdr_stream *xdr, struct svc_rqst *rqstp,
  572. kgid_t gid)
  573. {
  574. u32 id = from_kgid(&init_user_ns, gid);
  575. return encode_name_from_id(xdr, rqstp, IDMAP_TYPE_GROUP, id);
  576. }