Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
auth.c
Go to the documentation of this file.
1 /* Copyright (C) 1995, 1996 Olaf Kirch <[email protected]> */
2 
3 #include <linux/sched.h>
4 #include <linux/user_namespace.h>
5 #include "nfsd.h"
6 #include "auth.h"
7 
8 int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)
9 {
10  struct exp_flavor_info *f;
11  struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors;
12 
13  for (f = exp->ex_flavors; f < end; f++) {
14  if (f->pseudoflavor == rqstp->rq_cred.cr_flavor)
15  return f->flags;
16  }
17  return exp->ex_flags;
18 
19 }
20 
21 int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
22 {
23  struct group_info *rqgi;
24  struct group_info *gi;
25  struct cred *new;
26  int i;
27  int flags = nfsexp_flags(rqstp, exp);
28  int ret;
29 
30  validate_process_creds();
31 
32  /* discard any old override before preparing the new set */
33  revert_creds(get_cred(current->real_cred));
34  new = prepare_creds();
35  if (!new)
36  return -ENOMEM;
37 
38  new->fsuid = rqstp->rq_cred.cr_uid;
39  new->fsgid = rqstp->rq_cred.cr_gid;
40 
41  rqgi = rqstp->rq_cred.cr_group_info;
42 
43  if (flags & NFSEXP_ALLSQUASH) {
44  new->fsuid = exp->ex_anon_uid;
45  new->fsgid = exp->ex_anon_gid;
46  gi = groups_alloc(0);
47  if (!gi)
48  goto oom;
49  } else if (flags & NFSEXP_ROOTSQUASH) {
50  if (!new->fsuid)
51  new->fsuid = exp->ex_anon_uid;
52  if (!new->fsgid)
53  new->fsgid = exp->ex_anon_gid;
54 
55  gi = groups_alloc(rqgi->ngroups);
56  if (!gi)
57  goto oom;
58 
59  for (i = 0; i < rqgi->ngroups; i++) {
60  if (gid_eq(GLOBAL_ROOT_GID, GROUP_AT(rqgi, i)))
61  GROUP_AT(gi, i) = make_kgid(&init_user_ns, exp->ex_anon_gid);
62  else
63  GROUP_AT(gi, i) = GROUP_AT(rqgi, i);
64  }
65  } else {
66  gi = get_group_info(rqgi);
67  }
68 
69  if (new->fsuid == (uid_t) -1)
70  new->fsuid = exp->ex_anon_uid;
71  if (new->fsgid == (gid_t) -1)
72  new->fsgid = exp->ex_anon_gid;
73 
74  ret = set_groups(new, gi);
75  put_group_info(gi);
76  if (ret < 0)
77  goto error;
78 
79  if (new->fsuid)
80  new->cap_effective = cap_drop_nfsd_set(new->cap_effective);
81  else
82  new->cap_effective = cap_raise_nfsd_set(new->cap_effective,
83  new->cap_permitted);
84  validate_process_creds();
85  put_cred(override_creds(new));
86  put_cred(new);
87  validate_process_creds();
88  return 0;
89 
90 oom:
91  ret = -ENOMEM;
92 error:
93  abort_creds(new);
94  return ret;
95 }
96