/net/sunrpc/svcauth_unix.c

http://github.com/mirrors/linux · C · 932 lines · 763 code · 124 blank · 45 comment · 112 complexity · 94744edb84a29740e255ff818a061682 MD5 · raw file

  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <linux/types.h>
  3. #include <linux/sched.h>
  4. #include <linux/module.h>
  5. #include <linux/sunrpc/types.h>
  6. #include <linux/sunrpc/xdr.h>
  7. #include <linux/sunrpc/svcsock.h>
  8. #include <linux/sunrpc/svcauth.h>
  9. #include <linux/sunrpc/gss_api.h>
  10. #include <linux/sunrpc/addr.h>
  11. #include <linux/err.h>
  12. #include <linux/seq_file.h>
  13. #include <linux/hash.h>
  14. #include <linux/string.h>
  15. #include <linux/slab.h>
  16. #include <net/sock.h>
  17. #include <net/ipv6.h>
  18. #include <linux/kernel.h>
  19. #include <linux/user_namespace.h>
  20. #define RPCDBG_FACILITY RPCDBG_AUTH
  21. #include "netns.h"
  22. /*
  23. * AUTHUNIX and AUTHNULL credentials are both handled here.
  24. * AUTHNULL is treated just like AUTHUNIX except that the uid/gid
  25. * are always nobody (-2). i.e. we do the same IP address checks for
  26. * AUTHNULL as for AUTHUNIX, and that is done here.
  27. */
  28. struct unix_domain {
  29. struct auth_domain h;
  30. /* other stuff later */
  31. };
  32. extern struct auth_ops svcauth_null;
  33. extern struct auth_ops svcauth_unix;
  34. static void svcauth_unix_domain_release_rcu(struct rcu_head *head)
  35. {
  36. struct auth_domain *dom = container_of(head, struct auth_domain, rcu_head);
  37. struct unix_domain *ud = container_of(dom, struct unix_domain, h);
  38. kfree(dom->name);
  39. kfree(ud);
  40. }
  41. static void svcauth_unix_domain_release(struct auth_domain *dom)
  42. {
  43. call_rcu(&dom->rcu_head, svcauth_unix_domain_release_rcu);
  44. }
  45. struct auth_domain *unix_domain_find(char *name)
  46. {
  47. struct auth_domain *rv;
  48. struct unix_domain *new = NULL;
  49. rv = auth_domain_find(name);
  50. while(1) {
  51. if (rv) {
  52. if (new && rv != &new->h)
  53. svcauth_unix_domain_release(&new->h);
  54. if (rv->flavour != &svcauth_unix) {
  55. auth_domain_put(rv);
  56. return NULL;
  57. }
  58. return rv;
  59. }
  60. new = kmalloc(sizeof(*new), GFP_KERNEL);
  61. if (new == NULL)
  62. return NULL;
  63. kref_init(&new->h.ref);
  64. new->h.name = kstrdup(name, GFP_KERNEL);
  65. if (new->h.name == NULL) {
  66. kfree(new);
  67. return NULL;
  68. }
  69. new->h.flavour = &svcauth_unix;
  70. rv = auth_domain_lookup(name, &new->h);
  71. }
  72. }
  73. EXPORT_SYMBOL_GPL(unix_domain_find);
  74. /**************************************************
  75. * cache for IP address to unix_domain
  76. * as needed by AUTH_UNIX
  77. */
  78. #define IP_HASHBITS 8
  79. #define IP_HASHMAX (1<<IP_HASHBITS)
  80. struct ip_map {
  81. struct cache_head h;
  82. char m_class[8]; /* e.g. "nfsd" */
  83. struct in6_addr m_addr;
  84. struct unix_domain *m_client;
  85. struct rcu_head m_rcu;
  86. };
  87. static void ip_map_put(struct kref *kref)
  88. {
  89. struct cache_head *item = container_of(kref, struct cache_head, ref);
  90. struct ip_map *im = container_of(item, struct ip_map,h);
  91. if (test_bit(CACHE_VALID, &item->flags) &&
  92. !test_bit(CACHE_NEGATIVE, &item->flags))
  93. auth_domain_put(&im->m_client->h);
  94. kfree_rcu(im, m_rcu);
  95. }
  96. static inline int hash_ip6(const struct in6_addr *ip)
  97. {
  98. return hash_32(ipv6_addr_hash(ip), IP_HASHBITS);
  99. }
  100. static int ip_map_match(struct cache_head *corig, struct cache_head *cnew)
  101. {
  102. struct ip_map *orig = container_of(corig, struct ip_map, h);
  103. struct ip_map *new = container_of(cnew, struct ip_map, h);
  104. return strcmp(orig->m_class, new->m_class) == 0 &&
  105. ipv6_addr_equal(&orig->m_addr, &new->m_addr);
  106. }
  107. static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
  108. {
  109. struct ip_map *new = container_of(cnew, struct ip_map, h);
  110. struct ip_map *item = container_of(citem, struct ip_map, h);
  111. strcpy(new->m_class, item->m_class);
  112. new->m_addr = item->m_addr;
  113. }
  114. static void update(struct cache_head *cnew, struct cache_head *citem)
  115. {
  116. struct ip_map *new = container_of(cnew, struct ip_map, h);
  117. struct ip_map *item = container_of(citem, struct ip_map, h);
  118. kref_get(&item->m_client->h.ref);
  119. new->m_client = item->m_client;
  120. }
  121. static struct cache_head *ip_map_alloc(void)
  122. {
  123. struct ip_map *i = kmalloc(sizeof(*i), GFP_KERNEL);
  124. if (i)
  125. return &i->h;
  126. else
  127. return NULL;
  128. }
  129. static int ip_map_upcall(struct cache_detail *cd, struct cache_head *h)
  130. {
  131. return sunrpc_cache_pipe_upcall(cd, h);
  132. }
  133. static void ip_map_request(struct cache_detail *cd,
  134. struct cache_head *h,
  135. char **bpp, int *blen)
  136. {
  137. char text_addr[40];
  138. struct ip_map *im = container_of(h, struct ip_map, h);
  139. if (ipv6_addr_v4mapped(&(im->m_addr))) {
  140. snprintf(text_addr, 20, "%pI4", &im->m_addr.s6_addr32[3]);
  141. } else {
  142. snprintf(text_addr, 40, "%pI6", &im->m_addr);
  143. }
  144. qword_add(bpp, blen, im->m_class);
  145. qword_add(bpp, blen, text_addr);
  146. (*bpp)[-1] = '\n';
  147. }
  148. static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr);
  149. static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time64_t expiry);
  150. static int ip_map_parse(struct cache_detail *cd,
  151. char *mesg, int mlen)
  152. {
  153. /* class ipaddress [domainname] */
  154. /* should be safe just to use the start of the input buffer
  155. * for scratch: */
  156. char *buf = mesg;
  157. int len;
  158. char class[8];
  159. union {
  160. struct sockaddr sa;
  161. struct sockaddr_in s4;
  162. struct sockaddr_in6 s6;
  163. } address;
  164. struct sockaddr_in6 sin6;
  165. int err;
  166. struct ip_map *ipmp;
  167. struct auth_domain *dom;
  168. time64_t expiry;
  169. if (mesg[mlen-1] != '\n')
  170. return -EINVAL;
  171. mesg[mlen-1] = 0;
  172. /* class */
  173. len = qword_get(&mesg, class, sizeof(class));
  174. if (len <= 0) return -EINVAL;
  175. /* ip address */
  176. len = qword_get(&mesg, buf, mlen);
  177. if (len <= 0) return -EINVAL;
  178. if (rpc_pton(cd->net, buf, len, &address.sa, sizeof(address)) == 0)
  179. return -EINVAL;
  180. switch (address.sa.sa_family) {
  181. case AF_INET:
  182. /* Form a mapped IPv4 address in sin6 */
  183. sin6.sin6_family = AF_INET6;
  184. ipv6_addr_set_v4mapped(address.s4.sin_addr.s_addr,
  185. &sin6.sin6_addr);
  186. break;
  187. #if IS_ENABLED(CONFIG_IPV6)
  188. case AF_INET6:
  189. memcpy(&sin6, &address.s6, sizeof(sin6));
  190. break;
  191. #endif
  192. default:
  193. return -EINVAL;
  194. }
  195. expiry = get_expiry(&mesg);
  196. if (expiry ==0)
  197. return -EINVAL;
  198. /* domainname, or empty for NEGATIVE */
  199. len = qword_get(&mesg, buf, mlen);
  200. if (len < 0) return -EINVAL;
  201. if (len) {
  202. dom = unix_domain_find(buf);
  203. if (dom == NULL)
  204. return -ENOENT;
  205. } else
  206. dom = NULL;
  207. /* IPv6 scope IDs are ignored for now */
  208. ipmp = __ip_map_lookup(cd, class, &sin6.sin6_addr);
  209. if (ipmp) {
  210. err = __ip_map_update(cd, ipmp,
  211. container_of(dom, struct unix_domain, h),
  212. expiry);
  213. } else
  214. err = -ENOMEM;
  215. if (dom)
  216. auth_domain_put(dom);
  217. cache_flush();
  218. return err;
  219. }
  220. static int ip_map_show(struct seq_file *m,
  221. struct cache_detail *cd,
  222. struct cache_head *h)
  223. {
  224. struct ip_map *im;
  225. struct in6_addr addr;
  226. char *dom = "-no-domain-";
  227. if (h == NULL) {
  228. seq_puts(m, "#class IP domain\n");
  229. return 0;
  230. }
  231. im = container_of(h, struct ip_map, h);
  232. /* class addr domain */
  233. addr = im->m_addr;
  234. if (test_bit(CACHE_VALID, &h->flags) &&
  235. !test_bit(CACHE_NEGATIVE, &h->flags))
  236. dom = im->m_client->h.name;
  237. if (ipv6_addr_v4mapped(&addr)) {
  238. seq_printf(m, "%s %pI4 %s\n",
  239. im->m_class, &addr.s6_addr32[3], dom);
  240. } else {
  241. seq_printf(m, "%s %pI6 %s\n", im->m_class, &addr, dom);
  242. }
  243. return 0;
  244. }
  245. static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class,
  246. struct in6_addr *addr)
  247. {
  248. struct ip_map ip;
  249. struct cache_head *ch;
  250. strcpy(ip.m_class, class);
  251. ip.m_addr = *addr;
  252. ch = sunrpc_cache_lookup_rcu(cd, &ip.h,
  253. hash_str(class, IP_HASHBITS) ^
  254. hash_ip6(addr));
  255. if (ch)
  256. return container_of(ch, struct ip_map, h);
  257. else
  258. return NULL;
  259. }
  260. static inline struct ip_map *ip_map_lookup(struct net *net, char *class,
  261. struct in6_addr *addr)
  262. {
  263. struct sunrpc_net *sn;
  264. sn = net_generic(net, sunrpc_net_id);
  265. return __ip_map_lookup(sn->ip_map_cache, class, addr);
  266. }
  267. static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
  268. struct unix_domain *udom, time64_t expiry)
  269. {
  270. struct ip_map ip;
  271. struct cache_head *ch;
  272. ip.m_client = udom;
  273. ip.h.flags = 0;
  274. if (!udom)
  275. set_bit(CACHE_NEGATIVE, &ip.h.flags);
  276. ip.h.expiry_time = expiry;
  277. ch = sunrpc_cache_update(cd, &ip.h, &ipm->h,
  278. hash_str(ipm->m_class, IP_HASHBITS) ^
  279. hash_ip6(&ipm->m_addr));
  280. if (!ch)
  281. return -ENOMEM;
  282. cache_put(ch, cd);
  283. return 0;
  284. }
  285. static inline int ip_map_update(struct net *net, struct ip_map *ipm,
  286. struct unix_domain *udom, time64_t expiry)
  287. {
  288. struct sunrpc_net *sn;
  289. sn = net_generic(net, sunrpc_net_id);
  290. return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry);
  291. }
  292. void svcauth_unix_purge(struct net *net)
  293. {
  294. struct sunrpc_net *sn;
  295. sn = net_generic(net, sunrpc_net_id);
  296. cache_purge(sn->ip_map_cache);
  297. }
  298. EXPORT_SYMBOL_GPL(svcauth_unix_purge);
  299. static inline struct ip_map *
  300. ip_map_cached_get(struct svc_xprt *xprt)
  301. {
  302. struct ip_map *ipm = NULL;
  303. struct sunrpc_net *sn;
  304. if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) {
  305. spin_lock(&xprt->xpt_lock);
  306. ipm = xprt->xpt_auth_cache;
  307. if (ipm != NULL) {
  308. sn = net_generic(xprt->xpt_net, sunrpc_net_id);
  309. if (cache_is_expired(sn->ip_map_cache, &ipm->h)) {
  310. /*
  311. * The entry has been invalidated since it was
  312. * remembered, e.g. by a second mount from the
  313. * same IP address.
  314. */
  315. xprt->xpt_auth_cache = NULL;
  316. spin_unlock(&xprt->xpt_lock);
  317. cache_put(&ipm->h, sn->ip_map_cache);
  318. return NULL;
  319. }
  320. cache_get(&ipm->h);
  321. }
  322. spin_unlock(&xprt->xpt_lock);
  323. }
  324. return ipm;
  325. }
  326. static inline void
  327. ip_map_cached_put(struct svc_xprt *xprt, struct ip_map *ipm)
  328. {
  329. if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) {
  330. spin_lock(&xprt->xpt_lock);
  331. if (xprt->xpt_auth_cache == NULL) {
  332. /* newly cached, keep the reference */
  333. xprt->xpt_auth_cache = ipm;
  334. ipm = NULL;
  335. }
  336. spin_unlock(&xprt->xpt_lock);
  337. }
  338. if (ipm) {
  339. struct sunrpc_net *sn;
  340. sn = net_generic(xprt->xpt_net, sunrpc_net_id);
  341. cache_put(&ipm->h, sn->ip_map_cache);
  342. }
  343. }
  344. void
  345. svcauth_unix_info_release(struct svc_xprt *xpt)
  346. {
  347. struct ip_map *ipm;
  348. ipm = xpt->xpt_auth_cache;
  349. if (ipm != NULL) {
  350. struct sunrpc_net *sn;
  351. sn = net_generic(xpt->xpt_net, sunrpc_net_id);
  352. cache_put(&ipm->h, sn->ip_map_cache);
  353. }
  354. }
  355. /****************************************************************************
  356. * auth.unix.gid cache
  357. * simple cache to map a UID to a list of GIDs
  358. * because AUTH_UNIX aka AUTH_SYS has a max of UNX_NGROUPS
  359. */
  360. #define GID_HASHBITS 8
  361. #define GID_HASHMAX (1<<GID_HASHBITS)
  362. struct unix_gid {
  363. struct cache_head h;
  364. kuid_t uid;
  365. struct group_info *gi;
  366. struct rcu_head rcu;
  367. };
  368. static int unix_gid_hash(kuid_t uid)
  369. {
  370. return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS);
  371. }
  372. static void unix_gid_put(struct kref *kref)
  373. {
  374. struct cache_head *item = container_of(kref, struct cache_head, ref);
  375. struct unix_gid *ug = container_of(item, struct unix_gid, h);
  376. if (test_bit(CACHE_VALID, &item->flags) &&
  377. !test_bit(CACHE_NEGATIVE, &item->flags))
  378. put_group_info(ug->gi);
  379. kfree_rcu(ug, rcu);
  380. }
  381. static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew)
  382. {
  383. struct unix_gid *orig = container_of(corig, struct unix_gid, h);
  384. struct unix_gid *new = container_of(cnew, struct unix_gid, h);
  385. return uid_eq(orig->uid, new->uid);
  386. }
  387. static void unix_gid_init(struct cache_head *cnew, struct cache_head *citem)
  388. {
  389. struct unix_gid *new = container_of(cnew, struct unix_gid, h);
  390. struct unix_gid *item = container_of(citem, struct unix_gid, h);
  391. new->uid = item->uid;
  392. }
  393. static void unix_gid_update(struct cache_head *cnew, struct cache_head *citem)
  394. {
  395. struct unix_gid *new = container_of(cnew, struct unix_gid, h);
  396. struct unix_gid *item = container_of(citem, struct unix_gid, h);
  397. get_group_info(item->gi);
  398. new->gi = item->gi;
  399. }
  400. static struct cache_head *unix_gid_alloc(void)
  401. {
  402. struct unix_gid *g = kmalloc(sizeof(*g), GFP_KERNEL);
  403. if (g)
  404. return &g->h;
  405. else
  406. return NULL;
  407. }
  408. static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h)
  409. {
  410. return sunrpc_cache_pipe_upcall_timeout(cd, h);
  411. }
  412. static void unix_gid_request(struct cache_detail *cd,
  413. struct cache_head *h,
  414. char **bpp, int *blen)
  415. {
  416. char tuid[20];
  417. struct unix_gid *ug = container_of(h, struct unix_gid, h);
  418. snprintf(tuid, 20, "%u", from_kuid(&init_user_ns, ug->uid));
  419. qword_add(bpp, blen, tuid);
  420. (*bpp)[-1] = '\n';
  421. }
  422. static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid);
  423. static int unix_gid_parse(struct cache_detail *cd,
  424. char *mesg, int mlen)
  425. {
  426. /* uid expiry Ngid gid0 gid1 ... gidN-1 */
  427. int id;
  428. kuid_t uid;
  429. int gids;
  430. int rv;
  431. int i;
  432. int err;
  433. time64_t expiry;
  434. struct unix_gid ug, *ugp;
  435. if (mesg[mlen - 1] != '\n')
  436. return -EINVAL;
  437. mesg[mlen-1] = 0;
  438. rv = get_int(&mesg, &id);
  439. if (rv)
  440. return -EINVAL;
  441. uid = make_kuid(current_user_ns(), id);
  442. ug.uid = uid;
  443. expiry = get_expiry(&mesg);
  444. if (expiry == 0)
  445. return -EINVAL;
  446. rv = get_int(&mesg, &gids);
  447. if (rv || gids < 0 || gids > 8192)
  448. return -EINVAL;
  449. ug.gi = groups_alloc(gids);
  450. if (!ug.gi)
  451. return -ENOMEM;
  452. for (i = 0 ; i < gids ; i++) {
  453. int gid;
  454. kgid_t kgid;
  455. rv = get_int(&mesg, &gid);
  456. err = -EINVAL;
  457. if (rv)
  458. goto out;
  459. kgid = make_kgid(current_user_ns(), gid);
  460. if (!gid_valid(kgid))
  461. goto out;
  462. ug.gi->gid[i] = kgid;
  463. }
  464. groups_sort(ug.gi);
  465. ugp = unix_gid_lookup(cd, uid);
  466. if (ugp) {
  467. struct cache_head *ch;
  468. ug.h.flags = 0;
  469. ug.h.expiry_time = expiry;
  470. ch = sunrpc_cache_update(cd,
  471. &ug.h, &ugp->h,
  472. unix_gid_hash(uid));
  473. if (!ch)
  474. err = -ENOMEM;
  475. else {
  476. err = 0;
  477. cache_put(ch, cd);
  478. }
  479. } else
  480. err = -ENOMEM;
  481. out:
  482. if (ug.gi)
  483. put_group_info(ug.gi);
  484. return err;
  485. }
  486. static int unix_gid_show(struct seq_file *m,
  487. struct cache_detail *cd,
  488. struct cache_head *h)
  489. {
  490. struct user_namespace *user_ns = m->file->f_cred->user_ns;
  491. struct unix_gid *ug;
  492. int i;
  493. int glen;
  494. if (h == NULL) {
  495. seq_puts(m, "#uid cnt: gids...\n");
  496. return 0;
  497. }
  498. ug = container_of(h, struct unix_gid, h);
  499. if (test_bit(CACHE_VALID, &h->flags) &&
  500. !test_bit(CACHE_NEGATIVE, &h->flags))
  501. glen = ug->gi->ngroups;
  502. else
  503. glen = 0;
  504. seq_printf(m, "%u %d:", from_kuid_munged(user_ns, ug->uid), glen);
  505. for (i = 0; i < glen; i++)
  506. seq_printf(m, " %d", from_kgid_munged(user_ns, ug->gi->gid[i]));
  507. seq_printf(m, "\n");
  508. return 0;
  509. }
  510. static const struct cache_detail unix_gid_cache_template = {
  511. .owner = THIS_MODULE,
  512. .hash_size = GID_HASHMAX,
  513. .name = "auth.unix.gid",
  514. .cache_put = unix_gid_put,
  515. .cache_upcall = unix_gid_upcall,
  516. .cache_request = unix_gid_request,
  517. .cache_parse = unix_gid_parse,
  518. .cache_show = unix_gid_show,
  519. .match = unix_gid_match,
  520. .init = unix_gid_init,
  521. .update = unix_gid_update,
  522. .alloc = unix_gid_alloc,
  523. };
  524. int unix_gid_cache_create(struct net *net)
  525. {
  526. struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
  527. struct cache_detail *cd;
  528. int err;
  529. cd = cache_create_net(&unix_gid_cache_template, net);
  530. if (IS_ERR(cd))
  531. return PTR_ERR(cd);
  532. err = cache_register_net(cd, net);
  533. if (err) {
  534. cache_destroy_net(cd, net);
  535. return err;
  536. }
  537. sn->unix_gid_cache = cd;
  538. return 0;
  539. }
  540. void unix_gid_cache_destroy(struct net *net)
  541. {
  542. struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
  543. struct cache_detail *cd = sn->unix_gid_cache;
  544. sn->unix_gid_cache = NULL;
  545. cache_purge(cd);
  546. cache_unregister_net(cd, net);
  547. cache_destroy_net(cd, net);
  548. }
  549. static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid)
  550. {
  551. struct unix_gid ug;
  552. struct cache_head *ch;
  553. ug.uid = uid;
  554. ch = sunrpc_cache_lookup_rcu(cd, &ug.h, unix_gid_hash(uid));
  555. if (ch)
  556. return container_of(ch, struct unix_gid, h);
  557. else
  558. return NULL;
  559. }
  560. static struct group_info *unix_gid_find(kuid_t uid, struct svc_rqst *rqstp)
  561. {
  562. struct unix_gid *ug;
  563. struct group_info *gi;
  564. int ret;
  565. struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net,
  566. sunrpc_net_id);
  567. ug = unix_gid_lookup(sn->unix_gid_cache, uid);
  568. if (!ug)
  569. return ERR_PTR(-EAGAIN);
  570. ret = cache_check(sn->unix_gid_cache, &ug->h, &rqstp->rq_chandle);
  571. switch (ret) {
  572. case -ENOENT:
  573. return ERR_PTR(-ENOENT);
  574. case -ETIMEDOUT:
  575. return ERR_PTR(-ESHUTDOWN);
  576. case 0:
  577. gi = get_group_info(ug->gi);
  578. cache_put(&ug->h, sn->unix_gid_cache);
  579. return gi;
  580. default:
  581. return ERR_PTR(-EAGAIN);
  582. }
  583. }
  584. int
  585. svcauth_unix_set_client(struct svc_rqst *rqstp)
  586. {
  587. struct sockaddr_in *sin;
  588. struct sockaddr_in6 *sin6, sin6_storage;
  589. struct ip_map *ipm;
  590. struct group_info *gi;
  591. struct svc_cred *cred = &rqstp->rq_cred;
  592. struct svc_xprt *xprt = rqstp->rq_xprt;
  593. struct net *net = xprt->xpt_net;
  594. struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
  595. switch (rqstp->rq_addr.ss_family) {
  596. case AF_INET:
  597. sin = svc_addr_in(rqstp);
  598. sin6 = &sin6_storage;
  599. ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &sin6->sin6_addr);
  600. break;
  601. case AF_INET6:
  602. sin6 = svc_addr_in6(rqstp);
  603. break;
  604. default:
  605. BUG();
  606. }
  607. rqstp->rq_client = NULL;
  608. if (rqstp->rq_proc == 0)
  609. return SVC_OK;
  610. ipm = ip_map_cached_get(xprt);
  611. if (ipm == NULL)
  612. ipm = __ip_map_lookup(sn->ip_map_cache, rqstp->rq_server->sv_program->pg_class,
  613. &sin6->sin6_addr);
  614. if (ipm == NULL)
  615. return SVC_DENIED;
  616. switch (cache_check(sn->ip_map_cache, &ipm->h, &rqstp->rq_chandle)) {
  617. default:
  618. BUG();
  619. case -ETIMEDOUT:
  620. return SVC_CLOSE;
  621. case -EAGAIN:
  622. return SVC_DROP;
  623. case -ENOENT:
  624. return SVC_DENIED;
  625. case 0:
  626. rqstp->rq_client = &ipm->m_client->h;
  627. kref_get(&rqstp->rq_client->ref);
  628. ip_map_cached_put(xprt, ipm);
  629. break;
  630. }
  631. gi = unix_gid_find(cred->cr_uid, rqstp);
  632. switch (PTR_ERR(gi)) {
  633. case -EAGAIN:
  634. return SVC_DROP;
  635. case -ESHUTDOWN:
  636. return SVC_CLOSE;
  637. case -ENOENT:
  638. break;
  639. default:
  640. put_group_info(cred->cr_group_info);
  641. cred->cr_group_info = gi;
  642. }
  643. return SVC_OK;
  644. }
  645. EXPORT_SYMBOL_GPL(svcauth_unix_set_client);
  646. static int
  647. svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)
  648. {
  649. struct kvec *argv = &rqstp->rq_arg.head[0];
  650. struct kvec *resv = &rqstp->rq_res.head[0];
  651. struct svc_cred *cred = &rqstp->rq_cred;
  652. if (argv->iov_len < 3*4)
  653. return SVC_GARBAGE;
  654. if (svc_getu32(argv) != 0) {
  655. dprintk("svc: bad null cred\n");
  656. *authp = rpc_autherr_badcred;
  657. return SVC_DENIED;
  658. }
  659. if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
  660. dprintk("svc: bad null verf\n");
  661. *authp = rpc_autherr_badverf;
  662. return SVC_DENIED;
  663. }
  664. /* Signal that mapping to nobody uid/gid is required */
  665. cred->cr_uid = INVALID_UID;
  666. cred->cr_gid = INVALID_GID;
  667. cred->cr_group_info = groups_alloc(0);
  668. if (cred->cr_group_info == NULL)
  669. return SVC_CLOSE; /* kmalloc failure - client must retry */
  670. /* Put NULL verifier */
  671. svc_putnl(resv, RPC_AUTH_NULL);
  672. svc_putnl(resv, 0);
  673. rqstp->rq_cred.cr_flavor = RPC_AUTH_NULL;
  674. return SVC_OK;
  675. }
  676. static int
  677. svcauth_null_release(struct svc_rqst *rqstp)
  678. {
  679. if (rqstp->rq_client)
  680. auth_domain_put(rqstp->rq_client);
  681. rqstp->rq_client = NULL;
  682. if (rqstp->rq_cred.cr_group_info)
  683. put_group_info(rqstp->rq_cred.cr_group_info);
  684. rqstp->rq_cred.cr_group_info = NULL;
  685. return 0; /* don't drop */
  686. }
  687. struct auth_ops svcauth_null = {
  688. .name = "null",
  689. .owner = THIS_MODULE,
  690. .flavour = RPC_AUTH_NULL,
  691. .accept = svcauth_null_accept,
  692. .release = svcauth_null_release,
  693. .set_client = svcauth_unix_set_client,
  694. };
  695. static int
  696. svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
  697. {
  698. struct kvec *argv = &rqstp->rq_arg.head[0];
  699. struct kvec *resv = &rqstp->rq_res.head[0];
  700. struct svc_cred *cred = &rqstp->rq_cred;
  701. struct user_namespace *userns;
  702. u32 slen, i;
  703. int len = argv->iov_len;
  704. if ((len -= 3*4) < 0)
  705. return SVC_GARBAGE;
  706. svc_getu32(argv); /* length */
  707. svc_getu32(argv); /* time stamp */
  708. slen = XDR_QUADLEN(svc_getnl(argv)); /* machname length */
  709. if (slen > 64 || (len -= (slen + 3)*4) < 0)
  710. goto badcred;
  711. argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */
  712. argv->iov_len -= slen*4;
  713. /*
  714. * Note: we skip uid_valid()/gid_valid() checks here for
  715. * backwards compatibility with clients that use -1 id's.
  716. * Instead, -1 uid or gid is later mapped to the
  717. * (export-specific) anonymous id by nfsd_setuser.
  718. * Supplementary gid's will be left alone.
  719. */
  720. userns = (rqstp->rq_xprt && rqstp->rq_xprt->xpt_cred) ?
  721. rqstp->rq_xprt->xpt_cred->user_ns : &init_user_ns;
  722. cred->cr_uid = make_kuid(userns, svc_getnl(argv)); /* uid */
  723. cred->cr_gid = make_kgid(userns, svc_getnl(argv)); /* gid */
  724. slen = svc_getnl(argv); /* gids length */
  725. if (slen > UNX_NGROUPS || (len -= (slen + 2)*4) < 0)
  726. goto badcred;
  727. cred->cr_group_info = groups_alloc(slen);
  728. if (cred->cr_group_info == NULL)
  729. return SVC_CLOSE;
  730. for (i = 0; i < slen; i++) {
  731. kgid_t kgid = make_kgid(userns, svc_getnl(argv));
  732. cred->cr_group_info->gid[i] = kgid;
  733. }
  734. groups_sort(cred->cr_group_info);
  735. if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
  736. *authp = rpc_autherr_badverf;
  737. return SVC_DENIED;
  738. }
  739. /* Put NULL verifier */
  740. svc_putnl(resv, RPC_AUTH_NULL);
  741. svc_putnl(resv, 0);
  742. rqstp->rq_cred.cr_flavor = RPC_AUTH_UNIX;
  743. return SVC_OK;
  744. badcred:
  745. *authp = rpc_autherr_badcred;
  746. return SVC_DENIED;
  747. }
  748. static int
  749. svcauth_unix_release(struct svc_rqst *rqstp)
  750. {
  751. /* Verifier (such as it is) is already in place.
  752. */
  753. if (rqstp->rq_client)
  754. auth_domain_put(rqstp->rq_client);
  755. rqstp->rq_client = NULL;
  756. if (rqstp->rq_cred.cr_group_info)
  757. put_group_info(rqstp->rq_cred.cr_group_info);
  758. rqstp->rq_cred.cr_group_info = NULL;
  759. return 0;
  760. }
  761. struct auth_ops svcauth_unix = {
  762. .name = "unix",
  763. .owner = THIS_MODULE,
  764. .flavour = RPC_AUTH_UNIX,
  765. .accept = svcauth_unix_accept,
  766. .release = svcauth_unix_release,
  767. .domain_release = svcauth_unix_domain_release,
  768. .set_client = svcauth_unix_set_client,
  769. };
  770. static const struct cache_detail ip_map_cache_template = {
  771. .owner = THIS_MODULE,
  772. .hash_size = IP_HASHMAX,
  773. .name = "auth.unix.ip",
  774. .cache_put = ip_map_put,
  775. .cache_upcall = ip_map_upcall,
  776. .cache_request = ip_map_request,
  777. .cache_parse = ip_map_parse,
  778. .cache_show = ip_map_show,
  779. .match = ip_map_match,
  780. .init = ip_map_init,
  781. .update = update,
  782. .alloc = ip_map_alloc,
  783. };
  784. int ip_map_cache_create(struct net *net)
  785. {
  786. struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
  787. struct cache_detail *cd;
  788. int err;
  789. cd = cache_create_net(&ip_map_cache_template, net);
  790. if (IS_ERR(cd))
  791. return PTR_ERR(cd);
  792. err = cache_register_net(cd, net);
  793. if (err) {
  794. cache_destroy_net(cd, net);
  795. return err;
  796. }
  797. sn->ip_map_cache = cd;
  798. return 0;
  799. }
  800. void ip_map_cache_destroy(struct net *net)
  801. {
  802. struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
  803. struct cache_detail *cd = sn->ip_map_cache;
  804. sn->ip_map_cache = NULL;
  805. cache_purge(cd);
  806. cache_unregister_net(cd, net);
  807. cache_destroy_net(cd, net);
  808. }