2005-04-17 02:20:36 +04:00
/*
* linux / fs / nfsd / auth . c
*
* Copyright ( C ) 1995 , 1996 Olaf Kirch < okir @ monad . swb . de >
*/
# include <linux/types.h>
# include <linux/sched.h>
# include <linux/sunrpc/svc.h>
# include <linux/sunrpc/svcauth.h>
# include <linux/nfsd/nfsd.h>
2007-07-19 12:49:20 +04:00
# include <linux/nfsd/export.h>
2008-02-20 23:49:00 +03:00
# include "auth.h"
2005-04-17 02:20:36 +04:00
2007-07-19 12:49:20 +04:00
int nfsexp_flags ( struct svc_rqst * rqstp , struct svc_export * exp )
2007-07-17 15:04:52 +04:00
{
struct exp_flavor_info * f ;
struct exp_flavor_info * end = exp - > ex_flavors + exp - > ex_nflavors ;
for ( f = exp - > ex_flavors ; f < end ; f + + ) {
if ( f - > pseudoflavor = = rqstp - > rq_flavor )
return f - > flags ;
}
return exp - > ex_flags ;
}
2005-04-17 02:20:36 +04:00
int nfsd_setuser ( struct svc_rqst * rqstp , struct svc_export * exp )
{
2006-04-11 09:55:30 +04:00
struct svc_cred cred = rqstp - > rq_cred ;
2005-04-17 02:20:36 +04:00
int i ;
2007-07-17 15:04:52 +04:00
int flags = nfsexp_flags ( rqstp , exp ) ;
2005-04-17 02:20:36 +04:00
int ret ;
2007-07-17 15:04:52 +04:00
if ( flags & NFSEXP_ALLSQUASH ) {
2006-04-11 09:55:30 +04:00
cred . cr_uid = exp - > ex_anon_uid ;
cred . cr_gid = exp - > ex_anon_gid ;
cred . cr_group_info = groups_alloc ( 0 ) ;
2007-07-17 15:04:52 +04:00
} else if ( flags & NFSEXP_ROOTSQUASH ) {
2005-04-17 02:20:36 +04:00
struct group_info * gi ;
2006-04-11 09:55:30 +04:00
if ( ! cred . cr_uid )
cred . cr_uid = exp - > ex_anon_uid ;
if ( ! cred . cr_gid )
cred . cr_gid = exp - > ex_anon_gid ;
gi = groups_alloc ( cred . cr_group_info - > ngroups ) ;
2005-04-17 02:20:36 +04:00
if ( gi )
2006-04-11 09:55:30 +04:00
for ( i = 0 ; i < cred . cr_group_info - > ngroups ; i + + ) {
if ( ! GROUP_AT ( cred . cr_group_info , i ) )
2005-04-17 02:20:36 +04:00
GROUP_AT ( gi , i ) = exp - > ex_anon_gid ;
else
2006-04-11 09:55:30 +04:00
GROUP_AT ( gi , i ) = GROUP_AT ( cred . cr_group_info , i ) ;
2005-04-17 02:20:36 +04:00
}
2006-04-11 09:55:30 +04:00
cred . cr_group_info = gi ;
} else
get_group_info ( cred . cr_group_info ) ;
2005-04-17 02:20:36 +04:00
2006-04-11 09:55:30 +04:00
if ( cred . cr_uid ! = ( uid_t ) - 1 )
current - > fsuid = cred . cr_uid ;
2005-04-17 02:20:36 +04:00
else
current - > fsuid = exp - > ex_anon_uid ;
2006-04-11 09:55:30 +04:00
if ( cred . cr_gid ! = ( gid_t ) - 1 )
current - > fsgid = cred . cr_gid ;
2005-04-17 02:20:36 +04:00
else
current - > fsgid = exp - > ex_anon_gid ;
2006-04-11 09:55:30 +04:00
if ( ! cred . cr_group_info )
2005-04-17 02:20:36 +04:00
return - ENOMEM ;
2006-04-11 09:55:30 +04:00
ret = set_current_groups ( cred . cr_group_info ) ;
put_group_info ( cred . cr_group_info ) ;
if ( ( cred . cr_uid ) ) {
2008-02-05 09:29:42 +03:00
current - > cap_effective =
cap_drop_nfsd_set ( current - > cap_effective ) ;
2005-04-17 02:20:36 +04:00
} else {
2008-02-05 09:29:42 +03:00
current - > cap_effective =
cap_raise_nfsd_set ( current - > cap_effective ,
current - > cap_permitted ) ;
2005-04-17 02:20:36 +04:00
}
return ret ;
}