1 /*
2  * linux/fs/nfsd/auth.c
3  *
4  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
5  */
6 
7 #include <linux/types.h>
8 #include <linux/sched.h>
9 #include <linux/sunrpc/svc.h>
10 #include <linux/sunrpc/svcauth.h>
11 #include <linux/nfsd/nfsd.h>
12 
13 #define	CAP_NFSD_MASK (CAP_FS_MASK|CAP_TO_MASK(CAP_SYS_RESOURCE))
14 void
nfsd_setuser(struct svc_rqst * rqstp,struct svc_export * exp)15 nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
16 {
17 	struct svc_cred	*cred = &rqstp->rq_cred;
18 	int		i;
19 
20 	if (rqstp->rq_userset)
21 		return;
22 
23 	if (exp->ex_flags & NFSEXP_ALLSQUASH) {
24 		cred->cr_uid = exp->ex_anon_uid;
25 		cred->cr_gid = exp->ex_anon_gid;
26 		cred->cr_groups[0] = NOGROUP;
27 	} else if (exp->ex_flags & NFSEXP_ROOTSQUASH) {
28 		if (!cred->cr_uid)
29 			cred->cr_uid = exp->ex_anon_uid;
30 		if (!cred->cr_gid)
31 			cred->cr_gid = exp->ex_anon_gid;
32 		for (i = 0; i < NGROUPS; i++)
33 			if (!cred->cr_groups[i])
34 				cred->cr_groups[i] = exp->ex_anon_gid;
35 	}
36 
37 	if (cred->cr_uid != (uid_t) -1)
38 		current->fsuid = cred->cr_uid;
39 	else
40 		current->fsuid = exp->ex_anon_uid;
41 	if (cred->cr_gid != (gid_t) -1)
42 		current->fsgid = cred->cr_gid;
43 	else
44 		current->fsgid = exp->ex_anon_gid;
45 	for (i = 0; i < NGROUPS; i++) {
46 		gid_t group = cred->cr_groups[i];
47 		if (group == (gid_t) NOGROUP)
48 			break;
49 		current->groups[i] = group;
50 	}
51 	current->ngroups = i;
52 
53 	if ((cred->cr_uid)) {
54 		cap_t(current->cap_effective) &= ~CAP_NFSD_MASK;
55 	} else {
56 		cap_t(current->cap_effective) |= (CAP_NFSD_MASK &
57 						  current->cap_permitted);
58 	}
59 
60 	rqstp->rq_userset = 1;
61 }
62