Skip to content

Commit

Permalink
SUNRPC: add svcauth_map_clnt_to_svc_cred_local
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
westonandrosadamson authored and Anna Schumaker committed Sep 23, 2024
1 parent 2c89198 commit 199f212
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
5 changes: 5 additions & 0 deletions include/linux/sunrpc/svcauth.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/sunrpc/msg_prot.h>
#include <linux/sunrpc/cache.h>
#include <linux/sunrpc/gss_api.h>
#include <linux/sunrpc/clnt.h>
#include <linux/hash.h>
#include <linux/stringhash.h>
#include <linux/cred.h>
Expand Down Expand Up @@ -157,6 +158,10 @@ extern enum svc_auth_status svc_set_client(struct svc_rqst *rqstp);
extern int svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops);
extern void svc_auth_unregister(rpc_authflavor_t flavor);

extern void svcauth_map_clnt_to_svc_cred_local(struct rpc_clnt *clnt,
const struct cred *,
struct svc_cred *);

extern struct auth_domain *unix_domain_find(char *name);
extern void auth_domain_put(struct auth_domain *item);
extern struct auth_domain *auth_domain_lookup(char *name, struct auth_domain *new);
Expand Down
28 changes: 28 additions & 0 deletions net/sunrpc/svcauth.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <linux/sunrpc/svcauth.h>
#include <linux/err.h>
#include <linux/hash.h>
#include <linux/user_namespace.h>

#include <trace/events/sunrpc.h>

Expand Down Expand Up @@ -175,6 +176,33 @@ rpc_authflavor_t svc_auth_flavor(struct svc_rqst *rqstp)
}
EXPORT_SYMBOL_GPL(svc_auth_flavor);

/**
* svcauth_map_clnt_to_svc_cred_local - maps a generic cred
* to a svc_cred suitable for use in nfsd.
* @clnt: rpc_clnt associated with nfs client
* @cred: generic cred associated with nfs client
* @svc: returned svc_cred that is suitable for use in nfsd
*/
void svcauth_map_clnt_to_svc_cred_local(struct rpc_clnt *clnt,
const struct cred *cred,
struct svc_cred *svc)
{
struct user_namespace *userns = clnt->cl_cred ?
clnt->cl_cred->user_ns : &init_user_ns;

memset(svc, 0, sizeof(struct svc_cred));

svc->cr_uid = KUIDT_INIT(from_kuid_munged(userns, cred->fsuid));
svc->cr_gid = KGIDT_INIT(from_kgid_munged(userns, cred->fsgid));
svc->cr_flavor = clnt->cl_auth->au_flavor;
if (cred->group_info)
svc->cr_group_info = get_group_info(cred->group_info);
/* These aren't relevant for local (network is bypassed) */
svc->cr_principal = NULL;
svc->cr_gss_mech = NULL;
}
EXPORT_SYMBOL_GPL(svcauth_map_clnt_to_svc_cred_local);

/**************************************************
* 'auth_domains' are stored in a hash table indexed by name.
* When the last reference to an 'auth_domain' is dropped,
Expand Down

0 comments on commit 199f212

Please sign in to comment.