Skip to content

Commit 199f212

Browse files
westonandrosadamsonAnna Schumaker
authored andcommitted
SUNRPC: add svcauth_map_clnt_to_svc_cred_local
Add new funtion svcauth_map_clnt_to_svc_cred_local which maps a generic cred to a svc_cred suitable for use in nfsd. This is needed by the localio code to map nfs client creds to nfs server credentials. Following from net/sunrpc/auth_unix.c:unx_marshal() it is clear that ->fsuid and ->fsgid must be used (rather than ->uid and ->gid). In addition, these uid and gid must be translated with from_kuid_munged() so local client uses correct uid and gid when acting as local server. Jeff Layton noted: This is where the magic happens. Since we're working in kuid_t/kgid_t, we don't need to worry about further idmapping. Suggested-by: NeilBrown <[email protected]> # to approximate unx_marshal() Signed-off-by: Weston Andros Adamson <[email protected]> Signed-off-by: Trond Myklebust <[email protected]> Co-developed-by: Mike Snitzer <[email protected]> Signed-off-by: Mike Snitzer <[email protected]> Reviewed-by: Chuck Lever <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Reviewed-by: NeilBrown <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent 2c89198 commit 199f212

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

include/linux/sunrpc/svcauth.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/sunrpc/msg_prot.h>
1515
#include <linux/sunrpc/cache.h>
1616
#include <linux/sunrpc/gss_api.h>
17+
#include <linux/sunrpc/clnt.h>
1718
#include <linux/hash.h>
1819
#include <linux/stringhash.h>
1920
#include <linux/cred.h>
@@ -157,6 +158,10 @@ extern enum svc_auth_status svc_set_client(struct svc_rqst *rqstp);
157158
extern int svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops);
158159
extern void svc_auth_unregister(rpc_authflavor_t flavor);
159160

161+
extern void svcauth_map_clnt_to_svc_cred_local(struct rpc_clnt *clnt,
162+
const struct cred *,
163+
struct svc_cred *);
164+
160165
extern struct auth_domain *unix_domain_find(char *name);
161166
extern void auth_domain_put(struct auth_domain *item);
162167
extern struct auth_domain *auth_domain_lookup(char *name, struct auth_domain *new);

net/sunrpc/svcauth.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/sunrpc/svcauth.h>
1919
#include <linux/err.h>
2020
#include <linux/hash.h>
21+
#include <linux/user_namespace.h>
2122

2223
#include <trace/events/sunrpc.h>
2324

@@ -175,6 +176,33 @@ rpc_authflavor_t svc_auth_flavor(struct svc_rqst *rqstp)
175176
}
176177
EXPORT_SYMBOL_GPL(svc_auth_flavor);
177178

179+
/**
180+
* svcauth_map_clnt_to_svc_cred_local - maps a generic cred
181+
* to a svc_cred suitable for use in nfsd.
182+
* @clnt: rpc_clnt associated with nfs client
183+
* @cred: generic cred associated with nfs client
184+
* @svc: returned svc_cred that is suitable for use in nfsd
185+
*/
186+
void svcauth_map_clnt_to_svc_cred_local(struct rpc_clnt *clnt,
187+
const struct cred *cred,
188+
struct svc_cred *svc)
189+
{
190+
struct user_namespace *userns = clnt->cl_cred ?
191+
clnt->cl_cred->user_ns : &init_user_ns;
192+
193+
memset(svc, 0, sizeof(struct svc_cred));
194+
195+
svc->cr_uid = KUIDT_INIT(from_kuid_munged(userns, cred->fsuid));
196+
svc->cr_gid = KGIDT_INIT(from_kgid_munged(userns, cred->fsgid));
197+
svc->cr_flavor = clnt->cl_auth->au_flavor;
198+
if (cred->group_info)
199+
svc->cr_group_info = get_group_info(cred->group_info);
200+
/* These aren't relevant for local (network is bypassed) */
201+
svc->cr_principal = NULL;
202+
svc->cr_gss_mech = NULL;
203+
}
204+
EXPORT_SYMBOL_GPL(svcauth_map_clnt_to_svc_cred_local);
205+
178206
/**************************************************
179207
* 'auth_domains' are stored in a hash table indexed by name.
180208
* When the last reference to an 'auth_domain' is dropped,

0 commit comments

Comments
 (0)