auth.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /*
  2. * linux/fs/nfsd/auth.c
  3. *
  4. * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
  5. */
  6. #include <linux/types.h>
  7. #include <linux/sched.h>
  8. #include <linux/sunrpc/svc.h>
  9. #include <linux/sunrpc/svcauth.h>
  10. #include <linux/nfsd/nfsd.h>
  11. #define CAP_NFSD_MASK (CAP_FS_MASK|CAP_TO_MASK(CAP_SYS_RESOURCE))
  12. static int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)
  13. {
  14. struct exp_flavor_info *f;
  15. struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors;
  16. for (f = exp->ex_flavors; f < end; f++) {
  17. if (f->pseudoflavor == rqstp->rq_flavor)
  18. return f->flags;
  19. }
  20. return exp->ex_flags;
  21. }
  22. int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
  23. {
  24. struct svc_cred cred = rqstp->rq_cred;
  25. int i;
  26. int flags = nfsexp_flags(rqstp, exp);
  27. int ret;
  28. if (flags & NFSEXP_ALLSQUASH) {
  29. cred.cr_uid = exp->ex_anon_uid;
  30. cred.cr_gid = exp->ex_anon_gid;
  31. cred.cr_group_info = groups_alloc(0);
  32. } else if (flags & NFSEXP_ROOTSQUASH) {
  33. struct group_info *gi;
  34. if (!cred.cr_uid)
  35. cred.cr_uid = exp->ex_anon_uid;
  36. if (!cred.cr_gid)
  37. cred.cr_gid = exp->ex_anon_gid;
  38. gi = groups_alloc(cred.cr_group_info->ngroups);
  39. if (gi)
  40. for (i = 0; i < cred.cr_group_info->ngroups; i++) {
  41. if (!GROUP_AT(cred.cr_group_info, i))
  42. GROUP_AT(gi, i) = exp->ex_anon_gid;
  43. else
  44. GROUP_AT(gi, i) = GROUP_AT(cred.cr_group_info, i);
  45. }
  46. cred.cr_group_info = gi;
  47. } else
  48. get_group_info(cred.cr_group_info);
  49. if (cred.cr_uid != (uid_t) -1)
  50. current->fsuid = cred.cr_uid;
  51. else
  52. current->fsuid = exp->ex_anon_uid;
  53. if (cred.cr_gid != (gid_t) -1)
  54. current->fsgid = cred.cr_gid;
  55. else
  56. current->fsgid = exp->ex_anon_gid;
  57. if (!cred.cr_group_info)
  58. return -ENOMEM;
  59. ret = set_current_groups(cred.cr_group_info);
  60. put_group_info(cred.cr_group_info);
  61. if ((cred.cr_uid)) {
  62. cap_t(current->cap_effective) &= ~CAP_NFSD_MASK;
  63. } else {
  64. cap_t(current->cap_effective) |= (CAP_NFSD_MASK &
  65. current->cap_permitted);
  66. }
  67. return ret;
  68. }