1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
4 #include <linux/sched.h>
8 int nfsexp_flags(struct svc_cred
*cred
, struct svc_export
*exp
)
10 struct exp_flavor_info
*f
;
11 struct exp_flavor_info
*end
= exp
->ex_flavors
+ exp
->ex_nflavors
;
13 for (f
= exp
->ex_flavors
; f
< end
; f
++) {
14 if (f
->pseudoflavor
== cred
->cr_flavor
)
21 int nfsd_setuser(struct svc_cred
*cred
, struct svc_export
*exp
)
23 struct group_info
*rqgi
;
24 struct group_info
*gi
;
27 int flags
= nfsexp_flags(cred
, exp
);
29 /* discard any old override before preparing the new set */
30 revert_creds(get_cred(current_real_cred()));
31 new = prepare_creds();
35 new->fsuid
= cred
->cr_uid
;
36 new->fsgid
= cred
->cr_gid
;
38 rqgi
= cred
->cr_group_info
;
40 if (flags
& NFSEXP_ALLSQUASH
) {
41 new->fsuid
= exp
->ex_anon_uid
;
42 new->fsgid
= exp
->ex_anon_gid
;
46 } else if (flags
& NFSEXP_ROOTSQUASH
) {
47 if (uid_eq(new->fsuid
, GLOBAL_ROOT_UID
))
48 new->fsuid
= exp
->ex_anon_uid
;
49 if (gid_eq(new->fsgid
, GLOBAL_ROOT_GID
))
50 new->fsgid
= exp
->ex_anon_gid
;
52 gi
= groups_alloc(rqgi
->ngroups
);
56 for (i
= 0; i
< rqgi
->ngroups
; i
++) {
57 if (gid_eq(GLOBAL_ROOT_GID
, rqgi
->gid
[i
]))
58 gi
->gid
[i
] = exp
->ex_anon_gid
;
60 gi
->gid
[i
] = rqgi
->gid
[i
];
63 /* Each thread allocates its own gi, no race */
66 gi
= get_group_info(rqgi
);
69 if (uid_eq(new->fsuid
, INVALID_UID
))
70 new->fsuid
= exp
->ex_anon_uid
;
71 if (gid_eq(new->fsgid
, INVALID_GID
))
72 new->fsgid
= exp
->ex_anon_gid
;
77 if (!uid_eq(new->fsuid
, GLOBAL_ROOT_UID
))
78 new->cap_effective
= cap_drop_nfsd_set(new->cap_effective
);
80 new->cap_effective
= cap_raise_nfsd_set(new->cap_effective
,
82 put_cred(override_creds(new));