diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-03-12 12:24:49 -0400 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-03-14 13:42:38 -0400 |
| commit | 9a559efd4199c9812d339e23cc1b6055366b224f (patch) | |
| tree | 44ae54434a6bd368693ea76b210448496e222e46 | |
| parent | 4ccda2cdd8d156b6f49440653d5d6997e0facf97 (diff) | |
SUNRPC: Add a generic RPC credential
Add an rpc credential that is not tied to any particular auth mechanism,
but that can be cached by NFS, and later used to look up a cred for
whichever auth mechanism that turns out to be valid when the RPC call is
being made.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
| -rw-r--r-- | include/linux/sunrpc/auth.h | 3 | ||||
| -rw-r--r-- | net/sunrpc/Makefile | 2 | ||||
| -rw-r--r-- | net/sunrpc/auth.c | 1 | ||||
| -rw-r--r-- | net/sunrpc/auth_generic.c | 142 |
4 files changed, 147 insertions, 1 deletions
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index 348546c7826c..70644ed67996 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h | |||
| @@ -125,9 +125,12 @@ extern const struct rpc_authops authunix_ops; | |||
| 125 | extern const struct rpc_authops authnull_ops; | 125 | extern const struct rpc_authops authnull_ops; |
| 126 | 126 | ||
| 127 | void __init rpc_init_authunix(void); | 127 | void __init rpc_init_authunix(void); |
| 128 | void __init rpc_init_generic_auth(void); | ||
| 128 | void __init rpcauth_init_module(void); | 129 | void __init rpcauth_init_module(void); |
| 129 | void __exit rpcauth_remove_module(void); | 130 | void __exit rpcauth_remove_module(void); |
| 131 | void __exit rpc_destroy_generic_auth(void); | ||
| 130 | 132 | ||
| 133 | struct rpc_cred * rpc_lookup_cred(void); | ||
| 131 | int rpcauth_register(const struct rpc_authops *); | 134 | int rpcauth_register(const struct rpc_authops *); |
| 132 | int rpcauth_unregister(const struct rpc_authops *); | 135 | int rpcauth_unregister(const struct rpc_authops *); |
| 133 | struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *); | 136 | struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *); |
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile index 92e1dbe50947..5369aa369b35 100644 --- a/net/sunrpc/Makefile +++ b/net/sunrpc/Makefile | |||
| @@ -8,7 +8,7 @@ obj-$(CONFIG_SUNRPC_GSS) += auth_gss/ | |||
| 8 | obj-$(CONFIG_SUNRPC_XPRT_RDMA) += xprtrdma/ | 8 | obj-$(CONFIG_SUNRPC_XPRT_RDMA) += xprtrdma/ |
| 9 | 9 | ||
| 10 | sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \ | 10 | sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \ |
| 11 | auth.o auth_null.o auth_unix.o \ | 11 | auth.o auth_null.o auth_unix.o auth_generic.o \ |
| 12 | svc.o svcsock.o svcauth.o svcauth_unix.o \ | 12 | svc.o svcsock.o svcauth.o svcauth_unix.o \ |
| 13 | rpcb_clnt.o timer.o xdr.o \ | 13 | rpcb_clnt.o timer.o xdr.o \ |
| 14 | sunrpc_syms.o cache.o rpc_pipe.o \ | 14 | sunrpc_syms.o cache.o rpc_pipe.o \ |
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 1cdb163c4f89..012f2a320638 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
| @@ -566,6 +566,7 @@ static struct shrinker rpc_cred_shrinker = { | |||
| 566 | void __init rpcauth_init_module(void) | 566 | void __init rpcauth_init_module(void) |
| 567 | { | 567 | { |
| 568 | rpc_init_authunix(); | 568 | rpc_init_authunix(); |
| 569 | rpc_init_generic_auth(); | ||
| 569 | register_shrinker(&rpc_cred_shrinker); | 570 | register_shrinker(&rpc_cred_shrinker); |
| 570 | } | 571 | } |
| 571 | 572 | ||
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c new file mode 100644 index 000000000000..6f129b1b20a0 --- /dev/null +++ b/net/sunrpc/auth_generic.c | |||
| @@ -0,0 +1,142 @@ | |||
| 1 | /* | ||
| 2 | * Generic RPC credential | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008, Trond Myklebust <Trond.Myklebust@netapp.com> | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/err.h> | ||
| 8 | #include <linux/types.h> | ||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/sched.h> | ||
| 11 | #include <linux/sunrpc/auth.h> | ||
| 12 | #include <linux/sunrpc/clnt.h> | ||
| 13 | #include <linux/sunrpc/debug.h> | ||
| 14 | #include <linux/sunrpc/sched.h> | ||
| 15 | |||
| 16 | #ifdef RPC_DEBUG | ||
| 17 | # define RPCDBG_FACILITY RPCDBG_AUTH | ||
| 18 | #endif | ||
| 19 | |||
| 20 | struct generic_cred { | ||
| 21 | struct rpc_cred gc_base; | ||
| 22 | struct auth_cred acred; | ||
| 23 | }; | ||
| 24 | |||
| 25 | static struct rpc_auth generic_auth; | ||
| 26 | static struct rpc_cred_cache generic_cred_cache; | ||
| 27 | static const struct rpc_credops generic_credops; | ||
| 28 | |||
| 29 | /* | ||
| 30 | * Public call interface | ||
| 31 | */ | ||
| 32 | struct rpc_cred *rpc_lookup_cred(void) | ||
| 33 | { | ||
| 34 | return rpcauth_lookupcred(&generic_auth, 0); | ||
| 35 | } | ||
| 36 | EXPORT_SYMBOL_GPL(rpc_lookup_cred); | ||
| 37 | |||
| 38 | /* | ||
| 39 | * Lookup generic creds for current process | ||
| 40 | */ | ||
| 41 | static struct rpc_cred * | ||
| 42 | generic_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) | ||
| 43 | { | ||
| 44 | return rpcauth_lookup_credcache(&generic_auth, acred, flags); | ||
| 45 | } | ||
| 46 | |||
| 47 | static struct rpc_cred * | ||
| 48 | generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) | ||
| 49 | { | ||
| 50 | struct generic_cred *gcred; | ||
| 51 | |||
| 52 | gcred = kmalloc(sizeof(*gcred), GFP_KERNEL); | ||
| 53 | if (gcred == NULL) | ||
| 54 | return ERR_PTR(-ENOMEM); | ||
| 55 | |||
| 56 | rpcauth_init_cred(&gcred->gc_base, acred, &generic_auth, &generic_credops); | ||
| 57 | gcred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE; | ||
| 58 | |||
| 59 | gcred->acred.uid = acred->uid; | ||
| 60 | gcred->acred.gid = acred->gid; | ||
| 61 | gcred->acred.group_info = acred->group_info; | ||
| 62 | if (gcred->acred.group_info != NULL) | ||
| 63 | get_group_info(gcred->acred.group_info); | ||
| 64 | |||
| 65 | dprintk("RPC: allocated generic cred %p for uid %d gid %d\n", | ||
| 66 | gcred, acred->uid, acred->gid); | ||
| 67 | return &gcred->gc_base; | ||
| 68 | } | ||
| 69 | |||
| 70 | static void | ||
| 71 | generic_free_cred(struct rpc_cred *cred) | ||
| 72 | { | ||
| 73 | struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base); | ||
| 74 | |||
| 75 | dprintk("RPC: generic_free_cred %p\n", gcred); | ||
| 76 | if (gcred->acred.group_info != NULL) | ||
| 77 | put_group_info(gcred->acred.group_info); | ||
| 78 | kfree(gcred); | ||
| 79 | } | ||
| 80 | |||
| 81 | static void | ||
| 82 | generic_free_cred_callback(struct rcu_head *head) | ||
| 83 | { | ||
| 84 | struct rpc_cred *cred = container_of(head, struct rpc_cred, cr_rcu); | ||
| 85 | generic_free_cred(cred); | ||
| 86 | } | ||
| 87 | |||
| 88 | static void | ||
| 89 | generic_destroy_cred(struct rpc_cred *cred) | ||
| 90 | { | ||
| 91 | call_rcu(&cred->cr_rcu, generic_free_cred_callback); | ||
| 92 | } | ||
| 93 | |||
| 94 | /* | ||
| 95 | * Match credentials against current process creds. | ||
| 96 | */ | ||
| 97 | static int | ||
| 98 | generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags) | ||
| 99 | { | ||
| 100 | struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base); | ||
| 101 | |||
| 102 | if (gcred->acred.uid != acred->uid || | ||
| 103 | gcred->acred.gid != acred->gid || | ||
| 104 | gcred->acred.group_info != acred->group_info) | ||
| 105 | return 0; | ||
| 106 | return 1; | ||
| 107 | } | ||
| 108 | |||
| 109 | void __init rpc_init_generic_auth(void) | ||
| 110 | { | ||
| 111 | spin_lock_init(&generic_cred_cache.lock); | ||
| 112 | } | ||
| 113 | |||
| 114 | void __exit rpc_destroy_generic_auth(void) | ||
| 115 | { | ||
| 116 | rpcauth_clear_credcache(&generic_cred_cache); | ||
| 117 | } | ||
| 118 | |||
| 119 | static struct rpc_cred_cache generic_cred_cache = { | ||
| 120 | {{ NULL, },}, | ||
| 121 | }; | ||
| 122 | |||
| 123 | static const struct rpc_authops generic_auth_ops = { | ||
| 124 | .owner = THIS_MODULE, | ||
| 125 | #ifdef RPC_DEBUG | ||
| 126 | .au_name = "Generic", | ||
| 127 | #endif | ||
| 128 | .lookup_cred = generic_lookup_cred, | ||
| 129 | .crcreate = generic_create_cred, | ||
| 130 | }; | ||
| 131 | |||
| 132 | static struct rpc_auth generic_auth = { | ||
| 133 | .au_ops = &generic_auth_ops, | ||
| 134 | .au_count = ATOMIC_INIT(0), | ||
| 135 | .au_credcache = &generic_cred_cache, | ||
| 136 | }; | ||
| 137 | |||
| 138 | static const struct rpc_credops generic_credops = { | ||
| 139 | .cr_name = "Generic cred", | ||
| 140 | .crdestroy = generic_destroy_cred, | ||
| 141 | .crmatch = generic_match, | ||
| 142 | }; | ||
