1 /* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
3 #include <linux/sched.h>
7 int nfsexp_flags(struct svc_rqst
*rqstp
, struct svc_export
*exp
)
9 struct exp_flavor_info
*f
;
10 struct exp_flavor_info
*end
= exp
->ex_flavors
+ exp
->ex_nflavors
;
12 for (f
= exp
->ex_flavors
; f
< end
; f
++) {
13 if (f
->pseudoflavor
== rqstp
->rq_cred
.cr_flavor
)
20 int nfsd_setuser(struct svc_rqst
*rqstp
, struct svc_export
*exp
)
22 struct group_info
*rqgi
;
23 struct group_info
*gi
;
26 int flags
= nfsexp_flags(rqstp
, exp
);
28 validate_process_creds();
30 /* discard any old override before preparing the new set */
31 revert_creds(get_cred(current_real_cred()));
32 new = prepare_creds();
36 new->fsuid
= rqstp
->rq_cred
.cr_uid
;
37 new->fsgid
= rqstp
->rq_cred
.cr_gid
;
39 rqgi
= rqstp
->rq_cred
.cr_group_info
;
41 if (flags
& NFSEXP_ALLSQUASH
) {
42 new->fsuid
= exp
->ex_anon_uid
;
43 new->fsgid
= exp
->ex_anon_gid
;
47 } else if (flags
& NFSEXP_ROOTSQUASH
) {
48 if (uid_eq(new->fsuid
, GLOBAL_ROOT_UID
))
49 new->fsuid
= exp
->ex_anon_uid
;
50 if (gid_eq(new->fsgid
, GLOBAL_ROOT_GID
))
51 new->fsgid
= exp
->ex_anon_gid
;
53 gi
= groups_alloc(rqgi
->ngroups
);
57 for (i
= 0; i
< rqgi
->ngroups
; i
++) {
58 if (gid_eq(GLOBAL_ROOT_GID
, GROUP_AT(rqgi
, i
)))
59 GROUP_AT(gi
, i
) = exp
->ex_anon_gid
;
61 GROUP_AT(gi
, i
) = GROUP_AT(rqgi
, i
);
65 /* Each thread allocates its own gi, no race */
68 gi
= get_group_info(rqgi
);
71 if (uid_eq(new->fsuid
, INVALID_UID
))
72 new->fsuid
= exp
->ex_anon_uid
;
73 if (gid_eq(new->fsgid
, INVALID_GID
))
74 new->fsgid
= exp
->ex_anon_gid
;
79 if (!uid_eq(new->fsuid
, GLOBAL_ROOT_UID
))
80 new->cap_effective
= cap_drop_nfsd_set(new->cap_effective
);
82 new->cap_effective
= cap_raise_nfsd_set(new->cap_effective
,
84 validate_process_creds();
85 put_cred(override_creds(new));
87 validate_process_creds();